@aleph-ai/tinyaleph 1.3.0 → 1.4.1
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 +423 -12
- package/backends/cryptographic/index.js +455 -2
- package/core/beacon.js +735 -0
- package/core/crt-homology.js +1004 -0
- package/core/enochian-vocabulary.js +910 -0
- package/core/enochian.js +744 -0
- package/core/errors.js +587 -0
- package/core/hilbert.js +651 -1
- package/core/index.js +86 -1
- package/core/lambda.js +284 -33
- package/core/logger.js +350 -0
- package/core/prime.js +136 -1
- package/core/quaternion-semantics.js +623 -0
- package/core/reduction.js +391 -1
- package/core/rformer-crt.js +892 -0
- package/core/topology.js +655 -0
- package/docs/README.md +54 -0
- package/docs/design/PYTHON_PORT_DESIGN.md +1400 -0
- package/docs/reference/07-topology.md +257 -0
- package/docs/reference/08-observer.md +421 -0
- package/docs/reference/09-crt-homology.md +369 -0
- package/modular.js +231 -3
- package/package.json +1 -1
|
@@ -0,0 +1,910 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enochian Formal Language System
|
|
3
|
+
*
|
|
4
|
+
* Implements the Enochian ceremonial language as a formal prime-indexed system:
|
|
5
|
+
* - 21-letter Enochian alphabet with prime mappings
|
|
6
|
+
* - Prime basis PE = {7, 11, 13, 17, 19, 23, 29}
|
|
7
|
+
* - Twist modes {α, μ, ω} with angles κ(p) = 360/p
|
|
8
|
+
* - Core vocabulary words (ZACAR, ZORGE, etc.)
|
|
9
|
+
* - The 19 Calls (ritual invocation sequences)
|
|
10
|
+
* - Sedenion integration for 16D hypercomplex operations
|
|
11
|
+
* - Twist closure validation
|
|
12
|
+
*
|
|
13
|
+
* From Section 7.4 of the Sentient Observer Whitepaper:
|
|
14
|
+
* The Enochian layer provides a low-bandwidth prime-mode surface language
|
|
15
|
+
* for robust symbolic packets with geometric validity gates.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const { isPrime, nthPrime, firstNPrimes } = require('./prime');
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// ENOCHIAN ALPHABET (21 Letters)
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The Enochian alphabet consists of 21 letters, each mapped to a prime number.
|
|
26
|
+
* The mapping follows the original Dee/Kelley system with prime assignments.
|
|
27
|
+
*/
|
|
28
|
+
const ENOCHIAN_ALPHABET = [
|
|
29
|
+
{ letter: 'A', name: 'Un', prime: 2, meaning: 'Beginning', phonetic: 'ah' },
|
|
30
|
+
{ letter: 'B', name: 'Pa', prime: 3, meaning: 'Father', phonetic: 'beh' },
|
|
31
|
+
{ letter: 'C', name: 'Veh', prime: 5, meaning: 'Creation', phonetic: 'keh' },
|
|
32
|
+
{ letter: 'D', name: 'Gal', prime: 7, meaning: 'Foundation', phonetic: 'deh' },
|
|
33
|
+
{ letter: 'E', name: 'Or', prime: 11, meaning: 'Light', phonetic: 'eh' },
|
|
34
|
+
{ letter: 'F', name: 'Don', prime: 13, meaning: 'Dominion', phonetic: 'feh' },
|
|
35
|
+
{ letter: 'G', name: 'Ged', prime: 17, meaning: 'Spirit', phonetic: 'geh' },
|
|
36
|
+
{ letter: 'H', name: 'Na', prime: 19, meaning: 'Lord', phonetic: 'heh' },
|
|
37
|
+
{ letter: 'I', name: 'Gon', prime: 23, meaning: 'Faith', phonetic: 'ee' },
|
|
38
|
+
{ letter: 'K', name: 'Ur', prime: 29, meaning: 'Fire', phonetic: 'kah' },
|
|
39
|
+
{ letter: 'L', name: 'Tal', prime: 31, meaning: 'Earth', phonetic: 'leh' },
|
|
40
|
+
{ letter: 'M', name: 'Mals', prime: 37, meaning: 'Mind', phonetic: 'meh' },
|
|
41
|
+
{ letter: 'N', name: 'Drun', prime: 41, meaning: 'Power', phonetic: 'neh' },
|
|
42
|
+
{ letter: 'O', name: 'Med', prime: 43, meaning: 'Oil/Mercy', phonetic: 'oh' },
|
|
43
|
+
{ letter: 'P', name: 'Ceph', prime: 47, meaning: 'Judgment', phonetic: 'peh' },
|
|
44
|
+
{ letter: 'Q', name: 'Ger', prime: 53, meaning: 'Nature', phonetic: 'kweh' },
|
|
45
|
+
{ letter: 'R', name: 'Graph', prime: 59, meaning: 'Throne', phonetic: 'reh' },
|
|
46
|
+
{ letter: 'S', name: 'Fam', prime: 61, meaning: 'Voice', phonetic: 'seh' },
|
|
47
|
+
{ letter: 'T', name: 'Gisg', prime: 67, meaning: 'Time', phonetic: 'teh' },
|
|
48
|
+
{ letter: 'U', name: 'Van', prime: 71, meaning: 'Motion', phonetic: 'oo' },
|
|
49
|
+
{ letter: 'Z', name: 'Ceph', prime: 73, meaning: 'Completion', phonetic: 'zed' }
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
// Create lookup maps
|
|
53
|
+
const letterToPrime = new Map();
|
|
54
|
+
const primeToLetter = new Map();
|
|
55
|
+
const letterToData = new Map();
|
|
56
|
+
|
|
57
|
+
for (const entry of ENOCHIAN_ALPHABET) {
|
|
58
|
+
letterToPrime.set(entry.letter, entry.prime);
|
|
59
|
+
primeToLetter.set(entry.prime, entry.letter);
|
|
60
|
+
letterToData.set(entry.letter, entry);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ============================================================================
|
|
64
|
+
// PRIME BASIS PE
|
|
65
|
+
// ============================================================================
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The Enochian Prime Basis PE
|
|
69
|
+
* These seven primes form the foundation of Enochian computation
|
|
70
|
+
* PE = {7, 11, 13, 17, 19, 23, 29}
|
|
71
|
+
*/
|
|
72
|
+
const PRIME_BASIS = [7, 11, 13, 17, 19, 23, 29];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Semantic meanings of basis primes
|
|
76
|
+
*/
|
|
77
|
+
const BASIS_MEANINGS = new Map([
|
|
78
|
+
[7, 'Foundation/Structure'],
|
|
79
|
+
[11, 'Light/Illumination'],
|
|
80
|
+
[13, 'Dominion/Authority'],
|
|
81
|
+
[17, 'Spirit/Intelligence'],
|
|
82
|
+
[19, 'Lord/Governance'],
|
|
83
|
+
[23, 'Faith/Belief'],
|
|
84
|
+
[29, 'Fire/Transformation']
|
|
85
|
+
]);
|
|
86
|
+
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// TWIST MODES
|
|
89
|
+
// ============================================================================
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Twist modes represent different operational aspects
|
|
93
|
+
* Each mode applies a different phase transformation
|
|
94
|
+
*/
|
|
95
|
+
const TWIST_MODES = {
|
|
96
|
+
ALPHA: 'α', // Assertion mode
|
|
97
|
+
MU: 'μ', // Modal mode
|
|
98
|
+
OMEGA: 'ω' // Completion mode
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Calculate twist angle for a prime: κ(p) = 360/p
|
|
103
|
+
* @param {number} p - Prime number
|
|
104
|
+
* @returns {number} Twist angle in degrees
|
|
105
|
+
*/
|
|
106
|
+
function twistAngle(p) {
|
|
107
|
+
if (!isPrime(p)) {
|
|
108
|
+
throw new Error(`${p} is not prime`);
|
|
109
|
+
}
|
|
110
|
+
return 360 / p;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Calculate twist in radians
|
|
115
|
+
* @param {number} p - Prime number
|
|
116
|
+
* @returns {number} Twist angle in radians
|
|
117
|
+
*/
|
|
118
|
+
function twistRadians(p) {
|
|
119
|
+
return (2 * Math.PI) / p;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* TwistOperator - Represents a twist operation on prime space
|
|
124
|
+
*/
|
|
125
|
+
class TwistOperator {
|
|
126
|
+
constructor(prime, mode = TWIST_MODES.ALPHA) {
|
|
127
|
+
if (!isPrime(prime)) {
|
|
128
|
+
throw new Error(`${prime} is not prime`);
|
|
129
|
+
}
|
|
130
|
+
this.prime = prime;
|
|
131
|
+
this.mode = mode;
|
|
132
|
+
this.angle = twistAngle(prime);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get the rotation matrix for this twist (2D projection)
|
|
137
|
+
*/
|
|
138
|
+
getRotationMatrix() {
|
|
139
|
+
const theta = twistRadians(this.prime);
|
|
140
|
+
const cos = Math.cos(theta);
|
|
141
|
+
const sin = Math.sin(theta);
|
|
142
|
+
return [
|
|
143
|
+
[cos, -sin],
|
|
144
|
+
[sin, cos]
|
|
145
|
+
];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Apply twist to a point (2D)
|
|
150
|
+
*/
|
|
151
|
+
apply2D(x, y) {
|
|
152
|
+
const theta = twistRadians(this.prime);
|
|
153
|
+
return {
|
|
154
|
+
x: x * Math.cos(theta) - y * Math.sin(theta),
|
|
155
|
+
y: x * Math.sin(theta) + y * Math.cos(theta)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Compose with another twist operator
|
|
161
|
+
*/
|
|
162
|
+
compose(other) {
|
|
163
|
+
// Twist composition adds angles (mod 360)
|
|
164
|
+
const newAngle = (this.angle + other.angle) % 360;
|
|
165
|
+
// Find prime approximation for combined angle
|
|
166
|
+
const combinedPrime = Math.round(360 / newAngle);
|
|
167
|
+
return new TwistOperator(
|
|
168
|
+
isPrime(combinedPrime) ? combinedPrime : this.prime,
|
|
169
|
+
this.mode
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
toString() {
|
|
174
|
+
return `Twist(${this.prime}, ${this.mode}, ${this.angle.toFixed(2)}°)`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Validate twist closure for a sequence of primes
|
|
180
|
+
* Closure means the total twist is a multiple of 360°
|
|
181
|
+
*/
|
|
182
|
+
function validateTwistClosure(primes) {
|
|
183
|
+
let totalAngle = 0;
|
|
184
|
+
for (const p of primes) {
|
|
185
|
+
if (!isPrime(p)) {
|
|
186
|
+
return { valid: false, reason: `${p} is not prime` };
|
|
187
|
+
}
|
|
188
|
+
totalAngle += twistAngle(p);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Check if close to multiple of 360
|
|
192
|
+
const closeness = totalAngle % 360;
|
|
193
|
+
const isClosed = closeness < 1 || closeness > 359;
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
valid: isClosed,
|
|
197
|
+
totalAngle,
|
|
198
|
+
closeness: Math.min(closeness, 360 - closeness),
|
|
199
|
+
revolutions: Math.round(totalAngle / 360)
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ============================================================================
|
|
204
|
+
// ENOCHIAN WORD CLASS
|
|
205
|
+
// ============================================================================
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* EnochianWord - Represents a word in the Enochian language
|
|
209
|
+
*/
|
|
210
|
+
class EnochianWord {
|
|
211
|
+
/**
|
|
212
|
+
* @param {string} word - The Enochian word in Latin transliteration
|
|
213
|
+
* @param {string} meaning - English meaning
|
|
214
|
+
* @param {Object} options - Additional options
|
|
215
|
+
*/
|
|
216
|
+
constructor(word, meaning, options = {}) {
|
|
217
|
+
this.word = word.toUpperCase();
|
|
218
|
+
this.meaning = meaning;
|
|
219
|
+
this.category = options.category || 'general';
|
|
220
|
+
this.callNumber = options.callNumber || null;
|
|
221
|
+
|
|
222
|
+
// Calculate prime representation
|
|
223
|
+
this.primes = this.toPrimes();
|
|
224
|
+
this.primeProduct = this.calculateProduct();
|
|
225
|
+
this.twistSum = this.calculateTwistSum();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Convert word to prime sequence
|
|
230
|
+
*/
|
|
231
|
+
toPrimes() {
|
|
232
|
+
const primes = [];
|
|
233
|
+
for (const char of this.word) {
|
|
234
|
+
if (letterToPrime.has(char)) {
|
|
235
|
+
primes.push(letterToPrime.get(char));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return primes;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Calculate product of all letter primes
|
|
243
|
+
*/
|
|
244
|
+
calculateProduct() {
|
|
245
|
+
return this.primes.reduce((a, b) => a * b, 1);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Calculate sum of twist angles
|
|
250
|
+
*/
|
|
251
|
+
calculateTwistSum() {
|
|
252
|
+
return this.primes.reduce((sum, p) => sum + twistAngle(p), 0);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Get twist closure status
|
|
257
|
+
*/
|
|
258
|
+
getTwistClosure() {
|
|
259
|
+
return validateTwistClosure(this.primes);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get word as letter-prime pairs
|
|
264
|
+
*/
|
|
265
|
+
toLetterPrimePairs() {
|
|
266
|
+
const pairs = [];
|
|
267
|
+
for (let i = 0; i < this.word.length; i++) {
|
|
268
|
+
const char = this.word[i];
|
|
269
|
+
if (letterToPrime.has(char)) {
|
|
270
|
+
pairs.push({
|
|
271
|
+
letter: char,
|
|
272
|
+
prime: letterToPrime.get(char),
|
|
273
|
+
data: letterToData.get(char)
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return pairs;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Check if word uses only basis primes
|
|
282
|
+
*/
|
|
283
|
+
usesBasisOnly() {
|
|
284
|
+
return this.primes.every(p => PRIME_BASIS.includes(p));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Get resonance with another word (based on shared primes)
|
|
289
|
+
*/
|
|
290
|
+
resonanceWith(other) {
|
|
291
|
+
const primeSet = new Set(this.primes);
|
|
292
|
+
const otherSet = new Set(other.primes);
|
|
293
|
+
const shared = [...primeSet].filter(p => otherSet.has(p));
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
sharedPrimes: shared,
|
|
297
|
+
resonanceScore: shared.length / Math.max(primeSet.size, otherSet.size),
|
|
298
|
+
harmonicRatio: this.primeProduct / other.primeProduct
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
toString() {
|
|
303
|
+
return `${this.word} (${this.meaning}) [${this.primes.join(',')}]`;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ============================================================================
|
|
308
|
+
// CORE VOCABULARY
|
|
309
|
+
// ============================================================================
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* The core Enochian vocabulary as defined in the paper
|
|
313
|
+
*/
|
|
314
|
+
const CORE_VOCABULARY = [
|
|
315
|
+
// Divine names and titles
|
|
316
|
+
new EnochianWord('ZACAR', 'Move', { category: 'command' }),
|
|
317
|
+
new EnochianWord('ZORGE', 'Be friendly unto me', { category: 'invocation' }),
|
|
318
|
+
new EnochianWord('ZAMRAN', 'Appear', { category: 'command' }),
|
|
319
|
+
new EnochianWord('OL', 'I', { category: 'pronoun' }),
|
|
320
|
+
new EnochianWord('SONF', 'Reign', { category: 'verb' }),
|
|
321
|
+
new EnochianWord('VORS', 'Over', { category: 'preposition' }),
|
|
322
|
+
new EnochianWord('CIAL', 'Earth', { category: 'noun' }),
|
|
323
|
+
new EnochianWord('IALPIR', 'Burning flames', { category: 'noun' }),
|
|
324
|
+
new EnochianWord('NOCO', 'Servant', { category: 'noun' }),
|
|
325
|
+
new EnochianWord('HOATH', 'True worshipper', { category: 'noun' }),
|
|
326
|
+
new EnochianWord('IAIDA', 'Highest', { category: 'adjective' }),
|
|
327
|
+
new EnochianWord('GONO', 'Faith', { category: 'noun' }),
|
|
328
|
+
new EnochianWord('GOHE', 'Power', { category: 'noun' }),
|
|
329
|
+
new EnochianWord('GOHED', 'Everlasting', { category: 'adjective' }),
|
|
330
|
+
new EnochianWord('MICMA', 'Behold', { category: 'command' }),
|
|
331
|
+
new EnochianWord('ADGT', 'Can', { category: 'verb' }),
|
|
332
|
+
new EnochianWord('LONDOH', 'Kingdom', { category: 'noun' }),
|
|
333
|
+
new EnochianWord('ERAN', 'Promise', { category: 'noun' }),
|
|
334
|
+
new EnochianWord('SOBAM', 'Whose', { category: 'relative' }),
|
|
335
|
+
new EnochianWord('CASARM', 'Beginning', { category: 'noun' }),
|
|
336
|
+
|
|
337
|
+
// Elemental terms
|
|
338
|
+
new EnochianWord('BITOM', 'Fire tablet', { category: 'element' }),
|
|
339
|
+
new EnochianWord('NANTA', 'Earth tablet', { category: 'element' }),
|
|
340
|
+
new EnochianWord('HCOMA', 'Water tablet', { category: 'element' }),
|
|
341
|
+
new EnochianWord('EXARP', 'Air tablet', { category: 'element' }),
|
|
342
|
+
|
|
343
|
+
// Angelic names
|
|
344
|
+
new EnochianWord('MADRIAX', 'Heavens', { category: 'realm' }),
|
|
345
|
+
new EnochianWord('ZIRDO', 'I am', { category: 'verb' }),
|
|
346
|
+
new EnochianWord('NIIS', 'Come', { category: 'command' }),
|
|
347
|
+
new EnochianWord('DLUGA', 'Give', { category: 'command' }),
|
|
348
|
+
new EnochianWord('ZODACARE', 'Move therefore', { category: 'command' }),
|
|
349
|
+
new EnochianWord('OD', 'And', { category: 'conjunction' }),
|
|
350
|
+
new EnochianWord('MOSPLEH', 'Crowns', { category: 'noun' }),
|
|
351
|
+
new EnochianWord('RAAS', 'East', { category: 'direction' }),
|
|
352
|
+
new EnochianWord('SOBOLN', 'West', { category: 'direction' }),
|
|
353
|
+
new EnochianWord('IADNAH', 'Knowledge', { category: 'noun' }),
|
|
354
|
+
new EnochianWord('VAOAN', 'Truth', { category: 'noun' })
|
|
355
|
+
];
|
|
356
|
+
|
|
357
|
+
// Create word lookup
|
|
358
|
+
const wordLookup = new Map();
|
|
359
|
+
for (const word of CORE_VOCABULARY) {
|
|
360
|
+
wordLookup.set(word.word, word);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// ============================================================================
|
|
364
|
+
// THE 19 CALLS (Keys)
|
|
365
|
+
// ============================================================================
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* EnochianCall - Represents one of the 19 Calls (Keys)
|
|
369
|
+
*/
|
|
370
|
+
class EnochianCall {
|
|
371
|
+
/**
|
|
372
|
+
* @param {number} number - Call number (1-19)
|
|
373
|
+
* @param {string} name - Name of the call
|
|
374
|
+
* @param {string[]} words - Array of Enochian words in the call
|
|
375
|
+
* @param {string} purpose - Purpose of the call
|
|
376
|
+
*/
|
|
377
|
+
constructor(number, name, words, purpose) {
|
|
378
|
+
this.number = number;
|
|
379
|
+
this.name = name;
|
|
380
|
+
this.words = words;
|
|
381
|
+
this.purpose = purpose;
|
|
382
|
+
this.enochianWords = this.parseWords();
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Parse word strings to EnochianWord objects
|
|
387
|
+
*/
|
|
388
|
+
parseWords() {
|
|
389
|
+
return this.words.map(w => {
|
|
390
|
+
if (wordLookup.has(w.toUpperCase())) {
|
|
391
|
+
return wordLookup.get(w.toUpperCase());
|
|
392
|
+
}
|
|
393
|
+
return new EnochianWord(w, 'unknown', { callNumber: this.number });
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Get all primes used in this call
|
|
399
|
+
*/
|
|
400
|
+
getAllPrimes() {
|
|
401
|
+
const primes = [];
|
|
402
|
+
for (const word of this.enochianWords) {
|
|
403
|
+
primes.push(...word.primes);
|
|
404
|
+
}
|
|
405
|
+
return primes;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Calculate the total twist of this call
|
|
410
|
+
*/
|
|
411
|
+
getTotalTwist() {
|
|
412
|
+
const primes = this.getAllPrimes();
|
|
413
|
+
return validateTwistClosure(primes);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Get prime signature (product of all primes mod large number)
|
|
418
|
+
*/
|
|
419
|
+
getPrimeSignature() {
|
|
420
|
+
const primes = this.getAllPrimes();
|
|
421
|
+
let product = 1n;
|
|
422
|
+
for (const p of primes) {
|
|
423
|
+
product = (product * BigInt(p)) % BigInt(10 ** 15);
|
|
424
|
+
}
|
|
425
|
+
return product.toString();
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
toString() {
|
|
429
|
+
return `Call ${this.number}: ${this.name} - ${this.purpose}`;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* The 19 Enochian Calls (simplified representation)
|
|
435
|
+
* Each call serves a specific purpose in the Enochian system
|
|
436
|
+
*/
|
|
437
|
+
const THE_NINETEEN_CALLS = [
|
|
438
|
+
new EnochianCall(1, 'First Key',
|
|
439
|
+
['OL', 'SONF', 'VORS', 'GOHE', 'IAD', 'BALT', 'LANSH'],
|
|
440
|
+
'Opening and invocation of the Spirit'),
|
|
441
|
+
|
|
442
|
+
new EnochianCall(2, 'Second Key',
|
|
443
|
+
['ADGT', 'VPAAH', 'ZONG', 'OM', 'FAAIP', 'SALD'],
|
|
444
|
+
'Invocation of knowledge and wisdom'),
|
|
445
|
+
|
|
446
|
+
new EnochianCall(3, 'Third Key',
|
|
447
|
+
['MICMA', 'GOHO', 'PIAD', 'ZIRDO', 'NOCO', 'MAD'],
|
|
448
|
+
'Invocation of understanding'),
|
|
449
|
+
|
|
450
|
+
new EnochianCall(4, 'Fourth Key',
|
|
451
|
+
['OTHIL', 'LASDI', 'BABAGE', 'OD', 'DORPHA', 'GOHOL'],
|
|
452
|
+
'Control of earthly elements'),
|
|
453
|
+
|
|
454
|
+
new EnochianCall(5, 'Fifth Key',
|
|
455
|
+
['SAPAH', 'ZIMII', 'DUIV', 'OD', 'NOAS', 'TAAOG'],
|
|
456
|
+
'Governance of the mighty sounds'),
|
|
457
|
+
|
|
458
|
+
new EnochianCall(6, 'Sixth Key',
|
|
459
|
+
['GAHE', 'SAANIR', 'OD', 'CHRISTEOS', 'YRPOIL', 'TIOBL'],
|
|
460
|
+
'Invocation of spirits of Air'),
|
|
461
|
+
|
|
462
|
+
new EnochianCall(7, 'Seventh Key',
|
|
463
|
+
['RAAS', 'ISALMAN', 'PARADIZ', 'OE', 'COMSELH', 'AZIAZOR'],
|
|
464
|
+
'Invocation of spirits of Water'),
|
|
465
|
+
|
|
466
|
+
new EnochianCall(8, 'Eighth Key',
|
|
467
|
+
['BAZMELO', 'ITA', 'PIRIPSON', 'OLN', 'NAZARTH', 'OX'],
|
|
468
|
+
'Invocation of spirits of Earth'),
|
|
469
|
+
|
|
470
|
+
new EnochianCall(9, 'Ninth Key',
|
|
471
|
+
['MICAO', 'LI', 'OFEKUFA', 'OD', 'BEZET', 'IAIDA'],
|
|
472
|
+
'Invocation of spirits of Fire'),
|
|
473
|
+
|
|
474
|
+
new EnochianCall(10, 'Tenth Key',
|
|
475
|
+
['KORAXO', 'KHIS', 'OD', 'IPIAMON', 'OD', 'DLUGAR'],
|
|
476
|
+
'First Aethyr - LIL'),
|
|
477
|
+
|
|
478
|
+
new EnochianCall(11, 'Eleventh Key',
|
|
479
|
+
['OXIAYAL', 'HOLDO', 'OD', 'ZIROM', 'OD', 'CORAXO'],
|
|
480
|
+
'Second Aethyr - ARN'),
|
|
481
|
+
|
|
482
|
+
new EnochianCall(12, 'Twelfth Key',
|
|
483
|
+
['NONCP', 'ZACAM', 'GMICALZ', 'SOBOL', 'ATH', 'ANANAEL'],
|
|
484
|
+
'Third Aethyr - ZOM'),
|
|
485
|
+
|
|
486
|
+
new EnochianCall(13, 'Thirteenth Key',
|
|
487
|
+
['NAPEAI', 'BABAGEN', 'DS', 'BRIN', 'VX', 'OOAONA'],
|
|
488
|
+
'Fourth Aethyr - PAZ'),
|
|
489
|
+
|
|
490
|
+
new EnochianCall(14, 'Fourteenth Key',
|
|
491
|
+
['NOROMI', 'BAGIE', 'PASBS', 'OIAD', 'DS', 'TRINT'],
|
|
492
|
+
'Fifth Aethyr - LIT'),
|
|
493
|
+
|
|
494
|
+
new EnochianCall(15, 'Fifteenth Key',
|
|
495
|
+
['ILS', 'TABAAN', 'LIALPRT', 'CASARMAN', 'UPAAHI', 'CHIS'],
|
|
496
|
+
'Sixth Aethyr - MAZ'),
|
|
497
|
+
|
|
498
|
+
new EnochianCall(16, 'Sixteenth Key',
|
|
499
|
+
['ILS', 'VIUIALPRT', 'SALMAN', 'BALT', 'DS', 'ACROODZI'],
|
|
500
|
+
'Seventh Aethyr - DEO'),
|
|
501
|
+
|
|
502
|
+
new EnochianCall(17, 'Seventeenth Key',
|
|
503
|
+
['ILS', 'DIAL', 'PRDZAR', 'CCASCRG', 'NOAS', 'TA'],
|
|
504
|
+
'Eighth Aethyr - ZID'),
|
|
505
|
+
|
|
506
|
+
new EnochianCall(18, 'Eighteenth Key',
|
|
507
|
+
['ILS', 'MICAOLZ', 'SAANIR', 'CAOSGO', 'OD', 'FISIS'],
|
|
508
|
+
'Ninth through Eighteenth Aethyrs'),
|
|
509
|
+
|
|
510
|
+
new EnochianCall(19, 'Nineteenth Key',
|
|
511
|
+
['MADRIAX', 'DS', 'PRAF', 'LIL', 'CHIS', 'MICAOLZ', 'SAANIR'],
|
|
512
|
+
'Call of the 30 Aethyrs (with insertion)')
|
|
513
|
+
];
|
|
514
|
+
|
|
515
|
+
// ============================================================================
|
|
516
|
+
// SEDENION INTEGRATION (16D Hypercomplex)
|
|
517
|
+
// ============================================================================
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* SedenionElement - 16-dimensional hypercomplex number for Enochian operations
|
|
521
|
+
* Sedenions extend octonions with 16 basis elements: e₀=1, e₁...e₁₅
|
|
522
|
+
*/
|
|
523
|
+
class SedenionElement {
|
|
524
|
+
constructor(components = null) {
|
|
525
|
+
// 16 components: e0 (real) through e15
|
|
526
|
+
this.components = components || new Array(16).fill(0);
|
|
527
|
+
if (this.components.length !== 16) {
|
|
528
|
+
throw new Error('Sedenion must have exactly 16 components');
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Create from Enochian word
|
|
534
|
+
*/
|
|
535
|
+
static fromWord(word) {
|
|
536
|
+
const components = new Array(16).fill(0);
|
|
537
|
+
const enochianWord = word instanceof EnochianWord ? word : new EnochianWord(word, '');
|
|
538
|
+
|
|
539
|
+
// Map primes to sedenion dimensions
|
|
540
|
+
for (let i = 0; i < enochianWord.primes.length && i < 16; i++) {
|
|
541
|
+
// Use prime modulo for component, scaled
|
|
542
|
+
components[i] = enochianWord.primes[i] / 100;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return new SedenionElement(components);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Create from prime basis coefficients
|
|
550
|
+
*/
|
|
551
|
+
static fromBasis(coefficients) {
|
|
552
|
+
const components = new Array(16).fill(0);
|
|
553
|
+
// Map 7 basis primes to first 7 non-real components
|
|
554
|
+
for (let i = 0; i < Math.min(coefficients.length, 7); i++) {
|
|
555
|
+
components[i + 1] = coefficients[i]; // e1 through e7
|
|
556
|
+
}
|
|
557
|
+
return new SedenionElement(components);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Get real part (e0)
|
|
562
|
+
*/
|
|
563
|
+
real() {
|
|
564
|
+
return this.components[0];
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Get imaginary parts (e1...e15)
|
|
569
|
+
*/
|
|
570
|
+
imaginary() {
|
|
571
|
+
return this.components.slice(1);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Conjugate: negate all imaginary parts
|
|
576
|
+
*/
|
|
577
|
+
conjugate() {
|
|
578
|
+
const conj = [this.components[0]];
|
|
579
|
+
for (let i = 1; i < 16; i++) {
|
|
580
|
+
conj.push(-this.components[i]);
|
|
581
|
+
}
|
|
582
|
+
return new SedenionElement(conj);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Norm squared: sum of squares of all components
|
|
587
|
+
*/
|
|
588
|
+
normSquared() {
|
|
589
|
+
return this.components.reduce((sum, c) => sum + c * c, 0);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Norm: square root of norm squared
|
|
594
|
+
*/
|
|
595
|
+
norm() {
|
|
596
|
+
return Math.sqrt(this.normSquared());
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Add two sedenions
|
|
601
|
+
*/
|
|
602
|
+
add(other) {
|
|
603
|
+
const result = this.components.map((c, i) => c + other.components[i]);
|
|
604
|
+
return new SedenionElement(result);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Subtract two sedenions
|
|
609
|
+
*/
|
|
610
|
+
subtract(other) {
|
|
611
|
+
const result = this.components.map((c, i) => c - other.components[i]);
|
|
612
|
+
return new SedenionElement(result);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Scale by scalar
|
|
617
|
+
*/
|
|
618
|
+
scale(s) {
|
|
619
|
+
const result = this.components.map(c => c * s);
|
|
620
|
+
return new SedenionElement(result);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Sedenion multiplication (Cayley-Dickson construction)
|
|
625
|
+
* Sedenions are NOT a division algebra - they have zero divisors
|
|
626
|
+
*/
|
|
627
|
+
multiply(other) {
|
|
628
|
+
// Use Cayley-Dickson: if a,b are octonions, (a,b)(c,d) = (ac - d*b, da + bc*)
|
|
629
|
+
// For simplicity, implement component-wise using multiplication table
|
|
630
|
+
const result = new Array(16).fill(0);
|
|
631
|
+
|
|
632
|
+
// Full 16x16 multiplication is complex; here's a simplified version
|
|
633
|
+
// that captures the essential structure
|
|
634
|
+
for (let i = 0; i < 16; i++) {
|
|
635
|
+
for (let j = 0; j < 16; j++) {
|
|
636
|
+
const [k, sign] = sedenionMultTable(i, j);
|
|
637
|
+
result[k] += sign * this.components[i] * other.components[j];
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
return new SedenionElement(result);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Apply twist operation
|
|
646
|
+
*/
|
|
647
|
+
twist(prime) {
|
|
648
|
+
const angle = twistRadians(prime);
|
|
649
|
+
const cos = Math.cos(angle);
|
|
650
|
+
const sin = Math.sin(angle);
|
|
651
|
+
|
|
652
|
+
// Apply rotation in multiple planes
|
|
653
|
+
const result = [...this.components];
|
|
654
|
+
for (let i = 1; i < 16; i += 2) {
|
|
655
|
+
if (i + 1 < 16) {
|
|
656
|
+
const x = result[i];
|
|
657
|
+
const y = result[i + 1];
|
|
658
|
+
result[i] = x * cos - y * sin;
|
|
659
|
+
result[i + 1] = x * sin + y * cos;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return new SedenionElement(result);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* Convert to array
|
|
668
|
+
*/
|
|
669
|
+
toArray() {
|
|
670
|
+
return [...this.components];
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Check if close to zero
|
|
675
|
+
*/
|
|
676
|
+
isZero(epsilon = 1e-10) {
|
|
677
|
+
return this.normSquared() < epsilon;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
toString() {
|
|
681
|
+
const parts = [];
|
|
682
|
+
const names = ['', 'e₁', 'e₂', 'e₃', 'e₄', 'e₅', 'e₆', 'e₇',
|
|
683
|
+
'e₈', 'e₉', 'e₁₀', 'e₁₁', 'e₁₂', 'e₁₃', 'e₁₄', 'e₁₅'];
|
|
684
|
+
|
|
685
|
+
for (let i = 0; i < 16; i++) {
|
|
686
|
+
if (Math.abs(this.components[i]) > 1e-10) {
|
|
687
|
+
const coef = this.components[i].toFixed(4);
|
|
688
|
+
parts.push(i === 0 ? coef : `${coef}${names[i]}`);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
return parts.length > 0 ? parts.join(' + ') : '0';
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Sedenion multiplication table
|
|
698
|
+
* Returns [resultIndex, sign] for e_i * e_j
|
|
699
|
+
*/
|
|
700
|
+
function sedenionMultTable(i, j) {
|
|
701
|
+
if (i === 0) return [j, 1];
|
|
702
|
+
if (j === 0) return [i, 1];
|
|
703
|
+
if (i === j) return [0, -1]; // e_i^2 = -1 for i > 0
|
|
704
|
+
|
|
705
|
+
// Use XOR for index (captures much of the algebra's structure)
|
|
706
|
+
const k = i ^ j;
|
|
707
|
+
|
|
708
|
+
// Sign is more complex; simplified here
|
|
709
|
+
// In full implementation, use proper Cayley-Dickson doubling
|
|
710
|
+
const sign = ((i & j) !== 0) ? -1 : 1;
|
|
711
|
+
|
|
712
|
+
return [k, sign];
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// ============================================================================
|
|
716
|
+
// ENOCHIAN COMPUTATION ENGINE
|
|
717
|
+
// ============================================================================
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* EnochianEngine - Performs computations in the Enochian formal system
|
|
721
|
+
*/
|
|
722
|
+
class EnochianEngine {
|
|
723
|
+
constructor() {
|
|
724
|
+
this.vocabulary = wordLookup;
|
|
725
|
+
this.calls = THE_NINETEEN_CALLS;
|
|
726
|
+
this.basisPrimes = PRIME_BASIS;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Parse Enochian text into words
|
|
731
|
+
*/
|
|
732
|
+
parse(text) {
|
|
733
|
+
const words = text.toUpperCase().split(/\s+/);
|
|
734
|
+
return words.map(w => {
|
|
735
|
+
if (this.vocabulary.has(w)) {
|
|
736
|
+
return this.vocabulary.get(w);
|
|
737
|
+
}
|
|
738
|
+
return new EnochianWord(w, 'unknown');
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Compute prime signature of text
|
|
744
|
+
*/
|
|
745
|
+
primeSignature(text) {
|
|
746
|
+
const words = this.parse(text);
|
|
747
|
+
const allPrimes = [];
|
|
748
|
+
for (const word of words) {
|
|
749
|
+
allPrimes.push(...word.primes);
|
|
750
|
+
}
|
|
751
|
+
return allPrimes;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Convert text to sedenion representation
|
|
756
|
+
*/
|
|
757
|
+
toSedenion(text) {
|
|
758
|
+
const primes = this.primeSignature(text);
|
|
759
|
+
let result = new SedenionElement();
|
|
760
|
+
|
|
761
|
+
for (const p of primes) {
|
|
762
|
+
const elem = SedenionElement.fromBasis([p / 100]);
|
|
763
|
+
result = result.add(elem);
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
return result;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* Apply twist sequence to sedenion
|
|
771
|
+
*/
|
|
772
|
+
applyTwists(sedenion, primes) {
|
|
773
|
+
let result = sedenion;
|
|
774
|
+
for (const p of primes) {
|
|
775
|
+
result = result.twist(p);
|
|
776
|
+
}
|
|
777
|
+
return result;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Compute resonance between two texts
|
|
782
|
+
*/
|
|
783
|
+
resonance(text1, text2) {
|
|
784
|
+
const s1 = this.toSedenion(text1);
|
|
785
|
+
const s2 = this.toSedenion(text2);
|
|
786
|
+
|
|
787
|
+
// Inner product (normalized)
|
|
788
|
+
const dot = s1.components.reduce((sum, c, i) => sum + c * s2.components[i], 0);
|
|
789
|
+
return dot / (s1.norm() * s2.norm() || 1);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Validate if text has twist closure
|
|
794
|
+
*/
|
|
795
|
+
hasTwistClosure(text) {
|
|
796
|
+
const primes = this.primeSignature(text);
|
|
797
|
+
return validateTwistClosure(primes);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Get call by number
|
|
802
|
+
*/
|
|
803
|
+
getCall(number) {
|
|
804
|
+
return this.calls.find(c => c.number === number);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Execute a call (compute its sedenion representation)
|
|
809
|
+
*/
|
|
810
|
+
executeCall(number) {
|
|
811
|
+
const call = this.getCall(number);
|
|
812
|
+
if (!call) {
|
|
813
|
+
throw new Error(`Call ${number} not found`);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
const primes = call.getAllPrimes();
|
|
817
|
+
let result = new SedenionElement();
|
|
818
|
+
|
|
819
|
+
for (const word of call.enochianWords) {
|
|
820
|
+
const wordSed = SedenionElement.fromWord(word);
|
|
821
|
+
result = result.add(wordSed);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// Apply twists from all primes
|
|
825
|
+
result = this.applyTwists(result, primes);
|
|
826
|
+
|
|
827
|
+
return {
|
|
828
|
+
call: call,
|
|
829
|
+
sedenion: result,
|
|
830
|
+
norm: result.norm(),
|
|
831
|
+
twistClosure: call.getTotalTwist()
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Find words that resonate with given prime
|
|
837
|
+
*/
|
|
838
|
+
findResonantWords(prime) {
|
|
839
|
+
const resonant = [];
|
|
840
|
+
for (const [word, wordObj] of this.vocabulary) {
|
|
841
|
+
if (wordObj.primes.includes(prime)) {
|
|
842
|
+
resonant.push(wordObj);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
return resonant;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Compute basis decomposition of text
|
|
850
|
+
*/
|
|
851
|
+
basisDecomposition(text) {
|
|
852
|
+
const primes = this.primeSignature(text);
|
|
853
|
+
const basisCounts = new Map();
|
|
854
|
+
|
|
855
|
+
for (const p of PRIME_BASIS) {
|
|
856
|
+
basisCounts.set(p, 0);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
for (const p of primes) {
|
|
860
|
+
if (PRIME_BASIS.includes(p)) {
|
|
861
|
+
basisCounts.set(p, basisCounts.get(p) + 1);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
return {
|
|
866
|
+
basisCounts: Object.fromEntries(basisCounts),
|
|
867
|
+
nonBasisPrimes: primes.filter(p => !PRIME_BASIS.includes(p)),
|
|
868
|
+
basisRatio: primes.filter(p => PRIME_BASIS.includes(p)).length / (primes.length || 1)
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// ============================================================================
|
|
874
|
+
// EXPORTS
|
|
875
|
+
// ============================================================================
|
|
876
|
+
|
|
877
|
+
module.exports = {
|
|
878
|
+
// Alphabet
|
|
879
|
+
ENOCHIAN_ALPHABET,
|
|
880
|
+
letterToPrime,
|
|
881
|
+
primeToLetter,
|
|
882
|
+
letterToData,
|
|
883
|
+
|
|
884
|
+
// Prime Basis
|
|
885
|
+
PRIME_BASIS,
|
|
886
|
+
BASIS_MEANINGS,
|
|
887
|
+
|
|
888
|
+
// Twist Operations
|
|
889
|
+
TWIST_MODES,
|
|
890
|
+
twistAngle,
|
|
891
|
+
twistRadians,
|
|
892
|
+
TwistOperator,
|
|
893
|
+
validateTwistClosure,
|
|
894
|
+
|
|
895
|
+
// Words
|
|
896
|
+
EnochianWord,
|
|
897
|
+
CORE_VOCABULARY,
|
|
898
|
+
wordLookup,
|
|
899
|
+
|
|
900
|
+
// Calls
|
|
901
|
+
EnochianCall,
|
|
902
|
+
THE_NINETEEN_CALLS,
|
|
903
|
+
|
|
904
|
+
// Sedenions
|
|
905
|
+
SedenionElement,
|
|
906
|
+
sedenionMultTable,
|
|
907
|
+
|
|
908
|
+
// Engine
|
|
909
|
+
EnochianEngine
|
|
910
|
+
};
|