diff --git a/src/data/propers/common/holy-innocents-antiphon.yml b/src/data/propers/common/holy-innocents-antiphon.yml new file mode 100644 index 0000000..bd017e4 --- /dev/null +++ b/src/data/propers/common/holy-innocents-antiphon.yml @@ -0,0 +1,9 @@ +# Verified against Divinum Officium (Latin/English Sancti/12-28.txt's own +# [Ant 1] — the Lauds-hour antiphon, not Terce's. +id: holy-innocents-antiphon +text: + la: "Hi sunt, * qui cum muliéribus non sunt coinquináti: vírgines enim sunt, et sequúntur Agnum quocúmque íerit." + en: "These are they * who were not defiled with women; for they are virgins, and follow the Lamb whithersoever he goeth." +status: + la: verified + en: verified diff --git a/src/data/propers/common/holy-innocents-collect.yml b/src/data/propers/common/holy-innocents-collect.yml new file mode 100644 index 0000000..bee6c67 --- /dev/null +++ b/src/data/propers/common/holy-innocents-collect.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — read +# directly from the reference engine's own real-date output (2026-12-28). +id: holy-innocents-collect +text: + la: | + Orémus. + Deus, cujus hodiérna die præcónium Innocéntes Mártyres non loquéndo, sed moriéndo conféssi sunt: ómnia in nobis vitiórum mala mortífica; ut fidem tuam, quam lingua nostra lóquitur, étiam móribus vita fateátur. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + O God, whose praise the martyred Innocents on this day confessed, not by speaking, but by dying, destroy all the evils of sin in us, that our life also may proclaim in deeds, thy faith which our tongues profess. + Through Jesus Christ, thy Son our Lord, Who liveth and reigneth with thee, in the unity of the Holy Ghost, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/immaculate-conception-collect.yml b/src/data/propers/common/immaculate-conception-collect.yml new file mode 100644 index 0000000..4e12577 --- /dev/null +++ b/src/data/propers/common/immaculate-conception-collect.yml @@ -0,0 +1,25 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — Latin +# read from the live prayTertia query's own real-date output (2025-12-08); +# its English side rendered a *different* Marian feast's text by mistake +# (same class of query glitch as All Saints/St. Damasus this pull, just +# silent instead of empty, and caught only by cross-checking against the +# raw source file directly), so the English was read from +# web/www/horas/English/Sancti/12-08.txt instead. Its own closing formula +# ("$Per eumdem", not the standard "$Per Dominum") is expanded to this +# project's standard closing form for consistency, same convention used +# throughout. +id: immaculate-conception-collect +text: + la: | + Orémus. + Deus, qui per immaculátam Vírginis Conceptiónem dignum Fílio tuo habitáculum præparásti: quǽsumus; ut qui ex morte ejúsdem Fílii tui prævísa, eam ab omni labe præservásti, nos quoque mundos ejus intercessióne ad te perveníre concédas. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + O God, by the Immaculate Conception of the Virgin, thou prepared a worthy habitation for thy Son; we beseech thee, that, as by the foreseen death of thy same Son thou preserved her from all stain of sin, so thou would grant us also, through her intercession, to come to thee with pure hearts. + Through Jesus Christ, thy Son our Lord, Who liveth and reigneth with thee, in the unity of the Holy Ghost, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-bibiana-collect.yml b/src/data/propers/common/st-bibiana-collect.yml new file mode 100644 index 0000000..7d0ad48 --- /dev/null +++ b/src/data/propers/common/st-bibiana-collect.yml @@ -0,0 +1,20 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — Latin +# read from the live prayTertia query's own real-date output (2025-12-02); +# its English side didn't render an Oratio translation (same gap as All +# Saints and St. Damasus this pull), so the English was read directly from +# the raw source file (web/www/horas/English/Sancti/12-02.txt) instead. +id: st-bibiana-collect +text: + la: | + Orémus. + Deus, ómnium largítor bonórum, qui in fámula tua Bibiána cum virginitátis flore martýrii palmam conjunxísti: mentes nostras ejus intercessióne tibi caritáte conjúnge; ut, amótis perículis, prǽmia consequámur ætérna. + Qui vivis et regnas cum Deo Patre, in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + O God, the Giver of all good gifts, Who unto the lily of pure maidenhood in the hand of thy servant Bibiana, didst join the palm of a glorious martyrdom, grant us, we beseech thee, at her pleading, that our hearts and minds being joined to thee by thy love, we may escape all dangers which do presently beset us, and finally attain unto thine everlasting joy. + Who livest and reignest with God the Father, in the unity of the Holy Spirit, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-damasus-collect.yml b/src/data/propers/common/st-damasus-collect.yml new file mode 100644 index 0000000..ed6c9bf --- /dev/null +++ b/src/data/propers/common/st-damasus-collect.yml @@ -0,0 +1,16 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) -- Latin +# read directly from the reference engine's own real-date output +# (2025-12-11). No English translation exists in this reference project at +# all (checked both the live query and the raw English Sancti/12-11.txt +# file directly -- only the biographical Lectios are translated, not the +# Oratio), so en is left honestly missing rather than translated here. +id: st-damasus-collect +text: + la: | + Orémus. + Exáudi, Dómine, preces nostras: et interveniénte beáto Dámaso Confessóre tuo atque Pontífice, indulgéntiam nobis tríbue placátus et pacem. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. +status: + la: verified + en: missing diff --git a/src/data/propers/common/st-john-apostle-antiphon.yml b/src/data/propers/common/st-john-apostle-antiphon.yml new file mode 100644 index 0000000..750add6 --- /dev/null +++ b/src/data/propers/common/st-john-apostle-antiphon.yml @@ -0,0 +1,9 @@ +# Verified against Divinum Officium (Latin/English Sancti/12-27.txt's own +# [Ant 1] — the Lauds-hour antiphon, not Terce's. +id: st-john-apostle-antiphon +text: + la: "Iste est Joánnes, * qui supra pectus Dómini in cena recúbuit: beátus Apóstolus, cui reveláta sunt secréta cæléstia." + en: "This is John * who leaned at supper on the bosom of the Lord. Blessed Apostle, to whom heavenly secrets were revealed." +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-john-apostle-collect.yml b/src/data/propers/common/st-john-apostle-collect.yml new file mode 100644 index 0000000..1f2557e --- /dev/null +++ b/src/data/propers/common/st-john-apostle-collect.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — read +# directly from the reference engine's own real-date output (2025-12-27). +id: st-john-apostle-collect +text: + la: | + Orémus. + Ecclésiam tuam, Dómine, benígnus illústra: ut beáti Joánnis Apóstoli tui et Evangelístæ, illumináta doctrínis, ad dona pervéniat sempitérna. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + Shine upon thy Church, O Lord, in thy goodness, that, enlightened by the teachings of Blessed John, thy Apostle and Evangelist, she may attain to everlasting gifts. + Through Jesus Christ, thy Son our Lord, Who liveth and reigneth with thee, in the unity of the Holy Ghost, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-lucy-antiphon.yml b/src/data/propers/common/st-lucy-antiphon.yml new file mode 100644 index 0000000..dd60312 --- /dev/null +++ b/src/data/propers/common/st-lucy-antiphon.yml @@ -0,0 +1,9 @@ +# Verified against Divinum Officium (Latin/English Sancti/12-13.txt's own +# [Ant 1] — the Lauds-hour antiphon, not Terce's. +id: st-lucy-antiphon +text: + la: "In tua patiéntia * possedísti ánimam tuam, Lúcia, sponsa Christi: odísti quæ in mundo sunt, et coruscas cum Angelis: sánguine proprio inimícum vicisti." + en: "In patience * hast thou possessed thy soul, Lucy, Bride of Christ thou hast hated the things that are in the world, and art glorified among the Angels; thou hast shed thine own blood, and conquered the Adversary." +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-nicholas-collect.yml b/src/data/propers/common/st-nicholas-collect.yml new file mode 100644 index 0000000..ee8faf7 --- /dev/null +++ b/src/data/propers/common/st-nicholas-collect.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — read +# directly from the reference engine's own real-date output (2025-12-06). +id: st-nicholas-collect +text: + la: | + Orémus. + Deus, qui beátum Nicoláum Pontíficem innúmeris decorásti miráculis: tríbue, quǽsumus; ut ejus méritis et précibus a gehénnæ incéndiis liberémur. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + O God, who didst glorify the blessed Bishop Nicholas with innumerable miracles; grant, we beseech thee, that, by his merits and prayers, we may be saved from the fires of hell. + Through Jesus Christ, thy Son our Lord, Who liveth and reigneth with thee, in the unity of the Holy Ghost, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-stephen-protomartyr-antiphon.yml b/src/data/propers/common/st-stephen-protomartyr-antiphon.yml new file mode 100644 index 0000000..5445c44 --- /dev/null +++ b/src/data/propers/common/st-stephen-protomartyr-antiphon.yml @@ -0,0 +1,11 @@ +# Verified against Divinum Officium (Latin/English Sancti/12-26.txt's own +# [Ant 1] — the Lauds-hour antiphon, not Terce's, and this feast's own +# canonical source for the same text duplicated (unmodified) at +# finding-of-st-stephen-antiphon.yml (Aug 3). +id: st-stephen-protomartyr-antiphon +text: + la: "Stéphanus autem * plenus grátia et fortitúdine, faciébat signa magna in pópulo." + en: "And Stephen, full of grace * and fortitude, did great signs among the people." +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-stephen-protomartyr-collect.yml b/src/data/propers/common/st-stephen-protomartyr-collect.yml new file mode 100644 index 0000000..6bd2039 --- /dev/null +++ b/src/data/propers/common/st-stephen-protomartyr-collect.yml @@ -0,0 +1,21 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — read +# directly from the reference engine's own real-date output (2025-12-26). +# Nearly identical wording to finding-of-st-stephen-collect.yml (Aug 3, +# which cross-references this feast's text with one word substituted) -- +# this is that substitution's own source text, given here in full rather +# than as a reference, per this project's one-file-per-id convention. +id: st-stephen-protomartyr-collect +text: + la: | + Orémus. + Da nobis, quǽsumus, Dómine, imitári quod cólimus: ut discámus et inimícos dilígere; quia ejus natalícia celebrámus, qui novit étiam pro persecutóribus exoráre Dóminum nostrum Jesum Christum Fílium tuum: + Qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + Grant us, we beseech thee, O Lord, so to imitate what we revere, that we may learn to love even our enemies; for we celebrate the heavenly birthday of him who knew how to pray for his very persecutors to our Lord Jesus Christ: + Who with thee liveth and reigneth, in the unity of the Holy Spirit, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-thomas-apostle-antiphon.yml b/src/data/propers/common/st-thomas-apostle-antiphon.yml new file mode 100644 index 0000000..426ab0b --- /dev/null +++ b/src/data/propers/common/st-thomas-apostle-antiphon.yml @@ -0,0 +1,9 @@ +# Verified against Divinum Officium (Latin/English Sancti/12-21.txt's own +# [Ant 1] — the Lauds-hour antiphon, not Terce's. +id: st-thomas-apostle-antiphon +text: + la: "Quia vidísti me * Thoma, credidísti: beáti qui non vidérunt, et credidérunt, allelúja." + en: "Because thou hast seen me, * Thomas, thou hast believed: blessed are they that have not seen and have believed, alleluia." +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-thomas-apostle-collect.yml b/src/data/propers/common/st-thomas-apostle-collect.yml new file mode 100644 index 0000000..3a9061f --- /dev/null +++ b/src/data/propers/common/st-thomas-apostle-collect.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — read +# directly from the reference engine's own real-date output (2026-12-21). +id: st-thomas-apostle-collect +text: + la: | + Orémus. + Da nobis, quǽsumus, Dómine, beáti Apóstoli tui Thomæ solemnitátibus gloriári: ut ejus semper et patrocíniis sublevémur; et fidem cóngrua devotióne sectémur. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + Grant us, Lord, we beseech thee, to glory in the solemnity of thy blessed Apostle Thomas, that we may ever be aided by his patronage, and follow his faith with true devotion. + Through Jesus Christ, thy Son our Lord, Who liveth and reigneth with thee, in the unity of the Holy Ghost, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/src/data/propers/common/st-thomas-becket-collect.yml b/src/data/propers/common/st-thomas-becket-collect.yml new file mode 100644 index 0000000..d7fd90f --- /dev/null +++ b/src/data/propers/common/st-thomas-becket-collect.yml @@ -0,0 +1,17 @@ +# Verified against Divinum Officium (Monastic Tridentinum 1617) — read +# directly from the reference engine's own real-date output (2025-12-29). +id: st-thomas-becket-collect +text: + la: | + Orémus. + Deus, pro cujus Ecclésia gloriósus Póntifex Thomas gládiis impiórum occúbuit: præsta, quǽsumus; ut omnes, qui ejus implórant auxílium, petitiónis suæ salutárem consequántur efféctum. + Per Dóminum nostrum Jesum Christum, Fílium tuum: qui tecum vivit et regnat in unitáte Spíritus Sancti, Deus, per ómnia sǽcula sæculórum. + ℟. Amen. + en: | + Let us pray. + O God, in defence of Whose Church the glorious Bishop Thomas fell by the swords of wicked men, grant, we beseech thee, that all that ask his help, may obtain wholesome fruit of their petition. + Through Jesus Christ, thy Son our Lord, Who liveth and reigneth with thee, in the unity of the Holy Ghost, God, world without end. + ℟. Amen. +status: + la: verified + en: verified diff --git a/tests/calendar/december-sanctoral.test.ts b/tests/calendar/december-sanctoral.test.ts new file mode 100644 index 0000000..9057cd9 --- /dev/null +++ b/tests/calendar/december-sanctoral.test.ts @@ -0,0 +1,95 @@ +import { describe, expect, it } from 'vitest'; +import { resolveDay } from '../../src/calendar'; +import { getDayCollect } from '../../src/hours/resolve-common'; + +// Clean per-annum years for these dates (no Sunday collision) — see +// data/calendar/saints/*.yml for per-saint source detail. +describe('December sanctoral pull (first pass, 12/12)', () => { + it('a Simplex saint on an ordinary Advent feria is only ever commemorated, the feria itself staying primary', () => { + const day = resolveDay('2025-12-02'); + expect(day.winner.kind).toBe('temporal'); + expect(day.commemorations).toEqual([ + { kind: 'sanctoral', id: 'st-bibiana', name: 'St. Bibiana, Virgin and Martyr', rank: 'simplex' }, + ]); + // The feria wins, so the day's collect is the governing Sunday's own + // (already authored), not St. Bibiana's (which has none) -- the + // commemoration is real but doesn't change which collect is prayed. + expect(getDayCollect(day).status.en).toBe('verified'); + }); + + it('a Semiduplex saint wins outright over an ordinary Advent feria, which is commemorated in return, with a real proper collect', () => { + const day = resolveDay('2025-12-06'); + expect(day.winner).toEqual({ + kind: 'sanctoral', + id: 'st-nicholas', + name: 'St. Nicholas, Bishop and Confessor', + rank: 'semiduplex', + }); + expect(day.commemorations.length).toBe(1); + expect(day.commemorations[0]?.kind).toBe('temporal'); + expect(getDayCollect(day).status.en).toBe('verified'); + }); + + it('the Immaculate Conception wins outright with a real proper collect and antiphon, backfilled this month', () => { + const day = resolveDay('2025-12-08'); + expect(day.winner).toEqual({ + kind: 'sanctoral', + id: 'immaculate-conception', + name: 'The Immaculate Conception of the Blessed Virgin Mary', + rank: 'duplex-1-classis', + }); + expect(getDayCollect(day).status.en).toBe('verified'); + }); + + it('St. Thomas the Apostle wins outright with a real proper collect and antiphon, distinct from his own Vigil on Advent Ember Saturday', () => { + const day = resolveDay('2026-12-21'); + expect(day.winner).toEqual({ + kind: 'sanctoral', + id: 'st-thomas-apostle', + name: 'St. Thomas, Apostle', + rank: 'duplex-2-classis', + }); + expect(getDayCollect(day).status.en).toBe('verified'); + }); + + it('the Christmas Octave "Comites Christi" days each win outright with real propers, the Octave day commemorated in return', () => { + const stephen = resolveDay('2025-12-26'); + const john = resolveDay('2025-12-27'); + const innocents = resolveDay('2026-12-28'); + expect(stephen.winner).toEqual({ + kind: 'sanctoral', + id: 'st-stephen-protomartyr', + name: 'St. Stephen, Protomartyr', + rank: 'duplex-2-classis', + }); + expect(john.winner).toEqual({ + kind: 'sanctoral', + id: 'st-john-apostle', + name: 'St. John, Apostle and Evangelist', + rank: 'duplex-2-classis', + }); + expect(innocents.winner).toEqual({ + kind: 'sanctoral', + id: 'holy-innocents', + name: 'The Holy Innocents, Martyrs', + rank: 'duplex-2-classis', + }); + for (const day of [stephen, john, innocents]) { + expect(day.commemorations.length).toBe(1); + expect(day.commemorations[0]?.kind).toBe('temporal'); + expect(getDayCollect(day).status.en).toBe('verified'); + } + }); + + it('St. Thomas of Canterbury, only Semiduplex, still wins outright within the Christmas Octave -- the concrete case behind this month\'s temporal-category fix', () => { + const day = resolveDay('2025-12-29'); + expect(day.winner).toEqual({ + kind: 'sanctoral', + id: 'st-thomas-becket', + name: 'St. Thomas of Canterbury, Bishop and Martyr', + rank: 'semiduplex', + }); + expect(day.commemorations.length).toBe(1); + expect(day.commemorations[0]?.kind).toBe('temporal'); + }); +});