chart2txt 0.5.2 → 0.6.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.
Files changed (39) hide show
  1. package/dist/chart2txt.min.js +1 -1
  2. package/dist/config/ChartSettings.d.ts +1 -0
  3. package/dist/config/ChartSettings.js +1 -0
  4. package/dist/constants.js +4 -2
  5. package/dist/core/aspectPatterns.d.ts +5 -0
  6. package/dist/core/aspectPatterns.js +444 -0
  7. package/dist/core/aspects.js +94 -9
  8. package/dist/core/astrology.d.ts +8 -2
  9. package/dist/core/astrology.js +23 -6
  10. package/dist/core/dignities.d.ts +27 -0
  11. package/dist/core/dignities.js +136 -0
  12. package/dist/core/dispositors.d.ts +22 -0
  13. package/dist/core/dispositors.js +143 -0
  14. package/dist/core/signDistributions.d.ts +31 -0
  15. package/dist/core/signDistributions.js +150 -0
  16. package/dist/formatters/text/sections/angles.js +4 -4
  17. package/dist/formatters/text/sections/aspectPatterns.d.ts +7 -0
  18. package/dist/formatters/text/sections/aspectPatterns.js +175 -0
  19. package/dist/formatters/text/sections/aspects.js +7 -4
  20. package/dist/formatters/text/sections/birthdata.js +1 -1
  21. package/dist/formatters/text/sections/dispositors.d.ts +7 -0
  22. package/dist/formatters/text/sections/dispositors.js +20 -0
  23. package/dist/formatters/text/sections/houseOverlays.js +10 -34
  24. package/dist/formatters/text/sections/houses.d.ts +6 -0
  25. package/dist/formatters/text/sections/houses.js +36 -0
  26. package/dist/formatters/text/sections/planets.js +11 -26
  27. package/dist/formatters/text/sections/signDistributions.d.ts +25 -0
  28. package/dist/formatters/text/sections/signDistributions.js +67 -0
  29. package/dist/formatters/text/textFormatter.js +37 -3
  30. package/dist/types.d.ts +61 -0
  31. package/dist/utils/formatting.d.ts +6 -0
  32. package/dist/utils/formatting.js +13 -0
  33. package/dist/utils/houseCalculations.d.ts +13 -0
  34. package/dist/utils/houseCalculations.js +65 -0
  35. package/dist/utils/precision.d.ts +49 -0
  36. package/dist/utils/precision.js +71 -0
  37. package/dist/utils/validation.d.ts +37 -0
  38. package/dist/utils/validation.js +181 -0
  39. package/package.json +2 -1
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeSignDistributions = analyzeSignDistributions;
4
+ exports.formatElementDistribution = formatElementDistribution;
5
+ exports.formatModalityDistribution = formatModalityDistribution;
6
+ exports.formatPolarityDistribution = formatPolarityDistribution;
7
+ const astrology_1 = require("./astrology");
8
+ // Sign classifications
9
+ const SIGN_ELEMENTS = {
10
+ Aries: 'Fire',
11
+ Leo: 'Fire',
12
+ Sagittarius: 'Fire',
13
+ Taurus: 'Earth',
14
+ Virgo: 'Earth',
15
+ Capricorn: 'Earth',
16
+ Gemini: 'Air',
17
+ Libra: 'Air',
18
+ Aquarius: 'Air',
19
+ Cancer: 'Water',
20
+ Scorpio: 'Water',
21
+ Pisces: 'Water',
22
+ };
23
+ const SIGN_MODALITIES = {
24
+ Aries: 'Cardinal',
25
+ Cancer: 'Cardinal',
26
+ Libra: 'Cardinal',
27
+ Capricorn: 'Cardinal',
28
+ Taurus: 'Fixed',
29
+ Leo: 'Fixed',
30
+ Scorpio: 'Fixed',
31
+ Aquarius: 'Fixed',
32
+ Gemini: 'Mutable',
33
+ Virgo: 'Mutable',
34
+ Sagittarius: 'Mutable',
35
+ Pisces: 'Mutable',
36
+ };
37
+ const SIGN_POLARITIES = {
38
+ Aries: 'Masculine',
39
+ Gemini: 'Masculine',
40
+ Leo: 'Masculine',
41
+ Libra: 'Masculine',
42
+ Sagittarius: 'Masculine',
43
+ Aquarius: 'Masculine',
44
+ Taurus: 'Feminine',
45
+ Cancer: 'Feminine',
46
+ Virgo: 'Feminine',
47
+ Scorpio: 'Feminine',
48
+ Capricorn: 'Feminine',
49
+ Pisces: 'Feminine',
50
+ };
51
+ /**
52
+ * Analyzes the distribution of planets across elements, modalities, and polarities
53
+ * @param planets Array of planet points
54
+ * @param includeAscendant Optional ascendant degree to include in analysis
55
+ * @returns Sign distribution analysis
56
+ */
57
+ function analyzeSignDistributions(planets, includeAscendant) {
58
+ const elements = {
59
+ Fire: [],
60
+ Earth: [],
61
+ Air: [],
62
+ Water: [],
63
+ };
64
+ const modalities = {
65
+ Cardinal: 0,
66
+ Fixed: 0,
67
+ Mutable: 0,
68
+ };
69
+ const polarities = {
70
+ Masculine: 0,
71
+ Feminine: 0,
72
+ };
73
+ // Process planets
74
+ planets.forEach((planet) => {
75
+ const sign = (0, astrology_1.getDegreeSign)(planet.degree);
76
+ const element = SIGN_ELEMENTS[sign];
77
+ const modality = SIGN_MODALITIES[sign];
78
+ const polarity = SIGN_POLARITIES[sign];
79
+ if (element) {
80
+ elements[element].push(planet.name);
81
+ }
82
+ if (modality) {
83
+ modalities[modality]++;
84
+ }
85
+ if (polarity) {
86
+ polarities[polarity]++;
87
+ }
88
+ });
89
+ // Process ascendant if provided
90
+ if (includeAscendant !== undefined) {
91
+ const ascSign = (0, astrology_1.getDegreeSign)(includeAscendant);
92
+ const ascElement = SIGN_ELEMENTS[ascSign];
93
+ const ascModality = SIGN_MODALITIES[ascSign];
94
+ const ascPolarity = SIGN_POLARITIES[ascSign];
95
+ if (ascElement) {
96
+ elements[ascElement].push('Ascendant');
97
+ }
98
+ if (ascModality) {
99
+ modalities[ascModality]++;
100
+ }
101
+ if (ascPolarity) {
102
+ polarities[ascPolarity]++;
103
+ }
104
+ }
105
+ return { elements, modalities, polarities };
106
+ }
107
+ /**
108
+ * Formats element distribution for display
109
+ * @param elements Element distribution data
110
+ * @returns Array of formatted strings
111
+ */
112
+ function formatElementDistribution(elements) {
113
+ const output = [];
114
+ Object.entries(elements).forEach(([element, planets]) => {
115
+ if (planets.length > 0) {
116
+ const planetList = planets.join(', ');
117
+ output.push(`${element}: ${planets.length} (${planetList})`);
118
+ }
119
+ });
120
+ return output;
121
+ }
122
+ /**
123
+ * Formats modality distribution for display
124
+ * @param modalities Modality distribution data
125
+ * @returns Array of formatted strings
126
+ */
127
+ function formatModalityDistribution(modalities) {
128
+ const output = [];
129
+ Object.entries(modalities).forEach(([modality, count]) => {
130
+ if (count > 0) {
131
+ output.push(`${modality}: ${count}`);
132
+ }
133
+ });
134
+ return output;
135
+ }
136
+ /**
137
+ * Formats polarity distribution for display
138
+ * @param polarities Polarity distribution data
139
+ * @returns Array of formatted strings
140
+ */
141
+ function formatPolarityDistribution(polarities) {
142
+ const output = [];
143
+ if (polarities['Masculine'] > 0) {
144
+ output.push(`Masculine (Active): ${polarities['Masculine']}`);
145
+ }
146
+ if (polarities['Feminine'] > 0) {
147
+ output.push(`Feminine (Receptive): ${polarities['Feminine']}`);
148
+ }
149
+ return output;
150
+ }
@@ -11,16 +11,16 @@ const astrology_1 = require("../../../core/astrology");
11
11
  function generateAnglesOutput(ascDegree, mcDegree) {
12
12
  const output = ['[ANGLES]'];
13
13
  if (ascDegree !== undefined) {
14
- output.push(`ASC: ${Math.floor((0, astrology_1.getDegreeInSign)(ascDegree))}° ${(0, astrology_1.getDegreeSign)(ascDegree)}`);
14
+ output.push(`Ascendant: ${Math.floor((0, astrology_1.getDegreeInSign)(ascDegree))}° ${(0, astrology_1.getDegreeSign)(ascDegree)}`);
15
15
  }
16
16
  else {
17
- output.push('ASC: Not available');
17
+ output.push('Ascendant: Not available');
18
18
  }
19
19
  if (mcDegree !== undefined) {
20
- output.push(`MC: ${Math.floor((0, astrology_1.getDegreeInSign)(mcDegree))}° ${(0, astrology_1.getDegreeSign)(mcDegree)}`);
20
+ output.push(`Midheaven: ${Math.floor((0, astrology_1.getDegreeInSign)(mcDegree))}° ${(0, astrology_1.getDegreeSign)(mcDegree)}`);
21
21
  }
22
22
  else {
23
- output.push('MC: Not available');
23
+ output.push('Midheaven: Not available');
24
24
  }
25
25
  return output;
26
26
  }
@@ -0,0 +1,7 @@
1
+ import { AspectPattern } from '../../../types';
2
+ /**
3
+ * Generates the [ASPECT PATTERNS] section of the chart output.
4
+ * @param patterns Array of detected aspect patterns
5
+ * @returns An array of strings for the output.
6
+ */
7
+ export declare function generateAspectPatternsOutput(patterns: AspectPattern[]): string[];
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateAspectPatternsOutput = generateAspectPatternsOutput;
4
+ const astrology_1 = require("../../../core/astrology");
5
+ const formatting_1 = require("../../../utils/formatting");
6
+ /**
7
+ * Format a planet position for display
8
+ */
9
+ function formatPlanetPosition(planet) {
10
+ const degInSign = Math.floor((0, astrology_1.getDegreeInSign)(planet.degree));
11
+ const houseStr = planet.house ? ` (${(0, formatting_1.getOrdinal)(planet.house)} house)` : '';
12
+ return `${planet.name} ${degInSign}° ${planet.sign}${houseStr}`;
13
+ }
14
+ /**
15
+ * Format a T-Square pattern
16
+ */
17
+ function formatTSquare(pattern) {
18
+ if (pattern.type !== 'T-Square')
19
+ return [];
20
+ const output = ['T-Square:'];
21
+ output.push(` - Apex: ${formatPlanetPosition(pattern.apex)}`);
22
+ output.push(` - Opposition: ${formatPlanetPosition(pattern.opposition[0])} - ${formatPlanetPosition(pattern.opposition[1])}`);
23
+ output.push(` - Mode: ${pattern.mode}`);
24
+ output.push(` - Average orb: ${pattern.averageOrb.toFixed(1)}°`);
25
+ output.push('');
26
+ return output;
27
+ }
28
+ /**
29
+ * Format a Grand Trine pattern
30
+ */
31
+ function formatGrandTrine(pattern) {
32
+ if (pattern.type !== 'Grand Trine')
33
+ return [];
34
+ const output = ['Grand Trine:'];
35
+ pattern.planets.forEach((planet, index) => {
36
+ output.push(` - Planet ${index + 1}: ${formatPlanetPosition(planet)}`);
37
+ });
38
+ output.push(` - Element: ${pattern.element}`);
39
+ output.push(` - Average orb: ${pattern.averageOrb.toFixed(1)}°`);
40
+ output.push('');
41
+ return output;
42
+ }
43
+ /**
44
+ * Format a Stellium pattern
45
+ */
46
+ function formatStellium(pattern) {
47
+ if (pattern.type !== 'Stellium')
48
+ return [];
49
+ const output = ['Stellium:'];
50
+ const planetNames = pattern.planets.map((p) => p.name).join(', ');
51
+ output.push(` - Planets: ${planetNames}`);
52
+ if (pattern.sign) {
53
+ output.push(` - Sign: ${pattern.sign}`);
54
+ }
55
+ if (pattern.houses.length > 0) {
56
+ const houseStr = pattern.houses.length === 1
57
+ ? `${(0, formatting_1.getOrdinal)(pattern.houses[0])}`
58
+ : pattern.houses.map((h) => (0, formatting_1.getOrdinal)(h)).join('-');
59
+ output.push(` - Houses: ${houseStr}`);
60
+ }
61
+ output.push(` - Span: ${pattern.span.toFixed(1)}°`);
62
+ output.push('');
63
+ return output;
64
+ }
65
+ /**
66
+ * Format a Grand Cross pattern
67
+ */
68
+ function formatGrandCross(pattern) {
69
+ if (pattern.type !== 'Grand Cross')
70
+ return [];
71
+ const output = ['Grand Cross:'];
72
+ pattern.planets.forEach((planet, index) => {
73
+ output.push(` - Planet ${index + 1}: ${formatPlanetPosition(planet)}`);
74
+ });
75
+ output.push(` - Mode: ${pattern.mode}`);
76
+ output.push(` - Average orb: ${pattern.averageOrb.toFixed(1)}°`);
77
+ output.push('');
78
+ return output;
79
+ }
80
+ /**
81
+ * Format a Yod pattern
82
+ */
83
+ function formatYod(pattern) {
84
+ if (pattern.type !== 'Yod')
85
+ return [];
86
+ const output = ['Yod:'];
87
+ output.push(` - Apex: ${formatPlanetPosition(pattern.apex)}`);
88
+ output.push(` - Base planet 1: ${formatPlanetPosition(pattern.base[0])}`);
89
+ output.push(` - Base planet 2: ${formatPlanetPosition(pattern.base[1])}`);
90
+ output.push(` - Average orb: ${pattern.averageOrb.toFixed(1)}°`);
91
+ output.push('');
92
+ return output;
93
+ }
94
+ /**
95
+ * Format a Mystic Rectangle pattern
96
+ */
97
+ function formatMysticRectangle(pattern) {
98
+ if (pattern.type !== 'Mystic Rectangle')
99
+ return [];
100
+ const output = ['Mystic Rectangle:'];
101
+ output.push(` - Opposition 1: ${formatPlanetPosition(pattern.oppositions[0][0])} - ${formatPlanetPosition(pattern.oppositions[0][1])}`);
102
+ output.push(` - Opposition 2: ${formatPlanetPosition(pattern.oppositions[1][0])} - ${formatPlanetPosition(pattern.oppositions[1][1])}`);
103
+ output.push(` - Average orb: ${pattern.averageOrb.toFixed(1)}°`);
104
+ output.push('');
105
+ return output;
106
+ }
107
+ /**
108
+ * Format a Kite pattern
109
+ */
110
+ function formatKite(pattern) {
111
+ if (pattern.type !== 'Kite')
112
+ return [];
113
+ const output = ['Kite:'];
114
+ const grandTrineStr = pattern.grandTrine.map((p) => p.name).join(', ');
115
+ output.push(` - Grand Trine planets: ${grandTrineStr}`);
116
+ output.push(` - Opposition planet: ${formatPlanetPosition(pattern.opposition)}`);
117
+ output.push(` - Average orb: ${pattern.averageOrb.toFixed(1)}°`);
118
+ output.push('');
119
+ return output;
120
+ }
121
+ /**
122
+ * Generates the [ASPECT PATTERNS] section of the chart output.
123
+ * @param patterns Array of detected aspect patterns
124
+ * @returns An array of strings for the output.
125
+ */
126
+ function generateAspectPatternsOutput(patterns) {
127
+ const output = ['[ASPECT PATTERNS]'];
128
+ if (patterns.length === 0) {
129
+ output.push('No aspect patterns detected.');
130
+ return output;
131
+ }
132
+ // Sort patterns by type for consistent output
133
+ const sortOrder = [
134
+ 'T-Square',
135
+ 'Grand Trine',
136
+ 'Grand Cross',
137
+ 'Stellium',
138
+ 'Yod',
139
+ 'Mystic Rectangle',
140
+ 'Kite',
141
+ ];
142
+ const sortedPatterns = patterns.sort((a, b) => {
143
+ return sortOrder.indexOf(a.type) - sortOrder.indexOf(b.type);
144
+ });
145
+ sortedPatterns.forEach((pattern) => {
146
+ switch (pattern.type) {
147
+ case 'T-Square':
148
+ output.push(...formatTSquare(pattern));
149
+ break;
150
+ case 'Grand Trine':
151
+ output.push(...formatGrandTrine(pattern));
152
+ break;
153
+ case 'Stellium':
154
+ output.push(...formatStellium(pattern));
155
+ break;
156
+ case 'Grand Cross':
157
+ output.push(...formatGrandCross(pattern));
158
+ break;
159
+ case 'Yod':
160
+ output.push(...formatYod(pattern));
161
+ break;
162
+ case 'Mystic Rectangle':
163
+ output.push(...formatMysticRectangle(pattern));
164
+ break;
165
+ case 'Kite':
166
+ output.push(...formatKite(pattern));
167
+ break;
168
+ }
169
+ });
170
+ // Remove trailing empty line
171
+ if (output[output.length - 1] === '') {
172
+ output.pop();
173
+ }
174
+ return output;
175
+ }
@@ -24,15 +24,15 @@ p2IsTransit = false) {
24
24
  });
25
25
  if (categoryAspects.length > 0) {
26
26
  aspectsFoundInAnyCategory = true;
27
- let orbRangeStr = `orb < ${category.maxOrb.toFixed(1)}°`;
27
+ let orbRangeStr = `orb under ${category.maxOrb.toFixed(1)}°`;
28
28
  if (category.minOrb !== undefined) {
29
29
  // Ensure minOrb is less than maxOrb for sensible range string
30
30
  orbRangeStr =
31
31
  category.minOrb < category.maxOrb
32
32
  ? `orb ${category.minOrb.toFixed(1)}-${category.maxOrb.toFixed(1)}°`
33
- : `orb > ${category.minOrb.toFixed(1)}° & < ${category.maxOrb.toFixed(1)}°`; // Fallback for unusual category def
33
+ : `orb over ${category.minOrb.toFixed(1)}° & under ${category.maxOrb.toFixed(1)}°`; // Fallback for unusual category def
34
34
  }
35
- output.push(`[${category.name.toUpperCase()}: ${orbRangeStr}]`);
35
+ output.push(`[${category.name}: ${orbRangeStr}]`);
36
36
  categoryAspects.sort((a, b) => a.orb - b.orb); // Sort by orb tightness
37
37
  categoryAspects.forEach((asp) => {
38
38
  const p1NameStr = p1ChartName
@@ -50,7 +50,10 @@ p2IsTransit = false) {
50
50
  p2NameStr = `${p2ChartName}'s ${asp.planetB}`;
51
51
  }
52
52
  // If neither p2IsTransit nor p2ChartName, it's a natal chart aspect, e.g. "Venus opposition Pluto: 1.2°"
53
- output.push(`${p1NameStr} ${asp.aspectType} ${p2NameStr}: ${asp.orb.toFixed(1)}°`);
53
+ const applicationStr = asp.application && asp.application !== 'exact'
54
+ ? ` (${asp.application})`
55
+ : '';
56
+ output.push(`${p1NameStr} ${asp.aspectType} ${p2NameStr}: ${asp.orb.toFixed(1)}°${applicationStr}`);
54
57
  });
55
58
  }
56
59
  });
@@ -16,6 +16,6 @@ function generateBirthdataOutput(location, timestamp, settings, sectionTitle = '
16
16
  const dateStr = (0, datetime_1.formatDateCustom)(timestamp, settings.dateFormat);
17
17
  const timeStr = (0, datetime_1.formatTime)(timestamp);
18
18
  return [
19
- `${sectionTitle} ${location || 'Unknown Location'}, ${dateStr}, ${timeStr}`,
19
+ `${sectionTitle} ${location || 'Unknown Location'} | ${dateStr} | ${timeStr}`,
20
20
  ];
21
21
  }
@@ -0,0 +1,7 @@
1
+ import { Point } from '../../../types';
2
+ /**
3
+ * Generates the [DISPOSITOR TREE] section of the chart output.
4
+ * @param planets Array of planet points.
5
+ * @returns An array of strings for the output.
6
+ */
7
+ export declare function generateDispositorsOutput(planets: Point[]): string[];
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateDispositorsOutput = generateDispositorsOutput;
4
+ const dispositors_1 = require("../../../core/dispositors");
5
+ /**
6
+ * Generates the [DISPOSITOR TREE] section of the chart output.
7
+ * @param planets Array of planet points.
8
+ * @returns An array of strings for the output.
9
+ */
10
+ function generateDispositorsOutput(planets) {
11
+ const output = ['[DISPOSITOR TREE]'];
12
+ if (planets.length === 0) {
13
+ output.push('No planets available for dispositor analysis.');
14
+ return output;
15
+ }
16
+ const analysis = (0, dispositors_1.analyzeDispositors)(planets);
17
+ const formattedAnalysis = (0, dispositors_1.formatDispositorAnalysis)(analysis);
18
+ output.push(...formattedAnalysis);
19
+ return output;
20
+ }
@@ -1,32 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateHouseOverlaysOutput = generateHouseOverlaysOutput;
4
- // Helper function to determine which house a point falls into
5
- function getHouseForPoint(pointDegree, houseCusps) {
6
- if (!houseCusps || houseCusps.length !== 12) {
7
- // console.error("Invalid or missing houseCusps array for getHouseForPoint.");
8
- return 0; // Indicate failure or inability to calculate
9
- }
10
- for (let i = 0; i < 12; i++) {
11
- const cuspStart = houseCusps[i]; // Cusp of current house (e.g., for House 1, i=0, cuspStart = Cusp 1)
12
- const cuspEnd = houseCusps[(i + 1) % 12]; // Cusp of next house (e.g., for House 1, cuspEnd = Cusp 2)
13
- // Check if the point degree falls between cuspStart and cuspEnd
14
- if (cuspStart < cuspEnd) {
15
- // Normal case: e.g., Cusp1=10, Cusp2=40. Point is between 10 and 40.
16
- if (pointDegree >= cuspStart && pointDegree < cuspEnd) {
17
- return i + 1; // House number is i+1 (cusps are 0-indexed, houses 1-indexed)
18
- }
19
- }
20
- else {
21
- // Wrap-around case: e.g., Cusp12=330, Cusp1=20. Point is >=330 OR <20.
22
- if (pointDegree >= cuspStart || pointDegree < cuspEnd) {
23
- return i + 1; // House number is i+1
24
- }
25
- }
26
- }
27
- // console.warn(`Point ${pointDegree} did not fall into any house with cusps: ${houseCusps.join(', ')}.`);
28
- return 0; // Should ideally not be reached if cusps correctly cover 360 degrees
29
- }
4
+ const formatting_1 = require("../../../utils/formatting");
5
+ const houseCalculations_1 = require("../../../utils/houseCalculations");
30
6
  /**
31
7
  * Generates the [HOUSE OVERLAYS] section for synastry.
32
8
  * @param chart1 The first chart data.
@@ -43,12 +19,12 @@ function generateHouseOverlaysOutput(chart1, chart2, settings) {
43
19
  output.push(`${c1Name}'s planets in ${c2Name}'s houses:`);
44
20
  if (chart1.planets && chart1.planets.length > 0) {
45
21
  chart1.planets.forEach((planet) => {
46
- const houseNumber = getHouseForPoint(planet.degree, chart2.houseCusps);
47
- if (houseNumber > 0) {
48
- output.push(`${planet.name}: House ${houseNumber}`);
22
+ const houseNumber = (0, houseCalculations_1.getHouseForPoint)(planet.degree, chart2.houseCusps);
23
+ if (houseNumber) {
24
+ output.push(`- ${planet.name}: ${(0, formatting_1.getOrdinal)(houseNumber)}`);
49
25
  }
50
26
  else {
51
- output.push(`${planet.name}: (Could not determine house in ${c2Name})`);
27
+ output.push(`- ${planet.name}: (Could not determine house in ${c2Name})`);
52
28
  }
53
29
  });
54
30
  }
@@ -65,12 +41,12 @@ function generateHouseOverlaysOutput(chart1, chart2, settings) {
65
41
  output.push(`${c2Name}'s planets in ${c1Name}'s houses:`);
66
42
  if (chart2.planets && chart2.planets.length > 0) {
67
43
  chart2.planets.forEach((planet) => {
68
- const houseNumber = getHouseForPoint(planet.degree, chart1.houseCusps);
69
- if (houseNumber > 0) {
70
- output.push(`${planet.name}: House ${houseNumber}`);
44
+ const houseNumber = (0, houseCalculations_1.getHouseForPoint)(planet.degree, chart1.houseCusps);
45
+ if (houseNumber) {
46
+ output.push(`- ${planet.name}: ${(0, formatting_1.getOrdinal)(houseNumber)}`);
71
47
  }
72
48
  else {
73
- output.push(`${planet.name}: (Could not determine house in ${c1Name})`);
49
+ output.push(`- ${planet.name}: (Could not determine house in ${c1Name})`);
74
50
  }
75
51
  });
76
52
  }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generates the [HOUSE CUSPS] section of the chart output.
3
+ * @param houseCusps Array of 12 house cusp degrees (0-360), or undefined if not available.
4
+ * @returns An array of strings for the output.
5
+ */
6
+ export declare function generateHousesOutput(houseCusps?: number[]): string[];
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateHousesOutput = generateHousesOutput;
4
+ const astrology_1 = require("../../../core/astrology");
5
+ const formatting_1 = require("../../../utils/formatting");
6
+ /**
7
+ * Generates the [HOUSE CUSPS] section of the chart output.
8
+ * @param houseCusps Array of 12 house cusp degrees (0-360), or undefined if not available.
9
+ * @returns An array of strings for the output.
10
+ */
11
+ function generateHousesOutput(houseCusps) {
12
+ const output = ['[HOUSE CUSPS]'];
13
+ if (!houseCusps || houseCusps.length !== 12) {
14
+ output.push('House cusps not available');
15
+ return output;
16
+ }
17
+ // Format houses in two columns: 1-6 and 7-12
18
+ for (let i = 0; i < 6; i++) {
19
+ const leftHouseIndex = i;
20
+ const rightHouseIndex = i + 6;
21
+ const leftCusp = houseCusps[leftHouseIndex];
22
+ const rightCusp = houseCusps[rightHouseIndex];
23
+ const leftSign = (0, astrology_1.getDegreeSign)(leftCusp);
24
+ const leftDegInSign = Math.floor((0, astrology_1.getDegreeInSign)(leftCusp));
25
+ const leftHouseLabel = (0, formatting_1.getOrdinal)(leftHouseIndex + 1) + ' house';
26
+ const rightSign = (0, astrology_1.getDegreeSign)(rightCusp);
27
+ const rightDegInSign = Math.floor((0, astrology_1.getDegreeInSign)(rightCusp));
28
+ const rightHouseLabel = (0, formatting_1.getOrdinal)(rightHouseIndex + 1) + ' house';
29
+ // Pad the left side to align columns
30
+ const leftPart = `${leftHouseLabel}: ${leftDegInSign}° ${leftSign}`;
31
+ const paddedLeftPart = leftPart.padEnd(24); // Adjust padding as needed
32
+ const rightPart = `${rightHouseLabel}: ${rightDegInSign}° ${rightSign}`;
33
+ output.push(`${paddedLeftPart} ${rightPart}`);
34
+ }
35
+ return output;
36
+ }
@@ -2,28 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generatePlanetsOutput = generatePlanetsOutput;
4
4
  const astrology_1 = require("../../../core/astrology");
5
- // Helper function to determine which house a point falls into
6
- // (Copied from houseOverlays.ts - consider moving to a shared util if used in more places)
7
- function getHouseForPoint(pointDegree, houseCusps) {
8
- if (!houseCusps || houseCusps.length !== 12) {
9
- return 0; // Indicate failure or inability to calculate
10
- }
11
- for (let i = 0; i < 12; i++) {
12
- const cuspStart = houseCusps[i];
13
- const cuspEnd = houseCusps[(i + 1) % 12];
14
- if (cuspStart < cuspEnd) {
15
- if (pointDegree >= cuspStart && pointDegree < cuspEnd) {
16
- return i + 1;
17
- }
18
- }
19
- else {
20
- if (pointDegree >= cuspStart || pointDegree < cuspEnd) {
21
- return i + 1;
22
- }
23
- }
24
- }
25
- return 0; // Should not be reached if cusps cover 360 degrees
26
- }
5
+ const dignities_1 = require("../../../core/dignities");
6
+ const formatting_1 = require("../../../utils/formatting");
7
+ const houseCalculations_1 = require("../../../utils/houseCalculations");
27
8
  /**
28
9
  * Generates the [PLANETS] section of the chart output.
29
10
  * @param planets Array of planet points.
@@ -36,12 +17,16 @@ function generatePlanetsOutput(planets, houseCusps, settings) {
36
17
  planets.forEach((planet) => {
37
18
  const sign = (0, astrology_1.getDegreeSign)(planet.degree);
38
19
  const degInSign = Math.floor((0, astrology_1.getDegreeInSign)(planet.degree));
39
- const retrogradeIndicator = planet.speed !== undefined && planet.speed < 0 ? ' Rx' : '';
20
+ const retrogradeIndicator = planet.speed !== undefined && planet.speed < 0 ? ' Retrograde' : '';
21
+ const dignities = (0, dignities_1.formatPlanetWithDignities)(planet, houseCusps);
40
22
  let line = `${planet.name}: ${degInSign}° ${sign}${retrogradeIndicator}`;
23
+ if (dignities) {
24
+ line += ` ${dignities}`;
25
+ }
41
26
  if (houseCusps && houseCusps.length === 12) {
42
- const houseNumber = getHouseForPoint(planet.degree, houseCusps);
43
- if (houseNumber > 0) {
44
- line += `, House ${houseNumber}`;
27
+ const houseNumber = (0, houseCalculations_1.getHouseForPoint)(planet.degree, houseCusps);
28
+ if (houseNumber) {
29
+ line += `, ${(0, formatting_1.getOrdinal)(houseNumber)} house`;
45
30
  }
46
31
  }
47
32
  output.push(line);
@@ -0,0 +1,25 @@
1
+ import { Point } from '../../../types';
2
+ /**
3
+ * Generates the [ELEMENT DISTRIBUTION] section of the chart output.
4
+ * @param planets Array of planet points.
5
+ * @param chartName Optional chart name for the header.
6
+ * @param ascendant Optional ascendant degree to include in analysis.
7
+ * @returns An array of strings for the output.
8
+ */
9
+ export declare function generateElementDistributionOutput(planets: Point[], chartName?: string, ascendant?: number): string[];
10
+ /**
11
+ * Generates the [MODALITY DISTRIBUTION] section of the chart output.
12
+ * @param planets Array of planet points.
13
+ * @param chartName Optional chart name for the header.
14
+ * @param ascendant Optional ascendant degree to include in analysis.
15
+ * @returns An array of strings for the output.
16
+ */
17
+ export declare function generateModalityDistributionOutput(planets: Point[], chartName?: string, ascendant?: number): string[];
18
+ /**
19
+ * Generates the [POLARITY] section of the chart output.
20
+ * @param planets Array of planet points.
21
+ * @param chartName Optional chart name for the header.
22
+ * @param ascendant Optional ascendant degree to include in analysis.
23
+ * @returns An array of strings for the output.
24
+ */
25
+ export declare function generatePolarityOutput(planets: Point[], chartName?: string, ascendant?: number): string[];