# Prabhupāda Says — Project Context ## What this project is A Next.js app that converts legacy RTF files containing Vedic scriptures and teachings by His Divine Grace A.C. Bhaktivedanta Swami Prabhupāda into structured, browsable content with proper Unicode Sanskrit. The original RTF files use **custom font encodings** (Indevr, ScaGoudy, Inbenr/Inbeni, RM Devanagari, Balaram, etc.) where ASCII characters map to Devanagari/Bengali glyphs and IAST diacritical marks. The extraction pipeline decodes these into proper Unicode, generates Devanagari from IAST, and stores everything in MongoDB for serving via a Next.js frontend. --- ## Tech Stack - **Next.js 16** with Turbopack, React 19, TypeScript - **Tailwind CSS v4** with `@tailwindcss/postcss` - **shadcn/ui** (base-nova style, lucide icons) — components: Button, Card, Badge, Tooltip, Input, Drawer - **next-themes** for dark/light/system mode - **vaul** for mobile drawer navigation - **Prisma v6** with MongoDB (provider `prisma-client-js`) - **MongoDB** native driver (`mongodb` package) for seeding (Prisma requires replica set for writes) - **Python 3** with BeautifulSoup4 + `indic-transliteration` for HTML extraction scripts - **Database**: MongoDB at `DATABASE_URL` env variable with `?authSource=admin` --- ## Project Structure ``` spsays-training/ ├── app/ │ ├── page.tsx → Landing page with Logo, links to Books/Essays/Journals/Glossary/Other Documents/RTFs │ ├── layout.tsx → ThemeProvider + TooltipProvider + PasswordGate wrapper │ ├── globals.css → Vintage color palette + reading settings CSS │ ├── books/ │ │ ├── page.tsx → Books index (searchable grid, diacritic-aware search) │ │ ├── books-grid.tsx → Client component for searchable book grid │ │ ├── chapter-viewer.tsx → Shared client component for verse-based books (BG/SB/CC/SB1962) │ │ ├── extracted-verse-count.tsx → (i) tooltip for verse counts │ │ ├── bg/ → Bhagavad-gītā (18 chapters, 653 verses) │ │ ├── sb/ → Śrīmad-Bhāgavatam (10 cantos, 8258 verses) │ │ ├── cc/ → Caitanya-caritāmṛta (3 līlās, 11348 verses) │ │ ├── sb1962/ → SB First Canto 1962 Edition (19 chapters, 762 verses) │ │ ├── kb/ → Kṛṣṇa Book (89 chapters, 2 volumes) │ │ ├── nod/ → The Nectar of Devotion (51 chapters, 4 parts) │ │ ├── tlc/ → Teachings of Lord Caitanya (32 chapters, 2 parts) │ │ ├── iso/ → Śrī Īśopaniṣad (18 mantras + invocation) │ │ ├── noi/ → The Nectar of Instruction (11 texts) │ │ ├── ej/ → Easy Journey to Other Planets (2 chapters) │ │ ├── ek/ → Elevation to Kṛṣṇa Consciousness (6 chapters) │ │ ├── mg/ → Kṛṣṇa Consciousness: The Matchless Gift (7 chapters) │ │ ├── bbd/ → Beyond Birth and Death (5 chapters) │ │ ├── owk/ → On the Way to Kṛṣṇa (5 chapters) │ │ ├── rv/ → Rāja-vidyā: The King of Knowledge (8 chapters) │ │ ├── poy/ → The Perfection of Yoga (11 chapters) │ │ ├── pqpa/ → Perfect Questions Perfect Answers (9 chapters) │ │ ├── ttp/ → Transcendental Teachings of Prahlāda Mahārāja (5 chapters) │ │ ├── ochkm/ → On Chanting the Hare Kṛṣṇa Mantra (4 chapters) │ │ ├── hkh/ → The Kṛṣṇa Consciousness Handbook (19 chapters) │ │ ├── ssr/ → The Science of Self-Realization (8 chapters, 50 sub-chapters) │ │ ├── ds/ → Dialectic Spiritualism (13 chapters, 36 sub-chapters) │ │ └── va/ → Vaiśiṣṭyāṣṭakam (8 chapters) │ ├── magazines/ │ │ ├── page.tsx → Magazines index page (grouped by flag: "Pre 1978") │ │ └── [slug]/ │ │ ├── page.tsx → Magazine issue listing (grouped by volume) │ │ └── [issue]/page.tsx → Individual issue reader with sidebar │ ├── letters/ │ │ ├── page.tsx → Letters index with 3-way nav (year/recipient/location) │ │ ├── letters-nav.tsx → Client component for tab navigation │ │ ├── letters-browser.tsx → Client component with search + pagination │ │ ├── [slug]/page.tsx → Individual letter reader with prev/next │ │ ├── year/[year]/page.tsx → Letters filtered by year │ │ ├── recipient/[name]/page.tsx → Letters filtered by recipient │ │ └── location/[name]/page.tsx → Letters filtered by location │ ├── essays/ │ │ ├── page.tsx → Essays grid page (searchable) │ │ ├── essays-grid.tsx → Client component for searchable essay grid │ │ └── [slug]/page.tsx → Individual essay reader │ ├── journals/ │ │ ├── page.tsx → Journals index page (grid) │ │ └── [slug]/ │ │ ├── page.tsx → Journal chapter listing (hierarchical: months → days) │ │ └── [chapter]/page.tsx → Individual journal entry reader │ ├── other-documents/ │ │ ├── page.tsx → Other documents grid page (searchable) │ │ ├── other-documents-grid.tsx → Client component for searchable grid │ │ └── [slug]/ │ │ ├── page.tsx → Document chapter listing │ │ └── [chapter]/page.tsx → Individual chapter reader │ ├── glossary/ │ │ ├── page.tsx → Server component wrapper │ │ └── glossary-client.tsx → Searchable client component (2749 entries) │ ├── rtfs/ │ │ ├── page.tsx → RTF file listing (gated by ALLOW_RTF env) │ │ └── [slug]/page.tsx → RTF iframe viewer │ └── api/ │ ├── books/ │ │ ├── route.ts → GET all book metas │ │ └── [book]/ │ │ ├── route.ts → GET single book meta │ │ └── verses/route.ts → GET verses (?chapter=&verse=&division=&indexOnly=&page=&limit=) │ ├── glossary/route.ts → GET all glossary entries │ └── verify-access/route.ts → GET (check if password enabled) + POST (validate key) ├── components/ │ ├── ui/ → shadcn components (button, card, badge, tooltip, input, drawer) │ ├── page-header.tsx → Shared header with ReadingSettings │ ├── reading-settings.tsx → Theme/font/size/justify accessibility settings panel │ ├── mobile-nav.tsx → Left-slide drawer for mobile sidebar navigation │ ├── logo.tsx → Theme-aware logo component (light/dark variants) │ ├── password-gate.tsx → Client-side password protection (runtime check) │ └── theme-provider.tsx → next-themes wrapper ├── lib/ │ ├── db.ts → Prisma client singleton │ ├── api.ts → Data access layer (getAllBooks, getBookMeta, getChapterVerses, etc.) │ ├── utils.ts → cn() helper │ ├── nod.ts → NoD data access (Prisma) │ ├── tlc.ts → TLC data access (Prisma) │ ├── iso.ts → Īśopaniṣad data access (Prisma) │ ├── noi.ts → NoI data access (Prisma) │ ├── ej.ts → Easy Journey data access (Prisma) │ ├── ek.ts → Elevation to KC data access (Prisma) │ ├── mg.ts → Matchless Gift data access (Prisma) │ ├── bbd.ts → Beyond Birth and Death data access (Prisma) │ ├── owk.ts → On the Way to Kṛṣṇa data access (Prisma) │ ├── rv.ts → Rāja-vidyā data access (Prisma) │ ├── poy.ts → Perfection of Yoga data access (Prisma) │ ├── pqpa.ts → Perfect Questions data access (Prisma) │ ├── ttp.ts → Prahlāda Mahārāja data access (Prisma) │ ├── ochkm.ts → On Chanting data access (Prisma) │ ├── hkh.ts → KC Handbook data access (Prisma) │ ├── ssr.ts → Science of Self-Realization data access (Prisma, hierarchical) │ ├── ds.ts → Dialectic Spiritualism data access (Prisma, hierarchical) │ ├── te.ts → Two Essays data access (Prisma, uses essays collection) │ ├── va.ts → Vaiśiṣṭyāṣṭakam data access (Prisma) │ ├── other-documents.ts → Other Documents data access (Prisma, dedicated collections) │ ├── journals.ts → Journals data access (Prisma, dedicated collections) │ ├── magazines.ts → Magazines data access (Prisma, dedicated collections) │ ├── letters.ts → Letters data access (Prisma, queries by year/recipient/location) │ └── jsons/books/ → Extracted JSON data (all books) │ ├── bg/, sb/, cc/, sb-1962/, kb/ → Original verse/prose books │ ├── nod/, tlc/, iso/, noi/ → Extracted from other.html │ ├── ej/, ek/, mg/, bbd/, owk/ → Small prose books │ ├── rv/, poy/, pqpa/, ttp/, ochkm/ → More prose books │ ├── hkh/, ssr/, ds/ → Large structured books │ ├── te/ → Two Essays │ ├── va/ → Vaiśiṣṭyāṣṭakam │ ├── glossary/index.json → 2,749 glossary entries │ ├── essays/ → Essay JSON files (pre-1977, cc-essays, standalone, etc.) │ ├── other-documents/ → Other document JSON files (12 documents) │ ├── journals/ → Journal JSON files (2 journals, 300 chapters) │ ├── magazines/ → Magazine JSON files (2 magazines, 59 issues) │ │ ├── btg/ → Back to Godhead (1944–1960), 29 issues │ │ └── btg-1978/ → Back to Godhead (1966–1973), 30 issues │ └── letters/ → Letter JSON files (6,866 letters, grouped by year) │ ├── index.json → Summary index (stats, top recipients/locations) │ ├── 1947.json … 1977.json → 28 year-based letter files │ └── undated.json → 58 undated letters ├── prisma/ │ └── schema.prisma → Verse, BookMeta, ProseChapter, Essay, GlossaryEntry, OtherDocumentMeta, OtherDocumentChapter, JournalMeta, JournalChapter, MagazineMeta, MagazineIssue, Letter models ├── scripts/ │ ├── bg_extract.py → BG extraction from bg.html │ ├── sb_extract.py → SB extraction from sb.html │ ├── cc_extract.py → CC extraction from cc.html │ ├── sb1962_extract.py → 1962 SB extraction │ ├── nod_extract.py → NoD extraction from other.html │ ├── tlc_extract.py → TLC extraction from other.html │ ├── iso_extract.py → Īśopaniṣad extraction from other.html │ ├── noi_extract.py → NoI extraction from other.html │ ├── ej_extract.py → Easy Journey extraction │ ├── ek_extract.py → Elevation to KC extraction │ ├── mg_extract.py → Matchless Gift extraction │ ├── bbd_extract.py → Beyond Birth and Death extraction │ ├── owk_extract.py → On the Way to Kṛṣṇa extraction │ ├── rv_extract.py → Rāja-vidyā extraction │ ├── poy_extract.py → Perfection of Yoga extraction │ ├── pqpa_extract.py → Perfect Questions extraction │ ├── ttp_extract.py → Prahlāda Mahārāja extraction │ ├── ochkm_extract.py → On Chanting extraction │ ├── hkh_extract.py → KC Handbook extraction │ ├── ssr_extract.py → Science of Self-Realization extraction (hierarchical sub-chapters) │ ├── ds_extract.py → Dialectic Spiritualism extraction (hierarchical sub-chapters) │ ├── te_extract.py → Two Essays extraction │ ├── glossary_extract.py → Glossary extraction │ ├── seed-db.ts → Main MongoDB seeder (BG, SB, CC, SB1962, KB, glossary) │ ├── seed-nod.ts … seed-ds.ts → Individual book seeders │ ├── seed-te.ts → Two Essays seeder (uses essays collection) │ ├── seed-va.ts → Vaiśiṣṭyāṣṭakam seeder │ ├── seed-pre-1977-essays.ts → Pre-1977 essays seeder (13 essays) │ ├── seed-other-documents.ts → Other documents seeder (dedicated collections) │ ├── seed-journals.ts → Journals seeder (dedicated collections) │ ├── jaladuta_diary_extract.py → Jaladuta Diary extraction (83 day entries) │ ├── the_beginning_extract.py → The Beginning extraction (189 day entries + 20 excerpts) │ ├── btg_extract.py → BTG (1944–1960) extraction from btg-1960.html │ ├── btg_1978_extract.py → BTG (1966–1973) extraction from btg-1978.html │ ├── seed-magazines.ts → Magazines seeder (dedicated collections) │ ├── letters_extract.py → Letters extraction from letters.html (6,866 letters) │ ├── seed-letters.ts → Letters seeder (per-document inserts) │ ├── kb_extract_*.py → KB extraction scripts (intro, vol1, vol2) │ ├── inject-fonts.py → Inject @font-face rules into converted HTML │ └── fix-bengali-encoding.py → Fix Bengali font encoding in cc.html └── public/ ├── rtfs/ → Original RTF files (~430MB, 17 files) ├── html/ → HTML converted from RTF (textutil + @font-face injection) ├── fonts/ → Custom TTF fonts (Balaram, ScaGoudy, Indevr, Inbenr, RM Devanagari, etc.) ├── logo_dark.png → Logo for light theme (with "says.org") ├── logo_light.png → Logo for dark theme (subtle script) └── robots.txt → Disallow all crawlers ``` --- ## Database Schema (Prisma + MongoDB) ```prisma type Synonym { word String meanings String[] } model Verse { id String @id @default(auto()) @map("_id") @db.ObjectId book String // "bg" | "sb" | "cc" | "sb1962" | "iso" | "noi" division String? // null for BG/SB1962/ISO/NOI; canto for SB; lila for CC chapter Int verse Int verseEnd Int? reference String bookTitle String devanagari String bengali String? // only CC has Bengali transliteration String synonyms Synonym[] translation String purport String[] @@unique([book, division, chapter, verse]) @@index([book]) @@index([book, division]) @@index([book, division, chapter]) @@map("verses") } model BookMeta { id String @id @default(auto()) @map("_id") @db.ObjectId book String @unique data Json @@map("book_meta") } model ProseChapter { id String @id @default(auto()) @map("_id") @db.ObjectId book String volume Int // 0 = no volumes (sentinel for non-volume books) chapter Int? // null for intro segments title String type String // "chapter" | "intro-segment" | "conclusion" slug String order Int paragraphs String[] @@unique([book, volume, slug]) @@index([book]) @@index([book, volume]) @@index([book, volume, type]) @@map("prose_chapters") } model Essay { id String @id @default(auto()) @map("_id") @db.ObjectId slug String @unique title String author String year Int? group String? // e.g., "two-essays" order Int paragraphs String[] @@index([group]) @@map("essays") } model OtherDocumentMeta { id String @id @default(auto()) @map("_id") @db.ObjectId book String @unique data Json @@map("other_document_meta") } model OtherDocumentChapter { id String @id @default(auto()) @map("_id") @db.ObjectId book String chapter Int title String type String slug String order Int paragraphs String[] @@unique([book, slug]) @@index([book]) @@map("other_document_chapters") } model JournalMeta { id String @id @default(auto()) @map("_id") @db.ObjectId book String @unique data Json @@map("journal_meta") } model JournalChapter { id String @id @default(auto()) @map("_id") @db.ObjectId book String chapter Int title String type String slug String order Int paragraphs String[] @@unique([book, slug]) @@index([book]) @@map("journal_chapters") } model MagazineMeta { id String @id @default(auto()) @map("_id") @db.ObjectId book String @unique data Json @@map("magazine_meta") } model MagazineIssue { id String @id @default(auto()) @map("_id") @db.ObjectId book String volume Int part Int title String slug String order Int paragraphs String[] paragraphsJson String? // JSON string fallback for large issues (BSON wire protocol workaround) @@unique([book, slug]) @@index([book]) @@index([book, volume]) @@map("magazine_issues") } model Letter { id String @id @default(auto()) @map("_id") @db.ObjectId slug String @unique recipients String[] // array of individual recipient names recipientDisplay String // original combined string for display date String? dateRef String? year Int? month Int? day Int? location String? salutation String? paragraphs String[] @@index([year]) @@index([recipients]) @@index([location]) @@index([year, month]) @@map("letters") } model GlossaryEntry { id String @id @default(auto()) @map("_id") @db.ObjectId term String definition String definitionHtml String @@unique([term]) @@map("glossary") } model Disciple { id String @id @default(auto()) @map("_id") @db.ObjectId initiatedName String suffix String // "Dasa" | "Devi Dasi" | "Sw" initiationDate DateTime? // 1st of the month (exact day unknown unless verified) initiationPlace String? karmiName String? // pre-initiation (birth) name avatar String? // URL to profile photo about String? // biographical notes tags String[] isVerified Boolean @default(false) @@index([initiatedName]) @@index([initiationPlace]) @@index([initiationDate]) @@index([suffix]) @@index([tags]) @@map("disciples") } ``` --- ## Disciples Collection Scraped from `https://sp.krishna.com/disciples_a` through `disciples_y` (21 letter pages; F, Q, W, X, Z have no pages). - **Total**: 4,747 disciples - **3,296** Dasa, **1,450** Devi Dasi, **1** Svāmī - **4,554** have initiation dates (month + year); **193** are missing dates - **4,703** have initiation places; **44** are missing places - Initiation dates are set to the **1st day of the month** (exact day unknown from this source) - On the UI, exact dates should only be shown when `isVerified` is `true` - `karmiName`, `avatar`, `about`, and `tags` are empty by default — intended for manual curation Data files: `data/disciples_a_b_c_d_e.json`, `data/disciples_g_to_l.json`, `data/disciples_m_n_o_p.json`, `data/disciples_r_s_t.json`, `data/disciples_u_v_y.json` Seed script: `npx tsx scripts/seed-disciples.ts` --- ## Books Extracted ### Verse-based Books (stored in `verses` collection) | Book | Code | Verses | Chapters | Division | |------|------|--------|----------|----------| | Bhagavad-gītā As It Is | `bg` | 653 | 18 | — | | Śrīmad-Bhāgavatam | `sb` | 8,258 | 213 | 10 cantos | | Śrī Caitanya-caritāmṛta | `cc` | 11,348 | 62 | 3 līlās | | SB First Canto (1962 Edition) | `sb1962` | 762 | 19 | — | | Śrī Īśopaniṣad | `iso` | 19 | — | Invocation + 18 mantras | | The Nectar of Instruction | `noi` | 11 | — | 11 texts | | Śrī Brahma-saṁhitā | `bs` | 62 | 1 (Ch. 5) | — | | Mukunda-mālā-stotra | `mm` | 6 | 1 | — | | Nārada-bhakti-sūtra | `nbs` | 8 | 1 | — | ### Prose Books (stored in `prose_chapters` collection) | Book | Code | Chapters | Source | |------|------|----------|--------| | Kṛṣṇa Book | `kb` | 89 (2 volumes) | other.html | | The Nectar of Devotion | `nod` | 51 (4 parts) | other.html | | Teachings of Lord Caitanya | `tlc` | 32 (2 parts) | other.html (1968 ed., plain English) | | Easy Journey to Other Planets | `ej` | 2 | other.html | | Elevation to Kṛṣṇa Consciousness | `ek` | 6 | other.html | | Kṛṣṇa Consciousness: The Matchless Gift | `mg` | 7 | other.html | | Beyond Birth and Death | `bbd` | 5 | other.html | | On the Way to Kṛṣṇa | `owk` | 5 | other.html | | Rāja-vidyā: The King of Knowledge | `rv` | 8 | other.html | | The Perfection of Yoga | `poy` | 11 | other.html | | Perfect Questions Perfect Answers | `pqpa` | 9 | other.html | | Transcendental Teachings of Prahlāda Mahārāja | `ttp` | 5 | other.html | | On Chanting the Hare Kṛṣṇa Mantra | `ochkm` | 4 | other.html | | The Kṛṣṇa Consciousness Handbook | `hkh` | 19 | other.html | | The Science of Self-Realization | `ssr` | 50 sub-chapters (8 parents) | other.html | | Dialectic Spiritualism | `ds` | 36 sub-chapters (13 parents) | other.html | | Life Comes from Life | `lcl` | 16 | other.html | | Light of the Bhāgavata | `lob` | 48 | other.html | | Teachings of Lord Kapila | `tlk` | 18 | other.html | | Teachings of Queen Kuntī | `tqk` | 26 | other.html | | Gītār Gān | `gg` | 18 | other.html (Bengali poetic BG) | | Songs of the Vaiṣṇava Ācāryas | `sva` | 67 songs (4 parts, hierarchical) | other.html | | Message of Godhead | `mog` | 3 | others-before-1977.html | | Śrī Caitanya-bhāgavata Commentary | `cbhc` | 4 | others-before-1977.html | | Bhagavāner Kathā | `bk` | 2 | others-before-1977.html (ScaGoudy) | | Prayers of King Kulaśekhara (1958) | `pk` | 6 | others-before-1977.html | | Vaiśiṣṭyāṣṭakam | `va` | 8 | others-before-1977.html | ### Essays (stored in `essays` collection) | Essay | Slug | Group | Year | |-------|------|-------|------| | Krishna The Reservoir Of Pleasure | `krishna-reservoir-of-pleasure` | `two-essays` | 1966 | | Who Is Crazy? | `who-is-crazy` | `two-essays` | 1966 | | The Spiritual Masters | `the-spiritual-masters` | `cc-essays` | 1960 | | The Absolute Truth | `the-absolute-truth` | `cc-essays` | 1957 | | The Causes of Lord Caitanya's Incarnation | `causes-of-lord-caitanyas-incarnation` | `cc-essays` | 1957 | | The Confidential Reasons for Lord Caitanya's Appearance | `confidential-reasons-for-lord-caitanyas-appearance` | `cc-essays` | 1957 | | The Glories of Lord Nityānanda | `glories-of-lord-nityananda` | `cc-essays` | 1957 | | Man Is the Architect of His Own Fortune | `man-is-the-architect-of-his-own-fortune` | `pre-1977-essays` | — | | What Is the Matter with the World? | `what-is-the-matter-with-the-world` | `pre-1977-essays` | 1957 | | Religion Is Godly Life | `religion-is-godly-life` | `pre-1977-essays` | — | | Truth and Beauty | `truth-and-beauty` | `pre-1977-essays` | 1958 | | Misuse of Public Fund in the Name of Religion | `misuse-of-public-fund-in-the-name-of-religion` | `pre-1977-essays` | 1958 | | Perfection at Home | `perfection-at-home` | `pre-1977-essays` | — | | How Should One Cultivate Human Spirit | `how-should-one-cultivate-human-spirit` | `pre-1977-essays` | 1961 | | Viswa Dharma | `viswa-dharma` | `pre-1977-essays` | — | | Glorification of Śrīla Bhaktisiddhānta Sarasvatī Ṭhākura | `glorification-of-srila-bhaktisiddhanta-sarasvati-thakura` | `pre-1977-essays` | 1952 | | Who Is Crazy? (Back to Godhead #66) | `who-is-crazy-btg66` | `pre-1977-essays` | — | | Manifestation of Dharma in Human Being | `manifestation-of-dharma-in-human-being` | `pre-1977-essays` | 1972 | | Message of Krishna Consciousness | `message-of-krishna-consciousness` | `pre-1977-essays` | 1972 | | A Wrong Civilization | `a-wrong-civilization` | `pre-1977-essays` | 1936 | | Vedānta-sūtra (Typed Transcript) | `vedanta-sutra-typed` | `typed-transcripts` | 1969 | | Shaktipujah | `shaktipujah` | `reviews` | — | | Devotee and the Divinity | `devotee-and-the-divinity` | `standalone` | — | ### Other Documents (stored in `other_document_meta` + `other_document_chapters` collections) | Document | Code | Chapters | |----------|------|----------| | An Analysis of Bhagwat Geeta | `analysis-bg` | 3 | | Solution of Present Crisis by Bhagwat Geeta | `solution-crisis` | 4 | | Śrī Caitanya Mahāprabhu | `sri-caitanya` | 3 | | Conception of Geeta Nagari on the Principles of Gandhi | `geeta-nagari` | 1 | | The Real Peace Formula | `real-peace-formula` | 3 | | International Institution for God Consciousness | `intl-institution-god-consciousness` | 1 | | "Srimad Bhawatam" India's Message of Peace and Goodwill | `srimad-bhawatam-message` | 1 | | Viraha Aṣṭaka | `viraha-astaka` | 8 | | Vṛndāvana Bhajana | `vrndavana-bhajana` | 1 | | Prayer unto the Lotus Feet of Kṛṣṇa | `prayer-unto-lotus-feet-of-krsna` | 1 | | Märkine Bhägavata-dharma | `markine-bhagavata-dharma` | 1 | | Jaladuta Pamphlet | `jaladuta-pamphlet` | 1 | ### Journals (stored in `journal_meta` + `journal_chapters` collections) | Journal | Code | Chapters | Structure | |---------|------|----------|-----------| | The Jaladuta Diary, 1965 | `jaladuta-diary` | 85 | Preface, Introduction, 83 day entries grouped by month (Apr–Nov 1965) | | The Beginning — The 1966 New York Journal | `the-beginning` | 215 | Introduction, 3 place-based chapters with day entries, Memoranda, Epilogue, 20 Excerpts | ### Magazines (stored in `magazine_meta` + `magazine_issues` collections) | Magazine | Code | Issues | Articles | Flag | Source | |----------|------|--------|----------|------|--------| | Back to Godhead (1944–1960) | `btg` | 29 | 89 | Pre 1978 | btg-1960.html | | Back to Godhead (1966–1973) | `btg-1978` | 30 | 1,035 | Pre 1978 | btg-1978.html | ### Letters (stored in `letters` collection) | Metric | Value | |--------|-------| | Total letters | 6,866 | | Unique recipients (individual) | 2,243 | | Unique locations | 164 | | Year range | 1947–1977 | | Total paragraphs | 52,261 | **Top recipients**: Satsvarupa (182), Brahmananda (168), Hansadutta (117), Tamala Krsna (115), Gurudasa (103), Mukunda (105), Madhudvisa (90), Karandhara (90) **Top locations**: Los Angeles (1,392), Bombay (1,086), Vrindaban (532), Mayapur (305), London (264), Calcutta (250), Honolulu (239) **Schema notes**: - `recipients` is an array of individual names (e.g., `["Mukunda", "Janaki"]`) - `recipientDisplay` is the original combined string (e.g., `"Mukunda, Janaki"`) - Searching for a recipient uses Prisma `{ has: name }` to match any letter where that person appears - Multi-recipient groups are split by `,`, `;`, ` and `, ` & ` - Trailing punctuation (`:`, `,`, `.`) cleaned from names ### Other | Content | Collection | |---------|-----------| | Glossary (2,749 entries) | `glossary` | --- ## Font Encoding System ### ScaGoudy → IAST mapping (used in BG, SB, CC, ISO, NOI, NoD, and most 1969+ books) ``` ä→ā Ä→Ā å→ṛ Å→Ṛ ñ→ṣ Ñ→Ṣ ö→ṭ Ö→Ṭ ë→ṇ Ë→Ṇ ò→ḍ Ò→Ḍ ç→ś Ç→Ś ì→ṅ ï→ñ ü→ū Ü→Ū é→ī É→Ī à→ṁ ù→ḥ è→ṝ û→ṁl ÿ→ḷ ``` ### Bengali fonts (Inbenr/Inbeni in CC) Custom-encoded fonts where ASCII codepoints render as Bengali script. Fixed by `fix-bengali-encoding.py`. ### RM Devanagari font (used in ISO, NOI) Custom-encoded Devanagari font (p51 CSS class). The text appears as garbled ASCII without the font. **Skipped during extraction** — Unicode Devanagari is generated from IAST transliteration instead. ### Devanagari generation IAST transliteration → Devanagari via `indic-transliteration` library. Key fixes: - `join_virama_words()` — joins virāma + consonant AND virāma + vowel - `normalize_devanagari_anusvara()` — ङ् → ं before velars, ञ् → ं before palatals ### Books without ScaGoudy encoding - **TLC (1968 Edition)** — plain English transliterations ("Krishna" not "Kṛṣṇa") - **Two Essays (1966)** — plain English - **GG (Gītār Gān)** — Bengali poetic text (ScaGoudy decoded for transliteration) - **LCL (Life Comes from Life)** — dialogue book, ScaGoudy decoded - **MOG, CBHC, PK** — pre-1977 handwritten documents, plain English - **BK (Bhagavāner Kathā)** — pre-1977, uses ScaGoudy encoding - **CC Essays, Vedānta-sūtra transcript** — plain English - All other books from other.html use ScaGoudy encoding --- ## Book Types and URL Patterns ### Verse-based books (use ChapterViewer client component) | Route Pattern | Books | |---------------|-------| | `/books/bg/[chapter]/[verse]` | BG | | `/books/sb/[canto]/[chapter]/[verse]` | SB | | `/books/cc/[lila]/[chapter]/[verse]` | CC | | `/books/sb1962/[chapter]/[verse]` | SB1962 | | `/books/iso/[mantra]` | Īśopaniṣad (verse + intro segments) | | `/books/noi/[text]` | Nectar of Instruction (verse + intro segments) | | `/books/bs/[chapter]/[verse]` | Brahma-saṁhitā (chapter 5, 62 verses) | | `/books/mm/[chapter]/[verse]` | Mukunda-mālā-stotra (6 mantras) | | `/books/nbs/[chapter]/[verse]` | Nārada-bhakti-sūtra (8 sūtras) | ### Prose books (use per-book data layers + reading pages) | Route Pattern | Books | |---------------|-------| | `/books/kb/[volume]/[slug]` | Kṛṣṇa Book | | `/books/{code}/[chapter]` | NoD, TLC, EJ, EK, MG, BBD, OWK, RV, POY, PQPA, TTP, OCHKM, HKH, LCL, LOB, TLK, TQK, GG, MOG, CBHC, BK, PK | ### Hierarchical prose books (sub-chapters as separate pages) | Route Pattern | Books | |---------------|-------| | `/books/ssr/[chapter]` | Science of Self-Realization (slugs: "1-1", "1-2", "intro-foreword", etc.) | | `/books/ds/[chapter]` | Dialectic Spiritualism (slugs: "1-1" = Socrates, "1-2" = Plato, etc.) | | `/books/sva/[chapter]` | Songs of the Vaiṣṇava Ācāryas (slugs: "1-1" = Śrī Guru Praṇāma, etc.) | ### Essays | Route | Content | |-------|---------| | `/essays` | Searchable essay grid (23 essays across 6 groups) | | `/essays/[slug]` | Individual essay reader | ### Other Documents | Route | Content | |-------|---------| | `/other-documents` | Searchable other documents grid (12 documents) | | `/other-documents/[slug]` | Document index (chapter listing) | | `/other-documents/[slug]/[chapter]` | Individual chapter reader | ### Journals | Route | Content | |-------|---------| | `/journals` | Journals index (grid) | | `/journals/[slug]` | Journal chapter listing (hierarchical: place → month → day) | | `/journals/[slug]/[chapter]` | Individual journal entry reader (slug-based, e.g., `apr-3`, `sep-17`, `excerpt-...`) | ### Magazines | Route | Content | |-------|---------| | `/magazines` | Magazines index (grouped by flag: "Pre 1978 Editions") | | `/magazines/[slug]` | Magazine issue listing (grouped by volume) | | `/magazines/[slug]/[issue]` | Individual issue reader (slug-based, e.g., `v1-p1`, `no-17`) | ### Letters | Route | Content | |-------|---------| | `/letters` | Letters index with 3-way navigation tabs | | `/letters?view=year` | Year grid (1947–1977) with search | | `/letters?view=recipient` | Recipient list (2,243 individuals) with search + pagination | | `/letters?view=location` | Location grid (164 locations) with search + pagination | | `/letters/year/1968` | All letters from a specific year | | `/letters/recipient/Mukunda` | All letters to/including a specific recipient | | `/letters/location/Los%20Angeles` | All letters from a specific location | | `/letters/[slug]` | Individual letter reader with prev/next navigation | ### Other routes | Route | Content | |-------|---------| | `/` | Landing page (responsive 3-column grid) | | `/books` | Searchable book grid | | `/glossary` | Searchable glossary (2,749 entries) | | `/journals` | Journals (2 journals, 300 chapters) | | `/magazines` | Magazines (2 magazines, 59 issues, Pre 1978) | | `/letters` | Letters (6,866 letters, 3-way navigation) | | `/rtfs` | RTF viewer (gated by ALLOW_RTF=true) | | `/api/verify-access` | Password protection endpoint | --- ## Volume Convention Books without volumes use `volume: 0` as a sentinel value in the `prose_chapters` collection. This satisfies the Prisma schema's `@@unique([book, volume, slug])` constraint without requiring schema changes. - KB uses `volume: 1` and `volume: 2` - All other prose books use `volume: 0` --- ## Hierarchical Books (SSR, DS) SSR and DS have parent chapters with sub-chapters stored as individual `prose_chapters` docs: - Sub-chapter slugs: `"1-1"`, `"1-2"`, `"2-1"`, etc. - Parent chapter info stored in `intro.json` metadata: ```json { "chapters": [ { "number": 1, "title": "Learning the Science of the Soul", "subChapters": [ { "slug": "1-1", "title": "Seeing the Aim of Human Life" }, { "slug": "1-2", "title": "Your Original Consciousness Is Kṛṣṇa Consciousness" } ] } ] } ``` - Sidebar UI shows parent headings (non-clickable) with sub-chapters indented below - Prev/next navigation skips parent headings --- ## UI Features ### Reading Settings (accessibility) - **Theme**: Light / Dark / System toggle - **Serif Font**: Toggle to switch reading content to Georgia/serif - **Font Size**: Slider (XS → XXL) using CSS `zoom` on `main` and `aside` - **Justify Text**: Toggle for justified text alignment on reading content - Settings persist in `localStorage` under `spsays_reading_prefs` - Applied via CSS classes on `` element ### Mobile Navigation - Left-slide drawer (vaul) triggered by a menu button next to the Previous button - Only visible below `lg` breakpoint - Shows the full sidebar navigation grouped by section - Implemented in all 24+ reader pages via shared `MobileNav` component ### Search - Books page: diacritic-aware search (typing "Krsna" matches "Kṛṣṇa") - Glossary page: full-text search across terms and definitions - Uses Unicode NFD normalization + manual IAST character stripping ### Color Palette - **Light mode ("Aged Parchment")**: Warm cream backgrounds, deep sepia text, saffron/ochre primary - **Dark mode ("Ancient Manuscript")**: Deep warm brown backgrounds, parchment text, golden saffron primary ### Password Protection - Client-side gate component (`PasswordGate`) wrapping the entire app - Runtime check via `GET /api/verify-access` (checks if `ACCESS_KEY` env var is set) - Validation via `POST /api/verify-access` (compares submitted key) - Stores valid key in `sessionStorage` - Bypassed when `ACCESS_KEY` is not set --- ## Environment Variables ``` DATABASE_URL=mongodb://user:pass@host:port/spsays?authSource=admin ALLOW_RTF=true # optional — enables RTF viewer routes ACCESS_KEY="secret" # optional — enables password protection (quote if contains #) ``` --- ## How to Run ```bash # Development npm run dev # Prisma npx prisma generate # Regenerate Prisma client after schema changes # Extraction scripts (Python 3 + beautifulsoup4 + indic-transliteration) python3 scripts/bg_extract.py # Extract BG python3 scripts/sb_extract.py # Extract SB python3 scripts/cc_extract.py # Extract CC python3 scripts/nod_extract.py # Extract NoD from other.html python3 scripts/iso_extract.py # Extract Īśopaniṣad from other.html python3 scripts/ssr_extract.py # Extract SSR from other.html python3 scripts/ds_extract.py # Extract DS from other.html # ... (similar for all other books) # Database seeding npx tsx scripts/seed-db.ts # Seed BG, SB, CC, SB1962, KB, glossary npx tsx scripts/seed-nod.ts # Seed NoD npx tsx scripts/seed-iso.ts # Seed Īśopaniṣad npx tsx scripts/seed-te.ts # Seed Two Essays # ... (similar for all other books) # Build npx next build ``` --- ## Verse JSON Schema (BG/SB/CC/SB1962/ISO/NOI) ```json { "book_title": "Śrīmad-Bhāgavatam", "canto": 1, "chapter": 1, "verse": 1, "verse_end": null, "reference": "SB 1.1.1", "devanagari": "ॐ नमो भगवते वासुदेवाय\nजन्माद्यस्य यतो ...", "bengali": null, "transliteration": "om namo bhagavate vāsudevāya\njanmādy asya yato ...", "synonyms": [ { "word": "om", "meanings": ["O my Lord"] }, { "word": "namaḥ", "meanings": ["offering my obeisances"] } ], "translation": "I offer my obeisances unto Lord Śrī Kṛṣṇa...", "purport": ["paragraph 1...", "paragraph 2..."] } ``` ## Prose Chapter JSON Schema ```json { "book": "ek", "chapter": 1, "title": "Choosing Human and Animal Lives", "type": "chapter", "paragraphs": ["heading", "body text...", "