@hebcal/leyning 8.2.6 → 8.2.7

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/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @hebcal/leyning v8.2.6 */
1
+ /*! @hebcal/leyning v8.2.7 */
2
2
  import { flags, months, HDate, HebrewCalendar, Locale, ParshaEvent, HolidayEvent, Event } from '@hebcal/core';
3
3
 
4
4
  var numverses = {
@@ -53,7 +53,14 @@ var numverses = {
53
53
  * Names of the books of the Torah. BOOK[1] === 'Genesis'
54
54
  * @readonly
55
55
  */
56
- const BOOK = ['', 'Genesis', 'Exodus', 'Leviticus', 'Numbers', 'Deuteronomy'];
56
+ const BOOK = [
57
+ '',
58
+ 'Genesis',
59
+ 'Exodus',
60
+ 'Leviticus',
61
+ 'Numbers',
62
+ 'Deuteronomy',
63
+ ];
57
64
  /**
58
65
  * Formats parsha as a string
59
66
  * @param parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
@@ -62,7 +69,9 @@ function parshaToString(parsha) {
62
69
  if (typeof parsha === 'string') {
63
70
  return parsha;
64
71
  }
65
- else if (!Array.isArray(parsha) || parsha.length === 0 || parsha.length > 2) {
72
+ else if (!Array.isArray(parsha) ||
73
+ parsha.length === 0 ||
74
+ parsha.length > 2) {
66
75
  throw new TypeError(`Bad parsha argument: ${parsha}`);
67
76
  }
68
77
  let s = parsha[0];
@@ -129,16 +138,16 @@ function formatAliyahShort(aliyah, showBook) {
129
138
  * @private
130
139
  */
131
140
  function isChapVerseBefore(a, b) {
132
- const cv1 = a.split(':').map((x) => +x);
133
- const cv2 = b.split(':').map((x) => +x);
134
- return (cv1[0] * 100 + cv1[1]) < (cv2[0] * 100 + cv2[1]);
141
+ const cv1 = a.split(':').map(x => +x);
142
+ const cv2 = b.split(':').map(x => +x);
143
+ return cv1[0] * 100 + cv1[1] < cv2[0] * 100 + cv2[1];
135
144
  }
136
145
  /**
137
146
  * Summarizes an `AliyotMap` by collapsing all adjacent aliyot.
138
147
  * Finds any non-overlapping parts (e.g. special 7th aliyah or maftir)
139
148
  */
140
149
  function makeLeyningParts(aliyot) {
141
- const nums = Object.keys(aliyot).filter((x) => {
150
+ const nums = Object.keys(aliyot).filter(x => {
142
151
  if (x.length === 1) {
143
152
  return true;
144
153
  }
@@ -151,15 +160,17 @@ function makeLeyningParts(aliyot) {
151
160
  for (let i = 0; i < nums.length; i++) {
152
161
  const num = nums[i];
153
162
  const aliyah = aliyot[num];
154
- if ((i === nums.length - 1) && (aliyah.k === end.k) && (aliyah.e === end.e)) {
163
+ if (i === nums.length - 1 && aliyah.k === end.k && aliyah.e === end.e) {
155
164
  // short-circuit when final aliyah is within the previous (e.g. M inside of 7)
156
165
  continue;
157
166
  }
158
- const prevEndChap = +(end.e.split(':')[0]);
159
- const curStartChap = +(aliyah.b.split(':')[0]);
167
+ const prevEndChap = +end.e.split(':')[0];
168
+ const curStartChap = +aliyah.b.split(':')[0];
160
169
  const sameOrNextChap = curStartChap === prevEndChap || curStartChap === prevEndChap + 1;
161
- if ((i !== 0) &&
162
- (aliyah.k !== start.k || isChapVerseBefore(aliyah.b, start.e) || !sameOrNextChap)) {
170
+ if (i !== 0 &&
171
+ (aliyah.k !== start.k ||
172
+ isChapVerseBefore(aliyah.b, start.e) ||
173
+ !sameOrNextChap)) {
163
174
  parts.push({ k: start.k, b: start.b, e: end.e });
164
175
  start = aliyah;
165
176
  }
@@ -225,7 +236,9 @@ function cloneHaftara(haft) {
225
236
  * Returns the total number of verses in an array of Aliyah (or haftarah) objects
226
237
  */
227
238
  function sumVerses(aliyot) {
228
- return Array.isArray(aliyot) ? aliyot.reduce((prev, cur) => prev + cur.v, 0) : aliyot.v;
239
+ return Array.isArray(aliyot)
240
+ ? aliyot.reduce((prev, cur) => prev + cur.v, 0)
241
+ : aliyot.v;
229
242
  }
230
243
 
231
244
  var festivals0 = { "Pesach I": {
@@ -880,9 +893,15 @@ function lookupFestival(holiday) {
880
893
  return result;
881
894
  }
882
895
 
883
- const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI | flags.OMER_COUNT | flags.SHABBAT_MEVARCHIM |
884
- flags.MOLAD | flags.USER_EVENT | flags.HEBREW_DATE | flags.MISHNA_YOMI |
885
- flags.MODERN_HOLIDAY | flags.YERUSHALMI_YOMI;
896
+ const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI |
897
+ flags.OMER_COUNT |
898
+ flags.SHABBAT_MEVARCHIM |
899
+ flags.MOLAD |
900
+ flags.USER_EVENT |
901
+ flags.HEBREW_DATE |
902
+ flags.MISHNA_YOMI |
903
+ flags.MODERN_HOLIDAY |
904
+ flags.YERUSHALMI_YOMI;
886
905
  /**
887
906
  * Based on the event date, type and title, finds the relevant leyning key
888
907
  * @param ev event
@@ -906,13 +925,15 @@ function getLeyningKeyForEvent(ev, il = false) {
906
925
  const day = hd.getDate();
907
926
  const dow = hd.abs() % 7;
908
927
  const month = hd.getMonth();
909
- const isShabbat = (dow == 6);
910
- const isRoshChodesh = (day == 1 || day == 30);
928
+ const isShabbat = dow == 6;
929
+ const isRoshChodesh = day == 1 || day == 30;
911
930
  const holiday = ev.basename();
912
931
  const isPesach = holiday === 'Pesach';
913
932
  if (il && isPesach) {
914
933
  if (isShabbat) {
915
- return day === 15 || day === 21 ? desc + ' (on Shabbat)' : 'Pesach Shabbat Chol ha-Moed';
934
+ return day === 15 || day === 21
935
+ ? desc + ' (on Shabbat)'
936
+ : 'Pesach Shabbat Chol ha-Moed';
916
937
  }
917
938
  return desc;
918
939
  }
@@ -929,10 +950,10 @@ function getLeyningKeyForEvent(ev, il = false) {
929
950
  return 'Sukkot Final Day (Hoshana Raba)';
930
951
  }
931
952
  if (isPesach && cholHaMoedDay) {
932
- if (dow === 0 && desc === 'Pesach IV (CH\'\'M)') {
953
+ if (dow === 0 && desc === "Pesach IV (CH''M)") {
933
954
  return 'Pesach Chol ha-Moed Day 2 on Sunday';
934
955
  }
935
- else if (dow === 1 && desc === 'Pesach V (CH\'\'M)') {
956
+ else if (dow === 1 && desc === "Pesach V (CH''M)") {
936
957
  return 'Pesach Chol ha-Moed Day 3 on Monday';
937
958
  }
938
959
  }
@@ -944,7 +965,7 @@ function getLeyningKeyForEvent(ev, il = false) {
944
965
  return 'Shabbat Rosh Chodesh Chanukah';
945
966
  }
946
967
  else if (isRoshChodesh && chanukahDay == 7) {
947
- return `Chanukah Day 7 (on Rosh Chodesh)`;
968
+ return 'Chanukah Day 7 (on Rosh Chodesh)';
948
969
  }
949
970
  else if (isShabbat) {
950
971
  return `Chanukah Day ${chanukahDay} (on Shabbat)`;
@@ -953,7 +974,8 @@ function getLeyningKeyForEvent(ev, il = false) {
953
974
  return `Chanukah Day ${chanukahDay}`;
954
975
  }
955
976
  }
956
- if (isRoshChodesh && (desc == 'Shabbat HaChodesh' || desc == 'Shabbat Shekalim')) {
977
+ if (isRoshChodesh &&
978
+ (desc == 'Shabbat HaChodesh' || desc == 'Shabbat Shekalim')) {
957
979
  return desc + ' (on Rosh Chodesh)';
958
980
  }
959
981
  if (il && desc == 'Shmini Atzeret') {
@@ -1000,8 +1022,8 @@ function getLeyningKeyForEvent(ev, il = false) {
1000
1022
  if (isRoshChodesh) {
1001
1023
  return desc;
1002
1024
  }
1003
- if (desc === 'Tish\'a B\'Av (observed)') {
1004
- return 'Tish\'a B\'Av';
1025
+ if (desc === "Tish'a B'Av (observed)") {
1026
+ return "Tish'a B'Av";
1005
1027
  }
1006
1028
  return undefined;
1007
1029
  }
@@ -1078,7 +1100,7 @@ function specialReadings2(parsha, hd, il, aliyot) {
1078
1100
  }
1079
1101
  const parshaName = parshaToString(parsha);
1080
1102
  const events0 = HebrewCalendar.getHolidaysOnDate(hd, il) || [];
1081
- const events = events0.filter((ev) => !(ev.getFlags() & flags.ROSH_CHODESH));
1103
+ const events = events0.filter(ev => !(ev.getFlags() & flags.ROSH_CHODESH));
1082
1104
  for (const ev of events) {
1083
1105
  if (ev.getDesc() === 'Shabbat Shuva') {
1084
1106
  handleSpecial(`Shabbat Shuva (with ${parshaName})`);
@@ -1098,9 +1120,9 @@ function specialReadings2(parsha, hd, il, aliyot) {
1098
1120
  handleSpecial('Pinchas occurring after 17 Tammuz');
1099
1121
  }
1100
1122
  else if (day === 30 || day === 1) {
1101
- const key = (parshaName === 'Masei' || parshaName === 'Matot-Masei') ?
1102
- `${parshaName} on Shabbat Rosh Chodesh` :
1103
- 'Shabbat Rosh Chodesh';
1123
+ const key = parshaName === 'Masei' || parshaName === 'Matot-Masei'
1124
+ ? `${parshaName} on Shabbat Rosh Chodesh`
1125
+ : 'Shabbat Rosh Chodesh';
1104
1126
  handleSpecial(key);
1105
1127
  }
1106
1128
  else if (parshaName === 'Ki Teitzei' && day === 14) {
@@ -1112,7 +1134,8 @@ function specialReadings2(parsha, hd, il, aliyot) {
1112
1134
  // Source: Luaḥ Hashanah, Rabbi Miles B. Cohen and Leslie Rubin
1113
1135
  handleSpecial('Ki Teitzei with 3rd Haftarah of Consolation');
1114
1136
  }
1115
- else if (parshaName === 'Kedoshim' && (day === 26 || day === 28 || day === 6)) {
1137
+ else if (parshaName === 'Kedoshim' &&
1138
+ (day === 26 || day === 28 || day === 6)) {
1116
1139
  // Kedoshim is read separately from Achrei Mot in ~37% of years.
1117
1140
  // When this happens, it is will be read on
1118
1141
  // 26th or 28th of Nisan (Achrei Mot was Shabbat HaGadol, ~10%),
@@ -1152,7 +1175,9 @@ function getLeyningForHolidayKey(key, cholHaMoedDay, il) {
1152
1175
  return undefined;
1153
1176
  }
1154
1177
  const israelOnly = src.il;
1155
- if (typeof israelOnly === 'boolean' && typeof il === 'boolean' && il !== israelOnly) {
1178
+ if (typeof israelOnly === 'boolean' &&
1179
+ typeof il === 'boolean' &&
1180
+ il !== israelOnly) {
1156
1181
  return undefined;
1157
1182
  }
1158
1183
  const leyning = {
@@ -1176,15 +1201,15 @@ function getLeyningForHolidayKey(key, cholHaMoedDay, il) {
1176
1201
  leyning.summaryParts = parts;
1177
1202
  }
1178
1203
  }
1179
- Object.values(leyning.fullkriyah).map((aliyah) => calculateNumVerses(aliyah));
1204
+ Object.values(leyning.fullkriyah).map(aliyah => calculateNumVerses(aliyah));
1180
1205
  }
1181
1206
  if (src.haft) {
1182
- const haft = leyning.haft = cloneHaftara(src.haft);
1207
+ const haft = (leyning.haft = cloneHaftara(src.haft));
1183
1208
  leyning.haftara = makeSummaryFromParts(haft);
1184
1209
  leyning.haftaraNumV = sumVerses(haft);
1185
1210
  }
1186
1211
  if (src.seph) {
1187
- const seph = leyning.seph = cloneHaftara(src.seph);
1212
+ const seph = (leyning.seph = cloneHaftara(src.seph));
1188
1213
  leyning.sephardic = makeSummaryFromParts(seph);
1189
1214
  leyning.sephardicNumV = sumVerses(seph);
1190
1215
  }
@@ -2540,7 +2565,7 @@ function makeLeyningNames(parsha) {
2540
2565
  const name = parshaToString(parsha);
2541
2566
  return {
2542
2567
  en: name,
2543
- he: parsha.map((s) => Locale.lookupTranslation(s, 'he')).join('־'),
2568
+ he: parsha.map(s => Locale.lookupTranslation(s, 'he')).join('־'),
2544
2569
  };
2545
2570
  }
2546
2571
  /**
@@ -2577,13 +2602,13 @@ function getLeyningForParshaShabbatOnly(parsha) {
2577
2602
  const hkey = getHaftaraKey(parshaNameArray);
2578
2603
  const haft0 = parshiyotObj[hkey].haft;
2579
2604
  if (haft0) {
2580
- const haft = result.haft = cloneHaftara(haft0);
2605
+ const haft = (result.haft = cloneHaftara(haft0));
2581
2606
  result.haftara = makeSummaryFromParts(haft);
2582
2607
  result.haftaraNumV = sumVerses(haft);
2583
2608
  }
2584
2609
  const seph0 = parshiyotObj[hkey].seph;
2585
2610
  if (seph0) {
2586
- const seph = result.seph = cloneHaftara(seph0);
2611
+ const seph = (result.seph = cloneHaftara(seph0));
2587
2612
  result.sephardic = makeSummaryFromParts(seph);
2588
2613
  result.sephardicNumV = sumVerses(seph);
2589
2614
  }
@@ -2642,11 +2667,11 @@ function getLeyningForParshaHaShavua(ev, il = false) {
2642
2667
  const special = specialReadings2(parsha, hd, il, result.fullkriyah);
2643
2668
  const reason = special.reason;
2644
2669
  if (special.haft) {
2645
- const haft = result.haft = cloneHaftara(special.haft);
2670
+ const haft = (result.haft = cloneHaftara(special.haft));
2646
2671
  result.haftara = makeSummaryFromParts(haft);
2647
2672
  result.haftaraNumV = sumVerses(haft);
2648
2673
  if (special.seph) {
2649
- const seph = result.seph = cloneHaftara(special.seph);
2674
+ const seph = (result.seph = cloneHaftara(special.seph));
2650
2675
  result.sephardic = makeSummaryFromParts(seph);
2651
2676
  result.sephardicNumV = sumVerses(seph);
2652
2677
  }
@@ -2787,6 +2812,9 @@ function getLeyningOnDate(hdate, il, wantarray = false) {
2787
2812
  }
2788
2813
  const reading = getLeyningForHoliday(ev, il);
2789
2814
  if (reading) {
2815
+ // Skip duplicate readings from overlapping events (eg, Rosh Chodesh + Chanukah)
2816
+ if (arr.some(r => r.name.en === reading.name.en))
2817
+ continue;
2790
2818
  const fk = reading.fullkriyah;
2791
2819
  if (fk) {
2792
2820
  hasFullKriyah = true;
@@ -2842,14 +2870,16 @@ function getMincha(ev, il) {
2842
2870
  }
2843
2871
 
2844
2872
  const fmt = new Intl.DateTimeFormat('en-US', {
2845
- year: 'numeric', month: 'short', day: '2-digit',
2873
+ year: 'numeric',
2874
+ month: 'short',
2875
+ day: '2-digit',
2846
2876
  });
2847
2877
  function fmtDate(dt) {
2848
2878
  const s = fmt.format(dt).split(' ');
2849
2879
  return s[1].substring(0, 2) + '-' + s[0] + '-' + s[2];
2850
2880
  }
2851
2881
  function getParshaDates(events) {
2852
- const parshaEvents = events.filter((ev) => ev.getFlags() === flags.PARSHA_HASHAVUA);
2882
+ const parshaEvents = events.filter(ev => ev.getFlags() === flags.PARSHA_HASHAVUA);
2853
2883
  const emptyMap = {};
2854
2884
  const parshaDates = parshaEvents.reduce((set, ev) => {
2855
2885
  set[ev.getDate().toString()] = true;
@@ -2868,7 +2898,8 @@ function writeFullKriyahCsv(stream, hyear, il) {
2868
2898
  const parshaDates = getParshaDates(events);
2869
2899
  stream.write('"Date","Parashah","Aliyah","Reading","Verses"\r\n');
2870
2900
  for (const ev of events) {
2871
- if (ev.getFlags() === flags.PARSHA_HASHAVUA || !parshaDates[ev.getDate().toString()]) {
2901
+ if (ev.getFlags() === flags.PARSHA_HASHAVUA ||
2902
+ !parshaDates[ev.getDate().toString()]) {
2872
2903
  writeFullKriyahEvent(stream, ev, il);
2873
2904
  }
2874
2905
  }
@@ -2889,7 +2920,9 @@ function writeFullKriyahEvent(stream, ev, il) {
2889
2920
  }
2890
2921
  const mask = ev.getFlags();
2891
2922
  const isParsha = mask === flags.PARSHA_HASHAVUA;
2892
- const reading = isParsha ? getLeyningForParshaHaShavua(ev, il) : getLeyningForHoliday(ev, il);
2923
+ const reading = isParsha
2924
+ ? getLeyningForParshaHaShavua(ev, il)
2925
+ : getLeyningForHoliday(ev, il);
2893
2926
  if (reading) {
2894
2927
  writeCsvLines(stream, ev, reading, il, isParsha);
2895
2928
  if (!isParsha) {
@@ -2918,7 +2951,9 @@ function writeHolidayMincha(stream, ev, il) {
2918
2951
  * Formats reading for CSV
2919
2952
  */
2920
2953
  function writeCsvLines(stream, ev, reading, il, isParsha) {
2921
- const parsha = isParsha ? ev.basename() : getLeyningKeyForEvent(ev, il) || ev.render();
2954
+ const parsha = isParsha
2955
+ ? ev.basename()
2956
+ : getLeyningKeyForEvent(ev, il) || ev.render();
2922
2957
  const date = fmtDate(ev.getDate().greg());
2923
2958
  const lines = getFullKriyahLines(reading);
2924
2959
  for (const s of lines) {
@@ -2958,7 +2993,11 @@ function getFullKriyahLines(reading) {
2958
2993
  if ((_c = reading.reason) === null || _c === void 0 ? void 0 : _c.sephardic) {
2959
2994
  sephardic += ' | ' + reading.reason.sephardic;
2960
2995
  }
2961
- lines.push(['Haftara for Sephardim', sephardic, reading.sephardicNumV || '']);
2996
+ lines.push([
2997
+ 'Haftara for Sephardim',
2998
+ sephardic,
2999
+ reading.sephardicNumV || '',
3000
+ ]);
2962
3001
  }
2963
3002
  if (reading.triHaftara) {
2964
3003
  const haftara = reading.triHaftara.replace(/,/g, ';');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hebcal/leyning",
3
- "version": "8.2.6",
3
+ "version": "8.2.7",
4
4
  "author": "Michael J. Radwin (https://github.com/mjradwin)",
5
5
  "keywords": [
6
6
  "hebcal",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "license": "BSD-2-Clause",
60
60
  "devDependencies": {
61
- "@babel/preset-env": "^7.25.7",
61
+ "@babel/preset-env": "^7.25.8",
62
62
  "@babel/preset-typescript": "^7.25.7",
63
63
  "@rollup/plugin-commonjs": "^28.0.0",
64
64
  "@rollup/plugin-json": "^6.1.0",
@@ -66,13 +66,13 @@
66
66
  "@rollup/plugin-terser": "^0.4.4",
67
67
  "@rollup/plugin-typescript": "^12.1.0",
68
68
  "@types/jest": "^29.5.13",
69
- "@types/node": "^22.7.4",
70
- "gts": "^5.3.1",
69
+ "@types/node": "^22.7.5",
70
+ "gts": "^6.0.0",
71
71
  "jest": "^29.7.0",
72
72
  "rollup": "^4.24.0",
73
73
  "rollup-plugin-dts": "^6.1.1",
74
74
  "ts-jest": "^29.2.5",
75
- "typedoc": "^0.26.8",
76
- "typescript": "^5.6.2"
75
+ "typedoc": "^0.26.9",
76
+ "typescript": "^5.6.3"
77
77
  }
78
78
  }