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