@essrt/physics 1.6.0 → 1.8.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@essrt/physics",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "ESSRT (Expanding Solar System Resonance Theory) physics core \u2014 pure, injectable-constants, no I/O, no globals, no DOM. The complete model incl. fitted coefficients; every published version immutably ships one recorded model identity.",
5
5
  "essrt": {
6
6
  "modelVersion": "v11.0",
@@ -52,6 +52,7 @@
52
52
  "./deltat/recession-history": "./src/deltat/recession-history.cjs",
53
53
  "./climate/l1-orbital": "./src/climate/l1-orbital.cjs",
54
54
  "./eclipse/finders": "./src/eclipse/finders.cjs",
55
+ "./eclipse/sun-planetary-completion": "./src/eclipse/sun-planetary-completion.cjs",
55
56
  "./reference/published-curves": "./src/reference/published-curves.cjs",
56
57
  "./sun/longitude-correction": "./src/sun/longitude-correction.cjs"
57
58
  },
@@ -17,7 +17,7 @@
17
17
  */
18
18
 
19
19
  /** @type {string} */
20
- export const COEFFICIENTS_HASH = "bf011174cdd73175";
20
+ export const COEFFICIENTS_HASH = "17f2ead87bad401e";
21
21
 
22
22
  /** @type {Readonly<Record<string, unknown>>} */
23
23
  export const FITTED_COEFFICIENTS = Object.freeze({
@@ -37,7 +37,7 @@ export const FITTED_COEFFICIENTS = Object.freeze({
37
37
  MEEUS_DISTANCE_TERMS: {"meanKm":385000.56,"terms":[[0,0,1,0,-20905355],[2,0,-1,0,-3699111],[2,0,0,0,-2955968],[0,0,2,0,-569925],[0,1,0,0,48888],[0,0,0,2,-3149],[2,0,-2,0,246158],[2,-1,-1,0,-152138],[2,0,1,0,-170733],[2,-1,0,0,-204586],[0,1,-1,0,-129620],[1,0,0,0,108743],[0,1,1,0,104755],[2,0,0,-2,10321],[0,0,1,2,0],[0,0,1,-2,79661],[4,0,-1,0,-34782],[0,0,3,0,-23210],[4,0,-2,0,-21636],[2,1,-1,0,24208],[2,1,0,0,30824],[1,0,-1,0,-8379],[1,1,0,0,-16675],[2,-1,1,0,-12831],[2,0,2,0,-10445],[4,0,0,0,-11650],[2,0,-3,0,14403],[0,1,-2,0,-7003],[2,0,-1,2,0],[2,-1,-2,0,10056],[1,0,1,0,6322],[2,-2,0,0,-9884],[0,1,2,0,5751],[0,2,0,0,0],[2,-2,-1,0,-4950],[2,0,1,-2,4130],[2,0,0,2,0],[4,-1,-1,0,-3958],[0,0,2,2,0],[3,0,-1,0,3258],[2,1,1,0,2616],[4,-1,-2,0,-1897],[0,2,-1,0,-2117],[2,2,-1,0,2354],[2,1,-2,0,0],[2,-1,0,-2,0],[4,0,1,0,-1423],[0,0,4,0,-1117],[4,-1,0,0,-1571],[1,0,-2,0,-1739],[2,1,0,-2,0],[0,0,2,-2,-4421],[1,1,1,0,0],[3,0,-2,0,0],[4,0,-3,0,0],[2,-1,2,0,0],[0,2,1,0,1165],[1,1,-1,0,0],[2,0,3,0,0],[2,0,-1,-2,8752]]},
38
38
  MEEUS_LATITUDE_TERMS: [[0,0,0,1,5128122],[0,0,1,1,280602],[0,0,1,-1,277693],[2,0,0,-1,173237],[2,0,-1,1,55413],[2,0,-1,-1,46271],[2,0,0,1,32573],[0,0,2,1,17198],[2,0,1,-1,9266],[0,0,2,-1,8822],[2,-1,0,-1,8216],[2,0,-2,-1,4324],[2,0,1,1,4200],[2,1,0,-1,-3359],[2,-1,-1,1,2463],[2,-1,0,1,2211],[2,-1,-1,-1,2065],[0,1,-1,-1,-1870],[4,0,-1,-1,1828],[0,1,0,1,-1794],[0,0,0,3,-1749],[0,1,-1,1,-1565],[1,0,0,1,-1491],[0,1,1,1,-1475],[0,1,1,-1,-1410],[0,1,0,-1,-1344],[1,0,0,-1,-1335],[0,0,3,1,1107],[4,0,0,-1,1021],[4,0,-1,1,833],[0,0,1,-3,777],[4,0,-2,1,671],[2,0,0,-3,607],[2,0,2,-1,596],[2,-1,1,-1,491],[2,0,-2,1,-451],[0,0,3,-1,439],[2,0,2,1,422],[2,0,-3,-1,421],[2,1,-1,1,-366],[2,1,0,1,-351],[4,0,0,1,331],[2,-1,1,1,315],[2,-2,0,-1,302],[0,0,1,3,-283],[2,1,1,-1,-229],[1,1,0,-1,223],[1,1,0,1,223],[0,1,-2,-1,-220],[2,1,-1,-1,-220],[1,0,1,1,-185],[2,-1,-2,-1,181],[0,1,2,1,-177],[4,0,-2,-1,176],[4,-1,-1,-1,166],[1,0,1,-1,-164],[4,0,1,-1,132],[1,0,-1,-1,-119],[4,-1,0,-1,115],[2,-2,0,1,107]],
39
39
  MEEUS_LONGITUDE_TERMS: [[0,0,1,0,6288774],[2,0,-1,0,1274027],[2,0,0,0,658314],[0,0,2,0,213618],[0,1,0,0,-185116],[0,0,0,2,-114332],[2,0,-2,0,58793],[2,-1,-1,0,57066],[2,0,1,0,53322],[2,-1,0,0,45758],[0,1,-1,0,-40923],[1,0,0,0,-34720],[0,1,1,0,-30383],[2,0,0,-2,15327],[0,0,1,2,-12528],[0,0,1,-2,10980],[4,0,-1,0,10675],[0,0,3,0,10034],[4,0,-2,0,8548],[2,1,-1,0,-7888],[2,1,0,0,-6766],[1,0,-1,0,-5163],[1,1,0,0,4987],[2,-1,1,0,4036],[2,0,2,0,3994],[4,0,0,0,3861],[2,0,-3,0,3665],[0,1,-2,0,-2689],[2,0,-1,2,-2602],[2,-1,-2,0,2390],[1,0,1,0,-2348],[2,-2,0,0,2236],[0,1,2,0,-2120],[0,2,0,0,-2069],[2,-2,-1,0,2048],[2,0,1,-2,-1773],[2,0,0,2,-1595],[4,-1,-1,0,1215],[0,0,2,2,-1110],[3,0,-1,0,-892],[2,1,1,0,-810],[4,-1,-2,0,759],[0,2,-1,0,-713],[2,2,-1,0,-700],[2,1,-2,0,691],[2,-1,0,-2,596],[4,0,1,0,549],[0,0,4,0,537],[4,-1,0,0,520],[1,0,-2,0,-487],[2,1,0,-2,-399],[0,0,2,-2,-381],[1,1,1,0,351],[3,0,-2,0,-340],[4,0,-3,0,330],[2,-1,2,0,327],[0,2,1,0,-323],[1,1,-1,0,299],[2,0,3,0,294]],
40
- MOON_CORRECTION: {"raSinD":7.184453869061568e-7,"raCosD":0.000007773645658437624,"raSinMp":1.4279023255816577e-7,"raCosMp":-0.000016143853244117095,"raSinMs":0.00004290517368813111,"raCosMs":-0.000028078099681085273,"decSinD":-0.00001414309929430708,"decCosD":0.000007487034647903192,"decSinMp":0.000008568789356865513,"decCosMp":0.000010874252100847628,"decSinMs":-0.00002315228957457375,"decCosMs":0.0000057588397049875064},
40
+ MOON_CORRECTION: {"raSinD":9.271947210519989e-7,"raCosD":0.000008006404520924476,"raSinMp":1.1204039552952881e-7,"raCosMp":0.00015598691756074661,"raSinMs":0.000046466175922768945,"raCosMs":-0.000026863682640572646,"decSinD":-0.00001401592938296191,"decCosD":0.000008298627389693594,"decSinMp":0.000011200415554408102,"decCosMp":0.000012560894843740268,"decSinMs":-0.000022822668163376816,"decCosMs":0.0000058037429930742395},
41
41
  MOON_CORRECTION_RESIDUAL: {"raSinD":0.000002,"raCosD":0.000003,"raSinMp":-0.000027,"raCosMp":-0.001421,"raSinMs":-0.000036,"raCosMs":0.000028,"decSinD":0.000015,"decCosD":-0.000009,"decSinMp":0.000015,"decCosMp":-0.000026,"decSinMs":0.000024,"decCosMs":-0.000006},
42
42
  PARALLAX_DEC_CORRECTION: {"mercury":{"A":6.700037685778925,"B":-2.604777297599697,"C":-0.026739271604734192,"D":4.170737674287511,"E":4.256972915774902,"F":-0.9837125753048931,"G":-0.5459179709765268,"H":-0.053992515478549705,"I":0.023143692666321693,"J":0.021746675705011317,"K":0.28571768327922037,"L":-3.089311002323392,"M":-1.6663642767024116,"N":0.25418831641807943,"O":2.606777772734403,"P":-0.010100424363964897,"Q":0.03726592447513974,"R":-0.002729300126648922,"S":0.062387061685681006,"U":-2.6607036541323623,"V":0.3503036150720401,"W":-0.03616797705435646,"X":-0.014729393729958969,"Y":-0.0792572111579338,"Z":0.15270562809315788,"AA":-2.1397107842200627,"AB":0.10557056575192245,"AC":-0.001098525732448129,"AD":0.013715710359671571,"AE":-0.056268101871056235,"AF":0.01573636221706488,"AG":0.0016234811704477683,"AH":-0.3603882008620395,"AI":2.558062165328397,"AJ":0.003820632570230043,"AK":0.07903941196974806,"AL":0.009049744986616714,"AM":-0.017914059042993286,"AN":0.01724320827197873,"AO":-0.11535105228395143,"AP":-2.2572994703987312,"AQ":0.9567889703344088,"AR":-0.004696813017900493,"AS":-0.0026193472202396453,"AT":-0.000010797828781028959,"AU_":-0.00041799558764774123,"AV":0.005029552843565625,"AW":0.003314963327250127,"AX":-3.5974582779429767,"AY":-4.360019542498722,"AZ":-0.45796017511269216,"BA":0.16485081644244332,"BB":-0.22656901543235952,"BC":-0.1788918703619125,"BD":0.08509351845777446,"BE":0.09558021531104745,"BF":1.0802493099721011,"BG":-1.2902555451658506,"BH":-2.072526585665037,"BI":0.9965172237914703,"BJ":-1.088823764744844,"BK":1.7690212205490012,"BL":-0.0013193888792583657,"BM":0.00043079767298396404,"BN":-0.00436215106046169,"BO":-0.09345641418507068,"BP":0.005686595235084227,"BQ":0.6322717574035317,"BR":-2.264392968207422,"BS":3.5106057020508086,"BT":-0.1952986710019841,"BU":-0.07562379671355761,"BV":0.02683811332039621,"BW":-1.4578195939898249,"BX":0.2141653674834016,"BY":0.03209512498487983,"BZ":2.1800655351271003,"CA":0.011162980042946987},"venus":{"A":18.438800016384782,"B":14.608954618140798,"C":0.0008079771962658688,"D":-2.099209192614694,"E":-0.7344906188407444,"F":-0.6883273982431268,"G":1.058351790796272,"H":-0.002719745099518921,"I":0.006043575552687459,"J":0.010242561383047874,"K":0.07393613081649943,"L":-27.889246915549187,"M":-12.998695793466156,"N":0.9377871220324304,"O":3.8951604470187586,"P":0.004294685353400707,"Q":-0.0001418284193126508,"R":-0.012110615490255838,"S":-0.002688169726960245,"U":0.15286475346056108,"V":10.54015504119257,"W":-0.7824560800435445,"X":0.22757894714263888,"Y":-0.07851822456479952,"Z":-10.735720913524647,"AA":2.461587355763489,"AB":-0.5941578063716758,"AC":-0.00007629820237624609,"AD":0.001404509614641589,"AE":-0.4635888531183637,"AF":0.06116874926391816,"AG":-0.1804322461685143,"AH":-2.04691075320088,"AI":8.826462018604063,"AJ":-0.00006079692116666415,"AK":0.06827499162658916,"AL":0.006045937071520336,"AM":-0.003212011279856513,"AN":0.007797741417579499,"AO":-0.01472212674100526,"AP":0.2273825498882576,"AQ":-0.024932413572228137,"AR":0.00012580318191020192,"AS":-0.00008550960090862308,"AT":-0.00003619035392638591,"AU_":0.00008590036605263681,"AV":-0.0001304757905080779,"AW":0.00006326802404791136,"AX":0.20691535853066376,"AY":-0.551533998425989,"AZ":-0.6835565055552159,"BA":-0.2426476425999497,"BB":-0.09046808534931959,"BC":-0.019881979589216385,"BD":0.04049953047043522,"BE":0.017829362666402903,"BF":-0.09100120479638729,"BG":-0.3861164878375928,"BH":0.01974990671258103,"BI":0.008551676945564128,"BJ":-0.11909854115393763,"BK":0.28027884158093225,"BL":0.0003992433854618241,"BM":0.00031983926671100055,"BN":-0.00006109233078572129,"BO":-0.011044474851733075,"BP":-0.003392487650390541,"BQ":-0.02258764781406311,"BR":-0.3669570679260029,"BS":-0.5649383091343524,"BT":0.10088926125002406,"BU":-0.05705364594341064,"BV":-0.16396762845326374,"BW":-0.09004008861182801,"BX":0.004241959291894234,"BY":0.026686186359608084,"BZ":0.1419237051403289,"CA":-0.0025140445949467247},"mars":{"A":28.815415092841405,"B":9.884280701390434,"C":-0.01207602288784132,"D":2.791932638869104,"E":0.4103518763591426,"F":-0.7930137620327851,"G":-0.4811605119390412,"H":-0.03206366922767504,"I":-0.18727977056408004,"J":-0.027099162864854715,"K":0.058456467742403054,"L":-92.90304465302425,"M":3.8461478923327506,"N":-1.2997477476003807,"O":-2.2484297798144164,"P":-0.08895741462328964,"Q":-0.04975467364495583,"R":0.0006002409987542177,"S":0.08452228635165193,"U":-0.15312457452312617,"V":74.05643378992663,"W":1.2721507579703994,"X":0.3761178289618893,"Y":0.3745108220477574,"Z":-15.52892231831707,"AA":-8.087636028130966,"AB":0.8004994953666502,"AC":0.02342590666454258,"AD":0.06615971093164369,"AE":2.8500954387137534,"AF":-0.582749638016733,"AG":-0.517735388694119,"AH":3.2912266836563417,"AI":-2.4863583704637304,"AJ":0.03091188482033274,"AK":1.0512276104548886,"AL":0.004127121259076039,"AM":-0.006922773182275047,"AN":0.01992730249563062,"AO":-0.01649245749745051,"AP":-0.9087834954069749,"AQ":0.01035064959690267,"AR":0.000840062214109013,"AS":-0.0008614979805971351,"AT":0.00016409266018561775,"AU_":0.0003464940215982185,"AV":-0.0013100559793906878,"AW":0.0011903323947371656,"AX":0.23230111864205277,"AY":-0.4884668898741724,"AZ":-0.13019794267737045,"BA":0.2579834377082836,"BB":-0.001039307776917545,"BC":0.009859586891119064,"BD":-0.006903823799784434,"BE":-0.009397345815513975,"BF":-0.06096561757551176,"BG":-0.042927055194389066,"BH":0.02971246769002293,"BI":0.026966836066213192,"BJ":-0.19865214348748256,"BK":0.08560298386719924,"BL":0.00270870026499547,"BM":0.009791857130244625,"BN":-0.008261079084784122,"BO":-0.16536385684325475,"BP":-0.0019712759186671903,"BQ":0.13108565872057448},"jupiter":{"A":-86.18652456602464,"B":357.6235433339336,"C":0.0020937642127950838,"D":177.65201160476448,"E":21.14986193430207,"F":3.6946862263108065,"G":6.322505373074678,"H":0.36727311871046614,"I":-0.14377975079858044,"J":0.25906310398472937,"K":-0.05553556943521053,"L":548.2953168203015,"M":262.54664621892323,"N":-3.0049409291366835,"O":31.459722325341726,"P":0.009767706724090205,"Q":-0.09153370866548584,"R":-0.362325720027099,"S":0.10455804182558602,"U":-67.76958322466986,"V":-536.6953725032831,"W":449.8709923950208,"X":0.7888228591415766,"Y":-1.2571940509535724,"Z":-1845.0146232508255,"AA":-2209.59983058046,"AB":-23.46392307894978,"AC":-0.001373942504895614,"AD":0.49637234241612216,"AE":-2.8696854394888627,"AF":4.343274145670834,"AG":-3.560442697533569,"AH":-220.74360461052734,"AI":6278.811306729325,"AJ":-0.04000230276838313,"AK":-32.65840284797526,"AL":0.010810383430527341,"AM":0.03412817469074218,"AN":-1.7771451697438272,"AO":0.31229420636890726,"AP":-4187.69134519847,"AQ":86.76104012054923,"AR":0.004278570861778165,"AS":-0.016828428270072786,"AT":-0.003480478227383403,"AU_":-0.0033527770015614636,"AV":-0.057603411366513015,"AW":0.1385292751536785,"AX":-6.149518335371986,"AY":-2.197321161259289,"AZ":0.8476998564796648,"BA":0.44641090174888737,"BB":-0.020433403444870456,"BC":-0.0009423322991206785,"BD":0.001220251155825309,"BE":0.0009706709578882608,"BF":-0.3510753327748172,"BG":-2.545239392361982,"BH":44.87342178479444,"BI":-10.570270320704969,"BJ":-0.648503749688652,"BK":-0.31554942629714033,"BL":-0.009225743874744528,"BM":-0.024108845926181302,"BN":-0.009240103578699975,"BO":-5.299723722249408,"BP":-30.68150094063025,"BQ":4628.416005672514},"saturn":{"A":-207.25542199002246,"B":-3157.986249085314,"C":0.0018054630776403635,"D":-71.54884222535226,"E":-275.7460610105105,"F":17.19797684583906,"G":5.239868539469993,"H":-1.5082151664112666,"I":4.159245862828977,"J":10.182677750713726,"K":-1.822798266289854,"L":5985.778041590761,"M":16927.209147519312,"N":-18.278312493637742,"O":-1.2133262756127663,"P":-0.24324377112448198,"Q":-0.08705948534301343,"R":-7.792074798933607,"S":-0.10739008591863759,"U":939.0875804640182,"V":-38270.65600508662,"W":3131.27352700526,"X":1.0880522843054958,"Y":-6.9860283742682165,"Z":30084.949545440675,"AA":-12988.473050238777,"AB":-57.72634767013708,"AC":0.21399154655902344,"AD":-14.339906039497595,"AE":5.669843100249634,"AF":67.57888931114057,"AG":-28.567497772384456,"AH":1116.2993625010433,"AI":50714.90499609082,"AJ":-0.021984818354376184,"AK":1811.0396176990175,"AL":-0.244905515418467,"AM":0.02091525287029858,"AN":-24.225497262471414,"AO":19.18409464773167,"AP":-146987.67458752787,"AQ":-419.71962759249885,"AR":0.00528995218134993,"AS":0.007354987463046254,"AT":0.7204971030843809,"AU_":0.9356952710673667,"AV":0.04924228069831819,"AW":-0.2151058415169218,"AX":19.96382244586338,"AY":0.11700603418006138,"AZ":-0.625788601694214,"BA":-0.1670708956511064,"BB":0.22267125477941652,"BC":0.6949407216191301,"BD":-0.02825297676233263,"BE":-0.0907567160134372,"BF":8.207379751758793,"BG":3.90578362634002,"BH":-636.4658219577055,"BI":118.87821890657695,"BJ":-12.604999356840958,"BK":-1.4799209042837433,"BL":0.10692631778470216,"BM":-0.08565571459659248,"BN":0.36932009703035507,"BO":-1445.7139269539662,"BP":-55.59635683231884,"BQ":357518.22501006647},"uranus":{"A":306.2166925388946,"B":-5255.526222295014,"C":-0.0046203363456736365,"D":345.66141807281065,"E":-489.22603782608996,"F":69.31803628729722,"G":-8.16330810057621,"H":2.8136869430397424,"I":-31.885649700995433,"J":7.04723982411388,"K":-1.409444631898979,"L":-6704.759710522734,"M":-58615.85209718142,"N":-97.57034903925486,"O":587.741295514298,"P":0.09205103982793686,"Q":0.2896474532722344,"R":-3.4995977709394106,"S":-0.2881627967456984,"U":10366.238174871332,"V":14963.14401979186,"W":-4591.770402638542,"X":30.757162064745344,"Y":-19.143689497389587,"Z":101714.89948123854,"AA":35775.48040091958,"AB":321.2267821106437,"AC":0.093919590733212,"AD":244.09886679895655,"AE":1782.5959285005154,"AF":305.182785987962,"AG":-237.19874153881955,"AH":-8614.549633991248,"AI":-476462.52575453866,"AJ":0.04532037723072073,"AK":-35271.37949546775,"AL":-0.2655084496610414,"AM":0.2760412017639621,"AN":-65.97183494937308,"AO":25.342186193927137,"AP":1180681.5133036529,"AQ":-68871.76138369141,"AR":-0.00959177626350222,"AS":0.0035021872237666262,"AT":-0.0008298702852194759,"AU_":-0.0012741694157979433,"AV":0.24727681839907503,"AW":-0.07860593850504717,"AX":84.21554688087404,"AY":-25.480013894251996,"AZ":-2.913305088913732,"BA":1.0533488134302693,"BB":-0.030073456632227383,"BC":0.0696373820721673,"BD":0.0015702468077155825,"BE":-0.003242039061010034,"BF":-8.894127486344686,"BG":9.790747628258188,"BH":-10224.51700149402,"BI":1717.4428192202624,"BJ":-55.01285473534335,"BK":19.453453804892224,"BL":0.06129223339384178,"BM":0.1640600811159042,"BN":-0.051167129890705536,"BO":14328.774614047079,"BP":-2430.99062430001,"BQ":-5924811.938712782},"neptune":{"A":1771.8032907795593,"B":-14252.402813793931,"C":-0.003305205940586913,"D":-1761.31141804805,"E":-99.57761078069841,"F":4.895820481575424,"G":12.192458610327632,"H":-0.7107948946900113,"I":8.082830475966176,"J":19.165469843732385,"K":2.4686144024202887,"L":-93920.94415451893,"M":43954.56189430981,"N":21.521251067054457,"O":674.2562128927834,"P":0.10189056807865449,"Q":0.0008395650212050576,"R":-9.774170648123551,"S":0.15668602366867135,"U":2286.3989222572045,"V":1217195.597974617,"W":1488.7213911701458,"X":8.89430840413938,"Y":-7.1442756840528885,"Z":433325.47554134537,"AA":29534.598295333893,"AB":-520.591372689882,"AC":-0.008156816156283463,"AD":-148.58557016257825,"AE":-659.5992267737988,"AF":230.03129419117454,"AG":-365.03444815710066,"AH":-19014.772161467212,"AI":142380.75998446197,"AJ":0.08817846566087975,"AK":-11492.82914202538,"AL":-0.09130570342787159,"AM":-0.051881750871522386,"AN":-292.2971853624466,"AO":-43.767841141243906,"AP":-1056908.7671557555,"AQ":-16942.209004211865,"AR":-0.004112316513788364,"AS":-0.007307630378566316,"AT":-0.0007429920635838918,"AU_":-0.000600934792309428,"AV":0.12825454729794317,"AW":0.21965103139418243,"AX":150.3703474341384,"AY":-26.68004052738075,"AZ":-3.033240718479064,"BA":0.4787693370908318,"BB":0.46411327300388316,"BC":1.1146309094225062,"BD":-0.016636860173701654,"BE":-0.03609760280806461,"BF":14.532825725889316,"BG":11.374381265330227,"BH":-52905.05869812508,"BI":11338.080230262934,"BJ":-169.173813220467,"BK":-145.41541324964123,"BL":0.007477417612765949,"BM":-0.05979203121866853,"BN":-0.047905259094758394,"BO":4448.123612004437,"BP":1292.1976394067697,"BQ":7912667.175246304}},
43
43
  PARALLAX_RA_CORRECTION: {"mercury":{"A":-1.2624661944404456,"B":2.6863112964811555,"C":0.19575700670599372,"D":-2.906214372624309,"E":-13.183777476009693,"F":-1.2180916153815395,"G":-0.8640617767581873,"H":0.12792930667825467,"I":0.03227588609527135,"J":-0.2614441573297094,"K":0.0813706723988613,"L":0.7312264539806415,"M":-9.028189319495453,"N":0.5103044840562379,"O":2.5947028252873223,"P":-0.0011061272831027781,"Q":0.0026771852807334798,"R":0.08110117560533142,"S":-0.19970095478281985,"U":5.845776077338316,"V":-0.1819329696344311,"W":-0.02297359350171375,"X":-0.017793525110268518,"Y":-0.07073166874135262,"Z":-0.131144620913566,"AA":2.4049488954965663,"AB":0.02312942157097053,"AC":-0.001815267755801757,"AD":-0.08646223914620331,"AE":-0.10605221507307847,"AF":0.014176992720252971,"AG":-0.0018518882002530785,"AH":-0.23227240130494892,"AI":-1.8584736053689146,"AJ":0.00033071851843363204,"AK":0.10703308915509917,"AL":0.021117630528532053,"AM":-0.0020926302754887337,"AN":0.11402665517998929,"AO":0.028869251348623597,"AP":7.493223593613009,"AQ":-1.2848749659356948,"AR":-0.0002472708723020921,"AS":-0.0007520361087863282,"AT":0.00028285303284495225,"AU_":0.00007830465356395358,"AV":0.00043905701110399963,"AW":0.000030668476535772714,"AX":2.809662919126381,"AY":0.3395118582976892,"AZ":-2.0146288672748147,"BA":-0.8674099628784465,"BB":0.09444159083646869,"BC":-0.0509340549868202,"BD":-0.06294452834207123,"BE":0.07698670836236542,"BF":1.4314664253594007,"BG":0.8456060562208395,"BH":3.1114864598301035,"BI":-2.5273848552692044,"BJ":1.8826905326228083,"BK":-1.8937022812931974,"BL":0.002043144539970173,"BM":0.0023408884768942604,"BN":-0.006908276519306399,"BO":0.03760087960015646,"BP":-0.04473713469772564,"BQ":-1.8183627524087906,"BR":4.344833459503872,"BS":-0.3981990114435509,"BT":0.09208934873202747,"BU":-0.6484727714741892,"BV":-2.377848461827422,"BW":-2.3953813293357498,"BX":0.007139052657126929,"BY":0.6973719954377928,"BZ":-4.007098727234658,"CA":1.5389669622637028},"venus":{"A":10.50180347250677,"B":1.6115507337982637,"C":0.12185709341476718,"D":1.1758841091890726,"E":-0.7649730097576236,"F":-0.07215690418722387,"G":-0.398766576146737,"H":-0.007515629288774714,"I":-0.022241294442672293,"J":-0.02071654492347299,"K":0.0034877949658192295,"L":-13.778337303151831,"M":-4.480745161542748,"N":0.3768400801561066,"O":-6.682544300441005,"P":-0.014062167588977966,"Q":-0.002160631706046572,"R":0.02530711510244273,"S":-0.10681418878344617,"U":0.1278651702981844,"V":4.7834793377922376,"W":0.10339239447001473,"X":0.36107129913309954,"Y":-0.16824077814261063,"Z":-1.1781573409518307,"AA":-0.6191557143693847,"AB":0.3657449749621167,"AC":0.013506171106224629,"AD":0.006535983791757687,"AE":-0.24492625223162162,"AF":0.15813870861003546,"AG":-0.21103229643702465,"AH":2.2920895768532272,"AI":3.196608342781668,"AJ":0.002626639693720725,"AK":0.0033245057317207857,"AL":0.0002834456066981897,"AM":-0.001858688577820034,"AN":0.004247204764438588,"AO":-0.0005739864534293679,"AP":0.02101581333161604,"AQ":-0.01927172118418605,"AR":-0.00011558099580428654,"AS":-0.00014016776694747272,"AT":0.00011310674528782863,"AU_":0.0001836067642771059,"AV":0.00017187572180364394,"AW":0.00021962843962826457,"AX":5.10541971519483,"AY":1.5720976420767618,"AZ":-0.3084782670186565,"BA":-0.5180162049692704,"BB":-0.02427784127176867,"BC":0.00021199114247581863,"BD":-0.0035983194891761163,"BE":0.020257837512199114,"BF":-0.07917686513874839,"BG":-0.05795498421080915,"BH":0.011687250453595003,"BI":0.009824807249740627,"BJ":-0.04078556662918309,"BK":0.05666414267413859,"BL":-0.0009259942886187582,"BM":-0.00023647678040071045,"BN":-0.00005945994114116887,"BO":-0.0005820232309831,"BP":-0.0019539654949732484,"BQ":-0.001990422791593072,"BR":3.6928642028111174,"BS":-0.07211090488449633,"BT":-0.0024606848227019247,"BU":-0.01984783372235677,"BV":0.29230787240708733,"BW":0.1127790650584296,"BX":0.005033938198234437,"BY":0.007923151363615905,"BZ":-0.007388036841373295,"CA":0.11404401396464135},"mars":{"A":-8.580986429873457,"B":15.49165293812389,"C":0.0011987799709545627,"D":-3.1259851251623383,"E":0.8042905119150386,"F":-0.30223245812324434,"G":-2.0865237383503223,"H":0.015426850513707848,"I":0.4858971082527013,"J":0.045106616637330704,"K":0.09012242229014977,"L":18.323531127246557,"M":-1.5343993879795765,"N":2.256232344156873,"O":8.441999827673003,"P":0.011853883301550867,"Q":0.013972237923754741,"R":-0.3135911673778576,"S":0.062341564452407905,"U":-1.0927645981918732,"V":-6.777516533617324,"W":-0.8769035394654608,"X":-0.4515251588414861,"Y":-1.0813794435457127,"Z":-23.390310027364656,"AA":3.3141135108066484,"AB":3.3562129703387296,"AC":0.0015402221882144494,"AD":-0.26759616582564216,"AE":-3.4732825791782322,"AF":1.7493971043601058,"AG":0.36176246962094394,"AH":-12.86902342505569,"AI":3.9721205303775515,"AJ":-0.05010506219687092,"AK":-0.3102618922894082,"AL":-0.02967004498312139,"AM":0.0023998603195846437,"AN":-0.11525214514447422,"AO":-0.02449312244143661,"AP":-0.6216826355034938,"AQ":0.3640245286851739,"AR":-0.0009440995968233166,"AS":0.00016329967317982752,"AT":-0.00008658951717735545,"AU_":0.0003000651984207248,"AV":0.0008197248367158941,"AW":0.00045491366212074683,"AX":0.2827597091212645,"AY":-0.5330427400964823,"AZ":-0.14216440815591483,"BA":-0.5227113193192159,"BB":0.07175726137582543,"BC":-0.13325433351455374,"BD":-0.010785499917757723,"BE":0.014235010813465258,"BF":0.422333743006821,"BG":0.2114651193149289,"BH":0.12663842379169893,"BI":0.12045288021315569,"BJ":0.39706016740546574,"BK":-0.019264175627156054,"BL":0.00043441408973849625,"BM":0.0016866941779158967,"BN":0.008212205291256129,"BO":0.1773240958172119,"BP":0.013141419801377357,"BQ":0.10502421715430374},"jupiter":{"A":73.60705538660548,"B":-51.18396067077931,"C":-0.012683639847400592,"D":-145.87580668034548,"E":6.750795411188141,"F":-4.323395174585395,"G":-7.17280223703923,"H":-0.005547524124380607,"I":-1.448418887675968,"J":-0.12297365100675876,"K":0.13608142693151346,"L":-797.4143594464567,"M":153.74845501657802,"N":9.052512971723086,"O":25.032372779053553,"P":-0.07956597309321006,"Q":0.10571521352013931,"R":-0.34173163707410664,"S":1.2571237679122806,"U":-24.877301214036965,"V":2160.5373778443923,"W":-112.20505702801353,"X":0.23472087611186773,"Y":-0.17270004920469942,"Z":255.86751556232525,"AA":1245.0548169246738,"AB":31.589358879691865,"AC":0.05127501508524254,"AD":3.061840181352519,"AE":-45.207727552911365,"AF":1.2379866674663522,"AG":3.4189040134961557,"AH":-151.2769773557087,"AI":-4295.646366980781,"AJ":0.03938005568085161,"AK":122.93706090770318,"AL":0.042269791567244454,"AM":-0.06044838877866652,"AN":-0.5198634917938268,"AO":-0.5260582056897466,"AP":2157.254492922557,"AQ":33.808860612934716,"AR":0.0650511967862885,"AS":-0.05921984925436313,"AT":-0.001448174231708382,"AU_":0.0007864238988601562,"AV":-0.37407986765306905,"AW":0.47015556242605366,"AX":-1.4777323105257762,"AY":3.5795373021382533,"AZ":0.24509900738678028,"BA":-0.7453220304134833,"BB":0.05021683403405868,"BC":-0.040039826874268596,"BD":-0.012321107768873768,"BE":-0.002014756273598403,"BF":0.5364814137307119,"BG":-0.4916688095608202,"BH":12.037892501304148,"BI":17.583285308662244,"BJ":-3.372085717128781,"BK":-0.5048550038798754,"BL":0.06344529082198552,"BM":0.037594005490166504,"BN":0.002950009356494017,"BO":-35.790741285857,"BP":23.614975347602435,"BQ":-2606.7677215951635},"saturn":{"A":683.1684741999636,"B":1056.9190043497867,"C":-0.09928805829013544,"D":886.4765194444545,"E":-397.85689530935093,"F":85.19635053543863,"G":35.03865264866053,"H":0.741508811532784,"I":7.653709923760092,"J":-9.858072613122257,"K":16.784599733618965,"L":-13292.50456919721,"M":28118.715651779785,"N":3.00864732348499,"O":954.9707251193618,"P":0.992507119707308,"Q":-0.6166172907071269,"R":14.472894044164846,"S":-2.899479549644592,"U":3349.2799937905875,"V":64828.084848753955,"W":11055.069575326743,"X":-12.398412573033584,"Y":20.615235058797783,"Z":-10087.205632694964,"AA":-53490.523269281344,"AB":-263.57541776595735,"AC":-1.0009146790376031,"AD":-35.62043597182463,"AE":-264.5765424068978,"AF":-171.1353012315377,"AG":88.3974697502865,"AH":-7011.319023657963,"AI":362976.5836766142,"AJ":-0.6413430014154567,"AK":-8704.41364303315,"AL":0.5703046712408298,"AM":0.9506573298153468,"AN":12.091826168071037,"AO":-97.37720793818912,"AP":-408817.7451462118,"AQ":-9497.980235224795,"AR":-0.024404449155653086,"AS":-0.02839494192159417,"AT":-1.75301887846653,"AU_":-3.4143048610989486,"AV":0.44387547270997946,"AW":-0.7776773809099239,"AX":10.491805647483163,"AY":-1.4507426401232077,"AZ":-1.8807073211331684,"BA":-0.17255404020124554,"BB":-0.4567247037277052,"BC":-0.11206249607880416,"BD":0.01756811099505344,"BE":0.09924140875004377,"BF":-4.1595738484665095,"BG":-30.109707211544194,"BH":2.5185668682030466,"BI":224.74638917042145,"BJ":22.92111218091077,"BK":29.375806332730352,"BL":-0.2152120396290023,"BM":0.14958270143505933,"BN":-1.0345243682880405,"BO":1758.4657810932008,"BP":-693.9700419654798,"BQ":940833.2833944175},"uranus":{"A":11.207000699629626,"B":-723.6705661878349,"C":-0.009209653748023478,"D":39.818644086925374,"E":481.1877116704091,"F":-133.492646234193,"G":11.677653157380378,"H":1.3131631672023718,"I":19.18380643872835,"J":-1.4016756434851774,"K":-0.5092966424543167,"L":327.1743189939473,"M":-4464.142652441692,"N":230.25439808856493,"O":-276.9276728555573,"P":-0.026890493065581608,"Q":0.1255498961200215,"R":2.227319359352209,"S":0.02478922357332871,"U":-8996.359115406458,"V":-10226.261942444979,"W":-815.0353390025593,"X":-14.434744281985664,"Y":-6.244794258855242,"Z":13692.6287823568,"AA":2774.6609106436927,"AB":-217.08960507201004,"AC":0.016539731880322244,"AD":-127.98034443312092,"AE":-3531.2444594632148,"AF":97.78788146655975,"AG":34.85413027619682,"AH":2131.2501172069474,"AI":10291.55208425153,"AJ":0.2738699581998041,"AK":49269.77897152423,"AL":0.1283442485988776,"AM":-0.1896109122755499,"AN":24.78698074137529,"AO":9.158094190905777,"AP":19682.38536036837,"AQ":55800.28537194861,"AR":0.03936750325123831,"AS":0.010990631539588205,"AT":0.0007240142817469139,"AU_":0.000016627432132347658,"AV":-0.8040059678549067,"AW":-0.2229130998854057,"AX":9.612606306361021,"AY":5.558537282500359,"AZ":-0.40704930228941333,"BA":-0.483327166170621,"BB":0.32491892068971784,"BC":-0.2068883686422936,"BD":-0.017457819372571792,"BE":0.013852086330092758,"BF":-17.13708033410244,"BG":7.419125558709895,"BH":-592.0231858821052,"BI":1315.7867708287645,"BJ":-22.631162281342892,"BK":-4.281446352394082,"BL":-0.4419941684485309,"BM":-0.21581172145696342,"BN":0.024017311013968756,"BO":-16755.88397849671,"BP":370.20882877786033,"BQ":56042.59098892245},"neptune":{"A":311.719561526752,"B":1250.448299881487,"C":-0.0018253923640905697,"D":-1787.0326807064062,"E":-450.26517327054813,"F":-610.9184584757664,"G":66.30438556111037,"H":-0.591835095901021,"I":-43.22670338188271,"J":-9.699473610640425,"K":-0.447442221819277,"L":-19348.620006857123,"M":210100.21918130363,"N":997.8514018292453,"O":218.33876301851467,"P":0.023190917489532812,"Q":0.1488466676074853,"R":4.57275129455479,"S":1.2848364659010587,"U":16102.757071058459,"V":300599.07714750344,"W":31679.251104835937,"X":26.019481290832786,"Y":2.258661104489687,"Z":-37954.5386686903,"AA":-91749.75132784437,"AB":-2062.2518039996107,"AC":0.1207023467970581,"AD":565.3604323926318,"AE":-23759.20176662644,"AF":-59.79655237719051,"AG":-48.41063688016182,"AH":-2881.9846204331875,"AI":1029430.9891551735,"AJ":-0.005910284826919552,"AK":544824.2235320859,"AL":0.08365278868545829,"AM":0.008142591612184266,"AN":140.74863743318485,"AO":6.796735594764506,"AP":-5392906.08831124,"AQ":-184599.53650102098,"AR":0.001155743464919815,"AS":-0.00010810844919768743,"AT":0.0000395003690166643,"AU_":0.000022585952582786626,"AV":-0.03320508210504993,"AW":0.006553644735206795,"AX":12.993327729205685,"AY":25.157530584382656,"AZ":-0.45361936572496814,"BA":-0.8589817032855688,"BB":0.7194131602870631,"BC":-0.661709339834956,"BD":-0.023960826108684673,"BE":0.02181102686997434,"BF":7.724586965032558,"BG":-5.557975354392591,"BH":413.83536258950085,"BI":468.44027498032403,"BJ":19.928675610359125,"BK":-1.3147664998833528,"BL":0.16777542060537107,"BM":-0.0042878374006099385,"BN":-0.038809433588998694,"BO":-180653.2092899589,"BP":1970.6176048137258,"BQ":44018887.38962854}},
@@ -2,14 +2,14 @@
2
2
  // Gives the TypeScript website full type safety at the boundary (§2g) while
3
3
  // packages/physics stays JavaScript.
4
4
 
5
- export declare const CONSTANTS_HASH: "fa3230753655d190";
5
+ export declare const CONSTANTS_HASH: "844b86db470b9937";
6
6
 
7
7
  export declare const MODEL_VERSION: string;
8
8
 
9
9
  export declare const PREPRINT_DOI: string;
10
10
 
11
11
  export declare const DEFAULT_CONSTANTS: {
12
- readonly hash: "fa3230753655d190";
12
+ readonly hash: "844b86db470b9937";
13
13
  readonly additionalBodies: {
14
14
  "pluto": {
15
15
  "name": string;
@@ -32,7 +32,7 @@
32
32
  * carry it so a counterfactual is reproducible (§2d).
33
33
  * @type {string}
34
34
  */
35
- export const CONSTANTS_HASH = "fa3230753655d190";
35
+ export const CONSTANTS_HASH = "844b86db470b9937";
36
36
 
37
37
  /** Model version label — single source: public/input/model-version.json (§10 two-axis scheme). */
38
38
  export const MODEL_VERSION = "v11.0";
@@ -42,7 +42,7 @@ export const PREPRINT_DOI = "10.21203/rs.3.rs-8758810/v4";
42
42
 
43
43
  /** @type {Readonly<Record<string, unknown>>} */
44
44
  export const DEFAULT_CONSTANTS = Object.freeze({
45
- hash: "fa3230753655d190",
45
+ hash: "844b86db470b9937",
46
46
  additionalBodies: {
47
47
  "pluto": {
48
48
  "name": "Pluto",
@@ -248,7 +248,7 @@ export const DEFAULT_CONSTANTS = Object.freeze({
248
248
  "moonStartposApsidal": 347.5476,
249
249
  "moonStartposNodal": 64.0435,
250
250
  "moonStartposMoon": 67.8443,
251
- "moonMeeusLpCorrection": 0.009382053237928125
251
+ "moonMeeusLpCorrection": 0.009081766072295829
252
252
  },
253
253
  moonMeeus: {
254
254
  "elpW1T2Decomposition_arcsecPerCy2": {
@@ -57,6 +57,7 @@
57
57
  * @property {(dDaysTT: number) => {lonDeg: number, latDeg: number, distKm: number}} moonFullAtDaysTT
58
58
  * full-series Moon: ecliptic-of-date longitude/latitude (deg) + distance (km), TT axis (days since J2000)
59
59
  * @property {(jdUT: number) => number} sunLonDegAt - geometric mean sun longitude (deg), JD(UT) axis with the finder's internal ΔT
60
+ * @property {(T: number) => number} sunCompletionDeg - planetary completion (deg) at T centuries TT, SUBTRACTED from the finder sun (see eclipse/sun-planetary-completion.cjs; the finders deliberately stay without it — their fitted anchors and certified canon statistics were produced on the bare form, and elongation-class timing absorbs the omission into the fitted phases)
60
61
  * @property {(jd: number) => number} deltaTSecondsAt - framework ΔT (J2000-zeroed convention)
61
62
  * @property {(year: number) => number} obliquityDegAt - framework obliquity (deg) at calendar year
62
63
  * @property {(year: number) => number} eccentricityAt - framework Earth-orbit eccentricity at calendar year
@@ -122,8 +123,8 @@ function createBesselian(deps) {
122
123
  const jb = jdUT + K.ttBridgeSeconds / 86400; // finder-axis input → its internal ΔT lands on true TT
123
124
  const year = deps.yearFromJD(jb);
124
125
  const eps = deps.obliquityDegAt(year) * D2R;
125
- const sunLon = deps.sunLonDegAt(jb);
126
126
  const dTT = (jb - K.j2000JD) + deps.deltaTSecondsAt(jb) / 86400;
127
+ const sunLon = deps.sunLonDegAt(jb) - deps.sunCompletionDeg(dTT / K.julianCenturyDays);
127
128
  const moon = deps.moonFullAtDaysTT(dTT);
128
129
  return {
129
130
  S: eclToEq(sunLon, 0, sunDistanceKm(year, sunLon), eps),
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Sun planetary completion — the 20.3h location-tier term table.
3
+ *
4
+ * The finder Sun (framework linear rate + Kepler EoC + the fitted
5
+ * SUN_HARMONICS) omits the classical planetary perturbations of the
6
+ * geocentric Sun (the Newcomb Venus/Jupiter/Mars terms and the
7
+ * Earth-around-EMB wobble). Measured against JPL Horizons (ObsEcLon,
8
+ * geocentric, leading-nutation-bridged to mean-of-date) on 960
9
+ * deterministic all-phase epochs 1970–2049: the omission is 10.0″ RMS
10
+ * of Sun-longitude scatter; this table removes the coherent part,
11
+ * 10.0″ → 2.9″ RMS, with every term era-stable (amplitude and phase
12
+ * agree between the 1970–2009 and 2010–2049 half-samples).
13
+ *
14
+ * THE CONSTANT-ATTRIBUTION RULE (the 20.3h-lite trap, resolved here):
15
+ * the table carries NO constant term — the all-phase fit attributes the
16
+ * constant to the tier's existing anchors, so the terms ship without
17
+ * the +6″ syzygy-mean penalty that an eclipse-sample fit produced (at
18
+ * new moon the EMB argument D locks near 0 and its cos-component
19
+ * becomes a constant; fitting on eclipses alone poisons the mean).
20
+ * Verified on the 179-eclipse-syzygy sample: elongation mean stays
21
+ * +1.1″ → +1.5″ while RMS drops 10.6″ → 5.5″; and on the 15 NASA
22
+ * path-table centerline points: shadow-plane mean 6.0″ → 3.6″, max
23
+ * 10.1″ → 5.0″, every event improved.
24
+ *
25
+ * Arguments are of-date mean longitudes (IAU-class instrument
26
+ * polynomials, degrees/Julian-century TT). They are phase carriers for
27
+ * the fitted amplitudes — the framework-native derivation of these
28
+ * term tables is the 20.3e research item. Terms with ambiguous
29
+ * identifications (the ~8-yr band, the 414-day Venus/three-planet
30
+ * blend, E−M, E−S) are deliberately NOT shipped: each failed the
31
+ * half-sample stability test or has no unique two-planet argument at
32
+ * the window's frequency resolution (~1.5″ RSS accepted as floor).
33
+ *
34
+ * Sign convention: the table models (framework − truth), so consumers
35
+ * SUBTRACT the evaluation from the finder Sun longitude.
36
+ */
37
+
38
+ 'use strict';
39
+
40
+ /** Of-date mean-longitude polynomials, degrees per Julian century TT. */
41
+ const ARG_RATES = {
42
+ lV: [181.979801, 58517.815676], // Venus
43
+ lE: [100.466457, 36000.769780], // Earth (EMB)
44
+ lM: [355.433000, 19141.696300], // Mars
45
+ lJ: [34.351519, 3036.302389], // Jupiter
46
+ D: [297.8501921, 445267.1114034], // Moon mean elongation (EMB wobble carrier)
47
+ };
48
+
49
+ /**
50
+ * The fitted table: [k·lV, k·lE, k·lM, k·lJ, k·D, cosAmp″, sinAmp″].
51
+ * Fit: 960-epoch all-phase LSQ vs JPL Horizons DE441-class ObsEcLon,
52
+ * free constant excluded from shipment; SE 0.13″ per coefficient.
53
+ */
54
+ const TERMS = [
55
+ [1, -1, 0, 0, 0, 0, -5.08], // V−E (Venus synodic)
56
+ [2, -2, 0, 0, 0, 0, 5.55], // 2(V−E)
57
+ [3, -3, 0, 0, 0, 0, 0.68], // 3(V−E)
58
+ [2, -3, 0, 0, 0, -2.64, 0], // 2V−3E (the classic Newcomb Venus term)
59
+ [0, 1, 0, -1, 0, 0, 7.19], // E−J (Jupiter synodic)
60
+ [0, 2, 0, -2, 0, 0, -2.81], // 2(E−J)
61
+ [0, 1, 0, -2, 0, -1.34, 0.97],// E−2J
62
+ [0, 2, -2, 0, 0, 0, 2.05], // 2(E−M) (Mars)
63
+ [0, 2, 0, 0, 0, 0, 1.42], // 2lE (semiannual Kepler leftover)
64
+ [0, 0, 0, 0, 1, 0, -6.64], // D (Earth-around-EMB wobble, 6.44″ theory)
65
+ ];
66
+
67
+ const D2R = Math.PI / 180;
68
+
69
+ /**
70
+ * Planetary-completion correction to the finder Sun longitude.
71
+ * @param {number} T - Julian centuries TT from J2000
72
+ * @returns {number} degrees — SUBTRACT from the finder Sun longitude
73
+ */
74
+ function sunPlanetaryCompletionDeg(T) {
75
+ const lV = (ARG_RATES.lV[0] + ARG_RATES.lV[1] * T) * D2R;
76
+ const lE = (ARG_RATES.lE[0] + ARG_RATES.lE[1] * T) * D2R;
77
+ const lM = (ARG_RATES.lM[0] + ARG_RATES.lM[1] * T) * D2R;
78
+ const lJ = (ARG_RATES.lJ[0] + ARG_RATES.lJ[1] * T) * D2R;
79
+ const D = (ARG_RATES.D[0] + ARG_RATES.D[1] * T) * D2R;
80
+ let arcsec = 0;
81
+ for (const [kV, kE, kM, kJ, kD, cA, sA] of TERMS) {
82
+ const th = kV * lV + kE * lE + kM * lM + kJ * lJ + kD * D;
83
+ arcsec += cA * Math.cos(th) + sA * Math.sin(th);
84
+ }
85
+ return arcsec / 3600;
86
+ }
87
+
88
+ module.exports = { sunPlanetaryCompletionDeg };
package/src/model.js CHANGED
@@ -31,6 +31,7 @@ import { createMoonMonthChain } from './moon/month-chain.cjs';
31
31
  import { createChainCycleIntegrator } from './chain-cycles/index.cjs';
32
32
  import { createMoonArguments, jdToDecimalYear } from './moon/arguments.cjs';
33
33
  import { createMoonSeries } from './moon/series.cjs';
34
+ import { sunPlanetaryCompletionDeg } from './eclipse/sun-planetary-completion.cjs';
34
35
  import { createEclipseFinders } from './eclipse/finders.cjs';
35
36
  import { createBesselian } from './eclipse/besselian.cjs';
36
37
  import { driver2PeriodSecondsAtAge } from './planets/orbit-chain.cjs';
@@ -732,6 +733,24 @@ export function assembleModel(C, F) {
732
733
  cyclesBetween,
733
734
  isDeepTime: () => true,
734
735
  isFrameworkNative: () => true,
736
+ // (d′) of-date rate completion: the DYNAMICAL axial precession (the
737
+ // tweakpane day-form identity — real at J2000, epoch-valid) and the
738
+ // KINEMATIC pair's beat the chains embed. MATCHED TRIPLE with the
739
+ // tools-lib and browser wirings.
740
+ pDynDegPerYearAt: /** @param {number} year */ (year) => {
741
+ const sid = siderealYearDays(year);
742
+ const sol = tropicalYearDirectDays(year);
743
+ return 360 * (sid - sol) / sid;
744
+ },
745
+ pKinDegPerYearAt: /** @param {number} year */ (year) => {
746
+ // MODEL-START-anchored age, matching the tools-lib/browser wirings
747
+ // bit-exactly — NOT yearToTMa's 2000.0 convention (the recorded
748
+ // 0.4977-yr parity trap, same class as getMoonDistanceKm above).
749
+ const t = (startmodelYear - year) / 1e6;
750
+ const sid = deepLod.siderealYearSecondsAtAge(t);
751
+ const trop = deepLod.tropicalYearSecondsAtAge(t);
752
+ return (sid === null || trop === null) ? 0 : 360 * (sid - trop) / sid;
753
+ },
735
754
  },
736
755
  });
737
756
 
@@ -843,6 +862,7 @@ export function assembleModel(C, F) {
843
862
  return { lonDeg: ev.lonDeg, latDeg: ev.latDeg, distKm: ev.distKm };
844
863
  },
845
864
  sunLonDegAt: /** @param {number} jdUT */ (jdUT) => eclipseFinders.sunLonDegAt(jdUT),
865
+ sunCompletionDeg: sunPlanetaryCompletionDeg,
846
866
  deltaTSecondsAt: /** @param {number} jd */ (jd) => (jdTTFromUT(jd) - jd) * 86400,
847
867
  obliquityDegAt: obliquityDeg,
848
868
  eccentricityAt,
@@ -879,6 +899,14 @@ export function assembleModel(C, F) {
879
899
  siderealYearSecondsAtYear: /** @param {number} year @returns {number} */ (year) => deepLod.siderealYearSecondsAtAge(yearToTMa(year)),
880
900
  deltaTSecondsAtYear: deltaTSeconds,
881
901
  cyclesBetween,
902
+ // The DYNAMICAL axial precession period (the tweakpane identity):
903
+ // day-form beat of the sidereal and solar year evaluators — real at
904
+ // J2000 (~25,771 yr ≈ IAU), epoch-valid at any age. The same value
905
+ // the (d′) of-date rate completion integrates.
906
+ axialPrecessionYearsAtYear: /** @param {number} year @returns {number} */ (year) => {
907
+ const sid = siderealYearDays(year);
908
+ return sid / (sid - tropicalYearDirectDays(year));
909
+ },
882
910
  }),
883
911
  earth: Object.freeze({
884
912
  perihelionLongitudeDeg: earthPerihelionDeg,
@@ -99,10 +99,17 @@ function jdToDecimalYear(jd) {
99
99
  * cyclesBetween: (yearA: number, yearB: number, divisorN: number) => (number | null),
100
100
  * isDeepTime: () => boolean,
101
101
  * isFrameworkNative: () => boolean,
102
+ * pDynDegPerYearAt?: (year: number) => number,
103
+ * pKinDegPerYearAt?: (year: number) => number,
102
104
  * },
103
105
  * }} deps — fns are the ENGINE'S OWN chain wrappers (each engine's toggle
104
106
  * semantics ride along); eccAt/channelIntegral are the shared moon ecc
105
- * channel; constants are J2000-frozen injections.
107
+ * channel; constants are J2000-frozen injections. The OPTIONAL precession
108
+ * pair powers the (d′) of-date rate completion: pDyn = the DYNAMICAL
109
+ * axial precession (day-form beat of the engine's sidereal/solar year
110
+ * evaluators — the tweakpane identity, real at J2000, epoch-valid);
111
+ * pKin = the KINEMATIC pair's beat (the H/13-family mean the chains
112
+ * embed). Absent ⇒ the completion is disabled (pre-(d′) behaviour).
106
113
  */
107
114
  function createMoonArguments({ constants, fns }) {
108
115
  const {
@@ -117,6 +124,7 @@ function createMoonArguments({ constants, fns }) {
117
124
  eccAt, channelIntegral, computeObliquityEarth, jdToSIyear,
118
125
  tropicalOrbitsBetween, apsidalOfDateCyclesBetween, nodalOfDateCyclesBetween,
119
126
  cyclesBetween, isDeepTime, isFrameworkNative,
127
+ pDynDegPerYearAt, pKinDegPerYearAt,
120
128
  } = fns;
121
129
 
122
130
  // ── The _FW_MOON bundle: Meeus Ch. 47 J2000 anchors + derived checks ─────
@@ -196,14 +204,19 @@ function createMoonArguments({ constants, fns }) {
196
204
  // ── Bounded Lp carriers (K_PL / C_OBL derived lazily — zero new constants)
197
205
  /** @type {number | null} */
198
206
  let kPl = null;
199
- /** @param {number} T @returns {number} */
200
- function planetaryCarrier(T) {
201
- if (T === 0) return 0;
207
+ /** @returns {number} */
208
+ function kPlValue() {
202
209
  if (kPl === null) {
203
210
  const de2dT = Math.pow(eccAt(50), 2) - Math.pow(eccAt(-50), 2); // Δ(e²) per cy at J2000
204
211
  const t2Obl = (elpEarthFigureJ2ArcsecPerCy2 + elpGeneralPrecessionPA_T2ArcsecPerCy2) / 3600;
205
212
  kPl = 2 * (bundle.T2_LP - bundle.T2_LP_TIDAL - t2Obl) / de2dT;
206
213
  }
214
+ return kPl;
215
+ }
216
+ /** @param {number} T @returns {number} */
217
+ function planetaryCarrier(T) {
218
+ if (T === 0) return 0;
219
+ const k = kPlValue();
207
220
  // The channel's e0 anchor CONST — not eccAt(0), which under integrated
208
221
  // phase carries the R3 drift correction (the 8.2-2 convention).
209
222
  const e0sq = eccE0 * eccE0;
@@ -213,7 +226,7 @@ function createMoonArguments({ constants, fns }) {
213
226
  const h = T / N;
214
227
  let sum = f(0) + f(T);
215
228
  for (let i = 1; i < N; i++) sum += f(i * h) * (i % 2 ? 4 : 2);
216
- return kPl * sum * h / 3;
229
+ return k * sum * h / 3;
217
230
  }
218
231
 
219
232
  /** @type {{eps0: number, C: number} | null} */
@@ -222,7 +235,14 @@ function createMoonArguments({ constants, fns }) {
222
235
  function obliquityCarrier(T) {
223
236
  if (T === 0) return 0;
224
237
  if (obl === null) {
225
- const T2_OBL = (elpEarthFigureJ2ArcsecPerCy2 + elpGeneralPrecessionPA_T2ArcsecPerCy2) / 3600;
238
+ // (d′): when the of-date rate completion is live, its ∫(p_dyn p_kin)
239
+ // carries the model-native share of the precession ACCELERATION
240
+ // (ṗΔ_eff/2 per T²); the carrier's normalization is reduced by exactly
241
+ // that share so the TOTAL Lp T² stays the certified, DE441-validated
242
+ // budget (J2 + Lieske ṗ_A/2) — the model-vs-Lieske ṗ difference lives
243
+ // here as one visible derived term, never hidden.
244
+ const T2_OBL = (elpEarthFigureJ2ArcsecPerCy2 + elpGeneralPrecessionPA_T2ArcsecPerCy2) / 3600
245
+ - rateCompInit().pdSlopeDegPerCy2 / 2;
226
246
  const eps0 = computeObliquityEarth(2000);
227
247
  const epsDot = computeObliquityEarth(2050) - computeObliquityEarth(1950);
228
248
  obl = { eps0, C: 2 * T2_OBL / epsDot };
@@ -236,11 +256,191 @@ function createMoonArguments({ constants, fns }) {
236
256
  return /** @type {{eps0: number, C: number}} */ (obl).C * sum * h / 3;
237
257
  }
238
258
 
259
+ // ── Secular-ë completion carrier (ṅ campaign, plan §12i item 0 (c)) ──────
260
+ // The certified snapshot's Lp T³/T⁴ tail is DERIVED physics (v4 D3,
261
+ // tools/explore/v4-d3-tails.js): the Adams–Laplace channel's curvature
262
+ // under the SECULAR-theory ë reproduces 1/538841 at 98.8%. The H/3 line's
263
+ // own ë is ~7× smaller with the opposite bulk effect — the documented BCE
264
+ // drift-row divergence, sharply localized here — so the always-chains
265
+ // branch, which integrates the H/3 channel, loses that content (measured:
266
+ // deep−snapshot Lp 2c = +0.91″/cy² over 27 cy = +0.68 tail + 0.22 the
267
+ // channel's own curvature + 0.03 convention; dense DE441 confirms the
268
+ // certified tail at ×1.0 — canon−DE441 2c = +0.11 ± 0.13″/cy², 300
269
+ // epochs; instruments: tools/explore/u2-args-branch-isolation.mjs,
270
+ // u2-lp-decomposition.mjs, u2-dense-de441.mjs). This third carrier
271
+ // integrates the CURVATURE difference of e² (secular Taylor − H/3
272
+ // channel) through the same K_PL conversion: zero through T² by
273
+ // construction (the certified T² normalization is untouched), < 0.001″
274
+ // in the modern era, the derived tail across the eclipse corpus. The
275
+ // envelope is the H/3 quarter-period cos² taper (H/12 yr — lattice-
276
+ // derived, no new constant): the completion saturates there, so deep
277
+ // time keeps the pure H-lattice claim (no open polynomial). The
278
+ // channel's own third-order content is not subtracted (ω³-suppressed,
279
+ // negligible); the T⁴ secular remainder beyond the channel term stays a
280
+ // documented deviation (D3: 40.8% derived; ≈ −7″ at −135).
281
+ /** @type {{dd2: number, d3Sec: number, Tq: number} | null} */
282
+ let secComp = null;
283
+ /** @param {number} T @returns {number} */
284
+ function lpSecularCompletion(T) {
285
+ if (T === 0) return 0;
286
+ if (secComp === null) {
287
+ // d²(e²)/dT², d³(e²)/dT³ under the quadratic secular e(T) (per cy)
288
+ const d2Sec = 2 * (eccentricityDotJ2000 * eccentricityDotJ2000
289
+ + eccentricityJ2000 * eccentricityDotDotJ2000);
290
+ const d3Sec = 6 * eccentricityDotJ2000 * eccentricityDotDotJ2000;
291
+ // the H/3 channel's own d²(e²)/dT² — central difference at ±10 cy
292
+ /** @param {number} tCy */
293
+ const e2 = (tCy) => { const e = eccAt(tCy * 100); return e * e; };
294
+ const d2Ch = (e2(10) - 2 * e2(0) + e2(-10)) / 100;
295
+ secComp = { dd2: d2Sec - d2Ch, d3Sec, Tq: holisticYearJ2000 / 12 / 100 };
296
+ }
297
+ const S = secComp;
298
+ /** @param {number} t */
299
+ const f = (t) => {
300
+ const q = Math.abs(t) / S.Tq;
301
+ if (q >= 1) return 0;
302
+ const env = Math.cos(Math.PI / 2 * q) ** 2;
303
+ return (0.5 * S.dd2 * t * t + S.d3Sec * t * t * t / 6) * env;
304
+ };
305
+ const N = Math.max(2, 2 * Math.ceil(Math.abs(T) * 100 / 2000));
306
+ const h = T / N;
307
+ let sum = f(0) + f(T);
308
+ for (let i = 1; i < N; i++) sum += f(i * h) * (i % 2 ? 4 : 2);
309
+ return kPlValue() * sum * h / 3;
310
+ }
311
+
239
312
  // ── Deep-time branch: always-chains (Stage B) ────────────────────────────
240
313
  /** @type {number | null} */
241
314
  let argsY0 = null;
242
- /** @param {number} jd @returns {MoonArgsDeg | null} */
243
- function fwArgsDeep(jd) {
315
+
316
+ // ── Of-date rate completion (ṅ campaign (d′)) ────────────────────────────
317
+ // The chains' J2000 rates differ from the certified bundle rates by the
318
+ // kinematic-vs-dynamical precession (tropical: the +0.006 s month offset
319
+ // ≡ Δp = p_dyn − p_kin exactly) plus per-chain construction residues
320
+ // (anomalistic +0.030 s ↔ −22″/cy, etc.) — measured end-to-end as the
321
+ // argument linears −4.08/+0.42/+1.72/−21.99/+2.27 ″/cy (instruments:
322
+ // u2-args-branch-isolation + the (d′) rate attribution). Two parts:
323
+ // 1. pFix = ∫(p_dyn − p_kin) dy — the DYNAMICAL precession accumulation
324
+ // (Dennis's tweakpane identity), applied to every of-date longitude
325
+ // (Lp, ϖ, Ω; it cancels in D/M/Mp/F as of-date differences must).
326
+ // Natively BOUNDED at deep time: p_dyn oscillates about the lattice
327
+ // mean p_kin, so the integral never runs away — no taper. Two-tier
328
+ // lazy cumulative Simpson table (25-yr cells to ±30 kyr, 500-yr to
329
+ // ±1 Myr, frozen beyond — deep-Moon display class, documented).
330
+ // 2. Residual per-chain rate anchors, SELF-MEASURED at build (±25-yr
331
+ // central difference of the raw compositions vs the certified bundle
332
+ // rates, timeline conversion measured from jdToSIyear — assuming the
333
+ // day-scale would inject ~29″/cy) and applied through the H/12 cos²
334
+ // taper integral (analytic): full in the historical window, frozen
335
+ // ≤ ~0.9° at deep time. Zero new physical constants anywhere.
336
+ /** @type {{ok: boolean, pFix: (dyYears: number) => number, pdSlopeDegPerCy2: number} | null} */
337
+ let rateComp = null;
338
+ function rateCompInit() {
339
+ if (rateComp !== null) return rateComp;
340
+ if (!pDynDegPerYearAt || !pKinDegPerYearAt) {
341
+ rateComp = { ok: false, pFix: () => 0, pdSlopeDegPerCy2: 0 };
342
+ return rateComp;
343
+ }
344
+ if (argsY0 === null) argsY0 = jdToSIyear(j2000JD);
345
+ const y0 = argsY0;
346
+ const pDynAt = pDynDegPerYearAt, pKinAt = pKinDegPerYearAt;
347
+ /** @param {number} y */
348
+ const pd = (y) => pDynAt(y) - pKinAt(y); // deg/yr
349
+ // effective in-window ṗΔ (secant over the ancient span — robust against
350
+ // the slow oscillation, matches the 27-cy quadratic fit)
351
+ const pdSlopeDegPerCy2 = (pd(y0) - pd(y0 - 2700)) / 27 * 100;
352
+ const FS = 25, FR = 30000, CS = 500, CR = 1000000;
353
+ const nF = FR / FS;
354
+ const fineP = new Float64Array(nF + 1), fineF = new Float64Array(nF + 1);
355
+ let fineBuilt = false;
356
+ /** @type {Float64Array | null} */ let coarseP = null;
357
+ /** @type {Float64Array | null} */ let coarseF = null;
358
+ /** @param {number} a @param {number} h */
359
+ const cell = (a, h) => (pd(a) + 4 * pd(a + h / 2) + pd(a + h)) * h / 6;
360
+ const buildFine = () => {
361
+ for (let i = 0; i < nF; i++) {
362
+ fineF[i + 1] = fineF[i] + cell(y0 + i * FS, FS);
363
+ fineP[i + 1] = fineP[i] - cell(y0 - (i + 1) * FS, FS);
364
+ }
365
+ fineBuilt = true;
366
+ };
367
+ const buildCoarse = () => {
368
+ const nC = (CR - FR) / CS;
369
+ coarseF = new Float64Array(nC + 1);
370
+ coarseP = new Float64Array(nC + 1);
371
+ coarseF[0] = fineF[nF];
372
+ coarseP[0] = fineP[nF];
373
+ for (let i = 0; i < nC; i++) {
374
+ coarseF[i + 1] = coarseF[i] + cell(y0 + FR + i * CS, CS);
375
+ coarseP[i + 1] = coarseP[i] - cell(y0 - FR - (i + 1) * CS, CS);
376
+ }
377
+ };
378
+ /** @param {number} dy @returns {number} degrees */
379
+ const pFix = (dy) => {
380
+ if (!fineBuilt) buildFine();
381
+ const a = Math.abs(dy);
382
+ if (a <= FR) {
383
+ const arr = dy >= 0 ? fineF : fineP;
384
+ const x = a / FS, i = Math.floor(x), f = x - i;
385
+ return i >= nF ? arr[nF] : arr[i] + f * (arr[i + 1] - arr[i]);
386
+ }
387
+ if (coarseF === null || coarseP === null) buildCoarse();
388
+ const arr = /** @type {Float64Array} */ (dy >= 0 ? coarseF : coarseP);
389
+ const nC = arr.length - 1;
390
+ const x = (a - FR) / CS, i = Math.floor(x), f = x - i;
391
+ if (i >= nC) return arr[nC]; // frozen beyond ±1 Myr (documented)
392
+ return arr[i] + f * (arr[i + 1] - arr[i]);
393
+ };
394
+ rateComp = { ok: true, pFix, pdSlopeDegPerCy2 };
395
+ return rateComp;
396
+ }
397
+
398
+ /** Analytic taper integral: ∫₀^dy cos²(π t / 2T_q) dt, saturating at
399
+ * ±T_q/2 — the (c) taper convention at first order.
400
+ * @param {number} dy @param {number} Tq @returns {number} */
401
+ function iEnv(dy, Tq) {
402
+ if (Math.abs(dy) >= Tq) return Math.sign(dy) * Tq / 2;
403
+ return dy / 2 + (Tq / (2 * Math.PI)) * Math.sin(Math.PI * dy / Tq);
404
+ }
405
+
406
+ /** @type {{ok: boolean, Lp: number, w: number, om: number, Lsun: number, ws: number, Tq: number} | null} */
407
+ let rcAnchors = null;
408
+ function anchorsInit() {
409
+ if (rcAnchors !== null) return rcAnchors;
410
+ const RC = rateCompInit();
411
+ if (!RC.ok) {
412
+ rcAnchors = { ok: false, Lp: 0, w: 0, om: 0, Lsun: 0, ws: 0, Tq: 1 };
413
+ return rcAnchors;
414
+ }
415
+ // timeline conversion measured from the injected jdToSIyear itself
416
+ const dppd = (jdToSIyear(j2000JD + 5000) - jdToSIyear(j2000JD - 5000)) / 10000; // y-units/day
417
+ const k = 1 / (36525 * dppd); // deg/cy → deg per y-unit
418
+ const jdOff = 25 / dppd;
419
+ const a = fwArgsDeepParts(j2000JD - jdOff);
420
+ const b = fwArgsDeepParts(j2000JD + jdOff);
421
+ if (a === null || b === null) {
422
+ rcAnchors = { ok: false, Lp: 0, w: 0, om: 0, Lsun: 0, ws: 0, Tq: 1 };
423
+ return rcAnchors;
424
+ }
425
+ const span = b.dy - a.dy;
426
+ const B = bundle;
427
+ rcAnchors = {
428
+ ok: true,
429
+ Lp: B.LPR * k - (b.Lp - a.Lp) / span,
430
+ w: B.WDOT * k - (b.w - a.w) / span,
431
+ om: B.NDOT * k - (b.om - a.om) / span,
432
+ Lsun: (B.LPR - B.DR) * k - (b.Lsun - a.Lsun) / span,
433
+ ws: (B.LPR - B.DR - B.MR) * k - (b.ws - a.ws) / span,
434
+ Tq: holisticYearJ2000 / 12,
435
+ };
436
+ return rcAnchors;
437
+ }
438
+
439
+ /** Raw deep composition — UNWRAPPED of-date parts incl. pFix, NO anchors
440
+ * (the anchors are measured against exactly this).
441
+ * @param {number} jd
442
+ * @returns {{Lp: number, w: number, om: number, Lsun: number, ws: number, dy: number} | null} */
443
+ function fwArgsDeepParts(jd) {
244
444
  const A = bundle;
245
445
  if (argsY0 === null) argsY0 = jdToSIyear(j2000JD);
246
446
  const y = jdToSIyear(jd);
@@ -249,15 +449,42 @@ function createMoonArguments({ constants, fns }) {
249
449
  const Nnod = nodalOfDateCyclesBetween(argsY0, y);
250
450
  const Nperi = cyclesBetween(argsY0, y, 16);
251
451
  if (Ntrop === null || Naps === null || Nnod === null || Nperi === null) return null; // tidal-lock guard
252
- /** @param {number} x */
253
- const wrap = (x) => ((x % 360) + 360) % 360;
254
452
  const dev = sunSecularDeviations(jd);
255
453
  const Tj = (jd - j2000JD) / julianCenturyDays;
256
- const Lp = A.LP0 + 360 * Ntrop + planetaryCarrier(Tj) + obliquityCarrier(Tj);
454
+ const dy = y - argsY0;
455
+ // pFix rides Lp ONLY: the obliquity carrier's PA reduction compensates
456
+ // its ṗΔ·T²/2 there, keeping total Lp T² certified. The apsidal/nodal
457
+ // chains' own curvature is ALREADY certified-consistent (v4 checks;
458
+ // pre-(d′) isolation −0.20/+0.13″/cy²), so ϖ/Ω take only the tapered
459
+ // rate anchors — which self-measure and absorb their Δp rate share.
460
+ // Deep time: Mp/F inherit Lp's bounded pFix oscillation uncancelled
461
+ // (physically p-free args; bounded, display-class — documented).
462
+ const pF = rateCompInit().pFix(dy);
463
+ const Lp = A.LP0 + 360 * Ntrop + planetaryCarrier(Tj) + obliquityCarrier(Tj)
464
+ + lpSecularCompletion(Tj) + pF;
257
465
  const w = (A.LP0 - A.MP0) + 360 * Naps; // perigee ϖ (of-date, advance)
258
466
  const om = (A.LP0 - A.F0) - 360 * Nnod; // node Ω (of-date, regression)
259
- const Lsun = (A.LP0 - A.D0) + 360 * (y - argsY0) + dev.dLs; // mean Sun (model timeline)
467
+ const Lsun = (A.LP0 - A.D0) + 360 * dy + dev.dLs; // mean Sun (model timeline)
260
468
  const ws = (A.LP0 - A.D0 - A.M0) + 360 * Nperi + dev.dPeri; // Sun perihelion (H/16 chain)
469
+ return { Lp, w, om, Lsun, ws, dy };
470
+ }
471
+
472
+ /** @param {number} jd @returns {MoonArgsDeg | null} */
473
+ function fwArgsDeep(jd) {
474
+ const P = fwArgsDeepParts(jd);
475
+ if (P === null) return null;
476
+ let { Lp, w, om, Lsun, ws } = P;
477
+ const AN = anchorsInit();
478
+ if (AN.ok) {
479
+ const I = iEnv(P.dy, AN.Tq);
480
+ Lp += AN.Lp * I;
481
+ w += AN.w * I;
482
+ om += AN.om * I;
483
+ Lsun += AN.Lsun * I;
484
+ ws += AN.ws * I;
485
+ }
486
+ /** @param {number} x */
487
+ const wrap = (x) => ((x % 360) + 360) % 360;
261
488
  return {
262
489
  Lp: wrap(Lp), D: wrap(Lp - Lsun), M: wrap(Lsun - ws),
263
490
  Mp: wrap(Lp - w), F: wrap(Lp - om),
@@ -314,7 +541,10 @@ function createMoonArguments({ constants, fns }) {
314
541
  return isFrameworkNative() ? fwArgs(jdTT) : pureMeeusArgs(jdTT);
315
542
  }
316
543
 
317
- return { argsAt, fwArgs, fwArgsDeep, pureMeeusArgs, sunSecularDeviations, planetaryCarrier, obliquityCarrier, bundle };
544
+ // _rateCompletion: probe hook (instruments/verification) the (d′) state:
545
+ // whether the completion is live, its measured ṗΔ, and the five anchors.
546
+ return { argsAt, fwArgs, fwArgsDeep, pureMeeusArgs, sunSecularDeviations, planetaryCarrier, obliquityCarrier, lpSecularCompletion, bundle,
547
+ _rateCompletion: () => ({ rc: rateCompInit(), anchors: anchorsInit() }) };
318
548
  }
319
549
 
320
550
  module.exports = { createMoonArguments, jdToDecimalYear };