shabbat-gate 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,115 @@
1
+ # Changelog
2
+
3
+ All notable changes to this package are documented here. Format loosely follows
4
+ [Keep a Changelog](https://keepachangelog.com/).
5
+
6
+ ## [0.2.0] - Unreleased
7
+
8
+ ### Added
9
+
10
+ - `ShabbatGateConfig.enforceVisitorLocation` - when `true`, the gate blocks a visitor during
11
+ Shabbat/Yom Tov in *their own* location (from Cloudflare's `request.cf` geolocation), not
12
+ only Israel's. The site is closed to them if it's Shabbat in Israel **or** where they are,
13
+ so an overseas visitor stays blocked from Israel's candle-lighting right through their own
14
+ local havdalah. Holidays for a visitor outside Israel use diaspora two-day Yom Tov reckoning
15
+ (`i=off`); Chanukah/Purim/Yom HaAtzma'ut/Chol HaMoed stay open either way. Falls back to the
16
+ Israel-only decision when a request has no geolocation (local `wrangler dev`, unplaceable IP).
17
+ Defaults to `false` (original Israel-only behavior).
18
+ - **Localized secondary holding-page message.** For a visitor physically outside Israel, the
19
+ default holding page now shows the Hebrew message, then (below a blank-line gap) a message in
20
+ the visitor's own browser language (from `Accept-Language`). Built-in languages: English
21
+ (default/fallback), French, Russian, Spanish, German, and Arabic (right-to-left).
22
+ Hebrew-speaking visitors and visitors
23
+ in Israel get no second message. Reopen time is shown in the visitor's own timezone. Works
24
+ independently of `enforceVisitorLocation` (whenever the site is closed and the visitor is
25
+ known to be abroad).
26
+ - New exports supporting the above: `fetchWindows` now takes an optional third `options`
27
+ argument (`{ israelMode?, tzid? }`) for computing a non-Israel calendar; `mergeWindows`
28
+ (coalesces overlapping window lists into continuous ones); `SUPPORTED_LANGUAGES`,
29
+ `resolveVisitorLanguage`, and the `SecondaryMessage` / `SupportedLanguage` /
30
+ `FetchWindowsOptions` types.
31
+
32
+ ### Changed
33
+
34
+ - `HoldingPageContext` gained an optional `secondary?: SecondaryMessage` field (the localized
35
+ block). Existing custom `renderHoldingPage` functions are unaffected - the field is optional
36
+ and simply ignored if unused.
37
+ - The default holding page now HTML-escapes `siteName` and all label fields before
38
+ interpolation.
39
+
40
+ ## [0.1.3] - 2026-07-12
41
+
42
+ ### Fixed
43
+
44
+ - **Windows were computed for the wrong location past the nearest Shabbat.** `fetchWindows`
45
+ used to call two separate Hebcal endpoints: `/shabbat` (accurate for the given
46
+ `latitude`/`longitude`, but - confirmed by testing live against the API - it silently
47
+ ignores the requested `start`/`end` range and always returns only the single nearest
48
+ Shabbat) and `/hebcal` for holidays (which took a hardcoded `geonameid` for Jerusalem,
49
+ never the coordinates passed in). Net effect: only the very next Shabbat was ever
50
+ correctly localized; every window after that was computed for Jerusalem regardless of
51
+ the site's configured location.
52
+ - **Duplicate/inconsistent windows around the nearest Shabbat**, a direct consequence of
53
+ the bug above - the two endpoints could both emit a window for the same week, a few
54
+ minutes apart, with nothing merging or de-duplicating them.
55
+ - **A holiday's Hebrew label could leak into the following, unrelated Shabbat window.**
56
+ `pairWindows` tracked "the most recently seen holiday item" as a running pointer. Some
57
+ `holiday`-category items - fast days such as Tish'a B'Av, which are `maj=on` but have no
58
+ candle-lighting/havdalah of their own - never got consumed into a window, so their label
59
+ stayed "current" and was wrongly attached to the next real window (e.g. an ordinary
60
+ Shabbat mislabeled with the fast day's name). Fixed by matching each window's opening
61
+ `candles` event to a holiday via Hebcal's own `memo` field instead of positional
62
+ tracking.
63
+
64
+ **Root fix for both window bugs**: `fetchWindows` now makes a single call to the
65
+ `/hebcal` endpoint with `ss=on` (weekly Shabbat) added alongside `maj=on` (major
66
+ holidays), passing `latitude`/`longitude` directly instead of a `geonameid`. This
67
+ returns every window in the requested range, correctly localized, already merged and
68
+ chronologically ordered - eliminating the two-source reconciliation that caused both bugs.
69
+
70
+ ### Added
71
+
72
+ - `ShabbatGateConfig.bufferMinutes` - closes the site a configurable number of minutes
73
+ *before* candle-lighting and reopens it the same number of minutes *after* havdalah, on
74
+ top of the raw Hebcal window. Applied at decision time (not baked into the 24h cache), so
75
+ changing it takes effect immediately.
76
+ - `createShabbatGateForWorker(config)` - an adapter for plain Cloudflare Workers with a
77
+ static `assets` binding (as opposed to Pages Functions). Returns
78
+ `(request: Request) => Promise<Response | null>`: `null` means "let the real site
79
+ through", a `Response` means "serve the holding page". Shares all fail-open/caching/
80
+ bypass logic with `createShabbatGate` internally, so the two can't drift apart.
81
+ - `INTERNAL_CACHE_KEY_URL` export - the fixed internal Workers-Cache-API key this package
82
+ uses to cache the merged window list for ~24h. Exported so consumers doing their own
83
+ caching of derived data (e.g. windows with a hand-rolled buffer) can pick a different key
84
+ and avoid silently serving stale data for up to a day.
85
+
86
+ ## [0.1.2] - 2026-07-10
87
+
88
+ ### Fixed
89
+
90
+ - Holding page showed the generic literal "הדלקת נרות"/"הבדלה" as the closure reason for
91
+ every window, Shabbat or holiday alike (Hebcal's `candles`/`havdalah` items always carry
92
+ that generic text in their `hebrew` field, never the actual occasion name). Plain Shabbat
93
+ weeks now default to "שבת קודש" (opening) / "השבת" (closing); holiday windows pick up the
94
+ holiday's own Hebrew name (e.g. "ערב ראש השנה").
95
+
96
+ ### Documentation
97
+
98
+ - Documented the Cloudflare Worker + `assets` binding `run_worker_first: true` gotcha:
99
+ without it, requests matching a static asset are served directly and the gate's `fetch`
100
+ handler never runs, so the site never actually closes despite looking correctly wired up.
101
+ Found live in production on the package's first real-world Worker (non-Pages) deployment.
102
+
103
+ ## [0.1.1] - 2026-07-10
104
+
105
+ ### Added
106
+
107
+ - Hebrew README (`README.he.md`), for the package's primary intended audience.
108
+
109
+ ## [0.1.0] - 2026-07-10
110
+
111
+ ### Added
112
+
113
+ - Initial release: bot/crawler allowlist, Hebcal Shabbat + major-holiday window fetching
114
+ (Israel single-day Yom Tov mode), `createShabbatGate` Pages Functions middleware,
115
+ bypass query param, ~24h caching via the Workers Cache API, and fail-open error handling.
package/README.he.md CHANGED
@@ -1,90 +1,190 @@
1
- # shabbat-gate
2
-
3
- Middleware ל-Cloudflare Pages / Workers שסוגר אתר לגולשים אנושיים בזמן שבת וחגי ישראל
4
- המרכזיים (לפי כללי שמירת שבת בישראל) - תוך מתן גישה תמידית למנועי חיפוש ולסורקי AI, כך
5
- שה-SEO לא נפגע.
6
-
7
- [English README](README.md)
8
-
9
- ## למה זה עובד ככה
10
-
11
- - **יום טוב חד-יומי לפי ישראל, לא ספירת חו"ל.** לוח החגים נשלף מה-API החינמי של Hebcal
12
- עם הפרמטר `i=on`, שקריטי - בלעדיו מתקבלת ספירת חו"ל (יום חסימה מיותר) במקום יום טוב
13
- חד-יומי, כפי שנהוג בישראל.
14
- - **בוטים תמיד עוברים.** רשימת אלוול רחבה, לא תלוית רישיות, של user-agent (Googlebot,
15
- Bingbot, GPTBot, ClaudeBot ורבים נוספים) נבדקת ראשונה, לפני כל שאר הלוגיקה. השער משפיע
16
- רק על גולשים אנושיים - סורקים ומנועי אינדוקס רואים את האתר האמיתי 24/7, כך שדירוג
17
- וניראות ב-AI-search לא נפגעים מכך שהאתר "סגור".
18
- - **נכשל פתוח (Fail open).** כל שגיאה (תקלת רשת, תשובת API לא תקינה, מה שלא יהיה) גורמת
19
- למעבר לאתר האמיתי במקום הצגת דף שגיאה. חסימה בטעות ביום שלישי רגיל היא באג אמיתי וגלוי;
20
- אי-חסימה נדירה בזמן שגיאה היא תקלה קטנה ובלתי נראית.
21
-
22
- ## התקנה
23
-
24
- ```sh
25
- npm install shabbat-gate
26
- ```
27
-
28
- ## שימוש
29
-
30
- בפרויקט Cloudflare Pages, מוסיפים קובץ `functions/_middleware.ts`:
31
-
32
- ```ts
33
- import { createShabbatGate } from 'shabbat-gate';
34
-
35
- const gate = createShabbatGate({ siteName: 'שם האתר שלי' });
36
-
37
- export const onRequest: PagesFunction = (context) => gate(context);
38
- ```
39
-
40
- ## קונפיגורציה
41
-
42
- ```ts
43
- export interface ShabbatGateConfig {
44
- siteName: string;
45
-
46
- /** קווי אורך/רוחב עשרוניים לחישוב זמנים. ברירת מחדל לשניהם היא ירושלים (31.7683,
47
- * 35.2137) אם לא סופקו - נקודת ייחוס טובה לכל ישראל ברזולוציה הזו. */
48
- latitude?: number;
49
- longitude?: number;
50
-
51
- /** שם פרמטר + ערך נדרש ב-query string שעוקפים את השער לגמרי, כדי שבעל האתר יוכל
52
- * לבדוק/לתצוגה מקדימה בכל יום. חשוב לבחור ערך שלא ניתן לניחוש - זו נוחות לבדיקות,
53
- * לא הרשאה אמיתית. */
54
- bypassParam?: string;
55
- bypassValue?: string;
56
-
57
- /** פונקציית רינדור מותאמת אישית לדף ה"סגור", אופציונלית. ברירת המחדל היא דף בעברית,
58
- * רספונסיבי למובייל, שמציג את שם האתר ומתי הוא ייפתח מחדש. */
59
- renderHoldingPage?: (ctx: { siteName: string; reasonLabel: string; untilLabel: string }) => string;
60
- }
61
- ```
62
-
63
- דוגמה מלאה:
64
-
65
- ```ts
66
- import { createShabbatGate } from 'shabbat-gate';
67
-
68
- const gate = createShabbatGate({
69
- siteName: 'tehila·games',
70
- latitude: 31.7683,
71
- longitude: 35.2137,
72
- bypassParam: 'preview',
73
- bypassValue: 'letmein-9f3a7c',
74
- });
75
-
76
- export const onRequest: PagesFunction = (context) => gate(context);
77
- ```
78
-
79
- ## איך זה עובד
80
-
81
- 1. בדיקת בוט (regex אלוול על header ה-`user-agent`) - התאמה עוברת ישירות.
82
- 2. בדיקת bypass - אם פרמטר ה-query וערכו תואמים, עוברים ישירות.
83
- 3. שליפה (עם caching לכ-24 שעות דרך Workers Cache API) של רשימת חלונות שבת וחגים
84
- מאוחדת מ-Hebcal, כ-45 יום קדימה.
85
- 4. אם הזמן הנוכחי נופל בתוך חלון, מוצג דף ה"סגור" (HTTP 200). אחרת, האתר האמיתי עובר.
86
- 5. כל שגיאה בדרך גורמת למעבר לאתר האמיתי.
87
-
88
- ## רישיון
89
-
90
- MIT
1
+ # shabbat-gate
2
+
3
+ Middleware ל-Cloudflare Pages / Workers שסוגר אתר לגולשים אנושיים בזמן שבת וחגי ישראל
4
+ המרכזיים (לפי כללי שמירת שבת בישראל) - תוך מתן גישה תמידית למנועי חיפוש ולסורקי AI, כך
5
+ שה-SEO לא נפגע.
6
+
7
+ [English README](README.md)
8
+
9
+ ## למה זה עובד ככה
10
+
11
+ - **יום טוב חד-יומי לפי ישראל, לא ספירת חו"ל.** לוח החגים נשלף מה-API החינמי של Hebcal
12
+ עם הפרמטר `i=on`, שקריטי - בלעדיו מתקבלת ספירת חו"ל (יום חסימה מיותר) במקום יום טוב
13
+ חד-יומי, כפי שנהוג בישראל.
14
+ - **בוטים תמיד עוברים.** רשימת אלוול רחבה, לא תלוית רישיות, של user-agent (Googlebot,
15
+ Bingbot, GPTBot, ClaudeBot ורבים נוספים) נבדקת ראשונה, לפני כל שאר הלוגיקה. השער משפיע
16
+ רק על גולשים אנושיים - סורקים ומנועי אינדוקס רואים את האתר האמיתי 24/7, כך שדירוג
17
+ וניראות ב-AI-search לא נפגעים מכך שהאתר "סגור".
18
+ - **נכשל פתוח (Fail open).** כל שגיאה (תקלת רשת, תשובת API לא תקינה, מה שלא יהיה) גורמת
19
+ למעבר לאתר האמיתי במקום הצגת דף שגיאה. חסימה בטעות ביום שלישי רגיל היא באג אמיתי וגלוי;
20
+ אי-חסימה נדירה בזמן שגיאה היא תקלה קטנה ובלתי נראית.
21
+
22
+ ## התקנה
23
+
24
+ ```sh
25
+ npm install shabbat-gate
26
+ ```
27
+
28
+ ## שימוש
29
+
30
+ בפרויקט Cloudflare Pages, מוסיפים קובץ `functions/_middleware.ts`:
31
+
32
+ ```ts
33
+ import { createShabbatGate } from 'shabbat-gate';
34
+
35
+ const gate = createShabbatGate({ siteName: 'שם האתר שלי' });
36
+
37
+ export const onRequest: PagesFunction = (context) => gate(context);
38
+ ```
39
+
40
+ ### שימוש עם Worker רגיל + assets binding (לא Pages)
41
+
42
+ `createShabbatGate` מחזירה handler בצורה של Pages Functions (`(context) => Response`), וזה
43
+ לא מתאים ל-signature של `fetch(request, env)` של Worker רגיל (אין `next()`). במקום זאת יש
44
+ להשתמש ב-`createShabbatGateForWorker` - היא מחזירה `null` כשצריך לתת לאתר האמיתי לעבור, ו-
45
+ `Response` כשצריך להציג את דף ה"סגור":
46
+
47
+ ```ts
48
+ import { createShabbatGateForWorker } from 'shabbat-gate';
49
+
50
+ const gate = createShabbatGateForWorker({ siteName: 'שם האתר שלי' });
51
+
52
+ export default {
53
+ async fetch(request: Request, env: { ASSETS: Fetcher }) {
54
+ const blocked = await gate(request);
55
+ return blocked ?? env.ASSETS.fetch(request);
56
+ },
57
+ };
58
+ ```
59
+
60
+ **מוקש שמבטל את כל השער בשקט:** Cloudflare Worker עם `assets` binding מגיש כל בקשה שתואמת
61
+ קובץ בתיקיית ה-assets **ישירות**, בלי להריץ בכלל את ה-`fetch` handler של ה-Worker - אלא אם
62
+ מגדירים `run_worker_first: true`. בלי זה, קוד השער רץ ונראה מחובר נכון, הבדיקות עוברות, אבל
63
+ בקשות אמיתיות לעמודים (שכמעט תמיד תואמות קובץ סטטי) אף פעם לא מגיעות אליו, אז האתר בפועל
64
+ אף פעם לא נסגר. ב-`wrangler.jsonc`:
65
+
66
+ ```jsonc
67
+ {
68
+ "assets": {
69
+ "directory": "./dist",
70
+ "binding": "ASSETS",
71
+ "run_worker_first": true
72
+ }
73
+ }
74
+ ```
75
+
76
+ ## קונפיגורציה
77
+
78
+ ```ts
79
+ export interface ShabbatGateConfig {
80
+ siteName: string;
81
+
82
+ /** קווי אורך/רוחב עשרוניים לחישוב זמנים. ברירת מחדל לשניהם היא ירושלים (31.7683,
83
+ * 35.2137) אם לא סופקו - נקודת ייחוס טובה לכל ישראל ברזולוציה הזו. */
84
+ latitude?: number;
85
+ longitude?: number;
86
+
87
+ /** שם פרמטר + ערך נדרש ב-query string שעוקפים את השער לגמרי, כדי שבעל האתר יוכל
88
+ * לבדוק/לתצוגה מקדימה בכל יום. חשוב לבחור ערך שלא ניתן לניחוש - זו נוחות לבדיקות,
89
+ * לא הרשאה אמיתית. */
90
+ bypassParam?: string;
91
+ bypassValue?: string;
92
+
93
+ /** פונקציית רינדור מותאמת אישית לדף ה"סגור", אופציונלית. ברירת המחדל היא דף בעברית,
94
+ * רספונסיבי למובייל, שמציג את שם האתר ומתי הוא ייפתח מחדש. `reasonLabel` ו-`closingLabel`
95
+ * שונים דקדוקית עבור שבת רגילה ("שבת קודש" בפתיחה מול "השבת" בסגירה) - יש להשתמש
96
+ * ב-`closingLabel` עבור "ניפגש שוב אחרי ___", לא לחזור על `reasonLabel`. */
97
+ renderHoldingPage?: (ctx: {
98
+ siteName: string;
99
+ reasonLabel: string;
100
+ closingLabel: string;
101
+ untilLabel: string;
102
+ /** הודעה מקומית אופציונלית שמוצגת מתחת להודעה בעברית (עם רווח), עבור גולש מחוץ
103
+ * לישראל, בשפת הדפדפן שלו. חסרה עבור גולשים בישראל / דוברי עברית / כשמיקום
104
+ * הגולש לא ידוע. */
105
+ secondary?: { dir: 'ltr' | 'rtl'; lines: string[] };
106
+ }) => string;
107
+
108
+ /** דקות לסגור את האתר *לפני* הדלקת נרות ולפתוח אותו *אחרי* הבדלה, מעל החלון הגולמי
109
+ * מ-Hebcal. ברירת מחדל: 0. שימושי כרפידת בטחון מול סחיפת שעון / גלישה של הרגע
110
+ * האחרון בדיוק בגבול החלון. */
111
+ bufferMinutes?: number;
112
+
113
+ /** כשמוגדר `true`, חוסם גולש גם בזמן שבת/יום-טוב *במיקום שלו עצמו* (לפי הגאו-לוקיישן
114
+ * של Cloudflare ב-`request.cf`), לא רק בזמן של ישראל. האתר סגור לגולש אם זו שבת
115
+ * בישראל *או* במקום שבו הוא נמצא - כך שגולש בחו"ל נשאר חסום מהדלקת הנרות בישראל ועד
116
+ * צאת השבת המקומית שלו. חגים לגולש מחוץ לישראל מחושבים לפי יום-טוב שני של גלויות
117
+ * (יומיים). ברירת מחדל: `false` (שער לפי ישראל בלבד, ההתנהגות המקורית). אם אין נתוני
118
+ * מיקום לבקשה (למשל `wrangler dev` מקומי, או IP ש-Cloudflare לא ממקם) - אותה בקשה
119
+ * נופלת חזרה להחלטה לפי ישראל בלבד. */
120
+ enforceVisitorLocation?: boolean;
121
+ }
122
+ ```
123
+
124
+ ### חסימה גם לפי אזור הזמן של הגולש (`enforceVisitorLocation`)
125
+
126
+ ברירת המחדל: השער מחושב לפי לוח הזמנים של **ישראל** בלבד, לכל גולש בעולם. ברגע שיוצאת
127
+ שבת בישראל, האתר נפתח לכולם - גם לגולש בארה"ב שאצלו עדיין שבת.
128
+
129
+ עם `enforceVisitorLocation: true` השער הופך ל**איחוד של שתי שבתות**: האתר סגור לגולש אם
130
+ זו שבת/יום-טוב בישראל **או** במיקום שממנו הוא גולש. דוגמה לגולש בניו יורק: הוא נחסם כבר
131
+ מהדלקת הנרות בישראל (גם אם אצלו עדיין יום שישי בצהריים), ונשאר חסום ברצף עד צאת השבת
132
+ המקומית שלו. חגים מחושבים לו לפי חשבון גלותי (יום-טוב שני של גלויות). חנוכה, פורים, יום
133
+ העצמאות וחול המועד לא חוסמים - לא בישראל ולא בחו"ל.
134
+
135
+ ### הודעה בשפה מקומית לגולש מחו"ל
136
+
137
+ כשגולש נמצא מחוץ לישראל, דף ה"סגור" הדיפולטי מציג קודם את ההודעה בעברית, ומתחתיה (עם
138
+ רווח של שתי שורות) הודעה בשפת הדפדפן שלו (לפי כותרת `Accept-Language`). שפות מובנות:
139
+ אנגלית (ברירת מחדל), צרפתית, רוסית, ספרדית, גרמנית, וערבית (מוצגת מימין לשמאל). גולש דובר
140
+ עברית או גולש בישראל לא מקבל שורה שנייה. שעת הפתיחה מוצגת לגולש מחו"ל באזור הזמן שלו. זה עובד גם ללא
141
+ `enforceVisitorLocation` (בכל פעם שהאתר סגור וידוע שהגולש בחו"ל).
142
+
143
+ דוגמה מלאה:
144
+
145
+ ```ts
146
+ import { createShabbatGate } from 'shabbat-gate';
147
+
148
+ const gate = createShabbatGate({
149
+ siteName: 'tehila·games',
150
+ latitude: 31.7683,
151
+ longitude: 35.2137,
152
+ bypassParam: 'preview',
153
+ bypassValue: 'letmein-9f3a7c',
154
+ bufferMinutes: 10,
155
+ });
156
+
157
+ export const onRequest: PagesFunction = (context) => gate(context);
158
+ ```
159
+
160
+ ## איך זה עובד
161
+
162
+ 1. בדיקת בוט (regex אלוול על header ה-`user-agent`) - התאמה עוברת ישירות.
163
+ 2. בדיקת bypass - אם פרמטר ה-query וערכו תואמים, עוברים ישירות.
164
+ 3. שליפה (עם caching לכ-24 שעות דרך Workers Cache API) של רשימת חלונות שבת וחגים
165
+ מאוחדת מ-Hebcal, כ-45 יום קדימה - קריאה אחת ל-endpoint `/hebcal` (`ss=on` לשבתות
166
+ שבועיות + `maj=on` לחגים מרכזיים), עם `latitude`/`longitude` מועברים ישירות, כך שכל
167
+ חלון מחושב נכון למיקום שהוגדר, לא רק החלון הקרוב ביותר.
168
+ 4. אם הוגדר `bufferMinutes`, הוא מוחל מעל החלונות שנשלפו לפני בדיקת הזמן.
169
+ 5. אם הוגדר `enforceVisitorLocation`, נשלף לוח זמנים שני לפי מיקום הגולש (מ-`request.cf`,
170
+ בחשבון גלותי לגולש מחוץ לישראל) ומאוחד עם חלונות ישראל - חוסמים אם הזמן נופל באחד
171
+ מהם. חלונות חופפים ממוזגים לחלון רציף אחד כדי ששעת הפתיחה המוצגת תהיה מדויקת.
172
+ 6. אם הזמן הנוכחי נופל בתוך חלון, מוצג דף ה"סגור" (HTTP 200). אחרת, האתר האמיתי עובר.
173
+ 7. כל שגיאה בדרך גורמת למעבר לאתר האמיתי.
174
+
175
+ ## מפתח קאש פנימי
176
+
177
+ רשימת החלונות המאוחדת נשמרת בקאש תחת מפתח פנימי קבוע
178
+ (`https://internal.cache/shabbat-gate-windows-v1`, מיוצא בשם `INTERNAL_CACHE_KEY_URL`) לכ-24
179
+ שעות דרך Workers Cache API. אם הקוד שלכם עושה caching משלו לנתונים נגזרים (למשל חלונות עם
180
+ buffer משלכם), כדאי להשתמש במפתח אחר - שימוש חוזר במפתח הזה יגרום בשקט להחזרת נתונים ישנים
181
+ ולא-מעובדים למשך עד 24 שעות.
182
+
183
+ ## היסטוריית שינויים
184
+
185
+ ב-[CHANGELOG.md](CHANGELOG.md) (באנגלית) מתועד מה השתנה בכל גרסה, כולל הסבר לשורש כל
186
+ באג שתוקן.
187
+
188
+ ## רישיון
189
+
190
+ MIT