@ugfoundation/swaralipi-js 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +347 -0
  2. package/README.md +257 -0
  3. package/dist/batch-NF2Q2CFS.js +47 -0
  4. package/dist/batch-NF2Q2CFS.js.map +1 -0
  5. package/dist/chunk-C6O7DYU5.js +115 -0
  6. package/dist/chunk-C6O7DYU5.js.map +1 -0
  7. package/dist/chunk-GWXI2HJA.js +14 -0
  8. package/dist/chunk-GWXI2HJA.js.map +1 -0
  9. package/dist/chunk-N3NNWAOW.js +593 -0
  10. package/dist/chunk-N3NNWAOW.js.map +1 -0
  11. package/dist/cli.cjs +913 -0
  12. package/dist/cli.cjs.map +1 -0
  13. package/dist/cli.d.cts +1 -0
  14. package/dist/cli.d.ts +1 -0
  15. package/dist/cli.js +91 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/convert/index.cjs +720 -0
  18. package/dist/convert/index.cjs.map +1 -0
  19. package/dist/convert/index.d.cts +270 -0
  20. package/dist/convert/index.d.ts +270 -0
  21. package/dist/convert/index.js +5 -0
  22. package/dist/convert/index.js.map +1 -0
  23. package/dist/index.cjs +143 -0
  24. package/dist/index.cjs.map +1 -0
  25. package/dist/index.d.cts +4 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.js +4 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/player/index.cjs +775 -0
  30. package/dist/player/index.cjs.map +1 -0
  31. package/dist/player/index.d.cts +285 -0
  32. package/dist/player/index.d.ts +285 -0
  33. package/dist/player/index.js +743 -0
  34. package/dist/player/index.js.map +1 -0
  35. package/dist/schema-gxhG45OK.d.cts +467 -0
  36. package/dist/schema-gxhG45OK.d.ts +467 -0
  37. package/dist/spec/index.cjs +143 -0
  38. package/dist/spec/index.cjs.map +1 -0
  39. package/dist/spec/index.d.cts +70 -0
  40. package/dist/spec/index.d.ts +70 -0
  41. package/dist/spec/index.js +4 -0
  42. package/dist/spec/index.js.map +1 -0
  43. package/dist/taals-DguYW0wf.d.cts +60 -0
  44. package/dist/taals-DguYW0wf.d.ts +60 -0
  45. package/dist/viewer/index.cjs +998 -0
  46. package/dist/viewer/index.cjs.map +1 -0
  47. package/dist/viewer/index.d.cts +285 -0
  48. package/dist/viewer/index.d.ts +285 -0
  49. package/dist/viewer/index.js +814 -0
  50. package/dist/viewer/index.js.map +1 -0
  51. package/package.json +93 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/convert/codec.ts","../src/convert/grid.ts","../src/convert/taal-map.ts","../src/convert/assemble.ts","../src/convert/extract.ts","../src/convert/report.ts","../src/convert/index.ts"],"names":[],"mappings":"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","file":"chunk-N3NNWAOW.js","sourcesContent":["/**\n * The Swarabitan ASCII codec: decode one grid-cell text into spec `Note`s.\n *\n * NLTR renders notation through the legacy \"Swarabitan\" webfont, which maps\n * ASCII to akarmatrik glyphs. The table below was derived by dumping every\n * glyph of `Swarabitan.woff` (tools/font-dump/) and cross-checking against\n * the Swarabitan legend scans, the rendered reference screenshot of song\n * 4270, and corpus-wide token statistics. Evidence per assignment:\n *\n * Letters (full-size glyphs):\n * s=স r=র g=গ m=ম p=প q=ধ n=ন — the seven shuddha letters\n * d=দ (komal dha) t=জ্ঞ (komal ga) — legend: কোমল র—ঋ, কোমল গ—জ্ঞ,\n * k=ক্ষ (tivra ma) u=ণ (komal ni) — কড়ি ম—ক্ষ, কোমল ধ—দ, কোমল ন—ণ\n * v=ঋ (komal re)\n * Modifiers:\n * f = রেফ above → taar octave (zero-width high combining mark)\n * h = হসন্ত below → mandra octave (low combining mark; corpus nh/uh/dh/ph)\n * leading '-' = no new vowel attack (melisma; lyric row shows ৹)\n * trailing 'a' = the আ-কার matra carrier; k letter-units in one cell\n * share it → k notes of 1/k matra each\n * UPPERCASE letter = small raised form = কণ (kan/grace) prefix; takes its\n * own f/h (corpus: Sfua, NHsa, QHpha); width ratios ~0.65\n * confirm uppercase↔lowercase pairing\n * Structurals (own cells):\n * A = thin full-height bar → দাঁড়ি vibhag separator (fixed columns)\n * l = serif danda I → cycle end; ll / single-glyph L = section\n * %=সা &=নি — precomposed one-matra forms (rare)\n * Known-but-kept-raw marks (drawn pieces the spec doesn't model yet):\n * w x = left/right ends of a long under-arc; E J j y $ < > = _ = arc/line\n * fill segments; | = thin yugal-dari stop mark (mostly annotation rows);\n * digits/!/@ (+f/F sam tick) = taal beat labels; b=× o O e ` + , . i : ;\n * = dots/ticks/duration marks; B C * ^ ~ c = rare precomposed/legacy forms.\n *\n * Decoding never throws: any chunk outside the grammar becomes a raw-only\n * note and is reported as unknown — zero data loss by construction.\n */\nimport type { Note, Octave, Svara, SvaraLetter } from '../spec/index.js';\n\nexport interface CellDecode {\n notes: Note[];\n /** Chunks that failed the grammar (reported, kept as raw notes). */\n unknownTokens: string[];\n /** Chunks understood but intentionally left raw (marks, beat labels …). */\n knownRawTokens: string[];\n /** True if at least one chunk decoded to a semantic note. */\n decoded: boolean;\n}\n\ninterface LetterDef {\n letter: SvaraLetter;\n komal?: true;\n tivra?: true;\n}\n\n/** ASCII → svara letter (+ komal/tivra). The five non-shuddha glyph letters\n * are distinct characters in akarmatrik, so the flags live here. */\nconst LETTERS: Record<string, LetterDef> = {\n s: { letter: 's' },\n r: { letter: 'r' },\n g: { letter: 'g' },\n m: { letter: 'm' },\n p: { letter: 'p' },\n q: { letter: 'd' }, // ধ — shuddha dha\n n: { letter: 'n' },\n d: { letter: 'd', komal: true }, // দ\n t: { letter: 'g', komal: true }, // জ্ঞ\n k: { letter: 'm', tivra: true }, // ক্ষ\n u: { letter: 'n', komal: true }, // ণ\n v: { letter: 'r', komal: true }, // ঋ\n};\n\n/** Standalone structural tokens (bars are handled by the bar-run rule). */\nconst STRUCTURALS: Record<string, () => Note> = {\n '%': () => ({ svara: ['madhyam', 's'] }), // precomposed সা\n '&': () => ({ svara: ['madhyam', 'n'] }), // precomposed নি\n};\n\n/**\n * Bar/bracket runs: `l`(I danda) `ll`/`L`(II) `llll`/`LL`(IIII) `A`(দাঁড়ি),\n * plus composites the corpus writes into one cell — `l[]l` / `L[]L` (the\n * legend's \"I [ ] I\" return-to-asthayi-with-changed-notes marker), `AA`,\n * and `-A` (the previous note's continuation dash sharing the dari's cell).\n */\nconst BAR_RUN_RE = /^(-)?([lLA[\\]]+)$/;\n\nfunction decodeBarRun(body: string): Note[] | undefined {\n const m = body.match(BAR_RUN_RE);\n if (!m || !/[lLA]/.test(m[2]!)) return undefined;\n const notes: Note[] = [];\n if (m[1]) notes.push({ sustain: true });\n const run = m[2]!;\n let i = 0;\n while (i < run.length) {\n const ch = run[i]!;\n if (ch === 'l' || ch === 'L') {\n let j = i;\n while (j < run.length && run[j] === ch) j++;\n const strokes = (j - i) * (ch === 'L' ? 2 : 1);\n notes.push({ bar: strokes >= 4 ? 'quad' : strokes >= 2 ? 'double' : 'single' });\n i = j;\n } else if (ch === 'A') {\n notes.push({ bar: 'dari' });\n i++;\n } else {\n notes.push({ brackets: [{ kind: 'alt', edge: ch === '[' ? 'open' : 'close' }] });\n i++;\n }\n }\n return notes;\n}\n\n/** Marks/labels that are understood but deliberately preserved raw-only. */\nconst KNOWN_RAW_RE = [\n /^[wxyjEJ$<>=_]+$/, // arc & line drawing segments\n /^\\|+$/, // thin yugal-dari stop mark\n /^[0-9!@#]{1,2}[fF]?:?$/, // beat-number labels incl. 10–16 (sam tick = f/F, e.g. 1f / 1F / 2:)\n /^[oOe`+,.;:iI~^*bcBCWXYFHZz'\"?]$/, // dots, ticks, duration marks, legacy forms\n];\n\nconst OPEN_BRACKETS: Record<string, 'repeat' | 'skip' | 'alt'> = {\n '{': 'repeat',\n '(': 'skip',\n '[': 'alt',\n};\nconst CLOSE_BRACKETS: Record<string, 'repeat' | 'skip' | 'alt'> = {\n '}': 'repeat',\n ')': 'skip',\n ']': 'alt',\n};\n\nfunction octaveOf(mark: string | undefined): Octave {\n if (mark === 'f' || mark === 'F') return 'taar';\n if (mark === 'h' || mark === 'H') return 'mandra';\n return 'madhyam';\n}\n\n/**\n * Body grammar of one chunk (brackets already peeled):\n *\n * [beat-digit] ['-'] [KAN] unit* ['a'] [fh] [i:] [KAN] [beat-digit]\n *\n * where unit = letter [fh] and KAN = uppercase letter [fFhH]. Corpus\n * realities beyond the canonical `[-]KAN unit+ a` shape:\n * - octave mark typed after the আ-কার: `saf` ≡ `sfa` (taar sa) — the reph\n * applies to the last unit;\n * - trailing `i` (two stacked rings, ঃ-shaped — the ছেদ/cut mark) or `:`\n * after the matra: an articulation mark; the note decodes normally and\n * the mark stays visible in `raw`;\n * - trailing KAN (`-aR`): an anticipatory grace drawn at the cell's right\n * edge, leading into the next note — attached to this cell's last note;\n * - the cut mark may also lead or sit between units (`-iqi`, `mpimi`);\n * - leading `z` = blank spacer glyph (empty outline in the font) — skipped.\n * A standalone detached `a` (no hyphen) is a 1-matra rest per the legend\n * (\"হাইফেন-বর্জিত … বিরামের মাত্রা\").\n */\nconst BODY_RE =\n /^([0-9!@][fF]?)?([zj]*)(-)?([i:])?(?:([SRGMPQNDTKUV])([fFhH])?)?((?:[srgmpqndtkuv][fh]?[i:]?)+)?(a)?([fh])?([i:])?(?:([SRGMPQNDTKUV])([fFhH])?)?([0-9!@][fF]?)?(-)?$/;\n\nfunction decodeChunk(chunk: string): { notes: Note[]; kind: 'decoded' | 'known' | 'unknown' } {\n // 1. Peel brackets.\n const opens: ('repeat' | 'skip' | 'alt')[] = [];\n const closes: ('repeat' | 'skip' | 'alt')[] = [];\n let body = chunk;\n while (body.length > 0) {\n const kind = OPEN_BRACKETS[body[0]!];\n if (kind === undefined) break;\n opens.push(kind);\n body = body.slice(1);\n }\n while (body.length > 0) {\n const kind = CLOSE_BRACKETS[body[body.length - 1]!];\n if (kind === undefined) break;\n closes.unshift(kind);\n body = body.slice(0, -1);\n }\n\n const finish = (notes: Note[], kind: 'decoded' | 'known' | 'unknown') => {\n if (notes.length === 0) notes.push({});\n const first = notes[0]!;\n const last = notes[notes.length - 1]!;\n if (opens.length > 0) first.brackets = [...opens.map((kind_) => ({ kind: kind_, edge: 'open' as const })), ...(first.brackets ?? [])];\n if (closes.length > 0) last.brackets = [...(last.brackets ?? []), ...closes.map((kind_) => ({ kind: kind_, edge: 'close' as const }))];\n return { notes, kind };\n };\n\n // 2. Bracket-only chunk → raw carrier for the bracket edges.\n if (body === '') return finish([{}], 'decoded');\n\n // 3. Bar/bracket runs, then the remaining standalone structurals.\n const barRun = decodeBarRun(body);\n if (barRun) return finish(barRun, 'decoded');\n const structural = STRUCTURALS[body];\n if (structural) return finish([structural()], 'decoded');\n\n // 4. Known raw marks.\n if (KNOWN_RAW_RE.some((re) => re.test(body))) return finish([{}], 'known');\n\n // 5. Note grammar.\n const m = body.match(BODY_RE);\n if (m) {\n const [, , , hyphen, , kanLetter, kanOct, unitsStr, aakar, postOct, , trailKan, trailKanOct] = m;\n const attachKan = (note: Note, letter: string, oct: string | undefined) => {\n const def = LETTERS[letter.toLowerCase()]!;\n // NOTE: the spec kan is a plain [octave, letter] tuple, so a komal\n // kan letter (e.g. D = small দ) is projected onto its shuddha\n // letter; the exact glyph stays recoverable from `raw`.\n note.kan = [octaveOf(oct?.toLowerCase()), def.letter] as Svara;\n };\n if (unitsStr) {\n const units = unitsStr.match(/[srgmpqndtkuv][fh]?/g) ?? [];\n const notes: Note[] = units.map((unit) => {\n const def = LETTERS[unit[0]!]!;\n const note: Note = { svara: [octaveOf(unit[1]), def.letter] as Svara };\n if (def.komal) note.komal = true;\n if (def.tivra) note.tivra = true;\n if (units.length > 1) note.durationMatra = 1 / units.length;\n return note;\n });\n const last = notes[notes.length - 1]!;\n // Post-আকার octave mark (`saf`): applies to the last unit unless it\n // already carries its own mark.\n if (postOct && last.svara![0] === 'madhyam') {\n last.svara = [octaveOf(postOct), last.svara![1]] as Svara;\n }\n if (hyphen) notes[0]!.sustain = true;\n if (kanLetter) attachKan(notes[0]!, kanLetter, kanOct);\n if (trailKan && last.kan === undefined) attachKan(last, trailKan, trailKanOct);\n return finish(notes, 'decoded');\n }\n if (aakar) {\n // '-a' = sustain (hold previous pitch, no new attack);\n // bare detached 'a' = one-matra rest (legend: hyphen-less matra sign).\n const note: Note = hyphen ? { sustain: true } : { rest: true };\n if (trailKan) attachKan(note, trailKan, trailKanOct);\n else if (kanLetter) attachKan(note, kanLetter, kanOct);\n return finish([note], 'decoded');\n }\n if (hyphen && !kanLetter && !trailKan) {\n // A bare continuation dash (`-`, `-i`) — the আ-কার is implied.\n return finish([{ sustain: true }], 'decoded');\n }\n // Kan without units, or digit-edges with no note between — keep raw.\n }\n\n return finish([{}], 'unknown');\n}\n\n/**\n * Decode one cell's text. Multi-chunk cells (whitespace-separated) emit\n * notes in order; the first note of each chunk carries that chunk's source\n * text in `raw`, so joining a cell's `raw` values with spaces reproduces\n * the normalized cell text (the lossless property tests rely on this).\n */\nexport function decodeCell(text: string): CellDecode {\n const chunks = text.split(/\\s+/).filter((c) => c.length > 0);\n const out: CellDecode = { notes: [], unknownTokens: [], knownRawTokens: [], decoded: false };\n for (const chunk of chunks) {\n const { notes, kind } = decodeChunk(chunk);\n notes[0]!.raw = chunk;\n if (kind === 'decoded') out.decoded = true;\n else if (kind === 'known') out.knownRawTokens.push(chunk);\n else out.unknownTokens.push(chunk);\n out.notes.push(...notes);\n }\n return out;\n}\n","/**\n * Grid → systems.\n *\n * Rows group into 4-row \"systems\", role given by `row % 4` (verified with\n * zero exceptions across the whole corpus):\n * 0 → annotation row rendered ABOVE the staff (alt-on-repeat passages,\n * stop marks, beat numbers — sparse),\n * 1 → notation row (style1, Swarabitan codes),\n * 2 → annotation row rendered BELOW the staff (sparse),\n * 3 → lyric row (style2, Bengali).\n * Cells align across the four rows strictly by column id (rows can be\n * ragged, so never align by index).\n */\nimport type { NltrPage } from './extract.js';\n\nexport interface System {\n /** System index (source rows 4k..4k+3). */\n index: number;\n above: Map<number, string>;\n notation: Map<number, string>;\n below: Map<number, string>;\n lyric: Map<number, string>;\n maxCol: number;\n}\n\nconst ROLES = ['above', 'notation', 'below', 'lyric'] as const;\n\nexport function buildSystems(page: NltrPage): { systems: System[]; warnings: string[] } {\n const warnings: string[] = [];\n const byIndex = new Map<number, System>();\n let styleMismatches = 0;\n\n for (const cell of page.cells) {\n if (cell.text === '') continue;\n const role = ROLES[cell.row % 4]!;\n // Notation/annotation rows are style1, lyric rows style2 — corpus-wide\n // invariant. A mismatch is recorded but the row role (from row % 4) wins.\n const expected = role === 'lyric' ? 'style2' : 'style1';\n if (cell.style !== expected) styleMismatches++;\n\n const index = Math.floor(cell.row / 4);\n let system = byIndex.get(index);\n if (!system) {\n system = {\n index,\n above: new Map(),\n notation: new Map(),\n below: new Map(),\n lyric: new Map(),\n maxCol: 0,\n };\n byIndex.set(index, system);\n }\n system[role].set(cell.col, cell.text);\n if (cell.col > system.maxCol) system.maxCol = cell.col;\n }\n\n if (styleMismatches > 0) {\n warnings.push(`${styleMismatches} cell(s) had an unexpected style class for their row role`);\n }\n\n // Keep source order; drop systems with no content at all (trailing blank\n // systems are common).\n const systems = [...byIndex.values()].sort((a, b) => a.index - b.index);\n return { systems, warnings };\n}\n","/**\n * Resolve the printed Bengali তাল name (+ the grid's own geometry) into a\n * spec `Taal`.\n *\n * Evidence chain, strongest first:\n * 1. bhaag hints in the name itself — `ধামার(৩/২/২/৩/৪)` → [3,2,2,3,4];\n * 2. the name table below (the 7 player-sampled taals from TAALS, plus\n * well-attested Rabindrik taals with stable definitions);\n * 3. the grid geometry: bar/dari columns partition each cycle into bhaags\n * (`numCols = avartan × (numBeats + nDaris) + 1` held on every checked\n * song), which both derives unknown taals and cross-checks named ones.\n * তালমুক্ত (free rhythm) and unresolvable names yield no `taal`; the\n * verbatim name always lands in `meta.taalName`.\n */\nimport { TAALS, type Taal } from '../spec/index.js';\nimport type { System } from './grid.js';\n\nconst BN_DIGIT_MAP: Record<string, string> = {\n '০': '0',\n '১': '1',\n '২': '2',\n '৩': '3',\n '৪': '4',\n '৫': '5',\n '৬': '6',\n '৭': '7',\n '৮': '8',\n '৯': '9',\n};\n\n/** Parse an integer written with Bengali or ASCII digits. */\nexport function bnInt(s: string | undefined): number | undefined {\n if (s === undefined) return undefined;\n const ascii = s.trim().replace(/[০-৯]/g, (d) => BN_DIGIT_MAP[d] ?? d);\n return /^\\d+$/.test(ascii) ? Number(ascii) : undefined;\n}\n\n/** Names mapping straight onto the 7 player-sampled TAALS ids. */\nconst BN_TAAL_MAP: Record<string, keyof typeof TAALS> = {\n দাদরা: 'dadra',\n কাহারবা: 'kehrwa',\n একতালা: 'ektaal',\n একতাল: 'ektaal',\n তিনতালা: 'teentaal',\n ত্রিতাল: 'teentaal',\n ঝাঁপতাল: 'jhaptaal',\n ঝাঁপ: 'jhaptaal',\n রুপক: 'rupak',\n রূপক: 'rupak',\n আড়াচৌতাল: 'adachautaal',\n};\n\n/** Long-tail taals with stable textbook definitions (ids transliterated). */\nconst BN_TAAL_DEFS: Record<string, Taal> = {\n তেওড়া: { id: 'teora', numBeats: 7, bhaags: [3, 2, 2], sam: 0 },\n তেওরা: { id: 'teora', numBeats: 7, bhaags: [3, 2, 2], sam: 0 },\n ঝম্পক: { id: 'jhampak', numBeats: 5, bhaags: [3, 2], sam: 0 },\n ষষ্ঠী: { id: 'shashthi', numBeats: 6, bhaags: [2, 4], sam: 0 },\n রুপকড়া: { id: 'rupakda', numBeats: 8, bhaags: [3, 2, 3], sam: 0 },\n রূপকড়া: { id: 'rupakda', numBeats: 8, bhaags: [3, 2, 3], sam: 0 },\n নবতাল: { id: 'nabataal', numBeats: 9, bhaags: [5, 4], sam: 0 },\n একাদশী: { id: 'ekadashi', numBeats: 11, bhaags: [3, 4, 4], sam: 0 },\n নবপঞ্চ: { id: 'nabapancha', numBeats: 18, bhaags: [2, 4, 4, 4, 4], sam: 0 },\n ধামার: { id: 'dhamar', numBeats: 14, bhaags: [3, 2, 2, 3, 4], sam: 0 },\n চৌতাল: { id: 'choutaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0 },\n সুরফাঁক: { id: 'surphank', numBeats: 10, sam: 0 },\n};\n\n/**\n * Readable ids for the remaining census names whose beat count varies by\n * song (or isn't well-attested) — numBeats comes from hints/geometry only.\n */\nconst BN_TAAL_IDS: Record<string, string> = {\n কাওয়ালি: 'kawali',\n খেমটা: 'khemta',\n আড়াঠেকা: 'araatheka',\n কাশ্মীরি: 'kashmiri',\n যৎ: 'yat',\n মধ্যমান: 'madhyaman',\n অর্দ্ধঝাঁপ: 'ardhajhanp',\n অর্ধঝাঁপ: 'ardhajhanp',\n 'বিলম্বিত ত্রিতাল': 'vilambit-teentaal',\n};\n\n/** Free-rhythm marker — never resolves to a taal. */\nconst TAAL_FREE = 'তালমুক্ত';\n\nexport interface GridGeometry {\n /** Total columns of the widest full notation row. */\n numCols: number;\n /** Matra count of one cycle (notes between cycle bars, daris excluded). */\n numBeats?: number;\n /** Bhaag division of one cycle, from dari positions. */\n bhaags?: number[];\n}\n\n/** Bar-class tokens (cycle/section dandas) and the vibhag dari. */\nconst BAR_TOKENS = new Set(['l', 'll', 'lll', 'llll', 'L', 'LL', '|']);\nconst DARI_TOKEN = 'A';\n\n/**\n * Derive cycle geometry from the first notation row shaped `bar … bar`.\n * Returns per-cycle numBeats/bhaags when at least one full cycle is visible.\n */\nexport function deriveGeometry(systems: System[]): GridGeometry | undefined {\n let numCols = 0;\n for (const system of systems) {\n if (system.notation.size === 0) continue;\n const cols = [...system.notation.keys()].sort((a, b) => a - b);\n numCols = Math.max(numCols, cols.length);\n const barCols = cols.filter((c) => BAR_TOKENS.has(system.notation.get(c)!));\n if (barCols.length < 2) continue;\n // First full cycle: between the first two bar columns.\n const from = barCols[0]!;\n const to = barCols[1]!;\n const inner = cols.filter((c) => c > from && c < to);\n if (inner.length === 0) continue;\n const bhaags: number[] = [];\n let run = 0;\n for (const c of inner) {\n if (system.notation.get(c) === DARI_TOKEN) {\n if (run > 0) bhaags.push(run);\n run = 0;\n } else {\n run++;\n }\n }\n if (run > 0) bhaags.push(run);\n const numBeats = bhaags.reduce((a, b) => a + b, 0);\n if (numBeats === 0) continue;\n return { numCols: cols.length, numBeats, bhaags: bhaags.length > 1 ? bhaags : undefined };\n }\n return numCols > 0 ? { numCols } : undefined;\n}\n\nexport interface ResolvedTaal {\n taal?: Taal;\n taalName?: string;\n avartan?: number;\n /** Which evidence resolved the taal. */\n matched: 'taals' | 'table' | 'geometry' | 'none';\n warnings: string[];\n}\n\nexport function resolveTaal(\n nameRaw: string | undefined,\n avartanRaw: string | undefined,\n geometry: GridGeometry | undefined,\n): ResolvedTaal {\n const warnings: string[] = [];\n const avartan = bnInt(avartanRaw);\n const taalName = nameRaw?.trim() || undefined;\n\n if (!taalName || taalName === TAAL_FREE) {\n return { taalName, avartan, matched: 'none', warnings };\n }\n\n // 1. Split `name(৩/২/…)` into base name + bhaag hint.\n const parenMatch = taalName.match(/^(.*?)\\s*\\(([০-৯\\d/\\s]+)\\)\\s*$/);\n const base = (parenMatch ? parenMatch[1]! : taalName).trim();\n let hintBhaags: number[] | undefined;\n if (parenMatch) {\n const parts = parenMatch[2]!.split('/').map((p) => bnInt(p));\n if (parts.every((p): p is number => p !== undefined) && parts.length > 0) {\n hintBhaags = parts;\n }\n }\n // `অখন্ড ৬ মাত্রা` — \"unbroken N matra\".\n const akhandaMatch = base.match(/^অখন্ড\\s+([০-৯\\d]+)\\s*মাত্রা$/);\n\n // 2. Name lookup.\n let taal: Taal | undefined;\n let matched: ResolvedTaal['matched'] = 'none';\n const mappedId = BN_TAAL_MAP[base];\n if (mappedId) {\n taal = { ...TAALS[mappedId] };\n matched = 'taals';\n } else if (BN_TAAL_DEFS[base]) {\n taal = { ...BN_TAAL_DEFS[base] };\n matched = 'table';\n } else if (akhandaMatch) {\n const beats = bnInt(akhandaMatch[1]);\n if (beats) {\n taal = { id: `akhanda-${beats}`, numBeats: beats, sam: 0 };\n matched = 'table';\n }\n }\n\n // 3. Reconcile with the source's own declaration. A parens hint is part\n // of the printed taal name, so it overrides the table; grid geometry is\n // our own derivation and only ever warns against a name-resolved taal.\n const hintBeats = hintBhaags?.reduce((a, b) => a + b, 0);\n if (taal) {\n if (hintBeats !== undefined && hintBeats !== taal.numBeats) {\n warnings.push(\n `taal ${taal.id}: name declares ${hintBeats} beats (${hintBhaags!.join('/')}), table says ${taal.numBeats} — using the name's`,\n );\n taal = { id: taal.id, numBeats: hintBeats, sam: 0 };\n if (hintBhaags!.length > 1) taal.bhaags = hintBhaags;\n } else if (hintBhaags && hintBhaags.length > 1) {\n const tableBhaags = taal.bhaags?.join('/');\n if (tableBhaags && tableBhaags !== hintBhaags.join('/')) {\n warnings.push(\n `taal ${taal.id}: name declares bhaags ${hintBhaags.join('/')}, table says ${tableBhaags} — using the name's`,\n );\n const { khaali: _khaali, ...rest } = taal;\n taal = { ...rest, bhaags: hintBhaags };\n }\n }\n } else if (hintBeats !== undefined || geometry?.numBeats !== undefined) {\n const evidenceBeats = (hintBeats ?? geometry?.numBeats)!;\n const evidenceBhaags = hintBhaags ?? geometry?.bhaags;\n // 4. Unknown name — derive entirely from evidence; keep a readable id\n // (transliteration table, else the Bengali name itself — ids are free-form).\n taal = { id: BN_TAAL_IDS[base] ?? base, numBeats: evidenceBeats, sam: 0 };\n if (evidenceBhaags && evidenceBhaags.length > 1) taal.bhaags = evidenceBhaags;\n matched = 'geometry';\n } else {\n warnings.push(`unresolved taal name: ${taalName}`);\n }\n\n // Geometry cross-check for table-resolved taals.\n if (taal && geometry?.numBeats !== undefined && geometry.numBeats !== taal.numBeats) {\n warnings.push(\n `grid geometry says ${geometry.numBeats} beats per cycle but taal ${taal.id} has ${taal.numBeats}`,\n );\n }\n\n return { taal, taalName, avartan, matched, warnings };\n}\n","/**\n * Assembly: systems → spec document.\n *\n * Each system becomes one `Row`. Within a row, columns are walked in order;\n * a notation cell's decoded notes join the row, with the column-aligned\n * lyric / above / below content attached to the cell's first note. Columns\n * that have lyric or annotation content but no notation emit a carrier note\n * (legal per the spec refine). The whole song is one unnamed part: NLTR\n * prints no section labels, and `ll` cannot be split on safely because it\n * also marks mid-song asthayi returns.\n */\nimport { SPEC_VERSION, swaralipiSchema, type Meta, type Note, type Row, type Swaralipi } from '../spec/index.js';\nimport { decodeCell } from './codec.js';\nimport type { NltrPage } from './extract.js';\nimport { buildSystems } from './grid.js';\nimport { deriveGeometry, resolveTaal } from './taal-map.js';\nimport type { FileReport } from './report.js';\n\nexport interface ConvertOptions {\n /** NLTR song/node id (usually the source filename). */\n nltrId?: number;\n /** Override the provenance URL stored in `meta.source`. */\n source?: string;\n}\n\nexport interface ConvertResult {\n doc: Swaralipi;\n report: FileReport;\n}\n\nconst segmenter = new Intl.Segmenter('bn', { granularity: 'grapheme' });\n\n/** Split a lyric cell into grapheme clusters (ক+া = 1, র+্ = 1, ৹ = 1). */\nexport function splitLyric(text: string): string[] {\n return [...segmenter.segment(text)].map((s) => s.segment);\n}\n\nexport function assemble(page: NltrPage, opts: ConvertOptions = {}): ConvertResult {\n const { systems, warnings } = buildSystems(page);\n const geometry = deriveGeometry(systems);\n const resolved = resolveTaal(page.header.taalNameRaw, page.header.avartanRaw, geometry);\n warnings.push(...resolved.warnings);\n\n const report: FileReport = {\n nltrId: opts.nltrId,\n title: page.header.title ?? '',\n taalName: resolved.taalName,\n taalId: resolved.taal?.id,\n taalMatched: resolved.matched,\n systems: 0,\n notationCells: 0,\n lyricCells: 0,\n annotationCells: 0,\n decodedCells: 0,\n knownRawCells: 0,\n unknownCells: 0,\n unknownTokens: {},\n lyricAlignMismatches: 0,\n warnings,\n };\n const countUnknown = (tokens: string[]) => {\n for (const t of tokens) report.unknownTokens[t] = (report.unknownTokens[t] ?? 0) + 1;\n };\n\n const rows: Row[] = [];\n for (const system of systems) {\n const notes: Note[] = [];\n for (let col = 0; col <= system.maxCol; col++) {\n const notationText = system.notation.get(col);\n const lyricText = system.lyric.get(col);\n const aboveText = system.above.get(col);\n const belowText = system.below.get(col);\n if (\n notationText === undefined &&\n lyricText === undefined &&\n aboveText === undefined &&\n belowText === undefined\n ) {\n continue;\n }\n\n let cellNotes: Note[];\n if (notationText !== undefined) {\n report.notationCells++;\n const decode = decodeCell(notationText);\n countUnknown(decode.unknownTokens);\n if (decode.unknownTokens.length > 0) report.unknownCells++;\n else if (decode.decoded) report.decodedCells++;\n else report.knownRawCells++;\n cellNotes = decode.notes;\n } else {\n cellNotes = [{}]; // carrier for lyric/annotation on an empty column\n }\n\n if (lyricText !== undefined) {\n report.lyricCells++;\n attachLyric(cellNotes, lyricText, report);\n }\n if (aboveText !== undefined) {\n report.annotationCells++;\n const decode = decodeCell(aboveText);\n countUnknown(decode.unknownTokens);\n cellNotes[0]!.above = decode.notes;\n }\n if (belowText !== undefined) {\n report.annotationCells++;\n const decode = decodeCell(belowText);\n countUnknown(decode.unknownTokens);\n cellNotes[0]!.below = decode.notes;\n }\n notes.push(...cellNotes);\n }\n if (notes.length > 0) {\n rows.push({ notes });\n report.systems++;\n }\n }\n\n const meta: Meta = { title: page.header.title ?? `NLTR ${opts.nltrId ?? 'song'}` };\n if (opts.nltrId !== undefined) meta.nltrId = opts.nltrId;\n if (resolved.taal) meta.taal = resolved.taal;\n if (resolved.taalName) meta.taalName = resolved.taalName;\n if (resolved.avartan !== undefined) meta.avartan = resolved.avartan;\n const source =\n opts.source ??\n (opts.nltrId !== undefined\n ? `https://rabindra-rachanabali.nltr.org/node/${opts.nltrId}`\n : page.header.printId !== undefined\n ? `https://rabindra-rachanabali.nltr.org/node/${page.header.printId}`\n : undefined);\n if (source) meta.source = source;\n\n // Validate against the spec before returning — an assembler bug must fail\n // the file, never emit an invalid document.\n const doc = swaralipiSchema.parse({ version: SPEC_VERSION, meta, parts: [{ rows }] });\n return { doc, report };\n}\n\n/**\n * Attach a lyric cell to its notation cell's notes. When the grapheme\n * cluster count matches the cell's note count the sub-syllables map 1:1\n * (e.g. `অ৹` onto the two notes of `nsfa`); otherwise the whole string\n * lands on the first note (never invent splits).\n */\nfunction attachLyric(cellNotes: Note[], lyricText: string, report: FileReport): void {\n if (cellNotes.length > 1) {\n const clusters = splitLyric(lyricText);\n if (clusters.length === cellNotes.length) {\n clusters.forEach((cluster, i) => {\n cellNotes[i]!.lyric = cluster;\n });\n return;\n }\n report.lyricAlignMismatches++;\n }\n cellNotes[0]!.lyric = lyricText;\n}\n","/**\n * NLTR HTML extraction — the lowest layer of the converter.\n *\n * The 1,738 cached NLTR pages are machine-generated and 100% structurally\n * uniform (verified across all 2.79M cells), so extraction is deliberately\n * a strict regex parse with a count assertion rather than a lenient DOM\n * walk: any structural surprise fails the file loudly (`ExtractError`)\n * instead of silently mis-treeing.\n *\n * Page anatomy:\n * - a metadata table of `style3` triples: label (নাম / তাল / আবর্তন), ':',\n * value;\n * - one grid of cells `<td width='auto' id=R.C> <span class='styleN'>\n * <div align='center'>TOKEN</div></span></td>` where `id` is the\n * `row.col` coordinate (often unquoted) and `&nbsp;` marks an empty cell.\n */\n\n/** One grid cell. `text` is entity-decoded and whitespace-normalized ('' = empty). */\nexport interface RawCell {\n row: number;\n col: number;\n /** `style1` = Swarabitan notation, `style2` = Bengali lyric. */\n style: string;\n text: string;\n}\n\n/** The style3 metadata header values, verbatim (Bengali). */\nexport interface NltrHeader {\n title?: string;\n taalNameRaw?: string;\n avartanRaw?: string;\n /** NLTR's internal print node id (`/print/<id>`), for provenance. */\n printId?: number;\n}\n\nexport interface NltrPage {\n header: NltrHeader;\n cells: RawCell[];\n maxRow: number;\n}\n\n/** Structural surprise in the source HTML (not a decode problem). */\nexport class ExtractError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ExtractError';\n }\n}\n\nconst NAMED_ENTITIES: Record<string, string> = {\n nbsp: ' ',\n amp: '&',\n lt: '<',\n gt: '>',\n quot: '\"',\n apos: \"'\",\n};\n\n/** Decode the handful of entities NLTR emits (named + numeric). */\nexport function decodeEntities(s: string): string {\n return s.replace(/&(?:#x([0-9a-fA-F]+)|#(\\d+)|([a-zA-Z]+));/g, (m, hex, dec, name) => {\n if (hex) return String.fromCodePoint(parseInt(hex, 16));\n if (dec) return String.fromCodePoint(parseInt(dec, 10));\n return NAMED_ENTITIES[name] ?? m;\n });\n}\n\n/**\n * Normalize cell text: decode entities, drop format/control characters\n * (U+200E etc. occur in lyric cells), collapse whitespace (incl. NBSP),\n * and canonicalize to NFC (NLTR mixes precomposed/decomposed forms of\n * ড়/ঢ়/য়; NFC settles both on the decomposed form since these are\n * composition exclusions).\n */\nfunction normalizeCellText(s: string): string {\n return decodeEntities(s)\n .replace(/\\p{Cf}/gu, '')\n .replace(/[\\s ]+/gu, ' ')\n .trim()\n .normalize('NFC');\n}\n\n// Cell alignment is center except for arc end-pieces (w/x), which NLTR\n// emits with align='right'/'left' so they visually join the neighbor cell.\nconst CELL_RE =\n /<td width='auto' id=[\"']?(\\d+)\\.(\\d+)[\"']?\\s*>\\s*<span class='(style\\d)'><div align='(?:center|left|right)'>([\\s\\S]*?)<\\/div><\\/span><\\/td>/g;\n\nconst META_ROW_RE =\n /<tr><td><div align='left'><span class='style3'>([^<]*)<\\/span><\\/div><\\/td><td><div align='left'><span class='style3'>:<\\/span><\\/div><\\/td><td><div align='left'><span class='style3'>([^<]*)<\\/span><\\/div><\\/td><\\/tr>/g;\n\n/** Parse one NLTR swaralipi page. Throws `ExtractError` on structural surprise. */\nexport function extractPage(html: string): NltrPage {\n const header: NltrHeader = {};\n for (const m of html.matchAll(META_ROW_RE)) {\n const label = normalizeCellText(m[1]!);\n const value = normalizeCellText(m[2]!);\n if (label === 'নাম') header.title = value;\n else if (label === 'তাল') header.taalNameRaw = value;\n else if (label === 'আবর্তন') header.avartanRaw = value;\n }\n const printMatch = html.match(/\\/print\\/(\\d+)/);\n if (printMatch) header.printId = Number(printMatch[1]);\n\n const cells: RawCell[] = [];\n let maxRow = 0;\n for (const m of html.matchAll(CELL_RE)) {\n const row = Number(m[1]);\n const col = Number(m[2]);\n cells.push({ row, col, style: m[3]!, text: normalizeCellText(m[4]!) });\n if (row > maxRow) maxRow = row;\n }\n\n // Strict-parse assertion: every grid <td> must have been captured.\n const tdCount = (html.match(/<td width='auto' id=/g) ?? []).length;\n if (cells.length !== tdCount) {\n throw new ExtractError(\n `grid cell mismatch: matched ${cells.length} cells but found ${tdCount} '<td width=' openers`,\n );\n }\n if (cells.length === 0) throw new ExtractError('no swaralipi grid cells found');\n if (header.title === undefined) throw new ExtractError('no নাম metadata row found');\n\n return { header, cells, maxRow };\n}\n","/**\n * Conversion reporting: per-file decode statistics and the batch aggregate.\n * The unknown-token histogram is the feedback loop for growing the codec.\n */\n\nexport interface FileReport {\n nltrId?: number;\n title: string;\n taalName?: string;\n taalId?: string;\n taalMatched: 'taals' | 'table' | 'geometry' | 'none';\n systems: number;\n notationCells: number;\n lyricCells: number;\n annotationCells: number;\n /** Notation cells with ≥1 semantic note and no unknown chunk. */\n decodedCells: number;\n /** Notation cells consisting only of understood-but-raw marks. */\n knownRawCells: number;\n /** Notation cells containing ≥1 chunk outside the grammar. */\n unknownCells: number;\n unknownTokens: Record<string, number>;\n lyricAlignMismatches: number;\n warnings: string[];\n}\n\nexport interface BatchFailure {\n file: string;\n error: string;\n}\n\nexport interface BatchReport {\n files: number;\n ok: number;\n failed: number;\n failures: BatchFailure[];\n systems: number;\n notationCells: number;\n lyricCells: number;\n annotationCells: number;\n decodedCells: number;\n knownRawCells: number;\n unknownCells: number;\n /** decoded / (decoded + knownRaw + unknown) over notation cells. */\n decodeRate: number;\n unknownRate: number;\n /** All unknown tokens, sorted by frequency (descending). */\n unknownTokens: Record<string, number>;\n lyricAlignMismatches: number;\n /** taalName → count + resolution outcome. */\n taals: Record<string, { count: number; taalId?: string; matched: string }>;\n warningCounts: Record<string, number>;\n}\n\nexport function aggregate(reports: FileReport[], failures: BatchFailure[]): BatchReport {\n const out: BatchReport = {\n files: reports.length + failures.length,\n ok: reports.length,\n failed: failures.length,\n failures,\n systems: 0,\n notationCells: 0,\n lyricCells: 0,\n annotationCells: 0,\n decodedCells: 0,\n knownRawCells: 0,\n unknownCells: 0,\n decodeRate: 0,\n unknownRate: 0,\n unknownTokens: {},\n lyricAlignMismatches: 0,\n taals: {},\n warningCounts: {},\n };\n const unknown = new Map<string, number>();\n for (const r of reports) {\n out.systems += r.systems;\n out.notationCells += r.notationCells;\n out.lyricCells += r.lyricCells;\n out.annotationCells += r.annotationCells;\n out.decodedCells += r.decodedCells;\n out.knownRawCells += r.knownRawCells;\n out.unknownCells += r.unknownCells;\n out.lyricAlignMismatches += r.lyricAlignMismatches;\n for (const [tok, n] of Object.entries(r.unknownTokens)) {\n unknown.set(tok, (unknown.get(tok) ?? 0) + n);\n }\n const taalKey = r.taalName ?? '<none>';\n const taalEntry = (out.taals[taalKey] ??= { count: 0, taalId: r.taalId, matched: r.taalMatched });\n taalEntry.count++;\n for (const w of r.warnings) {\n // Collapse per-file numbers so identical warning shapes aggregate.\n const shape = w.replace(/\\d+/g, 'N');\n out.warningCounts[shape] = (out.warningCounts[shape] ?? 0) + 1;\n }\n }\n out.unknownTokens = Object.fromEntries([...unknown.entries()].sort((a, b) => b[1] - a[1]));\n if (out.notationCells > 0) {\n out.decodeRate = out.decodedCells / out.notationCells;\n out.unknownRate = out.unknownCells / out.notationCells;\n }\n return out;\n}\n\nexport function formatSummary(r: BatchReport): string {\n const pct = (x: number) => `${(x * 100).toFixed(2)}%`;\n const lines = [\n `files: ${r.ok}/${r.files} converted${r.failed ? ` (${r.failed} FAILED)` : ''}`,\n `systems: ${r.systems} notation cells: ${r.notationCells} lyric cells: ${r.lyricCells} annotation cells: ${r.annotationCells}`,\n `decoded: ${r.decodedCells} (${pct(r.decodeRate)}) known-raw: ${r.knownRawCells} unknown: ${r.unknownCells} (${pct(r.unknownRate)})`,\n `lyric alignment fallbacks: ${r.lyricAlignMismatches}`,\n ];\n const unknowns = Object.entries(r.unknownTokens);\n if (unknowns.length > 0) {\n lines.push(`unknown tokens (${unknowns.length} distinct, top 20):`);\n for (const [tok, n] of unknowns.slice(0, 20)) lines.push(` ${String(n).padStart(6)} ${JSON.stringify(tok)}`);\n }\n const taalLines = Object.entries(r.taals).sort((a, b) => b[1].count - a[1].count);\n lines.push(`taals (${taalLines.length} distinct):`);\n for (const [name, info] of taalLines.slice(0, 15)) {\n lines.push(` ${String(info.count).padStart(5)} ${name} → ${info.taalId ?? '—'} [${info.matched}]`);\n }\n if (r.failed > 0) {\n lines.push('failures:');\n for (const f of r.failures.slice(0, 10)) lines.push(` ${f.file}: ${f.error}`);\n }\n return lines.join('\\n');\n}\n","/**\n * @ugfoundation/swaralipi-js/convert\n *\n * NLTR HTML → swaralipi JSON converter (Node-only subpath export).\n * `convertNltrHtml` itself is pure (string in, document out); file/dir\n * batch helpers live in the CLI (`swaralipi convert`).\n */\nimport { assemble, type ConvertOptions, type ConvertResult } from './assemble.js';\nimport { extractPage } from './extract.js';\n\nexport { ExtractError, extractPage } from './extract.js';\nexport type { NltrHeader, NltrPage, RawCell } from './extract.js';\nexport { buildSystems } from './grid.js';\nexport type { System } from './grid.js';\nexport { decodeCell } from './codec.js';\nexport type { CellDecode } from './codec.js';\nexport { bnInt, deriveGeometry, resolveTaal } from './taal-map.js';\nexport type { GridGeometry, ResolvedTaal } from './taal-map.js';\nexport { assemble, splitLyric } from './assemble.js';\nexport type { ConvertOptions, ConvertResult } from './assemble.js';\nexport { aggregate, formatSummary } from './report.js';\nexport type { BatchFailure, BatchReport, FileReport } from './report.js';\n\n/**\n * Convert one NLTR swaralipi page (HTML source text) into a validated\n * spec document plus a decode report.\n *\n * Throws `ExtractError` when the HTML does not look like an NLTR swaralipi\n * grid; cell-level decode problems never throw (they degrade to `raw`).\n */\nexport function convertNltrHtml(html: string, opts: ConvertOptions = {}): ConvertResult {\n return assemble(extractPage(html), opts);\n}\n"]}