@ugfoundation/swaralipi-js 0.8.0 → 0.8.2
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.
- package/dist/{batch-NJMT3M5Z.js → batch-6FPBT5DP.js} +4 -4
- package/dist/{batch-NJMT3M5Z.js.map → batch-6FPBT5DP.js.map} +1 -1
- package/dist/{chunk-4HMHTXDE.js → chunk-FULC22MN.js} +3 -3
- package/dist/{chunk-4HMHTXDE.js.map → chunk-FULC22MN.js.map} +1 -1
- package/dist/{chunk-YFVAVICF.js → chunk-UMBKIGVQ.js} +3 -3
- package/dist/{chunk-YFVAVICF.js.map → chunk-UMBKIGVQ.js.map} +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/convert/index.cjs +1 -1
- package/dist/convert/index.cjs.map +1 -1
- package/dist/convert/index.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/spec/index.cjs +1 -1
- package/dist/spec/index.cjs.map +1 -1
- package/dist/spec/index.d.cts +1 -1
- package/dist/spec/index.d.ts +1 -1
- package/dist/spec/index.js +1 -1
- package/dist/viewer/index.cjs +156 -87
- package/dist/viewer/index.cjs.map +1 -1
- package/dist/viewer/index.d.cts +11 -5
- package/dist/viewer/index.d.ts +11 -5
- package/dist/viewer/index.js +155 -86
- package/dist/viewer/index.js.map +1 -1
- package/package.json +1 -1
package/dist/viewer/index.cjs
CHANGED
|
@@ -260,7 +260,7 @@ var init_spec = __esm({
|
|
|
260
260
|
init_grace();
|
|
261
261
|
init_lay();
|
|
262
262
|
init_svara();
|
|
263
|
-
SPEC_VERSION = "0.8.
|
|
263
|
+
SPEC_VERSION = "0.8.2";
|
|
264
264
|
}
|
|
265
265
|
});
|
|
266
266
|
|
|
@@ -642,42 +642,64 @@ function alignRows(rows) {
|
|
|
642
642
|
}
|
|
643
643
|
function resolveArcs(cells) {
|
|
644
644
|
const arcs = [];
|
|
645
|
-
let
|
|
645
|
+
let open;
|
|
646
646
|
let sawEnds = false;
|
|
647
647
|
const fillCells = [];
|
|
648
|
-
const openAt = (
|
|
648
|
+
const openAt = (cell, note) => {
|
|
649
649
|
sawEnds = true;
|
|
650
|
-
|
|
650
|
+
open ??= { cell, note };
|
|
651
651
|
};
|
|
652
|
-
const closeAt = (
|
|
652
|
+
const closeAt = (cell, note) => {
|
|
653
653
|
sawEnds = true;
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
654
|
+
const from = open ?? { cell: 0, note: 0 };
|
|
655
|
+
arcs.push({
|
|
656
|
+
start: from.cell,
|
|
657
|
+
startNote: from.note,
|
|
658
|
+
end: cell,
|
|
659
|
+
endNote: note,
|
|
660
|
+
openLeft: open === void 0,
|
|
661
|
+
openRight: false
|
|
662
|
+
});
|
|
663
|
+
open = void 0;
|
|
660
664
|
};
|
|
661
665
|
cells.forEach((cell, i) => {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
666
|
+
const pitched = cell.notes.flatMap((n, j) => isPitched(n) ? [j] : []);
|
|
667
|
+
const first = pitched[0] ?? 0;
|
|
668
|
+
const last = pitched[pitched.length - 1] ?? cell.notes.length - 1;
|
|
669
|
+
let marks = "";
|
|
670
|
+
cell.notes.forEach((note, j) => {
|
|
671
|
+
if (note.meend === "start") openAt(i, j);
|
|
672
|
+
else if (note.meend === "end") closeAt(i, j);
|
|
673
|
+
for (const b of note.below ?? []) if (isArcRaw(b.raw)) marks += b.raw;
|
|
674
|
+
});
|
|
675
|
+
const reopens = /[xX].*[wW]/.test(marks);
|
|
676
|
+
for (const ch of marks) {
|
|
677
|
+
if (ch === "w" || ch === "W") openAt(i, reopens ? last : first);
|
|
678
|
+
else if (ch === "x" || ch === "X") closeAt(i, reopens ? first : last);
|
|
679
|
+
else if (ch === "$") {
|
|
680
|
+
openAt(i, first);
|
|
681
|
+
closeAt(i, last);
|
|
682
|
+
} else fillCells.push(i);
|
|
673
683
|
}
|
|
674
684
|
});
|
|
675
|
-
|
|
676
|
-
|
|
685
|
+
const lastCell = Math.max(cells.length - 1, 0);
|
|
686
|
+
const lastNote = (c) => Math.max((cells[c]?.notes.length ?? 1) - 1, 0);
|
|
687
|
+
if (open !== void 0) {
|
|
688
|
+
arcs.push({
|
|
689
|
+
start: open.cell,
|
|
690
|
+
startNote: open.note,
|
|
691
|
+
end: lastCell,
|
|
692
|
+
endNote: lastNote(lastCell),
|
|
693
|
+
openLeft: false,
|
|
694
|
+
openRight: true
|
|
695
|
+
});
|
|
677
696
|
} else if (!sawEnds && fillCells.length > 0) {
|
|
697
|
+
const end = Math.max(...fillCells);
|
|
678
698
|
arcs.push({
|
|
679
699
|
start: Math.min(...fillCells),
|
|
680
|
-
|
|
700
|
+
startNote: 0,
|
|
701
|
+
end,
|
|
702
|
+
endNote: lastNote(end),
|
|
681
703
|
openLeft: true,
|
|
682
704
|
openRight: true,
|
|
683
705
|
line: true
|
|
@@ -685,6 +707,35 @@ function resolveArcs(cells) {
|
|
|
685
707
|
}
|
|
686
708
|
return arcs;
|
|
687
709
|
}
|
|
710
|
+
function arcInk(cells, arcs) {
|
|
711
|
+
const ink = { cells: cells.map(() => ""), notes: cells.map((c) => c.notes.map(() => "")) };
|
|
712
|
+
const mark = (c, j, cls, clip = false) => {
|
|
713
|
+
ink.notes[c][j] += ` ${cls}`;
|
|
714
|
+
if (clip && !ink.cells[c].includes(" sw-mk")) ink.cells[c] += " sw-mk";
|
|
715
|
+
};
|
|
716
|
+
for (const arc of arcs) {
|
|
717
|
+
const { start: s, end: e, startNote: j, endNote: k } = arc;
|
|
718
|
+
const hookL = arc.line !== true && !arc.openLeft;
|
|
719
|
+
const hookR = arc.line !== true && !arc.openRight;
|
|
720
|
+
if (s === e && hookL && hookR) {
|
|
721
|
+
if (j === k) {
|
|
722
|
+
mark(s, j, "sw-mos");
|
|
723
|
+
mark(s, j, "sw-mcs");
|
|
724
|
+
} else {
|
|
725
|
+
mark(s, j, "sw-mob");
|
|
726
|
+
for (let n = j + 1; n < k; n++) mark(s, n, "sw-mf");
|
|
727
|
+
mark(s, k, "sw-mcb");
|
|
728
|
+
}
|
|
729
|
+
continue;
|
|
730
|
+
}
|
|
731
|
+
for (let c = s; c <= e; c++) {
|
|
732
|
+
if (c === s && hookL) mark(c, j, "sw-mo", true);
|
|
733
|
+
else if (c === e && hookR) mark(c, k, "sw-mc", true);
|
|
734
|
+
else mark(c, 0, "sw-mm", true);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return ink;
|
|
738
|
+
}
|
|
688
739
|
var SVARA_CHAR = /[srgmpqndtkuv]/;
|
|
689
740
|
function rawMarks(raw, count) {
|
|
690
741
|
if (raw === void 0) return void 0;
|
|
@@ -860,21 +911,9 @@ function renderNote(note, kind, opts, ctx) {
|
|
|
860
911
|
const raw = rawDisplay(note);
|
|
861
912
|
return bracketGlyphs(note, "open") + (raw !== void 0 ? `<span class="sw-raw" title="${escapeHtml(raw)}">${escapeHtml(raw)}</span>` : "") + bracketGlyphs(note, "close");
|
|
862
913
|
}
|
|
863
|
-
function renderArc(arc, offset) {
|
|
864
|
-
const open = arc.line === true;
|
|
865
|
-
const cls = [
|
|
866
|
-
"sw-arc",
|
|
867
|
-
arc.openLeft || open ? "sw-arc--openl" : "",
|
|
868
|
-
arc.openRight || open ? "sw-arc--openr" : ""
|
|
869
|
-
].filter(Boolean).join(" ");
|
|
870
|
-
const left = open || arc.openLeft ? "" : '<i class="sw-arc-l">w</i>';
|
|
871
|
-
const right = open || arc.openRight ? "" : '<i class="sw-arc-r">x</i>';
|
|
872
|
-
const from = offset + arc.start + COL_BASE;
|
|
873
|
-
const to = offset + arc.end + COL_BASE + 1;
|
|
874
|
-
return `<span class="${cls}" style="grid-column:${from} / ${to}">${left}<i class="sw-arc-m"></i>${right}</span>`;
|
|
875
|
-
}
|
|
876
914
|
function renderRow(row, partIdx, rowIdx, offset, ctx) {
|
|
877
915
|
const cells = groupRowIntoCells(row.notes);
|
|
916
|
+
const ink = arcInk(cells, resolveArcs(cells));
|
|
878
917
|
const out = [];
|
|
879
918
|
if (row.label !== void 0)
|
|
880
919
|
out.push(`<span class="sw-label">${escapeHtml(ctx.tr(row.label))}</span>`);
|
|
@@ -884,11 +923,10 @@ function renderRow(row, partIdx, rowIdx, offset, ctx) {
|
|
|
884
923
|
const barCls = cell.kind === "bar" ? " sw-bar-cell" : "";
|
|
885
924
|
const notes = cell.notes.map((note, j) => {
|
|
886
925
|
const path = `${partIdx}.${rowIdx}.${cell.start + j}`;
|
|
887
|
-
const cls = isPitched(note) ? " sw-p" : "";
|
|
888
926
|
const bar = note.bar !== void 0 ? ` sw-bar sw-bar--${note.bar}` : "";
|
|
889
|
-
return `<span class="sw-n${
|
|
927
|
+
return `<span class="sw-n${bar}${ink.notes[ci][j]}" data-note="${path}">${renderNote(note, cell.kind, opts[j], ctx)}</span>`;
|
|
890
928
|
}).join("");
|
|
891
|
-
out.push(`<span class="sw-cell${barCls}" style="grid-column:${col}">${notes}</span>`);
|
|
929
|
+
out.push(`<span class="sw-cell${barCls}${ink.cells[ci]}" style="grid-column:${col}">${notes}</span>`);
|
|
892
930
|
const slices = cellLyricSlices(cell);
|
|
893
931
|
if (slices !== void 0) {
|
|
894
932
|
const html = slices.map((t) => `<span>${escapeHtml(lyricText(t, ctx))}</span>`).join("");
|
|
@@ -901,7 +939,6 @@ function renderRow(row, partIdx, rowIdx, offset, ctx) {
|
|
|
901
939
|
if (below.length > 0)
|
|
902
940
|
out.push(`<span class="sw-below" style="grid-column:${col}">${renderAnnotation(below, ctx)}</span>`);
|
|
903
941
|
});
|
|
904
|
-
for (const arc of resolveArcs(cells)) out.push(renderArc(arc, offset));
|
|
905
942
|
return `<div class="sw-row">${out.join("")}</div>`;
|
|
906
943
|
}
|
|
907
944
|
function renderHeader(meta, ctx) {
|
|
@@ -959,7 +996,7 @@ function fitSwaralipi(root, minScale = 0, zoom = 1, minSpacing = 0.35, minSize =
|
|
|
959
996
|
sheet.style.removeProperty("--sw-size");
|
|
960
997
|
sheet.style.removeProperty("--sw-tight");
|
|
961
998
|
const available = scroll.clientWidth;
|
|
962
|
-
let natural = block.
|
|
999
|
+
let natural = block.offsetWidth;
|
|
963
1000
|
if (available === 0 || natural === 0) continue;
|
|
964
1001
|
if (natural > available && minSpacing < 1) {
|
|
965
1002
|
let loose = minSpacing;
|
|
@@ -967,11 +1004,11 @@ function fitSwaralipi(root, minScale = 0, zoom = 1, minSpacing = 0.35, minSize =
|
|
|
967
1004
|
for (let i = 0; i < 6; i++) {
|
|
968
1005
|
const mid = (loose + tight) / 2;
|
|
969
1006
|
sheet.style.setProperty("--sw-tight", String(mid));
|
|
970
|
-
if (block.
|
|
1007
|
+
if (block.offsetWidth <= available) loose = mid;
|
|
971
1008
|
else tight = mid;
|
|
972
1009
|
}
|
|
973
1010
|
sheet.style.setProperty("--sw-tight", String(loose));
|
|
974
|
-
natural = block.
|
|
1011
|
+
natural = block.offsetWidth;
|
|
975
1012
|
}
|
|
976
1013
|
const base = parseFloat(getComputedStyle(sheet).fontSize);
|
|
977
1014
|
if (!(base > 0)) continue;
|
|
@@ -1069,31 +1106,45 @@ ${FONT_FACES}
|
|
|
1069
1106
|
column-gap: calc(var(--sw-cell-gap, 0.4em) * var(--sw-tight, 1));
|
|
1070
1107
|
align-items: end;
|
|
1071
1108
|
width: max-content;
|
|
1109
|
+
/* The last column's cell spacers overhang half a gap past the grid; clip
|
|
1110
|
+
that sideways so it neither counts as width to fit nor raises a scrollbar. */
|
|
1111
|
+
overflow-x: clip;
|
|
1072
1112
|
}
|
|
1073
1113
|
.sw-part { display: contents; }
|
|
1114
|
+
/* Four FIXED bands per row \u2014 above / notation / arc / lyric \u2014 so a beat label,
|
|
1115
|
+
* a \u0995\u09A3 or a \u09AE\u09C0\u09A1\u09BC never changes how far a line sits from its words: the
|
|
1116
|
+
* notation hugs its lyric and the next system starts a little further off,
|
|
1117
|
+
* as the printed \u09B8\u09CD\u09AC\u09B0\u09AC\u09BF\u09A4\u09BE\u09A8 sets it. Content taller than its band overflows
|
|
1118
|
+
* rather than pushing the rhythm apart. */
|
|
1074
1119
|
.sw-row {
|
|
1075
1120
|
grid-column: 1 / -1;
|
|
1076
1121
|
display: grid;
|
|
1077
1122
|
grid-template-columns: subgrid;
|
|
1078
|
-
grid-template-rows:
|
|
1123
|
+
grid-template-rows: 0.95em 1.35em 0.4em 1.35em;
|
|
1079
1124
|
align-items: end;
|
|
1080
|
-
padding: 0.
|
|
1125
|
+
padding-bottom: 0.35em;
|
|
1126
|
+
line-height: 1.35;
|
|
1081
1127
|
}
|
|
1082
1128
|
.sw-label { grid-column: 1; grid-row: 2; padding-right: 0.5em; font-weight: 600; }
|
|
1083
1129
|
|
|
1084
|
-
/* One column per cell
|
|
1085
|
-
* flex
|
|
1086
|
-
*
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
.sw-cell
|
|
1090
|
-
.sw-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
.sw-
|
|
1096
|
-
.sw-
|
|
1130
|
+
/* One column per cell, its notes set tight as one word (\u09B0\u09B8\u09BE) and centred by
|
|
1131
|
+
* two flex spacers. Each spacer overhangs half the column gap (a min-width
|
|
1132
|
+
* paid back by a negative margin, so the column is sized by the notes alone),
|
|
1133
|
+
* which lets neighbouring cells' spacers meet mid-gap: a \u09AE\u09C0\u09A1\u09BC crossing cells is
|
|
1134
|
+
* inked by these boxes with no hole between them. */
|
|
1135
|
+
.sw-cell, .sw-lyr { display: flex; justify-content: center; white-space: nowrap; }
|
|
1136
|
+
.sw-cell {
|
|
1137
|
+
--sw-half-gap: calc(var(--sw-cell-gap, 0.4em) * var(--sw-tight, 1) / 2);
|
|
1138
|
+
grid-row: 2;
|
|
1139
|
+
align-self: stretch;
|
|
1140
|
+
}
|
|
1141
|
+
.sw-cell::before, .sw-cell::after { content: ''; flex: 1 0 0; min-width: var(--sw-half-gap); }
|
|
1142
|
+
.sw-cell::before { margin-left: calc(var(--sw-half-gap) * -1); }
|
|
1143
|
+
.sw-cell::after { margin-right: calc(var(--sw-half-gap) * -1); }
|
|
1144
|
+
.sw-cell > .sw-n { position: relative; }
|
|
1145
|
+
.sw-above { grid-row: 1; font-size: 0.62em; line-height: 1; justify-self: center; white-space: nowrap; }
|
|
1146
|
+
.sw-below { grid-row: 3; font-size: 0.62em; line-height: 1; justify-self: center; white-space: nowrap; }
|
|
1147
|
+
.sw-lyr { grid-row: 4; }
|
|
1097
1148
|
|
|
1098
1149
|
/* ---- notation clusters & marks ---- */
|
|
1099
1150
|
.sw-cl { position: relative; display: inline-block; }
|
|
@@ -1114,12 +1165,16 @@ ${FONT_FACES}
|
|
|
1114
1165
|
.sw-ati-taar::before { top: -0.3em; }
|
|
1115
1166
|
.sw-ati-mandra::before { bottom: -0.35em; }
|
|
1116
1167
|
|
|
1117
|
-
/* grace notes: small raised clusters \u2014 \u0995\u09A3 before the note, \u09B0\u09C7\u09B6 after it
|
|
1168
|
+
/* grace notes: small raised clusters \u2014 \u0995\u09A3 before the note, \u09B0\u09C7\u09B6 after it.
|
|
1169
|
+
* line-height 0 (here and on .sw-micro): a raised inline box taller than the
|
|
1170
|
+
* strut grows its line box and drops that one note's baseline below its
|
|
1171
|
+
* neighbours' (css2 \xA710.8). */
|
|
1118
1172
|
.sw-kan,
|
|
1119
1173
|
.sw-resh {
|
|
1120
1174
|
position: relative;
|
|
1121
1175
|
display: inline-block;
|
|
1122
1176
|
font-size: 0.58em;
|
|
1177
|
+
line-height: 0;
|
|
1123
1178
|
vertical-align: 0.75em;
|
|
1124
1179
|
}
|
|
1125
1180
|
.sw-kan { margin-right: 0.08em; }
|
|
@@ -1151,7 +1206,7 @@ ${FONT_FACES}
|
|
|
1151
1206
|
.sw-cut::before { top: 0.2em; }
|
|
1152
1207
|
.sw-cut::after { top: 0.55em; }
|
|
1153
1208
|
.sw-br { opacity: 0.8; padding: 0 0.06em; }
|
|
1154
|
-
.sw-micro { font-size: 0.6em; vertical-align: super; opacity: 0.8; }
|
|
1209
|
+
.sw-micro { font-size: 0.6em; line-height: 0; vertical-align: super; opacity: 0.8; }
|
|
1155
1210
|
|
|
1156
1211
|
/* raw fallback: never dropped, visibly non-notation. Swarabitan first \u2014
|
|
1157
1212
|
* raw IS that font's encoding, so undecoded cells show NLTR's own glyphs
|
|
@@ -1171,32 +1226,46 @@ ${FONT_FACES}
|
|
|
1171
1226
|
/* a bar owns a whole column but needs no matra of width */
|
|
1172
1227
|
.sw-bar-cell { min-width: 0; }
|
|
1173
1228
|
|
|
1174
|
-
/* ---- \u09AE\u09C0\u09A1\u09BC under-arcs (from w/x segments and spec meend) ----
|
|
1175
|
-
* Swarabitan
|
|
1176
|
-
* flat
|
|
1177
|
-
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1180
|
-
.sw-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1229
|
+
/* ---- \u09AE\u09C0\u09A1\u09BC under-arcs (from w/x/$ segments and spec meend) ----
|
|
1230
|
+
* Swarabitan's own arc, all langs: w is the opening hook, curling down from
|
|
1231
|
+
* its tip into a flat, x its mirror, y that flat alone \u2014 and they join
|
|
1232
|
+
* hole-free, so one run of text is a whole end (tools/align-check/glyph.html).
|
|
1233
|
+
* Each end sets its hook tip on its note's centre and runs the flat toward the
|
|
1234
|
+
* other end (render.ts arcInk): across cells it is cut at the mid-gap, where
|
|
1235
|
+
* the next cell's run carries on (.sw-mk clips a cell half a gap past each
|
|
1236
|
+
* side, as far as its spacers reach); inside one cell, at its note's edge. So
|
|
1237
|
+
* a long arc extends the flat and a short one trims it off. line-height 0 sets
|
|
1238
|
+
* every run's baseline the same distance below its note. The clip reaches
|
|
1239
|
+
* 0.5px further so two cells' anti-aliased edges overlap instead of leaving a
|
|
1240
|
+
* hairline seam between their identical flats. */
|
|
1241
|
+
.sw-mk { clip-path: inset(-3em calc(var(--sw-half-gap) * -1 - 0.5px)); }
|
|
1242
|
+
.sw-mo::after, .sw-mob::after, .sw-mos::after,
|
|
1243
|
+
.sw-mc::before, .sw-mcb::before, .sw-mcs::before,
|
|
1244
|
+
.sw-mf::before, .sw-mm::before {
|
|
1245
|
+
content: 'yyyyyyyyyyyy';
|
|
1246
|
+
position: absolute;
|
|
1247
|
+
top: calc(100% + 0.05em);
|
|
1248
|
+
font-family: Swarabitan;
|
|
1185
1249
|
font-size: 0.9em;
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
.sw-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1250
|
+
line-height: 0;
|
|
1251
|
+
white-space: pre;
|
|
1252
|
+
overflow-x: clip;
|
|
1253
|
+
}
|
|
1254
|
+
.sw-mo::after, .sw-mob::after, .sw-mos::after { content: 'wyyyyyyyyyyyy'; }
|
|
1255
|
+
/* rtl: a closing run cut short keeps its hook on its right edge */
|
|
1256
|
+
.sw-mc::before, .sw-mcb::before, .sw-mcs::before { content: 'yyyyyyyyyyyyx'; direction: rtl; }
|
|
1257
|
+
.sw-mo::after, .sw-mob::after { left: 50%; }
|
|
1258
|
+
.sw-mc::before, .sw-mcb::before { right: 50%; }
|
|
1259
|
+
.sw-mos::after { left: 0; }
|
|
1260
|
+
.sw-mcs::before { right: 0; }
|
|
1261
|
+
.sw-mf::before { left: 0; right: 0; }
|
|
1262
|
+
.sw-mm::before { left: -12em; }
|
|
1263
|
+
/* Inside one cell a hook gets half a note to curl in, about a third of its
|
|
1264
|
+
* curl: squeezed to half width (same stroke) it lands flat at the cut, so the
|
|
1265
|
+
* two flats meet level whatever the notes' widths \u2014 a small arc, not a V. */
|
|
1266
|
+
.sw-mob::after, .sw-mos::after, .sw-mcb::before, .sw-mcs::before { width: 100%; transform: scaleX(0.5); }
|
|
1267
|
+
.sw-mob::after, .sw-mos::after { transform-origin: left; }
|
|
1268
|
+
.sw-mcb::before, .sw-mcs::before { transform-origin: right; }
|
|
1200
1269
|
|
|
1201
1270
|
/* ---- annotation content ---- */
|
|
1202
1271
|
.sw-beat { position: relative; display: inline-block; padding: 0 0.1em; }
|