@hebcal/core 5.0.0 → 5.0.2
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 +136 -225
- package/dist/bundle.js +551 -596
- package/dist/bundle.min.js +2 -2
- package/dist/index.js +433 -478
- package/dist/index.mjs +433 -478
- package/package.json +9 -9
package/dist/index.mjs
CHANGED
|
@@ -1,349 +1,4 @@
|
|
|
1
|
-
/*! @hebcal/core v5.0.
|
|
2
|
-
const GERESH = '׳';
|
|
3
|
-
const GERSHAYIM = '״';
|
|
4
|
-
const heb2num = {
|
|
5
|
-
'א': 1,
|
|
6
|
-
'ב': 2,
|
|
7
|
-
'ג': 3,
|
|
8
|
-
'ד': 4,
|
|
9
|
-
'ה': 5,
|
|
10
|
-
'ו': 6,
|
|
11
|
-
'ז': 7,
|
|
12
|
-
'ח': 8,
|
|
13
|
-
'ט': 9,
|
|
14
|
-
'י': 10,
|
|
15
|
-
'כ': 20,
|
|
16
|
-
'ל': 30,
|
|
17
|
-
'מ': 40,
|
|
18
|
-
'נ': 50,
|
|
19
|
-
'ס': 60,
|
|
20
|
-
'ע': 70,
|
|
21
|
-
'פ': 80,
|
|
22
|
-
'צ': 90,
|
|
23
|
-
'ק': 100,
|
|
24
|
-
'ר': 200,
|
|
25
|
-
'ש': 300,
|
|
26
|
-
'ת': 400
|
|
27
|
-
};
|
|
28
|
-
const num2heb = new Map();
|
|
29
|
-
Object.keys(heb2num).forEach(key => {
|
|
30
|
-
const val = heb2num[key];
|
|
31
|
-
num2heb.set(val, key);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @private
|
|
36
|
-
* @param {number} num
|
|
37
|
-
* @return {number[]}
|
|
38
|
-
*/
|
|
39
|
-
function num2digits(num) {
|
|
40
|
-
const digits = [];
|
|
41
|
-
while (num > 0) {
|
|
42
|
-
if (num === 15 || num === 16) {
|
|
43
|
-
digits.push(9);
|
|
44
|
-
digits.push(num - 9);
|
|
45
|
-
break;
|
|
46
|
-
}
|
|
47
|
-
let incr = 100;
|
|
48
|
-
let i;
|
|
49
|
-
for (i = 400; i > num; i -= incr) {
|
|
50
|
-
if (i === incr) {
|
|
51
|
-
incr = incr / 10;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
digits.push(i);
|
|
55
|
-
num -= i;
|
|
56
|
-
}
|
|
57
|
-
return digits;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Converts a numerical value to a string of Hebrew letters.
|
|
62
|
-
*
|
|
63
|
-
* When specifying years of the Hebrew calendar in the present millennium,
|
|
64
|
-
* we omit the thousands (which is presently 5 [ה]).
|
|
65
|
-
* @example
|
|
66
|
-
* gematriya(5774) // 'תשע״ד' - cropped to 774
|
|
67
|
-
* gematriya(25) // 'כ״ה'
|
|
68
|
-
* gematriya(60) // 'ס׳'
|
|
69
|
-
* gematriya(3761) // 'ג׳תשס״א'
|
|
70
|
-
* gematriya(1123) // 'א׳קכ״ג'
|
|
71
|
-
* @param {number} number
|
|
72
|
-
* @return {string}
|
|
73
|
-
*/
|
|
74
|
-
function gematriya(number) {
|
|
75
|
-
const num = parseInt(number, 10);
|
|
76
|
-
if (!num) {
|
|
77
|
-
throw new TypeError(`invalid parameter to gematriya ${number}`);
|
|
78
|
-
}
|
|
79
|
-
let str = '';
|
|
80
|
-
const thousands = Math.floor(num / 1000);
|
|
81
|
-
if (thousands > 0 && thousands !== 5) {
|
|
82
|
-
const tdigits = num2digits(thousands);
|
|
83
|
-
for (const tdig of tdigits) {
|
|
84
|
-
str += num2heb.get(tdig);
|
|
85
|
-
}
|
|
86
|
-
str += GERESH;
|
|
87
|
-
}
|
|
88
|
-
const digits = num2digits(num % 1000);
|
|
89
|
-
if (digits.length == 1) {
|
|
90
|
-
return str + num2heb.get(digits[0]) + GERESH;
|
|
91
|
-
}
|
|
92
|
-
for (let i = 0; i < digits.length; i++) {
|
|
93
|
-
if (i + 1 === digits.length) {
|
|
94
|
-
str += GERSHAYIM;
|
|
95
|
-
}
|
|
96
|
-
str += num2heb.get(digits[i]);
|
|
97
|
-
}
|
|
98
|
-
return str;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Converts a string of Hebrew letters to a numerical value.
|
|
103
|
-
*
|
|
104
|
-
* Only considers the value of Hebrew letters `א` through `ת`.
|
|
105
|
-
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
|
|
106
|
-
* and vowels (nekudot).
|
|
107
|
-
*
|
|
108
|
-
* @param {string} str
|
|
109
|
-
* @return {number}
|
|
110
|
-
*/
|
|
111
|
-
function gematriyaStrToNum(str) {
|
|
112
|
-
let num = 0;
|
|
113
|
-
const gereshIdx = str.indexOf(GERESH);
|
|
114
|
-
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
115
|
-
const thousands = str.substring(0, gereshIdx);
|
|
116
|
-
num += gematriyaStrToNum(thousands) * 1000;
|
|
117
|
-
str = str.substring(gereshIdx);
|
|
118
|
-
}
|
|
119
|
-
for (const ch of str) {
|
|
120
|
-
const n = heb2num[ch];
|
|
121
|
-
if (typeof n === 'number') {
|
|
122
|
-
num += n;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return num;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const noopLocale = {
|
|
129
|
-
headers: {
|
|
130
|
-
'plural-forms': 'nplurals=2; plural=(n!=1);'
|
|
131
|
-
},
|
|
132
|
-
contexts: {
|
|
133
|
-
'': {}
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
const alias = {
|
|
137
|
-
'h': 'he',
|
|
138
|
-
'a': 'ashkenazi',
|
|
139
|
-
's': 'en',
|
|
140
|
-
'': 'en'
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
/** @private */
|
|
144
|
-
const locales = new Map();
|
|
145
|
-
/** @private */
|
|
146
|
-
let activeLocale = null;
|
|
147
|
-
/** @private */
|
|
148
|
-
let activeName = null;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* A locale in Hebcal is used for translations/transliterations of
|
|
152
|
-
* holidays. `@hebcal/core` supports four locales by default
|
|
153
|
-
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
|
|
154
|
-
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
|
|
155
|
-
* * `he` - Hebrew (e.g. "שַׁבָּת")
|
|
156
|
-
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
|
|
157
|
-
*/
|
|
158
|
-
class Locale {
|
|
159
|
-
/**
|
|
160
|
-
* Returns translation only if `locale` offers a non-empty translation for `id`.
|
|
161
|
-
* Otherwise, returns `undefined`.
|
|
162
|
-
* @param {string} id Message ID to translate
|
|
163
|
-
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
164
|
-
* @return {string}
|
|
165
|
-
*/
|
|
166
|
-
static lookupTranslation(id, locale) {
|
|
167
|
-
const locale0 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
168
|
-
const loc = typeof locale == 'string' && locales.get(locale0) || activeLocale;
|
|
169
|
-
const array = loc[id];
|
|
170
|
-
if (array && array.length && array[0].length) {
|
|
171
|
-
return array[0];
|
|
172
|
-
}
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* By default, if no translation was found, returns `id`.
|
|
178
|
-
* @param {string} id Message ID to translate
|
|
179
|
-
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
180
|
-
* @return {string}
|
|
181
|
-
*/
|
|
182
|
-
static gettext(id, locale) {
|
|
183
|
-
const text = this.lookupTranslation(id, locale);
|
|
184
|
-
if (typeof text == 'undefined') {
|
|
185
|
-
return id;
|
|
186
|
-
}
|
|
187
|
-
return text;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Register locale translations.
|
|
192
|
-
* @param {string} locale Locale name (i.e.: `'he'`, `'fr'`)
|
|
193
|
-
* @param {LocaleData} data parsed data from a `.po` file.
|
|
194
|
-
*/
|
|
195
|
-
static addLocale(locale, data) {
|
|
196
|
-
if (typeof locale !== 'string') {
|
|
197
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
198
|
-
}
|
|
199
|
-
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
200
|
-
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
201
|
-
}
|
|
202
|
-
locales.set(locale.toLowerCase(), data.contexts['']);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Adds a translation to `locale`, replacing any previous translation.
|
|
207
|
-
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
208
|
-
* @param {string} id Message ID to translate
|
|
209
|
-
* @param {string} translation Translation text
|
|
210
|
-
*/
|
|
211
|
-
static addTranslation(locale, id, translation) {
|
|
212
|
-
if (typeof locale !== 'string') {
|
|
213
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
214
|
-
}
|
|
215
|
-
const locale0 = locale.toLowerCase();
|
|
216
|
-
const loc = locales.get(locale0);
|
|
217
|
-
if (!loc) {
|
|
218
|
-
throw new TypeError(`Unknown locale: ${locale}`);
|
|
219
|
-
}
|
|
220
|
-
if (typeof id !== 'string' || id.length === 0) {
|
|
221
|
-
throw new TypeError(`Invalid id: ${id}`);
|
|
222
|
-
}
|
|
223
|
-
const isArray = Array.isArray(translation);
|
|
224
|
-
if (isArray) {
|
|
225
|
-
const t0 = translation[0];
|
|
226
|
-
if (typeof t0 !== 'string' || t0.length === 0) {
|
|
227
|
-
throw new TypeError(`Invalid translation array: ${translation}`);
|
|
228
|
-
}
|
|
229
|
-
} else if (typeof translation !== 'string') {
|
|
230
|
-
throw new TypeError(`Invalid translation: ${translation}`);
|
|
231
|
-
}
|
|
232
|
-
loc[id] = isArray ? translation : [translation];
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Adds multiple translations to `locale`, replacing any previous translations.
|
|
236
|
-
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
237
|
-
* @param {LocaleData} data parsed data from a `.po` file.
|
|
238
|
-
*/
|
|
239
|
-
static addTranslations(locale, data) {
|
|
240
|
-
if (typeof locale !== 'string') {
|
|
241
|
-
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
242
|
-
}
|
|
243
|
-
const locale0 = locale.toLowerCase();
|
|
244
|
-
const loc = locales.get(locale0);
|
|
245
|
-
if (!loc) {
|
|
246
|
-
throw new TypeError(`Unknown locale: ${locale}`);
|
|
247
|
-
}
|
|
248
|
-
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
249
|
-
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
250
|
-
}
|
|
251
|
-
const ctx = data.contexts[''];
|
|
252
|
-
Object.keys(ctx).forEach(id => {
|
|
253
|
-
loc[id] = ctx[id];
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Activates a locale. Throws an error if the locale has not been previously added.
|
|
258
|
-
* After setting the locale to be used, all strings marked for translations
|
|
259
|
-
* will be represented by the corresponding translation in the specified locale.
|
|
260
|
-
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`)
|
|
261
|
-
* @return {LocaleData}
|
|
262
|
-
*/
|
|
263
|
-
static useLocale(locale) {
|
|
264
|
-
const locale0 = locale.toLowerCase();
|
|
265
|
-
const obj = locales.get(locale0);
|
|
266
|
-
if (!obj) {
|
|
267
|
-
throw new RangeError(`Locale '${locale}' not found`);
|
|
268
|
-
}
|
|
269
|
-
activeName = alias[locale0] || locale0;
|
|
270
|
-
activeLocale = obj;
|
|
271
|
-
return activeLocale;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Returns the name of the active locale (i.e. 'he', 'ashkenazi', 'fr')
|
|
276
|
-
* @return {string}
|
|
277
|
-
*/
|
|
278
|
-
static getLocaleName() {
|
|
279
|
-
return activeName;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Returns the names of registered locales
|
|
284
|
-
* @return {string[]}
|
|
285
|
-
*/
|
|
286
|
-
static getLocaleNames() {
|
|
287
|
-
const keys = Array.from(locales.keys());
|
|
288
|
-
return keys.sort((a, b) => a.localeCompare(b));
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* @param {number} n
|
|
293
|
-
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
294
|
-
* @return {string}
|
|
295
|
-
*/
|
|
296
|
-
static ordinal(n, locale) {
|
|
297
|
-
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
298
|
-
const locale0 = locale1 || activeName;
|
|
299
|
-
if (!locale0) {
|
|
300
|
-
return this.getEnOrdinal(n);
|
|
301
|
-
}
|
|
302
|
-
switch (locale0) {
|
|
303
|
-
case 'en':
|
|
304
|
-
case 's':
|
|
305
|
-
case 'a':
|
|
306
|
-
case 'ashkenazi':
|
|
307
|
-
case 'ashkenazi_litvish':
|
|
308
|
-
case 'ashkenazi_poylish':
|
|
309
|
-
case 'ashkenazi_standard':
|
|
310
|
-
return this.getEnOrdinal(n);
|
|
311
|
-
case 'es':
|
|
312
|
-
return n + 'º';
|
|
313
|
-
case 'h':
|
|
314
|
-
case 'he':
|
|
315
|
-
case 'he-x-nonikud':
|
|
316
|
-
return String(n);
|
|
317
|
-
default:
|
|
318
|
-
return n + '.';
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* @private
|
|
324
|
-
* @param {number} n
|
|
325
|
-
* @return {string}
|
|
326
|
-
*/
|
|
327
|
-
static getEnOrdinal(n) {
|
|
328
|
-
const s = ['th', 'st', 'nd', 'rd'];
|
|
329
|
-
const v = n % 100;
|
|
330
|
-
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Removes nekudot from Hebrew string
|
|
335
|
-
* @param {string} str
|
|
336
|
-
* @return {string}
|
|
337
|
-
*/
|
|
338
|
-
static hebrewStripNikkud(str) {
|
|
339
|
-
return str.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
Locale.addLocale('en', noopLocale);
|
|
343
|
-
Locale.addLocale('s', noopLocale);
|
|
344
|
-
Locale.addLocale('', noopLocale);
|
|
345
|
-
Locale.useLocale('en');
|
|
346
|
-
|
|
1
|
+
/*! @hebcal/core v5.0.2 */
|
|
347
2
|
/** @private */
|
|
348
3
|
const lengths = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
349
4
|
/** @private */
|
|
@@ -937,76 +592,413 @@ function toSimpleHebrewDate(obj) {
|
|
|
937
592
|
else {
|
|
938
593
|
throw new TypeError(`Argument not a Date: ${obj}`);
|
|
939
594
|
}
|
|
940
|
-
}
|
|
941
|
-
function getYahrzeitHD(hyear, date) {
|
|
942
|
-
let hDeath = toSimpleHebrewDate(date);
|
|
943
|
-
if (hyear <= hDeath.yy) {
|
|
944
|
-
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
945
|
-
return undefined;
|
|
595
|
+
}
|
|
596
|
+
function getYahrzeitHD(hyear, date) {
|
|
597
|
+
let hDeath = toSimpleHebrewDate(date);
|
|
598
|
+
if (hyear <= hDeath.yy) {
|
|
599
|
+
// Hebrew year ${hyear} occurs on or before original date in ${hDeath.yy}
|
|
600
|
+
return undefined;
|
|
601
|
+
}
|
|
602
|
+
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hDeath.yy + 1)) {
|
|
603
|
+
// If it's Heshvan 30 it depends on the first anniversary;
|
|
604
|
+
// if that was not Heshvan 30, use the day before Kislev 1.
|
|
605
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, KISLEV$1, 1) - 1);
|
|
606
|
+
}
|
|
607
|
+
else if (hDeath.mm == KISLEV$1 && hDeath.dd == 30 && shortKislev(hDeath.yy + 1)) {
|
|
608
|
+
// If it's Kislev 30 it depends on the first anniversary;
|
|
609
|
+
// if that was not Kislev 30, use the day before Teveth 1.
|
|
610
|
+
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
611
|
+
}
|
|
612
|
+
else if (hDeath.mm == ADAR_II) {
|
|
613
|
+
// If it's Adar II, use the same day in last month of year (Adar or Adar II).
|
|
614
|
+
hDeath.mm = monthsInYear(hyear);
|
|
615
|
+
}
|
|
616
|
+
else if (hDeath.mm == ADAR_I$1 && hDeath.dd == 30 && !isLeapYear(hyear)) {
|
|
617
|
+
// If it's the 30th in Adar I and year is not a leap year
|
|
618
|
+
// (so Adar has only 29 days), use the last day in Shevat.
|
|
619
|
+
hDeath.dd = 30;
|
|
620
|
+
hDeath.mm = SHVAT;
|
|
621
|
+
}
|
|
622
|
+
// In all other cases, use the normal anniversary of the date of death.
|
|
623
|
+
// advance day to rosh chodesh if needed
|
|
624
|
+
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hyear)) {
|
|
625
|
+
hDeath.mm = KISLEV$1;
|
|
626
|
+
hDeath.dd = 1;
|
|
627
|
+
}
|
|
628
|
+
else if (hDeath.mm == KISLEV$1 && hDeath.dd == 30 && shortKislev(hyear)) {
|
|
629
|
+
hDeath.mm = TEVET$1;
|
|
630
|
+
hDeath.dd = 1;
|
|
631
|
+
}
|
|
632
|
+
hDeath.yy = hyear;
|
|
633
|
+
return hDeath;
|
|
634
|
+
}
|
|
635
|
+
function getBirthdayHD(hyear, date) {
|
|
636
|
+
const orig = toSimpleHebrewDate(date);
|
|
637
|
+
const origYear = orig.yy;
|
|
638
|
+
if (hyear === origYear) {
|
|
639
|
+
return orig;
|
|
640
|
+
}
|
|
641
|
+
else if (hyear < origYear) {
|
|
642
|
+
// Hebrew year ${hyear} occurs on or before original date in ${origYear}
|
|
643
|
+
return undefined;
|
|
644
|
+
}
|
|
645
|
+
const isOrigLeap = isLeapYear(origYear);
|
|
646
|
+
let month = orig.mm;
|
|
647
|
+
let day = orig.dd;
|
|
648
|
+
if ((month == ADAR_I$1 && !isOrigLeap) || (month == ADAR_II && isOrigLeap)) {
|
|
649
|
+
month = monthsInYear(hyear);
|
|
650
|
+
}
|
|
651
|
+
else if (month == CHESHVAN && day == 30 && !longCheshvan(hyear)) {
|
|
652
|
+
month = KISLEV$1;
|
|
653
|
+
day = 1;
|
|
654
|
+
}
|
|
655
|
+
else if (month == KISLEV$1 && day == 30 && shortKislev(hyear)) {
|
|
656
|
+
month = TEVET$1;
|
|
657
|
+
day = 1;
|
|
658
|
+
}
|
|
659
|
+
else if (month == ADAR_I$1 && day == 30 && isOrigLeap && !isLeapYear(hyear)) {
|
|
660
|
+
month = NISAN$3;
|
|
661
|
+
day = 1;
|
|
662
|
+
}
|
|
663
|
+
return { yy: hyear, mm: month, dd: day };
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
const GERESH = '׳';
|
|
667
|
+
const GERSHAYIM = '״';
|
|
668
|
+
const alefbet = {
|
|
669
|
+
'א': 1,
|
|
670
|
+
'ב': 2,
|
|
671
|
+
'ג': 3,
|
|
672
|
+
'ד': 4,
|
|
673
|
+
'ה': 5,
|
|
674
|
+
'ו': 6,
|
|
675
|
+
'ז': 7,
|
|
676
|
+
'ח': 8,
|
|
677
|
+
'ט': 9,
|
|
678
|
+
'י': 10,
|
|
679
|
+
'כ': 20,
|
|
680
|
+
'ל': 30,
|
|
681
|
+
'מ': 40,
|
|
682
|
+
'נ': 50,
|
|
683
|
+
'ס': 60,
|
|
684
|
+
'ע': 70,
|
|
685
|
+
'פ': 80,
|
|
686
|
+
'צ': 90,
|
|
687
|
+
'ק': 100,
|
|
688
|
+
'ר': 200,
|
|
689
|
+
'ש': 300,
|
|
690
|
+
'ת': 400,
|
|
691
|
+
};
|
|
692
|
+
const heb2num = new Map();
|
|
693
|
+
const num2heb = new Map();
|
|
694
|
+
for (const [key, val] of Object.entries(alefbet)) {
|
|
695
|
+
heb2num.set(key, val);
|
|
696
|
+
num2heb.set(val, key);
|
|
697
|
+
}
|
|
698
|
+
function num2digits(num) {
|
|
699
|
+
const digits = [];
|
|
700
|
+
while (num > 0) {
|
|
701
|
+
if (num === 15 || num === 16) {
|
|
702
|
+
digits.push(9);
|
|
703
|
+
digits.push(num - 9);
|
|
704
|
+
break;
|
|
705
|
+
}
|
|
706
|
+
let incr = 100;
|
|
707
|
+
let i;
|
|
708
|
+
for (i = 400; i > num; i -= incr) {
|
|
709
|
+
if (i === incr) {
|
|
710
|
+
incr = incr / 10;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
digits.push(i);
|
|
714
|
+
num -= i;
|
|
715
|
+
}
|
|
716
|
+
return digits;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Converts a numerical value to a string of Hebrew letters.
|
|
720
|
+
*
|
|
721
|
+
* When specifying years of the Hebrew calendar in the present millennium,
|
|
722
|
+
* we omit the thousands (which is presently 5 [ה]).
|
|
723
|
+
* @example
|
|
724
|
+
* gematriya(5774) // 'תשע״ד' - cropped to 774
|
|
725
|
+
* gematriya(25) // 'כ״ה'
|
|
726
|
+
* gematriya(60) // 'ס׳'
|
|
727
|
+
* gematriya(3761) // 'ג׳תשס״א'
|
|
728
|
+
* gematriya(1123) // 'א׳קכ״ג'
|
|
729
|
+
* @param {number} num
|
|
730
|
+
* @return {string}
|
|
731
|
+
*/
|
|
732
|
+
function gematriya(num) {
|
|
733
|
+
const num0 = num;
|
|
734
|
+
const num1 = parseInt(num0, 10);
|
|
735
|
+
if (!num1) {
|
|
736
|
+
throw new TypeError(`invalid parameter to gematriya ${num}`);
|
|
737
|
+
}
|
|
738
|
+
let str = '';
|
|
739
|
+
const thousands = Math.floor(num1 / 1000);
|
|
740
|
+
if (thousands > 0 && thousands !== 5) {
|
|
741
|
+
const tdigits = num2digits(thousands);
|
|
742
|
+
for (const tdig of tdigits) {
|
|
743
|
+
str += num2heb.get(tdig);
|
|
744
|
+
}
|
|
745
|
+
str += GERESH;
|
|
746
|
+
}
|
|
747
|
+
const digits = num2digits(num1 % 1000);
|
|
748
|
+
if (digits.length == 1) {
|
|
749
|
+
return str + num2heb.get(digits[0]) + GERESH;
|
|
750
|
+
}
|
|
751
|
+
for (let i = 0; i < digits.length; i++) {
|
|
752
|
+
if (i + 1 === digits.length) {
|
|
753
|
+
str += GERSHAYIM;
|
|
754
|
+
}
|
|
755
|
+
str += num2heb.get(digits[i]);
|
|
756
|
+
}
|
|
757
|
+
return str;
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Converts a string of Hebrew letters to a numerical value.
|
|
761
|
+
*
|
|
762
|
+
* Only considers the value of Hebrew letters `א` through `ת`.
|
|
763
|
+
* Ignores final Hebrew letters such as `ך` (kaf sofit) or `ם` (mem sofit)
|
|
764
|
+
* and vowels (nekudot).
|
|
765
|
+
*
|
|
766
|
+
* @param {string} str
|
|
767
|
+
* @return {number}
|
|
768
|
+
*/
|
|
769
|
+
function gematriyaStrToNum(str) {
|
|
770
|
+
let num = 0;
|
|
771
|
+
const gereshIdx = str.indexOf(GERESH);
|
|
772
|
+
if (gereshIdx !== -1 && gereshIdx !== str.length - 1) {
|
|
773
|
+
const thousands = str.substring(0, gereshIdx);
|
|
774
|
+
num += gematriyaStrToNum(thousands) * 1000;
|
|
775
|
+
str = str.substring(gereshIdx);
|
|
776
|
+
}
|
|
777
|
+
for (const ch of str) {
|
|
778
|
+
const n = heb2num.get(ch);
|
|
779
|
+
if (typeof n === 'number') {
|
|
780
|
+
num += n;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
return num;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const noopLocale = {
|
|
787
|
+
headers: {
|
|
788
|
+
'plural-forms': 'nplurals=2; plural=(n!=1);'
|
|
789
|
+
},
|
|
790
|
+
contexts: {
|
|
791
|
+
'': {}
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
const alias = {
|
|
795
|
+
'h': 'he',
|
|
796
|
+
'a': 'ashkenazi',
|
|
797
|
+
's': 'en',
|
|
798
|
+
'': 'en'
|
|
799
|
+
};
|
|
800
|
+
|
|
801
|
+
/** @private */
|
|
802
|
+
const locales = new Map();
|
|
803
|
+
/** @private */
|
|
804
|
+
let activeLocale = null;
|
|
805
|
+
/** @private */
|
|
806
|
+
let activeName = null;
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* A locale in Hebcal is used for translations/transliterations of
|
|
810
|
+
* holidays. `@hebcal/core` supports four locales by default
|
|
811
|
+
* * `en` - default, Sephardic transliterations (e.g. "Shabbat")
|
|
812
|
+
* * `ashkenazi` - Ashkenazi transliterations (e.g. "Shabbos")
|
|
813
|
+
* * `he` - Hebrew (e.g. "שַׁבָּת")
|
|
814
|
+
* * `he-x-NoNikud` - Hebrew without nikud (e.g. "שבת")
|
|
815
|
+
*/
|
|
816
|
+
class Locale {
|
|
817
|
+
/**
|
|
818
|
+
* Returns translation only if `locale` offers a non-empty translation for `id`.
|
|
819
|
+
* Otherwise, returns `undefined`.
|
|
820
|
+
* @param {string} id Message ID to translate
|
|
821
|
+
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
822
|
+
* @return {string}
|
|
823
|
+
*/
|
|
824
|
+
static lookupTranslation(id, locale) {
|
|
825
|
+
const locale0 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
826
|
+
const loc = typeof locale == 'string' && locales.get(locale0) || activeLocale;
|
|
827
|
+
const array = loc[id];
|
|
828
|
+
if (array && array.length && array[0].length) {
|
|
829
|
+
return array[0];
|
|
830
|
+
}
|
|
831
|
+
return undefined;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
/**
|
|
835
|
+
* By default, if no translation was found, returns `id`.
|
|
836
|
+
* @param {string} id Message ID to translate
|
|
837
|
+
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
838
|
+
* @return {string}
|
|
839
|
+
*/
|
|
840
|
+
static gettext(id, locale) {
|
|
841
|
+
const text = this.lookupTranslation(id, locale);
|
|
842
|
+
if (typeof text == 'undefined') {
|
|
843
|
+
return id;
|
|
946
844
|
}
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
845
|
+
return text;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Register locale translations.
|
|
850
|
+
* @param {string} locale Locale name (i.e.: `'he'`, `'fr'`)
|
|
851
|
+
* @param {LocaleData} data parsed data from a `.po` file.
|
|
852
|
+
*/
|
|
853
|
+
static addLocale(locale, data) {
|
|
854
|
+
if (typeof locale !== 'string') {
|
|
855
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
951
856
|
}
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
// if that was not Kislev 30, use the day before Teveth 1.
|
|
955
|
-
hDeath = abs2hebrew(hebrew2abs(hyear, TEVET$1, 1) - 1);
|
|
857
|
+
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
858
|
+
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
956
859
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
860
|
+
locales.set(locale.toLowerCase(), data.contexts['']);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Adds a translation to `locale`, replacing any previous translation.
|
|
865
|
+
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
866
|
+
* @param {string} id Message ID to translate
|
|
867
|
+
* @param {string} translation Translation text
|
|
868
|
+
*/
|
|
869
|
+
static addTranslation(locale, id, translation) {
|
|
870
|
+
if (typeof locale !== 'string') {
|
|
871
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
960
872
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
hDeath.mm = SHVAT;
|
|
873
|
+
const locale0 = locale.toLowerCase();
|
|
874
|
+
const loc = locales.get(locale0);
|
|
875
|
+
if (!loc) {
|
|
876
|
+
throw new TypeError(`Unknown locale: ${locale}`);
|
|
966
877
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !longCheshvan(hyear)) {
|
|
970
|
-
hDeath.mm = KISLEV$1;
|
|
971
|
-
hDeath.dd = 1;
|
|
878
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
879
|
+
throw new TypeError(`Invalid id: ${id}`);
|
|
972
880
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
881
|
+
const isArray = Array.isArray(translation);
|
|
882
|
+
if (isArray) {
|
|
883
|
+
const t0 = translation[0];
|
|
884
|
+
if (typeof t0 !== 'string' || t0.length === 0) {
|
|
885
|
+
throw new TypeError(`Invalid translation array: ${translation}`);
|
|
886
|
+
}
|
|
887
|
+
} else if (typeof translation !== 'string') {
|
|
888
|
+
throw new TypeError(`Invalid translation: ${translation}`);
|
|
976
889
|
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
890
|
+
loc[id] = isArray ? translation : [translation];
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Adds multiple translations to `locale`, replacing any previous translations.
|
|
894
|
+
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`).
|
|
895
|
+
* @param {LocaleData} data parsed data from a `.po` file.
|
|
896
|
+
*/
|
|
897
|
+
static addTranslations(locale, data) {
|
|
898
|
+
if (typeof locale !== 'string') {
|
|
899
|
+
throw new TypeError(`Invalid locale name: ${locale}`);
|
|
985
900
|
}
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
901
|
+
const locale0 = locale.toLowerCase();
|
|
902
|
+
const loc = locales.get(locale0);
|
|
903
|
+
if (!loc) {
|
|
904
|
+
throw new TypeError(`Unknown locale: ${locale}`);
|
|
989
905
|
}
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
let day = orig.dd;
|
|
993
|
-
if ((month == ADAR_I$1 && !isOrigLeap) || (month == ADAR_II && isOrigLeap)) {
|
|
994
|
-
month = monthsInYear(hyear);
|
|
906
|
+
if (typeof data.contexts !== 'object' || typeof data.contexts[''] !== 'object') {
|
|
907
|
+
throw new TypeError(`Locale '${locale}' invalid compact format`);
|
|
995
908
|
}
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
909
|
+
const ctx = data.contexts[''];
|
|
910
|
+
Object.assign(loc, ctx);
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Activates a locale. Throws an error if the locale has not been previously added.
|
|
914
|
+
* After setting the locale to be used, all strings marked for translations
|
|
915
|
+
* will be represented by the corresponding translation in the specified locale.
|
|
916
|
+
* @param {string} locale Locale name (i.e: `'he'`, `'fr'`)
|
|
917
|
+
* @return {LocaleData}
|
|
918
|
+
*/
|
|
919
|
+
static useLocale(locale) {
|
|
920
|
+
const locale0 = locale.toLowerCase();
|
|
921
|
+
const obj = locales.get(locale0);
|
|
922
|
+
if (!obj) {
|
|
923
|
+
throw new RangeError(`Locale '${locale}' not found`);
|
|
999
924
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
925
|
+
activeName = alias[locale0] || locale0;
|
|
926
|
+
activeLocale = obj;
|
|
927
|
+
return activeLocale;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Returns the name of the active locale (i.e. 'he', 'ashkenazi', 'fr')
|
|
932
|
+
* @return {string}
|
|
933
|
+
*/
|
|
934
|
+
static getLocaleName() {
|
|
935
|
+
return activeName;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* Returns the names of registered locales
|
|
940
|
+
* @return {string[]}
|
|
941
|
+
*/
|
|
942
|
+
static getLocaleNames() {
|
|
943
|
+
const keys = Array.from(locales.keys());
|
|
944
|
+
return keys.sort((a, b) => a.localeCompare(b));
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* @param {number} n
|
|
949
|
+
* @param {string} [locale] Optional locale name (i.e: `'he'`, `'fr'`). Defaults to active locale.
|
|
950
|
+
* @return {string}
|
|
951
|
+
*/
|
|
952
|
+
static ordinal(n, locale) {
|
|
953
|
+
const locale1 = locale === null || locale === void 0 ? void 0 : locale.toLowerCase();
|
|
954
|
+
const locale0 = locale1 || activeName;
|
|
955
|
+
if (!locale0) {
|
|
956
|
+
return this.getEnOrdinal(n);
|
|
1003
957
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
958
|
+
switch (locale0) {
|
|
959
|
+
case 'en':
|
|
960
|
+
case 's':
|
|
961
|
+
case 'a':
|
|
962
|
+
case 'ashkenazi':
|
|
963
|
+
case 'ashkenazi_litvish':
|
|
964
|
+
case 'ashkenazi_poylish':
|
|
965
|
+
case 'ashkenazi_standard':
|
|
966
|
+
return this.getEnOrdinal(n);
|
|
967
|
+
case 'es':
|
|
968
|
+
return n + 'º';
|
|
969
|
+
case 'h':
|
|
970
|
+
case 'he':
|
|
971
|
+
case 'he-x-nonikud':
|
|
972
|
+
return String(n);
|
|
973
|
+
default:
|
|
974
|
+
return n + '.';
|
|
1007
975
|
}
|
|
1008
|
-
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* @private
|
|
980
|
+
* @param {number} n
|
|
981
|
+
* @return {string}
|
|
982
|
+
*/
|
|
983
|
+
static getEnOrdinal(n) {
|
|
984
|
+
const s = ['th', 'st', 'nd', 'rd'];
|
|
985
|
+
const v = n % 100;
|
|
986
|
+
return n + (s[(v - 20) % 10] || s[v] || s[0]);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Removes nekudot from Hebrew string
|
|
991
|
+
* @param {string} str
|
|
992
|
+
* @return {string}
|
|
993
|
+
*/
|
|
994
|
+
static hebrewStripNikkud(str) {
|
|
995
|
+
return str.replace(/[\u0590-\u05bd]/g, '').replace(/[\u05bf-\u05c7]/g, '');
|
|
996
|
+
}
|
|
1009
997
|
}
|
|
998
|
+
Locale.addLocale('en', noopLocale);
|
|
999
|
+
Locale.addLocale('s', noopLocale);
|
|
1000
|
+
Locale.addLocale('', noopLocale);
|
|
1001
|
+
Locale.useLocale('en');
|
|
1010
1002
|
|
|
1011
1003
|
/**
|
|
1012
1004
|
* @private
|
|
@@ -1835,7 +1827,7 @@ class Event {
|
|
|
1835
1827
|
this.desc = desc;
|
|
1836
1828
|
this.mask = +mask;
|
|
1837
1829
|
if (typeof attrs === 'object' && attrs !== null) {
|
|
1838
|
-
Object.
|
|
1830
|
+
Object.assign(this, attrs);
|
|
1839
1831
|
}
|
|
1840
1832
|
}
|
|
1841
1833
|
/**
|
|
@@ -3428,10 +3420,10 @@ class Location extends GeoLocation {
|
|
|
3428
3420
|
return true;
|
|
3429
3421
|
}
|
|
3430
3422
|
}
|
|
3431
|
-
|
|
3423
|
+
for (const city of classicCities0) {
|
|
3432
3424
|
const location = new Location(city[2], city[3], city[1] == 'IL', city[4], city[0], city[1], undefined, city[5]);
|
|
3433
3425
|
Location.addLocation(location.getName(), location);
|
|
3434
|
-
}
|
|
3426
|
+
}
|
|
3435
3427
|
|
|
3436
3428
|
const _formatters = new Map();
|
|
3437
3429
|
|
|
@@ -5610,40 +5602,7 @@ const MINOR_HOLIDAY$1 = flags.MINOR_HOLIDAY;
|
|
|
5610
5602
|
const EREV$1 = flags.EREV;
|
|
5611
5603
|
// const CHOL_HAMOED = flags.CHOL_HAMOED;
|
|
5612
5604
|
|
|
5613
|
-
|
|
5614
|
-
* Avoid dependency on ES6 Map object
|
|
5615
|
-
* @private
|
|
5616
|
-
*/
|
|
5617
|
-
class SimpleMap {
|
|
5618
|
-
/**
|
|
5619
|
-
* @param {string} key
|
|
5620
|
-
* @return {boolean}
|
|
5621
|
-
*/
|
|
5622
|
-
has(key) {
|
|
5623
|
-
return typeof this[key] !== 'undefined';
|
|
5624
|
-
}
|
|
5625
|
-
/**
|
|
5626
|
-
* @param {string} key
|
|
5627
|
-
* @return {any}
|
|
5628
|
-
*/
|
|
5629
|
-
get(key) {
|
|
5630
|
-
return this[key];
|
|
5631
|
-
}
|
|
5632
|
-
/**
|
|
5633
|
-
* @param {string} key
|
|
5634
|
-
* @param {any} val
|
|
5635
|
-
*/
|
|
5636
|
-
set(key, val) {
|
|
5637
|
-
this[key] = val;
|
|
5638
|
-
}
|
|
5639
|
-
/**
|
|
5640
|
-
* @return {string[]}
|
|
5641
|
-
*/
|
|
5642
|
-
keys() {
|
|
5643
|
-
return Object.keys(this);
|
|
5644
|
-
}
|
|
5645
|
-
}
|
|
5646
|
-
const sedraCache = new SimpleMap();
|
|
5605
|
+
const sedraCache = new Map();
|
|
5647
5606
|
|
|
5648
5607
|
/**
|
|
5649
5608
|
* @private
|
|
@@ -5687,13 +5646,12 @@ function getHolidaysForYear_(year) {
|
|
|
5687
5646
|
}
|
|
5688
5647
|
const RH = new HDate(1, TISHREI$1, year);
|
|
5689
5648
|
const pesach = new HDate(15, NISAN$1, year);
|
|
5690
|
-
const
|
|
5649
|
+
const map = new Map();
|
|
5691
5650
|
// eslint-disable-next-line require-jsdoc
|
|
5692
5651
|
function add(...events) {
|
|
5693
|
-
|
|
5694
|
-
events.forEach(ev => {
|
|
5652
|
+
for (const ev of events) {
|
|
5695
5653
|
const key = ev.date.toString();
|
|
5696
|
-
const arr =
|
|
5654
|
+
const arr = map.get(key);
|
|
5697
5655
|
if (typeof arr === 'object') {
|
|
5698
5656
|
if (arr[0].getFlags() & flags.EREV) {
|
|
5699
5657
|
arr.unshift(ev);
|
|
@@ -5701,17 +5659,17 @@ function getHolidaysForYear_(year) {
|
|
|
5701
5659
|
arr.push(ev);
|
|
5702
5660
|
}
|
|
5703
5661
|
} else {
|
|
5704
|
-
|
|
5662
|
+
map.set(key, [ev]);
|
|
5705
5663
|
}
|
|
5706
|
-
}
|
|
5664
|
+
}
|
|
5707
5665
|
}
|
|
5708
|
-
|
|
5666
|
+
for (const h of staticHolidays) {
|
|
5709
5667
|
const hd = new HDate(h.dd, h.mm, year);
|
|
5710
5668
|
const ev = new HolidayEvent(hd, h.desc, h.flags);
|
|
5711
5669
|
if (h.emoji) ev.emoji = h.emoji;
|
|
5712
5670
|
if (h.chmDay) ev.cholHaMoedDay = h.chmDay;
|
|
5713
5671
|
add(ev);
|
|
5714
|
-
}
|
|
5672
|
+
}
|
|
5715
5673
|
|
|
5716
5674
|
// standard holidays that don't shift based on year
|
|
5717
5675
|
add(new RoshHashanaEvent(RH, year, CHAG | LIGHT_CANDLES_TZEIS$1));
|
|
@@ -5763,7 +5721,7 @@ function getHolidaysForYear_(year) {
|
|
|
5763
5721
|
if (yomHaZikaronDt) {
|
|
5764
5722
|
add(new HolidayEvent(yomHaZikaronDt, 'Yom HaZikaron', MODERN_HOLIDAY$1, emojiIsraelFlag), new HolidayEvent(yomHaZikaronDt.next(), 'Yom HaAtzma\'ut', MODERN_HOLIDAY$1, emojiIsraelFlag));
|
|
5765
5723
|
}
|
|
5766
|
-
|
|
5724
|
+
for (const h of staticModernHolidays) {
|
|
5767
5725
|
if (year >= h.firstYear) {
|
|
5768
5726
|
let hd = new HDate(h.dd, h.mm, year);
|
|
5769
5727
|
const dow = hd.getDay();
|
|
@@ -5781,7 +5739,7 @@ function getHolidaysForYear_(year) {
|
|
|
5781
5739
|
}
|
|
5782
5740
|
add(ev);
|
|
5783
5741
|
}
|
|
5784
|
-
}
|
|
5742
|
+
}
|
|
5785
5743
|
let tamuz17 = new HDate(17, TAMUZ, year);
|
|
5786
5744
|
let tamuz17attrs;
|
|
5787
5745
|
if (tamuz17.getDay() == SAT$1) {
|
|
@@ -5852,8 +5810,8 @@ function getHolidaysForYear_(year) {
|
|
|
5852
5810
|
emoji: '☀️'
|
|
5853
5811
|
}));
|
|
5854
5812
|
}
|
|
5855
|
-
yearCache.set(year,
|
|
5856
|
-
return
|
|
5813
|
+
yearCache.set(year, map);
|
|
5814
|
+
return map;
|
|
5857
5815
|
}
|
|
5858
5816
|
|
|
5859
5817
|
/**
|
|
@@ -5920,7 +5878,7 @@ class DailyLearning {
|
|
|
5920
5878
|
}
|
|
5921
5879
|
}
|
|
5922
5880
|
|
|
5923
|
-
const version="5.0.
|
|
5881
|
+
const version="5.0.2";
|
|
5924
5882
|
|
|
5925
5883
|
const headers$1={"plural-forms":"nplurals=2; plural=(n > 1);"};const contexts$1={"":{Shabbat:["Shabbos"],"Achrei Mot":["Achrei Mos"],Bechukotai:["Bechukosai"],"Beha'alotcha":["Beha'aloscha"],Bereshit:["Bereshis"],Chukat:["Chukas"],"Erev Shavuot":["Erev Shavuos"],"Erev Sukkot":["Erev Sukkos"],"Ki Tavo":["Ki Savo"],"Ki Teitzei":["Ki Seitzei"],"Ki Tisa":["Ki Sisa"],Matot:["Matos"],"Purim Katan":["Purim Koton"],"Shabbat Chazon":["Shabbos Chazon"],"Shabbat HaChodesh":["Shabbos HaChodesh"],"Shabbat HaGadol":["Shabbos HaGadol"],"Shabbat Nachamu":["Shabbos Nachamu"],"Shabbat Parah":["Shabbos Parah"],"Shabbat Shekalim":["Shabbos Shekalim"],"Shabbat Shuva":["Shabbos Shuvah"],"Shabbat Zachor":["Shabbos Zachor"],Shavuot:["Shavuos"],"Shavuot I":["Shavuos I"],"Shavuot II":["Shavuos II"],Shemot:["Shemos"],"Shmini Atzeret":["Shmini Atzeres"],"Simchat Torah":["Simchas Torah"],Sukkot:["Sukkos"],"Sukkot I":["Sukkos I"],"Sukkot II":["Sukkos II"],"Sukkot II (CH''M)":["Sukkos II (CH''M)"],"Sukkot III (CH''M)":["Sukkos III (CH''M)"],"Sukkot IV (CH''M)":["Sukkos IV (CH''M)"],"Sukkot V (CH''M)":["Sukkos V (CH''M)"],"Sukkot VI (CH''M)":["Sukkos VI (CH''M)"],"Sukkot VII (Hoshana Raba)":["Sukkos VII (Hoshana Raba)"],"Ta'anit Bechorot":["Ta'anis Bechoros"],"Ta'anit Esther":["Ta'anis Esther"],Toldot:["Toldos"],Vaetchanan:["Vaeschanan"],Yitro:["Yisro"],"Vezot Haberakhah":["Vezos Haberakhah"],Parashat:["Parshas"],"Leil Selichot":["Leil Selichos"],"Shabbat Mevarchim Chodesh":["Shabbos Mevorchim Chodesh"],"Shabbat Shirah":["Shabbos Shirah"],Tevet:["Teves"],"Asara B'Tevet":["Asara B'Teves"],"Alot HaShachar":["Alos HaShachar"],"Kriat Shema, sof zeman":["Krias Shema, sof zman"],"Tefilah, sof zeman":["Tefilah, sof zman"],"Kriat Shema, sof zeman (MGA)":["Krias Shema, sof zman (MGA)"],"Tefilah, sof zeman (MGA)":["Tefilah, sof zman (MGA)"],"Chatzot HaLailah":["Chatzos HaLailah"],"Chatzot hayom":["Chatzos"],"Tzeit HaKochavim":["Tzeis HaKochavim"],"Birkat Hachamah":["Birkas Hachamah"],"Shushan Purim Katan":["Shushan Purim Koton"]}};var poAshkenazi = {headers:headers$1,contexts:contexts$1};
|
|
5926
5884
|
|
|
@@ -5933,9 +5891,9 @@ Locale.addLocale('he', poHe);
|
|
|
5933
5891
|
Locale.addLocale('h', poHe);
|
|
5934
5892
|
const heStrs = poHe.contexts[''];
|
|
5935
5893
|
const heNoNikud = {};
|
|
5936
|
-
Object.
|
|
5937
|
-
heNoNikud[key] = [Locale.hebrewStripNikkud(
|
|
5938
|
-
}
|
|
5894
|
+
for (const [key, val] of Object.entries(heStrs)) {
|
|
5895
|
+
heNoNikud[key] = [Locale.hebrewStripNikkud(val[0])];
|
|
5896
|
+
}
|
|
5939
5897
|
const poHeNoNikud = {
|
|
5940
5898
|
headers: poHe.headers,
|
|
5941
5899
|
contexts: {
|
|
@@ -6216,24 +6174,12 @@ const RECOGNIZED_OPTIONS = {
|
|
|
6216
6174
|
* @param {CalOptions} options
|
|
6217
6175
|
*/
|
|
6218
6176
|
function warnUnrecognizedOptions(options) {
|
|
6219
|
-
Object.keys(options)
|
|
6177
|
+
for (const k of Object.keys(options)) {
|
|
6220
6178
|
if (typeof RECOGNIZED_OPTIONS[k] === 'undefined' && !unrecognizedAlreadyWarned.has(k)) {
|
|
6221
6179
|
console.warn(`Ignoring unrecognized HebrewCalendar option: ${k}`);
|
|
6222
6180
|
unrecognizedAlreadyWarned.add(k);
|
|
6223
6181
|
}
|
|
6224
|
-
}
|
|
6225
|
-
}
|
|
6226
|
-
|
|
6227
|
-
/**
|
|
6228
|
-
* A bit like Object.assign(), but just a shallow copy
|
|
6229
|
-
* @private
|
|
6230
|
-
* @param {any} target
|
|
6231
|
-
* @param {any} source
|
|
6232
|
-
* @return {any}
|
|
6233
|
-
*/
|
|
6234
|
-
function shallowCopy(target, source) {
|
|
6235
|
-
Object.keys(source).forEach(k => target[k] = source[k]);
|
|
6236
|
-
return target;
|
|
6182
|
+
}
|
|
6237
6183
|
}
|
|
6238
6184
|
const israelCityOffset = {
|
|
6239
6185
|
'Jerusalem': 40,
|
|
@@ -6594,6 +6540,7 @@ function observedInDiaspora(ev) {
|
|
|
6594
6540
|
return ev.observedInDiaspora();
|
|
6595
6541
|
}
|
|
6596
6542
|
const yearArrayCache = new Map();
|
|
6543
|
+
const holidaysOnDate = new Map();
|
|
6597
6544
|
|
|
6598
6545
|
/**
|
|
6599
6546
|
* HebrewCalendar is the main interface to the `@hebcal/core` library.
|
|
@@ -6711,7 +6658,7 @@ class HebrewCalendar {
|
|
|
6711
6658
|
* @return {Event[]}
|
|
6712
6659
|
*/
|
|
6713
6660
|
static calendar(options = {}) {
|
|
6714
|
-
options =
|
|
6661
|
+
options = Object.assign({}, options); // so we can modify freely
|
|
6715
6662
|
checkCandleOptions(options);
|
|
6716
6663
|
const location = options.location = options.location || defaultLocation;
|
|
6717
6664
|
const il = options.il = options.il || location.il || false;
|
|
@@ -6760,9 +6707,9 @@ class HebrewCalendar {
|
|
|
6760
6707
|
const dow = hd.getDay();
|
|
6761
6708
|
let candlesEv;
|
|
6762
6709
|
const ev = holidaysYear.get(hd.toString()) || [];
|
|
6763
|
-
|
|
6710
|
+
for (const e of ev) {
|
|
6764
6711
|
candlesEv = appendHolidayAndRelated(evts, e, options, candlesEv, dow);
|
|
6765
|
-
}
|
|
6712
|
+
}
|
|
6766
6713
|
if (options.sedrot && dow === SAT) {
|
|
6767
6714
|
const parsha0 = sedra.lookup(abs);
|
|
6768
6715
|
if (!parsha0.chag) {
|
|
@@ -6771,8 +6718,7 @@ class HebrewCalendar {
|
|
|
6771
6718
|
}
|
|
6772
6719
|
const dailyLearning = options.dailyLearning;
|
|
6773
6720
|
if (typeof dailyLearning === 'object') {
|
|
6774
|
-
Object.
|
|
6775
|
-
const val = dailyLearning[key];
|
|
6721
|
+
for (const [key, val] of Object.entries(dailyLearning)) {
|
|
6776
6722
|
if (val) {
|
|
6777
6723
|
const name = key === 'yerushalmi' ? val === 2 ? 'yerushalmi-schottenstein' : 'yerushalmi-vilna' : key;
|
|
6778
6724
|
const learningEv = DailyLearning.lookup(name, hd);
|
|
@@ -6780,7 +6726,7 @@ class HebrewCalendar {
|
|
|
6780
6726
|
evts.push(learningEv);
|
|
6781
6727
|
}
|
|
6782
6728
|
}
|
|
6783
|
-
}
|
|
6729
|
+
}
|
|
6784
6730
|
}
|
|
6785
6731
|
if (options.omer && abs >= beginOmer && abs <= endOmer) {
|
|
6786
6732
|
const omer = abs - beginOmer + 1;
|
|
@@ -6942,20 +6888,29 @@ class HebrewCalendar {
|
|
|
6942
6888
|
}
|
|
6943
6889
|
|
|
6944
6890
|
/**
|
|
6945
|
-
* Returns an array of Events on this date (or undefined if no events)
|
|
6891
|
+
* Returns an array of Events on this date (or `undefined` if no events)
|
|
6946
6892
|
* @param {HDate|Date|number} date Hebrew Date, Gregorian date, or absolute R.D. day number
|
|
6947
6893
|
* @param {boolean} [il] use the Israeli schedule for holidays
|
|
6948
6894
|
* @return {Event[]}
|
|
6949
6895
|
*/
|
|
6950
6896
|
static getHolidaysOnDate(date, il) {
|
|
6951
6897
|
const hd = HDate.isHDate(date) ? date : new HDate(date);
|
|
6898
|
+
const hdStr = hd.toString();
|
|
6899
|
+
const cacheKey = hdStr + '/' + (typeof il === 'undefined' ? 2 : il ? 1 : 0);
|
|
6900
|
+
if (holidaysOnDate.has(cacheKey)) {
|
|
6901
|
+
return holidaysOnDate.get(cacheKey);
|
|
6902
|
+
}
|
|
6952
6903
|
const yearMap = getHolidaysForYear_(hd.getFullYear());
|
|
6953
|
-
const events = yearMap.get(
|
|
6904
|
+
const events = yearMap.get(hdStr);
|
|
6905
|
+
// if il isn't a boolean return both diaspora + IL for day
|
|
6954
6906
|
if (typeof il === 'undefined' || typeof events === 'undefined') {
|
|
6907
|
+
holidaysOnDate.set(cacheKey, events);
|
|
6955
6908
|
return events;
|
|
6956
6909
|
}
|
|
6957
6910
|
const myFilter = il ? observedInIsrael : observedInDiaspora;
|
|
6958
|
-
|
|
6911
|
+
const filtered = events.filter(myFilter);
|
|
6912
|
+
holidaysOnDate.set(cacheKey, filtered);
|
|
6913
|
+
return filtered;
|
|
6959
6914
|
}
|
|
6960
6915
|
|
|
6961
6916
|
/**
|