"""Firdaria (LOG-11) — perska technika time-lord. Sekwencja okresów głównych zależy od sekty (dzień/noc). Sekta: urodzenie dzienne, gdy Słońce jest nad horyzontem, czyli po tej samej stronie osi Asc–Dsc co MC. Klasyczne długości okresów (lata): Su 10, Ve 8, Me 13, Mo 9, Sa 11, Ju 12, Ma 7 (razem 70) + Węzeł Północny 3 + Węzeł Południowy 2 = 75 lat. Każdy okres główny planety dzieli się na 7 podokresów (sub-lord w tej samej kolejności, cyklicznie). Węzły — bez podokresów (najczęstsza konwencja). """ from __future__ import annotations from datetime import datetime, timedelta DAY_ORDER = ["Sun", "Venus", "Mercury", "Moon", "Saturn", "Jupiter", "Mars"] NIGHT_ORDER = ["Moon", "Saturn", "Jupiter", "Mars", "Sun", "Venus", "Mercury"] YEARS = {"Sun": 10, "Venus": 8, "Mercury": 13, "Moon": 9, "Saturn": 11, "Jupiter": 12, "Mars": 7} NODES = [("North Node", 3), ("South Node", 2)] DAYS_PER_YEAR = 365.2422 def is_day_birth(sun_lon: float, asc: float, mc: float) -> bool: """Słońce nad horyzontem = ta sama półkula osi Asc–Dsc co MC.""" return (((sun_lon - asc) % 360.0) < 180.0) == (((mc - asc) % 360.0) < 180.0) def _date(birth: datetime, years: float) -> str: return (birth + timedelta(days=years * DAYS_PER_YEAR)).date().isoformat() def firdaria(birth: datetime, sun_lon: float, asc: float, mc: float) -> dict: """Pełny rozkład Firdarii: sekta, kolejność, okresy główne i podokresy.""" day = is_day_birth(sun_lon, asc, mc) order = DAY_ORDER if day else NIGHT_ORDER majors = [(lord, YEARS[lord]) for lord in order] + NODES periods: list[dict] = [] age = 0.0 for lord, yrs in majors: period = {"lord": lord, "years": yrs, "start": _date(birth, age), "end": _date(birth, age + yrs)} if lord in YEARS: # planeta -> 7 podokresów sub_len = yrs / 7.0 i = order.index(lord) sub_age = age subs: list[dict] = [] for k in range(7): sub_lord = order[(i + k) % 7] subs.append({"lord": sub_lord, "start": _date(birth, sub_age), "end": _date(birth, sub_age + sub_len)}) sub_age += sub_len period["sub"] = subs periods.append(period) age += yrs return {"sect": "day" if day else "night", "order": order, "periods": periods}