@hebcal/leyning 6.2.1 → 6.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @hebcal/leyning v6.2.1 */
1
+ /*! @hebcal/leyning v6.2.3 */
2
2
  import { flags, months, HDate, HebrewCalendar, Event, Locale, ParshaEvent } from '@hebcal/core';
3
3
 
4
4
  const Genesis=[0,31,25,24,26,32,22,24,22,29,32,32,20,18,24,21,16,27,33,38,18,34,24,20,67,34,35,46,22,35,43,54,33,20,31,29,43,36,30,23,23,57,38,34,34,28,34,31,22,33,26];const Exodus=[0,22,25,22,31,23,30,29,28,35,29,10,51,22,31,27,36,16,27,25,26,37,30,33,18,40,37,21,43,46,38,18,35,23,35,35,38,29,31,43,38];const Leviticus=[0,17,16,17,35,26,23,38,36,24,20,47,8,59,57,33,34,16,30,37,27,24,33,44,23,55,46,34];const Numbers=[0,54,34,51,49,31,27,89,26,23,36,35,16,33,45,41,35,28,32,22,29,35,41,30,25,19,65,23,31,39,17,54,42,56,29,34,13];const Deuteronomy=[0,46,37,29,49,30,25,26,20,29,22,32,31,19,29,23,22,20,22,21,20,23,29,26,22,19,19,26,69,28,20,30,52,29,12];const Joshua=[0,18,24,17,24,15,27,26,35,27,43,23,24,33,15,63,10,18,28,51,9,45,34,16,33];const Judges=[0,36,23,31,24,31,40,25,35,57,18,40,15,25,20,20,31,13,31,30,48,25];const Ruth=[0,22,23,18,22];const Isaiah=[0,31,22,26,6,30,13,25,23,20,34,16,6,22,32,9,14,14,7,25,6,17,25,18,23,12,21,13,29,24,33,9,20,24,17,10,22,38,22,8,31,29,25,28,28,25,13,15,22,26,11,23,15,12,17,13,12,21,14,21,22,11,12,19,11,25,24];const Jeremiah=[0,19,37,25,31,31,30,34,23,25,25,23,17,27,22,21,21,27,23,15,18,14,30,40,10,38,24,22,17,32,24,40,44,26,22,19,32,21,28,18,16,18,22,13,30,5,28,7,47,39,46,64,34];const Lamentations=[0,22,22,66,22,22];const Baruch=[0,22,35,38,37,9,72];const Ezekiel=[0,28,10,27,17,17,14,27,18,11,22,25,28,23,23,8,63,24,32,14,44,37,31,49,27,17,21,36,26,21,26,18,32,33,31,15,38,28,23,29,49,26,20,27,31,25,24,23,35];const Daniel=[0,21,49,100,34,30,29,28,27,27,21,45,13,64,42];const Hosea=[0,9,25,5,19,15,11,16,14,17,15,11,15,15,10];const Joel=[0,20,27,5,21];const Amos=[0,15,16,15,13,27,14,17,14,15];const Obadiah=[0,21];const Jonah=[0,16,11,10,11];const Micah=[0,16,13,12,14,14,16,20];const Nachum=[0,14,14,19];const Habakkuk=[0,17,20,19];const Zephaniah=[0,18,15,20];const Haggai=[0,15,23];const Zechariah=[0,17,17,10,14,11,15,14,23,17,12,17,14,9,21];const Malachi=[0,14,17,24];var numverses = {Genesis:Genesis,Exodus:Exodus,Leviticus:Leviticus,Numbers:Numbers,Deuteronomy:Deuteronomy,Joshua:Joshua,Judges:Judges,Ruth:Ruth,"I Samuel":[0,28,36,21,22,12,21,17,22,27,27,15,25,23,52,35,23,58,30,24,42,16,23,28,23,43,25,12,25,11,31,13],"II Samuel":[0,27,32,39,12,25,23,29,18,13,19,27,31,39,33,37,23,29,32,44,26,22,51,39,25],"I Kings":[0,53,46,28,20,32,38,51,66,28,29,43,33,34,31,34,34,24,46,21,43,29,54],"II Kings":[0,18,25,27,44,27,33,20,29,37,36,20,22,25,29,38,20,41,37,37,21,26,20,37,20,30],Isaiah:Isaiah,Jeremiah:Jeremiah,Lamentations:Lamentations,Baruch:Baruch,Ezekiel:Ezekiel,Daniel:Daniel,Hosea:Hosea,Joel:Joel,Amos:Amos,Obadiah:Obadiah,Jonah:Jonah,Micah:Micah,Nachum:Nachum,Habakkuk:Habakkuk,Zephaniah:Zephaniah,Haggai:Haggai,Zechariah:Zechariah,Malachi:Malachi};
@@ -8,23 +8,21 @@ const Genesis=[0,31,25,24,26,32,22,24,22,29,32,32,20,18,24,21,16,27,33,38,18,34,
8
8
  * @readonly
9
9
  * @const {string[]}
10
10
  */
11
-
12
11
  const BOOK = ['', 'Genesis', 'Exodus', 'Leviticus', 'Numbers', 'Deuteronomy'];
12
+
13
13
  /**
14
14
  * Formats parsha as a string
15
15
  * @param {string[]} parsha
16
16
  * @return {string}
17
17
  */
18
-
19
18
  function parshaToString(parsha) {
20
19
  let s = parsha[0];
21
-
22
20
  if (parsha.length == 2) {
23
21
  s += '-' + parsha[1];
24
22
  }
25
-
26
23
  return s;
27
24
  }
25
+
28
26
  /**
29
27
  * Represents an aliyah
30
28
  * @typedef {Object} Aliyah
@@ -40,10 +38,10 @@ function parshaToString(parsha) {
40
38
  * @param {any} src
41
39
  * @return {any}
42
40
  */
43
-
44
41
  function clone(src) {
45
42
  return JSON.parse(JSON.stringify(src));
46
43
  }
44
+
47
45
  /**
48
46
  * Calculates the number of verses in an aliyah or haftara based on
49
47
  * the `b` (begin verse), `e` (end verse) and `k` (book).
@@ -51,98 +49,85 @@ function clone(src) {
51
49
  * @param {Aliyah} aliyah
52
50
  * @return {number}
53
51
  */
54
-
55
52
  function calculateNumVerses(aliyah) {
56
53
  if (aliyah.v) {
57
54
  return aliyah.v;
58
55
  }
59
-
60
56
  const chapVerseBegin = aliyah.b.split(':');
61
57
  const chapVerseEnd = aliyah.e.split(':');
62
58
  const c1 = parseInt(chapVerseBegin[0], 10);
63
59
  const c2 = parseInt(chapVerseEnd[0], 10);
64
60
  const v1 = parseInt(chapVerseBegin[1], 10);
65
61
  const v2 = parseInt(chapVerseEnd[1], 10);
66
-
67
62
  if (c1 === c2) {
68
63
  aliyah.v = v2 - v1 + 1;
69
64
  } else if (typeof aliyah.k === 'string') {
70
65
  const numv = numverses[aliyah.k];
71
-
72
66
  if (typeof numv !== 'object' || !numv.length) {
73
67
  throw new ReferenceError(`Can't find numverses for ${aliyah.k}`);
74
68
  }
75
-
76
69
  let total = numv[c1] - v1 + 1;
77
-
78
70
  for (let chap = c1 + 1; chap < c2; chap++) {
79
71
  total += numv[chap];
80
72
  }
81
-
82
73
  total += v2;
83
74
  aliyah.v = total;
84
75
  }
85
-
86
76
  return aliyah.v;
87
77
  }
78
+
88
79
  /**
89
80
  * Formats an aliyah object like "Numbers 28:9-28:15"
90
81
  * @param {Aliyah} a aliyah
91
82
  * @return {string}
92
83
  */
93
-
94
84
  function formatAliyahWithBook(a) {
95
85
  return `${a.k} ${a.b}-${a.e}`;
96
86
  }
87
+
97
88
  /**
98
89
  * Formats an aliyah object like "Numbers 28:9-15"
99
90
  * @param {Aliyah} aliyah
100
91
  * @param {boolean} showBook
101
92
  * @return {string}
102
93
  */
103
-
104
94
  function formatAliyahShort(aliyah, showBook) {
105
95
  const begin = aliyah.b;
106
96
  const end0 = aliyah.e;
107
97
  const prefix = showBook ? aliyah.k + ' ' : '';
108
-
109
98
  if (begin === end0) {
110
99
  return `${prefix}${begin}`;
111
100
  }
112
-
113
101
  const cv1 = begin.split(':');
114
102
  const cv2 = end0.split(':');
115
103
  const end = cv1[0] === cv2[0] ? cv2[1] : end0;
116
104
  return `${prefix}${begin}-${end}`;
117
105
  }
106
+
118
107
  /**
119
108
  * Returns the total number of verses in an array of Aliyah (or haftarah) objects
120
109
  * @param {Aliyah|Aliyah[]} aliyot
121
110
  * @return {number}
122
111
  */
123
-
124
112
  function sumVerses(aliyot) {
125
113
  return Array.isArray(aliyot) ? aliyot.reduce((prev, cur) => prev + cur.v, 0) : aliyot.v;
126
114
  }
115
+
127
116
  /**
128
117
  * @private
129
118
  * @param {Aliyah|Aliyah[]} haft
130
119
  * @return {Aliyah|Aliyah[]}
131
120
  */
132
-
133
121
  function cloneHaftara(haft) {
134
122
  if (!haft) {
135
123
  return haft;
136
124
  }
137
-
138
125
  const dest = clone(haft);
139
-
140
126
  if (Array.isArray(dest)) {
141
127
  dest.map(calculateNumVerses);
142
128
  } else {
143
129
  calculateNumVerses(dest);
144
130
  }
145
-
146
131
  return dest;
147
132
  }
148
133
 
@@ -152,39 +137,33 @@ function cloneHaftara(haft) {
152
137
  * @param {string} b
153
138
  * @return {boolean}
154
139
  */
155
-
156
140
  function isChapVerseBefore(a, b) {
157
141
  const cv1 = a.split(':').map(x => +x);
158
142
  const cv2 = b.split(':').map(x => +x);
159
143
  return cv1[0] * 100 + cv1[1] < cv2[0] * 100 + cv2[1];
160
144
  }
145
+
161
146
  /**
162
147
  * Summarizes an `AliyotMap` by collapsing all adjacent aliyot.
163
148
  * Finds any non-overlapping parts (e.g. special 7th aliyah or maftir)
164
149
  * @param {Object<string,Aliyah>} aliyot
165
150
  * @return {Aliyah[]}
166
151
  */
167
-
168
-
169
152
  function makeLeyningParts(aliyot) {
170
153
  const nums = Object.keys(aliyot).filter(x => x.length === 1);
171
154
  let start = aliyot[nums[0]];
172
155
  let end = start;
173
156
  const parts = [];
174
-
175
157
  for (let i = 0; i < nums.length; i++) {
176
158
  const num = nums[i];
177
159
  const aliyah = aliyot[num];
178
-
179
160
  if (i === nums.length - 1 && aliyah.k === end.k && aliyah.e === end.e) {
180
161
  // short-circuit when final aliyah is within the previous (e.g. M inside of 7)
181
162
  continue;
182
163
  }
183
-
184
164
  const prevEndChap = +end.e.split(':')[0];
185
165
  const curStartChap = +aliyah.b.split(':')[0];
186
166
  const sameOrNextChap = curStartChap === prevEndChap || curStartChap === prevEndChap + 1;
187
-
188
167
  if (i !== 0 && (aliyah.k !== start.k || isChapVerseBefore(aliyah.b, start.e) || !sameOrNextChap)) {
189
168
  parts.push({
190
169
  k: start.k,
@@ -193,10 +172,8 @@ function makeLeyningParts(aliyot) {
193
172
  });
194
173
  start = aliyah;
195
174
  }
196
-
197
175
  end = aliyah;
198
176
  }
199
-
200
177
  parts.push({
201
178
  k: start.k,
202
179
  b: start.b,
@@ -204,6 +181,7 @@ function makeLeyningParts(aliyot) {
204
181
  });
205
182
  return parts;
206
183
  }
184
+
207
185
  /**
208
186
  * Returns a string representation of the leyning parts.
209
187
  * Separate verse ranges read from the same book are separated
@@ -213,77 +191,64 @@ function makeLeyningParts(aliyot) {
213
191
  * @param {Aliyah|Aliyah[]} parts
214
192
  * @return {string}
215
193
  */
216
-
217
194
  function makeSummaryFromParts(parts) {
218
195
  if (!Array.isArray(parts)) {
219
196
  parts = [parts];
220
197
  }
221
-
222
198
  let prev = parts[0];
223
199
  let summary = formatAliyahShort(prev, true);
224
-
225
200
  for (let i = 1; i < parts.length; i++) {
226
201
  const part = parts[i];
227
-
228
202
  if (part.k === prev.k) {
229
203
  summary += ', ';
230
204
  } else {
231
205
  summary += `; ${part.k} `;
232
206
  }
233
-
234
207
  summary += formatAliyahShort(part, false);
235
208
  prev = part;
236
209
  }
237
-
238
210
  return summary;
239
211
  }
212
+
240
213
  /**
241
214
  * Makes a summary of the leyning, like "Genesis 6:9-11:32"
242
215
  * @param {Object<string,Aliyah>} aliyot
243
216
  * @return {string}
244
217
  */
245
-
246
218
  function makeLeyningSummary(aliyot) {
247
219
  const parts = makeLeyningParts(aliyot);
248
220
  return makeSummaryFromParts(parts);
249
221
  }
250
222
 
251
- const Purim={fullkriyah:{"1":{p:16,k:2,b:"17:8",e:"17:10"},"2":{p:16,k:2,b:"17:11",e:"17:13"},"3":{p:16,k:2,b:"17:14",e:"17:16"}}};var festivals = {"Pesach I":{haft:{k:"Joshua",b:"5:2",e:"6:1"},fullkriyah:{"1":{p:15,k:2,b:"12:21",e:"12:24"},"2":{p:15,k:2,b:"12:25",e:"12:28"},"3":{p:15,k:2,b:"12:29",e:"12:36"},"4":{p:15,k:2,b:"12:37",e:"12:42"},"5":{p:15,k:2,b:"12:43",e:"12:51"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach I (on Shabbat)":{haft:{k:"Joshua",b:"5:2",e:"6:1"},fullkriyah:{"1":{p:15,k:2,b:"12:21",e:"12:24"},"2":{p:15,k:2,b:"12:25",e:"12:28"},"3":{p:15,k:2,b:"12:29",e:"12:32"},"4":{p:15,k:2,b:"12:33",e:"12:36"},"5":{p:15,k:2,b:"12:37",e:"12:42"},"6":{p:15,k:2,b:"12:43",e:"12:47"},"7":{p:15,k:2,b:"12:48",e:"12:51"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach II":{haft:[{k:"II Kings",b:"23:1",e:"23:9"},{k:"II Kings",b:"23:21",e:"23:25"}],fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach II (CH''M)":{note:"Israel only - according to Vaani T'fillati Siddur Yisraeli",fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:8"},"2":{p:31,k:3,b:"23:9",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:44"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 1":{fullkriyah:{"1":{p:15,k:2,b:"13:1",e:"13:4"},"2":{p:15,k:2,b:"13:5",e:"13:10"},"3":{p:15,k:2,b:"13:11",e:"13:16"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 2":{fullkriyah:{"1":{p:18,k:2,b:"22:24",e:"22:26"},"2":{p:18,k:2,b:"22:27",e:"23:5"},"3":{p:18,k:2,b:"23:6",e:"23:19"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 3":{fullkriyah:{"1":{p:21,k:2,b:"34:1",e:"34:10"},"2":{p:21,k:2,b:"34:11",e:"34:17"},"3":{p:21,k:2,b:"34:18",e:"34:26"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 4":{fullkriyah:{"1":{p:36,k:4,b:"9:1",e:"9:5"},"2":{p:36,k:4,b:"9:6",e:"9:8"},"3":{p:36,k:4,b:"9:9",e:"9:14"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Shabbat Chol ha-Moed":{haft:{k:"Ezekiel",b:"37:1",e:"37:14"},fullkriyah:{"1":{p:21,k:2,b:"33:12",e:"33:16"},"2":{p:21,k:2,b:"33:17",e:"33:19"},"3":{p:21,k:2,b:"33:20",e:"33:23"},"4":{p:21,k:2,b:"34:1",e:"34:3"},"5":{p:21,k:2,b:"34:4",e:"34:10"},"6":{p:21,k:2,b:"34:11",e:"34:17"},"7":{p:21,k:2,b:"34:18",e:"34:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VII":{haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":{p:16,k:2,b:"13:17",e:"13:22"},"2":{p:16,k:2,b:"14:1",e:"14:8"},"3":{p:16,k:2,b:"14:9",e:"14:14"},"4":{p:16,k:2,b:"14:15",e:"14:25"},"5":{p:16,k:2,b:"14:26",e:"15:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VII (on Shabbat)":{haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":{p:16,k:2,b:"13:17",e:"13:19"},"2":{p:16,k:2,b:"13:20",e:"13:22"},"3":{p:16,k:2,b:"14:1",e:"14:4"},"4":{p:16,k:2,b:"14:5",e:"14:8"},"5":{p:16,k:2,b:"14:9",e:"14:14"},"6":{p:16,k:2,b:"14:15",e:"14:25"},"7":{p:16,k:2,b:"14:26",e:"15:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VIII":{haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:47,k:5,b:"15:19",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VIII (on Shabbat)":{haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach III (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 1"},"Pesach IV (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 2"},"Pesach V (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 3"},"Pesach VI (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 4"},"Shavuot I":{haft:[{k:"Ezekiel",b:"1:1",e:"1:28"},{k:"Ezekiel",b:"3:12",e:"3:12"}],fullkriyah:{"1":{p:17,k:2,b:"19:1",e:"19:6"},"2":{p:17,k:2,b:"19:7",e:"19:13"},"3":{p:17,k:2,b:"19:14",e:"19:19"},"4":{p:17,k:2,b:"19:20",e:"20:14"},"5":{p:17,k:2,b:"20:15",e:"20:23"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Shavuot II":{haft:{k:"Habakkuk",b:"3:1",e:"3:19"},fullkriyah:{"1":{p:47,k:5,b:"15:19",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Shavuot II (on Shabbat)":{haft:{k:"Habakkuk",b:"3:1",e:"3:19"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Fast Day (Morning)":{fullkriyah:{"1":{p:21,k:2,b:"32:11",e:"32:14"},"2":{p:21,k:2,b:"34:1",e:"34:3"},"3":{p:21,k:2,b:"34:4",e:"34:10"}}},"Fast Day (Afternoon)":{haft:{k:"Isaiah",b:"55:6",e:"56:8"},fullkriyah:{"1":{p:21,k:2,b:"32:11",e:"32:14"},"2":{p:21,k:2,b:"34:1",e:"34:3"},"3":{p:21,k:2,b:"34:4",e:"34:10"}}},"Asara B'Tevet":{alias:true,key:"Fast Day (Morning)"},"Ta'anit Bechorot":{alias:true,key:"Fast Day (Morning)"},"Ta'anit Esther":{alias:true,key:"Fast Day (Morning)"},"Tzom Gedaliah":{alias:true,key:"Fast Day (Morning)"},"Tzom Tammuz":{alias:true,key:"Fast Day (Morning)"},"Asara B'Tevet (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Ta'anit Bechorot (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Ta'anit Esther (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tzom Gedaliah (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tzom Tammuz (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tish'a B'Av":{haft:{k:"Jeremiah",b:"8:13",e:"9:23"},fullkriyah:{"1":{p:45,k:5,b:"4:25",e:"4:29"},"2":{p:45,k:5,b:"4:30",e:"4:35"},"3":{p:45,k:5,b:"4:36",e:"4:40"}}},"Tish'a B'Av (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Rosh Hashana I":{haft:{k:"I Samuel",b:"1:1",e:"2:10"},fullkriyah:{"1":{p:4,k:1,b:"21:1",e:"21:4"},"2":{p:4,k:1,b:"21:5",e:"21:12"},"3":{p:4,k:1,b:"21:13",e:"21:21"},"4":{p:4,k:1,b:"21:22",e:"21:27"},"5":{p:4,k:1,b:"21:28",e:"21:34"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Rosh Hashana I (on Shabbat)":{haft:{k:"I Samuel",b:"1:1",e:"2:10"},fullkriyah:{"1":{p:4,k:1,b:"21:1",e:"21:4"},"2":{p:4,k:1,b:"21:5",e:"21:8"},"3":{p:4,k:1,b:"21:9",e:"21:12"},"4":{p:4,k:1,b:"21:13",e:"21:17"},"5":{p:4,k:1,b:"21:18",e:"21:21"},"6":{p:4,k:1,b:"21:22",e:"21:27"},"7":{p:4,k:1,b:"21:28",e:"21:34"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Rosh Hashana II":{haft:{k:"Jeremiah",b:"31:1",e:"31:19"},fullkriyah:{"1":{p:4,k:1,b:"22:1",e:"22:3"},"2":{p:4,k:1,b:"22:4",e:"22:8"},"3":{p:4,k:1,b:"22:9",e:"22:14"},"4":{p:4,k:1,b:"22:15",e:"22:19"},"5":{p:4,k:1,b:"22:20",e:"22:24"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Yom Kippur":{haft:{k:"Isaiah",b:"57:14",e:"58:14"},fullkriyah:{"1":{p:29,k:3,b:"16:1",e:"16:6"},"2":{p:29,k:3,b:"16:7",e:"16:11"},"3":{p:29,k:3,b:"16:12",e:"16:17"},"4":{p:29,k:3,b:"16:18",e:"16:24"},"5":{p:29,k:3,b:"16:25",e:"16:30"},"6":{p:29,k:3,b:"16:31",e:"16:34"},M:{p:41,k:4,b:"29:7",e:"29:11"}}},"Yom Kippur (on Shabbat)":{haft:{k:"Isaiah",b:"57:14",e:"58:14"},fullkriyah:{"1":{p:29,k:3,b:"16:1",e:"16:3"},"2":{p:29,k:3,b:"16:4",e:"16:6"},"3":{p:29,k:3,b:"16:7",e:"16:11"},"4":{p:29,k:3,b:"16:12",e:"16:17"},"5":{p:29,k:3,b:"16:18",e:"16:24"},"6":{p:29,k:3,b:"16:25",e:"16:30"},"7":{p:29,k:3,b:"16:31",e:"16:34"},M:{p:41,k:4,b:"29:7",e:"29:11"}}},"Yom Kippur (Mincha)":{alias:true,key:"Yom Kippur (Mincha, Traditional)"},"Yom Kippur (Mincha, Traditional)":{haft:[{k:"Jonah",b:"1:1",e:"4:11"},{k:"Micah",b:"7:18",e:"7:20"}],fullkriyah:{"1":{p:29,k:3,b:"18:1",e:"18:5"},"2":{p:29,k:3,b:"18:6",e:"18:21"},"3":{p:29,k:3,b:"18:22",e:"18:30"}}},"Yom Kippur (Mincha, Alternate)":{haft:[{k:"Jonah",b:"1:1",e:"4:11"},{k:"Micah",b:"7:18",e:"7:20"}],fullkriyah:{"1":{p:30,k:3,b:"19:1",e:"19:4"},"2":{p:30,k:3,b:"19:5",e:"19:10"},"3":{p:30,k:3,b:"19:11",e:"19:18"}}},"Sukkot I":{haft:{k:"Zechariah",b:"14:1",e:"14:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot I (on Shabbat)":{haft:{k:"Zechariah",b:"14:1",e:"14:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"22:33"},"2":{p:31,k:3,b:"23:1",e:"23:3"},"3":{p:31,k:3,b:"23:4",e:"23:8"},"4":{p:31,k:3,b:"23:9",e:"23:14"},"5":{p:31,k:3,b:"23:15",e:"23:22"},"6":{p:31,k:3,b:"23:23",e:"23:32"},"7":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot II":{haft:{k:"I Kings",b:"8:2",e:"8:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot Chol ha-Moed Day 1":{fullkriyah:{"1":{p:41,k:4,b:"29:17",e:"29:19"},"2":{p:41,k:4,b:"29:20",e:"29:22"},"3":{p:41,k:4,b:"29:23",e:"29:25"},"4":{p:41,k:4,b:"29:17",e:"29:22"}}},"Sukkot Chol ha-Moed Day 2":{fullkriyah:{"1":{p:41,k:4,b:"29:20",e:"29:22"},"2":{p:41,k:4,b:"29:23",e:"29:25"},"3":{p:41,k:4,b:"29:26",e:"29:28"},"4":{p:41,k:4,b:"29:20",e:"29:25"}}},"Sukkot Chol ha-Moed Day 3":{fullkriyah:{"1":{p:41,k:4,b:"29:23",e:"29:25"},"2":{p:41,k:4,b:"29:26",e:"29:28"},"3":{p:41,k:4,b:"29:29",e:"29:31"},"4":{p:41,k:4,b:"29:23",e:"29:28"}}},"Sukkot Chol ha-Moed Day 4":{fullkriyah:{"1":{p:41,k:4,b:"29:26",e:"29:28"},"2":{p:41,k:4,b:"29:29",e:"29:31"},"3":{p:41,k:4,b:"29:32",e:"29:34"},"4":{p:41,k:4,b:"29:26",e:"29:31"}}},"Sukkot Chol ha-Moed Day 5":{fullkriyah:{"1":{p:41,k:4,b:"29:29",e:"29:31"},"2":{p:41,k:4,b:"29:32",e:"29:34"},"3":{p:41,k:4,b:"29:35",e:"29:37"},"4":{p:41,k:4,b:"29:29",e:"29:34"}}},"Sukkot Shabbat Chol ha-Moed":{haft:{k:"Ezekiel",b:"38:18",e:"39:16"},fullkriyah:{"1":{p:21,k:2,b:"33:12",e:"33:16"},"2":{p:21,k:2,b:"33:17",e:"33:19"},"3":{p:21,k:2,b:"33:20",e:"33:23"},"4":{p:21,k:2,b:"34:1",e:"34:3"},"5":{p:21,k:2,b:"34:4",e:"34:10"},"6":{p:21,k:2,b:"34:11",e:"34:17"},"7":{p:21,k:2,b:"34:18",e:"34:26"},"M-day1":{p:41,k:4,b:"29:17",e:"29:22"},"M-day2":{p:41,k:4,b:"29:20",e:"29:25"},"M-day3":{p:41,k:4,b:"29:23",e:"29:28"},"M-day4":{p:41,k:4,b:"29:26",e:"29:31"},"M-day5":{p:41,k:4,b:"29:29",e:"29:34"}}},"Sukkot Final Day (Hoshana Raba)":{fullkriyah:{"1":{p:41,k:4,b:"29:26",e:"29:28"},"2":{p:41,k:4,b:"29:29",e:"29:31"},"3":{p:41,k:4,b:"29:32",e:"29:34"},"4":{p:41,k:4,b:"29:29",e:"29:34"}}},"Shmini Atzeret":{haft:{k:"I Kings",b:"8:54",e:"8:66"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"16:3"},"4":{p:47,k:5,b:"16:4",e:"16:8"},"5":{p:47,k:5,b:"16:9",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Shmini Atzeret (on Shabbat)":{haft:{k:"I Kings",b:"8:54",e:"8:66"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Erev Simchat Torah":{fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"},"4":{p:54,k:5,b:"33:18",e:"33:21"},"5":{p:54,k:5,b:"33:22",e:"33:26"}}},"Simchat Torah":{haft:{k:"Joshua",b:"1:1",e:"1:18"},fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"},"4":{p:54,k:5,b:"33:18",e:"33:21"},"5":{p:54,k:5,b:"33:22",e:"33:26"},"6":{p:54,k:5,b:"33:27",e:"34:12"},"7":{p:1,k:1,b:"1:1",e:"2:3"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Shabbat Rosh Chodesh Chanukah":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:35,k:4,b:"7:42",e:"7:47"}}},"Chanukah Day 1":{fullkriyah:{"1":{p:35,k:4,b:"7:1",e:"7:11"},"2":{p:35,k:4,b:"7:12",e:"7:14"},"3":{p:35,k:4,b:"7:15",e:"7:17"}},alt:{"1":{p:35,k:4,b:"7:1",e:"7:3"},"2":{p:35,k:4,b:"7:4",e:"7:11"},"3":{p:35,k:4,b:"7:12",e:"7:17"}}},"Chanukah Day 1 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:1",e:"7:17"}}},"Chanukah Day 2":{fullkriyah:{"1":{p:35,k:4,b:"7:18",e:"7:20"},"2":{p:35,k:4,b:"7:21",e:"7:23"},"3":{p:35,k:4,b:"7:24",e:"7:29"}},alt:{"1":{p:35,k:4,b:"7:18",e:"7:20"},"2":{p:35,k:4,b:"7:21",e:"7:23"},"3":{p:35,k:4,b:"7:18",e:"7:23"}}},"Chanukah Day 2 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:18",e:"7:23"}}},"Chanukah Day 3":{fullkriyah:{"1":{p:35,k:4,b:"7:24",e:"7:26"},"2":{p:35,k:4,b:"7:27",e:"7:29"},"3":{p:35,k:4,b:"7:30",e:"7:35"}},alt:{"1":{p:35,k:4,b:"7:24",e:"7:26"},"2":{p:35,k:4,b:"7:27",e:"7:29"},"3":{p:35,k:4,b:"7:24",e:"7:29"}}},"Chanukah Day 3 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:24",e:"7:29"}}},"Chanukah Day 4":{fullkriyah:{"1":{p:35,k:4,b:"7:30",e:"7:32"},"2":{p:35,k:4,b:"7:33",e:"7:35"},"3":{p:35,k:4,b:"7:36",e:"7:41"}},alt:{"1":{p:35,k:4,b:"7:30",e:"7:32"},"2":{p:35,k:4,b:"7:33",e:"7:35"},"3":{p:35,k:4,b:"7:30",e:"7:35"}}},"Chanukah Day 4 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:30",e:"7:35"}}},"Chanukah Day 5":{fullkriyah:{"1":{p:35,k:4,b:"7:36",e:"7:38"},"2":{p:35,k:4,b:"7:39",e:"7:41"},"3":{p:35,k:4,b:"7:42",e:"7:47"}},alt:{"1":{p:35,k:4,b:"7:36",e:"7:38"},"2":{p:35,k:4,b:"7:39",e:"7:41"},"3":{p:35,k:4,b:"7:36",e:"7:41"}}},"Chanukah Day 5 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:36",e:"7:41"}}},"Chanukah Day 6":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:5"},"2":{p:41,k:4,b:"28:6",e:"28:10"},"3":{p:41,k:4,b:"28:11",e:"28:15"},"4":{p:35,k:4,b:"7:42",e:"7:47"}}},"Chanukah Day 7":{fullkriyah:{"1":{p:35,k:4,b:"7:48",e:"7:50"},"2":{p:35,k:4,b:"7:51",e:"7:53"},"3":{p:35,k:4,b:"7:54",e:"7:59"}},alt:{"1":{p:35,k:4,b:"7:48",e:"7:50"},"2":{p:35,k:4,b:"7:51",e:"7:53"},"3":{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 7 (on Rosh Chodesh)":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:5"},"2":{p:41,k:4,b:"28:6",e:"28:10"},"3":{p:41,k:4,b:"28:11",e:"28:15"},"4":{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 7 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 8":{fullkriyah:{"1":{p:35,k:4,b:"7:54",e:"7:56"},"2":{p:35,k:4,b:"7:57",e:"7:59"},"3":{p:35,k:4,b:"7:60",e:"8:4"}}},"Chanukah Day 8 (on Shabbat)":{haft:{k:"I Kings",b:"7:40",e:"7:50"},fullkriyah:{M:{p:35,k:4,b:"7:54",e:"8:4"}}},Purim:Purim,"Shushan Purim":{fullkriyah:{"1":{p:16,k:2,b:"17:8",e:"17:10"},"2":{p:16,k:2,b:"17:11",e:"17:13"},"3":{p:16,k:2,b:"17:14",e:"17:16"}}},"Shushan Purim (on Shabbat)":{note:"Jerusalem & walled cities only: special maftir Exodus 17:8-16, same Haftara as Shabbat Zachor"},"Shabbat HaChodesh":{haft:{k:"Ezekiel",b:"45:16",e:"46:18"},fullkriyah:{M:{p:15,k:2,b:"12:1",e:"12:20"}}},"Shabbat HaChodesh (on Rosh Chodesh)":{haft:{k:"Ezekiel",b:"45:16",e:"46:18"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:15,k:2,b:"12:1",e:"12:20"}}},"Shabbat HaGadol":{haft:{k:"Malachi",b:"3:4",e:"3:24"}},"Shabbat Parah":{haft:{k:"Ezekiel",b:"36:16",e:"36:38"},fullkriyah:{M:{p:39,k:4,b:"19:1",e:"19:22"}}},"Shabbat Shekalim":{haft:{k:"II Kings",b:"12:1",e:"12:17"},fullkriyah:{M:{p:21,k:2,b:"30:11",e:"30:16"}}},"Shabbat Shekalim (on Rosh Chodesh)":{haft:{k:"II Kings",b:"12:1",e:"12:17"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:21,k:2,b:"30:11",e:"30:16"}}},"Shabbat Shuva (with Vayeilech)":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"}]},"Shabbat Shuva (with Ha'Azinu)":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Joel",b:"2:15",e:"2:27"}],seph:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"}]},"Shabbat Shuva":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"},{k:"Joel",b:"2:15",e:"2:27"}]},"Shabbat Zachor":{haft:{k:"I Samuel",b:"15:2",e:"15:34"},fullkriyah:{M:{p:49,k:5,b:"25:17",e:"25:19"}}},"Pinchas occurring after 17 Tammuz":{haft:{k:"Jeremiah",b:"1:1",e:"2:3"}},"Masei on Shabbat Rosh Chodesh":{haft:[{k:"Jeremiah",b:"2:4",e:"2:28"},{k:"Jeremiah",b:"3:4",e:"3:4"},{k:"Isaiah",b:"66:1",e:"66:1"},{k:"Isaiah",b:"66:23",e:"66:23"}]},"Matot-Masei on Shabbat Rosh Chodesh":{alias:true,key:"Masei on Shabbat Rosh Chodesh"},"Rosh Chodesh":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:3"},"2":{p:41,k:4,b:"28:3",e:"28:5"},"3":{p:41,k:4,b:"28:6",e:"28:10"},"4":{p:41,k:4,b:"28:11",e:"28:15"}}},"Rosh Chodesh Nisan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Iyyar":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Sivan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Tamuz":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Av":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Elul":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Tishrei":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Cheshvan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Kislev":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Sh'vat":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar I":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar II":{alias:true,key:"Rosh Chodesh"},"Shabbat Rosh Chodesh":{haft:{k:"Isaiah",b:"66:1",e:"66:24"},fullkriyah:{M:{p:41,k:4,b:"28:9",e:"28:15"}}},"Shabbat Machar Chodesh":{haft:{k:"I Samuel",b:"20:18",e:"20:42"}}};
223
+ const Purim={fullkriyah:{"1":{p:16,k:2,b:"17:8",e:"17:10"},"2":{p:16,k:2,b:"17:11",e:"17:13"},"3":{p:16,k:2,b:"17:14",e:"17:16"}}};var festivals = {"Pesach I":{haft:{k:"Joshua",b:"5:2",e:"6:1"},fullkriyah:{"1":{p:15,k:2,b:"12:21",e:"12:24"},"2":{p:15,k:2,b:"12:25",e:"12:28"},"3":{p:15,k:2,b:"12:29",e:"12:36"},"4":{p:15,k:2,b:"12:37",e:"12:42"},"5":{p:15,k:2,b:"12:43",e:"12:51"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach I (on Shabbat)":{haft:{k:"Joshua",b:"5:2",e:"6:1"},fullkriyah:{"1":{p:15,k:2,b:"12:21",e:"12:24"},"2":{p:15,k:2,b:"12:25",e:"12:28"},"3":{p:15,k:2,b:"12:29",e:"12:32"},"4":{p:15,k:2,b:"12:33",e:"12:36"},"5":{p:15,k:2,b:"12:37",e:"12:42"},"6":{p:15,k:2,b:"12:43",e:"12:47"},"7":{p:15,k:2,b:"12:48",e:"12:51"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach II":{haft:[{k:"II Kings",b:"23:1",e:"23:9"},{k:"II Kings",b:"23:21",e:"23:25"}],fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"28:16",e:"28:25"}}},"Pesach II (CH''M)":{note:"Israel only - according to Vaani T'fillati Siddur Yisraeli",fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:8"},"2":{p:31,k:3,b:"23:9",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:44"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 1":{fullkriyah:{"1":{p:15,k:2,b:"13:1",e:"13:4"},"2":{p:15,k:2,b:"13:5",e:"13:10"},"3":{p:15,k:2,b:"13:11",e:"13:16"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 2":{fullkriyah:{"1":{p:18,k:2,b:"22:24",e:"22:26"},"2":{p:18,k:2,b:"22:27",e:"23:5"},"3":{p:18,k:2,b:"23:6",e:"23:19"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 3":{fullkriyah:{"1":{p:21,k:2,b:"34:1",e:"34:10"},"2":{p:21,k:2,b:"34:11",e:"34:17"},"3":{p:21,k:2,b:"34:18",e:"34:26"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Chol ha-Moed Day 4":{fullkriyah:{"1":{p:36,k:4,b:"9:1",e:"9:5"},"2":{p:36,k:4,b:"9:6",e:"9:8"},"3":{p:36,k:4,b:"9:9",e:"9:14"},"4":{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach Shabbat Chol ha-Moed":{haft:{k:"Ezekiel",b:"37:1",e:"37:14"},fullkriyah:{"1":{p:21,k:2,b:"33:12",e:"33:16"},"2":{p:21,k:2,b:"33:17",e:"33:19"},"3":{p:21,k:2,b:"33:20",e:"33:23"},"4":{p:21,k:2,b:"34:1",e:"34:3"},"5":{p:21,k:2,b:"34:4",e:"34:10"},"6":{p:21,k:2,b:"34:11",e:"34:17"},"7":{p:21,k:2,b:"34:18",e:"34:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VII":{haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":{p:16,k:2,b:"13:17",e:"13:22"},"2":{p:16,k:2,b:"14:1",e:"14:8"},"3":{p:16,k:2,b:"14:9",e:"14:14"},"4":{p:16,k:2,b:"14:15",e:"14:25"},"5":{p:16,k:2,b:"14:26",e:"15:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VII (on Shabbat)":{haft:{k:"II Samuel",b:"22:1",e:"22:51"},fullkriyah:{"1":{p:16,k:2,b:"13:17",e:"13:19"},"2":{p:16,k:2,b:"13:20",e:"13:22"},"3":{p:16,k:2,b:"14:1",e:"14:4"},"4":{p:16,k:2,b:"14:5",e:"14:8"},"5":{p:16,k:2,b:"14:9",e:"14:14"},"6":{p:16,k:2,b:"14:15",e:"14:25"},"7":{p:16,k:2,b:"14:26",e:"15:26"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VIII":{haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:47,k:5,b:"15:19",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach VIII (on Shabbat)":{haft:{k:"Isaiah",b:"10:32",e:"12:6"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:19",e:"28:25"}}},"Pesach III (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 1"},"Pesach IV (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 2"},"Pesach V (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 3"},"Pesach VI (CH''M)":{alias:true,il:true,key:"Pesach Chol ha-Moed Day 4"},"Shavuot I":{haft:[{k:"Ezekiel",b:"1:1",e:"1:28"},{k:"Ezekiel",b:"3:12",e:"3:12"}],fullkriyah:{"1":{p:17,k:2,b:"19:1",e:"19:6"},"2":{p:17,k:2,b:"19:7",e:"19:13"},"3":{p:17,k:2,b:"19:14",e:"19:19"},"4":{p:17,k:2,b:"19:20",e:"20:14"},"5":{p:17,k:2,b:"20:15",e:"20:23"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Shavuot II":{haft:{k:"Habakkuk",b:"3:1",e:"3:19"},fullkriyah:{"1":{p:47,k:5,b:"15:19",e:"15:23"},"2":{p:47,k:5,b:"16:1",e:"16:3"},"3":{p:47,k:5,b:"16:4",e:"16:8"},"4":{p:47,k:5,b:"16:9",e:"16:12"},"5":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Shavuot II (on Shabbat)":{haft:{k:"Habakkuk",b:"3:1",e:"3:19"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"28:26",e:"28:31"}}},"Fast Day (Morning)":{fullkriyah:{"1":{p:21,k:2,b:"32:11",e:"32:14"},"2":{p:21,k:2,b:"34:1",e:"34:3"},"3":{p:21,k:2,b:"34:4",e:"34:10"}}},"Fast Day (Afternoon)":{haft:{k:"Isaiah",b:"55:6",e:"56:8"},fullkriyah:{"1":{p:21,k:2,b:"32:11",e:"32:14"},"2":{p:21,k:2,b:"34:1",e:"34:3"},M:{p:21,k:2,b:"34:4",e:"34:10"}}},"Asara B'Tevet":{alias:true,key:"Fast Day (Morning)"},"Ta'anit Bechorot":{alias:true,key:"Fast Day (Morning)"},"Ta'anit Esther":{alias:true,key:"Fast Day (Morning)"},"Tzom Gedaliah":{alias:true,key:"Fast Day (Morning)"},"Tzom Tammuz":{alias:true,key:"Fast Day (Morning)"},"Asara B'Tevet (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Ta'anit Bechorot (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Ta'anit Esther (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tzom Gedaliah (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tzom Tammuz (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Tish'a B'Av":{haft:{k:"Jeremiah",b:"8:13",e:"9:23"},fullkriyah:{"1":{p:45,k:5,b:"4:25",e:"4:29"},"2":{p:45,k:5,b:"4:30",e:"4:35"},"3":{p:45,k:5,b:"4:36",e:"4:40"}}},"Tish'a B'Av (Mincha)":{alias:true,key:"Fast Day (Afternoon)"},"Rosh Hashana I":{haft:{k:"I Samuel",b:"1:1",e:"2:10"},fullkriyah:{"1":{p:4,k:1,b:"21:1",e:"21:4"},"2":{p:4,k:1,b:"21:5",e:"21:12"},"3":{p:4,k:1,b:"21:13",e:"21:21"},"4":{p:4,k:1,b:"21:22",e:"21:27"},"5":{p:4,k:1,b:"21:28",e:"21:34"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Rosh Hashana I (on Shabbat)":{haft:{k:"I Samuel",b:"1:1",e:"2:10"},fullkriyah:{"1":{p:4,k:1,b:"21:1",e:"21:4"},"2":{p:4,k:1,b:"21:5",e:"21:8"},"3":{p:4,k:1,b:"21:9",e:"21:12"},"4":{p:4,k:1,b:"21:13",e:"21:17"},"5":{p:4,k:1,b:"21:18",e:"21:21"},"6":{p:4,k:1,b:"21:22",e:"21:27"},"7":{p:4,k:1,b:"21:28",e:"21:34"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Rosh Hashana II":{haft:{k:"Jeremiah",b:"31:1",e:"31:19"},fullkriyah:{"1":{p:4,k:1,b:"22:1",e:"22:3"},"2":{p:4,k:1,b:"22:4",e:"22:8"},"3":{p:4,k:1,b:"22:9",e:"22:14"},"4":{p:4,k:1,b:"22:15",e:"22:19"},"5":{p:4,k:1,b:"22:20",e:"22:24"},M:{p:41,k:4,b:"29:1",e:"29:6"}}},"Yom Kippur":{haft:{k:"Isaiah",b:"57:14",e:"58:14"},fullkriyah:{"1":{p:29,k:3,b:"16:1",e:"16:6"},"2":{p:29,k:3,b:"16:7",e:"16:11"},"3":{p:29,k:3,b:"16:12",e:"16:17"},"4":{p:29,k:3,b:"16:18",e:"16:24"},"5":{p:29,k:3,b:"16:25",e:"16:30"},"6":{p:29,k:3,b:"16:31",e:"16:34"},M:{p:41,k:4,b:"29:7",e:"29:11"}}},"Yom Kippur (on Shabbat)":{haft:{k:"Isaiah",b:"57:14",e:"58:14"},fullkriyah:{"1":{p:29,k:3,b:"16:1",e:"16:3"},"2":{p:29,k:3,b:"16:4",e:"16:6"},"3":{p:29,k:3,b:"16:7",e:"16:11"},"4":{p:29,k:3,b:"16:12",e:"16:17"},"5":{p:29,k:3,b:"16:18",e:"16:24"},"6":{p:29,k:3,b:"16:25",e:"16:30"},"7":{p:29,k:3,b:"16:31",e:"16:34"},M:{p:41,k:4,b:"29:7",e:"29:11"}}},"Yom Kippur (Mincha)":{alias:true,key:"Yom Kippur (Mincha, Traditional)"},"Yom Kippur (Mincha, Traditional)":{haft:[{k:"Jonah",b:"1:1",e:"4:11"},{k:"Micah",b:"7:18",e:"7:20"}],fullkriyah:{"1":{p:29,k:3,b:"18:1",e:"18:5"},"2":{p:29,k:3,b:"18:6",e:"18:21"},M:{p:29,k:3,b:"18:22",e:"18:30"}}},"Yom Kippur (Mincha, Alternate)":{haft:[{k:"Jonah",b:"1:1",e:"4:11"},{k:"Micah",b:"7:18",e:"7:20"}],fullkriyah:{"1":{p:30,k:3,b:"19:1",e:"19:4"},"2":{p:30,k:3,b:"19:5",e:"19:10"},M:{p:30,k:3,b:"19:11",e:"19:18"}}},"Sukkot I":{haft:{k:"Zechariah",b:"14:1",e:"14:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot I (on Shabbat)":{haft:{k:"Zechariah",b:"14:1",e:"14:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"22:33"},"2":{p:31,k:3,b:"23:1",e:"23:3"},"3":{p:31,k:3,b:"23:4",e:"23:8"},"4":{p:31,k:3,b:"23:9",e:"23:14"},"5":{p:31,k:3,b:"23:15",e:"23:22"},"6":{p:31,k:3,b:"23:23",e:"23:32"},"7":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot II":{haft:{k:"I Kings",b:"8:2",e:"8:21"},fullkriyah:{"1":{p:31,k:3,b:"22:26",e:"23:3"},"2":{p:31,k:3,b:"23:4",e:"23:14"},"3":{p:31,k:3,b:"23:15",e:"23:22"},"4":{p:31,k:3,b:"23:23",e:"23:32"},"5":{p:31,k:3,b:"23:33",e:"23:44"},M:{p:41,k:4,b:"29:12",e:"29:16"}}},"Sukkot Chol ha-Moed Day 1":{fullkriyah:{"1":{p:41,k:4,b:"29:17",e:"29:19"},"2":{p:41,k:4,b:"29:20",e:"29:22"},"3":{p:41,k:4,b:"29:23",e:"29:25"},"4":{p:41,k:4,b:"29:17",e:"29:22"}}},"Sukkot Chol ha-Moed Day 2":{fullkriyah:{"1":{p:41,k:4,b:"29:20",e:"29:22"},"2":{p:41,k:4,b:"29:23",e:"29:25"},"3":{p:41,k:4,b:"29:26",e:"29:28"},"4":{p:41,k:4,b:"29:20",e:"29:25"}}},"Sukkot Chol ha-Moed Day 3":{fullkriyah:{"1":{p:41,k:4,b:"29:23",e:"29:25"},"2":{p:41,k:4,b:"29:26",e:"29:28"},"3":{p:41,k:4,b:"29:29",e:"29:31"},"4":{p:41,k:4,b:"29:23",e:"29:28"}}},"Sukkot Chol ha-Moed Day 4":{fullkriyah:{"1":{p:41,k:4,b:"29:26",e:"29:28"},"2":{p:41,k:4,b:"29:29",e:"29:31"},"3":{p:41,k:4,b:"29:32",e:"29:34"},"4":{p:41,k:4,b:"29:26",e:"29:31"}}},"Sukkot Chol ha-Moed Day 5":{fullkriyah:{"1":{p:41,k:4,b:"29:29",e:"29:31"},"2":{p:41,k:4,b:"29:32",e:"29:34"},"3":{p:41,k:4,b:"29:35",e:"29:37"},"4":{p:41,k:4,b:"29:29",e:"29:34"}}},"Sukkot Shabbat Chol ha-Moed":{haft:{k:"Ezekiel",b:"38:18",e:"39:16"},fullkriyah:{"1":{p:21,k:2,b:"33:12",e:"33:16"},"2":{p:21,k:2,b:"33:17",e:"33:19"},"3":{p:21,k:2,b:"33:20",e:"33:23"},"4":{p:21,k:2,b:"34:1",e:"34:3"},"5":{p:21,k:2,b:"34:4",e:"34:10"},"6":{p:21,k:2,b:"34:11",e:"34:17"},"7":{p:21,k:2,b:"34:18",e:"34:26"},"M-day1":{p:41,k:4,b:"29:17",e:"29:22"},"M-day2":{p:41,k:4,b:"29:20",e:"29:25"},"M-day3":{p:41,k:4,b:"29:23",e:"29:28"},"M-day4":{p:41,k:4,b:"29:26",e:"29:31"},"M-day5":{p:41,k:4,b:"29:29",e:"29:34"}}},"Sukkot Final Day (Hoshana Raba)":{fullkriyah:{"1":{p:41,k:4,b:"29:26",e:"29:28"},"2":{p:41,k:4,b:"29:29",e:"29:31"},"3":{p:41,k:4,b:"29:32",e:"29:34"},"4":{p:41,k:4,b:"29:29",e:"29:34"}}},"Shmini Atzeret":{haft:{k:"I Kings",b:"8:54",e:"8:66"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"16:3"},"4":{p:47,k:5,b:"16:4",e:"16:8"},"5":{p:47,k:5,b:"16:9",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Shmini Atzeret (on Shabbat)":{haft:{k:"I Kings",b:"8:54",e:"8:66"},fullkriyah:{"1":{p:47,k:5,b:"14:22",e:"14:29"},"2":{p:47,k:5,b:"15:1",e:"15:18"},"3":{p:47,k:5,b:"15:19",e:"15:23"},"4":{p:47,k:5,b:"16:1",e:"16:3"},"5":{p:47,k:5,b:"16:4",e:"16:8"},"6":{p:47,k:5,b:"16:9",e:"16:12"},"7":{p:47,k:5,b:"16:13",e:"16:17"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Erev Simchat Torah":{fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"},"4":{p:54,k:5,b:"33:18",e:"33:21"},"5":{p:54,k:5,b:"33:22",e:"33:26"}}},"Simchat Torah":{haft:{k:"Joshua",b:"1:1",e:"1:18"},fullkriyah:{"1":{p:54,k:5,b:"33:1",e:"33:7"},"2":{p:54,k:5,b:"33:8",e:"33:12"},"3":{p:54,k:5,b:"33:13",e:"33:17"},"4":{p:54,k:5,b:"33:18",e:"33:21"},"5":{p:54,k:5,b:"33:22",e:"33:26"},"6":{p:54,k:5,b:"33:27",e:"34:12"},"7":{p:1,k:1,b:"1:1",e:"2:3"},M:{p:41,k:4,b:"29:35",e:"30:1"}}},"Shabbat Rosh Chodesh Chanukah":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:35,k:4,b:"7:42",e:"7:47"}}},"Chanukah Day 1":{fullkriyah:{"1":{p:35,k:4,b:"7:1",e:"7:11"},"2":{p:35,k:4,b:"7:12",e:"7:14"},"3":{p:35,k:4,b:"7:15",e:"7:17"}},alt:{"1":{p:35,k:4,b:"7:1",e:"7:3"},"2":{p:35,k:4,b:"7:4",e:"7:11"},"3":{p:35,k:4,b:"7:12",e:"7:17"}}},"Chanukah Day 1 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:1",e:"7:17"}}},"Chanukah Day 2":{fullkriyah:{"1":{p:35,k:4,b:"7:18",e:"7:20"},"2":{p:35,k:4,b:"7:21",e:"7:23"},"3":{p:35,k:4,b:"7:24",e:"7:29"}},alt:{"1":{p:35,k:4,b:"7:18",e:"7:20"},"2":{p:35,k:4,b:"7:21",e:"7:23"},"3":{p:35,k:4,b:"7:18",e:"7:23"}}},"Chanukah Day 2 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:18",e:"7:23"}}},"Chanukah Day 3":{fullkriyah:{"1":{p:35,k:4,b:"7:24",e:"7:26"},"2":{p:35,k:4,b:"7:27",e:"7:29"},"3":{p:35,k:4,b:"7:30",e:"7:35"}},alt:{"1":{p:35,k:4,b:"7:24",e:"7:26"},"2":{p:35,k:4,b:"7:27",e:"7:29"},"3":{p:35,k:4,b:"7:24",e:"7:29"}}},"Chanukah Day 3 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:24",e:"7:29"}}},"Chanukah Day 4":{fullkriyah:{"1":{p:35,k:4,b:"7:30",e:"7:32"},"2":{p:35,k:4,b:"7:33",e:"7:35"},"3":{p:35,k:4,b:"7:36",e:"7:41"}},alt:{"1":{p:35,k:4,b:"7:30",e:"7:32"},"2":{p:35,k:4,b:"7:33",e:"7:35"},"3":{p:35,k:4,b:"7:30",e:"7:35"}}},"Chanukah Day 4 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:30",e:"7:35"}}},"Chanukah Day 5":{fullkriyah:{"1":{p:35,k:4,b:"7:36",e:"7:38"},"2":{p:35,k:4,b:"7:39",e:"7:41"},"3":{p:35,k:4,b:"7:42",e:"7:47"}},alt:{"1":{p:35,k:4,b:"7:36",e:"7:38"},"2":{p:35,k:4,b:"7:39",e:"7:41"},"3":{p:35,k:4,b:"7:36",e:"7:41"}}},"Chanukah Day 5 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:36",e:"7:41"}}},"Chanukah Day 6":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:5"},"2":{p:41,k:4,b:"28:6",e:"28:10"},"3":{p:41,k:4,b:"28:11",e:"28:15"},"4":{p:35,k:4,b:"7:42",e:"7:47"}}},"Chanukah Day 7":{fullkriyah:{"1":{p:35,k:4,b:"7:48",e:"7:50"},"2":{p:35,k:4,b:"7:51",e:"7:53"},"3":{p:35,k:4,b:"7:54",e:"7:59"}},alt:{"1":{p:35,k:4,b:"7:48",e:"7:50"},"2":{p:35,k:4,b:"7:51",e:"7:53"},"3":{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 7 (on Rosh Chodesh)":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:5"},"2":{p:41,k:4,b:"28:6",e:"28:10"},"3":{p:41,k:4,b:"28:11",e:"28:15"},"4":{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 7 (on Shabbat)":{haft:{k:"Zechariah",b:"2:14",e:"4:7"},fullkriyah:{M:{p:35,k:4,b:"7:48",e:"7:53"}}},"Chanukah Day 8":{fullkriyah:{"1":{p:35,k:4,b:"7:54",e:"7:56"},"2":{p:35,k:4,b:"7:57",e:"7:59"},"3":{p:35,k:4,b:"7:60",e:"8:4"}}},"Chanukah Day 8 (on Shabbat)":{haft:{k:"I Kings",b:"7:40",e:"7:50"},fullkriyah:{M:{p:35,k:4,b:"7:54",e:"8:4"}}},Purim:Purim,"Shushan Purim":{fullkriyah:{"1":{p:16,k:2,b:"17:8",e:"17:10"},"2":{p:16,k:2,b:"17:11",e:"17:13"},"3":{p:16,k:2,b:"17:14",e:"17:16"}}},"Shushan Purim (on Shabbat)":{note:"Jerusalem & walled cities only: special maftir Exodus 17:8-16, same Haftara as Shabbat Zachor"},"Shabbat HaChodesh":{haft:{k:"Ezekiel",b:"45:16",e:"46:18"},fullkriyah:{M:{p:15,k:2,b:"12:1",e:"12:20"}}},"Shabbat HaChodesh (on Rosh Chodesh)":{haft:{k:"Ezekiel",b:"45:16",e:"46:18"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:15,k:2,b:"12:1",e:"12:20"}}},"Shabbat HaGadol":{haft:{k:"Malachi",b:"3:4",e:"3:24"}},"Shabbat Parah":{haft:{k:"Ezekiel",b:"36:16",e:"36:38"},fullkriyah:{M:{p:39,k:4,b:"19:1",e:"19:22"}}},"Shabbat Shekalim":{haft:{k:"II Kings",b:"12:1",e:"12:17"},fullkriyah:{M:{p:21,k:2,b:"30:11",e:"30:16"}}},"Shabbat Shekalim (on Rosh Chodesh)":{haft:{k:"II Kings",b:"12:1",e:"12:17"},fullkriyah:{"7":{p:41,k:4,b:"28:9",e:"28:15"},M:{p:21,k:2,b:"30:11",e:"30:16"}}},"Shabbat Shuva (with Vayeilech)":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"}]},"Shabbat Shuva (with Ha'Azinu)":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Joel",b:"2:15",e:"2:27"}],seph:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"}]},"Shabbat Shuva":{haft:[{k:"Hosea",b:"14:2",e:"14:10"},{k:"Micah",b:"7:18",e:"7:20"},{k:"Joel",b:"2:15",e:"2:27"}]},"Shabbat Zachor":{haft:{k:"I Samuel",b:"15:2",e:"15:34"},fullkriyah:{M:{p:49,k:5,b:"25:17",e:"25:19"}}},"Pinchas occurring after 17 Tammuz":{haft:{k:"Jeremiah",b:"1:1",e:"2:3"}},"Masei on Shabbat Rosh Chodesh":{haft:[{k:"Jeremiah",b:"2:4",e:"2:28"},{k:"Jeremiah",b:"3:4",e:"3:4"},{k:"Isaiah",b:"66:1",e:"66:1"},{k:"Isaiah",b:"66:23",e:"66:23"}]},"Matot-Masei on Shabbat Rosh Chodesh":{alias:true,key:"Masei on Shabbat Rosh Chodesh"},"Rosh Chodesh":{fullkriyah:{"1":{p:41,k:4,b:"28:1",e:"28:3"},"2":{p:41,k:4,b:"28:3",e:"28:5"},"3":{p:41,k:4,b:"28:6",e:"28:10"},"4":{p:41,k:4,b:"28:11",e:"28:15"}}},"Rosh Chodesh Nisan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Iyyar":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Sivan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Tamuz":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Av":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Elul":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Tishrei":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Cheshvan":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Kislev":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Sh'vat":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar I":{alias:true,key:"Rosh Chodesh"},"Rosh Chodesh Adar II":{alias:true,key:"Rosh Chodesh"},"Shabbat Rosh Chodesh":{haft:{k:"Isaiah",b:"66:1",e:"66:24"},fullkriyah:{M:{p:41,k:4,b:"28:9",e:"28:15"}}},"Shabbat Machar Chodesh":{haft:{k:"I Samuel",b:"20:18",e:"20:42"}}};
252
224
 
253
225
  /**
254
226
  * Is there a special festival Torah Reading for `holiday`?
255
227
  * @param {string} holiday
256
228
  * @return {boolean}
257
229
  */
258
-
259
230
  function hasFestival(holiday) {
260
231
  return typeof festivals[holiday] === 'object';
261
232
  }
233
+
262
234
  /**
263
235
  * Returns the raw metadata for festival reading for `holiday`
264
236
  * @param {string} holiday
265
237
  * @return {any}
266
238
  */
267
-
268
239
  function lookupFestival(holiday) {
269
240
  let src = festivals[holiday];
270
-
271
241
  if (typeof src === 'undefined') {
272
242
  return undefined;
273
243
  }
274
-
275
244
  if (src.alias) {
276
245
  const tmp = festivals[src.key];
277
-
278
246
  if (typeof tmp === 'undefined') {
279
247
  throw new Error(`Leyning alias ${holiday} => ${src.key} not found`);
280
248
  }
281
-
282
249
  src = tmp;
283
250
  }
284
-
285
251
  const result = src.fullkriyah ? clone(src) : src;
286
-
287
252
  if (result.fullkriyah) {
288
253
  Object.values(result.fullkriyah).forEach(aliyah => {
289
254
  if (typeof aliyah.k === 'number') {
@@ -291,32 +256,27 @@ function lookupFestival(holiday) {
291
256
  }
292
257
  });
293
258
  }
294
-
295
259
  return result;
296
260
  }
297
261
 
298
- const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI | flags.OMER_COUNT | flags.SHABBAT_MEVARCHIM | flags.MOLAD | flags.USER_EVENT | flags.HEBREW_DATE | flags.MISHNA_YOMI | flags.MODERN_HOLIDAY;
262
+ const HOLIDAY_IGNORE_MASK = flags.DAF_YOMI | flags.OMER_COUNT | flags.SHABBAT_MEVARCHIM | flags.MOLAD | flags.USER_EVENT | flags.HEBREW_DATE | flags.MISHNA_YOMI | flags.MODERN_HOLIDAY | flags.YERUSHALMI_YOMI;
263
+
299
264
  /**
300
265
  * Based on the event date, type and title, finds the relevant leyning key
301
266
  * @param {Event} ev event
302
267
  * @param {boolean} [il] true if Israel holiday scheme
303
268
  * @return {string} key to look up in holiday-reading.json
304
269
  */
305
-
306
270
  function getLeyningKeyForEvent(ev, il = false) {
307
271
  const mask = ev.getFlags();
308
-
309
272
  if (mask & HOLIDAY_IGNORE_MASK) {
310
273
  return undefined;
311
- } // Skip all Erevs except for Simchat Torah
312
-
313
-
274
+ }
275
+ // Skip all Erevs except for Simchat Torah
314
276
  const desc = ev.getDesc();
315
-
316
277
  if (mask & flags.EREV && desc !== 'Erev Simchat Torah') {
317
278
  return undefined;
318
279
  }
319
-
320
280
  const hd = ev.getDate();
321
281
  const day = hd.getDate();
322
282
  const dow = hd.abs() % 7;
@@ -325,15 +285,12 @@ function getLeyningKeyForEvent(ev, il = false) {
325
285
  const isRoshChodesh = day == 1 || day == 30;
326
286
  const holiday = ev.basename();
327
287
  const isPesach = holiday === 'Pesach';
328
-
329
288
  if (il && isPesach) {
330
289
  if (isShabbat) {
331
290
  return day === 15 || day === 21 ? desc + ' (on Shabbat)' : 'Pesach Shabbat Chol ha-Moed';
332
291
  }
333
-
334
292
  return desc;
335
293
  }
336
-
337
294
  if (day == 1 && month === months.TISHREI) {
338
295
  return isShabbat ? 'Rosh Hashana I (on Shabbat)' : 'Rosh Hashana I';
339
296
  } else if (ev.cholHaMoedDay) {
@@ -342,12 +299,10 @@ function getLeyningKeyForEvent(ev, il = false) {
342
299
  return holiday + ' Shabbat Chol ha-Moed';
343
300
  } else if (desc == 'Sukkot VII (Hoshana Raba)') {
344
301
  return 'Sukkot Final Day (Hoshana Raba)';
345
- } // If Shabbat falls on the third day of Chol ha-Moed Pesach,
302
+ }
303
+ // If Shabbat falls on the third day of Chol ha-Moed Pesach,
346
304
  // the readings for the third, fourth, and fifth days are moved ahead
347
-
348
-
349
305
  let cholHaMoedDay = ev.cholHaMoedDay;
350
-
351
306
  if (isPesach && cholHaMoedDay >= 3) {
352
307
  if (dow == 0 && cholHaMoedDay == 4) {
353
308
  cholHaMoedDay = 3;
@@ -355,7 +310,6 @@ function getLeyningKeyForEvent(ev, il = false) {
355
310
  cholHaMoedDay = 4;
356
311
  }
357
312
  }
358
-
359
313
  return `${holiday} Chol ha-Moed Day ${cholHaMoedDay}`;
360
314
  } else if (ev.chanukahDay) {
361
315
  if (isShabbat && isRoshChodesh) {
@@ -368,54 +322,42 @@ function getLeyningKeyForEvent(ev, il = false) {
368
322
  return `Chanukah Day ${ev.chanukahDay}`;
369
323
  }
370
324
  }
371
-
372
325
  if (isRoshChodesh && (desc == 'Shabbat HaChodesh' || desc == 'Shabbat Shekalim')) {
373
326
  return desc + ' (on Rosh Chodesh)';
374
327
  }
375
-
376
328
  if (desc == 'Shavuot') {
377
329
  return 'Shavuot I';
378
330
  } else if (il && desc == 'Shmini Atzeret') {
379
331
  return 'Simchat Torah';
380
332
  }
381
-
382
333
  if (isShabbat && 'Shabbat' != desc.substring(0, 7)) {
383
334
  if (isRoshChodesh) {
384
335
  if (desc === 'Rosh Chodesh Tevet') {
385
336
  return 'Shabbat Rosh Chodesh Chanukah';
386
337
  }
387
-
388
338
  return 'Shabbat Rosh Chodesh';
389
339
  }
390
-
391
340
  const desc2 = desc + ' (on Shabbat)';
392
-
393
341
  if (hasFestival(desc2)) {
394
342
  return desc2;
395
343
  }
396
344
  }
397
-
398
345
  if (hasFestival(desc)) {
399
346
  return desc;
400
347
  }
401
-
402
348
  if (isShabbat) {
403
349
  const tommorow = hd.next().getDate();
404
-
405
350
  if (tommorow === 30 || tommorow === 1) {
406
351
  return 'Shabbat Machar Chodesh';
407
352
  }
408
353
  }
409
-
410
354
  if (desc === 'Rosh Hashana LaBehemot') {
411
355
  return undefined;
412
356
  }
413
-
414
357
  if (desc === 'Rosh Chodesh Tevet') {
415
358
  if (isShabbat) {
416
359
  return 'Shabbat Rosh Chodesh Chanukah';
417
360
  }
418
-
419
361
  if (day === 30 || HDate.shortKislev(hd.getFullYear())) {
420
362
  return 'Chanukah Day 6'; // 30th of Kislev or 1st of Tevet
421
363
  } else {
@@ -426,11 +368,9 @@ function getLeyningKeyForEvent(ev, il = false) {
426
368
  if (isRoshChodesh) {
427
369
  return desc;
428
370
  }
429
-
430
371
  if (desc === 'Tish\'a B\'Av (observed)') {
431
372
  return 'Tish\'a B\'Av';
432
373
  }
433
-
434
374
  return undefined;
435
375
  }
436
376
 
@@ -438,45 +378,40 @@ function getLeyningKeyForEvent(ev, il = false) {
438
378
  * @private
439
379
  * @param {Object<string,Aliyah>} aliyot
440
380
  */
441
-
442
381
  function aliyotCombine67(aliyot) {
443
382
  const a6 = clone(aliyot['6']);
444
383
  const a7 = aliyot['7'];
445
-
446
384
  if (a6.k !== a7.k) {
447
385
  throw new Error('Impossible to combine aliyot 6 & 7: ' + JSON.stringify(aliyot));
448
386
  }
449
-
450
387
  delete aliyot['7'];
451
388
  aliyot['6'] = {
452
389
  k: a6.k,
453
390
  b: a6.b,
454
391
  e: a7.e
455
392
  };
456
-
457
393
  if (a6.v && a7.v) {
458
394
  aliyot['6'].v = a6.v + a7.v;
459
395
  }
460
396
  }
397
+
461
398
  /**
462
399
  * @private
463
400
  * @param {Object<string,Aliyah>} aliyot
464
401
  * @param {Object<string,Aliyah>} special
465
402
  */
466
-
467
-
468
403
  function mergeAliyotWithSpecial(aliyot, special) {
469
404
  if (special['7']) {
470
405
  aliyotCombine67(aliyot);
471
406
  aliyot['7'] = clone(special['7']);
472
407
  calculateNumVerses(aliyot['7']);
473
408
  }
474
-
475
409
  if (special['M']) {
476
410
  aliyot['M'] = clone(special['M']);
477
411
  calculateNumVerses(aliyot['M']);
478
412
  }
479
413
  }
414
+
480
415
  /**
481
416
  * Determines if the regular parashat haShavua coincides with an event that requires
482
417
  * a special maftir or Haftara (for example Shabbat HaGadol, Shabbat Chanukah, Rosh
@@ -495,38 +430,32 @@ function mergeAliyotWithSpecial(aliyot, special) {
495
430
  * @param {boolean} [wantSeph]
496
431
  * @return {Aliyah | Aliyah[]}
497
432
  */
498
-
499
-
500
433
  function specialReadings(hd, il, aliyot, reason, parsha, wantSeph = false) {
501
434
  let haft;
502
435
  let seph;
503
436
  let specialHaft = false;
504
- const parshaName = parsha ? parshaToString(parsha) : null; // eslint-disable-next-line require-jsdoc
437
+ const parshaName = parsha ? parshaToString(parsha) : null;
505
438
 
439
+ // eslint-disable-next-line require-jsdoc
506
440
  function handleSpecial(key) {
507
441
  const special = lookupFestival(key);
508
-
509
442
  if (!special) {
510
443
  return;
511
444
  }
512
-
513
445
  if (special.haft && !specialHaft) {
514
446
  haft = cloneHaftara(special.haft);
515
447
  reason.haftara = key;
516
448
  specialHaft = true;
517
-
518
449
  if (special.seph) {
519
450
  seph = cloneHaftara(special.seph);
520
451
  reason.sephardic = key;
521
452
  }
522
453
  }
523
-
524
454
  if (special.fullkriyah) {
525
455
  mergeAliyotWithSpecial(aliyot, special.fullkriyah);
526
456
  Object.keys(special.fullkriyah).map(k => reason[k] = key);
527
457
  }
528
458
  }
529
-
530
459
  const events0 = HebrewCalendar.getHolidaysOnDate(hd, il) || [];
531
460
  const events = events0.filter(ev => !(ev.getFlags() & flags.ROSH_CHODESH));
532
461
  events.forEach(ev => {
@@ -534,16 +463,13 @@ function specialReadings(hd, il, aliyot, reason, parsha, wantSeph = false) {
534
463
  handleSpecial(`Shabbat Shuva (with ${parshaName})`);
535
464
  } else {
536
465
  const key = getLeyningKeyForEvent(ev, il);
537
-
538
466
  if (key) {
539
467
  handleSpecial(key);
540
468
  }
541
469
  }
542
470
  });
543
-
544
471
  if (!haft) {
545
472
  const day = hd.getDate();
546
-
547
473
  if (parshaName === 'Pinchas' && day > 17) {
548
474
  // Pinchas is always read in Tamuz (never another month)
549
475
  // either on the 14, 16, 17 (in Israel), 19, 21, 23, 24
@@ -553,13 +479,11 @@ function specialReadings(hd, il, aliyot, reason, parsha, wantSeph = false) {
553
479
  handleSpecial(key);
554
480
  } else {
555
481
  const tommorow = hd.next().getDate();
556
-
557
482
  if (tommorow === 30 || tommorow === 1) {
558
483
  handleSpecial('Shabbat Machar Chodesh');
559
484
  }
560
485
  }
561
486
  }
562
-
563
487
  if (wantSeph && haft) {
564
488
  return {
565
489
  haft,
@@ -618,7 +542,6 @@ const Bereshit={num:1,hebrew:"בְּרֵאשִׁית",book:1,haft:{k:"Isaiah",b:
618
542
  * @param {boolean} [il] true if Israel holiday scheme
619
543
  * @return {Leyning} map of aliyot
620
544
  */
621
-
622
545
  function getLeyningForHoliday(ev, il = false) {
623
546
  if (typeof ev !== 'object' || !(ev instanceof Event)) {
624
547
  throw new TypeError(`Bad event argument: ${ev}`);
@@ -627,11 +550,11 @@ function getLeyningForHoliday(ev, il = false) {
627
550
  } else if (ev.getFlags() & HOLIDAY_IGNORE_MASK) {
628
551
  return undefined;
629
552
  }
630
-
631
553
  const key = getLeyningKeyForEvent(ev, il);
632
554
  const leyning = getLeyningForHolidayKey(key, ev.cholHaMoedDay);
633
555
  return leyning;
634
556
  }
557
+
635
558
  /**
636
559
  * Looks up leyning for a given holiday key. Key should be an
637
560
  * (untranslated) string used in holiday-readings.json. Returns some
@@ -640,62 +563,50 @@ function getLeyningForHoliday(ev, il = false) {
640
563
  * @param {number} [cholHaMoedDay]
641
564
  * @return {Leyning} map of aliyot
642
565
  */
643
-
644
566
  function getLeyningForHolidayKey(key, cholHaMoedDay) {
645
567
  if (typeof key !== 'string') {
646
568
  return undefined;
647
569
  }
648
-
649
570
  const src = lookupFestival(key);
650
-
651
571
  if (typeof src === 'undefined') {
652
572
  return undefined;
653
573
  }
654
-
655
574
  const leyning = {
656
575
  name: {
657
576
  en: key,
658
577
  he: Locale.lookupTranslation(key, 'he')
659
578
  }
660
579
  };
661
-
662
580
  if (src.fullkriyah) {
663
581
  leyning.fullkriyah = clone(src.fullkriyah);
664
-
665
582
  if (key === 'Sukkot Shabbat Chol ha-Moed' && cholHaMoedDay) {
666
583
  leyning.fullkriyah['M'] = leyning.fullkriyah[`M-day${cholHaMoedDay}`];
667
-
668
584
  for (let day = 1; day <= 5; day++) {
669
585
  delete leyning.fullkriyah[`M-day${day}`];
670
586
  }
671
587
  }
672
-
673
588
  if (typeof leyning.fullkriyah['1'] === 'object') {
674
589
  const parts = makeLeyningParts(leyning.fullkriyah);
675
590
  leyning.summary = makeSummaryFromParts(parts);
676
-
677
591
  if (parts.length > 1) {
678
592
  leyning.summaryParts = parts;
679
593
  }
680
594
  }
681
-
682
595
  Object.values(leyning.fullkriyah).map(aliyah => calculateNumVerses(aliyah));
683
596
  }
684
-
685
597
  if (src.haft) {
686
598
  const haft = leyning.haft = cloneHaftara(src.haft);
687
599
  leyning.haftara = makeSummaryFromParts(haft);
688
600
  leyning.haftaraNumV = sumVerses(haft);
689
601
  }
690
-
691
602
  if (src.seph) {
692
603
  const seph = leyning.seph = cloneHaftara(src.seph);
693
604
  leyning.sephardic = makeSummaryFromParts(seph);
694
605
  leyning.sephardicNumV = sumVerses(seph);
695
606
  }
696
-
697
607
  return leyning;
698
608
  }
609
+
699
610
  /**
700
611
  * on doubled parshiot, read only the second Haftarah
701
612
  * except for Nitzavim-Vayelech
@@ -703,7 +614,6 @@ function getLeyningForHolidayKey(key, cholHaMoedDay) {
703
614
  * @param {string[]} parsha
704
615
  * @return {string}
705
616
  */
706
-
707
617
  function getHaftaraKey(parsha) {
708
618
  if (parsha.length == 1 || parsha[0] == 'Nitzavim') {
709
619
  return parsha[0];
@@ -711,20 +621,17 @@ function getHaftaraKey(parsha) {
711
621
  return parsha[1];
712
622
  }
713
623
  }
624
+
714
625
  /**
715
626
  * Looks up regular leyning for a weekly parsha with no special readings
716
627
  * @param {string|string[]} parsha untranslated name like 'Pinchas' or ['Pinchas'] or ['Matot','Masei']
717
628
  * @return {Leyning} map of aliyot
718
629
  */
719
-
720
-
721
630
  function getLeyningForParsha(parsha) {
722
631
  const isParshaString = typeof parsha === 'string';
723
-
724
632
  if (!isParshaString && (!Array.isArray(parsha) || parsha.length !== 1 && parsha.length !== 2)) {
725
633
  throw new TypeError(`Bad parsha argument: ${parsha}`);
726
634
  }
727
-
728
635
  const name = isParshaString ? parsha : parshaToString(parsha);
729
636
  const raw = parshiyotObj[name];
730
637
  const fullkriyah = {};
@@ -743,7 +650,6 @@ function getLeyningForParsha(parsha) {
743
650
  const parts = makeLeyningParts(fullkriyah);
744
651
  const summary = makeSummaryFromParts(parts);
745
652
  /** @type {Leyning} */
746
-
747
653
  const result = {
748
654
  name: {
749
655
  en: name,
@@ -754,28 +660,22 @@ function getLeyningForParsha(parsha) {
754
660
  summary,
755
661
  fullkriyah: fullkriyah
756
662
  };
757
-
758
663
  if (parts.length > 1) {
759
664
  result.summaryParts = parts;
760
665
  }
761
-
762
666
  const hkey = getHaftaraKey(parshaNameArray);
763
667
  const haft0 = parshiyotObj[hkey].haft;
764
-
765
668
  if (haft0) {
766
669
  const haft = result.haft = cloneHaftara(haft0);
767
670
  result.haftara = makeSummaryFromParts(haft);
768
671
  result.haftaraNumV = sumVerses(haft);
769
672
  }
770
-
771
673
  if (raw.seph) {
772
674
  const seph = result.seph = cloneHaftara(raw.seph);
773
675
  result.sephardic = makeSummaryFromParts(seph);
774
676
  result.sephardicNumV = sumVerses(seph);
775
677
  }
776
-
777
678
  const weekdaySrc = raw.weekday || parshiyotObj[parshaNameArray[0]].weekday;
778
-
779
679
  if (weekdaySrc) {
780
680
  const weekday = result.weekday = {};
781
681
  ['1', '2', '3'].forEach(num => {
@@ -789,9 +689,9 @@ function getLeyningForParsha(parsha) {
789
689
  weekday[num] = aliyah;
790
690
  });
791
691
  }
792
-
793
692
  return result;
794
693
  }
694
+
795
695
  /**
796
696
  * Looks up leyning for a regular Shabbat parsha, including any special
797
697
  * maftir or Haftara.
@@ -799,42 +699,35 @@ function getLeyningForParsha(parsha) {
799
699
  * @param {boolean} [il] in Israel
800
700
  * @return {Leyning} map of aliyot
801
701
  */
802
-
803
702
  function getLeyningForParshaHaShavua(ev, il = false) {
804
703
  if (!ev instanceof Event) {
805
704
  throw new TypeError(`Bad event argument: ${ev}`);
806
705
  } else if (ev.getFlags() != flags.PARSHA_HASHAVUA) {
807
706
  throw new TypeError(`Event must be parsha hashavua: ${ev.getDesc()}`);
808
- } // first, collect the default aliyot and haftara
809
-
810
-
707
+ }
708
+ // first, collect the default aliyot and haftara
811
709
  const parsha = ev.parsha;
812
710
  const result = getLeyningForParsha(parsha);
813
711
  const reason = {};
814
- const hd = ev.getDate(); // Now, check for special maftir or haftara on same date
815
-
712
+ const hd = ev.getDate();
713
+ // Now, check for special maftir or haftara on same date
816
714
  const specialHaftara = specialReadings(hd, il, result.fullkriyah, reason, parsha, true);
817
-
818
715
  if (specialHaftara) {
819
716
  const haft = result.haft = cloneHaftara(specialHaftara.haft);
820
717
  result.haftara = makeSummaryFromParts(haft);
821
718
  result.haftaraNumV = sumVerses(haft);
822
-
823
719
  if (specialHaftara.seph) {
824
720
  const seph = result.seph = cloneHaftara(specialHaftara.seph);
825
721
  result.sephardic = makeSummaryFromParts(seph);
826
722
  result.sephardicNumV = sumVerses(seph);
827
723
  }
828
724
  }
829
-
830
725
  if (reason['7'] || reason['M']) {
831
726
  const parts = makeLeyningParts(result.fullkriyah);
832
727
  result.summary = makeSummaryFromParts(parts);
833
728
  result.summaryParts = parts;
834
729
  }
835
-
836
730
  const reasons = Object.keys(reason);
837
-
838
731
  if (reasons.length !== 0) {
839
732
  result.reason = reason;
840
733
  reasons.forEach(num => {
@@ -844,18 +737,17 @@ function getLeyningForParshaHaShavua(ev, il = false) {
844
737
  hafts.forEach(haft => haft.reason = reason[num]);
845
738
  } else {
846
739
  const aliyah = result.fullkriyah[num];
847
-
848
740
  if (typeof aliyah === 'object') {
849
741
  aliyah.reason = reason[num];
850
742
  }
851
743
  }
852
744
  });
853
- } // to avoid confusion, don't include Saturday mincha reading here
854
-
855
-
745
+ }
746
+ // to avoid confusion, don't include Saturday mincha reading here
856
747
  delete result.weekday;
857
748
  return result;
858
749
  }
750
+
859
751
  /**
860
752
  * Looks up leyning for a regular Shabbat, Monday/Thursday weekday or holiday.
861
753
  *
@@ -873,28 +765,22 @@ function getLeyningForParshaHaShavua(ev, il = false) {
873
765
  * @param {boolean} il in Israel
874
766
  * @return {Leyning} map of aliyot
875
767
  */
876
-
877
768
  function getLeyningOnDate(hdate, il) {
878
769
  const dow = hdate.getDay();
879
770
  const hyear = hdate.getFullYear();
880
771
  const sedra = HebrewCalendar.getSedra(hyear, il);
881
772
  const parsha = sedra.lookup(hdate);
882
-
883
773
  if (dow === 6 && !parsha.chag) {
884
774
  const parshaEvent = new ParshaEvent(hdate, parsha.parsha, il);
885
775
  return getLeyningForParshaHaShavua(parshaEvent, il);
886
776
  }
887
-
888
777
  const events = HebrewCalendar.getHolidaysOnDate(hdate, il) || [];
889
-
890
778
  for (let i = 0; i < events.length; i++) {
891
779
  const reading = getLeyningForHoliday(events[i], il);
892
-
893
780
  if (reading) {
894
781
  return reading;
895
782
  }
896
783
  }
897
-
898
784
  if (dow === 1 || dow === 4) {
899
785
  const saturday = hdate.onOrAfter(6);
900
786
  const parsha2 = findParshaHaShavua(saturday);
@@ -906,44 +792,38 @@ function getLeyningOnDate(hdate, il) {
906
792
  weekday: reading.weekday
907
793
  };
908
794
  return result;
909
- } // no reading today: it's not Shabbat, Mon/Thu, or a Torah-reading holiday
910
-
911
-
795
+ }
796
+ // no reading today: it's not Shabbat, Mon/Thu, or a Torah-reading holiday
912
797
  return undefined;
913
798
  }
799
+
914
800
  /**
915
801
  * @private
916
802
  * @param {HDate} saturday
917
803
  * @param {boolean} il
918
804
  * @return {Leyning}
919
805
  */
920
-
921
806
  function findParshaHaShavua(saturday, il) {
922
807
  const hyear = saturday.getFullYear();
923
808
  const sedra = HebrewCalendar.getSedra(hyear, il);
924
809
  const parsha = sedra.lookup(saturday);
925
-
926
810
  if (!parsha.chag) {
927
811
  return parsha;
928
- } // Search for next regular parsha, which could even spill into next year
929
-
930
-
812
+ }
813
+ // Search for next regular parsha, which could even spill into next year
931
814
  const endOfYear = new HDate(1, months.TISHREI, hyear + 1).abs() - 1;
932
815
  const endAbs = endOfYear + 30;
933
-
934
816
  for (let sat2 = saturday.abs() + 7; sat2 <= endAbs; sat2 += 7) {
935
817
  const sedra2 = sat2 > endOfYear ? HebrewCalendar.getSedra(hyear + 1, il) : sedra;
936
818
  const parsha2 = sedra2.lookup(sat2);
937
-
938
819
  if (!parsha2.chag) {
939
820
  return parsha2;
940
821
  }
941
822
  }
942
823
  /* NOTREACHED */
943
-
944
-
945
824
  return null;
946
825
  }
826
+
947
827
  /**
948
828
  * Parsha metadata
949
829
  * @typedef {Object} ParshaMeta
@@ -962,22 +842,16 @@ function findParshaHaShavua(saturday, il) {
962
842
  * @param {string|string[]} parsha
963
843
  * @return {ParshaMeta}
964
844
  */
965
-
966
-
967
845
  function lookupParsha(parsha) {
968
846
  const isParshaString = typeof parsha === 'string';
969
-
970
847
  if (!isParshaString && (!Array.isArray(parsha) || parsha.length !== 1 && parsha.length !== 2)) {
971
848
  throw new TypeError(`Bad parsha argument: ${parsha}`);
972
849
  }
973
-
974
850
  const name = isParshaString ? parsha : parshaToString(parsha);
975
851
  const raw = parshiyotObj[name];
976
-
977
852
  if (typeof raw !== 'object') {
978
853
  throw new TypeError(`Bad parsha argument: ${parsha}`);
979
854
  }
980
-
981
855
  return raw;
982
856
  }
983
857
 
@@ -986,23 +860,22 @@ const fmt = new Intl.DateTimeFormat('en-US', {
986
860
  month: 'short',
987
861
  day: '2-digit'
988
862
  });
863
+
989
864
  /**
990
865
  * @private
991
866
  * @param {Date} dt
992
867
  * @return {string}
993
868
  */
994
-
995
869
  function fmtDate(dt) {
996
870
  const s = fmt.format(dt).split(' ');
997
871
  return s[1].substring(0, 2) + '-' + s[0] + '-' + s[2];
998
872
  }
873
+
999
874
  /**
1000
875
  * @private
1001
876
  * @param {Event[]} events
1002
877
  * @return {Object<string,boolean>}
1003
878
  */
1004
-
1005
-
1006
879
  function getParshaDates(events) {
1007
880
  const parshaEvents = events.filter(ev => ev.getFlags() === flags.PARSHA_HASHAVUA);
1008
881
  const parshaDates = parshaEvents.reduce((set, ev) => {
@@ -1011,13 +884,13 @@ function getParshaDates(events) {
1011
884
  }, {});
1012
885
  return parshaDates;
1013
886
  }
887
+
1014
888
  /**
1015
889
  * @private
1016
890
  * @param {fs.WriteStream} stream
1017
891
  * @param {number} hyear
1018
892
  * @param {boolean} il
1019
893
  */
1020
-
1021
894
  function writeFullKriyahCsv(stream, hyear, il) {
1022
895
  const events0 = HebrewCalendar.calendar({
1023
896
  year: hyear,
@@ -1034,68 +907,61 @@ function writeFullKriyahCsv(stream, hyear, il) {
1034
907
  }
1035
908
  });
1036
909
  }
910
+
1037
911
  /**
1038
912
  * @private
1039
913
  * @param {Event} ev
1040
914
  * @return {boolean}
1041
915
  */
1042
-
1043
916
  function ignore(ev) {
1044
917
  const mask = ev.getFlags();
1045
-
1046
918
  if (mask === flags.SPECIAL_SHABBAT) {
1047
919
  return true;
1048
920
  }
1049
-
1050
921
  if (mask !== flags.ROSH_CHODESH) {
1051
922
  return false;
1052
923
  }
1053
-
1054
924
  return ev.getDate().getDay() === 6;
1055
925
  }
926
+
1056
927
  /**
1057
928
  * @private
1058
929
  * @param {fs.WriteStream} stream
1059
930
  * @param {Event} ev
1060
931
  * @param {boolean} il
1061
932
  */
1062
-
1063
-
1064
933
  function writeFullKriyahEvent(stream, ev, il) {
1065
934
  if (ignore(ev)) {
1066
935
  return;
1067
936
  }
1068
-
1069
937
  const mask = ev.getFlags();
1070
938
  const isParsha = mask === flags.PARSHA_HASHAVUA;
1071
939
  const reading = isParsha ? getLeyningForParshaHaShavua(ev, il) : getLeyningForHoliday(ev, il);
1072
-
1073
940
  if (reading) {
1074
941
  writeCsvLines(stream, ev, reading, il, isParsha);
1075
-
1076
942
  if (!isParsha) {
1077
943
  writeHolidayMincha(stream, ev, il);
1078
944
  }
1079
945
  }
1080
946
  }
947
+
1081
948
  /**
1082
949
  * @private
1083
950
  * @param {fs.WriteStream} stream
1084
951
  * @param {Event} ev
1085
952
  * @param {boolean} il
1086
953
  */
1087
-
1088
954
  function writeHolidayMincha(stream, ev, il) {
1089
955
  const desc = ev.getDesc();
1090
956
  const minchaDesc1 = desc + ' (Mincha)';
1091
957
  const readingMincha1 = getLeyningForHolidayKey(minchaDesc1);
1092
958
  const readingMincha = readingMincha1 || getLeyningForHolidayKey(getLeyningKeyForEvent(ev, il) + ' (Mincha)');
1093
-
1094
959
  if (readingMincha) {
1095
960
  const minchaEv = new Event(ev.getDate(), minchaDesc1, flags.USER_EVENT);
1096
961
  writeCsvLines(stream, minchaEv, readingMincha, il, false);
1097
962
  }
1098
963
  }
964
+
1099
965
  /**
1100
966
  * Formats reading for CSV
1101
967
  * @param {fs.WriteStream} stream
@@ -1104,75 +970,59 @@ function writeHolidayMincha(stream, ev, il) {
1104
970
  * @param {boolean} il
1105
971
  * @param {boolean} isParsha
1106
972
  */
1107
-
1108
973
  function writeCsvLines(stream, ev, reading, il, isParsha) {
1109
974
  const parsha = isParsha ? ev.basename() : getLeyningKeyForEvent(ev, il) || ev.render();
1110
975
  const date = fmtDate(ev.getDate().greg());
1111
976
  const lines = getFullKriyahLines(reading);
1112
977
  lines.forEach(s => {
1113
978
  const code = s[0].charCodeAt(0);
1114
-
1115
979
  if (code < 48 || code > 57) {
1116
980
  s[0] = `"${s[0]}"`;
1117
981
  }
1118
-
1119
982
  stream.write(`${date},"${parsha}",${s[0]},"${s[1]}",${s[2]}\r\n`);
1120
983
  });
1121
984
  stream.write('\r\n');
1122
985
  }
986
+
1123
987
  /**
1124
988
  * @private
1125
989
  * @param {any} reading
1126
990
  * @return {any[]}
1127
991
  */
1128
-
1129
992
  function getFullKriyahLines(reading) {
1130
993
  const lines = [];
1131
-
1132
994
  if (reading.fullkriyah) {
1133
995
  Object.keys(reading.fullkriyah).forEach(num => {
1134
996
  const a = reading.fullkriyah[num];
1135
-
1136
997
  if (typeof a !== 'undefined') {
1137
998
  var _reading$reason;
1138
-
1139
999
  const k = num == 'M' ? 'maf' : num;
1140
1000
  let aliyah = formatAliyahWithBook(a);
1141
-
1142
1001
  if ((_reading$reason = reading.reason) !== null && _reading$reason !== void 0 && _reading$reason[num]) {
1143
1002
  aliyah += ' | ' + reading.reason[num];
1144
1003
  }
1145
-
1146
1004
  lines.push([k, aliyah, a.v || '']);
1147
1005
  }
1148
1006
  });
1149
1007
  }
1150
-
1151
1008
  let specialHaftara = false;
1152
-
1153
1009
  if (reading.haftara) {
1154
1010
  var _reading$reason2;
1155
-
1156
1011
  let haftara = reading.haftara.replace(/,/g, ';');
1157
-
1158
1012
  if ((_reading$reason2 = reading.reason) !== null && _reading$reason2 !== void 0 && _reading$reason2.haftara) {
1159
1013
  specialHaftara = true;
1160
1014
  haftara += ' | ' + reading.reason.haftara;
1161
1015
  }
1162
-
1163
1016
  lines.push(['Haftara', haftara, reading.haftaraNumV || '']);
1164
1017
  }
1165
-
1166
1018
  if (reading.sephardic && !specialHaftara) {
1167
1019
  const sephardic = reading.sephardic.replace(/,/g, ';');
1168
1020
  lines.push(['Haftara for Sephardim', sephardic, reading.sephardicNumV || '']);
1169
1021
  }
1170
-
1171
1022
  if (reading.triHaftara) {
1172
1023
  const haftara = reading.triHaftara.replace(/,/g, ';');
1173
1024
  lines.push(['Alternate Haftara', haftara, reading.triHaftaraNumV || '']);
1174
1025
  }
1175
-
1176
1026
  return lines;
1177
1027
  }
1178
1028