ascii-side-of-the-moon 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,12 +24,23 @@ npx ascii-side-of-the-moon "2025-09-19 21:30"
24
24
  # (Latitude and longitude are optional, but both must be supplied together;
25
25
  # elevation is ignored unless lat/lon are provided.)
26
26
  npx ascii-side-of-the-moon 2025-09-19T21:30 --lat 37.7749 --lon -122.4194 --elevation 25
27
+
28
+ # Choose a reference frame for the moon orientation
29
+ npx ascii-side-of-the-moon 2025-09-19 --frame=celestial_up # Celestial north up (default without lat/lon)
30
+ npx ascii-side-of-the-moon 2025-09-19 --frame=celestial_down # Celestial south up (inverted)
31
+ npx ascii-side-of-the-moon 2025-09-19 --frame=observer --lat 40.7 --lon -74 # Observer view (zenith up)
27
32
  ```
28
33
 
29
34
  The CLI will display the ASCII moon art along with information about the moon's phase, illumination percentage, distance, and angular diameter.
30
35
  When an observer location is supplied, the renderer also knows the altitude/azimuth
31
36
  and can draw the horizon line to show whether the moon is above or below your local horizon.
32
37
 
38
+ ### Frame Options
39
+
40
+ - `celestial_up` - Standard geocentric orientation with celestial north up (default when no lat/lon provided)
41
+ - `celestial_down` - Inverted orientation with celestial south up
42
+ - `observer` - Observer-relative orientation with zenith up, uses parallactic angle (default when lat/lon provided)
43
+
33
44
  ## Example
34
45
 
35
46
  ```js
@@ -60,8 +71,13 @@ this enables horizon-aware rendering and correct rotation for your sky.
60
71
 
61
72
  ### `renderMoon(moonState: MoonState, options?: RenderOptions): string`
62
73
  Renders the moon as ASCII art. Returns a 29×60 character string.
63
- `RenderOptions` now includes `showHorizon` (default `true`): set it to `false`
64
- if you want to suppress the horizon overlay even when altitude data is available.
74
+
75
+ `RenderOptions` includes:
76
+ - `showHorizon` (default `true` for observer frame): set to `false` to suppress the horizon overlay
77
+ - `frame`: Reference frame for the moon orientation:
78
+ - `"celestial_up"` - Celestial north up (default when no position data)
79
+ - `"celestial_down"` - Celestial south up (180° rotation)
80
+ - `"observer"` - Observer's zenith up, uses parallactic angle (default when position data available)
65
81
 
66
82
  ### `getMoonPhase(moonState: MoonState): string`
67
83
  Returns the English name of the moon phase (e.g., "New Moon", "Waxing Crescent", "First Quarter", "Waxing Gibbous", "Full Moon", "Waning Gibbous", "Last Quarter", "Waning Crescent").
@@ -88,6 +104,11 @@ pnpm run render:demo 2025-01-01 21:30 --lat 37.7749 --lon -122.4194 --elevation
88
104
 
89
105
  # Just observer location (uses current date/time)
90
106
  pnpm run render:demo --lat 40.7128 --lon -74.0060
107
+
108
+ # Choose a reference frame
109
+ pnpm run render:demo 2025-01-01 --frame=celestial_up # Celestial north up
110
+ pnpm run render:demo 2025-01-01 --frame=celestial_down # Celestial south up (inverted)
111
+ pnpm run render:demo 2025-01-01 --frame=observer --lat 40.7 --lon -74 # Observer view
91
112
  ```
92
113
 
93
114
  Render an animation:
package/dist/cli.cjs CHANGED
@@ -594,9 +594,16 @@ function rotateCharacters(ascii, angleDeg, centerX, centerY) {
594
594
  }
595
595
  return output.map((row) => row.join("")).join("\n");
596
596
  }
597
+ function resolveFrame(state, options) {
598
+ if (options.frame !== void 0) {
599
+ return options.frame;
600
+ }
601
+ return state.position !== void 0 ? "observer" : "celestial_up";
602
+ }
597
603
  function renderMoon(state, _options = {}) {
598
604
  const options = _options ?? {};
599
- const showHorizon = options.showHorizon !== false;
605
+ const frame = resolveFrame(state, options);
606
+ const showHorizon = options.showHorizon ?? frame === "observer";
600
607
  const nearestMoon = findNearestMoonState(state);
601
608
  const dim = asciiMoonDim(nearestMoon.ascii);
602
609
  let textureAscii = nearestMoon.ascii;
@@ -678,16 +685,19 @@ function renderMoon(state, _options = {}) {
678
685
  out.push(row);
679
686
  }
680
687
  let composed = out.join("\n");
681
- if (state.position?.parallacticAngle !== void 0) {
682
- const rotation = -state.position.parallacticAngle;
683
- if (Math.abs(rotation) > 0.1) {
684
- composed = rotateCharacters(
685
- composed,
686
- rotation,
687
- dim.centerX,
688
- dim.centerY
689
- );
690
- }
688
+ let rotation = 0;
689
+ if (frame === "celestial_down") {
690
+ rotation = 180;
691
+ } else if (frame === "observer" && state.position?.parallacticAngle !== void 0) {
692
+ rotation = -state.position.parallacticAngle;
693
+ }
694
+ if (Math.abs(rotation) > 0.1) {
695
+ composed = rotateCharacters(
696
+ composed,
697
+ rotation,
698
+ dim.centerX,
699
+ dim.centerY
700
+ );
691
701
  }
692
702
  return showHorizon ? overlayHorizon(composed, state, dim) : composed;
693
703
  }
@@ -790,6 +800,13 @@ function combineDateAndTime(datePart, timePart) {
790
800
  }
791
801
  return `${datePart}T${timePart}`;
792
802
  }
803
+ var VALID_FRAMES = ["celestial_up", "celestial_down", "observer"];
804
+ function parseFrameOrThrow(value) {
805
+ if (!VALID_FRAMES.includes(value)) {
806
+ throw new Error(`Invalid frame value: ${value}. Must be one of: ${VALID_FRAMES.join(", ")}.`);
807
+ }
808
+ return value;
809
+ }
793
810
  function parseCliArgs(args, options = {}) {
794
811
  const nowProvider = options.now ?? (() => /* @__PURE__ */ new Date());
795
812
  let datePart;
@@ -797,6 +814,7 @@ function parseCliArgs(args, options = {}) {
797
814
  let latitude;
798
815
  let longitude;
799
816
  let elevation;
817
+ let frame;
800
818
  for (let i = 0; i < args.length; i++) {
801
819
  const arg = args[i];
802
820
  if (arg.startsWith("--")) {
@@ -826,6 +844,12 @@ function parseCliArgs(args, options = {}) {
826
844
  i = nextIndex;
827
845
  break;
828
846
  }
847
+ case "frame": {
848
+ const { value, nextIndex } = readFlagValue(args, i, inline);
849
+ frame = parseFrameOrThrow(value);
850
+ i = nextIndex;
851
+ break;
852
+ }
829
853
  default:
830
854
  throw new Error(`Unknown flag: ${flag}`);
831
855
  }
@@ -853,9 +877,11 @@ function parseCliArgs(args, options = {}) {
853
877
  longitude,
854
878
  elevationMeters: elevation
855
879
  } : void 0;
880
+ const resolvedFrame = frame ?? (observer ? "observer" : "celestial_up");
856
881
  return {
857
882
  date,
858
- observer
883
+ observer,
884
+ frame: resolvedFrame
859
885
  };
860
886
  }
861
887
 
@@ -864,7 +890,7 @@ function main(argv = process.argv.slice(2)) {
864
890
  try {
865
891
  const args = parseCliArgs(argv);
866
892
  const moonState = getMoonState(args.date, args.observer);
867
- const asciiMoon = renderMoon(moonState);
893
+ const asciiMoon = renderMoon(moonState, { frame: args.frame });
868
894
  console.log(asciiMoon);
869
895
  } catch (error) {
870
896
  const message = error instanceof Error ? error.message : String(error);
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var h=require('astronomy-engine');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var h__namespace=/*#__PURE__*/_interopNamespace(h);var s=h__namespace.default??h__namespace;function X($,g){let n=new Date($.getTime());return n.setDate(n.getDate()+g),n}function k($){return ($%360+360)%360}function N($){let g=s.GeoVector(s.Body.Sun,$,true),n=s.GeoVector(s.Body.Moon,$,true),B=s.EquatorFromVector(g),t=s.EquatorFromVector(n),R=(B.ra-t.ra)*15*s.DEG2RAD,r=t.dec*s.DEG2RAD,a=B.dec*s.DEG2RAD,o=Math.sin(R),i=Math.cos(R),e=o,l=Math.cos(r)*Math.tan(a)-Math.sin(r)*i,A=Math.atan2(e,l)*s.RAD2DEG;return k(A)}function Y($){let g=($%24+24)%24;return g>12&&(g-=24),g}function G($){let g=s.Illumination(s.Body.Moon,$).phase_fraction;return s.Illumination(s.Body.Moon,X($,1)).phase_fraction>g}function H($,g,n){let B=s.SiderealTime($),t=g.longitude/15,R=Y(t+B-n.ra)*15*s.DEG2RAD,r=g.latitude*s.DEG2RAD,a=n.dec*s.DEG2RAD,o=Math.sin(R),i=Math.tan(r)*Math.cos(a)-Math.sin(a)*Math.cos(R);return Math.atan2(o,i)*s.RAD2DEG}function v($,g){let n=new s.Observer(g.latitude,g.longitude,g.elevationMeters??0),B=s.Equator(s.Body.Moon,$,n,true,true),t=s.Horizon($,n,B.ra,B.dec,"normal");return {azimuth:k(t.azimuth),altitude:t.altitude,parallacticAngle:H($,g,B)}}function J($,g){let n=s.Illumination(s.Body.Moon,$),B=s.Libration($);return {date:$,phase:{phaseAngleDeg:n.phase_angle,illuminatedFraction:n.phase_fraction,isWaxing:G($),brightLimbAngle:N($)},size:{distanceKm:B.dist_km,angularDiameterDeg:B.diam_deg},libration:{elon:B.elon,elat:B.elat},position:g?v($,g):void 0}}function V($){let{phaseAngleDeg:g,illuminatedFraction:n}=$.phase,B=$.phase.isWaxing??g>90,t=(g%360+360)%360,_=t>180?360-t:t,R=10,r=10,a=8,o=.98,i=.02,e=.02;return _<=R||n>=o?"Full Moon":_>=180-r||n<=i?"New Moon":Math.abs(_-90)<=a||Math.abs(n-.5)<=e?B?"First Quarter":"Last Quarter":_<90?B?"Waxing Gibbous":"Waning Gibbous":B?"Waxing Crescent":"Waning Crescent"}var T={moons:[{index:0,distance_km:405493.5,libration_elat:-0.888,libration_elon:-0.412,ascii:`
1
+ 'use strict';var z=require('astronomy-engine');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var z__namespace=/*#__PURE__*/_interopNamespace(z);var o=z__namespace.default??z__namespace;function Y($,g){let n=new Date($.getTime());return n.setDate(n.getDate()+g),n}function j($){return ($%360+360)%360}function G($){let g=o.GeoVector(o.Body.Sun,$,true),n=o.GeoVector(o.Body.Moon,$,true),_=o.EquatorFromVector(g),t=o.EquatorFromVector(n),B=(_.ra-t.ra)*15*o.DEG2RAD,e=t.dec*o.DEG2RAD,s=_.dec*o.DEG2RAD,a=Math.sin(B),i=Math.cos(B),r=a,l=Math.cos(e)*Math.tan(s)-Math.sin(e)*i,m=Math.atan2(r,l)*o.RAD2DEG;return j(m)}function H($){let g=($%24+24)%24;return g>12&&(g-=24),g}function v($){let g=o.Illumination(o.Body.Moon,$).phase_fraction;return o.Illumination(o.Body.Moon,Y($,1)).phase_fraction>g}function J($,g,n){let _=o.SiderealTime($),t=g.longitude/15,B=H(t+_-n.ra)*15*o.DEG2RAD,e=g.latitude*o.DEG2RAD,s=n.dec*o.DEG2RAD,a=Math.sin(B),i=Math.tan(e)*Math.cos(s)-Math.sin(s)*Math.cos(B);return Math.atan2(a,i)*o.RAD2DEG}function V($,g){let n=new o.Observer(g.latitude,g.longitude,g.elevationMeters??0),_=o.Equator(o.Body.Moon,$,n,true,true),t=o.Horizon($,n,_.ra,_.dec,"normal");return {azimuth:j(t.azimuth),altitude:t.altitude,parallacticAngle:J($,g,_)}}function Q($,g){let n=o.Illumination(o.Body.Moon,$),_=o.Libration($);return {date:$,phase:{phaseAngleDeg:n.phase_angle,illuminatedFraction:n.phase_fraction,isWaxing:v($),brightLimbAngle:G($)},size:{distanceKm:_.dist_km,angularDiameterDeg:_.diam_deg},libration:{elon:_.elon,elat:_.elat},position:g?V($,g):void 0}}function I($){let{phaseAngleDeg:g,illuminatedFraction:n}=$.phase,_=$.phase.isWaxing??g>90,t=(g%360+360)%360,R=t>180?360-t:t,B=10,e=10,s=8,a=.98,i=.02,r=.02;return R<=B||n>=a?"Full Moon":R>=180-e||n<=i?"New Moon":Math.abs(R-90)<=s||Math.abs(n-.5)<=r?_?"First Quarter":"Last Quarter":R<90?_?"Waxing Gibbous":"Waning Gibbous":_?"Waxing Crescent":"Waning Crescent"}var Z={moons:[{index:0,distance_km:405493.5,libration_elat:-0.888,libration_elon:-0.412,ascii:`
2
2
 
3
3
  ._ . - .
4
4
  ,_++> a, +. \`-.
@@ -894,12 +894,12 @@
894
894
  'FFF'"Z"@MGR^^'\`
895
895
 
896
896
 
897
- `}]};var c=60,d=29,L=-45;function I($){let g=$.split(`
898
- `),n=1/0,B=-1/0,t=1/0,_=-1/0;if(g.forEach((a,o)=>{let i=a.search(/\S/);if(i!==-1){let e=a.search(/\s+$/);n=Math.min(n,i),B=Math.max(B,e===-1?a.length-1:e-1),t===1/0&&(t=o),_=o;}}),n===1/0)return {width:c,height:d,centerX:Math.floor(c/2),centerY:Math.floor(d/2)};let R=B-n+1,r=_-t+1;return {width:R,height:r,centerX:n+Math.floor(R/2),centerY:t+Math.floor(r/2)}}function P($,g,n){return Math.min(n,Math.max(g,$))}function K($){return $*Math.PI/180}function S($,g,n,B=0){let t=K($),_=K(B),R;g!==void 0?R=K(g):R=K(n?270:90);let r=-Math.sin(R),a=-Math.cos(R),o=r*Math.sin(t),i=a*Math.sin(t),e=Math.cos(t),l=i*Math.cos(_)-e*Math.sin(_),A=i*Math.sin(_)+e*Math.cos(_);i=l,e=A;let W=Math.sqrt(o*o+i*i+e*e);return {sx:o/W,sy:i/W,sz:e/W}}function q($,g,n,B,t){let _=1/c,R=1/d,r=[-0.5,-0.25,0,.25,.5],a=0,o=0;for(let i of r)for(let e of r){let l=$+i*_,A=g+e*R,W=l*l+A*A;if(W>1)continue;let w=Math.sqrt(Math.max(0,1-W)),b=l*n+A*B+w*t;a+=Math.max(0,b),o++;}return o===0?0:a/o}function C($){let B=0,t=1/0;for(let _=0;_<T.moons.length;_++){let R=T.moons[_],r=Math.abs(R.distance_km-$.size.distanceKm)*1,a=Math.abs(R.libration_elat-$.libration.elat)*1e4,o=Math.abs(R.libration_elon-$.libration.elon)*1e4,i=r+a+o;i<t&&(t=i,B=_);}return T.moons[B]}var j=22/10;function p($,g,n,B){let t=(g%360+360)%360;if(Math.abs(t)<.1)return $;let _=$.split(`
899
- `),R=_.length,r=_[0]?.length??0,a=n??(r-1)/2,o=B??(R-1)/2,i=t*Math.PI/180,e=Math.cos(i),l=Math.sin(i),A=Array.from({length:R},()=>Array(r).fill(" "));for(let W=0;W<R;W++)for(let w=0;w<r;w++){let b=w-a,x=(W-o)*j,f=b*e-x*l,M=b*l+x*e,y=Math.round(f+a),u=Math.round(M/j+o);if(y>=0&&y<r&&u>=0&&u<R){let E=_[u]?.[y]??" ";A[W][w]=E;}}return A.map(W=>W.join("")).join(`
900
- `)}function U($,g={}){let B=(g??{}).showHorizon!==false,t=C($),_=I(t.ascii),R=t.ascii;Math.abs(L)>.1&&(R=p(R,L,_.centerX,_.centerY));let r=R.split(`
901
- `),{sx:a,sy:o,sz:i}=S($.phase.phaseAngleDeg,$.phase.brightLimbAngle,$.phase.isWaxing,$.libration.elat),e=Array.from({length:d},()=>Array(c).fill(0)),l=Array.from({length:d},()=>Array(c).fill(-1)),A=Array.from({length:d},()=>Array(c).fill(false)),W=0,w=0;for(let M=0;M<d;M++)for(let y=0;y<c;y++){let u=y-_.centerX,E=M-_.centerY,m=u/(_.width/2),F=E/(_.height/2),Z=m*m+F*F;if(Z>1){e[M][y]=0,l[M][y]=-1;continue}A[M][y]=true,W++;let z=q(m,F,a,o,i);e[M][y]=z,z>0&&w++;let D=Math.sqrt(Math.max(0,1-Z));l[M][y]=m*a+F*o+D*i;}let b=Array.from({length:d},()=>Array(c).fill(false));if(w>0)for(let M=0;M<d;M++)for(let y=0;y<c;y++)b[M][y]=e[M][y]>0;else {let M=P($.phase.illuminatedFraction??0,0,1),y=Math.max(1,Math.round(M*W)),u=[];for(let E=0;E<d;E++)for(let m=0;m<c;m++)A[E][m]&&u.push({ix:m,iy:E,v:l[E][m]});u.sort((E,m)=>m.v-E.v);for(let E=0;E<Math.min(y,u.length);E++){let{ix:m,iy:F}=u[E];b[F][m]=true;}}let x=[];for(let M=0;M<d;M++){let y="",u=r[M]??"";for(let E=0;E<c;E++)b[M][E]?y+=u[E]??" ":y+=" ";x.push(y);}let f=x.join(`
902
- `);if($.position?.parallacticAngle!==void 0){let M=-$.position.parallacticAngle;Math.abs(M)>.1&&(f=p(f,M,_.centerX,_.centerY));}return B?O(f,$,_):f}function O($,g,n){let B=g.position;if(!B||g.size.angularDiameterDeg<=0)return $;let t=B.altitude??0,_=g.size.angularDiameterDeg/2,R=t+_;if(t-_>=0)return $;let a=$.split(`
903
- `),o=g.size.angularDiameterDeg/Math.max(1,n.height),i=n.centerY+t/o;i=Math.round(P(i,0,d-1));let e;return R<=0?e=`${Math.abs(t).toFixed(1).replace(/\.0$/,"")}-deg-below-horizon`:e="horizon",a[i]=$$(e),a.join(`
904
- `)}function $$($){let n=`--${$.trim().replace(/\s+/g,"-")}--`;if(n.length>c&&(n=n.slice(0,c)),n.length===c)return n;let B=c-n.length,t=Math.floor(B/2),_=B-t;return "-".repeat(t)+n+"-".repeat(_)}exports.getMoonPhase=V;exports.getMoonState=J;exports.renderMoon=U;//# sourceMappingURL=index.cjs.map
897
+ `}]};var c=60,A=29,p=-45;function q($){let g=$.split(`
898
+ `),n=1/0,_=-1/0,t=1/0,R=-1/0;if(g.forEach((s,a)=>{let i=s.search(/\S/);if(i!==-1){let r=s.search(/\s+$/);n=Math.min(n,i),_=Math.max(_,r===-1?s.length-1:r-1),t===1/0&&(t=a),R=a;}}),n===1/0)return {width:c,height:A,centerX:Math.floor(c/2),centerY:Math.floor(A/2)};let B=_-n+1,e=R-t+1;return {width:B,height:e,centerX:n+Math.floor(B/2),centerY:t+Math.floor(e/2)}}function X($,g,n){return Math.min(n,Math.max(g,$))}function T($){return $*Math.PI/180}function C($,g,n,_=0){let t=T($),R=T(_),B;g!==void 0?B=T(g):B=T(n?270:90);let e=-Math.sin(B),s=-Math.cos(B),a=e*Math.sin(t),i=s*Math.sin(t),r=Math.cos(t),l=i*Math.cos(R)-r*Math.sin(R),m=i*Math.sin(R)+r*Math.cos(R);i=l,r=m;let W=Math.sqrt(a*a+i*i+r*r);return {sx:a/W,sy:i/W,sz:r/W}}function U($,g,n,_,t){let R=1/c,B=1/A,e=[-0.5,-0.25,0,.25,.5],s=0,a=0;for(let i of e)for(let r of e){let l=$+i*R,m=g+r*B,W=l*l+m*m;if(W>1)continue;let d=Math.sqrt(Math.max(0,1-W)),f=l*n+m*_+d*t;s+=Math.max(0,f),a++;}return a===0?0:s/a}function O($){let _=0,t=1/0;for(let R=0;R<Z.moons.length;R++){let B=Z.moons[R],e=Math.abs(B.distance_km-$.size.distanceKm)*1,s=Math.abs(B.libration_elat-$.libration.elat)*1e4,a=Math.abs(B.libration_elon-$.libration.elon)*1e4,i=e+s+a;i<t&&(t=i,_=R);}return Z.moons[_]}var P=22/10;function D($,g,n,_){let t=(g%360+360)%360;if(Math.abs(t)<.1)return $;let R=$.split(`
899
+ `),B=R.length,e=R[0]?.length??0,s=n??(e-1)/2,a=_??(B-1)/2,i=t*Math.PI/180,r=Math.cos(i),l=Math.sin(i),m=Array.from({length:B},()=>Array(e).fill(" "));for(let W=0;W<B;W++)for(let d=0;d<e;d++){let f=d-s,F=(W-a)*P,h=f*r-F*l,x=f*l+F*r,w=Math.round(h+s),M=Math.round(x/P+a);if(w>=0&&w<e&&M>=0&&M<B){let y=R[M]?.[w]??" ";m[W][d]=y;}}return m.map(W=>W.join("")).join(`
900
+ `)}function $$($,g){return g.frame!==void 0?g.frame:$.position!==void 0?"observer":"celestial_up"}function n$($,g={}){let n=g??{},_=$$($,n),t=n.showHorizon??_==="observer",R=O($),B=q(R.ascii),e=R.ascii;Math.abs(p)>.1&&(e=D(e,p,B.centerX,B.centerY));let s=e.split(`
901
+ `),{sx:a,sy:i,sz:r}=C($.phase.phaseAngleDeg,$.phase.brightLimbAngle,$.phase.isWaxing,$.libration.elat),l=Array.from({length:A},()=>Array(c).fill(0)),m=Array.from({length:A},()=>Array(c).fill(-1)),W=Array.from({length:A},()=>Array(c).fill(false)),d=0,f=0;for(let M=0;M<A;M++)for(let y=0;y<c;y++){let b=y-B.centerX,E=M-B.centerY,u=b/(B.width/2),K=E/(B.height/2),k=u*u+K*K;if(k>1){l[M][y]=0,m[M][y]=-1;continue}W[M][y]=true,d++;let L=U(u,K,a,i,r);l[M][y]=L,L>0&&f++;let N=Math.sqrt(Math.max(0,1-k));m[M][y]=u*a+K*i+N*r;}let F=Array.from({length:A},()=>Array(c).fill(false));if(f>0)for(let M=0;M<A;M++)for(let y=0;y<c;y++)F[M][y]=l[M][y]>0;else {let M=X($.phase.illuminatedFraction??0,0,1),y=Math.max(1,Math.round(M*d)),b=[];for(let E=0;E<A;E++)for(let u=0;u<c;u++)W[E][u]&&b.push({ix:u,iy:E,v:m[E][u]});b.sort((E,u)=>u.v-E.v);for(let E=0;E<Math.min(y,b.length);E++){let{ix:u,iy:K}=b[E];F[K][u]=true;}}let h=[];for(let M=0;M<A;M++){let y="",b=s[M]??"";for(let E=0;E<c;E++)F[M][E]?y+=b[E]??" ":y+=" ";h.push(y);}let x=h.join(`
902
+ `),w=0;return _==="celestial_down"?w=180:_==="observer"&&$.position?.parallacticAngle!==void 0&&(w=-$.position.parallacticAngle),Math.abs(w)>.1&&(x=D(x,w,B.centerX,B.centerY)),t?g$(x,$,B):x}function g$($,g,n){let _=g.position;if(!_||g.size.angularDiameterDeg<=0)return $;let t=_.altitude??0,R=g.size.angularDiameterDeg/2,B=t+R;if(t-R>=0)return $;let s=$.split(`
903
+ `),a=g.size.angularDiameterDeg/Math.max(1,n.height),i=n.centerY+t/a;i=Math.round(X(i,0,A-1));let r;return B<=0?r=`${Math.abs(t).toFixed(1).replace(/\.0$/,"")}-deg-below-horizon`:r="horizon",s[i]=_$(r),s.join(`
904
+ `)}function _$($){let n=`--${$.trim().replace(/\s+/g,"-")}--`;if(n.length>c&&(n=n.slice(0,c)),n.length===c)return n;let _=c-n.length,t=Math.floor(_/2),R=_-t;return "-".repeat(t)+n+"-".repeat(R)}exports.getMoonPhase=I;exports.getMoonState=Q;exports.renderMoon=n$;//# sourceMappingURL=index.cjs.map
905
905
  //# sourceMappingURL=index.cjs.map