@ondoher/enigma 1.0.2 → 1.0.5
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/README.md +75 -48
- package/dist/index.d.ts +899 -0
- package/jsconfig.json +7 -1
- package/lib/enigma/Encoder.js +154 -12
- package/lib/enigma/Enigma.js +45 -59
- package/lib/enigma/EnigmaTypes.d.ts +115 -18
- package/lib/enigma/EntryDisc.js +2 -8
- package/lib/enigma/PlugBoard.js +4 -9
- package/lib/enigma/Reflector.js +5 -9
- package/lib/enigma/Rotor.js +43 -36
- package/lib/enigma/index.js +1 -1
- package/lib/enigma/tests/EnigmaSpec.js +21 -15
- package/lib/enigma/tests/RotorData.js +1 -1
- package/lib/enigma/tests/RotorSpec.js +3 -1
- package/lib/generator/CodeBook.js +3 -3
- package/lib/generator/Generator.js +6 -5
- package/lib/generator/GeneratorTypes.d.ts +2 -1
- package/lib/utils/Random.js +1 -1
- package/package.json +8 -2
- package/scripts/EnigmaData.js +236 -0
- package/scripts/hamlet.html +8880 -0
- package/scripts/make-validated-data.js +4 -0
- package/scripts/parseHamlet.js +32 -0
- package/scripts/test-messages.js +60 -0
- package/scripts/test.js +118 -0
- package/scripts/x +6446 -0
- package/tsconfig.json +19 -0
- package/types/enigma/Encoder.d.ts +128 -0
- package/types/enigma/Enigma.d.ts +88 -0
- package/types/enigma/EntryDisc.d.ts +17 -0
- package/types/enigma/Inventory.d.ts +91 -0
- package/types/enigma/PlugBoard.d.ts +26 -0
- package/types/enigma/Reflector.d.ts +14 -0
- package/types/enigma/Rotor.d.ts +59 -0
- package/types/enigma/consts.d.ts +1 -0
- package/types/enigma/index.d.ts +5 -0
- package/types/enigma/standardInventory.d.ts +71 -0
- package/types/enigma/tests/EnigmaData.d.ts +46 -0
- package/types/enigma/tests/EnigmaSpec.d.ts +1 -0
- package/types/enigma/tests/PlugBoardData.d.ts +4 -0
- package/types/enigma/tests/PlugBoardSpec.d.ts +1 -0
- package/types/enigma/tests/RotorData.d.ts +15 -0
- package/types/enigma/tests/RotorSpec.d.ts +1 -0
- package/types/generator/CodeBook.d.ts +82 -0
- package/types/generator/Generator.d.ts +67 -0
- package/types/generator/hamlet.d.ts +2 -0
- package/types/generator/index.d.ts +3 -0
- package/types/index.d.ts +899 -0
- package/types/utils/Random.d.ts +131 -0
package/jsconfig.json
CHANGED
package/lib/enigma/Encoder.js
CHANGED
|
@@ -10,14 +10,21 @@ export default class Encoder {
|
|
|
10
10
|
* Constructor for the base encoder
|
|
11
11
|
*
|
|
12
12
|
* @param {string} name
|
|
13
|
+
* @param {ComponentType} type
|
|
13
14
|
* @param {EncoderSetup} settings
|
|
14
15
|
*/
|
|
15
|
-
constructor(name, settings) {
|
|
16
|
+
constructor(name, type, settings) {
|
|
16
17
|
let {cb, alphabet = STANDARD_ALPHABET} = settings;
|
|
17
18
|
this.name = name;
|
|
19
|
+
this.type = type;
|
|
18
20
|
this.alphabet = alphabet;
|
|
19
21
|
this.contactCount = alphabet.length;
|
|
20
|
-
|
|
22
|
+
/** @type {{[name: string]: Listener}} */
|
|
23
|
+
this.listeners = {}
|
|
24
|
+
|
|
25
|
+
if (cb) {
|
|
26
|
+
this.listeners["constructor"] = cb;
|
|
27
|
+
}
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
/**
|
|
@@ -31,6 +38,52 @@ export default class Encoder {
|
|
|
31
38
|
return (connector + this.contactCount * 2) % this.contactCount;
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param {string} letter
|
|
44
|
+
*
|
|
45
|
+
* @returns {boolean}
|
|
46
|
+
*/
|
|
47
|
+
verifyLetter(letter) {
|
|
48
|
+
if (letter.length !== 1 || this.alphabet.indexOf(letter) === -1) {
|
|
49
|
+
if (letter !== ' ') {
|
|
50
|
+
console.warn(`Unexpected character ${letter}`);
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Call this method to convert a letter to a connector value
|
|
60
|
+
*
|
|
61
|
+
* @param {string} letter
|
|
62
|
+
* @returns {number | undefined}
|
|
63
|
+
*/
|
|
64
|
+
letterToConnector(letter) {
|
|
65
|
+
if (!this.verifyLetter(letter)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return this.alphabet.indexOf(letter);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Call this method to turn a connector to a letter value
|
|
74
|
+
*
|
|
75
|
+
* @param {number} connector
|
|
76
|
+
* @returns {string | undefined}
|
|
77
|
+
*/
|
|
78
|
+
connectorToLetter(connector) {
|
|
79
|
+
if (connector >= this.alphabet.length) {
|
|
80
|
+
console.warn(`Unexpected connector ${connector}`);
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return this.alphabet[connector];
|
|
85
|
+
}
|
|
86
|
+
|
|
34
87
|
/**
|
|
35
88
|
* Given an alphabetic connection map, convert that into an array of
|
|
36
89
|
* numbers. The index into the array or string is the input connector, and
|
|
@@ -79,23 +132,112 @@ export default class Encoder {
|
|
|
79
132
|
}
|
|
80
133
|
|
|
81
134
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
135
|
+
*
|
|
136
|
+
* @param {number | string} input
|
|
137
|
+
* @param {Direction} direction
|
|
138
|
+
*/
|
|
139
|
+
fireInput(input, direction) {
|
|
140
|
+
if (typeof input === 'number') input = this.connectorToLetter(input)
|
|
141
|
+
|
|
142
|
+
/** @type {EventData} */
|
|
143
|
+
let eventData = {
|
|
144
|
+
name: this.name,
|
|
145
|
+
type: this.type,
|
|
146
|
+
direction,
|
|
147
|
+
description: `${this.type} "${this.name}" received signal on ${input}`,
|
|
148
|
+
event: 'input',
|
|
149
|
+
input: input
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.fire('input', this.name, eventData);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
*
|
|
157
|
+
* @param {number | string} output
|
|
158
|
+
* @param {Direction} direction
|
|
159
|
+
*/
|
|
160
|
+
fireOutput(output, direction) {
|
|
161
|
+
if (typeof output === 'number') output = this.connectorToLetter(output)
|
|
162
|
+
|
|
163
|
+
/** @type {EventData} */
|
|
164
|
+
let eventData = {
|
|
165
|
+
name: this.name,
|
|
166
|
+
type: this.type,
|
|
167
|
+
direction,
|
|
168
|
+
description: `${this.type} "${this.name}" sent signal on ${output}`,
|
|
169
|
+
event: 'output',
|
|
170
|
+
output: output
|
|
171
|
+
}
|
|
172
|
+
this.fire('output', this.name, eventData);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @param {number | string} input
|
|
178
|
+
* @param {number | string} output
|
|
179
|
+
* @param {Direction} direction
|
|
180
|
+
*/
|
|
181
|
+
fireTranslate(input, output, direction) {
|
|
182
|
+
if (typeof input === 'number') input = this.connectorToLetter(input)
|
|
183
|
+
if (typeof output === 'number') output = this.connectorToLetter(output)
|
|
184
|
+
|
|
185
|
+
/** @type {EventData} */
|
|
186
|
+
let eventData = {
|
|
187
|
+
name: this.name,
|
|
188
|
+
type: this.type,
|
|
189
|
+
direction,
|
|
190
|
+
description: `${this.type} "${this.name}" translated ${input} to ${output}`,
|
|
191
|
+
event: 'translate',
|
|
192
|
+
input, output
|
|
193
|
+
}
|
|
194
|
+
this.fire('translate', this.name, eventData);
|
|
195
|
+
}
|
|
84
196
|
|
|
85
|
-
|
|
197
|
+
/**
|
|
198
|
+
*
|
|
199
|
+
* @param {number | string} input
|
|
200
|
+
* @param {number | string} output
|
|
201
|
+
* @param {Direction} direction
|
|
202
|
+
*/
|
|
203
|
+
fireEncodeSet(input, output, direction) {
|
|
204
|
+
this.fireInput(input, direction);
|
|
205
|
+
this.fireOutput(output, direction);
|
|
206
|
+
this.fireTranslate(input, output, direction);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Call this method to add a function to be called when important events
|
|
211
|
+
* happen to a component. The name can be used to later remove the listener
|
|
212
|
+
*
|
|
213
|
+
* @param {string} name - the name of the listener
|
|
214
|
+
* @param {Listener} cb - the function to be called.
|
|
215
|
+
*/
|
|
216
|
+
listen(name, cb) {
|
|
217
|
+
this.listeners[name] = cb;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Call this method to remove a listener
|
|
222
|
+
*
|
|
223
|
+
* @param {string} name - the name of the listener
|
|
86
224
|
*/
|
|
87
|
-
|
|
88
|
-
this.
|
|
225
|
+
unlisten(name) {
|
|
226
|
+
delete this.listeners[name];
|
|
89
227
|
}
|
|
90
228
|
|
|
91
229
|
/**
|
|
92
|
-
* Call this method to call
|
|
230
|
+
* Call this method to call any event listeners
|
|
93
231
|
*
|
|
94
|
-
* @param {
|
|
95
|
-
* @param
|
|
232
|
+
* @param {EventName} event - the event being fired
|
|
233
|
+
* @param {String} name - the name of the component firing the event
|
|
234
|
+
* @param {EventData} data - the event data
|
|
96
235
|
*/
|
|
97
|
-
fire(name,
|
|
98
|
-
|
|
236
|
+
fire(event, name, data) {
|
|
237
|
+
let listeners = Object.values(this.listeners);
|
|
238
|
+
for (let cb of listeners) {
|
|
239
|
+
cb(event, name, data)
|
|
240
|
+
}
|
|
99
241
|
}
|
|
100
242
|
|
|
101
243
|
}
|
package/lib/enigma/Enigma.js
CHANGED
|
@@ -11,47 +11,33 @@ import Encoder from "./Encoder.js";
|
|
|
11
11
|
* parameters to the constructor and the config method reference the names of
|
|
12
12
|
* standard Enigma parts. These are retrieved from the Inventory instance
|
|
13
13
|
*/
|
|
14
|
-
export default class Enigma {
|
|
14
|
+
export default class Enigma extends Encoder {
|
|
15
15
|
/**
|
|
16
16
|
* The constructor for the Enigma. This represents the unconfigurable
|
|
17
17
|
* settings of the device.
|
|
18
18
|
*
|
|
19
|
+
* @param {string} name
|
|
19
20
|
* @param {EnigmaSetup} settings
|
|
20
21
|
*/
|
|
21
|
-
constructor(settings) {
|
|
22
|
-
|
|
22
|
+
constructor(name, settings) {
|
|
23
|
+
super(name, "Enigma", settings)
|
|
24
|
+
let {entryDisc = 'default', reflector, alphabet = STANDARD_ALPHABET} = settings;
|
|
23
25
|
let entryDiscSettings = inventory.getEntryDisc(entryDisc)
|
|
24
26
|
|
|
25
27
|
let reflectorSettings = inventory.getReflector(reflector)
|
|
26
28
|
this.alphabet = alphabet;
|
|
27
|
-
this.plugboard = new PlugBoard('
|
|
28
|
-
this.entryDisc = new EntryDisc('
|
|
29
|
-
this.reflector = new Reflector(
|
|
29
|
+
this.plugboard = new PlugBoard('default', {});
|
|
30
|
+
this.entryDisc = new EntryDisc('default', entryDiscSettings);
|
|
31
|
+
this.reflector = new Reflector(reflector, reflectorSettings)
|
|
30
32
|
this.length = alphabet.length;
|
|
31
33
|
/** @type {Rotor[]} */
|
|
32
34
|
this._rotors = [];
|
|
33
35
|
/** @type {{[rotor: number]: boolean}} */
|
|
34
36
|
this.pending = [];
|
|
35
|
-
this.name = model;
|
|
36
37
|
/** @type {Encoder[]} */
|
|
37
38
|
this.encoders = [];
|
|
38
39
|
/**@type {SimplifiedConfiguration & {reflector: string}} */
|
|
39
|
-
this._configuration = {reflector}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Call this method to normalize a connector number to be within the
|
|
44
|
-
* the length of the current alphabet
|
|
45
|
-
*
|
|
46
|
-
* @param {Number} connector the number to be normalized
|
|
47
|
-
*
|
|
48
|
-
* @returns {Number} the normalized connector number
|
|
49
|
-
*/
|
|
50
|
-
normalize(connector) {
|
|
51
|
-
connector += this.length;
|
|
52
|
-
connector = connector % this.length
|
|
53
|
-
|
|
54
|
-
return connector;
|
|
40
|
+
this._configuration = {reflector, ringSettings: [], rotors: [], plugs: ''};
|
|
55
41
|
}
|
|
56
42
|
|
|
57
43
|
/**
|
|
@@ -94,7 +80,7 @@ export default class Enigma {
|
|
|
94
80
|
/** @type {number[]} */
|
|
95
81
|
let ringOffsets = []
|
|
96
82
|
|
|
97
|
-
// because the rotors are specified in the reverse
|
|
83
|
+
// because the rotors are specified in the reverse order they are used,
|
|
98
84
|
// we have to do the same for the ringSettings.
|
|
99
85
|
if (Array.isArray(ringSettings)) {
|
|
100
86
|
ringSettings = ringSettings.reverse();
|
|
@@ -114,36 +100,46 @@ export default class Enigma {
|
|
|
114
100
|
}
|
|
115
101
|
|
|
116
102
|
this._rotors = useRotors.map(function(name, idx) {
|
|
117
|
-
return new Rotor(
|
|
103
|
+
return new Rotor(`${name}`, {...inventory.getRotor(name), alphabet: this.alphabet, ringSetting: ringOffsets[idx], cb: this.cb});
|
|
118
104
|
}, this);
|
|
119
105
|
|
|
120
106
|
this.encoders = [this.plugboard, this.entryDisc, ...this.rotors];
|
|
121
107
|
|
|
122
108
|
this._configuration = {...this._configuration,
|
|
123
109
|
rotors,
|
|
124
|
-
ringOffsets,
|
|
110
|
+
ringSettings: ringOffsets,
|
|
125
111
|
plugs: this.plugboard.plugs
|
|
126
112
|
}
|
|
127
113
|
}
|
|
128
114
|
|
|
129
115
|
/**
|
|
130
|
-
* Call this method to step the rotors one time. This method will manage the
|
|
116
|
+
* Call this method to "step" the rotors one time. This method will manage the
|
|
131
117
|
* stepping between all rotors
|
|
132
118
|
*/
|
|
133
119
|
step() {
|
|
134
|
-
this._rotors.forEach(
|
|
120
|
+
this._rotors.forEach((rotor, idx) => {
|
|
135
121
|
if (rotor.isFixed()) return;
|
|
136
122
|
|
|
137
123
|
// This is the double stepping. Only do this for the middle rotor
|
|
138
124
|
if (rotor.willTurnover() && idx === 1) {
|
|
139
125
|
this.pending[idx] = true
|
|
126
|
+
/** @type {EventData} */
|
|
127
|
+
let eventData = {
|
|
128
|
+
name: rotor.name,
|
|
129
|
+
description: `rotor ${rotor.name} double stepping from ${rotor.offset}`,
|
|
130
|
+
type: this.type,
|
|
131
|
+
event: "double-step",
|
|
132
|
+
offset: rotor.offset,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
this.fire('double-step', rotor.name, eventData);
|
|
140
136
|
};
|
|
141
137
|
|
|
142
138
|
if (this.pending[idx]) {
|
|
143
139
|
this.pending[idx] = false;
|
|
144
140
|
if (rotor.step()) this.pending[idx + 1] = true;
|
|
145
141
|
}
|
|
146
|
-
}
|
|
142
|
+
});
|
|
147
143
|
|
|
148
144
|
// The first rotor is always stepping
|
|
149
145
|
this.pending[0] = true;
|
|
@@ -171,8 +167,7 @@ export default class Enigma {
|
|
|
171
167
|
start = setup;
|
|
172
168
|
}
|
|
173
169
|
|
|
174
|
-
start = [...start].reverse();
|
|
175
|
-
|
|
170
|
+
start = [...start].reverse().join('');
|
|
176
171
|
// reset the rotation pending state
|
|
177
172
|
this.pending = {0: true};
|
|
178
173
|
|
|
@@ -190,23 +185,22 @@ export default class Enigma {
|
|
|
190
185
|
*/
|
|
191
186
|
keyPress(letter) {
|
|
192
187
|
letter = letter.toUpperCase();
|
|
193
|
-
if (
|
|
194
|
-
if (letter !== ' ')
|
|
195
|
-
console.warn(`Unexpected character ${letter}`);
|
|
188
|
+
if (!this.verifyLetter(letter)) {
|
|
196
189
|
return;
|
|
197
190
|
}
|
|
198
191
|
|
|
199
|
-
this.
|
|
192
|
+
let connector = this.letterToConnector(letter);
|
|
193
|
+
this.fireInput(letter, "right");
|
|
200
194
|
this.step();
|
|
201
195
|
|
|
202
196
|
// encode to the right
|
|
203
|
-
|
|
197
|
+
connector = this.encoders.reduce(function(connector, encoder, idx) {
|
|
204
198
|
connector = encoder.encode('right', connector);
|
|
205
199
|
return connector;
|
|
206
200
|
}.bind(this), this.alphabet.indexOf(letter));
|
|
207
201
|
|
|
208
202
|
// reflector
|
|
209
|
-
connector = this.reflector.encode('
|
|
203
|
+
connector = this.reflector.encode('turn-around', connector);
|
|
210
204
|
|
|
211
205
|
// encode to the left
|
|
212
206
|
connector = this.encoders.reduceRight(function(connector, encoder) {
|
|
@@ -214,9 +208,11 @@ export default class Enigma {
|
|
|
214
208
|
return connector;
|
|
215
209
|
}.bind(this), connector)
|
|
216
210
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
211
|
+
const outputLetter = this.connectorToLetter(connector);
|
|
212
|
+
|
|
213
|
+
this.fireOutput(outputLetter, "left");
|
|
214
|
+
this.fireTranslate(letter, outputLetter, "end-to-end");
|
|
215
|
+
return outputLetter;
|
|
220
216
|
}
|
|
221
217
|
|
|
222
218
|
/**
|
|
@@ -227,7 +223,7 @@ export default class Enigma {
|
|
|
227
223
|
*
|
|
228
224
|
* @returns {String} the encoded string.
|
|
229
225
|
*/
|
|
230
|
-
|
|
226
|
+
translate(start, text) {
|
|
231
227
|
this.setStart(start)
|
|
232
228
|
let letters = [...text];
|
|
233
229
|
let output = letters.map(function(letter) {
|
|
@@ -238,27 +234,17 @@ export default class Enigma {
|
|
|
238
234
|
}
|
|
239
235
|
|
|
240
236
|
/**
|
|
241
|
-
* Call this method to call the event listener
|
|
242
237
|
*
|
|
243
|
-
* @param {
|
|
244
|
-
* @param
|
|
238
|
+
* @param {string} name
|
|
239
|
+
* @param {Listener} cb
|
|
245
240
|
*/
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Call this method to set a function to be called when important events
|
|
252
|
-
* happen to a component.
|
|
241
|
+
listen(name, cb) {
|
|
242
|
+
super.listen(name, cb);
|
|
253
243
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
this.cb = cb;
|
|
258
|
-
this.encoders.forEach(function(encoder) {
|
|
259
|
-
encoder.listen(cb);
|
|
260
|
-
});
|
|
244
|
+
for (let encoder of this.encoders) {
|
|
245
|
+
encoder.listen(name, cb)
|
|
246
|
+
}
|
|
261
247
|
|
|
262
|
-
this.reflector.listen(cb);
|
|
248
|
+
this.reflector.listen(name, cb);
|
|
263
249
|
}
|
|
264
250
|
}
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
-
// type Listener = (
|
|
2
|
-
// /** name of the event being fired*/
|
|
3
|
-
// event: string,
|
|
4
1
|
|
|
5
|
-
// /** the name of th component firing the event */
|
|
6
|
-
// name: string,
|
|
7
2
|
|
|
8
|
-
|
|
9
|
-
// message: string,
|
|
10
|
-
|
|
11
|
-
// /** event specific data */
|
|
12
|
-
// info: object
|
|
13
|
-
|
|
14
|
-
// ) => void;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
type Listener = (...params: unknown[]) => void;
|
|
3
|
+
type ComponentType = ("Entry Wheel" | "Plugboard" | "Reflector" | "Rotor" | "Enigma")
|
|
19
4
|
|
|
20
5
|
interface EncoderSetup {
|
|
21
6
|
/** if specified defines an alternate alphabet for the enigma */
|
|
@@ -35,7 +20,7 @@ interface EncoderSetup {
|
|
|
35
20
|
* Defines how the enigma hardware is constructed. These are the settings that
|
|
36
21
|
* cannot be changed
|
|
37
22
|
*/
|
|
38
|
-
interface EnigmaSetup extends
|
|
23
|
+
interface EnigmaSetup extends EncoderSetup {
|
|
39
24
|
/** which entry disc is part of the machine, defaults to "default" */
|
|
40
25
|
entryDisc?: string;
|
|
41
26
|
/** which reflector is part of the machine */
|
|
@@ -98,4 +83,116 @@ interface RotorSetup extends EncoderSetup {
|
|
|
98
83
|
turnovers?: string;
|
|
99
84
|
}
|
|
100
85
|
|
|
101
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Defines the possible directions for a translation.
|
|
88
|
+
*
|
|
89
|
+
* - **right** - the signal is moving from the right to the left
|
|
90
|
+
* - **left** - the signal is moving from left to right
|
|
91
|
+
* - **turn-around** - the signal is transitioning between directions, this is
|
|
92
|
+
* sent from the reflector
|
|
93
|
+
*/
|
|
94
|
+
type Direction = ("right" | "left" | "turn-around" | "end-to-end");
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Defines the possible events sent from the enigma components.
|
|
98
|
+
*
|
|
99
|
+
* **translate** - fired when the input signal is changed from one value to another
|
|
100
|
+
* **input** - fired when a signal first enters the component
|
|
101
|
+
* **output** - fired when the signal exits the component
|
|
102
|
+
*
|
|
103
|
+
*/
|
|
104
|
+
type EventName = ("translate" | "input" | "output" | "step" | "double-step");
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Defines the common data for an event
|
|
108
|
+
*/
|
|
109
|
+
type EventBase = {
|
|
110
|
+
/** the name of the component sending the event */
|
|
111
|
+
name: string;
|
|
112
|
+
|
|
113
|
+
type: ComponentType;
|
|
114
|
+
|
|
115
|
+
/** a human readable description of the event */
|
|
116
|
+
description: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Defines the data sent for a translate event
|
|
121
|
+
*/
|
|
122
|
+
type TranslateData = {
|
|
123
|
+
/** the event name */
|
|
124
|
+
event: "translate";
|
|
125
|
+
|
|
126
|
+
/** the direction the signal was sent */
|
|
127
|
+
direction: Direction;
|
|
128
|
+
|
|
129
|
+
/** the starting value */
|
|
130
|
+
input: number | string;
|
|
131
|
+
|
|
132
|
+
/** the translated value */
|
|
133
|
+
output: number | string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* defines the data sent for a rotor step
|
|
138
|
+
*/
|
|
139
|
+
type StepData = {
|
|
140
|
+
/** the event name */
|
|
141
|
+
event: "step";
|
|
142
|
+
|
|
143
|
+
/** the starting rotor position */
|
|
144
|
+
start: number;
|
|
145
|
+
|
|
146
|
+
/** the ending rotor position */
|
|
147
|
+
stop: number;
|
|
148
|
+
|
|
149
|
+
/** the locations of the turnover points for this rotor */
|
|
150
|
+
turnover: boolean;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
type DoubleStepData = {
|
|
154
|
+
event: "double-step",
|
|
155
|
+
offset: number;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Defines the data sent with an input event
|
|
160
|
+
*/
|
|
161
|
+
type InputData = {
|
|
162
|
+
/** the event name */
|
|
163
|
+
event: "input";
|
|
164
|
+
|
|
165
|
+
/** the input connection */
|
|
166
|
+
input: number | string;
|
|
167
|
+
|
|
168
|
+
/** the direction the signal was sent */
|
|
169
|
+
direction: Direction;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Defines the data sent with an output event
|
|
174
|
+
*/
|
|
175
|
+
type OutputData = {
|
|
176
|
+
/** the event name */
|
|
177
|
+
event: "output";
|
|
178
|
+
|
|
179
|
+
/** the output connection */
|
|
180
|
+
output: number | string;
|
|
181
|
+
|
|
182
|
+
/** the direction the signal was sent */
|
|
183
|
+
direction: Direction;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Defines the discriminated union for all the event data */
|
|
187
|
+
type EventData = EventBase & (TranslateData | StepData | InputData | OutputData | DoubleStepData);
|
|
188
|
+
|
|
189
|
+
type Listener = (
|
|
190
|
+
/** name of the event being fired*/
|
|
191
|
+
event: string,
|
|
192
|
+
|
|
193
|
+
/** the name of th component firing the event */
|
|
194
|
+
name: string,
|
|
195
|
+
|
|
196
|
+
/** event specific data */
|
|
197
|
+
data: EventData
|
|
198
|
+
) => void;
|
package/lib/enigma/EntryDisc.js
CHANGED
|
@@ -15,7 +15,7 @@ export default class EntryDisc extends Encoder {
|
|
|
15
15
|
* between input and output contacts
|
|
16
16
|
*/
|
|
17
17
|
constructor(name, settings) {
|
|
18
|
-
super(name, settings);
|
|
18
|
+
super(name, "Entry Wheel", settings);
|
|
19
19
|
var {map = STANDARD_ALPHABET} = settings;
|
|
20
20
|
this.rightMap = this.makeMap(map);
|
|
21
21
|
this.leftMap = this.makeReverseMap(this.rightMap);
|
|
@@ -31,14 +31,8 @@ export default class EntryDisc extends Encoder {
|
|
|
31
31
|
*/
|
|
32
32
|
encode(direction, input) {
|
|
33
33
|
var result = direction === 'right' ? this.rightMap[input]: this.leftMap[input];
|
|
34
|
-
var evName = direction === 'right' ? 'encode-right' : 'encode-left';
|
|
35
34
|
|
|
36
|
-
this.
|
|
37
|
-
`${evName} ${this.name}, input: ${input}, output: ${result}`, {
|
|
38
|
-
input: input,
|
|
39
|
-
output: result,
|
|
40
|
-
}
|
|
41
|
-
);
|
|
35
|
+
this.fireEncodeSet(input, result, direction);
|
|
42
36
|
return result;
|
|
43
37
|
}
|
|
44
38
|
}
|
package/lib/enigma/PlugBoard.js
CHANGED
|
@@ -14,7 +14,7 @@ export default class PlugBoard extends Encoder {
|
|
|
14
14
|
* using an alternate alphabet
|
|
15
15
|
*/
|
|
16
16
|
constructor(name = 'plugboard', settings = {}) {
|
|
17
|
-
super(name, settings);
|
|
17
|
+
super(name, "Plugboard", settings);
|
|
18
18
|
|
|
19
19
|
var {alphabet = STANDARD_ALPHABET, map} = settings;
|
|
20
20
|
this.alphabet = alphabet;
|
|
@@ -57,20 +57,15 @@ export default class PlugBoard extends Encoder {
|
|
|
57
57
|
* Call this method to convert the input connector number to the output in
|
|
58
58
|
* the given direction.
|
|
59
59
|
*
|
|
60
|
-
* @param {
|
|
60
|
+
* @param {Direction} direction either right for moving towards the reflector or
|
|
61
61
|
* left if moving back
|
|
62
62
|
* @param {Number} input the input connector
|
|
63
63
|
* @returns {Number} the output connector
|
|
64
64
|
*/
|
|
65
65
|
encode(direction, input) {
|
|
66
66
|
var result = direction === 'right' ? this.rightMap[input]: this.leftMap[input];
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
`${evName} ${this.name}, input: ${input}, output: ${result}`, {
|
|
70
|
-
input: input,
|
|
71
|
-
output: result,
|
|
72
|
-
}
|
|
73
|
-
);
|
|
67
|
+
|
|
68
|
+
this.fireEncodeSet(input, result, direction);
|
|
74
69
|
|
|
75
70
|
return result;
|
|
76
71
|
}
|
package/lib/enigma/Reflector.js
CHANGED
|
@@ -13,7 +13,7 @@ export default class Reflector extends Encoder {
|
|
|
13
13
|
* @param {EncoderSetup} settings The definition of the reflector
|
|
14
14
|
*/
|
|
15
15
|
constructor(name, settings) {
|
|
16
|
-
super(name, settings);
|
|
16
|
+
super(name, "Reflector", settings);
|
|
17
17
|
var {map = STANDARD_ALPHABET} = settings;
|
|
18
18
|
|
|
19
19
|
this.map = this.makeMap(map);
|
|
@@ -24,20 +24,16 @@ export default class Reflector extends Encoder {
|
|
|
24
24
|
* the point where direction changes this does not have a distinction
|
|
25
25
|
* between a left and right signal path.
|
|
26
26
|
*
|
|
27
|
-
* @param {Direction}
|
|
27
|
+
* @param {Direction} direction since this is the point where signal direction
|
|
28
28
|
* changes from right to left this parameter is not used.
|
|
29
29
|
* @param {Number} input this is the input connector
|
|
30
30
|
*
|
|
31
31
|
* @returns {Number} the mapped output connector
|
|
32
32
|
*/
|
|
33
|
-
encode(
|
|
33
|
+
encode(direction, input) {
|
|
34
34
|
var result = this.map[input];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{
|
|
38
|
-
input: input,
|
|
39
|
-
output: result,
|
|
40
|
-
});
|
|
35
|
+
|
|
36
|
+
this.fireEncodeSet(input, result, direction)
|
|
41
37
|
|
|
42
38
|
return result;
|
|
43
39
|
}
|