notations 1.0.4 → 1.0.7
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/README.md +1 -0
- package/dist/NotationView.css +15 -0
- package/dist/NotationView.css.map +1 -1
- package/dist/NotationView.min.css +1 -1
- package/dist/NotationView.min.css.map +1 -1
- package/dist/notations.umd.js +469 -108
- package/dist/notations.umd.min.js +2 -2
- package/dist/notations.umd.min.js.map +1 -1
- package/lib/cjs/beats.js +1 -1
- package/lib/cjs/beats.js.map +1 -1
- package/lib/cjs/block.d.ts +4 -0
- package/lib/cjs/block.js +24 -0
- package/lib/cjs/block.js.map +1 -1
- package/lib/cjs/carnatic/NotationView.d.ts +1 -0
- package/lib/cjs/carnatic/NotationView.js +10 -0
- package/lib/cjs/carnatic/NotationView.js.map +1 -1
- package/lib/cjs/carnatic/atomviews.d.ts +4 -1
- package/lib/cjs/carnatic/atomviews.js +18 -2
- package/lib/cjs/carnatic/atomviews.js.map +1 -1
- package/lib/cjs/carnatic/embelishments.d.ts +18 -1
- package/lib/cjs/carnatic/embelishments.js +87 -1
- package/lib/cjs/carnatic/embelishments.js.map +1 -1
- package/lib/cjs/core.d.ts +18 -3
- package/lib/cjs/core.js +161 -21
- package/lib/cjs/core.js.map +1 -1
- package/lib/cjs/entity.d.ts +4 -0
- package/lib/cjs/entity.js +12 -0
- package/lib/cjs/entity.js.map +1 -1
- package/lib/cjs/events.d.ts +56 -0
- package/lib/cjs/events.js +27 -0
- package/lib/cjs/events.js.map +1 -0
- package/lib/cjs/index.d.ts +1 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/shapes.d.ts +13 -1
- package/lib/cjs/shapes.js +35 -7
- package/lib/cjs/shapes.js.map +1 -1
- package/lib/esm/beats.js +1 -1
- package/lib/esm/beats.js.map +1 -1
- package/lib/esm/block.d.ts +4 -0
- package/lib/esm/block.js +24 -0
- package/lib/esm/block.js.map +1 -1
- package/lib/esm/carnatic/NotationView.d.ts +1 -0
- package/lib/esm/carnatic/NotationView.js +10 -0
- package/lib/esm/carnatic/NotationView.js.map +1 -1
- package/lib/esm/carnatic/atomviews.d.ts +4 -1
- package/lib/esm/carnatic/atomviews.js +19 -3
- package/lib/esm/carnatic/atomviews.js.map +1 -1
- package/lib/esm/carnatic/embelishments.d.ts +18 -1
- package/lib/esm/carnatic/embelishments.js +85 -0
- package/lib/esm/carnatic/embelishments.js.map +1 -1
- package/lib/esm/core.d.ts +18 -3
- package/lib/esm/core.js +161 -21
- package/lib/esm/core.js.map +1 -1
- package/lib/esm/entity.d.ts +4 -0
- package/lib/esm/entity.js +12 -0
- package/lib/esm/entity.js.map +1 -1
- package/lib/esm/events.d.ts +56 -0
- package/lib/esm/events.js +24 -0
- package/lib/esm/events.js.map +1 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/shapes.d.ts +13 -1
- package/lib/esm/shapes.js +34 -7
- package/lib/esm/shapes.js.map +1 -1
- package/package.json +3 -1
- package/styles/NotationView.scss +15 -0
package/lib/cjs/core.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.Role = exports.Line = exports.Group = exports.Note = exports.Syllable = exports.Literal = exports.Space = exports.Rest = exports.Marker = exports.LeafAtom = exports.Atom = exports.AtomType = exports.ONE = exports.ZERO = void 0;
|
|
37
37
|
const TSU = __importStar(require("@panyam/tsutils"));
|
|
38
38
|
const entity_1 = require("./entity");
|
|
39
|
+
const events_1 = require("./events");
|
|
39
40
|
exports.ZERO = TSU.Num.Fraction.ZERO;
|
|
40
41
|
exports.ONE = TSU.Num.Fraction.ONE;
|
|
41
42
|
var AtomType;
|
|
@@ -245,10 +246,39 @@ class Group extends Atom {
|
|
|
245
246
|
constructor(...atoms) {
|
|
246
247
|
super(atoms.length == 0 ? exports.ZERO : exports.ONE);
|
|
247
248
|
this.TYPE = "Group";
|
|
248
|
-
this.
|
|
249
|
+
this.durationIsSpeedMultiplier = false;
|
|
249
250
|
this.atoms = new TSU.Lists.ValueList();
|
|
251
|
+
this._observers = [];
|
|
250
252
|
this.addAtoms(false, ...atoms);
|
|
251
253
|
}
|
|
254
|
+
addObserver(observer) {
|
|
255
|
+
this._observers.push(observer);
|
|
256
|
+
return () => this.removeObserver(observer);
|
|
257
|
+
}
|
|
258
|
+
removeObserver(observer) {
|
|
259
|
+
const index = this._observers.indexOf(observer);
|
|
260
|
+
if (index >= 0) {
|
|
261
|
+
this._observers.splice(index, 1);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
notifyObservers(type, atoms, index) {
|
|
265
|
+
var _a, _b, _c;
|
|
266
|
+
if (!this._eventsEnabled)
|
|
267
|
+
return;
|
|
268
|
+
for (const observer of this._observers) {
|
|
269
|
+
switch (type) {
|
|
270
|
+
case events_1.AtomChangeType.ADD:
|
|
271
|
+
(_a = observer.onAtomsAdded) === null || _a === void 0 ? void 0 : _a.call(observer, this, atoms, index);
|
|
272
|
+
break;
|
|
273
|
+
case events_1.AtomChangeType.INSERT:
|
|
274
|
+
(_b = observer.onAtomsInserted) === null || _b === void 0 ? void 0 : _b.call(observer, this, atoms, index);
|
|
275
|
+
break;
|
|
276
|
+
case events_1.AtomChangeType.REMOVE:
|
|
277
|
+
(_c = observer.onAtomsRemoved) === null || _c === void 0 ? void 0 : _c.call(observer, this, atoms);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
252
282
|
equals(another, expect = false) {
|
|
253
283
|
if (!super.equals(another))
|
|
254
284
|
return false;
|
|
@@ -256,30 +286,32 @@ class Group extends Atom {
|
|
|
256
286
|
}
|
|
257
287
|
copyTo(another) {
|
|
258
288
|
super.copyTo(another);
|
|
259
|
-
another.
|
|
260
|
-
|
|
289
|
+
another.durationIsSpeedMultiplier = this.durationIsSpeedMultiplier;
|
|
290
|
+
for (const atom of this.atoms.values()) {
|
|
291
|
+
another.atoms.add(atom.clone());
|
|
292
|
+
}
|
|
261
293
|
}
|
|
262
294
|
get duration() {
|
|
263
|
-
if (this.
|
|
295
|
+
if (this.durationIsSpeedMultiplier) {
|
|
264
296
|
return this.totalChildDuration.divby(this._duration);
|
|
265
297
|
}
|
|
266
298
|
else {
|
|
267
299
|
return this._duration;
|
|
268
300
|
}
|
|
269
301
|
}
|
|
270
|
-
setDurationAsMultiplier(
|
|
271
|
-
this.
|
|
302
|
+
setDurationAsMultiplier(asSpeedMultiplier = true) {
|
|
303
|
+
this.durationIsSpeedMultiplier = asSpeedMultiplier;
|
|
272
304
|
return this;
|
|
273
305
|
}
|
|
274
|
-
setDuration(d,
|
|
306
|
+
setDuration(d, asSpeedMultiplier = false) {
|
|
275
307
|
this._duration = d;
|
|
276
|
-
this.
|
|
308
|
+
this.durationIsSpeedMultiplier = asSpeedMultiplier;
|
|
277
309
|
return this;
|
|
278
310
|
}
|
|
279
311
|
debugValue() {
|
|
280
312
|
const out = Object.assign(Object.assign({}, super.debugValue()), { atoms: Array.from(this.atoms.values(), (a) => a.debugValue()) });
|
|
281
|
-
if (this.
|
|
282
|
-
out.
|
|
313
|
+
if (this.durationIsSpeedMultiplier)
|
|
314
|
+
out.durationIsSpeedMultiplier = true;
|
|
283
315
|
return out;
|
|
284
316
|
}
|
|
285
317
|
splitAt(requiredDuration) {
|
|
@@ -287,13 +319,13 @@ class Group extends Atom {
|
|
|
287
319
|
return null;
|
|
288
320
|
}
|
|
289
321
|
const targetGroup = new Group();
|
|
290
|
-
if (this.
|
|
291
|
-
targetGroup.
|
|
322
|
+
if (this.durationIsSpeedMultiplier) {
|
|
323
|
+
targetGroup.durationIsSpeedMultiplier = true;
|
|
292
324
|
targetGroup._duration = this._duration;
|
|
293
325
|
}
|
|
294
326
|
let remainingDur = this.duration;
|
|
295
327
|
const totalChildDuration = this.totalChildDuration;
|
|
296
|
-
const durationFactor = this.
|
|
328
|
+
const durationFactor = this.durationIsSpeedMultiplier
|
|
297
329
|
? exports.ONE.divby(this._duration)
|
|
298
330
|
: this._duration.divby(totalChildDuration, true);
|
|
299
331
|
while (remainingDur.isGT(requiredDuration) && this.atoms.last) {
|
|
@@ -313,7 +345,7 @@ class Group extends Atom {
|
|
|
313
345
|
if (spillOver == null) {
|
|
314
346
|
throw new Error("Spill over cannot be null here");
|
|
315
347
|
}
|
|
316
|
-
if (!this.
|
|
348
|
+
if (!this.durationIsSpeedMultiplier) {
|
|
317
349
|
this._duration = requiredDuration;
|
|
318
350
|
}
|
|
319
351
|
else {
|
|
@@ -330,12 +362,27 @@ class Group extends Atom {
|
|
|
330
362
|
}
|
|
331
363
|
get totalChildDuration() {
|
|
332
364
|
let out = exports.ZERO;
|
|
333
|
-
|
|
365
|
+
for (const atom of this.atoms.values()) {
|
|
366
|
+
out = out.plus(atom.duration);
|
|
367
|
+
}
|
|
334
368
|
return out;
|
|
335
369
|
}
|
|
336
370
|
insertAtomsAt(beforeAtom, adjustDuration = false, ...atoms) {
|
|
337
|
-
adjustDuration = adjustDuration && !this.
|
|
371
|
+
adjustDuration = adjustDuration && !this.durationIsSpeedMultiplier;
|
|
338
372
|
const oldChildDuration = adjustDuration ? this.totalChildDuration : exports.ONE;
|
|
373
|
+
let insertIndex;
|
|
374
|
+
if (beforeAtom) {
|
|
375
|
+
insertIndex = 0;
|
|
376
|
+
for (const a of this.atoms.values()) {
|
|
377
|
+
if (a === beforeAtom)
|
|
378
|
+
break;
|
|
379
|
+
insertIndex++;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
insertIndex = this.atoms.size;
|
|
384
|
+
}
|
|
385
|
+
const addedAtoms = [];
|
|
339
386
|
for (const atom of atoms) {
|
|
340
387
|
if (atom.parentGroup != null) {
|
|
341
388
|
if (atom.parentGroup != this) {
|
|
@@ -352,11 +399,12 @@ class Group extends Atom {
|
|
|
352
399
|
else {
|
|
353
400
|
atom.parentGroup = this;
|
|
354
401
|
this.atoms.add(atom, beforeAtom);
|
|
402
|
+
addedAtoms.push(atom);
|
|
355
403
|
}
|
|
356
404
|
}
|
|
357
405
|
if (adjustDuration) {
|
|
358
406
|
if (this._duration.isZero) {
|
|
359
|
-
if (this.
|
|
407
|
+
if (this.durationIsSpeedMultiplier)
|
|
360
408
|
throw new Error("How can this be?");
|
|
361
409
|
this._duration = this.totalChildDuration;
|
|
362
410
|
}
|
|
@@ -365,18 +413,24 @@ class Group extends Atom {
|
|
|
365
413
|
this._duration = this._duration.times(scaleFactor, true);
|
|
366
414
|
}
|
|
367
415
|
}
|
|
416
|
+
if (addedAtoms.length > 0) {
|
|
417
|
+
const type = beforeAtom ? events_1.AtomChangeType.INSERT : events_1.AtomChangeType.ADD;
|
|
418
|
+
this.notifyObservers(type, addedAtoms, insertIndex);
|
|
419
|
+
}
|
|
368
420
|
return this;
|
|
369
421
|
}
|
|
370
422
|
addAtoms(adjustDuration = false, ...atoms) {
|
|
371
423
|
return this.insertAtomsAt(null, adjustDuration, ...atoms);
|
|
372
424
|
}
|
|
373
425
|
removeAtoms(adjustDuration = false, ...atoms) {
|
|
374
|
-
adjustDuration = adjustDuration && !this.
|
|
426
|
+
adjustDuration = adjustDuration && !this.durationIsSpeedMultiplier;
|
|
375
427
|
const oldChildDuration = adjustDuration ? this.totalChildDuration : exports.ONE;
|
|
428
|
+
const removedAtoms = [];
|
|
376
429
|
for (const atom of atoms) {
|
|
377
430
|
if (atom.parentGroup == this) {
|
|
378
431
|
this.atoms.remove(atom);
|
|
379
432
|
atom.parentGroup = null;
|
|
433
|
+
removedAtoms.push(atom);
|
|
380
434
|
}
|
|
381
435
|
else if (atom.parentGroup != null) {
|
|
382
436
|
throw new Error("Atom cannot be removed as it does not belong to this group");
|
|
@@ -384,7 +438,7 @@ class Group extends Atom {
|
|
|
384
438
|
}
|
|
385
439
|
if (adjustDuration) {
|
|
386
440
|
if (this._duration.isZero) {
|
|
387
|
-
if (this.
|
|
441
|
+
if (this.durationIsSpeedMultiplier)
|
|
388
442
|
throw new Error("How can this be?");
|
|
389
443
|
this._duration = this.totalChildDuration;
|
|
390
444
|
}
|
|
@@ -393,6 +447,9 @@ class Group extends Atom {
|
|
|
393
447
|
this._duration = this._duration.times(scaleFactor, true);
|
|
394
448
|
}
|
|
395
449
|
}
|
|
450
|
+
if (removedAtoms.length > 0) {
|
|
451
|
+
this.notifyObservers(events_1.AtomChangeType.REMOVE, removedAtoms, -1);
|
|
452
|
+
}
|
|
396
453
|
return this;
|
|
397
454
|
}
|
|
398
455
|
}
|
|
@@ -404,6 +461,17 @@ class Line extends entity_1.Entity {
|
|
|
404
461
|
this.offset = exports.ZERO;
|
|
405
462
|
this.roles = [];
|
|
406
463
|
this.marginText = "";
|
|
464
|
+
this._observers = [];
|
|
465
|
+
}
|
|
466
|
+
addObserver(observer) {
|
|
467
|
+
this._observers.push(observer);
|
|
468
|
+
return () => this.removeObserver(observer);
|
|
469
|
+
}
|
|
470
|
+
removeObserver(observer) {
|
|
471
|
+
const index = this._observers.indexOf(observer);
|
|
472
|
+
if (index >= 0) {
|
|
473
|
+
this._observers.splice(index, 1);
|
|
474
|
+
}
|
|
407
475
|
}
|
|
408
476
|
indexOfRole(name) {
|
|
409
477
|
for (let i = 0; i < this.roles.length; i++) {
|
|
@@ -435,15 +503,35 @@ class Line extends entity_1.Entity {
|
|
|
435
503
|
return this;
|
|
436
504
|
}
|
|
437
505
|
ensureRole(roleName, defaultToNotes) {
|
|
506
|
+
var _a;
|
|
438
507
|
let ri = this.roles.findIndex((r) => r.name == roleName);
|
|
439
508
|
if (ri < 0) {
|
|
440
509
|
ri = this.roles.length;
|
|
441
510
|
const role = new Role(this, roleName);
|
|
442
511
|
role.defaultToNotes = defaultToNotes;
|
|
443
512
|
this.roles.push(role);
|
|
513
|
+
if (this._eventsEnabled) {
|
|
514
|
+
for (const observer of this._observers) {
|
|
515
|
+
(_a = observer.onRoleAdded) === null || _a === void 0 ? void 0 : _a.call(observer, this, roleName, role);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
444
518
|
}
|
|
445
519
|
return this.roles[ri];
|
|
446
520
|
}
|
|
521
|
+
removeRole(roleName) {
|
|
522
|
+
var _a;
|
|
523
|
+
const ri = this.roles.findIndex((r) => r.name == roleName);
|
|
524
|
+
if (ri >= 0) {
|
|
525
|
+
this.roles.splice(ri, 1);
|
|
526
|
+
if (this._eventsEnabled) {
|
|
527
|
+
for (const observer of this._observers) {
|
|
528
|
+
(_a = observer.onRoleRemoved) === null || _a === void 0 ? void 0 : _a.call(observer, this, roleName);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
return false;
|
|
534
|
+
}
|
|
447
535
|
get duration() {
|
|
448
536
|
let max = exports.ZERO;
|
|
449
537
|
for (const role of this.roles) {
|
|
@@ -461,6 +549,35 @@ class Role extends entity_1.Entity {
|
|
|
461
549
|
this.TYPE = "Role";
|
|
462
550
|
this.defaultToNotes = true;
|
|
463
551
|
this.atoms = [];
|
|
552
|
+
this._observers = [];
|
|
553
|
+
}
|
|
554
|
+
addObserver(observer) {
|
|
555
|
+
this._observers.push(observer);
|
|
556
|
+
return () => this.removeObserver(observer);
|
|
557
|
+
}
|
|
558
|
+
removeObserver(observer) {
|
|
559
|
+
const index = this._observers.indexOf(observer);
|
|
560
|
+
if (index >= 0) {
|
|
561
|
+
this._observers.splice(index, 1);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
notifyObservers(type, atoms, index) {
|
|
565
|
+
var _a, _b, _c;
|
|
566
|
+
if (!this._eventsEnabled)
|
|
567
|
+
return;
|
|
568
|
+
for (const observer of this._observers) {
|
|
569
|
+
switch (type) {
|
|
570
|
+
case events_1.AtomChangeType.ADD:
|
|
571
|
+
(_a = observer.onAtomsAdded) === null || _a === void 0 ? void 0 : _a.call(observer, this, atoms, index);
|
|
572
|
+
break;
|
|
573
|
+
case events_1.AtomChangeType.INSERT:
|
|
574
|
+
(_b = observer.onAtomsInserted) === null || _b === void 0 ? void 0 : _b.call(observer, this, atoms, index);
|
|
575
|
+
break;
|
|
576
|
+
case events_1.AtomChangeType.REMOVE:
|
|
577
|
+
(_c = observer.onAtomsRemoved) === null || _c === void 0 ? void 0 : _c.call(observer, this, atoms);
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
464
581
|
}
|
|
465
582
|
get isEmpty() {
|
|
466
583
|
return this.atoms.length == 0;
|
|
@@ -469,7 +586,11 @@ class Role extends entity_1.Entity {
|
|
|
469
586
|
return { name: this.name, atoms: this.atoms.map((a) => a.debugValue()) };
|
|
470
587
|
}
|
|
471
588
|
addAtoms(...atoms) {
|
|
472
|
-
|
|
589
|
+
this.insertAtomsAt(this.atoms.length, ...atoms);
|
|
590
|
+
}
|
|
591
|
+
insertAtomsAt(index, ...atoms) {
|
|
592
|
+
const addedAtoms = [];
|
|
593
|
+
let last = index > 0 ? this.atoms[index - 1] : null;
|
|
473
594
|
for (const atom of atoms) {
|
|
474
595
|
if (atom.TYPE == AtomType.REST) {
|
|
475
596
|
if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {
|
|
@@ -477,10 +598,29 @@ class Role extends entity_1.Entity {
|
|
|
477
598
|
}
|
|
478
599
|
}
|
|
479
600
|
else {
|
|
480
|
-
this.atoms.
|
|
601
|
+
this.atoms.splice(index + addedAtoms.length, 0, atom);
|
|
602
|
+
addedAtoms.push(atom);
|
|
481
603
|
}
|
|
482
604
|
last = atom;
|
|
483
605
|
}
|
|
606
|
+
if (addedAtoms.length > 0) {
|
|
607
|
+
const isAppend = index >= this.atoms.length - addedAtoms.length;
|
|
608
|
+
const type = isAppend ? events_1.AtomChangeType.ADD : events_1.AtomChangeType.INSERT;
|
|
609
|
+
this.notifyObservers(type, addedAtoms, index);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
removeAtoms(...atoms) {
|
|
613
|
+
const removedAtoms = [];
|
|
614
|
+
for (const atom of atoms) {
|
|
615
|
+
const idx = this.atoms.indexOf(atom);
|
|
616
|
+
if (idx >= 0) {
|
|
617
|
+
this.atoms.splice(idx, 1);
|
|
618
|
+
removedAtoms.push(atom);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (removedAtoms.length > 0) {
|
|
622
|
+
this.notifyObservers(events_1.AtomChangeType.REMOVE, removedAtoms, -1);
|
|
623
|
+
}
|
|
484
624
|
}
|
|
485
625
|
copyTo(another) {
|
|
486
626
|
another.addAtoms(...this.atoms);
|
package/lib/cjs/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\nimport { LayoutParams } from \"./layouts\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport const ZERO = TSU.Num.Fraction.ZERO;\nexport const ONE = TSU.Num.Fraction.ONE;\n\n/**\n * AtomType enums are used to denote specific Atoms\n * Each type represents a specific musical or notational element.\n * @enum\n */\nexport enum AtomType {\n NOTE = \"Note\",\n LITERAL = \"Literal\",\n SYLLABLE = \"Syllable\",\n SPACE = \"Space\",\n GROUP = \"Group\",\n LABEL = \"Label\",\n REST = \"Rest\",\n MARKER = \"Marker\",\n}\n\n/**\n * Atoms are the base class for all timed entities that can appear in a Notation.\n * An Atom represents the fundamental building block of the notation system.\n */\nexport abstract class Atom extends TimedEntity {\n readonly TYPE: string = \"Atom\";\n\n protected _duration: Fraction;\n /** Markers to be displayed before this atom */\n markersBefore: Marker[];\n /** Markers to be displayed after this atom */\n markersAfter: Marker[];\n /** Next atom in the sequence */\n nextSibling: TSU.Nullable<Atom> = null;\n /** Previous atom in the sequence */\n prevSibling: TSU.Nullable<Atom> = null;\n /** The Group this Atom belongs to, if any */\n parentGroup: TSU.Nullable<Group> = null;\n\n /** Indicates if this Atom is a continuation from a previous atom */\n isContinuation = false;\n\n /**\n * Creates a new Atom with the specified duration.\n * @param duration The duration of the atom, defaults to ONE (1/1)\n */\n constructor(duration = ONE) {\n super();\n this._duration = duration || ONE;\n }\n\n /**\n * Splits this atom at the specified duration.\n * @param requiredDuration The duration at which to split the atom\n * @returns A new atom representing the portion beyond the split point, or null if no split is needed\n */\n abstract splitAt(requiredDuration: Fraction): TSU.Nullable<Atom>;\n\n /**\n * Returns a debug-friendly representation of this Atom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = super.debugValue();\n if (!this.duration.isOne) {\n out.duration = this.duration.factorized.toString();\n }\n if (this.isContinuation) {\n out.isContinuation = true;\n }\n if ((this.markersBefore || []).length > 0) {\n out.mbef = this.markersBefore.map((m) => m.debugValue());\n }\n if ((this.markersAfter || []).length > 0) {\n out.maft = this.markersAfter.map((m) => m.debugValue());\n }\n return out;\n }\n\n /**\n * Copies the properties of this atom to another atom.\n * @param another The target atom to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another._duration = new TSU.Num.Fraction(this.duration.num, this.duration.den);\n }\n\n /**\n * Gets the duration of this atom.\n */\n get duration(): Fraction {\n return this._duration;\n }\n\n /**\n * Sets the duration of this atom.\n */\n set duration(d: Fraction) {\n this._duration = d;\n }\n}\n\n/**\n * Base class for atoms that cannot contain other atoms.\n * LeafAtom represents atomic elements that can't be further subdivided.\n */\nexport abstract class LeafAtom extends Atom {\n readonly TYPE: string = \"LeafAtom\";\n\n /** Indicates if this atom is followed by a rest */\n beforeRest = false;\n\n /**\n * Splits this atom at a certain duration.\n * If this atom's duration is longer than the given duration, it's truncated\n * to the given duration and a continuation space is returned.\n *\n * @param duration The duration at which to split the atom\n * @returns A new Space atom representing the spillover if needed, otherwise null\n */\n splitAt(duration: Fraction): TSU.Nullable<Atom> {\n if (this.duration.cmp(duration) > 0) {\n const spillOver = this.createSpilloverSpace(this.duration.minus(duration));\n spillOver.isContinuation = true;\n this.duration = duration;\n // TODO - Here we need to move the markersAfter to the spill-over as it doesnt belong to this any more\n return spillOver;\n }\n return null;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n return new Space(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this LeafAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return this.beforeRest ? { ...super.debugValue(), beforeRest: true } : super.debugValue();\n }\n}\n\n/**\n * Represents a marker or annotation in the notation.\n * Markers can be placed before or after atoms to provide additional context.\n */\nexport class Marker extends Entity {\n readonly TYPE = \"Marker\";\n\n /**\n * Creates a new Marker with the specified text.\n * @param text The text content of the marker\n * @param isBefore Whether the marker should appear before (true) or after (false) its associated atom\n */\n constructor(\n public text: string,\n public isBefore = true,\n ) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this Marker.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), text: this.text, before: this.isBefore };\n }\n\n /**\n * Returns a string representation of this Marker.\n * @returns A string representation\n */\n toString(): string {\n return `Marker(${this.text}-${this.isBefore})`;\n }\n}\n\n/**\n * Represents a rest (silence) in the notation.\n * Rests are zero-length atoms that indicate a pause.\n */\nexport class Rest extends LeafAtom {\n readonly TYPE = \"Rest\";\n\n /**\n * Creates a new Rest.\n * Rests are zero length by default.\n */\n constructor() {\n super(ZERO);\n }\n}\n\n/**\n * Represents a space or silence in the notation.\n * Spaces can be used to denote either silence or continuations of previous notes.\n */\nexport class Space extends LeafAtom {\n readonly TYPE = \"Space\";\n\n /**\n * Indicates whether this is a silent space or a continuation of the previous note.\n */\n isSilent = false;\n\n /**\n * Creates a new Space with the specified duration and silence property.\n * @param duration The duration of the space, defaults to ONE (1/1)\n * @param isSilent Whether the space represents silence (true) or a continuation (false)\n */\n constructor(duration = ONE, isSilent = false) {\n super(duration);\n this.isSilent = isSilent;\n }\n\n /**\n * Returns a debug-friendly representation of this Space.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), isSilent: this.isSilent };\n }\n\n /**\n * Returns a string representation of this Space.\n * @returns A string representation\n */\n toString(): string {\n return `Space(${this.duration}-${this.isSilent})`;\n }\n\n /**\n * Copies the properties of this Space to another Space.\n * @param another The target Space to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.isSilent = this.isSilent;\n }\n\n /**\n * Checks if this Space is equal to another Space.\n * @param another The Space to compare with\n * @returns True if the Spaces are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.isSilent == another.isSilent;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom with the same silence property as this Space\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n const out = super.createSpilloverSpace(duration);\n out.isSilent = this.isSilent;\n return out;\n }\n}\n\n/**\n * Represents a literal value in the notation.\n * Literals are the basic building blocks for notes and syllables.\n */\nexport class Literal extends LeafAtom {\n readonly TYPE: string = \"Literal\";\n\n /**\n * The embellishments applied to this Literal.\n */\n embelishments: any[] = [];\n\n /**\n * Creates a new Literal with the specified value and duration.\n * @param value The string value of the literal\n * @param duration The duration of the literal, defaults to ONE (1/1)\n */\n constructor(\n public value: string,\n duration = ONE,\n ) {\n super(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this Literal.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), value: this.value };\n if (this.embelishments.length > 0) {\n out.embs = this.embelishments.map((e) => (\"debugValue\" in e ? e.debugValue() : e));\n }\n return out;\n }\n\n /**\n * Returns a string representation of this Literal.\n * @returns A string representation\n */\n toString(): string {\n return `Lit(${this.duration}-${this.value})`;\n }\n\n /**\n * Checks if this Literal is equal to another Literal.\n * @param another The Literal to compare with\n * @returns True if the Literals are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.value == another.value;\n }\n\n /**\n * Copies the properties of this Literal to another Literal.\n * @param another The target Literal to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.value = this.value;\n }\n}\n\n/**\n * Represents a syllable in lyrics or text to be sung.\n * Extends Literal to provide specialized handling for sung text.\n */\nexport class Syllable extends Literal {\n readonly TYPE = \"Syllable\";\n\n /**\n * Creates a Syllable from a Literal.\n * @param lit The Literal to convert to a Syllable\n * @returns A new Syllable with the properties of the Literal\n */\n static fromLit(lit: Literal): Syllable {\n if (lit.TYPE == AtomType.SYLLABLE) return lit as Syllable;\n const out = new Syllable(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a string representation of this Syllable.\n * @returns A string representation\n */\n toString(): string {\n return `Syll(${this.duration}-${this.value})`;\n }\n}\n\n/**\n * Represents a musical note in the notation.\n * Extends Literal to add properties specific to musical notes.\n */\nexport class Note extends Literal {\n readonly TYPE = \"Note\";\n\n /**\n * Which octave the note is in. Can be positive or negative to indicate higher or lower octaves.\n */\n octave = 0;\n\n /**\n * How the note is shifted - i.e., shifted towards major or minor by # of semi-tones.\n */\n shift: number | boolean = 0;\n\n /**\n * Creates a new Note with the specified properties.\n * @param value The string value of the note\n * @param duration The duration of the note, defaults to ONE (1/1)\n * @param octave The octave of the note, defaults to 0\n * @param shift The shift of the note, defaults to 0\n */\n constructor(value: string, duration = ONE, octave = 0, shift = 0) {\n super(value, duration);\n this.octave = octave;\n this.shift = shift;\n }\n\n /**\n * Creates a Note from a Literal.\n * @param lit The Literal to convert to a Note\n * @returns A new Note with the properties of the Literal\n */\n static fromLit(lit: Literal): Note {\n if (lit.TYPE == AtomType.NOTE) return lit as Note;\n const out = new Note(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this Note.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue() };\n if (this.octave != 0) out.octave = this.octave;\n if (this.shift != 0) out.shift = this.shift;\n return out;\n }\n\n /**\n * Returns a string representation of this Note.\n * @returns A string representation\n */\n toString(): string {\n return `Note(${this.duration}-${this.value}-${this.octave})`;\n }\n\n /**\n * Checks if this Note is equal to another Note.\n * @param another The Note to compare with\n * @returns True if the Notes are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.octave == another.octave && this.shift == another.shift;\n }\n\n /**\n * Copies the properties of this Note to another Note.\n * @param another The target Note to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.octave = this.octave;\n another.shift = this.shift;\n }\n}\n\n/**\n * Represents a group of atoms that are treated as a single unit.\n * Groups can contain any number of atoms, including other groups.\n */\nexport class Group extends Atom {\n readonly TYPE = \"Group\";\n\n /**\n * Indicates whether the duration is static or linear to the number of atoms in this group.\n * When true, the duration is used as a multiplier for the total child duration.\n * When false, the duration is absolute.\n */\n durationIsMultiplier = false;\n\n /**\n * The list of atoms in this group.\n */\n readonly atoms = new TSU.Lists.ValueList<Atom>();\n\n /**\n * Creates a new Group containing the specified atoms.\n * @param atoms The atoms to include in this group\n */\n constructor(...atoms: Atom[]) {\n super(atoms.length == 0 ? ZERO : ONE);\n this.addAtoms(false, ...atoms);\n }\n\n /**\n * Checks if this Group is equal to another Group.\n * @param another The Group to compare with\n * @param expect Optional parameter\n * @returns True if the Groups are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (!super.equals(another)) return false;\n return this.atoms.equals(another.atoms, (a1, a2) => a1.equals(a2));\n }\n\n /**\n * Copies the properties of this Group to another Group.\n * @param another The target Group to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.durationIsMultiplier = this.durationIsMultiplier;\n this.atoms.forEach((atom) => another.atoms.add(atom.clone()));\n }\n\n /**\n * Gets the duration of this group.\n * If durationIsMultiplier is true, returns the total child duration divided by the multiplier.\n * Otherwise, returns the absolute duration.\n */\n get duration(): Fraction {\n if (this.durationIsMultiplier) {\n return this.totalChildDuration.divby(this._duration);\n } else {\n return this._duration;\n }\n }\n\n /**\n * Sets this group to use a multiplier for duration calculations.\n * @param asMultiplier Whether to use the duration as a multiplier\n * @returns This Group instance for method chaining\n */\n setDurationAsMultiplier(asMultiplier = true): this {\n this.durationIsMultiplier = asMultiplier;\n return this;\n }\n\n /**\n * Sets the duration of this group.\n * @param d The new duration\n * @param asMultiplier Whether to use the duration as a multiplier\n * @returns This Group instance for method chaining\n */\n setDuration(d: Fraction, asMultiplier = false): this {\n this._duration = d;\n this.durationIsMultiplier = asMultiplier;\n return this;\n }\n\n /**\n * Returns a debug-friendly representation of this Group.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), atoms: Array.from(this.atoms.values(), (a) => a.debugValue()) };\n if (this.durationIsMultiplier) out.durationIsMultiplier = true;\n return out;\n }\n\n /**\n * Splits this group into two parts.\n * The first part (this group) fits within the given duration and everything else\n * longer than the given duration is returned as a new Group.\n *\n * @param requiredDuration The duration at which to split the group\n * @returns A new Group containing the atoms beyond the split point, or null if no split is needed\n */\n splitAt(requiredDuration: Fraction): TSU.Nullable<Group> {\n if (this.duration.isLTE(requiredDuration) || requiredDuration.isLTE(ZERO)) {\n return null;\n }\n const targetGroup = new Group();\n if (this.durationIsMultiplier) {\n targetGroup.durationIsMultiplier = true;\n targetGroup._duration = this._duration;\n }\n\n let remainingDur = this.duration;\n const totalChildDuration = this.totalChildDuration;\n const durationFactor = this.durationIsMultiplier\n ? ONE.divby(this._duration)\n : this._duration.divby(totalChildDuration, true);\n while (remainingDur.isGT(requiredDuration) && this.atoms.last) {\n const lastChild = this.atoms.last;\n // Child's duration is absolute in its own \"system\"\n // Its duration within the parent (this) group's frame of reference depends\n // on whether the parent's duration is absolute or as a multiplier\n //\n // realChildDuration = case (group.durationIsMultiper) {\n // | true => child.duration / this._duration\n // | false => child.duration * this._duration / total child duration\n // }\n const childDuration = lastChild.duration.times(durationFactor);\n const newDuration = remainingDur.minus(childDuration);\n if (newDuration.isGTE(requiredDuration)) {\n // remove ourselves and add to target\n // in both cases duration will be adjusted if need be\n this.removeAtoms(true, lastChild);\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, lastChild);\n if (newDuration.equals(requiredDuration)) {\n // we have reached the end so return\n return targetGroup;\n }\n } else {\n // our scenario is now this:\n //\n // totalParentDuration = 10\n // required = 8\n // lastChildDuration (relative to parent) is 5\n //\n // durWithoutLast = 10 - 5\n // newRequired = requiredDur - durWithoutLast = 3\n //\n // However 3 is a duration in the parent's frame of reference\n // this has to be converted back to the child's FoR\n const newRequiredDur = requiredDuration.minus(newDuration, true).divby(durationFactor, true);\n // console.log( \"newRequiredDur: \", newRequiredDur, \"requiedDur: \", requiredDuration, \"remainingDur: \", remainingDur,);\n // then the last item needs to be split, and by how much?\n const spillOver = lastChild.splitAt(newRequiredDur);\n if (spillOver == null) {\n throw new Error(\"Spill over cannot be null here\");\n }\n if (!this.durationIsMultiplier) {\n // Our own duration has also now changed\n this._duration = requiredDuration;\n } else {\n if (this._duration.isZero) throw new Error(\"How can this be?\");\n }\n spillOver.isContinuation = true;\n // Add spill over to the target\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, spillOver);\n return targetGroup;\n }\n remainingDur = newDuration;\n }\n return targetGroup;\n }\n\n /**\n * Gets the total duration of all child atoms.\n * @returns The sum of durations of all atoms in this group\n */\n get totalChildDuration(): Fraction {\n let out = ZERO;\n this.atoms.forEach((atom) => (out = out.plus(atom.duration)));\n return out;\n }\n\n /**\n * Inserts atoms before a given cursor atom.\n * If the cursor atom is null, the atoms are appended at the end.\n *\n * @param beforeAtom The atom before which to insert the new atoms, or null to append\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to insert\n * @returns This Group instance for method chaining\n */\n insertAtomsAt(beforeAtom: TSU.Nullable<Atom>, adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n // First form a chain of the given atoms\n for (const atom of atoms) {\n if (atom.parentGroup != null) {\n if (atom.parentGroup != this) {\n throw new Error(\"Atom belongs to another parent. Remove it first\");\n }\n atom.parentGroup.removeAtoms(false, atom);\n }\n if (atom.TYPE == AtomType.REST) {\n const last = this.atoms.last;\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n atom.parentGroup = this;\n this.atoms.add(atom, beforeAtom);\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n return this;\n }\n\n /**\n * Adds atoms to the end of this group's atom list.\n *\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to add\n * @returns This Group instance for method chaining\n */\n addAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n return this.insertAtomsAt(null, adjustDuration, ...atoms);\n }\n\n /**\n * Removes atoms from this group's child list.\n *\n * @param adjustDuration Whether to adjust this group's duration after removing atoms\n * @param atoms The atoms to remove\n * @returns This Group instance for method chaining\n */\n removeAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n for (const atom of atoms) {\n if (atom.parentGroup == this) {\n this.atoms.remove(atom);\n atom.parentGroup = null;\n } else if (atom.parentGroup != null) {\n throw new Error(\"Atom cannot be removed as it does not belong to this group\");\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n return this;\n }\n}\n\n/**\n * Represents a line of notation containing multiple roles.\n * A line can have atoms starting before or after the cycle.\n */\nexport class Line extends Entity {\n readonly TYPE: string = \"Line\";\n\n /**\n * Offset tells how many notes before or after the cycle this line's atoms start at.\n */\n offset: Fraction = ZERO;\n\n /**\n * The roles contained in this line.\n */\n roles: Role[] = [];\n\n /**\n * Text to be displayed in the margin of the line.\n * This is a hacky solution to doing left side pre-margin text typically\n * found in notations - e.g., line X of a pallavi has this. This makes vertical\n * space less wasteful.\n *\n * A better solution is inter-beat annotation but it is very complex for now.\n */\n marginText = \"\";\n\n /**\n * The LayoutParams associated with this line.\n */\n layoutParams: LayoutParams;\n\n /**\n * Finds the index of a role with the given name.\n * @param name The name of the role to find\n * @returns The index of the role, or -1 if not found\n */\n indexOfRole(name: string): number {\n for (let i = 0; i < this.roles.length; i++) {\n if (this.roles[i].name == name) return i;\n }\n return -1;\n }\n\n /**\n * Checks if this line is empty (has no content in any role).\n */\n get isEmpty(): boolean {\n for (const r of this.roles) if (!r.isEmpty) return false;\n return true;\n }\n\n /**\n * Returns a debug-friendly representation of this Line.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n roles: this.roles.map((r) => r.debugValue()),\n };\n if (!this.offset.isZero) {\n out.offset = this.offset.toString();\n }\n return out;\n }\n\n /**\n * Copies the properties of this Line to another Line.\n * @param another The target Line to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.roles = this.roles.map((r) => r.clone());\n }\n\n /**\n * Adds atoms to a role in this line.\n * @param roleName The name of the role to add atoms to\n * @param defaultToNotes Whether to default to notes for this role\n * @param atoms The atoms to add\n * @returns This Line instance for method chaining\n */\n addAtoms(roleName: string, defaultToNotes: boolean, ...atoms: Atom[]): this {\n const role = this.ensureRole(roleName, defaultToNotes);\n role.addAtoms(...atoms);\n return this;\n }\n\n /**\n * Ensures a role with the given name exists in this line, creating it if needed.\n * @param roleName The name of the role to ensure\n * @param defaultToNotes Whether to default to notes for this role\n * @returns The role with the specified name\n */\n ensureRole(roleName: string, defaultToNotes: boolean): Role {\n // Ensure we have this many roles\n let ri = this.roles.findIndex((r) => r.name == roleName);\n if (ri < 0) {\n ri = this.roles.length;\n const role = new Role(this, roleName);\n role.defaultToNotes = defaultToNotes;\n this.roles.push(role);\n }\n return this.roles[ri];\n }\n\n /**\n * Gets the maximum duration across all roles in this line.\n */\n get duration(): Fraction {\n let max = ZERO;\n for (const role of this.roles) {\n max = TSU.Num.Fraction.max(role.duration, max);\n }\n return max;\n }\n}\n\n/**\n * Represents a specific role or voice in a line of notation.\n * Each role contains a sequence of atoms.\n */\nexport class Role extends Entity {\n readonly TYPE = \"Role\";\n\n /**\n * Whether this role represents notes by default.\n */\n defaultToNotes = true;\n\n /**\n * The atoms in this role.\n */\n atoms: Atom[] = [];\n\n /**\n * Creates a new Role with the specified line and name.\n * @param line The line this role belongs to\n * @param name The name of the role\n */\n constructor(\n public readonly line: Line,\n public readonly name: string,\n ) {\n super();\n }\n\n /**\n * Checks if this role is empty (has no atoms).\n */\n get isEmpty(): boolean {\n return this.atoms.length == 0;\n }\n\n /**\n * Returns a debug-friendly representation of this Role.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { name: this.name, atoms: this.atoms.map((a) => a.debugValue()) };\n }\n\n /**\n * Adds atoms to this role.\n * @param atoms The atoms to add\n */\n addAtoms(...atoms: Atom[]): void {\n let last: null | Atom = null;\n for (const atom of atoms) {\n if (atom.TYPE == AtomType.REST) {\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n this.atoms.push(atom);\n }\n last = atom;\n }\n }\n\n /**\n * Copies the properties of this Role to another Role.\n * @param another The target Role to copy properties to\n */\n copyTo(another: Role): void {\n another.addAtoms(...this.atoms);\n }\n\n /**\n * Gets the total duration of all atoms in this role.\n */\n get duration(): Fraction {\n return this.atoms.reduce((a, b) => a.plus(b.duration), ZERO);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\nimport { LayoutParams } from \"./layouts\";\nimport { AtomChangeType, GroupObserver, RoleObserver, LineObserver } from \"./events\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport const ZERO = TSU.Num.Fraction.ZERO;\nexport const ONE = TSU.Num.Fraction.ONE;\n\n/**\n * AtomType enums are used to denote specific Atoms\n * Each type represents a specific musical or notational element.\n * @enum\n */\nexport enum AtomType {\n NOTE = \"Note\",\n LITERAL = \"Literal\",\n SYLLABLE = \"Syllable\",\n SPACE = \"Space\",\n GROUP = \"Group\",\n LABEL = \"Label\",\n REST = \"Rest\",\n MARKER = \"Marker\",\n}\n\n/**\n * Atoms are the base class for all timed entities that can appear in a Notation.\n * An Atom represents the fundamental building block of the notation system.\n */\nexport abstract class Atom extends TimedEntity {\n readonly TYPE: string = \"Atom\";\n\n protected _duration: Fraction;\n /** Markers to be displayed before this atom */\n markersBefore: Marker[];\n /** Markers to be displayed after this atom */\n markersAfter: Marker[];\n /** Next atom in the sequence */\n nextSibling: TSU.Nullable<Atom> = null;\n /** Previous atom in the sequence */\n prevSibling: TSU.Nullable<Atom> = null;\n /** The Group this Atom belongs to, if any */\n parentGroup: TSU.Nullable<Group> = null;\n\n /** Indicates if this Atom is a continuation from a previous atom */\n isContinuation = false;\n\n /**\n * Creates a new Atom with the specified duration.\n * @param duration The duration of the atom, defaults to ONE (1/1)\n */\n constructor(duration = ONE) {\n super();\n this._duration = duration || ONE;\n }\n\n /**\n * Splits this atom at the specified duration.\n * @param requiredDuration The duration at which to split the atom\n * @returns A new atom representing the portion beyond the split point, or null if no split is needed\n */\n abstract splitAt(requiredDuration: Fraction): TSU.Nullable<Atom>;\n\n /**\n * Returns a debug-friendly representation of this Atom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = super.debugValue();\n if (!this.duration.isOne) {\n out.duration = this.duration.factorized.toString();\n }\n if (this.isContinuation) {\n out.isContinuation = true;\n }\n if ((this.markersBefore || []).length > 0) {\n out.mbef = this.markersBefore.map((m) => m.debugValue());\n }\n if ((this.markersAfter || []).length > 0) {\n out.maft = this.markersAfter.map((m) => m.debugValue());\n }\n return out;\n }\n\n /**\n * Copies the properties of this atom to another atom.\n * @param another The target atom to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another._duration = new TSU.Num.Fraction(this.duration.num, this.duration.den);\n }\n\n /**\n * Gets the duration of this atom.\n */\n get duration(): Fraction {\n return this._duration;\n }\n\n /**\n * Sets the duration of this atom.\n */\n set duration(d: Fraction) {\n this._duration = d;\n }\n}\n\n/**\n * Base class for atoms that cannot contain other atoms.\n * LeafAtom represents atomic elements that can't be further subdivided.\n */\nexport abstract class LeafAtom extends Atom {\n readonly TYPE: string = \"LeafAtom\";\n\n /** Indicates if this atom is followed by a rest */\n beforeRest = false;\n\n /**\n * Splits this atom at a certain duration.\n * If this atom's duration is longer than the given duration, it's truncated\n * to the given duration and a continuation space is returned.\n *\n * @param duration The duration at which to split the atom\n * @returns A new Space atom representing the spillover if needed, otherwise null\n */\n splitAt(duration: Fraction): TSU.Nullable<Atom> {\n if (this.duration.cmp(duration) > 0) {\n const spillOver = this.createSpilloverSpace(this.duration.minus(duration));\n spillOver.isContinuation = true;\n this.duration = duration;\n // TODO - Here we need to move the markersAfter to the spill-over as it doesnt belong to this any more\n return spillOver;\n }\n return null;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n return new Space(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this LeafAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return this.beforeRest ? { ...super.debugValue(), beforeRest: true } : super.debugValue();\n }\n}\n\n/**\n * Represents a marker or annotation in the notation.\n * Markers can be placed before or after atoms to provide additional context.\n */\nexport class Marker extends Entity {\n readonly TYPE = \"Marker\";\n\n /**\n * Creates a new Marker with the specified text.\n * @param text The text content of the marker\n * @param isBefore Whether the marker should appear before (true) or after (false) its associated atom\n */\n constructor(\n public text: string,\n public isBefore = true,\n ) {\n super();\n }\n\n /**\n * Returns a debug-friendly representation of this Marker.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), text: this.text, before: this.isBefore };\n }\n\n /**\n * Returns a string representation of this Marker.\n * @returns A string representation\n */\n toString(): string {\n return `Marker(${this.text}-${this.isBefore})`;\n }\n}\n\n/**\n * Represents a rest (silence) in the notation.\n * Rests are zero-length atoms that indicate a pause.\n */\nexport class Rest extends LeafAtom {\n readonly TYPE = \"Rest\";\n\n /**\n * Creates a new Rest.\n * Rests are zero length by default.\n */\n constructor() {\n super(ZERO);\n }\n}\n\n/**\n * Represents a space or silence in the notation.\n * Spaces can be used to denote either silence or continuations of previous notes.\n */\nexport class Space extends LeafAtom {\n readonly TYPE = \"Space\";\n\n /**\n * Indicates whether this is a silent space or a continuation of the previous note.\n */\n isSilent = false;\n\n /**\n * Creates a new Space with the specified duration and silence property.\n * @param duration The duration of the space, defaults to ONE (1/1)\n * @param isSilent Whether the space represents silence (true) or a continuation (false)\n */\n constructor(duration = ONE, isSilent = false) {\n super(duration);\n this.isSilent = isSilent;\n }\n\n /**\n * Returns a debug-friendly representation of this Space.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), isSilent: this.isSilent };\n }\n\n /**\n * Returns a string representation of this Space.\n * @returns A string representation\n */\n toString(): string {\n return `Space(${this.duration}-${this.isSilent})`;\n }\n\n /**\n * Copies the properties of this Space to another Space.\n * @param another The target Space to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.isSilent = this.isSilent;\n }\n\n /**\n * Checks if this Space is equal to another Space.\n * @param another The Space to compare with\n * @returns True if the Spaces are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.isSilent == another.isSilent;\n }\n\n /**\n * Creates a Space atom to represent spillover duration when splitting.\n * @param duration The duration of the spillover\n * @returns A new Space atom with the same silence property as this Space\n */\n protected createSpilloverSpace(duration: Fraction): Space {\n const out = super.createSpilloverSpace(duration);\n out.isSilent = this.isSilent;\n return out;\n }\n}\n\n/**\n * Represents a literal value in the notation.\n * Literals are the basic building blocks for notes and syllables.\n */\nexport class Literal extends LeafAtom {\n readonly TYPE: string = \"Literal\";\n\n /**\n * The embellishments applied to this Literal.\n */\n embelishments: any[] = [];\n\n /**\n * Creates a new Literal with the specified value and duration.\n * @param value The string value of the literal\n * @param duration The duration of the literal, defaults to ONE (1/1)\n */\n constructor(\n public value: string,\n duration = ONE,\n ) {\n super(duration);\n }\n\n /**\n * Returns a debug-friendly representation of this Literal.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), value: this.value };\n if (this.embelishments.length > 0) {\n out.embs = this.embelishments.map((e) => (\"debugValue\" in e ? e.debugValue() : e));\n }\n return out;\n }\n\n /**\n * Returns a string representation of this Literal.\n * @returns A string representation\n */\n toString(): string {\n return `Lit(${this.duration}-${this.value})`;\n }\n\n /**\n * Checks if this Literal is equal to another Literal.\n * @param another The Literal to compare with\n * @returns True if the Literals are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.value == another.value;\n }\n\n /**\n * Copies the properties of this Literal to another Literal.\n * @param another The target Literal to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.value = this.value;\n }\n}\n\n/**\n * Represents a syllable in lyrics or text to be sung.\n * Extends Literal to provide specialized handling for sung text.\n */\nexport class Syllable extends Literal {\n readonly TYPE = \"Syllable\";\n\n /**\n * Creates a Syllable from a Literal.\n * @param lit The Literal to convert to a Syllable\n * @returns A new Syllable with the properties of the Literal\n */\n static fromLit(lit: Literal): Syllable {\n if (lit.TYPE == AtomType.SYLLABLE) return lit as Syllable;\n const out = new Syllable(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a string representation of this Syllable.\n * @returns A string representation\n */\n toString(): string {\n return `Syll(${this.duration}-${this.value})`;\n }\n}\n\n/**\n * Represents a musical note in the notation.\n * Extends Literal to add properties specific to musical notes.\n */\nexport class Note extends Literal {\n readonly TYPE = \"Note\";\n\n /**\n * Which octave the note is in. Can be positive or negative to indicate higher or lower octaves.\n */\n octave = 0;\n\n /**\n * How the note is shifted - i.e., shifted towards major or minor by # of semi-tones.\n */\n shift: number | boolean = 0;\n\n /**\n * Creates a new Note with the specified properties.\n * @param value The string value of the note\n * @param duration The duration of the note, defaults to ONE (1/1)\n * @param octave The octave of the note, defaults to 0\n * @param shift The shift of the note, defaults to 0\n */\n constructor(value: string, duration = ONE, octave = 0, shift = 0) {\n super(value, duration);\n this.octave = octave;\n this.shift = shift;\n }\n\n /**\n * Creates a Note from a Literal.\n * @param lit The Literal to convert to a Note\n * @returns A new Note with the properties of the Literal\n */\n static fromLit(lit: Literal): Note {\n if (lit.TYPE == AtomType.NOTE) return lit as Note;\n const out = new Note(lit.value, lit.duration);\n out.embelishments = lit.embelishments;\n out.beforeRest = lit.beforeRest;\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this Note.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue() };\n if (this.octave != 0) out.octave = this.octave;\n if (this.shift != 0) out.shift = this.shift;\n return out;\n }\n\n /**\n * Returns a string representation of this Note.\n * @returns A string representation\n */\n toString(): string {\n return `Note(${this.duration}-${this.value}-${this.octave})`;\n }\n\n /**\n * Checks if this Note is equal to another Note.\n * @param another The Note to compare with\n * @returns True if the Notes are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.octave == another.octave && this.shift == another.shift;\n }\n\n /**\n * Copies the properties of this Note to another Note.\n * @param another The target Note to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.octave = this.octave;\n another.shift = this.shift;\n }\n}\n\n/**\n * Represents a group of atoms that are treated as a single unit.\n * Groups can contain any number of atoms, including other groups.\n */\nexport class Group extends Atom {\n readonly TYPE = \"Group\";\n\n /**\n * Indicates whether the duration is static or linear to the number of atoms in this group.\n * When true, the duration is used as a multiplier for the total child duration.\n * When false, the duration is absolute.\n */\n durationIsSpeedMultiplier = false;\n\n /**\n * The list of atoms in this group.\n */\n readonly atoms = new TSU.Lists.ValueList<Atom>();\n\n /**\n * Observers that receive notifications when atoms change.\n */\n private _observers: GroupObserver<Atom, Group>[] = [];\n\n /**\n * Creates a new Group containing the specified atoms.\n * @param atoms The atoms to include in this group\n */\n constructor(...atoms: Atom[]) {\n super(atoms.length == 0 ? ZERO : ONE);\n this.addAtoms(false, ...atoms);\n }\n\n /**\n * Adds an observer to receive atom change notifications.\n * @param observer The observer to add\n * @returns A function to remove the observer\n */\n addObserver(observer: GroupObserver<Atom, Group>): () => void {\n this._observers.push(observer);\n return () => this.removeObserver(observer);\n }\n\n /**\n * Removes an observer.\n * @param observer The observer to remove\n */\n removeObserver(observer: GroupObserver<Atom, Group>): void {\n const index = this._observers.indexOf(observer);\n if (index >= 0) {\n this._observers.splice(index, 1);\n }\n }\n\n /**\n * Notifies observers of atom changes.\n */\n private notifyObservers(type: AtomChangeType, atoms: Atom[], index: number): void {\n if (!this._eventsEnabled) return;\n for (const observer of this._observers) {\n switch (type) {\n case AtomChangeType.ADD:\n observer.onAtomsAdded?.(this, atoms, index);\n break;\n case AtomChangeType.INSERT:\n observer.onAtomsInserted?.(this, atoms, index);\n break;\n case AtomChangeType.REMOVE:\n observer.onAtomsRemoved?.(this, atoms);\n break;\n }\n }\n }\n\n /**\n * Checks if this Group is equal to another Group.\n * @param another The Group to compare with\n * @param expect Optional parameter\n * @returns True if the Groups are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (!super.equals(another)) return false;\n return this.atoms.equals(another.atoms, (a1, a2) => a1.equals(a2));\n }\n\n /**\n * Copies the properties of this Group to another Group.\n * @param another The target Group to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.durationIsSpeedMultiplier = this.durationIsSpeedMultiplier;\n for (const atom of this.atoms.values()) {\n another.atoms.add(atom.clone());\n }\n }\n\n /**\n * Gets the duration of this group.\n * If durationIsSpeedMultiplier is true, returns the total child duration divided by the multiplier.\n * Otherwise, returns the absolute duration.\n */\n get duration(): Fraction {\n if (this.durationIsSpeedMultiplier) {\n return this.totalChildDuration.divby(this._duration);\n } else {\n return this._duration;\n }\n }\n\n /**\n * Sets this group to use a multiplier for duration calculations.\n * @param asSpeedMultiplier Whether to use the duration as a speed multiplier. Eg If our duration was 2 and this was\n * set then since the speed is doubled - then the actual duration is halved.\n * @returns This Group instance for method chaining\n */\n setDurationAsMultiplier(asSpeedMultiplier = true): this {\n this.durationIsSpeedMultiplier = asSpeedMultiplier;\n return this;\n }\n\n /**\n * Sets the duration of this group.\n * @param d The new duration\n * @param asSpeedMultiplier Whether to use the duration as a speed multiplier. Eg If our duration was 2 and this was\n * set then since the speed is doubled - then the actual duration is halved.\n * @returns This Group instance for method chaining\n */\n setDuration(d: Fraction, asSpeedMultiplier = false): this {\n this._duration = d;\n this.durationIsSpeedMultiplier = asSpeedMultiplier;\n return this;\n }\n\n /**\n * Returns a debug-friendly representation of this Group.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = { ...super.debugValue(), atoms: Array.from(this.atoms.values(), (a) => a.debugValue()) };\n if (this.durationIsSpeedMultiplier) out.durationIsSpeedMultiplier = true;\n return out;\n }\n\n /**\n * Splits this group into two parts.\n * The first part (this group) fits within the given duration and everything else\n * longer than the given duration is returned as a new Group.\n *\n * @param requiredDuration The duration at which to split the group\n * @returns A new Group containing the atoms beyond the split point, or null if no split is needed\n */\n splitAt(requiredDuration: Fraction): TSU.Nullable<Group> {\n if (this.duration.isLTE(requiredDuration) || requiredDuration.isLTE(ZERO)) {\n return null;\n }\n const targetGroup = new Group();\n if (this.durationIsSpeedMultiplier) {\n targetGroup.durationIsSpeedMultiplier = true;\n targetGroup._duration = this._duration;\n }\n\n let remainingDur = this.duration;\n const totalChildDuration = this.totalChildDuration;\n const durationFactor = this.durationIsSpeedMultiplier\n ? ONE.divby(this._duration)\n : this._duration.divby(totalChildDuration, true);\n while (remainingDur.isGT(requiredDuration) && this.atoms.last) {\n const lastChild = this.atoms.last;\n // Child's duration is absolute in its own \"system\"\n // Its duration within the parent (this) group's frame of reference depends\n // on whether the parent's duration is absolute or as a multiplier\n //\n // realChildDuration = case (group.durationIsMultiper) {\n // | true => child.duration / this._duration\n // | false => child.duration * this._duration / total child duration\n // }\n const childDuration = lastChild.duration.times(durationFactor);\n const newDuration = remainingDur.minus(childDuration);\n if (newDuration.isGTE(requiredDuration)) {\n // remove ourselves and add to target\n // in both cases duration will be adjusted if need be\n this.removeAtoms(true, lastChild);\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, lastChild);\n if (newDuration.equals(requiredDuration)) {\n // we have reached the end so return\n return targetGroup;\n }\n } else {\n // our scenario is now this:\n //\n // totalParentDuration = 10\n // required = 8\n // lastChildDuration (relative to parent) is 5\n //\n // durWithoutLast = 10 - 5\n // newRequired = requiredDur - durWithoutLast = 3\n //\n // However 3 is a duration in the parent's frame of reference\n // this has to be converted back to the child's FoR\n const newRequiredDur = requiredDuration.minus(newDuration, true).divby(durationFactor, true);\n // console.log( \"newRequiredDur: \", newRequiredDur, \"requiedDur: \", requiredDuration, \"remainingDur: \", remainingDur,);\n // then the last item needs to be split, and by how much?\n const spillOver = lastChild.splitAt(newRequiredDur);\n if (spillOver == null) {\n throw new Error(\"Spill over cannot be null here\");\n }\n if (!this.durationIsSpeedMultiplier) {\n // Our own duration has also now changed\n this._duration = requiredDuration;\n } else {\n if (this._duration.isZero) throw new Error(\"How can this be?\");\n }\n spillOver.isContinuation = true;\n // Add spill over to the target\n targetGroup.insertAtomsAt(targetGroup.atoms.first, true, spillOver);\n return targetGroup;\n }\n remainingDur = newDuration;\n }\n return targetGroup;\n }\n\n /**\n * Gets the total duration of all child atoms.\n * @returns The sum of durations of all atoms in this group\n */\n get totalChildDuration(): Fraction {\n let out = ZERO;\n for (const atom of this.atoms.values()) {\n out = out.plus(atom.duration);\n }\n return out;\n }\n\n /**\n * Inserts atoms before a given cursor atom.\n * If the cursor atom is null, the atoms are appended at the end.\n *\n * @param beforeAtom The atom before which to insert the new atoms, or null to append\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to insert\n * @returns This Group instance for method chaining\n */\n insertAtomsAt(beforeAtom: TSU.Nullable<Atom>, adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsSpeedMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n\n // Calculate insertion index for event notification\n let insertIndex: number;\n if (beforeAtom) {\n // Find index of beforeAtom using for loop\n insertIndex = 0;\n for (const a of this.atoms.values()) {\n if (a === beforeAtom) break;\n insertIndex++;\n }\n } else {\n // Appending to end - use size property\n insertIndex = this.atoms.size;\n }\n\n // Track which atoms were actually added (excluding REST atoms)\n const addedAtoms: Atom[] = [];\n\n // First form a chain of the given atoms\n for (const atom of atoms) {\n if (atom.parentGroup != null) {\n if (atom.parentGroup != this) {\n throw new Error(\"Atom belongs to another parent. Remove it first\");\n }\n atom.parentGroup.removeAtoms(false, atom);\n }\n if (atom.TYPE == AtomType.REST) {\n const last = this.atoms.last;\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n atom.parentGroup = this;\n this.atoms.add(atom, beforeAtom);\n addedAtoms.push(atom);\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsSpeedMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n\n // Notify observers if atoms were added\n if (addedAtoms.length > 0) {\n const type = beforeAtom ? AtomChangeType.INSERT : AtomChangeType.ADD;\n this.notifyObservers(type, addedAtoms, insertIndex);\n }\n\n return this;\n }\n\n /**\n * Adds atoms to the end of this group's atom list.\n *\n * @param adjustDuration Whether to adjust this group's duration based on the new atoms\n * @param atoms The atoms to add\n * @returns This Group instance for method chaining\n */\n addAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n return this.insertAtomsAt(null, adjustDuration, ...atoms);\n }\n\n /**\n * Removes atoms from this group's child list.\n *\n * @param adjustDuration Whether to adjust this group's duration after removing atoms\n * @param atoms The atoms to remove\n * @returns This Group instance for method chaining\n */\n removeAtoms(adjustDuration = false, ...atoms: Atom[]): this {\n adjustDuration = adjustDuration && !this.durationIsSpeedMultiplier;\n const oldChildDuration = adjustDuration ? this.totalChildDuration : ONE;\n\n // Track which atoms were actually removed\n const removedAtoms: Atom[] = [];\n\n for (const atom of atoms) {\n if (atom.parentGroup == this) {\n this.atoms.remove(atom);\n atom.parentGroup = null;\n removedAtoms.push(atom);\n } else if (atom.parentGroup != null) {\n throw new Error(\"Atom cannot be removed as it does not belong to this group\");\n }\n }\n if (adjustDuration) {\n if (this._duration.isZero) {\n if (this.durationIsSpeedMultiplier) throw new Error(\"How can this be?\");\n this._duration = this.totalChildDuration;\n } else {\n const scaleFactor = this.totalChildDuration.divby(oldChildDuration);\n this._duration = this._duration.times(scaleFactor, true);\n }\n }\n\n // Notify observers if atoms were removed\n if (removedAtoms.length > 0) {\n this.notifyObservers(AtomChangeType.REMOVE, removedAtoms, -1);\n }\n\n return this;\n }\n}\n\n/**\n * Represents a line of notation containing multiple roles.\n * A line can have atoms starting before or after the cycle.\n */\nexport class Line extends Entity {\n readonly TYPE: string = \"Line\";\n\n /**\n * Offset tells how many notes before or after the cycle this line's atoms start at.\n */\n offset: Fraction = ZERO;\n\n /**\n * The roles contained in this line.\n */\n roles: Role[] = [];\n\n /**\n * Text to be displayed in the margin of the line.\n * This is a hacky solution to doing left side pre-margin text typically\n * found in notations - e.g., line X of a pallavi has this. This makes vertical\n * space less wasteful.\n *\n * A better solution is inter-beat annotation but it is very complex for now.\n */\n marginText = \"\";\n\n /**\n * The LayoutParams associated with this line.\n */\n layoutParams: LayoutParams;\n\n /**\n * Observers that receive notifications when roles change.\n */\n private _observers: LineObserver<Role, Line>[] = [];\n\n /**\n * Adds an observer to receive role change notifications.\n * @param observer The observer to add\n * @returns A function to remove the observer\n */\n addObserver(observer: LineObserver<Role, Line>): () => void {\n this._observers.push(observer);\n return () => this.removeObserver(observer);\n }\n\n /**\n * Removes an observer.\n * @param observer The observer to remove\n */\n removeObserver(observer: LineObserver<Role, Line>): void {\n const index = this._observers.indexOf(observer);\n if (index >= 0) {\n this._observers.splice(index, 1);\n }\n }\n\n /**\n * Finds the index of a role with the given name.\n * @param name The name of the role to find\n * @returns The index of the role, or -1 if not found\n */\n indexOfRole(name: string): number {\n for (let i = 0; i < this.roles.length; i++) {\n if (this.roles[i].name == name) return i;\n }\n return -1;\n }\n\n /**\n * Checks if this line is empty (has no content in any role).\n */\n get isEmpty(): boolean {\n for (const r of this.roles) if (!r.isEmpty) return false;\n return true;\n }\n\n /**\n * Returns a debug-friendly representation of this Line.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n roles: this.roles.map((r) => r.debugValue()),\n };\n if (!this.offset.isZero) {\n out.offset = this.offset.toString();\n }\n return out;\n }\n\n /**\n * Copies the properties of this Line to another Line.\n * @param another The target Line to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.roles = this.roles.map((r) => r.clone());\n }\n\n /**\n * Adds atoms to a role in this line.\n * @param roleName The name of the role to add atoms to\n * @param defaultToNotes Whether to default to notes for this role\n * @param atoms The atoms to add\n * @returns This Line instance for method chaining\n */\n addAtoms(roleName: string, defaultToNotes: boolean, ...atoms: Atom[]): this {\n const role = this.ensureRole(roleName, defaultToNotes);\n role.addAtoms(...atoms);\n return this;\n }\n\n /**\n * Ensures a role with the given name exists in this line, creating it if needed.\n * @param roleName The name of the role to ensure\n * @param defaultToNotes Whether to default to notes for this role\n * @returns The role with the specified name\n */\n ensureRole(roleName: string, defaultToNotes: boolean): Role {\n // Ensure we have this many roles\n let ri = this.roles.findIndex((r) => r.name == roleName);\n if (ri < 0) {\n ri = this.roles.length;\n const role = new Role(this, roleName);\n role.defaultToNotes = defaultToNotes;\n this.roles.push(role);\n\n // Notify observers of new role\n if (this._eventsEnabled) {\n for (const observer of this._observers) {\n observer.onRoleAdded?.(this, roleName, role);\n }\n }\n }\n return this.roles[ri];\n }\n\n /**\n * Removes a role from this line.\n * @param roleName The name of the role to remove\n * @returns True if the role was removed, false if not found\n */\n removeRole(roleName: string): boolean {\n const ri = this.roles.findIndex((r) => r.name == roleName);\n if (ri >= 0) {\n this.roles.splice(ri, 1);\n\n // Notify observers of removed role\n if (this._eventsEnabled) {\n for (const observer of this._observers) {\n observer.onRoleRemoved?.(this, roleName);\n }\n }\n return true;\n }\n return false;\n }\n\n /**\n * Gets the maximum duration across all roles in this line.\n */\n get duration(): Fraction {\n let max = ZERO;\n for (const role of this.roles) {\n max = TSU.Num.Fraction.max(role.duration, max);\n }\n return max;\n }\n}\n\n/**\n * Represents a specific role or voice in a line of notation.\n * Each role contains a sequence of atoms.\n */\nexport class Role extends Entity {\n readonly TYPE = \"Role\";\n\n /**\n * Whether this role represents notes by default.\n */\n defaultToNotes = true;\n\n /**\n * The atoms in this role.\n */\n atoms: Atom[] = [];\n\n /**\n * Observers that receive notifications when atoms change.\n */\n private _observers: RoleObserver<Atom, Role>[] = [];\n\n /**\n * Creates a new Role with the specified line and name.\n * @param line The line this role belongs to\n * @param name The name of the role\n */\n constructor(\n public readonly line: Line,\n public readonly name: string,\n ) {\n super();\n }\n\n /**\n * Adds an observer to receive atom change notifications.\n * @param observer The observer to add\n * @returns A function to remove the observer\n */\n addObserver(observer: RoleObserver<Atom, Role>): () => void {\n this._observers.push(observer);\n return () => this.removeObserver(observer);\n }\n\n /**\n * Removes an observer.\n * @param observer The observer to remove\n */\n removeObserver(observer: RoleObserver<Atom, Role>): void {\n const index = this._observers.indexOf(observer);\n if (index >= 0) {\n this._observers.splice(index, 1);\n }\n }\n\n /**\n * Notifies observers of atom changes.\n */\n private notifyObservers(type: AtomChangeType, atoms: Atom[], index: number): void {\n if (!this._eventsEnabled) return;\n for (const observer of this._observers) {\n switch (type) {\n case AtomChangeType.ADD:\n observer.onAtomsAdded?.(this, atoms, index);\n break;\n case AtomChangeType.INSERT:\n observer.onAtomsInserted?.(this, atoms, index);\n break;\n case AtomChangeType.REMOVE:\n observer.onAtomsRemoved?.(this, atoms);\n break;\n }\n }\n }\n\n /**\n * Checks if this role is empty (has no atoms).\n */\n get isEmpty(): boolean {\n return this.atoms.length == 0;\n }\n\n /**\n * Returns a debug-friendly representation of this Role.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { name: this.name, atoms: this.atoms.map((a) => a.debugValue()) };\n }\n\n /**\n * Adds atoms to the end of this role.\n * @param atoms The atoms to add\n */\n addAtoms(...atoms: Atom[]): void {\n this.insertAtomsAt(this.atoms.length, ...atoms);\n }\n\n /**\n * Inserts atoms at a specific index in this role.\n * @param index The index at which to insert\n * @param atoms The atoms to insert\n */\n insertAtomsAt(index: number, ...atoms: Atom[]): void {\n // Track which atoms were actually added (excluding REST atoms)\n const addedAtoms: Atom[] = [];\n let last: null | Atom = index > 0 ? this.atoms[index - 1] : null;\n\n for (const atom of atoms) {\n if (atom.TYPE == AtomType.REST) {\n if (last && last.TYPE != AtomType.GROUP && last.TYPE != AtomType.LABEL) {\n (last as LeafAtom).beforeRest = true;\n }\n } else {\n this.atoms.splice(index + addedAtoms.length, 0, atom);\n addedAtoms.push(atom);\n }\n last = atom;\n }\n\n // Notify observers if atoms were added\n if (addedAtoms.length > 0) {\n const isAppend = index >= this.atoms.length - addedAtoms.length;\n const type = isAppend ? AtomChangeType.ADD : AtomChangeType.INSERT;\n this.notifyObservers(type, addedAtoms, index);\n }\n }\n\n /**\n * Removes atoms from this role.\n * @param atoms The atoms to remove\n */\n removeAtoms(...atoms: Atom[]): void {\n const removedAtoms: Atom[] = [];\n\n for (const atom of atoms) {\n const idx = this.atoms.indexOf(atom);\n if (idx >= 0) {\n this.atoms.splice(idx, 1);\n removedAtoms.push(atom);\n }\n }\n\n // Notify observers if atoms were removed\n if (removedAtoms.length > 0) {\n this.notifyObservers(AtomChangeType.REMOVE, removedAtoms, -1);\n }\n }\n\n /**\n * Copies the properties of this Role to another Role.\n * @param another The target Role to copy properties to\n */\n copyTo(another: Role): void {\n another.addAtoms(...this.atoms);\n }\n\n /**\n * Gets the total duration of all atoms in this role.\n */\n get duration(): Fraction {\n return this.atoms.reduce((a, b) => a.plus(b.duration), ZERO);\n }\n}\n"]}
|
package/lib/cjs/entity.d.ts
CHANGED
|
@@ -4,7 +4,11 @@ export declare class Entity {
|
|
|
4
4
|
private static counter;
|
|
5
5
|
readonly uuid: number;
|
|
6
6
|
protected _parent: TSU.Nullable<Entity>;
|
|
7
|
+
protected _eventsEnabled: boolean;
|
|
7
8
|
constructor(config?: any);
|
|
9
|
+
enableEvents(): this;
|
|
10
|
+
disableEvents(): this;
|
|
11
|
+
get eventsEnabled(): boolean;
|
|
8
12
|
get parent(): TSU.Nullable<Entity>;
|
|
9
13
|
setParent(parent: TSU.Nullable<Entity>): void;
|
|
10
14
|
debugValue(): any;
|
package/lib/cjs/entity.js
CHANGED
|
@@ -6,10 +6,22 @@ class Entity {
|
|
|
6
6
|
this.TYPE = "Entity";
|
|
7
7
|
this.uuid = Entity.counter++;
|
|
8
8
|
this._parent = null;
|
|
9
|
+
this._eventsEnabled = false;
|
|
9
10
|
config = config || {};
|
|
10
11
|
if (config.metadata)
|
|
11
12
|
throw new Error("See where metadata is being passed");
|
|
12
13
|
}
|
|
14
|
+
enableEvents() {
|
|
15
|
+
this._eventsEnabled = true;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
disableEvents() {
|
|
19
|
+
this._eventsEnabled = false;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
get eventsEnabled() {
|
|
23
|
+
return this._eventsEnabled;
|
|
24
|
+
}
|
|
13
25
|
get parent() {
|
|
14
26
|
return this._parent;
|
|
15
27
|
}
|
package/lib/cjs/entity.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":";;;AAgBA,MAAa,MAAM;IAmBjB,YAAY,SAAc,IAAI;QAlBrB,SAAI,GAAW,QAAQ,CAAC;QAIxB,SAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAEvB,YAAO,GAAyB,IAAI,CAAC;QAMrC,mBAAc,GAAG,KAAK,CAAC;QAO/B,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC7E,CAAC;IAOD,YAAY;QACV,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAMD,aAAa;QACX,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAKD,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAMD,SAAS,CAAC,MAA4B;QACpC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAOD,UAAU;QACR,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAMD,QAAQ;QACN,OAAO,eAAe,IAAI,CAAC,IAAI,GAAG,CAAC;IACrC,CAAC;IAQD,MAAM,CAAC,OAAa,EAAE,MAAM,GAAG,KAAK;QAClC,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IAUD,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC;IAMD,MAAM,CAAC,OAAa;IAEpB,CAAC;IAMS,WAAW;QACnB,OAAO,IAAK,IAAI,CAAC,WAAmB,EAAE,CAAC;IACzC,CAAC;;AAzHH,wBA0HC;AAvHgB,cAAO,GAAG,CAAC,AAAJ,CAAK;AA6H7B,MAAsB,WAAY,SAAQ,MAAM;IAAhD;;QACW,SAAI,GAAW,aAAa,CAAC;IAgBxC,CAAC;IAHC,MAAM,CAAC,OAAa;QAClB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;CACF;AAjBD,kCAiBC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n\n/**\n * A common Entity base class with support for unique IDs, parent references,\n * copying, and debug info. This serves as the foundation for all entities\n * in the notation system.\n *\n * Note: Child management is intentionally NOT included here. Each container type\n * (BlockContainer, Line, Group, etc.) defines its own child management with\n * appropriate types.\n *\n * Observer Pattern:\n * Each observable entity subclass (Group, Role, Line, Block) manages its own\n * typed observer list. This provides type safety and clear contracts between\n * observables and observers.\n */\nexport class Entity {\n readonly TYPE: string = \"Entity\";\n\n private static counter = 0;\n /** Unique identifier for this entity */\n readonly uuid = Entity.counter++;\n /** Parent entity in the tree hierarchy */\n protected _parent: TSU.Nullable<Entity> = null;\n\n /**\n * Whether events/observer notifications are enabled for this entity.\n * Subclasses check this flag before notifying observers.\n */\n protected _eventsEnabled = false;\n\n /**\n * Creates a new Entity.\n * @param config Optional configuration object\n */\n constructor(config: any = null) {\n config = config || {};\n if (config.metadata) throw new Error(\"See where metadata is being passed\");\n }\n\n /**\n * Enables observer notifications for this entity.\n * Call this to activate change notifications on entities that support them.\n * @returns This entity for method chaining\n */\n enableEvents(): this {\n this._eventsEnabled = true;\n return this;\n }\n\n /**\n * Disables observer notifications for this entity.\n * @returns This entity for method chaining\n */\n disableEvents(): this {\n this._eventsEnabled = false;\n return this;\n }\n\n /**\n * Checks if events/observer notifications are enabled.\n */\n get eventsEnabled(): boolean {\n return this._eventsEnabled;\n }\n\n /**\n * Gets the parent entity.\n */\n get parent(): TSU.Nullable<Entity> {\n return this._parent;\n }\n\n /**\n * Sets the parent entity.\n * @param parent The parent entity to set\n */\n setParent(parent: TSU.Nullable<Entity>): void {\n this._parent = parent;\n }\n\n /**\n * Returns a debug-friendly representation of this entity.\n * Usually overridden by children to add more debug info.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { type: this.TYPE };\n }\n\n /**\n * Returns a simple string representation of this Entity.\n * @returns A string representation\n */\n toString(): string {\n return `Entity(id = ${this.uuid})`;\n }\n\n /**\n * Checks if this Entity is equal to another Entity.\n * @param another The Entity to compare with\n * @param expect Optional parameter\n * @returns True if the Entities are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (this.TYPE != another.TYPE) return false;\n return true;\n }\n\n /**\n * Creates a clone of this entity.\n * Cloning is a two-part process:\n * 1. Creation of a new instance via this.newInstance()\n * 2. Copying of data into the new instance via this.copyTo()\n *\n * @returns A new instance of the same type with the same properties\n */\n clone(): this {\n const out = this.newInstance();\n this.copyTo(out);\n return out;\n }\n\n /**\n * Copies information about this instance into another instance of the same type.\n * @param another The target instance to copy properties to\n */\n copyTo(another: this): void {\n // Subclasses override to copy their specific properties\n }\n\n /**\n * First part of the cloning process where the instance is created.\n * @returns A new instance of the same type\n */\n protected newInstance(): this {\n return new (this.constructor as any)();\n }\n}\n\n/**\n * Music is all about timing! TimedEntities are base of all entities that\n * have a duration. This is an abstract class that all timed entities inherit from.\n */\nexport abstract class TimedEntity extends Entity {\n readonly TYPE: string = \"TimedEntity\";\n\n /**\n * Gets the duration of this entity in terms of beats.\n * By default, entity durations are readonly.\n */\n abstract get duration(): TSU.Num.Fraction;\n\n /**\n * Checks if this TimedEntity is equal to another TimedEntity.\n * @param another The TimedEntity to compare with\n * @returns True if the TimedEntities are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.duration.equals(another.duration);\n }\n}\n"]}
|