klio 1.2.6 → 1.2.7
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 +1 -0
- package/package.json +1 -1
- package/src/astrology/astrologyService.js +270 -10
- package/src/cli/cli.js +183 -1
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -148,7 +148,6 @@ function calculateHouses(julianDay, houseSystem = 'K', useBirthLocation = false)
|
|
|
148
148
|
latitude = config.birthData.location.latitude;
|
|
149
149
|
longitude = config.birthData.location.longitude;
|
|
150
150
|
locationName = `${config.birthData.location.name}, ${config.birthData.location.country}`;
|
|
151
|
-
console.log(`Verwende Geburtsort: ${locationName} (${latitude}° Breitengrad, ${longitude}° Längengrad)`);
|
|
152
151
|
} else if (useBirthLocation) {
|
|
153
152
|
// Geburtsort ist konfiguriert, aber kein Standort - verwende Standardort
|
|
154
153
|
latitude = defaultLatitude;
|
|
@@ -480,19 +479,19 @@ function findExactAspectTime(planet1, planet2, aspectType, startDate) {
|
|
|
480
479
|
return null;
|
|
481
480
|
}
|
|
482
481
|
|
|
483
|
-
// Wir suchen in einem
|
|
484
|
-
// um den exakten Aspekt zu finden
|
|
482
|
+
// Wir suchen in einem vernünftigen Zeitfenster (90 Tage in der Zukunft)
|
|
483
|
+
// um den nächsten exakten Aspekt zu finden
|
|
485
484
|
// Besonders wichtig für langsame Planeten wie Saturn, Uranus, Neptun, Pluto
|
|
486
485
|
let bestMatch = null;
|
|
487
486
|
let bestDistance = Infinity;
|
|
488
487
|
|
|
489
|
-
// Suche in
|
|
490
|
-
const searchWindow =
|
|
488
|
+
// Suche nur in der Zukunft (0-90 Tage nach dem Startdatum)
|
|
489
|
+
const searchWindow = 90; // Tage
|
|
491
490
|
|
|
492
|
-
// Wir suchen
|
|
493
|
-
const stepsPerDay =
|
|
491
|
+
// Wir suchen in kleineren Schritten (alle 2 Stunden), um präzisere Ergebnisse zu erhalten
|
|
492
|
+
const stepsPerDay = 12; // 2-Stunden-Schritte
|
|
494
493
|
|
|
495
|
-
for (let daysOffset =
|
|
494
|
+
for (let daysOffset = 0; daysOffset <= searchWindow; daysOffset++) {
|
|
496
495
|
for (let hourOffset = 0; hourOffset < 24; hourOffset++) { // Jede Stunde
|
|
497
496
|
for (let minuteOffset = 0; minuteOffset < 60; minuteOffset += 5) { // Alle 5 Minuten
|
|
498
497
|
const testDate = addDays(startDate, daysOffset);
|
|
@@ -518,7 +517,56 @@ function findExactAspectTime(planet1, planet2, aspectType, startDate) {
|
|
|
518
517
|
}
|
|
519
518
|
|
|
520
519
|
// Wenn wir einen Aspekt gefunden haben, der nah genug am Ziel ist, geben wir ihn zurück
|
|
521
|
-
|
|
520
|
+
// Strengere Toleranz von 0.5° für bessere Genauigkeit
|
|
521
|
+
if (bestMatch && bestDistance <= 0.5) { // Toleranz von 0.5°
|
|
522
|
+
return bestMatch;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Funktion zum Finden des letzten exakten Aspekts in der Vergangenheit (für separative Phasen)
|
|
529
|
+
function findLastExactAspectTime(planet1, planet2, aspectType, startDate) {
|
|
530
|
+
const targetAngle = getAspectAngle(aspectType);
|
|
531
|
+
|
|
532
|
+
if (targetAngle === null) {
|
|
533
|
+
return null;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// Suche in der Vergangenheit (bis zu 180 Tage vor dem Startdatum)
|
|
537
|
+
let bestMatch = null;
|
|
538
|
+
let bestDistance = Infinity;
|
|
539
|
+
|
|
540
|
+
// Suche in einem Zeitfenster von 180 Tagen vor dem Startdatum
|
|
541
|
+
const searchWindow = 180; // Tage
|
|
542
|
+
|
|
543
|
+
for (let daysOffset = -searchWindow; daysOffset <= 0; daysOffset++) {
|
|
544
|
+
for (let hourOffset = 0; hourOffset < 24; hourOffset++) { // Jede Stunde
|
|
545
|
+
for (let minuteOffset = 0; minuteOffset < 60; minuteOffset += 5) { // Alle 5 Minuten
|
|
546
|
+
const testDate = addDays(startDate, daysOffset);
|
|
547
|
+
testDate.hour = hourOffset;
|
|
548
|
+
testDate.minute = minuteOffset;
|
|
549
|
+
|
|
550
|
+
// Berechne die Positionen der beiden Planeten
|
|
551
|
+
const planet1Data = getAstrologicalData(planet1, testDate);
|
|
552
|
+
const planet2Data = getAstrologicalData(planet2, testDate);
|
|
553
|
+
|
|
554
|
+
// Berechne den Winkel zwischen den Planeten
|
|
555
|
+
const angleDiff = Math.abs(planet1Data.longitude - planet2Data.longitude) % 360;
|
|
556
|
+
const normalizedAngle = Math.min(angleDiff, 360 - angleDiff);
|
|
557
|
+
const distanceToTarget = Math.abs(normalizedAngle - targetAngle);
|
|
558
|
+
|
|
559
|
+
// Speichere das beste Ergebnis
|
|
560
|
+
if (distanceToTarget < bestDistance) {
|
|
561
|
+
bestDistance = distanceToTarget;
|
|
562
|
+
bestMatch = {...testDate};
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Wenn wir einen Aspekt gefunden haben, der nah genug am Ziel ist, geben wir ihn zurück
|
|
569
|
+
if (bestMatch && bestDistance <= 0.5) { // Toleranz von 0.5°
|
|
522
570
|
return bestMatch;
|
|
523
571
|
}
|
|
524
572
|
|
|
@@ -1132,6 +1180,214 @@ async function calculatePersonalTransits(transitDate = null, birthData = null) {
|
|
|
1132
1180
|
};
|
|
1133
1181
|
}
|
|
1134
1182
|
|
|
1183
|
+
// Funktion zur Berechnung persönlicher Transit-Aspekte
|
|
1184
|
+
function calculatePersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null) {
|
|
1185
|
+
if (!birthData) {
|
|
1186
|
+
birthData = getBirthDataFromConfig();
|
|
1187
|
+
if (!birthData) {
|
|
1188
|
+
console.error('Keine Geburtsdaten verfügbar für persönliche Transit-Aspekte.');
|
|
1189
|
+
return null;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// Verwende aktuelles Datum, wenn kein Transitdatum angegeben
|
|
1194
|
+
if (!transitDate) {
|
|
1195
|
+
transitDate = getCurrentTimeInTimezone();
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// Berechne aktuelle Planetenpositionen (Transit)
|
|
1199
|
+
const transitPlanets = {};
|
|
1200
|
+
for (const [name, planetId] of Object.entries(planets)) {
|
|
1201
|
+
const data = getAstrologicalData(name, transitDate);
|
|
1202
|
+
transitPlanets[name] = data.longitude;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
// Berechne Geburtsplanetenpositionen (Radix)
|
|
1206
|
+
const birthPlanets = {};
|
|
1207
|
+
for (const [name, planetId] of Object.entries(planets)) {
|
|
1208
|
+
const data = getAstrologicalData(name, birthData);
|
|
1209
|
+
birthPlanets[name] = data.longitude;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
// Berechne Aspekte zwischen Transit- und Geburtsplaneten
|
|
1213
|
+
const aspects = [];
|
|
1214
|
+
const aspectTypes = [
|
|
1215
|
+
{ name: 'Konjunktion', angle: 0, orb: 8 },
|
|
1216
|
+
{ name: 'Opposition', angle: 180, orb: 8 },
|
|
1217
|
+
{ name: 'Quadrat', angle: 90, orb: 6 },
|
|
1218
|
+
{ name: 'Trigon', angle: 120, orb: 6 },
|
|
1219
|
+
{ name: 'Sextil', angle: 60, orb: 4 }
|
|
1220
|
+
];
|
|
1221
|
+
|
|
1222
|
+
// Vergleiche jeden Transitplaneten mit jedem Geburtsplaneten
|
|
1223
|
+
for (const [transitName, transitLongitude] of Object.entries(transitPlanets)) {
|
|
1224
|
+
for (const [birthName, birthLongitude] of Object.entries(birthPlanets)) {
|
|
1225
|
+
// Überspringe, wenn es sich um denselben Planeten handelt
|
|
1226
|
+
if (transitName === birthName) continue;
|
|
1227
|
+
|
|
1228
|
+
// Berechne den Winkelunterschied
|
|
1229
|
+
const angleDiff = Math.abs(transitLongitude - birthLongitude) % 360;
|
|
1230
|
+
const normalizedAngle = Math.min(angleDiff, 360 - angleDiff);
|
|
1231
|
+
|
|
1232
|
+
// Prüfe auf Aspekte
|
|
1233
|
+
for (const aspect of aspectTypes) {
|
|
1234
|
+
if (Math.abs(normalizedAngle - aspect.angle) <= aspect.orb) {
|
|
1235
|
+
aspects.push({
|
|
1236
|
+
transitPlanet: transitName,
|
|
1237
|
+
birthPlanet: birthName,
|
|
1238
|
+
type: aspect.name,
|
|
1239
|
+
angle: normalizedAngle.toFixed(2),
|
|
1240
|
+
orb: Math.abs(normalizedAngle - aspect.angle).toFixed(2),
|
|
1241
|
+
transitLongitude: transitLongitude,
|
|
1242
|
+
birthLongitude: birthLongitude
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// Filtere nach Zielplanet, falls angegeben
|
|
1250
|
+
const filteredAspects = targetPlanet
|
|
1251
|
+
? aspects.filter(aspect => aspect.transitPlanet === targetPlanet)
|
|
1252
|
+
: aspects;
|
|
1253
|
+
|
|
1254
|
+
return {
|
|
1255
|
+
transitDate: transitDate,
|
|
1256
|
+
birthData: birthData,
|
|
1257
|
+
aspects: filteredAspects
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
// Funktion zur Anzeige persönlicher Transit-Aspekte
|
|
1262
|
+
function showPersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null) {
|
|
1263
|
+
const aspectData = calculatePersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
1264
|
+
|
|
1265
|
+
if (!aspectData || aspectData.aspects.length === 0) {
|
|
1266
|
+
console.log('Keine persönlichen Transit-Aspekte gefunden.');
|
|
1267
|
+
return;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
const transitDateDisplay = transitDate || getCurrentTimeInTimezone();
|
|
1271
|
+
console.log(`Persönliche Transit-Aspekte (${transitDateDisplay.day}.${transitDateDisplay.month}.${transitDateDisplay.year}):`);
|
|
1272
|
+
console.log('================================================================================');
|
|
1273
|
+
console.log('| Transit | Geburts | Aspekt | Orb | Transit Pos | Geburts Pos |');
|
|
1274
|
+
console.log('================================================================================');
|
|
1275
|
+
|
|
1276
|
+
// Hole zusätzliche Informationen für die Anzeige
|
|
1277
|
+
const transitPlanetsData = {};
|
|
1278
|
+
const birthPlanetsData = {};
|
|
1279
|
+
|
|
1280
|
+
for (const [name] of Object.entries(planets)) {
|
|
1281
|
+
transitPlanetsData[name] = getAstrologicalData(name, transitDateDisplay);
|
|
1282
|
+
birthPlanetsData[name] = getAstrologicalData(name, birthData);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
aspectData.aspects.forEach(aspect => {
|
|
1286
|
+
const transitPlanetData = transitPlanetsData[aspect.transitPlanet];
|
|
1287
|
+
const birthPlanetData = birthPlanetsData[aspect.birthPlanet];
|
|
1288
|
+
|
|
1289
|
+
const transitPlanetFormatted = aspect.transitPlanet.charAt(0).toUpperCase() + aspect.transitPlanet.slice(1);
|
|
1290
|
+
const birthPlanetFormatted = aspect.birthPlanet.charAt(0).toUpperCase() + aspect.birthPlanet.slice(1);
|
|
1291
|
+
const aspectName = aspect.type.padEnd(11, ' ');
|
|
1292
|
+
const orb = aspect.orb.padEnd(4, ' ');
|
|
1293
|
+
const transitPos = `${transitPlanetData.sign} ${transitPlanetData.degreeInSign}°`;
|
|
1294
|
+
const birthPos = `${birthPlanetData.sign} ${birthPlanetData.degreeInSign}°`;
|
|
1295
|
+
|
|
1296
|
+
console.log(`| ${transitPlanetFormatted.padEnd(10)} | ${birthPlanetFormatted.padEnd(10)} | ${aspectName} | ${orb}° | ${transitPos.padEnd(11)} | ${birthPos.padEnd(11)} |`);
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1299
|
+
console.log('================================================================================');
|
|
1300
|
+
console.log(`Gesamt: ${aspectData.aspects.length} persönliche Transit-Aspekte gefunden`);
|
|
1301
|
+
console.log('\nErklärung: Diese Aspekte zeigen, wie die aktuellen Planetenpositionen');
|
|
1302
|
+
console.log('mit deinen Geburtspositionen interagieren (Transit → Radix).');
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
// Funktion für kombinierte Analyse (Geburts- und Transit-Aspekte mit Häusern)
|
|
1306
|
+
async function showCombinedAnalysis(planetName, transitDate = null, birthData = null, houseSystem = 'K') {
|
|
1307
|
+
if (!birthData) {
|
|
1308
|
+
birthData = getBirthDataFromConfig();
|
|
1309
|
+
if (!birthData) {
|
|
1310
|
+
console.error('Keine Geburtsdaten verfügbar für kombinierte Analyse.');
|
|
1311
|
+
return null;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
// Verwende aktuelles Datum, wenn kein Transitdatum angegeben
|
|
1316
|
+
if (!transitDate) {
|
|
1317
|
+
transitDate = getCurrentTimeInTimezone();
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
// Berechne Häuser basierend auf Geburtsdaten
|
|
1321
|
+
const birthJulianDay = calculateJulianDayUTC(birthData, getTimezoneOffset(birthData, birthData.location?.timezone || 'Europe/Zurich'));
|
|
1322
|
+
const houses = await calculateHouses(birthJulianDay, houseSystem === 'koch' ? 'K' : houseSystem === 'wholesign' ? 'W' : 'G', true);
|
|
1323
|
+
|
|
1324
|
+
// Berechne aktuelle Planetenpositionen (Transit)
|
|
1325
|
+
const transitPlanetData = getAstrologicalData(planetName, transitDate);
|
|
1326
|
+
const transitLongitude = transitPlanetData.longitude;
|
|
1327
|
+
const transitHouse = getPlanetHouse(transitLongitude, houses.house);
|
|
1328
|
+
|
|
1329
|
+
// Berechne Geburtsplanetenpositionen (Radix)
|
|
1330
|
+
const birthPlanetData = getAstrologicalData(planetName, birthData);
|
|
1331
|
+
const birthLongitude = birthPlanetData.longitude;
|
|
1332
|
+
const birthHouse = getPlanetHouse(birthLongitude, houses.house);
|
|
1333
|
+
|
|
1334
|
+
// Berechne Geburtsaspekte für den Planeten
|
|
1335
|
+
const birthAspects = calculatePlanetAspects(planetName, birthData, true);
|
|
1336
|
+
|
|
1337
|
+
// Berechne Transit-Aspekte für den Planeten
|
|
1338
|
+
const transitAspectsData = calculatePersonalTransitAspects(transitDate, birthData, planetName);
|
|
1339
|
+
const transitAspects = transitAspectsData ? transitAspectsData.aspects : [];
|
|
1340
|
+
|
|
1341
|
+
// Zeige kombinierte Analyse an
|
|
1342
|
+
console.log(`Kombinierte Analyse für ${planetName.charAt(0).toUpperCase() + planetName.slice(1)}:`);
|
|
1343
|
+
console.log('================================================================================');
|
|
1344
|
+
console.log(`Analyse-Datum: ${transitDate.day}.${transitDate.month}.${transitDate.year}`);
|
|
1345
|
+
console.log(`Geburtsdatum: ${birthData.day}.${birthData.month}.${birthData.year} ${birthData.hour}:${birthData.minute.toString().padStart(2, '0')}`);
|
|
1346
|
+
console.log(`Haus-System: ${houseSystem.charAt(0).toUpperCase() + houseSystem.slice(1)} (basierend auf Geburts-ASC)`);
|
|
1347
|
+
console.log('');
|
|
1348
|
+
|
|
1349
|
+
// Zeige Planetenpositionen und Häuser
|
|
1350
|
+
console.log('Positionen und Häuser:');
|
|
1351
|
+
console.log('--------------------------------------------------------------------------------');
|
|
1352
|
+
console.log(`Transit: ${transitPlanetData.sign} ${transitPlanetData.degreeInSign}° (Haus ${transitHouse})`);
|
|
1353
|
+
console.log(`Geburt: ${birthPlanetData.sign} ${birthPlanetData.degreeInSign}° (Haus ${birthHouse})`);
|
|
1354
|
+
console.log('');
|
|
1355
|
+
|
|
1356
|
+
// Zeige Geburtsaspekte
|
|
1357
|
+
if (birthAspects.length > 0) {
|
|
1358
|
+
console.log('Geburtsaspekte (Radix → Radix):');
|
|
1359
|
+
console.log('--------------------------------------------------------------------------------');
|
|
1360
|
+
birthAspects.forEach(aspect => {
|
|
1361
|
+
const aspectPlanetData = getAstrologicalData(aspect.planet, birthData);
|
|
1362
|
+
const aspectHouse = getPlanetHouse(parseFloat(aspectPlanetData.degreeInSign) + (signs.indexOf(aspectPlanetData.sign) * 30), houses.house);
|
|
1363
|
+
console.log(`${aspect.type.padEnd(12)} mit ${aspect.planet.padEnd(8)} (${aspectPlanetData.sign} ${aspectPlanetData.degreeInSign}° Haus ${aspectHouse}) - Orb: ${aspect.orb}°`);
|
|
1364
|
+
});
|
|
1365
|
+
console.log('');
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
// Zeige Transit-Aspekte
|
|
1369
|
+
if (transitAspects.length > 0) {
|
|
1370
|
+
console.log('Transit-Aspekte (Transit → Radix):');
|
|
1371
|
+
console.log('--------------------------------------------------------------------------------');
|
|
1372
|
+
transitAspects.forEach(aspect => {
|
|
1373
|
+
const birthPlanetData = getAstrologicalData(aspect.birthPlanet, birthData);
|
|
1374
|
+
const birthHouse = getPlanetHouse(parseFloat(birthPlanetData.degreeInSign) + (signs.indexOf(birthPlanetData.sign) * 30), houses.house);
|
|
1375
|
+
console.log(`${aspect.type.padEnd(12)} mit ${aspect.birthPlanet.padEnd(8)} (${birthPlanetData.sign} ${birthPlanetData.degreeInSign}° Haus ${birthHouse}) - Orb: ${aspect.orb}°`);
|
|
1376
|
+
});
|
|
1377
|
+
console.log('');
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
return {
|
|
1381
|
+
transitPlanetData,
|
|
1382
|
+
birthPlanetData,
|
|
1383
|
+
transitHouse,
|
|
1384
|
+
birthHouse,
|
|
1385
|
+
birthAspects,
|
|
1386
|
+
transitAspects,
|
|
1387
|
+
houses
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1135
1391
|
// Funktion zur Analyse der Elementverteilung
|
|
1136
1392
|
function analyzeElementDistribution(dateComponents, useBirthData = false) {
|
|
1137
1393
|
const elementCounts = {
|
|
@@ -1321,9 +1577,13 @@ module.exports = {
|
|
|
1321
1577
|
getAspectAngle,
|
|
1322
1578
|
getFutureAspects,
|
|
1323
1579
|
findExactAspectTime,
|
|
1580
|
+
findLastExactAspectTime,
|
|
1324
1581
|
detectAspectFigures,
|
|
1325
1582
|
showAspectFigures,
|
|
1326
|
-
calculatePersonalTransits
|
|
1583
|
+
calculatePersonalTransits,
|
|
1584
|
+
calculatePersonalTransitAspects,
|
|
1585
|
+
showPersonalTransitAspects,
|
|
1586
|
+
showCombinedAnalysis
|
|
1327
1587
|
};
|
|
1328
1588
|
|
|
1329
1589
|
// Funktion zur Berechnung vergangener Aspekte zwischen zwei Planeten
|
package/src/cli/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Command } = require('commander');
|
|
2
2
|
const { planets, signs } = require('../astrology/astrologyConstants');
|
|
3
3
|
const { showRetrogradePlanets } = require('../astrology/retrogradeService');
|
|
4
|
-
const { getCurrentTimeInTimezone, showAspectFigures, analyzeElementDistribution, getTimezoneOffset, calculateJulianDayUTC, calculateHouses, getAstrologicalData, getPlanetHouse, showPlanetAspects, calculatePlanetAspects, getAllActiveAspects, showAllActiveAspects, getBirthDataFromConfig, detectAspectFigures, calculatePersonalTransits } = require('../astrology/astrologyService');
|
|
4
|
+
const { getCurrentTimeInTimezone, showAspectFigures, analyzeElementDistribution, getTimezoneOffset, calculateJulianDayUTC, calculateHouses, getAstrologicalData, getPlanetHouse, showPlanetAspects, calculatePlanetAspects, getAllActiveAspects, showAllActiveAspects, getBirthDataFromConfig, detectAspectFigures, calculatePersonalTransits, showPersonalTransitAspects, showCombinedAnalysis, calculatePersonalTransitAspects, determineAspectPhase, findExactAspectTime, findLastExactAspectTime } = require('../astrology/astrologyService');
|
|
5
5
|
const { performSetup, showConfigStatus, loadConfig, setAIModel, askAIModel } = require('../config/configService');
|
|
6
6
|
const { parseAppleHealthXML } = require('../health/healthService');
|
|
7
7
|
const { analyzeStepsByPlanetSign, analyzeStressByPlanetAspects, analyzePlanetAspectsForSleep } = require('../health/healthAnalysis');
|
|
@@ -110,6 +110,8 @@ program
|
|
|
110
110
|
.option('--el', 'Zeigt die Elementverteilung der Planeten in einem horizontalen Chart an')
|
|
111
111
|
.option('--af', 'Zeigt aktive Aspektfiguren wie T-Quadrate, Große Trigone, etc. an')
|
|
112
112
|
.option('--transite', 'Zeigt persönliche Transite basierend auf Geburtsdaten an')
|
|
113
|
+
.option('--transit-aspekte', 'Zeigt persönliche Transit-Aspekte (Transit → Radix) an')
|
|
114
|
+
.option('--tr', 'Zeigt persönliche Transit-Aspekte (Transit → Radix) an (Kurzform)')
|
|
113
115
|
.option('--v <count>', 'Zeigt vergangene Aspekte zwischen zwei Planeten an (Format: --v <count> planet1 aspectType planet2)')
|
|
114
116
|
.option('--z <count>', 'Zeigt zukünftige Aspekte zwischen zwei Planeten an (Format: --z <count> planet1 aspectType planet2)')
|
|
115
117
|
.description('Zeigt astrologische Daten für einen Planeten an')
|
|
@@ -408,6 +410,186 @@ program
|
|
|
408
410
|
return;
|
|
409
411
|
}
|
|
410
412
|
|
|
413
|
+
// Kombinierte Analyse anzeigen, falls --a --i und --tr (oder --transit-aspekte) zusammen mit --hs angegeben
|
|
414
|
+
if ((options.a && shouldUseBirthData(options) && (options.transitAspekte || options.tr)) ||
|
|
415
|
+
(options.transitAspekte || options.tr) && options.hs) {
|
|
416
|
+
|
|
417
|
+
// Geburtsdaten sind erforderlich
|
|
418
|
+
const birthData = getBirthDataFromConfig();
|
|
419
|
+
if (!birthData) {
|
|
420
|
+
console.error('Fehler: Kombinierte Analyse erfordert Geburtsdaten. Bitte führe --setup aus.');
|
|
421
|
+
process.exit(1);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Benutzerdefiniertes Datum verwenden, falls angegeben
|
|
425
|
+
let transitDate = null;
|
|
426
|
+
if (options.d) {
|
|
427
|
+
// Versuche, das Datum als DD.MM.YYYY oder DD.MM.YYYY HH:MM zu parsen
|
|
428
|
+
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
429
|
+
const match = options.d.match(dateRegex);
|
|
430
|
+
|
|
431
|
+
if (match) {
|
|
432
|
+
const day = parseInt(match[1], 10);
|
|
433
|
+
const month = parseInt(match[2], 10);
|
|
434
|
+
const year = parseInt(match[3], 10);
|
|
435
|
+
const hour = match[4] ? parseInt(match[4], 10) : 12; // Standard: 12 Uhr
|
|
436
|
+
const minute = match[5] ? parseInt(match[5], 10) : 0; // Standard: 0 Minuten
|
|
437
|
+
|
|
438
|
+
// Überprüfe, ob das Datum gültig ist
|
|
439
|
+
const date = new Date(year, month - 1, day, hour, minute);
|
|
440
|
+
if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
|
|
441
|
+
transitDate = {
|
|
442
|
+
day: day,
|
|
443
|
+
month: month,
|
|
444
|
+
year: year,
|
|
445
|
+
hour: hour,
|
|
446
|
+
minute: minute
|
|
447
|
+
};
|
|
448
|
+
} else {
|
|
449
|
+
console.error('Ungültiges Datum:', options.d);
|
|
450
|
+
console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM"');
|
|
451
|
+
process.exit(1);
|
|
452
|
+
}
|
|
453
|
+
} else {
|
|
454
|
+
console.error('Ungültiges Datum:', options.d);
|
|
455
|
+
console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM"');
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Haus-System bestimmen
|
|
461
|
+
const houseSystem = options.hs ? options.hs.toLowerCase() : 'koch';
|
|
462
|
+
|
|
463
|
+
// Zeige kombinierte Analyse an
|
|
464
|
+
const targetPlanet = planetArg ? planetArg.toLowerCase() : null;
|
|
465
|
+
if (targetPlanet) {
|
|
466
|
+
await showCombinedAnalysis(targetPlanet, transitDate, birthData, houseSystem);
|
|
467
|
+
} else {
|
|
468
|
+
// Wenn kein Planet angegeben ist, zeige NUR die Transit-Aspekte-Tabelle
|
|
469
|
+
console.log('Transit-Aspekte (Transit → Radix):');
|
|
470
|
+
console.log('================================================================================');
|
|
471
|
+
console.log('| Transit | Aspekt | Mit Planet | Orb | Transit Pos | Transit Haus | Geburts Haus | Phase | Exaktes Datum/Uhrzeit |');
|
|
472
|
+
console.log('================================================================================');
|
|
473
|
+
|
|
474
|
+
// Berechne Häuser einmal für alle Planeten
|
|
475
|
+
const birthJulianDay = calculateJulianDayUTC(birthData, getTimezoneOffset(birthData, birthData.location?.timezone || 'Europe/Zurich'));
|
|
476
|
+
const houses = await calculateHouses(birthJulianDay, houseSystem === 'koch' ? 'K' : houseSystem === 'wholesign' ? 'W' : 'G', true);
|
|
477
|
+
const transitDateDisplay = transitDate || getCurrentTimeInTimezone();
|
|
478
|
+
|
|
479
|
+
// Zeige Transit-Aspekte für alle Planeten
|
|
480
|
+
for (const [planetName] of Object.entries(planets)) {
|
|
481
|
+
const transitPlanetData = getAstrologicalData(planetName, transitDateDisplay);
|
|
482
|
+
const transitHouse = getPlanetHouse(parseFloat(transitPlanetData.degreeInSign) + (signs.indexOf(transitPlanetData.sign) * 30), houses.house);
|
|
483
|
+
const transitAspectsData = calculatePersonalTransitAspects(transitDateDisplay, birthData, planetName);
|
|
484
|
+
const transitAspects = transitAspectsData ? transitAspectsData.aspects : [];
|
|
485
|
+
if (transitAspects.length > 0) {
|
|
486
|
+
transitAspects.forEach(aspect => {
|
|
487
|
+
const birthPlanetData = getAstrologicalData(aspect.birthPlanet, birthData);
|
|
488
|
+
const birthHouse = getPlanetHouse(parseFloat(birthPlanetData.degreeInSign) + (signs.indexOf(birthPlanetData.sign) * 30), houses.house);
|
|
489
|
+
|
|
490
|
+
// Bestimme die Aspekt-Phase
|
|
491
|
+
const aspectAngles = {
|
|
492
|
+
'Konjunktion': 0,
|
|
493
|
+
'Opposition': 180,
|
|
494
|
+
'Quadrat': 90,
|
|
495
|
+
'Trigon': 120,
|
|
496
|
+
'Sextil': 60
|
|
497
|
+
};
|
|
498
|
+
const targetAngle = aspectAngles[aspect.type];
|
|
499
|
+
const phase = determineAspectPhase(planetName, aspect.birthPlanet, transitDateDisplay, aspect.type, targetAngle);
|
|
500
|
+
|
|
501
|
+
// Berechne das genaue Datum und die Uhrzeit für diesen Aspekt
|
|
502
|
+
const exactDateTime = findExactAspectTime(planetName, aspect.birthPlanet, aspect.type, transitDateDisplay);
|
|
503
|
+
let dateTimeStr = '-';
|
|
504
|
+
if (exactDateTime) {
|
|
505
|
+
dateTimeStr = `${String(exactDateTime.day).padStart(2, '0')}.${String(exactDateTime.month).padStart(2, '0')}.${exactDateTime.year} ${String(exactDateTime.hour).padStart(2, '0')}:${String(exactDateTime.minute).padStart(2, '0')}`;
|
|
506
|
+
} else if (phase === 'separativ') {
|
|
507
|
+
// Für separative Phasen: Suche das letzte exakte Datum in der Vergangenheit
|
|
508
|
+
const lastExactDateTime = findLastExactAspectTime(planetName, aspect.birthPlanet, aspect.type, transitDateDisplay);
|
|
509
|
+
if (lastExactDateTime) {
|
|
510
|
+
dateTimeStr = `${String(lastExactDateTime.day).padStart(2, '0')}.${String(lastExactDateTime.month).padStart(2, '0')}.${lastExactDateTime.year} ${String(lastExactDateTime.hour).padStart(2, '0')}:${String(lastExactDateTime.minute).padStart(2, '0')} (e)`;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
const transitPlanetFormatted = planetName.charAt(0).toUpperCase() + planetName.slice(1);
|
|
515
|
+
const aspectTypeFormatted = aspect.type.padEnd(11);
|
|
516
|
+
const aspectPlanetFormatted = aspect.birthPlanet.charAt(0).toUpperCase() + aspect.birthPlanet.slice(1);
|
|
517
|
+
const orbFormatted = aspect.orb.padEnd(4);
|
|
518
|
+
const transitPosFormatted = `${transitPlanetData.sign} ${transitPlanetData.degreeInSign}°`;
|
|
519
|
+
const transitHouseFormatted = transitHouse.toString().padEnd(11);
|
|
520
|
+
const birthHouseFormatted = birthHouse.toString().padEnd(11);
|
|
521
|
+
const phaseFormatted = phase === 'separativ' ? 'separativ'.padEnd(11) : phase.padEnd(11);
|
|
522
|
+
const dateTimeFormatted = dateTimeStr.padEnd(22);
|
|
523
|
+
|
|
524
|
+
console.log(`| ${transitPlanetFormatted.padEnd(10)} | ${aspectTypeFormatted} | ${aspectPlanetFormatted.padEnd(10)} | ${orbFormatted}° | ${transitPosFormatted.padEnd(16)} | ${transitHouseFormatted} | ${birthHouseFormatted} | ${phaseFormatted} | ${dateTimeFormatted} |`);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
console.log('================================================================================');
|
|
530
|
+
console.log(`\nAnalyse-Datum: ${transitDateDisplay.day}.${transitDateDisplay.month}.${transitDateDisplay.year}`);
|
|
531
|
+
console.log(`Geburtsdatum: ${birthData.day}.${birthData.month}.${birthData.year} ${birthData.hour}:${birthData.minute.toString().padStart(2, '0')}`);
|
|
532
|
+
console.log(`Haus-System: ${houseSystem.charAt(0).toUpperCase() + houseSystem.slice(1)} (basierend auf Geburts-ASC)`);
|
|
533
|
+
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Persönliche Transit-Aspekte anzeigen, falls --transit-aspekte oder --tr Option angegeben
|
|
540
|
+
if (options.transitAspekte || options.tr) {
|
|
541
|
+
// Geburtsdaten sind für Transit-Aspekte erforderlich
|
|
542
|
+
const birthData = getBirthDataFromConfig();
|
|
543
|
+
if (!birthData) {
|
|
544
|
+
console.error('Fehler: Persönliche Transit-Aspekte erfordern Geburtsdaten. Bitte führe --setup aus, um deine Geburtsdaten zu konfigurieren.');
|
|
545
|
+
process.exit(1);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// Benutzerdefiniertes Datum verwenden, falls angegeben
|
|
549
|
+
let transitDate = null;
|
|
550
|
+
if (options.d) {
|
|
551
|
+
// Versuche, das Datum als DD.MM.YYYY oder DD.MM.YYYY HH:MM zu parsen
|
|
552
|
+
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
553
|
+
const match = options.d.match(dateRegex);
|
|
554
|
+
|
|
555
|
+
if (match) {
|
|
556
|
+
const day = parseInt(match[1], 10);
|
|
557
|
+
const month = parseInt(match[2], 10);
|
|
558
|
+
const year = parseInt(match[3], 10);
|
|
559
|
+
const hour = match[4] ? parseInt(match[4], 10) : 12; // Standard: 12 Uhr
|
|
560
|
+
const minute = match[5] ? parseInt(match[5], 10) : 0; // Standard: 0 Minuten
|
|
561
|
+
|
|
562
|
+
// Überprüfe, ob das Datum gültig ist
|
|
563
|
+
const date = new Date(year, month - 1, day, hour, minute);
|
|
564
|
+
if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
|
|
565
|
+
transitDate = {
|
|
566
|
+
day: day,
|
|
567
|
+
month: month,
|
|
568
|
+
year: year,
|
|
569
|
+
hour: hour,
|
|
570
|
+
minute: minute
|
|
571
|
+
};
|
|
572
|
+
console.log(`Verwende Transitdatum: ${day}.${month}.${year} ${hour}:${minute.toString().padStart(2, '0')}`);
|
|
573
|
+
} else {
|
|
574
|
+
console.error('Ungültiges Datum:', options.d);
|
|
575
|
+
console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM" (mit Anführungszeichen für Datum mit Uhrzeit)');
|
|
576
|
+
process.exit(1);
|
|
577
|
+
}
|
|
578
|
+
} else {
|
|
579
|
+
console.error('Ungültiges Datum:', options.d);
|
|
580
|
+
console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM" (mit Anführungszeichen für Datum mit Uhrzeit)');
|
|
581
|
+
process.exit(1);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Zeige persönliche Transit-Aspekte an
|
|
586
|
+
// Verwende den spezifischen Planeten, falls angegeben, oder alle Planeten
|
|
587
|
+
const targetPlanet = planetArg ? planetArg.toLowerCase() : null;
|
|
588
|
+
showPersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
589
|
+
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
|
|
411
593
|
// Aspektfiguren anzeigen, falls --af Option angegeben (ohne Planet erforderlich)
|
|
412
594
|
if (options.af) {
|
|
413
595
|
// Geburtsdaten verwenden, falls --ich Option angegeben
|