klio 1.2.6 → 1.2.9
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 +322 -25
- package/src/cli/cli.js +182 -1
- package/src/health/fileAnalysis.js +20 -8
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;
|
|
@@ -269,6 +268,9 @@ function getAstrologicalData(planetName, customDate = null) {
|
|
|
269
268
|
|
|
270
269
|
// Verwende das angegebene Datum oder das aktuelle Datum (mit Zeitzonenberücksichtigung)
|
|
271
270
|
let calcYear, calcMonth, calcDay, calcHour, calcMinute;
|
|
271
|
+
let timezoneOffsetMinutes;
|
|
272
|
+
let timezone = null;
|
|
273
|
+
let baseDate;
|
|
272
274
|
|
|
273
275
|
if (customDate) {
|
|
274
276
|
calcYear = customDate.year;
|
|
@@ -276,6 +278,18 @@ function getAstrologicalData(planetName, customDate = null) {
|
|
|
276
278
|
calcDay = customDate.day;
|
|
277
279
|
calcHour = customDate.hour;
|
|
278
280
|
calcMinute = customDate.minute;
|
|
281
|
+
baseDate = customDate;
|
|
282
|
+
// Versuche, die Zeitzone vom customDate abzuleiten (z.B. Geburtsort)
|
|
283
|
+
if (customDate.location && customDate.location.timezone) {
|
|
284
|
+
timezone = customDate.location.timezone;
|
|
285
|
+
} else {
|
|
286
|
+
try {
|
|
287
|
+
const config = loadConfig();
|
|
288
|
+
if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
289
|
+
timezone = config.currentLocation.timezone;
|
|
290
|
+
}
|
|
291
|
+
} catch (_) {}
|
|
292
|
+
}
|
|
279
293
|
} else {
|
|
280
294
|
// Verwende die aktuelle Zeit in der konfigurierten Zeitzone
|
|
281
295
|
const timeData = getCurrentTimeInTimezone();
|
|
@@ -284,9 +298,24 @@ function getAstrologicalData(planetName, customDate = null) {
|
|
|
284
298
|
calcDay = timeData.day;
|
|
285
299
|
calcHour = timeData.hour;
|
|
286
300
|
calcMinute = timeData.minute;
|
|
301
|
+
baseDate = timeData;
|
|
302
|
+
try {
|
|
303
|
+
const config = loadConfig();
|
|
304
|
+
if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
305
|
+
timezone = config.currentLocation.timezone;
|
|
306
|
+
}
|
|
307
|
+
} catch (_) {}
|
|
287
308
|
}
|
|
288
309
|
|
|
289
|
-
|
|
310
|
+
// Bestimme Offset in Minuten (Lokalzeit - UTC)
|
|
311
|
+
if (timezone) {
|
|
312
|
+
timezoneOffsetMinutes = getTimezoneOffset({ year: calcYear, month: calcMonth, day: calcDay, hour: calcHour, minute: calcMinute }, timezone);
|
|
313
|
+
} else {
|
|
314
|
+
// Fallback: Systemoffset umkehren, damit (Lokalzeit - UTC) entsteht
|
|
315
|
+
timezoneOffsetMinutes = -new Date().getTimezoneOffset();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const julianDay = calculateJulianDayUTC({ year: calcYear, month: calcMonth, day: calcDay, hour: calcHour, minute: calcMinute }, timezoneOffsetMinutes);
|
|
290
319
|
const flag = swisseph.SEFLG_SWIEPH | swisseph.SEFLG_SPEED;
|
|
291
320
|
const result = swisseph.swe_calc_ut(julianDay, planet, flag);
|
|
292
321
|
|
|
@@ -341,13 +370,18 @@ function getCriticalPlanets(customDate = null) {
|
|
|
341
370
|
timeData = getCurrentTimeInTimezone();
|
|
342
371
|
}
|
|
343
372
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
373
|
+
// Berücksichtige die lokale Zeitzone für die Umrechnung nach UTC
|
|
374
|
+
let timezone = null;
|
|
375
|
+
try {
|
|
376
|
+
const config = loadConfig();
|
|
377
|
+
if (customDate && customDate.location && customDate.location.timezone) {
|
|
378
|
+
timezone = customDate.location.timezone;
|
|
379
|
+
} else if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
380
|
+
timezone = config.currentLocation.timezone;
|
|
381
|
+
}
|
|
382
|
+
} catch (_) {}
|
|
383
|
+
const offsetMinutes = timezone ? getTimezoneOffset(timeData, timezone) : -new Date().getTimezoneOffset();
|
|
384
|
+
const julianDay = calculateJulianDayUTC(timeData, offsetMinutes);
|
|
351
385
|
|
|
352
386
|
// Berechne Positionen aller Planeten
|
|
353
387
|
for (const [name, planetId] of Object.entries(planets)) {
|
|
@@ -480,19 +514,19 @@ function findExactAspectTime(planet1, planet2, aspectType, startDate) {
|
|
|
480
514
|
return null;
|
|
481
515
|
}
|
|
482
516
|
|
|
483
|
-
// Wir suchen in einem
|
|
484
|
-
// um den exakten Aspekt zu finden
|
|
517
|
+
// Wir suchen in einem vernünftigen Zeitfenster (90 Tage in der Zukunft)
|
|
518
|
+
// um den nächsten exakten Aspekt zu finden
|
|
485
519
|
// Besonders wichtig für langsame Planeten wie Saturn, Uranus, Neptun, Pluto
|
|
486
520
|
let bestMatch = null;
|
|
487
521
|
let bestDistance = Infinity;
|
|
488
522
|
|
|
489
|
-
// Suche in
|
|
490
|
-
const searchWindow =
|
|
523
|
+
// Suche nur in der Zukunft (0-90 Tage nach dem Startdatum)
|
|
524
|
+
const searchWindow = 90; // Tage
|
|
491
525
|
|
|
492
|
-
// Wir suchen
|
|
493
|
-
const stepsPerDay =
|
|
526
|
+
// Wir suchen in kleineren Schritten (alle 2 Stunden), um präzisere Ergebnisse zu erhalten
|
|
527
|
+
const stepsPerDay = 12; // 2-Stunden-Schritte
|
|
494
528
|
|
|
495
|
-
for (let daysOffset =
|
|
529
|
+
for (let daysOffset = 0; daysOffset <= searchWindow; daysOffset++) {
|
|
496
530
|
for (let hourOffset = 0; hourOffset < 24; hourOffset++) { // Jede Stunde
|
|
497
531
|
for (let minuteOffset = 0; minuteOffset < 60; minuteOffset += 5) { // Alle 5 Minuten
|
|
498
532
|
const testDate = addDays(startDate, daysOffset);
|
|
@@ -518,7 +552,56 @@ function findExactAspectTime(planet1, planet2, aspectType, startDate) {
|
|
|
518
552
|
}
|
|
519
553
|
|
|
520
554
|
// Wenn wir einen Aspekt gefunden haben, der nah genug am Ziel ist, geben wir ihn zurück
|
|
521
|
-
|
|
555
|
+
// Strengere Toleranz von 0.5° für bessere Genauigkeit
|
|
556
|
+
if (bestMatch && bestDistance <= 0.5) { // Toleranz von 0.5°
|
|
557
|
+
return bestMatch;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Funktion zum Finden des letzten exakten Aspekts in der Vergangenheit (für separative Phasen)
|
|
564
|
+
function findLastExactAspectTime(planet1, planet2, aspectType, startDate) {
|
|
565
|
+
const targetAngle = getAspectAngle(aspectType);
|
|
566
|
+
|
|
567
|
+
if (targetAngle === null) {
|
|
568
|
+
return null;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Suche in der Vergangenheit (bis zu 180 Tage vor dem Startdatum)
|
|
572
|
+
let bestMatch = null;
|
|
573
|
+
let bestDistance = Infinity;
|
|
574
|
+
|
|
575
|
+
// Suche in einem Zeitfenster von 180 Tagen vor dem Startdatum
|
|
576
|
+
const searchWindow = 180; // Tage
|
|
577
|
+
|
|
578
|
+
for (let daysOffset = -searchWindow; daysOffset <= 0; daysOffset++) {
|
|
579
|
+
for (let hourOffset = 0; hourOffset < 24; hourOffset++) { // Jede Stunde
|
|
580
|
+
for (let minuteOffset = 0; minuteOffset < 60; minuteOffset += 5) { // Alle 5 Minuten
|
|
581
|
+
const testDate = addDays(startDate, daysOffset);
|
|
582
|
+
testDate.hour = hourOffset;
|
|
583
|
+
testDate.minute = minuteOffset;
|
|
584
|
+
|
|
585
|
+
// Berechne die Positionen der beiden Planeten
|
|
586
|
+
const planet1Data = getAstrologicalData(planet1, testDate);
|
|
587
|
+
const planet2Data = getAstrologicalData(planet2, testDate);
|
|
588
|
+
|
|
589
|
+
// Berechne den Winkel zwischen den Planeten
|
|
590
|
+
const angleDiff = Math.abs(planet1Data.longitude - planet2Data.longitude) % 360;
|
|
591
|
+
const normalizedAngle = Math.min(angleDiff, 360 - angleDiff);
|
|
592
|
+
const distanceToTarget = Math.abs(normalizedAngle - targetAngle);
|
|
593
|
+
|
|
594
|
+
// Speichere das beste Ergebnis
|
|
595
|
+
if (distanceToTarget < bestDistance) {
|
|
596
|
+
bestDistance = distanceToTarget;
|
|
597
|
+
bestMatch = {...testDate};
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Wenn wir einen Aspekt gefunden haben, der nah genug am Ziel ist, geben wir ihn zurück
|
|
604
|
+
if (bestMatch && bestDistance <= 0.5) { // Toleranz von 0.5°
|
|
522
605
|
return bestMatch;
|
|
523
606
|
}
|
|
524
607
|
|
|
@@ -565,13 +648,16 @@ function isPlanetRetrograde(planetName, dateComponents) {
|
|
|
565
648
|
if (planet === undefined) return false;
|
|
566
649
|
|
|
567
650
|
// Berechne die Position mit Geschwindigkeitsinformation
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
651
|
+
// Konvertiere Datum zu UTC basierend auf konfigurierter Zeitzone
|
|
652
|
+
let tz = null;
|
|
653
|
+
try {
|
|
654
|
+
const config = loadConfig();
|
|
655
|
+
if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
656
|
+
tz = config.currentLocation.timezone;
|
|
657
|
+
}
|
|
658
|
+
} catch (_) {}
|
|
659
|
+
const off = tz ? getTimezoneOffset(dateComponents, tz) : -new Date().getTimezoneOffset();
|
|
660
|
+
const julianDay = calculateJulianDayUTC(dateComponents, off);
|
|
575
661
|
|
|
576
662
|
const flag = swisseph.SEFLG_SWIEPH | swisseph.SEFLG_SPEED;
|
|
577
663
|
const result = swisseph.swe_calc_ut(julianDay, planet, flag);
|
|
@@ -1132,6 +1218,213 @@ async function calculatePersonalTransits(transitDate = null, birthData = null) {
|
|
|
1132
1218
|
};
|
|
1133
1219
|
}
|
|
1134
1220
|
|
|
1221
|
+
// Funktion zur Berechnung persönlicher Transit-Aspekte
|
|
1222
|
+
function calculatePersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null) {
|
|
1223
|
+
if (!birthData) {
|
|
1224
|
+
birthData = getBirthDataFromConfig();
|
|
1225
|
+
if (!birthData) {
|
|
1226
|
+
console.error('Keine Geburtsdaten verfügbar für persönliche Transit-Aspekte.');
|
|
1227
|
+
return null;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
// Verwende aktuelles Datum, wenn kein Transitdatum angegeben
|
|
1232
|
+
if (!transitDate) {
|
|
1233
|
+
transitDate = getCurrentTimeInTimezone();
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// Berechne aktuelle Planetenpositionen (Transit)
|
|
1237
|
+
const transitPlanets = {};
|
|
1238
|
+
for (const [name, planetId] of Object.entries(planets)) {
|
|
1239
|
+
const data = getAstrologicalData(name, transitDate);
|
|
1240
|
+
transitPlanets[name] = data.longitude;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
// Berechne Geburtsplanetenpositionen (Radix)
|
|
1244
|
+
const birthPlanets = {};
|
|
1245
|
+
for (const [name, planetId] of Object.entries(planets)) {
|
|
1246
|
+
const data = getAstrologicalData(name, birthData);
|
|
1247
|
+
birthPlanets[name] = data.longitude;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
// Berechne Aspekte zwischen Transit- und Geburtsplaneten
|
|
1251
|
+
const aspects = [];
|
|
1252
|
+
const aspectTypes = [
|
|
1253
|
+
{ name: 'Konjunktion', angle: 0, orb: 8 },
|
|
1254
|
+
{ name: 'Opposition', angle: 180, orb: 8 },
|
|
1255
|
+
{ name: 'Quadrat', angle: 90, orb: 6 },
|
|
1256
|
+
{ name: 'Trigon', angle: 120, orb: 6 },
|
|
1257
|
+
{ name: 'Sextil', angle: 60, orb: 4 }
|
|
1258
|
+
];
|
|
1259
|
+
|
|
1260
|
+
// Vergleiche jeden Transitplaneten mit jedem Geburtsplaneten
|
|
1261
|
+
for (const [transitName, transitLongitude] of Object.entries(transitPlanets)) {
|
|
1262
|
+
for (const [birthName, birthLongitude] of Object.entries(birthPlanets)) {
|
|
1263
|
+
// Überspringe, wenn es sich um denselben Planeten handelt
|
|
1264
|
+
if (transitName === birthName) continue;
|
|
1265
|
+
|
|
1266
|
+
// Berechne den Winkelunterschied
|
|
1267
|
+
const angleDiff = Math.abs(transitLongitude - birthLongitude) % 360;
|
|
1268
|
+
const normalizedAngle = Math.min(angleDiff, 360 - angleDiff);
|
|
1269
|
+
|
|
1270
|
+
// Prüfe auf Aspekte
|
|
1271
|
+
for (const aspect of aspectTypes) {
|
|
1272
|
+
if (Math.abs(normalizedAngle - aspect.angle) <= aspect.orb) {
|
|
1273
|
+
aspects.push({
|
|
1274
|
+
transitPlanet: transitName,
|
|
1275
|
+
birthPlanet: birthName,
|
|
1276
|
+
type: aspect.name,
|
|
1277
|
+
angle: normalizedAngle.toFixed(2),
|
|
1278
|
+
orb: Math.abs(normalizedAngle - aspect.angle).toFixed(2),
|
|
1279
|
+
transitLongitude: transitLongitude,
|
|
1280
|
+
birthLongitude: birthLongitude
|
|
1281
|
+
});
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
// Filtere nach Zielplanet, falls angegeben
|
|
1288
|
+
const filteredAspects = targetPlanet
|
|
1289
|
+
? aspects.filter(aspect => aspect.transitPlanet === targetPlanet)
|
|
1290
|
+
: aspects;
|
|
1291
|
+
|
|
1292
|
+
return {
|
|
1293
|
+
transitDate: transitDate,
|
|
1294
|
+
birthData: birthData,
|
|
1295
|
+
aspects: filteredAspects
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// Funktion zur Anzeige persönlicher Transit-Aspekte
|
|
1300
|
+
function showPersonalTransitAspects(transitDate = null, birthData = null, targetPlanet = null) {
|
|
1301
|
+
const aspectData = calculatePersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
1302
|
+
|
|
1303
|
+
if (!aspectData || aspectData.aspects.length === 0) {
|
|
1304
|
+
console.log('Keine persönlichen Transit-Aspekte gefunden.');
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
const transitDateDisplay = transitDate || getCurrentTimeInTimezone();
|
|
1309
|
+
console.log(`Persönliche Transit-Aspekte (${transitDateDisplay.day}.${transitDateDisplay.month}.${transitDateDisplay.year}):`);
|
|
1310
|
+
console.log('================================================================================');
|
|
1311
|
+
console.log('| Transit | Geburts | Aspekt | Orb | Transit Pos | Geburts Pos |');
|
|
1312
|
+
console.log('================================================================================');
|
|
1313
|
+
|
|
1314
|
+
// Hole zusätzliche Informationen für die Anzeige
|
|
1315
|
+
const transitPlanetsData = {};
|
|
1316
|
+
const birthPlanetsData = {};
|
|
1317
|
+
|
|
1318
|
+
for (const [name] of Object.entries(planets)) {
|
|
1319
|
+
transitPlanetsData[name] = getAstrologicalData(name, transitDateDisplay);
|
|
1320
|
+
birthPlanetsData[name] = getAstrologicalData(name, birthData);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
aspectData.aspects.forEach(aspect => {
|
|
1324
|
+
const transitPlanetData = transitPlanetsData[aspect.transitPlanet];
|
|
1325
|
+
const birthPlanetData = birthPlanetsData[aspect.birthPlanet];
|
|
1326
|
+
|
|
1327
|
+
const transitPlanetFormatted = aspect.transitPlanet.charAt(0).toUpperCase() + aspect.transitPlanet.slice(1);
|
|
1328
|
+
const birthPlanetFormatted = aspect.birthPlanet.charAt(0).toUpperCase() + aspect.birthPlanet.slice(1);
|
|
1329
|
+
const aspectName = aspect.type.padEnd(11, ' ');
|
|
1330
|
+
const orb = aspect.orb.padEnd(4, ' ');
|
|
1331
|
+
const transitPos = `${transitPlanetData.sign} ${transitPlanetData.degreeInSign}°`;
|
|
1332
|
+
const birthPos = `${birthPlanetData.sign} ${birthPlanetData.degreeInSign}°`;
|
|
1333
|
+
|
|
1334
|
+
console.log(`| ${transitPlanetFormatted.padEnd(10)} | ${birthPlanetFormatted.padEnd(10)} | ${aspectName} | ${orb}° | ${transitPos.padEnd(11)} | ${birthPos.padEnd(11)} |`);
|
|
1335
|
+
});
|
|
1336
|
+
|
|
1337
|
+
console.log('================================================================================');
|
|
1338
|
+
console.log(`Gesamt: ${aspectData.aspects.length} persönliche Transit-Aspekte gefunden`);
|
|
1339
|
+
console.log('\nErklärung: Diese Aspekte zeigen, wie die aktuellen Planetenpositionen');
|
|
1340
|
+
console.log('mit deinen Geburtspositionen interagieren (Transit → Radix).');
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
// Funktion für kombinierte Analyse (Geburts- und Transit-Aspekte mit Häusern)
|
|
1344
|
+
async function showCombinedAnalysis(planetName, transitDate = null, birthData = null, houseSystem = 'K') {
|
|
1345
|
+
if (!birthData) {
|
|
1346
|
+
birthData = getBirthDataFromConfig();
|
|
1347
|
+
if (!birthData) {
|
|
1348
|
+
console.error('Keine Geburtsdaten verfügbar für kombinierte Analyse.');
|
|
1349
|
+
return null;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
// Verwende aktuelles Datum, wenn kein Transitdatum angegeben
|
|
1354
|
+
if (!transitDate) {
|
|
1355
|
+
transitDate = getCurrentTimeInTimezone();
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
// Berechne Häuser basierend auf Geburtsdaten
|
|
1359
|
+
const birthJulianDay = calculateJulianDayUTC(birthData, getTimezoneOffset(birthData, birthData.location?.timezone || 'Europe/Zurich'));
|
|
1360
|
+
const houses = await calculateHouses(birthJulianDay, houseSystem === 'koch' ? 'K' : houseSystem === 'wholesign' ? 'W' : 'G', true);
|
|
1361
|
+
|
|
1362
|
+
// Berechne aktuelle Planetenpositionen (Transit)
|
|
1363
|
+
const transitPlanetData = getAstrologicalData(planetName, transitDate);
|
|
1364
|
+
const transitLongitude = transitPlanetData.longitude;
|
|
1365
|
+
const transitHouse = getPlanetHouse(transitLongitude, houses.house);
|
|
1366
|
+
|
|
1367
|
+
// Berechne Geburtsplanetenpositionen (Radix)
|
|
1368
|
+
const birthPlanetData = getAstrologicalData(planetName, birthData);
|
|
1369
|
+
const birthLongitude = birthPlanetData.longitude;
|
|
1370
|
+
const birthHouse = getPlanetHouse(birthLongitude, houses.house);
|
|
1371
|
+
|
|
1372
|
+
// Berechne Geburtsaspekte für den Planeten
|
|
1373
|
+
const birthAspects = calculatePlanetAspects(planetName, birthData, true);
|
|
1374
|
+
|
|
1375
|
+
// Berechne Transit-Aspekte für den Planeten
|
|
1376
|
+
const transitAspectsData = calculatePersonalTransitAspects(transitDate, birthData, planetName);
|
|
1377
|
+
const transitAspects = transitAspectsData ? transitAspectsData.aspects : [];
|
|
1378
|
+
|
|
1379
|
+
// Zeige kombinierte Analyse an
|
|
1380
|
+
console.log(`Kombinierte Analyse für ${planetName.charAt(0).toUpperCase() + planetName.slice(1)}:`);
|
|
1381
|
+
console.log('================================================================================');
|
|
1382
|
+
console.log(`Analyse-Datum: ${transitDate.day}.${transitDate.month}.${transitDate.year}`);
|
|
1383
|
+
console.log(`Geburtsdatum: ${birthData.day}.${birthData.month}.${birthData.year} ${birthData.hour}:${birthData.minute.toString().padStart(2, '0')}`);
|
|
1384
|
+
console.log('');
|
|
1385
|
+
|
|
1386
|
+
// Zeige Planetenpositionen und Häuser
|
|
1387
|
+
console.log('Positionen und Häuser:');
|
|
1388
|
+
console.log('--------------------------------------------------------------------------------');
|
|
1389
|
+
console.log(`Transit: ${transitPlanetData.sign} ${transitPlanetData.degreeInSign}° (Haus ${transitHouse})`);
|
|
1390
|
+
console.log(`Geburt: ${birthPlanetData.sign} ${birthPlanetData.degreeInSign}° (Haus ${birthHouse})`);
|
|
1391
|
+
console.log('');
|
|
1392
|
+
|
|
1393
|
+
// Zeige Geburtsaspekte
|
|
1394
|
+
if (birthAspects.length > 0) {
|
|
1395
|
+
console.log('Geburtsaspekte (Radix → Radix):');
|
|
1396
|
+
console.log('--------------------------------------------------------------------------------');
|
|
1397
|
+
birthAspects.forEach(aspect => {
|
|
1398
|
+
const aspectPlanetData = getAstrologicalData(aspect.planet, birthData);
|
|
1399
|
+
const aspectHouse = getPlanetHouse(parseFloat(aspectPlanetData.degreeInSign) + (signs.indexOf(aspectPlanetData.sign) * 30), houses.house);
|
|
1400
|
+
console.log(`${aspect.type.padEnd(12)} mit ${aspect.planet.padEnd(8)} (${aspectPlanetData.sign} ${aspectPlanetData.degreeInSign}° Haus ${aspectHouse}) - Orb: ${aspect.orb}°`);
|
|
1401
|
+
});
|
|
1402
|
+
console.log('');
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
// Zeige Transit-Aspekte
|
|
1406
|
+
if (transitAspects.length > 0) {
|
|
1407
|
+
console.log('Transit-Aspekte (Transit → Radix):');
|
|
1408
|
+
console.log('--------------------------------------------------------------------------------');
|
|
1409
|
+
transitAspects.forEach(aspect => {
|
|
1410
|
+
const birthPlanetData = getAstrologicalData(aspect.birthPlanet, birthData);
|
|
1411
|
+
const birthHouse = getPlanetHouse(parseFloat(birthPlanetData.degreeInSign) + (signs.indexOf(birthPlanetData.sign) * 30), houses.house);
|
|
1412
|
+
console.log(`${aspect.type.padEnd(12)} mit ${aspect.birthPlanet.padEnd(8)} (${birthPlanetData.sign} ${birthPlanetData.degreeInSign}° Haus ${birthHouse}) - Orb: ${aspect.orb}°`);
|
|
1413
|
+
});
|
|
1414
|
+
console.log('');
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
return {
|
|
1418
|
+
transitPlanetData,
|
|
1419
|
+
birthPlanetData,
|
|
1420
|
+
transitHouse,
|
|
1421
|
+
birthHouse,
|
|
1422
|
+
birthAspects,
|
|
1423
|
+
transitAspects,
|
|
1424
|
+
houses
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1135
1428
|
// Funktion zur Analyse der Elementverteilung
|
|
1136
1429
|
function analyzeElementDistribution(dateComponents, useBirthData = false) {
|
|
1137
1430
|
const elementCounts = {
|
|
@@ -1321,9 +1614,13 @@ module.exports = {
|
|
|
1321
1614
|
getAspectAngle,
|
|
1322
1615
|
getFutureAspects,
|
|
1323
1616
|
findExactAspectTime,
|
|
1617
|
+
findLastExactAspectTime,
|
|
1324
1618
|
detectAspectFigures,
|
|
1325
1619
|
showAspectFigures,
|
|
1326
|
-
calculatePersonalTransits
|
|
1620
|
+
calculatePersonalTransits,
|
|
1621
|
+
calculatePersonalTransitAspects,
|
|
1622
|
+
showPersonalTransitAspects,
|
|
1623
|
+
showCombinedAnalysis
|
|
1327
1624
|
};
|
|
1328
1625
|
|
|
1329
1626
|
// 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, getAspectAngle, getFutureAspects, getPastAspects } = 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,185 @@ 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
|
+
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// Persönliche Transit-Aspekte anzeigen, falls --transit-aspekte oder --tr Option angegeben
|
|
539
|
+
if (options.transitAspekte || options.tr) {
|
|
540
|
+
// Geburtsdaten sind für Transit-Aspekte erforderlich
|
|
541
|
+
const birthData = getBirthDataFromConfig();
|
|
542
|
+
if (!birthData) {
|
|
543
|
+
console.error('Fehler: Persönliche Transit-Aspekte erfordern Geburtsdaten. Bitte führe --setup aus, um deine Geburtsdaten zu konfigurieren.');
|
|
544
|
+
process.exit(1);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Benutzerdefiniertes Datum verwenden, falls angegeben
|
|
548
|
+
let transitDate = null;
|
|
549
|
+
if (options.d) {
|
|
550
|
+
// Versuche, das Datum als DD.MM.YYYY oder DD.MM.YYYY HH:MM zu parsen
|
|
551
|
+
const dateRegex = /^(\d{1,2})\.(\d{1,2})\.(\d{4})(?:\s+(\d{1,2}):(\d{2}))?$/;
|
|
552
|
+
const match = options.d.match(dateRegex);
|
|
553
|
+
|
|
554
|
+
if (match) {
|
|
555
|
+
const day = parseInt(match[1], 10);
|
|
556
|
+
const month = parseInt(match[2], 10);
|
|
557
|
+
const year = parseInt(match[3], 10);
|
|
558
|
+
const hour = match[4] ? parseInt(match[4], 10) : 12; // Standard: 12 Uhr
|
|
559
|
+
const minute = match[5] ? parseInt(match[5], 10) : 0; // Standard: 0 Minuten
|
|
560
|
+
|
|
561
|
+
// Überprüfe, ob das Datum gültig ist
|
|
562
|
+
const date = new Date(year, month - 1, day, hour, minute);
|
|
563
|
+
if (date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day) {
|
|
564
|
+
transitDate = {
|
|
565
|
+
day: day,
|
|
566
|
+
month: month,
|
|
567
|
+
year: year,
|
|
568
|
+
hour: hour,
|
|
569
|
+
minute: minute
|
|
570
|
+
};
|
|
571
|
+
console.log(`Verwende Transitdatum: ${day}.${month}.${year} ${hour}:${minute.toString().padStart(2, '0')}`);
|
|
572
|
+
} else {
|
|
573
|
+
console.error('Ungültiges Datum:', options.d);
|
|
574
|
+
console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM" (mit Anführungszeichen für Datum mit Uhrzeit)');
|
|
575
|
+
process.exit(1);
|
|
576
|
+
}
|
|
577
|
+
} else {
|
|
578
|
+
console.error('Ungültiges Datum:', options.d);
|
|
579
|
+
console.error('💡 Bitte verwende das Format: DD.MM.YYYY oder "DD.MM.YYYY HH:MM" (mit Anführungszeichen für Datum mit Uhrzeit)');
|
|
580
|
+
process.exit(1);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Zeige persönliche Transit-Aspekte an
|
|
585
|
+
// Verwende den spezifischen Planeten, falls angegeben, oder alle Planeten
|
|
586
|
+
const targetPlanet = planetArg ? planetArg.toLowerCase() : null;
|
|
587
|
+
showPersonalTransitAspects(transitDate, birthData, targetPlanet);
|
|
588
|
+
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
|
|
411
592
|
// Aspektfiguren anzeigen, falls --af Option angegeben (ohne Planet erforderlich)
|
|
412
593
|
if (options.af) {
|
|
413
594
|
// Geburtsdaten verwenden, falls --ich Option angegeben
|
|
@@ -28,10 +28,16 @@ async function analyzeHouseDistribution(planetName, folderPath, houseSystem = 'K
|
|
|
28
28
|
const planetLongitude = planetData.longitude;
|
|
29
29
|
|
|
30
30
|
// Berechne die Hausposition für dieses Datum
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
const { calculateJulianDayUTC, getTimezoneOffset, loadConfig } = require('../astrology/astrologyService');
|
|
32
|
+
let tz = null;
|
|
33
|
+
try {
|
|
34
|
+
const config = loadConfig();
|
|
35
|
+
if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
36
|
+
tz = config.currentLocation.timezone;
|
|
37
|
+
}
|
|
38
|
+
} catch (_) {}
|
|
39
|
+
const off = tz ? getTimezoneOffset(dateComponents, tz) : -new Date().getTimezoneOffset();
|
|
40
|
+
const julianDay = calculateJulianDayUTC(dateComponents, off);
|
|
35
41
|
|
|
36
42
|
const houses = await calculateHouses(julianDay, houseSystem);
|
|
37
43
|
const planetHouse = getPlanetHouse(planetLongitude, houses.house);
|
|
@@ -89,10 +95,16 @@ async function filterFilesByHouse(planetName, folderPath, targetHouse, houseSyst
|
|
|
89
95
|
const planetLongitude = planetData.longitude;
|
|
90
96
|
|
|
91
97
|
// Berechne die Hausposition für dieses Datum
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
const { calculateJulianDayUTC, getTimezoneOffset, loadConfig } = require('../astrology/astrologyService');
|
|
99
|
+
let tz = null;
|
|
100
|
+
try {
|
|
101
|
+
const config = loadConfig();
|
|
102
|
+
if (config && config.currentLocation && config.currentLocation.timezone) {
|
|
103
|
+
tz = config.currentLocation.timezone;
|
|
104
|
+
}
|
|
105
|
+
} catch (_) {}
|
|
106
|
+
const off = tz ? getTimezoneOffset(dateComponents, tz) : -new Date().getTimezoneOffset();
|
|
107
|
+
const julianDay = calculateJulianDayUTC(dateComponents, off);
|
|
96
108
|
|
|
97
109
|
const houses = await calculateHouses(julianDay, houseSystem);
|
|
98
110
|
const planetHouse = getPlanetHouse(planetLongitude, houses.house);
|