from abstract_utilities import *
texts = """=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/constants/index.ts ===

"export * from './planets';\nexport * from './satellites';\nexport * from './scale_utils';\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/constants/scale_utils.ts ===

"import {\n    MU_SUN,\n    AU_EARTH,\n    MU_EARTH\n} from './planets';\n//time\nexport function exponential(i: number, k: number) {\n    return i * (10 ** (k))\n\n}\nexport const SECOND: number = 1\nexport const ZEPTOSECOND: number = exponential(SECOND, -21);\nexport const ATTOSECOND: number = exponential(SECOND, -18);\nexport const FEMTOSECOND: number = exponential(SECOND, -15);\nexport const PICOSECOND: number = exponential(SECOND, -12);\nexport const NANOSECOND: number = exponential(SECOND, -9);\nexport const MICROSECOND: number = exponential(SECOND, -6);\nexport const MILISECOND: number = exponential(SECOND, -3);\nexport const CENTISECOND: number = exponential(SECOND, -2);\nexport const DECISECOND: number = exponential(SECOND, -1);\nexport const MINUTE: number = SECOND * 60;\nexport const HOUR: number = MINUTE * 60;\nexport const DAY: number = HOUR * 24;\nexport const YEAR: number = DAY * 365;\nexport const MONTH: number = YEAR / 12;\n\n//math\nexport const PI = Math.PI\nexport const PI2 = 2 * PI\n\n//scale\nexport const TIME_SCALE: number = MONTH;\nexport const T_MERCURY: number = 88 * DAY;\n\n//steps\nexport const MAX_REAL_SEC: number = DECISECOND\nexport const MAX_STEP: number = 6 * HOUR; // 6 h\nexport const STEPS_PER_ORBIT: number = 2000;\nexport const DT: number = MINUTE; // e.g. 60 s per step\n\n//length\nexport const MAX_TRAIL_LENGTH: number = STEPS_PER_ORBIT;\n\n//surface softening\nexport const SOFTENING: number = 1e8; // Reduced for surface launches\n\n//conversions\nexport const METERS_PER_MILE = 1609.34;\nexport const METERS_PER_KM = 1000;\nexport const METERS_PER_FOOT = 0.3048;\nexport const toMeters = (v: number, unit: string): number => {\n    switch (unit) {\n        case 'km': return v * METERS_PER_KM;\n        case 'mi': return v * METERS_PER_MILE;\n        case 'ft': return v * METERS_PER_FOOT;\n        default: return v;\n    }\n};\n\nexport const toSeconds = (v: number, unit: string): number => {\n    switch (unit) {\n        case 'min': return v * MINUTE;\n        case 'h': return v * HOUR;\n        case 'day': return v * DAY;\n        default: return v;\n    }\n};\n\nexport const fromMeters = (d: number, unit: string): number => {\n    switch (unit) {\n        case 'km': return d / METERS_PER_KM;\n        case 'mi': return d / METERS_PER_MILE;\n        case 'ft': return d / METERS_PER_FOOT;\n        default: return d;\n    }\n};\nexport const velocityToMs = (value: number, unit: string): number => {\n    switch (unit) {\n        case 'km/s': return value * METERS_PER_KM;\n        case 'mph': return value * (METERS_PER_MILE / HOUR);  // 1 mph = 0.44704 m/s\n        case 'ft/s': return value * METERS_PER_FOOT;  // 1 ft/s = 0.3048 m/s\n        default: return value;  // m/s\n    }\n};\n\nexport const velocityFromMs = (value: number, unit: string): number => {\n    switch (unit) {\n        case 'km/s': return value / METERS_PER_KM;\n        case 'mph': return value / (METERS_PER_MILE / HOUR);\n        case 'ft/s': return value / METERS_PER_FOOT;\n        default: return value;\n    }\n};\nexport const fromMps = (v: number, dist_unit: string, time_unit: string): number => {\n    const dist_conv: number = toMeters(1, dist_unit);\n    const time_conv: number = toSeconds(1, time_unit);\n    return v * (time_conv / dist_conv);\n};\n\n\n/**\n * Convert meters to pixels, based on Earth’s semi-major axis as 1 AU.\n * @param meters - distance in meters\n * @returns equivalent length in pixels\n */\nexport function toPixels(meters: number): number {\n    return (meters / AU_EARTH) * PIXELS_PER_AU;\n}\n\n/**\n * Convert gravitational parameter (m³/s²) to px³/s².\n * @param mu - gravitational parameter in m³/s²\n * @returns equivalent in px³/s²\n */\nexport function mu_m3(mu: number): number {\n    return mu * Math.pow(PIXELS_PER_METER, 3);\n}\n// Unit conversion constants\nexport const PIXELS_PER_AU: number = 130;                // px in 1 AU\nexport const METERS_PER_AU: number = AU_EARTH;\nexport const PIXELS_PER_METER: number = PIXELS_PER_AU / METERS_PER_AU;\nexport const MU_PER_PX: number = mu_m3(MU_SUN);\n\n\n\nexport const getObjUnits = (\n    sm_axis: number,\n    eccentricity: number\n) => {\n    const p: number = sm_axis * (1 - eccentricity ** 2);\n    const T: number = 2 * Math.PI * Math.sqrt(sm_axis ** 3 / MU_EARTH);\n    const n: number = 2 * Math.PI / T;\n    const apo: number = sm_axis * (1 + eccentricity);\n    return { p, T, n, apo };\n};\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/constants/planets.ts ===

'import type { BodyData } from \'./../../interfaces\';\n// Celestial bodies data\n\nexport const bodies: BodyData[] = [\n    { name: \'Sun\', m0_deg: 0, mu: 1.32712440018e20, a: 0, e: 0, radiusPx: 20, color: \'yellow\', radius: 696000000, escapeVel: 61770, n: 0, peri_lon_deg: 0 },\n    { name: \'Mercury\', m0_deg: 252.25032350, mu: 2.20320e13, a: 5.7909927e10, e: 0.20563593, radiusPx: 4, color: \'#a6a6a6\', radius: 2440000, escapeVel: 4300, n: 1, peri_lon_deg: 77.45779628 }, // Updated m0_deg to mean longitude L for consistency\n    { name: \'Venus\', m0_deg: 181.97909950, mu: 3.24859e14, a: 1.0820948e11, e: 0.00677672, radiusPx: 7, color: \'#e0c16b\', radius: 6052000, escapeVel: 10400, n: 2, peri_lon_deg: 131.60246718 },\n    { name: \'Earth\', m0_deg: 100.46457166, mu: 3.98600e14, a: 1.49598261e11, e: 0.01671123, radiusPx: 8, color: \'#4e6ef2\', radius: 6371000, escapeVel: 11200, n: 3, peri_lon_deg: 102.93768193 },\n    { name: \'Mars\', m0_deg: -4.55343205, mu: 4.28284e13, a: 2.2793664e11, e: 0.09339410, radiusPx: 6, color: \'#c1440e\', radius: 3390000, escapeVel: 5030, n: 4, peri_lon_deg: -23.94362959 },\n    { name: \'Jupiter\', m0_deg: 34.39644051, mu: 1.26687e17, a: 7.7841200e11, e: 0.04838624, radiusPx: 14, color: \'#d2a679\', radius: 71492000, escapeVel: 59500, n: 5, peri_lon_deg: 14.72847983 },\n    { name: \'Saturn\', m0_deg: 49.95424423, mu: 3.79312e16, a: 1.4267254e12, e: 0.05386179, radiusPx: 12, color: \'#e3c168\', radius: 60268000, escapeVel: 35500, n: 6, peri_lon_deg: 92.59887831 },\n    { name: \'Uranus\', m0_deg: 313.23810451, mu: 5.79394e15, a: 2.8706582e12, e: 0.04725744, radiusPx: 10, color: \'#7fbde8\', radius: 25559000, escapeVel: 21300, n: 7, peri_lon_deg: 170.95427630 },\n    { name: \'Neptune\', m0_deg: -55.12002969, mu: 6.83653e15, a: 4.4983964e12, e: 0.00859048, radiusPx: 10, color: \'#4363d8\', radius: 24764000, escapeVel: 23500, n: 8, peri_lon_deg: 44.96476227 }\n];\n\n// Fast lookup by name (case-insensitive)\nexport const bodyMap: { [key: string]: BodyData } = Object.fromEntries(\n    bodies.map(b => [b.name.toLowerCase(), b])\n);\nexport function isBodyData(x: any): x is BodyData {\n    return (\n        !!x &&\n        typeof x.name === \'string\' &&\n        typeof x.m0_deg === \'number\' &&\n        typeof x.mu === \'number\' &&\n        typeof x.a === \'number\' &&\n        typeof x.e === \'number\' &&\n        typeof x.radiusPx === \'number\' &&\n        typeof x.color === \'string\' &&\n        typeof x.radius === \'number\' &&\n        typeof x.escapeVel === \'number\' &&\n        typeof x.n === \'number\'\n    );\n}\n/**\n * Get a BodyData object by name (case-insensitive).\n * @param name - name of the body (e.g. \'earth\')\n * @returns BodyData or undefined if not found\n */\nexport function getBody(body: string | BodyData | number | undefined): BodyData | undefined {\n    if (typeof body === \'string\') {\n        body = bodyMap[body.toLowerCase()] as BodyData;\n    }\n    if (typeof body === \'number\' && body < bodies.length) {\n        body = bodies[body] as BodyData;\n    }\n    if (isBodyData(body)) {\n        return body as BodyData;\n    }\n\n}\nexport function getBodyIndex(name: string): number {\n    const idx = bodies.findIndex(b => b.name.toLowerCase() === name.toLowerCase());\n    if (idx < 0) throw new Error(`No body named "${name}"`);\n    return idx;\n}\nexport function getBodyMu(body: string | BodyData | number | undefined) {\n    let mu: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        mu = body.mu\n    }\n    return mu;\n}\nexport function getBodyRadius(body: string | BodyData | number | undefined) {\n    let radius: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        radius = body.radius\n    }\n    return radius\n}\nexport function getBodyName(body: string | BodyData | number | undefined) {\n    let name: string = \'\'\n    body = getBody(body) as BodyData;\n    if (body) {\n        name = body.name\n    }\n    return name;\n}\nexport function getBodyEccentricity(body: string | BodyData | number | undefined) {\n    let e: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        e = body.e\n    }\n    return e;\n}\nexport function getBodyAcceleration(body: string | BodyData | number | undefined) {\n    let a: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        a = body.a\n    }\n    return a;\n}\nexport function getBodyRadiusPx(body: string | BodyData | number | undefined) {\n    let radius: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        radius = body.radiusPx\n    }\n    return radius;\n}\nexport function getBodyN(body: string | BodyData | number | undefined) {\n    let n: number = 0\n    body = getBody(body) as BodyData;\n    if (body) {\n        n = body.n\n    }\n    return n\n}\nexport function getBodyColor(body: string | BodyData | number | undefined) {\n    let color: string = \'#555\'\n    body = getBody(body) as BodyData;\n    if (body) {\n        color = body.color\n    }\n    return color\n}\nexport function getVCirc(body: string | BodyData | number | undefined) {\n    let vCirc: any\n    const r = getBodyRadius(body);  // Change to physical radius\n    const mu = getBodyMu(body);\n    if (mu && r) {\n        vCirc = Math.sqrt(mu / r);\n    }\n    return vCirc\n}\n\n//sun\nexport const SUN_BODY: BodyData = getBody(\'sun\')!;\nexport const MU_SUN: number = SUN_BODY.mu;\nexport const AU_SUN: number = SUN_BODY.a;\n\n//earth\nexport const EARTH_BODY: BodyData = getBody(\'earth\')!;\nexport const MU_EARTH: number = EARTH_BODY.mu;\nexport const AU_EARTH: number = EARTH_BODY.a;        // meters in 1 AU\n\n\n\n'


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/constants/satellites.ts ===

"// satellites.ts\nimport { MU_EARTH } from './planets';\nimport type { BodyData } from './../../interfaces';\nimport { getObjUnits } from './scale_utils';\nimport { computeEccentricAnomaly } from './../functions/helperFunctions'\nexport const MU_MOON = 4.9048695e12; // m^3/s^2\nexport const satellites: BodyData[] = [\n    {\n        name: 'Moon',\n        m0_deg: 0,\n        mu: MU_MOON,              // <-- was MU_EARTH\n        a: 3.844e8,\n        e: 0.0549,\n        radiusPx: 5,\n        color: 'lightgray',\n        radius: 1.737e6,\n        escapeVel: 2380,\n        n: 9\n    },\n    {\n        name: 'ISS',\n        m0_deg: 0,\n        mu: MU_EARTH,\n        a: (6.371e6 + 417e3),\n        e: computeEccentricAnomaly(422e3, 413e3),\n        radiusPx: 2,\n        color: 'white',\n        radius: 0,           // negligible\n        escapeVel: 0,\n        n: 10\n    }\n];\n//moon\nexport const a_moon: number = 3.844e8;\nexport const e_moon: number = 0.0549;\nexport const {\n    p: p_moon,\n    T: T_moon,\n    n: n_moon,\n    apo: apo_moon\n} = getObjUnits(\n    a_moon,\n    e_moon);\n\n//iss\nexport const R_e: number = 6.371e6;\nexport const perigee: number = R_e + 413e3;\nexport const apogee: number = R_e + 422e3;\nexport const a_iss: number = (perigee + apogee) / 2;\nexport const e_iss: number = (apogee - perigee) / (perigee + apogee);\nexport const v_iss_mph: number = 24000;\nexport const {\n    p: p_iss,\n    T: T_iss,\n    n: n_iss,\n    apo: apo_iss\n} = getObjUnits(\n    a_iss,\n    e_iss\n);\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/orbit_utils.ts ===

"import React from 'react';\nimport type { BodyInit, OrbitState, BodyData, Accel, OrbitParams, State } from './../../interfaces';\nimport { MU_PER_PX, METERS_PER_AU, MU_SUN, MU_EARTH, bodies, SOFTENING, MAX_TRAIL_LENGTH, toMeters, toSeconds, R_e, getBodyN, getBody, getBodyMu } from './../constants';\nimport { getObjRefCurrent, getCurrentStateRef } from './stateFunctions'\nimport { deriveHillRadius, calculateAcceleration, calculateHalfDrift, calculateDrift } from './utilities'\nexport function initOrbit(\n  body: BodyInit,\n  cx: number,\n  cy: number\n): OrbitState {\n  const r_px = body.orbitRadiusM * METERS_PER_AU;\n  const v_px_s = Math.sqrt(MU_PER_PX / r_px);\n  return {\n    x: cx + r_px,\n    y: cy,\n    vx: 0,\n    vy: v_px_s\n  };\n}\n\nexport function stepOrbit(\n  state: OrbitState,\n  cx: number,\n  cy: number,\n  dt: number\n): OrbitState {\n  const dx = state.x - cx;\n  const dy = state.y - cy;\n  const dist = Math.hypot(dx, dy);\n  const a = -MU_PER_PX / (dist * dist);\n  const ax = a * (dx / dist);\n  const ay = a * (dy / dist);\n\n  const vx = state.vx + ax * dt;\n  const vy = state.vy + ay * dt;\n  const x = state.x + vx * dt;\n  const y = state.y + vy * dt;\n\n  return { x, y, vx, vy };\n}\n\nexport function checkCapture(probeRef, stateRef, runningRef) {\n  const pr = probeRef.current;\n  bodies.slice(1).forEach((planet, idx) => {\n    const s = stateRef.current[idx + 1];\n    const dx = pr.x - s.x, dy = pr.y - s.y;\n    const r = Math.hypot(dx, dy);\n    const Rsoi = deriveHillRadius(planet);\n    if (r < Rsoi) {\n      const dvx = pr.vx - s.vx, dvy = pr.vy - s.vy;\n      const vRel2 = dvx * dvx + dvy * dvy;\n      const escape2 = 2 * planet.mu / r;\n      if (vRel2 < escape2) {\n        console.log(`🚀 Probe captured by ${planet.name}`);\n\n      }\n    }\n  });\n}\n\n\n// Update probe using leapfrog integration\nexport const updateProbeoldd = (stateRef, probeRef, physicsDt, runningRef, trailRef) => {\n  const pr = getObjRefCurrent(probeRef);\n  const acc1 = calculateAcceleration(pr, getObjRefCurrent(stateRef), bodies);  // Pass bodies array instead of map(b => b.mu)\n  calculateHalfDrift(pr, acc1, physicsDt)\n  calculateDrift(pr, physicsDt)\n  const acc2 = calculateAcceleration(pr, getObjRefCurrent(stateRef), bodies);  // Pass bodies array instead of map(b => b.mu)\n  calculateHalfDrift(pr, acc2, physicsDt)\n\n  if (getObjRefCurrent(runningRef)) {\n    const trailRefCurrent = getObjRefCurrent(trailRef)\n    trailRefCurrent.push({ x: pr.x, y: pr.y });\n    if (trailRefCurrent.length > MAX_TRAIL_LENGTH) trailRefCurrent.shift();\n  }\n};\n\n\n\n// Update planets using leapfrog integration\nexport const updatePlanetss = (\n  stateRef: React.MutableRefObject<\n    Array<{ x: number; y: number; vx: number; vy: number; ax?: number; ay?: number }>\n  >,\n  physicsDt: number\n) => {\n  const S = stateRef.current;\n\n  // Zero out accelerations\n  S.forEach(s => {\n    s.ax = 0;\n    s.ay = 0;\n  });\n\n  // Accumulate pairwise gravitational acceleration\n  for (let i = 0; i < S.length; i++) {\n    for (let j = 0; j < S.length; j++) {\n      if (i === j) continue;\n      const si = S[i];\n      const sj = S[j];\n      const mu = bodies[j].mu;             // use gravitational parameter directly\n\n      const dx = sj.x - si.x;\n      const dy = sj.y - si.y;\n      const r2 = dx * dx + dy * dy;\n      if (r2 < 1e-6) continue;\n      const invR = 1 / Math.sqrt(r2);\n      const aMag = mu / r2;                // mu / r²\n\n      si.ax! += aMag * dx * invR;\n      si.ay! += aMag * dy * invR;\n    }\n  }\n\n  // Integrate velocities and positions (Euler)\n  S.forEach(s => {\n    s.vx += s.ax! * physicsDt;\n    s.vy += s.ay! * physicsDt;\n    s.x += s.vx * physicsDt;\n    s.y += s.vy * physicsDt;\n  });\n};\n\nexport function updatePlanetsoldd(\n  stateRef: React.MutableRefObject<Array<{ x: number; y: number; vx: number; vy: number }>>,\n  physicsDt: number\n) {\n  const S = stateRef.current;\n  const n = S.length;\n\n  // 1) compute initial accelerations\n  const accs = S.map((si, i) =>\n    calculateAcceleration(si, S, bodies)\n  );\n\n  // 2) half‐kick\n  for (let i = 0; i < n; i++) {\n    S[i].vx += accs[i].ax * (physicsDt / 2);\n    S[i].vy += accs[i].ay * (physicsDt / 2);\n  }\n\n  // 3) drift\n  for (let i = 0; i < n; i++) {\n    S[i].x += S[i].vx * physicsDt;\n    S[i].y += S[i].vy * physicsDt;\n  }\n\n  // 4) compute new accelerations\n  const accs2 = S.map((si, i) =>\n    calculateAcceleration(si, S, bodies)\n  );\n\n  // 5) half‐kick again\n  for (let i = 0; i < n; i++) {\n    S[i].vx += accs2[i].ax * (physicsDt / 2);\n    S[i].vy += accs2[i].ay * (physicsDt / 2);\n  }\n}\n\n\n\n/**\n * Compute the probe’s specific orbital energy relative to body at `bodyIdx`:\n *   ε = ½ v_rel² − μ / r\n * If ε < 0 → bound; ε = 0 → parabolic; ε > 0 → unbound.\n */\nexport function computeSpecificEnergy(\n  probeRef: React.MutableRefObject<State>,\n  stateRef: React.MutableRefObject<State[]>,\n  body: string | BodyData | number | undefined\n): number {\n  const pr = probeRef.current;\n  const bs = getCurrentStateRef(stateRef, body);\n\n  const μ = getBodyMu(body);\n\n  const dx = pr.x - bs.x;\n  const dy = pr.y - bs.y;\n  const dvx = pr.vx - bs.vx;\n  const dvy = pr.vy - bs.vy;\n\n  const r = Math.hypot(dx, dy);\n  const v2 = dvx * dvx + dvy * dvy;\n\n  return 0.5 * v2 - μ / r;\n}\n/**\n * Place the probe on the surface of `planetIdx` at angle `theta` (rad),\n * then give it a purely tangential kick of magnitude vLaunch (m/s).\n */\nexport function launchFromPlanet(\n  probeRef: React.MutableRefObject<State>,\n  stateRef: React.MutableRefObject<State[]>,\n  planet: string | BodyData | number,\n  vLaunch: number,\n  theta: number\n) {\n  const body = getBody(planet);\n  if (!body) return;\n  const idx = getBodyN(body);\n  const planetState = stateRef.current[idx];\n  const R = body.radius;\n\n  const x0 = planetState.x + R * Math.cos(theta);\n  const y0 = planetState.y + R * Math.sin(theta);\n\n  const ux = -Math.sin(theta);\n  const uy = Math.cos(theta);\n\n  const { vx: pvx, vy: pvy } = planetState;\n\n  probeRef.current = {\n    x: x0,\n    y: y0,\n    vx: pvx + vLaunch * ux,\n    vy: pvy + vLaunch * uy,\n  };\n}\nexport const computeUserOrbit = ({\n  angleDeg,\n  targetAlt,\n  altUnit,\n  targetVel,\n  velDistUnit,\n  velTimeUnit,\n}: {\n  angleDeg: number;\n  targetAlt: number;\n  altUnit: string;\n  targetVel: number;\n  velDistUnit: string;\n  velTimeUnit: string;\n}): OrbitParams => {\n  const φ = angleDeg * Math.PI / 180;\n  const r0 = R_e + toMeters(targetAlt, altUnit);\n  const v0 = toMeters(targetVel, velDistUnit) / toSeconds(1, velTimeUnit);\n  const hSpec = r0 * v0 * Math.cos(φ);\n  const ε = v0 * v0 / 2 - MU_EARTH / r0;\n\n  let a, e, p, n, M0;\n  if (ε < 0) {\n    a = -MU_EARTH / (2 * ε);\n    e = Math.sqrt(1 - hSpec * hSpec / (MU_EARTH * a));\n    p = a * (1 - e * e);\n    n = Math.sqrt(MU_EARTH / (a * a * a));\n    const θ0 = φ + Math.asin(Math.sin(φ) / e);\n    const E0 = 2 * Math.atan(Math.sqrt((1 - e) / (1 + e)) * Math.tan(θ0 / 2));\n    M0 = E0 - e * Math.sin(E0);\n  } else {\n    a = -MU_EARTH / (2 * ε);\n    e = Math.sqrt(1 + hSpec * hSpec / (MU_EARTH * Math.abs(a)));\n    p = a * (1 - e * e);\n    n = Math.sqrt(MU_EARTH / (-a * a * a));\n    const θ0 = φ + Math.asin(Math.sin(φ) / e);\n    const coshH0 = (e + Math.cos(θ0)) / (1 + e * Math.cos(θ0));\n    const H0 = Math.acosh(coshH0);\n    M0 = e * Math.sinh(H0) - H0;\n  }\n\n  return { a, e, p, n, M0 };\n};\n\nexport const computeMoonTransfer = (r1: number, r2: number, μ: number, v0: number) => {\n  const eps = v0 * v0 / 2 - μ / r1;\n  const a = -μ / (2 * eps);\n  const h = r1 * v0;\n  const e = Math.sqrt(1 - h * h / (μ * a));\n  const p = a * (1 - e * e);\n  const n = Math.sqrt(μ / Math.abs(a * a * a));\n  const cosθ2 = (p / r2 - 1) / e;\n\n  if (cosθ2 < -1 || cosθ2 > 1) {\n    return { timeSec: null, distMeters: 0, pivotRad: null };\n  }\n\n  const θ2 = Math.acos(cosθ2);\n  let M2;\n  if (eps < 0) {\n    const E2 = 2 * Math.atan(Math.sqrt((1 - e) / (1 + e)) * Math.tan(θ2 / 2));\n    M2 = E2 - e * Math.sin(E2);\n  } else {\n    const H2 = Math.log(\n      (Math.sqrt(e + 1) + Math.sqrt(e - 1) * Math.tan(θ2 / 2)) /\n      (Math.sqrt(e + 1) - Math.sqrt(e - 1) * Math.tan(θ2 / 2))\n    );\n    M2 = e * Math.sinh(H2) - H2;\n  }\n\n  const timeSec = M2 / n;\n  let distMeters = 0;\n  const steps = 200;\n  for (let i = 0; i <= steps; i++) {\n    const θ = θ2 * (i / steps);\n    const r = p / (1 + e * Math.cos(θ));\n    const drdθ = p * e * Math.sin(θ) / ((1 + e * Math.cos(θ)) ** 2);\n    const ds = Math.hypot(r, drdθ) * (θ2 / steps);\n    distMeters += ds;\n  }\n\n  const vCirc = Math.sqrt(μ / r1);\n  const ratio = Math.min(1, Math.max(-1, vCirc / v0));\n  const pivotRad = Math.acos(ratio);\n\n  return { timeSec, distMeters, pivotRad };\n};\n\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/draw_utils.ts ===

"import React from 'react'\nimport { getBody, getBodyName, getBodyMu, getBodyN, getBodyColor, getBodyAcceleration, PI2, bodies as BODIES, getBodyRadiusPx, PIXELS_PER_AU, MILISECOND } from './../constants';\nimport { BodyData } from './../../interfaces';\nimport { calculatePairwiseAcceleration, getCurrentStateRef } from './../functions';\n\n\n\nexport function drawGravityVectors(showVectors: any, probeRef: any, stateRef: any, ds: any, ctx: any) {\n\n    Object.keys(showVectors).forEach(sourceName => {\n        if (!showVectors[sourceName]) return;\n        const Body = getBody(sourceName);\n        const n = getBodyN(sourceName);\n        if (n < 0) return;\n        const sourceState = stateRef.current[n];\n        const maxMag = calculateAllAccels(showVectors, stateRef, probeRef, sourceState)\n        // For each target body (except source)\n        drawTargetBodyAndVelocityVectors(stateRef, sourceState, Body, maxMag, ds, ctx)\n        // For probe\n        drawProbeAndVelocityVectors(probeRef, sourceState, Body, maxMag, ds, ctx)\n    });\n}\nexport function getDefaultIfNull(obj: any, defaultValue: any = null) {\n    if (obj == null) {\n        obj = defaultValue;\n    }\n    return obj;\n}\n\nexport function getArc(\n    ctx: any,\n    x: number | null = null,\n    y: number | null = null,\n    r: number | null = null,\n    z: number | null = null,\n    pi: number | null = null\n) {\n    x = getDefaultIfNull(x, 0);\n    y = getDefaultIfNull(y, 0);\n    r = getDefaultIfNull(r, 0);\n    z = getDefaultIfNull(z, 0);\n    pi = getDefaultIfNull(pi, PI2);\n    ctx.arc(x, y, r, z, pi);\n}\n\nexport function getPlanetRadius(body: any, scale: number) {\n\n    return getBodyRadiusPx(body) / scale;\n}\n\nexport function ctxStrokeColor(body: any, ctx: any, color: any = null) {\n    color = color || getBodyColor(body);\n    ctx.strokeStyle = color;\n}\n\nexport function ctxLineWidth(ds: any, ctx: any) {\n    ctx.lineWidth = 1 / ds;\n}\n\nexport function drawOrbitsOld(ds: any, ctx: any, bodies: BodyData[] | null = null) {\n    bodies = bodies || BODIES;\n    bodies.slice(1).forEach(b => {\n        const a = getBodyAcceleration(b);\n        ctx.beginPath();\n        getArc(ctx, 0, 0, a, 0);\n        ctxStrokeColor(b, ctx, '#555');\n        ctxLineWidth(ds, ctx);\n        ctx.stroke();\n    });\n}\nexport function drawOrbits(ds: any, ctx: any, bodies: BodyData[] | null = null, showOrbits: { [name: string]: boolean }) {\n    bodies = bodies || BODIES;\n    bodies.slice(1).forEach(b => {\n        if (!showOrbits[b.name]) return;\n        const steps = 360; // For smoothness\n        ctx.beginPath();\n        for (let i = 0; i <= steps; i++) {\n            let theta = (i / steps) * 2 * Math.PI;\n            const r = b.a * (1 - b.e ** 2) / (1 + b.e * Math.cos(theta));\n            let x = r * Math.cos(theta);\n            let y = r * Math.sin(theta);\n            const rot = (b.peri_lon_deg ?? 0) * Math.PI / 180;\n            const xr = x * Math.cos(rot) - y * Math.sin(rot);\n            const yr = x * Math.sin(rot) + y * Math.cos(rot);\n            if (i === 0) ctx.moveTo(xr, yr);\n            else ctx.lineTo(xr, yr);\n        }\n        ctx.closePath();\n        ctxStrokeColor(b, ctx, '#555');\n        ctxLineWidth(ds, ctx);\n        ctx.stroke();\n    });\n}\nexport function drawPlanetTrails(trailRefs: React.MutableRefObject<{ x: number; y: number }[][]>, ds: any, ctx: any) {\n    trailRefs.current.forEach((trail, i) => {\n        if (i === 0 || trail.length < 2) return; // Skip Sun\n        ctx.beginPath();\n        trail.forEach((p, j) => {\n            j === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y);\n        });\n        ctx.strokeStyle = getBodyColor(BODIES[i]) + '80'; // Semi-transparent planet color\n        ctxLineWidth(ds, ctx);\n        ctx.stroke();\n    });\n}\n\nexport function drawBodies(s: any, body: any, ds: any, ctx: any, scale: number) {\n    const color = getBodyColor(body);\n    const radius = getPlanetRadius(body, scale);\n    ctx.beginPath();\n    getArc(ctx, s.x, s.y, radius / PI2);\n    ctx.fillStyle = color;\n    ctx.fill();\n}\n\nexport function drawProbeTrail(trailRef: any, ds: any, ctx: any) {\n    if (trailRef.current.length > 1) {\n        ctx.beginPath();\n        trailRef.current.forEach((p, i) => {\n            i === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y);\n        });\n        ctx.strokeStyle = 'rgba(255,255,255,0.5)';\n        ctxLineWidth(ds, ctx);\n        ctx.stroke();\n    }\n}\n\nexport function drawProbe(probeRef: any, ds: any, ctx: any) {\n    ctx.beginPath();\n    ctx.arc(probeRef.current.x, probeRef.current.y, 5 / ds, 0, 2 * Math.PI);\n    ctx.fillStyle = 'white';\n    ctx.fill();\n}\n\nexport function animateProbeAcceleration(probeRef: any, stateRef: any, setProbeAccels: any, bodies: BodyData[] | null = null) {\n    const accels: Array<{ name: string; ax: number; ay: number; mag: number }> = [];\n    bodies = bodies || BODIES;\n    for (let j = 0; j < bodies.length; j++) {\n        const acc = calculatePairwiseAcceleration(probeRef.current, stateRef.current[j], bodies[j].mu);\n        const mag = Math.hypot(acc.ax, acc.ay);\n        accels.push({ name: bodies[j].name, ax: acc.ax, ay: acc.ay, mag });\n    }\n    setProbeAccels(accels);\n}\n\nexport function drawBodiesAndVelocityVectors(showVectors: any, ds: any, ctx: any, stateRef: any, scale: number, bodies: BodyData[] | null = null) {\n    bodies = bodies || BODIES;\n    stateRef.current.forEach((s, i) => {\n        const name = getBodyName(i);\n        if (showVectors[name]) {\n            const vx = s.vx;\n            const vy = s.vy;\n            const vMag = Math.hypot(vx, vy);\n            if (vMag > 0) {\n                const vectorLenPx = 50;\n                const headLenPx = 10;\n                const len = vectorLenPx / ds;\n                const headLen = headLenPx / ds;\n                ctxStrokeColor(i, ctx);\n                ctxLineWidth(ds, ctx);\n                ctx.beginPath();\n                ctx.moveTo(s.x, s.y);\n                ctx.lineTo(s.x + (vx / vMag) * len, s.y + (vy / vMag) * len);\n                ctx.stroke();\n                const angle = Math.atan2(vy, vx);\n                [-Math.PI / 6, Math.PI / 6].forEach(theta => {\n                    ctx.beginPath();\n                    ctx.moveTo(s.x + (vx / vMag) * len, s.y + (vy / vMag) * len);\n                    ctx.lineTo(\n                        s.x + (vx / vMag) * len - headLen * Math.cos(angle + theta),\n                        s.y + (vy / vMag) * len - headLen * Math.sin(angle + theta)\n                    );\n                    ctx.stroke();\n                });\n            }\n        }\n        drawBodies(s, i, ds, ctx, scale);\n    });\n}\n\nexport function drawVelocityVector(\n    acc: { ax: number; ay: number },\n    aMag: number,\n    body: any,\n    ctx: CanvasRenderingContext2D,\n    ds: number,\n    pr: { x: number; y: number },\n    maxMag: number\n) {\n    const dirX = acc.ax / aMag;\n    const dirY = acc.ay / aMag;\n    const BASE_PX = 50;\n    const screenLen = (aMag / maxMag) * BASE_PX;\n    const simLen = screenLen / ds;\n    const headSim = (10 / ds);\n    ctxStrokeColor(body, ctx);\n    ctx.lineWidth = 1 / ds;\n    ctx.beginPath();\n    ctx.moveTo(pr.x, pr.y);\n    ctx.lineTo(pr.x + dirX * simLen, pr.y + dirY * simLen);\n    ctx.stroke();\n    const angle = Math.atan2(acc.ay, acc.ax);\n    [-Math.PI / 6, Math.PI / 6].forEach(theta => {\n        ctx.beginPath();\n        ctx.moveTo(pr.x + dirX * simLen, pr.y + dirY * simLen);\n        ctx.lineTo(\n            pr.x + dirX * simLen - headSim * Math.cos(angle + theta),\n            pr.y + dirY * simLen - headSim * Math.sin(angle + theta)\n        );\n        ctx.stroke();\n    });\n}\n\nfunction sphereOfInfluence(body: BodyData): number {\n    const sunMu = BODIES[0].mu;\n    return body.a * Math.pow(body.mu / sunMu, 0.4);\n}\n\nfunction drawInfluenceZones(ctx: CanvasRenderingContext2D, ds: number, stateRef: any) {\n    BODIES.slice(1).forEach((body, i) => {\n        const soi = sphereOfInfluence(body);\n        const s = stateRef.current[i + 1];\n        ctx.save();\n        ctx.beginPath();\n        ctx.arc(s.x, s.y, soi, 0, Math.PI * 2);\n        ctx.fillStyle = body.color + '33';\n        ctx.fill();\n        ctx.restore();\n    });\n}\n\nexport function calculateAllAccels(showVectors: any, stateRef: any, probeRef: any, sourceState: any) {\n    const allAccels = Object.entries(showVectors)\n        .filter(([name, on]) => on)\n        .flatMap(([name]) => {\n            const i = getBodyN(name);\n            if (i < 0) return [];\n            const sourceAccels = [...stateRef.current.map((s, j) => {\n                const acc = calculatePairwiseAcceleration(stateRef.current[j], sourceState, BODIES[i].mu);\n                return Math.hypot(acc.ax, acc.ay);\n            })];\n            return sourceAccels;\n        });\n    const maxMag = Math.max(...allAccels, 1e-6);\n    return maxMag;\n}\n\nexport function drawProbeAndVelocityVectors(objectRef: any, sourceState: any, body: any, maxMag: any, ds: any, ctx: any) {\n    const pr = objectRef.current;\n    const mu = getBodyMu(body);\n    const accProbe = calculatePairwiseAcceleration(pr, sourceState, mu);\n    const aMagProbe = Math.hypot(accProbe.ax, accProbe.ay);\n    if (aMagProbe > 0) {\n        drawVelocityVector(accProbe, aMagProbe, body, ctx, ds, pr, maxMag);\n    }\n}\n\nexport function drawTargetBodyAndVelocityVectors(objectRef: any, sourceState: any, body: any, maxMag: any, ds: any, ctx: any) {\n    objectRef.current.forEach((pr, targetIdx) => {\n        const mu = getBodyMu(body);\n        const sourceIdx = getBodyN(body);\n        if (targetIdx === sourceIdx) return;\n        const acc = calculatePairwiseAcceleration(pr, sourceState, mu);\n        const aMag = Math.hypot(acc.ax, acc.ay);\n        if (aMag === 0) return;\n        drawVelocityVector(acc, aMag, body, ctx, ds, pr, maxMag);\n    });\n}\n\nexport function drawProbeAccelerationVectors(probeRef: any, probeAccels: any, ds: any, ctx: any) {\n    if (probeAccels.length > 0) {\n        ctx.strokeStyle = 'red';\n        ctx.lineWidth = 2 / ds;\n        const maxMag = Math.max(...probeAccels.map(a => a.mag));\n        probeAccels.forEach(a => {\n            if (a.mag === 0) return;\n            const scaleLen = (a.mag / maxMag) * 50;\n            const dirX = a.ax / a.mag;\n            const dirY = a.ay / a.mag;\n            const dirX_sim = dirX * (scaleLen / ds);\n            const dirY_sim = dirY * (scaleLen / ds);\n            const endX = probeRef.current.x + dirX_sim;\n            const endY = probeRef.current.y + dirY_sim;\n            ctx.beginPath();\n            ctx.moveTo(probeRef.current.x, probeRef.current.y);\n            ctx.lineTo(endX, endY);\n            ctx.stroke();\n            const headLen = 5 / ds;\n            const angle = Math.atan2(dirY_sim, dirX_sim);\n            ctx.beginPath();\n            ctx.moveTo(endX, endY);\n            ctx.lineTo(endX - headLen * Math.cos(angle - Math.PI / 6), endY - headLen * Math.sin(angle - Math.PI / 6));\n            ctx.moveTo(endX, endY);\n            ctx.lineTo(endX - headLen * Math.cos(angle + Math.PI / 6), endY - headLen * Math.sin(angle + Math.PI / 6));\n            ctx.stroke();\n        });\n    }\n}\n\nexport const drawSimulation = (\n    canvasRef: React.RefObject<HTMLCanvasElement>,\n    zoomRef: React.MutableRefObject<number>,\n    trailRef: React.MutableRefObject<{ x: number; y: number }[]>,\n    probeRef: React.MutableRefObject<{ x: number; y: number; vx: number; vy: number }>,\n    stateRef: React.MutableRefObject<Array<{ x: number; y: number; vx: number; vy: number }>>,\n    probeAccels: Array<{ name: string; ax: number; ay: number; mag: number }>,\n    showVectors: { [name: string]: boolean },\n    scale: number,\n    pan: { x: number; y: number },\n    trailRefs: React.MutableRefObject<{ x: number; y: number }[][]>,\n    showOrbits: { [name: string]: boolean },\n    showSimTrails: any,\n    showActualTrails: any,\n    planetTrailsRef: any,\n    officialTrailsRef: any,\n    objectScale: any\n\n) => {\n    const c = canvasRef.current;\n    if (!c) return;\n    const ctx = c.getContext('2d');\n    if (!ctx) return;\n\n    const W = c.width, H = c.height;\n    const ds = scale * zoomRef.current;\n\n    ctx.setTransform(1, 0, 0, 1, 0, 0);\n    ctx.clearRect(0, 0, W, H);\n\n    // Center on Sun\n    ctx.translate(W / 2, H / 2);\n    ctx.scale(ds, ds);\n\n    drawOrbits(ds, ctx, null, showOrbits);\n    drawInfluenceZones(ctx, ds, stateRef);\n    drawPlanetTrails(trailRefs, ds, ctx);\n    drawProbeTrail(trailRef, ds, ctx);\n    drawBodiesAndVelocityVectors(showVectors, ds, ctx, stateRef, scale / objectScale);\n    drawProbe(probeRef, ds, ctx);\n    drawProbeAccelerationVectors(probeRef, probeAccels, ds, ctx);\n    drawGravityVectors(showVectors, probeRef, stateRef, ds, ctx);\n    // New: planet sim trails\n    BODIES.slice(1).forEach((b, i) => {\n        if (showSimTrails[b.name] && planetTrailsRef.current[i].length > 1) {\n            ctx.beginPath();\n            planetTrailsRef.current[i].forEach((p, j) => {\n                j === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y);\n            });\n            ctx.strokeStyle = `${b.color}80`; // Semi-transparent\n            ctxLineWidth(ds, ctx);\n            ctx.stroke();\n        }\n    });\n\n    // New: planet actual trails\n    BODIES.slice(1).forEach((b, i) => {\n        if (showActualTrails[b.name] && officialTrailsRef.current[i].length > 1) {\n            ctx.beginPath();\n            officialTrailsRef.current[i].forEach((p, j) => {\n                j === 0 ? ctx.moveTo(p.x, p.y) : ctx.lineTo(p.x, p.y);\n            });\n            ctx.strokeStyle = `${b.color}80`; // More transparent, or dashed: ctx.setLineDash([5/ds, 5/ds]);\n            ctxLineWidth(ds, ctx);\n            ctx.stroke();\n            ctx.setLineDash([]); // Reset if dashed\n        }\n    });\n};"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/utilities.ts ===

"import { MU_SUN, getBodyAcceleration, getBody, getBodyMu, SOFTENING, bodies as BODIES } from './../constants';\nimport type { PositionAndVelocity } from './../../interfaces';\nimport { BodyData } from '../../interfaces';\nimport { computeCurrentMeanAnomaly, computeEccentricAnomaly, computeTheta, computeInstantaneousOrbitalRadius, computeDistanceToApogee, computeThetas } from './helperFunctions';\n// Initialize simulation state with real-time positions and stable velocities\n\n\n//hill radius\nexport function computeHillRadius(\n    a: number,\n    mu: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    return a * Math.pow(mu / (3 * muCentral), 1 / 3);\n}\nexport function deriveHillRadius(\n    body: string | BodyData | number | undefined,\n    muCentral: number | null = null\n) {\n    const a = getBodyAcceleration(body)\n    const mu = getBodyMu(body)\n    return computeHillRadius(a, mu, muCentral);\n}\n\n\n// Calculate gravitational acceleration between two bodies\nexport const calculatePairwiseAcceleration = (target, other, mu, body?: BodyData) => {\n    const dx = other.x - target.x;\n    const dy = other.y - target.y;\n    const d2 = dx * dx + dy * dy + SOFTENING;\n    const r = Math.sqrt(d2 - SOFTENING);\n\n\n    const invR3 = 1 / (d2 * Math.sqrt(d2));\n    return { ax: mu * dx * invR3, ay: mu * dy * invR3 };\n};\n// Calculate total acceleration on a target due to all other bodies\nexport const calculateAcceleration = (target, others, bodiesList) => {  // Change muList to bodiesList: BodyData[]\n    let ax = 0, ay = 0;\n    for (let j = 0; j < others.length; j++) {\n        const acc = calculatePairwiseAcceleration(target, others[j], bodiesList[j].mu, bodiesList[j]);\n        ax += acc.ax;\n        ay += acc.ay;\n    }\n    return { ax, ay };\n};\n\n\n\n//half drift\nexport function calculateHalfDrift(\n    pr: any,\n    acc: any,\n    physicsDt: number\n) {\n    pr.vx += 0.5 * acc.ax * physicsDt;\n    pr.vy += 0.5 * acc.ay * physicsDt;\n    return pr\n}\nexport function deriveHalfDrift(\n    probeRef: any,\n    stateRef: any,\n    physicsDt: number,\n    bodies: any = null\n) {\n    const pr = probeRef.current;\n    const s = stateRef.current\n    bodies = bodies || BODIES\n    const acc = calculateAcceleration(pr, s, bodies);  // Pass bodies array instead of map(b => b.mu)\n    return calculateHalfDrift(pr, acc, physicsDt)\n}\n\n//drift\nexport function calculateDrift(\n    pr: any,\n    physicsDt: number\n) {\n    pr.x += pr.vx * physicsDt;\n    pr.y += pr.vy * physicsDt;\n    return pr\n}\nexport function deriveDrift(\n    probeRef: any,\n    physicsDt: number\n) {\n    const pr = probeRef.current;\n    return calculateDrift(pr, physicsDt)\n}\n\n//PositionAndVelocity\nexport const computePositionAndVelocity = (\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    time: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n): PositionAndVelocity => {\n    M0 = M0 || 0\n    const M = computeCurrentMeanAnomaly(n, time, M0)\n    let E = computeEccentricAnomaly(M, e)\n    const θ = computeTheta(e, E)\n    const r = computeInstantaneousOrbitalRadius(p, e, θ)\n    const v = computeOrbitalSpeed(r, a, muCentral)\n    const dist_to_apo = computeDistanceToApogee(e, a, r)\n    return { r, theta: θ, v, dist_to_apo };\n};\n\nexport function derivePositionAndVelocity(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const a = body.a;\n    const e = body.e || 0;\n    const p = deriveSemiLatusRectum(body)\n    const n = deriveMeanMotion(body, muCentral)\n    const { r, theta } = computePositionAndVelocity(a, e, p, n, timeElapsed, M0);\n    return { r, theta }\n}\n\n\n\n//OrbitalPeriod\nexport function computeOrbitalPeriod(\n    a: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const T = 2 * Math.PI * Math.sqrt((a ** 3) / muCentral);\n    return T\n}\nexport function deriveOrbitalPeriod(\n    body: BodyData,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const a = body.a\n    const T = computeOrbitalPeriod(a, muCentral)\n    return T\n}\n\n//MeanMotion\nexport function computeMeanMotion(\n    a: number,\n    muCentral: number | null = null\n) {\n    const T = computeOrbitalPeriod(a, muCentral)\n    const n = 2 * Math.PI / T;\n    return n\n}\nexport function deriveMeanMotion(\n    body: BodyData,\n    muCentral: number | null = null\n) {\n    const T = deriveOrbitalPeriod(body, muCentral)\n    const n = 2 * Math.PI / T;\n    return n\n}\n\n\n//Position\nexport function computePosition(\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    timeElapsed: number,\n    M0: number | null = 0\n) {\n    const { r, theta } = computePositionAndVelocity(a, e, p, n, timeElapsed, M0)\n    const { cosTheta, sinTheta } = computeThetas(theta)\n    const x = r * cosTheta;\n    const y = r * sinTheta;\n    return { x, y }\n\n}\nexport function derivePosition(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const { r, theta } = derivePositionAndVelocity(body, timeElapsed, M0, muCentral)\n    const { cosTheta, sinTheta } = computeThetas(theta)\n    const x = r * cosTheta;\n    const y = r * sinTheta;\n    return { x, y }\n\n}\n\n//SemiLatusRectum\nexport function computeSemiLatusRectum(\n    a: number,\n    e: number\n) {\n    const p = a * (1 - e * e); // a(1−e2)a(1−e2), the semi-latus rectum.\n    return p\n}\nexport function deriveSemiLatusRectum(\n    body: BodyData,\n) {\n    const a = body.a; //is its semi-major axis aa,\n    const e = body.e; // is its eccentricity ee.\n    const p = computeSemiLatusRectum(a, e)\n    return p\n}\n\n//OrbitalSpeed\nexport function computeOrbitalSpeed(\n    r: number,\n    a: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const v = Math.sqrt(muCentral * (2 / r - 1 / a)); //v = μ(2r−1a)μ(r2\u200b−a1\u200b) , the orbital speed from the vis-viva equation\n    return v\n}\nexport function deriveOrbitalSpeed(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const a = body.a; //is its semi-major axis aa,\n    muCentral = muCentral || MU_SUN\n    M0 = M0 || 0\n    const { r, theta } = derivePositionAndVelocity(body, timeElapsed, M0, muCentral)\n    const v = computeOrbitalSpeed(r, a, muCentral)\n    return v\n}\n\n//SpecificAngularMomentum\nexport function computeSpecificAngularMomentum(\n    p: number,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    const h = Math.sqrt(muCentral * p); // μ\u2009pμp \u200b, the specific angular momentum.\n    return h\n}\nexport function deriveSpecificAngularMomentum(\n    body: any,\n    muCentral: number | null = null\n) {\n    const p = deriveSemiLatusRectum(body)\n    const h = computeSpecificAngularMomentum(p, muCentral)\n    return h\n}\n\n//VelocityVector\nexport function computeVelocityVector(\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    muCentral = muCentral || MU_SUN\n    M0 = M0 || 0\n    const { r, theta } = computePositionAndVelocity(a, e, p, n, timeElapsed, M0);\n    const h = computeSpecificAngularMomentum(p, muCentral)\n    const { cosTheta, sinTheta } = computeThetas(theta)\n    const vx = -(h / r) * sinTheta; // components of the velocity vector in the orbital plane, given by vx=−hr\u2009sin\u2061θ\n    const vy = (h / r) * (e + cosTheta); // components of the velocity vector in the orbital plane, given by vy=hr\u2009(e+cos\u2061θ).\n    return { vx, vy }\n}\nexport function deriveVelocityVector(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const a = body.a; //is its semi-major axis aa,\n    const e = body.e; // is its eccentricity ee.\n    const p = deriveSemiLatusRectum(body)\n    //const v = deriveOrbitalSpeed(body, timeElapsed, muCentral, M0)\n    //const h = deriveSpecificAngularMomentum(body,muCentral)\n    const n = deriveMeanMotion(body, muCentral)\n    const { vx, vy } = computeVelocityVector(a, e, p, n, timeElapsed, M0, muCentral)\n    return { vx, vy }\n}\n\n//PositionAndVelocityVector\nexport function computePositionAndVelocityVector(\n    a: number,\n    e: number,\n    p: number,\n    n: number,\n    timeElapsed: number,\n    M0: number | null = 0,\n    muCentral: number | null = null\n) {\n    const { x, y } = computePosition(a, e, p, n, timeElapsed, M0)\n    // Compute velocity using vis-viva equation and correct orientation\n    const { vx, vy } = computeVelocityVector(a, e, p, n, timeElapsed, M0, muCentral)\n    return { x, y, vx, vy };\n}\n\nexport function derivePeriPositionAndVelocityVector(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number = 0,\n    muCentral: number | null = null\n) {\n    // In utilities.ts, inside computePositionAndVelocityVector\n    const peri_lon = body.peri_lon_deg\n    const periRad = peri_lon ?? 0;  // peri_lon in radians; convert deg to rad when passing\n    const cosPeri = Math.cos(periRad);\n    const sinPeri = Math.sin(periRad);\n    const { x, y } = derivePosition(body, timeElapsed, M0, muCentral)\n    // Rotate position\n    const x_rot = x * cosPeri - y * sinPeri;\n    const y_rot = x * sinPeri + y * cosPeri;\n    const { vx, vy } = deriveVelocityVector(body, timeElapsed, M0, muCentral)\n    // Rotate velocity\n    const vx_rot = vx * cosPeri - vy * sinPeri;\n    const vy_rot = vx * sinPeri + vy * cosPeri;\n\n    return { x: x_rot, y: y_rot, vx: vx_rot, vy: vy_rot };\n}\nexport function derivePositionAndVelocityVector(\n    body: BodyData,\n    timeElapsed: number,\n    M0: number | null = null,\n    muCentral: number | null = null\n) {\n    M0 = M0 || 0\n    if (body?.peri_lon_deg) {\n        M0 = ((body.m0_deg - body.peri_lon_deg + 360) % 360) * Math.PI / 180\n        return derivePeriPositionAndVelocityVector(body, timeElapsed, M0, MU_SUN)\n    }\n\n    const { x, y } = derivePosition(body, timeElapsed, M0, muCentral)\n    // Compute velocity using vis-viva equation and correct orientation\n    const { vx, vy } = deriveVelocityVector(body, timeElapsed, M0, muCentral)\n    return { x, y, vx, vy };\n}\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/helperFunctions.ts ===

'\nexport function computeThetas(theta: number) {\n    const cosTheta = Math.cos(theta);\n    const sinTheta = Math.sin(theta);\n    return { cosTheta, sinTheta }\n}\nexport function computeTheta(\n    e: number,\n    E: number\n) {\n    const θ = 2 * Math.atan2(\n        Math.sqrt(1 + e) * Math.sin(E / 2),\n        Math.sqrt(1 - e) * Math.cos(E / 2)\n    );\n    return θ\n}\nexport function computeInstantaneousOrbitalRadius(\n    p: number,\n    e: number,\n    θ: number\n) {\n    const r = p / (1 + e * Math.cos(θ));\n    return r\n}\nexport function computeCurrentMeanAnomaly(\n    n: number,\n    time: number,\n    M0: number\n) {\n    const M = (n * time + M0) % (2 * Math.PI);\n    return M\n}\nexport function computeNewtonRaphsonCorrection(\n    M: number,\n    e: number,\n    E: number\n) {\n    const dE = (M - E + e * Math.sin(E)) / (1 - e * Math.cos(E));\n    return dE;\n}\nexport function computeEccentricAnomaly(\n    M: number,\n    e: number\n) {\n    let E = M;\n    for (let i = 0; i < 50; i++) {\n        const dE = computeNewtonRaphsonCorrection(M, e, E)\n        E += dE;\n        if (Math.abs(dE) < 1e-9) break;\n    }\n    return E\n}\nexport function computeDistanceToApogee(\n    e: number,\n    a: number,\n    r: number\n) {\n    let dist_to_apo = 0;\n    if (e < 1) {\n        dist_to_apo = a * (1 + e) - r;\n    }\n    return dist_to_apo\n}\n'


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/index.ts ===

"export * from './draw_utils';\nexport * from './helperFunctions';\nexport * from './initialize_utils';\nexport * from './orbit_utils';\nexport * from './stateFunctions';\nexport * from './utilities';"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/initialize_utils.ts ===

"import React from 'react';\nimport { bodies } from './../constants'\nimport { derivePositionAndVelocityVector } from './utilities';\nimport { computeOfficialPositions } from './../astronomia_utils'\n// Initialize simulation state\nexport const initializeSimulation = (\n  startDate,\n  simOffset,\n  stateRef,\n  setSimTime,\n  probeRef,\n  trailRef,\n  lastTimeRef) => {\n  if (stateRef?.current) {\n    stateRef.current = bodies.map((b, i) => {\n      if (i === 0) return { x: 0, y: 0, vx: 0, vy: 0 };\n      const ω = Math.sqrt(bodies[0].mu / (b.a ** 3));\n      return { x: b.a, y: 0, vx: 0, vy: ω * b.a };\n    });\n    probeRef.current = { x: 2e11, y: 0, vx: 0, vy: 3e4 };\n    trailRef.current = [];\n    setSimTime(0);\n    lastTimeRef.current = performance.now();\n  }\n};\n/**\n * Re-initializes all planet & probe state at the chosen start date + offset.\n *\n * @param startDate  The calendar date chosen by the user\n * @param simOffset  Seconds of extra offset (can be negative) from startDate\n * @param stateRef   React ref for planet state array\n * @param setSimTime Setter for simTime (resets to zero)\n * @param probeRef   React ref for your probe object\n * @param trailRef   React ref for your probe trail\n * @param lastTimeRef React ref for performance.now() baseline\n */\nexport function initializeSimulationElapsed(\n  startDate: Date,\n  simOffset: number,\n  stateRef: React.MutableRefObject<any[]>,\n  setSimTime: React.Dispatch<React.SetStateAction<number>>,\n  probeRef: React.MutableRefObject<any>,\n  trailRef: React.MutableRefObject<any[]>,\n  lastTimeRef: React.MutableRefObject<number>,\n  planetTrailsRef?: React.MutableRefObject<any[]>, // Optional if not always present\n  officialTrailsRef?: React.MutableRefObject<any[]>,\n  simTimeRef?: React.MutableRefObject<number>\n) {\n  // 1) compute epoch of J2000 in seconds\n  const epochJ2000 = new Date('2000-01-01T12:00:00Z').getTime() / 1000;\n\n  // 2) compute your chosen start instant in seconds\n  const startEpochSec = (startDate.getTime() / 1000) + simOffset;\n\n  // 3) elapsed seconds since J2000\n  const timeElapsed = startEpochSec - epochJ2000;\n\n  // Use VSOP for initial positions\n  const initialPos = computeOfficialPositions(bodies.slice(1), startDate);\n\n  // Compute velocities via finite difference (small dt for accuracy)\n  const dt_sec = 1; // 1 second; small enough for derivative approximation\n  const futureDate = new Date(startDate.getTime() + dt_sec * 1000);\n  const futurePos = computeOfficialPositions(bodies.slice(1), futureDate);\n\n  stateRef.current = bodies.map((b, i) => {\n    if (i === 0) return { x: 0, y: 0, vx: 0, vy: 0 }; // Sun fixed at origin\n    const pos = initialPos[b.name];\n    const fpos = futurePos[b.name];\n    if (!pos || !fpos) {\n      // Fallback to Keplerian if VSOP fails (unlikely)\n      let M0: any = null\n      if (b?.m0_deg) {\n        M0 = b.m0_deg\n      }\n      const { x, y, vx, vy } = derivePositionAndVelocityVector(\n        b,\n        timeElapsed,\n        M0\n      )\n\n\n      return { x, y, vx, vy };\n    }\n    const vx = (fpos.x - pos.x) / dt_sec;\n    const vy = (fpos.y - pos.y) / dt_sec;\n    return { x: pos.x, y: pos.y, vx, vy };\n  });\n\n  // 5) reset probe & trail\n  probeRef.current = { x: 2e11, y: 0, vx: 0, vy: 3e4 };\n  trailRef.current = [];\n\n  // 6) reset simTime counter and timestamp\n  setSimTime(0);\n  lastTimeRef.current = performance.now();\n\n  // Reset trails if refs provided\n  if (planetTrailsRef) planetTrailsRef.current = bodies.slice(1).map(() => []);\n  if (officialTrailsRef) officialTrailsRef.current = bodies.slice(1).map(() => []);\n  if (simTimeRef) simTimeRef.current = 0;\n}\n\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/functions/stateFunctions.ts ===

"import { bodies as BODIES, getBodyN } from './../constants'\nimport type { Accel, BodyData } from './../../interfaces'\nexport function getMuList() {\n    return BODIES.map(b => b.mu)\n}\n\nexport function getObjRefCurrent(objRef) {\n    return objRef.current;\n}\nexport function getObjRefLength(objRef) {\n    const current = getObjRefCurrent(objRef)\n    return current.length;\n\n}\nexport function getObjRefAcc(objRef) {\n    const n = getObjRefLength(objRef)\n    const acc: Accel[] = Array(n).fill(0).map(_ => ({ ax: 0, ay: 0 }));\n    return acc\n}\n\nexport function getCurrentStateRef(stateRef: any, body: string | BodyData | number | undefined) {\n    let s: any\n    const planetIdx = getBodyN(body);\n    if (planetIdx != null) {\n        s = stateRef.current[planetIdx];\n    }\n    return s\n}"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/object/index.ts ===

"export * from './update_utils'\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/object/update_utils.ts ===

"import React from 'react';\nimport {\n    bodies,\n    getBody,\n    getBodyMu,\n    getBodyRadius,\n    getVCirc,\n    getBodyName,\n    getBodyAcceleration,\n    SOFTENING,\n    MU_SUN,\n    MAX_TRAIL_LENGTH,\n    DT\n} from './../constants';\nimport type { BodyData, PositionAndVelocity } from './../../interfaces';\nimport {\n    calculateAcceleration,\n    calculateHalfDrift,\n    deriveHalfDrift,\n    calculateDrift,\n    deriveDrift,\n    derivePositionAndVelocityVector,\n    computePositionAndVelocity,\n    derivePosition,\n    deriveOrbitalPeriod\n} from './../functions';\n\n// Update planets with leapfrog integration\n// Update planets with leapfrog integration\nexport function updatePlanets(\n    stateRef: React.MutableRefObject<{ x: number; y: number; vx: number; vy: number }[]>,\n    physicsDt: number,\n    trailRefs: React.MutableRefObject<{ x: number; y: number }[][]>,\n    trailTimers: React.MutableRefObject<number[]>\n) {\n    const s = stateRef.current;\n    const samplePoints = MAX_TRAIL_LENGTH; // Target number of points per orbit\n\n    // First half-drift\n    for (let i = 1; i < s.length; i++) { // Skip Sun (i=0)\n        s[i] = calculateHalfDrift(s[i], calculateAcceleration(s[i], s, bodies), physicsDt);\n    }\n\n    // Drift and trail update\n    for (let i = 1; i < s.length; i++) { // Skip Sun\n        s[i] = calculateDrift(s[i], physicsDt);\n\n        // Update trail timer and sample position\n        trailTimers.current[i] += physicsDt;\n        const T = deriveOrbitalPeriod(bodies[i], MU_SUN); // Orbital period in seconds\n        const sampleInterval = T / samplePoints; // Dynamic interval per planet\n\n        if (trailTimers.current[i] >= sampleInterval) {\n            const trail = trailRefs.current[i];\n            trail.push({ x: s[i].x, y: s[i].y });\n            // Limit trail to MAX_TRAIL_LENGTH (2000) instead of full orbit points\n            if (trail.length > MAX_TRAIL_LENGTH) {\n                trail.shift(); // Remove oldest point\n            }\n            trailTimers.current[i] -= sampleInterval; // Reset timer\n        }\n    }\n\n    // Second half-drift\n    for (let i = 1; i < s.length; i++) { // Skip Sun\n        s[i] = calculateHalfDrift(s[i], calculateAcceleration(s[i], s, bodies), physicsDt);\n    }\n}\n// Update probe\nexport function updateProbe(\n    stateRef: React.MutableRefObject<{ x: number; y: number; vx: number; vy: number }[]>,\n    probeRef: React.MutableRefObject<{ x: number; y: number; vx: number; vy: number }>,\n    physicsDt: number,\n    runningRef: React.MutableRefObject<boolean>,\n    trailRef: React.MutableRefObject<{ x: number; y: number }[]>\n) {\n    if (!runningRef.current) return;\n    let pr = probeRef.current;\n    deriveHalfDrift(probeRef, stateRef, physicsDt);\n    deriveDrift(probeRef, physicsDt);\n    deriveHalfDrift(probeRef, stateRef, physicsDt);\n    trailRef.current.push({ x: pr.x, y: pr.y });\n    if (trailRef.current.length > MAX_TRAIL_LENGTH) {\n        trailRef.current.shift();\n    }\n}\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/utilities/canvas_utils.ts ===

"export const drawSun = (\n  ctx: CanvasRenderingContext2D,\n  cx: number,\n  cy: number\n) => {\n  ctx.beginPath();\n  ctx.arc(cx, cy, 20, 0, 2 * Math.PI);\n  ctx.fillStyle = 'yellow';\n  ctx.fill();\n};\n\nexport const drawBody = (\n  ctx: CanvasRenderingContext2D,\n  x: number,\n  y: number,\n  radiusPx: number,\n  color: string\n) => {\n  ctx.beginPath();\n  ctx.arc(x, y, radiusPx, 0, 2 * Math.PI);\n  ctx.fillStyle = color;\n  ctx.fill();\n};\n"


――――――――――――――――――



=== /var/www/html/abstractendeavors/abstract_react/src/Components/charts/ellipse/src/functions/utilities/index.ts ===

"export * from './canvas_utils';\n"


――――――――――――――――――
"""
for section in texts.split('――――――――――――――――――'):
    if section:
        section = eatAll(section,[' ','\n','\t'])
        splLines = section.split('===')
        path = splLines[1][1:-1]
        contentLines = '==='.join(splLines[2:])
        contents = eatAll(contentLines,[' ','\n','\t'])
       
        quote = contents[0]
       
        if quote in ["'","'"]:
           
            for i,char in enumerate(reversed(contents)):
                
                if char == quote:
                    
                    contents = contents[1:-(i+1)]
                    break
        write_to_file(contents=contents[1:-1],file_path=path)
        



