From 8e281d5b2cf53a48a842908ea3edb4e9d1086375 Mon Sep 17 00:00:00 2001 From: Brian Glass Date: Fri, 28 Aug 2026 13:41:27 -0400 Subject: [PATCH 01/29] Audit the Slavic readings against oca.org: 97.1% for 2026 The Slavic data predates the Greek tradition by years and had never been measured against its own source, the way docs/greek-lectionary.md measured Greek against goarch.org. This is that measurement: 329/339 dates match for 2026, with ten differing in three coherent groups. The largest group is one unmodelled rule rather than four separate mistakes. The app and oca.org disagree about whether the ordinary daily-cycle reading is also read when a feast claims the day, and they disagree in both directions: on Jan 1, Jan 5 and Dec 24 oca.org reads it alongside the festal reading and the app omits it; on Jan 3, a Saturday before a great feast, oca.org drops it and the app adds it. Not fixed here -- the rule is inferred from four dates in one year, and this project confirms across several years before coding. Two traps in oca.org's monthly tables are recorded because both produced confidently wrong numbers. Their columns are not positionally stable: Feb-Apr carry an extra column, and a Lenten day's Old Testament lessons sit in the cells a Liturgy day uses for Epistle and Gospel, so reading slots off column numbers scored the app at 73.7%. And neither side is self-consistent about slots -- oca.org labels Holy Week's Bridegroom gospels "(Matins)" while the app files them under "Gospel" -- so the audit matches on citations and reports missing and extra separately rather than pairing by slot. Also notes that oca.org 403s a user agent containing the word "harvester". That is a keyword filter, not the access policy: robots.txt allows these paths and asks for Crawl-delay: 10, which tools/oca/fetch.py honours. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019nQRjJpPqW89xqzAf1vsEX --- .gitignore | 4 + data/oca_raw/readings-2026.json | 4176 ++++++++++++++++++++++++++++++ data/oca_readings_diff-2026.json | 114 + docs/oca-audit.md | 124 + tools/oca/README.md | 35 + tools/oca/audit_readings.py | 137 + tools/oca/explain_diff.py | 63 + tools/oca/fetch.py | 54 + tools/oca/harvest_readings.py | 93 + tools/oca/harvest_saints.py | 87 + tools/oca/refs.py | 124 + 11 files changed, 5011 insertions(+) create mode 100644 data/oca_raw/readings-2026.json create mode 100644 data/oca_readings_diff-2026.json create mode 100644 docs/oca-audit.md create mode 100644 tools/oca/README.md create mode 100644 tools/oca/audit_readings.py create mode 100644 tools/oca/explain_diff.py create mode 100644 tools/oca/fetch.py create mode 100644 tools/oca/harvest_readings.py create mode 100644 tools/oca/harvest_saints.py create mode 100644 tools/oca/refs.py diff --git a/.gitignore b/.gitignore index 0adbdb6a..24f16e13 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ ve .firebase static default-cache + +# Raw HTML cache for the oca.org harvests; the parsed JSON beside it is +# what matters, and this is re-fetchable (slowly -- see tools/oca/README.md). +data/oca_raw/_cache/ diff --git a/data/oca_raw/readings-2026.json b/data/oca_raw/readings-2026.json new file mode 100644 index 00000000..058ef3bf --- /dev/null +++ b/data/oca_raw/readings-2026.json @@ -0,0 +1,4176 @@ +{ + "2026-01-01": [ + { + "citations": [ + "Colossians 2:8-12", + "Luke 2:20-21,40-52" + ], + "label": "Circumcision" + }, + { + "citations": [ + "Hebrews 7:26-8:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 10:35-11:7", + "Mark 11:27-33" + ], + "label": "" + } + ], + "2026-01-02": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 11:8, 11-16", + "Mark 12:1-12" + ], + "label": "" + } + ], + "2026-01-03": [ + { + "citations": [ + "1 Timothy 3:14-4:5", + "Matthew 3:1-11" + ], + "label": "Saturday Before" + } + ], + "2026-01-04": [ + { + "citations": [ + "2 Timothy 4:5-8", + "Mark 1:1-8" + ], + "label": "Sunday Before" + } + ], + "2026-01-05": [ + { + "citations": [ + "Hebrews 11:17-23, 27-31", + "Mark 8:11-21" + ], + "label": "" + }, + { + "citations": [ + "1 Corinthians 9:19-27", + "Luke 3:1-18" + ], + "label": "" + } + ], + "2026-01-06": [ + { + "citations": [ + "Titus 2:11-14; 3:4-7", + "Matthew 3:13-17" + ], + "label": "" + } + ], + "2026-01-07": [ + { + "citations": [ + "James 1:1-18", + "Mark 8:30-34" + ], + "label": "" + }, + { + "citations": [ + "Acts 19:1-8", + "John 1:29-34" + ], + "label": "Forerunner" + } + ], + "2026-01-08": [ + { + "citations": [ + "James 1:19-27", + "Mark 9:10-16" + ], + "label": "" + } + ], + "2026-01-09": [ + { + "citations": [ + "James 2:1-13", + "Mark 9:33-41" + ], + "label": "" + } + ], + "2026-01-10": [ + { + "citations": [ + "Ephesians 6:10-17", + "Matthew 4:1-11" + ], + "label": "Saturday After" + }, + { + "citations": [ + "Colossians 1:3-6", + "Luke 14:1-11" + ], + "label": "" + } + ], + "2026-01-11": [ + { + "citations": [ + "2 Corinthians 4:6-15", + "Matthew 11:27-30" + ], + "label": "Saint" + }, + { + "citations": [ + "Ephesians 4:7-13", + "Matthew 4:12-17" + ], + "label": "Sunday After" + } + ], + "2026-01-12": [ + { + "citations": [ + "James 2:14-26", + "Mark 9:42-10:1" + ], + "label": "" + } + ], + "2026-01-13": [ + { + "citations": [ + "James 3:1-10", + "Mark 10:2-12" + ], + "label": "" + } + ], + "2026-01-14": [ + { + "citations": [ + "James 3:11-4:6", + "Mark 10:11-16" + ], + "label": "" + } + ], + "2026-01-15": [ + { + "citations": [ + "James 4:7-5:9", + "Mark 10:17-27" + ], + "label": "" + } + ], + "2026-01-16": [ + { + "citations": [ + "1 Peter 1:1-2, 10-12, 2:6-10", + "Mark 10:23-32" + ], + "label": "" + } + ], + "2026-01-17": [ + { + "citations": [ + "Hebrews 13:17-21", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Thessalonians 5:14-23", + "Luke 16:10-15" + ], + "label": "" + } + ], + "2026-01-18": [ + { + "citations": [ + "1 Timothy 1:15-17", + "Luke 18:35-43" + ], + "label": "" + } + ], + "2026-01-19": [ + { + "citations": [ + "James 2:14-26", + "Mark 10:46-52" + ], + "label": "" + } + ], + "2026-01-20": [ + { + "citations": [ + "Hebrews 13:17-21", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "James 3:1-10", + "Mark 11:11-23" + ], + "label": "" + } + ], + "2026-01-21": [ + { + "citations": [ + "James 3:11-4:6", + "Mark 11:22-26" + ], + "label": "" + } + ], + "2026-01-22": [ + { + "citations": [ + "James 4:7-5:9", + "Mark 11:27-33" + ], + "label": "" + } + ], + "2026-01-23": [ + { + "citations": [ + "1 Peter 1:1-2, 10-12, 2:6-10", + "Mark 12:1-12" + ], + "label": "" + } + ], + "2026-01-24": [ + { + "citations": [ + "1 Thessalonians 5:14-23", + "Luke 17:3-10" + ], + "label": "" + } + ], + "2026-01-25": [ + { + "citations": [ + "1 Corinthians 12:7-11", + "John 10:9-16" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Timothy 4:9-15", + "Luke 19:1-10" + ], + "label": "" + } + ], + "2026-01-26": [ + { + "citations": [ + "1 Peter 2:21-3:9", + "Mark 12:13-17" + ], + "label": "" + } + ], + "2026-01-27": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "John 10:9-16" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Peter 3:10-22", + "Mark 12:18-27" + ], + "label": "" + } + ], + "2026-01-28": [ + { + "citations": [ + "1 Peter 4:1-11", + "Mark 12:28-37" + ], + "label": "" + } + ], + "2026-01-29": [ + { + "citations": [ + "1 Peter 4:12-5:5", + "Mark 12:38-44" + ], + "label": "" + } + ], + "2026-01-30": [ + { + "citations": [ + "Hebrews 13:7-16", + "Matthew 5:14-19" + ], + "label": "Hierarchs" + }, + { + "citations": [ + "2 Peter 1:1-10", + "Mark 13:1-8" + ], + "label": "" + } + ], + "2026-01-31": [ + { + "citations": [ + "2 Timothy 2:11-19", + "Luke 18:2-8" + ], + "label": "" + } + ], + "2026-02-01": [ + { + "citations": [ + "2 Timothy 3:10-15", + "Luke 18:10-14" + ], + "label": "" + } + ], + "2026-02-02": [ + { + "citations": [ + "2 Peter 1:20-2:9", + "Mark 13:9-13" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 7:7-17", + "Luke 2:22-40" + ], + "label": "Meeting" + } + ], + "2026-02-03": [ + { + "citations": [ + "2 Peter 2:9-22", + "Mark 13:14-23" + ], + "label": "" + } + ], + "2026-02-04": [ + { + "citations": [ + "2 Peter 3:1-18", + "Mark 13:24-31" + ], + "label": "" + } + ], + "2026-02-05": [ + { + "citations": [ + "Hebrews 13:17-21", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "1 John 1:8-2:6", + "Mark 13:31-14:2" + ], + "label": "" + } + ], + "2026-02-06": [ + { + "citations": [ + "1 John 2:7-17", + "Mark 14:3-9" + ], + "label": "" + } + ], + "2026-02-07": [ + { + "citations": [ + "2 Timothy 3:1-9", + "Luke 20:46-21:4" + ], + "label": "" + } + ], + "2026-02-08": [ + { + "citations": [ + "1 Corinthians 6:12-20", + "Luke 15:11-32" + ], + "label": "" + } + ], + "2026-02-09": [ + { + "citations": [ + "Hebrews 7:7-17", + "Luke 2:22-40" + ], + "label": "Meeting" + }, + { + "citations": [ + "1 John 2:18-3:10", + "Mark 11:1-11" + ], + "label": "" + } + ], + "2026-02-10": [ + { + "citations": [ + "1 John 3:11-20", + "Mark 14:10-42" + ], + "label": "" + } + ], + "2026-02-11": [ + { + "citations": [ + "1 John 3:21-4:6", + "Mark 14:43-15:1" + ], + "label": "" + } + ], + "2026-02-12": [ + { + "citations": [ + "1 John 4:20-5:21", + "Mark 15:1-15" + ], + "label": "" + } + ], + "2026-02-13": [ + { + "citations": [ + "2 John 1:1-13", + "Mark 15:22-25, 33-41" + ], + "label": "" + } + ], + "2026-02-14": [ + { + "citations": [ + "1 Thessalonians 4:13-17", + "John 5:24-30" + ], + "label": "Departed" + }, + { + "citations": [ + "1 Corinthians 10:23-28", + "Luke 21:8-9, 25-27, 33-36" + ], + "label": "" + } + ], + "2026-02-15": [ + { + "citations": [ + "1 Corinthians 8:8-9:2", + "Matthew 25:31-46" + ], + "label": "" + } + ], + "2026-02-16": [ + { + "citations": [ + "3 John 1:1-15", + "Luke 19:29-40, 22:7-39" + ], + "label": "" + } + ], + "2026-02-17": [ + { + "citations": [ + "Jude 1:1-10", + "Luke 22:39-42, 45-23:1" + ], + "label": "" + } + ], + "2026-02-18": [ + { + "citations": [ + "Joel 2:12-26", + "Joel 3:12-21" + ], + "label": "" + } + ], + "2026-02-19": [ + { + "citations": [ + "Jude 1:11-25", + "Luke 23:2-34, 44-56" + ], + "label": "" + } + ], + "2026-02-20": [ + { + "citations": [ + "Zechariah 8:7-17", + "Zechariah 8:19-23" + ], + "label": "" + } + ], + "2026-02-21": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Matthew 11:27-30" + ], + "label": "Departed" + }, + { + "citations": [ + "Romans 14:19-23, 16:25-27", + "Matthew 6:1-13" + ], + "label": "" + } + ], + "2026-02-22": [ + { + "citations": [ + "Romans 13:11-14:4", + "Matthew 6:14-21" + ], + "label": "" + } + ], + "2026-02-23": [ + { + "citations": [ + "Isaiah 1:1-20", + "Genesis 1:1-13", + "Proverbs 1:1-20" + ], + "label": "" + } + ], + "2026-02-24": [ + { + "citations": [ + "Isaiah 1:19-2:4", + "Genesis 1:14-23", + "Proverbs 1:20-33" + ], + "label": "" + }, + { + "citations": [ + "2 Corinthians 4:6-15", + "Matthew 11:2-15" + ], + "label": "Forerunner" + } + ], + "2026-02-25": [ + { + "citations": [ + "Isaiah 2:3-11", + "Genesis 1:24-2:3", + "Proverbs 2:1-22" + ], + "label": "" + } + ], + "2026-02-26": [ + { + "citations": [ + "Isaiah 2:11-21", + "Genesis 2:4-19", + "Proverbs 3:1-18" + ], + "label": "" + } + ], + "2026-02-27": [ + { + "citations": [ + "Isaiah 3:1-15", + "Genesis 2:20-3:20", + "Proverbs 3:19-34" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 13:17-21", + "John 10:9-16" + ], + "label": "St. Raphael" + } + ], + "2026-02-28": [ + { + "citations": [ + "2 Timothy 2:1-10", + "John 15:17-16:2" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 1:1-12", + "Mark 2:23-3:5" + ], + "label": "" + } + ], + "2026-03-01": [ + { + "citations": [ + "Hebrews 11:24-26, 32-12:2", + "John 1:43-51" + ], + "label": "" + } + ], + "2026-03-02": [ + { + "citations": [ + "Isaiah 4:2-5:7", + "Genesis 3:21-4:7", + "Proverbs 3:34-4:22" + ], + "label": "" + } + ], + "2026-03-03": [ + { + "citations": [ + "Isaiah 5:7-16", + "Genesis 4:8-15", + "Proverbs 5:1-15" + ], + "label": "" + } + ], + "2026-03-04": [ + { + "citations": [ + "Isaiah 5:16-25", + "Genesis 4:16-26", + "Proverbs 5:15-6:3" + ], + "label": "" + } + ], + "2026-03-05": [ + { + "citations": [ + "Isaiah 6:1-12", + "Genesis 5:1-24", + "Proverbs 6:3-20" + ], + "label": "" + } + ], + "2026-03-06": [ + { + "citations": [ + "Isaiah 7:1-15", + "Genesis 5:32-6:8", + "Proverbs 6:20-7:1" + ], + "label": "" + } + ], + "2026-03-07": [ + { + "citations": [ + "1 Thessalonians 4:13-17", + "John 5:24-30" + ], + "label": "Departed" + }, + { + "citations": [ + "Hebrews 3:12-16", + "Mark 1:35-44" + ], + "label": "" + } + ], + "2026-03-08": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "John 10:9-16" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 1:10-2:3", + "Mark 2:1-12" + ], + "label": "" + } + ], + "2026-03-09": [ + { + "citations": [ + "Isaiah 8:13-9:7", + "Genesis 6:9-22", + "Proverbs 8:1-21" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 12:1-10", + "Matthew 20:1-16" + ], + "label": "Martyrs" + } + ], + "2026-03-10": [ + { + "citations": [ + "Isaiah 9:9-10:4", + "Genesis 7:1-15", + "Proverbs 8:32-9:11" + ], + "label": "" + } + ], + "2026-03-11": [ + { + "citations": [ + "Isaiah 10:12-20", + "Genesis 7:6-9", + "Proverbs 9:12-18" + ], + "label": "" + } + ], + "2026-03-12": [ + { + "citations": [ + "Isaiah 11:10-12:2", + "Genesis 7:11-8:3", + "Proverbs 10:1-22" + ], + "label": "" + } + ], + "2026-03-13": [ + { + "citations": [ + "Isaiah 13:2-13", + "Genesis 8:4-21", + "Proverbs 10:31-11:12" + ], + "label": "" + } + ], + "2026-03-14": [ + { + "citations": [ + "1 Thessalonians 4:13-17", + "John 5:24-30" + ], + "label": "Departed" + }, + { + "citations": [ + "Hebrews 10:32-38", + "Mark 2:14-17" + ], + "label": "" + } + ], + "2026-03-15": [ + { + "citations": [ + "Hebrews 4:14-5:6", + "Mark 8:34-9:1" + ], + "label": "" + } + ], + "2026-03-16": [ + { + "citations": [ + "Isaiah 14:24-32", + "Genesis 8:21-9:7", + "Proverbs 11:19-12:6" + ], + "label": "" + } + ], + "2026-03-17": [ + { + "citations": [ + "Isaiah 25:1-9", + "Genesis 9:8-17", + "Proverbs 12:8-22" + ], + "label": "" + } + ], + "2026-03-18": [ + { + "citations": [ + "Isaiah 26:21-27:9", + "Genesis 9:18-10:1", + "Proverbs 12:23-13:9" + ], + "label": "" + } + ], + "2026-03-19": [ + { + "citations": [ + "Isaiah 28:14-22", + "Genesis 10:32-11:9", + "Proverbs 13:19-14:6" + ], + "label": "" + } + ], + "2026-03-20": [ + { + "citations": [ + "Isaiah 29:13-23", + "Genesis 12:1-7", + "Proverbs 14:15-26" + ], + "label": "" + } + ], + "2026-03-21": [ + { + "citations": [ + "1 Corinthians 15:47-57", + "John 5:24-30" + ], + "label": "Departed" + }, + { + "citations": [ + "Hebrews 6:9-12", + "Mark 7:31-37" + ], + "label": "" + } + ], + "2026-03-22": [ + { + "citations": [ + "Ephesians 5:9-19", + "Matthew 4:25-5:12" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 6:13-20", + "Mark 9:17-31" + ], + "label": "" + } + ], + "2026-03-23": [ + { + "citations": [ + "Isaiah 37:33-38:6", + "Genesis 13:12-18", + "Proverbs 14:27-15:4" + ], + "label": "" + } + ], + "2026-03-24": [ + { + "citations": [ + "Isaiah 40:18-31", + "Genesis 15:1-15", + "Proverbs 15:7-19" + ], + "label": "" + } + ], + "2026-03-25": [ + { + "citations": [ + "Isaiah 41:4-14", + "Genesis 17:1-9", + "Proverbs 15:20-16:9" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 2:11-18", + "Luke 1:24-38" + ], + "label": "Theotokos" + } + ], + "2026-03-26": [ + { + "citations": [ + "Isaiah 42:5-16", + "Genesis 18:20-33", + "Proverbs 16:17-17:17" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 2:11-18", + "Luke 1:24-38" + ], + "label": "Theotokos" + } + ], + "2026-03-27": [ + { + "citations": [ + "Isaiah 45:11-17", + "Genesis 22:1-18", + "Proverbs 17:17-18:5" + ], + "label": "" + } + ], + "2026-03-28": [ + { + "citations": [ + "Hebrews 9:1-7", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + }, + { + "citations": [ + "Hebrews 9:24-28", + "Mark 8:27-31" + ], + "label": "" + } + ], + "2026-03-29": [ + { + "citations": [ + "Galatians 3:23-29", + "Luke 7:36-50" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 9:11-14", + "Mark 10:32-45" + ], + "label": "" + } + ], + "2026-03-30": [ + { + "citations": [ + "Isaiah 48:17-49:4", + "Genesis 27:1-41", + "Proverbs 19:16-25" + ], + "label": "" + } + ], + "2026-03-31": [ + { + "citations": [ + "Isaiah 49:6-10", + "Genesis 31:3-16", + "Proverbs 21:3-21" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 7:26-8:2", + "John 10:9-16" + ], + "label": "St. Innocent" + } + ], + "2026-04-01": [ + { + "citations": [ + "Isaiah 58:1-11", + "Genesis 43:26-31, 45:1-16", + "Proverbs 21:23-22:4" + ], + "label": "" + } + ], + "2026-04-02": [ + { + "citations": [ + "Isaiah 65:8-16", + "Genesis 46:1-7", + "Proverbs 23:15-24:5" + ], + "label": "" + } + ], + "2026-04-03": [ + { + "citations": [ + "Isaiah 66:10-24", + "Genesis 49:33-50:26", + "Proverbs 31:8-31" + ], + "label": "" + } + ], + "2026-04-04": [ + { + "citations": [ + "Hebrews 12:28-13:8", + "John 11:1-45" + ], + "label": "" + } + ], + "2026-04-05": [ + { + "citations": [ + "Philippians 4:4-9", + "John 12:1-18" + ], + "label": "" + } + ], + "2026-04-06": [ + { + "citations": [ + "Matthew 21:18-43" + ], + "label": "Matins" + }, + { + "citations": [ + "Ezekiel 1:1-20", + "Exodus 1:1-20", + "Job 1:1-12" + ], + "label": "Vespers" + }, + { + "citations": [ + "Matthew 24:3-35" + ], + "label": "Presanctified" + } + ], + "2026-04-07": [ + { + "citations": [ + "Hebrews 7:26-8:2" + ], + "label": "Matins" + }, + { + "citations": [ + "Ezekiel 1:21-28 (1:1-28,2:1 LXX)", + "Exodus 2:5-10", + "Job 1:13-22" + ], + "label": "Vespers" + }, + { + "citations": [ + "Matthew 24:36-26:2" + ], + "label": "Presanctified" + } + ], + "2026-04-08": [ + { + "citations": [ + "John 12:17-50" + ], + "label": "Matins" + }, + { + "citations": [ + "Ezekiel 2:3-3:3", + "Exodus 2:11-22", + "Job 2:1-10" + ], + "label": "Vespers" + }, + { + "citations": [ + "Matthew 26:6-16" + ], + "label": "Presanctified" + } + ], + "2026-04-09": [ + { + "citations": [ + "Luke 22:1-39" + ], + "label": "Matins" + }, + { + "citations": [ + "Exodus 19:10-19", + "Job 38:1-23; 42:1-5", + "Isaiah 50:4-11" + ], + "label": "Vespers" + }, + { + "citations": [ + "1 Corinthians 11:23-32", + "Matt. 26:2-20; John 13:3-17; Matt. 26:21-39; Luke 22:43-45; Matt. 26:40-27:2" + ], + "label": "Composite" + } + ], + "2026-04-10": [ + { + "citations": [ + "Exodus 33:11-23", + "Job 42:12-17 LXX", + "Isaiah 52:13-54:1" + ], + "label": "Vespers" + }, + { + "citations": [ + "1 Corinthians 1:18-2:2", + "Matt. 27:1-38; Luke 23:39-43; Matt. 27:39-54; John 19:31-37; Matt. 27:55-61" + ], + "label": "Vespers" + } + ], + "2026-04-11": [ + { + "citations": [ + "Ezekiel 37:1-14", + "1 Corinthians 5:6-8; Galatians 3:13-14", + "Matthew 27:62-66" + ], + "label": "Matins" + }, + { + "citations": [ + "Romans 6:3-11", + "Matthew 28:1-20" + ], + "label": "" + } + ], + "2026-04-12": [ + { + "citations": [ + "Acts 1:1-8", + "John 1:1-17" + ], + "label": "" + } + ], + "2026-04-13": [ + { + "citations": [ + "John 20:19-25" + ], + "label": "Vespers" + }, + { + "citations": [ + "Acts 1:12-17, 21-26", + "John 1:18-28" + ], + "label": "" + } + ], + "2026-04-14": [ + { + "citations": [ + "Acts 2:14-21", + "Luke 24:12-35" + ], + "label": "" + } + ], + "2026-04-15": [ + { + "citations": [ + "Acts 2:22-36", + "John 1:35-51" + ], + "label": "" + } + ], + "2026-04-16": [ + { + "citations": [ + "Acts 2:38-43", + "John 3:1-15" + ], + "label": "" + } + ], + "2026-04-17": [ + { + "citations": [ + "Philippians 2:5-11", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + }, + { + "citations": [ + "Acts 3:1-8", + "John 2:12-22" + ], + "label": "" + } + ], + "2026-04-18": [ + { + "citations": [ + "Acts 3:11-16", + "John 3:22-33" + ], + "label": "" + } + ], + "2026-04-19": [ + { + "citations": [ + "Acts 5:12-20", + "John 20:19-31" + ], + "label": "" + } + ], + "2026-04-20": [ + { + "citations": [ + "Acts 3:19-26", + "John 2:1-11" + ], + "label": "" + } + ], + "2026-04-21": [ + { + "citations": [ + "Acts 4:1-10", + "John 3:16-21" + ], + "label": "" + } + ], + "2026-04-22": [ + { + "citations": [ + "Acts 4:13-22", + "John 5:17-24" + ], + "label": "" + } + ], + "2026-04-23": [ + { + "citations": [ + "Acts 12:1-11", + "John 15:17-16:2" + ], + "label": "Saint" + }, + { + "citations": [ + "Acts 4:23-31", + "John 5:24-30" + ], + "label": "" + } + ], + "2026-04-24": [ + { + "citations": [ + "Acts 5:1-11", + "John 5:30-6:2" + ], + "label": "" + } + ], + "2026-04-25": [ + { + "citations": [ + "1 Peter 5:6-14", + "Mark 6:7-13" + ], + "label": "Saint" + }, + { + "citations": [ + "Acts 5:21-33", + "John 6:14-27" + ], + "label": "" + } + ], + "2026-04-26": [ + { + "citations": [ + "Acts 6:1-7", + "Mark 15:43-16:8" + ], + "label": "" + } + ], + "2026-04-27": [ + { + "citations": [ + "Acts 6:8-7:5, 47-60", + "John 4:46-54" + ], + "label": "" + } + ], + "2026-04-28": [ + { + "citations": [ + "Acts 8:5-17", + "John 6:27-33" + ], + "label": "" + } + ], + "2026-04-29": [ + { + "citations": [ + "Acts 8:18-25", + "John 6:35-39" + ], + "label": "" + } + ], + "2026-04-30": [ + { + "citations": [ + "Acts 12:1-11", + "Luke 5:1-11" + ], + "label": "Saint" + }, + { + "citations": [ + "Acts 8:26-39", + "John 6:40-44" + ], + "label": "" + } + ], + "2026-05-01": [ + { + "citations": [ + "Acts 8:40-9:19", + "John 6:48-54" + ], + "label": "" + } + ], + "2026-05-02": [ + { + "citations": [ + "Acts 9:20-31", + "John 15:17-16:2" + ], + "label": "" + } + ], + "2026-05-03": [ + { + "citations": [ + "Hebrews 13:7-16", + "Matthew 11:27-30" + ], + "label": "Saint" + }, + { + "citations": [ + "Acts 9:32-42", + "John 5:1-15" + ], + "label": "" + } + ], + "2026-05-04": [ + { + "citations": [ + "Acts 10:1-16", + "John 6:56-69" + ], + "label": "" + } + ], + "2026-05-05": [ + { + "citations": [ + "Acts 10:21-33", + "John 7:1-13" + ], + "label": "" + } + ], + "2026-05-06": [ + { + "citations": [ + "Acts 14:6-18", + "John 7:14-30" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 2:11-18", + "John 5:1-4" + ], + "label": "Blessing of Waters" + } + ], + "2026-05-07": [ + { + "citations": [ + "Galatians 1:11-19", + "John 10:1-9" + ], + "label": "Saint" + }, + { + "citations": [ + "Acts 10:34-43", + "John 8:12-20" + ], + "label": "" + } + ], + "2026-05-08": [ + { + "citations": [ + "1 John 1:1-7", + "John 19:25-27; 21:24-25" + ], + "label": "St. John" + }, + { + "citations": [ + "Acts 10:44-11:10", + "John 8:21-30" + ], + "label": "" + } + ], + "2026-05-09": [ + { + "citations": [ + "Acts 12:1-11", + "John 8:31-42" + ], + "label": "" + } + ], + "2026-05-10": [ + { + "citations": [ + "1 Corinthians 4:9-16", + "Matthew 13:54-58" + ], + "label": "Saint" + }, + { + "citations": [ + "Acts 11:19-26, 29-30", + "John 4:5-42" + ], + "label": "" + } + ], + "2026-05-11": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "Matthew 5:14-19" + ], + "label": "Saints" + }, + { + "citations": [ + "Acts 12:12-17", + "John 8:42-51" + ], + "label": "" + } + ], + "2026-05-12": [ + { + "citations": [ + "Acts 12:25-13:12", + "John 8:51-59" + ], + "label": "" + } + ], + "2026-05-13": [ + { + "citations": [ + "Acts 13:13-24", + "John 6:5-14" + ], + "label": "" + } + ], + "2026-05-14": [ + { + "citations": [ + "Acts 14:20-27", + "John 9:39-10:9" + ], + "label": "" + } + ], + "2026-05-15": [ + { + "citations": [ + "Acts 15:5-34", + "John 10:17-28" + ], + "label": "" + } + ], + "2026-05-16": [ + { + "citations": [ + "Acts 15:35-41", + "John 10:27-38" + ], + "label": "" + } + ], + "2026-05-17": [ + { + "citations": [ + "Acts 16:16-34", + "John 9:1-38" + ], + "label": "" + } + ], + "2026-05-18": [ + { + "citations": [ + "Acts 17:1-15", + "John 11:47-57" + ], + "label": "" + } + ], + "2026-05-19": [ + { + "citations": [ + "Acts 17:19-28", + "John 12:19-36" + ], + "label": "" + } + ], + "2026-05-20": [ + { + "citations": [ + "Acts 18:22-28", + "John 12:36-47" + ], + "label": "" + } + ], + "2026-05-21": [ + { + "citations": [ + "Acts 1:1-12", + "Luke 24:36-53" + ], + "label": "" + } + ], + "2026-05-22": [ + { + "citations": [ + "Acts 19:1-8", + "John 14:1-11" + ], + "label": "" + } + ], + "2026-05-23": [ + { + "citations": [ + "Acts 20:7-12", + "John 14:10-21" + ], + "label": "" + } + ], + "2026-05-24": [ + { + "citations": [ + "Acts 20:16-18, 28-36", + "John 17:1-13" + ], + "label": "" + } + ], + "2026-05-25": [ + { + "citations": [ + "2 Corinthians 4:6-15", + "Matthew 11:2-15" + ], + "label": "Forerunner" + }, + { + "citations": [ + "Acts 21:8-14", + "John 14:27-15:7" + ], + "label": "" + } + ], + "2026-05-26": [ + { + "citations": [ + "Acts 21:26-32", + "John 16:2-13" + ], + "label": "" + } + ], + "2026-05-27": [ + { + "citations": [ + "Acts 23:1-11", + "John 16:15-23" + ], + "label": "" + } + ], + "2026-05-28": [ + { + "citations": [ + "Acts 25:13-19", + "John 16:23-33" + ], + "label": "" + } + ], + "2026-05-29": [ + { + "citations": [ + "Acts 27:1-44", + "John 17:18-26" + ], + "label": "" + } + ], + "2026-05-30": [ + { + "citations": [ + "1 Thessalonians 4:13-17", + "John 5:24-30" + ], + "label": "Departed" + }, + { + "citations": [ + "1 Corinthians 15:47-57", + "John 6:35-39" + ], + "label": "Departed, variant" + }, + { + "citations": [ + "Acts 28:1-31", + "John 21:15-25" + ], + "label": "" + } + ], + "2026-05-31": [ + { + "citations": [ + "Acts 2:1-11", + "John 7:37-52, 8:12" + ], + "label": "" + } + ], + "2026-06-01": [ + { + "citations": [ + "Ephesians 5:9-19", + "Matthew 18:10-20" + ], + "label": "" + } + ], + "2026-06-02": [ + { + "citations": [ + "Romans 1:1-7, 13-17", + "Matthew 4:25-5:13" + ], + "label": "" + } + ], + "2026-06-03": [ + { + "citations": [ + "Romans 1:18-27", + "Matthew 5:20-26" + ], + "label": "" + } + ], + "2026-06-04": [ + { + "citations": [ + "Romans 1:28-2:9", + "Matthew 5:27-32" + ], + "label": "" + } + ], + "2026-06-05": [ + { + "citations": [ + "Romans 2:14-29", + "Matthew 5:33-41" + ], + "label": "" + } + ], + "2026-06-06": [ + { + "citations": [ + "Romans 1:7-12", + "Matthew 5:42-48" + ], + "label": "" + } + ], + "2026-06-07": [ + { + "citations": [ + "Hebrews 11:33-12:2", + "Matthew 10:32-33, 37-38, 19:27-30" + ], + "label": "" + } + ], + "2026-06-08": [ + { + "citations": [ + "Romans 2:28-3:18", + "Matthew 6:31-34, 7:9-11" + ], + "label": "" + } + ], + "2026-06-09": [ + { + "citations": [ + "Romans 4:4-12", + "Matthew 7:15-21" + ], + "label": "" + } + ], + "2026-06-10": [ + { + "citations": [ + "Romans 4:13-25", + "Matthew 7:21-23" + ], + "label": "" + } + ], + "2026-06-11": [ + { + "citations": [ + "Acts 11:19-26, 29-30", + "Luke 10:16-21" + ], + "label": "Apostles" + }, + { + "citations": [ + "Romans 5:10-16", + "Matthew 8:23-27" + ], + "label": "" + } + ], + "2026-06-12": [ + { + "citations": [ + "Romans 5:17-6:2", + "Matthew 9:14-17" + ], + "label": "" + } + ], + "2026-06-13": [ + { + "citations": [ + "Romans 3:19-26", + "Matthew 7:1-8" + ], + "label": "" + } + ], + "2026-06-14": [ + { + "citations": [ + "Hebrews 11:33-12:2", + "Matthew 4:25-5:12" + ], + "label": "Saints" + }, + { + "citations": [ + "Romans 2:10-16", + "Matthew 4:18-23" + ], + "label": "" + } + ], + "2026-06-15": [ + { + "citations": [ + "Romans 7:1-13", + "Matthew 9:36-10:8" + ], + "label": "" + } + ], + "2026-06-16": [ + { + "citations": [ + "Romans 7:14-8:2", + "Matthew 10:9-15" + ], + "label": "" + } + ], + "2026-06-17": [ + { + "citations": [ + "Romans 8:2-13", + "Matthew 10:16-22" + ], + "label": "" + } + ], + "2026-06-18": [ + { + "citations": [ + "Romans 8:22-27", + "Matthew 10:23-31" + ], + "label": "" + } + ], + "2026-06-19": [ + { + "citations": [ + "Jude 1-10", + "John 14:21-24" + ], + "label": "Apostle" + }, + { + "citations": [ + "Romans 9:6-19", + "Matthew 10:32-36, 11:1" + ], + "label": "" + } + ], + "2026-06-20": [ + { + "citations": [ + "Romans 3:28-4:3", + "Matthew 7:24-8:4" + ], + "label": "" + } + ], + "2026-06-21": [ + { + "citations": [ + "Romans 5:1-10", + "Matthew 6:22-33" + ], + "label": "" + } + ], + "2026-06-22": [ + { + "citations": [ + "Romans 9:18-33", + "Matthew 11:2-15" + ], + "label": "" + } + ], + "2026-06-23": [ + { + "citations": [ + "Romans 10:11-11:2", + "Matthew 11:16-20" + ], + "label": "" + } + ], + "2026-06-24": [ + { + "citations": [ + "Romans 13:11-14:4", + "Luke 1:1-25, 57-68, 76, 80" + ], + "label": "Forerunner" + }, + { + "citations": [ + "Romans 11:2-12", + "Matthew 11:20-26" + ], + "label": "" + } + ], + "2026-06-25": [ + { + "citations": [ + "Romans 11:13-24", + "Matthew 11:27-30" + ], + "label": "" + } + ], + "2026-06-26": [ + { + "citations": [ + "Romans 11:25-36", + "Matthew 12:1-8" + ], + "label": "" + } + ], + "2026-06-27": [ + { + "citations": [ + "Romans 6:11-17", + "Matthew 8:14-23" + ], + "label": "" + } + ], + "2026-06-28": [ + { + "citations": [ + "Romans 6:18-23", + "Matthew 8:5-13" + ], + "label": "" + } + ], + "2026-06-29": [ + { + "citations": [ + "2 Corinthians 11:21-12:9", + "Matthew 16:13-19" + ], + "label": "Apostles" + }, + { + "citations": [ + "Romans 12:4-5, 15-21", + "Matthew 12:9-13" + ], + "label": "" + } + ], + "2026-06-30": [ + { + "citations": [ + "1 Corinthians 4:9-16", + "Mark 3:13-19" + ], + "label": "Apostles" + }, + { + "citations": [ + "Romans 14:9-18", + "Matthew 12:14-16, 22-30" + ], + "label": "" + } + ], + "2026-07-01": [ + { + "citations": [ + "Romans 15:7-16", + "Matthew 12:38-45" + ], + "label": "" + } + ], + "2026-07-02": [ + { + "citations": [ + "Romans 15:17-29", + "Matthew 12:46-13:3" + ], + "label": "" + } + ], + "2026-07-03": [ + { + "citations": [ + "Romans 16:1-16", + "Matthew 13:4-9" + ], + "label": "" + } + ], + "2026-07-04": [ + { + "citations": [ + "Romans 8:14-21", + "Matthew 9:9-13" + ], + "label": "" + } + ], + "2026-07-05": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "either Saint" + }, + { + "citations": [ + "Romans 10:1-10", + "Matthew 8:28-9:1" + ], + "label": "" + } + ], + "2026-07-06": [ + { + "citations": [ + "Romans 16:17-24", + "Matthew 13:10-23" + ], + "label": "" + } + ], + "2026-07-07": [ + { + "citations": [ + "1 Corinthians 1:1-9", + "Matthew 13:24-30" + ], + "label": "" + } + ], + "2026-07-08": [ + { + "citations": [ + "1 Corinthians 2:9-3:8", + "Matthew 13:31-36" + ], + "label": "" + } + ], + "2026-07-09": [ + { + "citations": [ + "1 Corinthians 3:18-23", + "Matthew 13:36-43" + ], + "label": "" + } + ], + "2026-07-10": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Matthew 4:25-5:12" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Corinthians 4:5-8", + "Matthew 13:44-54" + ], + "label": "" + } + ], + "2026-07-11": [ + { + "citations": [ + "Romans 9:1-5", + "Matthew 9:18-26" + ], + "label": "" + } + ], + "2026-07-12": [ + { + "citations": [ + "Romans 12:6-14", + "Matthew 9:1-8" + ], + "label": "" + } + ], + "2026-07-13": [ + { + "citations": [ + "1 Corinthians 5:9-6:11", + "Matthew 13:54-58" + ], + "label": "" + } + ], + "2026-07-14": [ + { + "citations": [ + "1 Corinthians 6:20-7:12", + "Matthew 14:1-13" + ], + "label": "" + } + ], + "2026-07-15": [ + { + "citations": [ + "Galatians 1:11-19", + "John 10:1-9" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Corinthians 7:12-24", + "Matthew 14:35-15:11" + ], + "label": "" + } + ], + "2026-07-16": [ + { + "citations": [ + "1 Corinthians 7:24-35", + "Matthew 15:12-21" + ], + "label": "" + } + ], + "2026-07-17": [ + { + "citations": [ + "1 Corinthians 7:35-8:7", + "Matthew 15:29-31" + ], + "label": "" + } + ], + "2026-07-18": [ + { + "citations": [ + "Romans 12:1-3", + "Matthew 10:37-11:1" + ], + "label": "" + } + ], + "2026-07-19": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Hebrews 13:7-16", + "John 17:1-13" + ], + "label": "Fathers" + }, + { + "citations": [ + "Romans 15:1-7", + "Matthew 9:27-35" + ], + "label": "" + } + ], + "2026-07-20": [ + { + "citations": [ + "James 5:10-20", + "Luke 4:22-30" + ], + "label": "Prophet" + }, + { + "citations": [ + "1 Corinthians 9:13-18", + "Matthew 16:1-6" + ], + "label": "" + } + ], + "2026-07-21": [ + { + "citations": [ + "1 Corinthians 10:5-12", + "Matthew 16:6-12" + ], + "label": "" + } + ], + "2026-07-22": [ + { + "citations": [ + "1 Corinthians 10:12-22", + "Matthew 16:20-24" + ], + "label": "" + } + ], + "2026-07-23": [ + { + "citations": [ + "1 Corinthians 10:28-11:7", + "Matthew 16:24-28" + ], + "label": "" + } + ], + "2026-07-24": [ + { + "citations": [ + "Romans 8:28-39", + "John 15:17-16:2" + ], + "label": "Saints" + }, + { + "citations": [ + "1 Corinthians 11:8-22", + "Matthew 17:10-18" + ], + "label": "" + } + ], + "2026-07-25": [ + { + "citations": [ + "Galatians 4:22-31", + "Luke 8:16-21" + ], + "label": "Saint" + }, + { + "citations": [ + "Romans 13:1-10", + "Matthew 12:30-37" + ], + "label": "" + } + ], + "2026-07-26": [ + { + "citations": [ + "Philippians 3:7-14", + "Mark 10:29-31, 42-45" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Corinthians 1:10-18", + "Matthew 14:14-22" + ], + "label": "" + } + ], + "2026-07-27": [ + { + "citations": [ + "2 Timothy 2:1-10", + "John 15:17-16:2" + ], + "label": "St. Panteleimon" + }, + { + "citations": [ + "1 Corinthians 11:31-12:6", + "Matthew 18:1-11" + ], + "label": "" + } + ], + "2026-07-28": [ + { + "citations": [ + "1 Corinthians 12:12-26", + "Matthew 18:18-22, 19:1-2, 13-15" + ], + "label": "" + } + ], + "2026-07-29": [ + { + "citations": [ + "1 Corinthians 13:4-14:5", + "Matthew 20:1-16" + ], + "label": "" + } + ], + "2026-07-30": [ + { + "citations": [ + "1 Corinthians 14:6-19", + "Matthew 20:17-28" + ], + "label": "" + } + ], + "2026-07-31": [ + { + "citations": [ + "1 Corinthians 14:26-40", + "Matthew 21:12-14, 17-20" + ], + "label": "" + } + ], + "2026-08-01": [ + { + "citations": [ + "1 Corinthians 1:18-24", + "John 19:6-11, 13-20, 25-28, 30-35" + ], + "label": "Cross" + }, + { + "citations": [ + "Hebrews 11:33-12:2", + "Matthew 10:32-36; 11:1" + ], + "label": "Martyrs" + }, + { + "citations": [ + "Hebrews 2:11-18", + "John 5:1-4" + ], + "label": "At the Blessing of Waters" + }, + { + "citations": [ + "Romans 14:6-9", + "Matthew 15:32-39" + ], + "label": "" + } + ], + "2026-08-02": [ + { + "citations": [ + "1 Corinthians 3:9-17", + "Matthew 14:22-34" + ], + "label": "" + } + ], + "2026-08-03": [ + { + "citations": [ + "1 Corinthians 15:12-19", + "Matthew 21:18-22" + ], + "label": "" + } + ], + "2026-08-04": [ + { + "citations": [ + "1 Corinthians 15:29-38", + "Matthew 21:23-27" + ], + "label": "" + } + ], + "2026-08-05": [ + { + "citations": [ + "1 Corinthians 16:4-12", + "Matthew 21:28-32" + ], + "label": "" + } + ], + "2026-08-06": [ + { + "citations": [ + "2 Corinthians 1:1-7", + "Matthew 21:43-46" + ], + "label": "" + }, + { + "citations": [ + "2 Peter 1:10-19", + "Matthew 17:1-9" + ], + "label": "Transfiguration" + } + ], + "2026-08-07": [ + { + "citations": [ + "2 Corinthians 1:12-20", + "Matthew 22:23-33" + ], + "label": "" + } + ], + "2026-08-08": [ + { + "citations": [ + "Romans 15:30-33", + "Matthew 17:24-18:4" + ], + "label": "" + } + ], + "2026-08-09": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "1 Corinthians 4:9-16", + "Matthew 17:14-23" + ], + "label": "" + } + ], + "2026-08-10": [ + { + "citations": [ + "2 Corinthians 2:4-15", + "Matthew 23:13-22" + ], + "label": "" + } + ], + "2026-08-11": [ + { + "citations": [ + "2 Corinthians 2:14-3:3", + "Matthew 23:23-28" + ], + "label": "" + } + ], + "2026-08-12": [ + { + "citations": [ + "2 Corinthians 3:4-11", + "Matthew 23:29-39" + ], + "label": "" + } + ], + "2026-08-13": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "Matthew 5:14-19" + ], + "label": "St. Tikhon" + }, + { + "citations": [ + "2 Corinthians 4:1-6", + "Matthew 24:13-28" + ], + "label": "" + } + ], + "2026-08-14": [ + { + "citations": [ + "2 Corinthians 4:13-18", + "Matthew 24:27-33, 42-51" + ], + "label": "" + } + ], + "2026-08-15": [ + { + "citations": [ + "1 Corinthians 1:3-9", + "Matthew 19:3-12" + ], + "label": "" + }, + { + "citations": [ + "Philippians 2:5-11", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + } + ], + "2026-08-16": [ + { + "citations": [ + "Colossians 1:12-18", + "Luke 9:51-56; 10:22-24" + ], + "label": "Image" + }, + { + "citations": [ + "1 Corinthians 9:2-12", + "Matthew 18:23-35" + ], + "label": "" + } + ], + "2026-08-17": [ + { + "citations": [ + "2 Corinthians 5:10-15", + "Mark 1:9-15" + ], + "label": "" + } + ], + "2026-08-18": [ + { + "citations": [ + "2 Corinthians 5:15-21", + "Mark 1:16-22" + ], + "label": "" + } + ], + "2026-08-19": [ + { + "citations": [ + "2 Corinthians 6:11-16", + "Mark 1:23-28" + ], + "label": "" + } + ], + "2026-08-20": [ + { + "citations": [ + "2 Corinthians 7:1-10", + "Mark 1:29-35" + ], + "label": "" + } + ], + "2026-08-21": [ + { + "citations": [ + "2 Corinthians 7:10-16", + "Mark 2:18-22" + ], + "label": "" + } + ], + "2026-08-22": [ + { + "citations": [ + "1 Corinthians 1:26-29", + "Matthew 20:29-34" + ], + "label": "" + } + ], + "2026-08-23": [ + { + "citations": [ + "Philippians 2:5-11", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + }, + { + "citations": [ + "1 Corinthians 15:1-11", + "Matthew 19:16-26" + ], + "label": "" + } + ], + "2026-08-24": [ + { + "citations": [ + "2 Corinthians 8:7-15", + "Mark 3:6-12" + ], + "label": "" + } + ], + "2026-08-25": [ + { + "citations": [ + "2 Corinthians 8:16-9:5", + "Mark 3:13-19" + ], + "label": "" + } + ], + "2026-08-26": [ + { + "citations": [ + "2 Corinthians 9:12-10:7", + "Mark 3:20-27" + ], + "label": "" + } + ], + "2026-08-27": [ + { + "citations": [ + "2 Corinthians 10:7-18", + "Mark 3:28-35" + ], + "label": "" + } + ], + "2026-08-28": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "2 Corinthians 11:5-21", + "Mark 4:1-9" + ], + "label": "" + } + ], + "2026-08-29": [ + { + "citations": [ + "Acts 13:25-33", + "Mark 6:14-30" + ], + "label": "Forerunner" + }, + { + "citations": [ + "1 Corinthians 2:6-9", + "Matthew 22:15-22" + ], + "label": "" + } + ], + "2026-08-30": [ + { + "citations": [ + "1 Corinthians 16:13-24", + "Matthew 21:33-42" + ], + "label": "" + } + ], + "2026-08-31": [ + { + "citations": [ + "2 Corinthians 12:10-19", + "Mark 4:10-23" + ], + "label": "" + } + ], + "2026-09-01": [ + { + "citations": [ + "1 Timothy 2:1-7", + "Luke 4:16-22" + ], + "label": "New Year" + }, + { + "citations": [ + "Colossians 3:12-16", + "Matthew 11:27-30" + ], + "label": "St. Simeon" + }, + { + "citations": [ + "2 Corinthians 12:20-13:2", + "Mark 4:24-34" + ], + "label": "" + } + ], + "2026-09-02": [ + { + "citations": [ + "2 Corinthians 13:3-14", + "Mark 4:35-41" + ], + "label": "" + } + ], + "2026-09-03": [ + { + "citations": [ + "Galatians 1:1-10, 20-2:5", + "Mark 5:1-20" + ], + "label": "" + } + ], + "2026-09-04": [ + { + "citations": [ + "Galatians 2:6-10", + "Mark 5:22-24, 35-6:1" + ], + "label": "" + } + ], + "2026-09-05": [ + { + "citations": [ + "1 Corinthians 4:1-5", + "Matthew 23:1-12" + ], + "label": "" + } + ], + "2026-09-06": [ + { + "citations": [ + "2 Corinthians 1:21-2:4", + "Matthew 22:1-14" + ], + "label": "" + } + ], + "2026-09-07": [ + { + "citations": [ + "Galatians 2:11-16", + "Mark 5:24-34" + ], + "label": "" + } + ], + "2026-09-08": [ + { + "citations": [ + "Galatians 2:21-3:7", + "Mark 6:1-7" + ], + "label": "" + }, + { + "citations": [ + "Philippians 2:5-11", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + } + ], + "2026-09-09": [ + { + "citations": [ + "Galatians 3:15-22", + "Mark 6:7-13" + ], + "label": "" + } + ], + "2026-09-10": [ + { + "citations": [ + "Galatians 3:23-4:5", + "Mark 6:30-45" + ], + "label": "" + } + ], + "2026-09-11": [ + { + "citations": [ + "Galatians 4:8-21", + "Mark 6:45-53" + ], + "label": "" + } + ], + "2026-09-12": [ + { + "citations": [ + "Philippians 2:5-11", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + }, + { + "citations": [ + "1 Corinthians 2:6-9", + "Matthew 10:37-11:1" + ], + "label": "Saturday Before" + }, + { + "citations": [ + "1 Corinthians 4:17-5:5", + "Matthew 24:1-13" + ], + "label": "" + } + ], + "2026-09-13": [ + { + "citations": [ + "Hebrews 3:1-4", + "Matthew 16:13-18" + ], + "label": "Church" + }, + { + "citations": [ + "Galatians 6:11-18", + "John 3:13-17" + ], + "label": "Sunday Before" + }, + { + "citations": [ + "2 Corinthians 4:6-15", + "Matthew 22:35-46" + ], + "label": "" + } + ], + "2026-09-14": [ + { + "citations": [ + "Galatians 4:28-5:10", + "Mark 6:54-7:8" + ], + "label": "" + }, + { + "citations": [ + "1 Corinthians 1:18-24", + "John 19:6-11, 13-20, 25-28, 30-35" + ], + "label": "" + } + ], + "2026-09-15": [ + { + "citations": [ + "Galatians 5:11-21", + "Mark 7:5-16" + ], + "label": "" + } + ], + "2026-09-16": [ + { + "citations": [ + "Galatians 6:2-10", + "Mark 7:14-24" + ], + "label": "" + } + ], + "2026-09-17": [ + { + "citations": [ + "Ephesians 1:1-9", + "Mark 7:24-30" + ], + "label": "" + } + ], + "2026-09-18": [ + { + "citations": [ + "Ephesians 1:7-17", + "Mark 8:1-10" + ], + "label": "" + } + ], + "2026-09-19": [ + { + "citations": [ + "1 Corinthians 1:26-29", + "John 8:21-30" + ], + "label": "Saturday After" + }, + { + "citations": [ + "1 Corinthians 10:23-28", + "Matthew 24:34-44" + ], + "label": "" + } + ], + "2026-09-20": [ + { + "citations": [ + "Galatians 2:16-20", + "Mark 8:34-9:1" + ], + "label": "Sunday After" + }, + { + "citations": [ + "2 Corinthians 6:1-10", + "Matthew 25:14-30" + ], + "label": "" + } + ], + "2026-09-21": [ + { + "citations": [ + "Ephesians 1:22-2:3", + "Luke 3:19-22" + ], + "label": "" + } + ], + "2026-09-22": [ + { + "citations": [ + "Ephesians 2:19-3:7", + "Luke 3:23-4:1" + ], + "label": "" + } + ], + "2026-09-23": [ + { + "citations": [ + "Galatians 4:22-31", + "Luke 1:5-25" + ], + "label": "Forerunner" + }, + { + "citations": [ + "Ephesians 3:8-21", + "Luke 4:1-15" + ], + "label": "" + } + ], + "2026-09-24": [ + { + "citations": [ + "Romans 8:28-39", + "Luke 21:12-19" + ], + "label": "New Martyrs" + }, + { + "citations": [ + "Ephesians 4:14-19", + "Luke 4:16-22" + ], + "label": "" + } + ], + "2026-09-25": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Ephesians 4:17-25", + "Luke 4:22-30" + ], + "label": "" + } + ], + "2026-09-26": [ + { + "citations": [ + "1 John 4:12-19", + "John 19:25-27; 21:24-25" + ], + "label": "St. John" + }, + { + "citations": [ + "1 Corinthians 14:20-25", + "Luke 4:31-36" + ], + "label": "" + } + ], + "2026-09-27": [ + { + "citations": [ + "2 Corinthians 6:16-7:1", + "Luke 5:1-11" + ], + "label": "" + } + ], + "2026-09-28": [ + { + "citations": [ + "2 Corinthians 4:6-15", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Ephesians 4:25-32", + "Luke 4:37-44" + ], + "label": "" + } + ], + "2026-09-29": [ + { + "citations": [ + "Ephesians 5:20-26", + "Luke 5:12-16" + ], + "label": "" + } + ], + "2026-09-30": [ + { + "citations": [ + "Ephesians 5:25-33", + "Luke 5:33-39" + ], + "label": "" + } + ], + "2026-10-01": [ + { + "citations": [ + "Hebrews 9:1-7", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + }, + { + "citations": [ + "Ephesians 5:33-6:9", + "Luke 6:12-19" + ], + "label": "" + } + ], + "2026-10-02": [ + { + "citations": [ + "Ephesians 6:18-24", + "Luke 6:17-23" + ], + "label": "" + } + ], + "2026-10-03": [ + { + "citations": [ + "1 Corinthians 15:39-45", + "Luke 5:17-26" + ], + "label": "" + } + ], + "2026-10-04": [ + { + "citations": [ + "2 Corinthians 9:6-11", + "Luke 6:31-36" + ], + "label": "" + } + ], + "2026-10-05": [ + { + "citations": [ + "Philippians 1:1-7", + "Luke 6:24-30" + ], + "label": "" + } + ], + "2026-10-06": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "John 10:9-16" + ], + "label": "St. Innocent" + }, + { + "citations": [ + "Philippians 1:8-14", + "Luke 6:37-45" + ], + "label": "" + } + ], + "2026-10-07": [ + { + "citations": [ + "Philippians 1:12-20", + "Luke 6:46-7:1" + ], + "label": "" + } + ], + "2026-10-08": [ + { + "citations": [ + "Philippians 1:20-27", + "Luke 7:17-30" + ], + "label": "" + } + ], + "2026-10-09": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "John 10:9-16" + ], + "label": "St. Tikhon" + }, + { + "citations": [ + "Philippians 1:27-2:4", + "Luke 7:31-35" + ], + "label": "" + } + ], + "2026-10-10": [ + { + "citations": [ + "1 Corinthians 15:58-16:3", + "Luke 5:27-32" + ], + "label": "" + } + ], + "2026-10-11": [ + { + "citations": [ + "Hebrews 13:7-16", + "John 17:1-13" + ], + "label": "Fathers" + }, + { + "citations": [ + "2 Corinthians 11:31-12:9", + "Luke 7:11-16" + ], + "label": "" + } + ], + "2026-10-12": [ + { + "citations": [ + "Philippians 2:12-16", + "Luke 7:36-50" + ], + "label": "" + } + ], + "2026-10-13": [ + { + "citations": [ + "Philippians 2:17-23", + "Luke 8:1-3" + ], + "label": "" + } + ], + "2026-10-14": [ + { + "citations": [ + "Philippians 2:24-30", + "Luke 8:22-25" + ], + "label": "" + } + ], + "2026-10-15": [ + { + "citations": [ + "Philippians 3:1-8", + "Luke 9:7-11" + ], + "label": "" + } + ], + "2026-10-16": [ + { + "citations": [ + "Philippians 3:8-19", + "Luke 9:12-18" + ], + "label": "" + } + ], + "2026-10-17": [ + { + "citations": [ + "2 Corinthians 1:8-11", + "Luke 6:1-10" + ], + "label": "" + } + ], + "2026-10-18": [ + { + "citations": [ + "Colossians 4:5-9, 14, 18", + "Luke 10:16-21" + ], + "label": "St. Luke" + }, + { + "citations": [ + "Galatians 1:11-19", + "Luke 8:5-15" + ], + "label": "" + } + ], + "2026-10-19": [ + { + "citations": [ + "Philippians 4:10-23", + "Luke 9:18-22" + ], + "label": "" + } + ], + "2026-10-20": [ + { + "citations": [ + "Colossians 1:1-2, 7-11", + "Luke 9:23-27" + ], + "label": "" + } + ], + "2026-10-21": [ + { + "citations": [ + "Colossians 1:18-23", + "Luke 9:44-50" + ], + "label": "" + } + ], + "2026-10-22": [ + { + "citations": [ + "Colossians 1:24-29", + "Luke 9:49-56" + ], + "label": "" + } + ], + "2026-10-23": [ + { + "citations": [ + "Gal 1:11-19", + "Matthew 13:54-58" + ], + "label": "Saint" + }, + { + "citations": [ + "Colossians 2:1-7", + "Luke 10:1-15" + ], + "label": "" + } + ], + "2026-10-24": [ + { + "citations": [ + "1 Thessalonians 4:13-17", + "John 5:24-30" + ], + "label": "Departed" + }, + { + "citations": [ + "2 Corinthians 3:12-18", + "Luke 7:1-10" + ], + "label": "" + } + ], + "2026-10-25": [ + { + "citations": [ + "Galatians 2:16-20", + "Luke 16:19-31" + ], + "label": "" + } + ], + "2026-10-26": [ + { + "citations": [ + "Hebrews 12:6-13, 25-27", + "Matthew 8:23-27" + ], + "label": "Earthquake" + }, + { + "citations": [ + "2 Timothy 2:1-10", + "John 15:17-16:2" + ], + "label": "St. Demetrius" + }, + { + "citations": [ + "Colossians 2:13-20", + "Luke 10:22-24" + ], + "label": "" + } + ], + "2026-10-27": [ + { + "citations": [ + "Colossians 2:20-3:3", + "Luke 11:1-10" + ], + "label": "" + } + ], + "2026-10-28": [ + { + "citations": [ + "Colossians 3:17-4:1", + "Luke 11:9-13" + ], + "label": "" + } + ], + "2026-10-29": [ + { + "citations": [ + "Colossians 4:2-9", + "Luke 11:14-23" + ], + "label": "" + } + ], + "2026-10-30": [ + { + "citations": [ + "Colossians 4:10-18", + "Luke 11:23-26" + ], + "label": "" + } + ], + "2026-10-31": [ + { + "citations": [ + "2 Corinthians 5:1-10", + "John 10:9-16" + ], + "label": "St. John Kochurov" + } + ], + "2026-11-01": [ + { + "citations": [ + "Galatians 6:11-18", + "Luke 8:26-39" + ], + "label": "" + } + ], + "2026-11-02": [ + { + "citations": [ + "1 Thessalonians 1:1-5", + "Luke 11:29-33" + ], + "label": "" + } + ], + "2026-11-03": [ + { + "citations": [ + "1 Thessalonians 1:6-10", + "Luke 11:34-41" + ], + "label": "" + } + ], + "2026-11-04": [ + { + "citations": [ + "1 Thessalonians 2:1-8", + "Luke 11:42-46" + ], + "label": "" + } + ], + "2026-11-05": [ + { + "citations": [ + "1 Thessalonians 2:9-14", + "Luke 11:47-12:1" + ], + "label": "" + } + ], + "2026-11-06": [ + { + "citations": [ + "1 Thessalonians 2:14-19", + "Luke 12:2-12" + ], + "label": "" + } + ], + "2026-11-07": [ + { + "citations": [ + "2 Corinthians 8:1-5", + "Luke 9:1-6" + ], + "label": "" + } + ], + "2026-11-08": [ + { + "citations": [ + "Hebrews 2:2-10", + "Luke 10:16-21" + ], + "label": "Angels" + }, + { + "citations": [ + "Ephesians 2:4-10", + "Luke 8:41-56" + ], + "label": "" + } + ], + "2026-11-09": [ + { + "citations": [ + "1 Thessalonians 2:20-3:8", + "Luke 12:13-15, 22-31" + ], + "label": "" + } + ], + "2026-11-10": [ + { + "citations": [ + "1 Thessalonians 3:9-13", + "Luke 12:42-48" + ], + "label": "" + } + ], + "2026-11-11": [ + { + "citations": [ + "1 Thessalonians 4:1-12", + "Luke 12:48-59" + ], + "label": "" + } + ], + "2026-11-12": [ + { + "citations": [ + "1 Thessalonians 5:1-8", + "Luke 13:1-9" + ], + "label": "" + } + ], + "2026-11-13": [ + { + "citations": [ + "Hebrews 7:26-8:2", + "John 10:9-16" + ], + "label": "St. John Chrysostom" + }, + { + "citations": [ + "1 Thessalonians 5:9-13, 24-28", + "Luke 13:31-35" + ], + "label": "" + } + ], + "2026-11-14": [ + { + "citations": [ + "1 Corinthians 4:9-16", + "John 1:43-51" + ], + "label": "Apostle" + }, + { + "citations": [ + "2 Corinthians 11:1-6", + "Luke 9:37-43" + ], + "label": "" + } + ], + "2026-11-15": [ + { + "citations": [ + "Ephesians 2:14-22", + "Luke 10:25-37" + ], + "label": "" + } + ], + "2026-11-16": [ + { + "citations": [ + "1 Corinthians 4:9-16", + "Matthew 9:9-13" + ], + "label": "Apostle" + }, + { + "citations": [ + "2 Thessalonians 1:1-10", + "Luke 14:12-15" + ], + "label": "" + } + ], + "2026-11-17": [ + { + "citations": [ + "2 Thessalonians 1:10-2:2", + "Luke 14:25-35" + ], + "label": "" + } + ], + "2026-11-18": [ + { + "citations": [ + "2 Thessalonians 2:1-12", + "Luke 15:1-10" + ], + "label": "" + } + ], + "2026-11-19": [ + { + "citations": [ + "2 Thessalonians 2:13-3:5", + "Luke 16:1-9" + ], + "label": "" + } + ], + "2026-11-20": [ + { + "citations": [ + "2 Thessalonians 3:6-18", + "Luke 16:15-18, 17:1-4" + ], + "label": "" + } + ], + "2026-11-21": [ + { + "citations": [ + "Galatians 1:3-10", + "Luke 9:57-62" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 9:1-7", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + } + ], + "2026-11-22": [ + { + "citations": [ + "Ephesians 4:1-6", + "Luke 12:16-21" + ], + "label": "" + } + ], + "2026-11-23": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Matthew 11:27-30" + ], + "label": "St. Alexander" + }, + { + "citations": [ + "1 Timothy 1:1-7", + "Luke 17:20-25" + ], + "label": "" + } + ], + "2026-11-24": [ + { + "citations": [ + "1 Timothy 1:8-14", + "Luke 17:26-37" + ], + "label": "" + } + ], + "2026-11-25": [ + { + "citations": [ + "Hebrews 9:1-7", + "Luke 10:38-42; 11:27-28" + ], + "label": "Theotokos" + }, + { + "citations": [ + "1 Timothy 1:18-20, 2:8-15", + "Luke 18:15-17, 26-30" + ], + "label": "" + } + ], + "2026-11-26": [ + { + "citations": [ + "1 Timothy 3:1-13", + "Luke 18:31-34" + ], + "label": "" + } + ], + "2026-11-27": [ + { + "citations": [ + "1 Timothy 4:4-8, 16", + "Luke 19:12-28" + ], + "label": "" + } + ], + "2026-11-28": [ + { + "citations": [ + "Galatians 3:8-12", + "Luke 10:19-21" + ], + "label": "" + } + ], + "2026-11-29": [ + { + "citations": [ + "Ephesians 5:9-19", + "Luke 13:10-17" + ], + "label": "" + } + ], + "2026-11-30": [ + { + "citations": [ + "1 Corinthians 4:9-16", + "John 1:35-51" + ], + "label": "Apostle" + }, + { + "citations": [ + "1 Timothy 5:1-10", + "Luke 19:37-44" + ], + "label": "" + } + ], + "2026-12-01": [ + { + "citations": [ + "1 Timothy 5:11-21", + "Luke 19:45-48" + ], + "label": "" + } + ], + "2026-12-02": [ + { + "citations": [ + "1 Timothy 5:22-6:11", + "Luke 20:1-8" + ], + "label": "" + } + ], + "2026-12-03": [ + { + "citations": [ + "1 Timothy 6:17-21", + "Luke 20:9-18" + ], + "label": "" + } + ], + "2026-12-04": [ + { + "citations": [ + "Hebrews 13:7-16", + "Luke 12:32-40" + ], + "label": "St. Alexander" + }, + { + "citations": [ + "2 Timothy 1:1-2, 8-18", + "Luke 20:19-26" + ], + "label": "" + } + ], + "2026-12-05": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Matthew 11:27-30" + ], + "label": "Saint" + }, + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 12:32-40" + ], + "label": "" + } + ], + "2026-12-06": [ + { + "citations": [ + "Hebrews 13:17-21", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Ephesians 6:10-17", + "Luke 17:12-19" + ], + "label": "" + } + ], + "2026-12-07": [ + { + "citations": [ + "2 Timothy 2:20-26", + "Luke 20:27-44" + ], + "label": "" + } + ], + "2026-12-08": [ + { + "citations": [ + "2 Timothy 3:16-4:4", + "Luke 21:12-19" + ], + "label": "" + } + ], + "2026-12-09": [ + { + "citations": [ + "Galatians 4:22-31", + "Luke 8:16-21" + ], + "label": "St. Anna" + }, + { + "citations": [ + "2 Timothy 4:9-22", + "Luke 21:5-7, 10-11, 20-24" + ], + "label": "" + } + ], + "2026-12-10": [ + { + "citations": [ + "Titus 1:5-2:1", + "Luke 21:28-33" + ], + "label": "" + } + ], + "2026-12-11": [ + { + "citations": [ + "Titus 1:15-2:10", + "Luke 21:37-22:8" + ], + "label": "" + } + ], + "2026-12-12": [ + { + "citations": [ + "Ephesians 1:16-23", + "Luke 13:18-29" + ], + "label": "" + } + ], + "2026-12-13": [ + { + "citations": [ + "Galatians 5:22-6:2", + "Luke 6:17-23" + ], + "label": "Saint" + }, + { + "citations": [ + "Colossians 3:4-11", + "Luke 14:16-24" + ], + "label": "" + } + ], + "2026-12-14": [ + { + "citations": [ + "Hebrews 3:5-11, 17-19", + "Mark 8:11-21" + ], + "label": "" + } + ], + "2026-12-15": [ + { + "citations": [ + "Hebrews 4:1-13", + "Mark 8:22-26" + ], + "label": "" + } + ], + "2026-12-16": [ + { + "citations": [ + "Hebrews 5:11-6:8", + "Mark 8:30-34" + ], + "label": "" + } + ], + "2026-12-17": [ + { + "citations": [ + "Hebrews 7:1-6", + "Mark 9:10-16" + ], + "label": "" + } + ], + "2026-12-18": [ + { + "citations": [ + "Hebrews 7:18-25", + "Mark 9:33-41" + ], + "label": "" + } + ], + "2026-12-19": [ + { + "citations": [ + "Galatians 3:8-12", + "Luke 13:18-29" + ], + "label": "Saturday Before" + }, + { + "citations": [ + "Ephesians 2:11-13", + "Luke 14:1-11" + ], + "label": "" + } + ], + "2026-12-20": [ + { + "citations": [ + "Hebrews 11:9-10, 17-23, 32-40", + "Matthew 1:1-25" + ], + "label": "Sunday Before" + } + ], + "2026-12-21": [ + { + "citations": [ + "Hebrews 8:7-13", + "Mark 9:42-10:1" + ], + "label": "" + } + ], + "2026-12-22": [ + { + "citations": [ + "Hebrews 9:8-10, 15-23", + "Mark 10:2-12" + ], + "label": "" + } + ], + "2026-12-23": [ + { + "citations": [ + "Hebrews 10:1-18", + "Mark 10:11-16" + ], + "label": "" + } + ], + "2026-12-24": [ + { + "citations": [ + "Hebrews 10:35-11:7", + "Mark 10:17-27" + ], + "label": "" + }, + { + "citations": [ + "Hebrews 1:1-12", + "Luke 2:1-20" + ], + "label": "" + } + ], + "2026-12-25": [ + { + "citations": [ + "Galatians 4:4-7", + "Matthew 2:1-12" + ], + "label": "Nativity" + } + ], + "2026-12-26": [ + { + "citations": [ + "1 Timothy 6:11-16", + "Matthew 12:15-21" + ], + "label": "Saturday After" + }, + { + "citations": [ + "Hebrews 2:11-18", + "Matthew 2:13-23" + ], + "label": "Theotokos" + } + ], + "2026-12-27": [ + { + "citations": [ + "Acts 6:8-15; 7:1-5, 47-60", + "Matthew 21:33-42" + ], + "label": "Saint" + }, + { + "citations": [ + "Galatians 1:11-19", + "Matthew 2:13-23" + ], + "label": "Sunday After" + } + ], + "2026-12-28": [ + { + "citations": [ + "Hebrews 11:17-23, 27-31", + "Mark 10:46-52" + ], + "label": "" + } + ], + "2026-12-29": [ + { + "citations": [ + "Hebrews 12:25-26, 13:22-25", + "Mark 11:11-23" + ], + "label": "" + } + ], + "2026-12-30": [ + { + "citations": [ + "James 1:1-18", + "Mark 11:22-26" + ], + "label": "" + } + ], + "2026-12-31": [ + { + "citations": [ + "James 1:19-27", + "Mark 11:27-33" + ], + "label": "" + } + ] +} \ No newline at end of file diff --git a/data/oca_readings_diff-2026.json b/data/oca_readings_diff-2026.json new file mode 100644 index 00000000..1cd38ca1 --- /dev/null +++ b/data/oca_readings_diff-2026.json @@ -0,0 +1,114 @@ +[ + { + "date": "2026-01-01", + "labels": [ + "Circumcision", + "Saint" + ], + "missing": [ + "HEB10:35", + "MARK11:27" + ], + "extra": [] + }, + { + "date": "2026-01-03", + "labels": [ + "Saturday Before" + ], + "missing": [], + "extra": [ + "EPH5:1", + "LUKE17:3" + ] + }, + { + "date": "2026-01-05", + "labels": [], + "missing": [ + "HEB11:17", + "MARK8:11" + ], + "extra": [] + }, + { + "date": "2026-03-26", + "labels": [ + "Theotokos" + ], + "missing": [ + "HEB2:11", + "LUKE1:24" + ], + "extra": [] + }, + { + "date": "2026-04-07", + "labels": [ + "Matins", + "Vespers", + "Presanctified" + ], + "missing": [], + "extra": [ + "MATT22:15", + "JOHN10:9" + ] + }, + { + "date": "2026-04-09", + "labels": [ + "Matins", + "Vespers", + "Composite" + ], + "missing": [], + "extra": [ + "JOHN13:1", + "JOHN13:12" + ] + }, + { + "date": "2026-05-21", + "labels": [], + "missing": [], + "extra": [ + "ACTS26:1", + "JOHN10:1" + ] + }, + { + "date": "2026-10-31", + "labels": [ + "St. John Kochurov" + ], + "missing": [ + "JOHN10:9" + ], + "extra": [ + "HEB13:7", + "LUKE8:16", + "LUKE12:32" + ] + }, + { + "date": "2026-11-08", + "labels": [ + "Angels" + ], + "missing": [], + "extra": [ + "1COR12:27", + "MATT10:1" + ] + }, + { + "date": "2026-12-24", + "labels": [], + "missing": [ + "HEB10:35", + "MARK10:17" + ], + "extra": [] + } +] \ No newline at end of file diff --git a/docs/oca-audit.md b/docs/oca-audit.md new file mode 100644 index 00000000..590bdd15 --- /dev/null +++ b/docs/oca-audit.md @@ -0,0 +1,124 @@ +# Auditing the Slavic data against oca.org + +The Slavic readings have been in this app since long before the Greek tradition +was added, and they were never measured against their own source the way Greek +was measured against goarch.org (`docs/greek-lectionary.md`, which took Greek +from 96.1% to 99.1%). This is that measurement. + +**Current state: 329/339 dates match for 2026 — 97.1%.** Ten dates differ, in +three coherent groups, and the largest group is a single unmodelled rule rather +than ten separate mistakes. + +## Sources + +| what | URL | cost | +|---|---|---| +| a year of Liturgy readings | `/readings/monthly/YYYY/MM` | 12 pages | +| one day, all services | `/readings/daily/YYYY/MM/DD` | 1 page | +| one day's commemorations | `/saints/lives/YYYY/MM/DD` | 1 page | + +oca.org's `robots.txt` allows all of these — it disallows only two unrelated +paths — and asks for `Crawl-delay: 10`, which `tools/oca/fetch.py` honours and +caches around. + +**It 403s some user agents on a keyword match.** A UA containing the word +"harvester" is refused, as is `python-urllib/3.14`; an honest self-identifying +string is served fine. That is a crude keyword filter, not an access policy — +robots.txt is the policy. Identify yourself properly; do not impersonate a +browser. + +## Two traps in the monthly tables + +Both of these produced confidently wrong numbers before being caught. + +**The columns are not positionally stable.** January and May–December give four +cells a row; February, March and April give five. The extra column is not +consistently anything — on 2/1 it is empty with the Epistle and Gospel after +it, while on 2/18 a Lenten day's two Old Testament lessons sit in the very +cells a Liturgy day uses for Epistle and Gospel. Reading slots off column +numbers swaps Epistle and Gospel for a third of the year: it scored the app at +**73.7%** when the true figure was far higher. Classify by book instead — +`tools/oca/refs.py:slot()`. + +**Neither side is self-consistent about which slot a reading belongs to.** +oca.org labels Holy Week's Bridegroom gospels `(Matins)`; the app files those +same readings under source `Gospel`. The app splits Theophany Eve across Hours, +Vespers and the Blessing of Waters where oca.org prints two rows. Excluding +oca.org's service-labelled rows to compensate made things *worse* — 95.6%, with +false differences on exactly the hardest days. + +So the audit does not pair readings by slot at all. It asks two questions +separately: + +- **missing** — oca.org lists it and the app has it nowhere. A real gap. +- **extra** — the app shows it as an Epistle or Gospel and oca.org lists + nothing like it. Restricted to those two sources so the app's much fuller + Vespers and Hours data is not counted against it. + +## What differs + +Every date below was confirmed against `/readings/daily/`, which lists all +services, in case the monthly table was abbreviating. It was not. + +### 1. The ordinary daily cycle on feast days — 4 dates, one rule + +The app and oca.org disagree about whether the ordinary daily-cycle reading is +*also* read when a feast or its eve claims the day. Both directions occur: + +| date | day | oca.org | the app | +|---|---|---|---| +| Jan 1 | Circumcision + St Basil | reads `Heb 10:35-11:7` / `Mark 11:27-33` as well | omits it | +| Jan 5 | Eve of Theophany | reads `Heb 11:17-23,27-31` / `Mark 8:11-21` as well | omits it | +| Dec 24 | Eve of Nativity | reads `Heb 10:35-11:7` / `Mark 10:17-27` as well | omits it | +| Jan 3 | Saturday before Theophany | reads **only** `1 Tim 3:14-4:5` / `Matt 3:1-11` | adds `Eph 5:1-8` / `Luke 17:3-10` | + +The first three are one rule and the fourth is its mirror, which is what makes +this worth fixing as a rule rather than four data rows: on a *feast or eve* the +ordinary reading survives alongside the festal one, and on a *Saturday or +Sunday before or after* a great feast it is replaced. The app currently has it +backwards in both cases. + +Not yet implemented — the fix belongs in the reading-selection logic, and the +rule above is inferred from four dates in one year. **Confirm it across several +years before coding it**, the same standard the Greek work held to. + +### 2. Readings the app shows on days oca.org gives to Holy Week — 3 dates + +| date | day | the app also shows | +|---|---|---| +| Apr 7 | Great and Holy Tuesday | `Matt 22:15` (Bridegroom), `John 10:9` (St Tikhon) | +| Apr 9 | Great and Holy Thursday | `John 13:1-11`, `John 13:12-17` (the Washing of the Feet) | +| Oct 31 | — | `Heb 13:7`, `Luke 8:16`, `Luke 12:32`; oca.org has `John 10:9` | + +Apr 7 is the informative one. The Repose of St Tikhon falls on Great and Holy +Tuesday in 2026, and oca.org gives him no readings at all — Holy Week +suppresses them. The app serves them. This is a ranking question, not a data +error, and it is the same shape as the fast-exception ranking work in +`docs/greek-fasting.md`. + +The two foot-washing gospels on Apr 9 are genuinely served, but at the Washing +rite rather than the Liturgy; the app files them under `Gospel`. That is a +`source` classification issue, not a missing or spurious reading. + +### 3. Single dates, not yet explained — 3 dates + +`2026-03-26` (missing `Heb 2:11` / `Luke 1:24`), `2026-05-21` (extra +`Acts 26:1` / `John 10:1`), `2026-11-08` (extra `1 Cor 12:27` / `Matt 10:1`). +All three are feast-adjacent — the Synaxis of Gabriel, Constantine and Helen, +and the Synaxis of the Archangel Michael. They may well fall under group 1 once +that rule is confirmed across more years. + +## What this does not cover + +The monthly tables give the Liturgy, plus Vespers Old Testament lessons in the +Lenten months only. **Matins is not covered at all, and Vespers only partly**, +so a clean report here says nothing about them. The app's Vespers and Hours +data is far fuller than anything checked here. + +`/readings/daily/` *does* list every service — Jan 1 returns all ten readings +including the Vespers and Matins ones — and would support a complete audit at +365 requests a year rather than 12. That is the obvious next step if the +Liturgy-level gaps above turn out to be worth chasing. + +Only 2026 has been audited. One year is enough to find a rule but not to +confirm one. diff --git a/tools/oca/README.md b/tools/oca/README.md new file mode 100644 index 00000000..84adadfc --- /dev/null +++ b/tools/oca/README.md @@ -0,0 +1,35 @@ +# tools/oca + +Harvesting and auditing against oca.org, the source the app's `common` and +`slavic` data was originally compiled from. Findings live in +`docs/oca-audit.md`; this file says which script produced what. + +Read `docs/oca-audit.md` first if you are here to change something — it records +two traps in these pages that produced confidently wrong numbers. + +| script | does | +|---|---| +| `fetch.py` | shared HTTP: on-disk cache, `Crawl-delay: 10`, the UA that works | +| `harvest_readings.py YEAR` | 12 monthly pages -> `data/oca_raw/readings-YYYY.json` | +| `harvest_saints.py YEAR` | 365 daily pages -> `data/oca_raw/saints-YYYY.json` (~1 hour) | +| `refs.py` | `canon()` citation tokens, `slot()` book classification, `near()` | +| `audit_readings.py YEAR` | app vs oca.org -> `data/oca_readings_diff-YYYY.json` | +| `explain_diff.py DATE...` | both sides of one day in full, with sources and labels | + +Everything is cached under `data/oca_raw/_cache/`, so re-running a harvest is +instant. That matters: at a 10-second crawl delay a fresh year of saints is +about an hour. Delete the cache only if you mean to re-fetch. + +`refs.py:canon()` came from `tools/greek/three_way.py`, where the ordinal and +single-chapter traps were worked out. Prefer this copy for new work. + +## Typical run + +```sh +python tools/oca/harvest_readings.py 2026 # no Django needed +docker compose run --rm local python tools/oca/audit_readings.py 2026 +docker compose run --rm local python tools/oca/explain_diff.py --all 2026 +``` + +The harvests are plain HTTP and run on the host; the audits need Django and run +in the container. diff --git a/tools/oca/audit_readings.py b/tools/oca/audit_readings.py new file mode 100644 index 00000000..9f73a60f --- /dev/null +++ b/tools/oca/audit_readings.py @@ -0,0 +1,137 @@ +"""Audit the app's Slavic Liturgy readings against oca.org, a full year at a time. + + docker compose run --rm local python tools/oca/audit_readings.py 2026 + +The Slavic data has been in this app since long before the Greek tradition was +added, and until now it had never been measured against its own source the way +Greek was measured against goarch.org. This is that measurement. + +Scope is the Liturgy Epistle and Gospel. The harvested pages also carry Vespers +Old Testament lessons in the Lenten months, but not consistently across the +year, so OT citations are counted and reported separately rather than audited +-- a clean report here says nothing about Vespers, Matins or the Hours. + +Comparison is set-based per date and classified by book, never positional. See +harvest_readings.py for why position is unusable, and refs.slot() for the +classification. oca.org lists a date's reading sets in its own order with +free-text labels, so the only reliable question is whether the same citations +are present. A date passes when every OCA citation has a near() match among the +app's and vice versa. + +Writes data/oca_readings_diff-YYYY.json with every mismatch for follow-up. +""" +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) +os.chdir(sys.path[0]) + +import asyncio +import datetime +import json + +import django + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orthocal.settings') +django.setup() + +from calendarium.datetools import Tradition # noqa: E402 +from calendarium.liturgics import Day # noqa: E402 + +from tools.oca.refs import canon, near, slot # noqa: E402 + + +# Slot is deliberately NOT used to pair readings up. Neither side is +# self-consistent about it: oca.org labels Holy Week's Bridegroom gospels +# "(Matins)" while the app files those same readings under source "Gospel", and +# the app splits Theophany Eve across Hours, Vespers and Blessing of Waters +# where oca.org prints two rows. Matching by slot invented differences on +# precisely the hardest days -- it moved the score the wrong way and flagged +# readings both sides plainly had. Match on the citation, and report the two +# directions separately, which is what actually needs fixing: +# +# missing -- oca.org lists it, the app has it nowhere. A real gap. +# extra -- the app shows it as an Epistle or Gospel, oca.org lists nothing +# like it. Restricted to those two sources so the app's much +# fuller Vespers/Hours data is not counted against it. + + +def match(ours, theirs): + """Pair up two citation lists by near(); return what is left over.""" + unmatched_theirs, pool = [], list(ours) + for t in theirs: + hit = next((o for o in pool if near(o, t)), None) + if hit is None: + unmatched_theirs.append(t) + else: + pool.remove(hit) + return pool, unmatched_theirs # ours-only, theirs-only + + +async def audit(year): + with open(f'data/oca_raw/readings-{year}.json') as f: + oca = json.load(f) + + diffs = [] + checked = clean = ot_only = 0 + date = datetime.date(year, 1, 1) + while date.year == year: + rows = oca.get(date.isoformat()) + if not rows: + date += datetime.timedelta(days=1) + continue + + day = Day(date.year, date.month, date.day, tradition=Tradition.Slavic) + await day.ainitialize() + readings = await day.aget_readings() + + all_ours = [canon(r.pericope.display) for r in readings] + liturgy_ours = [canon(r.pericope.display) for r in readings + if r.source in ('Epistle', 'Gospel')] + theirs = [canon(c) for row in rows for c in row['citations']] + theirs = [t for t in theirs if t] + + # A day whose only OCA content is Old Testament is a Lenten Vespers day + # with no Liturgy. Out of scope rather than a mismatch. + if theirs and all(slot(t) == 'OT' for t in theirs): + ot_only += 1 + date += datetime.timedelta(days=1) + continue + + _, missing = match(all_ours, theirs) + extra, _ = match(liturgy_ours, theirs) + + checked += 1 + if missing or extra: + diffs.append({ + 'date': date.isoformat(), + 'labels': [r['label'] for r in rows if r['label']], + 'missing': missing, + 'extra': extra, + }) + else: + clean += 1 + + date += datetime.timedelta(days=1) + + path = f'data/oca_readings_diff-{year}.json' + with open(path, 'w') as f: + json.dump(diffs, f, indent=1) + + pct = 100.0 * clean / checked if checked else 0.0 + print(f'{year}: {clean}/{checked} dates match ({pct:.1f}%), {len(diffs)} differ -> {path}') + print(f' ({ot_only} Lenten days skipped: Old Testament only, no Liturgy)') + for d in diffs[:30]: + bits = [] + if d['missing']: + bits.append(f"missing={d['missing']}") + if d['extra']: + bits.append(f"extra={d['extra']}") + print(f" {d['date']} {' '.join(bits)}") + if len(diffs) > 25: + print(f' ... and {len(diffs) - 25} more in {path}') + + +if __name__ == '__main__': + for year in (sys.argv[1:] or ['2026']): + asyncio.run(audit(int(year))) diff --git a/tools/oca/explain_diff.py b/tools/oca/explain_diff.py new file mode 100644 index 00000000..508daec5 --- /dev/null +++ b/tools/oca/explain_diff.py @@ -0,0 +1,63 @@ +"""Print the app's and oca.org's full readings side by side for given dates. + + docker compose run --rm local python tools/oca/explain_diff.py 2026-01-01 ... + docker compose run --rm local python tools/oca/explain_diff.py --all 2026 + +audit_readings.py reports which citations differ; this shows the whole day on +both sides, with our `source`/`desc` and oca.org's labels, which is what it +takes to tell a real gap from a difference in how a day is decomposed. +""" +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) +os.chdir(sys.path[0]) + +import asyncio +import datetime +import json + +import django + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orthocal.settings') +django.setup() + +from calendarium.datetools import Tradition # noqa: E402 +from calendarium.liturgics import Day # noqa: E402 + + +async def show(datestr): + date = datetime.date.fromisoformat(datestr) + with open(f'data/oca_raw/readings-{date.year}.json') as f: + oca = json.load(f) + + day = Day(date.year, date.month, date.day, tradition=Tradition.Slavic) + await day.ainitialize() + readings = await day.aget_readings() + + print(f'\n=== {datestr} ({date:%A}) ===') + print(f' app titles : {"; ".join(day.titles) or "-"}') + print(f' app feasts : {"; ".join(day.feasts) or "-"}') + print(' app readings:') + for r in readings: + desc = f' [{r.desc}]' if r.desc else '' + print(f' {r.source:<16} {r.pericope.display}{desc}') + print(' oca.org:') + for row in oca.get(datestr, []): + label = f' ({row["label"]})' if row['label'] else '' + print(f' {" / ".join(row["citations"])}{label}') + + +async def main(args): + if args and args[0] == '--all': + year = int(args[1]) + with open(f'data/oca_readings_diff-{year}.json') as f: + dates = [d['date'] for d in json.load(f)] + else: + dates = args + for d in dates: + await show(d) + + +if __name__ == '__main__': + asyncio.run(main(sys.argv[1:])) diff --git a/tools/oca/fetch.py b/tools/oca/fetch.py new file mode 100644 index 00000000..81c6f0ab --- /dev/null +++ b/tools/oca/fetch.py @@ -0,0 +1,54 @@ +"""Shared fetching for the oca.org harvests. + +oca.org has no API, and no interstitial of the kind goarch.org sits behind. +Its robots.txt allows everything we touch (it disallows only two unrelated +paths) and asks for `Crawl-delay: 10`, which DELAY honours. Every page is +cached on disk, so re-running a harvest costs nothing after the first pass -- +which matters a great deal at ten seconds a request. + +One trap: oca.org 403s some user agents on a keyword match. A UA containing +the word "harvester" is refused; `python-urllib/3.14` is refused; the honest +self-identifying string below is served fine. That filter is a crude keyword +block, not the site's access policy -- robots.txt is the policy, and it says +yes. Identify yourself properly rather than impersonating a browser. +""" +import hashlib +import os +import time +import urllib.request + +CACHE = 'data/oca_raw/_cache' +DELAY = 10.0 # seconds; oca.org's robots.txt asks for Crawl-delay: 10 +UA = 'orthocal-bot/1.0 (+https://orthocal.info)' + +_last = [0.0] + + +def get(url, cache=True): + """Fetch a URL, caching the body on disk. Returns str, or None on 404.""" + os.makedirs(CACHE, exist_ok=True) + path = os.path.join(CACHE, hashlib.sha1(url.encode()).hexdigest() + '.html') + + if cache and os.path.exists(path): + with open(path, encoding='utf-8') as f: + return f.read() or None + + wait = DELAY - (time.time() - _last[0]) + if wait > 0: + time.sleep(wait) + + req = urllib.request.Request(url, headers={'User-Agent': UA}) + try: + with urllib.request.urlopen(req, timeout=30) as r: + body = r.read().decode('utf-8', 'replace') + except urllib.error.HTTPError as e: + if e.code == 404: + body = '' + else: + raise + finally: + _last[0] = time.time() + + with open(path, 'w', encoding='utf-8') as f: + f.write(body) + return body or None diff --git a/tools/oca/harvest_readings.py b/tools/oca/harvest_readings.py new file mode 100644 index 00000000..db9a5e24 --- /dev/null +++ b/tools/oca/harvest_readings.py @@ -0,0 +1,93 @@ +"""Harvest a year of OCA daily Liturgy readings into data/oca_raw/. + + python tools/oca/harvest_readings.py 2026 [2025 ...] + +Source: https://www.oca.org/readings/monthly/YYYY/MM -- twelve small tables a +year, each row a date with its citations and an optional free-text label: + + 1/1 + Colossians 2:8-12 + Luke 2:20-21,40-52 + (Circumcision) + +**The columns are not positionally stable, so this stores cells, not slots.** +January and May-December give four cells a row; February, March and April give +five. The extra column is not consistently anything: on 2/1 it is empty and the +Epistle and Gospel follow it, while on 2/18 a Lenten day's two Old Testament +lessons occupy the very cells a Liturgy day uses for Epistle and Gospel. +Reading Epistle and Gospel off column numbers silently swaps them for a third +of the year -- it scored the app at 73.7% when the real figure was far higher. +Classify by book instead: tools/oca/refs.py `slot()`. + +A date carries one row per reading set, so most days have one or two and a +feast can have several. The label is free text, not a controlled vocabulary -- +"(Saint)", "(Saturday Before)", "(Forerunner)". Do not try to map labels onto +our `source` field; match on the citations and treat the label as a hint. + +This page gives the Liturgy plus, in the Lenten months, Vespers Old Testament +lessons. Matins is not here. + +Writes data/oca_raw/readings-YYYY.json: + {"YYYY-MM-DD": [{"citations": [...], "label": "..."}, ...]} +""" +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) +os.chdir(sys.path[0]) + +import html +import json +import re + +from tools.oca.fetch import get + +CELL = re.compile(r']*>(.*?)', re.S) +DATE = re.compile(r'^(\d+)/(\d+)$') + + +def clean(s): + return re.sub(r'\s+', ' ', html.unescape(re.sub(r'<[^>]+>', '', s))).strip() + + +def harvest(year): + out = {} + for month in range(1, 13): + page = get(f'https://www.oca.org/readings/monthly/{year}/{month:02d}') + if page is None: + print(f' {year}-{month:02d}: no page') + continue + n = 0 + for row in re.findall(r'(.*?)', page, re.S): + cells = [clean(c) for c in CELL.findall(row)] + if not cells: + continue + m = DATE.match(cells[0]) + if not m or int(m.group(1)) != month: + continue + + # Everything after the date is either a citation or the label; the + # label is the parenthesised one, and empty cells are padding. + label, citations = '', [] + for c in cells[1:]: + if not c: + continue + if c.startswith('(') and c.endswith(')'): + label = c.strip('()') + else: + citations.append(c) + + key = f'{year}-{month:02d}-{int(m.group(2)):02d}' + out.setdefault(key, []).append({'citations': citations, 'label': label}) + n += 1 + print(f' {year}-{month:02d}: {n} rows') + + path = f'data/oca_raw/readings-{year}.json' + with open(path, 'w') as f: + json.dump(out, f, indent=1, sort_keys=True) + print(f'{year}: {len(out)} dates, {sum(len(v) for v in out.values())} rows -> {path}') + + +if __name__ == '__main__': + for year in (sys.argv[1:] or ['2026']): + harvest(int(year)) diff --git a/tools/oca/harvest_saints.py b/tools/oca/harvest_saints.py new file mode 100644 index 00000000..90b5db53 --- /dev/null +++ b/tools/oca/harvest_saints.py @@ -0,0 +1,87 @@ +"""Harvest a year of OCA commemorations into data/oca_raw/saints-YYYY.json. + + python tools/oca/harvest_saints.py 2026 + +Source: https://www.oca.org/saints/lives/YYYY/MM/DD -- one page a day, each +listing the day's commemorations as
blocks with a +heading and a permalink carrying a stable numeric id: + + /saints/lives/2026/01/15/100196-venerable-paul-of-thebes + +The id is the useful part. Titles are prose and vary in wording between +sources, but the id is oca.org's own identity for that saint, so it is what to +match on when the same figure appears on two dates. + +**This is 365 requests at oca.org's requested Crawl-delay of 10 seconds -- +about an hour.** Everything is cached on disk by tools/oca/fetch.py, so it is a +one-time cost; re-runs are instant. Run it in the background. + +Saints are overwhelmingly fixed-date, so one year covers nearly all of them. +The exceptions are the movable commemorations tied to Pascha, which land on +different calendar dates each year -- do not treat a single year's harvest as a +complete census of those. +""" +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) +os.chdir(sys.path[0]) + +import datetime +import html +import json +import re + +from tools.oca.fetch import get + +ARTICLE = re.compile(r'