@hebcal/core 6.11.0 → 6.13.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 (91) hide show
  1. package/dist/bundle.js +1689 -1920
  2. package/dist/bundle.js.map +1 -1
  3. package/dist/bundle.min.js +18 -19
  4. package/dist/bundle.min.js.map +1 -1
  5. package/dist/esm/DailyLearning.js +5 -15
  6. package/dist/esm/DailyLearning.js.map +1 -1
  7. package/dist/esm/HebrewDateEvent.d.ts +0 -4
  8. package/dist/esm/HebrewDateEvent.js +2 -6
  9. package/dist/esm/HebrewDateEvent.js.map +1 -1
  10. package/dist/esm/HolidayEvent.js +6 -10
  11. package/dist/esm/HolidayEvent.js.map +1 -1
  12. package/dist/esm/MevarchimChodeshEvent.js +2 -2
  13. package/dist/esm/MevarchimChodeshEvent.js.map +1 -1
  14. package/dist/esm/ParshaEvent.js +4 -4
  15. package/dist/esm/ParshaEvent.js.map +1 -1
  16. package/dist/esm/TimedEvent.js +4 -5
  17. package/dist/esm/TimedEvent.js.map +1 -1
  18. package/dist/esm/YomKippurKatanEvent.js +2 -2
  19. package/dist/esm/YomKippurKatanEvent.js.map +1 -1
  20. package/dist/esm/ashkenazi.po.js +1 -1
  21. package/dist/esm/calendar.js +7 -40
  22. package/dist/esm/calendar.js.map +1 -1
  23. package/dist/esm/candles.d.ts +3 -5
  24. package/dist/esm/candles.js +6 -20
  25. package/dist/esm/candles.js.map +1 -1
  26. package/dist/esm/cities.json.js +1 -1
  27. package/dist/esm/event.js +4 -6
  28. package/dist/esm/event.js.map +1 -1
  29. package/dist/esm/getStartAndEnd.d.ts +1 -1
  30. package/dist/esm/getStartAndEnd.js +8 -9
  31. package/dist/esm/getStartAndEnd.js.map +1 -1
  32. package/dist/esm/hallel.d.ts +1 -3
  33. package/dist/esm/hallel.js +2 -4
  34. package/dist/esm/hallel.js.map +1 -1
  35. package/dist/esm/he-x-NoNikud.po.d.ts +1 -0
  36. package/dist/esm/he-x-NoNikud.po.js +2 -2
  37. package/dist/esm/he-x-NoNikud.po.js.map +1 -1
  38. package/dist/esm/he.po.d.ts +1 -0
  39. package/dist/esm/he.po.js +2 -2
  40. package/dist/esm/he.po.js.map +1 -1
  41. package/dist/esm/hebcal.js +6 -12
  42. package/dist/esm/hebcal.js.map +1 -1
  43. package/dist/esm/holidays.d.ts +1 -1
  44. package/dist/esm/holidays.js +111 -131
  45. package/dist/esm/holidays.js.map +1 -1
  46. package/dist/esm/index.js +1 -1
  47. package/dist/esm/isAssurBemlacha.js +5 -18
  48. package/dist/esm/isAssurBemlacha.js.map +1 -1
  49. package/dist/esm/isAveilut.js +2 -5
  50. package/dist/esm/isAveilut.js.map +1 -1
  51. package/dist/esm/isFastDay.js +3 -4
  52. package/dist/esm/isFastDay.js.map +1 -1
  53. package/dist/esm/locale.js +1 -1
  54. package/dist/esm/location.js +2 -7
  55. package/dist/esm/location.js.map +1 -1
  56. package/dist/esm/modern.d.ts +8 -13
  57. package/dist/esm/modern.js +141 -17
  58. package/dist/esm/modern.js.map +1 -1
  59. package/dist/esm/molad.js +2 -2
  60. package/dist/esm/molad.js.map +1 -1
  61. package/dist/esm/moladBase.js +2 -3
  62. package/dist/esm/moladBase.js.map +1 -1
  63. package/dist/esm/moladDate.js +1 -1
  64. package/dist/esm/moladDate.js.map +1 -1
  65. package/dist/esm/omer.js +22 -28
  66. package/dist/esm/omer.js.map +1 -1
  67. package/dist/esm/parshaName.d.ts +1 -1
  68. package/dist/esm/parshaName.js +3 -4
  69. package/dist/esm/parshaName.js.map +1 -1
  70. package/dist/esm/parshaYear.js +1 -1
  71. package/dist/esm/pkgVersion.d.ts +1 -1
  72. package/dist/esm/pkgVersion.js +2 -2
  73. package/dist/esm/pkgVersion.js.map +1 -1
  74. package/dist/esm/reformatTimeStr.js +17 -16
  75. package/dist/esm/reformatTimeStr.js.map +1 -1
  76. package/dist/esm/sedra.d.ts +0 -2
  77. package/dist/esm/sedra.js +19 -28
  78. package/dist/esm/sedra.js.map +1 -1
  79. package/dist/esm/sefira.json.js +1 -1
  80. package/dist/esm/staticHolidays.d.ts +8 -14
  81. package/dist/esm/staticHolidays.js +179 -470
  82. package/dist/esm/staticHolidays.js.map +1 -1
  83. package/dist/esm/string.js +1 -1
  84. package/dist/esm/tachanun.js +2 -6
  85. package/dist/esm/tachanun.js.map +1 -1
  86. package/dist/esm/zmanim.d.ts +0 -2
  87. package/dist/esm/zmanim.js +27 -27
  88. package/dist/esm/zmanim.js.map +1 -1
  89. package/package.json +6 -6
  90. package/po/he-x-NoNikud.po +3 -0
  91. package/po/he.po +3 -0
package/dist/bundle.js CHANGED
@@ -1,16 +1,19 @@
1
- /*! @hebcal/core v6.11.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1
+ /*! @hebcal/core v6.13.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
2
2
  var hebcal = (function (exports) {
3
3
  'use strict';
4
4
 
5
5
  /** DO NOT EDIT THIS AUTO-GENERATED FILE! */
6
- const version = '6.11.0';
6
+ const version = '6.13.0';
7
7
 
8
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
9
- /** @private */
10
- const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
11
- /** @private */
12
- const monthLengths = [lengths, lengths.slice()];
13
- monthLengths[1][2] = 29;
8
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
9
+ /**
10
+ * Days per Gregorian month (1-based), indexed first by `+isGregLeapYear()`.
11
+ * @private
12
+ */
13
+ const monthLengths = [
14
+ [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
15
+ [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
16
+ ];
14
17
  /**
15
18
  * @private
16
19
  */
@@ -88,8 +91,7 @@ function daysInGregMonth(month, year) {
88
91
  * isDate(1700000000000); // false
89
92
  */
90
93
  function isDate(obj) {
91
- // eslint-disable-next-line no-prototype-builtins
92
- return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
94
+ return obj instanceof Date;
93
95
  }
94
96
  /**
95
97
  * @private
@@ -189,8 +191,7 @@ function abs2greg(abs) {
189
191
  return dt;
190
192
  }
191
193
 
192
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
193
- /* eslint-disable @typescript-eslint/no-namespace */
194
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
194
195
  /**
195
196
  * Gregorian date helper functions.
196
197
  *
@@ -210,16 +211,15 @@ function abs2greg(abs) {
210
211
  * greg.greg2abs(new Date(2008, 10, 13)); // 733359
211
212
  * greg.isLeapYear(2024); // true
212
213
  */
213
- exports.greg = void 0;
214
- (function (greg) {
215
- })(exports.greg || (exports.greg = {}));
216
- exports.greg.abs2greg = abs2greg;
217
- exports.greg.daysInMonth = daysInGregMonth;
218
- exports.greg.greg2abs = greg2abs;
219
- exports.greg.isDate = isDate;
220
- exports.greg.isLeapYear = isGregLeapYear;
214
+ const greg = {
215
+ abs2greg,
216
+ daysInMonth: daysInGregMonth,
217
+ greg2abs,
218
+ isDate,
219
+ isLeapYear: isGregLeapYear,
220
+ };
221
221
 
222
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
222
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
223
223
  /**
224
224
  * Removes niqqud from Hebrew string
225
225
  * @example
@@ -235,23 +235,23 @@ function hebrewStripNikkud(str) {
235
235
  return a.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
236
236
  }
237
237
 
238
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
238
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
239
239
  /*
240
240
  * More minimal HDate
241
241
  */
242
- const NISAN$5 = 1;
243
- const IYYAR$2 = 2;
244
- const SIVAN$2 = 3;
242
+ const NISAN$6 = 1;
243
+ const IYYAR$3 = 2;
244
+ const SIVAN$3 = 3;
245
245
  const TAMUZ$2 = 4;
246
- const AV$2 = 5;
247
- const ELUL$1 = 6;
248
- const TISHREI$2 = 7;
249
- const CHESHVAN$2 = 8;
246
+ const AV$3 = 5;
247
+ const ELUL$2 = 6;
248
+ const TISHREI$3 = 7;
249
+ const CHESHVAN$3 = 8;
250
250
  const KISLEV$2 = 9;
251
251
  const TEVET$2 = 10;
252
- const SHVAT$1 = 11;
252
+ const SHVAT$2 = 11;
253
253
  const ADAR_I$2 = 12;
254
- const ADAR_II$2 = 13;
254
+ const ADAR_II$3 = 13;
255
255
  /**
256
256
  * Hebrew months of the year (NISAN=1, TISHREI=7).
257
257
  *
@@ -271,31 +271,31 @@ const ADAR_II$2 = 13;
271
271
  */
272
272
  const months = {
273
273
  /** Nissan / ניסן */
274
- NISAN: NISAN$5,
274
+ NISAN: NISAN$6,
275
275
  /** Iyyar / אייר */
276
- IYYAR: IYYAR$2,
276
+ IYYAR: IYYAR$3,
277
277
  /** Sivan / סיון */
278
- SIVAN: SIVAN$2,
278
+ SIVAN: SIVAN$3,
279
279
  /** Tamuz (sometimes Tammuz) / תמוז */
280
280
  TAMUZ: TAMUZ$2,
281
281
  /** Av / אב */
282
- AV: AV$2,
282
+ AV: AV$3,
283
283
  /** Elul / אלול */
284
- ELUL: ELUL$1,
284
+ ELUL: ELUL$2,
285
285
  /** Tishrei / תִּשְׁרֵי */
286
- TISHREI: TISHREI$2,
286
+ TISHREI: TISHREI$3,
287
287
  /** Cheshvan / חשון */
288
- CHESHVAN: CHESHVAN$2,
288
+ CHESHVAN: CHESHVAN$3,
289
289
  /** Kislev / כסלו */
290
290
  KISLEV: KISLEV$2,
291
291
  /** Tevet / טבת */
292
292
  TEVET: TEVET$2,
293
293
  /** Sh'vat / שבט */
294
- SHVAT: SHVAT$1,
294
+ SHVAT: SHVAT$2,
295
295
  /** Adar or Adar Rishon / אדר */
296
296
  ADAR_I: ADAR_I$2,
297
297
  /** Adar Sheini (only on leap years) / אדר ב׳ */
298
- ADAR_II: ADAR_II$2,
298
+ ADAR_II: ADAR_II$3,
299
299
  };
300
300
  const NISAN_STR = 'Nisan';
301
301
  const monthNames0 = [
@@ -368,17 +368,17 @@ function hebrew2abs(year, month, day) {
368
368
  throw new RangeError(`hebrew2abs: invalid year ${year}`);
369
369
  }
370
370
  let tempabs = day;
371
- if (month < TISHREI$2) {
371
+ if (month < TISHREI$3) {
372
372
  const endMonth = monthsInYear(year);
373
- for (let m = TISHREI$2; m <= endMonth; m++) {
373
+ for (let m = TISHREI$3; m <= endMonth; m++) {
374
374
  tempabs += daysInMonth(m, year);
375
375
  }
376
- for (let m = NISAN$5; m < month; m++) {
376
+ for (let m = NISAN$6; m < month; m++) {
377
377
  tempabs += daysInMonth(m, year);
378
378
  }
379
379
  }
380
380
  else {
381
- for (let m = TISHREI$2; m < month; m++) {
381
+ for (let m = TISHREI$3; m < month; m++) {
382
382
  tempabs += daysInMonth(m, year);
383
383
  }
384
384
  }
@@ -475,7 +475,7 @@ function daysInMonth(month, year) {
475
475
  return d;
476
476
  if (month === ADAR_I$2)
477
477
  return isLeapYear(year) ? 30 : 29;
478
- if (month === CHESHVAN$2)
478
+ if (month === CHESHVAN$3)
479
479
  return longCheshvan(year) ? 30 : 29;
480
480
  return shortKislev(year) ? 29 : 30; // KISLEV
481
481
  }
@@ -606,6 +606,52 @@ function longCheshvan(year) {
606
606
  function shortKislev(year) {
607
607
  return daysInYear(year) % 10 === 3;
608
608
  }
609
+ /**
610
+ * Resolves the "Adar I vs Adar II" ambiguity from the ordinal that trails
611
+ * an Adar month name.
612
+ *
613
+ * By the time this is called the caller has already decided the month is
614
+ * Adar (the name began with `ad` or `אד`) and has normalized `c`: trimmed,
615
+ * lower-cased, nikud removed, and any leading bet prefix stripped. This
616
+ * looks only at whatever follows the `adar`/`אדר` stem, ignoring the
617
+ * separator (space, hyphen, period) and any gershayim, and answers which
618
+ * of the two Adars was meant.
619
+ *
620
+ * Recognized as **Adar I** (the _first_ Adar): a bare `1`, roman `i`,
621
+ * Latin `a`, `alef`/`aleph`/`alaph`, `rishon` (any `rish…`), or Hebrew
622
+ * `א` / `ראשון` (any `ראש…`) / `אלף` (any `אל…`).
623
+ *
624
+ * Everything else resolves to **Adar II** (the _second_ Adar). That covers
625
+ * the explicit second-Adar spellings — `2`, roman `ii`, Latin `b`,
626
+ * `bet`/`beit`/`beis`, `sheni`/`sheini`, Hebrew `ב` / `שני` — but is also
627
+ * the deliberate default for the ambiguous cases: a bare `Adar` with no
628
+ * ordinal at all, or an unrecognized suffix such as `Adar Bogus`. An
629
+ * unqualified Adar conventionally denotes the second Adar in a leap year,
630
+ * so defaulting there keeps a silent miss on the more likely month.
631
+ *
632
+ * @param c normalized month name, already known to start with `adar`/`אדר`
633
+ * @returns {@link ADAR_I} (12) or {@link ADAR_II} (13)
634
+ */
635
+ function adarFromName(c) {
636
+ // Look only at the ordinal after the "adar"/"אדר" stem, and drop the
637
+ // separator (space/hyphen/period) plus any gershayim so that
638
+ // "Adar I", "Adar-I", "AdarI" and "אדר א׳" all reduce to the same token.
639
+ const suffix = c.replace(/^(adar|אדר)/, '').replace(/[\s.'`\-׳״]/g, '');
640
+ if (suffix === '1' ||
641
+ suffix === 'i' ||
642
+ suffix === 'a' ||
643
+ suffix === 'א' ||
644
+ suffix.startsWith('alef') ||
645
+ suffix.startsWith('aleph') ||
646
+ suffix.startsWith('alaph') ||
647
+ suffix.startsWith('rish') ||
648
+ suffix.startsWith('ראש') /* ראש (rishon) */ ||
649
+ suffix.startsWith('אל') /* אלף (alef) */) {
650
+ return ADAR_I$2;
651
+ }
652
+ // Explicit second-Adar spellings and every ambiguous form default here.
653
+ return ADAR_II$3;
654
+ }
609
655
  /**
610
656
  * Converts Hebrew month string name to numeric.
611
657
  *
@@ -613,17 +659,39 @@ function shortKislev(year) {
613
659
  * names with or without nikud (`'חשון'`, `'תִּשְׁרֵי'`), an optional bet
614
660
  * prefix (`'בתמוז'`), and passes numbers through unchanged. Matching is
615
661
  * case-insensitive and only needs enough of the name to be unambiguous.
616
- * `'Adar'` resolves to Adar I; `'Adar II'` (and `'אדר ב׳'`) to Adar II.
662
+ *
663
+ * Before matching, the name is trimmed and lower-cased, its nikud is
664
+ * removed (so `'תִּשְׁרֵי'` matches `'תשרי'`), and a single leading Hebrew
665
+ * bet — the "in/of" prefix, as in `'בתמוז'` ("in Tamuz") — is dropped.
666
+ *
667
+ * ### Adar in a leap year
668
+ *
669
+ * Once the name is recognized as Adar, the trailing ordinal decides
670
+ * between Adar I and Adar II across the many ways it gets written:
671
+ *
672
+ * - **Adar I** — `'Adar I'`, `'Adar 1'`, `'Adar Alef'`, `'Adar Rishon'`,
673
+ * `'אדר א'`, `'אדר ראשון'`.
674
+ * - **Adar II** — `'Adar II'`, `'Adar 2'`, `'Adar Bet'`, `'Adar Sheni'`,
675
+ * `'אדר ב'`, `'אדר שני'`.
676
+ *
677
+ * When the ordinal is missing or unrecognized (a bare `'Adar'`, or
678
+ * something like `'Adar Bogus'`) the result is **ambiguous and defaults to
679
+ * Adar II**, following the convention that an unqualified Adar means the
680
+ * second Adar in a leap year. See {@link adarFromName} for the full set of
681
+ * accepted spellings.
682
+ *
617
683
  * @param monthName monthName
618
684
  * @returns Hebrew month number (1=NISAN, 7=TISHREI)
619
685
  * @throws {TypeError} if `monthName` is neither a string nor a number
620
686
  * @throws {RangeError} if the name is not recognized, or a numeric month
621
687
  * is outside 1-14
622
688
  * @example
623
- * monthFromName('Cheshvan'); // 8
624
- * monthFromName('חשון'); // 8
625
- * monthFromName('Adar II'); // 13
626
- * monthFromName(7); // 7 (passthrough)
689
+ * monthFromName('Cheshvan'); // 8
690
+ * monthFromName('חשון'); // 8
691
+ * monthFromName('Adar Rishon'); // 12 (Adar I)
692
+ * monthFromName('Adar II'); // 13 (Adar II)
693
+ * monthFromName('Adar'); // 13 (ambiguous, defaults to Adar II)
694
+ * monthFromName(7); // 7 (passthrough)
627
695
  */
628
696
  function monthFromName(monthName) {
629
697
  if (typeof monthName === 'number') {
@@ -670,23 +738,23 @@ function monthFromName(monthName) {
670
738
  if (c[1] === 'o') {
671
739
  break; /* this catches "november" */
672
740
  }
673
- return NISAN$5;
741
+ return NISAN$6;
674
742
  case 'i':
675
- return IYYAR$2;
743
+ return IYYAR$3;
676
744
  case 'e':
677
- return ELUL$1;
745
+ return ELUL$2;
678
746
  case 'c':
679
747
  case 'ח':
680
- return CHESHVAN$2;
748
+ return CHESHVAN$3;
681
749
  case 'k':
682
750
  case 'כ':
683
751
  return KISLEV$2;
684
752
  case 's':
685
753
  switch (c[1]) {
686
754
  case 'i':
687
- return SIVAN$2;
755
+ return SIVAN$3;
688
756
  case 'h':
689
- return SHVAT$1;
757
+ return SHVAT$2;
690
758
  }
691
759
  break;
692
760
  case 't':
@@ -694,7 +762,7 @@ function monthFromName(monthName) {
694
762
  case 'a':
695
763
  return TAMUZ$2;
696
764
  case 'i':
697
- return TISHREI$2;
765
+ return TISHREI$3;
698
766
  case 'e':
699
767
  return TEVET$2;
700
768
  }
@@ -702,33 +770,27 @@ function monthFromName(monthName) {
702
770
  case 'a':
703
771
  switch (c[1]) {
704
772
  case 'v':
705
- return AV$2;
773
+ return AV$3;
706
774
  case 'd':
707
- if (/(1|[^i]i|a|א)$/i.test(c)) {
708
- return ADAR_I$2;
709
- }
710
- return ADAR_II$2; // else assume sheini
775
+ return adarFromName(c);
711
776
  }
712
777
  break;
713
778
  case 'ס':
714
- return SIVAN$2;
779
+ return SIVAN$3;
715
780
  case 'ט':
716
781
  return TEVET$2;
717
782
  case 'ש':
718
- return SHVAT$1;
783
+ return SHVAT$2;
719
784
  case 'א':
720
785
  switch (c[1]) {
721
786
  case 'ב':
722
- return AV$2;
787
+ return AV$3;
723
788
  case 'ד':
724
- if (/(1|[^i]i|a|א)$/i.test(c)) {
725
- return ADAR_I$2;
726
- }
727
- return ADAR_II$2; // else assume sheini
789
+ return adarFromName(c);
728
790
  case 'י':
729
- return IYYAR$2;
791
+ return IYYAR$3;
730
792
  case 'ל':
731
- return ELUL$1;
793
+ return ELUL$2;
732
794
  }
733
795
  break;
734
796
  case 'ת':
@@ -736,32 +798,33 @@ function monthFromName(monthName) {
736
798
  case 'מ':
737
799
  return TAMUZ$2;
738
800
  case 'ש':
739
- return TISHREI$2;
801
+ return TISHREI$3;
740
802
  }
741
803
  break;
742
804
  }
743
805
  throw new RangeError(`bad monthName: ${monthName}`);
744
806
  }
745
807
 
746
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
747
- const NISAN$4 = months.NISAN;
748
- const CHESHVAN$1 = months.CHESHVAN;
808
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
809
+ const NISAN$5 = months.NISAN;
810
+ const CHESHVAN$2 = months.CHESHVAN;
749
811
  const KISLEV$1 = months.KISLEV;
750
812
  const TEVET$1 = months.TEVET;
751
- const SHVAT = months.SHVAT;
813
+ const SHVAT$1 = months.SHVAT;
752
814
  const ADAR_I$1 = months.ADAR_I;
753
- const ADAR_II$1 = months.ADAR_II;
815
+ const ADAR_II$2 = months.ADAR_II;
754
816
  /**
755
817
  * Returns true if the object is a SimpleHebrewDate
756
818
  * @private
757
819
  */
758
- function isSimpleHebrewDate$1(obj0) {
759
- const obj = obj0;
760
- return (typeof obj === 'object' &&
761
- obj !== null &&
762
- typeof obj.yy === 'number' &&
763
- typeof obj.mm === 'number' &&
764
- typeof obj.dd === 'number');
820
+ function isSimpleHebrewDate$1(obj) {
821
+ if (typeof obj !== 'object' || obj === null) {
822
+ return false;
823
+ }
824
+ const hd = obj;
825
+ return (typeof hd.yy === 'number' &&
826
+ typeof hd.mm === 'number' &&
827
+ typeof hd.dd === 'number');
765
828
  }
766
829
  /**
767
830
  * Normalizes any accepted form of an event date into a `SimpleHebrewDate`.
@@ -775,15 +838,12 @@ function isSimpleHebrewDate$1(obj0) {
775
838
  */
776
839
  function toSimpleHebrewDate(obj) {
777
840
  if (isSimpleHebrewDate$1(obj)) {
778
- const hd = obj;
779
- return { yy: hd.yy, mm: hd.mm, dd: hd.dd };
841
+ return { yy: obj.yy, mm: obj.mm, dd: obj.dd };
780
842
  }
781
843
  else if (isDate(obj)) {
782
- const abs = greg2abs(obj);
783
- return abs2hebrew(abs);
844
+ return abs2hebrew(greg2abs(obj));
784
845
  }
785
846
  else {
786
- // typeof obj === 'number'
787
847
  return abs2hebrew(obj);
788
848
  }
789
849
  }
@@ -849,7 +909,7 @@ function getYahrzeitHD(hyear, date) {
849
909
  // Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
850
910
  return undefined;
851
911
  }
852
- if (hDeath.mm === CHESHVAN$1 &&
912
+ if (hDeath.mm === CHESHVAN$2 &&
853
913
  hDeath.dd === 30 &&
854
914
  !longCheshvan(hDeath.yy + 1)) {
855
915
  // If it's Heshvan 30 it depends on the first anniversary;
@@ -863,7 +923,7 @@ function getYahrzeitHD(hyear, date) {
863
923
  // if that was not Kislev 30, use the day before Teveth 1.
864
924
  hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
865
925
  }
866
- else if (hDeath.mm === ADAR_II$1) {
926
+ else if (hDeath.mm === ADAR_II$2) {
867
927
  // If it's Adar II, use the same day in last month of year (Adar or Adar II).
868
928
  hDeath.mm = monthsInYear(hyear);
869
929
  }
@@ -871,11 +931,11 @@ function getYahrzeitHD(hyear, date) {
871
931
  // If it's the 30th in Adar I and year is not a leap year
872
932
  // (so Adar has only 29 days), use the last day in Shevat.
873
933
  hDeath.dd = 30;
874
- hDeath.mm = SHVAT;
934
+ hDeath.mm = SHVAT$1;
875
935
  }
876
936
  // In all other cases, use the normal anniversary of the date of death.
877
937
  // advance day to rosh chodesh if needed
878
- if (hDeath.mm === CHESHVAN$1 && hDeath.dd === 30 && !longCheshvan(hyear)) {
938
+ if (hDeath.mm === CHESHVAN$2 && hDeath.dd === 30 && !longCheshvan(hyear)) {
879
939
  hDeath.mm = KISLEV$1;
880
940
  hDeath.dd = 1;
881
941
  }
@@ -943,10 +1003,10 @@ function getBirthdayHD(hyear, date) {
943
1003
  const isOrigLeap = isLeapYear(origYear);
944
1004
  let month = orig.mm;
945
1005
  let day = orig.dd;
946
- if ((month === ADAR_I$1 && !isOrigLeap) || (month === ADAR_II$1 && isOrigLeap)) {
1006
+ if ((month === ADAR_I$1 && !isOrigLeap) || (month === ADAR_II$2 && isOrigLeap)) {
947
1007
  month = monthsInYear(hyear);
948
1008
  }
949
- else if (month === CHESHVAN$1 && day === 30 && !longCheshvan(hyear)) {
1009
+ else if (month === CHESHVAN$2 && day === 30 && !longCheshvan(hyear)) {
950
1010
  month = KISLEV$1;
951
1011
  day = 1;
952
1012
  }
@@ -958,13 +1018,13 @@ function getBirthdayHD(hyear, date) {
958
1018
  day === 30 &&
959
1019
  isOrigLeap &&
960
1020
  !isLeapYear(hyear)) {
961
- month = NISAN$4;
1021
+ month = NISAN$5;
962
1022
  day = 1;
963
1023
  }
964
1024
  return { yy: hyear, mm: month, dd: day };
965
1025
  }
966
1026
 
967
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1027
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
968
1028
  const GERESH = '׳';
969
1029
  const GERSHAYIM = '״';
970
1030
  const heb2num = {
@@ -995,6 +1055,19 @@ const num2heb = {};
995
1055
  for (const [key, val] of Object.entries(heb2num)) {
996
1056
  num2heb[val] = key;
997
1057
  }
1058
+ /**
1059
+ * Final (sofit) Hebrew letters mapped to the value of their base form.
1060
+ * Used only when parsing a gematriya string; `gematriya()` never emits
1061
+ * these forms, so they are kept out of `heb2num` to avoid clobbering the
1062
+ * `num2heb` reverse map.
1063
+ */
1064
+ const sofit2num = {
1065
+ ך: 20,
1066
+ ם: 40,
1067
+ ן: 50,
1068
+ ף: 80,
1069
+ ץ: 90,
1070
+ };
998
1071
  function num2digits(num) {
999
1072
  const digits = [];
1000
1073
  while (num > 0) {
@@ -1027,7 +1100,7 @@ function num2digits(num) {
1027
1100
  * gematriya(1123) // 'א׳קכ״ג'
1028
1101
  */
1029
1102
  function gematriya(num) {
1030
- const num1 = parseInt(num, 10);
1103
+ const num1 = parseInt(String(num), 10);
1031
1104
  if (!num1 || num1 < 0) {
1032
1105
  throw new TypeError(`invalid number: ${num}`);
1033
1106
  }
@@ -1055,11 +1128,14 @@ function gematriya(num) {
1055
1128
  /**
1056
1129
  * Converts a string of Hebrew letters to a numerical value.
1057
1130
  *
1058
- * Only considers the value of Hebrew letters `א` through `ת`.
1059
- * Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
1060
- * and vowels (nekudot).
1131
+ * Considers the value of Hebrew letters `א` through `ת`, and the five final
1132
+ * (sofit) forms `ך`, `ם`, `ן`, `ף`, `ץ`, which count as their base letters
1133
+ * (20, 40, 50, 80, 90). This matches how Hebrew years are written — e.g.
1134
+ * `תש״ף` is 780 — since the last letter of a year falls in final form.
1135
+ * Vowels (nekudot) are ignored.
1061
1136
  * @example
1062
1137
  * gematriyaStrToNum('תשע״ד'); // 774
1138
+ * gematriyaStrToNum('תש״ף'); // 780 (final pe)
1063
1139
  * gematriyaStrToNum('ט״ו'); // 15
1064
1140
  * gematriyaStrToNum('ג׳תשס״א'); // 3761 (thousands prefix)
1065
1141
  */
@@ -1075,7 +1151,7 @@ function gematriyaStrToNum(str) {
1075
1151
  str = str.substring(gereshIdx);
1076
1152
  }
1077
1153
  for (const ch of str) {
1078
- const n = heb2num[ch];
1154
+ const n = heb2num[ch] ?? sofit2num[ch];
1079
1155
  if (typeof n === 'number') {
1080
1156
  num += n;
1081
1157
  }
@@ -1083,7 +1159,7 @@ function gematriyaStrToNum(str) {
1083
1159
  return num;
1084
1160
  }
1085
1161
 
1086
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1162
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1087
1163
  /**
1088
1164
  * Formats a number with leading zeros so the resulting string is 4 digits long.
1089
1165
  * Similar to `string.padStart(4, '0')` but will also format
@@ -1123,7 +1199,7 @@ function pad2(num) {
1123
1199
  return String(num);
1124
1200
  }
1125
1201
 
1126
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1202
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1127
1203
  const _formatters = new Map();
1128
1204
  /**
1129
1205
  * @private
@@ -1204,13 +1280,13 @@ function isoDateString(dt) {
1204
1280
  pad2(dt.getDate()));
1205
1281
  }
1206
1282
 
1207
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1283
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1208
1284
  var poAshkenazi$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "und-x-ashkenaz" }, "contexts": { "": { "Tevet": ["Teves"] } } };
1209
1285
 
1210
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1286
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1211
1287
  var poHe$1 = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he" }, "contexts": { "": { "Adar": ["אֲדָר"], "Adar I": ["אֲדָר א׳"], "Adar II": ["אֲדָר ב׳"], "Av": ["אָב"], "Cheshvan": ["חֶשְׁוָן"], "Elul": ["אֱלוּל"], "Iyyar": ["אִיָּיר"], "Kislev": ["כִּסְלֵו"], "Nisan": ["נִיסָן"], "Sh'vat": ["שְׁבָט"], "Sivan": ["סִיוָן"], "Tamuz": ["תַּמּוּז"], "Tammuz": ["תַּמּוּז"], "Tevet": ["טֵבֵת"], "Tishrei": ["תִּשְׁרֵי"] } } };
1212
1288
 
1213
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1289
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1214
1290
  const noopLocale = {
1215
1291
  headers: { 'plural-forms': 'nplurals=2; plural=(n!=1);' },
1216
1292
  contexts: { '': {} },
@@ -1494,7 +1570,7 @@ Locale.addLocale('he', poHe$1);
1494
1570
  const poHeNoNikud$1 = Locale.copyLocaleNoNikud(poHe$1);
1495
1571
  Locale.addLocale('he-x-NoNikud', poHeNoNikud$1);
1496
1572
 
1497
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1573
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
1498
1574
  /*
1499
1575
  Hebcal - A Jewish Calendar Generator
1500
1576
  Copyright (c) 1994-2020 Danny Sadinoff
@@ -1777,7 +1853,7 @@ class HDate {
1777
1853
  const locale0 = locale || 'en';
1778
1854
  const day = this.getDate();
1779
1855
  const monthName0 = Locale.gettext(this.getMonthName(), locale0);
1780
- const monthName = monthName0.replace(/'/g, '’');
1856
+ const monthName = monthName0.replaceAll("'", '’');
1781
1857
  const nth = Locale.ordinal(day, locale0);
1782
1858
  const dayOf = getDayOfTranslation(locale0);
1783
1859
  const dateStr = `${nth}${dayOf} ${monthName}`;
@@ -2177,15 +2253,16 @@ class HDate {
2177
2253
  * HDate.isHDate(12345); // false
2178
2254
  * HDate.isHDate('15 Cheshvan 5769'); // false
2179
2255
  */
2180
- static isHDate(obj0) {
2181
- const obj = obj0;
2182
- return (obj !== null &&
2183
- typeof obj === 'object' &&
2184
- typeof obj.yy === 'number' &&
2185
- typeof obj.mm === 'number' &&
2186
- typeof obj.dd === 'number' &&
2187
- typeof obj.greg === 'function' &&
2188
- typeof obj.abs === 'function');
2256
+ static isHDate(obj) {
2257
+ if (typeof obj !== 'object' || obj === null) {
2258
+ return false;
2259
+ }
2260
+ const hd = obj;
2261
+ return (typeof hd.yy === 'number' &&
2262
+ typeof hd.mm === 'number' &&
2263
+ typeof hd.dd === 'number' &&
2264
+ typeof hd.greg === 'function' &&
2265
+ typeof hd.abs === 'function');
2189
2266
  }
2190
2267
  /**
2191
2268
  * Construct a new instance of `HDate` from a Gematriya-formatted string.
@@ -2329,7 +2406,7 @@ function onOrBefore(day, t, offset) {
2329
2406
  return new HDate(HDate.dayOnOrBefore(day, t.abs() + offset));
2330
2407
  }
2331
2408
 
2332
- /*! @hebcal/hdate v0.22.8, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
2409
+ /*! @hebcal/hdate v0.23.0, distributed under GPLv2 https://www.gnu.org/licenses/gpl-2.0.txt */
2333
2410
  /**
2334
2411
  * Calculates yahrzeit, the anniversary of a death, and returns it as an
2335
2412
  * {@link HDate}.
@@ -2412,9 +2489,9 @@ function birthdayOrAnniversary(hyear, date) {
2412
2489
 
2413
2490
  var poAshkenazi = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "und-x-ashkenaz" }, "contexts": { "": { "Shabbat": ["Shabbos"], "Achrei Mot": ["Achrei Mos"], "Bechukotai": ["Bechukosai"], "Beha'alotcha": ["Beha’aloscha"], "Bereshit": ["Bereshis"], "Chukat": ["Chukas"], "Erev Shavuot": ["Erev Shavuos"], "Erev Sukkot": ["Erev Sukkos"], "Ki Tavo": ["Ki Savo"], "Ki Teitzei": ["Ki Seitzei"], "Ki Tisa": ["Ki Sisa"], "Matot": ["Matos"], "Pesach Shabbat Chol ha-Moed": ["Pesach Shabbos Chol ha-Moed"], "Purim Katan": ["Purim Koton"], "Rosh Hashana LaBehemot": ["Rosh Hashana LaBeheimos"], "Shabbat Chazon": ["Shabbos Chazon"], "Shabbat HaChodesh": ["Shabbos HaChodesh"], "Shabbat HaGadol": ["Shabbos HaGadol"], "Shabbat Nachamu": ["Shabbos Nachamu"], "Shabbat Parah": ["Shabbos Parah"], "Shabbat Shekalim": ["Shabbos Shekalim"], "Shabbat Shuva": ["Shabbos Shuvah"], "Shabbat Zachor": ["Shabbos Zachor"], "Shavuot": ["Shavuos"], "Shavuot I": ["Shavuos I"], "Shavuot II": ["Shavuos II"], "Shemot": ["Shemos"], "Shmini Atzeret": ["Shmini Atzeres"], "Simchat Torah": ["Simchas Torah"], "Sukkot": ["Sukkos"], "Sukkot I": ["Sukkos I"], "Sukkot II": ["Sukkos II"], "Sukkot II (CH''M)": ["Sukkos II (CH’’M)"], "Sukkot III (CH''M)": ["Sukkos III (CH’’M)"], "Sukkot IV (CH''M)": ["Sukkos IV (CH’’M)"], "Sukkot V (CH''M)": ["Sukkos V (CH’’M)"], "Sukkot VI (CH''M)": ["Sukkos VI (CH’’M)"], "Sukkot VII (Hoshana Raba)": ["Sukkos VII (Hoshana Raba)"], "Sukkot Shabbat Chol ha-Moed": ["Sukkos Shabbos Chol ha-Moed"], "Ta'anit Bechorot": ["Ta’anis Bechoros"], "Ta'anit BeHaB": ["Ta’anis BeHaB"], "Ta'anit Esther": ["Ta’anis Esther"], "Toldot": ["Toldos"], "Vaetchanan": ["Vaeschanan"], "Yitro": ["Yisro"], "Vezot Haberakhah": ["Vezos Haberakhah"], "Parashat": ["Parshas"], "Leil Selichot": ["Leil Selichos"], "Shabbat Mevarchim Chodesh": ["Shabbos Mevorchim Chodesh"], "Shabbat Shirah": ["Shabbos Shirah"], "Asara B'Tevet": ["Asara B’Teves"], "Birkat Hachamah": ["Birkas HaChamah"], "Birkat HaChamah": ["Birkas HaChamah"], "Shushan Purim Katan": ["Shushan Purim Koton"], "Alot HaShachar": ["Alos HaShachar"], "Misheyakir": ["Misheyakir"], "Misheyakir Machmir": ["Misheyakir Machmir"], "Sunrise": ["Sunrise"], "Kriat Shema, sof zeman": ["Krias Shema, sof zman"], "Tefilah, sof zeman": ["Tefilah, sof zman"], "Kriat Shema, sof zeman (MGA)": ["Krias Shema, sof zman (MGA)"], "Kriat Shema, sof zeman (GRA)": ["Krias Shema, sof zman (GRA)"], "Tefilah, sof zeman (MGA)": ["Tefilah, sof zman (MGA)"], "Tefilah, sof zeman (GRA)": ["Tefilah, sof zman (GRA)"], "Chatzot HaLailah": ["Chatzos HaLailah"], "Chatzot HaYom": ["Chatzos"], "Chatzot hayom": ["Chatzos"], "Mincha Gedolah": ["Mincha Gedolah"], "Mincha Ketanah": ["Mincha Ketanah"], "Plag HaMincha": ["Plag HaMincha"], "Sunset": ["Sunset"], "Bein HaShemashot": ["Bein HaShemashos"], "Tzeit HaKochavim": ["Tzeis HaKochavim"] } } };
2414
2491
 
2415
- var poHe = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he_IL" }, "contexts": { "": { "Shabbat": ["שַׁבָּת"], "Parashat": ["פָּרָשַׁת"], "Achrei Mot": ["אַחֲרֵי מוֹת"], "Balak": ["בָּלָק"], "Bamidbar": ["בְּמִדְבַּר"], "Bechukotai": ["בְּחֻקֹּתַי"], "Beha'alotcha": ["בְּהַעֲלֹתְךָ"], "Behar": ["בְּהַר"], "Bereshit": ["בְּרֵאשִׁית"], "Beshalach": ["בְּשַׁלַּח"], "Bo": ["בֹּא"], "Chayei Sara": ["חַיֵּי שָֹרָה"], "Chukat": ["חֻקַּת"], "Devarim": ["דְּבָרִים"], "Eikev": ["עֵקֶב"], "Emor": ["אֱמוֹר"], "Ha'azinu": ["הַאֲזִינוּ"], "Kedoshim": ["קְדֹשִׁים"], "Ki Tavo": ["כִּי־תָבוֹא"], "Ki Teitzei": ["כִּי־תֵצֵא"], "Ki Tisa": ["כִּי תִשָּׂא"], "Korach": ["קֹרַח"], "Lech-Lecha": ["לֶךְ־לְךָ"], "Masei": ["מַסְעֵי"], "Matot": ["מַטּוֹת"], "Metzora": ["מְצֹרָע"], "Miketz": ["מִקֵּץ"], "Mishpatim": ["מִשְׁפָּטִים"], "Nasso": ["נָשׂא"], "Nitzavim": ["נִצָּבִים"], "Noach": ["נֹחַ"], "Pekudei": ["פְקוּדֵי"], "Pinchas": ["פִּינְחָס"], "Re'eh": ["רְאֵה"], "Sh'lach": ["שְׁלַח־לְךָ"], "Shemot": ["שְׁמוֹת"], "Shmini": ["שְּׁמִינִי"], "Shoftim": ["שׁוֹפְטִים"], "Tazria": ["תַזְרִיעַ"], "Terumah": ["תְּרוּמָה"], "Tetzaveh": ["תְּצַוֶּה"], "Toldot": ["תּוֹלְדוֹת"], "Tzav": ["צַו"], "Vaera": ["וָאֵרָא"], "Vaetchanan": ["וָאֶתְחַנַּן"], "Vayakhel": ["וַיַּקְהֵל"], "Vayechi": ["וַיְחִי"], "Vayeilech": ["וַיֵּלֶךְ"], "Vayera": ["וַיֵּרָא"], "Vayeshev": ["וַיֵּשֶׁב"], "Vayetzei": ["וַיֵּצֵא"], "Vayigash": ["וַיִּגַּשׁ"], "Vayikra": ["וַיִּקְרָא"], "Vayishlach": ["וַיִּשְׁלַח"], "Vezot Haberakhah": ["וְזֹאת הַבְּרָכָה"], "Yitro": ["יִתְרוֹ"], "Asara B'Tevet": ["עֲשָׂרָה בְּטֵבֵת"], "Candle lighting": ["הַדְלָקַת נֵרוֹת"], "Chanukah": ["חֲנוּכָּה"], "Chanukah: 1 Candle": ["חֲנוּכָּה: א׳ נֵר"], "Chanukah: 2 Candles": ["חֲנוּכָּה: ב׳ נֵרוֹת"], "Chanukah: 3 Candles": ["חֲנוּכָּה: ג׳ נֵרוֹת"], "Chanukah: 4 Candles": ["חֲנוּכָּה: ד׳ נֵרוֹת"], "Chanukah: 5 Candles": ["חֲנוּכָּה: ה׳ נֵרוֹת"], "Chanukah: 6 Candles": ["חֲנוּכָּה: ו׳ נֵרוֹת"], "Chanukah: 7 Candles": ["חֲנוּכָּה: ז׳ נֵרוֹת"], "Chanukah: 8 Candles": ["חֲנוּכָּה: ח׳ נֵרוֹת"], "Chanukah: 8th Day": ["חֲנוּכָּה: יוֹם ח׳"], "Days of the Omer": ["סְפִירַת הָעוֹמֶר"], "Omer": ["עוֹמֶר"], "day of the Omer": ["בָּעוֹמֶר"], "Erev Pesach": ["עֶרֶב פֶּסַח"], "Erev Purim": ["עֶרֶב פּוּרִים"], "Erev Rosh Hashana": ["עֶרֶב רֹאשׁ הַשָּׁנָה"], "Erev Shavuot": ["עֶרֶב שָׁבוּעוֹת"], "Erev Simchat Torah": ["עֶרֶב שִׂמְחַת תּוֹרָה"], "Erev Sukkot": ["עֶרֶב סֻכּוֹת"], "Erev Tish'a B'Av": ["עֶרֶב תִּשְׁעָה בְּאָב"], "Erev Yom Kippur": ["עֶרֶב יוֹם כִּפּוּר"], "Havdalah": ["הַבְדָּלָה"], "Lag BaOmer": ["ל״ג בָּעוֹמֶר"], "Leil Selichot": ["סְלִיחוֹת"], "Pesach": ["פֶּסַח"], "Pesach I": ["פֶּסַח א׳"], "Pesach II": ["פֶּסַח ב׳"], "Pesach II (CH''M)": ["פֶּסַח ב׳ (חוה״מ)"], "Pesach III (CH''M)": ["פֶּסַח ג׳ (חוה״מ)"], "Pesach IV (CH''M)": ["פֶּסַח ד׳ (חוה״מ)"], "Pesach Sheni": ["פֶּסַח שֵׁנִי"], "Pesach V (CH''M)": ["פֶּסַח ה׳ (חוה״מ)"], "Pesach VI (CH''M)": ["פֶּסַח ו׳ (חוה״מ)"], "Pesach VII": ["פֶּסַח ז׳"], "Pesach VIII": ["פֶּסַח ח׳"], "Pesach Shabbat Chol ha-Moed": ["שַׁבַּת חֹל הַמּוֹעֵד פֶּסַח"], "Purim": ["פּוּרִים"], "Purim Katan": ["פּוּרִים קָטָן"], "Rosh Chodesh": ["רֹאשׁ חוֹדֶשׁ"], "Rosh Hashana": ["רֹאשׁ הַשָּׁנָה"], "Rosh Hashana I": ["רֹאשׁ הַשָּׁנָה א׳"], "Rosh Hashana II": ["רֹאשׁ הַשָּׁנָה ב׳"], "Shabbat Chazon": ["שַׁבַּת חֲזוֹן"], "Shabbat HaChodesh": ["שַׁבַּת הַחֹדֶשׁ"], "Shabbat HaGadol": ["שַׁבַּת הַגָּדוֹל"], "Shabbat Nachamu": ["שַׁבַּת נַחֲמוּ"], "Shabbat Parah": ["שַׁבַּת פָּרָה"], "Shabbat Shekalim": ["שַׁבַּת שְׁקָלִים"], "Shabbat Shuva": ["שַׁבַּת שׁוּבָה"], "Shabbat Zachor": ["שַׁבַּת זָכוֹר"], "Shavuot": ["שָׁבוּעוֹת"], "Shavuot I": ["שָׁבוּעוֹת א׳"], "Shavuot II": ["שָׁבוּעוֹת ב׳"], "Shmini Atzeret": ["שְׁמִינִי עֲצֶרֶת"], "Shushan Purim": ["שׁוּשָׁן פּוּרִים"], "Sigd": ["חַג הַסִּיגְד"], "Simchat Torah": ["שִׂמְחַת תּוֹרָה"], "Sukkot": ["סֻכּוֹת"], "Sukkot I": ["סֻכּוֹת א׳"], "Sukkot II": ["סֻכּוֹת ב׳"], "Sukkot II (CH''M)": ["סֻכּוֹת ב׳ (חוה״מ)"], "Sukkot III (CH''M)": ["סֻכּוֹת ג׳ (חוה״מ)"], "Sukkot IV (CH''M)": ["סֻכּוֹת ד׳ (חוה״מ)"], "Sukkot V (CH''M)": ["סֻכּוֹת ה׳ (חוה״מ)"], "Sukkot VI (CH''M)": ["סֻכּוֹת ו׳ (חוה״מ)"], "Sukkot VII (Hoshana Raba)": ["סֻכּוֹת ז׳ (הוֹשַׁעְנָא רַבָּה)"], "Sukkot Shabbat Chol ha-Moed": ["שַׁבַּת חֹל הַמּוֹעֵד סֻכּוֹת"], "Ta'anit Bechorot": ["תַּעֲנִית בְּכוֹרוֹת"], "Ta'anit BeHaB": ["תַּעֲנִית בה״ב"], "Ta'anit Esther": ["תַּעֲנִית אֶסְתֵּר"], "Tish'a B'Av": ["תִּשְׁעָה בְּאָב"], "Tu B'Av": ["ט״וּ בְּאָב"], "Tu BiShvat": ["ט״וּ בִּשְׁבָט"], "Tu B'Shvat": ["ט״וּ בִּשְׁבָט"], "Tzom Gedaliah": ["צוֹם גְּדַלְיָה"], "Tzom Tammuz": ["צוֹם י״ז בְּתַמּוּז"], "Yom HaAtzma'ut": ["יוֹם הָעַצְמָאוּת"], "Yom HaShoah": ["יוֹם הַשּׁוֹאָה"], "Yom HaZikaron": ["יוֹם הַזִּכָּרוֹן"], "Yom Kippur": ["יוֹם כִּפּוּר"], "Yom Yerushalayim": ["יוֹם יְרוּשָׁלַיִם"], "Yom HaAliyah": ["יוֹם הַעֲלִיָּה"], "Yom HaAliyah School Observance": ["שְׁמִירָת בֵּית הַסֵפֶר לְיוֹם הַעֲלִיָּה"], "Rosh Chodesh Adar": ["רֹאשׁ חוֹדֶשׁ אֲדָר"], "Rosh Chodesh Adar I": ["רֹאשׁ חוֹדֶשׁ אֲדָר א׳"], "Rosh Chodesh Adar II": ["רֹאשׁ חוֹדֶשׁ אֲדָר ב׳"], "Rosh Chodesh Av": ["רֹאשׁ חוֹדֶשׁ אָב"], "Rosh Chodesh Cheshvan": ["רֹאשׁ חוֹדֶשׁ חֶשְׁוָן"], "Rosh Chodesh Elul": ["רֹאשׁ חוֹדֶשׁ אֱלוּל"], "Rosh Chodesh Iyyar": ["רֹאשׁ חוֹדֶשׁ אִיָּיר"], "Rosh Chodesh Kislev": ["רֹאשׁ חוֹדֶשׁ כִּסְלֵו"], "Rosh Chodesh Nisan": ["רֹאשׁ חוֹדֶשׁ נִיסָן"], "Rosh Chodesh Sh'vat": ["רֹאשׁ חוֹדֶשׁ שְׁבָט"], "Rosh Chodesh Sivan": ["רֹאשׁ חוֹדֶשׁ סִיוָן"], "Rosh Chodesh Tamuz": ["רֹאשׁ חוֹדֶשׁ תַּמּוּז"], "Rosh Chodesh Tammuz": ["רֹאשׁ חוֹדֶשׁ תַּמּוּז"], "Rosh Chodesh Tevet": ["רֹאשׁ חוֹדֶשׁ טֵבֵת"], "min": ["דַּקּוֹת"], "Fast begins": ["תְּחִילַּת הַצוֹם"], "Fast ends": ["סִיּוּם הַצוֹם"], "Rosh Hashana LaBehemot": ["רֹאשׁ הַשָּׁנָה לְמַעְשַׂר בְּהֵמָה"], "Tish'a B'Av (observed)": ["(תִּשְׁעָה בְּאָב (נִדְחָה"], "Shabbat Mevarchim Chodesh": ["שַׁבַּת מְבָרְכִים חוֹדֶשׁ"], "Shabbat Shirah": ["שַׁבַּת שִׁירָה"], "Lovingkindness": ["חֶסֶד"], "Might": ["גְּבוּרָה"], "Beauty": ["תִּפְאֶרֶת"], "Eternity": ["נֶּצַח"], "Splendor": ["הוֹד"], "Foundation": ["יְּסוֹד"], "Majesty": ["מַּלְכוּת"], "day": ["יוֹם"], "Yom Kippur Katan": ["יוֹם כִּפּוּר קָטָן"], "Yizkor": ["יִזְכּוֹר"], "Family Day": ["יוֹם הַמִּשׁפָּחָה"], "Yitzhak Rabin Memorial Day": ["יוֹם הַזִּכָּרוֹן לְיִצְחָק רַבִּין"], "Jabotinsky Day": ["יוֹם זַ׳בּוֹטִינְסְקִי"], "Herzl Day": ["יוֹם הֶרְצְל"], "Ben-Gurion Day": ["יוֹם בֶּן־גּוּרִיּוֹן"], "Hebrew Language Day": ["יוֹם הַשָׂפָה הַעִברִית"], "Birkat Hachamah": ["בִּרְכַּת הַחַמָּה"], "Birkat HaChamah": ["בִּרְכַּת הַחַמָּה"], "Shushan Purim Katan": ["שׁוּשָׁן פּוּרִים קָטָן"], "Purim Meshulash": ["פּוּרִים מְשׁוּלָּשׁ"], "Chag HaBanot": ["חַג הַבָּנוֹת"], "Molad": ["מוֹלָד הָלְּבָנָה"], "chalakim": ["חֲלָקִים"], "Alot HaShachar": ["עֲלוֹת הַשַּׁחַר"], "Misheyakir": ["מִשֶּׁיַּכִּיר"], "Misheyakir Machmir": ["מִשֶּׁיַּכִּיר מַחְמִיר"], "Sunrise": ["נֵץ הַחַמָּה"], "Kriat Shema, sof zeman": ["סוֹף זְמַן קְרִיאַת שְׁמַע"], "Tefilah, sof zeman": ["סוֹף זְמַן תְּפִלָּה"], "Kriat Shema, sof zeman (MGA)": ["סוֹף זְמַן קְרִיאַת שְׁמַע (מג״א)"], "Kriat Shema, sof zeman (GRA)": ["סוֹף זְמַן קְרִיאַת שְׁמַע (גְּרָ״א)"], "Tefilah, sof zeman (MGA)": ["סוֹף זְמַן תְּפִלָּה (מג״א)"], "Tefilah, sof zeman (GRA)": ["סוֹף זְמַן תְּפִלָּה (גְּרָ״א)"], "Chatzot HaLailah": ["חֲצוֹת הַלַּיְלָה"], "Chatzot HaYom": ["חֲצוֹת הַיּוֹם"], "Chatzot hayom": ["חֲצוֹת הַיּוֹם"], "Mincha Gedolah": ["מִנְחָה גְּדוֹלָה"], "Mincha Ketanah": ["מִנְחָה קְטַנָּה"], "Plag HaMincha": ["פְּלַג הַמִּנְחָה"], "Sunset": ["שְׁקִיעַת הַחַמָּה"], "Bein HaShemashot": ["בֵּין הַשְּׁמָשׁוֹת"], "Tzeit HaKochavim": ["צֵאת הַכּוֹכָבִים"], "Biur Chametz": ["בִּעוּר חָמֵץ"], "Finish eating chametz": ["סוֹף זְמַן אֲכִילַת חָמֵץ"] } } };
2492
+ var poHe = { "headers": { "plural-forms": "nplurals=2; plural=(n > 1);", "language": "he_IL" }, "contexts": { "": { "Shabbat": ["שַׁבָּת"], "Parashat": ["פָּרָשַׁת"], "Achrei Mot": ["אַחֲרֵי מוֹת"], "Balak": ["בָּלָק"], "Bamidbar": ["בְּמִדְבַּר"], "Bechukotai": ["בְּחֻקֹּתַי"], "Beha'alotcha": ["בְּהַעֲלֹתְךָ"], "Behar": ["בְּהַר"], "Bereshit": ["בְּרֵאשִׁית"], "Beshalach": ["בְּשַׁלַּח"], "Bo": ["בֹּא"], "Chayei Sara": ["חַיֵּי שָֹרָה"], "Chukat": ["חֻקַּת"], "Devarim": ["דְּבָרִים"], "Eikev": ["עֵקֶב"], "Emor": ["אֱמוֹר"], "Ha'azinu": ["הַאֲזִינוּ"], "Kedoshim": ["קְדֹשִׁים"], "Ki Tavo": ["כִּי־תָבוֹא"], "Ki Teitzei": ["כִּי־תֵצֵא"], "Ki Tisa": ["כִּי תִשָּׂא"], "Korach": ["קֹרַח"], "Lech-Lecha": ["לֶךְ־לְךָ"], "Masei": ["מַסְעֵי"], "Matot": ["מַטּוֹת"], "Metzora": ["מְצֹרָע"], "Miketz": ["מִקֵּץ"], "Mishpatim": ["מִשְׁפָּטִים"], "Nasso": ["נָשׂא"], "Nitzavim": ["נִצָּבִים"], "Noach": ["נֹחַ"], "Pekudei": ["פְקוּדֵי"], "Pinchas": ["פִּינְחָס"], "Re'eh": ["רְאֵה"], "Sh'lach": ["שְׁלַח־לְךָ"], "Shemot": ["שְׁמוֹת"], "Shmini": ["שְּׁמִינִי"], "Shoftim": ["שׁוֹפְטִים"], "Tazria": ["תַזְרִיעַ"], "Terumah": ["תְּרוּמָה"], "Tetzaveh": ["תְּצַוֶּה"], "Toldot": ["תּוֹלְדוֹת"], "Tzav": ["צַו"], "Vaera": ["וָאֵרָא"], "Vaetchanan": ["וָאֶתְחַנַּן"], "Vayakhel": ["וַיַּקְהֵל"], "Vayechi": ["וַיְחִי"], "Vayeilech": ["וַיֵּלֶךְ"], "Vayera": ["וַיֵּרָא"], "Vayeshev": ["וַיֵּשֶׁב"], "Vayetzei": ["וַיֵּצֵא"], "Vayigash": ["וַיִּגַּשׁ"], "Vayikra": ["וַיִּקְרָא"], "Vayishlach": ["וַיִּשְׁלַח"], "Vezot Haberakhah": ["וְזֹאת הַבְּרָכָה"], "Yitro": ["יִתְרוֹ"], "Asara B'Tevet": ["עֲשָׂרָה בְּטֵבֵת"], "Candle lighting": ["הַדְלָקַת נֵרוֹת"], "Chanukah": ["חֲנוּכָּה"], "Chanukah: 1 Candle": ["חֲנוּכָּה: א׳ נֵר"], "Chanukah: 2 Candles": ["חֲנוּכָּה: ב׳ נֵרוֹת"], "Chanukah: 3 Candles": ["חֲנוּכָּה: ג׳ נֵרוֹת"], "Chanukah: 4 Candles": ["חֲנוּכָּה: ד׳ נֵרוֹת"], "Chanukah: 5 Candles": ["חֲנוּכָּה: ה׳ נֵרוֹת"], "Chanukah: 6 Candles": ["חֲנוּכָּה: ו׳ נֵרוֹת"], "Chanukah: 7 Candles": ["חֲנוּכָּה: ז׳ נֵרוֹת"], "Chanukah: 8 Candles": ["חֲנוּכָּה: ח׳ נֵרוֹת"], "Chanukah: 8th Day": ["חֲנוּכָּה: יוֹם ח׳"], "Days of the Omer": ["סְפִירַת הָעוֹמֶר"], "Omer": ["עוֹמֶר"], "day of the Omer": ["בָּעוֹמֶר"], "Erev Pesach": ["עֶרֶב פֶּסַח"], "Erev Purim": ["עֶרֶב פּוּרִים"], "Erev Rosh Hashana": ["עֶרֶב רֹאשׁ הַשָּׁנָה"], "Erev Shavuot": ["עֶרֶב שָׁבוּעוֹת"], "Erev Simchat Torah": ["עֶרֶב שִׂמְחַת תּוֹרָה"], "Erev Sukkot": ["עֶרֶב סֻכּוֹת"], "Erev Tish'a B'Av": ["עֶרֶב תִּשְׁעָה בְּאָב"], "Erev Yom Kippur": ["עֶרֶב יוֹם כִּפּוּר"], "Havdalah": ["הַבְדָּלָה"], "Lag BaOmer": ["ל״ג בָּעוֹמֶר"], "Leil Selichot": ["סְלִיחוֹת"], "Pesach": ["פֶּסַח"], "Pesach I": ["פֶּסַח א׳"], "Pesach II": ["פֶּסַח ב׳"], "Pesach II (CH''M)": ["פֶּסַח ב׳ (חוה״מ)"], "Pesach III (CH''M)": ["פֶּסַח ג׳ (חוה״מ)"], "Pesach IV (CH''M)": ["פֶּסַח ד׳ (חוה״מ)"], "Pesach Sheni": ["פֶּסַח שֵׁנִי"], "Pesach V (CH''M)": ["פֶּסַח ה׳ (חוה״מ)"], "Pesach VI (CH''M)": ["פֶּסַח ו׳ (חוה״מ)"], "Pesach VII": ["פֶּסַח ז׳"], "Pesach VIII": ["פֶּסַח ח׳"], "Pesach Shabbat Chol ha-Moed": ["שַׁבַּת חֹל הַמּוֹעֵד פֶּסַח"], "Purim": ["פּוּרִים"], "Purim Katan": ["פּוּרִים קָטָן"], "Rosh Chodesh": ["רֹאשׁ חוֹדֶשׁ"], "Rosh Hashana": ["רֹאשׁ הַשָּׁנָה"], "Rosh Hashana I": ["רֹאשׁ הַשָּׁנָה א׳"], "Rosh Hashana II": ["רֹאשׁ הַשָּׁנָה ב׳"], "Shabbat Chazon": ["שַׁבַּת חֲזוֹן"], "Shabbat HaChodesh": ["שַׁבַּת הַחֹדֶשׁ"], "Shabbat HaGadol": ["שַׁבַּת הַגָּדוֹל"], "Shabbat Nachamu": ["שַׁבַּת נַחֲמוּ"], "Shabbat Parah": ["שַׁבַּת פָּרָה"], "Shabbat Shekalim": ["שַׁבַּת שְׁקָלִים"], "Shabbat Shuva": ["שַׁבַּת שׁוּבָה"], "Shabbat Zachor": ["שַׁבַּת זָכוֹר"], "Shavuot": ["שָׁבוּעוֹת"], "Shavuot I": ["שָׁבוּעוֹת א׳"], "Shavuot II": ["שָׁבוּעוֹת ב׳"], "Shmini Atzeret": ["שְׁמִינִי עֲצֶרֶת"], "Shushan Purim": ["שׁוּשָׁן פּוּרִים"], "Sigd": ["חַג הַסִּיגְד"], "Simchat Torah": ["שִׂמְחַת תּוֹרָה"], "Sukkot": ["סֻכּוֹת"], "Sukkot I": ["סֻכּוֹת א׳"], "Sukkot II": ["סֻכּוֹת ב׳"], "Sukkot II (CH''M)": ["סֻכּוֹת ב׳ (חוה״מ)"], "Sukkot III (CH''M)": ["סֻכּוֹת ג׳ (חוה״מ)"], "Sukkot IV (CH''M)": ["סֻכּוֹת ד׳ (חוה״מ)"], "Sukkot V (CH''M)": ["סֻכּוֹת ה׳ (חוה״מ)"], "Sukkot VI (CH''M)": ["סֻכּוֹת ו׳ (חוה״מ)"], "Sukkot VII (Hoshana Raba)": ["סֻכּוֹת ז׳ (הוֹשַׁעְנָא רַבָּה)"], "Sukkot Shabbat Chol ha-Moed": ["שַׁבַּת חֹל הַמּוֹעֵד סֻכּוֹת"], "Ta'anit Bechorot": ["תַּעֲנִית בְּכוֹרוֹת"], "Ta'anit BeHaB": ["תַּעֲנִית בה״ב"], "Ta'anit Esther": ["תַּעֲנִית אֶסְתֵּר"], "Tish'a B'Av": ["תִּשְׁעָה בְּאָב"], "Tu B'Av": ["ט״וּ בְּאָב"], "Tu BiShvat": ["ט״וּ בִּשְׁבָט"], "Tu B'Shvat": ["ט״וּ בִּשְׁבָט"], "Tzom Gedaliah": ["צוֹם גְּדַלְיָה"], "Tzom Tammuz": ["צוֹם י״ז בְּתַמּוּז"], "Yom HaAtzma'ut": ["יוֹם הָעַצְמָאוּת"], "Yom HaShoah": ["יוֹם הַשּׁוֹאָה"], "Yom HaZikaron": ["יוֹם הַזִּכָּרוֹן"], "Yom Kippur": ["יוֹם כִּפּוּר"], "Yom Yerushalayim": ["יוֹם יְרוּשָׁלַיִם"], "Yom HaAliyah": ["יוֹם הַעֲלִיָּה"], "Yom HaAliyah School Observance": ["שְׁמִירָת בֵּית הַסֵפֶר לְיוֹם הַעֲלִיָּה"], "Rosh Chodesh Adar": ["רֹאשׁ חוֹדֶשׁ אֲדָר"], "Rosh Chodesh Adar I": ["רֹאשׁ חוֹדֶשׁ אֲדָר א׳"], "Rosh Chodesh Adar II": ["רֹאשׁ חוֹדֶשׁ אֲדָר ב׳"], "Rosh Chodesh Av": ["רֹאשׁ חוֹדֶשׁ אָב"], "Rosh Chodesh Cheshvan": ["רֹאשׁ חוֹדֶשׁ חֶשְׁוָן"], "Rosh Chodesh Elul": ["רֹאשׁ חוֹדֶשׁ אֱלוּל"], "Rosh Chodesh Iyyar": ["רֹאשׁ חוֹדֶשׁ אִיָּיר"], "Rosh Chodesh Kislev": ["רֹאשׁ חוֹדֶשׁ כִּסְלֵו"], "Rosh Chodesh Nisan": ["רֹאשׁ חוֹדֶשׁ נִיסָן"], "Rosh Chodesh Sh'vat": ["רֹאשׁ חוֹדֶשׁ שְׁבָט"], "Rosh Chodesh Sivan": ["רֹאשׁ חוֹדֶשׁ סִיוָן"], "Rosh Chodesh Tamuz": ["רֹאשׁ חוֹדֶשׁ תַּמּוּז"], "Rosh Chodesh Tammuz": ["רֹאשׁ חוֹדֶשׁ תַּמּוּז"], "Rosh Chodesh Tevet": ["רֹאשׁ חוֹדֶשׁ טֵבֵת"], "min": ["דַּקּוֹת"], "Fast begins": ["תְּחִילַּת הַצוֹם"], "Fast ends": ["סִיּוּם הַצוֹם"], "Rosh Hashana LaBehemot": ["רֹאשׁ הַשָּׁנָה לְמַעְשַׂר בְּהֵמָה"], "Tish'a B'Av (observed)": ["(תִּשְׁעָה בְּאָב (נִדְחָה"], "Shabbat Mevarchim Chodesh": ["שַׁבַּת מְבָרְכִים חוֹדֶשׁ"], "Shabbat Shirah": ["שַׁבַּת שִׁירָה"], "Lovingkindness": ["חֶסֶד"], "Might": ["גְּבוּרָה"], "Beauty": ["תִּפְאֶרֶת"], "Eternity": ["נֶּצַח"], "Splendor": ["הוֹד"], "Foundation": ["יְּסוֹד"], "Majesty": ["מַּלְכוּת"], "day": ["יוֹם"], "Yom Kippur Katan": ["יוֹם כִּפּוּר קָטָן"], "Yizkor": ["יִזְכּוֹר"], "Family Day": ["יוֹם הַמִּשׁפָּחָה"], "Yitzhak Rabin Memorial Day": ["יוֹם הַזִּכָּרוֹן לְיִצְחָק רַבִּין"], "Jabotinsky Day": ["יוֹם זַ׳בּוֹטִינְסְקִי"], "Herzl Day": ["יוֹם הֶרְצְל"], "Ben-Gurion Day": ["יוֹם בֶּן־גּוּרִיּוֹן"], "Hebrew Language Day": ["יוֹם הַשָׂפָה הַעִברִית"], "Birkat Hachamah": ["בִּרְכַּת הַחַמָּה"], "Birkat HaChamah": ["בִּרְכַּת הַחַמָּה"], "Shushan Purim Katan": ["שׁוּשָׁן פּוּרִים קָטָן"], "Purim Meshulash": ["פּוּרִים מְשׁוּלָּשׁ"], "Chag HaBanot": ["חַג הַבָּנוֹת"], "Molad": ["מוֹלָד הָלְּבָנָה"], "chalakim": ["חֲלָקִים"], "Alot HaShachar": ["עֲלוֹת הַשַּׁחַר"], "Misheyakir": ["מִשֶּׁיַּכִּיר"], "Misheyakir Machmir": ["מִשֶּׁיַּכִּיר מַחְמִיר"], "Sunrise": ["נֵץ הַחַמָּה"], "Kriat Shema, sof zeman": ["סוֹף זְמַן קְרִיאַת שְׁמַע"], "Tefilah, sof zeman": ["סוֹף זְמַן תְּפִלָּה"], "Kriat Shema, sof zeman (MGA)": ["סוֹף זְמַן קְרִיאַת שְׁמַע (מג״א)"], "Kriat Shema, sof zeman (GRA)": ["סוֹף זְמַן קְרִיאַת שְׁמַע (גְּרָ״א)"], "Tefilah, sof zeman (MGA)": ["סוֹף זְמַן תְּפִלָּה (מג״א)"], "Tefilah, sof zeman (GRA)": ["סוֹף זְמַן תְּפִלָּה (גְּרָ״א)"], "Chatzot HaLailah": ["חֲצוֹת הַלַּיְלָה"], "Chatzot HaYom": ["חֲצוֹת הַיּוֹם"], "Chatzot hayom": ["חֲצוֹת הַיּוֹם"], "Mincha Gedolah": ["מִנְחָה גְּדוֹלָה"], "Mincha Ketanah": ["מִנְחָה קְטַנָּה"], "Plag HaMincha": ["פְּלַג הַמִּנְחָה"], "Sunset": ["שְׁקִיעַת הַחַמָּה"], "Bein HaShemashot": ["בֵּין הַשְּׁמָשׁוֹת"], "Tzeit HaKochavim": ["צֵאת הַכּוֹכָבִים"], "Biur Chametz": ["בִּעוּר חָמֵץ"], "Finish eating chametz": ["סוֹף זְמַן אֲכִילַת חָמֵץ"], "Swords of Iron War Memorial Day": ["יוֹם הַזִּכָּרוֹן לְחַלְלֵי מִלְחֶמֶת חַרְבוֹת בַּרְזֶל"] } } };
2416
2493
 
2417
- var noNikudOverride = { "headers": { "plural-forms": "nplurals=2; plural=(n != 1);", "language": "he-x-NoNikud" }, "contexts": { "": { "Korach": ["קורח"], "Chukat": ["חוקת"], "Erev Yom Kippur": ["ערב יום כיפור"], "Yom Kippur": ["יום כיפור"], "Yom Kippur Katan": ["יום כיפור קטן"], "Pesach Shabbat Chol ha-Moed": ["שבת חול המועד פסח"], "Sukkot Shabbat Chol ha-Moed": ["שבת חול המועד סוכות"], "Erev Sukkot": ["ערב סוכות"], "Sukkot": ["סוכות"], "Sukkot I": ["סוכות א׳"], "Sukkot II": ["סוכות ב׳"], "Sukkot II (CH''M)": ["סוכות ב׳ (חוה״מ)"], "Sukkot III (CH''M)": ["סוכות ג׳ (חוה״מ)"], "Sukkot IV (CH''M)": ["סוכות ד׳ (חוה״מ)"], "Sukkot V (CH''M)": ["סוכות ה׳ (חוה״מ)"], "Sukkot VI (CH''M)": ["סוכות ו׳ (חוה״מ)"], "Sukkot VII (Hoshana Raba)": ["סוכות ז׳ (הושענא רבה)"] } } };
2494
+ var noNikudOverride = { "headers": { "plural-forms": "nplurals=2; plural=(n != 1);", "language": "he-x-NoNikud" }, "contexts": { "": { "Korach": ["קורח"], "Chukat": ["חוקת"], "Erev Yom Kippur": ["ערב יום כיפור"], "Yom Kippur": ["יום כיפור"], "Yom Kippur Katan": ["יום כיפור קטן"], "Pesach Shabbat Chol ha-Moed": ["שבת חול המועד פסח"], "Sukkot Shabbat Chol ha-Moed": ["שבת חול המועד סוכות"], "Erev Sukkot": ["ערב סוכות"], "Sukkot": ["סוכות"], "Sukkot I": ["סוכות א׳"], "Sukkot II": ["סוכות ב׳"], "Sukkot II (CH''M)": ["סוכות ב׳ (חוה״מ)"], "Sukkot III (CH''M)": ["סוכות ג׳ (חוה״מ)"], "Sukkot IV (CH''M)": ["סוכות ד׳ (חוה״מ)"], "Sukkot V (CH''M)": ["סוכות ה׳ (חוה״מ)"], "Sukkot VI (CH''M)": ["סוכות ו׳ (חוה״מ)"], "Sukkot VII (Hoshana Raba)": ["סוכות ז׳ (הושענא רבה)"], "Swords of Iron War Memorial Day": ["יום הזיכרון לחללי מלחמת חרבות ברזל"] } } };
2418
2495
 
2419
2496
  Locale.addTranslations('he', poHe);
2420
2497
  Locale.addTranslations('ashkenazi', poAshkenazi);
@@ -2746,11 +2823,9 @@ class Event {
2746
2823
  * .getCategories(); // ['roshchodesh']
2747
2824
  */
2748
2825
  getCategories() {
2749
- const mask = this.mask;
2750
- for (const attrs of flagToCategory) {
2751
- const attr0 = attrs[0];
2752
- if (mask & attr0) {
2753
- return attrs.slice(1);
2826
+ for (const [bit, ...categories] of flagToCategory) {
2827
+ if (this.mask & bit) {
2828
+ return categories;
2754
2829
  }
2755
2830
  }
2756
2831
  return ['unknown'];
@@ -2789,15 +2864,11 @@ class HebrewDateEvent extends Event {
2789
2864
  return hd.render(locale0, true);
2790
2865
  }
2791
2866
  }
2792
- /**
2793
- * @private
2794
- * @param locale
2795
- */
2796
2867
  renderBriefHebrew(locale) {
2797
2868
  const hd = this.getDate();
2798
2869
  const dd = hd.getDate();
2799
2870
  const mm = Locale.gettext(hd.getMonthName(), locale);
2800
- return gematriya(dd) + ' ' + mm;
2871
+ return `${gematriya(dd)} ${mm}`;
2801
2872
  }
2802
2873
  /**
2803
2874
  * @param [locale] Optional locale name (defaults to empty locale)
@@ -9072,14 +9143,12 @@ const ZIPCODES_TZ_MAP = {
9072
9143
  '15': 'Pacific/Palau', // Palau (GMT +9:00)
9073
9144
  '16': 'Pacific/Chuuk', // Micronesia (GMT +11:00)
9074
9145
  };
9075
- /** @private */
9076
9146
  const timeFormatCache = new QuickLRU({
9077
9147
  maxSize: 120,
9078
9148
  });
9079
9149
  /**
9080
9150
  * Gets a 24-hour time formatter (e.g. 07:41 or 20:03) from cache
9081
9151
  * or makes a new one if needed
9082
- * @private
9083
9152
  */
9084
9153
  function getFormatter(tzid) {
9085
9154
  const fmt = timeFormatCache.get(tzid);
@@ -9155,11 +9224,8 @@ class Location extends GeoLocation {
9155
9224
  cityName = String(cityName);
9156
9225
  }
9157
9226
  super(cityName || null, lat, long, elev, tzid);
9158
- this.il = Boolean(il);
9227
+ this.il = Boolean(il) || countryCode === 'IL';
9159
9228
  this.cc = countryCode;
9160
- if (countryCode === 'IL') {
9161
- this.il = true;
9162
- }
9163
9229
  this.geoid = geoid;
9164
9230
  }
9165
9231
  /**
@@ -9375,20 +9441,21 @@ class Location extends GeoLocation {
9375
9441
  }
9376
9442
  }
9377
9443
 
9378
- const hour12cc = {
9379
- US: 1,
9380
- CA: 1,
9381
- BR: 1,
9382
- AU: 1,
9383
- NZ: 1,
9384
- DO: 1,
9385
- PR: 1,
9386
- GR: 1,
9387
- IN: 1,
9388
- KR: 1,
9389
- NP: 1,
9390
- ZA: 1,
9391
- };
9444
+ /** Countries that conventionally use a 12-hour clock */
9445
+ const hour12cc = new Set([
9446
+ 'US',
9447
+ 'CA',
9448
+ 'BR',
9449
+ 'AU',
9450
+ 'NZ',
9451
+ 'DO',
9452
+ 'PR',
9453
+ 'GR',
9454
+ 'IN',
9455
+ 'KR',
9456
+ 'NP',
9457
+ 'ZA',
9458
+ ]);
9392
9459
  /**
9393
9460
  * Helper function to format a 24-hour (00:00-23:59) time string in either
9394
9461
  * 12-hour US format (e.g. `"8:13pm"`) or keep it in 24-hour format (e.g.
@@ -9415,7 +9482,7 @@ function reformatTimeStr(timeStr, suffix, options) {
9415
9482
  if (hour12 !== undefined && !hour12) {
9416
9483
  return timeStr;
9417
9484
  }
9418
- if (!hour12 && hour12cc[cc] === undefined) {
9485
+ if (!hour12 && !hour12cc.has(cc)) {
9419
9486
  return timeStr;
9420
9487
  }
9421
9488
  const hm = timeStr.split(':');
@@ -9515,13 +9582,12 @@ function calculateMolad(year, month) {
9515
9582
  hd = hd.next();
9516
9583
  }
9517
9584
  hour = (hour + 18) % 24;
9518
- const m = {
9585
+ return {
9519
9586
  hdate: hd,
9520
9587
  hour,
9521
9588
  minutes,
9522
9589
  chalakim: adjustedChalakim - minutes * CHALAKIM_PER_MINUTE,
9523
9590
  };
9524
- return m;
9525
9591
  }
9526
9592
 
9527
9593
  /** constant for milliseconds in a minute (60,000) */
@@ -9860,7 +9926,7 @@ class Molad {
9860
9926
  if (chalakim === 0) {
9861
9927
  return result;
9862
9928
  }
9863
- return result + ` ${and} ${chalakim} ${chalakimStr}`;
9929
+ return `${result} ${and} ${chalakim} ${chalakimStr}`;
9864
9930
  }
9865
9931
  }
9866
9932
  /** Represents a Molad announcement on Shabbat Mevarchim */
@@ -9894,11 +9960,13 @@ class MoladEvent extends Event {
9894
9960
  * `Temporal.ZonedDateTime`. Resolving the IANA zone to build a
9895
9961
  * `ZonedDateTime` costs roughly 750ns and nothing downstream uses it, which
9896
9962
  * made it the single most expensive step in a sunrise/sunset calculation.
9897
- * @private
9898
9963
  */
9899
9964
  function millisToDate(millis) {
9900
9965
  const res = new Date(millis);
9901
- res.setMilliseconds(0);
9966
+ // UTC setter: a local-time setter re-resolves the wall-clock time and, in
9967
+ // the repeated hour at the end of DST in the process time zone, would move
9968
+ // the instant an hour earlier. See hebcal/hebcal-es6#786.
9969
+ res.setUTCMilliseconds(0);
9902
9970
  return res;
9903
9971
  }
9904
9972
  /**
@@ -9923,11 +9991,17 @@ const CIVIL_ZENITH = GEOMETRIC_ZENITH + 6;
9923
9991
  * Length of one temporal (halachic) hour in milliseconds, i.e. one twelfth of
9924
9992
  * the day. Mirrors `NOAACalculator.getTemporalHour()`, including its floor, so
9925
9993
  * that results stay identical to the `ZonedDateTime` code path.
9926
- * @private
9927
9994
  */
9928
9995
  function temporalHourMillis(startOfDay, endOfDay) {
9929
9996
  return Math.floor((endOfDay - startOfDay) / 12);
9930
9997
  }
9998
+ /**
9999
+ * Returns the moment `hours` temporal hours after `startOfDay`, where one
10000
+ * temporal hour lasts `temporalHour` milliseconds
10001
+ */
10002
+ function addTemporalHours(startOfDay, temporalHour, hours) {
10003
+ return new Date(startOfDay.getTime() + Math.floor(hours * temporalHour));
10004
+ }
9931
10005
  /**
9932
10006
  * Calculate halachic times (zmanim / זְמַנִּים) for a given day and location.
9933
10007
  * Calculations are available for tzeit / tzais (nightfall),
@@ -10020,7 +10094,6 @@ class Zmanim {
10020
10094
  * as well; the adjustment is a no-op unless the zenith is exactly
10021
10095
  * {@link GEOMETRIC_ZENITH}, which is why degree-based zmanim are unaffected
10022
10096
  * by elevation.
10023
- * @private
10024
10097
  */
10025
10098
  sunriseMillis(zenith, useElevation) {
10026
10099
  const utc = useElevation
@@ -10030,7 +10103,6 @@ class Zmanim {
10030
10103
  }
10031
10104
  /**
10032
10105
  * Sunset counterpart of {@link sunriseMillis}.
10033
- * @private
10034
10106
  */
10035
10107
  sunsetMillis(zenith, useElevation) {
10036
10108
  const utc = useElevation
@@ -10248,8 +10320,7 @@ class Zmanim {
10248
10320
  sofZmanShmaMGA() {
10249
10321
  // Magen Avraham
10250
10322
  const [alot72, temporalHour] = this.getTemporalHour72(true);
10251
- const offset = Math.floor(3 * temporalHour);
10252
- return new Date(alot72.getTime() + offset);
10323
+ return addTemporalHours(alot72, temporalHour, 3);
10253
10324
  }
10254
10325
  /**
10255
10326
  * Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham.
@@ -10258,8 +10329,7 @@ class Zmanim {
10258
10329
  */
10259
10330
  sofZmanShmaMGA16Point1() {
10260
10331
  const [alot, temporalHour] = this.getTemporalHourByDeg(16.1);
10261
- const offset = Math.floor(3 * temporalHour);
10262
- return new Date(alot.getTime() + offset);
10332
+ return addTemporalHours(alot, temporalHour, 3);
10263
10333
  }
10264
10334
  /**
10265
10335
  * Latest Shema (MGA); Sunrise plus 3 halachic hours, according to Magen Avraham.
@@ -10272,8 +10342,7 @@ class Zmanim {
10272
10342
  */
10273
10343
  sofZmanShmaMGA19Point8() {
10274
10344
  const [alot, temporalHour] = this.getTemporalHourByDeg(19.8);
10275
- const offset = Math.floor(3 * temporalHour);
10276
- return new Date(alot.getTime() + offset);
10345
+ return addTemporalHours(alot, temporalHour, 3);
10277
10346
  }
10278
10347
  /**
10279
10348
  * Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham
@@ -10281,8 +10350,7 @@ class Zmanim {
10281
10350
  sofZmanTfillaMGA() {
10282
10351
  // Magen Avraham
10283
10352
  const [alot72, temporalHour] = this.getTemporalHour72(true);
10284
- const offset = Math.floor(4 * temporalHour);
10285
- return new Date(alot72.getTime() + offset);
10353
+ return addTemporalHours(alot72, temporalHour, 4);
10286
10354
  }
10287
10355
  /**
10288
10356
  * Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham.
@@ -10291,8 +10359,7 @@ class Zmanim {
10291
10359
  */
10292
10360
  sofZmanTfillaMGA16Point1() {
10293
10361
  const [alot, temporalHour] = this.getTemporalHourByDeg(16.1);
10294
- const offset = Math.floor(4 * temporalHour);
10295
- return new Date(alot.getTime() + offset);
10362
+ return addTemporalHours(alot, temporalHour, 4);
10296
10363
  }
10297
10364
  /**
10298
10365
  * Latest Shacharit (MGA); Sunrise plus 4 halachic hours, according to Magen Avraham.
@@ -10305,8 +10372,7 @@ class Zmanim {
10305
10372
  */
10306
10373
  sofZmanTfillaMGA19Point8() {
10307
10374
  const [alot, temporalHour] = this.getTemporalHourByDeg(19.8);
10308
- const offset = Math.floor(4 * temporalHour);
10309
- return new Date(alot.getTime() + offset);
10375
+ return addTemporalHours(alot, temporalHour, 4);
10310
10376
  }
10311
10377
  /**
10312
10378
  * Earliest Mincha – Mincha Gedola (GRA); Sunrise plus 6.5 halachic hours.
@@ -10334,8 +10400,7 @@ class Zmanim {
10334
10400
  */
10335
10401
  minchaGedolaMGA() {
10336
10402
  const [alot72, temporalHour] = this.getTemporalHour72(false);
10337
- const offset = Math.floor(6.5 * temporalHour);
10338
- return new Date(alot72.getTime() + offset);
10403
+ return addTemporalHours(alot72, temporalHour, 6.5);
10339
10404
  }
10340
10405
  /**
10341
10406
  * Preferable earliest time to recite Minchah – Mincha Ketana; Sunrise plus 9.5 halachic hours.
@@ -10360,7 +10425,7 @@ class Zmanim {
10360
10425
  */
10361
10426
  minchaKetanaMGA() {
10362
10427
  const [alot72, temporalHour] = this.getTemporalHour72(false);
10363
- return new Date(alot72.getTime() + Math.floor(9.5 * temporalHour));
10428
+ return addTemporalHours(alot72, temporalHour, 9.5);
10364
10429
  }
10365
10430
  /**
10366
10431
  * Plag haMincha; Sunrise plus 10.75 halachic hours.
@@ -10820,7 +10885,7 @@ class Zmanim {
10820
10885
  time.charCodeAt(1) === 0x34 && // '4'
10821
10886
  time.charCodeAt(2) === 0x3a // ':'
10822
10887
  ) {
10823
- return '00' + time.substring(2);
10888
+ return `00${time.substring(2)}`;
10824
10889
  }
10825
10890
  return time;
10826
10891
  }
@@ -10853,7 +10918,8 @@ class Zmanim {
10853
10918
  const offsetAbs = Math.abs(offset);
10854
10919
  const hours = Math.floor(offsetAbs / 60);
10855
10920
  const minutes = offsetAbs % 60;
10856
- return (offset < 0 ? '+' : '-') + pad2(hours) + ':' + pad2(minutes);
10921
+ const sign = offset < 0 ? '+' : '-';
10922
+ return `${sign}${pad2(hours)}:${pad2(minutes)}`;
10857
10923
  }
10858
10924
  /**
10859
10925
  * Returns a string like "2022-04-01T13:06:00-11:00"
@@ -10881,10 +10947,10 @@ class Zmanim {
10881
10947
  }
10882
10948
  if (roundMinute) {
10883
10949
  // For positive offsets only, round up to next minute if needed
10884
- if (offset > 0 && sunrise.getSeconds() >= 30) {
10950
+ if (offset > 0 && sunrise.getUTCSeconds() >= 30) {
10885
10951
  offset++;
10886
10952
  }
10887
- sunrise.setSeconds(0, 0);
10953
+ sunrise.setUTCSeconds(0, 0);
10888
10954
  }
10889
10955
  return new Date(sunrise.getTime() + offset * 60 * 1000);
10890
10956
  }
@@ -10903,10 +10969,10 @@ class Zmanim {
10903
10969
  }
10904
10970
  if (roundMinute) {
10905
10971
  // For Havdalah only, round up to next minute if needed
10906
- if (offset > 0 && sunset.getSeconds() >= 30) {
10972
+ if (offset > 0 && sunset.getUTCSeconds() >= 30) {
10907
10973
  offset++;
10908
10974
  }
10909
- sunset.setSeconds(0, 0);
10975
+ sunset.setUTCSeconds(0, 0);
10910
10976
  }
10911
10977
  return new Date(sunset.getTime() + offset * 60 * 1000);
10912
10978
  }
@@ -10946,1556 +11012,1373 @@ class Zmanim {
10946
11012
  }
10947
11013
  }
10948
11014
 
10949
- const SUN$1 = 0;
10950
- const TUE$1 = 2;
10951
- const FRI$2 = 5;
10952
- const SAT$3 = 6;
10953
- const NISAN$3 = months.NISAN;
10954
- const IYYAR$1 = months.IYYAR;
11015
+ const { NISAN: NISAN$4, IYYAR: IYYAR$2, SIVAN: SIVAN$2, AV: AV$2, ELUL: ELUL$1, TISHREI: TISHREI$2, SHVAT, ADAR_II: ADAR_II$1 } = months;
11016
+ const { CHAG: CHAG$1, LIGHT_CANDLES: LIGHT_CANDLES$2, YOM_TOV_ENDS: YOM_TOV_ENDS$1, CHUL_ONLY: CHUL_ONLY$1, IL_ONLY: IL_ONLY$2, LIGHT_CANDLES_TZEIS: LIGHT_CANDLES_TZEIS$3, MAJOR_FAST: MAJOR_FAST$2, MINOR_HOLIDAY: MINOR_HOLIDAY$2, EREV: EREV$2, CHOL_HAMOED: CHOL_HAMOED$1, } = flags;
10955
11017
  /**
10956
- * Yom HaShoah first observed in 1951.
10957
- * When the actual date of Yom Hashoah falls on a Friday, the
10958
- * state of Israel observes Yom Hashoah on the preceding
10959
- * Thursday. When it falls on a Sunday, Yom Hashoah is observed
10960
- * on the following Monday.
10961
- * http://www.ushmm.org/remembrance/dor/calendar/
10962
- * @private
10963
- * @param year
11018
+ * Transliterated names of holidays, used by `Event.getDesc()`
10964
11019
  */
10965
- function dateYomHaShoah(year) {
10966
- if (year < 5711) {
10967
- return null;
10968
- }
10969
- let nisan27dt = new HDate(27, NISAN$3, year);
10970
- if (nisan27dt.getDay() === FRI$2) {
10971
- nisan27dt = new HDate(26, NISAN$3, year);
10972
- }
10973
- else if (nisan27dt.getDay() === SUN$1) {
10974
- nisan27dt = new HDate(28, NISAN$3, year);
10975
- }
10976
- return nisan27dt;
11020
+ const holidayDesc = {
11021
+ /** Asara B'Tevet */
11022
+ ASARA_BTEVET: "Asara B'Tevet",
11023
+ /** Birkat Hachamah */
11024
+ BIRKAT_HACHAMAH: 'Birkat Hachamah',
11025
+ /** Chag HaBanot */
11026
+ CHAG_HABANOT: 'Chag HaBanot',
11027
+ /** Chanukah: 8th Day */
11028
+ CHANUKAH_8TH_DAY: 'Chanukah: 8th Day',
11029
+ /** Erev Tish'a B'Av */
11030
+ EREV_TISHA_BAV: "Erev Tish'a B'Av",
11031
+ /** Leil Selichot */
11032
+ LEIL_SELICHOT: 'Leil Selichot',
11033
+ /** Purim Katan */
11034
+ PURIM_KATAN: 'Purim Katan',
11035
+ /** Purim Meshulash */
11036
+ PURIM_MESHULASH: 'Purim Meshulash',
11037
+ /** Shabbat Chazon */
11038
+ SHABBAT_CHAZON: 'Shabbat Chazon',
11039
+ /** Shabbat HaChodesh */
11040
+ SHABBAT_HACHODESH: 'Shabbat HaChodesh',
11041
+ /** Shabbat HaGadol */
11042
+ SHABBAT_HAGADOL: 'Shabbat HaGadol',
11043
+ /** Shabbat Nachamu */
11044
+ SHABBAT_NACHAMU: 'Shabbat Nachamu',
11045
+ /** Shabbat Parah */
11046
+ SHABBAT_PARAH: 'Shabbat Parah',
11047
+ /** Shabbat Shekalim */
11048
+ SHABBAT_SHEKALIM: 'Shabbat Shekalim',
11049
+ /** Shabbat Shirah */
11050
+ SHABBAT_SHIRAH: 'Shabbat Shirah',
11051
+ /** Shabbat Shuva */
11052
+ SHABBAT_SHUVA: 'Shabbat Shuva',
11053
+ /** Shabbat Zachor */
11054
+ SHABBAT_ZACHOR: 'Shabbat Zachor',
11055
+ /** Shushan Purim Katan */
11056
+ SHUSHAN_PURIM_KATAN: 'Shushan Purim Katan',
11057
+ /** Ta'anit Bechorot */
11058
+ TAANIT_BECHOROT: "Ta'anit Bechorot",
11059
+ /** Ta'anit BeHaB */
11060
+ TAANIT_BEHAB: "Ta'anit BeHaB",
11061
+ /** Ta'anit Esther */
11062
+ TAANIT_ESTHER: "Ta'anit Esther",
11063
+ /** Tish'a B'Av */
11064
+ TISHA_BAV: "Tish'a B'Av",
11065
+ /** Tzom Gedaliah */
11066
+ TZOM_GEDALIAH: 'Tzom Gedaliah',
11067
+ /** Tzom Tammuz */
11068
+ TZOM_TAMMUZ: 'Tzom Tammuz',
11069
+ /** Yom HaAtzma'ut */
11070
+ YOM_HAATZMA_UT: "Yom HaAtzma'ut",
11071
+ /** Yom HaShoah */
11072
+ YOM_HASHOAH: 'Yom HaShoah',
11073
+ /** Yom HaZikaron */
11074
+ YOM_HAZIKARON: 'Yom HaZikaron',
11075
+ /** Ben-Gurion Day */
11076
+ BEN_GURION_DAY: 'Ben-Gurion Day',
11077
+ /** Chanukah: 1 Candle */
11078
+ CHANUKAH_1_CANDLE: 'Chanukah: 1 Candle',
11079
+ /** Erev Pesach */
11080
+ EREV_PESACH: 'Erev Pesach',
11081
+ /** Erev Purim */
11082
+ EREV_PURIM: 'Erev Purim',
11083
+ /** Erev Rosh Hashana */
11084
+ EREV_ROSH_HASHANA: 'Erev Rosh Hashana',
11085
+ /** Erev Shavuot */
11086
+ EREV_SHAVUOT: 'Erev Shavuot',
11087
+ /** Erev Sukkot */
11088
+ EREV_SUKKOT: 'Erev Sukkot',
11089
+ /** Erev Yom Kippur */
11090
+ EREV_YOM_KIPPUR: 'Erev Yom Kippur',
11091
+ /** Family Day */
11092
+ FAMILY_DAY: 'Family Day',
11093
+ /** Hebrew Language Day */
11094
+ HEBREW_LANGUAGE_DAY: 'Hebrew Language Day',
11095
+ /** Herzl Day */
11096
+ HERZL_DAY: 'Herzl Day',
11097
+ /** Jabotinsky Day */
11098
+ JABOTINSKY_DAY: 'Jabotinsky Day',
11099
+ /** Lag BaOmer */
11100
+ LAG_BAOMER: 'Lag BaOmer',
11101
+ /** Pesach I */
11102
+ PESACH_I: 'Pesach I',
11103
+ /** Pesach II */
11104
+ PESACH_II: 'Pesach II',
11105
+ /** Pesach III (CH''M) */
11106
+ PESACH_III_CHM: "Pesach III (CH''M)",
11107
+ /** Pesach II (CH''M) */
11108
+ PESACH_II_CHM: "Pesach II (CH''M)",
11109
+ /** Pesach IV (CH''M) */
11110
+ PESACH_IV_CHM: "Pesach IV (CH''M)",
11111
+ /** Pesach Sheni */
11112
+ PESACH_SHENI: 'Pesach Sheni',
11113
+ /** Pesach VII */
11114
+ PESACH_VII: 'Pesach VII',
11115
+ /** Pesach VIII */
11116
+ PESACH_VIII: 'Pesach VIII',
11117
+ /** Pesach VI (CH''M) */
11118
+ PESACH_VI_CHM: "Pesach VI (CH''M)",
11119
+ /** Pesach V (CH''M) */
11120
+ PESACH_V_CHM: "Pesach V (CH''M)",
11121
+ /** Purim */
11122
+ PURIM: 'Purim',
11123
+ /** Rosh Hashana II */
11124
+ ROSH_HASHANA_II: 'Rosh Hashana II',
11125
+ /** Rosh Hashana LaBehemot */
11126
+ ROSH_HASHANA_LABEHEMOT: 'Rosh Hashana LaBehemot',
11127
+ /** Shavuot */
11128
+ SHAVUOT: 'Shavuot',
11129
+ /** Shavuot I */
11130
+ SHAVUOT_I: 'Shavuot I',
11131
+ /** Shavuot II */
11132
+ SHAVUOT_II: 'Shavuot II',
11133
+ /** Shmini Atzeret */
11134
+ SHMINI_ATZERET: 'Shmini Atzeret',
11135
+ /** Shushan Purim */
11136
+ SHUSHAN_PURIM: 'Shushan Purim',
11137
+ /** Sigd */
11138
+ SIGD: 'Sigd',
11139
+ /** Simchat Torah */
11140
+ SIMCHAT_TORAH: 'Simchat Torah',
11141
+ /** Sukkot I */
11142
+ SUKKOT_I: 'Sukkot I',
11143
+ /** Sukkot II */
11144
+ SUKKOT_II: 'Sukkot II',
11145
+ /** Sukkot III (CH''M) */
11146
+ SUKKOT_III_CHM: "Sukkot III (CH''M)",
11147
+ /** Sukkot II (CH''M) */
11148
+ SUKKOT_II_CHM: "Sukkot II (CH''M)",
11149
+ /** Sukkot IV (CH''M) */
11150
+ SUKKOT_IV_CHM: "Sukkot IV (CH''M)",
11151
+ /** Sukkot VII (Hoshana Raba) */
11152
+ SUKKOT_VII_HOSHANA_RABA: 'Sukkot VII (Hoshana Raba)',
11153
+ /** Sukkot VI (CH''M) */
11154
+ SUKKOT_VI_CHM: "Sukkot VI (CH''M)",
11155
+ /** Sukkot V (CH''M) */
11156
+ SUKKOT_V_CHM: "Sukkot V (CH''M)",
11157
+ /** Tu B'Av */
11158
+ TU_BAV: "Tu B'Av",
11159
+ /** Tu BiShvat */
11160
+ TU_BISHVAT: 'Tu BiShvat',
11161
+ /** Yitzhak Rabin Memorial Day */
11162
+ YITZHAK_RABIN_MEMORIAL_DAY: 'Yitzhak Rabin Memorial Day',
11163
+ /** Yom HaAliyah */
11164
+ YOM_HAALIYAH: 'Yom HaAliyah',
11165
+ /** Yom HaAliyah School Observance */
11166
+ YOM_HAALIYAH_SCHOOL_OBSERVANCE: 'Yom HaAliyah School Observance',
11167
+ /** Yom Kippur */
11168
+ YOM_KIPPUR: 'Yom Kippur',
11169
+ /** Yom Yerushalayim */
11170
+ YOM_YERUSHALAYIM: 'Yom Yerushalayim',
11171
+ /** Candle lighting */
11172
+ CANDLE_LIGHTING: 'Candle lighting',
11173
+ /** Havdalah */
11174
+ HAVDALAH: 'Havdalah',
11175
+ /** Fast begins */
11176
+ FAST_BEGINS: 'Fast begins',
11177
+ /** Fast ends */
11178
+ FAST_ENDS: 'Fast ends',
11179
+ /** Biur Chametz */
11180
+ BIUR_CHAMETZ: 'Biur Chametz',
11181
+ /** Finish eating chametz */
11182
+ SOF_ZMAN_ACHILAT_CHAMETZ: 'Finish eating chametz',
11183
+ /** Yizkor */
11184
+ YIZKOR: 'Yizkor',
11185
+ /** Remembrance Day for the Fallen of the Swords of Iron War (October 7) */
11186
+ SWORDS_OF_IRON_WAR_MEMORIAL: 'Swords of Iron War Memorial Day',
11187
+ };
11188
+ const d = holidayDesc;
11189
+ const emojiRoshHashana = '🍏🍯';
11190
+ const emojiSukkot = '🌿🍋';
11191
+ const emojiPurim = '🎭️📜';
11192
+ const emojiPesach = '🫓';
11193
+ const emojiErevPesach = '🫓🍷';
11194
+ const emojiShavuot = '⛰️🌸';
11195
+ function holiday(mm, dd, desc, holidayFlags, extras) {
11196
+ return { mm, dd, desc, flags: holidayFlags, ...extras };
10977
11197
  }
10978
11198
  /**
10979
- * Yom HaAtzma'ut only celebrated after 1948
10980
- * @private
10981
- * @param year
11199
+ * Holidays that fall on a fixed Hebrew date. Entries marked `IL_ONLY` or
11200
+ * `CHUL_ONLY` differ between Israel and the Diaspora.
10982
11201
  */
10983
- function dateYomHaZikaron(year) {
10984
- if (year < 5708) {
10985
- return null;
10986
- }
10987
- let day;
10988
- const pesach = new HDate(15, NISAN$3, year);
10989
- const pdow = pesach.getDay();
10990
- if (pdow === SUN$1) {
10991
- day = 2;
10992
- }
10993
- else if (pdow === SAT$3) {
10994
- day = 3;
10995
- }
10996
- else if (year < 5764) {
10997
- day = 4;
10998
- }
10999
- else if (pdow === TUE$1) {
11000
- day = 5;
11001
- }
11002
- else {
11003
- day = 4;
11004
- }
11005
- return new HDate(day, IYYAR$1, year);
11006
- }
11007
-
11008
- /*
11009
- Hebcal - A Jewish Calendar Generator
11010
- Copyright (c) 1994-2020 Danny Sadinoff
11011
- Portions copyright Eyal Schachter and Michael J. Radwin
11012
-
11013
- https://github.com/hebcal/hebcal-es6
11202
+ const staticHolidays = [
11203
+ holiday(TISHREI$2, 2, d.ROSH_HASHANA_II, CHAG$1 | YOM_TOV_ENDS$1, {
11204
+ emoji: emojiRoshHashana,
11205
+ }),
11206
+ holiday(TISHREI$2, 9, d.EREV_YOM_KIPPUR, EREV$2 | LIGHT_CANDLES$2),
11207
+ holiday(TISHREI$2, 10, d.YOM_KIPPUR, CHAG$1 | MAJOR_FAST$2 | YOM_TOV_ENDS$1),
11208
+ // Sukkot chutz l'aretz
11209
+ holiday(TISHREI$2, 14, d.EREV_SUKKOT, CHUL_ONLY$1 | EREV$2 | LIGHT_CANDLES$2, {
11210
+ emoji: emojiSukkot,
11211
+ }),
11212
+ holiday(TISHREI$2, 15, d.SUKKOT_I, CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3, {
11213
+ emoji: emojiSukkot,
11214
+ }),
11215
+ holiday(TISHREI$2, 16, d.SUKKOT_II, CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1, {
11216
+ emoji: emojiSukkot,
11217
+ }),
11218
+ holiday(TISHREI$2, 17, d.SUKKOT_III_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11219
+ chmDay: 1,
11220
+ emoji: emojiSukkot,
11221
+ }),
11222
+ holiday(TISHREI$2, 18, d.SUKKOT_IV_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11223
+ chmDay: 2,
11224
+ emoji: emojiSukkot,
11225
+ }),
11226
+ holiday(TISHREI$2, 19, d.SUKKOT_V_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11227
+ chmDay: 3,
11228
+ emoji: emojiSukkot,
11229
+ }),
11230
+ holiday(TISHREI$2, 20, d.SUKKOT_VI_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11231
+ chmDay: 4,
11232
+ emoji: emojiSukkot,
11233
+ }),
11234
+ holiday(TISHREI$2, 22, d.SHMINI_ATZERET, CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3),
11235
+ holiday(TISHREI$2, 23, d.SIMCHAT_TORAH, CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1),
11236
+ // Sukkot Israel
11237
+ holiday(TISHREI$2, 14, d.EREV_SUKKOT, IL_ONLY$2 | EREV$2 | LIGHT_CANDLES$2, {
11238
+ emoji: emojiSukkot,
11239
+ }),
11240
+ holiday(TISHREI$2, 15, d.SUKKOT_I, IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1, {
11241
+ emoji: emojiSukkot,
11242
+ }),
11243
+ holiday(TISHREI$2, 16, d.SUKKOT_II_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11244
+ chmDay: 1,
11245
+ emoji: emojiSukkot,
11246
+ }),
11247
+ holiday(TISHREI$2, 17, d.SUKKOT_III_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11248
+ chmDay: 2,
11249
+ emoji: emojiSukkot,
11250
+ }),
11251
+ holiday(TISHREI$2, 18, d.SUKKOT_IV_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11252
+ chmDay: 3,
11253
+ emoji: emojiSukkot,
11254
+ }),
11255
+ holiday(TISHREI$2, 19, d.SUKKOT_V_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11256
+ chmDay: 4,
11257
+ emoji: emojiSukkot,
11258
+ }),
11259
+ holiday(TISHREI$2, 20, d.SUKKOT_VI_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11260
+ chmDay: 5,
11261
+ emoji: emojiSukkot,
11262
+ }),
11263
+ holiday(TISHREI$2, 22, d.SHMINI_ATZERET, IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1),
11264
+ // Hoshana Raba (both Israel and Diaspora)
11265
+ holiday(TISHREI$2, 21, d.SUKKOT_VII_HOSHANA_RABA, LIGHT_CANDLES$2 | CHOL_HAMOED$1, {
11266
+ chmDay: -1,
11267
+ emoji: emojiSukkot,
11268
+ }),
11269
+ holiday(SHVAT, 15, d.TU_BISHVAT, MINOR_HOLIDAY$2, { emoji: '🌳' }),
11270
+ holiday(ADAR_II$1, 13, d.EREV_PURIM, EREV$2 | MINOR_HOLIDAY$2, {
11271
+ emoji: emojiPurim,
11272
+ }),
11273
+ holiday(ADAR_II$1, 14, d.PURIM, MINOR_HOLIDAY$2, { emoji: emojiPurim }),
11274
+ holiday(ADAR_II$1, 15, d.SHUSHAN_PURIM, MINOR_HOLIDAY$2, { emoji: emojiPurim }),
11275
+ // Pesach Israel
11276
+ holiday(NISAN$4, 14, d.EREV_PESACH, IL_ONLY$2 | EREV$2 | LIGHT_CANDLES$2, {
11277
+ emoji: emojiErevPesach,
11278
+ }),
11279
+ holiday(NISAN$4, 15, d.PESACH_I, IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1, {
11280
+ emoji: emojiPesach,
11281
+ }),
11282
+ holiday(NISAN$4, 16, d.PESACH_II_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11283
+ chmDay: 1,
11284
+ emoji: emojiPesach,
11285
+ }),
11286
+ holiday(NISAN$4, 17, d.PESACH_III_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11287
+ chmDay: 2,
11288
+ emoji: emojiPesach,
11289
+ }),
11290
+ holiday(NISAN$4, 18, d.PESACH_IV_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11291
+ chmDay: 3,
11292
+ emoji: emojiPesach,
11293
+ }),
11294
+ holiday(NISAN$4, 19, d.PESACH_V_CHM, IL_ONLY$2 | CHOL_HAMOED$1, {
11295
+ chmDay: 4,
11296
+ emoji: emojiPesach,
11297
+ }),
11298
+ holiday(NISAN$4, 20, d.PESACH_VI_CHM, IL_ONLY$2 | CHOL_HAMOED$1 | LIGHT_CANDLES$2, {
11299
+ chmDay: 5,
11300
+ emoji: emojiPesach,
11301
+ }),
11302
+ holiday(NISAN$4, 21, d.PESACH_VII, IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1, {
11303
+ emoji: emojiPesach,
11304
+ }),
11305
+ // Pesach chutz l'aretz
11306
+ holiday(NISAN$4, 14, d.EREV_PESACH, CHUL_ONLY$1 | EREV$2 | LIGHT_CANDLES$2, {
11307
+ emoji: emojiErevPesach,
11308
+ }),
11309
+ holiday(NISAN$4, 15, d.PESACH_I, CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3, {
11310
+ emoji: emojiErevPesach,
11311
+ }),
11312
+ holiday(NISAN$4, 16, d.PESACH_II, CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1, {
11313
+ emoji: emojiPesach,
11314
+ }),
11315
+ holiday(NISAN$4, 17, d.PESACH_III_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11316
+ chmDay: 1,
11317
+ emoji: emojiPesach,
11318
+ }),
11319
+ holiday(NISAN$4, 18, d.PESACH_IV_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11320
+ chmDay: 2,
11321
+ emoji: emojiPesach,
11322
+ }),
11323
+ holiday(NISAN$4, 19, d.PESACH_V_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1, {
11324
+ chmDay: 3,
11325
+ emoji: emojiPesach,
11326
+ }),
11327
+ holiday(NISAN$4, 20, d.PESACH_VI_CHM, CHUL_ONLY$1 | CHOL_HAMOED$1 | LIGHT_CANDLES$2, {
11328
+ chmDay: 4,
11329
+ emoji: emojiPesach,
11330
+ }),
11331
+ holiday(NISAN$4, 21, d.PESACH_VII, CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3, {
11332
+ emoji: emojiPesach,
11333
+ }),
11334
+ holiday(NISAN$4, 22, d.PESACH_VIII, CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1, {
11335
+ emoji: emojiPesach,
11336
+ }),
11337
+ holiday(IYYAR$2, 14, d.PESACH_SHENI, MINOR_HOLIDAY$2),
11338
+ holiday(IYYAR$2, 18, d.LAG_BAOMER, MINOR_HOLIDAY$2, { emoji: '🔥' }),
11339
+ holiday(SIVAN$2, 5, d.EREV_SHAVUOT, EREV$2 | LIGHT_CANDLES$2, {
11340
+ emoji: emojiShavuot,
11341
+ }),
11342
+ holiday(SIVAN$2, 6, d.SHAVUOT, IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1, {
11343
+ emoji: emojiShavuot,
11344
+ }),
11345
+ holiday(SIVAN$2, 6, d.SHAVUOT_I, CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3, {
11346
+ emoji: emojiShavuot,
11347
+ }),
11348
+ holiday(SIVAN$2, 7, d.SHAVUOT_II, CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1, {
11349
+ emoji: emojiShavuot,
11350
+ }),
11351
+ holiday(AV$2, 15, d.TU_BAV, MINOR_HOLIDAY$2, { emoji: '❤️' }),
11352
+ holiday(ELUL$1, 1, d.ROSH_HASHANA_LABEHEMOT, MINOR_HOLIDAY$2, { emoji: '🐑' }),
11353
+ holiday(ELUL$1, 29, d.EREV_ROSH_HASHANA, EREV$2 | LIGHT_CANDLES$2, {
11354
+ emoji: emojiRoshHashana,
11355
+ }),
11356
+ ];
11014
11357
 
11015
- This program is free software; you can redistribute it and/or
11016
- modify it under the terms of the GNU General Public License
11017
- as published by the Free Software Foundation; either version 2
11018
- of the License, or (at your option) any later version.
11019
-
11020
- This program is distributed in the hope that it will be useful,
11021
- but WITHOUT ANY WARRANTY; without even the implied warranty of
11022
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11023
- GNU General Public License for more details.
11024
-
11025
- You should have received a copy of the GNU General Public License
11026
- along with this program. If not, see <http://www.gnu.org/licenses/>.
11027
- */
11028
- /*
11029
- * Many of the following algorithms were taken from hebrew calendar
11030
- * routines by Maimonedes, from his Mishneh Torah, and implemented by
11031
- * Nachum Dershowitz Department of Computer Science
11032
- * (217) 333-4219 University of Illinois at Urbana-Champaign
11033
- * nachum@cs.uiuedu 1304 West Springfield Avenue
11034
- * Urbana, Illinois 61801
11035
- *
11036
- * The routines were included in the emacs 19 distribution.
11037
- *
11038
- */
11039
- const INCOMPLETE = 0;
11040
- const REGULAR = 1;
11041
- const COMPLETE = 2;
11042
- function yearType(hyear) {
11043
- const longC = HDate.longCheshvan(hyear);
11044
- const shortK = HDate.shortKislev(hyear);
11045
- if (longC && !shortK) {
11046
- return COMPLETE;
11047
- }
11048
- if (!longC && shortK) {
11049
- return INCOMPLETE;
11050
- }
11051
- return REGULAR;
11052
- }
11053
11358
  /**
11054
- * Represents the weekly Torah-reading (Parashat HaShavua) schedule for an
11055
- * entire Hebrew year.
11359
+ * Represents a built-in holiday like Pesach, Purim or Tu BiShvat.
11056
11360
  *
11057
- * The schedule depends on the year's *keviyah* — the day of week of Rosh
11058
- * Hashana, whether the year is leap, whether Cheshvan/Kislev are long or
11059
- * short, and whether the schedule is for Israel or the Diaspora (since
11060
- * Israel and the Diaspora diverge in some years when the 8th day of Pesach
11061
- * or the 2nd day of Shavuot fall on Shabbat).
11361
+ * Most holiday-related events emitted by {@link calendar}
11362
+ * are instances of `HolidayEvent` or one of its subclasses
11363
+ * ({@link ChanukahEvent}, {@link AsaraBTevetEvent},
11364
+ * {@link RoshHashanaEvent}, {@link RoshChodeshEvent}).
11062
11365
  *
11063
- * Prefer {@link getSedra} over
11064
- * calling this constructor directly, since both cache their results.
11366
+ * Adds two notable behaviors over the base {@link Event}:
11065
11367
  *
11066
- * @example
11067
- * import {Sedra, HDate, months} from '@hebcal/core';
11068
- * const sedra = new Sedra(5784, false);
11069
- * const result = sedra.lookup(new HDate(15, months.CHESHVAN, 5784));
11070
- * console.log(result.parsha); // ['Vayera']
11368
+ * - {@link HolidayEvent.basename} strips qualifiers like `Erev `, ` I`/`II`,
11369
+ * `(CH''M)`, `(observed)`, candle counts, etc. (e.g. `"Erev Pesach"` →
11370
+ * `"Pesach"`).
11371
+ * - {@link HolidayEvent.url} returns a `https://www.hebcal.com/holidays/...`
11372
+ * link for the holiday.
11071
11373
  */
11072
- class Sedra {
11073
- /**
11074
- * Calculates the Parashat HaShavua schedule for an entire Hebrew year.
11075
- * @param hyear - Hebrew year (e.g. 5749)
11076
- * @param il - Use Israel sedra schedule (false for Diaspora)
11077
- */
11078
- constructor(hyear, il) {
11079
- hyear = +hyear;
11080
- this.year = hyear;
11081
- const rh0 = new HDate(1, months.TISHREI, hyear);
11082
- const rh = (this.rh = rh0.abs());
11083
- const rhDay = rh0.getDay() + 1;
11084
- // find the first Saturday on or after Rosh Hashana
11085
- this.firstSaturday = HDate.dayOnOrBefore(6, rh + 6);
11086
- const leap = +HDate.isLeapYear(hyear);
11087
- this.il = Boolean(il);
11088
- const type = yearType(hyear);
11089
- let key = `${leap}${rhDay}${type}`;
11090
- if (types[key]) {
11091
- this.theSedraArray = types[key];
11092
- this.yearKey = key;
11093
- }
11094
- else {
11095
- key = key + +this.il; // cast to num, then concat
11096
- this.theSedraArray = types[key];
11097
- this.yearKey = key;
11098
- }
11099
- if (!this.theSedraArray) {
11100
- throw new Error(`improper sedra year type ${key} calculated for ${hyear}`);
11374
+ class HolidayEvent extends Event {
11375
+ constructor(date, desc, mask = 0, attrs) {
11376
+ super(date, desc, mask, attrs);
11377
+ if (typeof attrs === 'object' && attrs !== null) {
11378
+ Object.assign(this, attrs);
11101
11379
  }
11102
11380
  }
11103
11381
  /**
11104
- * Returns the date a parsha is read this year, or `null` if it does not
11105
- * occur in this year's schedule.
11106
- *
11107
- * A doubled parsha (e.g. `'Matot-Masei'`) will only return a date in years
11108
- * where that pair is actually read together; in years where they are read
11109
- * separately, this returns `null`. Use {@link findContaining} to find the
11110
- * date a parsha is read regardless of whether it is doubled.
11382
+ * Returns a simplified (untranslated) name for this holiday, stripping
11383
+ * qualifiers so that related events group under one name.
11111
11384
  *
11112
- * Throws `RangeError` for an out-of-range numeric input or an invalid
11113
- * doubled-parsha pair, and `TypeError` for a malformed array argument.
11385
+ * Strips trailing 4-digit years, `(CH''M)`, `(observed)`, `(Hoshana Raba)`,
11386
+ * Roman-numeral day numbers (` I`, ` II`, ...), Chanukah candle counts,
11387
+ * `: 8th Day`, and a leading `"Erev "`.
11114
11388
  * @example
11115
- * import {Sedra} from '@hebcal/core';
11116
- * const sedra = new Sedra(5784, false);
11117
- * sedra.find('Noach')?.toString(); // '6 Cheshvan 5784'
11118
- * sedra.find(1)?.toString(); // '6 Cheshvan 5784', by 0-based index
11119
- * // Matot and Masei are doubled in 5784, so the pair has a date...
11120
- * sedra.find('Matot-Masei')?.toString(); // '28 Tamuz 5784'
11121
- * sedra.find(['Matot', 'Masei'])?.toString(); // '28 Tamuz 5784'
11122
- * // ...but neither half is read on its own that year:
11123
- * sedra.find('Matot'); // null
11124
- * @param parsha if a `string`, specified with Sephardic transliterations
11125
- * like `'Noach'` or `'Matot-Masei'`. If an array, must be a 1- or 2-element
11126
- * array such as `['Noach']` or `['Matot', 'Masei']`. If a `number`, should
11127
- * be a 0-based parsha index (`0` for Bereshit, `1` for Noach) or a negative
11128
- * number for a doubled parsha (e.g. `-21` for Vayakhel-Pekudei).
11129
- * Note that this index is 0-based, unlike {@link SedraResult.num} which
11130
- * is 1-based.
11389
+ * // 'Erev Pesach' => 'Pesach'
11390
+ * // 'Sukkot III (CH''M)' => 'Sukkot'
11391
+ * // 'Chanukah: 5 Candles' => 'Chanukah'
11392
+ * // 'Rosh Hashana 5784' => 'Rosh Hashana'
11131
11393
  */
11132
- find(parsha) {
11133
- if (typeof parsha === 'number') {
11134
- if (parsha >= parshiot.length || (parsha < 0 && !isValidDouble(parsha))) {
11135
- throw new RangeError(`Invalid parsha number: ${parsha}`);
11136
- }
11137
- return this.findInternal(parsha);
11394
+ basename() {
11395
+ return this.getDesc()
11396
+ .replace(/ \d{4}$/, '')
11397
+ .replace(/ \(CH''M\)$/, '')
11398
+ .replace(/ \(observed\)$/, '')
11399
+ .replace(/ \(Hoshana Raba\)$/, '')
11400
+ .replace(/ [IV]+$/, '')
11401
+ .replace(/: \d Candles?$/, '')
11402
+ .replace(/: 8th Day$/, '')
11403
+ .replace(/^Erev /, '');
11404
+ }
11405
+ /**
11406
+ * Returns a `https://www.hebcal.com/holidays/...` URL for more detail on
11407
+ * this holiday. Israel-only holidays get an `?i=on` query parameter.
11408
+ * Returns `undefined` for years outside `[100, 2999]`.
11409
+ */
11410
+ url() {
11411
+ const year = this.greg().getFullYear();
11412
+ if (year < 100 || year > 2999) {
11413
+ return undefined;
11138
11414
  }
11139
- if (typeof parsha === 'string') {
11140
- const num = parsha2id.get(parsha);
11141
- if (typeof num === 'number') {
11142
- return this.find(num);
11143
- }
11144
- if (parsha.includes('-')) {
11145
- if (parsha === CHMPESACH || parsha === CHMSUKOT) {
11146
- return this.findInternal(parsha);
11147
- }
11148
- return this.find(parsha.split('-'));
11149
- }
11150
- // try to find Saturday holiday like 'Yom Kippur'
11151
- return this.findInternal(parsha);
11415
+ const url = `https://www.hebcal.com/holidays/${urlFriendly(this.basename())}-${this.urlDateSuffix()}`;
11416
+ return this.hasFlag('IL_ONLY') ? `${url}?i=on` : url;
11417
+ }
11418
+ /**
11419
+ * The date portion of {@link url}. For most holidays this is just the
11420
+ * Gregorian year; subclasses override it when a year alone is ambiguous.
11421
+ */
11422
+ urlDateSuffix() {
11423
+ return String(this.greg().getFullYear());
11424
+ }
11425
+ getEmoji() {
11426
+ if (this.emoji) {
11427
+ return this.emoji;
11152
11428
  }
11153
- if (Array.isArray(parsha)) {
11154
- const plen = parsha.length;
11155
- if ((plen !== 1 && plen !== 2) || typeof parsha[0] !== 'string') {
11156
- throw new TypeError(`Invalid parsha argument: ${JSON.stringify(parsha)}`);
11157
- }
11158
- if (plen === 1) {
11159
- return this.find(parsha[0]);
11160
- }
11161
- const p1 = parsha[0];
11162
- const p2 = parsha[1];
11163
- const num1 = parsha2id.get(p1);
11164
- const num2 = parsha2id.get(p2);
11165
- if (typeof num1 !== 'number' ||
11166
- typeof num2 !== 'number' ||
11167
- num2 !== num1 + 1 ||
11168
- !isValidDouble(-num1)) {
11169
- throw new RangeError(`Unrecognized parsha name: ${p1}-${p2}`);
11170
- }
11171
- return this.find(-num1);
11429
+ if (this.hasFlag('SPECIAL_SHABBAT')) {
11430
+ return '🕍';
11172
11431
  }
11173
- return null; /* NOTREACHED */
11432
+ return '✡️';
11174
11433
  }
11175
- findInternal(parsha) {
11176
- const idx = this.theSedraArray.indexOf(parsha);
11177
- if (idx === -1) {
11178
- return null; // doesn't occur this year
11434
+ getCategories() {
11435
+ if (this.cholHaMoedDay) {
11436
+ return ['holiday', 'major', 'cholhamoed'];
11179
11437
  }
11180
- return new HDate(this.firstSaturday + idx * 7);
11438
+ const cats = super.getCategories();
11439
+ if (cats[0] !== 'unknown') {
11440
+ return cats;
11441
+ }
11442
+ // Don't depend on flags.MINOR_HOLIDAY always being set. Look for minor holidays.
11443
+ const desc = this.getDesc();
11444
+ switch (desc) {
11445
+ case holidayDesc.LAG_BAOMER:
11446
+ case holidayDesc.LEIL_SELICHOT:
11447
+ case holidayDesc.PESACH_SHENI:
11448
+ case holidayDesc.EREV_PURIM:
11449
+ case holidayDesc.PURIM_KATAN:
11450
+ case holidayDesc.SHUSHAN_PURIM:
11451
+ case holidayDesc.TU_BAV:
11452
+ case holidayDesc.TU_BISHVAT:
11453
+ case holidayDesc.ROSH_HASHANA_LABEHEMOT:
11454
+ return ['holiday', 'minor'];
11455
+ }
11456
+ return ['holiday', 'major'];
11181
11457
  }
11182
11458
  /**
11183
- * Returns the date a parsha is read this year, looking through both
11184
- * single and doubled forms.
11185
- *
11186
- * For example, if `'Matot'` is read individually this year, this returns
11187
- * its date; if it is read as part of `'Matot-Masei'` this year, this
11188
- * returns the date of `'Matot-Masei'` (and similarly for `'Masei'`).
11189
- * Conversely, asking for `'Matot-Masei'` in a year where they are split
11190
- * will return the date of `'Matot'` alone.
11191
- * @example
11192
- * import {Sedra} from '@hebcal/core';
11193
- * // Matot and Masei are doubled in 5784, so each half resolves to the
11194
- * // date of the combined reading:
11195
- * const sedra = new Sedra(5784, false);
11196
- * sedra.findContaining('Matot')?.toString(); // '28 Tamuz 5784'
11197
- * sedra.findContaining('Masei')?.toString(); // '28 Tamuz 5784'
11198
- * @example
11199
- * import {Sedra} from '@hebcal/core';
11200
- * // They are read separately in 5795, so each half has its own date, and
11201
- * // asking for the doubled name returns the date of the first half:
11202
- * const sedra = new Sedra(5795, false);
11203
- * sedra.findContaining('Matot')?.toString(); // '21 Tamuz 5795'
11204
- * sedra.findContaining('Masei')?.toString(); // '28 Tamuz 5795'
11205
- * sedra.findContaining('Matot-Masei')?.toString(); // '21 Tamuz 5795'
11459
+ * Returns (translated) description of this event
11460
+ * @param [locale] Optional locale name (defaults to empty locale)
11206
11461
  */
11207
- findContaining(parsha) {
11208
- const hdate = this.find(parsha);
11209
- if (hdate) {
11210
- return hdate;
11211
- }
11212
- if (typeof parsha === 'number') {
11213
- // a valid negative number (double parsha in a year where they are
11214
- // combined) would've been found above, and a invalid negative number
11215
- // would've thrown an error, so this parsha must be a positive number
11216
- // representing either p1 or p2
11217
- const p1 = -parsha;
11218
- if (isValidDouble(p1)) {
11219
- return this.find(p1);
11220
- }
11221
- else {
11222
- // this must be the second individual parsha of a doubled pair
11223
- // for example 29 for Kedoshim, so check for -28 for Achrei Mot-Kedoshim
11224
- return this.find(p1 + 1);
11225
- }
11226
- }
11227
- else {
11228
- const num = parsha2id.get(parsha);
11229
- if (num) {
11230
- // parsha is either the first or second individual parsha of
11231
- // a pair that is doubled this year
11232
- const p1 = -num;
11233
- if (isValidDouble(p1)) {
11234
- return this.find(p1);
11235
- }
11236
- else {
11237
- return this.find(p1 + 1);
11238
- }
11239
- }
11240
- else {
11241
- // this was indeed a doubled parsha, so return date of the first half
11242
- const [p1] = parsha.split('-');
11243
- return this.find(p1);
11244
- }
11245
- }
11462
+ render(locale) {
11463
+ const str = super.render(locale);
11464
+ return smartApostrophe(str);
11246
11465
  }
11247
11466
  /**
11248
- * Returns the underlying annual reading schedule as an array, where each
11249
- * entry corresponds to one Saturday (starting from the first Shabbat on
11250
- * or after Rosh Hashana). Entries are either:
11251
- * - a non-negative `number`: a 0-based parsha index (e.g. `0` for
11252
- * *Bereshit*)
11253
- * - a negative `number`: the negated first index of a doubled parsha
11254
- * (e.g. `-21` for *Vayakhel-Pekudei*)
11255
- * - a `string`: a holiday name when a Yom Tov displaces the weekly reading
11256
- * (e.g. `'Pesach Shabbat Chol ha-Moed'`, `'Yom Kippur'`)
11257
- *
11258
- * Used by `@hebcal/triennial`.
11467
+ * Returns a brief (translated) description of this event.
11468
+ * For most events, this is the same as render(). For some events, it procudes
11469
+ * a shorter text (e.g. without a time or added description).
11470
+ * @param [locale] Optional locale name (defaults to empty locale)
11259
11471
  */
11260
- getSedraArray() {
11261
- return this.theSedraArray;
11472
+ renderBrief(locale) {
11473
+ const str = super.renderBrief(locale);
11474
+ return smartApostrophe(str);
11475
+ }
11476
+ }
11477
+ /**
11478
+ * Because Asara B'Tevet often occurs twice in the same Gregorian year,
11479
+ * we subclass HolidayEvent to generate the correct URL.
11480
+ */
11481
+ class AsaraBTevetEvent extends HolidayEvent {
11482
+ /** Full `YYYYMMDD` date, since the Gregorian year alone is ambiguous here */
11483
+ urlDateSuffix() {
11484
+ const isoDate = isoDateString(this.greg());
11485
+ return isoDate.replaceAll('-', '');
11262
11486
  }
11487
+ }
11488
+ const chanukahEmoji = '🕎';
11489
+ const KEYCAP_DIGITS = [
11490
+ '0️⃣',
11491
+ '1️⃣',
11492
+ '2️⃣',
11493
+ '3️⃣',
11494
+ '4️⃣',
11495
+ '5️⃣',
11496
+ '6️⃣',
11497
+ '7️⃣',
11498
+ '8️⃣',
11499
+ '9️⃣',
11500
+ ];
11501
+ /**
11502
+ * Because Chanukah sometimes starts in December and ends in January,
11503
+ * we subclass HolidayEvent to generate the correct URL.
11504
+ */
11505
+ class ChanukahEvent extends HolidayEvent {
11263
11506
  /**
11264
- * Returns the R.D. (Rata Die / Fixed Date) absolute day number of the
11265
- * first Saturday on or after Rosh Hashana of this year. This is the
11266
- * anchor point for {@link getSedraArray} — index `0` of that array
11267
- * corresponds to this date.
11507
+ * @param chanukahDay should be undefined for 1st night of Chanukah
11268
11508
  */
11269
- getFirstSaturday() {
11270
- return this.firstSaturday;
11509
+ constructor(date, desc, mask, chanukahDay) {
11510
+ super(date, desc, mask);
11511
+ this.chanukahDay = chanukahDay;
11512
+ this.emoji = chanukahEmoji;
11513
+ if (chanukahDay !== 8) {
11514
+ const candles = chanukahDay ? chanukahDay + 1 : 1;
11515
+ this.emoji += KEYCAP_DIGITS[candles];
11516
+ }
11271
11517
  }
11272
- /** Returns the Hebrew year this `Sedra` instance covers. */
11273
- getYear() {
11274
- return this.year;
11518
+ urlDateSuffix() {
11519
+ const dt = this.greg();
11520
+ let year = dt.getFullYear();
11521
+ if (dt.getMonth() === 0) {
11522
+ year--;
11523
+ }
11524
+ return String(year);
11275
11525
  }
11526
+ }
11527
+ /** Represents Rosh Hashana, the Jewish New Year */
11528
+ class RoshHashanaEvent extends HolidayEvent {
11276
11529
  /**
11277
- * Returns details about the parsha read on the first Saturday on or after
11278
- * `hd`. If `hd` is itself a Saturday, the reading for that date is
11279
- * returned; otherwise the reading for the upcoming Saturday is returned.
11280
- *
11281
- * If the given date falls in the final days of the Hebrew year (after
11282
- * the last reading of this year's schedule), this method transparently
11283
- * delegates to the next year's `Sedra`.
11284
- * @example
11285
- * import {Sedra, HDate, months} from '@hebcal/core';
11286
- * const sedra = new Sedra(5784, false);
11287
- * // A Friday — returns the upcoming Shabbat's reading
11288
- * const result = sedra.lookup(new HDate(12, months.CHESHVAN, 5784));
11289
- * console.log(result.parsha); // ['Lech-Lecha']
11290
- * console.log(result.chag); // false
11291
- * console.log(result.hdate.toString()); // '13 Cheshvan 5784' (Saturday)
11292
- * @param hd Hebrew date or R.D. days
11530
+ * Normally created by {@link calendar} rather than directly.
11531
+ * @param date Hebrew date event occurs
11532
+ * @param hyear Hebrew year
11533
+ * @param mask optional holiday flags
11293
11534
  */
11294
- lookup(hd) {
11295
- const abs = typeof hd === 'number' ? hd : HDate.isHDate(hd) ? hd.abs() : NaN;
11296
- if (isNaN(abs)) {
11297
- throw new TypeError(`Bad date argument: ${hd}`);
11298
- }
11299
- if (abs < this.rh) {
11300
- throw new RangeError(`Date ${hd} before start of Hebrew year ${this.year}`);
11301
- }
11302
- // find the first saturday on or after today's date
11303
- const saturday = HDate.dayOnOrBefore(6, abs + 6);
11304
- const weekNum = (saturday - this.firstSaturday) / 7;
11305
- const index = this.theSedraArray[weekNum];
11306
- if (index === undefined) {
11307
- const sedra = getSedra(this.year + 1, this.il);
11308
- return sedra.lookup(saturday); // must be next year
11309
- }
11310
- const hdate = new HDate(saturday);
11311
- if (typeof index === 'string') {
11312
- // Shabbat has a chag. Return a description
11313
- return { parsha: [index], chag: true, hdate, il: this.il, num: 0 };
11314
- }
11315
- if (index >= 0) {
11316
- return {
11317
- parsha: [parshiot[index]],
11318
- chag: false,
11319
- num: index + 1,
11320
- hdate,
11321
- il: this.il,
11322
- };
11323
- }
11324
- const p1 = D(index); // undouble the parsha
11325
- return {
11326
- parsha: [parshiot[p1], parshiot[p1 + 1]],
11327
- chag: false,
11328
- num: [p1 + 1, p1 + 2],
11329
- hdate,
11330
- il: this.il,
11331
- };
11535
+ constructor(date, hyear, mask) {
11536
+ super(date, `Rosh Hashana ${hyear}`, mask);
11537
+ this.hyear = hyear;
11332
11538
  }
11333
11539
  /**
11334
- * Returns details about the parsha read on Monday or Thursday for `hd`, or
11335
- * `undefined` if `hd` is not a Monday or Thursday.
11336
- *
11337
- * Weekday Torah readings generally begin the upcoming Shabbat parsha. When
11338
- * the upcoming Shabbat is a holiday, this method returns the next regular
11339
- * parsha instead.
11340
- *
11341
- * For the Tishrei weekdays before Sukkot or Simchat Torah, the weekday
11342
- * reading is *Vezot Haberakhah* even though it is not read on Shabbat.
11343
- * @example
11344
- * import {Sedra, HDate, months} from '@hebcal/core';
11345
- * const sedra = new Sedra(5784, false);
11346
- * // Monday 8 Cheshvan — begins the upcoming Shabbat's parsha
11347
- * sedra.lookupWeekday(new HDate(8, months.CHESHVAN, 5784))?.parsha; // ['Lech-Lecha']
11348
- * // Tuesday is neither Monday nor Thursday
11349
- * sedra.lookupWeekday(new HDate(9, months.CHESHVAN, 5784)); // undefined
11350
- * // Thursday 17 Nisan — the upcoming Shabbat is Chol ha-Moed Pesach,
11351
- * // so the next regular parsha is returned instead
11352
- * sedra.lookupWeekday(new HDate(17, months.NISAN, 5784))?.parsha; // ['Achrei Mot']
11353
- * @param hd Hebrew date or R.D. days
11540
+ * Returns (translated) description of this event
11541
+ * @param [locale] Optional locale name (defaults to empty locale)
11354
11542
  */
11355
- lookupWeekday(hd) {
11356
- const abs = typeof hd === 'number' ? hd : HDate.isHDate(hd) ? hd.abs() : NaN;
11357
- if (isNaN(abs)) {
11358
- throw new TypeError(`Bad date argument: ${hd}`);
11359
- }
11360
- if (abs < this.rh) {
11361
- throw new RangeError(`Date ${hd} before start of Hebrew year ${this.year}`);
11362
- }
11363
- const hdate = new HDate(abs);
11364
- const day = hdate.getDay();
11365
- if (day !== 1 && day !== 4) {
11366
- return undefined;
11367
- }
11368
- const saturday = new HDate(HDate.dayOnOrBefore(6, abs + 6));
11369
- const parsha = this.lookup(saturday);
11370
- if (!parsha.chag) {
11371
- return parsha;
11372
- }
11373
- return this.findWeekdayParsha(saturday);
11543
+ render(locale) {
11544
+ return `${Locale.gettext('Rosh Hashana', locale)} ${this.hyear}`;
11374
11545
  }
11375
- findWeekdayParsha(saturday) {
11376
- const hyear = saturday.getFullYear();
11377
- const il = this.il;
11378
- if (saturday.getMonth() === months.TISHREI) {
11379
- const dd = saturday.getDate();
11380
- const simchatTorah = il ? 22 : 23;
11381
- if (dd > 2 && dd <= simchatTorah) {
11382
- return {
11383
- parsha: ['Vezot Haberakhah'],
11384
- chag: false,
11385
- num: 54,
11386
- hdate: saturday,
11387
- il,
11388
- };
11389
- }
11390
- }
11391
- const sedra = hyear === this.year ? this : getSedra(hyear, il);
11392
- const endOfYear = new HDate(1, months.TISHREI, hyear + 1).abs() - 1;
11393
- const endAbs = endOfYear + 30;
11394
- for (let sat2 = saturday.abs() + 7; sat2 <= endAbs; sat2 += 7) {
11395
- const sedra2 = sat2 > endOfYear ? getSedra(hyear + 1, il) : sedra;
11396
- const parsha2 = sedra2.lookup(sat2);
11397
- if (!parsha2.chag) {
11398
- return parsha2;
11399
- }
11400
- }
11401
- /* NOTREACHED */
11402
- throw new Error(`can't find weekday parsha for ${saturday}/${il}`);
11546
+ getEmoji() {
11547
+ return '🍏🍯';
11403
11548
  }
11404
11549
  }
11405
- /**
11406
- * The 54 parshiyot of the Torah as transilterated strings.
11407
- * * parshiot[0] == `Bereshit`
11408
- * * parshiot[1] == `Noach`
11409
- * * parshiot[52] == `Ha'azinu`
11410
- * * parshiot[53] == `Vezot Haberakhah`
11411
- * @readonly
11412
- * @type {string[]}
11413
- */
11414
- const parshiot = [
11415
- 'Bereshit',
11416
- 'Noach',
11417
- 'Lech-Lecha',
11418
- 'Vayera',
11419
- 'Chayei Sara',
11420
- 'Toldot',
11421
- 'Vayetzei',
11422
- 'Vayishlach',
11423
- 'Vayeshev',
11424
- 'Miketz',
11425
- 'Vayigash',
11426
- 'Vayechi',
11427
- 'Shemot',
11428
- 'Vaera',
11429
- 'Bo',
11430
- 'Beshalach',
11431
- 'Yitro',
11432
- 'Mishpatim',
11433
- 'Terumah',
11434
- 'Tetzaveh',
11435
- 'Ki Tisa',
11436
- 'Vayakhel',
11437
- 'Pekudei',
11438
- 'Vayikra',
11439
- 'Tzav',
11440
- 'Shmini',
11441
- 'Tazria',
11442
- 'Metzora',
11443
- 'Achrei Mot',
11444
- 'Kedoshim',
11445
- 'Emor',
11446
- 'Behar',
11447
- 'Bechukotai',
11448
- 'Bamidbar',
11449
- 'Nasso',
11450
- "Beha'alotcha",
11451
- "Sh'lach",
11452
- 'Korach',
11453
- 'Chukat',
11454
- 'Balak',
11455
- 'Pinchas',
11456
- 'Matot',
11457
- 'Masei',
11458
- 'Devarim',
11459
- 'Vaetchanan',
11460
- 'Eikev',
11461
- "Re'eh",
11462
- 'Shoftim',
11463
- 'Ki Teitzei',
11464
- 'Ki Tavo',
11465
- 'Nitzavim',
11466
- 'Vayeilech',
11467
- "Ha'azinu",
11468
- 'Vezot Haberakhah',
11469
- ];
11470
- // 0-based parsha IDs
11471
- const parsha2id = new Map();
11472
- for (let id = 0; id < parshiot.length; id++) {
11473
- const name = parshiot[id];
11474
- parsha2id.set(name, id);
11475
- }
11476
- // 0-based parsha IDs
11477
- const doubles = new Set([
11478
- 21, // Vayakhel-Pekudei
11479
- 26, // Tazria-Metzora
11480
- 28, // Achrei Mot-Kedoshim
11481
- 31, // Behar-Bechukotai
11482
- 38, // Chukat-Balak
11483
- 41, // Matot-Masei
11484
- 50, // Nitzavim-Vayeilech
11485
- ]);
11486
- /**
11487
- * @private
11488
- * @param id a negative number
11489
- */
11490
- function isValidDouble(id) {
11491
- return doubles.has(-id);
11492
- }
11493
- /**
11494
- * parsha doubler/undoubler
11495
- * @private
11496
- * @param p
11497
- */
11498
- function D(p) {
11499
- return -p;
11500
- }
11501
- const RH = 'Rosh Hashana'; // 0
11502
- const YK = 'Yom Kippur'; // 1
11503
- const SUKKOT = 'Sukkot'; // 0
11504
- const CHMSUKOT = 'Sukkot Shabbat Chol ha-Moed'; // 0
11505
- const SHMINI = 'Shmini Atzeret'; // 0
11506
- const PESACH = 'Pesach'; // 25
11507
- const PESACH1 = 'Pesach I';
11508
- const CHMPESACH = 'Pesach Shabbat Chol ha-Moed'; // 25
11509
- const PESACH7 = 'Pesach VII'; // 25
11510
- const PESACH8 = 'Pesach VIII';
11511
- const SHAVUOT$1 = 'Shavuot'; // 33
11512
- /**
11513
- * Returns an array from start to end
11514
- * @private
11515
- * @param start beginning number, inclusive
11516
- * @param stop ending number, inclusive
11517
- */
11518
- function range$1(start, stop) {
11519
- return Array.from({ length: stop - start + 1 }, (v, k) => k + start);
11520
- }
11521
- const yearStartVayeilech = [51, 52, CHMSUKOT];
11522
- const yearStartHaazinu = [52, YK, CHMSUKOT];
11523
- const yearStartRH = [RH, 52, SUKKOT, SHMINI];
11524
- const r020 = range$1(0, 20);
11525
- const r027 = range$1(0, 27);
11526
- const r3340 = range$1(33, 40);
11527
- const r4349 = range$1(43, 49);
11528
- const r4350 = range$1(43, 50);
11529
- /**
11530
- * The ordinary year types (keviot)
11531
- * names are leap/nonleap - day - incomplete/regular/complete - diaspora/Israel
11532
- * @private
11533
- * @readonly
11534
- */
11535
- const types = {
11536
- /* Hebrew year that starts on Monday, is `incomplete' (Heshvan and
11537
- * Kislev each have 29 days), and has Passover start on Tuesday. */
11538
- // e.g. 5753
11539
- '020': yearStartVayeilech.concat(r020, D(21), 23, 24, CHMPESACH, 25, D(26), D(28), 30, D(31), r3340, D(41), r4349, D(50)),
11540
- /* Hebrew year that starts on Monday, is `complete' (Heshvan and
11541
- * Kislev each have 30 days), and has Passover start on Thursday. */
11542
- // e.g. 5756
11543
- '0220': yearStartVayeilech.concat(r020, D(21), 23, 24, CHMPESACH, 25, D(26), D(28), 30, D(31), 33, SHAVUOT$1, range$1(34, 37), D(38), 40, D(41), r4349, D(50)),
11544
- /* Hebrew year that starts on Thursday, is `regular' (Heshvan has 29
11545
- * days and Kislev has 30 days), and has Passover start on Saturday. */
11546
- // e.g. 5701
11547
- '0510': yearStartHaazinu.concat(r020, D(21), 23, 24, PESACH1, PESACH8, 25, D(26), D(28), 30, D(31), r3340, D(41), r4350),
11548
- /* Hebrew year that starts on Thursday, is `regular' (Heshvan has 29
11549
- * days and Kislev has 30 days), and has Passover start on Saturday. */
11550
- // e.g. 5745
11551
- '0511': yearStartHaazinu.concat(r020, D(21), 23, 24, PESACH, 25, D(26), D(28), range$1(30, 40), D(41), r4350),
11552
- /* Hebrew year that starts on Thursday, is `complete' (Heshvan and
11553
- * Kislev each have 30 days), and has Passover start on Sunday. */
11554
- // e.g. 5754
11555
- '052': yearStartHaazinu.concat(range$1(0, 24), PESACH7, 25, D(26), D(28), 30, D(31), r3340, D(41), r4350),
11556
- /* Hebrew year that starts on Saturday, is `incomplete' (Heshvan and Kislev
11557
- * each have 29 days), and has Passover start on Sunday. */
11558
- // e.g. 5761
11559
- '070': yearStartRH.concat(r020, D(21), 23, 24, PESACH7, 25, D(26), D(28), 30, D(31), r3340, D(41), r4350),
11560
- /* Hebrew year that starts on Saturday, is `complete' (Heshvan and
11561
- * Kislev each have 30 days), and has Passover start on Tuesday. */
11562
- // e.g. 5716
11563
- '072': yearStartRH.concat(r020, D(21), 23, 24, CHMPESACH, 25, D(26), D(28), 30, D(31), r3340, D(41), r4349, D(50)),
11564
- /* -- The leap year types (keviot) -- */
11565
- /* Hebrew year that starts on Monday, is `incomplete' (Heshvan and
11566
- * Kislev each have 29 days), and has Passover start on Thursday. */
11567
- // e.g. 5746
11568
- '1200': yearStartVayeilech.concat(r027, CHMPESACH, range$1(28, 33), SHAVUOT$1, range$1(34, 37), D(38), 40, D(41), r4349, D(50)),
11569
- /* Hebrew year that starts on Monday, is `incomplete' (Heshvan and
11570
- * Kislev each have 29 days), and has Passover start on Thursday. */
11571
- // e.g. 5746
11572
- '1201': yearStartVayeilech.concat(r027, CHMPESACH, range$1(28, 40), D(41), r4349, D(50)),
11573
- /* Hebrew year that starts on Monday, is `complete' (Heshvan and
11574
- * Kislev each have 30 days), and has Passover start on Saturday. */
11575
- // e.g.5752
11576
- '1220': yearStartVayeilech.concat(r027, PESACH1, PESACH8, range$1(28, 40), D(41), r4350),
11577
- /* Hebrew year that starts on Monday, is `complete' (Heshvan and
11578
- * Kislev each have 30 days), and has Passover start on Saturday. */
11579
- // e.g.5752
11580
- '1221': yearStartVayeilech.concat(r027, PESACH, range$1(28, 50)),
11581
- /* Hebrew year that starts on Thursday, is `incomplete' (Heshvan and
11582
- * Kislev both have 29 days), and has Passover start on Sunday. */
11583
- // e.g. 5768
11584
- '150': yearStartHaazinu.concat(range$1(0, 28), PESACH7, range$1(29, 50)),
11585
- /* Hebrew year that starts on Thursday, is `complete' (Heshvan and
11586
- * Kislev both have 30 days), and has Passover start on Tuesday. */
11587
- // eg. 5771
11588
- '152': yearStartHaazinu.concat(range$1(0, 28), CHMPESACH, range$1(29, 49), D(50)),
11589
- /* Hebrew year that starts on Saturday, is `incomplete' (Heshvan and
11590
- * Kislev each have 29 days), and has Passover start on Tuesday. */
11591
- // e.g.5757
11592
- '170': yearStartRH.concat(r027, CHMPESACH, range$1(28, 40), D(41), r4349, D(50)),
11593
- /* Hebrew year that starts on Saturday, is `complete' (Heshvan and
11594
- * Kislev each have 30 days), and has Passover start on Thursday. */
11595
- '1720': yearStartRH.concat(r027, CHMPESACH, range$1(28, 33), SHAVUOT$1, range$1(34, 37), D(38), 40, D(41), r4349, D(50)),
11596
- };
11597
- /* Hebrew year that starts on Monday, is `complete' (Heshvan and
11598
- * Kislev each have 30 days), and has Passover start on Thursday. */
11599
- types['0221'] = types['020'];
11600
- /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
11601
- * days and Kislev has 30 days), and has Passover start on Thursday. */
11602
- // e.g. 5715
11603
- types['0310'] = types['0220'];
11604
- /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
11605
- * days and Kislev has 30 days), and has Passover start on Thursday. */
11606
- types['0311'] = types['020'];
11607
- /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
11608
- * days and Kislev has 30 days), and has Passover start on Saturday. */
11609
- // e.g. 5715
11610
- types['1310'] = types['1220'];
11611
- /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
11612
- * days and Kislev has 30 days), and has Passover start on Saturday. */
11613
- types['1311'] = types['1221'];
11614
- /* Hebrew year that starts on Saturday, is `complete' (Heshvan and
11615
- * Kislev each have 30 days), and has Passover start on Thursday. */
11616
- types['1721'] = types['170'];
11617
- const sedraCache = new QuickLRU({ maxSize: 120 });
11618
- /**
11619
- * Convenience function to create an instance of {@link Sedra} or reuse a
11620
- * previously created and cached instance for the same year and schedule.
11621
- *
11622
- * Prefer this over `new Sedra(...)` when calling repeatedly — an internal
11623
- * LRU cache (~120 entries) avoids recomputing the keviyah-specific schedule.
11624
- * @example
11625
- * import {getSedra, HDate, months} from '@hebcal/core';
11626
- * const sedra = getSedra(5784, false);
11627
- * const {parsha} = sedra.lookup(new HDate(15, months.CHESHVAN, 5784));
11628
- * console.log(parsha); // ['Vayera']
11629
- * @param hyear Hebrew year
11630
- * @param il Use Israel sedra schedule (`false` for Diaspora)
11631
- */
11632
- function getSedra(hyear, il) {
11633
- const cacheKey = `${hyear}-${il ? 1 : 0}`;
11634
- let sedra = sedraCache.get(cacheKey);
11635
- if (!sedra) {
11636
- sedra = new Sedra(hyear, il);
11637
- sedraCache.set(cacheKey, sedra);
11638
- }
11639
- return sedra;
11640
- }
11641
-
11642
- const Nisan = months.NISAN;
11643
- const Iyyar = months.IYYAR;
11644
- const Sivan = months.SIVAN;
11645
- const Tamuz = months.TAMUZ;
11646
- const Av = months.AV;
11647
- const Elul = months.ELUL;
11648
- const Tishrei = months.TISHREI;
11649
- const Cheshvan = months.CHESHVAN;
11650
- const Kislev = months.KISLEV;
11651
- const Shvat = months.SHVAT;
11652
- const Adar2 = months.ADAR_II;
11653
- const CHAG$1 = flags.CHAG;
11654
- const LIGHT_CANDLES$2 = flags.LIGHT_CANDLES;
11655
- const YOM_TOV_ENDS$1 = flags.YOM_TOV_ENDS;
11656
- const CHUL_ONLY$1 = flags.CHUL_ONLY;
11657
- const IL_ONLY$2 = flags.IL_ONLY;
11658
- const LIGHT_CANDLES_TZEIS$3 = flags.LIGHT_CANDLES_TZEIS;
11659
- const MAJOR_FAST$2 = flags.MAJOR_FAST;
11660
- const MINOR_HOLIDAY$2 = flags.MINOR_HOLIDAY;
11661
- const EREV$2 = flags.EREV;
11662
- const CHOL_HAMOED$1 = flags.CHOL_HAMOED;
11663
- const emojiPesach = '🫓';
11664
- const emojiSukkot = '🌿🍋';
11665
- const ROSH_HASHANA_II = 'Rosh Hashana II';
11666
- const EREV_YOM_KIPPUR = 'Erev Yom Kippur';
11667
- const YOM_KIPPUR = 'Yom Kippur';
11668
- const EREV_SUKKOT = 'Erev Sukkot';
11669
- const SUKKOT_I = 'Sukkot I';
11670
- const SUKKOT_II = 'Sukkot II';
11671
- const SUKKOT_III_CHM = "Sukkot III (CH''M)";
11672
- const SUKKOT_IV_CHM = "Sukkot IV (CH''M)";
11673
- const SUKKOT_V_CHM = "Sukkot V (CH''M)";
11674
- const SUKKOT_VI_CHM = "Sukkot VI (CH''M)";
11675
- const SHMINI_ATZERET = 'Shmini Atzeret';
11676
- const SIMCHAT_TORAH = 'Simchat Torah';
11677
- const SUKKOT_II_CHM = "Sukkot II (CH''M)";
11678
- const SUKKOT_VII_HOSHANA_RABA = 'Sukkot VII (Hoshana Raba)';
11679
- const CHANUKAH_1_CANDLE = 'Chanukah: 1 Candle';
11680
- const TU_BISHVAT = 'Tu BiShvat';
11681
- const EREV_PURIM = 'Erev Purim';
11682
- const PURIM = 'Purim';
11683
- const SHUSHAN_PURIM = 'Shushan Purim';
11684
- const EREV_PESACH = 'Erev Pesach';
11685
- const PESACH_I = 'Pesach I';
11686
- const PESACH_II = 'Pesach II';
11687
- const PESACH_II_CHM = "Pesach II (CH''M)";
11688
- const PESACH_III_CHM = "Pesach III (CH''M)";
11689
- const PESACH_IV_CHM = "Pesach IV (CH''M)";
11690
- const PESACH_V_CHM = "Pesach V (CH''M)";
11691
- const PESACH_VI_CHM = "Pesach VI (CH''M)";
11692
- const PESACH_VII = 'Pesach VII';
11693
- const PESACH_VIII = 'Pesach VIII';
11694
- const PESACH_SHENI = 'Pesach Sheni';
11695
- const LAG_BAOMER = 'Lag BaOmer';
11696
- const EREV_SHAVUOT = 'Erev Shavuot';
11697
- const SHAVUOT = 'Shavuot';
11698
- const SHAVUOT_I = 'Shavuot I';
11699
- const SHAVUOT_II = 'Shavuot II';
11700
- const TU_BAV = "Tu B'Av";
11701
- const ROSH_HASHANA_LABEHEMOT = 'Rosh Hashana LaBehemot';
11702
- const EREV_ROSH_HASHANA = 'Erev Rosh Hashana';
11703
- const YOM_YERUSHALAYIM = 'Yom Yerushalayim';
11704
- const BEN_GURION_DAY = 'Ben-Gurion Day';
11705
- const FAMILY_DAY = 'Family Day';
11706
- const YITZHAK_RABIN_MEMORIAL_DAY = 'Yitzhak Rabin Memorial Day';
11707
- const HERZL_DAY = 'Herzl Day';
11708
- const JABOTINSKY_DAY = 'Jabotinsky Day';
11709
- const SIGD = 'Sigd';
11710
- const YOM_HAALIYAH = 'Yom HaAliyah';
11711
- const YOM_HAALIYAH_SCHOOL_OBSERVANCE = 'Yom HaAliyah School Observance';
11712
- const HEBREW_LANGUAGE_DAY = 'Hebrew Language Day';
11713
- const CANDLE_LIGHTING$1 = 'Candle lighting';
11714
- const HAVDALAH$1 = 'Havdalah';
11715
- const FAST_BEGINS$1 = 'Fast begins';
11716
- const FAST_ENDS$1 = 'Fast ends';
11717
- const BIUR_CHAMETZ = 'Biur Chametz';
11718
- const SOF_ZMAN_ACHILAT_CHAMETZ = 'Finish eating chametz';
11719
- const YIZKOR$1 = 'Yizkor';
11720
- /**
11721
- * Transliterated names of holidays, used by `Event.getDesc()`
11722
- */
11723
- const holidayDesc = {
11724
- /** Asara B'Tevet */
11725
- ASARA_BTEVET: "Asara B'Tevet",
11726
- /** Birkat Hachamah */
11727
- BIRKAT_HACHAMAH: 'Birkat Hachamah',
11728
- /** Chag HaBanot */
11729
- CHAG_HABANOT: 'Chag HaBanot',
11730
- /** Chanukah: 8th Day */
11731
- CHANUKAH_8TH_DAY: 'Chanukah: 8th Day',
11732
- /** Erev Tish'a B'Av */
11733
- EREV_TISHA_BAV: "Erev Tish'a B'Av",
11734
- /** Leil Selichot */
11735
- LEIL_SELICHOT: 'Leil Selichot',
11736
- /** Purim Katan */
11737
- PURIM_KATAN: 'Purim Katan',
11738
- /** Purim Meshulash */
11739
- PURIM_MESHULASH: 'Purim Meshulash',
11740
- /** Shabbat Chazon */
11741
- SHABBAT_CHAZON: 'Shabbat Chazon',
11742
- /** Shabbat HaChodesh */
11743
- SHABBAT_HACHODESH: 'Shabbat HaChodesh',
11744
- /** Shabbat HaGadol */
11745
- SHABBAT_HAGADOL: 'Shabbat HaGadol',
11746
- /** Shabbat Nachamu */
11747
- SHABBAT_NACHAMU: 'Shabbat Nachamu',
11748
- /** Shabbat Parah */
11749
- SHABBAT_PARAH: 'Shabbat Parah',
11750
- /** Shabbat Shekalim */
11751
- SHABBAT_SHEKALIM: 'Shabbat Shekalim',
11752
- /** Shabbat Shirah */
11753
- SHABBAT_SHIRAH: 'Shabbat Shirah',
11754
- /** Shabbat Shuva */
11755
- SHABBAT_SHUVA: 'Shabbat Shuva',
11756
- /** Shabbat Zachor */
11757
- SHABBAT_ZACHOR: 'Shabbat Zachor',
11758
- /** Shushan Purim Katan */
11759
- SHUSHAN_PURIM_KATAN: 'Shushan Purim Katan',
11760
- /** Ta'anit Bechorot */
11761
- TAANIT_BECHOROT: "Ta'anit Bechorot",
11762
- /** Ta'anit BeHaB */
11763
- TAANIT_BEHAB: "Ta'anit BeHaB",
11764
- /** Ta'anit Esther */
11765
- TAANIT_ESTHER: "Ta'anit Esther",
11766
- /** Tish'a B'Av */
11767
- TISHA_BAV: "Tish'a B'Av",
11768
- /** Tzom Gedaliah */
11769
- TZOM_GEDALIAH: 'Tzom Gedaliah',
11770
- /** Tzom Tammuz */
11771
- TZOM_TAMMUZ: 'Tzom Tammuz',
11772
- /** Yom HaAtzma'ut */
11773
- YOM_HAATZMA_UT: "Yom HaAtzma'ut",
11774
- /** Yom HaShoah */
11775
- YOM_HASHOAH: 'Yom HaShoah',
11776
- /** Yom HaZikaron */
11777
- YOM_HAZIKARON: 'Yom HaZikaron',
11778
- /** Ben-Gurion Day */
11779
- BEN_GURION_DAY,
11780
- /** Chanukah: 1 Candle */
11781
- CHANUKAH_1_CANDLE,
11782
- /** Erev Pesach */
11783
- EREV_PESACH,
11784
- /** Erev Purim */
11785
- EREV_PURIM,
11786
- /** Erev Rosh Hashana */
11787
- EREV_ROSH_HASHANA,
11788
- /** Erev Shavuot */
11789
- EREV_SHAVUOT,
11790
- /** Erev Sukkot */
11791
- EREV_SUKKOT,
11792
- /** Erev Yom Kippur */
11793
- EREV_YOM_KIPPUR,
11794
- /** Family Day */
11795
- FAMILY_DAY,
11796
- /** Hebrew Language Day */
11797
- HEBREW_LANGUAGE_DAY,
11798
- /** Herzl Day */
11799
- HERZL_DAY,
11800
- /** Jabotinsky Day */
11801
- JABOTINSKY_DAY,
11802
- /** Lag BaOmer */
11803
- LAG_BAOMER,
11804
- /** Pesach I */
11805
- PESACH_I,
11806
- /** Pesach II */
11807
- PESACH_II,
11808
- /** Pesach III (CH''M) */
11809
- PESACH_III_CHM,
11810
- /** Pesach II (CH''M) */
11811
- PESACH_II_CHM,
11812
- /** Pesach IV (CH''M) */
11813
- PESACH_IV_CHM,
11814
- /** Pesach Sheni */
11815
- PESACH_SHENI,
11816
- /** Pesach VII */
11817
- PESACH_VII,
11818
- /** Pesach VIII */
11819
- PESACH_VIII,
11820
- /** Pesach VI (CH''M) */
11821
- PESACH_VI_CHM,
11822
- /** Pesach V (CH''M) */
11823
- PESACH_V_CHM,
11824
- /** Purim */
11825
- PURIM,
11826
- /** Rosh Hashana II */
11827
- ROSH_HASHANA_II,
11828
- /** Rosh Hashana LaBehemot */
11829
- ROSH_HASHANA_LABEHEMOT,
11830
- /** Shavuot */
11831
- SHAVUOT,
11832
- /** Shavuot I */
11833
- SHAVUOT_I,
11834
- /** Shavuot II */
11835
- SHAVUOT_II,
11836
- /** Shmini Atzeret */
11837
- SHMINI_ATZERET,
11838
- /** Shushan Purim */
11839
- SHUSHAN_PURIM,
11840
- /** Sigd */
11841
- SIGD,
11842
- /** Simchat Torah */
11843
- SIMCHAT_TORAH,
11844
- /** Sukkot I */
11845
- SUKKOT_I,
11846
- /** Sukkot II */
11847
- SUKKOT_II,
11848
- /** Sukkot III (CH''M) */
11849
- SUKKOT_III_CHM,
11850
- /** Sukkot II (CH''M) */
11851
- SUKKOT_II_CHM,
11852
- /** Sukkot IV (CH''M) */
11853
- SUKKOT_IV_CHM,
11854
- /** Sukkot VII (Hoshana Raba) */
11855
- SUKKOT_VII_HOSHANA_RABA,
11856
- /** Sukkot VI (CH''M) */
11857
- SUKKOT_VI_CHM,
11858
- /** Sukkot V (CH''M) */
11859
- SUKKOT_V_CHM,
11860
- /** Tu B\'Av */
11861
- TU_BAV,
11862
- /** Tu BiShvat */
11863
- TU_BISHVAT,
11864
- /** Yitzhak Rabin Memorial Day */
11865
- YITZHAK_RABIN_MEMORIAL_DAY,
11866
- /** Yom HaAliyah */
11867
- YOM_HAALIYAH,
11868
- /** Yom HaAliyah School Observance */
11869
- YOM_HAALIYAH_SCHOOL_OBSERVANCE,
11870
- /** Yom Kippur */
11871
- YOM_KIPPUR,
11872
- /** Yom Yerushalayim */
11873
- YOM_YERUSHALAYIM,
11874
- /** Candle lighting */
11875
- CANDLE_LIGHTING: CANDLE_LIGHTING$1,
11876
- /** Havdalah */
11877
- HAVDALAH: HAVDALAH$1,
11878
- /** Fast begins */
11879
- FAST_BEGINS: FAST_BEGINS$1,
11880
- /** Fast ends */
11881
- FAST_ENDS: FAST_ENDS$1,
11882
- /** Biur Chametz */
11883
- BIUR_CHAMETZ,
11884
- /** Finish eating chametz */
11885
- SOF_ZMAN_ACHILAT_CHAMETZ,
11886
- /** Yizkor */
11887
- YIZKOR: YIZKOR$1,
11888
- };
11889
- const staticHolidays = [
11890
- {
11891
- mm: Tishrei,
11892
- dd: 2,
11893
- desc: ROSH_HASHANA_II,
11894
- flags: CHAG$1 | YOM_TOV_ENDS$1,
11895
- emoji: '🍏🍯',
11896
- },
11897
- { mm: Tishrei, dd: 9, desc: EREV_YOM_KIPPUR, flags: EREV$2 | LIGHT_CANDLES$2 },
11898
- {
11899
- mm: Tishrei,
11900
- dd: 10,
11901
- desc: YOM_KIPPUR,
11902
- flags: CHAG$1 | MAJOR_FAST$2 | YOM_TOV_ENDS$1,
11903
- },
11904
- {
11905
- mm: Tishrei,
11906
- dd: 14,
11907
- desc: EREV_SUKKOT,
11908
- flags: CHUL_ONLY$1 | EREV$2 | LIGHT_CANDLES$2,
11909
- emoji: emojiSukkot,
11910
- },
11911
- {
11912
- mm: Tishrei,
11913
- dd: 15,
11914
- desc: SUKKOT_I,
11915
- flags: CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3,
11916
- emoji: emojiSukkot,
11917
- },
11918
- {
11919
- mm: Tishrei,
11920
- dd: 16,
11921
- desc: SUKKOT_II,
11922
- flags: CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1,
11923
- emoji: emojiSukkot,
11924
- },
11925
- {
11926
- mm: Tishrei,
11927
- dd: 17,
11928
- desc: SUKKOT_III_CHM,
11929
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
11930
- chmDay: 1,
11931
- emoji: emojiSukkot,
11932
- },
11933
- {
11934
- mm: Tishrei,
11935
- dd: 18,
11936
- desc: SUKKOT_IV_CHM,
11937
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
11938
- chmDay: 2,
11939
- emoji: emojiSukkot,
11940
- },
11941
- {
11942
- mm: Tishrei,
11943
- dd: 19,
11944
- desc: SUKKOT_V_CHM,
11945
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
11946
- chmDay: 3,
11947
- emoji: emojiSukkot,
11948
- },
11949
- {
11950
- mm: Tishrei,
11951
- dd: 20,
11952
- desc: SUKKOT_VI_CHM,
11953
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
11954
- chmDay: 4,
11955
- emoji: emojiSukkot,
11956
- },
11957
- {
11958
- mm: Tishrei,
11959
- dd: 22,
11960
- desc: SHMINI_ATZERET,
11961
- flags: CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3,
11962
- },
11963
- {
11964
- mm: Tishrei,
11965
- dd: 23,
11966
- desc: SIMCHAT_TORAH,
11967
- flags: CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1,
11968
- },
11969
- {
11970
- mm: Tishrei,
11971
- dd: 14,
11972
- desc: EREV_SUKKOT,
11973
- flags: IL_ONLY$2 | EREV$2 | LIGHT_CANDLES$2,
11974
- emoji: emojiSukkot,
11975
- },
11976
- {
11977
- mm: Tishrei,
11978
- dd: 15,
11979
- desc: SUKKOT_I,
11980
- flags: IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1,
11981
- emoji: emojiSukkot,
11982
- },
11983
- {
11984
- mm: Tishrei,
11985
- dd: 16,
11986
- desc: SUKKOT_II_CHM,
11987
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
11988
- chmDay: 1,
11989
- emoji: emojiSukkot,
11990
- },
11991
- {
11992
- mm: Tishrei,
11993
- dd: 17,
11994
- desc: SUKKOT_III_CHM,
11995
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
11996
- chmDay: 2,
11997
- emoji: emojiSukkot,
11998
- },
11999
- {
12000
- mm: Tishrei,
12001
- dd: 18,
12002
- desc: SUKKOT_IV_CHM,
12003
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12004
- chmDay: 3,
12005
- emoji: emojiSukkot,
12006
- },
12007
- {
12008
- mm: Tishrei,
12009
- dd: 19,
12010
- desc: SUKKOT_V_CHM,
12011
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12012
- chmDay: 4,
12013
- emoji: emojiSukkot,
12014
- },
12015
- {
12016
- mm: Tishrei,
12017
- dd: 20,
12018
- desc: SUKKOT_VI_CHM,
12019
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12020
- chmDay: 5,
12021
- emoji: emojiSukkot,
12022
- },
12023
- {
12024
- mm: Tishrei,
12025
- dd: 22,
12026
- desc: SHMINI_ATZERET,
12027
- flags: IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1,
12028
- },
12029
- {
12030
- mm: Tishrei,
12031
- dd: 21,
12032
- desc: SUKKOT_VII_HOSHANA_RABA,
12033
- flags: LIGHT_CANDLES$2 | CHOL_HAMOED$1,
12034
- chmDay: -1,
12035
- emoji: emojiSukkot,
12036
- },
12037
- { mm: Shvat, dd: 15, desc: TU_BISHVAT, flags: MINOR_HOLIDAY$2, emoji: '🌳' },
12038
- {
12039
- mm: Adar2,
12040
- dd: 13,
12041
- desc: EREV_PURIM,
12042
- flags: EREV$2 | MINOR_HOLIDAY$2,
12043
- emoji: '🎭️📜',
12044
- },
12045
- { mm: Adar2, dd: 14, desc: PURIM, flags: MINOR_HOLIDAY$2, emoji: '🎭️📜' },
12046
- {
12047
- mm: Adar2,
12048
- dd: 15,
12049
- desc: SHUSHAN_PURIM,
12050
- flags: MINOR_HOLIDAY$2,
12051
- emoji: '🎭️📜',
12052
- },
12053
- // Pesach Israel
12054
- {
12055
- mm: Nisan,
12056
- dd: 14,
12057
- desc: EREV_PESACH,
12058
- flags: IL_ONLY$2 | EREV$2 | LIGHT_CANDLES$2,
12059
- emoji: '🫓🍷',
12060
- },
12061
- {
12062
- mm: Nisan,
12063
- dd: 15,
12064
- desc: PESACH_I,
12065
- flags: IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1,
12066
- emoji: emojiPesach,
12067
- },
12068
- {
12069
- mm: Nisan,
12070
- dd: 16,
12071
- desc: PESACH_II_CHM,
12072
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12073
- chmDay: 1,
12074
- emoji: emojiPesach,
12075
- },
12076
- {
12077
- mm: Nisan,
12078
- dd: 17,
12079
- desc: PESACH_III_CHM,
12080
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12081
- chmDay: 2,
12082
- emoji: emojiPesach,
12083
- },
12084
- {
12085
- mm: Nisan,
12086
- dd: 18,
12087
- desc: PESACH_IV_CHM,
12088
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12089
- chmDay: 3,
12090
- emoji: emojiPesach,
12091
- },
12092
- {
12093
- mm: Nisan,
12094
- dd: 19,
12095
- desc: PESACH_V_CHM,
12096
- flags: IL_ONLY$2 | CHOL_HAMOED$1,
12097
- chmDay: 4,
12098
- emoji: emojiPesach,
12099
- },
12100
- {
12101
- mm: Nisan,
12102
- dd: 20,
12103
- desc: PESACH_VI_CHM,
12104
- flags: IL_ONLY$2 | CHOL_HAMOED$1 | LIGHT_CANDLES$2,
12105
- chmDay: 5,
12106
- emoji: emojiPesach,
12107
- },
12108
- {
12109
- mm: Nisan,
12110
- dd: 21,
12111
- desc: PESACH_VII,
12112
- flags: IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1,
12113
- emoji: emojiPesach,
12114
- },
12115
- // Pesach chutz l'aretz
12116
- {
12117
- mm: Nisan,
12118
- dd: 14,
12119
- desc: EREV_PESACH,
12120
- flags: CHUL_ONLY$1 | EREV$2 | LIGHT_CANDLES$2,
12121
- emoji: '🫓🍷',
12122
- },
12123
- {
12124
- mm: Nisan,
12125
- dd: 15,
12126
- desc: PESACH_I,
12127
- flags: CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3,
12128
- emoji: '🫓🍷',
12129
- },
12130
- {
12131
- mm: Nisan,
12132
- dd: 16,
12133
- desc: PESACH_II,
12134
- flags: CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1,
12135
- emoji: emojiPesach,
12136
- },
12137
- {
12138
- mm: Nisan,
12139
- dd: 17,
12140
- desc: PESACH_III_CHM,
12141
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
12142
- chmDay: 1,
12143
- emoji: emojiPesach,
12144
- },
12145
- {
12146
- mm: Nisan,
12147
- dd: 18,
12148
- desc: PESACH_IV_CHM,
12149
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
12150
- chmDay: 2,
12151
- emoji: emojiPesach,
12152
- },
12153
- {
12154
- mm: Nisan,
12155
- dd: 19,
12156
- desc: PESACH_V_CHM,
12157
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1,
12158
- chmDay: 3,
12159
- emoji: emojiPesach,
12160
- },
12161
- {
12162
- mm: Nisan,
12163
- dd: 20,
12164
- desc: PESACH_VI_CHM,
12165
- flags: CHUL_ONLY$1 | CHOL_HAMOED$1 | LIGHT_CANDLES$2,
12166
- chmDay: 4,
12167
- emoji: emojiPesach,
12168
- },
12169
- {
12170
- mm: Nisan,
12171
- dd: 21,
12172
- desc: PESACH_VII,
12173
- flags: CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3,
12174
- emoji: emojiPesach,
12175
- },
12176
- {
12177
- mm: Nisan,
12178
- dd: 22,
12179
- desc: PESACH_VIII,
12180
- flags: CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1,
12181
- emoji: emojiPesach,
12182
- },
12183
- { mm: Iyyar, dd: 14, desc: PESACH_SHENI, flags: MINOR_HOLIDAY$2 },
12184
- { mm: Iyyar, dd: 18, desc: LAG_BAOMER, flags: MINOR_HOLIDAY$2, emoji: '🔥' },
12185
- {
12186
- mm: Sivan,
12187
- dd: 5,
12188
- desc: EREV_SHAVUOT,
12189
- flags: EREV$2 | LIGHT_CANDLES$2,
12190
- emoji: '⛰️🌸',
12191
- },
12192
- {
12193
- mm: Sivan,
12194
- dd: 6,
12195
- desc: SHAVUOT,
12196
- flags: IL_ONLY$2 | CHAG$1 | YOM_TOV_ENDS$1,
12197
- emoji: '⛰️🌸',
12198
- },
12199
- {
12200
- mm: Sivan,
12201
- dd: 6,
12202
- desc: SHAVUOT_I,
12203
- flags: CHUL_ONLY$1 | CHAG$1 | LIGHT_CANDLES_TZEIS$3,
12204
- emoji: '⛰️🌸',
12205
- },
12206
- {
12207
- mm: Sivan,
12208
- dd: 7,
12209
- desc: SHAVUOT_II,
12210
- flags: CHUL_ONLY$1 | CHAG$1 | YOM_TOV_ENDS$1,
12211
- emoji: '⛰️🌸',
12212
- },
12213
- { mm: Av, dd: 15, desc: TU_BAV, flags: MINOR_HOLIDAY$2, emoji: '❤️' },
12214
- {
12215
- mm: Elul,
12216
- dd: 1,
12217
- desc: ROSH_HASHANA_LABEHEMOT,
12218
- flags: MINOR_HOLIDAY$2,
12219
- emoji: '🐑',
12220
- },
11550
+ const roshChodeshStr = 'Rosh Chodesh';
11551
+ /** Represents Rosh Chodesh, the beginning of a new month */
11552
+ class RoshChodeshEvent extends HolidayEvent {
11553
+ /**
11554
+ * Constructs Rosh Chodesh event
11555
+ * @param date Hebrew date event occurs
11556
+ * @param monthName Hebrew month name (not translated)
11557
+ */
11558
+ constructor(date, monthName) {
11559
+ super(date, `${roshChodeshStr} ${monthName}`, flags.ROSH_CHODESH);
11560
+ }
11561
+ /**
11562
+ * Returns (translated) description of this event
11563
+ * @param [locale] Optional locale name (defaults to empty locale)
11564
+ */
11565
+ render(locale) {
11566
+ const monthName = this.getDesc().substring(roshChodeshStr.length + 1);
11567
+ const monthName0 = Locale.gettext(monthName, locale);
11568
+ const monthName1 = smartApostrophe(monthName0);
11569
+ return `${Locale.gettext(roshChodeshStr, locale)} ${monthName1}`;
11570
+ }
11571
+ basename() {
11572
+ return this.getDesc();
11573
+ }
11574
+ getEmoji() {
11575
+ return this.emoji || '🌒';
11576
+ }
11577
+ }
11578
+
11579
+ var Day;
11580
+ (function (Day) {
11581
+ Day[Day["SUN"] = 0] = "SUN";
11582
+ Day[Day["TUE"] = 2] = "TUE";
11583
+ Day[Day["THU"] = 4] = "THU";
11584
+ Day[Day["FRI"] = 5] = "FRI";
11585
+ Day[Day["SAT"] = 6] = "SAT";
11586
+ })(Day || (Day = {}));
11587
+ const { NISAN: NISAN$3, IYYAR: IYYAR$1, CHESHVAN: CHESHVAN$1 } = months;
11588
+ /**
11589
+ * Yom HaShoah first observed in 1951.
11590
+ * When the actual date of Yom Hashoah falls on a Friday, the
11591
+ * state of Israel observes Yom Hashoah on the preceding
11592
+ * Thursday. When it falls on a Sunday, Yom Hashoah is observed
11593
+ * on the following Monday.
11594
+ * http://www.ushmm.org/remembrance/dor/calendar/
11595
+ */
11596
+ function dateYomHaShoah(year) {
11597
+ if (year < 5711) {
11598
+ return null;
11599
+ }
11600
+ let nisan27dt = new HDate(27, NISAN$3, year);
11601
+ if (nisan27dt.getDay() === Day.FRI) {
11602
+ nisan27dt = new HDate(26, NISAN$3, year);
11603
+ }
11604
+ else if (nisan27dt.getDay() === Day.SUN) {
11605
+ nisan27dt = new HDate(28, NISAN$3, year);
11606
+ }
11607
+ return nisan27dt;
11608
+ }
11609
+ /**
11610
+ * Yom HaAtzma'ut only celebrated after 1948
11611
+ * @internal
11612
+ */
11613
+ function dateYomHaZikaron(year) {
11614
+ if (year < 5708) {
11615
+ return null;
11616
+ }
11617
+ let day;
11618
+ const pesach = new HDate(15, NISAN$3, year);
11619
+ const pdow = pesach.getDay();
11620
+ if (pdow === Day.SUN) {
11621
+ day = 2;
11622
+ }
11623
+ else if (pdow === Day.SAT) {
11624
+ day = 3;
11625
+ }
11626
+ else if (year < 5764) {
11627
+ day = 4;
11628
+ }
11629
+ else if (pdow === Day.TUE) {
11630
+ day = 5;
11631
+ }
11632
+ else {
11633
+ day = 4;
11634
+ }
11635
+ return new HDate(day, IYYAR$1, year);
11636
+ }
11637
+ function postpone(hd, rule) {
11638
+ const dow = hd.getDay();
11639
+ switch (rule) {
11640
+ case 'friSatToThu':
11641
+ return dow === Day.FRI || dow === Day.SAT ? hd.onOrBefore(Day.THU) : hd;
11642
+ case 'friSatToSun':
11643
+ if (dow === Day.FRI)
11644
+ return hd.next().next();
11645
+ return dow === Day.SAT ? hd.next() : hd;
11646
+ case 'satToSun':
11647
+ return dow === Day.SAT ? hd.next() : hd;
11648
+ case undefined:
11649
+ return hd;
11650
+ default:
11651
+ return rule;
11652
+ }
11653
+ }
11654
+ const staticModernHolidays = [
12221
11655
  {
12222
- mm: Elul,
12223
- dd: 29,
12224
- desc: EREV_ROSH_HASHANA,
12225
- flags: EREV$2 | LIGHT_CANDLES$2,
12226
- emoji: '🍏🍯',
11656
+ firstYear: 5727,
11657
+ mm: IYYAR$1,
11658
+ dd: 28,
11659
+ desc: holidayDesc.YOM_YERUSHALAYIM,
11660
+ chul: true,
12227
11661
  },
12228
- ];
12229
- const staticModernHolidays = [
12230
- { firstYear: 5727, mm: Iyyar, dd: 28, desc: YOM_YERUSHALAYIM, chul: true },
12231
11662
  {
12232
11663
  firstYear: 5737,
12233
- mm: Kislev,
11664
+ mm: months.KISLEV,
12234
11665
  dd: 6,
12235
- desc: BEN_GURION_DAY,
12236
- satPostponeToSun: true,
12237
- friPostponeToSun: true,
11666
+ desc: holidayDesc.BEN_GURION_DAY,
11667
+ postpone: 'friSatToSun',
12238
11668
  },
12239
- { firstYear: 5750, mm: Shvat, dd: 30, desc: FAMILY_DAY },
11669
+ { firstYear: 5750, mm: months.SHVAT, dd: 30, desc: holidayDesc.FAMILY_DAY },
12240
11670
  {
12241
11671
  firstYear: 5758,
12242
- mm: Cheshvan,
11672
+ mm: CHESHVAN$1,
12243
11673
  dd: 12,
12244
- desc: YITZHAK_RABIN_MEMORIAL_DAY,
12245
- friSatMovetoThu: true,
11674
+ desc: holidayDesc.YITZHAK_RABIN_MEMORIAL_DAY,
11675
+ postpone: 'friSatToThu',
11676
+ },
11677
+ {
11678
+ firstYear: 5764,
11679
+ mm: IYYAR$1,
11680
+ dd: 10,
11681
+ desc: holidayDesc.HERZL_DAY,
11682
+ postpone: 'satToSun',
12246
11683
  },
12247
- { firstYear: 5764, mm: Iyyar, dd: 10, desc: HERZL_DAY, satPostponeToSun: true },
12248
11684
  {
12249
11685
  firstYear: 5765,
12250
- mm: Tamuz,
11686
+ mm: months.TAMUZ,
12251
11687
  dd: 29,
12252
- desc: JABOTINSKY_DAY,
12253
- satPostponeToSun: true,
11688
+ desc: holidayDesc.JABOTINSKY_DAY,
11689
+ postpone: 'satToSun',
12254
11690
  },
12255
11691
  {
12256
11692
  firstYear: 5769,
12257
- mm: Cheshvan,
11693
+ mm: CHESHVAN$1,
12258
11694
  dd: 29,
12259
- desc: SIGD,
11695
+ desc: holidayDesc.SIGD,
12260
11696
  chul: true,
12261
11697
  suppressEmoji: true,
12262
- friSatMovetoThu: true,
11698
+ postpone: 'friSatToThu',
11699
+ },
11700
+ { firstYear: 5777, mm: NISAN$3, dd: 10, desc: holidayDesc.YOM_HAALIYAH, chul: true },
11701
+ {
11702
+ firstYear: 5777,
11703
+ mm: CHESHVAN$1,
11704
+ dd: 7,
11705
+ desc: holidayDesc.YOM_HAALIYAH_SCHOOL_OBSERVANCE,
12263
11706
  },
12264
- { firstYear: 5777, mm: Nisan, dd: 10, desc: YOM_HAALIYAH, chul: true },
12265
- { firstYear: 5777, mm: Cheshvan, dd: 7, desc: YOM_HAALIYAH_SCHOOL_OBSERVANCE },
12266
11707
  // https://www.gov.il/he/departments/policies/2012_des5234
12267
11708
  {
12268
11709
  firstYear: 5773,
12269
11710
  mm: months.TEVET,
12270
11711
  dd: 21,
12271
- desc: HEBREW_LANGUAGE_DAY,
12272
- friSatMovetoThu: true,
11712
+ desc: holidayDesc.HEBREW_LANGUAGE_DAY,
11713
+ postpone: 'friSatToThu',
11714
+ },
11715
+ /**
11716
+ * https://fs.knesset.gov.il/25/law/25_lsr_14184773.pdf
11717
+ * (Published in Sefer HaChukim No. 3567 on 8 Av 5786 / July 22, 2026)
11718
+ */
11719
+ {
11720
+ firstYear: 5786,
11721
+ mm: months.TISHREI,
11722
+ dd: 24,
11723
+ desc: holidayDesc.SWORDS_OF_IRON_WAR_MEMORIAL,
11724
+ postpone: 'satToSun',
12273
11725
  },
12274
11726
  ];
11727
+ const { MODERN_HOLIDAY: MODERN_HOLIDAY$1, IL_ONLY: IL_ONLY$1 } = flags;
11728
+ const ISRAEL_FLAG = '🇮🇱';
11729
+ const emojiIsraelFlag = { emoji: ISRAEL_FLAG };
11730
+ /**
11731
+ * Generates the modern Israeli holidays and memorial days for a Hebrew year.
11732
+ * @internal
11733
+ * @param year Hebrew year
11734
+ */
11735
+ function modernHolidaysForYear(year) {
11736
+ const events = [];
11737
+ const nisan27dt = dateYomHaShoah(year);
11738
+ if (nisan27dt) {
11739
+ events.push(new HolidayEvent(nisan27dt, holidayDesc.YOM_HASHOAH, MODERN_HOLIDAY$1));
11740
+ }
11741
+ const yomHaZikaronDt = dateYomHaZikaron(year);
11742
+ if (yomHaZikaronDt) {
11743
+ events.push(new HolidayEvent(yomHaZikaronDt, holidayDesc.YOM_HAZIKARON, MODERN_HOLIDAY$1, emojiIsraelFlag), new HolidayEvent(yomHaZikaronDt.next(), holidayDesc.YOM_HAATZMA_UT, MODERN_HOLIDAY$1, emojiIsraelFlag));
11744
+ }
11745
+ for (const h of staticModernHolidays) {
11746
+ if (year >= h.firstYear) {
11747
+ const hd = postpone(new HDate(h.dd, h.mm, year), h.postpone);
11748
+ const mask = h.chul ? MODERN_HOLIDAY$1 : MODERN_HOLIDAY$1 | IL_ONLY$1;
11749
+ const ev = new HolidayEvent(hd, h.desc, mask);
11750
+ if (!h.suppressEmoji) {
11751
+ ev.emoji = ISRAEL_FLAG;
11752
+ }
11753
+ events.push(ev);
11754
+ }
11755
+ }
11756
+ return events;
11757
+ }
12275
11758
 
11759
+ /*
11760
+ Hebcal - A Jewish Calendar Generator
11761
+ Copyright (c) 1994-2020 Danny Sadinoff
11762
+ Portions copyright Eyal Schachter and Michael J. Radwin
11763
+
11764
+ https://github.com/hebcal/hebcal-es6
11765
+
11766
+ This program is free software; you can redistribute it and/or
11767
+ modify it under the terms of the GNU General Public License
11768
+ as published by the Free Software Foundation; either version 2
11769
+ of the License, or (at your option) any later version.
11770
+
11771
+ This program is distributed in the hope that it will be useful,
11772
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11773
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11774
+ GNU General Public License for more details.
11775
+
11776
+ You should have received a copy of the GNU General Public License
11777
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
11778
+ */
11779
+ /*
11780
+ * Many of the following algorithms were taken from hebrew calendar
11781
+ * routines by Maimonedes, from his Mishneh Torah, and implemented by
11782
+ * Nachum Dershowitz Department of Computer Science
11783
+ * (217) 333-4219 University of Illinois at Urbana-Champaign
11784
+ * nachum@cs.uiuedu 1304 West Springfield Avenue
11785
+ * Urbana, Illinois 61801
11786
+ *
11787
+ * The routines were included in the emacs 19 distribution.
11788
+ *
11789
+ */
11790
+ const INCOMPLETE = 0;
11791
+ const REGULAR = 1;
11792
+ const COMPLETE = 2;
11793
+ function yearType(hyear) {
11794
+ const longC = HDate.longCheshvan(hyear);
11795
+ const shortK = HDate.shortKislev(hyear);
11796
+ if (longC && !shortK) {
11797
+ return COMPLETE;
11798
+ }
11799
+ if (!longC && shortK) {
11800
+ return INCOMPLETE;
11801
+ }
11802
+ return REGULAR;
11803
+ }
12276
11804
  /**
12277
- * Represents a built-in holiday like Pesach, Purim or Tu BiShvat.
11805
+ * Represents the weekly Torah-reading (Parashat HaShavua) schedule for an
11806
+ * entire Hebrew year.
12278
11807
  *
12279
- * Most holiday-related events emitted by {@link calendar}
12280
- * are instances of `HolidayEvent` or one of its subclasses
12281
- * ({@link ChanukahEvent}, {@link AsaraBTevetEvent},
12282
- * {@link RoshHashanaEvent}, {@link RoshChodeshEvent}).
11808
+ * The schedule depends on the year's *keviyah* — the day of week of Rosh
11809
+ * Hashana, whether the year is leap, whether Cheshvan/Kislev are long or
11810
+ * short, and whether the schedule is for Israel or the Diaspora (since
11811
+ * Israel and the Diaspora diverge in some years when the 8th day of Pesach
11812
+ * or the 2nd day of Shavuot fall on Shabbat).
12283
11813
  *
12284
- * Adds two notable behaviors over the base {@link Event}:
11814
+ * Prefer {@link getSedra} over
11815
+ * calling this constructor directly, since both cache their results.
12285
11816
  *
12286
- * - {@link HolidayEvent.basename} strips qualifiers like `Erev `, ` I`/`II`,
12287
- * `(CH''M)`, `(observed)`, candle counts, etc. (e.g. `"Erev Pesach"` →
12288
- * `"Pesach"`).
12289
- * - {@link HolidayEvent.url} returns a `https://www.hebcal.com/holidays/...`
12290
- * link for the holiday.
11817
+ * @example
11818
+ * import {Sedra, HDate, months} from '@hebcal/core';
11819
+ * const sedra = new Sedra(5784, false);
11820
+ * const result = sedra.lookup(new HDate(15, months.CHESHVAN, 5784));
11821
+ * console.log(result.parsha); // ['Vayera']
12291
11822
  */
12292
- class HolidayEvent extends Event {
12293
- constructor(date, desc, mask = 0, attrs) {
12294
- super(date, desc, mask, attrs);
12295
- if (typeof attrs === 'object' && attrs !== null) {
12296
- Object.assign(this, attrs);
11823
+ class Sedra {
11824
+ /**
11825
+ * Calculates the Parashat HaShavua schedule for an entire Hebrew year.
11826
+ * @param hyear - Hebrew year (e.g. 5749)
11827
+ * @param il - Use Israel sedra schedule (false for Diaspora)
11828
+ */
11829
+ constructor(hyear, il) {
11830
+ hyear = +hyear;
11831
+ this.year = hyear;
11832
+ const rh0 = new HDate(1, months.TISHREI, hyear);
11833
+ const rh = (this.rh = rh0.abs());
11834
+ const rhDay = rh0.getDay() + 1;
11835
+ // find the first Saturday on or after Rosh Hashana
11836
+ this.firstSaturday = HDate.dayOnOrBefore(6, rh + 6);
11837
+ const leap = +HDate.isLeapYear(hyear);
11838
+ this.il = Boolean(il);
11839
+ const type = yearType(hyear);
11840
+ let key = `${leap}${rhDay}${type}`;
11841
+ if (types[key]) {
11842
+ this.theSedraArray = types[key];
11843
+ this.yearKey = key;
11844
+ }
11845
+ else {
11846
+ key = key + +this.il; // cast to num, then concat
11847
+ this.theSedraArray = types[key];
11848
+ this.yearKey = key;
11849
+ }
11850
+ if (!this.theSedraArray) {
11851
+ throw new Error(`improper sedra year type ${key} calculated for ${hyear}`);
11852
+ }
11853
+ }
11854
+ /**
11855
+ * Returns the date a parsha is read this year, or `null` if it does not
11856
+ * occur in this year's schedule.
11857
+ *
11858
+ * A doubled parsha (e.g. `'Matot-Masei'`) will only return a date in years
11859
+ * where that pair is actually read together; in years where they are read
11860
+ * separately, this returns `null`. Use {@link findContaining} to find the
11861
+ * date a parsha is read regardless of whether it is doubled.
11862
+ *
11863
+ * Throws `RangeError` for an out-of-range numeric input or an invalid
11864
+ * doubled-parsha pair, and `TypeError` for a malformed array argument.
11865
+ * @example
11866
+ * import {Sedra} from '@hebcal/core';
11867
+ * const sedra = new Sedra(5784, false);
11868
+ * sedra.find('Noach')?.toString(); // '6 Cheshvan 5784'
11869
+ * sedra.find(1)?.toString(); // '6 Cheshvan 5784', by 0-based index
11870
+ * // Matot and Masei are doubled in 5784, so the pair has a date...
11871
+ * sedra.find('Matot-Masei')?.toString(); // '28 Tamuz 5784'
11872
+ * sedra.find(['Matot', 'Masei'])?.toString(); // '28 Tamuz 5784'
11873
+ * // ...but neither half is read on its own that year:
11874
+ * sedra.find('Matot'); // null
11875
+ * @param parsha if a `string`, specified with Sephardic transliterations
11876
+ * like `'Noach'` or `'Matot-Masei'`. If an array, must be a 1- or 2-element
11877
+ * array such as `['Noach']` or `['Matot', 'Masei']`. If a `number`, should
11878
+ * be a 0-based parsha index (`0` for Bereshit, `1` for Noach) or a negative
11879
+ * number for a doubled parsha (e.g. `-21` for Vayakhel-Pekudei).
11880
+ * Note that this index is 0-based, unlike {@link SedraResult.num} which
11881
+ * is 1-based.
11882
+ */
11883
+ find(parsha) {
11884
+ if (typeof parsha === 'number') {
11885
+ if (parsha >= parshiot.length || (parsha < 0 && !isValidDouble(parsha))) {
11886
+ throw new RangeError(`Invalid parsha number: ${parsha}`);
11887
+ }
11888
+ return this.findInternal(parsha);
11889
+ }
11890
+ if (typeof parsha === 'string') {
11891
+ const num = parsha2id.get(parsha);
11892
+ if (typeof num === 'number') {
11893
+ return this.find(num);
11894
+ }
11895
+ if (parsha.includes('-')) {
11896
+ if (parsha === CHMPESACH || parsha === CHMSUKOT) {
11897
+ return this.findInternal(parsha);
11898
+ }
11899
+ return this.find(parsha.split('-'));
11900
+ }
11901
+ // try to find Saturday holiday like 'Yom Kippur'
11902
+ return this.findInternal(parsha);
11903
+ }
11904
+ if (Array.isArray(parsha)) {
11905
+ const plen = parsha.length;
11906
+ if ((plen !== 1 && plen !== 2) || typeof parsha[0] !== 'string') {
11907
+ throw new TypeError(`Invalid parsha argument: ${JSON.stringify(parsha)}`);
11908
+ }
11909
+ if (plen === 1) {
11910
+ return this.find(parsha[0]);
11911
+ }
11912
+ const p1 = parsha[0];
11913
+ const p2 = parsha[1];
11914
+ const num1 = parsha2id.get(p1);
11915
+ const num2 = parsha2id.get(p2);
11916
+ if (typeof num1 !== 'number' ||
11917
+ typeof num2 !== 'number' ||
11918
+ num2 !== num1 + 1 ||
11919
+ !isValidDouble(-num1)) {
11920
+ throw new RangeError(`Unrecognized parsha name: ${p1}-${p2}`);
11921
+ }
11922
+ return this.find(-num1);
11923
+ }
11924
+ return null; /* NOTREACHED */
11925
+ }
11926
+ findInternal(parsha) {
11927
+ const idx = this.theSedraArray.indexOf(parsha);
11928
+ if (idx === -1) {
11929
+ return null; // doesn't occur this year
12297
11930
  }
11931
+ return new HDate(this.firstSaturday + idx * 7);
12298
11932
  }
12299
11933
  /**
12300
- * Returns a simplified (untranslated) name for this holiday, stripping
12301
- * qualifiers so that related events group under one name.
11934
+ * Returns the date a parsha is read this year, looking through both
11935
+ * single and doubled forms.
12302
11936
  *
12303
- * Strips trailing 4-digit years, `(CH''M)`, `(observed)`, `(Hoshana Raba)`,
12304
- * Roman-numeral day numbers (` I`, ` II`, ...), Chanukah candle counts,
12305
- * `: 8th Day`, and a leading `"Erev "`.
11937
+ * For example, if `'Matot'` is read individually this year, this returns
11938
+ * its date; if it is read as part of `'Matot-Masei'` this year, this
11939
+ * returns the date of `'Matot-Masei'` (and similarly for `'Masei'`).
11940
+ * Conversely, asking for `'Matot-Masei'` in a year where they are split
11941
+ * will return the date of `'Matot'` alone.
12306
11942
  * @example
12307
- * // 'Erev Pesach' => 'Pesach'
12308
- * // 'Sukkot III (CH''M)' => 'Sukkot'
12309
- * // 'Chanukah: 5 Candles' => 'Chanukah'
12310
- * // 'Rosh Hashana 5784' => 'Rosh Hashana'
11943
+ * import {Sedra} from '@hebcal/core';
11944
+ * // Matot and Masei are doubled in 5784, so each half resolves to the
11945
+ * // date of the combined reading:
11946
+ * const sedra = new Sedra(5784, false);
11947
+ * sedra.findContaining('Matot')?.toString(); // '28 Tamuz 5784'
11948
+ * sedra.findContaining('Masei')?.toString(); // '28 Tamuz 5784'
11949
+ * @example
11950
+ * import {Sedra} from '@hebcal/core';
11951
+ * // They are read separately in 5795, so each half has its own date, and
11952
+ * // asking for the doubled name returns the date of the first half:
11953
+ * const sedra = new Sedra(5795, false);
11954
+ * sedra.findContaining('Matot')?.toString(); // '21 Tamuz 5795'
11955
+ * sedra.findContaining('Masei')?.toString(); // '28 Tamuz 5795'
11956
+ * sedra.findContaining('Matot-Masei')?.toString(); // '21 Tamuz 5795'
12311
11957
  */
12312
- basename() {
12313
- return this.getDesc()
12314
- .replace(/ \d{4}$/, '')
12315
- .replace(/ \(CH''M\)$/, '')
12316
- .replace(/ \(observed\)$/, '')
12317
- .replace(/ \(Hoshana Raba\)$/, '')
12318
- .replace(/ [IV]+$/, '')
12319
- .replace(/: \d Candles?$/, '')
12320
- .replace(/: 8th Day$/, '')
12321
- .replace(/^Erev /, '');
11958
+ findContaining(parsha) {
11959
+ const hdate = this.find(parsha);
11960
+ if (hdate) {
11961
+ return hdate;
11962
+ }
11963
+ if (typeof parsha === 'number') {
11964
+ // a valid negative number (double parsha in a year where they are
11965
+ // combined) would've been found above, and a invalid negative number
11966
+ // would've thrown an error, so this parsha must be a positive number
11967
+ // representing either p1 or p2
11968
+ const p1 = -parsha;
11969
+ if (isValidDouble(p1)) {
11970
+ return this.find(p1);
11971
+ }
11972
+ else {
11973
+ // this must be the second individual parsha of a doubled pair
11974
+ // for example 29 for Kedoshim, so check for -28 for Achrei Mot-Kedoshim
11975
+ return this.find(p1 + 1);
11976
+ }
11977
+ }
11978
+ else {
11979
+ const num = parsha2id.get(parsha);
11980
+ if (num) {
11981
+ // parsha is either the first or second individual parsha of
11982
+ // a pair that is doubled this year
11983
+ const p1 = -num;
11984
+ if (isValidDouble(p1)) {
11985
+ return this.find(p1);
11986
+ }
11987
+ else {
11988
+ return this.find(p1 + 1);
11989
+ }
11990
+ }
11991
+ else {
11992
+ // this was indeed a doubled parsha, so return date of the first half
11993
+ const [p1] = parsha.split('-');
11994
+ return this.find(p1);
11995
+ }
11996
+ }
12322
11997
  }
12323
11998
  /**
12324
- * Returns a `https://www.hebcal.com/holidays/...` URL for more detail on
12325
- * this holiday. Israel-only holidays get an `?i=on` query parameter.
12326
- * Returns `undefined` for years outside `[100, 2999]`.
11999
+ * Returns the underlying annual reading schedule as an array, where each
12000
+ * entry corresponds to one Saturday (starting from the first Shabbat on
12001
+ * or after Rosh Hashana). Entries are either:
12002
+ * - a non-negative `number`: a 0-based parsha index (e.g. `0` for
12003
+ * *Bereshit*)
12004
+ * - a negative `number`: the negated first index of a doubled parsha
12005
+ * (e.g. `-21` for *Vayakhel-Pekudei*)
12006
+ * - a `string`: a holiday name when a Yom Tov displaces the weekly reading
12007
+ * (e.g. `'Pesach Shabbat Chol ha-Moed'`, `'Yom Kippur'`)
12008
+ *
12009
+ * Used by `@hebcal/triennial`.
12327
12010
  */
12328
- url() {
12329
- const year = this.greg().getFullYear();
12330
- if (year < 100 || year > 2999) {
12331
- return undefined;
12332
- }
12333
- const url = 'https://www.hebcal.com/holidays/' +
12334
- urlFriendly(this.basename()) +
12335
- '-' +
12336
- this.urlDateSuffix();
12337
- return this.hasFlag('IL_ONLY') ? url + '?i=on' : url;
12011
+ getSedraArray() {
12012
+ return this.theSedraArray;
12338
12013
  }
12339
12014
  /**
12340
- * The date portion of {@link url}. For most holidays this is just the
12341
- * Gregorian year; subclasses override it when a year alone is ambiguous.
12015
+ * Returns the R.D. (Rata Die / Fixed Date) absolute day number of the
12016
+ * first Saturday on or after Rosh Hashana of this year. This is the
12017
+ * anchor point for {@link getSedraArray} — index `0` of that array
12018
+ * corresponds to this date.
12342
12019
  */
12343
- urlDateSuffix() {
12344
- const year = this.greg().getFullYear();
12345
- return String(year);
12020
+ getFirstSaturday() {
12021
+ return this.firstSaturday;
12346
12022
  }
12347
- getEmoji() {
12348
- if (this.emoji) {
12349
- return this.emoji;
12023
+ /** Returns the Hebrew year this `Sedra` instance covers. */
12024
+ getYear() {
12025
+ return this.year;
12026
+ }
12027
+ /**
12028
+ * Returns details about the parsha read on the first Saturday on or after
12029
+ * `hd`. If `hd` is itself a Saturday, the reading for that date is
12030
+ * returned; otherwise the reading for the upcoming Saturday is returned.
12031
+ *
12032
+ * If the given date falls in the final days of the Hebrew year (after
12033
+ * the last reading of this year's schedule), this method transparently
12034
+ * delegates to the next year's `Sedra`.
12035
+ * @example
12036
+ * import {Sedra, HDate, months} from '@hebcal/core';
12037
+ * const sedra = new Sedra(5784, false);
12038
+ * // A Friday — returns the upcoming Shabbat's reading
12039
+ * const result = sedra.lookup(new HDate(12, months.CHESHVAN, 5784));
12040
+ * console.log(result.parsha); // ['Lech-Lecha']
12041
+ * console.log(result.chag); // false
12042
+ * console.log(result.hdate.toString()); // '13 Cheshvan 5784' (Saturday)
12043
+ * @param hd Hebrew date or R.D. days
12044
+ */
12045
+ lookup(hd) {
12046
+ const abs = toAbsInYear(hd, this.rh, this.year);
12047
+ // find the first saturday on or after today's date
12048
+ const saturday = HDate.dayOnOrBefore(6, abs + 6);
12049
+ const weekNum = (saturday - this.firstSaturday) / 7;
12050
+ const index = this.theSedraArray[weekNum];
12051
+ if (index === undefined) {
12052
+ const sedra = getSedra(this.year + 1, this.il);
12053
+ return sedra.lookup(saturday); // must be next year
12350
12054
  }
12351
- if (this.hasFlag('SPECIAL_SHABBAT')) {
12352
- return '🕍';
12055
+ const hdate = new HDate(saturday);
12056
+ if (typeof index === 'string') {
12057
+ // Shabbat has a chag. Return a description
12058
+ return { parsha: [index], chag: true, hdate, il: this.il, num: 0 };
12059
+ }
12060
+ if (index >= 0) {
12061
+ return {
12062
+ parsha: [parshiot[index]],
12063
+ chag: false,
12064
+ num: index + 1,
12065
+ hdate,
12066
+ il: this.il,
12067
+ };
12068
+ }
12069
+ const p1 = D(index); // undouble the parsha
12070
+ return {
12071
+ parsha: [parshiot[p1], parshiot[p1 + 1]],
12072
+ chag: false,
12073
+ num: [p1 + 1, p1 + 2],
12074
+ hdate,
12075
+ il: this.il,
12076
+ };
12077
+ }
12078
+ /**
12079
+ * Returns details about the parsha read on Monday or Thursday for `hd`, or
12080
+ * `undefined` if `hd` is not a Monday or Thursday.
12081
+ *
12082
+ * Weekday Torah readings generally begin the upcoming Shabbat parsha. When
12083
+ * the upcoming Shabbat is a holiday, this method returns the next regular
12084
+ * parsha instead.
12085
+ *
12086
+ * For the Tishrei weekdays before Sukkot or Simchat Torah, the weekday
12087
+ * reading is *Vezot Haberakhah* even though it is not read on Shabbat.
12088
+ * @example
12089
+ * import {Sedra, HDate, months} from '@hebcal/core';
12090
+ * const sedra = new Sedra(5784, false);
12091
+ * // Monday 8 Cheshvan — begins the upcoming Shabbat's parsha
12092
+ * sedra.lookupWeekday(new HDate(8, months.CHESHVAN, 5784))?.parsha; // ['Lech-Lecha']
12093
+ * // Tuesday is neither Monday nor Thursday
12094
+ * sedra.lookupWeekday(new HDate(9, months.CHESHVAN, 5784)); // undefined
12095
+ * // Thursday 17 Nisan — the upcoming Shabbat is Chol ha-Moed Pesach,
12096
+ * // so the next regular parsha is returned instead
12097
+ * sedra.lookupWeekday(new HDate(17, months.NISAN, 5784))?.parsha; // ['Achrei Mot']
12098
+ * @param hd Hebrew date or R.D. days
12099
+ */
12100
+ lookupWeekday(hd) {
12101
+ const abs = toAbsInYear(hd, this.rh, this.year);
12102
+ const hdate = new HDate(abs);
12103
+ const day = hdate.getDay();
12104
+ if (day !== 1 && day !== 4) {
12105
+ return undefined;
12106
+ }
12107
+ const saturday = new HDate(HDate.dayOnOrBefore(6, abs + 6));
12108
+ const parsha = this.lookup(saturday);
12109
+ if (!parsha.chag) {
12110
+ return parsha;
12353
12111
  }
12354
- return '✡️';
12112
+ return this.findWeekdayParsha(saturday);
12355
12113
  }
12356
- getCategories() {
12357
- if (this.cholHaMoedDay) {
12358
- return ['holiday', 'major', 'cholhamoed'];
12359
- }
12360
- const cats = super.getCategories();
12361
- if (cats[0] !== 'unknown') {
12362
- return cats;
12114
+ findWeekdayParsha(saturday) {
12115
+ const hyear = saturday.getFullYear();
12116
+ const il = this.il;
12117
+ if (saturday.getMonth() === months.TISHREI) {
12118
+ const dd = saturday.getDate();
12119
+ const simchatTorah = il ? 22 : 23;
12120
+ if (dd > 2 && dd <= simchatTorah) {
12121
+ return {
12122
+ parsha: ['Vezot Haberakhah'],
12123
+ chag: false,
12124
+ num: 54,
12125
+ hdate: saturday,
12126
+ il,
12127
+ };
12128
+ }
12363
12129
  }
12364
- // Don't depend on flags.MINOR_HOLIDAY always being set. Look for minor holidays.
12365
- const desc = this.getDesc();
12366
- switch (desc) {
12367
- case holidayDesc.LAG_BAOMER:
12368
- case holidayDesc.LEIL_SELICHOT:
12369
- case holidayDesc.PESACH_SHENI:
12370
- case holidayDesc.EREV_PURIM:
12371
- case holidayDesc.PURIM_KATAN:
12372
- case holidayDesc.SHUSHAN_PURIM:
12373
- case holidayDesc.TU_BAV:
12374
- case holidayDesc.TU_BISHVAT:
12375
- case holidayDesc.ROSH_HASHANA_LABEHEMOT:
12376
- return ['holiday', 'minor'];
12130
+ const sedra = hyear === this.year ? this : getSedra(hyear, il);
12131
+ const endOfYear = new HDate(1, months.TISHREI, hyear + 1).abs() - 1;
12132
+ const endAbs = endOfYear + 30;
12133
+ for (let sat2 = saturday.abs() + 7; sat2 <= endAbs; sat2 += 7) {
12134
+ const sedra2 = sat2 > endOfYear ? getSedra(hyear + 1, il) : sedra;
12135
+ const parsha2 = sedra2.lookup(sat2);
12136
+ if (!parsha2.chag) {
12137
+ return parsha2;
12138
+ }
12377
12139
  }
12378
- return ['holiday', 'major'];
12140
+ /* NOTREACHED */
12141
+ throw new Error(`can't find weekday parsha for ${saturday}/${il}`);
12379
12142
  }
12380
- /**
12381
- * Returns (translated) description of this event
12382
- * @param [locale] Optional locale name (defaults to empty locale)
12383
- */
12384
- render(locale) {
12385
- const str = super.render(locale);
12386
- return smartApostrophe(str);
12143
+ }
12144
+ /**
12145
+ * The 54 parshiyot of the Torah as transilterated strings.
12146
+ * * parshiot[0] == `Bereshit`
12147
+ * * parshiot[1] == `Noach`
12148
+ * * parshiot[52] == `Ha'azinu`
12149
+ * * parshiot[53] == `Vezot Haberakhah`
12150
+ */
12151
+ const parshiot = [
12152
+ 'Bereshit',
12153
+ 'Noach',
12154
+ 'Lech-Lecha',
12155
+ 'Vayera',
12156
+ 'Chayei Sara',
12157
+ 'Toldot',
12158
+ 'Vayetzei',
12159
+ 'Vayishlach',
12160
+ 'Vayeshev',
12161
+ 'Miketz',
12162
+ 'Vayigash',
12163
+ 'Vayechi',
12164
+ 'Shemot',
12165
+ 'Vaera',
12166
+ 'Bo',
12167
+ 'Beshalach',
12168
+ 'Yitro',
12169
+ 'Mishpatim',
12170
+ 'Terumah',
12171
+ 'Tetzaveh',
12172
+ 'Ki Tisa',
12173
+ 'Vayakhel',
12174
+ 'Pekudei',
12175
+ 'Vayikra',
12176
+ 'Tzav',
12177
+ 'Shmini',
12178
+ 'Tazria',
12179
+ 'Metzora',
12180
+ 'Achrei Mot',
12181
+ 'Kedoshim',
12182
+ 'Emor',
12183
+ 'Behar',
12184
+ 'Bechukotai',
12185
+ 'Bamidbar',
12186
+ 'Nasso',
12187
+ "Beha'alotcha",
12188
+ "Sh'lach",
12189
+ 'Korach',
12190
+ 'Chukat',
12191
+ 'Balak',
12192
+ 'Pinchas',
12193
+ 'Matot',
12194
+ 'Masei',
12195
+ 'Devarim',
12196
+ 'Vaetchanan',
12197
+ 'Eikev',
12198
+ "Re'eh",
12199
+ 'Shoftim',
12200
+ 'Ki Teitzei',
12201
+ 'Ki Tavo',
12202
+ 'Nitzavim',
12203
+ 'Vayeilech',
12204
+ "Ha'azinu",
12205
+ 'Vezot Haberakhah',
12206
+ ];
12207
+ /**
12208
+ * Converts a `Sedra.lookup*()` argument to R.D. days, validating that it is a
12209
+ * date on or after Rosh Hashana of `year` (whose R.D. day is `rh`)
12210
+ */
12211
+ function toAbsInYear(hd, rh, year) {
12212
+ const abs = typeof hd === 'number' ? hd : HDate.isHDate(hd) ? hd.abs() : NaN;
12213
+ if (isNaN(abs)) {
12214
+ throw new TypeError(`Bad date argument: ${hd}`);
12387
12215
  }
12388
- /**
12389
- * Returns a brief (translated) description of this event.
12390
- * For most events, this is the same as render(). For some events, it procudes
12391
- * a shorter text (e.g. without a time or added description).
12392
- * @param [locale] Optional locale name (defaults to empty locale)
12393
- */
12394
- renderBrief(locale) {
12395
- const str = super.renderBrief(locale);
12396
- return smartApostrophe(str);
12216
+ if (abs < rh) {
12217
+ throw new RangeError(`Date ${hd} before start of Hebrew year ${year}`);
12397
12218
  }
12219
+ return abs;
12398
12220
  }
12221
+ // 0-based parsha IDs
12222
+ const parsha2id = new Map(parshiot.map((name, id) => [name, id]));
12223
+ // 0-based parsha IDs
12224
+ const doubles = new Set([
12225
+ 21, // Vayakhel-Pekudei
12226
+ 26, // Tazria-Metzora
12227
+ 28, // Achrei Mot-Kedoshim
12228
+ 31, // Behar-Bechukotai
12229
+ 38, // Chukat-Balak
12230
+ 41, // Matot-Masei
12231
+ 50, // Nitzavim-Vayeilech
12232
+ ]);
12399
12233
  /**
12400
- * Because Asara B'Tevet often occurs twice in the same Gregorian year,
12401
- * we subclass HolidayEvent to generate the correct URL.
12234
+ * @param id a negative number
12402
12235
  */
12403
- class AsaraBTevetEvent extends HolidayEvent {
12404
- /** Full `YYYYMMDD` date, since the Gregorian year alone is ambiguous here */
12405
- urlDateSuffix() {
12406
- const isoDate = isoDateString(this.greg());
12407
- return isoDate.replaceAll('-', '');
12408
- }
12236
+ function isValidDouble(id) {
12237
+ return doubles.has(-id);
12409
12238
  }
12410
- const chanukahEmoji = '🕎';
12411
- const KEYCAP_DIGITS = [
12412
- '0️⃣',
12413
- '1️⃣',
12414
- '2️⃣',
12415
- '3️⃣',
12416
- '4️⃣',
12417
- '5️⃣',
12418
- '6️⃣',
12419
- '7️⃣',
12420
- '8️⃣',
12421
- '9️⃣',
12422
- ];
12423
12239
  /**
12424
- * Because Chanukah sometimes starts in December and ends in January,
12425
- * we subclass HolidayEvent to generate the correct URL.
12240
+ * parsha doubler/undoubler
12241
+ * @param p
12242
+ */
12243
+ function D(p) {
12244
+ return -p;
12245
+ }
12246
+ const RH = 'Rosh Hashana'; // 0
12247
+ const YK = 'Yom Kippur'; // 1
12248
+ const SUKKOT = 'Sukkot'; // 0
12249
+ const CHMSUKOT = 'Sukkot Shabbat Chol ha-Moed'; // 0
12250
+ const SHMINI = 'Shmini Atzeret'; // 0
12251
+ const PESACH = 'Pesach'; // 25
12252
+ const PESACH1 = 'Pesach I';
12253
+ const CHMPESACH = 'Pesach Shabbat Chol ha-Moed'; // 25
12254
+ const PESACH7 = 'Pesach VII'; // 25
12255
+ const PESACH8 = 'Pesach VIII';
12256
+ const SHAVUOT = 'Shavuot'; // 33
12257
+ /**
12258
+ * Returns an array from start to end
12259
+ * @param start beginning number, inclusive
12260
+ * @param stop ending number, inclusive
12261
+ */
12262
+ function range$1(start, stop) {
12263
+ return Array.from({ length: stop - start + 1 }, (_, k) => k + start);
12264
+ }
12265
+ const yearStartVayeilech = [51, 52, CHMSUKOT];
12266
+ const yearStartHaazinu = [52, YK, CHMSUKOT];
12267
+ const yearStartRH = [RH, 52, SUKKOT, SHMINI];
12268
+ const r020 = range$1(0, 20);
12269
+ const r027 = range$1(0, 27);
12270
+ const r3340 = range$1(33, 40);
12271
+ const r4349 = range$1(43, 49);
12272
+ const r4350 = range$1(43, 50);
12273
+ /**
12274
+ * The ordinary year types (keviot)
12275
+ * names are leap/nonleap - day - incomplete/regular/complete - diaspora/Israel
12276
+ */
12277
+ const types = {
12278
+ /* Hebrew year that starts on Monday, is `incomplete' (Heshvan and
12279
+ * Kislev each have 29 days), and has Passover start on Tuesday. */
12280
+ // e.g. 5753
12281
+ '020': yearStartVayeilech.concat(r020, D(21), 23, 24, CHMPESACH, 25, D(26), D(28), 30, D(31), r3340, D(41), r4349, D(50)),
12282
+ /* Hebrew year that starts on Monday, is `complete' (Heshvan and
12283
+ * Kislev each have 30 days), and has Passover start on Thursday. */
12284
+ // e.g. 5756
12285
+ '0220': yearStartVayeilech.concat(r020, D(21), 23, 24, CHMPESACH, 25, D(26), D(28), 30, D(31), 33, SHAVUOT, range$1(34, 37), D(38), 40, D(41), r4349, D(50)),
12286
+ /* Hebrew year that starts on Thursday, is `regular' (Heshvan has 29
12287
+ * days and Kislev has 30 days), and has Passover start on Saturday. */
12288
+ // e.g. 5701
12289
+ '0510': yearStartHaazinu.concat(r020, D(21), 23, 24, PESACH1, PESACH8, 25, D(26), D(28), 30, D(31), r3340, D(41), r4350),
12290
+ /* Hebrew year that starts on Thursday, is `regular' (Heshvan has 29
12291
+ * days and Kislev has 30 days), and has Passover start on Saturday. */
12292
+ // e.g. 5745
12293
+ '0511': yearStartHaazinu.concat(r020, D(21), 23, 24, PESACH, 25, D(26), D(28), range$1(30, 40), D(41), r4350),
12294
+ /* Hebrew year that starts on Thursday, is `complete' (Heshvan and
12295
+ * Kislev each have 30 days), and has Passover start on Sunday. */
12296
+ // e.g. 5754
12297
+ '052': yearStartHaazinu.concat(range$1(0, 24), PESACH7, 25, D(26), D(28), 30, D(31), r3340, D(41), r4350),
12298
+ /* Hebrew year that starts on Saturday, is `incomplete' (Heshvan and Kislev
12299
+ * each have 29 days), and has Passover start on Sunday. */
12300
+ // e.g. 5761
12301
+ '070': yearStartRH.concat(r020, D(21), 23, 24, PESACH7, 25, D(26), D(28), 30, D(31), r3340, D(41), r4350),
12302
+ /* Hebrew year that starts on Saturday, is `complete' (Heshvan and
12303
+ * Kislev each have 30 days), and has Passover start on Tuesday. */
12304
+ // e.g. 5716
12305
+ '072': yearStartRH.concat(r020, D(21), 23, 24, CHMPESACH, 25, D(26), D(28), 30, D(31), r3340, D(41), r4349, D(50)),
12306
+ /* -- The leap year types (keviot) -- */
12307
+ /* Hebrew year that starts on Monday, is `incomplete' (Heshvan and
12308
+ * Kislev each have 29 days), and has Passover start on Thursday. */
12309
+ // e.g. 5746
12310
+ '1200': yearStartVayeilech.concat(r027, CHMPESACH, range$1(28, 33), SHAVUOT, range$1(34, 37), D(38), 40, D(41), r4349, D(50)),
12311
+ /* Hebrew year that starts on Monday, is `incomplete' (Heshvan and
12312
+ * Kislev each have 29 days), and has Passover start on Thursday. */
12313
+ // e.g. 5746
12314
+ '1201': yearStartVayeilech.concat(r027, CHMPESACH, range$1(28, 40), D(41), r4349, D(50)),
12315
+ /* Hebrew year that starts on Monday, is `complete' (Heshvan and
12316
+ * Kislev each have 30 days), and has Passover start on Saturday. */
12317
+ // e.g.5752
12318
+ '1220': yearStartVayeilech.concat(r027, PESACH1, PESACH8, range$1(28, 40), D(41), r4350),
12319
+ /* Hebrew year that starts on Monday, is `complete' (Heshvan and
12320
+ * Kislev each have 30 days), and has Passover start on Saturday. */
12321
+ // e.g.5752
12322
+ '1221': yearStartVayeilech.concat(r027, PESACH, range$1(28, 50)),
12323
+ /* Hebrew year that starts on Thursday, is `incomplete' (Heshvan and
12324
+ * Kislev both have 29 days), and has Passover start on Sunday. */
12325
+ // e.g. 5768
12326
+ '150': yearStartHaazinu.concat(range$1(0, 28), PESACH7, range$1(29, 50)),
12327
+ /* Hebrew year that starts on Thursday, is `complete' (Heshvan and
12328
+ * Kislev both have 30 days), and has Passover start on Tuesday. */
12329
+ // eg. 5771
12330
+ '152': yearStartHaazinu.concat(range$1(0, 28), CHMPESACH, range$1(29, 49), D(50)),
12331
+ /* Hebrew year that starts on Saturday, is `incomplete' (Heshvan and
12332
+ * Kislev each have 29 days), and has Passover start on Tuesday. */
12333
+ // e.g.5757
12334
+ '170': yearStartRH.concat(r027, CHMPESACH, range$1(28, 40), D(41), r4349, D(50)),
12335
+ /* Hebrew year that starts on Saturday, is `complete' (Heshvan and
12336
+ * Kislev each have 30 days), and has Passover start on Thursday. */
12337
+ '1720': yearStartRH.concat(r027, CHMPESACH, range$1(28, 33), SHAVUOT, range$1(34, 37), D(38), 40, D(41), r4349, D(50)),
12338
+ };
12339
+ /* Hebrew year that starts on Monday, is `complete' (Heshvan and
12340
+ * Kislev each have 30 days), and has Passover start on Thursday. */
12341
+ types['0221'] = types['020'];
12342
+ /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
12343
+ * days and Kislev has 30 days), and has Passover start on Thursday. */
12344
+ // e.g. 5715
12345
+ types['0310'] = types['0220'];
12346
+ /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
12347
+ * days and Kislev has 30 days), and has Passover start on Thursday. */
12348
+ types['0311'] = types['020'];
12349
+ /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
12350
+ * days and Kislev has 30 days), and has Passover start on Saturday. */
12351
+ // e.g. 5715
12352
+ types['1310'] = types['1220'];
12353
+ /* Hebrew year that starts on Tuesday, is `regular' (Heshvan has 29
12354
+ * days and Kislev has 30 days), and has Passover start on Saturday. */
12355
+ types['1311'] = types['1221'];
12356
+ /* Hebrew year that starts on Saturday, is `complete' (Heshvan and
12357
+ * Kislev each have 30 days), and has Passover start on Thursday. */
12358
+ types['1721'] = types['170'];
12359
+ const sedraCache = new QuickLRU({ maxSize: 120 });
12360
+ /**
12361
+ * Convenience function to create an instance of {@link Sedra} or reuse a
12362
+ * previously created and cached instance for the same year and schedule.
12363
+ *
12364
+ * Prefer this over `new Sedra(...)` when calling repeatedly — an internal
12365
+ * LRU cache (~120 entries) avoids recomputing the keviyah-specific schedule.
12366
+ * @example
12367
+ * import {getSedra, HDate, months} from '@hebcal/core';
12368
+ * const sedra = getSedra(5784, false);
12369
+ * const {parsha} = sedra.lookup(new HDate(15, months.CHESHVAN, 5784));
12370
+ * console.log(parsha); // ['Vayera']
12371
+ * @param hyear Hebrew year
12372
+ * @param il Use Israel sedra schedule (`false` for Diaspora)
12426
12373
  */
12427
- class ChanukahEvent extends HolidayEvent {
12428
- /**
12429
- * @param chanukahDay should be undefined for 1st night of Chanukah
12430
- */
12431
- constructor(date, desc, mask, chanukahDay) {
12432
- super(date, desc, mask);
12433
- this.chanukahDay = chanukahDay;
12434
- this.emoji = chanukahEmoji;
12435
- if (chanukahDay !== 8) {
12436
- const candles = chanukahDay ? chanukahDay + 1 : 1;
12437
- this.emoji += KEYCAP_DIGITS[candles];
12438
- }
12439
- }
12440
- urlDateSuffix() {
12441
- const dt = this.greg();
12442
- let year = dt.getFullYear();
12443
- if (dt.getMonth() === 0) {
12444
- year--;
12445
- }
12446
- return String(year);
12447
- }
12448
- }
12449
- /** Represents Rosh Hashana, the Jewish New Year */
12450
- class RoshHashanaEvent extends HolidayEvent {
12451
- /**
12452
- * Normally created by {@link calendar} rather than directly.
12453
- * @param date Hebrew date event occurs
12454
- * @param hyear Hebrew year
12455
- * @param mask optional holiday flags
12456
- */
12457
- constructor(date, hyear, mask) {
12458
- super(date, `Rosh Hashana ${hyear}`, mask);
12459
- this.hyear = hyear;
12460
- }
12461
- /**
12462
- * Returns (translated) description of this event
12463
- * @param [locale] Optional locale name (defaults to empty locale)
12464
- */
12465
- render(locale) {
12466
- return Locale.gettext('Rosh Hashana', locale) + ' ' + this.hyear;
12467
- }
12468
- getEmoji() {
12469
- return '🍏🍯';
12470
- }
12471
- }
12472
- const roshChodeshStr = 'Rosh Chodesh';
12473
- /** Represents Rosh Chodesh, the beginning of a new month */
12474
- class RoshChodeshEvent extends HolidayEvent {
12475
- /**
12476
- * Constructs Rosh Chodesh event
12477
- * @param date Hebrew date event occurs
12478
- * @param monthName Hebrew month name (not translated)
12479
- */
12480
- constructor(date, monthName) {
12481
- super(date, `${roshChodeshStr} ${monthName}`, flags.ROSH_CHODESH);
12482
- }
12483
- /**
12484
- * Returns (translated) description of this event
12485
- * @param [locale] Optional locale name (defaults to empty locale)
12486
- */
12487
- render(locale) {
12488
- const monthName = this.getDesc().substring(roshChodeshStr.length + 1);
12489
- const monthName0 = Locale.gettext(monthName, locale);
12490
- const monthName1 = smartApostrophe(monthName0);
12491
- return Locale.gettext(roshChodeshStr, locale) + ' ' + monthName1;
12492
- }
12493
- basename() {
12494
- return this.getDesc();
12495
- }
12496
- getEmoji() {
12497
- return this.emoji || '🌒';
12374
+ function getSedra(hyear, il) {
12375
+ const cacheKey = `${hyear}-${il ? 1 : 0}`;
12376
+ let sedra = sedraCache.get(cacheKey);
12377
+ if (!sedra) {
12378
+ sedra = new Sedra(hyear, il);
12379
+ sedraCache.set(cacheKey, sedra);
12498
12380
  }
12381
+ return sedra;
12499
12382
  }
12500
12383
 
12501
12384
  const ykk = 'Yom Kippur Katan';
@@ -12521,7 +12404,7 @@ class YomKippurKatanEvent extends HolidayEvent {
12521
12404
  render(locale) {
12522
12405
  const monthName0 = Locale.gettext(this.nextMonthName, locale);
12523
12406
  const monthName = smartApostrophe(monthName0);
12524
- return Locale.gettext(ykk, locale) + ' ' + monthName;
12407
+ return `${Locale.gettext(ykk, locale)} ${monthName}`;
12525
12408
  }
12526
12409
  /**
12527
12410
  * @param [locale] Optional locale name (defaults to empty locale)
@@ -12578,74 +12461,34 @@ function getHolidaysOnDate(date, il) {
12578
12461
  if (il === undefined || events === undefined) {
12579
12462
  return events;
12580
12463
  }
12581
- const filtered = events.filter(ev => ev.observedIn(il));
12582
- return filtered;
12583
- }
12584
- const CHAG = flags.CHAG;
12585
- const IL_ONLY$1 = flags.IL_ONLY;
12586
- const LIGHT_CANDLES_TZEIS$2 = flags.LIGHT_CANDLES_TZEIS;
12587
- const CHANUKAH_CANDLES$1 = flags.CHANUKAH_CANDLES;
12588
- const BEHAB$1 = flags.BEHAB;
12589
- const MINOR_FAST$1 = flags.MINOR_FAST;
12590
- const SPECIAL_SHABBAT$1 = flags.SPECIAL_SHABBAT;
12591
- const MODERN_HOLIDAY$1 = flags.MODERN_HOLIDAY;
12592
- const MAJOR_FAST$1 = flags.MAJOR_FAST;
12593
- const MINOR_HOLIDAY$1 = flags.MINOR_HOLIDAY;
12594
- const EREV$1 = flags.EREV;
12464
+ return events.filter(ev => ev.observedIn(il));
12465
+ }
12466
+ const { CHAG, LIGHT_CANDLES_TZEIS: LIGHT_CANDLES_TZEIS$2, CHANUKAH_CANDLES: CHANUKAH_CANDLES$1, BEHAB: BEHAB$1, MINOR_FAST: MINOR_FAST$1, SPECIAL_SHABBAT: SPECIAL_SHABBAT$1, MAJOR_FAST: MAJOR_FAST$1, MINOR_HOLIDAY: MINOR_HOLIDAY$1, EREV: EREV$1, } = flags;
12595
12467
  const SUN = 0;
12596
12468
  const TUE = 2;
12597
12469
  const THU = 4;
12598
12470
  const FRI$1 = 5;
12599
12471
  const SAT$2 = 6;
12600
- const NISAN$2 = months.NISAN;
12601
- const IYYAR = months.IYYAR;
12602
- const TAMUZ$1 = months.TAMUZ;
12603
- const AV$1 = months.AV;
12604
- const TISHREI$1 = months.TISHREI;
12605
- const CHESHVAN = months.CHESHVAN;
12606
- const KISLEV = months.KISLEV;
12607
- const TEVET = months.TEVET;
12608
- const ADAR_I = months.ADAR_I;
12609
- const ADAR_II = months.ADAR_II;
12610
- const emojiIsraelFlag = { emoji: '🇮🇱' };
12472
+ const { NISAN: NISAN$2, IYYAR, TAMUZ: TAMUZ$1, AV: AV$1, TISHREI: TISHREI$1, CHESHVAN, KISLEV, TEVET, ADAR_I, ADAR_II } = months;
12611
12473
  const yearCache = new QuickLRU({ maxSize: 120 });
12612
- /**
12613
- * Lower-level holidays interface, which returns a `Map` of `Event`s indexed by
12614
- * `HDate.toString()`. These events must filtered especially for `flags.IL_ONLY`
12615
- * or `flags.CHUL_ONLY` depending on Israel vs. Diaspora holiday scheme.
12616
- * @private
12617
- */
12618
- function getHolidaysForYear_(year) {
12619
- if (typeof year !== 'number') {
12620
- throw new TypeError(`bad Hebrew year: ${year}`);
12621
- }
12622
- if (year < 1 || year > 32658) {
12623
- throw new RangeError(`Hebrew year ${year} out of range 1-32658`);
12624
- }
12625
- const cached = yearCache.get(year);
12626
- if (cached) {
12627
- return cached;
12628
- }
12629
- const RH = new HDate(1, TISHREI$1, year);
12630
- const pesach = new HDate(15, NISAN$2, year);
12631
- const map = new Map();
12632
- function add(...events) {
12633
- for (const ev of events) {
12634
- const key = ev.date.toString();
12635
- const arr = map.get(key);
12636
- if (typeof arr === 'object') {
12637
- if (arr[0].hasFlag('EREV')) {
12638
- arr.unshift(ev);
12639
- }
12640
- else {
12641
- arr.push(ev);
12642
- }
12474
+ function addToMap(map, ...events) {
12475
+ for (const ev of events) {
12476
+ const key = ev.date.toString();
12477
+ const arr = map.get(key);
12478
+ if (arr !== undefined) {
12479
+ if (arr[0].hasFlag('EREV')) {
12480
+ arr.unshift(ev);
12643
12481
  }
12644
12482
  else {
12645
- map.set(key, [ev]);
12483
+ arr.push(ev);
12646
12484
  }
12647
12485
  }
12486
+ else {
12487
+ map.set(key, [ev]);
12488
+ }
12648
12489
  }
12490
+ }
12491
+ function addStaticHolidays(map, year) {
12649
12492
  for (const h of staticHolidays) {
12650
12493
  const hd = new HDate(h.dd, h.mm, year);
12651
12494
  const attrs = {};
@@ -12653,81 +12496,58 @@ function getHolidaysForYear_(year) {
12653
12496
  attrs.emoji = h.emoji;
12654
12497
  if (h.chmDay)
12655
12498
  attrs.cholHaMoedDay = h.chmDay;
12656
- const ev = new HolidayEvent(hd, h.desc, h.flags, attrs);
12657
- add(ev);
12499
+ addToMap(map, new HolidayEvent(hd, h.desc, h.flags, attrs));
12658
12500
  }
12501
+ }
12502
+ function addTishreiHolidays(map, year, RH) {
12659
12503
  // standard holidays that don't shift based on year
12660
- add(new RoshHashanaEvent(RH, year, CHAG | LIGHT_CANDLES_TZEIS$2));
12661
- // Variable date holidays
12504
+ addToMap(map, new RoshHashanaEvent(RH, year, CHAG | LIGHT_CANDLES_TZEIS$2));
12662
12505
  const tzomGedaliahDay = RH.getDay() === THU ? 4 : 3;
12663
- add(new HolidayEvent(new HDate(tzomGedaliahDay, TISHREI$1, year), holidayDesc.TZOM_GEDALIAH, MINOR_FAST$1));
12506
+ addToMap(map, new HolidayEvent(new HDate(tzomGedaliahDay, TISHREI$1, year), holidayDesc.TZOM_GEDALIAH, MINOR_FAST$1),
12664
12507
  // first SAT after RH
12665
- add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, 7 + RH.abs())), holidayDesc.SHABBAT_SHUVA, SPECIAL_SHABBAT$1));
12508
+ new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, 7 + RH.abs())), holidayDesc.SHABBAT_SHUVA, SPECIAL_SHABBAT$1));
12509
+ }
12510
+ function addChanukahAndTevet(map, year) {
12666
12511
  const rchTevet = HDate.shortKislev(year)
12667
12512
  ? new HDate(1, TEVET, year)
12668
12513
  : new HDate(30, KISLEV, year);
12669
- add(new HolidayEvent(rchTevet, holidayDesc.CHAG_HABANOT, MINOR_HOLIDAY$1));
12670
- add(new ChanukahEvent(new HDate(24, KISLEV, year), holidayDesc.CHANUKAH_1_CANDLE, EREV$1 | MINOR_HOLIDAY$1 | CHANUKAH_CANDLES$1, undefined));
12514
+ addToMap(map, new HolidayEvent(rchTevet, holidayDesc.CHAG_HABANOT, MINOR_HOLIDAY$1), new ChanukahEvent(new HDate(24, KISLEV, year), holidayDesc.CHANUKAH_1_CANDLE, EREV$1 | MINOR_HOLIDAY$1 | CHANUKAH_CANDLES$1, undefined));
12671
12515
  // yes, we know Kislev 30-32 are wrong
12672
12516
  // HDate() corrects the month automatically
12673
12517
  for (let candles = 2; candles <= 8; candles++) {
12674
12518
  const hd = new HDate(23 + candles, KISLEV, year);
12675
- add(new ChanukahEvent(hd, `Chanukah: ${candles} Candles`, MINOR_HOLIDAY$1 | CHANUKAH_CANDLES$1, candles - 1));
12519
+ addToMap(map, new ChanukahEvent(hd, `Chanukah: ${candles} Candles`, MINOR_HOLIDAY$1 | CHANUKAH_CANDLES$1, candles - 1));
12676
12520
  }
12677
- add(new ChanukahEvent(new HDate(32, KISLEV, year), holidayDesc.CHANUKAH_8TH_DAY, MINOR_HOLIDAY$1, 8));
12678
- add(new AsaraBTevetEvent(new HDate(10, TEVET, year), holidayDesc.ASARA_BTEVET, MINOR_FAST$1));
12521
+ addToMap(map, new ChanukahEvent(new HDate(32, KISLEV, year), holidayDesc.CHANUKAH_8TH_DAY, MINOR_HOLIDAY$1, 8), new AsaraBTevetEvent(new HDate(10, TEVET, year), holidayDesc.ASARA_BTEVET, MINOR_FAST$1));
12522
+ }
12523
+ function addPesachSeasonHolidays(map, year, pesach) {
12679
12524
  const pesachAbs = pesach.abs();
12680
- add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, pesachAbs - 43)), holidayDesc.SHABBAT_SHEKALIM, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, pesachAbs - 30)), holidayDesc.SHABBAT_ZACHOR, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(pesachAbs - (pesach.getDay() === TUE ? 33 : 31)), holidayDesc.TAANIT_ESTHER, MINOR_FAST$1));
12681
12525
  const haChodeshAbs = HDate.dayOnOrBefore(SAT$2, pesachAbs - 14);
12682
- add(new HolidayEvent(new HDate(haChodeshAbs - 7), holidayDesc.SHABBAT_PARAH, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(haChodeshAbs), holidayDesc.SHABBAT_HACHODESH, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, pesachAbs - 1)), holidayDesc.SHABBAT_HAGADOL, SPECIAL_SHABBAT$1), new HolidayEvent(
12526
+ addToMap(map, new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, pesachAbs - 43)), holidayDesc.SHABBAT_SHEKALIM, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, pesachAbs - 30)), holidayDesc.SHABBAT_ZACHOR, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(pesachAbs - (pesach.getDay() === TUE ? 33 : 31)), holidayDesc.TAANIT_ESTHER, MINOR_FAST$1), new HolidayEvent(new HDate(haChodeshAbs - 7), holidayDesc.SHABBAT_PARAH, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(haChodeshAbs), holidayDesc.SHABBAT_HACHODESH, SPECIAL_SHABBAT$1), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, pesachAbs - 1)), holidayDesc.SHABBAT_HAGADOL, SPECIAL_SHABBAT$1), new HolidayEvent(
12683
12527
  // if the fast falls on Shabbat, move to Thursday
12684
12528
  pesach.prev().getDay() === SAT$2
12685
12529
  ? pesach.onOrBefore(THU)
12686
12530
  : new HDate(14, NISAN$2, year), holidayDesc.TAANIT_BECHOROT, MINOR_FAST$1));
12687
- add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, new HDate(1, TISHREI$1, year + 1).abs() - 4)), holidayDesc.LEIL_SELICHOT, MINOR_HOLIDAY$1, { emoji: '🕍' }));
12531
+ }
12532
+ function addLeilSelichot(map, year) {
12533
+ addToMap(map, new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, new HDate(1, TISHREI$1, year + 1).abs() - 4)), holidayDesc.LEIL_SELICHOT, MINOR_HOLIDAY$1, { emoji: '🕍' }));
12534
+ }
12535
+ function addPurimVariants(map, year, pesach) {
12688
12536
  if (pesach.getDay() === SUN) {
12689
- add(new HolidayEvent(new HDate(16, ADAR_II, year), holidayDesc.PURIM_MESHULASH, MINOR_HOLIDAY$1));
12537
+ addToMap(map, new HolidayEvent(new HDate(16, ADAR_II, year), holidayDesc.PURIM_MESHULASH, MINOR_HOLIDAY$1));
12690
12538
  }
12691
12539
  if (HDate.isLeapYear(year)) {
12692
- add(new HolidayEvent(new HDate(14, ADAR_I, year), holidayDesc.PURIM_KATAN, MINOR_HOLIDAY$1, { emoji: '🎭️' }));
12693
- add(new HolidayEvent(new HDate(15, ADAR_I, year), holidayDesc.SHUSHAN_PURIM_KATAN, MINOR_HOLIDAY$1, { emoji: '🎭️' }));
12694
- }
12695
- const nisan27dt = dateYomHaShoah(year);
12696
- if (nisan27dt) {
12697
- add(new HolidayEvent(nisan27dt, holidayDesc.YOM_HASHOAH, MODERN_HOLIDAY$1));
12698
- }
12699
- const yomHaZikaronDt = dateYomHaZikaron(year);
12700
- if (yomHaZikaronDt) {
12701
- add(new HolidayEvent(yomHaZikaronDt, holidayDesc.YOM_HAZIKARON, MODERN_HOLIDAY$1, emojiIsraelFlag), new HolidayEvent(yomHaZikaronDt.next(), holidayDesc.YOM_HAATZMA_UT, MODERN_HOLIDAY$1, emojiIsraelFlag));
12702
- }
12703
- for (const h of staticModernHolidays) {
12704
- if (year >= h.firstYear) {
12705
- let hd = new HDate(h.dd, h.mm, year);
12706
- const dow = hd.getDay();
12707
- if (h.friSatMovetoThu && (dow === FRI$1 || dow === SAT$2)) {
12708
- hd = hd.onOrBefore(THU);
12709
- }
12710
- else if (h.friPostponeToSun && dow === FRI$1) {
12711
- hd = new HDate(hd.abs() + 2);
12712
- }
12713
- else if (h.satPostponeToSun && dow === SAT$2) {
12714
- hd = hd.next();
12715
- }
12716
- const mask = h.chul ? MODERN_HOLIDAY$1 : MODERN_HOLIDAY$1 | IL_ONLY$1;
12717
- const ev = new HolidayEvent(hd, h.desc, mask);
12718
- if (!h.suppressEmoji) {
12719
- ev.emoji = '🇮🇱';
12720
- }
12721
- add(ev);
12722
- }
12540
+ addToMap(map, new HolidayEvent(new HDate(14, ADAR_I, year), holidayDesc.PURIM_KATAN, MINOR_HOLIDAY$1, { emoji: '🎭️' }), new HolidayEvent(new HDate(15, ADAR_I, year), holidayDesc.SHUSHAN_PURIM_KATAN, MINOR_HOLIDAY$1, { emoji: '🎭️' }));
12723
12541
  }
12542
+ }
12543
+ function addSummerFasts(map, year) {
12724
12544
  let tamuz17 = new HDate(17, TAMUZ$1, year);
12725
12545
  let tamuz17attrs;
12726
12546
  if (tamuz17.getDay() === SAT$2) {
12727
12547
  tamuz17 = new HDate(18, TAMUZ$1, year);
12728
12548
  tamuz17attrs = { observed: true };
12729
12549
  }
12730
- add(new HolidayEvent(tamuz17, holidayDesc.TZOM_TAMMUZ, MINOR_FAST$1, tamuz17attrs));
12550
+ addToMap(map, new HolidayEvent(tamuz17, holidayDesc.TZOM_TAMMUZ, MINOR_FAST$1, tamuz17attrs));
12731
12551
  let av9dt = new HDate(9, AV$1, year);
12732
12552
  let av9title = holidayDesc.TISHA_BAV;
12733
12553
  let av9attrs;
@@ -12737,30 +12557,35 @@ function getHolidaysForYear_(year) {
12737
12557
  av9title += ' (observed)';
12738
12558
  }
12739
12559
  const av9abs = av9dt.abs();
12740
- add(new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, av9abs)), holidayDesc.SHABBAT_CHAZON, SPECIAL_SHABBAT$1), new HolidayEvent(av9dt.prev(), holidayDesc.EREV_TISHA_BAV, EREV$1 | MAJOR_FAST$1, av9attrs), new HolidayEvent(av9dt, av9title, MAJOR_FAST$1, av9attrs), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, av9abs + 7)), holidayDesc.SHABBAT_NACHAMU, SPECIAL_SHABBAT$1));
12560
+ addToMap(map, new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, av9abs)), holidayDesc.SHABBAT_CHAZON, SPECIAL_SHABBAT$1), new HolidayEvent(av9dt.prev(), holidayDesc.EREV_TISHA_BAV, EREV$1 | MAJOR_FAST$1, av9attrs), new HolidayEvent(av9dt, av9title, MAJOR_FAST$1, av9attrs), new HolidayEvent(new HDate(HDate.dayOnOrBefore(SAT$2, av9abs + 7)), holidayDesc.SHABBAT_NACHAMU, SPECIAL_SHABBAT$1));
12561
+ }
12562
+ function daysInPreviousMonth(month, year) {
12563
+ return month === NISAN$2
12564
+ ? HDate.daysInMonth(HDate.monthsInYear(year - 1), year - 1)
12565
+ : HDate.daysInMonth(month - 1, year);
12566
+ }
12567
+ function addRoshChodesh(map, year) {
12741
12568
  const monthsInYear = HDate.monthsInYear(year);
12742
12569
  for (let month = 1; month <= monthsInYear; month++) {
12743
12570
  const monthName = HDate.getMonthName(month, year);
12744
- if ((month === NISAN$2
12745
- ? HDate.daysInMonth(HDate.monthsInYear(year - 1), year - 1)
12746
- : HDate.daysInMonth(month - 1, year)) === 30) {
12747
- add(new RoshChodeshEvent(new HDate(1, month, year), monthName));
12748
- add(new RoshChodeshEvent(new HDate(30, month - 1, year), monthName));
12571
+ if (daysInPreviousMonth(month, year) === 30) {
12572
+ addToMap(map, new RoshChodeshEvent(new HDate(1, month, year), monthName));
12573
+ addToMap(map, new RoshChodeshEvent(new HDate(30, month - 1, year), monthName));
12749
12574
  }
12750
12575
  else if (month !== TISHREI$1) {
12751
- add(new RoshChodeshEvent(new HDate(1, month, year), monthName));
12576
+ addToMap(map, new RoshChodeshEvent(new HDate(1, month, year), monthName));
12752
12577
  }
12753
12578
  }
12754
- // Begin: Yom Kippur Katan
12579
+ }
12580
+ function addYomKippurKatan(map, year) {
12581
+ const monthsInYear = HDate.monthsInYear(year);
12755
12582
  // start at Iyyar because one may not fast during Nisan
12756
- for (let month = months.IYYAR; month <= monthsInYear; month++) {
12583
+ for (let month = IYYAR; month <= monthsInYear; month++) {
12757
12584
  const nextMonth = month + 1;
12758
12585
  // Yom Kippur Katan is not observed on the day before Rosh Hashanah.
12759
12586
  // Not observed prior to Rosh Chodesh Cheshvan because Yom Kippur has just passed.
12760
12587
  // Not observed before Rosh Chodesh Tevet, because that day is Hanukkah.
12761
- if (nextMonth === TISHREI$1 ||
12762
- nextMonth === months.CHESHVAN ||
12763
- nextMonth === TEVET) {
12588
+ if (nextMonth === TISHREI$1 || nextMonth === CHESHVAN || nextMonth === TEVET) {
12764
12589
  continue;
12765
12590
  }
12766
12591
  let ykk = new HDate(29, month, year);
@@ -12769,9 +12594,10 @@ function getHolidaysForYear_(year) {
12769
12594
  ykk = ykk.onOrBefore(THU);
12770
12595
  }
12771
12596
  const nextMonthName = HDate.getMonthName(nextMonth, year);
12772
- const ev = new YomKippurKatanEvent(ykk, nextMonthName);
12773
- add(ev);
12597
+ addToMap(map, new YomKippurKatanEvent(ykk, nextMonthName));
12774
12598
  }
12599
+ }
12600
+ function addBehab(map, year) {
12775
12601
  for (const month of [CHESHVAN, IYYAR]) {
12776
12602
  const roshChodesh = new HDate(1, month, year);
12777
12603
  let shabbos = new HDate(HDate.dayOnOrBefore(SAT$2, roshChodesh.abs() + 6));
@@ -12783,21 +12609,60 @@ function getHolidaysForYear_(year) {
12783
12609
  fastDays[2] = new HDate(17, IYYAR, year);
12784
12610
  }
12785
12611
  for (const hd of fastDays) {
12786
- add(new HolidayEvent(hd, holidayDesc.TAANIT_BEHAB, MINOR_FAST$1 | BEHAB$1));
12612
+ addToMap(map, new HolidayEvent(hd, holidayDesc.TAANIT_BEHAB, MINOR_FAST$1 | BEHAB$1));
12787
12613
  }
12788
12614
  }
12615
+ }
12616
+ /**
12617
+ * Lower-level holidays interface, which returns a `Map` of `Event`s indexed by
12618
+ * `HDate.toString()`. These events must filtered especially for `flags.IL_ONLY`
12619
+ * or `flags.CHUL_ONLY` depending on Israel vs. Diaspora holiday scheme.
12620
+ * @internal
12621
+ */
12622
+ function getHolidaysForYear_(year) {
12623
+ if (typeof year !== 'number') {
12624
+ throw new TypeError(`bad Hebrew year: ${year}`);
12625
+ }
12626
+ if (year < 1 || year > 32658) {
12627
+ throw new RangeError(`Hebrew year ${year} out of range 1-32658`);
12628
+ }
12629
+ const cached = yearCache.get(year);
12630
+ if (cached) {
12631
+ return cached;
12632
+ }
12633
+ const RH = new HDate(1, TISHREI$1, year);
12634
+ const pesach = new HDate(15, NISAN$2, year);
12635
+ const map = new Map();
12636
+ addStaticHolidays(map, year);
12637
+ addTishreiHolidays(map, year, RH);
12638
+ addChanukahAndTevet(map, year);
12639
+ addPesachSeasonHolidays(map, year, pesach);
12640
+ addLeilSelichot(map, year);
12641
+ addPurimVariants(map, year, pesach);
12642
+ addToMap(map, ...modernHolidaysForYear(year));
12643
+ addSummerFasts(map, year);
12644
+ addRoshChodesh(map, year);
12645
+ addYomKippurKatan(map, year);
12646
+ addBehab(map, year);
12789
12647
  const sedra = getSedra(year, false);
12790
12648
  const beshalachHd = sedra.find(15);
12791
- add(new HolidayEvent(beshalachHd, holidayDesc.SHABBAT_SHIRAH, SPECIAL_SHABBAT$1));
12649
+ if (beshalachHd === null) {
12650
+ throw new Error(`Parashat Beshalach not found in year ${year}`);
12651
+ }
12652
+ addToMap(map, new HolidayEvent(beshalachHd, holidayDesc.SHABBAT_SHIRAH, SPECIAL_SHABBAT$1));
12792
12653
  // Birkat Hachamah appears only once every 28 years
12793
12654
  const birkatHaChama = getBirkatHaChama(year);
12794
- if (birkatHaChama) {
12655
+ if (birkatHaChama !== undefined) {
12795
12656
  const hd = new HDate(birkatHaChama);
12796
- add(new HolidayEvent(hd, holidayDesc.BIRKAT_HACHAMAH, MINOR_HOLIDAY$1, { emoji: '☀️' }));
12657
+ addToMap(map, new HolidayEvent(hd, holidayDesc.BIRKAT_HACHAMAH, MINOR_HOLIDAY$1, { emoji: '☀️' }));
12797
12658
  }
12798
12659
  yearCache.set(year, map);
12799
12660
  return map;
12800
12661
  }
12662
+ /** 28 years of 365.25 days */
12663
+ const BIRKAT_HACHAMAH_CYCLE_DAYS = 10227;
12664
+ const BIRKAT_HACHAMAH_EPOCH_OFFSET = 1373429;
12665
+ const BIRKAT_HACHAMAH_REMAINDER = 172;
12801
12666
  /**
12802
12667
  * Birkat Hachamah appears only once every 28 years.
12803
12668
  * Although almost always in Nisan, it can occur in Adar II.
@@ -12806,7 +12671,6 @@ function getHolidaysForYear_(year) {
12806
12671
  *
12807
12672
  * Due to drift, this will eventually slip into Iyyar
12808
12673
  * - 2 Iyyar 7141 (Gregorian year 3381)
12809
- * @private
12810
12674
  */
12811
12675
  function getBirkatHaChama(year) {
12812
12676
  const leap = HDate.isLeapYear(year);
@@ -12815,12 +12679,12 @@ function getBirkatHaChama(year) {
12815
12679
  const baseRd = HDate.hebrew2abs(year, startMonth, startDay);
12816
12680
  for (let day = 0; day <= 40; day++) {
12817
12681
  const abs = baseRd + day;
12818
- const elapsed = abs + 1373429;
12819
- if (elapsed % 10227 === 172) {
12682
+ const elapsed = abs + BIRKAT_HACHAMAH_EPOCH_OFFSET;
12683
+ if (elapsed % BIRKAT_HACHAMAH_CYCLE_DAYS === BIRKAT_HACHAMAH_REMAINDER) {
12820
12684
  return abs;
12821
12685
  }
12822
12686
  }
12823
- return 0;
12687
+ return undefined;
12824
12688
  }
12825
12689
  /**
12826
12690
  * Returns a sorted array of holidays observed during the given Hebrew year,
@@ -12840,27 +12704,20 @@ function getHolidaysForYearArray(year, il) {
12840
12704
  const yearMap = getHolidaysForYear_(year);
12841
12705
  const startAbs = HDate.hebrew2abs(year, TISHREI$1, 1);
12842
12706
  const endAbs = HDate.hebrew2abs(year + 1, TISHREI$1, 1) - 1;
12843
- let events = [];
12707
+ const events = [];
12844
12708
  for (let absDt = startAbs; absDt <= endAbs; absDt++) {
12845
12709
  const hd = new HDate(absDt);
12846
12710
  const holidays = yearMap.get(hd.toString());
12847
12711
  if (holidays) {
12848
- const filtered = holidays.filter(ev => ev.observedIn(il));
12849
- events = events.concat(filtered);
12712
+ events.push(...holidays.filter(ev => ev.observedIn(il)));
12850
12713
  }
12851
12714
  }
12852
12715
  return events;
12853
12716
  }
12854
12717
 
12855
12718
  function isTomorrowShabbosOrYomTov(dow, events) {
12856
- if (dow === 5) {
12857
- return true;
12858
- }
12859
- const erev = events.find(ev => ev.hasAnyFlag('LIGHT_CANDLES', 'LIGHT_CANDLES_TZEIS'));
12860
- if (erev) {
12861
- return true;
12862
- }
12863
- return false;
12719
+ return (dow === 5 ||
12720
+ events.some(ev => ev.hasAnyFlag('LIGHT_CANDLES', 'LIGHT_CANDLES_TZEIS')));
12864
12721
  }
12865
12722
  /**
12866
12723
  * Returns true if it is _Shabbos_ or if it is a _Yom Tov_ day that has a
@@ -12871,14 +12728,7 @@ function isTomorrowShabbosOrYomTov(dow, events) {
12871
12728
  * @return `true` if the day is a _Yom Tov_ that is _assur bemlacha_, or _Shabbos_
12872
12729
  */
12873
12730
  function isTodayAssurBemelacha(dow, events) {
12874
- if (dow === 6) {
12875
- return true;
12876
- }
12877
- const chag = events.find(ev => ev.hasFlag('CHAG'));
12878
- if (chag) {
12879
- return true;
12880
- }
12881
- return false;
12731
+ return dow === 6 || events.some(ev => ev.hasFlag('CHAG'));
12882
12732
  }
12883
12733
  /**
12884
12734
  * Returns `true` if the given moment (date + time) falls within a period
@@ -12928,7 +12778,7 @@ function isAssurBemlacha(currentTime, location, useElevation) {
12928
12778
  const il = location.getIsrael();
12929
12779
  const currentMillis = currentTime.getTime();
12930
12780
  const dow = hd.getDay();
12931
- const events = getHolidaysOnDate(hd, il) || [];
12781
+ const events = getHolidaysOnDate(hd, il) ?? [];
12932
12782
  if (isTomorrowShabbosOrYomTov(dow, events) && currentMillis >= sunsetMillis) {
12933
12783
  return true;
12934
12784
  }
@@ -12941,10 +12791,7 @@ function isAssurBemlacha(currentTime, location, useElevation) {
12941
12791
  return false;
12942
12792
  }
12943
12793
 
12944
- const NISAN$1 = months.NISAN;
12945
- const SIVAN$1 = months.SIVAN;
12946
- const TAMUZ = months.TAMUZ;
12947
- const AV = months.AV;
12794
+ const { NISAN: NISAN$1, SIVAN: SIVAN$1, TAMUZ, AV } = months;
12948
12795
  const SAT$1 = 6;
12949
12796
  function getHDate(date) {
12950
12797
  return HDate.isHDate(date) ? date : new HDate(date);
@@ -13009,13 +12856,11 @@ function isAveilut(date) {
13009
12856
  * @return `true` if the date is a major or minor fast day
13010
12857
  */
13011
12858
  function isFastDay(date, il) {
13012
- const events = getHolidaysOnDate(date, il) || [];
13013
- const fastDay = events.find(ev => ev.hasAnyFlag('MAJOR_FAST', 'MINOR_FAST') && !ev.hasFlag('EREV'));
13014
- return Boolean(fastDay);
12859
+ const events = getHolidaysOnDate(date, il) ?? [];
12860
+ return events.some(ev => ev.hasAnyFlag('MAJOR_FAST', 'MINOR_FAST') && !ev.hasFlag('EREV'));
13015
12861
  }
13016
12862
 
13017
- const HAVDALAH = holidayDesc.HAVDALAH;
13018
- const CANDLE_LIGHTING = holidayDesc.CANDLE_LIGHTING;
12863
+ const { HAVDALAH, CANDLE_LIGHTING } = holidayDesc;
13019
12864
  /**
13020
12865
  * Base class for events that have an associated wall-clock time and
13021
12866
  * geographic location — for example, candle lighting, havdalah, and
@@ -13053,7 +12898,7 @@ class TimedEvent extends Event {
13053
12898
  * @param [locale] Optional locale name (defaults to empty locale)
13054
12899
  */
13055
12900
  render(locale) {
13056
- return Locale.gettext(this.getDesc(), locale) + ': ' + this.fmtTime;
12901
+ return `${Locale.gettext(this.getDesc(), locale)}: ${this.fmtTime}`;
13057
12902
  }
13058
12903
  /**
13059
12904
  * Returns translation of "Candle lighting" without the time.
@@ -13121,7 +12966,7 @@ class HavdalahEvent extends TimedEvent {
13121
12966
  * @param [locale] Optional locale name (defaults to empty locale)
13122
12967
  */
13123
12968
  render(locale) {
13124
- return this.renderBrief(locale) + ': ' + this.fmtTime;
12969
+ return `${this.renderBrief(locale)}: ${this.fmtTime}`;
13125
12970
  }
13126
12971
  /**
13127
12972
  * Returns translation of "Havdalah" without the time.
@@ -13140,11 +12985,9 @@ class HavdalahEvent extends TimedEvent {
13140
12985
  }
13141
12986
  }
13142
12987
 
13143
- const LIGHT_CANDLES$1 = flags.LIGHT_CANDLES;
13144
- const LIGHT_CANDLES_TZEIS$1 = flags.LIGHT_CANDLES_TZEIS;
13145
- /**
13146
- * @private
13147
- */
12988
+ const { LIGHT_CANDLES: LIGHT_CANDLES$1, LIGHT_CANDLES_TZEIS: LIGHT_CANDLES_TZEIS$1 } = flags;
12989
+ const { FAST_BEGINS, FAST_ENDS } = holidayDesc;
12990
+ /** @internal */
13148
12991
  function makeCandleEvent(ev, hd, options, isFriday, isSaturday) {
13149
12992
  let havdalahTitle = false;
13150
12993
  let useHavdalahOffset = isSaturday;
@@ -13186,36 +13029,29 @@ function makeCandleEvent(ev, hd, options, isFriday, isSaturday) {
13186
13029
  return new CandleLightingEvent(hd, mask, time, location, ev, options);
13187
13030
  }
13188
13031
  }
13189
- const FAST_BEGINS = holidayDesc.FAST_BEGINS;
13190
- const FAST_ENDS = holidayDesc.FAST_ENDS;
13191
13032
  /**
13192
13033
  * Tzeit HaKochavim as calculated by Rabbi Yechiel Michel Tucazinsky,
13193
13034
  * 6.45° below geometric zenith. Default end time for Tish'a B'Av.
13194
- * @private
13195
13035
  */
13196
13036
  const TZEIT_TUCAZINSKY = 6.45;
13197
13037
  /**
13198
13038
  * Observation of 3 medium-sized stars, 7.0833333° below geometric zenith.
13199
13039
  * Default end time for minor fasts in the Diaspora.
13200
- * @private
13201
13040
  */
13202
13041
  const TZEIT_3MEDIUM_STARS = 7.0833333;
13203
13042
  /**
13204
13043
  * Minutes after sunset that minor fasts (including Yom Kippur Katan) end in
13205
13044
  * Israel by default, following Rabbi Deblitzky's practice.
13206
13045
  * @see {https://www.yeshiva.org.il/calendar/timeprinciples}
13207
- * @private
13208
13046
  */
13209
13047
  const MINOR_FAST_END_MINUTES_IL = 15;
13210
13048
  /**
13211
13049
  * Alot HaShachar, 16.1° below geometric zenith.
13212
13050
  * Default start time for minor fasts.
13213
- * @private
13214
13051
  */
13215
13052
  const ALOT_16_POINT_1 = 16.1;
13216
13053
  /**
13217
13054
  * Returns `val` when it is a finite nonzero number, otherwise `undefined`
13218
- * @private
13219
13055
  */
13220
13056
  function nonzero(val) {
13221
13057
  return typeof val === 'number' && isFinite(val) && val !== 0 ? val : undefined;
@@ -13227,7 +13063,6 @@ function nonzero(val) {
13227
13063
  * minutes before sunrise; otherwise, when `options.fastStartDeg` is a nonzero
13228
13064
  * number, the fast begins when the sun is that many degrees below the horizon
13229
13065
  * in the morning. By default, minor fasts begin at Alot HaShachar (16.1°).
13230
- * @private
13231
13066
  */
13232
13067
  function makeFastStartTime(zmanim, options) {
13233
13068
  const fastStartMins = nonzero(options.fastStartMins);
@@ -13251,7 +13086,6 @@ function makeFastStartTime(zmanim, options) {
13251
13086
  * When neither is specified, the default depends on `options.il`:
13252
13087
  * - In Israel, minor fasts end 15 minutes after sunset (Rabbi Deblitzky's practice).
13253
13088
  * - Elsewhere, minor fasts end at tzeit 7.083° (3 medium-sized stars).
13254
- * @private
13255
13089
  */
13256
13090
  function makeFastEndTime(zmanim, isTishaBav, options) {
13257
13091
  if (isTishaBav) {
@@ -13325,7 +13159,7 @@ class FastDayEvent extends HolidayEvent {
13325
13159
  }
13326
13160
  /**
13327
13161
  * Makes a pair of events representing fast start and end times
13328
- * @private
13162
+ * @internal
13329
13163
  */
13330
13164
  function makeFastStartEnd(ev, options) {
13331
13165
  const desc = ev.getDesc();
@@ -13369,9 +13203,6 @@ function makeFastStartEnd(ev, options) {
13369
13203
  Object.assign(ev2, ev);
13370
13204
  return ev2;
13371
13205
  }
13372
- /**
13373
- * @private
13374
- */
13375
13206
  function makeTimedEvent(ev, time, desc, options) {
13376
13207
  const location = options.location;
13377
13208
  const hd = ev.getDate();
@@ -13406,7 +13237,7 @@ class TimedChanukahEvent extends ChanukahEvent {
13406
13237
  * Makes a candle-lighting event for Chankah (not on Friday/Saturday).
13407
13238
  * At one point this used civil dusk (6 degrees below horizon).
13408
13239
  * Another source suggests 4.6667 degrees below horizon.
13409
- * @private
13240
+ * @internal
13410
13241
  */
13411
13242
  function makeWeekdayChanukahCandleLighting(ev, options) {
13412
13243
  const hd = ev.getDate();
@@ -13564,7 +13395,7 @@ function omerTodayIsEn(omerDay) {
13564
13395
  str += ` and ${daysWithinWeeks} ${daysStr}`;
13565
13396
  }
13566
13397
  }
13567
- return str + ' of the Omer';
13398
+ return `${str} of the Omer`;
13568
13399
  }
13569
13400
  // adapted from pip hdate package (GPL)
13570
13401
  // https://github.com/py-libhdate/py-libhdate/blob/master/hdate/date.py
@@ -13583,23 +13414,23 @@ const ones = [
13583
13414
  ];
13584
13415
  const shnei = 'שְׁנֵי';
13585
13416
  const yamim = 'יָמִים';
13586
- const shneiYamim = shnei + ' ' + yamim;
13417
+ const shneiYamim = `${shnei} ${yamim}`;
13587
13418
  const shavuot = 'שָׁבוּעוֹת';
13588
13419
  const yom = 'יוֹם';
13589
- const yomEchad = yom + ' ' + ones[1];
13420
+ const yomEchad = `${yom} ${ones[1]}`;
13590
13421
  const asar = 'עָשָׂר';
13591
13422
  function omerTodayIsHe(omerDay) {
13592
13423
  const ten = Math.floor(omerDay / 10);
13593
13424
  const one = omerDay % 10;
13594
13425
  let str = 'הַיּוֹם ';
13595
13426
  if (omerDay === 11) {
13596
- str += 'אַחַד ' + asar;
13427
+ str += `אַחַד ${asar}`;
13597
13428
  }
13598
13429
  else if (omerDay === 12) {
13599
- str += 'שְׁנֵים ' + asar;
13430
+ str += `שְׁנֵים ${asar}`;
13600
13431
  }
13601
13432
  else if (12 < omerDay && omerDay < 20) {
13602
- str += ones[one] + ' ' + asar;
13433
+ str += `${ones[one]} ${asar}`;
13603
13434
  }
13604
13435
  else if (omerDay > 9) {
13605
13436
  str += ones[one];
@@ -13613,18 +13444,18 @@ function omerTodayIsHe(omerDay) {
13613
13444
  str += tens[ten];
13614
13445
  }
13615
13446
  if (omerDay < 11) {
13616
- str += ones[one] + ' ' + yamim + ' ';
13447
+ str += `${ones[one]} ${yamim} `;
13617
13448
  }
13618
13449
  else {
13619
- str += ' ' + yom + ' ';
13450
+ str += ` ${yom} `;
13620
13451
  }
13621
13452
  }
13622
13453
  else if (omerDay === 1) {
13623
- str += yomEchad + ' ';
13454
+ str += `${yomEchad} `;
13624
13455
  }
13625
13456
  else {
13626
13457
  // omer == 2
13627
- str += shneiYamim + ' ';
13458
+ str += `${shneiYamim} `;
13628
13459
  }
13629
13460
  if (omerDay > 6) {
13630
13461
  str = str.trim(); // remove trailing space before comma
@@ -13632,14 +13463,14 @@ function omerTodayIsHe(omerDay) {
13632
13463
  const weeks = Math.floor(omerDay / 7);
13633
13464
  const days = omerDay % 7;
13634
13465
  if (weeks > 2) {
13635
- str += ones[weeks] + ' ' + shavuot + ' ';
13466
+ str += `${ones[weeks]} ${shavuot} `;
13636
13467
  }
13637
13468
  else if (weeks === 1) {
13638
- str += 'שָׁבֽוּעַ' + ' ' + ones[1] + ' ';
13469
+ str += `שָׁבֽוּעַ ${ones[1]} `;
13639
13470
  }
13640
13471
  else {
13641
13472
  // weeks == 2
13642
- str += shnei + ' ' + shavuot + ' ';
13473
+ str += `${shnei} ${shavuot} `;
13643
13474
  }
13644
13475
  if (days) {
13645
13476
  if (days === 2 || days === 3) {
@@ -13652,14 +13483,14 @@ function omerTodayIsHe(omerDay) {
13652
13483
  str += 'וְ';
13653
13484
  }
13654
13485
  if (days > 2) {
13655
- str += ones[days] + ' ' + yamim + ' ';
13486
+ str += `${ones[days]} ${yamim} `;
13656
13487
  }
13657
13488
  else if (days === 1) {
13658
- str += yomEchad + ' ';
13489
+ str += `${yomEchad} `;
13659
13490
  }
13660
13491
  else {
13661
13492
  // days == 2
13662
- str += shneiYamim + ' ';
13493
+ str += `${shneiYamim} `;
13663
13494
  }
13664
13495
  }
13665
13496
  }
@@ -13698,8 +13529,7 @@ class OmerEvent extends Event {
13698
13529
  constructor(date, omerDay) {
13699
13530
  super(date, `Omer ${omerDay}`, flags.OMER_COUNT);
13700
13531
  checkDay(omerDay);
13701
- this.weekNumber = Math.floor((omerDay - 1) / 7) + 1;
13702
- this.daysWithinWeeks = omerDay % 7 || 7;
13532
+ [this.weekNumber, this.daysWithinWeeks] = getWeeks(omerDay);
13703
13533
  this.omer = omerDay;
13704
13534
  }
13705
13535
  /**
@@ -13725,8 +13555,7 @@ class OmerEvent extends Event {
13725
13555
  }
13726
13556
  const [weekNum, daysWithinWeeks] = getWeeks(this.omer);
13727
13557
  const config = sefirot[lang];
13728
- const pfxWords = config.pfxWords;
13729
- const words = config.words;
13558
+ const { pfxWords, words } = config;
13730
13559
  const week = pfxWords ? pfxWords[weekNum] : words[weekNum];
13731
13560
  const dayWithinWeek = words[daysWithinWeeks];
13732
13561
  const infix = pfxWords
@@ -13734,7 +13563,7 @@ class OmerEvent extends Event {
13734
13563
  : weekNum === 2 || weekNum === 6
13735
13564
  ? config.infix26
13736
13565
  : config.infix;
13737
- return (dayWithinWeek + ' ' + infix + week).normalize();
13566
+ return `${dayWithinWeek} ${infix}${week}`.normalize();
13738
13567
  }
13739
13568
  /**
13740
13569
  * @param [locale] Optional locale name (defaults to empty locale)
@@ -13743,18 +13572,14 @@ class OmerEvent extends Event {
13743
13572
  const isHebrewLocale = Locale.isHebrewLocale(locale);
13744
13573
  const omer = this.omer;
13745
13574
  const nth = isHebrewLocale ? gematriya(omer) : Locale.ordinal(omer, locale);
13746
- return nth + ' ' + Locale.gettext('day of the Omer', locale);
13575
+ return `${nth} ${Locale.gettext('day of the Omer', locale)}`;
13747
13576
  }
13748
13577
  /**
13749
13578
  * Returns translation of "Omer day 22" without ordinal numbers.
13750
13579
  * @param [locale] Optional locale name (defaults to empty locale)
13751
13580
  */
13752
13581
  renderBrief(locale) {
13753
- return (Locale.gettext('Omer', locale) +
13754
- ' ' +
13755
- Locale.gettext('day', locale) +
13756
- ' ' +
13757
- this.omer);
13582
+ return `${Locale.gettext('Omer', locale)} ${Locale.gettext('day', locale)} ${this.omer}`;
13758
13583
  }
13759
13584
  /**
13760
13585
  * Returns an emoji number symbol with a circle, for example `㊲`
@@ -13880,11 +13705,7 @@ class OmerEvent extends Event {
13880
13705
  }
13881
13706
 
13882
13707
  function range(start, end) {
13883
- const arr = [];
13884
- for (let i = start; i <= end; i++) {
13885
- arr.push(i);
13886
- }
13887
- return arr;
13708
+ return Array.from({ length: end - start + 1 }, (_, i) => start + i);
13888
13709
  }
13889
13710
  const NONE$1 = {
13890
13711
  shacharit: false,
@@ -13998,7 +13819,7 @@ function tachanunYear(year, il) {
13998
13819
  };
13999
13820
  }
14000
13821
 
14001
- /** @private */
13822
+ /** @internal */
14002
13823
  function renderParshaName(parsha, locale) {
14003
13824
  let name = Locale.gettext(parsha[0], locale);
14004
13825
  if (parsha.length === 2) {
@@ -14006,8 +13827,7 @@ function renderParshaName(parsha, locale) {
14006
13827
  name += hyphen + Locale.gettext(parsha[1], locale);
14007
13828
  }
14008
13829
  name = smartApostrophe(name);
14009
- const str = Locale.gettext('Parashat', locale) + ' ' + name;
14010
- return str.normalize();
13830
+ return `${Locale.gettext('Parashat', locale)} ${name}`.normalize();
14011
13831
  }
14012
13832
 
14013
13833
  /**
@@ -14041,7 +13861,7 @@ class ParshaEvent extends Event {
14041
13861
  !HDate.isHDate(parsha.hdate)) {
14042
13862
  throw new TypeError(`Invalid SedraResult argument: ${JSON.stringify(parsha)}`);
14043
13863
  }
14044
- const desc = 'Parashat ' + parsha.parsha.join('-');
13864
+ const desc = `Parashat ${parsha.parsha.join('-')}`;
14045
13865
  super(parsha.hdate, desc, flags.PARSHA_HASHAVUA);
14046
13866
  this.p = parsha;
14047
13867
  }
@@ -14060,8 +13880,8 @@ class ParshaEvent extends Event {
14060
13880
  return undefined;
14061
13881
  }
14062
13882
  const dt = this.urlDateSuffix();
14063
- const url = 'https://www.hebcal.com/sedrot/' + urlFriendly(this.basename()) + '-' + dt;
14064
- return this.p.il ? url + '?i=on' : url;
13883
+ const url = `https://www.hebcal.com/sedrot/${urlFriendly(this.basename())}-${dt}`;
13884
+ return this.p.il ? `${url}?i=on` : url;
14065
13885
  }
14066
13886
  /**
14067
13887
  * The date portion of {@link url}, as `YYYYMMDD` — a parsha name recurs every
@@ -14110,10 +13930,9 @@ function parshaYear(year, il) {
14110
13930
  return events;
14111
13931
  }
14112
13932
 
14113
- const TISHREI = months.TISHREI;
13933
+ const { TISHREI } = months;
14114
13934
  /**
14115
13935
  * Gets the R.D. days for a number, Date, or HDate
14116
- * @private
14117
13936
  */
14118
13937
  function getAbs(d) {
14119
13938
  if (typeof d === 'number')
@@ -14135,16 +13954,16 @@ function getYear(options) {
14135
13954
  const MAX_NUM_YEARS = 2000;
14136
13955
  /**
14137
13956
  * Parse options object to determine start & end days
14138
- * @private
13957
+ * @internal
14139
13958
  */
14140
13959
  function getStartAndEnd(options) {
14141
- const hasStart = options.start !== undefined;
14142
- const hasEnd = options.end !== undefined;
14143
- if (hasStart !== hasEnd) {
13960
+ const { start: start0, end: end0 } = options;
13961
+ if ((start0 === undefined) !== (end0 === undefined)) {
14144
13962
  throw new TypeError('options.start requires options.end');
14145
13963
  }
14146
- if (hasStart && hasEnd) {
14147
- const start = getAbs(options.start), end = getAbs(options.end);
13964
+ if (start0 !== undefined && end0 !== undefined) {
13965
+ const start = getAbs(start0);
13966
+ const end = getAbs(end0);
14148
13967
  if (end - start > 365 * MAX_NUM_YEARS) {
14149
13968
  throw new RangeError(`Date range exceeds ${MAX_NUM_YEARS} years`);
14150
13969
  }
@@ -14256,10 +14075,7 @@ class DailyLearning {
14256
14075
  if (typeof calendar !== 'function') {
14257
14076
  throw new TypeError(`Invalid calendar function: ${calendar}`);
14258
14077
  }
14259
- cals.set(name.toLowerCase(), {
14260
- fn: calendar,
14261
- startDate: startDate,
14262
- });
14078
+ cals.set(name.toLowerCase(), { fn: calendar, startDate });
14263
14079
  }
14264
14080
  /**
14265
14081
  * Returns the learning event for the given date from the named calendar,
@@ -14275,10 +14091,7 @@ class DailyLearning {
14275
14091
  */
14276
14092
  static lookup(name, hd, il) {
14277
14093
  const cal = cals.get(name.toLowerCase());
14278
- if (typeof cal === 'object') {
14279
- return cal.fn(hd, il);
14280
- }
14281
- return null;
14094
+ return cal ? cal.fn(hd, il) : null;
14282
14095
  }
14283
14096
  /**
14284
14097
  * Returns the first Hebrew date for which the named learning calendar
@@ -14287,11 +14100,7 @@ class DailyLearning {
14287
14100
  * @param name case insensitive
14288
14101
  */
14289
14102
  static getStartDate(name) {
14290
- const cal = cals.get(name.toLowerCase());
14291
- if (typeof cal === 'object') {
14292
- return cal.startDate;
14293
- }
14294
- return undefined;
14103
+ return cals.get(name.toLowerCase())?.startDate;
14295
14104
  }
14296
14105
  /**
14297
14106
  * Returns `true` if a learning calendar with the given name has been
@@ -14306,7 +14115,7 @@ class DailyLearning {
14306
14115
  * calendars.
14307
14116
  */
14308
14117
  static getCalendars() {
14309
- return Array.from(cals.keys());
14118
+ return [...cals.keys()];
14310
14119
  }
14311
14120
  }
14312
14121
 
@@ -14345,7 +14154,7 @@ class MevarchimChodeshEvent extends Event {
14345
14154
  render(locale) {
14346
14155
  const monthName0 = Locale.gettext(this.monthName, locale);
14347
14156
  const monthName = smartApostrophe(monthName0);
14348
- return Locale.gettext(mevarchimChodeshStr, locale) + ' ' + monthName;
14157
+ return `${Locale.gettext(mevarchimChodeshStr, locale)} ${monthName}`;
14349
14158
  }
14350
14159
  /**
14351
14160
  * Returns (translated) description of this event
@@ -14630,34 +14439,11 @@ function calendar(options = {}) {
14630
14439
  }
14631
14440
  const FRI = 5;
14632
14441
  const SAT = 6;
14633
- const NISAN = months.NISAN;
14634
- const SIVAN = months.SIVAN;
14635
- const ELUL = months.ELUL;
14636
- const LIGHT_CANDLES = flags.LIGHT_CANDLES;
14637
- const YOM_TOV_ENDS = flags.YOM_TOV_ENDS;
14638
- const CHUL_ONLY = flags.CHUL_ONLY;
14639
- const IL_ONLY = flags.IL_ONLY;
14640
- const LIGHT_CANDLES_TZEIS = flags.LIGHT_CANDLES_TZEIS;
14641
- const CHANUKAH_CANDLES = flags.CHANUKAH_CANDLES;
14642
- const MINOR_FAST = flags.MINOR_FAST;
14643
- const SPECIAL_SHABBAT = flags.SPECIAL_SHABBAT;
14644
- const MODERN_HOLIDAY = flags.MODERN_HOLIDAY;
14645
- const MAJOR_FAST = flags.MAJOR_FAST;
14646
- const ROSH_CHODESH = flags.ROSH_CHODESH;
14647
- const PARSHA_HASHAVUA = flags.PARSHA_HASHAVUA;
14648
- const DAF_YOMI = flags.DAF_YOMI;
14649
- const MISHNA_YOMI = flags.MISHNA_YOMI;
14650
- const NACH_YOMI = flags.NACH_YOMI;
14651
- const YERUSHALMI_YOMI = flags.YERUSHALMI_YOMI;
14652
- const OMER_COUNT = flags.OMER_COUNT;
14653
- const SHABBAT_MEVARCHIM = flags.SHABBAT_MEVARCHIM;
14654
- const MINOR_HOLIDAY = flags.MINOR_HOLIDAY;
14655
- const EREV = flags.EREV;
14656
- const CHOL_HAMOED = flags.CHOL_HAMOED;
14657
- const YOM_KIPPUR_KATAN = flags.YOM_KIPPUR_KATAN;
14658
- const YIZKOR = flags.YIZKOR;
14659
- const BEHAB = flags.BEHAB;
14442
+ const { NISAN, SIVAN, ELUL } = months;
14443
+ const { LIGHT_CANDLES, YOM_TOV_ENDS, CHUL_ONLY, IL_ONLY, LIGHT_CANDLES_TZEIS, CHANUKAH_CANDLES, MINOR_FAST, SPECIAL_SHABBAT, MODERN_HOLIDAY, MAJOR_FAST, ROSH_CHODESH, PARSHA_HASHAVUA, DAF_YOMI, MISHNA_YOMI, NACH_YOMI, YERUSHALMI_YOMI, OMER_COUNT, SHABBAT_MEVARCHIM, MINOR_HOLIDAY, EREV, CHOL_HAMOED, YOM_KIPPUR_KATAN, YIZKOR, BEHAB, } = flags;
14660
14444
  const unrecognizedAlreadyWarned = new Set();
14445
+ // The "as const satisfies Record<keyof CalOptions, 1>" line lets
14446
+ // compiler flag any CalOptions field missing from the list
14661
14447
  const RECOGNIZED_OPTIONS = {
14662
14448
  location: 1,
14663
14449
  year: 1,
@@ -14698,12 +14484,10 @@ const RECOGNIZED_OPTIONS = {
14698
14484
  useElevation: 1,
14699
14485
  yizkor: 1,
14700
14486
  };
14701
- /**
14702
- * @private
14703
- */
14487
+ const recognizedKeys = new Set(Object.keys(RECOGNIZED_OPTIONS));
14704
14488
  function warnUnrecognizedOptions(options) {
14705
14489
  for (const k of Object.keys(options)) {
14706
- if (RECOGNIZED_OPTIONS[k] === undefined && !unrecognizedAlreadyWarned.has(k)) {
14490
+ if (!recognizedKeys.has(k) && !unrecognizedAlreadyWarned.has(k)) {
14707
14491
  console.warn(`Ignoring unrecognized HebrewCalendar option: ${k}`);
14708
14492
  unrecognizedAlreadyWarned.add(k);
14709
14493
  }
@@ -14735,8 +14519,6 @@ const geoIdCandleOffset = {
14735
14519
  '293067': 30, // Zikhron Yaakov
14736
14520
  };
14737
14521
  /**
14738
- * @private
14739
- * @constant
14740
14522
  * This calculation is based on the position of the sun 36 minutes after sunset in Jerusalem
14741
14523
  * around the equinox / equilux, which is 8.5° below geometric zenith.
14742
14524
  * The Ohr Meir considers this the time that 3 small stars are visible,
@@ -14746,7 +14528,6 @@ const geoIdCandleOffset = {
14746
14528
  const TZEIT_3SMALL_STARS = 8.5;
14747
14529
  /**
14748
14530
  * Modifies options in-place
14749
- * @private
14750
14531
  */
14751
14532
  function checkCandleOptions(options) {
14752
14533
  if (!options.candlelighting) {
@@ -14825,7 +14606,6 @@ function overrideIsraelCandleMins(location) {
14825
14606
  }
14826
14607
  /**
14827
14608
  * Mask to filter Holiday array
14828
- * @private
14829
14609
  */
14830
14610
  function getMaskFromOptions(options) {
14831
14611
  if (typeof options.mask === 'number') {
@@ -14909,9 +14689,6 @@ function getMaskFromOptions(options) {
14909
14689
  return mask;
14910
14690
  }
14911
14691
  const defaultLocation = new Location(0, 0, false, 'UTC');
14912
- /**
14913
- * @private
14914
- */
14915
14692
  function setOptionsFromMask(options) {
14916
14693
  const m = options.mask || 0;
14917
14694
  if (m & ROSH_CHODESH)
@@ -14954,7 +14731,6 @@ function setOptionsFromMask(options) {
14954
14731
  /**
14955
14732
  * Appends the Event `ev` to the `events` array. Also may add related
14956
14733
  * timed events like candle-lighting or fast start/end
14957
- * @private
14958
14734
  */
14959
14735
  function appendHolidayAndRelated(candlesEv, events, ev, options, isFriday, isSaturday, hasUserMask) {
14960
14736
  const il = options.il || false;
@@ -15108,9 +14884,7 @@ function makeBiurChametzEvent(hd, options) {
15108
14884
  const NONE = 0;
15109
14885
  const HALF = 1;
15110
14886
  const WHOLE = 2;
15111
- /**
15112
- * @private
15113
- */
14887
+ /** @internal */
15114
14888
  function hallel_(events, hdate) {
15115
14889
  const abs = hdate.abs();
15116
14890
  for (const ev of events) {
@@ -15345,16 +15119,14 @@ class HebrewCalendar {
15345
15119
  * @param il use the Israeli holiday schedule
15346
15120
  */
15347
15121
  static eruvTavshilin(date, il) {
15348
- if (date.getDay() < 3 || date.getDay() > 4) {
15122
+ const dow = date.getDay();
15123
+ if (dow < 3 || dow > 4) {
15349
15124
  return false;
15350
15125
  }
15351
15126
  const today = new HDate(date);
15352
15127
  const friday = today.after(5);
15353
15128
  const tomorrow = today.next();
15354
- if (!isChag(friday, il) || isChag(today, il) || !isChag(tomorrow, il)) {
15355
- return false;
15356
- }
15357
- return true;
15129
+ return isChag(friday, il) && !isChag(today, il) && isChag(tomorrow, il);
15358
15130
  }
15359
15131
  /**
15360
15132
  * Helper function to format a 24-hour (00:00-23:59) time string in either
@@ -15463,13 +15235,9 @@ class HebrewCalendar {
15463
15235
  return tachanun(hdate, il);
15464
15236
  }
15465
15237
  }
15466
- /**
15467
- * @private
15468
- */
15469
15238
  function isChag(date, il) {
15470
- const events = getHolidaysOnDate(date, il) || [];
15471
- const chag = events.filter(ev => ev.hasFlag('CHAG'));
15472
- return chag.length !== 0;
15239
+ const events = getHolidaysOnDate(date, il) ?? [];
15240
+ return events.some(ev => ev.hasFlag('CHAG'));
15473
15241
  }
15474
15242
 
15475
15243
  exports.AsaraBTevetEvent = AsaraBTevetEvent;
@@ -15507,6 +15275,7 @@ exports.gematriyaStrToNum = gematriyaStrToNum;
15507
15275
  exports.getHolidaysOnDate = getHolidaysOnDate;
15508
15276
  exports.getMoladAsDate = getMoladAsDate;
15509
15277
  exports.getSedra = getSedra;
15278
+ exports.greg = greg;
15510
15279
  exports.holidayDesc = holidayDesc;
15511
15280
  exports.isAssurBemlacha = isAssurBemlacha;
15512
15281
  exports.isAveilut = isAveilut;