@ugfoundation/swaralipi-js 0.2.1 → 0.3.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 (37) hide show
  1. package/dist/{batch-SCSIUDB3.js → batch-QPSHVNDS.js} +4 -4
  2. package/dist/{batch-SCSIUDB3.js.map → batch-QPSHVNDS.js.map} +1 -1
  3. package/dist/{chunk-DINRYGRI.js → chunk-4YTOLN3C.js} +3 -3
  4. package/dist/{chunk-DINRYGRI.js.map → chunk-4YTOLN3C.js.map} +1 -1
  5. package/dist/chunk-V5ZSUJCA.js +354 -0
  6. package/dist/chunk-V5ZSUJCA.js.map +1 -0
  7. package/dist/{chunk-KYNCQ7OF.js → chunk-VCRWS3F3.js} +3 -3
  8. package/dist/{chunk-KYNCQ7OF.js.map → chunk-VCRWS3F3.js.map} +1 -1
  9. package/dist/cli.cjs +1 -1
  10. package/dist/cli.cjs.map +1 -1
  11. package/dist/cli.js +2 -2
  12. package/dist/convert/index.cjs +1 -1
  13. package/dist/convert/index.cjs.map +1 -1
  14. package/dist/convert/index.js +2 -2
  15. package/dist/index.cjs +1 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.js +1 -1
  18. package/dist/player/index.cjs +58 -2
  19. package/dist/player/index.cjs.map +1 -1
  20. package/dist/player/index.d.cts +12 -158
  21. package/dist/player/index.d.ts +12 -158
  22. package/dist/player/index.js +31 -324
  23. package/dist/player/index.js.map +1 -1
  24. package/dist/schedule-DhO_Xzz4.d.cts +167 -0
  25. package/dist/schedule-PTHUONrA.d.ts +167 -0
  26. package/dist/spec/index.cjs +1 -1
  27. package/dist/spec/index.cjs.map +1 -1
  28. package/dist/spec/index.d.cts +1 -1
  29. package/dist/spec/index.d.ts +1 -1
  30. package/dist/spec/index.js +1 -1
  31. package/dist/viewer/index.cjs +584 -54
  32. package/dist/viewer/index.cjs.map +1 -1
  33. package/dist/viewer/index.d.cts +177 -18
  34. package/dist/viewer/index.d.ts +177 -18
  35. package/dist/viewer/index.js +322 -30
  36. package/dist/viewer/index.js.map +1 -1
  37. package/package.json +7 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/spec/schema.ts","../../src/spec/taals.ts","../../src/spec/index.ts","../../src/viewer/glyphs.ts","../../src/viewer/render.ts","../../src/viewer/styles.ts","../../src/viewer/print.ts","../../src/viewer/transliterate.ts","../../src/viewer/element.ts"],"names":["z","note","escapeHtml","safeParseSwaralipi"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from 'zod';\n\n/**\n * swaralipi-js JSON spec — Zod schema + inferred types.\n\n/** Octave registers */\nexport const octaveSchema = z.enum([\n 'ati-mandra', // very low\n 'mandra', // low (dot below)\n 'madhyam', // middle\n 'taar', // high (ref/dot above)\n 'ati-taar', // very high\n]);\nexport type Octave = z.infer<typeof octaveSchema>;\n\n/**\n * The seven shuddha svara letters:\n * `d` = ধৈবত (dha), `n` = নিষাদ (ni). Komal/tivra are flags, not letters.\n */\nexport const svaraLetterSchema = z.enum(['s', 'r', 'g', 'm', 'p', 'd', 'n']);\nexport type SvaraLetter = z.infer<typeof svaraLetterSchema>;\n\n/** A pitch as `[octave, letter]` */\nexport const svaraSchema = z.tuple([octaveSchema, svaraLetterSchema]);\nexport type Svara = z.infer<typeof svaraSchema>;\n\n/** Microtone variants below komal (legend: অল্পকোমল / অতিকোমল). */\nexport const microtoneSchema = z.enum(['alpakomal', 'atikomal']);\nexport type Microtone = z.infer<typeof microtoneSchema>;\n\n/**\n * Barline weights. Swarabitan distinguishes the light দাঁড়ি (।) that\n * separates vibhags *within* a taal cycle from the দণ্ড (danda, I) strokes:\n * - `dari` — । vibhag separator inside the cycle\n * - `single` — I end of one taal cycle (ফেরা)\n * - `double` — II section (kali) boundary / return-to-asthayi marker\n * - `quad` — IIII end of the song\n */\nexport const barSchema = z.enum(['dari', 'single', 'double', 'quad']);\nexport type Bar = z.infer<typeof barSchema>;\n\n/**\n * A repeat-bracket edge. Brackets span a range of notes; the opening note\n * carries `{ ..., edge: 'open' }` and the closing note `{ ..., edge: 'close' }`.\n * kind: `repeat` = {} গুন্ডবন্ধনী, `skip` = () বক্রবন্ধনী (omit on repeat),\n * `alt` = [] সরল বন্ধনী (changed notes on repeat).\n */\nexport const bracketSchema = z.object({\n kind: z.enum(['repeat', 'skip', 'alt']),\n edge: z.enum(['open', 'close']),\n});\nexport type Bracket = z.infer<typeof bracketSchema>;\n\n/**\n * A single token in a row. A token is one of: a pitched note (`svara`),\n * a rest (`rest`), an আ-কার sustain (`sustain`), a barline (`bar`), or a\n * purely raw/undecoded cell (`raw`) — possibly carrying annotations\n * (`above`/`below`) or a lyric syllable on an otherwise empty column.\n * The `.refine` enforces that a note carries at least one of these so\n * truly empty tokens can't slip through.\n *\n * `above`/`below` make `Note` recursive, so the type is hand-written and\n * the schema is typed `z.ZodType<Note>` via `z.lazy` (all fields are\n * optional, hence input ≡ output and the annotation is sound).\n */\nexport interface Note {\n /** Pitch. Omitted for rests, sustains, and barlines. */\n svara?: Svara;\n /** কোমল (flat). */\n komal?: boolean;\n /** তীব্র / কড়ি (sharp — applies to ma). */\n tivra?: boolean;\n /** Sub-komal microtone (legend: অল্পকোমল / অতিকোমল). */\n microtone?: Microtone;\n /** Duration in মাত্রা (beats): 1 (default), 0.5, 0.25, 2, … */\n durationMatra?: number;\n /**\n * আ-কার: no new syllable attack. Alone (no `svara`) it holds the previous\n * note's pitch and vowel; combined with `svara` it is a melisma — the\n * pitch moves while the previous syllable's vowel continues (Swarabitan\n * writes these with a leading hyphen, e.g. `-sfa`).\n */\n sustain?: boolean;\n /** বিরাম: a rest of `durationMatra` beats. */\n rest?: boolean;\n /** কণ স্বর: a grace note attached before this note. */\n kan?: Svara;\n /** মীড় (glide/slur) endpoint. */\n meend?: 'start' | 'end';\n /** Barline. A bar token usually has no `svara`. */\n bar?: Bar;\n /** Repeat-bracket edges opening/closing on this token. */\n brackets?: Bracket[];\n /** Lyric syllable aligned under this note */\n lyric?: string;\n /** Lossless passthrough of the source cell (e.g. raw Swarabitan code). */\n raw?: string;\n /**\n * Annotation notes rendered above this column: alt-on-repeat passages\n * (legend: পরিবর্তিত স্বর in [ ] শিরোদেশে), stop marks, beat numbers.\n */\n above?: Note[];\n /** Annotation notes rendered below this column. */\n below?: Note[];\n}\n\nexport const noteSchema: z.ZodType<Note> = z.lazy(() =>\n z\n .object({\n svara: svaraSchema.optional(),\n komal: z.boolean().optional(),\n tivra: z.boolean().optional(),\n microtone: microtoneSchema.optional(),\n durationMatra: z.number().positive().optional(),\n sustain: z.boolean().optional(),\n rest: z.boolean().optional(),\n kan: svaraSchema.optional(),\n meend: z.enum(['start', 'end']).optional(),\n bar: barSchema.optional(),\n brackets: z.array(bracketSchema).optional(),\n lyric: z.string().optional(),\n raw: z.string().optional(),\n above: z.array(noteSchema).optional(),\n below: z.array(noteSchema).optional(),\n })\n .refine(\n (n) =>\n n.svara !== undefined ||\n n.rest === true ||\n n.sustain === true ||\n n.bar !== undefined ||\n n.raw !== undefined ||\n (n.brackets !== undefined && n.brackets.length > 0) ||\n (n.above !== undefined && n.above.length > 0) ||\n (n.below !== undefined && n.below.length > 0) ||\n n.lyric !== undefined,\n {\n message:\n 'note must carry one of: svara, rest, sustain, bar, raw, lyric, brackets, or a non-empty above/below',\n },\n ),\n);\n\n/** A written line of the song: a sequence of note tokens. */\nexport const rowSchema = z.object({\n /** Optional line label (e.g. a tuk/section marker). */\n label: z.string().optional(),\n notes: z.array(noteSchema),\n});\nexport type Row = z.infer<typeof rowSchema>;\n\n/** A structural section: আস্থায়ী / অন্তরা / সঞ্চারী / আভোগ, or free text. */\nexport const partSchema = z.object({\n name: z.string().optional(),\n rows: z.array(rowSchema),\n});\nexport type Part = z.infer<typeof partSchema>;\n\n/**\n * Taal definition. `numBeats` is the cycle length in মাত্রা; `bhaags` (if\n * present) must sum to `numBeats`; `sam`/`khaali` are 0-based beat indices.\n */\nexport const taalSchema = z\n .object({\n /** Player sample key, e.g. `dadra`, `teentaal`. */\n id: z.string(),\n /**\n * Which tabla loop variation to play, e.g. `pro` (CDN dir suffix). Optional\n * and additive — omitted means the taal's default variation, so existing\n * docs are unaffected. The player honors it but never exposes a variation\n * picker; selecting a non-default variation is the consumer's premium policy.\n */\n variation: z.string().optional(),\n numBeats: z.number().int().positive(),\n /** Vibhag groupings; if given, they sum to numBeats. */\n bhaags: z.array(z.number().int().positive()).optional(),\n /** Sam (cycle start) beat index, 0-based. */\n sam: z.number().int().nonnegative().optional(),\n /** Khaali (wave) beat indices, 0-based. */\n khaali: z.array(z.number().int().nonnegative()).optional(),\n })\n .refine((t) => t.bhaags === undefined || t.bhaags.reduce((a, b) => a + b, 0) === t.numBeats, {\n message: 'bhaags must sum to numBeats',\n });\nexport type Taal = z.infer<typeof taalSchema>;\n\n/** Document-level metadata. */\nexport const metaSchema = z.object({\n title: z.string(),\n /** Cross-reference to a gitabitan.io song content id (filename, immutable). */\n songId: z.string().optional(),\n /** Source NLTR node/song id. */\n nltrId: z.number().int().optional(),\n taal: taalSchema.optional(),\n /**\n * The taal name exactly as printed in the source (e.g. `তালমুক্ত`,\n * `ষষ্ঠী(২/৪)`). Always set by the NLTR converter; `taal` is set only\n * when the name resolves to a known definition.\n */\n taalName: z.string().optional(),\n /** Base pitch for playback, e.g. `C`, `C#`, or the player's `cs` form. */\n tonic: z.string().optional(),\n /** Default playback tempo in matra/min. Player-only — the viewer ignores it.\n * The player adopts it on `load()` (precedence: constructor `bpm` → `setBpm`\n * tweak → this → 90). `null` is the converter's blank placeholder = unset. */\n bpm: z.number().positive().nullable().optional(),\n raag: z.string().optional(),\n /** আবর্তন: number of taal cycles, when the source states it. */\n avartan: z.number().int().positive().optional(),\n /** স্বরলিপিকার (notation author). */\n notationBy: z.string().optional(),\n /** Provenance note or URL. */\n source: z.string().optional(),\n});\nexport type Meta = z.infer<typeof metaSchema>;\n\n/** A complete swaralipi document. */\nexport const swaralipiSchema = z.object({\n /** Spec version this document targets (see SPEC_VERSION in ./index). */\n version: z.string(),\n meta: metaSchema,\n parts: z.array(partSchema),\n});\nexport type Swaralipi = z.infer<typeof swaralipiSchema>;\n","import type { Taal } from './schema.js';\n\n/**\n * Reference definitions for the taals the player will sample:\n * adachautaal, dadra, ektaal, jhaptaal, kehrwa, rupak, shashthi, teentaal.\n *\n * `numBeats` and the `bhaags` given below are standard Hindustani taal theory.\n * `bhaags` is omitted where a single canonical division isn't well-agreed\n * (adachautaal) — we assert only what's uncontested. `sam` is beat 0 for all.\n *\n * Tabla loops live under `tabla/<id>/` by default; per-taal variation and\n * skip-bpm overrides (e.g. shashthi → `tabla/shashthi-pro/`) are in\n * instruments.ts's `TABLA_VARIATIONS`.\n */\nexport const TAALS = {\n dadra: { id: 'dadra', numBeats: 6, bhaags: [3, 3], sam: 0, khaali: [3] },\n kehrwa: { id: 'kehrwa', numBeats: 8, bhaags: [4, 4], sam: 0, khaali: [4] },\n rupak: { id: 'rupak', numBeats: 7, bhaags: [3, 2, 2], sam: 0, khaali: [0] },\n jhaptaal: { id: 'jhaptaal', numBeats: 10, bhaags: [2, 3, 2, 3], sam: 0, khaali: [5] },\n ektaal: { id: 'ektaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] },\n adachautaal: { id: 'adachautaal', numBeats: 14, sam: 0 },\n choutaal: { id: 'choutaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] }, // চৌতাল\n shashthi: { id: 'shashthi', numBeats: 6, bhaags: [2, 4], sam: 0 }, // ষষ্ঠী\n teora: { id: 'teora', numBeats: 7, bhaags: [3, 2, 2], sam: 0 }, // টেওরা\n teentaal: { id: 'teentaal', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] },\n aratheka: { id: 'aratheka', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] }, // আড়াঠেকা\n} as const satisfies Record<string, Taal>;\n\nexport type TaalId = keyof typeof TAALS;\n","/**\n * @ugfoundation/swaralipi-js/spec\n *\n * The swaralipi JSON spec: Zod schemas, inferred TS types, and parse helpers.\n */\nimport { swaralipiSchema, type Swaralipi } from './schema.js';\n\n/** Current spec version. Documents declare the version they target. */\nexport const SPEC_VERSION = '0.2.1';\n\nexport {\n octaveSchema,\n svaraLetterSchema,\n svaraSchema,\n microtoneSchema,\n barSchema,\n bracketSchema,\n noteSchema,\n rowSchema,\n partSchema,\n taalSchema,\n metaSchema,\n swaralipiSchema,\n} from './schema.js';\n\nexport type {\n Octave,\n SvaraLetter,\n Svara,\n Microtone,\n Bar,\n Bracket,\n Note,\n Row,\n Part,\n Taal,\n Meta,\n Swaralipi,\n} from './schema.js';\n\nexport { TAALS, type TaalId } from './taals.js';\n\n/** Parse + validate unknown data into a `Swaralipi`. Throws `ZodError` on failure. */\nexport function parseSwaralipi(data: unknown): Swaralipi {\n return swaralipiSchema.parse(data);\n}\n\n/** Non-throwing variant: returns Zod's `{ success, data | error }` result. */\nexport function safeParseSwaralipi(data: unknown) {\n return swaralipiSchema.safeParse(data);\n}\n","/**\n * Per-language notation encoding for the viewer.\n *\n * Every language renders its notation through a dedicated, purpose-built\n * font whose glyphs ARE the akarmatrik/Bhatkhande marks — so composeCluster\n * emits that font's ASCII encoding and the font does all the hard work\n * (komal/tivra forms, octave reph/dots, matra). This is why the viewer no\n * longer touches Unicode cluster composition at all: the old reph-over-\n * vowel, hasanta-before-matra and dotted-circle hazards simply don't exist\n * when the font supplies precomposed glyphs keyed by plain ASCII.\n *\n * - bn → NLTR's **Swarabitan** (the akarmatrik font this project decodes).\n * Letters s r g m p q n = স র গ ম প ধ ন (q=ধ); komal v t d u = ঋ জ্ঞ দ ণ;\n * tivra ma k = the authentic কড়ি-ম conjunct (ম-based — has NO Unicode\n * form, which is what forced this whole approach); suffix f = taar reph,\n * h = mandra hasanta; trailing a = the আ-কার matra carrier. See codec.ts.\n * - hi/en → **Ome Bhatkhande** Hindi/English (SIL OFL 1.1, © Omenad —\n * github.com/omenad/fonts). Same clean keymap for both: lowercase\n * s r g m p d n = the seven shuddha swaras, uppercase R G M D N = komal\n * Re/Ga, tivra Ma, komal Dha/Ni; octave suffix u/l = taar/mandra dot,\n * U/L = ati (two dots). Bhatkhande has no আ-কার, so no matra is appended.\n *\n * The font is applied by CSS keyed on `.sw-sheet`'s `lang` (see styles.ts);\n * composeCluster only chooses the ASCII. The single residual CSS mark is the\n * bn ati-octave extra dot (Swarabitan's f/h are single reph/hasanta only).\n */\nimport type { Octave, SvaraLetter } from '../spec/index.js';\n\nexport type ViewerLang = 'bn' | 'hi' | 'en';\n\n/** bn Swarabitan glyph keys (shuddha / komal / tivra). Missing komal/tivra\n * entries fall back to the shuddha key (those alterations don't occur). */\nconst SWARABITAN_SHUDDHA: Record<SvaraLetter, string> = {\n s: 's', r: 'r', g: 'g', m: 'm', p: 'p', d: 'q', n: 'n', // q = ধ\n};\nconst SWARABITAN_KOMAL: Partial<Record<SvaraLetter, string>> = {\n r: 'v', g: 't', d: 'd', n: 'u', // ঋ জ্ঞ দ ণ\n};\nconst SWARABITAN_TIVRA: Partial<Record<SvaraLetter, string>> = { m: 'k' }; // কড়ি-ম\n\n/** hi/en Ome Bhatkhande octave suffix (u/l single dot, U/L two dots). */\nconst BHATKHANDE_OCTAVE: Record<Octave, string> = {\n madhyam: '',\n taar: 'u',\n mandra: 'l',\n 'ati-taar': 'U',\n 'ati-mandra': 'L',\n};\n/** Letters that have a komal (flat) glyph in Bhatkhande = uppercase key. */\nconst BHATKHANDE_HAS_KOMAL = new Set<SvaraLetter>(['r', 'g', 'd', 'n']);\n\n/** Digits 0-9 in the target script (beat labels, avartan). */\nexport const DIGITS: Record<ViewerLang, string> = {\n bn: '০১২৩৪৫৬৭৮৯',\n hi: '०१२३४५६७८९',\n en: '0123456789',\n};\n\nexport interface LangMarks {\n /** Melisma / no-new-attack dash before a sustained cluster. */\n hyphen: string;\n /** Lyric continuation mark shown under sustains (the source uses ৹). */\n melisma: string;\n /** ছেদ cut/articulation mark (two stacked rings, ঃ-shaped). */\n cut: string;\n}\n\nexport const MARKS: Record<ViewerLang, LangMarks> = {\n bn: { hyphen: '-', melisma: '৹', cut: 'ঃ' },\n hi: { hyphen: '-', melisma: '॰', cut: 'ः' },\n en: { hyphen: '-', melisma: '·', cut: ':' },\n};\n\n/** Header labels (NLTR prints নাম / তাল / আবর্তন …). */\nexport const LABELS: Record<\n ViewerLang,\n { title: string; taal: string; raag: string; avartan: string; notationBy: string }\n> = {\n bn: { title: 'নাম', taal: 'তাল', raag: 'রাগ', avartan: 'আবর্তন', notationBy: 'স্বরলিপি' },\n hi: { title: 'नाम', taal: 'ताल', raag: 'राग', avartan: 'आवर्तन', notationBy: 'स्वरलिपि' },\n en: { title: 'Song', taal: 'Taal', raag: 'Raag', avartan: 'Avartan', notationBy: 'Notation' },\n};\n\n/** A composed notation cluster: the font's ASCII text plus any residual CSS\n * classes the font itself cannot express (only the bn ati-octave dot). */\nexport interface Cluster {\n text: string;\n classes: string[];\n}\n\nexport interface ComposeOptions {\n komal?: boolean;\n tivra?: boolean;\n octave: Octave;\n /** Append the আ-কার matra carrier (bn group-final notes only). */\n withMatra: boolean;\n lang: ViewerLang;\n}\n\n/**\n * Compose one svara into its notation-font ASCII. bn = Swarabitan\n * (letter + f/h octave + a matra); hi/en = Ome Bhatkhande (case-encoded\n * letter + u/l/U/L octave, no matra). The font renders the actual glyph.\n */\nexport function composeCluster(letter: SvaraLetter, opts: ComposeOptions): Cluster {\n const classes: string[] = [];\n\n if (opts.lang === 'bn') {\n let text =\n (opts.tivra && SWARABITAN_TIVRA[letter]) ||\n (opts.komal && SWARABITAN_KOMAL[letter]) ||\n SWARABITAN_SHUDDHA[letter];\n if (opts.octave === 'taar' || opts.octave === 'ati-taar') text += 'f';\n else if (opts.octave === 'mandra' || opts.octave === 'ati-mandra') text += 'h';\n // Swarabitan's f/h are single reph/hasanta; ati adds a CSS extra dot.\n if (opts.octave === 'ati-taar') classes.push('sw-ati-taar');\n if (opts.octave === 'ati-mandra') classes.push('sw-ati-mandra');\n if (opts.withMatra) text += 'a';\n return { text, classes };\n }\n\n // hi / en — Ome Bhatkhande.\n let base: string = letter;\n if (opts.tivra && letter === 'm') base = 'M';\n else if (opts.komal && BHATKHANDE_HAS_KOMAL.has(letter)) base = base.toUpperCase();\n return { text: base + BHATKHANDE_OCTAVE[opts.octave], classes };\n}\n\n/** Map ASCII digits in `s` to the target script's digits. */\nexport function localizeDigits(s: string, lang: ViewerLang): string {\n const digits = DIGITS[lang];\n return s.replace(/[0-9]/g, (d) => digits[d.charCodeAt(0) - 48]!);\n}\n","/**\n * Pure spec-JSON → HTML renderer. No DOM, no side effects: usable for SSR\n * (Astro/static sites emit `renderToHtml(doc)` next to a\n * `<style>${SWARALIPI_CSS}</style>`) and unit-testable in plain Node.\n *\n * Layout model (mirrors NLTR's 4-row systems): each spec `Row` becomes one\n * CSS grid with **one column per top-level note** and four grid rows —\n * above-annotations / notation / below (slur arcs, marks) / lyric. Source\n * cells (groups of sub-notes sharing one matra) become column *spans*, so\n * per-sub-note lyric alignment and P2.3's per-note highlight targets fall\n * out of the column model for free.\n *\n * Rendering is spec-driven (semantics, not `raw`): grouping derives from\n * `durationMatra` accumulation so hand-authored documents without `raw`\n * render identically. `raw` is consulted only for (a) raw-only fallback\n * notes (never dropped — dimmed, in Swarabitan when loaded), (b) the ছেদ\n * cut mark and beat labels, whose grammar lives in raw (see codec.ts).\n */\nimport type { Meta, Note, Row, Swaralipi } from '../spec/index.js';\nimport {\n composeCluster,\n LABELS,\n localizeDigits,\n MARKS,\n type LangMarks,\n type ViewerLang,\n} from './glyphs.js';\n\nexport interface RenderOptions {\n /** Notation + UI language. Default `bn`. */\n lang?: ViewerLang;\n /** Render the NLTR-style নাম/তাল/আবর্তন header block. Default true. */\n showHeader?: boolean;\n /**\n * Lyric/title transliterator for `hi`/`en` (see loadLyricTransliterator).\n * Without it, non-bn renders keep Bengali lyrics (graceful interim).\n */\n transliterate?: (bengaliText: string) => string;\n}\n\nconst NBSP = '\\u00A0';\nconst EPS = 1e-6;\n\nconst isIntegral = (x: number) => Math.abs(x - Math.round(x)) < EPS;\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/* ------------------------------------------------------------------ */\n/* Cell grouping */\n/* ------------------------------------------------------------------ */\n\nexport interface Cell {\n kind: 'bar' | 'group' | 'raw' | 'carrier';\n /** Index of the cell's first note within the row's notes array. */\n start: number;\n notes: Note[];\n}\n\nconst isPitched = (n: Note) => n.svara !== undefined || n.rest === true || n.sustain === true;\n\n/**\n * The raw text a raw-only note should display, or undefined when there is\n * nothing to show beyond what semantics already render (a bracket-only\n * chunk's raw is fully expressed by its bracket glyphs).\n */\nfunction rawDisplay(note: Note): string | undefined {\n if (note.raw === undefined) return undefined;\n if ((note.brackets?.length ?? 0) > 0 && /^[{}()[\\]]*$/.test(note.raw)) return undefined;\n return note.raw;\n}\n\n/**\n * Group a row's notes into rendered cells using a fractional-duration\n * accumulator (raw-independent — works for hand-authored docs):\n * - bar / raw-only / carrier notes force-close and form singleton cells;\n * - full-matra notes are singleton groups;\n * - fractional notes accumulate until the sum reaches an integer matra\n * boundary (epsilon for 1/3, 0.2 chains), then the group closes.\n * The converter emits k notes × 1/k per source cell, so groups coincide\n * with source cells; an incomplete trailing group still closes at row end\n * (the matra carrier lands on its last note).\n */\nexport function groupRowIntoCells(notes: Note[]): Cell[] {\n const cells: Cell[] = [];\n let cur: Cell | undefined;\n let acc = 0;\n const close = () => {\n if (cur) {\n cells.push(cur);\n cur = undefined;\n }\n acc = 0;\n };\n notes.forEach((note, i) => {\n if (note.bar !== undefined) {\n close();\n cells.push({ kind: 'bar', start: i, notes: [note] });\n return;\n }\n if (!isPitched(note)) {\n close();\n cells.push({ kind: rawDisplay(note) !== undefined ? 'raw' : 'carrier', start: i, notes: [note] });\n return;\n }\n const d = note.durationMatra ?? 1;\n if (isIntegral(d)) {\n close();\n cells.push({ kind: 'group', start: i, notes: [note] });\n return;\n }\n cur ??= { kind: 'group', start: i, notes: [] };\n cur.notes.push(note);\n acc += d;\n if (acc > EPS && isIntegral(acc)) close();\n });\n close();\n return cells;\n}\n\n/* ------------------------------------------------------------------ */\n/* Arc (slur) resolution */\n/* ------------------------------------------------------------------ */\n\nexport interface Arc {\n /** 1-based grid column of the arc's first / last note column. */\n startCol: number;\n endCol: number;\n /** True when the matching end lies on a previous / following system. */\n openLeft: boolean;\n openRight: boolean;\n /** Fill-segments-only row: render a straight underline, no curled ends. */\n line?: boolean;\n}\n\n/** Below-annotation raws that are arc drawing segments (codec known-raw):\n * w/x = left/right curled ends, the rest are straight fill pieces. */\nconst ARC_RAW_RE = /^[wWxXyYjJeEzZ$=_<>`\\\\]+$/;\nconst isArcRaw = (raw: string | undefined): raw is string =>\n raw !== undefined && ARC_RAW_RE.test(raw);\n\n/**\n * Resolve under-arcs for one row. Sources, scanned left→right:\n * - below-annotation raws: `w` opens at its cell's first column, `x`\n * closes at its cell's last column (\"xw\" in one cell = close-then-open);\n * - spec `meend: 'start' | 'end'` fields feed the same scan as synthetic\n * w/x at the note's own column.\n * Unmatched `x` → arc from column 1 with a squared-off (open) left end;\n * unclosed `w` → arc to the last column with an open right end — both\n * match the print's behavior when an arc continues across a system wrap.\n * A row with fill segments but no ends at all renders one straight line.\n */\nexport function resolveArcs(cells: Cell[], noteCount: number): Arc[] {\n const arcs: Arc[] = [];\n let openStart: number | undefined;\n let sawEnds = false;\n const fillCols: number[] = [];\n\n const openAt = (col: number) => {\n sawEnds = true;\n if (openStart === undefined) openStart = col;\n };\n const closeAt = (col: number) => {\n sawEnds = true;\n if (openStart !== undefined) {\n arcs.push({ startCol: openStart, endCol: col, openLeft: false, openRight: false });\n openStart = undefined;\n } else {\n arcs.push({ startCol: 1, endCol: col, openLeft: true, openRight: false });\n }\n };\n\n for (const cell of cells) {\n const firstCol = cell.start + 1;\n const lastCol = cell.start + cell.notes.length;\n cell.notes.forEach((note, j) => {\n const col = cell.start + j + 1;\n if (note.meend === 'start') openAt(col);\n else if (note.meend === 'end') closeAt(col);\n for (const b of note.below ?? []) {\n if (!isArcRaw(b.raw)) continue;\n for (const ch of b.raw) {\n if (ch === 'w' || ch === 'W') openAt(firstCol);\n else if (ch === 'x' || ch === 'X') closeAt(lastCol);\n else fillCols.push(firstCol, lastCol);\n }\n }\n });\n }\n\n if (openStart !== undefined) {\n arcs.push({ startCol: openStart, endCol: Math.max(noteCount, 1), openLeft: false, openRight: true });\n } else if (!sawEnds && fillCols.length > 0) {\n arcs.push({\n startCol: Math.min(...fillCols),\n endCol: Math.max(...fillCols),\n openLeft: true,\n openRight: true,\n line: true,\n });\n }\n return arcs;\n}\n\n/* ------------------------------------------------------------------ */\n/* Raw-derived marks (codec grammar: src/convert/codec.ts) */\n/* ------------------------------------------------------------------ */\n\n/** Count ছেদ cut marks in a decoded chunk's raw — every `i`/`:` in a chunk\n * that decoded to notes is a cut mark per the body grammar. Rendered as\n * group-trailing marks (positional approximation; raw keeps the truth). */\nfunction cutMarkCount(raw: string | undefined): number {\n if (raw === undefined) return 0;\n return (raw.match(/[i:]/g) ?? []).length;\n}\n\n/** Beat-number label (above rows): pure digits + optional sam tick. */\nfunction parseBeatLabel(raw: string): { digits: string; sam: boolean } | undefined {\n const m = raw.match(/^([0-9]{1,2})([fF])?:?$/);\n if (!m) return undefined;\n return { digits: m[1]!, sam: m[2] !== undefined };\n}\n\n/* ------------------------------------------------------------------ */\n/* Note / annotation fragments */\n/* ------------------------------------------------------------------ */\n\ninterface Ctx {\n lang: ViewerLang;\n marks: LangMarks;\n tr: (s: string) => string;\n}\n\nconst BRACKET_GLYPHS = {\n open: { repeat: '{', skip: '(', alt: '[' },\n close: { repeat: '}', skip: ')', alt: ']' },\n} as const;\n\nfunction bracketGlyphs(note: Note, edge: 'open' | 'close'): string {\n if (!note.brackets) return '';\n return note.brackets\n .filter((b) => b.edge === edge)\n .map((b) => `<span class=\"sw-br\">${BRACKET_GLYPHS[edge][b.kind]}</span>`)\n .join('');\n}\n\n/** A lone matra glyph: the note's own notation font supplies it — bn = the\n * Swarabitan আ-কার (`a`), hi/en = an en-dash (Bhatkhande has no matra sign).\n * Used for rests (বিরাম = detached matra), আ-কার holds and n>1 durations. */\nfunction matraGlyph(ctx: Ctx): string {\n return ctx.lang === 'bn' ? '<span class=\"sw-cl\">a</span>' : '<span class=\"sw-iso\">–</span>';\n}\n\nfunction renderKan(note: Note, ctx: Ctx): string {\n if (!note.kan) return '';\n const [octave, letter] = note.kan;\n const c = composeCluster(letter, { octave, withMatra: false, lang: ctx.lang });\n return `<span class=\"${['sw-kan', ...c.classes].join(' ')}\">${c.text}</span>`;\n}\n\ninterface PitchedOpts {\n /** This note ends its matra group → carries the আ-কার. */\n withMatra: boolean;\n /** ছেদ cut marks rendered after this (group-final) note. */\n cuts: number;\n}\n\n/** Inner HTML of one pitched/sustain/rest note: brackets, kan, melisma\n * hyphen, notation-font cluster, extra matras, cut marks, closing brackets.\n * The font (keyed on lang in styles.ts) renders komal/tivra/octave/matra —\n * composeCluster only picks the ASCII, so there is no Unicode hazard here. */\nfunction renderPitchedInner(note: Note, opts: PitchedOpts, ctx: Ctx): string {\n let inner = bracketGlyphs(note, 'open');\n inner += renderKan(note, ctx);\n if (note.sustain === true) inner += `<span class=\"sw-hy\">${ctx.marks.hyphen}</span>`;\n if (note.svara !== undefined) {\n const [octave, letter] = note.svara;\n const c = composeCluster(letter, {\n komal: note.komal,\n tivra: note.tivra,\n octave,\n withMatra: opts.withMatra,\n lang: ctx.lang,\n });\n inner += `<span class=\"${['sw-cl', ...c.classes].join(' ')}\">${c.text}</span>`;\n } else if (note.rest === true) {\n inner += matraGlyph(ctx);\n } else if (note.sustain === true && opts.withMatra) {\n inner += matraGlyph(ctx);\n }\n if (note.microtone !== undefined) {\n // Legend: অল্পকোমল = superscript ১ after the letter, অতিকোমল = ২.\n const mark = localizeDigits(note.microtone === 'atikomal' ? '2' : '1', ctx.lang);\n inner += `<span class=\"sw-micro\" title=\"${note.microtone}\">${mark}</span>`;\n }\n const d = note.durationMatra ?? 1;\n if (isIntegral(d) && d > 1 + EPS) inner += matraGlyph(ctx).repeat(Math.round(d) - 1);\n if (opts.cuts > 0) inner += `<span class=\"sw-cut\">${NBSP}${ctx.marks.cut}</span>`.repeat(opts.cuts);\n inner += bracketGlyphs(note, 'close');\n return inner;\n}\n\n/** Swarabitan glyphs (the .sw-bar font): A = vibhag dari, l = I cycle\n * danda, L = II section pair, song-end = II II. */\nconst BAR_GLYPHS = { dari: 'A', single: 'l', double: 'L', quad: 'LL' } as const;\n\nfunction renderBarInner(note: Note): string {\n return `${bracketGlyphs(note, 'open')}${BAR_GLYPHS[note.bar!]}${bracketGlyphs(note, 'close')}`;\n}\n\n/**\n * Render an annotation note list (above/below content) as inline mini\n * notation: beat labels, stop marks, bars, recursive note groups, raw\n * fallback. Reuses the same grouping as the main row.\n */\nfunction renderAnnotation(notes: Note[], ctx: Ctx): string {\n const parts: string[] = [];\n for (const cell of groupRowIntoCells(notes)) {\n if (cell.kind === 'bar') {\n const note = cell.notes[0]!;\n parts.push(`<span class=\"sw-bar sw-bar--${note.bar}\">${renderBarInner(note)}</span>`);\n continue;\n }\n if (cell.kind === 'group') {\n const cuts = cutMarkCount(cell.notes[0]!.raw);\n cell.notes.forEach((note, j) => {\n const last = j === cell.notes.length - 1;\n parts.push(\n `<span class=\"sw-n\">${renderPitchedInner(note, { withMatra: last, cuts: last ? cuts : 0 }, ctx)}</span>`,\n );\n });\n continue;\n }\n const note = cell.notes[0]!;\n const raw = rawDisplay(note);\n if (raw !== undefined) {\n const beat = parseBeatLabel(raw);\n if (beat) {\n parts.push(\n `<span class=\"sw-beat${beat.sam ? ' sw-sam' : ''}\">${localizeDigits(beat.digits, ctx.lang)}</span>`,\n );\n } else if (/^\\|+$/.test(raw)) {\n parts.push(`<span class=\"sw-stop\">${'<i></i>'.repeat(raw.length)}</span>`);\n } else {\n parts.push(`<span class=\"sw-raw\" title=\"${escapeHtml(raw)}\">${escapeHtml(raw)}</span>`);\n }\n continue;\n }\n const brackets = bracketGlyphs(note, 'open') + bracketGlyphs(note, 'close');\n if (brackets !== '') parts.push(`<span class=\"sw-carrier\">${brackets}</span>`);\n }\n return parts.join('');\n}\n\n/** Lyric cell text: the ৹ melisma mark is notation (not language text) —\n * swap it per-lang, transliterating only the linguistic remainder. */\nfunction lyricText(s: string, ctx: Ctx): string {\n return s\n .split('৹')\n .map((part) => (part === '' ? '' : ctx.tr(part)))\n .join(ctx.marks.melisma);\n}\n\n/* ------------------------------------------------------------------ */\n/* Row / header / document */\n/* ------------------------------------------------------------------ */\n\nfunction renderRow(row: Row, partIdx: number, rowIdx: number, ctx: Ctx): string {\n const cells = groupRowIntoCells(row.notes);\n const arcs = resolveArcs(cells, row.notes.length);\n const above: string[] = [];\n const notation: string[] = [];\n const below: string[] = [];\n const lyric: string[] = [];\n\n for (const cell of cells) {\n const firstCol = cell.start + 1;\n const lastCol = cell.start + cell.notes.length;\n const cellSpan =\n lastCol > firstCol ? `grid-column:${firstCol} / ${lastCol + 1}` : `grid-column:${firstCol}`;\n const cuts = cell.kind === 'group' ? cutMarkCount(cell.notes[0]!.raw) : 0;\n\n cell.notes.forEach((note, j) => {\n const col = cell.start + j + 1;\n const path = `${partIdx}.${rowIdx}.${cell.start + j}`;\n const cellEdges = `${j === 0 ? ' sw-cs' : ''}${j === cell.notes.length - 1 ? ' sw-ce' : ''}`;\n\n if (cell.kind === 'bar') {\n notation.push(\n `<span class=\"sw-bar sw-bar--${note.bar}${cellEdges}\" data-note=\"${path}\" style=\"grid-column:${col}\">${renderBarInner(note)}</span>`,\n );\n } else if (cell.kind === 'group') {\n const last = j === cell.notes.length - 1;\n notation.push(\n `<span class=\"sw-n${cellEdges}\" data-note=\"${path}\" style=\"grid-column:${col}\">${renderPitchedInner(note, { withMatra: last, cuts: last ? cuts : 0 }, ctx)}</span>`,\n );\n } else {\n const raw = rawDisplay(note);\n const inner =\n bracketGlyphs(note, 'open') +\n (raw !== undefined\n ? `<span class=\"sw-raw\" title=\"${escapeHtml(raw)}\">${escapeHtml(raw)}</span>`\n : '') +\n bracketGlyphs(note, 'close');\n if (inner !== '') {\n notation.push(\n `<span class=\"sw-n sw-carrier${cellEdges}\" data-note=\"${path}\" style=\"grid-column:${col}\">${inner}</span>`,\n );\n }\n }\n\n if (note.lyric !== undefined) {\n // Share the cell-gap inset (sw-cs) with the notation above, so the\n // lyric column-aligns with its note instead of drifting one gap left.\n lyric.push(\n `<span class=\"sw-lyr${j === 0 ? ' sw-cs' : ''}\" style=\"grid-column:${col}\">${escapeHtml(lyricText(note.lyric, ctx))}</span>`,\n );\n }\n if (note.above !== undefined && note.above.length > 0) {\n above.push(`<span class=\"sw-above\" style=\"${cellSpan}\">${renderAnnotation(note.above, ctx)}</span>`);\n }\n const nonArc = (note.below ?? []).filter((b) => !isArcRaw(b.raw));\n if (nonArc.length > 0) {\n below.push(`<span class=\"sw-below\" style=\"${cellSpan}\">${renderAnnotation(nonArc, ctx)}</span>`);\n }\n });\n }\n\n for (const arc of arcs) {\n const cls = [\n 'sw-arc',\n arc.openLeft ? 'sw-arc--openl' : '',\n arc.openRight ? 'sw-arc--openr' : '',\n arc.line === true ? 'sw-arc--line' : '',\n ]\n .filter(Boolean)\n .join(' ');\n below.push(`<span class=\"${cls}\" style=\"grid-column:${arc.startCol} / ${arc.endCol + 1}\"></span>`);\n }\n\n const label =\n row.label !== undefined ? `<span class=\"sw-label\">${escapeHtml(ctx.tr(row.label))}</span>` : '';\n return `<div class=\"sw-row\">${label}<div class=\"sw-grid\">${above.join('')}${notation.join('')}${below.join('')}${lyric.join('')}</div></div>`;\n}\n\nfunction renderHeader(meta: Meta, ctx: Ctx): string {\n const L = LABELS[ctx.lang];\n const rows: string[] = [];\n const add = (label: string, value: string) =>\n rows.push(\n `<div class=\"sw-meta-row\"><span class=\"sw-meta-label\">${escapeHtml(label)}</span><span class=\"sw-meta-value\">${escapeHtml(value)}</span></div>`,\n );\n add(L.title, ctx.tr(meta.title));\n const taal = meta.taalName ?? meta.taal?.id;\n if (taal !== undefined) add(L.taal, ctx.tr(taal));\n if (meta.raag !== undefined) add(L.raag, ctx.tr(meta.raag));\n if (meta.avartan !== undefined) add(L.avartan, localizeDigits(String(meta.avartan), ctx.lang));\n if (meta.notationBy !== undefined) add(L.notationBy, ctx.tr(meta.notationBy));\n return `<header class=\"sw-header\">${rows.join('')}</header>`;\n}\n\n/** Render a complete swaralipi document to an HTML string. Pair with\n * SWARALIPI_CSS (shadow DOM does this automatically; SSR consumers emit a\n * `<style>` themselves). All source text is HTML-escaped. */\nexport function renderToHtml(doc: Swaralipi, opts: RenderOptions = {}): string {\n const lang: ViewerLang = opts.lang ?? 'bn';\n const tr = lang !== 'bn' && opts.transliterate ? opts.transliterate : (s: string) => s;\n const ctx: Ctx = { lang, marks: MARKS[lang], tr };\n\n const out: string[] = [`<div class=\"sw-sheet\" lang=\"${lang}\">`];\n if (opts.showHeader !== false) out.push(renderHeader(doc.meta, ctx));\n doc.parts.forEach((part, p) => {\n out.push('<section class=\"sw-part\">');\n if (part.name !== undefined)\n out.push(`<h3 class=\"sw-part-name\">${escapeHtml(ctx.tr(part.name))}</h3>`);\n part.rows.forEach((row, r) => out.push(renderRow(row, p, r, ctx)));\n out.push('</section>');\n });\n out.push('</div>');\n return out.join('');\n}\n","/**\n * Encapsulated stylesheet for the viewer. Injected into the\n * `<swaralipi-sheet>` shadow root automatically; SSR consumers emit it\n * themselves: `<style>${SWARALIPI_CSS}</style>` next to `renderToHtml()`.\n *\n * Theming hooks (CSS custom properties, all optional):\n * --sw-font font stack (default: Noto Sans Bengali + system Bengali)\n * --sw-size base font size\n * --sw-cell-gap horizontal gap between source cells\n * --sw-hl player-highlight background (P2.3)\n * --sw-rule header rule / muted line color\n *\n * All ink uses `currentColor`, so the sheet follows the host's text color\n * (dark mode included). The only octave mark drawn as a pseudo-element is\n * the bn ati-octave extra dot (Swarabitan's f/h glyphs are a single\n * reph/hasanta); everything else is a real glyph in the notation font.\n */\n\n/** Notation fonts, self-hosted on the project CDN (CORS-enabled), keyed by\n * the CSS `font-family` this stylesheet uses. bn = NLTR's Swarabitan; hi/en\n * = Ome Bhatkhande (SIL OFL 1.1, © Omenad — github.com/omenad/fonts).\n * Self-hosters: declare your own \\`@font-face\\` for any of these families\n * before this stylesheet / before defineSwaralipiSheet() and it wins. */\nexport const NOTATION_FONT_URLS: Record<string, string> = {\n Swarabitan: 'https://cdn.daserve.in/webfonts/swarabitan/Swarabitan.ttf',\n ome_bhatkhande_hindi: 'https://cdn.daserve.in/webfonts/ome-bhatkhande/OmeBhatkhandeHindi.ttf',\n ome_bhatkhande_english:\n 'https://cdn.daserve.in/webfonts/ome-bhatkhande/OmeBhatkhandeEnglish.ttf',\n};\n\n/** @deprecated use NOTATION_FONT_URLS.Swarabitan */\nexport const SWARABITAN_FONT_URL = NOTATION_FONT_URLS.Swarabitan;\n\n/* Each language renders its notation through one dedicated font — the\n * glyphs ARE the akarmatrik/Bhatkhande marks, keyed by plain ASCII (see\n * glyphs.ts). @font-face covers document use (SSR, print); the element also\n * registers these via the FontFace API because @font-face inside a shadow\n * root's adopted sheet is ignored. display:block — a flash of the ASCII\n * fallback ('kfa', 'srgm') would read as content. */\nconst FONT_FACES = Object.entries(NOTATION_FONT_URLS)\n .map(\n ([family, url]) =>\n `@font-face { font-family: ${family}; src: url('${url}') format('truetype'); font-display: block; }`,\n )\n .join('\\n');\n\nexport const SWARALIPI_CSS = `\n${FONT_FACES}\n\n.sw-sheet {\n font-family: var(--sw-font, 'Noto Sans Bengali', 'Kohinoor Bangla', 'Bangla Sangam MN', 'Nirmala UI', 'Noto Sans Devanagari', sans-serif);\n font-size: var(--sw-size, 1.125rem);\n line-height: 1.5;\n}\n\n/* ---- notation font, per language (the note clusters + grace notes) ---- */\n.sw-sheet[lang=\"bn\"] .sw-cl, .sw-sheet[lang=\"bn\"] .sw-kan { font-family: Swarabitan, var(--sw-font, sans-serif); }\n.sw-sheet[lang=\"hi\"] .sw-cl, .sw-sheet[lang=\"hi\"] .sw-kan { font-family: ome_bhatkhande_hindi, var(--sw-font, sans-serif); }\n.sw-sheet[lang=\"en\"] .sw-cl, .sw-sheet[lang=\"en\"] .sw-kan { font-family: ome_bhatkhande_english, var(--sw-font, sans-serif); }\n\n/* ---- header ---- */\n.sw-header {\n margin: 0 0 0.75em;\n padding: 0 0 0.5em;\n border-bottom: 1px solid var(--sw-rule, rgba(128, 128, 128, 0.35));\n font-size: 0.95em;\n}\n.sw-meta-row { display: flex; gap: 0.3em; }\n.sw-meta-label { font-weight: 600; min-width: 4.5em; }\n.sw-meta-label::after { content: ':'; font-weight: 400; margin-left: 0.15em; }\n\n.sw-part-name { font-size: 0.85em; font-weight: 600; margin: 1em 0 0.2em; opacity: 0.85; }\n\n/* ---- row grid: above / notation / below(arcs) / lyric ---- */\n.sw-row {\n display: flex;\n align-items: flex-start;\n overflow-x: auto;\n padding: 0.4em 0;\n}\n.sw-label { flex: none; margin-right: 0.8em; font-weight: 600; }\n.sw-grid {\n display: grid;\n grid-template-rows: auto auto auto auto;\n grid-auto-columns: max-content;\n align-items: end;\n}\n.sw-above { grid-row: 1; font-size: 0.62em; justify-self: start; white-space: nowrap; padding-left: 0.2em; }\n.sw-n { grid-row: 2; justify-self: center; white-space: nowrap; }\n.sw-arc,\n.sw-below { grid-row: 3; }\n.sw-lyr { grid-row: 4; justify-self: center; white-space: nowrap; padding-top: 0.3em; }\n.sw-below { font-size: 0.62em; justify-self: start; white-space: nowrap; padding-left: 0.2em; }\n\n/* inter-cell gap as padding on each cell's first notation item, so arcs\n * and above-spans crossing cells stay continuous */\n.sw-cs { padding-left: var(--sw-cell-gap, 0.55em); }\n\n/* ---- notation clusters & marks ---- */\n.sw-cl { position: relative; display: inline-block; }\n\n/* bn ati-octave: Swarabitan's f/h give a single reph/hasanta, so ati adds\n * one extra dot above (ati-taar) / below (ati-mandra). bn-only — hi/en get\n * the two-dot glyph natively from the U/L octave suffix. */\n.sw-ati-taar::before,\n.sw-ati-mandra::before {\n content: '';\n position: absolute;\n left: 0.25em;\n width: 0.16em;\n height: 0.16em;\n border-radius: 50%;\n background: currentColor;\n}\n.sw-ati-taar::before { top: -0.3em; }\n.sw-ati-mandra::before { bottom: -0.35em; }\n\n/* kan grace: small raised cluster left of the main note */\n.sw-kan {\n position: relative;\n display: inline-block;\n font-size: 0.58em;\n vertical-align: 0.75em;\n margin-right: 0.08em;\n}\n\n.sw-hy { padding-right: 0.02em; }\n.sw-iso { display: inline-block; margin-left: -0.18em; }\n.sw-cut { font-size: 0.8em; display: inline-block; margin-left: -0.15em; }\n.sw-br { opacity: 0.8; padding: 0 0.06em; }\n.sw-micro { font-size: 0.6em; vertical-align: super; opacity: 0.8; }\n\n/* raw fallback: never dropped, visibly non-notation. Swarabitan first —\n * raw IS that font's encoding, so undecoded cells show NLTR's own glyphs\n * (dimmed: semantics unverified); monospace ASCII when the font is out. */\n.sw-raw {\n font-family: Swarabitan, ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.72em;\n opacity: 0.55;\n}\n\n/* ---- bars: dari (A) and danda (l/L) Swarabitan glyphs ---- */\n/* horizontal gap before a bar comes from its own .sw-cs padding-left —\n * never reset it with a padding shorthand here */\n.sw-bar {\n grid-row: 2;\n font-family: Swarabitan, var(--sw-font, sans-serif);\n white-space: nowrap;\n padding-right: 0.1em;\n}\n.sw-bar--quad { letter-spacing: 0.15em; }\n\n/* ---- under-arcs (slurs decoded from w/x segments and meend) ---- */\n.sw-arc {\n align-self: start;\n height: 0.4em;\n margin: 0.05em 0.25em 0;\n border: 0.09em solid currentColor;\n border-top: none;\n border-bottom-left-radius: 0.6em;\n border-bottom-right-radius: 0.6em;\n opacity: 0.85;\n}\n.sw-arc--openl { border-left: none; border-bottom-left-radius: 0; }\n.sw-arc--openr { border-right: none; border-bottom-right-radius: 0; }\n.sw-arc--line { border-left: none; border-right: none; border-radius: 0; height: 0.22em; }\n\n/* ---- annotation content ---- */\n.sw-beat { position: relative; display: inline-block; padding: 0 0.1em; }\n.sw-sam::after {\n content: '';\n position: absolute;\n top: -0.45em;\n left: 50%;\n width: 0.1em;\n height: 0.4em;\n background: currentColor;\n transform: rotate(14deg);\n}\n.sw-stop i {\n display: inline-block;\n width: 0.07em;\n height: 1em;\n margin: 0 0.07em;\n background: currentColor;\n vertical-align: text-bottom;\n}\n\n/* ---- player sync (P2.3) ---- */\n.sw-hl { background: var(--sw-hl, rgba(255, 196, 64, 0.45)); border-radius: 0.15em; }\n\n/* ---- element error box ---- */\n.sw-error {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.85em;\n padding: 0.6em 0.8em;\n border: 1px solid rgba(200, 64, 64, 0.6);\n border-radius: 0.3em;\n color: #b33;\n background: rgba(200, 64, 64, 0.08);\n}\n`;\n\n/**\n * Print stylesheet — pair with `SWARALIPI_CSS` (renderPrintDocument injects\n * both). Gated on `@media print`, so it also works if a consumer drops it into\n * a page and prints that page directly.\n *\n * - `print-color-adjust: exact` forces the marks that are drawn as tiny\n * `background: currentColor` pseudo-elements (octave dots, arcs, danda\n * strokes, sam tick) to actually print — browsers drop backgrounds by\n * default, which would silently strip the notation's diacritics.\n * - rows are un-clipped (no scrollbar on paper) and kept whole across page\n * breaks; part headings stay with their first row.\n */\nexport const SWARALIPI_PRINT_CSS = `\n@page { margin: 16mm; }\n@media print {\n .sw-sheet { -webkit-print-color-adjust: exact; print-color-adjust: exact; color: #000; }\n .sw-row { overflow: visible !important; break-inside: avoid; page-break-inside: avoid; }\n .sw-part { break-inside: auto; }\n .sw-part-name, .sw-header { break-after: avoid-page; page-break-after: avoid; }\n .sw-hl { background: none !important; }\n}\n`;\n","/**\n * Print / \"Save as PDF\" support.\n *\n * High-fidelity PDF of আকারমাত্রিক notation can only come from the browser's\n * own print engine — it reuses the exact HarfBuzz shaping (reph, conjuncts,\n * matra) and the CSS-drawn marks (octave dots, slur arcs, danda strokes) that\n * the viewer renders on screen. Rasterizers (html2canvas) and PDF-primitive\n * libraries (jsPDF/pdfmake) have no Indic shaping and drop pseudo-element\n * marks, so we deliberately avoid them.\n *\n * `renderPrintDocument` builds a self-contained HTML page from the pure\n * `renderToHtml` + `SWARALIPI_CSS` (so it sidesteps the shadow-DOM \"print drops\n * encapsulated styles\" gotcha); `printSwaralipi` prints it via a hidden iframe.\n * Both reuse the same renderer as the viewer, so the PDF matches the screen.\n */\nimport type { Swaralipi } from '../spec/index.js';\nimport type { ViewerLang } from './glyphs.js';\nimport { renderToHtml } from './render.js';\nimport { SWARALIPI_CSS, SWARALIPI_PRINT_CSS } from './styles.js';\n\nexport interface PrintOptions {\n /** Notation + UI language. Default `bn`. */\n lang?: ViewerLang;\n /** Render the নাম/তাল header block. Default true. */\n showHeader?: boolean;\n /** Lyric/title transliterator for hi/en (see loadLyricTransliterator). */\n transliterate?: (bengaliText: string) => string;\n /** Document `<title>` — the browser's default \"Save as PDF\" filename.\n * Defaults to the document's `meta.title`. */\n title?: string;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/**\n * Build a complete, standalone HTML document for printing a swaralipi sheet:\n * the rendered notation plus `SWARALIPI_CSS` and the print stylesheet, on a\n * white page. Usable for a hidden-iframe print, a new browser tab, or\n * server-side headless-Chrome PDF generation.\n */\nexport function renderPrintDocument(doc: Swaralipi, opts: PrintOptions = {}): string {\n const lang: ViewerLang = opts.lang ?? 'bn';\n const tr = lang !== 'bn' && opts.transliterate ? opts.transliterate : (s: string) => s;\n const title = opts.title ?? tr(doc.meta.title);\n const body = renderToHtml(doc, {\n lang,\n showHeader: opts.showHeader,\n transliterate: opts.transliterate,\n });\n return `<!doctype html>\n<html lang=\"${escapeHtml(lang)}\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${escapeHtml(title)}</title>\n<style>\n${SWARALIPI_CSS}\n${SWARALIPI_PRINT_CSS}\nhtml, body { margin: 0; }\nbody { color: #111; background: #fff; padding: 16px; -webkit-print-color-adjust: exact; print-color-adjust: exact; }\n.sw-sheet { max-width: 100%; }\n</style>\n</head>\n<body>${body}</body>\n</html>`;\n}\n\n/**\n * Open the browser print dialog for a swaralipi document (the user picks a\n * printer or \"Save as PDF\"). Renders into an off-screen iframe so it prints\n * only the sheet — independent of the host page's chrome and CSS — then cleans\n * up. Browser-only; throws in a non-DOM environment (use renderPrintDocument\n * for SSR / headless-Chrome instead).\n */\nexport function printSwaralipi(doc: Swaralipi, opts: PrintOptions = {}): void {\n if (typeof document === 'undefined') {\n throw new Error('printSwaralipi requires a DOM; use renderPrintDocument() for server-side PDF');\n }\n const html = renderPrintDocument(doc, opts);\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n // off-screen but rendered (display:none iframes print blank); a page-ish\n // width so rows lay out before the print stylesheet takes over.\n iframe.style.cssText = 'position:fixed; left:-10000px; top:0; width:800px; height:600px; border:0;';\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (win === null) {\n iframe.remove();\n return;\n }\n const cleanup = () => setTimeout(() => iframe.remove(), 1000);\n win.addEventListener('afterprint', cleanup, { once: true });\n let printed = false;\n const go = () => {\n if (printed) return;\n printed = true;\n try {\n win.focus();\n win.print();\n } catch {\n /* printing unavailable (e.g. headless) — leave cleanup to afterprint */\n }\n };\n // The notation is rendered ENTIRELY in the CDN notation fonts, so a\n // not-yet-downloaded face prints as raw ASCII — or blank, under\n // `font-display: block`. `fonts.ready` alone is not enough: it can resolve\n // before layout has even requested the faces. Force each declared face to\n // download, then print; a timeout prints anyway so a slow/unreachable font\n // (e.g. a lang whose CDN font isn't up yet) never blocks the dialog.\n const fonts = iframe.contentDocument?.fonts;\n if (fonts && typeof fonts.forEach === 'function') {\n const loads: Promise<unknown>[] = [Promise.resolve(fonts.ready)];\n fonts.forEach((face) => loads.push(face.load().catch(() => undefined)));\n void Promise.all(loads).then(go);\n setTimeout(go, 3000); // never let a slow/unreachable font block the dialog\n } else {\n setTimeout(go, 250);\n }\n };\n\n iframe.srcdoc = html;\n document.body.appendChild(iframe);\n}\n","/**\n * Lazy lyric transliteration for `hi` / `en` renders.\n *\n * Swara glyphs come from the sync tables in glyphs.ts; only *linguistic*\n * text (lyrics, title, names) needs transliteration, so sanscript loads via\n * dynamic import — `bn`-only consumers (and their bundles) never touch it.\n */\nimport type { ViewerLang } from './glyphs.js';\n\nexport type Transliterator = (bengaliText: string) => string;\n\nconst TARGET: Record<Exclude<ViewerLang, 'bn'>, string> = {\n hi: 'devanagari',\n en: 'iast',\n};\n\n/**\n * Load a Bengali→target transliterator for the given viewer language.\n * Returns undefined for `bn` (no work to do). Pass the result as\n * `RenderOptions.transliterate`; the `<swaralipi-sheet>` element wires this\n * automatically when its `lang` attribute changes.\n */\nexport async function loadLyricTransliterator(lang: ViewerLang): Promise<Transliterator | undefined> {\n if (lang === 'bn') return undefined;\n const mod = (await import('@indic-transliteration/sanscript')) as {\n default?: { t(text: string, from: string, to: string): string };\n t?(text: string, from: string, to: string): string;\n };\n const sanscript = mod.default ?? mod;\n const target = TARGET[lang];\n return (text) => sanscript.t!(text, 'bengali', target);\n}\n","/**\n * The `<swaralipi-sheet>` custom element — a thin shadow-DOM shell around\n * the pure renderer.\n *\n * The element class is created lazily inside defineSwaralipiSheet():\n * a top-level `extends HTMLElement` would throw on import in Node, and this\n * module must stay importable for SSR (where only renderToHtml is used).\n * Nothing registers automatically — call defineSwaralipiSheet() once.\n *\n * Validation is off by default (converter output is pre-validated); setting\n * `validate = true` parses documents against the Zod schema via a dynamic\n * import, so the viewer bundle stays free of bare runtime imports (it can\n * be loaded directly from dist/ in a browser without a bundler).\n */\nimport type { Swaralipi } from '../spec/index.js';\nimport { renderToHtml } from './render.js';\nimport { SWARALIPI_CSS, NOTATION_FONT_URLS } from './styles.js';\nimport { printSwaralipi, type PrintOptions } from './print.js';\nimport { loadLyricTransliterator, type Transliterator } from './transliterate.js';\nimport type { ViewerLang } from './glyphs.js';\n\nexport interface SwaralipiSheetElement extends HTMLElement {\n /** The document to render (property only; renders on assignment). */\n doc: Swaralipi | undefined;\n /** Parse documents against the spec schema before rendering. */\n validate: boolean;\n /** Add the player-highlight class to the note at \"part.row.note\". */\n highlight(path: string): HTMLElement | null;\n clearHighlights(): void;\n /** Open the print dialog (→ \"Save as PDF\") for the current document. */\n print(options?: PrintOptions): void;\n}\n\nconst LANGS: ReadonlySet<string> = new Set(['bn', 'hi', 'en']);\n\n/** Browsers ignore @font-face inside a shadow root's (adopted) stylesheet —\n * faces must live at document scope, so register the notation fonts there\n * via the FontFace API. No-op without FontFace (jsdom/SSR) or for any family\n * already present (SSR CSS on the page, or a self-hoster's own declaration). */\nfunction ensureNotationFonts(): void {\n if (typeof FontFace === 'undefined' || typeof document === 'undefined') return;\n const present = new Set<string>();\n for (const f of document.fonts) present.add(f.family.replace(/['\"]/g, ''));\n for (const [family, url] of Object.entries(NOTATION_FONT_URLS)) {\n if (present.has(family)) continue;\n document.fonts.add(new FontFace(family, `url(${url})`, { display: 'block' }));\n }\n}\n\nlet sharedSheet: CSSStyleSheet | undefined;\n\nfunction createElementClass(): CustomElementConstructor {\n return class SwaralipiSheet extends HTMLElement implements SwaralipiSheetElement {\n static observedAttributes = ['src', 'lang', 'hide-header'];\n\n #doc: Swaralipi | undefined;\n #root: ShadowRoot;\n #adopted = false;\n #abort: AbortController | undefined;\n #translit: Transliterator | undefined;\n #translitLang: ViewerLang | undefined;\n validate = false;\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: 'open' });\n if (\n typeof CSSStyleSheet !== 'undefined' &&\n 'replaceSync' in CSSStyleSheet.prototype &&\n 'adoptedStyleSheets' in this.#root\n ) {\n if (!sharedSheet) {\n sharedSheet = new CSSStyleSheet();\n sharedSheet.replaceSync(SWARALIPI_CSS);\n }\n this.#root.adoptedStyleSheets = [...this.#root.adoptedStyleSheets, sharedSheet];\n this.#adopted = true;\n }\n }\n\n get doc(): Swaralipi | undefined {\n return this.#doc;\n }\n\n set doc(value: Swaralipi | undefined) {\n this.#doc = value;\n if (value !== undefined && this.validate) {\n void import('../spec/index.js')\n .then(({ safeParseSwaralipi }) => {\n const result = safeParseSwaralipi(value);\n if (!result.success) this.#renderError(result.error.message);\n })\n .catch(() => undefined);\n }\n this.#render();\n }\n\n get #lang(): ViewerLang {\n const attr = this.getAttribute('lang');\n return attr !== null && LANGS.has(attr) ? (attr as ViewerLang) : 'bn';\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n if (name === 'src') {\n if (newValue !== null) void this.#load(newValue);\n return;\n }\n if (name === 'lang') this.#ensureTransliterator();\n this.#render();\n }\n\n connectedCallback(): void {\n this.#ensureTransliterator();\n this.#render();\n }\n\n disconnectedCallback(): void {\n this.#abort?.abort();\n }\n\n async #load(url: string): Promise<void> {\n this.#abort?.abort();\n const abort = new AbortController();\n this.#abort = abort;\n try {\n const res = await fetch(url, { signal: abort.signal });\n if (!res.ok) throw new Error(`fetch ${url}: HTTP ${res.status}`);\n this.doc = (await res.json()) as Swaralipi;\n } catch (err) {\n if (abort.signal.aborted) return;\n this.#renderError(err instanceof Error ? err.message : String(err));\n this.dispatchEvent(new ErrorEvent('error', { error: err, message: String(err) }));\n }\n }\n\n /** Load (once per lang) the lyric transliterator, then re-render. */\n #ensureTransliterator(): void {\n const lang = this.#lang;\n if (lang === 'bn' || this.#translitLang === lang) return;\n void loadLyricTransliterator(lang)\n .then((t) => {\n if (t === undefined || this.#lang !== lang) return;\n this.#translit = t;\n this.#translitLang = lang;\n this.#render();\n })\n .catch(() => undefined); // graceful: lyrics stay Bengali\n }\n\n #styleFallback(): string {\n return this.#adopted ? '' : `<style>${SWARALIPI_CSS}</style>`;\n }\n\n #render(): void {\n if (this.#doc === undefined) {\n this.#root.innerHTML = this.#styleFallback();\n return;\n }\n const lang = this.#lang;\n const html = renderToHtml(this.#doc, {\n lang,\n showHeader: !this.hasAttribute('hide-header'),\n transliterate: this.#translitLang === lang ? this.#translit : undefined,\n });\n this.#root.innerHTML = this.#styleFallback() + html;\n }\n\n #renderError(message: string): void {\n const div = document.createElement('div');\n div.className = 'sw-error';\n div.textContent = message;\n this.#root.innerHTML = this.#styleFallback();\n this.#root.appendChild(div);\n }\n\n highlight(path: string): HTMLElement | null {\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(path)) return null;\n const el = this.#root.querySelector<HTMLElement>(`[data-note=\"${path}\"]`);\n el?.classList.add('sw-hl');\n return el;\n }\n\n clearHighlights(): void {\n for (const el of this.#root.querySelectorAll('.sw-hl')) el.classList.remove('sw-hl');\n }\n\n print(options: PrintOptions = {}): void {\n if (this.#doc === undefined) return;\n const lang = this.#lang;\n printSwaralipi(this.#doc, {\n lang,\n showHeader: !this.hasAttribute('hide-header'),\n transliterate: this.#translitLang === lang ? this.#translit : undefined,\n ...options,\n });\n }\n };\n}\n\n/** Per-tag constructors: a custom-element class can only be registered\n * under one name, so each tag gets its own. */\nconst registered = new Map<string, CustomElementConstructor>();\n\n/**\n * Register `<swaralipi-sheet>` (or a custom tag name). Idempotent. Throws\n * outside a DOM environment — use renderToHtml() for SSR.\n */\nexport function defineSwaralipiSheet(tagName = 'swaralipi-sheet'): CustomElementConstructor {\n if (typeof customElements === 'undefined' || typeof HTMLElement === 'undefined') {\n throw new Error('swaralipi-sheet requires a DOM; use renderToHtml() for server-side rendering');\n }\n const existing = customElements.get(tagName);\n if (existing) return existing;\n ensureNotationFonts();\n const ctor = registered.get(tagName) ?? createElementClass();\n registered.set(tagName, ctor);\n customElements.define(tagName, ctor);\n return ctor;\n}\n"]}
1
+ {"version":3,"sources":["../../src/spec/taals.ts","../../src/spec/schema.ts","../../src/spec/index.ts","../../src/viewer/glyphs.ts","../../src/viewer/render.ts","../../src/viewer/styles.ts","../../src/player/pitch.ts","../../src/player/schedule.ts","../../src/viewer/staff.ts","../../src/player/instruments.ts","../../src/viewer/print.ts","../../src/viewer/transliterate.ts","../../src/viewer/element.ts"],"names":["z","note","EPS","escapeHtml","safeParseSwaralipi","html"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Taal } from './schema.js';\n\n/**\n * Reference definitions for the taals the player will sample:\n * adachautaal, dadra, ektaal, jhaptaal, kehrwa, rupak, shashthi, teentaal.\n *\n * `numBeats` and the `bhaags` given below are standard Hindustani taal theory.\n * `bhaags` is omitted where a single canonical division isn't well-agreed\n * (adachautaal) — we assert only what's uncontested. `sam` is beat 0 for all.\n *\n * Tabla loops live under `tabla/<id>/` by default; per-taal variation and\n * skip-bpm overrides (e.g. shashthi → `tabla/shashthi-pro/`) are in\n * instruments.ts's `TABLA_VARIATIONS`.\n */\nexport const TAALS = {\n dadra: { id: 'dadra', numBeats: 6, bhaags: [3, 3], sam: 0, khaali: [3] },\n kehrwa: { id: 'kehrwa', numBeats: 8, bhaags: [4, 4], sam: 0, khaali: [4] },\n rupak: { id: 'rupak', numBeats: 7, bhaags: [3, 2, 2], sam: 0, khaali: [0] },\n jhaptaal: { id: 'jhaptaal', numBeats: 10, bhaags: [2, 3, 2, 3], sam: 0, khaali: [5] },\n ektaal: { id: 'ektaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] },\n adachautaal: { id: 'adachautaal', numBeats: 14, sam: 0 },\n choutaal: { id: 'choutaal', numBeats: 12, bhaags: [2, 2, 2, 2, 2, 2], sam: 0, khaali: [2, 6] }, // চৌতাল\n shashthi: { id: 'shashthi', numBeats: 6, bhaags: [2, 4], sam: 0 }, // ষষ্ঠী\n teora: { id: 'teora', numBeats: 7, bhaags: [3, 2, 2], sam: 0 }, // টেওরা\n teentaal: { id: 'teentaal', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] },\n aratheka: { id: 'aratheka', numBeats: 16, bhaags: [4, 4, 4, 4], sam: 0, khaali: [8] }, // আড়াঠেকা\n} as const satisfies Record<string, Taal>;\n\nexport type TaalId = keyof typeof TAALS;\n","import { z } from 'zod';\n\n/**\n * swaralipi-js JSON spec — Zod schema + inferred types.\n\n/** Octave registers */\nexport const octaveSchema = z.enum([\n 'ati-mandra', // very low\n 'mandra', // low (dot below)\n 'madhyam', // middle\n 'taar', // high (ref/dot above)\n 'ati-taar', // very high\n]);\nexport type Octave = z.infer<typeof octaveSchema>;\n\n/**\n * The seven shuddha svara letters:\n * `d` = ধৈবত (dha), `n` = নিষাদ (ni). Komal/tivra are flags, not letters.\n */\nexport const svaraLetterSchema = z.enum(['s', 'r', 'g', 'm', 'p', 'd', 'n']);\nexport type SvaraLetter = z.infer<typeof svaraLetterSchema>;\n\n/** A pitch as `[octave, letter]` */\nexport const svaraSchema = z.tuple([octaveSchema, svaraLetterSchema]);\nexport type Svara = z.infer<typeof svaraSchema>;\n\n/** Microtone variants below komal (legend: অল্পকোমল / অতিকোমল). */\nexport const microtoneSchema = z.enum(['alpakomal', 'atikomal']);\nexport type Microtone = z.infer<typeof microtoneSchema>;\n\n/**\n * Barline weights. Swarabitan distinguishes the light দাঁড়ি (।) that\n * separates vibhags *within* a taal cycle from the দণ্ড (danda, I) strokes:\n * - `dari` — । vibhag separator inside the cycle\n * - `single` — I end of one taal cycle (ফেরা)\n * - `double` — II section (kali) boundary / return-to-asthayi marker\n * - `quad` — IIII end of the song\n */\nexport const barSchema = z.enum(['dari', 'single', 'double', 'quad']);\nexport type Bar = z.infer<typeof barSchema>;\n\n/**\n * A repeat-bracket edge. Brackets span a range of notes; the opening note\n * carries `{ ..., edge: 'open' }` and the closing note `{ ..., edge: 'close' }`.\n * kind: `repeat` = {} গুন্ডবন্ধনী, `skip` = () বক্রবন্ধনী (omit on repeat),\n * `alt` = [] সরল বন্ধনী (changed notes on repeat).\n */\nexport const bracketSchema = z.object({\n kind: z.enum(['repeat', 'skip', 'alt']),\n edge: z.enum(['open', 'close']),\n});\nexport type Bracket = z.infer<typeof bracketSchema>;\n\n/**\n * A single token in a row. A token is one of: a pitched note (`svara`),\n * a rest (`rest`), an আ-কার sustain (`sustain`), a barline (`bar`), or a\n * purely raw/undecoded cell (`raw`) — possibly carrying annotations\n * (`above`/`below`) or a lyric syllable on an otherwise empty column.\n * The `.refine` enforces that a note carries at least one of these so\n * truly empty tokens can't slip through.\n *\n * `above`/`below` make `Note` recursive, so the type is hand-written and\n * the schema is typed `z.ZodType<Note>` via `z.lazy` (all fields are\n * optional, hence input ≡ output and the annotation is sound).\n */\nexport interface Note {\n /** Pitch. Omitted for rests, sustains, and barlines. */\n svara?: Svara;\n /** কোমল (flat). */\n komal?: boolean;\n /** তীব্র / কড়ি (sharp — applies to ma). */\n tivra?: boolean;\n /** Sub-komal microtone (legend: অল্পকোমল / অতিকোমল). */\n microtone?: Microtone;\n /** Duration in মাত্রা (beats): 1 (default), 0.5, 0.25, 2, … */\n durationMatra?: number;\n /**\n * আ-কার: no new syllable attack. Alone (no `svara`) it holds the previous\n * note's pitch and vowel; combined with `svara` it is a melisma — the\n * pitch moves while the previous syllable's vowel continues (Swarabitan\n * writes these with a leading hyphen, e.g. `-sfa`).\n */\n sustain?: boolean;\n /** বিরাম: a rest of `durationMatra` beats. */\n rest?: boolean;\n /** কণ স্বর: a grace note attached before this note. */\n kan?: Svara;\n /** মীড় (glide/slur) endpoint. */\n meend?: 'start' | 'end';\n /** Barline. A bar token usually has no `svara`. */\n bar?: Bar;\n /** Repeat-bracket edges opening/closing on this token. */\n brackets?: Bracket[];\n /** Lyric syllable aligned under this note */\n lyric?: string;\n /** Lossless passthrough of the source cell (e.g. raw Swarabitan code). */\n raw?: string;\n /**\n * Annotation notes rendered above this column: alt-on-repeat passages\n * (legend: পরিবর্তিত স্বর in [ ] শিরোদেশে), stop marks, beat numbers.\n */\n above?: Note[];\n /** Annotation notes rendered below this column. */\n below?: Note[];\n}\n\nexport const noteSchema: z.ZodType<Note> = z.lazy(() =>\n z\n .object({\n svara: svaraSchema.optional(),\n komal: z.boolean().optional(),\n tivra: z.boolean().optional(),\n microtone: microtoneSchema.optional(),\n durationMatra: z.number().positive().optional(),\n sustain: z.boolean().optional(),\n rest: z.boolean().optional(),\n kan: svaraSchema.optional(),\n meend: z.enum(['start', 'end']).optional(),\n bar: barSchema.optional(),\n brackets: z.array(bracketSchema).optional(),\n lyric: z.string().optional(),\n raw: z.string().optional(),\n above: z.array(noteSchema).optional(),\n below: z.array(noteSchema).optional(),\n })\n .refine(\n (n) =>\n n.svara !== undefined ||\n n.rest === true ||\n n.sustain === true ||\n n.bar !== undefined ||\n n.raw !== undefined ||\n (n.brackets !== undefined && n.brackets.length > 0) ||\n (n.above !== undefined && n.above.length > 0) ||\n (n.below !== undefined && n.below.length > 0) ||\n n.lyric !== undefined,\n {\n message:\n 'note must carry one of: svara, rest, sustain, bar, raw, lyric, brackets, or a non-empty above/below',\n },\n ),\n);\n\n/** A written line of the song: a sequence of note tokens. */\nexport const rowSchema = z.object({\n /** Optional line label (e.g. a tuk/section marker). */\n label: z.string().optional(),\n notes: z.array(noteSchema),\n});\nexport type Row = z.infer<typeof rowSchema>;\n\n/** A structural section: আস্থায়ী / অন্তরা / সঞ্চারী / আভোগ, or free text. */\nexport const partSchema = z.object({\n name: z.string().optional(),\n rows: z.array(rowSchema),\n});\nexport type Part = z.infer<typeof partSchema>;\n\n/**\n * Taal definition. `numBeats` is the cycle length in মাত্রা; `bhaags` (if\n * present) must sum to `numBeats`; `sam`/`khaali` are 0-based beat indices.\n */\nexport const taalSchema = z\n .object({\n /** Player sample key, e.g. `dadra`, `teentaal`. */\n id: z.string(),\n /**\n * Which tabla loop variation to play, e.g. `pro` (CDN dir suffix). Optional\n * and additive — omitted means the taal's default variation, so existing\n * docs are unaffected. The player honors it but never exposes a variation\n * picker; selecting a non-default variation is the consumer's premium policy.\n */\n variation: z.string().optional(),\n numBeats: z.number().int().positive(),\n /** Vibhag groupings; if given, they sum to numBeats. */\n bhaags: z.array(z.number().int().positive()).optional(),\n /** Sam (cycle start) beat index, 0-based. */\n sam: z.number().int().nonnegative().optional(),\n /** Khaali (wave) beat indices, 0-based. */\n khaali: z.array(z.number().int().nonnegative()).optional(),\n })\n .refine((t) => t.bhaags === undefined || t.bhaags.reduce((a, b) => a + b, 0) === t.numBeats, {\n message: 'bhaags must sum to numBeats',\n });\nexport type Taal = z.infer<typeof taalSchema>;\n\n/** Document-level metadata. */\nexport const metaSchema = z.object({\n title: z.string(),\n /** Cross-reference to a gitabitan.io song content id (filename, immutable). */\n songId: z.string().optional(),\n /** Source NLTR node/song id. */\n nltrId: z.number().int().optional(),\n taal: taalSchema.optional(),\n /**\n * The taal name exactly as printed in the source (e.g. `তালমুক্ত`,\n * `ষষ্ঠী(২/৪)`). Always set by the NLTR converter; `taal` is set only\n * when the name resolves to a known definition.\n */\n taalName: z.string().optional(),\n /** Base pitch for playback, e.g. `C`, `C#`, or the player's `cs` form. */\n tonic: z.string().optional(),\n /** Default playback tempo in matra/min. Player-only — the viewer ignores it.\n * The player adopts it on `load()` (precedence: constructor `bpm` → `setBpm`\n * tweak → this → 90). `null` is the converter's blank placeholder = unset. */\n bpm: z.number().positive().nullable().optional(),\n raag: z.string().optional(),\n /** আবর্তন: number of taal cycles, when the source states it. */\n avartan: z.number().int().positive().optional(),\n /** স্বরলিপিকার (notation author). */\n notationBy: z.string().optional(),\n /** Provenance note or URL. */\n source: z.string().optional(),\n});\nexport type Meta = z.infer<typeof metaSchema>;\n\n/** A complete swaralipi document. */\nexport const swaralipiSchema = z.object({\n /** Spec version this document targets (see SPEC_VERSION in ./index). */\n version: z.string(),\n meta: metaSchema,\n parts: z.array(partSchema),\n});\nexport type Swaralipi = z.infer<typeof swaralipiSchema>;\n","/**\n * @ugfoundation/swaralipi-js/spec\n *\n * The swaralipi JSON spec: Zod schemas, inferred TS types, and parse helpers.\n */\nimport { swaralipiSchema, type Swaralipi } from './schema.js';\n\n/** Current spec version. Documents declare the version they target. */\nexport const SPEC_VERSION = '0.3.0';\n\nexport {\n octaveSchema,\n svaraLetterSchema,\n svaraSchema,\n microtoneSchema,\n barSchema,\n bracketSchema,\n noteSchema,\n rowSchema,\n partSchema,\n taalSchema,\n metaSchema,\n swaralipiSchema,\n} from './schema.js';\n\nexport type {\n Octave,\n SvaraLetter,\n Svara,\n Microtone,\n Bar,\n Bracket,\n Note,\n Row,\n Part,\n Taal,\n Meta,\n Swaralipi,\n} from './schema.js';\n\nexport { TAALS, type TaalId } from './taals.js';\n\n/** Parse + validate unknown data into a `Swaralipi`. Throws `ZodError` on failure. */\nexport function parseSwaralipi(data: unknown): Swaralipi {\n return swaralipiSchema.parse(data);\n}\n\n/** Non-throwing variant: returns Zod's `{ success, data | error }` result. */\nexport function safeParseSwaralipi(data: unknown) {\n return swaralipiSchema.safeParse(data);\n}\n","/**\n * Per-language notation encoding for the viewer.\n *\n * Every language renders its notation through a dedicated, purpose-built\n * font whose glyphs ARE the akarmatrik/Bhatkhande marks — so composeCluster\n * emits that font's ASCII encoding and the font does all the hard work\n * (komal/tivra forms, octave reph/dots, matra). This is why the viewer no\n * longer touches Unicode cluster composition at all: the old reph-over-\n * vowel, hasanta-before-matra and dotted-circle hazards simply don't exist\n * when the font supplies precomposed glyphs keyed by plain ASCII.\n *\n * - bn → NLTR's **Swarabitan** (the akarmatrik font this project decodes).\n * Letters s r g m p q n = স র গ ম প ধ ন (q=ধ); komal v t d u = ঋ জ্ঞ দ ণ;\n * tivra ma k = the authentic কড়ি-ম conjunct (ম-based — has NO Unicode\n * form, which is what forced this whole approach); suffix f = taar reph,\n * h = mandra hasanta; trailing a = the আ-কার matra carrier. See codec.ts.\n * - hi/en → **Ome Bhatkhande** Hindi/English (SIL OFL 1.1, © Omenad —\n * github.com/omenad/fonts). Same clean keymap for both: lowercase\n * s r g m p d n = the seven shuddha swaras, uppercase R G M D N = komal\n * Re/Ga, tivra Ma, komal Dha/Ni; octave suffix u/l = taar/mandra dot,\n * U/L = ati (two dots). Bhatkhande has no আ-কার, so no matra is appended.\n *\n * The font is applied by CSS keyed on `.sw-sheet`'s `lang` (see styles.ts);\n * composeCluster only chooses the ASCII. The single residual CSS mark is the\n * bn ati-octave extra dot (Swarabitan's f/h are single reph/hasanta only).\n */\nimport type { Octave, SvaraLetter } from '../spec/index.js';\n\n/** Akarmatrik/Bhatkhande grid languages, rendered synchronously by renderToHtml. */\nexport type GridLang = 'bn' | 'hi' | 'en';\n\n/** All viewer languages. `staff` = Western staff notation (async, via abcjs). */\nexport type ViewerLang = GridLang | 'staff';\n\n/** bn Swarabitan glyph keys (shuddha / komal / tivra). Missing komal/tivra\n * entries fall back to the shuddha key (those alterations don't occur). */\nconst SWARABITAN_SHUDDHA: Record<SvaraLetter, string> = {\n s: 's', r: 'r', g: 'g', m: 'm', p: 'p', d: 'q', n: 'n', // q = ধ\n};\nconst SWARABITAN_KOMAL: Partial<Record<SvaraLetter, string>> = {\n r: 'v', g: 't', d: 'd', n: 'u', // ঋ জ্ঞ দ ণ\n};\nconst SWARABITAN_TIVRA: Partial<Record<SvaraLetter, string>> = { m: 'k' }; // কড়ি-ম\n\n/** hi/en Ome Bhatkhande octave suffix (u/l single dot, U/L two dots). */\nconst BHATKHANDE_OCTAVE: Record<Octave, string> = {\n madhyam: '',\n taar: 'u',\n mandra: 'l',\n 'ati-taar': 'U',\n 'ati-mandra': 'L',\n};\n/** Letters that have a komal (flat) glyph in Bhatkhande = uppercase key. */\nconst BHATKHANDE_HAS_KOMAL = new Set<SvaraLetter>(['r', 'g', 'd', 'n']);\n\n/** Digits 0-9 in the target script (beat labels, avartan). */\nexport const DIGITS: Record<GridLang, string> = {\n bn: '০১২৩৪৫৬৭৮৯',\n hi: '०१२३४५६७८९',\n en: '0123456789',\n};\n\nexport interface LangMarks {\n /** Melisma / no-new-attack dash before a sustained cluster. */\n hyphen: string;\n /** Lyric continuation mark shown under sustains (the source uses ৹). */\n melisma: string;\n /** ছেদ cut/articulation mark (two stacked rings, ঃ-shaped). */\n cut: string;\n}\n\nexport const MARKS: Record<GridLang, LangMarks> = {\n bn: { hyphen: '-', melisma: '৹', cut: 'ঃ' },\n hi: { hyphen: '-', melisma: '॰', cut: 'ः' },\n en: { hyphen: '-', melisma: '·', cut: ':' },\n};\n\n/** Header labels (NLTR prints নাম / তাল / আবর্তন …). */\nexport const LABELS: Record<\n GridLang,\n { title: string; taal: string; raag: string; avartan: string; notationBy: string }\n> = {\n bn: { title: 'নাম', taal: 'তাল', raag: 'রাগ', avartan: 'আবর্তন', notationBy: 'স্বরলিপিকার' },\n hi: { title: 'नाम', taal: 'ताल', raag: 'राग', avartan: 'आवर्तन', notationBy: 'स्वरलिपिकार' },\n en: { title: 'Song', taal: 'Taal', raag: 'Raag', avartan: 'Avartan', notationBy: 'Notator' },\n};\n\n/** A composed notation cluster: the font's ASCII text plus any residual CSS\n * classes the font itself cannot express (only the bn ati-octave dot). */\nexport interface Cluster {\n text: string;\n classes: string[];\n}\n\nexport interface ComposeOptions {\n komal?: boolean;\n tivra?: boolean;\n octave: Octave;\n /** Append the আ-কার matra carrier (bn group-final notes only). */\n withMatra: boolean;\n lang: GridLang;\n}\n\n/**\n * Compose one svara into its notation-font ASCII. bn = Swarabitan\n * (letter + f/h octave + a matra); hi/en = Ome Bhatkhande (case-encoded\n * letter + u/l/U/L octave, no matra). The font renders the actual glyph.\n */\nexport function composeCluster(letter: SvaraLetter, opts: ComposeOptions): Cluster {\n const classes: string[] = [];\n\n if (opts.lang === 'bn') {\n let text =\n (opts.tivra && SWARABITAN_TIVRA[letter]) ||\n (opts.komal && SWARABITAN_KOMAL[letter]) ||\n SWARABITAN_SHUDDHA[letter];\n if (opts.octave === 'taar' || opts.octave === 'ati-taar') text += 'f';\n else if (opts.octave === 'mandra' || opts.octave === 'ati-mandra') text += 'h';\n // Swarabitan's f/h are single reph/hasanta; ati adds a CSS extra dot.\n if (opts.octave === 'ati-taar') classes.push('sw-ati-taar');\n if (opts.octave === 'ati-mandra') classes.push('sw-ati-mandra');\n if (opts.withMatra) text += 'a';\n return { text, classes };\n }\n\n // hi / en — Ome Bhatkhande.\n let base: string = letter;\n if (opts.tivra && letter === 'm') base = 'M';\n else if (opts.komal && BHATKHANDE_HAS_KOMAL.has(letter)) base = base.toUpperCase();\n return { text: base + BHATKHANDE_OCTAVE[opts.octave], classes };\n}\n\n/** Map ASCII digits in `s` to the target script's digits. */\nexport function localizeDigits(s: string, lang: GridLang): string {\n const digits = DIGITS[lang];\n return s.replace(/[0-9]/g, (d) => digits[d.charCodeAt(0) - 48]!);\n}\n","/**\n * Pure spec-JSON → HTML renderer. No DOM, no side effects: usable for SSR\n * (Astro/static sites emit `renderToHtml(doc)` next to a\n * `<style>${SWARALIPI_CSS}</style>`) and unit-testable in plain Node.\n *\n * Layout model (mirrors NLTR's 4-row systems): each spec `Row` becomes one\n * CSS grid with **one column per top-level note** and four grid rows —\n * above-annotations / notation / below (slur arcs, marks) / lyric. Source\n * cells (groups of sub-notes sharing one matra) become column *spans*, so\n * per-sub-note lyric alignment and P2.3's per-note highlight targets fall\n * out of the column model for free.\n *\n * Rendering is spec-driven (semantics, not `raw`): grouping derives from\n * `durationMatra` accumulation so hand-authored documents without `raw`\n * render identically. `raw` is consulted only for (a) raw-only fallback\n * notes (never dropped — dimmed, in Swarabitan when loaded), (b) the ছেদ\n * cut mark and beat labels, whose grammar lives in raw (see codec.ts).\n */\nimport type { Meta, Note, Row, Swaralipi } from '../spec/index.js';\nimport {\n composeCluster,\n LABELS,\n localizeDigits,\n MARKS,\n type GridLang,\n type LangMarks,\n type ViewerLang,\n} from './glyphs.js';\n\nexport interface RenderOptions {\n /** Notation + UI language. Default `bn`. */\n lang?: ViewerLang;\n /** Render the NLTR-style নাম/তাল/আবর্তন header block. Default true. */\n showHeader?: boolean;\n /**\n * Lyric/title transliterator for `hi`/`en` (see loadLyricTransliterator).\n * Without it, non-bn renders keep Bengali lyrics (graceful interim).\n */\n transliterate?: (bengaliText: string) => string;\n}\n\nconst NBSP = '\\u00A0';\nconst EPS = 1e-6;\n\nconst isIntegral = (x: number) => Math.abs(x - Math.round(x)) < EPS;\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/* ------------------------------------------------------------------ */\n/* Cell grouping */\n/* ------------------------------------------------------------------ */\n\nexport interface Cell {\n kind: 'bar' | 'group' | 'raw' | 'carrier';\n /** Index of the cell's first note within the row's notes array. */\n start: number;\n notes: Note[];\n}\n\nconst isPitched = (n: Note) => n.svara !== undefined || n.rest === true || n.sustain === true;\n\n/**\n * The raw text a raw-only note should display, or undefined when there is\n * nothing to show beyond what semantics already render (a bracket-only\n * chunk's raw is fully expressed by its bracket glyphs).\n */\nfunction rawDisplay(note: Note): string | undefined {\n if (note.raw === undefined) return undefined;\n if ((note.brackets?.length ?? 0) > 0 && /^[{}()[\\]]*$/.test(note.raw)) return undefined;\n return note.raw;\n}\n\n/**\n * Group a row's notes into rendered cells using a fractional-duration\n * accumulator (raw-independent — works for hand-authored docs):\n * - bar / raw-only / carrier notes force-close and form singleton cells;\n * - full-matra notes are singleton groups;\n * - fractional notes accumulate until the sum reaches an integer matra\n * boundary (epsilon for 1/3, 0.2 chains), then the group closes.\n * The converter emits k notes × 1/k per source cell, so groups coincide\n * with source cells; an incomplete trailing group still closes at row end\n * (the matra carrier lands on its last note).\n */\nexport function groupRowIntoCells(notes: Note[]): Cell[] {\n const cells: Cell[] = [];\n let cur: Cell | undefined;\n let acc = 0;\n const close = () => {\n if (cur) {\n cells.push(cur);\n cur = undefined;\n }\n acc = 0;\n };\n notes.forEach((note, i) => {\n if (note.bar !== undefined) {\n close();\n cells.push({ kind: 'bar', start: i, notes: [note] });\n return;\n }\n if (!isPitched(note)) {\n close();\n cells.push({ kind: rawDisplay(note) !== undefined ? 'raw' : 'carrier', start: i, notes: [note] });\n return;\n }\n const d = note.durationMatra ?? 1;\n if (isIntegral(d)) {\n close();\n cells.push({ kind: 'group', start: i, notes: [note] });\n return;\n }\n cur ??= { kind: 'group', start: i, notes: [] };\n cur.notes.push(note);\n acc += d;\n if (acc > EPS && isIntegral(acc)) close();\n });\n close();\n return cells;\n}\n\n/* ------------------------------------------------------------------ */\n/* Arc (slur) resolution */\n/* ------------------------------------------------------------------ */\n\nexport interface Arc {\n /** 1-based grid column of the arc's first / last note column. */\n startCol: number;\n endCol: number;\n /** True when the matching end lies on a previous / following system. */\n openLeft: boolean;\n openRight: boolean;\n /** Fill-segments-only row: render a straight underline, no curled ends. */\n line?: boolean;\n}\n\n/** Below-annotation raws that are arc drawing segments (codec known-raw):\n * w/x = left/right curled ends, the rest are straight fill pieces. */\nconst ARC_RAW_RE = /^[wWxXyYjJeEzZ$=_<>`\\\\]+$/;\nconst isArcRaw = (raw: string | undefined): raw is string =>\n raw !== undefined && ARC_RAW_RE.test(raw);\n\n/**\n * Resolve under-arcs for one row. Sources, scanned left→right:\n * - below-annotation raws: `w` opens at its cell's first column, `x`\n * closes at its cell's last column (\"xw\" in one cell = close-then-open);\n * - spec `meend: 'start' | 'end'` fields feed the same scan as synthetic\n * w/x at the note's own column.\n * Unmatched `x` → arc from column 1 with a squared-off (open) left end;\n * unclosed `w` → arc to the last column with an open right end — both\n * match the print's behavior when an arc continues across a system wrap.\n * A row with fill segments but no ends at all renders one straight line.\n */\nexport function resolveArcs(cells: Cell[], noteCount: number): Arc[] {\n const arcs: Arc[] = [];\n let openStart: number | undefined;\n let sawEnds = false;\n const fillCols: number[] = [];\n\n const openAt = (col: number) => {\n sawEnds = true;\n if (openStart === undefined) openStart = col;\n };\n const closeAt = (col: number) => {\n sawEnds = true;\n if (openStart !== undefined) {\n arcs.push({ startCol: openStart, endCol: col, openLeft: false, openRight: false });\n openStart = undefined;\n } else {\n arcs.push({ startCol: 1, endCol: col, openLeft: true, openRight: false });\n }\n };\n\n for (const cell of cells) {\n const firstCol = cell.start + 1;\n const lastCol = cell.start + cell.notes.length;\n cell.notes.forEach((note, j) => {\n const col = cell.start + j + 1;\n if (note.meend === 'start') openAt(col);\n else if (note.meend === 'end') closeAt(col);\n for (const b of note.below ?? []) {\n if (!isArcRaw(b.raw)) continue;\n for (const ch of b.raw) {\n if (ch === 'w' || ch === 'W') openAt(firstCol);\n else if (ch === 'x' || ch === 'X') closeAt(lastCol);\n else fillCols.push(firstCol, lastCol);\n }\n }\n });\n }\n\n if (openStart !== undefined) {\n arcs.push({ startCol: openStart, endCol: Math.max(noteCount, 1), openLeft: false, openRight: true });\n } else if (!sawEnds && fillCols.length > 0) {\n arcs.push({\n startCol: Math.min(...fillCols),\n endCol: Math.max(...fillCols),\n openLeft: true,\n openRight: true,\n line: true,\n });\n }\n return arcs;\n}\n\n/* ------------------------------------------------------------------ */\n/* Raw-derived marks (codec grammar: src/convert/codec.ts) */\n/* ------------------------------------------------------------------ */\n\n/** Count ছেদ cut marks in a decoded chunk's raw — every `i`/`:` in a chunk\n * that decoded to notes is a cut mark per the body grammar. Rendered as\n * group-trailing marks (positional approximation; raw keeps the truth). */\nfunction cutMarkCount(raw: string | undefined): number {\n if (raw === undefined) return 0;\n return (raw.match(/[i:]/g) ?? []).length;\n}\n\n/** Beat-number label (above rows): pure digits + optional sam tick. */\nfunction parseBeatLabel(raw: string): { digits: string; sam: boolean } | undefined {\n const m = raw.match(/^([0-9]{1,2})([fF])?:?$/);\n if (!m) return undefined;\n return { digits: m[1]!, sam: m[2] !== undefined };\n}\n\n/* ------------------------------------------------------------------ */\n/* Note / annotation fragments */\n/* ------------------------------------------------------------------ */\n\ninterface Ctx {\n lang: GridLang;\n marks: LangMarks;\n tr: (s: string) => string;\n}\n\nconst BRACKET_GLYPHS = {\n open: { repeat: '{', skip: '(', alt: '[' },\n close: { repeat: '}', skip: ')', alt: ']' },\n} as const;\n\nfunction bracketGlyphs(note: Note, edge: 'open' | 'close'): string {\n if (!note.brackets) return '';\n return note.brackets\n .filter((b) => b.edge === edge)\n .map((b) => `<span class=\"sw-br\">${BRACKET_GLYPHS[edge][b.kind]}</span>`)\n .join('');\n}\n\n/** A lone matra glyph: the note's own notation font supplies it — bn = the\n * Swarabitan আ-কার (`a`), hi/en = an en-dash (Bhatkhande has no matra sign).\n * Used for rests (বিরাম = detached matra), আ-কার holds and n>1 durations. */\nfunction matraGlyph(ctx: Ctx): string {\n return ctx.lang === 'bn' ? '<span class=\"sw-cl\">a</span>' : '<span class=\"sw-iso\">–</span>';\n}\n\nfunction renderKan(note: Note, ctx: Ctx): string {\n if (!note.kan) return '';\n const [octave, letter] = note.kan;\n const c = composeCluster(letter, { octave, withMatra: false, lang: ctx.lang });\n return `<span class=\"${['sw-kan', ...c.classes].join(' ')}\">${c.text}</span>`;\n}\n\ninterface PitchedOpts {\n /** This note ends its matra group → carries the আ-কার. */\n withMatra: boolean;\n /** ছেদ cut marks rendered after this (group-final) note. */\n cuts: number;\n}\n\n/** Inner HTML of one pitched/sustain/rest note: brackets, kan, melisma\n * hyphen, notation-font cluster, extra matras, cut marks, closing brackets.\n * The font (keyed on lang in styles.ts) renders komal/tivra/octave/matra —\n * composeCluster only picks the ASCII, so there is no Unicode hazard here. */\nfunction renderPitchedInner(note: Note, opts: PitchedOpts, ctx: Ctx): string {\n let inner = bracketGlyphs(note, 'open');\n inner += renderKan(note, ctx);\n if (note.sustain === true) inner += `<span class=\"sw-hy\">${ctx.marks.hyphen}</span>`;\n if (note.svara !== undefined) {\n const [octave, letter] = note.svara;\n const c = composeCluster(letter, {\n komal: note.komal,\n tivra: note.tivra,\n octave,\n withMatra: opts.withMatra,\n lang: ctx.lang,\n });\n inner += `<span class=\"${['sw-cl', ...c.classes].join(' ')}\">${c.text}</span>`;\n } else if (note.rest === true) {\n inner += matraGlyph(ctx);\n } else if (note.sustain === true && opts.withMatra) {\n inner += matraGlyph(ctx);\n }\n if (note.microtone !== undefined) {\n // Legend: অল্পকোমল = superscript ১ after the letter, অতিকোমল = ২.\n const mark = localizeDigits(note.microtone === 'atikomal' ? '2' : '1', ctx.lang);\n inner += `<span class=\"sw-micro\" title=\"${note.microtone}\">${mark}</span>`;\n }\n const d = note.durationMatra ?? 1;\n if (isIntegral(d) && d > 1 + EPS) inner += matraGlyph(ctx).repeat(Math.round(d) - 1);\n if (opts.cuts > 0) inner += `<span class=\"sw-cut\">${NBSP}${ctx.marks.cut}</span>`.repeat(opts.cuts);\n inner += bracketGlyphs(note, 'close');\n return inner;\n}\n\n/** Swarabitan glyphs (the .sw-bar font): A = vibhag dari, l = I cycle\n * danda, L = II section pair, song-end = II II. */\nconst BAR_GLYPHS = { dari: 'A', single: 'l', double: 'L', quad: 'LL' } as const;\n\nfunction renderBarInner(note: Note): string {\n return `${bracketGlyphs(note, 'open')}${BAR_GLYPHS[note.bar!]}${bracketGlyphs(note, 'close')}`;\n}\n\n/**\n * Render an annotation note list (above/below content) as inline mini\n * notation: beat labels, stop marks, bars, recursive note groups, raw\n * fallback. Reuses the same grouping as the main row.\n */\nfunction renderAnnotation(notes: Note[], ctx: Ctx): string {\n const parts: string[] = [];\n for (const cell of groupRowIntoCells(notes)) {\n if (cell.kind === 'bar') {\n const note = cell.notes[0]!;\n parts.push(`<span class=\"sw-bar sw-bar--${note.bar}\">${renderBarInner(note)}</span>`);\n continue;\n }\n if (cell.kind === 'group') {\n const cuts = cutMarkCount(cell.notes[0]!.raw);\n cell.notes.forEach((note, j) => {\n const last = j === cell.notes.length - 1;\n parts.push(\n `<span class=\"sw-n\">${renderPitchedInner(note, { withMatra: last, cuts: last ? cuts : 0 }, ctx)}</span>`,\n );\n });\n continue;\n }\n const note = cell.notes[0]!;\n const raw = rawDisplay(note);\n if (raw !== undefined) {\n const beat = parseBeatLabel(raw);\n if (beat) {\n parts.push(\n `<span class=\"sw-beat${beat.sam ? ' sw-sam' : ''}\">${localizeDigits(beat.digits, ctx.lang)}</span>`,\n );\n } else if (/^\\|+$/.test(raw)) {\n parts.push(`<span class=\"sw-stop\">${'<i></i>'.repeat(raw.length)}</span>`);\n } else {\n parts.push(`<span class=\"sw-raw\" title=\"${escapeHtml(raw)}\">${escapeHtml(raw)}</span>`);\n }\n continue;\n }\n const brackets = bracketGlyphs(note, 'open') + bracketGlyphs(note, 'close');\n if (brackets !== '') parts.push(`<span class=\"sw-carrier\">${brackets}</span>`);\n }\n return parts.join('');\n}\n\n/** Lyric cell text: the ৹ melisma mark is notation (not language text) —\n * swap it per-lang, transliterating only the linguistic remainder. */\nfunction lyricText(s: string, ctx: Ctx): string {\n return s\n .split('৹')\n .map((part) => (part === '' ? '' : ctx.tr(part)))\n .join(ctx.marks.melisma);\n}\n\n/* ------------------------------------------------------------------ */\n/* Row / header / document */\n/* ------------------------------------------------------------------ */\n\nfunction renderRow(row: Row, partIdx: number, rowIdx: number, ctx: Ctx): string {\n const cells = groupRowIntoCells(row.notes);\n const arcs = resolveArcs(cells, row.notes.length);\n const above: string[] = [];\n const notation: string[] = [];\n const below: string[] = [];\n const lyric: string[] = [];\n\n for (const cell of cells) {\n const firstCol = cell.start + 1;\n const lastCol = cell.start + cell.notes.length;\n const cellSpan =\n lastCol > firstCol ? `grid-column:${firstCol} / ${lastCol + 1}` : `grid-column:${firstCol}`;\n const cuts = cell.kind === 'group' ? cutMarkCount(cell.notes[0]!.raw) : 0;\n\n cell.notes.forEach((note, j) => {\n const col = cell.start + j + 1;\n const path = `${partIdx}.${rowIdx}.${cell.start + j}`;\n const cellEdges = `${j === 0 ? ' sw-cs' : ''}${j === cell.notes.length - 1 ? ' sw-ce' : ''}`;\n\n if (cell.kind === 'bar') {\n notation.push(\n `<span class=\"sw-bar sw-bar--${note.bar}${cellEdges}\" data-note=\"${path}\" style=\"grid-column:${col}\">${renderBarInner(note)}</span>`,\n );\n } else if (cell.kind === 'group') {\n const last = j === cell.notes.length - 1;\n notation.push(\n `<span class=\"sw-n${cellEdges}\" data-note=\"${path}\" style=\"grid-column:${col}\">${renderPitchedInner(note, { withMatra: last, cuts: last ? cuts : 0 }, ctx)}</span>`,\n );\n } else {\n const raw = rawDisplay(note);\n const inner =\n bracketGlyphs(note, 'open') +\n (raw !== undefined\n ? `<span class=\"sw-raw\" title=\"${escapeHtml(raw)}\">${escapeHtml(raw)}</span>`\n : '') +\n bracketGlyphs(note, 'close');\n if (inner !== '') {\n notation.push(\n `<span class=\"sw-n sw-carrier${cellEdges}\" data-note=\"${path}\" style=\"grid-column:${col}\">${inner}</span>`,\n );\n }\n }\n\n if (note.lyric !== undefined) {\n // Share the cell-gap inset (sw-cs) with the notation above, so the\n // lyric column-aligns with its note instead of drifting one gap left.\n lyric.push(\n `<span class=\"sw-lyr${j === 0 ? ' sw-cs' : ''}\" style=\"grid-column:${col}\">${escapeHtml(lyricText(note.lyric, ctx))}</span>`,\n );\n }\n if (note.above !== undefined && note.above.length > 0) {\n above.push(`<span class=\"sw-above\" style=\"${cellSpan}\">${renderAnnotation(note.above, ctx)}</span>`);\n }\n const nonArc = (note.below ?? []).filter((b) => !isArcRaw(b.raw));\n if (nonArc.length > 0) {\n below.push(`<span class=\"sw-below\" style=\"${cellSpan}\">${renderAnnotation(nonArc, ctx)}</span>`);\n }\n });\n }\n\n for (const arc of arcs) {\n const cls = [\n 'sw-arc',\n arc.openLeft ? 'sw-arc--openl' : '',\n arc.openRight ? 'sw-arc--openr' : '',\n arc.line === true ? 'sw-arc--line' : '',\n ]\n .filter(Boolean)\n .join(' ');\n below.push(`<span class=\"${cls}\" style=\"grid-column:${arc.startCol} / ${arc.endCol + 1}\"></span>`);\n }\n\n const label =\n row.label !== undefined ? `<span class=\"sw-label\">${escapeHtml(ctx.tr(row.label))}</span>` : '';\n return `<div class=\"sw-row\">${label}<div class=\"sw-grid\">${above.join('')}${notation.join('')}${below.join('')}${lyric.join('')}</div></div>`;\n}\n\nfunction renderHeader(meta: Meta, ctx: Ctx): string {\n return renderMetaHeader(meta, ctx.lang, ctx.tr);\n}\n\n/**\n * The নাম / তাল / রাগ / আবর্তন / স্বরলিপিকার header block, shared by the\n * akarmatrik grid and the staff view so both show the same metadata (localized\n * labels; values injected pre-localized by the consumer). Exported so the\n * staff renderer can reuse the exact markup + styling.\n */\nexport function renderMetaHeader(\n meta: Meta,\n lang: GridLang,\n tr: (s: string) => string = (s) => s,\n): string {\n const L = LABELS[lang];\n const rows: string[] = [];\n const add = (label: string, value: string) =>\n rows.push(\n `<div class=\"sw-meta-row\"><span class=\"sw-meta-label\">${escapeHtml(label)}</span><span class=\"sw-meta-value\">${escapeHtml(value)}</span></div>`,\n );\n add(L.title, tr(meta.title));\n const taal = meta.taalName ?? meta.taal?.id;\n if (taal !== undefined) add(L.taal, tr(taal));\n if (meta.raag !== undefined) add(L.raag, tr(meta.raag));\n if (meta.avartan !== undefined) add(L.avartan, localizeDigits(String(meta.avartan), lang));\n if (meta.notationBy !== undefined) add(L.notationBy, tr(meta.notationBy));\n return `<header class=\"sw-header\">${rows.join('')}</header>`;\n}\n\n/** Render a complete swaralipi document to an HTML string. Pair with\n * SWARALIPI_CSS (shadow DOM does this automatically; SSR consumers emit a\n * `<style>` themselves). All source text is HTML-escaped. */\nexport function renderToHtml(doc: Swaralipi, opts: RenderOptions = {}): string {\n // Grid renderer handles bn/hi/en; `staff` is async (see renderStaffHtml) and\n // reaches this path only via the print/element wrappers, which fall back to bn.\n const lang: GridLang = opts.lang === 'hi' || opts.lang === 'en' ? opts.lang : 'bn';\n const tr = lang !== 'bn' && opts.transliterate ? opts.transliterate : (s: string) => s;\n const ctx: Ctx = { lang, marks: MARKS[lang], tr };\n\n const out: string[] = [`<div class=\"sw-sheet\" lang=\"${lang}\">`];\n if (opts.showHeader !== false) out.push(renderHeader(doc.meta, ctx));\n doc.parts.forEach((part, p) => {\n out.push('<section class=\"sw-part\">');\n if (part.name !== undefined)\n out.push(`<h3 class=\"sw-part-name\">${escapeHtml(ctx.tr(part.name))}</h3>`);\n part.rows.forEach((row, r) => out.push(renderRow(row, p, r, ctx)));\n out.push('</section>');\n });\n out.push('</div>');\n return out.join('');\n}\n","/**\n * Encapsulated stylesheet for the viewer. Injected into the\n * `<swaralipi-sheet>` shadow root automatically; SSR consumers emit it\n * themselves: `<style>${SWARALIPI_CSS}</style>` next to `renderToHtml()`.\n *\n * Theming hooks (CSS custom properties, all optional):\n * --sw-font font stack (default: Noto Sans Bengali + system Bengali)\n * --sw-size base font size\n * --sw-cell-gap horizontal gap between source cells\n * --sw-hl player-highlight background (P2.3)\n * --sw-rule header rule / muted line color\n *\n * All ink uses `currentColor`, so the sheet follows the host's text color\n * (dark mode included). The only octave mark drawn as a pseudo-element is\n * the bn ati-octave extra dot (Swarabitan's f/h glyphs are a single\n * reph/hasanta); everything else is a real glyph in the notation font.\n */\n\n/** Notation fonts, self-hosted on the project CDN (CORS-enabled), keyed by\n * the CSS `font-family` this stylesheet uses. bn = NLTR's Swarabitan; hi/en\n * = Ome Bhatkhande (SIL OFL 1.1, © Omenad — github.com/omenad/fonts).\n * Self-hosters: declare your own \\`@font-face\\` for any of these families\n * before this stylesheet / before defineSwaralipiSheet() and it wins. */\nexport const NOTATION_FONT_URLS: Record<string, string> = {\n Swarabitan: 'https://webfonts-4qq.pages.dev/swarabitan/Swarabitan.ttf',\n ome_bhatkhande_hindi: 'https://webfonts-4qq.pages.dev/ome-bhatkhande/OmeBhatkhandeHindi.ttf',\n ome_bhatkhande_english:\n 'https://webfonts-4qq.pages.dev/ome-bhatkhande/OmeBhatkhandeEnglish.ttf',\n};\n\n/** @deprecated use NOTATION_FONT_URLS.Swarabitan */\nexport const SWARABITAN_FONT_URL = NOTATION_FONT_URLS.Swarabitan;\n\n/* Each language renders its notation through one dedicated font — the\n * glyphs ARE the akarmatrik/Bhatkhande marks, keyed by plain ASCII (see\n * glyphs.ts). @font-face covers document use (SSR, print); the element also\n * registers these via the FontFace API because @font-face inside a shadow\n * root's adopted sheet is ignored. display:block — a flash of the ASCII\n * fallback ('kfa', 'srgm') would read as content. */\nconst FONT_FACES = Object.entries(NOTATION_FONT_URLS)\n .map(\n ([family, url]) =>\n `@font-face { font-family: ${family}; src: url('${url}') format('truetype'); font-display: block; }`,\n )\n .join('\\n');\n\nexport const SWARALIPI_CSS = `\n${FONT_FACES}\n\n.sw-sheet {\n font-family: var(--sw-font, 'Noto Sans Bengali', 'Kohinoor Bangla', 'Bangla Sangam MN', 'Nirmala UI', 'Noto Sans Devanagari', sans-serif);\n font-size: var(--sw-size, 1.125rem);\n line-height: 1.5;\n}\n\n/* ---- notation font, per language (the note clusters + grace notes) ---- */\n.sw-sheet[lang=\"bn\"] .sw-cl, .sw-sheet[lang=\"bn\"] .sw-kan { font-family: Swarabitan, var(--sw-font, sans-serif); }\n.sw-sheet[lang=\"hi\"] .sw-cl, .sw-sheet[lang=\"hi\"] .sw-kan { font-family: ome_bhatkhande_hindi, var(--sw-font, sans-serif); }\n.sw-sheet[lang=\"en\"] .sw-cl, .sw-sheet[lang=\"en\"] .sw-kan { font-family: ome_bhatkhande_english, var(--sw-font, sans-serif); }\n\n/* ---- header ---- */\n.sw-header {\n margin: 0 0 0.75em;\n padding: 0 0 0.5em;\n border-bottom: 1px solid var(--sw-rule, rgba(128, 128, 128, 0.35));\n font-size: 0.95em;\n}\n.sw-meta-row { display: flex; gap: 0.3em; }\n.sw-meta-label { font-weight: 600; min-width: 4.5em; }\n.sw-meta-label::after { content: ':'; font-weight: 400; margin-left: 0.15em; }\n\n.sw-part-name { font-size: 0.85em; font-weight: 600; margin: 1em 0 0.2em; opacity: 0.85; }\n\n/* ---- row grid: above / notation / below(arcs) / lyric ---- */\n.sw-row {\n display: flex;\n align-items: flex-start;\n overflow-x: auto;\n padding: 0.4em 0;\n}\n.sw-label { flex: none; margin-right: 0.8em; font-weight: 600; }\n.sw-grid {\n display: grid;\n grid-template-rows: auto auto auto auto;\n grid-auto-columns: max-content;\n align-items: end;\n}\n.sw-above { grid-row: 1; font-size: 0.62em; justify-self: start; white-space: nowrap; padding-left: 0.2em; }\n.sw-n { grid-row: 2; justify-self: center; white-space: nowrap; }\n.sw-arc,\n.sw-below { grid-row: 3; }\n.sw-lyr { grid-row: 4; justify-self: center; white-space: nowrap; padding-top: 0.3em; }\n.sw-below { font-size: 0.62em; justify-self: start; white-space: nowrap; padding-left: 0.2em; }\n\n/* inter-cell gap as padding on each cell's first notation item, so arcs\n * and above-spans crossing cells stay continuous */\n.sw-cs { padding-left: var(--sw-cell-gap, 0.55em); }\n\n/* ---- notation clusters & marks ---- */\n.sw-cl { position: relative; display: inline-block; }\n\n/* bn ati-octave: Swarabitan's f/h give a single reph/hasanta, so ati adds\n * one extra dot above (ati-taar) / below (ati-mandra). bn-only — hi/en get\n * the two-dot glyph natively from the U/L octave suffix. */\n.sw-ati-taar::before,\n.sw-ati-mandra::before {\n content: '';\n position: absolute;\n left: 0.25em;\n width: 0.16em;\n height: 0.16em;\n border-radius: 50%;\n background: currentColor;\n}\n.sw-ati-taar::before { top: -0.3em; }\n.sw-ati-mandra::before { bottom: -0.35em; }\n\n/* kan grace: small raised cluster left of the main note */\n.sw-kan {\n position: relative;\n display: inline-block;\n font-size: 0.58em;\n vertical-align: 0.75em;\n margin-right: 0.08em;\n}\n\n.sw-hy { padding-right: 0.02em; }\n.sw-iso { display: inline-block; margin-left: -0.18em; }\n.sw-cut { font-size: 0.8em; display: inline-block; margin-left: -0.15em; }\n.sw-br { opacity: 0.8; padding: 0 0.06em; }\n.sw-micro { font-size: 0.6em; vertical-align: super; opacity: 0.8; }\n\n/* raw fallback: never dropped, visibly non-notation. Swarabitan first —\n * raw IS that font's encoding, so undecoded cells show NLTR's own glyphs\n * (dimmed: semantics unverified); monospace ASCII when the font is out. */\n.sw-raw {\n font-family: Swarabitan, ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.72em;\n opacity: 0.55;\n}\n\n/* ---- bars: dari (A) and danda (l/L) Swarabitan glyphs ---- */\n/* horizontal gap before a bar comes from its own .sw-cs padding-left —\n * never reset it with a padding shorthand here */\n.sw-bar {\n grid-row: 2;\n font-family: Swarabitan, var(--sw-font, sans-serif);\n white-space: nowrap;\n padding-right: 0.1em;\n}\n.sw-bar--quad { letter-spacing: 0.15em; }\n\n/* ---- under-arcs (slurs decoded from w/x segments and meend) ---- */\n.sw-arc {\n align-self: start;\n height: 0.4em;\n margin: 0.05em 0.25em 0;\n border: 0.09em solid currentColor;\n border-top: none;\n border-bottom-left-radius: 0.6em;\n border-bottom-right-radius: 0.6em;\n opacity: 0.85;\n}\n.sw-arc--openl { border-left: none; border-bottom-left-radius: 0; }\n.sw-arc--openr { border-right: none; border-bottom-right-radius: 0; }\n.sw-arc--line { border-left: none; border-right: none; border-radius: 0; height: 0.22em; }\n\n/* ---- annotation content ---- */\n.sw-beat { position: relative; display: inline-block; padding: 0 0.1em; }\n.sw-sam::after {\n content: '';\n position: absolute;\n top: -0.45em;\n left: 50%;\n width: 0.1em;\n height: 0.4em;\n background: currentColor;\n transform: rotate(14deg);\n}\n.sw-stop i {\n display: inline-block;\n width: 0.07em;\n height: 1em;\n margin: 0 0.07em;\n background: currentColor;\n vertical-align: text-bottom;\n}\n\n/* ---- player sync (P2.3) ---- */\n.sw-hl { background: var(--sw-hl, rgba(255, 196, 64, 0.45)); border-radius: 0.15em; }\n/* Staff notes are SVG <g> — background doesn't paint there, so recolour the\n glyph fill/stroke instead (abcjs draws note heads/stems as filled paths). */\n.sw-staff .sw-hl, .sw-staff .sw-hl * { fill: var(--sw-hl-note, #d68400); stroke: var(--sw-hl-note, #d68400); }\n\n/* ---- element error box ---- */\n.sw-error {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n font-size: 0.85em;\n padding: 0.6em 0.8em;\n border: 1px solid rgba(200, 64, 64, 0.6);\n border-radius: 0.3em;\n color: #b33;\n background: rgba(200, 64, 64, 0.08);\n}\n`;\n\n/**\n * Print stylesheet — pair with `SWARALIPI_CSS` (renderPrintDocument injects\n * both). Gated on `@media print`, so it also works if a consumer drops it into\n * a page and prints that page directly.\n *\n * - `print-color-adjust: exact` forces the marks that are drawn as tiny\n * `background: currentColor` pseudo-elements (octave dots, arcs, danda\n * strokes, sam tick) to actually print — browsers drop backgrounds by\n * default, which would silently strip the notation's diacritics.\n * - rows are un-clipped (no scrollbar on paper) and kept whole across page\n * breaks; part headings stay with their first row.\n */\nexport const SWARALIPI_PRINT_CSS = `\n@page { margin: 16mm; }\n@media print {\n .sw-sheet, .sw-staff { -webkit-print-color-adjust: exact; print-color-adjust: exact; color: #000; }\n .sw-row { overflow: visible !important; break-inside: avoid; page-break-inside: avoid; }\n .sw-part { break-inside: auto; }\n .sw-part-name, .sw-header { break-after: avoid-page; page-break-after: avoid; }\n .sw-hl { background: none !important; }\n /* Keep each engraved staff system whole across a page break (the abcjs line\n is a <div> wrapping the <svg>, so the break rule must sit on the div). */\n .sw-staff-lines > div { break-inside: avoid; page-break-inside: avoid; }\n .sw-staff-meta { break-after: avoid-page; page-break-after: avoid; }\n}\n`;\n\n/** Staff-notation (abcjs) wrapper chrome: instrument/tempo header + a fluid\n * SVG. The engraving itself is drawn by abcjs; this only frames it. */\nexport const SWARALIPI_STAFF_CSS = `\n.sw-staff { color: currentColor; }\n.sw-staff-meta { display: flex; gap: 1.25em; align-items: baseline; margin: 0 0 .5em; font-size: .95em; opacity: .85; }\n.sw-staff-instrument { font-weight: 600; }\n.sw-staff-drums { opacity: .75; }\n.sw-staff-tempo { font-variant-numeric: tabular-nums; }\n/* abcjs (oneSvgPerLine) wraps the music into one <div><svg> per system; stack\n them as short, swaralipi-style lines. abcjs sets a fixed pixel height +\n overflow:hidden on each wrapper div — neutralise it so the viewBox'd SVG can\n scale to the container (and to the print page) instead of being clipped. */\n.sw-staff-lines > div { margin: 0 0 .35em; height: auto !important; overflow: visible !important; }\n/* Fill up to the engraved (staffwidth) size — shrink to fit a narrow container,\n but never stretch past natural width (abcToSvg pins per-SVG max-width in px),\n else a short last system balloons. */\n.sw-staff-lines svg { display: block; width: 100%; height: auto; }\n.sw-staff-missing { padding: 1em; border: 1px dashed currentColor; border-radius: 6px; opacity: .8; font-size: .9em; }\n.sw-staff-title { font-size: 1.15em; font-weight: 700; }\n.sw-staff-subtitle { opacity: .8; font-size: .95em; margin-top: .15em; }\n`;\n","/**\n * Pure svara → pitch math for the player. No Tone, no audio — unit-testable\n * in plain Node and shared by the scheduler.\n *\n * The model: a tonic (Sa) pitch-class + a per-note scale degree + octave\n * register + komal/tivra/microtone accidentals → an absolute MIDI number,\n * which the Tone.Sampler pitch-shifts from the nearest santoor sample.\n */\nimport type { Note, Octave, SvaraLetter } from '../spec/index.js';\n\n/** Octave register offset in octaves, relative to madhyam (middle). */\nexport const OCTAVE_OFFSET: Record<Octave, number> = {\n 'ati-mandra': -2,\n mandra: -1,\n madhyam: 0,\n taar: 1,\n 'ati-taar': 2,\n};\n\n/**\n * Shuddha (natural) scale degrees in semitones above Sa — the Bilawal/major\n * thaat that Rabindrasangeet swaralipi notates against. `d` = dha, `n` = ni\n * (standard sargam letter convention).\n */\nexport const SHUDDHA: Record<SvaraLetter, number> = {\n s: 0,\n r: 2,\n g: 4,\n m: 5,\n p: 7,\n d: 9,\n n: 11,\n};\n\n/** Sharp-spelled pitch-class names, index = semitone 0–11. */\nconst SHARP_NAMES = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] as const;\n\n/** Pitch-class lookup. Accepts sharps (`C#`, `Cs`, `cs`) and flats (`Db`). */\nconst PITCH_CLASS: Record<string, number> = {\n c: 0,\n 'c#': 1,\n db: 1,\n d: 2,\n 'd#': 3,\n eb: 3,\n e: 4,\n 'e#': 5,\n fb: 4,\n f: 5,\n 'f#': 6,\n gb: 6,\n g: 7,\n 'g#': 8,\n ab: 8,\n a: 9,\n 'a#': 10,\n bb: 10,\n b: 11,\n 'b#': 0,\n cb: 11,\n};\n\n/**\n * Parse a tonic string to a pitch-class 0–11. Accepts `C`, `C#`, `Db`, and\n * the player/sample lowercase-`s` sharp form (`cs`, `Cs`); case-insensitive.\n * Unknown input falls back to 0 (C).\n */\nexport function parseTonic(tonic: string | undefined): number {\n if (!tonic) return 0;\n const key = tonic.trim().toLowerCase().replace(/s/g, '#');\n return PITCH_CLASS[key] ?? 0;\n}\n\n/**\n * Semitone of a note relative to Sa (degree + accidentals), ignoring octave.\n * Returns null when the note carries no pitch (rest/sustain-hold/bar).\n *\n * Microtones (অল্পকোমল/অতিকোমল) are approximated to the komal pitch — a\n * documented v1 limitation (the sampler can't bend a sub-komal microtone\n * cleanly per note); matches the viewer's placeholder treatment.\n */\nexport function svaraSemitone(note: Note): number | null {\n if (note.svara === undefined) return null;\n const [, letter] = note.svara;\n let semi = SHUDDHA[letter];\n if (note.komal === true || note.microtone !== undefined) semi -= 1;\n if (note.tivra === true) semi += 1;\n return semi;\n}\n\n/**\n * Absolute MIDI for a note, or null when it has no pitch. madhyam Sa lands on\n * the tonic in octave `baseOctave` (C4 = MIDI 60). Out-of-sample registers\n * are produced by the Sampler pitch-shifting from the nearest recorded note.\n */\nexport function svaraToMidi(note: Note, tonicPc: number, baseOctave = 4): number | null {\n const semi = svaraSemitone(note);\n if (semi === null || note.svara === undefined) return null;\n const [octave] = note.svara;\n return (baseOctave + 1 + OCTAVE_OFFSET[octave]) * 12 + tonicPc + semi;\n}\n\n/** MIDI of a kan (grace) svara — a bare `Svara` tuple, no accidentals. */\nexport function kanToMidi(\n svara: Note['kan'],\n tonicPc: number,\n baseOctave = 4,\n): number | null {\n if (svara === undefined) return null;\n const [octave, letter] = svara;\n return (baseOctave + 1 + OCTAVE_OFFSET[octave]) * 12 + tonicPc + SHUDDHA[letter];\n}\n\n/** MIDI → Tone note name (`C#4`). */\nexport function midiToSampleName(midi: number): string {\n const pc = ((midi % 12) + 12) % 12;\n const octave = Math.floor(midi / 12) - 1;\n return `${SHARP_NAMES[pc]}${octave}`;\n}\n\n/** MIDI → santoor sample filename stem (`cs4`): lowercase, `#` → `s`. */\nexport function sampleFileName(midi: number): string {\n return midiToSampleName(midi).toLowerCase().replace('#', 's');\n}\n","/**\n * Pure spec-doc → playback timeline. No Tone, no audio — the player turns\n * this `Schedule` into Transport events, but it is fully unit-testable on its\n * own and mirrors the viewer's spec-driven (not raw-driven) reading.\n *\n * Timing unit is the মাত্রা (matra / beat). One global beat cursor runs across\n * every part and row: NLTR \"systems\" (rows) are wraps of one continuous line,\n * and parts (asthayi → antara …) play back-to-back, so the music never pauses\n * at a row or part boundary.\n *\n * Each audible column carries the same `data-note` path the viewer emits\n * (`part.row.note`, note = absolute index into `row.notes`; see\n * src/viewer/render.ts), so `SwaralipiPlayer` can drive `highlight()` directly.\n */\nimport type { Note, Swaralipi } from '../spec/index.js';\nimport { kanToMidi, parseTonic, svaraToMidi } from './pitch.js';\n\nexport interface PlayEvent {\n /** Onset in matra from the start of the document. */\n beat: number;\n /** Ring length in matra (extended by following আ-কার holds). */\n durationBeats: number;\n /** Pitch as MIDI, or null for a rest / আ-কার hold column. */\n midi: number | null;\n /** Grace-note MIDI struck just before the main attack, when present. */\n kan: number | null;\n /** `part.row.note` highlight path. */\n path: string;\n kind: 'note' | 'rest' | 'sustain';\n}\n\nexport interface Schedule {\n events: PlayEvent[];\n /** Total length in matra (the cursor's final value). */\n totalBeats: number;\n}\n\nexport interface ScheduleOptions {\n /** Tonic; accepts `C`, `C#`, `cs`… (see parseTonic). Default C. */\n tonic?: string;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n}\n\n/** A column that produces no sound and no time advance (bar, bracket-only,\n * carrier, raw-only). Mirrors the viewer's non-pitched, non-rest classes. */\nconst isSilent = (n: Note): boolean =>\n n.svara === undefined && n.rest !== true && n.sustain !== true;\n\n/**\n * Walk a document into a flat, time-ordered list of play events.\n *\n * - svara note → an attack at the cursor; advances by `durationMatra ?? 1`.\n * - rest → a silent column that still advances the cursor.\n * - sustain **with** svara (melisma) → a fresh attack (the pitch moves under\n * a held vowel); advances.\n * - sustain **without** svara (আ-কার hold) → no attack, but the previous\n * audible note's ring is extended; still emitted (midi null) so the lyric\n * column highlights; advances.\n * - bar / bracket-only / carrier / raw-only → ignored (no event, no advance).\n */\nexport function buildSchedule(doc: Swaralipi, opts: ScheduleOptions = {}): Schedule {\n const tonicPc = parseTonic(opts.tonic ?? doc.meta.tonic);\n const baseOctave = opts.baseOctave ?? 4;\n const events: PlayEvent[] = [];\n let cursor = 0;\n /** Index in `events` of the last pitched attack, for hold-extension. */\n let lastPitched = -1;\n\n doc.parts.forEach((part, p) => {\n part.rows.forEach((row, r) => {\n row.notes.forEach((note, i) => {\n if (note.bar !== undefined || isSilent(note)) return;\n const path = `${p}.${r}.${i}`;\n const dur = note.durationMatra ?? 1;\n\n if (note.svara !== undefined) {\n // svara note or melisma — a real attack.\n events.push({\n beat: cursor,\n durationBeats: dur,\n midi: svaraToMidi(note, tonicPc, baseOctave),\n kan: kanToMidi(note.kan, tonicPc, baseOctave),\n path,\n kind: note.sustain === true ? 'sustain' : 'note',\n });\n lastPitched = events.length - 1;\n } else if (note.sustain === true) {\n // আ-কার hold — extend the ringing note, emit a silent highlight column.\n if (lastPitched >= 0) events[lastPitched]!.durationBeats += dur;\n events.push({ beat: cursor, durationBeats: dur, midi: null, kan: null, path, kind: 'sustain' });\n } else {\n // rest.\n events.push({ beat: cursor, durationBeats: dur, midi: null, kan: null, path, kind: 'rest' });\n }\n cursor += dur;\n });\n });\n });\n\n return { events, totalBeats: cursor };\n}\n","/**\n * Staff (Western) notation — a 4th \"language\" for the viewer.\n *\n * Staff notation IS the melody voice drawn as a Western score, so it reuses\n * the player's pure `buildSchedule` (the same (midi, beat, durationBeats, kan)\n * the MIDI export writes) and turns it into an **ABC notation** string, which\n * `abcjs` (MIT, zero-dep) engraves to SVG. abcjs is loaded through a *dynamic*\n * `import('abcjs')` — an optional peer dep, exactly like tone/lamejs — so the\n * viewer bundle keeps its bare-load guarantee and only consumers who want staff\n * notation install it. Without it, `renderStaffHtml` returns a graceful notice.\n *\n * Scope (matches the player/MIDI): a single treble-clef melody line. The chosen\n * instrument is a header label, not a clef change (the line is monophonic and\n * treble covers piano + violin range with ledger lines). Microtones render as\n * their komal approximation — the same documented limitation as playback, since\n * abcjs has no sub-komal glyph.\n */\nimport type { Swaralipi, Taal } from '../spec/index.js';\nimport { buildSchedule, type PlayEvent, type Schedule } from '../player/schedule.js';\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport { drumPattern, type DrumVoice } from '../player/instruments.js';\nimport { renderMetaHeader } from './render.js';\nimport type { GridLang } from './glyphs.js';\n\nexport interface StaffOptions {\n /** Tonic (Sa). Accepts `C`, `C#`, `cs`… Default: `meta.tonic`, else `C`. */\n tonic?: string;\n /** Octave of madhyam Sa (C4 = MIDI 60). Default 4. */\n baseOctave?: number;\n /** Tempo written into the score (Q:) and shown as a header. Default `meta.bpm`, else 90. */\n bpm?: number;\n /** Instrument name shown above the staff (label only — clef stays treble). */\n instrument?: string;\n /** Show the নাম/তাল/আবর্তন/স্বরলিপিকার header block. Default true. */\n showHeader?: boolean;\n /** Language for the header **labels** (values are injected pre-localized by\n * the consumer). Default `en` — staff is the Western view. */\n headerLang?: GridLang;\n /** Transliterate header values (title/taal/notator) — same fn as the grid. */\n transliterate?: (bengaliText: string) => string;\n /** Include the `w:` lyric line under each staff. Default true. */\n lyrics?: boolean;\n /** Matra per bar (one তাল cycle). Default `meta.taal.numBeats`, else 4. */\n beatsPerBar?: number;\n /** Target line width in px passed to abcjs (music wraps within it). Default 680. */\n staffwidth?: number;\n /** Preferred bars per wrapped line (swaralipi-short systems). Default 4. */\n measuresPerLine?: number;\n /** abcjs `scale`. Default 1. */\n scale?: number;\n /** Add a second percussion staff below the melody, sequencing a Western\n * drumset (kick/snare/hi-hat) to the taal's sam/tali/khaali structure —\n * the same pattern `SwaralipiPlayer`'s `rhythm: 'drums'` plays, engraved via\n * abcjs `%%percmap`. Default false (the score stays a single staff). Taal:\n * `meta.taal`, else a plain 4-beat cycle (matches `beatsPerBar`'s fallback). */\n drums?: boolean;\n}\n\n/* ---- MIDI → ABC pitch spelling -------------------------------------- */\n\n/** Sharp-spelled ABC pitch tokens, index = pitch-class 0–11. `^` = sharp. */\nconst ABC_SHARP = ['C', '^C', 'D', '^D', 'E', 'F', '^F', 'G', '^G', 'A', '^A', 'B'] as const;\n\n/**\n * MIDI number → ABC pitch token. ABC's octave anchor is fixed by the standard:\n * middle C (MIDI 60, C4) is uppercase `C`; lowercase `c` = C5; a comma drops an\n * octave (`C,` = C3), an apostrophe raises one (`c'` = C6). Sharps carry a `^`.\n */\nexport function midiToAbc(midi: number): string {\n const pc = ((midi % 12) + 12) % 12;\n const octave = Math.floor(midi / 12) - 1; // MIDI 60 → 4\n const token = ABC_SHARP[pc]!;\n const acc = token[0] === '^' ? '^' : '';\n const letter = acc ? token[1]! : token[0]!;\n return octave >= 5\n ? acc + letter.toLowerCase() + \"'\".repeat(octave - 5)\n : acc + letter + ','.repeat(4 - octave);\n}\n\n/**\n * ABC duration suffix for a beat length, where the unit note (`L:`) is one\n * matra = a quarter note. Whole numbers append the multiplier (`2`, `3`);\n * simple fractions use `/n` (`/2` = eighth); anything else falls back to the\n * nearest 1/4-matra count of `/4` units so odd durations still sum correctly.\n */\nexport function abcDuration(beats: number): string {\n if (Math.abs(beats - 1) < 1e-6) return '';\n if (Math.abs(beats - Math.round(beats)) < 1e-6) return String(Math.round(beats));\n const inv = 1 / beats;\n if (Math.abs(inv - Math.round(inv)) < 1e-6) return `/${Math.round(inv)}`;\n // Fallback: express in sixteenth-note (1/4-matra) units, e.g. 0.75 → 3/4.\n const sixteenths = Math.max(1, Math.round(beats * 4));\n return `${sixteenths}/4`;\n}\n\n/** One ABC note token: optional grace, the pitch, its duration. */\nfunction abcNote(ev: PlayEvent): string {\n const grace = ev.kan !== null ? `{${midiToAbc(ev.kan)}}` : '';\n return `${grace}${midiToAbc(ev.midi!)}${abcDuration(ev.durationBeats)}`;\n}\n\n/**\n * The `part.row.note` path for each ABC note/rest token, in emission order —\n * i.e. index N here is abcjs's `data-index=\"N\"` (verified: abcjs assigns one\n * incrementing index per `.abcjs-note`/`.abcjs-rest` element, in tune order,\n * and skips bars entirely — the same tokens `buildAbc` pushes). Used to paint\n * `data-note` onto the engraved SVG so playback highlighting reuses the exact\n * `highlight()`/`data-note` mechanism the grid languages already have.\n */\nfunction eventPaths(schedule: Schedule): string[] {\n const paths: string[] = [];\n for (const ev of schedule.events) {\n if (ev.midi !== null || ev.kind === 'rest') paths.push(ev.path);\n }\n return paths;\n}\n\n/* ---- Schedule → ABC tune -------------------------------------------- */\n\n/** Strip newlines/field-leaders so a title/text is safe inside an ABC field. */\nfunction abcText(s: string): string {\n return s.replace(/[\\r\\n]+/g, ' ').trim();\n}\n\n/**\n * Build a complete ABC tune string from a schedule. Pure and dependency-free\n * (the testable seam). Rests advance time as `z`; melody notes carry duration;\n * lyrics become a `w:` line aligned to the notes.\n *\n * Bar lines are inserted every `beatsPerBar` matra (= one তাল cycle, so an ABC\n * measure is one আবর্তন). This is what lets abcjs **wrap into short systems** —\n * it only breaks lines at bar lines. `M:` is set to match so the notes-per-bar\n * check-out. The tempo (`Q:`) rides the header.\n *\n * `drums`, if given, is the taal's per-beat `drumPattern()` — a second\n * `V:2 clef=perc` percussion staff is added below the melody, cycling that\n * pattern one quarter-note per matra with `%%percmap` GM drum sounds (see\n * `buildDrumVoice`). Both voices share the same bar grid, so they wrap and\n * align together.\n */\nexport function buildAbc(\n schedule: Schedule,\n lyricOf: (ev: PlayEvent) => string | undefined,\n opts: { bpm: number; lyrics: boolean; beatsPerBar: number; drums?: DrumVoice[] },\n): string {\n const beatsPerBar = opts.beatsPerBar > 0 ? opts.beatsPerBar : 4;\n const tokens: string[] = [];\n const words: string[] = [];\n let barPos = 0; // matra elapsed within the current measure\n const EPS = 1e-6;\n\n const advance = (dur: number) => {\n barPos += dur;\n // Close every full measure (a note may fill/overflow more than one).\n while (barPos >= beatsPerBar - EPS) {\n tokens.push('|');\n words.push('|');\n barPos -= beatsPerBar;\n }\n };\n\n for (const ev of schedule.events) {\n if (ev.midi === null) {\n if (ev.kind === 'rest') {\n tokens.push(`z${abcDuration(ev.durationBeats)}`);\n words.push('*');\n advance(ev.durationBeats);\n }\n continue; // zero-time আ-কার holds already folded into the previous note\n }\n tokens.push(abcNote(ev));\n const lyr = lyricOf(ev);\n // abcjs splits w: on spaces; '~' joins a multi-word syllable, '*' is blank.\n words.push(lyr ? abcText(lyr).replace(/\\s+/g, '~') : '*');\n advance(ev.durationBeats);\n }\n\n // Final barline (song end) if the last note didn't land exactly on a bar.\n if (tokens.length && tokens[tokens.length - 1] !== '|') tokens.push('|]');\n else if (tokens.length) tokens[tokens.length - 1] = '|]';\n\n // No T: title — abcjs draws it oversized above the first system and collides\n // with the host page. Title/tempo/instrument live in the `.sw-staff` wrapper.\n const meter = ratioMeter(beatsPerBar);\n const head = ['X:1', `M:${meter}`, 'L:1/4', `Q:1/4=${Math.round(opts.bpm)}`];\n if (opts.drums) head.push(...percMapLines(opts.drums));\n head.push('K:C treble');\n\n const melodyBody = tokens.length ? tokens.join(' ') : 'z |]';\n const lines = [...head];\n if (opts.drums) {\n lines.push('V:1', melodyBody);\n if (opts.lyrics && words.some((w) => w !== '*' && w !== '|')) lines.push(`w: ${words.join(' ')}`);\n lines.push('V:2 clef=perc stem=up', buildDrumVoice(schedule.totalBeats, beatsPerBar, opts.drums));\n } else {\n lines.push(melodyBody);\n if (opts.lyrics && words.some((w) => w !== '*' && w !== '|')) lines.push(`w: ${words.join(' ')}`);\n }\n return lines.join('\\n');\n}\n\n/** Meter string for a bar of N quarter-note beats (N/4). */\nfunction ratioMeter(beats: number): string {\n return `${Math.max(1, Math.round(beats))}/4`;\n}\n\n/* ---- Percussion voice (Western-drumset rendering of the taal) -------- */\n\n/** ABC pitch letter used as each drum voice's percmap key (arbitrary but\n * fixed — must be a real ABC note letter, not `z`/`x`, which abcjs reserves\n * for rests/invisible rests). GM percussion names abcjs's `%%percmap`\n * understands; see the General MIDI drum map. */\nconst DRUM_ABC: Record<DrumVoice, { note: string; gm: string }> = {\n kick: { note: 'F,', gm: 'bass-drum-1' },\n snare: { note: 'C', gm: 'acoustic-snare' },\n hihat: { note: 'g', gm: 'closed-hi-hat' },\n tom1: { note: 'E', gm: 'high-tom' },\n tom2: { note: 'A,', gm: 'low-mid-tom' },\n tom3: { note: 'D,', gm: 'low-floor-tom' },\n};\n\n/** `%%percmap` header lines mapping each used drum voice to its GM sound. */\nfunction percMapLines(voices: Iterable<DrumVoice>): string[] {\n const seen = new Set<DrumVoice>();\n const lines: string[] = [];\n for (const v of voices) {\n if (seen.has(v)) continue;\n seen.add(v);\n const { note, gm } = DRUM_ABC[v];\n lines.push(`%%percmap ${note} ${gm}`);\n }\n return lines;\n}\n\n/**\n * Build the `V:2 clef=perc` drum-voice tune body: one quarter-note token per\n * matra for `totalBeats` (cycling `drumPattern`), barred every `beatsPerBar`\n * matra — the same bar grid as the melody voice, so both staves wrap and\n * align together.\n */\nfunction buildDrumVoice(totalBeats: number, beatsPerBar: number, pattern: DrumVoice[]): string {\n const n = Math.max(1, Math.ceil(totalBeats));\n const tokens: string[] = [];\n for (let beat = 0; beat < n; beat++) {\n tokens.push(DRUM_ABC[pattern[beat % pattern.length]!].note);\n if ((beat + 1) % beatsPerBar === 0) tokens.push('|');\n }\n if (tokens.length === 0 || tokens[tokens.length - 1] !== '|') tokens.push('|]');\n else tokens[tokens.length - 1] = '|]';\n return tokens.join(' ');\n}\n\n/* ---- Doc → ABC (wires the schedule to the doc's lyrics) -------------- */\n\n/** Map each schedule event back to its source note's lyric via the `part.row.note` path. */\nfunction lyricLookup(doc: Swaralipi): (ev: PlayEvent) => string | undefined {\n return (ev) => {\n const [p, r, i] = ev.path.split('.').map(Number);\n return doc.parts[p!]?.rows[r!]?.notes[i!]?.lyric;\n };\n}\n\n/** The taal driving the drum pattern: the doc's own (if known to the player's\n * sample/theory tables), else a plain 4-beat cycle — mirrors the player's own\n * `taalId ?? { numBeats: 4, sam: 0 }` fallback in `#buildRhythm`. */\nfunction resolveDrumTaal(doc: Swaralipi): Pick<Taal, 'numBeats' | 'sam' | 'bhaags' | 'khaali'> {\n const id = doc.meta.taal?.id;\n return id !== undefined && id in TAALS ? TAALS[id as TaalId] : { numBeats: 4, sam: 0 };\n}\n\n/** Build the ABC tune string for a whole document (schedule + lyrics + tempo).\n * The measure length is one তাল cycle (`meta.taal.numBeats`), falling back to 4.\n * `opts.drums` adds the percussion staff (see `buildAbc`). */\nexport function docToAbc(doc: Swaralipi, opts: StaffOptions = {}): string {\n const schedule = buildSchedule(doc, { tonic: opts.tonic, baseOctave: opts.baseOctave });\n const bpm = opts.bpm ?? doc.meta.bpm ?? 90;\n const beatsPerBar = opts.beatsPerBar ?? doc.meta.taal?.numBeats ?? 4;\n const drums = opts.drums ? drumPattern(resolveDrumTaal(doc)) : undefined;\n return buildAbc(schedule, lyricLookup(doc), { bpm, lyrics: opts.lyrics !== false, beatsPerBar, drums });\n}\n\n/* ---- ABC → SVG via abcjs (browser/jsdom only) ----------------------- */\n\n/**\n * Render an ABC tune string to engraved HTML using abcjs. Requires a DOM\n * (`document`) — abcjs measures glyphs and draws into an element; call it in a\n * browser, in a print iframe, or under jsdom (tests stub `getBBox`). abcjs is\n * dynamically imported so it is never bundled or loaded unless staff notation\n * is actually used.\n *\n * The music is **wrapped into short systems** (a few bars per line, each its\n * own SVG-in-DIV) — matching how আকারমাত্রিক swaralipi is laid out in stacked\n * rows rather than one long staff. Returns the full multi-line markup (all\n * line DIVs), or a notice string if abcjs is not installed.\n *\n * `notePaths`, if given, is the `part.row.note` highlight path for each ABC\n * melody note/rest token in schedule order (see `eventPaths`). The melody is\n * voice 0; abcjs emits its `.abcjs-v0.abcjs-note`/`.abcjs-rest` elements in\n * document order = that same order, so painting `notePaths[i]` onto the i-th\n * melody element gives every engraved note the same `data-note` attribute the\n * grid languages use — playback highlighting works identically for staff. (We\n * key off voice + document order, NOT `data-index`: with a drum voice abcjs\n * numbers each line/voice block separately, so data-index isn't global order.)\n */\nexport async function abcToSvg(abc: string, opts: StaffOptions = {}, notePaths?: string[]): Promise<string> {\n if (typeof document === 'undefined') {\n throw new Error('abcToSvg requires a DOM; render staff notation in the browser or print iframe');\n }\n let ABCJS: typeof import('abcjs');\n try {\n const mod = await import('abcjs');\n ABCJS = (mod as { default?: typeof import('abcjs') }).default ?? mod;\n } catch {\n return `<div class=\"sw-staff-missing\">Staff notation needs the optional <code>abcjs</code> package.</div>`;\n }\n // abcjs measures glyph/line heights from live layout to decide where to wrap\n // and split systems — a purely detached div reports height 0, collapsing the\n // staves. So render into an off-screen-but-attached host, read the markup,\n // then remove it.\n const host = document.createElement('div');\n host.style.cssText = 'position:fixed; left:-10000px; top:0; width:720px; visibility:hidden;';\n const mount = document.body ?? document.documentElement;\n mount.appendChild(host);\n try {\n ABCJS.renderAbc(host, abc, {\n add_classes: true,\n staffwidth: opts.staffwidth ?? 680,\n scale: opts.scale ?? 1,\n // Reflow into short lines. staffwidth is the width budget;\n // preferredMeasuresPerLine keeps systems swaralipi-short.\n // (Not `responsive: resize` — its absolute-positioned aspect-ratio wrapper\n // overlaps the header and mis-sizes on the print page.)\n wrap: { minSpacing: 1.8, maxSpacing: 2.7, preferredMeasuresPerLine: opts.measuresPerLine ?? 4 },\n // CRUCIAL: put each wrapped system in its OWN <svg> (default is all systems\n // stacked in one tall SVG, which is atomic and can't page-break — that was\n // the near-blank-first-page / mid-staff-cutoff print bug). One SVG per line\n // lets `break-inside: avoid` keep each staff whole while pages fill.\n oneSvgPerLine: true,\n });\n // abcjs sizes each SVG with fixed pixel width/height and NO viewBox, so it\n // can't shrink to a narrow container / print page. Give each a viewBox and\n // drop the fixed size; the CSS then scales it (aspect ratio preserved).\n for (const svg of host.querySelectorAll('svg')) {\n const w = parseFloat(svg.getAttribute('width') ?? '');\n const h = parseFloat(svg.getAttribute('height') ?? '');\n if (w > 0 && h > 0) {\n // abcjs (v6) sets a fixed pixel width/height (and a viewBox). The fixed\n // width blocks shrinking to a narrow container, but dropping it lets the\n // CSS `width:100%` STRETCH a short system to fill a wide container. So\n // drop the fixed size (shrink-to-fit) but pin max-width to the engraved\n // width (never stretch past it) — the score stays swaralipi-sized.\n if (!svg.getAttribute('viewBox')) svg.setAttribute('viewBox', `0 0 ${w} ${h}`);\n svg.setAttribute('preserveAspectRatio', 'xMinYMin meet');\n svg.removeAttribute('width');\n svg.removeAttribute('height');\n svg.setAttribute('style', `max-width:${w}px`);\n }\n }\n // Paint data-note onto each engraved MELODY note/rest so playback\n // highlighting works exactly like the grid languages (see notePaths doc).\n // abcjs's `data-index` is NOT global tune order — with a drum voice it\n // numbers each (line, voice) block separately, so the drum notes get indices\n // that collide with the melody's. The melody is always voice 0 (`abcjs-v0`);\n // its note/rest elements appear in document order = schedule order, so we\n // match `notePaths` by position over just those, ignoring data-index.\n if (notePaths) {\n const melody = host.querySelectorAll('.abcjs-v0.abcjs-note, .abcjs-v0.abcjs-rest');\n let i = 0;\n for (const el of melody) {\n const path = notePaths[i++];\n if (path !== undefined) el.setAttribute('data-note', path);\n }\n }\n // abcjs emits one <div><svg>…</svg></div> per wrapped line; return them all.\n return host.innerHTML;\n } finally {\n host.remove();\n }\n}\n\n/**\n * Full doc → staff-notation HTML fragment: the shared নাম/তাল/আবর্তন/স্বরলিপিকার\n * header (same block as the akarmatrik grid, so the staff shows the identical\n * metadata) + an instrument label + the wrapped Western systems. Styled by\n * SWARALIPI_CSS + SWARALIPI_STAFF_CSS. Async because abcjs is dynamic-imported.\n */\nexport async function renderStaffHtml(doc: Swaralipi, opts: StaffOptions = {}): Promise<string> {\n const bpm = opts.bpm ?? doc.meta.bpm ?? 90;\n const abc = docToAbc(doc, { ...opts, bpm });\n const schedule = buildSchedule(doc, { tonic: opts.tonic, baseOctave: opts.baseOctave });\n const engraved = await abcToSvg(abc, opts, eventPaths(schedule));\n // The abcjs output is the wrapped systems (or the \"needs abcjs\" notice, which\n // is passed through un-wrapped).\n const lines = engraved.includes('sw-staff-missing')\n ? engraved\n : `<div class=\"sw-staff-lines\">${engraved}</div>`;\n // Same header as the grid (title/taal/raag/avartan/notator). Labels in\n // headerLang (default en — the Western view); values are pre-localized by\n // the consumer. abcjs engraves the tempo (Q:) itself, so the instrument label\n // is the only extra strip.\n const header =\n opts.showHeader === false ? '' : renderMetaHeader(doc.meta, opts.headerLang ?? 'en', opts.transliterate);\n const metaParts: string[] = [];\n if (opts.instrument) metaParts.push(`<span class=\"sw-staff-instrument\">${escapeAttr(opts.instrument)}</span>`);\n if (opts.drums) metaParts.push(`<span class=\"sw-staff-drums\">+ drums</span>`);\n const meta = metaParts.length ? `<div class=\"sw-staff-meta\">${metaParts.join('')}</div>` : '';\n return `<div class=\"sw-staff\">${header}${meta}${lines}</div>`;\n}\n\nfunction escapeAttr(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n","/**\n * Tone.js instrument/asset factories. Tone is **injected** (never imported\n * here) so this module — like the scheduler — stays free of a static `tone`\n * dependency; the player passes the dynamically-imported module in.\n *\n * Melodic instruments are a small registry (INSTRUMENTS) of Tone.Sampler\n * note→file maps + where to fetch them. `piano` (CC-BY Salamander) is the\n * default and CDN-hosted, as are `harmonium`/`violin`/`flute` (CC-BY,\n * tonejs-instruments); `santoor` is local (under the player's `soundsBaseUrl`).\n * Consumers can register more (e.g. a self-hosted sitar) via the player's\n * `customInstruments` option — true sampled sitar/sarod/sarangi/esraj have no\n * free web set, only commercial Kontakt libraries.\n *\n * Asset layout under `soundsBaseUrl`:\n * santoor/<note>.mp3 c4..c7 + sharps (37 files)\n * tanpura/<pc>.mp3 12 pitch classes (c, cs, d, …)\n * tabla/<seg>/<seg><bpm>bpm.mp3 seg = <taal>[-<variation>], bpm 60..300 step 15\n * metronome/metro2.mp3\n */\n// Import TAALS from the taals subpath (not the ../spec/index barrel): the\n// barrel re-exports schema.ts, which statically imports zod — pulling that into\n// the player would break its \"loads bare in a browser\" guarantee. taals.ts has\n// only a type-only schema import, so this keeps the player runtime zod-free.\nimport type { Taal } from '../spec/schema.js';\nimport { TAALS, type TaalId } from '../spec/taals.js';\nimport { sampleFileName } from './pitch.js';\n\n/** The dynamically-imported Tone module, typed without importing it. */\nexport type ToneModule = typeof import('tone');\n\n/** A melodic instrument: a Tone.Sampler note→filename map + where to find it. */\nexport interface InstrumentDef {\n /** Human label for UIs. */\n label: string;\n /** Tone.Sampler `urls`: note name (`C#4`) → filename (`Cs4.mp3`). */\n urls: Record<string, string>;\n /** Sample directory: an absolute URL, or — when `local` — a path segment\n * appended to the player's `soundsBaseUrl`. */\n baseUrl: string;\n /** `baseUrl` is relative to `soundsBaseUrl` (needs it set). */\n local?: boolean;\n /** Sampler release time in seconds. */\n release?: number;\n}\n\n/** Built-in melody instrument ids (consumers may add their own via the\n * player's `customInstruments`, so the runtime id type stays open). */\nexport type InstrumentId = string;\n\n/**\n * Default host for the project's samples (santoor / tabla / tanpura /\n * metronome) — CC-BY, redistribution-verified and CORS-enabled, so the player\n * works with zero config. Override via the player's `soundsBaseUrl` to\n * self-host. (Melody defaults to the CDN-hosted piano, so it needs no host.)\n */\nexport const DEFAULT_SOUNDS_BASE = 'https://cdn.daserve.in/swaralipijs-instruments/';\n/** CC-BY Salamander Grand Piano (Tone's de-facto piano), CDN-hosted. */\nexport const SALAMANDER_BASE = 'https://tonejs.github.io/audio/salamander/';\n/** CC-BY tonejs-instruments sample CDN (harmonium/violin/flute). */\nexport const TONEJS_INSTRUMENTS_BASE = 'https://nbrosowsky.github.io/tonejs-instruments/samples/';\n\n/** Build a Tone.Sampler `urls` map from bare note keys (`C#4` → `Cs4.mp3`). */\nfunction keyMap(keys: readonly string[]): Record<string, string> {\n const m: Record<string, string> = {};\n for (const k of keys) m[k] = `${k.replace('#', 's')}.mp3`;\n return m;\n}\n\nconst PIANO_KEYS = [\n 'A0', 'C1', 'D#1', 'F#1', 'A1', 'C2', 'D#2', 'F#2', 'A2', 'C3', 'D#3', 'F#3',\n 'A3', 'C4', 'D#4', 'F#4', 'A4', 'C5', 'D#5', 'F#5', 'A5', 'C6', 'D#6', 'F#6',\n 'A6', 'C7', 'D#7', 'F#7', 'A7', 'C8',\n] as const;\n// harmonium — a core Rabindrasangeet accompaniment (C2..C5).\nconst HARMONIUM_KEYS = [\n 'C2', 'C#2', 'D2', 'D#2', 'E2', 'F2', 'F#2', 'G2', 'G#2', 'A2', 'A#2',\n 'C3', 'C#3', 'D3', 'D#3', 'E3', 'F3', 'F#3', 'G3', 'G#3', 'A3', 'A#3',\n 'C4', 'C#4', 'D4', 'D#4', 'E4', 'F4', 'F#4', 'G4', 'G#4', 'A4', 'A#4',\n 'C5', 'C#5', 'D5',\n] as const;\nconst VIOLIN_KEYS = ['A3', 'C4', 'E4', 'G4', 'A4', 'C5', 'E5', 'G5', 'A5', 'C6', 'E6', 'G6', 'A6', 'C7'] as const;\nconst FLUTE_KEYS = ['C4', 'E4', 'A4', 'C5', 'E5', 'A5', 'C6', 'E6', 'A6', 'C7'] as const;\n\n/** Built-in melody instruments. santoor is local; the rest are CDN-hosted\n * (CC-BY) so they need only network — `pianoBaseUrl`/`customInstruments`\n * override for self-hosting. */\nexport const INSTRUMENTS: Record<string, InstrumentDef> = {\n piano: { label: 'Grand piano', urls: keyMap(PIANO_KEYS), baseUrl: SALAMANDER_BASE, release: 1 },\n santoor: { label: 'Santoor', urls: santoorUrls(), baseUrl: 'santoor/', local: true, release: 1.2 },\n harmonium: { label: 'Harmonium', urls: keyMap(HARMONIUM_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}harmonium/`, release: 1.4 },\n violin: { label: 'Violin', urls: keyMap(VIOLIN_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}violin/`, release: 1 },\n flute: { label: 'Flute', urls: keyMap(FLUTE_KEYS), baseUrl: `${TONEJS_INSTRUMENTS_BASE}flute/`, release: 1 },\n};\n\n/** Taals with recorded tabla loops (everything else → metronome fallback). */\nexport const SAMPLED_TAALS: ReadonlySet<TaalId> = new Set(\n Object.keys(TAALS) as TaalId[],\n);\n\n/** Available tabla loop tempos (file suffix `…<bpm>bpm.mp3`). */\nexport const TABLA_BPMS: readonly number[] = Array.from({ length: 17 }, (_, i) => 60 + i * 15);\n\n/**\n * Tabla loop variations per taal. Most taals have one unnamed loop at\n * `tabla/<id>/`; an entry here overrides that:\n * - `variations` lists the variation suffixes, **first = default**.\n * A lone named variation (shashthi → `pro`, i.e. `tabla/shashthi-pro/`) IS\n * the default; later entries are premium upsells the player never auto-selects.\n * An empty-string entry (kehrwa → `''`) means the unnamed `tabla/<id>/` loop\n * is the default and a named entry follows it as an upsell.\n * - `skipBpms` are grid tempos this taal's loops were not recorded at.\n * Consumers read this to build a variation/upsell UI; the player itself only\n * ever plays the default (or whatever a doc's `meta.taal.variation` pins).\n */\nexport const TABLA_VARIATIONS: Record<\n string,\n { variations: string[]; skipBpms?: number[] }\n> = {\n // ষষ্ঠী loops live under `tabla/shashthi-pro/`; full bpm grid recorded except 225.\n shashthi: { variations: ['pro'], skipBpms: [225] },\n // Kehrwa keeps its unnamed default loop; `qawwali` (tabla/kehrwa-qawwali/) is a\n // premium upsell variation recorded 90–300 (no 60/75).\n // ponytail: skipBpms is per-taal, so it can't restrict qawwali's 60/75 without\n // also dropping them from the default (which has them) — a qawwali doc pinned\n // ≤67 bpm 404s harmlessly. Make skipBpms per-variation only if that edge bites.\n kehrwa: { variations: ['', 'qawwali'] },\n};\n\n/** Tabla tempos actually available for a taal: the grid minus any it lacks. */\nexport function tablaBpms(taalId: string): readonly number[] {\n const skip = TABLA_VARIATIONS[taalId]?.skipBpms;\n return skip && skip.length ? TABLA_BPMS.filter((b) => !skip.includes(b)) : TABLA_BPMS;\n}\n\n/** CDN directory/filename segment for a taal's tabla loop: `<taalId>` or\n * `<taalId>-<variation>` (explicit variation, else the taal's default). */\nfunction tablaSeg(taalId: string, variation?: string): string {\n const v = variation ?? TABLA_VARIATIONS[taalId]?.variations[0]; // default = first variation, else unnamed\n return v ? `${taalId}-${v}` : taalId;\n}\n\n/** Ensure exactly one trailing slash. */\nexport function normalizeBase(url: string): string {\n return url.endsWith('/') ? url : `${url}/`;\n}\n\n/** The 37 santoor samples, as a Tone.Sampler `urls` map (`C4` → `c4.mp3`). */\nexport function santoorUrls(): Record<string, string> {\n const urls: Record<string, string> = {};\n const add = (midi: number) => {\n const stem = sampleFileName(midi); // e.g. cs4\n const name = stem.replace('s', '#').replace(/^(.)/, (c) => c.toUpperCase()); // C#4\n urls[name] = `${stem}.mp3`;\n };\n for (let midi = 60; midi <= 95; midi++) add(midi); // C4..B6 (full)\n add(96); // C7\n return urls;\n}\n\nconst PC_BASE: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** Parse a sample note name (`C#4`, `Ds3`, `Bb2`) to a MIDI number. */\nexport function noteToMidi(name: string): number {\n const m = /^([a-g])([#sb]?)(-?\\d+)$/i.exec(name.trim());\n if (!m) return NaN;\n const base = PC_BASE[m[1]!.toLowerCase()]!;\n const acc = m[2] === 'b' ? -1 : m[2] === '' ? 0 : 1; // # / s → sharp\n return (Number(m[3]) + 1) * 12 + base + acc;\n}\n\n/**\n * Restrict a Sampler `urls` map to just the samples needed to cover MIDI\n * `[lo, hi]`: every sample inside the range, plus the nearest one below and\n * above it (so Tone interpolates the edges without extrapolating). Cuts a\n * typical song from ~37 santoor files to a handful — a big win on mobile and\n * never worse on fast links (Tone fetches what's left in parallel). The\n * Sampler pitch-shifts from the nearest sample, so audio is unchanged.\n */\nexport function subsetUrls(\n urls: Record<string, string>,\n lo: number,\n hi: number,\n): Record<string, string> {\n const entries = Object.entries(urls)\n .map(([k, f]) => ({ k, f, midi: noteToMidi(k) }))\n .filter((e) => Number.isFinite(e.midi))\n .sort((a, b) => a.midi - b.midi);\n if (entries.length === 0) return { ...urls };\n\n const keep = new Set<string>();\n for (const e of entries) if (e.midi >= lo && e.midi <= hi) keep.add(e.k);\n // nearest sample at/below lo and at/above hi for clean interpolation\n let floor: string | undefined;\n let ceil: string | undefined;\n for (const e of entries) if (e.midi <= lo) floor = e.k;\n for (const e of entries) if (e.midi >= hi) { ceil = e.k; break; }\n if (floor) keep.add(floor);\n if (ceil) keep.add(ceil);\n if (keep.size === 0) {\n // range entirely outside the sample set — keep the single nearest sample\n const mid = (lo + hi) / 2;\n const nearest = entries.reduce((a, b) => (Math.abs(b.midi - mid) < Math.abs(a.midi - mid) ? b : a));\n keep.add(nearest.k);\n }\n\n const out: Record<string, string> = {};\n for (const e of entries) if (keep.has(e.k)) out[e.k] = e.f;\n return out;\n}\n\n/** Resolve a representative sample URL for an instrument (its first sample),\n * used to probe availability. undefined when a local instrument has no\n * `soundsBaseUrl` or the def has no samples. */\nexport function instrumentSampleUrl(def: InstrumentDef, soundsBaseUrl?: string): string | undefined {\n if (def.local && soundsBaseUrl === undefined) return undefined;\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const file = Object.values(def.urls)[0];\n return file === undefined ? undefined : `${normalizeBase(base)}${file}`;\n}\n\n/**\n * Liveness check for a sample URL: a single tiny ranged GET (one byte), the\n * same CORS-enabled fetch Tone uses to load the buffer — so a pass means Tone\n * can actually load it. Resolves false on any error/timeout/non-2xx, and false\n * (no throw) when `fetch` is unavailable (Node/SSR). `Range: bytes=0-0` is a\n * CORS-safelisted header, so no preflight.\n */\nexport async function probeUrl(url: string, timeoutMs = 6000): Promise<boolean> {\n if (typeof fetch === 'undefined') return false;\n const ctrl = typeof AbortController !== 'undefined' ? new AbortController() : undefined;\n const timer = ctrl ? setTimeout(() => ctrl.abort(), timeoutMs) : undefined;\n try {\n const res = await fetch(url, {\n method: 'GET',\n headers: { Range: 'bytes=0-0' },\n cache: 'no-store',\n signal: ctrl?.signal,\n });\n return res.ok; // 200 / 206\n } catch {\n return false;\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n}\n\n/**\n * Snap a tabla loop's end to the nearest whole beat of its measured length so a\n * slightly-mistrimmed file still phase-locks to the melody grid instead of\n * drifting a fraction of a beat each cycle. `spb` = seconds per beat (60/bpm).\n * No-op for correctly trimmed loops (already an integer beat count); never\n * extends past the buffer — a too-short file can't be repaired here.\n *\n * ponytail: belt-and-braces for off-spec audio; the real fix is trimming each\n * loop to exactly `cycles × numBeats × 60/bpm` seconds at production time.\n */\nexport function quantizeLoopEnd(durationSec: number, spb: number): number {\n if (spb <= 0) return durationSec;\n const beats = Math.round(durationSec / spb);\n if (beats < 1) return durationSec; // too short to snap to a beat\n return Math.min(beats * spb, durationSec);\n}\n\n/** Snap an arbitrary bpm to the nearest available tabla tempo (default grid;\n * pass a taal's `tablaBpms()` so it never snaps to a tempo that taal lacks). */\nexport function nearestTablaBpm(bpm: number, bpms: readonly number[] = TABLA_BPMS): number {\n return bpms.reduce((best, b) => (Math.abs(b - bpm) < Math.abs(best - bpm) ? b : best), bpms[0]!);\n}\n\n/** URL of the tabla loop for a taal at a (snapped) bpm, optionally a named\n * variation (defaults to the taal's default variation — see TABLA_VARIATIONS). */\nexport function tablaUrl(base: string, taalId: string, bpm: number, variation?: string): string {\n const seg = tablaSeg(taalId, variation);\n return `${normalizeBase(base)}tabla/${seg}/${seg}${bpm}bpm.mp3`;\n}\n\n/** URL of the metronome click. */\nexport function metronomeUrl(base: string): string {\n return `${normalizeBase(base)}metronome/metro2.mp3`;\n}\n\n/** Build the metronome click `Tone.Player`. */\nexport function createMetronome(Tone: ToneModule, base: string) {\n return new Tone.Player(metronomeUrl(base));\n}\n\n/** Tanpura pitch-class sample stems (filename = `<stem>.mp3`). */\nexport const TANPURA_PCS = ['c', 'cs', 'd', 'ds', 'e', 'f', 'fs', 'g', 'gs', 'a', 'as', 'b'] as const;\n\n/* ---- Drum kit (Western-drumset rendering of an Indian taal) ------------\n *\n * A real drumset \"translation\" of tabla bols is an established practice\n * (e.g. Sunny Jain's Drum Atlas: India — kick on sam, snare on the accented\n * tali claps, hi-hat filling/ghosting the khaali wave), not something\n * invented here. DRUM_VOICES are one-shot acoustic-kit samples (CC0-cleared\n * Apache-2.0 Tonejs/audio collection, https://github.com/Tonejs/audio,\n * already the CDN this project uses directly for the Salamander piano) —\n * same trust tier as the other CDN-hosted instruments, no new hosting.\n */\nexport const DRUM_KIT_BASE = 'https://tonejs.github.io/audio/drum-samples/acoustic-kit/';\n\nexport type DrumVoice = 'kick' | 'snare' | 'hihat' | 'tom1' | 'tom2' | 'tom3';\nconst DRUM_FILES: Record<DrumVoice, string> = {\n kick: 'kick.mp3',\n snare: 'snare.mp3',\n hihat: 'hihat.mp3',\n tom1: 'tom1.mp3',\n tom2: 'tom2.mp3',\n tom3: 'tom3.mp3',\n};\n\n/** Build the drum-kit `Tone.Players` (one-shot voices, not looped/pitched). */\nexport function createDrumKit(Tone: ToneModule, base: string = DRUM_KIT_BASE) {\n const urls: Record<string, string> = {};\n for (const [voice, file] of Object.entries(DRUM_FILES)) urls[voice] = file;\n return new Tone.Players({ urls, baseUrl: normalizeBase(base) });\n}\n\n/**\n * Per-beat drumset voice for one তাল cycle, following sam/tali/khaali theory:\n * sam (cycle start) → kick, the first beat of each accented (non-khaali)\n * vibhag → snare (the tali clap), the first beat of a khaali vibhag → closed\n * hihat (the khaali \"wave off\"), every other beat → hihat (fill, keeping the\n * kit's groove going the way a tabla's filler strokes do).\n */\nexport function drumPattern(taal: Pick<Taal, 'numBeats' | 'sam' | 'bhaags' | 'khaali'>): DrumVoice[] {\n const n = taal.numBeats;\n const sam = taal.sam ?? 0;\n const khaali = new Set(taal.khaali ?? []);\n const bhaags = taal.bhaags ?? [n];\n const pattern: DrumVoice[] = new Array(n).fill('hihat');\n\n let pos = 0;\n for (const len of bhaags) {\n pattern[pos] = khaali.has(pos) ? 'hihat' : 'snare';\n pos += len;\n }\n pattern[sam] = 'kick';\n return pattern;\n}\n\n/**\n * Build a melody `Tone.Sampler` for an instrument def. Resolves the sample\n * directory (local → under `soundsBaseUrl`, else the def's absolute CDN URL)\n * and, when a MIDI `range` is given, loads only the samples that cover it.\n */\nexport function createSampler(\n Tone: ToneModule,\n def: InstrumentDef,\n soundsBaseUrl: string | undefined,\n range?: { lo: number; hi: number },\n) {\n const base = def.local ? `${normalizeBase(soundsBaseUrl ?? '')}${def.baseUrl}` : def.baseUrl;\n const urls = range ? subsetUrls(def.urls, range.lo, range.hi) : def.urls;\n return new Tone.Sampler({ urls, baseUrl: normalizeBase(base), release: def.release ?? 1 });\n}\n\n/** Build a tanpura `Tone.Players` loading only the given pitch-class stems\n * (the drone only ever plays Sa + Pa, so we fetch 2 files, not 12). */\nexport function createTanpura(Tone: ToneModule, base: string, stems: readonly string[] = TANPURA_PCS) {\n const urls: Record<string, string> = {};\n for (const s of stems) urls[s] = `${s}.mp3`;\n return new Tone.Players({ urls, baseUrl: `${normalizeBase(base)}tanpura/` });\n}\n","/**\n * Print / \"Save as PDF\" support.\n *\n * High-fidelity PDF of আকারমাত্রিক notation can only come from the browser's\n * own print engine — it reuses the exact HarfBuzz shaping (reph, conjuncts,\n * matra) and the CSS-drawn marks (octave dots, slur arcs, danda strokes) that\n * the viewer renders on screen. Rasterizers (html2canvas) and PDF-primitive\n * libraries (jsPDF/pdfmake) have no Indic shaping and drop pseudo-element\n * marks, so we deliberately avoid them. Staff notation (lang `staff`) is drawn\n * by abcjs to SVG, which the same print engine engraves faithfully.\n *\n * `renderPrintDocument` builds a self-contained HTML page from the pure\n * `renderToHtml` + `SWARALIPI_CSS` (so it sidesteps the shadow-DOM \"print drops\n * encapsulated styles\" gotcha); `printSwaralipi` prints it via a hidden iframe.\n * Both reuse the same renderer as the viewer, so the PDF matches the screen.\n *\n * Every printed page also carries a light diagonal watermark and a notator\n * credit footer — both defaulted for gitabitan.io but overridable by consumers.\n */\nimport type { Swaralipi } from '../spec/index.js';\nimport type { ViewerLang } from './glyphs.js';\nimport { renderToHtml } from './render.js';\nimport { renderStaffHtml, type StaffOptions } from './staff.js';\nimport { SWARALIPI_CSS, SWARALIPI_PRINT_CSS, SWARALIPI_STAFF_CSS } from './styles.js';\n\n/** Default diagonal page watermark (empty string disables it). */\nexport const DEFAULT_WATERMARK = 'www.gitabitan.io';\n/** Default notator credit printed in the footer. */\nexport const DEFAULT_NOTATOR = 'gitabitan.io Team';\n\nexport interface PrintOptions extends StaffOptions {\n /** Notation + UI language. `staff` = Western staff notation. Default `bn`. */\n lang?: ViewerLang;\n /** Render the নাম/তাল header block. Default true. */\n showHeader?: boolean;\n /** Lyric/title transliterator for hi/en (see loadLyricTransliterator). */\n transliterate?: (bengaliText: string) => string;\n /** Document `<title>` — the browser's default \"Save as PDF\" filename.\n * Defaults to the document's `meta.title`. */\n title?: string;\n /** Diagonal full-page watermark. Default `www.gitabitan.io`; '' to disable. */\n watermark?: string;\n /** Notator credited in the footer. Default `gitabitan.io Team`; '' to disable.\n * A document's `meta.notationBy` takes precedence when present. */\n notator?: string;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/** Fixed diagonal watermark that repeats on every printed page (Chrome tiles a\n * `position: fixed` layer per page). currentColor kept very faint. */\nfunction watermarkCss(text: string): string {\n if (!text) return '';\n return `\n.sw-watermark {\n position: fixed; inset: 0; z-index: 0; pointer-events: none;\n display: flex; align-items: center; justify-content: center;\n overflow: hidden;\n -webkit-print-color-adjust: exact; print-color-adjust: exact;\n}\n.sw-watermark span {\n font-size: 11vw; font-weight: 700; letter-spacing: .08em;\n color: rgba(0,0,0,0.07); transform: rotate(-35deg); white-space: nowrap;\n}\nbody > .sw-sheet, body > .sw-footer { position: relative; z-index: 1; }\n`;\n}\n\n/** Build the body chrome (watermark layer + notator footer) shared by all langs. */\nfunction chrome(text: string, notator: string): { top: string; bottom: string } {\n const top = text ? `<div class=\"sw-watermark\" aria-hidden=\"true\"><span>${escapeHtml(text)}</span></div>` : '';\n const bottom = notator ? `<footer class=\"sw-footer\">${escapeHtml(notator)}</footer>` : '';\n return { top, bottom };\n}\n\n/** Resolve the notator: doc's meta.notationBy wins, else the option/default. */\nfunction resolveNotator(doc: Swaralipi, opts: PrintOptions): string {\n return doc.meta.notationBy ?? opts.notator ?? DEFAULT_NOTATOR;\n}\n\n/** Assemble the full standalone HTML page around a rendered body fragment. */\nfunction pageHtml(lang: ViewerLang, title: string, bodyHtml: string, opts: PrintOptions, doc: Swaralipi): string {\n const watermark = opts.watermark ?? DEFAULT_WATERMARK;\n const { top, bottom } = chrome(watermark, resolveNotator(doc, opts));\n return `<!doctype html>\n<html lang=\"${escapeHtml(lang)}\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${escapeHtml(title)}</title>\n<style>\n${SWARALIPI_CSS}\n${SWARALIPI_STAFF_CSS}\n${SWARALIPI_PRINT_CSS}\n${watermarkCss(watermark)}\nhtml, body { margin: 0; }\nbody { color: #111; background: #fff; padding: 16px; -webkit-print-color-adjust: exact; print-color-adjust: exact; }\n.sw-sheet { max-width: 100%; }\n.sw-footer { margin-top: 12px; padding-top: 6px; border-top: 1px solid #ddd; font-size: 12px; color: #555; text-align: right; }\n</style>\n</head>\n<body>${top}${bodyHtml}${bottom}</body>\n</html>`;\n}\n\n/**\n * Build a complete, standalone HTML document for printing an akarmatrik\n * (bn/hi/en) swaralipi sheet, with watermark + notator footer. Usable for a\n * hidden-iframe print, a new browser tab, or server-side headless-Chrome PDF.\n *\n * For `lang: 'staff'` this renders the grid instead (staff engraving is async\n * — use `renderStaffPrintDocument` or `printSwaralipi`, which handle it).\n */\nexport function renderPrintDocument(doc: Swaralipi, opts: PrintOptions = {}): string {\n const lang: ViewerLang = opts.lang === 'staff' ? 'bn' : opts.lang ?? 'bn';\n const tr = lang !== 'bn' && opts.transliterate ? opts.transliterate : (s: string) => s;\n const title = opts.title ?? tr(doc.meta.title);\n const body = renderToHtml(doc, { lang, showHeader: opts.showHeader, transliterate: opts.transliterate });\n return pageHtml(lang, title, body, opts, doc);\n}\n\n/**\n * Async variant that engraves staff notation (abcjs) into the print page. Falls\n * back to the grid document for non-staff langs. Returns a self-contained HTML\n * string (for headless-Chrome PDF or a print iframe).\n */\nexport async function renderStaffPrintDocument(doc: Swaralipi, opts: PrintOptions = {}): Promise<string> {\n if (opts.lang !== 'staff') return renderPrintDocument(doc, opts);\n const title = opts.title ?? doc.meta.title;\n // renderStaffHtml renders the shared নাম/তাল/আবর্তন/স্বরলিপিকার header itself\n // (same block as the grid), so the page just wraps its output.\n const staff = await renderStaffHtml(doc, opts);\n return pageHtml('en', title, staff, opts, doc);\n}\n\n/**\n * Open the browser print dialog for a swaralipi document (the user picks a\n * printer or \"Save as PDF\"). Renders into an off-screen iframe so it prints\n * only the sheet — independent of the host page's chrome and CSS — then cleans\n * up. Browser-only; throws in a non-DOM environment (use renderPrintDocument /\n * renderStaffPrintDocument for SSR / headless-Chrome instead).\n */\nexport function printSwaralipi(doc: Swaralipi, opts: PrintOptions = {}): void {\n if (typeof document === 'undefined') {\n throw new Error('printSwaralipi requires a DOM; use renderPrintDocument() for server-side PDF');\n }\n // Grid langs render synchronously (preserving the sync print contract); only\n // staff must await abcjs before the iframe exists.\n if (opts.lang === 'staff') {\n void renderStaffPrintDocument(doc, opts).then(printHtmlInIframe);\n } else {\n printHtmlInIframe(renderPrintDocument(doc, opts));\n }\n}\n\n/** Print an already-assembled HTML page via a hidden, off-screen iframe. */\nfunction printHtmlInIframe(html: string): void {\n const iframe = document.createElement('iframe');\n iframe.setAttribute('aria-hidden', 'true');\n // off-screen but rendered (display:none iframes print blank); a page-ish\n // width so rows lay out before the print stylesheet takes over.\n iframe.style.cssText = 'position:fixed; left:-10000px; top:0; width:800px; height:600px; border:0;';\n\n iframe.onload = () => {\n const win = iframe.contentWindow;\n if (win === null) {\n iframe.remove();\n return;\n }\n const cleanup = () => setTimeout(() => iframe.remove(), 1000);\n win.addEventListener('afterprint', cleanup, { once: true });\n let printed = false;\n const go = () => {\n if (printed) return;\n printed = true;\n try {\n win.focus();\n win.print();\n } catch {\n /* printing unavailable (e.g. headless) — leave cleanup to afterprint */\n }\n };\n // The notation is rendered ENTIRELY in the CDN notation fonts, so a\n // not-yet-downloaded face prints as raw ASCII — or blank, under\n // `font-display: block`. `fonts.ready` alone is not enough: it can resolve\n // before layout has even requested the faces. Force each declared face to\n // download, then print; a timeout prints anyway so a slow/unreachable font\n // (e.g. a lang whose CDN font isn't up yet) never blocks the dialog.\n const fonts = iframe.contentDocument?.fonts;\n if (fonts && typeof fonts.forEach === 'function') {\n const loads: Promise<unknown>[] = [Promise.resolve(fonts.ready)];\n fonts.forEach((face) => loads.push(face.load().catch(() => undefined)));\n void Promise.all(loads).then(go);\n setTimeout(go, 3000); // never let a slow/unreachable font block the dialog\n } else {\n setTimeout(go, 250);\n }\n };\n\n iframe.srcdoc = html;\n document.body.appendChild(iframe);\n}\n","/**\n * Lazy lyric transliteration for `hi` / `en` renders.\n *\n * Swara glyphs come from the sync tables in glyphs.ts; only *linguistic*\n * text (lyrics, title, names) needs transliteration, so sanscript loads via\n * dynamic import — `bn`-only consumers (and their bundles) never touch it.\n */\nimport type { GridLang, ViewerLang } from './glyphs.js';\n\nexport type Transliterator = (bengaliText: string) => string;\n\nconst TARGET: Record<Exclude<GridLang, 'bn'>, string> = {\n hi: 'devanagari',\n en: 'iast',\n};\n\n/**\n * Load a Bengali→target transliterator for the given viewer language.\n * Returns undefined for `bn` (no work to do). Pass the result as\n * `RenderOptions.transliterate`; the `<swaralipi-sheet>` element wires this\n * automatically when its `lang` attribute changes.\n */\nexport async function loadLyricTransliterator(lang: ViewerLang): Promise<Transliterator | undefined> {\n if (lang === 'bn' || lang === 'staff') return undefined; // staff has no lyric script to convert\n const mod = (await import('@indic-transliteration/sanscript')) as {\n default?: { t(text: string, from: string, to: string): string };\n t?(text: string, from: string, to: string): string;\n };\n const sanscript = mod.default ?? mod;\n const target = TARGET[lang];\n return (text) => sanscript.t!(text, 'bengali', target);\n}\n","/**\n * The `<swaralipi-sheet>` custom element — a thin shadow-DOM shell around\n * the pure renderer.\n *\n * The element class is created lazily inside defineSwaralipiSheet():\n * a top-level `extends HTMLElement` would throw on import in Node, and this\n * module must stay importable for SSR (where only renderToHtml is used).\n * Nothing registers automatically — call defineSwaralipiSheet() once.\n *\n * Validation is off by default (converter output is pre-validated); setting\n * `validate = true` parses documents against the Zod schema via a dynamic\n * import, so the viewer bundle stays free of bare runtime imports (it can\n * be loaded directly from dist/ in a browser without a bundler).\n */\nimport type { Swaralipi } from '../spec/index.js';\nimport { renderToHtml } from './render.js';\nimport { renderStaffHtml, type StaffOptions } from './staff.js';\nimport { SWARALIPI_CSS, SWARALIPI_STAFF_CSS, NOTATION_FONT_URLS } from './styles.js';\nimport { printSwaralipi, type PrintOptions } from './print.js';\nimport { loadLyricTransliterator, type Transliterator } from './transliterate.js';\nimport type { ViewerLang } from './glyphs.js';\n\nexport interface SwaralipiSheetElement extends HTMLElement {\n /** The document to render (property only; renders on assignment). */\n doc: Swaralipi | undefined;\n /** Parse documents against the spec schema before rendering. */\n validate: boolean;\n /** Add the player-highlight class to the note at \"part.row.note\". */\n highlight(path: string): HTMLElement | null;\n clearHighlights(): void;\n /** Open the print dialog (→ \"Save as PDF\") for the current document. */\n print(options?: PrintOptions): void;\n /** Options for the `staff` language (instrument label, tonic, bpm…). */\n staffOptions: StaffOptions;\n}\n\nconst LANGS: ReadonlySet<string> = new Set(['bn', 'hi', 'en', 'staff']);\n\n/** Browsers ignore @font-face inside a shadow root's (adopted) stylesheet —\n * faces must live at document scope, so register the notation fonts there\n * via the FontFace API. No-op without FontFace (jsdom/SSR) or for any family\n * already present (SSR CSS on the page, or a self-hoster's own declaration). */\nfunction ensureNotationFonts(): void {\n if (typeof FontFace === 'undefined' || typeof document === 'undefined') return;\n const present = new Set<string>();\n for (const f of document.fonts) present.add(f.family.replace(/['\"]/g, ''));\n for (const [family, url] of Object.entries(NOTATION_FONT_URLS)) {\n if (present.has(family)) continue;\n document.fonts.add(new FontFace(family, `url(${url})`, { display: 'block' }));\n }\n}\n\nlet sharedSheet: CSSStyleSheet | undefined;\n\nfunction createElementClass(): CustomElementConstructor {\n return class SwaralipiSheet extends HTMLElement implements SwaralipiSheetElement {\n static observedAttributes = ['src', 'lang', 'hide-header'];\n\n #doc: Swaralipi | undefined;\n #root: ShadowRoot;\n #adopted = false;\n #abort: AbortController | undefined;\n #translit: Transliterator | undefined;\n #translitLang: ViewerLang | undefined;\n #renderSeq = 0;\n #staffOptions: StaffOptions = {};\n validate = false;\n\n constructor() {\n super();\n this.#root = this.attachShadow({ mode: 'open' });\n if (\n typeof CSSStyleSheet !== 'undefined' &&\n 'replaceSync' in CSSStyleSheet.prototype &&\n 'adoptedStyleSheets' in this.#root\n ) {\n if (!sharedSheet) {\n sharedSheet = new CSSStyleSheet();\n sharedSheet.replaceSync(SWARALIPI_CSS + SWARALIPI_STAFF_CSS);\n }\n this.#root.adoptedStyleSheets = [...this.#root.adoptedStyleSheets, sharedSheet];\n this.#adopted = true;\n }\n }\n\n get doc(): Swaralipi | undefined {\n return this.#doc;\n }\n\n set doc(value: Swaralipi | undefined) {\n this.#doc = value;\n if (value !== undefined && this.validate) {\n void import('../spec/index.js')\n .then(({ safeParseSwaralipi }) => {\n const result = safeParseSwaralipi(value);\n if (!result.success) this.#renderError(result.error.message);\n })\n .catch(() => undefined);\n }\n this.#render();\n }\n\n get staffOptions(): StaffOptions {\n return this.#staffOptions;\n }\n\n set staffOptions(value: StaffOptions) {\n this.#staffOptions = value;\n if (this.#lang === 'staff') this.#render(); // live-update the score\n }\n\n get #lang(): ViewerLang {\n const attr = this.getAttribute('lang');\n return attr !== null && LANGS.has(attr) ? (attr as ViewerLang) : 'bn';\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) return;\n if (name === 'src') {\n if (newValue !== null) void this.#load(newValue);\n return;\n }\n if (name === 'lang') this.#ensureTransliterator();\n this.#render();\n }\n\n connectedCallback(): void {\n this.#ensureTransliterator();\n this.#render();\n }\n\n disconnectedCallback(): void {\n this.#abort?.abort();\n }\n\n async #load(url: string): Promise<void> {\n this.#abort?.abort();\n const abort = new AbortController();\n this.#abort = abort;\n try {\n const res = await fetch(url, { signal: abort.signal });\n if (!res.ok) throw new Error(`fetch ${url}: HTTP ${res.status}`);\n this.doc = (await res.json()) as Swaralipi;\n } catch (err) {\n if (abort.signal.aborted) return;\n this.#renderError(err instanceof Error ? err.message : String(err));\n this.dispatchEvent(new ErrorEvent('error', { error: err, message: String(err) }));\n }\n }\n\n /** Load (once per lang) the lyric transliterator, then re-render. */\n #ensureTransliterator(): void {\n const lang = this.#lang;\n if (lang === 'bn' || this.#translitLang === lang) return;\n void loadLyricTransliterator(lang)\n .then((t) => {\n if (t === undefined || this.#lang !== lang) return;\n this.#translit = t;\n this.#translitLang = lang;\n this.#render();\n })\n .catch(() => undefined); // graceful: lyrics stay Bengali\n }\n\n #styleFallback(): string {\n return this.#adopted ? '' : `<style>${SWARALIPI_CSS}${SWARALIPI_STAFF_CSS}</style>`;\n }\n\n #render(): void {\n const seq = ++this.#renderSeq; // guards against out-of-order async staff renders\n if (this.#doc === undefined) {\n this.#root.innerHTML = this.#styleFallback();\n return;\n }\n const lang = this.#lang;\n if (lang === 'staff') {\n const doc = this.#doc;\n void renderStaffHtml(doc, this.staffOptions)\n .then((html) => {\n if (seq === this.#renderSeq) this.#root.innerHTML = this.#styleFallback() + html;\n })\n .catch(() => undefined);\n return;\n }\n const html = renderToHtml(this.#doc, {\n lang,\n showHeader: !this.hasAttribute('hide-header'),\n transliterate: this.#translitLang === lang ? this.#translit : undefined,\n });\n this.#root.innerHTML = this.#styleFallback() + html;\n }\n\n #renderError(message: string): void {\n const div = document.createElement('div');\n div.className = 'sw-error';\n div.textContent = message;\n this.#root.innerHTML = this.#styleFallback();\n this.#root.appendChild(div);\n }\n\n highlight(path: string): HTMLElement | null {\n if (!/^\\d+\\.\\d+\\.\\d+$/.test(path)) return null;\n const el = this.#root.querySelector<HTMLElement>(`[data-note=\"${path}\"]`);\n el?.classList.add('sw-hl');\n return el;\n }\n\n clearHighlights(): void {\n for (const el of this.#root.querySelectorAll('.sw-hl')) el.classList.remove('sw-hl');\n }\n\n print(options: PrintOptions = {}): void {\n if (this.#doc === undefined) return;\n const lang = this.#lang;\n printSwaralipi(this.#doc, {\n lang,\n showHeader: !this.hasAttribute('hide-header'),\n transliterate: this.#translitLang === lang ? this.#translit : undefined,\n ...(lang === 'staff' ? this.staffOptions : {}),\n ...options,\n });\n }\n };\n}\n\n/** Per-tag constructors: a custom-element class can only be registered\n * under one name, so each tag gets its own. */\nconst registered = new Map<string, CustomElementConstructor>();\n\n/**\n * Register `<swaralipi-sheet>` (or a custom tag name). Idempotent. Throws\n * outside a DOM environment — use renderToHtml() for SSR.\n */\nexport function defineSwaralipiSheet(tagName = 'swaralipi-sheet'): CustomElementConstructor {\n if (typeof customElements === 'undefined' || typeof HTMLElement === 'undefined') {\n throw new Error('swaralipi-sheet requires a DOM; use renderToHtml() for server-side rendering');\n }\n const existing = customElements.get(tagName);\n if (existing) return existing;\n ensureNotationFonts();\n const ctor = registered.get(tagName) ?? createElementClass();\n registered.set(tagName, ctor);\n customElements.define(tagName, ctor);\n return ctor;\n}\n"]}