@hebcal/core 5.3.4 → 5.3.6
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/bundle.js +9 -4
- package/dist/bundle.min.js +2 -2
- package/dist/index.cjs +695 -592
- package/dist/index.mjs +695 -592
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @hebcal/core v5.3.
|
|
1
|
+
/*! @hebcal/core v5.3.6 */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-namespace, no-inner-declarations */
|
|
3
3
|
/** @private */
|
|
4
4
|
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
@@ -9,29 +9,29 @@ monthLengths[1][2] = 29;
|
|
|
9
9
|
* @private
|
|
10
10
|
*/
|
|
11
11
|
function mod$1(x, y) {
|
|
12
|
-
|
|
12
|
+
return x - y * Math.floor(x / y);
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* @private
|
|
16
16
|
*/
|
|
17
17
|
function quotient(x, y) {
|
|
18
|
-
|
|
18
|
+
return Math.floor(x / y);
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* @private
|
|
22
22
|
* @param abs - R.D. number of days
|
|
23
23
|
*/
|
|
24
24
|
function yearFromFixed(abs) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
const l0 = abs - 1;
|
|
26
|
+
const n400 = quotient(l0, 146097);
|
|
27
|
+
const d1 = mod$1(l0, 146097);
|
|
28
|
+
const n100 = quotient(d1, 36524);
|
|
29
|
+
const d2 = mod$1(d1, 36524);
|
|
30
|
+
const n4 = quotient(d2, 1461);
|
|
31
|
+
const d3 = mod$1(d2, 1461);
|
|
32
|
+
const n1 = quotient(d3, 365);
|
|
33
|
+
const year = 400 * n400 + 100 * n100 + 4 * n4 + n1;
|
|
34
|
+
return n100 !== 4 && n1 !== 4 ? year + 1 : year;
|
|
35
35
|
}
|
|
36
36
|
/*
|
|
37
37
|
const ABS_14SEP1752 = 639797;
|
|
@@ -42,95 +42,101 @@ const ABS_2SEP1752 = 639785;
|
|
|
42
42
|
*/
|
|
43
43
|
var greg;
|
|
44
44
|
(function (greg) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
greg.isLeapYear = isLeapYear;
|
|
54
|
-
/**
|
|
55
|
-
* Number of days in the Gregorian month for given year
|
|
56
|
-
* @param {number} month Gregorian month (1=January, 12=December)
|
|
57
|
-
* @param {number} year Gregorian year
|
|
58
|
-
* @return {number}
|
|
59
|
-
*/
|
|
60
|
-
function daysInMonth(month, year) {
|
|
61
|
-
// 1 based months
|
|
62
|
-
return monthLengths[+isLeapYear(year)][month];
|
|
63
|
-
}
|
|
64
|
-
greg.daysInMonth = daysInMonth;
|
|
65
|
-
/**
|
|
66
|
-
* Returns true if the object is a Javascript Date
|
|
67
|
-
* @param {Object} obj
|
|
68
|
-
* @return {boolean}
|
|
69
|
-
*/
|
|
70
|
-
function isDate(obj) {
|
|
71
|
-
// eslint-disable-next-line no-prototype-builtins
|
|
72
|
-
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
73
|
-
}
|
|
74
|
-
greg.isDate = isDate;
|
|
75
|
-
/**
|
|
76
|
-
* @private
|
|
77
|
-
* @param year
|
|
78
|
-
* @param month (1-12)
|
|
79
|
-
* @param day (1-31)
|
|
80
|
-
*/
|
|
81
|
-
function toFixed(year, month, day) {
|
|
82
|
-
const py = year - 1;
|
|
83
|
-
return 365 * py + quotient(py, 4) - quotient(py, 100) + quotient(py, 400) + quotient(367 * month - 362, 12) + (month <= 2 ? 0 : isLeapYear(year) ? -1 : -2) + day;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
87
|
-
* @param {Date} date Gregorian date
|
|
88
|
-
* @return {number}
|
|
89
|
-
*/
|
|
90
|
-
function greg2abs(date) {
|
|
91
|
-
if (!isDate(date)) {
|
|
92
|
-
throw new TypeError(`Argument not a Date: ${date}`);
|
|
45
|
+
/**
|
|
46
|
+
* Returns true if the Gregorian year is a leap year
|
|
47
|
+
* @param {number} year Gregorian year
|
|
48
|
+
* @return {boolean}
|
|
49
|
+
*/
|
|
50
|
+
function isLeapYear(year) {
|
|
51
|
+
return !(year % 4) && (!!(year % 100) || !(year % 400));
|
|
93
52
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
53
|
+
greg.isLeapYear = isLeapYear;
|
|
54
|
+
/**
|
|
55
|
+
* Number of days in the Gregorian month for given year
|
|
56
|
+
* @param {number} month Gregorian month (1=January, 12=December)
|
|
57
|
+
* @param {number} year Gregorian year
|
|
58
|
+
* @return {number}
|
|
59
|
+
*/
|
|
60
|
+
function daysInMonth(month, year) {
|
|
61
|
+
// 1 based months
|
|
62
|
+
return monthLengths[+isLeapYear(year)][month];
|
|
98
63
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
* (April, 1993), pages 383-404 for an explanation.
|
|
109
|
-
* @param {number} abs - R.D. number of days
|
|
110
|
-
* @return {Date}
|
|
111
|
-
*/
|
|
112
|
-
function abs2greg(abs) {
|
|
113
|
-
if (typeof abs !== 'number') {
|
|
114
|
-
throw new TypeError(`Argument not a Number: ${abs}`);
|
|
64
|
+
greg.daysInMonth = daysInMonth;
|
|
65
|
+
/**
|
|
66
|
+
* Returns true if the object is a Javascript Date
|
|
67
|
+
* @param {Object} obj
|
|
68
|
+
* @return {boolean}
|
|
69
|
+
*/
|
|
70
|
+
function isDate(obj) {
|
|
71
|
+
// eslint-disable-next-line no-prototype-builtins
|
|
72
|
+
return typeof obj === 'object' && Date.prototype.isPrototypeOf(obj);
|
|
115
73
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
74
|
+
greg.isDate = isDate;
|
|
75
|
+
/**
|
|
76
|
+
* @private
|
|
77
|
+
* @param year
|
|
78
|
+
* @param month (1-12)
|
|
79
|
+
* @param day (1-31)
|
|
80
|
+
*/
|
|
81
|
+
function toFixed(year, month, day) {
|
|
82
|
+
const py = year - 1;
|
|
83
|
+
return (365 * py +
|
|
84
|
+
quotient(py, 4) -
|
|
85
|
+
quotient(py, 100) +
|
|
86
|
+
quotient(py, 400) +
|
|
87
|
+
quotient(367 * month - 362, 12) +
|
|
88
|
+
(month <= 2 ? 0 : isLeapYear(year) ? -1 : -2) +
|
|
89
|
+
day);
|
|
120
90
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Converts Gregorian date to absolute R.D. (Rata Die) days
|
|
93
|
+
* @param {Date} date Gregorian date
|
|
94
|
+
* @return {number}
|
|
95
|
+
*/
|
|
96
|
+
function greg2abs(date) {
|
|
97
|
+
if (!isDate(date)) {
|
|
98
|
+
throw new TypeError(`Argument not a Date: ${date}`);
|
|
99
|
+
}
|
|
100
|
+
const abs = toFixed(date.getFullYear(), date.getMonth() + 1, date.getDate());
|
|
101
|
+
/*
|
|
102
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
103
|
+
throw new RangeError(`Invalid Date: ${date}`);
|
|
104
|
+
}
|
|
105
|
+
*/
|
|
106
|
+
return abs;
|
|
107
|
+
}
|
|
108
|
+
greg.greg2abs = greg2abs;
|
|
109
|
+
/**
|
|
110
|
+
* Converts from Rata Die (R.D. number) to Gregorian date.
|
|
111
|
+
* See the footnote on page 384 of ``Calendrical Calculations, Part II:
|
|
112
|
+
* Three Historical Calendars'' by E. M. Reingold, N. Dershowitz, and S. M.
|
|
113
|
+
* Clamen, Software--Practice and Experience, Volume 23, Number 4
|
|
114
|
+
* (April, 1993), pages 383-404 for an explanation.
|
|
115
|
+
* @param {number} abs - R.D. number of days
|
|
116
|
+
* @return {Date}
|
|
117
|
+
*/
|
|
118
|
+
function abs2greg(abs) {
|
|
119
|
+
if (typeof abs !== 'number') {
|
|
120
|
+
throw new TypeError(`Argument not a Number: ${abs}`);
|
|
121
|
+
}
|
|
122
|
+
abs = Math.trunc(abs);
|
|
123
|
+
/*
|
|
124
|
+
if (abs < ABS_14SEP1752 && abs > ABS_2SEP1752) {
|
|
125
|
+
throw new RangeError(`Invalid Date: ${abs}`);
|
|
126
|
+
}
|
|
127
|
+
*/
|
|
128
|
+
const year = yearFromFixed(abs);
|
|
129
|
+
const priorDays = abs - toFixed(year, 1, 1);
|
|
130
|
+
const correction = abs < toFixed(year, 3, 1) ? 0 : isLeapYear(year) ? 1 : 2;
|
|
131
|
+
const month = quotient(12 * (priorDays + correction) + 373, 367);
|
|
132
|
+
const day = abs - toFixed(year, month, 1) + 1;
|
|
133
|
+
const dt = new Date(year, month - 1, day);
|
|
134
|
+
if (year < 100 && year >= 0) {
|
|
135
|
+
dt.setFullYear(year);
|
|
136
|
+
}
|
|
137
|
+
return dt;
|
|
138
|
+
}
|
|
139
|
+
greg.abs2greg = abs2greg;
|
|
134
140
|
})(greg || (greg = {}));
|
|
135
141
|
|
|
136
142
|
/*
|
|
@@ -155,40 +161,56 @@ const ADAR_II$2 = 13;
|
|
|
155
161
|
* @enum {number}
|
|
156
162
|
*/
|
|
157
163
|
const months = {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
164
|
+
/** Nissan / ניסן */
|
|
165
|
+
NISAN: 1,
|
|
166
|
+
/** Iyyar / אייר */
|
|
167
|
+
IYYAR: 2,
|
|
168
|
+
/** Sivan / סיון */
|
|
169
|
+
SIVAN: 3,
|
|
170
|
+
/** Tamuz (sometimes Tammuz) / תמוז */
|
|
171
|
+
TAMUZ: 4,
|
|
172
|
+
/** Av / אב */
|
|
173
|
+
AV: 5,
|
|
174
|
+
/** Elul / אלול */
|
|
175
|
+
ELUL: 6,
|
|
176
|
+
/** Tishrei / תִּשְׁרֵי */
|
|
177
|
+
TISHREI: 7,
|
|
178
|
+
/** Cheshvan / חשון */
|
|
179
|
+
CHESHVAN: 8,
|
|
180
|
+
/** Kislev / כסלו */
|
|
181
|
+
KISLEV: 9,
|
|
182
|
+
/** Tevet / טבת */
|
|
183
|
+
TEVET: 10,
|
|
184
|
+
/** Sh'vat / שבט */
|
|
185
|
+
SHVAT: 11,
|
|
186
|
+
/** Adar or Adar Rishon / אדר */
|
|
187
|
+
ADAR_I: 12,
|
|
188
|
+
/** Adar Sheini (only on leap years) / אדר ב׳ */
|
|
189
|
+
ADAR_II: 13,
|
|
184
190
|
};
|
|
185
|
-
const monthNames0 = [
|
|
191
|
+
const monthNames0 = [
|
|
192
|
+
'',
|
|
193
|
+
'Nisan',
|
|
194
|
+
'Iyyar',
|
|
195
|
+
'Sivan',
|
|
196
|
+
'Tamuz',
|
|
197
|
+
'Av',
|
|
198
|
+
'Elul',
|
|
199
|
+
'Tishrei',
|
|
200
|
+
'Cheshvan',
|
|
201
|
+
'Kislev',
|
|
202
|
+
'Tevet',
|
|
203
|
+
"Sh'vat",
|
|
204
|
+
];
|
|
186
205
|
/**
|
|
187
206
|
* Transliterations of Hebrew month names.
|
|
188
207
|
* Regular years are index 0 and leap years are index 1.
|
|
189
208
|
* @private
|
|
190
209
|
*/
|
|
191
|
-
const monthNames = [
|
|
210
|
+
const monthNames = [
|
|
211
|
+
monthNames0.concat(['Adar', 'Nisan']),
|
|
212
|
+
monthNames0.concat(['Adar I', 'Adar II', 'Nisan']),
|
|
213
|
+
];
|
|
192
214
|
const edCache = new Map();
|
|
193
215
|
const EPOCH = -1373428;
|
|
194
216
|
// Avg year length in the cycle (19 solar years with 235 lunar months)
|
|
@@ -197,9 +219,9 @@ const AVG_HEBYEAR_DAYS = 365.24682220597794;
|
|
|
197
219
|
* @private
|
|
198
220
|
*/
|
|
199
221
|
function assertNumber(n, name) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
222
|
+
if (typeof n !== 'number' || isNaN(n)) {
|
|
223
|
+
throw new TypeError(`invalid parameter '${name}' not a number: ${n}`);
|
|
224
|
+
}
|
|
203
225
|
}
|
|
204
226
|
/**
|
|
205
227
|
* Converts Hebrew date to R.D. (Rata Die) fixed days.
|
|
@@ -211,32 +233,33 @@ function assertNumber(n, name) {
|
|
|
211
233
|
* @return {number}
|
|
212
234
|
*/
|
|
213
235
|
function hebrew2abs(year, month, day) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
236
|
+
assertNumber(year, 'year');
|
|
237
|
+
assertNumber(month, 'month');
|
|
238
|
+
assertNumber(day, 'day');
|
|
239
|
+
if (year < 1) {
|
|
240
|
+
throw new RangeError(`hebrew2abs: invalid year ${year}`);
|
|
241
|
+
}
|
|
242
|
+
let tempabs = day;
|
|
243
|
+
if (month < TISHREI$2) {
|
|
244
|
+
for (let m = TISHREI$2; m <= monthsInYear(year); m++) {
|
|
245
|
+
tempabs += daysInMonth(m, year);
|
|
246
|
+
}
|
|
247
|
+
for (let m = NISAN$4; m < month; m++) {
|
|
248
|
+
tempabs += daysInMonth(m, year);
|
|
249
|
+
}
|
|
227
250
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
251
|
+
else {
|
|
252
|
+
for (let m = TISHREI$2; m < month; m++) {
|
|
253
|
+
tempabs += daysInMonth(m, year);
|
|
254
|
+
}
|
|
231
255
|
}
|
|
232
|
-
|
|
233
|
-
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
256
|
+
return EPOCH + elapsedDays(year) + tempabs - 1;
|
|
234
257
|
}
|
|
235
258
|
/**
|
|
236
259
|
* @private
|
|
237
260
|
*/
|
|
238
261
|
function newYear(year) {
|
|
239
|
-
|
|
262
|
+
return EPOCH + elapsedDays(year);
|
|
240
263
|
}
|
|
241
264
|
/**
|
|
242
265
|
* Converts absolute R.D. days to Hebrew date
|
|
@@ -244,27 +267,23 @@ function newYear(year) {
|
|
|
244
267
|
* @return {SimpleHebrewDate}
|
|
245
268
|
*/
|
|
246
269
|
function abs2hebrew(abs) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
yy: year,
|
|
265
|
-
mm: month,
|
|
266
|
-
dd: day
|
|
267
|
-
};
|
|
270
|
+
assertNumber(abs, 'abs');
|
|
271
|
+
abs = Math.trunc(abs);
|
|
272
|
+
if (abs <= EPOCH) {
|
|
273
|
+
throw new RangeError(`abs2hebrew: ${abs} is before epoch`);
|
|
274
|
+
}
|
|
275
|
+
// first, quickly approximate year
|
|
276
|
+
let year = Math.floor((abs - EPOCH) / AVG_HEBYEAR_DAYS);
|
|
277
|
+
while (newYear(year) <= abs) {
|
|
278
|
+
++year;
|
|
279
|
+
}
|
|
280
|
+
--year;
|
|
281
|
+
let month = abs < hebrew2abs(year, 1, 1) ? 7 : 1;
|
|
282
|
+
while (abs > hebrew2abs(year, month, daysInMonth(month, year))) {
|
|
283
|
+
++month;
|
|
284
|
+
}
|
|
285
|
+
const day = 1 + abs - hebrew2abs(year, month, 1);
|
|
286
|
+
return { yy: year, mm: month, dd: day };
|
|
268
287
|
}
|
|
269
288
|
/**
|
|
270
289
|
* Returns true if Hebrew year is a leap year
|
|
@@ -272,7 +291,7 @@ function abs2hebrew(abs) {
|
|
|
272
291
|
* @return {boolean}
|
|
273
292
|
*/
|
|
274
293
|
function isLeapYear(year) {
|
|
275
|
-
|
|
294
|
+
return (1 + year * 7) % 19 < 7;
|
|
276
295
|
}
|
|
277
296
|
/**
|
|
278
297
|
* Number of months in this Hebrew year (either 12 or 13 depending on leap year)
|
|
@@ -280,7 +299,7 @@ function isLeapYear(year) {
|
|
|
280
299
|
* @return {number}
|
|
281
300
|
*/
|
|
282
301
|
function monthsInYear(year) {
|
|
283
|
-
|
|
302
|
+
return 12 + +isLeapYear(year); // boolean is cast to 1 or 0
|
|
284
303
|
}
|
|
285
304
|
/**
|
|
286
305
|
* Number of days in Hebrew month in a given year (29 or 30)
|
|
@@ -289,19 +308,22 @@ function monthsInYear(year) {
|
|
|
289
308
|
* @return {number}
|
|
290
309
|
*/
|
|
291
310
|
function daysInMonth(month, year) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
311
|
+
switch (month) {
|
|
312
|
+
case IYYAR$1:
|
|
313
|
+
case TAMUZ$1:
|
|
314
|
+
case ELUL$1:
|
|
315
|
+
case TEVET$2:
|
|
316
|
+
case ADAR_II$2:
|
|
317
|
+
return 29;
|
|
318
|
+
}
|
|
319
|
+
if ((month === ADAR_I$2 && !isLeapYear(year)) ||
|
|
320
|
+
(month === CHESHVAN$1 && !longCheshvan(year)) ||
|
|
321
|
+
(month === KISLEV$2 && shortKislev(year))) {
|
|
322
|
+
return 29;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
return 30;
|
|
326
|
+
}
|
|
305
327
|
}
|
|
306
328
|
/**
|
|
307
329
|
* Returns a transliterated string name of Hebrew month in year,
|
|
@@ -310,12 +332,12 @@ function daysInMonth(month, year) {
|
|
|
310
332
|
* @param {number} year Hebrew year
|
|
311
333
|
*/
|
|
312
334
|
function getMonthName(month, year) {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
335
|
+
assertNumber(month, 'month');
|
|
336
|
+
assertNumber(year, 'year');
|
|
337
|
+
if (month < 1 || month > 14) {
|
|
338
|
+
throw new TypeError(`bad month argument ${month}`);
|
|
339
|
+
}
|
|
340
|
+
return monthNames[+isLeapYear(year)][month];
|
|
319
341
|
}
|
|
320
342
|
/**
|
|
321
343
|
* Days from sunday prior to start of Hebrew calendar to mean
|
|
@@ -324,13 +346,13 @@ function getMonthName(month, year) {
|
|
|
324
346
|
* @return {number}
|
|
325
347
|
*/
|
|
326
348
|
function elapsedDays(year) {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
349
|
+
const n = edCache.get(year);
|
|
350
|
+
if (typeof n === 'number') {
|
|
351
|
+
return n;
|
|
352
|
+
}
|
|
353
|
+
const elapsed = elapsedDays0(year);
|
|
354
|
+
edCache.set(year, elapsed);
|
|
355
|
+
return elapsed;
|
|
334
356
|
}
|
|
335
357
|
/**
|
|
336
358
|
* Days from sunday prior to start of Hebrew calendar to mean
|
|
@@ -339,25 +361,29 @@ function elapsedDays(year) {
|
|
|
339
361
|
* @param year Hebrew year
|
|
340
362
|
*/
|
|
341
363
|
function elapsedDays0(year) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
364
|
+
const prevYear = year - 1;
|
|
365
|
+
const mElapsed = 235 * Math.floor(prevYear / 19) + // Months in complete 19 year lunar (Metonic) cycles so far
|
|
366
|
+
12 * (prevYear % 19) + // Regular months in this cycle
|
|
367
|
+
Math.floor(((prevYear % 19) * 7 + 1) / 19); // Leap months this cycle
|
|
368
|
+
const pElapsed = 204 + 793 * (mElapsed % 1080);
|
|
369
|
+
const hElapsed = 5 +
|
|
370
|
+
12 * mElapsed +
|
|
371
|
+
793 * Math.floor(mElapsed / 1080) +
|
|
372
|
+
Math.floor(pElapsed / 1080);
|
|
373
|
+
const parts = (pElapsed % 1080) + 1080 * (hElapsed % 24);
|
|
374
|
+
const day = 1 + 29 * mElapsed + Math.floor(hElapsed / 24);
|
|
375
|
+
let altDay = day;
|
|
376
|
+
if (parts >= 19440 ||
|
|
377
|
+
(2 === day % 7 && parts >= 9924 && !isLeapYear(year)) ||
|
|
378
|
+
(1 === day % 7 && parts >= 16789 && isLeapYear(prevYear))) {
|
|
379
|
+
altDay++;
|
|
380
|
+
}
|
|
381
|
+
if (altDay % 7 === 0 || altDay % 7 === 3 || altDay % 7 === 5) {
|
|
382
|
+
return altDay + 1;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
return altDay;
|
|
386
|
+
}
|
|
361
387
|
}
|
|
362
388
|
/**
|
|
363
389
|
* Number of days in the hebrew YEAR.
|
|
@@ -367,7 +393,7 @@ function elapsedDays0(year) {
|
|
|
367
393
|
* @return {number}
|
|
368
394
|
*/
|
|
369
395
|
function daysInYear(year) {
|
|
370
|
-
|
|
396
|
+
return elapsedDays(year + 1) - elapsedDays(year);
|
|
371
397
|
}
|
|
372
398
|
/**
|
|
373
399
|
* true if Cheshvan is long in Hebrew year
|
|
@@ -375,7 +401,7 @@ function daysInYear(year) {
|
|
|
375
401
|
* @return {boolean}
|
|
376
402
|
*/
|
|
377
403
|
function longCheshvan(year) {
|
|
378
|
-
|
|
404
|
+
return daysInYear(year) % 10 === 5;
|
|
379
405
|
}
|
|
380
406
|
/**
|
|
381
407
|
* true if Kislev is short in Hebrew year
|
|
@@ -383,7 +409,7 @@ function longCheshvan(year) {
|
|
|
383
409
|
* @return {boolean}
|
|
384
410
|
*/
|
|
385
411
|
function shortKislev(year) {
|
|
386
|
-
|
|
412
|
+
return daysInYear(year) % 10 === 3;
|
|
387
413
|
}
|
|
388
414
|
/**
|
|
389
415
|
* Converts Hebrew month string name to numeric
|
|
@@ -391,116 +417,116 @@ function shortKislev(year) {
|
|
|
391
417
|
* @return {number}
|
|
392
418
|
*/
|
|
393
419
|
function monthFromName(monthName) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
return months.IYYAR;
|
|
435
|
-
case 'e':
|
|
436
|
-
return months.ELUL;
|
|
437
|
-
case 'c':
|
|
438
|
-
case 'ח':
|
|
439
|
-
return months.CHESHVAN;
|
|
440
|
-
case 'k':
|
|
441
|
-
case 'כ':
|
|
442
|
-
return months.KISLEV;
|
|
443
|
-
case 's':
|
|
444
|
-
switch (c[1]) {
|
|
445
|
-
case 'i':
|
|
446
|
-
return months.SIVAN;
|
|
447
|
-
case 'h':
|
|
448
|
-
return months.SHVAT;
|
|
449
|
-
}
|
|
450
|
-
break;
|
|
451
|
-
case 't':
|
|
452
|
-
switch (c[1]) {
|
|
453
|
-
case 'a':
|
|
454
|
-
return months.TAMUZ;
|
|
420
|
+
if (typeof monthName === 'number') {
|
|
421
|
+
if (isNaN(monthName) || monthName < 1 || monthName > 14) {
|
|
422
|
+
throw new RangeError(`Invalid month name: ${monthName}`);
|
|
423
|
+
}
|
|
424
|
+
return monthName;
|
|
425
|
+
}
|
|
426
|
+
let c = monthName.trim().toLowerCase();
|
|
427
|
+
// If Hebrew month starts with a bet (for example `בתמוז`) then ignore it
|
|
428
|
+
if (c[0] === 'ב') {
|
|
429
|
+
c = c.substring(1);
|
|
430
|
+
}
|
|
431
|
+
/*
|
|
432
|
+
the Hebrew months are unique to their second letter
|
|
433
|
+
N Nisan (November?)
|
|
434
|
+
I Iyyar
|
|
435
|
+
E Elul
|
|
436
|
+
C Cheshvan
|
|
437
|
+
K Kislev
|
|
438
|
+
1 1Adar
|
|
439
|
+
2 2Adar
|
|
440
|
+
Si Sh Sivan, Shvat
|
|
441
|
+
Ta Ti Te Tamuz, Tishrei, Tevet
|
|
442
|
+
Av Ad Av, Adar
|
|
443
|
+
|
|
444
|
+
אב אד אי אל אב אדר אייר אלול
|
|
445
|
+
ח חשון
|
|
446
|
+
ט טבת
|
|
447
|
+
כ כסלו
|
|
448
|
+
נ ניסן
|
|
449
|
+
ס סיון
|
|
450
|
+
ש שבט
|
|
451
|
+
תמ תש תמוז תשרי
|
|
452
|
+
*/
|
|
453
|
+
switch (c[0]) {
|
|
454
|
+
case 'n':
|
|
455
|
+
case 'נ':
|
|
456
|
+
if (c[1] === 'o') {
|
|
457
|
+
break; /* this catches "november" */
|
|
458
|
+
}
|
|
459
|
+
return months.NISAN;
|
|
455
460
|
case 'i':
|
|
456
|
-
|
|
461
|
+
return months.IYYAR;
|
|
457
462
|
case 'e':
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
case '
|
|
464
|
-
|
|
465
|
-
case '
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
case '
|
|
497
|
-
|
|
463
|
+
return months.ELUL;
|
|
464
|
+
case 'c':
|
|
465
|
+
case 'ח':
|
|
466
|
+
return months.CHESHVAN;
|
|
467
|
+
case 'k':
|
|
468
|
+
case 'כ':
|
|
469
|
+
return months.KISLEV;
|
|
470
|
+
case 's':
|
|
471
|
+
switch (c[1]) {
|
|
472
|
+
case 'i':
|
|
473
|
+
return months.SIVAN;
|
|
474
|
+
case 'h':
|
|
475
|
+
return months.SHVAT;
|
|
476
|
+
}
|
|
477
|
+
break;
|
|
478
|
+
case 't':
|
|
479
|
+
switch (c[1]) {
|
|
480
|
+
case 'a':
|
|
481
|
+
return months.TAMUZ;
|
|
482
|
+
case 'i':
|
|
483
|
+
return months.TISHREI;
|
|
484
|
+
case 'e':
|
|
485
|
+
return months.TEVET;
|
|
486
|
+
}
|
|
487
|
+
break;
|
|
488
|
+
case 'a':
|
|
489
|
+
switch (c[1]) {
|
|
490
|
+
case 'v':
|
|
491
|
+
return months.AV;
|
|
492
|
+
case 'd':
|
|
493
|
+
if (/(1|[^i]i|a|א)$/i.test(monthName)) {
|
|
494
|
+
return months.ADAR_I;
|
|
495
|
+
}
|
|
496
|
+
return months.ADAR_II; // else assume sheini
|
|
497
|
+
}
|
|
498
|
+
break;
|
|
499
|
+
case 'ס':
|
|
500
|
+
return months.SIVAN;
|
|
501
|
+
case 'ט':
|
|
502
|
+
return months.TEVET;
|
|
498
503
|
case 'ש':
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
+
return months.SHVAT;
|
|
505
|
+
case 'א':
|
|
506
|
+
switch (c[1]) {
|
|
507
|
+
case 'ב':
|
|
508
|
+
return months.AV;
|
|
509
|
+
case 'ד':
|
|
510
|
+
if (/(1|[^i]i|a|א)$/i.test(monthName)) {
|
|
511
|
+
return months.ADAR_I;
|
|
512
|
+
}
|
|
513
|
+
return months.ADAR_II; // else assume sheini
|
|
514
|
+
case 'י':
|
|
515
|
+
return months.IYYAR;
|
|
516
|
+
case 'ל':
|
|
517
|
+
return months.ELUL;
|
|
518
|
+
}
|
|
519
|
+
break;
|
|
520
|
+
case 'ת':
|
|
521
|
+
switch (c[1]) {
|
|
522
|
+
case 'מ':
|
|
523
|
+
return months.TAMUZ;
|
|
524
|
+
case 'ש':
|
|
525
|
+
return months.TISHREI;
|
|
526
|
+
}
|
|
527
|
+
break;
|
|
528
|
+
}
|
|
529
|
+
throw new RangeError(`Unable to parse month name: ${monthName}`);
|
|
504
530
|
}
|
|
505
531
|
|
|
506
532
|
const NISAN$3 = months.NISAN;
|
|
@@ -516,140 +542,158 @@ const ADAR_II$1 = months.ADAR_II;
|
|
|
516
542
|
* @param {Object} obj
|
|
517
543
|
*/
|
|
518
544
|
function isSimpleHebrewDate(obj) {
|
|
519
|
-
|
|
545
|
+
return (typeof obj === 'object' &&
|
|
546
|
+
obj !== null &&
|
|
547
|
+
typeof obj.yy === 'number' &&
|
|
548
|
+
typeof obj.mm === 'number' &&
|
|
549
|
+
typeof obj.dd === 'number');
|
|
520
550
|
}
|
|
521
551
|
/**
|
|
522
552
|
* @private
|
|
523
553
|
*/
|
|
524
554
|
function toSimpleHebrewDate(obj) {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
555
|
+
if (isSimpleHebrewDate(obj)) {
|
|
556
|
+
return obj;
|
|
557
|
+
}
|
|
558
|
+
else if (typeof obj === 'number') {
|
|
559
|
+
return abs2hebrew(obj);
|
|
560
|
+
}
|
|
561
|
+
else if (greg.isDate(obj)) {
|
|
562
|
+
const abs = greg.greg2abs(obj);
|
|
563
|
+
return abs2hebrew(abs);
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
throw new TypeError(`Argument not a Date: ${obj}`);
|
|
567
|
+
}
|
|
535
568
|
}
|
|
536
569
|
function getYahrzeitHD(hyear, date) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
hDeath.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
+
let hDeath = toSimpleHebrewDate(date);
|
|
571
|
+
if (hyear <= hDeath.yy) {
|
|
572
|
+
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
573
|
+
return undefined;
|
|
574
|
+
}
|
|
575
|
+
if (hDeath.mm === CHESHVAN &&
|
|
576
|
+
hDeath.dd === 30 &&
|
|
577
|
+
!longCheshvan(hDeath.yy + 1)) {
|
|
578
|
+
// If it's Heshvan 30 it depends on the first anniversary;
|
|
579
|
+
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
580
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV$1, 1) - 1);
|
|
581
|
+
}
|
|
582
|
+
else if (hDeath.mm === KISLEV$1 &&
|
|
583
|
+
hDeath.dd === 30 &&
|
|
584
|
+
shortKislev(hDeath.yy + 1)) {
|
|
585
|
+
// If it's Kislev 30 it depends on the first anniversary;
|
|
586
|
+
// if that was not Kislev 30, use the day before Teveth 1.
|
|
587
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
588
|
+
}
|
|
589
|
+
else if (hDeath.mm === ADAR_II$1) {
|
|
590
|
+
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
591
|
+
hDeath.mm = monthsInYear(hyear);
|
|
592
|
+
}
|
|
593
|
+
else if (hDeath.mm === ADAR_I$1 && hDeath.dd === 30 && !isLeapYear(hyear)) {
|
|
594
|
+
// If it's the 30th in Adar I and year is not a leap year
|
|
595
|
+
// (so Adar has only 29 days), use the last day in Shevat.
|
|
596
|
+
hDeath.dd = 30;
|
|
597
|
+
hDeath.mm = SHVAT;
|
|
598
|
+
}
|
|
599
|
+
// In all other cases, use the normal anniversary of the date of death.
|
|
600
|
+
// advance day to rosh chodesh if needed
|
|
601
|
+
if (hDeath.mm === CHESHVAN && hDeath.dd === 30 && !longCheshvan(hyear)) {
|
|
602
|
+
hDeath.mm = KISLEV$1;
|
|
603
|
+
hDeath.dd = 1;
|
|
604
|
+
}
|
|
605
|
+
else if (hDeath.mm === KISLEV$1 && hDeath.dd === 30 && shortKislev(hyear)) {
|
|
606
|
+
hDeath.mm = TEVET$1;
|
|
607
|
+
hDeath.dd = 1;
|
|
608
|
+
}
|
|
609
|
+
hDeath.yy = hyear;
|
|
610
|
+
return hDeath;
|
|
570
611
|
}
|
|
571
612
|
function getBirthdayHD(hyear, date) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
month
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
day
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
613
|
+
const orig = toSimpleHebrewDate(date);
|
|
614
|
+
const origYear = orig.yy;
|
|
615
|
+
if (hyear === origYear) {
|
|
616
|
+
return orig;
|
|
617
|
+
}
|
|
618
|
+
else if (hyear < origYear) {
|
|
619
|
+
// Hebrew year ${hyear} occurs on or before original date in ${origYear}
|
|
620
|
+
return undefined;
|
|
621
|
+
}
|
|
622
|
+
const isOrigLeap = isLeapYear(origYear);
|
|
623
|
+
let month = orig.mm;
|
|
624
|
+
let day = orig.dd;
|
|
625
|
+
if ((month === ADAR_I$1 && !isOrigLeap) || (month === ADAR_II$1 && isOrigLeap)) {
|
|
626
|
+
month = monthsInYear(hyear);
|
|
627
|
+
}
|
|
628
|
+
else if (month === CHESHVAN && day === 30 && !longCheshvan(hyear)) {
|
|
629
|
+
month = KISLEV$1;
|
|
630
|
+
day = 1;
|
|
631
|
+
}
|
|
632
|
+
else if (month === KISLEV$1 && day === 30 && shortKislev(hyear)) {
|
|
633
|
+
month = TEVET$1;
|
|
634
|
+
day = 1;
|
|
635
|
+
}
|
|
636
|
+
else if (month === ADAR_I$1 &&
|
|
637
|
+
day === 30 &&
|
|
638
|
+
isOrigLeap &&
|
|
639
|
+
!isLeapYear(hyear)) {
|
|
640
|
+
month = NISAN$3;
|
|
641
|
+
day = 1;
|
|
642
|
+
}
|
|
643
|
+
return { yy: hyear, mm: month, dd: day };
|
|
600
644
|
}
|
|
601
645
|
|
|
602
646
|
const GERESH = '׳';
|
|
603
647
|
const GERSHAYIM = '״';
|
|
604
648
|
const alefbet = {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
649
|
+
א: 1,
|
|
650
|
+
ב: 2,
|
|
651
|
+
ג: 3,
|
|
652
|
+
ד: 4,
|
|
653
|
+
ה: 5,
|
|
654
|
+
ו: 6,
|
|
655
|
+
ז: 7,
|
|
656
|
+
ח: 8,
|
|
657
|
+
ט: 9,
|
|
658
|
+
י: 10,
|
|
659
|
+
כ: 20,
|
|
660
|
+
ל: 30,
|
|
661
|
+
מ: 40,
|
|
662
|
+
נ: 50,
|
|
663
|
+
ס: 60,
|
|
664
|
+
ע: 70,
|
|
665
|
+
פ: 80,
|
|
666
|
+
צ: 90,
|
|
667
|
+
ק: 100,
|
|
668
|
+
ר: 200,
|
|
669
|
+
ש: 300,
|
|
670
|
+
ת: 400,
|
|
627
671
|
};
|
|
628
672
|
const heb2num = new Map();
|
|
629
673
|
const num2heb = new Map();
|
|
630
674
|
for (const [key, val] of Object.entries(alefbet)) {
|
|
631
|
-
|
|
632
|
-
|
|
675
|
+
heb2num.set(key, val);
|
|
676
|
+
num2heb.set(val, key);
|
|
633
677
|
}
|
|
634
678
|
function num2digits(num) {
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
679
|
+
const digits = [];
|
|
680
|
+
while (num > 0) {
|
|
681
|
+
if (num === 15 || num === 16) {
|
|
682
|
+
digits.push(9);
|
|
683
|
+
digits.push(num - 9);
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
let incr = 100;
|
|
687
|
+
let i;
|
|
688
|
+
for (i = 400; i > num; i -= incr) {
|
|
689
|
+
if (i === incr) {
|
|
690
|
+
incr = incr / 10;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
digits.push(i);
|
|
694
|
+
num -= i;
|
|
648
695
|
}
|
|
649
|
-
digits
|
|
650
|
-
num -= i;
|
|
651
|
-
}
|
|
652
|
-
return digits;
|
|
696
|
+
return digits;
|
|
653
697
|
}
|
|
654
698
|
/**
|
|
655
699
|
* Converts a numerical value to a string of Hebrew letters.
|
|
@@ -666,31 +710,31 @@ function num2digits(num) {
|
|
|
666
710
|
* @return {string}
|
|
667
711
|
*/
|
|
668
712
|
function gematriya(num) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
713
|
+
const num0 = num;
|
|
714
|
+
const num1 = parseInt(num0, 10);
|
|
715
|
+
if (!num1) {
|
|
716
|
+
throw new TypeError(`invalid parameter to gematriya ${num}`);
|
|
717
|
+
}
|
|
718
|
+
let str = '';
|
|
719
|
+
const thousands = Math.floor(num1 / 1000);
|
|
720
|
+
if (thousands > 0 && thousands !== 5) {
|
|
721
|
+
const tdigits = num2digits(thousands);
|
|
722
|
+
for (const tdig of tdigits) {
|
|
723
|
+
str += num2heb.get(tdig);
|
|
724
|
+
}
|
|
725
|
+
str += GERESH;
|
|
680
726
|
}
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (digits.length === 1) {
|
|
685
|
-
return str + num2heb.get(digits[0]) + GERESH;
|
|
686
|
-
}
|
|
687
|
-
for (let i = 0; i < digits.length; i++) {
|
|
688
|
-
if (i + 1 === digits.length) {
|
|
689
|
-
str += GERSHAYIM;
|
|
727
|
+
const digits = num2digits(num1 % 1000);
|
|
728
|
+
if (digits.length === 1) {
|
|
729
|
+
return str + num2heb.get(digits[0]) + GERESH;
|
|
690
730
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
731
|
+
for (let i = 0; i < digits.length; i++) {
|
|
732
|
+
if (i + 1 === digits.length) {
|
|
733
|
+
str += GERSHAYIM;
|
|
734
|
+
}
|
|
735
|
+
str += num2heb.get(digits[i]);
|
|
736
|
+
}
|
|
737
|
+
return str;
|
|
694
738
|
}
|
|
695
739
|
/**
|
|
696
740
|
* Converts a string of Hebrew letters to a numerical value.
|
|
@@ -703,48 +747,75 @@ function gematriya(num) {
|
|
|
703
747
|
* @return {number}
|
|
704
748
|
*/
|
|
705
749
|
function gematriyaStrToNum(str) {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
750
|
+
let num = 0;
|
|
751
|
+
const gereshIdx = str.indexOf(GERESH);
|
|
752
|
+
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
753
|
+
const thousands = str.substring(0, gereshIdx);
|
|
754
|
+
num += gematriyaStrToNum(thousands) * 1000;
|
|
755
|
+
str = str.substring(gereshIdx);
|
|
756
|
+
}
|
|
757
|
+
for (const ch of str) {
|
|
758
|
+
const n = heb2num.get(ch);
|
|
759
|
+
if (typeof n === 'number') {
|
|
760
|
+
num += n;
|
|
761
|
+
}
|
|
717
762
|
}
|
|
718
|
-
|
|
719
|
-
return num;
|
|
763
|
+
return num;
|
|
720
764
|
}
|
|
721
765
|
|
|
722
766
|
const sefirot = {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
767
|
+
en: {
|
|
768
|
+
infix: 'within ',
|
|
769
|
+
infix26: 'within ',
|
|
770
|
+
words: [
|
|
771
|
+
'',
|
|
772
|
+
'Lovingkindness',
|
|
773
|
+
'Might',
|
|
774
|
+
'Beauty',
|
|
775
|
+
'Eternity',
|
|
776
|
+
'Splendor',
|
|
777
|
+
'Foundation',
|
|
778
|
+
'Majesty',
|
|
779
|
+
],
|
|
780
|
+
},
|
|
781
|
+
he: {
|
|
782
|
+
infix: 'שֶׁבְּ',
|
|
783
|
+
infix26: 'שֶׁבִּ',
|
|
784
|
+
words: [
|
|
785
|
+
'',
|
|
786
|
+
'חֶֽסֶד',
|
|
787
|
+
'גְבוּרָה',
|
|
788
|
+
'תִּפאֶרֶת',
|
|
789
|
+
'נֶּֽצַח',
|
|
790
|
+
'הוֹד',
|
|
791
|
+
'יְּסוֹד',
|
|
792
|
+
'מַּלְכוּת',
|
|
793
|
+
],
|
|
794
|
+
},
|
|
795
|
+
translit: {
|
|
796
|
+
infix: "sheb'",
|
|
797
|
+
infix26: 'shebi',
|
|
798
|
+
words: [
|
|
799
|
+
'',
|
|
800
|
+
'Chesed',
|
|
801
|
+
'Gevurah',
|
|
802
|
+
'Tiferet',
|
|
803
|
+
'Netzach',
|
|
804
|
+
'Hod',
|
|
805
|
+
'Yesod',
|
|
806
|
+
'Malkhut',
|
|
807
|
+
],
|
|
808
|
+
},
|
|
738
809
|
};
|
|
739
810
|
function checkDay(omerDay) {
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
811
|
+
if (omerDay < 1 || omerDay > 49) {
|
|
812
|
+
throw new RangeError(`Invalid Omer day ${omerDay}`);
|
|
813
|
+
}
|
|
743
814
|
}
|
|
744
815
|
function getWeeks(omerDay) {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
816
|
+
const weekNum = Math.floor((omerDay - 1) / 7) + 1;
|
|
817
|
+
const daysWithinWeeks = omerDay % 7 || 7;
|
|
818
|
+
return [weekNum, daysWithinWeeks];
|
|
748
819
|
}
|
|
749
820
|
/**
|
|
750
821
|
* Returns the sefira. For example, on day 8
|
|
@@ -756,13 +827,13 @@ function getWeeks(omerDay) {
|
|
|
756
827
|
* @returns a string such as `Lovingkindness within Might` or `חֶֽסֶד שֶׁבִּגְבוּרָה`
|
|
757
828
|
*/
|
|
758
829
|
function omerSefira(omerDay, lang) {
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
830
|
+
checkDay(omerDay);
|
|
831
|
+
const [weekNum, daysWithinWeeks] = getWeeks(omerDay);
|
|
832
|
+
const config = sefirot[lang];
|
|
833
|
+
const week = config.words[weekNum];
|
|
834
|
+
const dayWithinWeek = config.words[daysWithinWeeks];
|
|
835
|
+
const infix = weekNum === 2 || weekNum === 6 ? config.infix26 : config.infix;
|
|
836
|
+
return (dayWithinWeek + ' ' + infix + week).normalize();
|
|
766
837
|
}
|
|
767
838
|
/**
|
|
768
839
|
* Returns a sentence with that evening's omer count
|
|
@@ -772,102 +843,132 @@ function omerSefira(omerDay, lang) {
|
|
|
772
843
|
* or `הַיוֹם עֲשָׂרָה יָמִים, שְׁהֵם שָׁבוּעַ אֶחָד וְשְׁלוֹשָׁה יָמִים לָעוֹמֶר`
|
|
773
844
|
*/
|
|
774
845
|
function omerTodayIs(omerDay, lang) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
846
|
+
checkDay(omerDay);
|
|
847
|
+
if (lang === 'en') {
|
|
848
|
+
return omerTodayIsEn(omerDay);
|
|
849
|
+
}
|
|
850
|
+
else if (lang === 'he') {
|
|
851
|
+
return omerTodayIsHe(omerDay);
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
return undefined;
|
|
855
|
+
}
|
|
783
856
|
}
|
|
784
857
|
function omerTodayIsEn(omerDay) {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
858
|
+
const [weekNumber, daysWithinWeeks] = getWeeks(omerDay);
|
|
859
|
+
const totalDaysStr = omerDay === 1 ? 'day' : 'days';
|
|
860
|
+
let str = `Today is ${omerDay} ${totalDaysStr}`;
|
|
861
|
+
if (weekNumber > 1 || omerDay === 7) {
|
|
862
|
+
const day7 = daysWithinWeeks === 7;
|
|
863
|
+
const numWeeks = day7 ? weekNumber : weekNumber - 1;
|
|
864
|
+
const weeksStr = numWeeks === 1 ? 'week' : 'weeks';
|
|
865
|
+
str += `, which is ${numWeeks} ${weeksStr}`;
|
|
866
|
+
if (!day7) {
|
|
867
|
+
const daysStr = daysWithinWeeks === 1 ? 'day' : 'days';
|
|
868
|
+
str += ` and ${daysWithinWeeks} ${daysStr}`;
|
|
869
|
+
}
|
|
796
870
|
}
|
|
797
|
-
|
|
798
|
-
return str + ' of the Omer';
|
|
871
|
+
return str + ' of the Omer';
|
|
799
872
|
}
|
|
800
873
|
// adapted from pip hdate package (GPL)
|
|
801
874
|
// https://github.com/py-libhdate/py-libhdate/blob/master/hdate/date.py
|
|
802
875
|
const tens = ['', 'עֲשָׂרָה', 'עֶשְׂרִים', 'שְׁלוֹשִׁים', 'אַרְבָּעִים'];
|
|
803
|
-
const ones = [
|
|
876
|
+
const ones = [
|
|
877
|
+
'',
|
|
878
|
+
'אֶחָד',
|
|
879
|
+
'שְׁנַיִם',
|
|
880
|
+
'שְׁלוֹשָׁה',
|
|
881
|
+
'אַרְבָּעָה',
|
|
882
|
+
'חֲמִשָּׁה',
|
|
883
|
+
'שִׁשָּׁה',
|
|
884
|
+
'שִׁבְעָה',
|
|
885
|
+
'שְׁמוֹנָה',
|
|
886
|
+
'תִּשְׁעָה',
|
|
887
|
+
];
|
|
804
888
|
const shnei = 'שְׁנֵי';
|
|
805
889
|
const yamim = 'יָמִים';
|
|
806
890
|
const shneiYamim = shnei + ' ' + yamim;
|
|
807
891
|
const shavuot = 'שָׁבוּעוֹת';
|
|
808
892
|
const yom = 'יוֹם';
|
|
809
893
|
const yomEchad = yom + ' ' + ones[1];
|
|
894
|
+
const asar = 'עָשָׂר';
|
|
810
895
|
function omerTodayIsHe(omerDay) {
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
} else {
|
|
830
|
-
str += ' ' + yom + ' ';
|
|
896
|
+
const ten = Math.floor(omerDay / 10);
|
|
897
|
+
const one = omerDay % 10;
|
|
898
|
+
let str = 'הַיּוֹם ';
|
|
899
|
+
if (omerDay === 11) {
|
|
900
|
+
str += 'אַחַד ' + asar;
|
|
901
|
+
}
|
|
902
|
+
else if (omerDay === 12) {
|
|
903
|
+
str += 'שְׁנֵים ' + asar;
|
|
904
|
+
}
|
|
905
|
+
else if (12 < omerDay && omerDay < 20) {
|
|
906
|
+
str += ones[one] + ' ' + asar;
|
|
907
|
+
}
|
|
908
|
+
else if (omerDay > 9) {
|
|
909
|
+
str += ones[one];
|
|
910
|
+
if (one) {
|
|
911
|
+
str += ' ';
|
|
912
|
+
str += ten === 3 ? 'וּ' : 'וְ';
|
|
913
|
+
}
|
|
831
914
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
if (
|
|
844
|
-
str += ones[weeks] + ' ' + shavuot + ' ';
|
|
845
|
-
} else if (weeks === 1) {
|
|
846
|
-
str += 'שָׁבֽוּעַ' + ' ' + ones[1] + ' ';
|
|
847
|
-
} else {
|
|
848
|
-
// weeks == 2
|
|
849
|
-
str += shnei + ' ' + shavuot + ' ';
|
|
850
|
-
}
|
|
851
|
-
if (days) {
|
|
852
|
-
if (days === 2 || days === 3) {
|
|
853
|
-
str += 'וּ';
|
|
854
|
-
} else if (days === 5) {
|
|
855
|
-
str += 'וַ';
|
|
856
|
-
} else {
|
|
857
|
-
str += 'וְ';
|
|
858
|
-
}
|
|
859
|
-
if (days > 2) {
|
|
860
|
-
str += ones[days] + ' ' + yamim + ' ';
|
|
861
|
-
} else if (days === 1) {
|
|
915
|
+
if (omerDay > 2) {
|
|
916
|
+
if (omerDay > 20 || omerDay === 10 || omerDay === 20) {
|
|
917
|
+
str += tens[ten];
|
|
918
|
+
}
|
|
919
|
+
if (omerDay < 11) {
|
|
920
|
+
str += ones[one] + ' ' + yamim + ' ';
|
|
921
|
+
}
|
|
922
|
+
else {
|
|
923
|
+
str += ' ' + yom + ' ';
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
else if (omerDay === 1) {
|
|
862
927
|
str += yomEchad + ' ';
|
|
863
|
-
|
|
864
|
-
|
|
928
|
+
}
|
|
929
|
+
else {
|
|
930
|
+
// omer == 2
|
|
865
931
|
str += shneiYamim + ' ';
|
|
866
|
-
}
|
|
867
932
|
}
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
933
|
+
if (omerDay > 6) {
|
|
934
|
+
str = str.trim(); // remove trailing space before comma
|
|
935
|
+
str += ', שְׁהֵם ';
|
|
936
|
+
const weeks = Math.floor(omerDay / 7);
|
|
937
|
+
const days = omerDay % 7;
|
|
938
|
+
if (weeks > 2) {
|
|
939
|
+
str += ones[weeks] + ' ' + shavuot + ' ';
|
|
940
|
+
}
|
|
941
|
+
else if (weeks === 1) {
|
|
942
|
+
str += 'שָׁבֽוּעַ' + ' ' + ones[1] + ' ';
|
|
943
|
+
}
|
|
944
|
+
else {
|
|
945
|
+
// weeks == 2
|
|
946
|
+
str += shnei + ' ' + shavuot + ' ';
|
|
947
|
+
}
|
|
948
|
+
if (days) {
|
|
949
|
+
if (days === 2 || days === 3) {
|
|
950
|
+
str += 'וּ';
|
|
951
|
+
}
|
|
952
|
+
else if (days === 5) {
|
|
953
|
+
str += 'וַ';
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
str += 'וְ';
|
|
957
|
+
}
|
|
958
|
+
if (days > 2) {
|
|
959
|
+
str += ones[days] + ' ' + yamim + ' ';
|
|
960
|
+
}
|
|
961
|
+
else if (days === 1) {
|
|
962
|
+
str += yomEchad + ' ';
|
|
963
|
+
}
|
|
964
|
+
else {
|
|
965
|
+
// days == 2
|
|
966
|
+
str += shneiYamim + ' ';
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
str += 'לָעֽוֹמֶר';
|
|
971
|
+
return str.normalize();
|
|
871
972
|
}
|
|
872
973
|
/**
|
|
873
974
|
* Returns an emoji number symbol with a circle, for example `㊲`
|
|
@@ -876,16 +977,18 @@ function omerTodayIsHe(omerDay) {
|
|
|
876
977
|
* @returns a single Unicode character from `①` through `㊾`
|
|
877
978
|
*/
|
|
878
979
|
function omerEmoji(omerDay) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
980
|
+
checkDay(omerDay);
|
|
981
|
+
if (omerDay <= 20) {
|
|
982
|
+
return String.fromCodePoint(9312 + omerDay - 1);
|
|
983
|
+
}
|
|
984
|
+
else if (omerDay <= 35) {
|
|
985
|
+
// between 21 and 35 inclusive
|
|
986
|
+
return String.fromCodePoint(12881 + omerDay - 21);
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
// between 36 and 49 inclusive
|
|
990
|
+
return String.fromCodePoint(12977 + omerDay - 36);
|
|
991
|
+
}
|
|
889
992
|
}
|
|
890
993
|
|
|
891
994
|
const noopLocale = {
|
|
@@ -10353,7 +10456,7 @@ class DailyLearning {
|
|
|
10353
10456
|
}
|
|
10354
10457
|
|
|
10355
10458
|
// DO NOT EDIT THIS AUTO-GENERATED FILE!
|
|
10356
|
-
const version = '5.3.
|
|
10459
|
+
const version = '5.3.6';
|
|
10357
10460
|
|
|
10358
10461
|
const NONE$1 = 0;
|
|
10359
10462
|
const HALF = 1;
|