mihrab-methods 0.0.0-stage → 1.0.1

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 (217) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +319 -2
  3. package/certification.json +120 -0
  4. package/data/corrections/algeria.json +784 -0
  5. package/data/corrections/diyanet.json +18444 -0
  6. package/data/corrections/indonesia.json +210 -0
  7. package/data/corrections/morocco.json +993 -0
  8. package/data/corrections/sweden.json +516 -0
  9. package/dist/cjs/algeria.d.ts +4 -0
  10. package/dist/cjs/algeria.js +22 -0
  11. package/dist/cjs/authorities/algeria.d.ts +3 -0
  12. package/dist/cjs/authorities/algeria.js +57 -0
  13. package/dist/cjs/authorities/diyanet.d.ts +9 -0
  14. package/dist/cjs/authorities/diyanet.js +90 -0
  15. package/dist/cjs/authorities/indonesia.d.ts +4 -0
  16. package/dist/cjs/authorities/indonesia.js +82 -0
  17. package/dist/cjs/authorities/morocco.d.ts +5 -0
  18. package/dist/cjs/authorities/morocco.js +65 -0
  19. package/dist/cjs/authorities/slug.d.ts +2 -0
  20. package/dist/cjs/authorities/slug.js +17 -0
  21. package/dist/cjs/authorities/sweden.d.ts +3 -0
  22. package/dist/cjs/authorities/sweden.js +58 -0
  23. package/dist/cjs/core/api.d.ts +61 -0
  24. package/dist/cjs/core/api.js +177 -0
  25. package/dist/cjs/core/civilDate.d.ts +17 -0
  26. package/dist/cjs/core/civilDate.js +41 -0
  27. package/dist/cjs/core/clock.d.ts +22 -0
  28. package/dist/cjs/core/clock.js +67 -0
  29. package/dist/cjs/core/compute.d.ts +10 -0
  30. package/dist/cjs/core/compute.js +59 -0
  31. package/dist/cjs/core/correctionList.d.ts +25 -0
  32. package/dist/cjs/core/correctionList.js +62 -0
  33. package/dist/cjs/core/fetchLatest.d.ts +61 -0
  34. package/dist/cjs/core/fetchLatest.js +192 -0
  35. package/dist/cjs/core/index.d.ts +14 -0
  36. package/dist/cjs/core/index.js +45 -0
  37. package/dist/cjs/core/registry.d.ts +28 -0
  38. package/dist/cjs/core/registry.js +34 -0
  39. package/dist/cjs/core/types.d.ts +193 -0
  40. package/dist/cjs/core/types.js +22 -0
  41. package/dist/cjs/core.d.ts +2 -0
  42. package/dist/cjs/core.js +18 -0
  43. package/dist/cjs/data/generated/algeriaCertification.d.ts +3 -0
  44. package/dist/cjs/data/generated/algeriaCertification.js +4 -0
  45. package/dist/cjs/data/generated/algeriaCities.d.ts +8 -0
  46. package/dist/cjs/data/generated/algeriaCities.js +5 -0
  47. package/dist/cjs/data/generated/algeriaCorrections.d.ts +3 -0
  48. package/dist/cjs/data/generated/algeriaCorrections.js +4 -0
  49. package/dist/cjs/data/generated/algeriaMethodPoints.d.ts +2 -0
  50. package/dist/cjs/data/generated/algeriaMethodPoints.js +5 -0
  51. package/dist/cjs/data/generated/countryOutlines.d.ts +5 -0
  52. package/dist/cjs/data/generated/countryOutlines.js +5 -0
  53. package/dist/cjs/data/generated/diyanetCertification.d.ts +3 -0
  54. package/dist/cjs/data/generated/diyanetCertification.js +4 -0
  55. package/dist/cjs/data/generated/diyanetCorrections.d.ts +3 -0
  56. package/dist/cjs/data/generated/diyanetCorrections.js +4 -0
  57. package/dist/cjs/data/generated/diyanetCountries.d.ts +5 -0
  58. package/dist/cjs/data/generated/diyanetCountries.js +5 -0
  59. package/dist/cjs/data/generated/diyanetTurkeyPoints.d.ts +7 -0
  60. package/dist/cjs/data/generated/diyanetTurkeyPoints.js +5 -0
  61. package/dist/cjs/data/generated/diyanetWorldPoints.d.ts +10 -0
  62. package/dist/cjs/data/generated/diyanetWorldPoints.js +5 -0
  63. package/dist/cjs/data/generated/indonesiaCertification.d.ts +3 -0
  64. package/dist/cjs/data/generated/indonesiaCertification.js +4 -0
  65. package/dist/cjs/data/generated/indonesiaCorrections.d.ts +3 -0
  66. package/dist/cjs/data/generated/indonesiaCorrections.js +4 -0
  67. package/dist/cjs/data/generated/kemenagMethodPoints.d.ts +2 -0
  68. package/dist/cjs/data/generated/kemenagMethodPoints.js +5 -0
  69. package/dist/cjs/data/generated/kemenagPlaces.d.ts +8 -0
  70. package/dist/cjs/data/generated/kemenagPlaces.js +5 -0
  71. package/dist/cjs/data/generated/moroccoCertification.d.ts +3 -0
  72. package/dist/cjs/data/generated/moroccoCertification.js +4 -0
  73. package/dist/cjs/data/generated/moroccoCities.d.ts +8 -0
  74. package/dist/cjs/data/generated/moroccoCities.js +5 -0
  75. package/dist/cjs/data/generated/moroccoCorrections.d.ts +3 -0
  76. package/dist/cjs/data/generated/moroccoCorrections.js +4 -0
  77. package/dist/cjs/data/generated/moroccoMethodPoints.d.ts +2 -0
  78. package/dist/cjs/data/generated/moroccoMethodPoints.js +5 -0
  79. package/dist/cjs/data/generated/swedenCertification.d.ts +3 -0
  80. package/dist/cjs/data/generated/swedenCertification.js +4 -0
  81. package/dist/cjs/data/generated/swedenCorrections.d.ts +3 -0
  82. package/dist/cjs/data/generated/swedenCorrections.js +4 -0
  83. package/dist/cjs/data/generated/swedenPlaces.d.ts +5 -0
  84. package/dist/cjs/data/generated/swedenPlaces.js +5 -0
  85. package/dist/cjs/diyanet.d.ts +4 -0
  86. package/dist/cjs/diyanet.js +22 -0
  87. package/dist/cjs/index.d.ts +19 -0
  88. package/dist/cjs/index.js +37 -0
  89. package/dist/cjs/indonesia.d.ts +4 -0
  90. package/dist/cjs/indonesia.js +22 -0
  91. package/dist/cjs/locate.d.ts +21 -0
  92. package/dist/cjs/locate.js +204 -0
  93. package/dist/cjs/methods/algeria.d.ts +56 -0
  94. package/dist/cjs/methods/algeria.js +119 -0
  95. package/dist/cjs/methods/indonesia.d.ts +31 -0
  96. package/dist/cjs/methods/indonesia.js +94 -0
  97. package/dist/cjs/methods/morocco.d.ts +61 -0
  98. package/dist/cjs/methods/morocco.js +113 -0
  99. package/dist/cjs/methods/revisions.d.ts +15 -0
  100. package/dist/cjs/methods/revisions.js +18 -0
  101. package/dist/cjs/methods/scratch-congress.d.ts +87 -0
  102. package/dist/cjs/methods/scratch-congress.js +539 -0
  103. package/dist/cjs/methods/sweden.d.ts +88 -0
  104. package/dist/cjs/methods/sweden.js +568 -0
  105. package/dist/cjs/morocco.d.ts +4 -0
  106. package/dist/cjs/morocco.js +22 -0
  107. package/dist/cjs/sun/preciseSun.d.ts +19 -0
  108. package/dist/cjs/sun/preciseSun.js +185 -0
  109. package/dist/cjs/sweden.d.ts +4 -0
  110. package/dist/cjs/sweden.js +22 -0
  111. package/dist/esm/algeria.d.ts +4 -0
  112. package/dist/esm/algeria.js +4 -0
  113. package/dist/esm/authorities/algeria.d.ts +3 -0
  114. package/dist/esm/authorities/algeria.js +51 -0
  115. package/dist/esm/authorities/diyanet.d.ts +9 -0
  116. package/dist/esm/authorities/diyanet.js +83 -0
  117. package/dist/esm/authorities/indonesia.d.ts +4 -0
  118. package/dist/esm/authorities/indonesia.js +75 -0
  119. package/dist/esm/authorities/morocco.d.ts +5 -0
  120. package/dist/esm/authorities/morocco.js +59 -0
  121. package/dist/esm/authorities/slug.d.ts +2 -0
  122. package/dist/esm/authorities/slug.js +14 -0
  123. package/dist/esm/authorities/sweden.d.ts +3 -0
  124. package/dist/esm/authorities/sweden.js +52 -0
  125. package/dist/esm/core/api.d.ts +61 -0
  126. package/dist/esm/core/api.js +163 -0
  127. package/dist/esm/core/civilDate.d.ts +17 -0
  128. package/dist/esm/core/civilDate.js +36 -0
  129. package/dist/esm/core/clock.d.ts +22 -0
  130. package/dist/esm/core/clock.js +60 -0
  131. package/dist/esm/core/compute.d.ts +10 -0
  132. package/dist/esm/core/compute.js +56 -0
  133. package/dist/esm/core/correctionList.d.ts +25 -0
  134. package/dist/esm/core/correctionList.js +56 -0
  135. package/dist/esm/core/fetchLatest.d.ts +61 -0
  136. package/dist/esm/core/fetchLatest.js +184 -0
  137. package/dist/esm/core/index.d.ts +14 -0
  138. package/dist/esm/core/index.js +14 -0
  139. package/dist/esm/core/registry.d.ts +28 -0
  140. package/dist/esm/core/registry.js +28 -0
  141. package/dist/esm/core/types.d.ts +193 -0
  142. package/dist/esm/core/types.js +18 -0
  143. package/dist/esm/core.d.ts +2 -0
  144. package/dist/esm/core.js +2 -0
  145. package/dist/esm/data/generated/algeriaCertification.d.ts +3 -0
  146. package/dist/esm/data/generated/algeriaCertification.js +2 -0
  147. package/dist/esm/data/generated/algeriaCities.d.ts +8 -0
  148. package/dist/esm/data/generated/algeriaCities.js +3 -0
  149. package/dist/esm/data/generated/algeriaCorrections.d.ts +3 -0
  150. package/dist/esm/data/generated/algeriaCorrections.js +2 -0
  151. package/dist/esm/data/generated/algeriaMethodPoints.d.ts +2 -0
  152. package/dist/esm/data/generated/algeriaMethodPoints.js +3 -0
  153. package/dist/esm/data/generated/countryOutlines.d.ts +5 -0
  154. package/dist/esm/data/generated/countryOutlines.js +3 -0
  155. package/dist/esm/data/generated/diyanetCertification.d.ts +3 -0
  156. package/dist/esm/data/generated/diyanetCertification.js +2 -0
  157. package/dist/esm/data/generated/diyanetCorrections.d.ts +3 -0
  158. package/dist/esm/data/generated/diyanetCorrections.js +2 -0
  159. package/dist/esm/data/generated/diyanetCountries.d.ts +5 -0
  160. package/dist/esm/data/generated/diyanetCountries.js +3 -0
  161. package/dist/esm/data/generated/diyanetTurkeyPoints.d.ts +7 -0
  162. package/dist/esm/data/generated/diyanetTurkeyPoints.js +3 -0
  163. package/dist/esm/data/generated/diyanetWorldPoints.d.ts +10 -0
  164. package/dist/esm/data/generated/diyanetWorldPoints.js +3 -0
  165. package/dist/esm/data/generated/indonesiaCertification.d.ts +3 -0
  166. package/dist/esm/data/generated/indonesiaCertification.js +2 -0
  167. package/dist/esm/data/generated/indonesiaCorrections.d.ts +3 -0
  168. package/dist/esm/data/generated/indonesiaCorrections.js +2 -0
  169. package/dist/esm/data/generated/kemenagMethodPoints.d.ts +2 -0
  170. package/dist/esm/data/generated/kemenagMethodPoints.js +3 -0
  171. package/dist/esm/data/generated/kemenagPlaces.d.ts +8 -0
  172. package/dist/esm/data/generated/kemenagPlaces.js +3 -0
  173. package/dist/esm/data/generated/moroccoCertification.d.ts +3 -0
  174. package/dist/esm/data/generated/moroccoCertification.js +2 -0
  175. package/dist/esm/data/generated/moroccoCities.d.ts +8 -0
  176. package/dist/esm/data/generated/moroccoCities.js +3 -0
  177. package/dist/esm/data/generated/moroccoCorrections.d.ts +3 -0
  178. package/dist/esm/data/generated/moroccoCorrections.js +2 -0
  179. package/dist/esm/data/generated/moroccoMethodPoints.d.ts +2 -0
  180. package/dist/esm/data/generated/moroccoMethodPoints.js +3 -0
  181. package/dist/esm/data/generated/swedenCertification.d.ts +3 -0
  182. package/dist/esm/data/generated/swedenCertification.js +2 -0
  183. package/dist/esm/data/generated/swedenCorrections.d.ts +3 -0
  184. package/dist/esm/data/generated/swedenCorrections.js +2 -0
  185. package/dist/esm/data/generated/swedenPlaces.d.ts +5 -0
  186. package/dist/esm/data/generated/swedenPlaces.js +3 -0
  187. package/dist/esm/diyanet.d.ts +4 -0
  188. package/dist/esm/diyanet.js +4 -0
  189. package/dist/esm/index.d.ts +19 -0
  190. package/dist/esm/index.js +19 -0
  191. package/dist/esm/indonesia.d.ts +4 -0
  192. package/dist/esm/indonesia.js +4 -0
  193. package/dist/esm/locate.d.ts +21 -0
  194. package/dist/esm/locate.js +196 -0
  195. package/dist/esm/methods/algeria.d.ts +56 -0
  196. package/dist/esm/methods/algeria.js +114 -0
  197. package/dist/esm/methods/indonesia.d.ts +31 -0
  198. package/dist/esm/methods/indonesia.js +90 -0
  199. package/dist/esm/methods/morocco.d.ts +61 -0
  200. package/dist/esm/methods/morocco.js +107 -0
  201. package/dist/esm/methods/revisions.d.ts +15 -0
  202. package/dist/esm/methods/revisions.js +15 -0
  203. package/dist/esm/methods/scratch-congress.d.ts +87 -0
  204. package/dist/esm/methods/scratch-congress.js +534 -0
  205. package/dist/esm/methods/sweden.d.ts +88 -0
  206. package/dist/esm/methods/sweden.js +563 -0
  207. package/dist/esm/morocco.d.ts +4 -0
  208. package/dist/esm/morocco.js +4 -0
  209. package/dist/esm/package.json +1 -0
  210. package/dist/esm/sun/preciseSun.d.ts +19 -0
  211. package/dist/esm/sun/preciseSun.js +181 -0
  212. package/dist/esm/sweden.d.ts +4 -0
  213. package/dist/esm/sweden.js +4 -0
  214. package/docs/methods.md +190 -0
  215. package/package.json +178 -4
  216. package/schemas/certification.schema.json +59 -0
  217. package/schemas/corrections.schema.json +29 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Morocco — the Ministry of Habous and Islamic Affairs's method, as its
3
+ * timetable is computed (issue #10).
4
+ *
5
+ * Read off 77 days of the ministry's tables for its 164 located cities:
6
+ *
7
+ * • a precise Sun — Meeus's apparent Sun with the full nutation and his
8
+ * chapter-28 equation of time; a JPL ephemeris fits no better, NOAA's
9
+ * and the Almanac's series far worse — taken at each prayer's own
10
+ * moment (iterated), declination and equation of time alike;
11
+ * • Fajr 19°, Isha 17°, Asr one shadow length (Shafi'i);
12
+ * • Dhuhr five minutes after the transit;
13
+ * • sunrise 2.85 minutes before, and Maghrib 3.7 after, the Sun's upper
14
+ * limb on the horizon — refraction 34′ and the Sun's semi-diameter for
15
+ * its distance that day — less the city's own horizon dip;
16
+ * • Fajr rounded down to the minute, the rest to the nearest.
17
+ *
18
+ * The dip is the ministry's own per city and per side — the horizon east
19
+ * at sunrise, west at Maghrib, which mountains or the sea make different —
20
+ * fitted from its tables with the city's point (`data/moroccoMethodPoints.json`,
21
+ * about 0.02° per √metre of height); elsewhere 0.02°·√height, 0.86 of it at
22
+ * Maghrib. On 77 days of the ministry's tables for its 164 located cities
23
+ * this is its printed minute for 99.12 % of times, and never further than
24
+ * one; `data/corrections/morocco.json` holds the rest.
25
+ */
26
+ export type MoroccoInstants = {
27
+ fajr: Date;
28
+ sunrise: Date;
29
+ dhuhr: Date;
30
+ asr: Date;
31
+ maghrib: Date;
32
+ isha: Date;
33
+ };
34
+ /** Meeus's apparent Sun at `d` days from J2000.0: declination (rad), equation of time (minutes). */
35
+ export declare function meeusApparentSun(d: number): {
36
+ dec: number;
37
+ eot: number;
38
+ };
39
+ /** Minutes before the horizon crossing that the ministry prints sunrise, and after it Maghrib. */
40
+ export declare const MOROCCO_SUNRISE_MARGIN = -2.85;
41
+ export declare const MOROCCO_MAGHRIB_MARGIN = 3.7;
42
+ /** The share of the horizon dip Maghrib takes, against sunrise's whole, where a city's own is not known. */
43
+ export declare const MOROCCO_MAGHRIB_DIP_SHARE = 0.86;
44
+ /** Degrees of dip per √metre where the ministry's own value is not known. */
45
+ export declare const MOROCCO_DIP_PER_SQRT_M = 0.02;
46
+ /** Exact times, minutes past 00:00 UT of the civil date, margins applied, before rounding. NaN where one does not form. */
47
+ export declare function moroccoRawMinutes(latitude: number, longitude: number, year: number, month: number, day: number, dipDeg?: number, asrShadow?: number,
48
+ /** The horizon's dip westward, at Maghrib; MOROCCO_MAGHRIB_DIP_SHARE of `dipDeg` when not known. */
49
+ dipMaghribDeg?: number): {
50
+ fajr: number;
51
+ sunrise: number;
52
+ dhuhr: number;
53
+ asr: number;
54
+ maghrib: number;
55
+ isha: number;
56
+ };
57
+ /**
58
+ * The ministry's times for a point and civil date (month 0-based), on the
59
+ * minute. Null when a time does not form there.
60
+ */
61
+ export declare function moroccoTimes(latitude: number, longitude: number, year: number, month: number, day: number, dipDeg?: number, asrShadow?: number, dipMaghribDeg?: number): MoroccoInstants | null;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Morocco — the Ministry of Habous and Islamic Affairs's method, as its
3
+ * timetable is computed (issue #10).
4
+ *
5
+ * Read off 77 days of the ministry's tables for its 164 located cities:
6
+ *
7
+ * • a precise Sun — Meeus's apparent Sun with the full nutation and his
8
+ * chapter-28 equation of time; a JPL ephemeris fits no better, NOAA's
9
+ * and the Almanac's series far worse — taken at each prayer's own
10
+ * moment (iterated), declination and equation of time alike;
11
+ * • Fajr 19°, Isha 17°, Asr one shadow length (Shafi'i);
12
+ * • Dhuhr five minutes after the transit;
13
+ * • sunrise 2.85 minutes before, and Maghrib 3.7 after, the Sun's upper
14
+ * limb on the horizon — refraction 34′ and the Sun's semi-diameter for
15
+ * its distance that day — less the city's own horizon dip;
16
+ * • Fajr rounded down to the minute, the rest to the nearest.
17
+ *
18
+ * The dip is the ministry's own per city and per side — the horizon east
19
+ * at sunrise, west at Maghrib, which mountains or the sea make different —
20
+ * fitted from its tables with the city's point (`data/moroccoMethodPoints.json`,
21
+ * about 0.02° per √metre of height); elsewhere 0.02°·√height, 0.86 of it at
22
+ * Maghrib. On 77 days of the ministry's tables for its 164 located cities
23
+ * this is its printed minute for 99.12 % of times, and never further than
24
+ * one; `data/corrections/morocco.json` holds the rest.
25
+ */
26
+ const RAD = Math.PI / 180;
27
+ const DAY_MS = 86_400_000;
28
+ /** Meeus's apparent Sun at `d` days from J2000.0: declination (rad), equation of time (minutes). */
29
+ export function meeusApparentSun(d) {
30
+ const T = d / 36525;
31
+ const L0 = (((280.46646 + T * (36000.76983 + 0.0003032 * T)) % 360) + 360) % 360;
32
+ const M = (357.52911 + T * (35999.05029 - 0.0001537 * T)) * RAD;
33
+ const C = (1.914602 - T * (0.004817 + 0.000014 * T)) * Math.sin(M) +
34
+ (0.019993 - 0.000101 * T) * Math.sin(2 * M) +
35
+ 0.000289 * Math.sin(3 * M);
36
+ const om = (125.04 - 1934.136 * T) * RAD;
37
+ const eps0 = 23 + (26 + (21.448 - T * (46.815 + T * (0.00059 - T * 0.001813))) / 60) / 60;
38
+ const Lm = (280.4665 + 36000.7698 * T) * RAD;
39
+ const Lmoon = (218.3165 + 481267.8813 * T) * RAD;
40
+ const dpsi = (-17.2 * Math.sin(om) - 1.32 * Math.sin(2 * Lm) - 0.23 * Math.sin(2 * Lmoon) + 0.21 * Math.sin(2 * om)) / 3600;
41
+ const deps = (9.2 * Math.cos(om) + 0.57 * Math.cos(2 * Lm) + 0.1 * Math.cos(2 * Lmoon) - 0.09 * Math.cos(2 * om)) / 3600;
42
+ const lambda = (L0 + C - 0.00569 + dpsi) * RAD;
43
+ const eps = (eps0 + deps) * RAD;
44
+ const ra = (((Math.atan2(Math.cos(eps) * Math.sin(lambda), Math.cos(lambda)) / RAD) % 360) + 360) % 360;
45
+ const dec = Math.asin(Math.sin(eps) * Math.sin(lambda));
46
+ const E = L0 - 0.0057183 - ra + dpsi * Math.cos(eps);
47
+ const eot = ((((E + 180) % 360) + 360) % 360 - 180) * 4;
48
+ return { dec, eot };
49
+ }
50
+ const ITERATIONS = 3;
51
+ /** Minutes before the horizon crossing that the ministry prints sunrise, and after it Maghrib. */
52
+ export const MOROCCO_SUNRISE_MARGIN = -2.85;
53
+ export const MOROCCO_MAGHRIB_MARGIN = 3.7;
54
+ /** The share of the horizon dip Maghrib takes, against sunrise's whole, where a city's own is not known. */
55
+ export const MOROCCO_MAGHRIB_DIP_SHARE = 0.86;
56
+ /** Degrees of dip per √metre where the ministry's own value is not known. */
57
+ export const MOROCCO_DIP_PER_SQRT_M = 0.02;
58
+ /** Exact times, minutes past 00:00 UT of the civil date, margins applied, before rounding. NaN where one does not form. */
59
+ export function moroccoRawMinutes(latitude, longitude, year, month, day, dipDeg = 0, asrShadow = 1,
60
+ /** The horizon's dip westward, at Maghrib; MOROCCO_MAGHRIB_DIP_SHARE of `dipDeg` when not known. */
61
+ dipMaghribDeg = MOROCCO_MAGHRIB_DIP_SHARE * dipDeg) {
62
+ const d0 = (Date.UTC(year, month, day) - Date.UTC(2000, 0, 1)) / DAY_MS - 0.5;
63
+ const at = (t) => meeusApparentSun(d0 + t / 1440);
64
+ let noon = 720 - 4 * longitude;
65
+ for (let i = 0; i < ITERATIONS; i++)
66
+ noon = 720 - 4 * longitude - at(noon).eot;
67
+ const sp = Math.sin(latitude * RAD);
68
+ const cp = Math.cos(latitude * RAD);
69
+ // the upper limb on the horizon: refraction 34′ and the semi-diameter for the Sun's distance that day
70
+ const T = (d0 + noon / 1440) / 36525;
71
+ const Ma = (357.52911 + 35999.05029 * T) * RAD;
72
+ const horizon = -(34 / 60 + 0.26667 / (1.00014 - 0.016708 * Math.cos(Ma) - 0.00014 * Math.cos(2 * Ma)));
73
+ const event = (altitudeOf, sign, start) => {
74
+ let t = start;
75
+ for (let i = 0; i < ITERATIONS; i++) {
76
+ const { dec, eot } = at(t);
77
+ const c = (Math.sin(altitudeOf(dec) * RAD) - sp * Math.sin(dec)) / (cp * Math.cos(dec));
78
+ if (!(Math.abs(c) <= 1))
79
+ return NaN;
80
+ t = 720 - 4 * longitude - eot + (sign * 4 * Math.acos(c)) / RAD;
81
+ }
82
+ return t;
83
+ };
84
+ const fixed = (a) => () => a;
85
+ const asrAltitude = (dec) => Math.atan(1 / (asrShadow + Math.tan(Math.abs(latitude - dec / RAD) * RAD))) / RAD;
86
+ return {
87
+ fajr: event(fixed(-19), -1, noon - 420) - 0.5,
88
+ sunrise: event(fixed(horizon - dipDeg), -1, noon - 360) + MOROCCO_SUNRISE_MARGIN,
89
+ dhuhr: noon + 5,
90
+ asr: event(asrAltitude, 1, noon + 200),
91
+ maghrib: event(fixed(horizon - dipMaghribDeg), 1, noon + 360) + MOROCCO_MAGHRIB_MARGIN,
92
+ isha: event(fixed(-17), 1, noon + 420),
93
+ };
94
+ }
95
+ /**
96
+ * The ministry's times for a point and civil date (month 0-based), on the
97
+ * minute. Null when a time does not form there.
98
+ */
99
+ export function moroccoTimes(latitude, longitude, year, month, day, dipDeg = 0, asrShadow = 1, dipMaghribDeg) {
100
+ const r = moroccoRawMinutes(latitude, longitude, year, month, day, dipDeg, asrShadow, dipMaghribDeg);
101
+ const all = [r.fajr, r.sunrise, r.dhuhr, r.asr, r.maghrib, r.isha];
102
+ if (!all.every(Number.isFinite))
103
+ return null;
104
+ const start = Date.UTC(year, month, day);
105
+ const at = (m) => new Date(start + Math.floor(m + 0.5) * 60_000);
106
+ return { fajr: at(r.fajr), sunrise: at(r.sunrise), dhuhr: at(r.dhuhr), asr: at(r.asr), maghrib: at(r.maghrib), isha: at(r.isha) };
107
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Each method's revision: raised whenever a change to a method, or to the
3
+ * points it computes its places at, changes what it prints. A correction
4
+ * list is written for one revision (certification.json names it), and an
5
+ * app applies a list only to the revision it computes — a list for another
6
+ * would move the wrong minutes. An app on an older revision tells its user
7
+ * to update instead.
8
+ */
9
+ export declare const METHOD_REVISION: {
10
+ readonly sweden: 1;
11
+ readonly diyanet: 1;
12
+ readonly morocco: 1;
13
+ readonly algeria: 1;
14
+ readonly indonesia: 1;
15
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Each method's revision: raised whenever a change to a method, or to the
3
+ * points it computes its places at, changes what it prints. A correction
4
+ * list is written for one revision (certification.json names it), and an
5
+ * app applies a list only to the revision it computes — a list for another
6
+ * would move the wrong minutes. An app on an older revision tells its user
7
+ * to update instead.
8
+ */
9
+ export const METHOD_REVISION = {
10
+ sweden: 1,
11
+ diyanet: 1,
12
+ morocco: 1,
13
+ algeria: 1,
14
+ indonesia: 1,
15
+ };
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The International Prayer Times Congress method (Istanbul, 2021 — the
3
+ * Diyanet and the European Council for Fatwa and Research) as Diyanet's
4
+ * tables realise it. Islamiska Förbundet's Swedish tables are those
5
+ * tables, row for row, so this is Sweden's method (id 24).
6
+ *
7
+ * The published rules (awqatsalah.com, "Tespit Kriterleri"):
8
+ * - Dhuhr five minutes after transit; Asr one shadow (Dhuhr when the
9
+ * shadow never forms), four minutes late; sunrise seven early,
10
+ * Maghrib seven late ("temkin").
11
+ * - Neither the day nor the night is shorter than five hours.
12
+ * - True Fajr at 18°, true Isha at 16°. Where the 18° dawn no longer
13
+ * forms, the share of the night the sharia night's third took on the
14
+ * last day it did is carried: Isha that share of the night after
15
+ * Maghrib, Fajr the same share scaled by 18/16 before sunrise.
16
+ * - The move from true times to the carried ones is gradual, starting
17
+ * twenty minutes before (Isha) or after (Fajr) the takdir.
18
+ *
19
+ * What the tables turn out to do with them, read off Diyanet's own tables
20
+ * for all 160 Swedish places, 2024–2027 (99.98 % of times on the printed
21
+ * minute, the rest a fraction of a second from the rounding point):
22
+ * - The sun is taken once a day, at 0h UT less 45 s: Meeus's mean
23
+ * elements and equation of the centre, the TRUE (geometric) longitude,
24
+ * the apparent obliquity (mean plus nutation), the equation of time as
25
+ * the mean longitude less the right ascension, 0.106 s later; and
26
+ * two small waves by the mean longitude the formula leaves out: a few
27
+ * hundredths of a second on the transit, a tenth of an arc-second on
28
+ * the declination.
29
+ * - Coordinates are kept to three decimals of a degree.
30
+ * - Asr that never forms is printed at Dhuhr's time.
31
+ * - The night a share is taken of is the day's own: 24 h less the
32
+ * printed day, sunrise to Maghrib.
33
+ * - The five-hour floors hold each end separately, 150 minutes from the
34
+ * printed Dhuhr or from the midnight after it. Where midsummer's
35
+ * night is floored at both ends (to within a minute), that night
36
+ * anchors the season, and the floored times never step back: before
37
+ * midsummer no sunrise earlier than midsummer's and a floored Maghrib
38
+ * no earlier than the day before; after it no sunrise earlier nor
39
+ * Maghrib later than on any day since midsummer — and Fajr and Isha
40
+ * carried the same way.
41
+ * - The gradual transition is a straight line across the days next to
42
+ * the gap on which the true time lies within twenty minutes of the
43
+ * takdir at the gap's edge: twenty minutes away at the far end, the
44
+ * takdir at the edge.
45
+ *
46
+ * Beyond Sweden the same code gives Diyanet's tables worldwide, read off
47
+ * them for places on six continents:
48
+ * - Where the dawn forms all summer but midsummer's true Isha (at 16°)
49
+ * falls later than the share carried from that night, midsummer is the
50
+ * takdir's day — a gap of one day, with its ramps (from about 44.4°
51
+ * north: Austria, central France, northern Bosnia).
52
+ * - Isha is printed at 16° in some countries and 17° in others; the
53
+ * high-latitude rules are worked at 16° either way (`ishaDeg`).
54
+ *
55
+ * Times are minutes past 0h UT of the date, a frame the clock changes
56
+ * cannot bend; `congressTimes` turns them into instants.
57
+ */
58
+ /**
59
+ * Isha's depression: the Congress's 16° (Diyanet's in much of Europe,
60
+ * Russia, Central Asia, China and North America), or Diyanet's own 17°
61
+ * (elsewhere). The high-latitude rules are the Congress's at 16° either way;
62
+ * the angle sets only the true Isha printed.
63
+ */
64
+ export declare const CONGRESS_ISHA_DEG = 16;
65
+ export declare const DIYANET_ISHA_DEG = 17;
66
+ export type CongressInstants = {
67
+ fajr: Date;
68
+ sunrise: Date;
69
+ dhuhr: Date;
70
+ asr: Date;
71
+ maghrib: Date;
72
+ isha: Date;
73
+ };
74
+ /**
75
+ * The Congress method's times for a calendar date (year, month 0–11, day),
76
+ * as instants, unrounded. `asrShadow` is 1 for the standard Asr, 2 for the
77
+ * Hanafi one; the tables print the standard. `ishaDeg` is Isha's depression:
78
+ * 16° (the Congress's, Diyanet's in Europe and North America) or 17°
79
+ * (Diyanet's everywhere else).
80
+ */
81
+ export declare function congressTimes(latitude: number, longitude: number, year: number, month: number, day: number, asrShadow?: number, ishaDeg?: number): CongressInstants;
82
+ /** For tests and the verification tool: the year's structure as the method sees it. */
83
+ export declare function congressYearInfo(latitude: number, longitude: number, year: number): {
84
+ gap: [string, string] | null;
85
+ ratio: number | null;
86
+ midsummerFloors: boolean;
87
+ };