@libraz/libcantus 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +4 -0
  2. package/README_ja.md +4 -0
  3. package/dist/analyze/index.cjs +31 -7
  4. package/dist/analyze/index.cjs.map +1 -1
  5. package/dist/analyze/index.d.cts +155 -9
  6. package/dist/analyze/index.d.ts +155 -9
  7. package/dist/analyze/index.js +37 -13
  8. package/dist/{chunk-TT6PKMPR.cjs → chunk-35NBV2FT.cjs} +16 -16
  9. package/dist/{chunk-TT6PKMPR.cjs.map → chunk-35NBV2FT.cjs.map} +1 -1
  10. package/dist/{chunk-YPB3A3EY.cjs → chunk-3R3QVKY5.cjs} +314 -285
  11. package/dist/chunk-3R3QVKY5.cjs.map +1 -0
  12. package/dist/{chunk-GDKE6RQW.cjs → chunk-4R2LWV7E.cjs} +691 -413
  13. package/dist/chunk-4R2LWV7E.cjs.map +1 -0
  14. package/dist/{chunk-RVS4G4MR.cjs → chunk-76ZBTRG2.cjs} +198 -198
  15. package/dist/{chunk-RVS4G4MR.cjs.map → chunk-76ZBTRG2.cjs.map} +1 -1
  16. package/dist/{chunk-X6RJAHII.js → chunk-7KG3RTYS.js} +2 -2
  17. package/dist/{chunk-PQL7E5F6.js → chunk-AGOVW7U6.js} +1 -1
  18. package/dist/{chunk-PQL7E5F6.js.map → chunk-AGOVW7U6.js.map} +1 -1
  19. package/dist/{chunk-5KW7DNCJ.cjs → chunk-B2PW6EHN.cjs} +2423 -453
  20. package/dist/chunk-B2PW6EHN.cjs.map +1 -0
  21. package/dist/{chunk-J772DL3B.cjs → chunk-CGBADIO5.cjs} +53 -53
  22. package/dist/{chunk-J772DL3B.cjs.map → chunk-CGBADIO5.cjs.map} +1 -1
  23. package/dist/{chunk-R5VUXQMP.js → chunk-CPMB7P75.js} +1978 -8
  24. package/dist/chunk-CPMB7P75.js.map +1 -0
  25. package/dist/{chunk-VLE5R7PF.js → chunk-GNVN4PPJ.js} +1874 -8
  26. package/dist/chunk-GNVN4PPJ.js.map +1 -0
  27. package/dist/{chunk-Q6R3QAZD.cjs → chunk-IFZDWIKM.cjs} +2199 -333
  28. package/dist/chunk-IFZDWIKM.cjs.map +1 -0
  29. package/dist/{chunk-DKICR7AN.js → chunk-IPEF6NWB.js} +296 -18
  30. package/dist/chunk-IPEF6NWB.js.map +1 -0
  31. package/dist/{chunk-AWEMD747.js → chunk-M5RYMAFI.js} +3 -3
  32. package/dist/{chunk-HSY2VQXZ.js → chunk-MLBPXA4Z.js} +330 -728
  33. package/dist/chunk-MLBPXA4Z.js.map +1 -0
  34. package/dist/{chunk-H66ARFU5.js → chunk-NB25P3EH.js} +3 -3
  35. package/dist/{chunk-5JJ6EHEZ.cjs → chunk-NM7UAMC3.cjs} +62 -62
  36. package/dist/{chunk-5JJ6EHEZ.cjs.map → chunk-NM7UAMC3.cjs.map} +1 -1
  37. package/dist/{chunk-R7B5N2JK.cjs → chunk-PM4XJE2Y.cjs} +47 -47
  38. package/dist/{chunk-R7B5N2JK.cjs.map → chunk-PM4XJE2Y.cjs.map} +1 -1
  39. package/dist/{chunk-7GOKQJTQ.js → chunk-PUKJP2Z5.js} +2 -2
  40. package/dist/{chunk-QCXYKSZS.cjs → chunk-PWC4CRWT.cjs} +19 -19
  41. package/dist/{chunk-QCXYKSZS.cjs.map → chunk-PWC4CRWT.cjs.map} +1 -1
  42. package/dist/{chunk-FPBZFNCD.js → chunk-RFIBF2RR.js} +47 -18
  43. package/dist/{chunk-FPBZFNCD.js.map → chunk-RFIBF2RR.js.map} +1 -1
  44. package/dist/{chunk-XKSO2V5I.cjs → chunk-S5BKZZGM.cjs} +1 -1
  45. package/dist/{chunk-XKSO2V5I.cjs.map → chunk-S5BKZZGM.cjs.map} +1 -1
  46. package/dist/{chunk-HOHFYGKW.js → chunk-UMWZ4ZET.js} +2 -2
  47. package/dist/{chunk-XVMJO3QF.cjs → chunk-YFA7X2F6.cjs} +489 -887
  48. package/dist/chunk-YFA7X2F6.cjs.map +1 -0
  49. package/dist/{chunk-57WB2EDF.js → chunk-ZBUROTJQ.js} +3 -3
  50. package/dist/{coerce-wwdELNYS.d.ts → coerce-DP0vYu-x.d.ts} +77 -1
  51. package/dist/{coerce-CJlgULrQ.d.cts → coerce-DRERzdve.d.cts} +77 -1
  52. package/dist/core/index.cjs +5 -5
  53. package/dist/core/index.d.cts +2 -2
  54. package/dist/core/index.d.ts +2 -2
  55. package/dist/core/index.js +4 -4
  56. package/dist/generate/index.cjs +20 -8
  57. package/dist/generate/index.cjs.map +1 -1
  58. package/dist/generate/index.d.cts +87 -9
  59. package/dist/generate/index.d.ts +87 -9
  60. package/dist/generate/index.js +19 -7
  61. package/dist/{index-BaoKVVhE.d.cts → index-B9QLziDe.d.cts} +2 -2
  62. package/dist/{index-CnHQgqNh.d.ts → index-BHIUyjhZ.d.ts} +2 -2
  63. package/dist/{index-CBCP84rv.d.cts → index-BL5N2Oyz.d.cts} +1 -1
  64. package/dist/{index-D_hzxD8w.d.cts → index-BMweUlm5.d.cts} +3 -0
  65. package/dist/{index-Ci3xyows.d.ts → index-CL4b4gUQ.d.ts} +3 -0
  66. package/dist/{index-BzLNkmA7.d.cts → index-CY-3NVfy.d.cts} +486 -5
  67. package/dist/{index-CnIdP4EZ.d.ts → index-Dw2DP7vm.d.ts} +1 -1
  68. package/dist/{index-DpC-mDlV.d.ts → index-zaZdmnU4.d.ts} +486 -5
  69. package/dist/index.cjs +49 -13
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/index.d.cts +10 -10
  72. package/dist/index.d.ts +10 -10
  73. package/dist/index.js +55 -19
  74. package/dist/{masks-O73Rhj5d.d.ts → masks-Cc7-MzzY.d.ts} +1 -1
  75. package/dist/{masks-C8TWLFIi.d.cts → masks-pADfTOiD.d.cts} +1 -1
  76. package/dist/model/index.cjs +12 -12
  77. package/dist/model/index.d.cts +213 -16
  78. package/dist/model/index.d.ts +213 -16
  79. package/dist/model/index.js +11 -11
  80. package/dist/{index-DTsKaPaC.d.cts → profile-CQMEqdH9.d.cts} +88 -601
  81. package/dist/{index-BUtIf2go.d.ts → profile-DLdlIpS9.d.ts} +88 -601
  82. package/dist/theory/index.cjs +5 -5
  83. package/dist/theory/index.d.cts +7 -7
  84. package/dist/theory/index.d.ts +7 -7
  85. package/dist/theory/index.js +4 -4
  86. package/dist/{index-BpWOhkkE.d.ts → types-D-XgxGvp.d.cts} +1170 -14
  87. package/dist/{index-B3WCj_Hm.d.cts → types-Dh7C064C.d.ts} +1170 -14
  88. package/package.json +6 -5
  89. package/dist/chunk-5KW7DNCJ.cjs.map +0 -1
  90. package/dist/chunk-DKICR7AN.js.map +0 -1
  91. package/dist/chunk-GDKE6RQW.cjs.map +0 -1
  92. package/dist/chunk-HSY2VQXZ.js.map +0 -1
  93. package/dist/chunk-Q6R3QAZD.cjs.map +0 -1
  94. package/dist/chunk-R5VUXQMP.js.map +0 -1
  95. package/dist/chunk-VLE5R7PF.js.map +0 -1
  96. package/dist/chunk-XVMJO3QF.cjs.map +0 -1
  97. package/dist/chunk-YPB3A3EY.cjs.map +0 -1
  98. /package/dist/{chunk-X6RJAHII.js.map → chunk-7KG3RTYS.js.map} +0 -0
  99. /package/dist/{chunk-AWEMD747.js.map → chunk-M5RYMAFI.js.map} +0 -0
  100. /package/dist/{chunk-H66ARFU5.js.map → chunk-NB25P3EH.js.map} +0 -0
  101. /package/dist/{chunk-7GOKQJTQ.js.map → chunk-PUKJP2Z5.js.map} +0 -0
  102. /package/dist/{chunk-HOHFYGKW.js.map → chunk-UMWZ4ZET.js.map} +0 -0
  103. /package/dist/{chunk-57WB2EDF.js.map → chunk-ZBUROTJQ.js.map} +0 -0
@@ -8,7 +8,6 @@
8
8
 
9
9
 
10
10
 
11
- var _chunkQ6R3QAZDcjs = require('./chunk-Q6R3QAZD.cjs');
12
11
 
13
12
 
14
13
 
@@ -19,14 +18,11 @@ var _chunkQ6R3QAZDcjs = require('./chunk-Q6R3QAZD.cjs');
19
18
 
20
19
 
21
20
 
22
- var _chunkJ772DL3Bcjs = require('./chunk-J772DL3B.cjs');
23
21
 
24
22
 
25
- var _chunkTT6PKMPRcjs = require('./chunk-TT6PKMPR.cjs');
26
23
 
27
24
 
28
25
 
29
- var _chunkR7B5N2JKcjs = require('./chunk-R7B5N2JK.cjs');
30
26
 
31
27
 
32
28
 
@@ -34,6 +30,7 @@ var _chunkR7B5N2JKcjs = require('./chunk-R7B5N2JK.cjs');
34
30
 
35
31
 
36
32
 
33
+ var _chunkIFZDWIKMcjs = require('./chunk-IFZDWIKM.cjs');
37
34
 
38
35
 
39
36
 
@@ -46,11 +43,14 @@ var _chunkR7B5N2JKcjs = require('./chunk-R7B5N2JK.cjs');
46
43
 
47
44
 
48
45
 
46
+ var _chunkCGBADIO5cjs = require('./chunk-CGBADIO5.cjs');
49
47
 
50
48
 
49
+ var _chunk35NBV2FTcjs = require('./chunk-35NBV2FT.cjs');
51
50
 
52
51
 
53
52
 
53
+ var _chunkPM4XJE2Ycjs = require('./chunk-PM4XJE2Y.cjs');
54
54
 
55
55
 
56
56
 
@@ -58,7 +58,6 @@ var _chunkR7B5N2JKcjs = require('./chunk-R7B5N2JK.cjs');
58
58
 
59
59
 
60
60
 
61
- var _chunkYPB3A3EYcjs = require('./chunk-YPB3A3EY.cjs');
62
61
 
63
62
 
64
63
 
@@ -85,6 +84,7 @@ var _chunkYPB3A3EYcjs = require('./chunk-YPB3A3EY.cjs');
85
84
 
86
85
 
87
86
 
87
+ var _chunk3R3QVKY5cjs = require('./chunk-3R3QVKY5.cjs');
88
88
 
89
89
 
90
90
 
@@ -95,24 +95,59 @@ var _chunkYPB3A3EYcjs = require('./chunk-YPB3A3EY.cjs');
95
95
 
96
96
 
97
97
 
98
- var _chunkXKSO2V5Icjs = require('./chunk-XKSO2V5I.cjs');
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+ var _chunkS5BKZZGMcjs = require('./chunk-S5BKZZGM.cjs');
99
134
 
100
135
  // src/generate/context/draw.ts
101
136
  var DRAW_METHODS = ["at", "prob", "range", "float"];
102
137
  function assertDraw(draw, name = "draw") {
103
- const sampler = _chunkXKSO2V5Icjs.assertRecord.call(void 0, draw, name);
138
+ const sampler = _chunkS5BKZZGMcjs.assertRecord.call(void 0, draw, name);
104
139
  for (const method of DRAW_METHODS) {
105
- _chunkXKSO2V5Icjs.assertFunction.call(void 0, sampler[method], `${name}.${method}`);
140
+ _chunkS5BKZZGMcjs.assertFunction.call(void 0, sampler[method], `${name}.${method}`);
106
141
  }
107
142
  return sampler;
108
143
  }
109
144
  function assertSeedPath(path, name = "draw path") {
110
- const steps = _chunkXKSO2V5Icjs.assertArray.call(void 0, path, name);
145
+ const steps = _chunkS5BKZZGMcjs.assertArray.call(void 0, path, name);
111
146
  for (let index = 0; index < steps.length; index += 1) {
112
147
  const step = steps[index];
113
148
  if (typeof step !== "string" && !Number.isFinite(step)) {
114
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
115
- `${name}[${index}] must be a string or a finite number; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, step)}`
149
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
150
+ `${name}[${index}] must be a string or a finite number; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, step)}`
116
151
  );
117
152
  }
118
153
  }
@@ -121,7 +156,7 @@ function assertSeedPath(path, name = "draw path") {
121
156
  function drawFrom(rng, path) {
122
157
  const draw = rng.at(...path);
123
158
  if (!(draw >= 0 && draw < 1)) {
124
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`positional draw must be in [0, 1); received ${draw}`);
159
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`positional draw must be in [0, 1); received ${draw}`);
125
160
  }
126
161
  return draw;
127
162
  }
@@ -129,27 +164,27 @@ function drawsFrom(rng, ...prefix) {
129
164
  const at2 = (...path) => drawFrom(rng, [...prefix, ...path]);
130
165
  return {
131
166
  at: at2,
132
- prob: (p, ...path) => _chunkJ772DL3Bcjs.includeAt.call(void 0, rng, p, ...prefix, ...path),
167
+ prob: (p, ...path) => _chunkCGBADIO5cjs.includeAt.call(void 0, rng, p, ...prefix, ...path),
133
168
  range: (lo, hi, ...path) => {
134
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, lo, "range lower bound");
135
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, hi, "range upper bound");
169
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, lo, "range lower bound");
170
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, hi, "range upper bound");
136
171
  if (lo > hi) {
137
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
172
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
138
173
  `range lower bound must not exceed upper bound; received ${lo} > ${hi}`
139
174
  );
140
175
  }
141
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, hi - lo, "range span", 0);
176
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, hi - lo, "range span", 0);
142
177
  return lo + Math.floor(at2(...path) * (hi - lo + 1));
143
178
  },
144
179
  float: (lo, hi, ...path) => {
145
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, lo, "float lower bound");
146
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, hi, "float upper bound");
180
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, lo, "float lower bound");
181
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, hi, "float upper bound");
147
182
  if (lo > hi) {
148
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
183
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
149
184
  `float lower bound must not exceed upper bound; received ${lo} > ${hi}`
150
185
  );
151
186
  }
152
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, hi - lo, "float span");
187
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, hi - lo, "float span");
153
188
  return lo + at2(...path) * (hi - lo);
154
189
  }
155
190
  };
@@ -378,8 +413,8 @@ function sameTs(a, b) {
378
413
  return a.numerator === b.numerator && a.denominator === b.denominator;
379
414
  }
380
415
  function fitsQuery(entry, query) {
381
- const candidate = _chunkXKSO2V5Icjs.assertRecord.call(void 0, entry, "vocabulary entry");
382
- const asked = _chunkXKSO2V5Icjs.assertRecord.call(void 0, query, "vocabulary query");
416
+ const candidate = _chunkS5BKZZGMcjs.assertRecord.call(void 0, entry, "vocabulary entry");
417
+ const asked = _chunkS5BKZZGMcjs.assertRecord.call(void 0, query, "vocabulary query");
383
418
  if (asked.genre !== void 0 && candidate.genre !== asked.genre) {
384
419
  return false;
385
420
  }
@@ -392,7 +427,7 @@ function fitsQuery(entry, query) {
392
427
  return false;
393
428
  }
394
429
  }
395
- if (asked.ts !== void 0 && candidate.ts && !sameTs(candidate.ts, _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, asked.ts, "ts")))) {
430
+ if (asked.ts !== void 0 && candidate.ts && !sameTs(candidate.ts, _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, asked.ts, "ts")))) {
396
431
  return false;
397
432
  }
398
433
  if (asked.quality !== void 0 && candidate.fitsOver && !candidate.fitsOver.includes(asked.quality)) {
@@ -407,7 +442,7 @@ function fitsQuery(entry, query) {
407
442
  return asked.difficulty === void 0 || candidate.difficulty <= asked.difficulty;
408
443
  }
409
444
  function selectVocabulary(dictionary, query) {
410
- return _chunkXKSO2V5Icjs.assertArray.call(void 0, dictionary, "dictionary").filter(
445
+ return _chunkS5BKZZGMcjs.assertArray.call(void 0, dictionary, "dictionary").filter(
411
446
  (entry) => fitsQuery(entry, query)
412
447
  );
413
448
  }
@@ -421,12 +456,12 @@ function pickVocabulary(dictionary, query, draw, ...path) {
421
456
  return candidates[sampler.range(0, candidates.length - 1, ...path)];
422
457
  }
423
458
  function mergeVocabulary(builtIn, supplied) {
424
- const library = _chunkXKSO2V5Icjs.assertArray.call(void 0, builtIn, "builtIn");
425
- const extra = supplied === void 0 || supplied === null ? [] : _chunkXKSO2V5Icjs.assertArray.call(void 0, supplied, "supplied");
459
+ const library = _chunkS5BKZZGMcjs.assertArray.call(void 0, builtIn, "builtIn");
460
+ const extra = supplied === void 0 || supplied === null ? [] : _chunkS5BKZZGMcjs.assertArray.call(void 0, supplied, "supplied");
426
461
  if (extra.length === 0) {
427
462
  return [...library];
428
463
  }
429
- const idOf = (entry, index, side) => _chunkXKSO2V5Icjs.assertRecord.call(void 0, entry, `${side}[${index}]`).id;
464
+ const idOf = (entry, index, side) => _chunkS5BKZZGMcjs.assertRecord.call(void 0, entry, `${side}[${index}]`).id;
430
465
  const byId = new Map(extra.map((entry, index) => [idOf(entry, index, "supplied"), entry]));
431
466
  const merged = library.map((entry, index) => _nullishCoalesce(byId.get(idOf(entry, index, "builtIn")), () => ( entry)));
432
467
  const replaced = new Set(library.map((entry, index) => idOf(entry, index, "builtIn")));
@@ -439,9 +474,9 @@ function mergeVocabulary(builtIn, supplied) {
439
474
  }
440
475
  function vocabularyOfKind(entries, isMaterial) {
441
476
  const out = [];
442
- const recognises = _chunkXKSO2V5Icjs.assertFunction.call(void 0, isMaterial, "isMaterial");
443
- for (const entry of _chunkXKSO2V5Icjs.assertArray.call(void 0, entries, "entries")) {
444
- if (recognises(_chunkXKSO2V5Icjs.assertRecord.call(void 0, entry, "entry").material)) {
477
+ const recognises = _chunkS5BKZZGMcjs.assertFunction.call(void 0, isMaterial, "isMaterial");
478
+ for (const entry of _chunkS5BKZZGMcjs.assertArray.call(void 0, entries, "entries")) {
479
+ if (recognises(_chunkS5BKZZGMcjs.assertRecord.call(void 0, entry, "entry").material)) {
445
480
  out.push(entry);
446
481
  }
447
482
  }
@@ -449,42 +484,42 @@ function vocabularyOfKind(entries, isMaterial) {
449
484
  }
450
485
  function assertNames(values, allowed, label) {
451
486
  if (!Array.isArray(values)) {
452
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
453
- `${label} must be an array of names; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, values)}`
487
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
488
+ `${label} must be an array of names; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, values)}`
454
489
  );
455
490
  }
456
491
  values.forEach((value, index) => {
457
- _chunkXKSO2V5Icjs.assertOneOf.call(void 0, value, allowed, `${label}[${index}]`);
492
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, value, allowed, `${label}[${index}]`);
458
493
  });
459
494
  }
460
495
  function assertVocabulary(entry, label = "vocabulary entry") {
461
496
  if (typeof entry !== "object" || entry === null) {
462
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
463
- `${label} must be a dictionary entry; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, entry)}`
497
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
498
+ `${label} must be a dictionary entry; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, entry)}`
464
499
  );
465
500
  }
466
- _chunkXKSO2V5Icjs.assertOneOf.call(void 0, entry.genre, GENRES, `${label} genre`);
467
- _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _optionalChain([entry, 'access', _2 => _2.provenance, 'optionalAccess', _3 => _3.basis]), PROVENANCE_BASES, `${label} provenance basis`);
468
- assertNames(entry.articulations, _chunkXKSO2V5Icjs.ARTICULATIONS, `${label} articulations`);
501
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, entry.genre, GENRES, `${label} genre`);
502
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _optionalChain([entry, 'access', _2 => _2.provenance, 'optionalAccess', _3 => _3.basis]), PROVENANCE_BASES, `${label} provenance basis`);
503
+ assertNames(entry.articulations, _chunkS5BKZZGMcjs.ARTICULATIONS, `${label} articulations`);
469
504
  if (entry.sections !== void 0) {
470
505
  assertNames(entry.sections, PUBLIC_SECTIONS, `${label} sections`);
471
506
  }
472
507
  if (entry.fitsOver !== void 0) {
473
- assertNames(entry.fitsOver, _chunkYPB3A3EYcjs.chordQualities.call(void 0, ), `${label} fitsOver`);
508
+ assertNames(entry.fitsOver, _chunk3R3QVKY5cjs.chordQualities.call(void 0, ), `${label} fitsOver`);
474
509
  }
475
510
  if (entry.ts !== void 0) {
476
- _chunkXKSO2V5Icjs.assertTimeSignature.call(void 0, entry.ts, `${label} ts`);
511
+ _chunkS5BKZZGMcjs.assertTimeSignature.call(void 0, entry.ts, `${label} ts`);
477
512
  }
478
- _chunkXKSO2V5Icjs.assertRange.call(void 0, entry.difficulty, 1, 5, `${label} difficulty`);
513
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, entry.difficulty, 1, 5, `${label} difficulty`);
479
514
  if (entry.tempoRange !== void 0) {
480
515
  if (!Array.isArray(entry.tempoRange) || entry.tempoRange.length !== 2) {
481
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
482
- `${label} tempoRange must be a low and a high tempo; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, entry.tempoRange)}`
516
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
517
+ `${label} tempoRange must be a low and a high tempo; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, entry.tempoRange)}`
483
518
  );
484
519
  }
485
520
  const [low, high] = entry.tempoRange;
486
- _chunkXKSO2V5Icjs.assertRange.call(void 0, low, Number.MIN_VALUE, 1e3, `${label} tempoRange low`);
487
- _chunkXKSO2V5Icjs.assertRange.call(void 0, high, low, 1e3, `${label} tempoRange high`);
521
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, low, Number.MIN_VALUE, 1e3, `${label} tempoRange low`);
522
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, high, low, 1e3, `${label} tempoRange high`);
488
523
  }
489
524
  return entry;
490
525
  }
@@ -506,15 +541,15 @@ function atLevel(table, difficulty) {
506
541
  return low + (high - low) * (level - lower);
507
542
  }
508
543
  function assertDifficulty(difficulty, label = "complexity difficulty") {
509
- return _chunkXKSO2V5Icjs.assertRange.call(void 0, difficulty, MIN_DIFFICULTY, MAX_DIFFICULTY, label);
544
+ return _chunkS5BKZZGMcjs.assertRange.call(void 0, difficulty, MIN_DIFFICULTY, MAX_DIFFICULTY, label);
510
545
  }
511
546
  function sustainsStrokes(stepBeats, bpm, difficulty) {
512
547
  if (difficulty === void 0 || bpm === void 0) {
513
548
  return true;
514
549
  }
515
550
  assertDifficulty(difficulty);
516
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, bpm, "bpm");
517
- if (_chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, stepBeats, "stepBeats") <= 0) {
551
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, bpm, "bpm");
552
+ if (_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, stepBeats, "stepBeats") <= 0) {
518
553
  return true;
519
554
  }
520
555
  const rate = 1 / (stepBeats * secondsPerBeat(bpm));
@@ -525,9 +560,9 @@ function sustainsShift(semitones, stepBeats, bpm, difficulty) {
525
560
  return true;
526
561
  }
527
562
  assertDifficulty(difficulty);
528
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, bpm, "bpm");
529
- _chunkXKSO2V5Icjs.assertFiniteSemitones.call(void 0, semitones);
530
- if (_chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, stepBeats, "stepBeats") <= 0) {
563
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, bpm, "bpm");
564
+ _chunkS5BKZZGMcjs.assertFiniteSemitones.call(void 0, semitones);
565
+ if (_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, stepBeats, "stepBeats") <= 0) {
531
566
  return true;
532
567
  }
533
568
  const seconds = stepBeats * secondsPerBeat(bpm);
@@ -539,20 +574,20 @@ var DEFAULT_SEED = 0;
539
574
  var VERSION_SEGMENT = "v";
540
575
  function resolveContext(input) {
541
576
  if (input !== null && typeof input !== "number" && input !== void 0) {
542
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, input, "ctx");
577
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, input, "ctx");
543
578
  }
544
579
  if (input === null) {
545
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)("ctx must be a seed or a generation context; received null");
580
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("ctx must be a seed or a generation context; received null");
546
581
  }
547
582
  const ctx = typeof input === "number" ? { seed: input } : _nullishCoalesce(input, () => ( { seed: DEFAULT_SEED }));
548
- const seed = _chunkXKSO2V5Icjs.assertInteger.call(void 0, _nullishCoalesce(ctx.seed, () => ( DEFAULT_SEED)), "seed", 0, 4294967295);
583
+ const seed = _chunkS5BKZZGMcjs.assertInteger.call(void 0, _nullishCoalesce(ctx.seed, () => ( DEFAULT_SEED)), "seed", 0, 4294967295);
549
584
  const complexity = _nullishCoalesce(ctx.complexity, () => ( {}));
550
- const rhythmic = complexity.rhythmic === void 0 ? void 0 : _chunkXKSO2V5Icjs.assertRange.call(void 0, complexity.rhythmic, 0, 1, "complexity rhythmic");
551
- const harmonic = complexity.harmonic === void 0 ? void 0 : _chunkXKSO2V5Icjs.assertRange.call(void 0, complexity.harmonic, 0, 1, "complexity harmonic");
552
- const ornament2 = complexity.ornament === void 0 ? void 0 : _chunkXKSO2V5Icjs.assertRange.call(void 0, complexity.ornament, 0, 1, "complexity ornament");
585
+ const rhythmic = complexity.rhythmic === void 0 ? void 0 : _chunkS5BKZZGMcjs.assertRange.call(void 0, complexity.rhythmic, 0, 1, "complexity rhythmic");
586
+ const harmonic = complexity.harmonic === void 0 ? void 0 : _chunkS5BKZZGMcjs.assertRange.call(void 0, complexity.harmonic, 0, 1, "complexity harmonic");
587
+ const ornament2 = complexity.ornament === void 0 ? void 0 : _chunkS5BKZZGMcjs.assertRange.call(void 0, complexity.ornament, 0, 1, "complexity ornament");
553
588
  const difficulty = complexity.difficulty === void 0 ? void 0 : assertDifficulty(complexity.difficulty);
554
- const bpm = ctx.bpm === void 0 ? void 0 : _chunkXKSO2V5Icjs.assertRange.call(void 0, ctx.bpm, Number.MIN_VALUE, 1e3, "bpm");
555
- const algorithmVersion = _chunkJ772DL3Bcjs.resolveAlgorithmVersion.call(void 0, ctx.algorithmVersion);
589
+ const bpm = ctx.bpm === void 0 ? void 0 : _chunkS5BKZZGMcjs.assertRange.call(void 0, ctx.bpm, Number.MIN_VALUE, 1e3, "bpm");
590
+ const algorithmVersion = _chunkCGBADIO5cjs.resolveAlgorithmVersion.call(void 0, ctx.algorithmVersion);
556
591
  const supplied = ctx.rng;
557
592
  const instruments = ctx.instruments;
558
593
  const vocabulary = (_nullishCoalesce(ctx.vocabulary, () => ( []))).map(
@@ -568,12 +603,12 @@ function resolveContext(input) {
568
603
  algorithmVersion,
569
604
  instrument: (part) => _optionalChain([instruments, 'optionalAccess', _4 => _4[part]]),
570
605
  vocabulary,
571
- part: (name) => supplied ? drawsFrom(supplied, name, VERSION_SEGMENT, algorithmVersion) : drawsFrom(_chunkJ772DL3Bcjs.createPositionalRng.call(void 0, _chunkJ772DL3Bcjs.deriveSeed.call(void 0, seed, name, VERSION_SEGMENT, algorithmVersion)))
606
+ part: (name) => supplied ? drawsFrom(supplied, name, VERSION_SEGMENT, algorithmVersion) : drawsFrom(_chunkCGBADIO5cjs.createPositionalRng.call(void 0, _chunkCGBADIO5cjs.deriveSeed.call(void 0, seed, name, VERSION_SEGMENT, algorithmVersion)))
572
607
  };
573
608
  }
574
609
  function resolveContextWith(input, sugar) {
575
610
  const base = resolveContext(input);
576
- const supplied = sugar.ornament === void 0 ? void 0 : _chunkXKSO2V5Icjs.assertRange.call(void 0, sugar.ornament, 0, 1, "complexity ornament");
611
+ const supplied = sugar.ornament === void 0 ? void 0 : _chunkS5BKZZGMcjs.assertRange.call(void 0, sugar.ornament, 0, 1, "complexity ornament");
577
612
  const ornament2 = _nullishCoalesce(base.ornament, () => ( supplied));
578
613
  return { ...base, ornament: ornament2 };
579
614
  }
@@ -590,14 +625,14 @@ function placeAboveBass(pc, bassMidi) {
590
625
  return foldIntoBand(pc + 12 * Math.round((bassMidi - pc) / 12), bassMidi);
591
626
  }
592
627
  function placeRoot(pc, low) {
593
- return low + _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, pc - low);
628
+ return low + _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - low);
594
629
  }
595
630
  function barTiles(startBeat, endBeat, ts) {
596
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
631
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
597
632
  const tiles = [];
598
633
  for (let index = 0; ; index += 1) {
599
634
  const tileStart = startBeat + index * barBeats;
600
- if (tileStart >= endBeat - _chunkXKSO2V5Icjs.BEAT_EPS) {
635
+ if (tileStart >= endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
601
636
  break;
602
637
  }
603
638
  tiles.push({ startBeat: tileStart, endBeat: Math.min(tileStart + barBeats, endBeat) });
@@ -605,8 +640,8 @@ function barTiles(startBeat, endBeat, ts) {
605
640
  return tiles;
606
641
  }
607
642
  function midBarPulse(barStart, ts) {
608
- const pulse2 = _chunkXKSO2V5Icjs.pulseBeats.call(void 0, ts);
609
- return barStart + Math.floor((_chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts) / 2 + _chunkXKSO2V5Icjs.BEAT_EPS) / pulse2) * pulse2;
643
+ const pulse2 = _chunkS5BKZZGMcjs.pulseBeats.call(void 0, ts);
644
+ return barStart + Math.floor((_chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts) / 2 + _chunkS5BKZZGMcjs.BEAT_EPS) / pulse2) * pulse2;
610
645
  }
611
646
  function assertBassSegments(segments) {
612
647
  for (let index = 0; index < segments.length; index += 1) {
@@ -614,14 +649,14 @@ function assertBassSegments(segments) {
614
649
  if (segment === void 0) {
615
650
  continue;
616
651
  }
617
- _chunkXKSO2V5Icjs.assertRange.call(void 0, segment.startBeat, 0, Number.MAX_SAFE_INTEGER, `segments[${index}].startBeat`);
618
- _chunkXKSO2V5Icjs.assertRange.call(void 0, segment.endBeat, 0, Number.MAX_SAFE_INTEGER, `segments[${index}].endBeat`);
652
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, segment.startBeat, 0, Number.MAX_SAFE_INTEGER, `segments[${index}].startBeat`);
653
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, segment.endBeat, 0, Number.MAX_SAFE_INTEGER, `segments[${index}].endBeat`);
619
654
  if (segment.endBeat <= segment.startBeat) {
620
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`segments[${index}] must have a positive duration`);
655
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`segments[${index}] must have a positive duration`);
621
656
  }
622
657
  const previous = segments[index - 1];
623
- if (previous !== void 0 && segment.startBeat < previous.endBeat - _chunkXKSO2V5Icjs.BEAT_EPS) {
624
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
658
+ if (previous !== void 0 && segment.startBeat < previous.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
659
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
625
660
  `bass segments must not overlap: segments ${index - 1} and ${index} overlap`
626
661
  );
627
662
  }
@@ -631,22 +666,22 @@ function chordTonePcs(chord) {
631
666
  const seen = /* @__PURE__ */ new Set();
632
667
  const pcs = [];
633
668
  for (const interval of chord.intervals) {
634
- const pc = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc + interval);
669
+ const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
635
670
  if (!seen.has(pc)) {
636
671
  seen.add(pc);
637
672
  pcs.push(pc);
638
673
  }
639
674
  }
640
675
  if (pcs.length === 0) {
641
- pcs.push(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc));
676
+ pcs.push(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc));
642
677
  }
643
678
  return pcs;
644
679
  }
645
680
  function fifthPcOf2(chord) {
646
- return _nullishCoalesce(_chunkYPB3A3EYcjs.fifthPcOf.call(void 0, chord), () => ( _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc)));
681
+ return _nullishCoalesce(_chunk3R3QVKY5cjs.fifthPcOf.call(void 0, chord), () => ( _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc)));
647
682
  }
648
683
  function bassPcOf(chord) {
649
- return _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, _nullishCoalesce(chord.bassPc, () => ( chord.rootPc)));
684
+ return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _nullishCoalesce(chord.bassPc, () => ( chord.rootPc)));
650
685
  }
651
686
  function bassToneCycle(chord) {
652
687
  const bass = bassPcOf(chord);
@@ -656,19 +691,19 @@ function bassToneCycle(chord) {
656
691
  }
657
692
  function beatPositions(start, end, ts) {
658
693
  const positions = [];
659
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
660
- const pulse2 = _chunkXKSO2V5Icjs.pulseBeats.call(void 0, ts);
694
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
695
+ const pulse2 = _chunkS5BKZZGMcjs.pulseBeats.call(void 0, ts);
661
696
  const firstBar = Math.floor(start / barBeats);
662
- const lastBar = Math.floor((end - _chunkXKSO2V5Icjs.BEAT_EPS) / barBeats);
697
+ const lastBar = Math.floor((end - _chunkS5BKZZGMcjs.BEAT_EPS) / barBeats);
663
698
  for (let bar2 = firstBar; bar2 <= lastBar; bar2 += 1) {
664
699
  const barStart = bar2 * barBeats;
665
- const firstPulse = Math.max(0, Math.ceil((start - barStart - _chunkXKSO2V5Icjs.BEAT_EPS) / pulse2));
700
+ const firstPulse = Math.max(0, Math.ceil((start - barStart - _chunkS5BKZZGMcjs.BEAT_EPS) / pulse2));
666
701
  for (let index = firstPulse; ; index += 1) {
667
702
  const position = barStart + index * pulse2;
668
- if (position >= barStart + barBeats - _chunkXKSO2V5Icjs.BEAT_EPS || position >= end - _chunkXKSO2V5Icjs.BEAT_EPS) {
703
+ if (position >= barStart + barBeats - _chunkS5BKZZGMcjs.BEAT_EPS || position >= end - _chunkS5BKZZGMcjs.BEAT_EPS) {
669
704
  break;
670
705
  }
671
- if (position >= start - _chunkXKSO2V5Icjs.BEAT_EPS) {
706
+ if (position >= start - _chunkS5BKZZGMcjs.BEAT_EPS) {
672
707
  positions.push(position);
673
708
  }
674
709
  }
@@ -686,7 +721,7 @@ function bandFloor(low, instrument) {
686
721
  if (!instrument) {
687
722
  return low;
688
723
  }
689
- const range = _chunkJ772DL3Bcjs.instrumentRange.call(void 0, instrument);
724
+ const range = _chunkCGBADIO5cjs.instrumentRange.call(void 0, instrument);
690
725
  const dropped = low - 12 * Math.max(0, Math.ceil((low + 12 - range.high) / 12));
691
726
  return dropped + 12 * Math.max(0, Math.ceil((range.low - dropped) / 12));
692
727
  }
@@ -705,12 +740,12 @@ function neighborOnSide(target, dir, key, chromatic) {
705
740
  if (chromatic) {
706
741
  return semitone;
707
742
  }
708
- const cand = _chunkYPB3A3EYcjs.nearestScaleTone.call(void 0, target + dir * 2, key);
743
+ const cand = _chunk3R3QVKY5cjs.nearestScaleTone.call(void 0, target + dir * 2, key);
709
744
  const step = Math.abs(cand - target);
710
745
  return step >= 1 && step <= 2 ? cand : semitone;
711
746
  }
712
747
  function bassRegister(named, given, octave) {
713
- const instrument = given === void 0 ? named !== void 0 && named.kind === "stringed" ? named : void 0 : _chunkJ772DL3Bcjs.toStringedProfile.call(void 0, given, "instrument");
748
+ const instrument = given === void 0 ? named !== void 0 && named.kind === "stringed" ? named : void 0 : _chunkCGBADIO5cjs.toStringedProfile.call(void 0, given, "instrument");
714
749
  return { instrument, low: bandFloor(octave * 12 + 12, instrument) };
715
750
  }
716
751
 
@@ -719,31 +754,31 @@ var BAR_STEPS = 16;
719
754
  var BEAT_STEPS = 4;
720
755
  var STEP_BEATS = 1 / BEAT_STEPS;
721
756
  function assertGridEvents(events) {
722
- _chunkXKSO2V5Icjs.assertArray.call(void 0, events, "figure events");
757
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, events, "figure events");
723
758
  events.forEach((event, index) => {
724
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, event, `figure events[${index}]`);
725
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, event.step, `figure events[${index}].step`);
759
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, event, `figure events[${index}]`);
760
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, event.step, `figure events[${index}].step`);
726
761
  });
727
762
  return events;
728
763
  }
729
764
  function assertSpanSteps(spanSteps) {
730
- return _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, spanSteps, "figure span steps");
765
+ return _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, spanSteps, "figure span steps");
731
766
  }
732
767
  function streamOf(event) {
733
768
  return _nullishCoalesce(_nullishCoalesce(event.limb, () => ( event.voice)), () => ( ""));
734
769
  }
735
770
  var FIGURE_TS = { numerator: 4, denominator: 4 };
736
771
  function subdivisionBeats(ts) {
737
- const pulse2 = _chunkXKSO2V5Icjs.pulseBeats.call(void 0, ts);
738
- return _chunkXKSO2V5Icjs.isCompound.call(void 0, ts) ? pulse2 / 3 : pulse2 / 2;
772
+ const pulse2 = _chunkS5BKZZGMcjs.pulseBeats.call(void 0, ts);
773
+ return _chunkS5BKZZGMcjs.isCompound.call(void 0, ts) ? pulse2 / 3 : pulse2 / 2;
739
774
  }
740
775
  function gridMetricWeight(step, ts) {
741
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, step, "step");
742
- return stepWeight(step, _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts")));
776
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, step, "step");
777
+ return stepWeight(step, _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts")));
743
778
  }
744
779
  function stepWeight(step, ts) {
745
780
  const beats = step * STEP_BEATS;
746
- const weight = _chunkXKSO2V5Icjs.metricWeight.call(void 0, beats, ts);
781
+ const weight = _chunkS5BKZZGMcjs.metricWeight.call(void 0, beats, ts);
747
782
  if (weight > 0) {
748
783
  return weight + 1;
749
784
  }
@@ -753,8 +788,8 @@ function stepWeight(step, ts) {
753
788
  }
754
789
  function thin(events, amount, ts) {
755
790
  const figure = assertGridEvents(events);
756
- _chunkXKSO2V5Icjs.assertRange.call(void 0, amount, 0, 1, "thin amount");
757
- const signature = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts"));
791
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, amount, 0, 1, "thin amount");
792
+ const signature = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts"));
758
793
  const floor = Math.min(4, Math.floor(amount * 5));
759
794
  return figure.filter((event) => stepWeight(event.step, signature) >= floor);
760
795
  }
@@ -806,10 +841,10 @@ function syncopate(events, amount, draw, ...path) {
806
841
  const figure = assertGridEvents(events);
807
842
  const sampler = assertDraw(draw);
808
843
  assertSeedPath(path);
809
- const asked = typeof amount === "number" ? void 0 : _chunkXKSO2V5Icjs.assertRecord.call(void 0, amount, "amount");
844
+ const asked = typeof amount === "number" ? void 0 : _chunkS5BKZZGMcjs.assertRecord.call(void 0, amount, "amount");
810
845
  const dial = asked === void 0 ? amount : asked.amount;
811
- const signature = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(_optionalChain([asked, 'optionalAccess', _7 => _7.ts]), () => ( FIGURE_TS)), "ts"));
812
- _chunkXKSO2V5Icjs.assertRange.call(void 0, dial, 0, 1, "syncopate amount");
846
+ const signature = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(_optionalChain([asked, 'optionalAccess', _7 => _7.ts]), () => ( FIGURE_TS)), "ts"));
847
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, dial, 0, 1, "syncopate amount");
813
848
  const occupied = new Set(figure.map((event) => `${streamOf(event)}@${event.step}`));
814
849
  const out = [...figure];
815
850
  for (const event of figure) {
@@ -826,10 +861,10 @@ function syncopate(events, amount, draw, ...path) {
826
861
  }
827
862
  function ornamentBy(events, isOrnament, amount, draw, ...path) {
828
863
  const figure = assertGridEvents(events);
829
- const marks = _chunkXKSO2V5Icjs.assertFunction.call(void 0, isOrnament, "isOrnament");
864
+ const marks = _chunkS5BKZZGMcjs.assertFunction.call(void 0, isOrnament, "isOrnament");
830
865
  const sampler = assertDraw(draw);
831
866
  assertSeedPath(path);
832
- _chunkXKSO2V5Icjs.assertRange.call(void 0, amount, 0, 1, "ornament amount");
867
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, amount, 0, 1, "ornament amount");
833
868
  return figure.filter(
834
869
  (event) => !marks(event) || sampler.prob(amount, ...path, "ornament", event.step)
835
870
  );
@@ -837,14 +872,14 @@ function ornamentBy(events, isOrnament, amount, draw, ...path) {
837
872
  var NEUTRAL_RHYTHMIC = 0.5;
838
873
  function deform(events, opts, draw, ...path) {
839
874
  const figure = assertGridEvents(events);
840
- const asked = _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "opts");
875
+ const asked = _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "opts");
841
876
  assertDraw(draw);
842
877
  assertSeedPath(path);
843
878
  const spanSteps = assertSpanSteps(asked.spanSteps === void 0 ? BAR_STEPS : asked.spanSteps);
844
879
  const ts = _nullishCoalesce(asked.ts, () => ( FIGURE_TS));
845
880
  let out = asked.rate === "half" ? halfTime(figure, spanSteps) : asked.rate === "double" ? doubleTime(figure, spanSteps) : [...figure];
846
881
  if (asked.rhythmic !== void 0) {
847
- const rhythmic = _chunkXKSO2V5Icjs.assertRange.call(void 0, asked.rhythmic, 0, 1, "complexity rhythmic");
882
+ const rhythmic = _chunkS5BKZZGMcjs.assertRange.call(void 0, asked.rhythmic, 0, 1, "complexity rhythmic");
848
883
  if (rhythmic < NEUTRAL_RHYTHMIC) {
849
884
  out = thin(out, (NEUTRAL_RHYTHMIC - rhythmic) / NEUTRAL_RHYTHMIC, ts);
850
885
  } else if (rhythmic > NEUTRAL_RHYTHMIC) {
@@ -857,7 +892,7 @@ function deform(events, opts, draw, ...path) {
857
892
  }
858
893
  }
859
894
  if (asked.ornament !== void 0 && asked.isOrnament) {
860
- const isOrnament = _chunkXKSO2V5Icjs.assertFunction.call(void 0, asked.isOrnament, "opts.isOrnament");
895
+ const isOrnament = _chunkS5BKZZGMcjs.assertFunction.call(void 0, asked.isOrnament, "opts.isOrnament");
861
896
  out = ornamentBy(out, (event) => isOrnament(event), asked.ornament, draw, ...path);
862
897
  }
863
898
  return out.sort((a, b) => a.step - b.step);
@@ -867,7 +902,7 @@ function withinCeiling(events, bpm, difficulty) {
867
902
  if (difficulty === void 0 || bpm === void 0) {
868
903
  return true;
869
904
  }
870
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, bpm, "bpm");
905
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, bpm, "bpm");
871
906
  assertDifficulty(difficulty);
872
907
  if (figure.length < 2) {
873
908
  return true;
@@ -905,8 +940,8 @@ function impliedScaleTones(chord) {
905
940
  if (chordDegreeSemitone(7, chord) === void 0) {
906
941
  return void 0;
907
942
  }
908
- for (const match of _chunkR7B5N2JKcjs.chordScales.call(void 0, chord)) {
909
- const mask = _chunkYPB3A3EYcjs.namedScaleMask.call(void 0, match.name);
943
+ for (const match of _chunkPM4XJE2Ycjs.chordScales.call(void 0, chord)) {
944
+ const mask = _chunk3R3QVKY5cjs.namedScaleMask.call(void 0, match.name);
910
945
  if (mask === void 0) {
911
946
  continue;
912
947
  }
@@ -926,7 +961,7 @@ function replacedDegreeSemitone(degree, chord) {
926
961
  if (degree !== 3) {
927
962
  return void 0;
928
963
  }
929
- const sounds = (semitones) => chord.intervals.some((interval) => _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, interval) === semitones);
964
+ const sounds = (semitones) => chord.intervals.some((interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval) === semitones);
930
965
  if (sounds(3) || sounds(4)) {
931
966
  return void 0;
932
967
  }
@@ -938,12 +973,12 @@ function degreeSemitone(degree, alter, chord, key, implied) {
938
973
  const template = _nullishCoalesce(MAJOR_DEGREE_SEMITONES[within - 1], () => ( 0));
939
974
  const semitone = alter !== 0 ? template : _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(chordDegreeSemitone(within, chord), () => ( replacedDegreeSemitone(within, chord))), () => ( _optionalChain([implied, 'optionalAccess', _8 => _8[within - 1]]))), () => ( // A degree neither the chord nor its quality settles is a passing tone,
940
975
  // so the key decides it.
941
- _chunkYPB3A3EYcjs.nearestScaleTone.call(void 0, chord.rootPc + template, key) - chord.rootPc));
942
- return _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, semitone) + 12 * octaves + alter;
976
+ _chunk3R3QVKY5cjs.nearestScaleTone.call(void 0, chord.rootPc + template, key) - chord.rootPc));
977
+ return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, semitone) + 12 * octaves + alter;
943
978
  }
944
979
  function chordDegreeSemitone(degree, chord) {
945
980
  for (const interval of chord.intervals) {
946
- if (_chunkYPB3A3EYcjs.degreeOfInterval.call(void 0, interval, chord) === degree) {
981
+ if (_chunk3R3QVKY5cjs.degreeOfInterval.call(void 0, interval, chord) === degree) {
947
982
  return interval;
948
983
  }
949
984
  }
@@ -1173,28 +1208,28 @@ var BASS_LICKS = deepFreeze([
1173
1208
  var DEFAULT_BPM = 120;
1174
1209
  var DEFAULT_LICK_DENSITY = 0.6;
1175
1210
  function placeLicks(timeline, key, opts) {
1176
- const asked = _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "opts");
1177
- const placement = _chunkXKSO2V5Icjs.assertArray.call(void 0,
1211
+ const asked = _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "opts");
1212
+ const placement = _chunkS5BKZZGMcjs.assertArray.call(void 0,
1178
1213
  timeline,
1179
1214
  "timeline"
1180
1215
  );
1181
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, placement.length, "lick segments", asked.budget);
1182
- const genre = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, asked.genre, GENRES, "lick genre");
1183
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(asked.ts, () => ( DEFAULT_TS)), "ts"));
1216
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, placement.length, "lick segments", asked.budget);
1217
+ const genre = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, asked.genre, GENRES, "lick genre");
1218
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(asked.ts, () => ( DEFAULT_TS)), "ts"));
1184
1219
  const octave = _nullishCoalesce(asked.octave, () => ( DEFAULT_OCTAVE));
1185
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, octave, "lick octave", -1, 8);
1186
- const scale = _chunkYPB3A3EYcjs.toKeyScale.call(void 0, key);
1187
- const segments = placement.map((segment) => ({ ...segment, chord: _chunkYPB3A3EYcjs.toChordData.call(void 0, segment.chord) })).sort((a, b) => a.startBeat - b.startBeat);
1220
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, octave, "lick octave", -1, 8);
1221
+ const scale = _chunk3R3QVKY5cjs.toKeyScale.call(void 0, key);
1222
+ const segments = placement.map((segment) => ({ ...segment, chord: _chunk3R3QVKY5cjs.toChordData.call(void 0, segment.chord) })).sort((a, b) => a.startBeat - b.startBeat);
1188
1223
  assertBassSegments(segments);
1189
1224
  if (segments.length === 0) {
1190
1225
  return [];
1191
1226
  }
1192
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
1227
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
1193
1228
  const estimatedBars = segments.reduce(
1194
1229
  (count, segment) => count + Math.max(1, Math.ceil((segment.endBeat - segment.startBeat) / barBeats)),
1195
1230
  0
1196
1231
  );
1197
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, estimatedBars, "lick bars", asked.budget);
1232
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, estimatedBars, "lick bars", asked.budget);
1198
1233
  const resolved = resolveContext(asked.ctx);
1199
1234
  const draw = resolved.part("bass");
1200
1235
  const bpm = _nullishCoalesce(resolved.bpm, () => ( DEFAULT_BPM));
@@ -1254,7 +1289,7 @@ function placeLicks(timeline, key, opts) {
1254
1289
  }
1255
1290
  raw.push({ startBeat: rootAt, pitch: rootMidi, velocity: STRONG_VELOCITY });
1256
1291
  if (notes) {
1257
- const figureRoot = segment.chord.bassPc === void 0 ? placePc(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, segment.chord.rootPc), rootMidi, low) : placeAboveBass(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, segment.chord.rootPc), rootMidi);
1292
+ const figureRoot = segment.chord.bassPc === void 0 ? placePc(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, segment.chord.rootPc), rootMidi, low) : placeAboveBass(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, segment.chord.rootPc), rootMidi);
1258
1293
  for (const lickNote of notes) {
1259
1294
  const at2 = tileStart + lickNote.step * STEP_BEATS;
1260
1295
  const offset = degreeSemitone(
@@ -1264,12 +1299,12 @@ function placeLicks(timeline, key, opts) {
1264
1299
  scale,
1265
1300
  implied
1266
1301
  );
1267
- const pitch = Math.abs(at2 - rootAt) < _chunkXKSO2V5Icjs.BEAT_EPS && lickNote.degree === 1 && (_nullishCoalesce(lickNote.alter, () => ( 0))) === 0 ? rootMidi : figureRoot + offset;
1302
+ const pitch = Math.abs(at2 - rootAt) < _chunkS5BKZZGMcjs.BEAT_EPS && lickNote.degree === 1 && (_nullishCoalesce(lickNote.alter, () => ( 0))) === 0 ? rootMidi : figureRoot + offset;
1268
1303
  raw.push({
1269
1304
  startBeat: at2,
1270
1305
  pitch,
1271
1306
  velocity: Math.round(
1272
- (_chunkXKSO2V5Icjs.isStrongBeat.call(void 0, at2, ts) ? STRONG_VELOCITY : WEAK_VELOCITY) * lickNote.velocity
1307
+ (_chunkS5BKZZGMcjs.isStrongBeat.call(void 0, at2, ts) ? STRONG_VELOCITY : WEAK_VELOCITY) * lickNote.velocity
1273
1308
  ),
1274
1309
  note: lickNote
1275
1310
  });
@@ -1280,7 +1315,7 @@ function placeLicks(timeline, key, opts) {
1280
1315
  if (next && lastTilePlayed) {
1281
1316
  const lastBeat = next.startBeat - STEP_BEATS * BEAT_STEPS;
1282
1317
  const approachAt = _nullishCoalesce(materialOnsetIn(playedTile, lastBeat, next.startBeat), () => ( lastBeat));
1283
- if (approachAt > firstOnset + _chunkXKSO2V5Icjs.BEAT_EPS) {
1318
+ if (approachAt > firstOnset + _chunkS5BKZZGMcjs.BEAT_EPS) {
1284
1319
  const nextRoot = placeRoot(bassPcOf(next.chord), low);
1285
1320
  const occupied = soundingAt(raw, approachAt);
1286
1321
  const distance = occupied === void 0 ? 0 : Math.abs(occupied.pitch - nextRoot);
@@ -1310,12 +1345,12 @@ function placeLicks(timeline, key, opts) {
1310
1345
  nextStart - item.startBeat,
1311
1346
  written === void 0 ? Number.POSITIVE_INFINITY : written * STEP_BEATS
1312
1347
  );
1313
- if (durationBeat <= _chunkXKSO2V5Icjs.BEAT_EPS) {
1348
+ if (durationBeat <= _chunkS5BKZZGMcjs.BEAT_EPS) {
1314
1349
  continue;
1315
1350
  }
1316
- const placed = instrument ? _chunkJ772DL3Bcjs.foldIntoRange.call(void 0, item.pitch, instrument) : item.pitch;
1351
+ const placed = instrument ? _chunkCGBADIO5cjs.foldIntoRange.call(void 0, item.pitch, instrument) : item.pitch;
1317
1352
  const event = {
1318
- pitch: _chunkXKSO2V5Icjs.clampToMidi.call(void 0, placed, "generated bass pitch"),
1353
+ pitch: _chunkS5BKZZGMcjs.clampToMidi.call(void 0, placed, "generated bass pitch"),
1319
1354
  startBeat: item.startBeat,
1320
1355
  durationBeat,
1321
1356
  velocity: Math.max(1, Math.min(127, item.velocity))
@@ -1330,7 +1365,7 @@ function placeLicks(timeline, key, opts) {
1330
1365
  function soundingAt(raw, at2) {
1331
1366
  for (let index = raw.length - 1; index >= 0; index -= 1) {
1332
1367
  const item = raw[index];
1333
- if (item !== void 0 && Math.abs(item.startBeat - at2) < _chunkXKSO2V5Icjs.BEAT_EPS) {
1368
+ if (item !== void 0 && Math.abs(item.startBeat - at2) < _chunkS5BKZZGMcjs.BEAT_EPS) {
1334
1369
  return item;
1335
1370
  }
1336
1371
  }
@@ -1343,7 +1378,7 @@ function materialOnsetIn(played, from, to) {
1343
1378
  let last;
1344
1379
  for (const note2 of played.material.notes) {
1345
1380
  const at2 = played.tileStart + note2.step * STEP_BEATS;
1346
- if (at2 < from - _chunkXKSO2V5Icjs.BEAT_EPS || at2 > to - _chunkXKSO2V5Icjs.BEAT_EPS) {
1381
+ if (at2 < from - _chunkS5BKZZGMcjs.BEAT_EPS || at2 > to - _chunkS5BKZZGMcjs.BEAT_EPS) {
1347
1382
  continue;
1348
1383
  }
1349
1384
  last = last === void 0 ? at2 : Math.max(last, at2);
@@ -1353,7 +1388,7 @@ function materialOnsetIn(played, from, to) {
1353
1388
  function lastPitchBefore(raw, at2, fallback) {
1354
1389
  for (let index = raw.length - 1; index >= 0; index -= 1) {
1355
1390
  const item = raw[index];
1356
- if (item !== void 0 && item.startBeat < at2 - _chunkXKSO2V5Icjs.BEAT_EPS) {
1391
+ if (item !== void 0 && item.startBeat < at2 - _chunkS5BKZZGMcjs.BEAT_EPS) {
1357
1392
  return item.pitch;
1358
1393
  }
1359
1394
  }
@@ -1366,7 +1401,7 @@ function anchorStepOf(material, spanBeats) {
1366
1401
  first = note2.step;
1367
1402
  }
1368
1403
  }
1369
- if (first === void 0 || first < 0 || first * STEP_BEATS >= spanBeats - _chunkXKSO2V5Icjs.BEAT_EPS) {
1404
+ if (first === void 0 || first < 0 || first * STEP_BEATS >= spanBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
1370
1405
  return 0;
1371
1406
  }
1372
1407
  return first;
@@ -1393,7 +1428,7 @@ function fitToSegment(material, spanBeats, density, resolved, draw, path, bpm, d
1393
1428
  ...path
1394
1429
  );
1395
1430
  const spanSteps = spanBeats / STEP_BEATS;
1396
- const inside = deformed.filter((lickNote) => lickNote.step < spanSteps - _chunkXKSO2V5Icjs.BEAT_EPS);
1431
+ const inside = deformed.filter((lickNote) => lickNote.step < spanSteps - _chunkS5BKZZGMcjs.BEAT_EPS);
1397
1432
  if (inside.length === 0 || !withinCeiling(inside, bpm, difficulty)) {
1398
1433
  return void 0;
1399
1434
  }
@@ -1411,15 +1446,15 @@ var BASS_STYLES = Object.freeze([
1411
1446
  var DEFAULT_STYLE = "root";
1412
1447
  var DEFAULT_PICKUP_DENSITY = 0.35;
1413
1448
  function sounding(ctx, placed) {
1414
- return ctx.instrument ? _chunkJ772DL3Bcjs.foldIntoRange.call(void 0, placed, ctx.instrument) : placed;
1449
+ return ctx.instrument ? _chunkCGBADIO5cjs.foldIntoRange.call(void 0, placed, ctx.instrument) : placed;
1415
1450
  }
1416
1451
  function placeTone(ctx, pc) {
1417
1452
  return ctx.overBass ? placeAboveBass(pc, ctx.rootMidi) : placePc(pc, ctx.rootMidi, ctx.low);
1418
1453
  }
1419
1454
  function emit(ctx, pos, pc, midiOverride) {
1420
- const placed = _chunkXKSO2V5Icjs.clampToMidi.call(void 0, _nullishCoalesce(midiOverride, () => ( placeTone(ctx, pc))), "generated bass pitch");
1455
+ const placed = _chunkS5BKZZGMcjs.clampToMidi.call(void 0, _nullishCoalesce(midiOverride, () => ( placeTone(ctx, pc))), "generated bass pitch");
1421
1456
  const midi = sounding(ctx, placed);
1422
- const velocity = _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, pos, ctx.ts) ? STRONG_VELOCITY : WEAK_VELOCITY;
1457
+ const velocity = _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, pos, ctx.ts) ? STRONG_VELOCITY : WEAK_VELOCITY;
1423
1458
  ctx.notes.push({ startBeat: pos, pitch: midi, velocity });
1424
1459
  ctx.prevMidi = midi;
1425
1460
  return midi;
@@ -1431,7 +1466,7 @@ function buildRootFifth(ctx, seg) {
1431
1466
  for (const tile of barTiles(seg.startBeat, seg.endBeat, ctx.ts)) {
1432
1467
  emit(ctx, tile.startBeat, bassPcOf(seg.chord));
1433
1468
  const answer = midBarPulse(tile.startBeat, ctx.ts);
1434
- if (answer > tile.startBeat + _chunkXKSO2V5Icjs.BEAT_EPS && answer < tile.endBeat - _chunkXKSO2V5Icjs.BEAT_EPS) {
1469
+ if (answer > tile.startBeat + _chunkS5BKZZGMcjs.BEAT_EPS && answer < tile.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
1435
1470
  emit(ctx, answer, fifthPcOf2(seg.chord));
1436
1471
  }
1437
1472
  }
@@ -1441,7 +1476,7 @@ function buildPop(ctx, seg, index) {
1441
1476
  const rootPc = bassPcOf(seg.chord);
1442
1477
  let emitted = false;
1443
1478
  for (const pos of positions) {
1444
- if (_chunkXKSO2V5Icjs.isStrongBeat.call(void 0, pos, ctx.ts)) {
1479
+ if (_chunkS5BKZZGMcjs.isStrongBeat.call(void 0, pos, ctx.ts)) {
1445
1480
  emit(ctx, pos, rootPc);
1446
1481
  emitted = true;
1447
1482
  } else if (ctx.draw.prob(ctx.pickupDensity, "pickup", index, pos)) {
@@ -1502,7 +1537,7 @@ function buildWalking(ctx, seg, next, index) {
1502
1537
  if (next && count > 1 && i === count - 1) {
1503
1538
  const nextBass = placeRoot(bassPcOf(next.chord), ctx.low);
1504
1539
  const midi = approachNote2(ctx, nextBass, ctx.prevMidi, index);
1505
- emit(ctx, pos, _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, midi), midi);
1540
+ emit(ctx, pos, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, midi), midi);
1506
1541
  return;
1507
1542
  }
1508
1543
  const pc = _nullishCoalesce(tones[i % tones.length], () => ( bassPcOf(seg.chord)));
@@ -1510,29 +1545,29 @@ function buildWalking(ctx, seg, next, index) {
1510
1545
  });
1511
1546
  }
1512
1547
  function generateBassLine(opts) {
1513
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "bass line options");
1514
- _chunkXKSO2V5Icjs.assertArray.call(void 0, opts.segments, "bass segments");
1515
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, opts.segments.length, "bass segments", opts.budget);
1516
- const segments = opts.segments.map((segment) => ({ ...segment, chord: _chunkYPB3A3EYcjs.toChordData.call(void 0, segment.chord) })).sort((a, b) => a.startBeat - b.startBeat);
1548
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "bass line options");
1549
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, opts.segments, "bass segments");
1550
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, opts.segments.length, "bass segments", opts.budget);
1551
+ const segments = opts.segments.map((segment) => ({ ...segment, chord: _chunk3R3QVKY5cjs.toChordData.call(void 0, segment.chord) })).sort((a, b) => a.startBeat - b.startBeat);
1517
1552
  assertBassSegments(segments);
1518
1553
  if (segments.length === 0) {
1519
1554
  return [];
1520
1555
  }
1521
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS)), "ts"));
1522
- const style = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(opts.style, () => ( DEFAULT_STYLE)), BASS_STYLES, "bass style");
1556
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS)), "ts"));
1557
+ const style = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(opts.style, () => ( DEFAULT_STYLE)), BASS_STYLES, "bass style");
1523
1558
  const octave = _nullishCoalesce(opts.octave, () => ( DEFAULT_OCTAVE));
1524
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, octave, "bass octave", -1, 8);
1559
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, octave, "bass octave", -1, 8);
1525
1560
  const estimatedNotes = segments.reduce(
1526
1561
  (count, segment) => count + Math.max(1, Math.ceil(segment.endBeat - segment.startBeat)),
1527
1562
  0
1528
1563
  );
1529
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, estimatedNotes, "bass notes", opts.budget);
1564
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, estimatedNotes, "bass notes", opts.budget);
1530
1565
  const resolved = resolveContext(opts.ctx);
1531
1566
  const { instrument, low } = bassRegister(resolved.instrument("bass"), opts.instrument, octave);
1532
1567
  const ctx = {
1533
1568
  ts,
1534
1569
  low,
1535
- key: _chunkYPB3A3EYcjs.toKeyScale.call(void 0, opts.key),
1570
+ key: _chunk3R3QVKY5cjs.toKeyScale.call(void 0, opts.key),
1536
1571
  draw: resolved.part("bass"),
1537
1572
  notes: [],
1538
1573
  rootMidi: low,
@@ -1578,11 +1613,11 @@ function generateBassLine(opts) {
1578
1613
  }
1579
1614
  const nextStart = _nullishCoalesce(_optionalChain([ctx, 'access', _17 => _17.notes, 'access', _18 => _18[i + 1], 'optionalAccess', _19 => _19.startBeat]), () => ( lastEnd));
1580
1615
  const durationBeat = nextStart - note2.startBeat;
1581
- if (durationBeat <= _chunkXKSO2V5Icjs.BEAT_EPS) {
1616
+ if (durationBeat <= _chunkS5BKZZGMcjs.BEAT_EPS) {
1582
1617
  continue;
1583
1618
  }
1584
1619
  out.push({
1585
- pitch: _chunkXKSO2V5Icjs.clampToMidi.call(void 0, note2.pitch, "generated bass pitch"),
1620
+ pitch: _chunkS5BKZZGMcjs.clampToMidi.call(void 0, note2.pitch, "generated bass pitch"),
1586
1621
  startBeat: note2.startBeat,
1587
1622
  durationBeat,
1588
1623
  velocity: note2.velocity
@@ -1599,31 +1634,31 @@ function degreesOf(interval) {
1599
1634
  }
1600
1635
  function assertPlayable(pitch) {
1601
1636
  if (pitch < 0 || pitch > 127) {
1602
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`imitated pitch ${pitch} is outside the MIDI range 0..127`);
1637
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`imitated pitch ${pitch} is outside the MIDI range 0..127`);
1603
1638
  }
1604
1639
  return pitch;
1605
1640
  }
1606
1641
  function imitate(lead, opts) {
1607
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, lead, "imitate lead", { allowNonPositiveDuration: true });
1608
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "opts");
1609
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, opts.atBeat, "atBeat");
1610
- const interval = _chunkXKSO2V5Icjs.toSpelledInterval.call(void 0, opts.interval);
1611
- const key = _chunkYPB3A3EYcjs.toKeyScale.call(void 0, opts.key);
1642
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, lead, "imitate lead", { allowNonPositiveDuration: true });
1643
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "opts");
1644
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, opts.atBeat, "atBeat");
1645
+ const interval = _chunkS5BKZZGMcjs.toSpelledInterval.call(void 0, opts.interval);
1646
+ const key = _chunk3R3QVKY5cjs.toKeyScale.call(void 0, opts.key);
1612
1647
  const from = _nullishCoalesce(opts.from, () => ( Number.NEGATIVE_INFINITY));
1613
1648
  const to = _nullishCoalesce(opts.to, () => ( Number.POSITIVE_INFINITY));
1614
1649
  if (opts.from !== void 0) {
1615
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, opts.from, "from");
1650
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, opts.from, "from");
1616
1651
  }
1617
1652
  if (opts.to !== void 0) {
1618
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, opts.to, "to");
1653
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, opts.to, "to");
1619
1654
  }
1620
1655
  if (from > to) {
1621
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`imitate needs from <= to; received ${from} > ${to}`);
1656
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`imitate needs from <= to; received ${from} > ${to}`);
1622
1657
  }
1623
1658
  const velocityScale = _nullishCoalesce(opts.velocityScale, () => ( 1));
1624
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, velocityScale, "velocityScale");
1625
- const tonal = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(opts.answer, () => ( "real")), IMITATION_ANSWERS, "imitate answer") === "tonal";
1626
- const subject = _chunkXKSO2V5Icjs.dropSilentNotes.call(void 0, lead).filter((note2) => note2.startBeat >= from && note2.startBeat < to).sort((a, b) => a.startBeat - b.startBeat);
1659
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, velocityScale, "velocityScale");
1660
+ const tonal = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(opts.answer, () => ( "real")), IMITATION_ANSWERS, "imitate answer") === "tonal";
1661
+ const subject = _chunkS5BKZZGMcjs.dropSilentNotes.call(void 0, lead).filter((note2) => note2.startBeat >= from && note2.startBeat < to).sort((a, b) => a.startBeat - b.startBeat);
1627
1662
  const origin = _optionalChain([subject, 'access', _20 => _20[0], 'optionalAccess', _21 => _21.startBeat]);
1628
1663
  const pivot = _optionalChain([subject, 'access', _22 => _22[0], 'optionalAccess', _23 => _23.pitch]);
1629
1664
  if (origin === void 0 || pivot === void 0) {
@@ -1637,14 +1672,14 @@ function imitate(lead, opts) {
1637
1672
  let offset = 0;
1638
1673
  if (invert) {
1639
1674
  if (tonal) {
1640
- const here = _chunkYPB3A3EYcjs.scaleLadderPosition.call(void 0, pitch, key);
1641
- pitch = _chunkYPB3A3EYcjs.scaleLadderPitch.call(void 0, 2 * _chunkYPB3A3EYcjs.scaleLadderPosition.call(void 0, pivot, key).rung - here.rung, key);
1675
+ const here = _chunk3R3QVKY5cjs.scaleLadderPosition.call(void 0, pitch, key);
1676
+ pitch = _chunk3R3QVKY5cjs.scaleLadderPitch.call(void 0, 2 * _chunk3R3QVKY5cjs.scaleLadderPosition.call(void 0, pivot, key).rung - here.rung, key);
1642
1677
  offset = -here.offset;
1643
1678
  } else {
1644
1679
  pitch = 2 * pivot - pitch;
1645
1680
  }
1646
1681
  }
1647
- pitch = tonal ? _chunkYPB3A3EYcjs.shiftByScaleDegrees.call(void 0, pitch, degrees, key) + offset : pitch + Math.round(interval.semitones);
1682
+ pitch = tonal ? _chunk3R3QVKY5cjs.shiftByScaleDegrees.call(void 0, pitch, degrees, key) + offset : pitch + Math.round(interval.semitones);
1648
1683
  const answer = {
1649
1684
  ...note2,
1650
1685
  pitch: assertPlayable(pitch),
@@ -1669,7 +1704,7 @@ var DEFAULT_MELODY_VELOCITY = 96;
1669
1704
  var VELOCITY_DROP = 16;
1670
1705
  var TIE_BREAK_JITTER = 1e-6;
1671
1706
  function isWholeBeat(beat) {
1672
- return Math.abs(beat - Math.round(beat)) < _chunkXKSO2V5Icjs.BEAT_EPS;
1707
+ return Math.abs(beat - Math.round(beat)) < _chunkS5BKZZGMcjs.BEAT_EPS;
1673
1708
  }
1674
1709
  function melodyNoteAt(melody, beat) {
1675
1710
  return _optionalChain([melody, 'access', _24 => _24.at, 'call', _25 => _25(beat), 'optionalAccess', _26 => _26.note]);
@@ -1682,8 +1717,8 @@ function melodySnapshotAt(melody, beat) {
1682
1717
  if (current === void 0) {
1683
1718
  return void 0;
1684
1719
  }
1685
- const attacked = Math.abs(current.startBeat - beat) < _chunkXKSO2V5Icjs.BEAT_EPS;
1686
- const previous = attacked ? melodyNoteAt(melody, beat - _chunkXKSO2V5Icjs.BEAT_EPS * 2) : current;
1720
+ const attacked = Math.abs(current.startBeat - beat) < _chunkS5BKZZGMcjs.BEAT_EPS;
1721
+ const previous = attacked ? melodyNoteAt(melody, beat - _chunkS5BKZZGMcjs.BEAT_EPS * 2) : current;
1687
1722
  const snapshot = { pitch: current.pitch };
1688
1723
  if (previous !== void 0) {
1689
1724
  snapshot.prevPitch = previous.pitch;
@@ -1699,7 +1734,7 @@ function complementOnsets(melody, ts, spanStart, spanEnd, draw) {
1699
1734
  const onsets = [];
1700
1735
  const gridStart = Math.floor(spanStart / GRID_STEP) * GRID_STEP;
1701
1736
  let last = Number.NEGATIVE_INFINITY;
1702
- for (let beat = gridStart; beat < spanEnd - _chunkXKSO2V5Icjs.BEAT_EPS; beat += GRID_STEP) {
1737
+ for (let beat = gridStart; beat < spanEnd - _chunkS5BKZZGMcjs.BEAT_EPS; beat += GRID_STEP) {
1703
1738
  const attacked = melodyAttacksAt(melody, beat);
1704
1739
  const sounding2 = melodyNoteAt(melody, beat) !== void 0;
1705
1740
  let place = false;
@@ -1707,10 +1742,10 @@ function complementOnsets(melody, ts, spanStart, spanEnd, draw) {
1707
1742
  place = isWholeBeat(beat);
1708
1743
  } else if (!attacked) {
1709
1744
  place = draw.prob(isWholeBeat(beat) ? HOLD_ON_BEAT_PROB : HOLD_OFF_BEAT_PROB, "hold", beat);
1710
- } else if (_chunkXKSO2V5Icjs.isStrongBeat.call(void 0, beat, ts)) {
1745
+ } else if (_chunkS5BKZZGMcjs.isStrongBeat.call(void 0, beat, ts)) {
1711
1746
  place = draw.prob(REINFORCE_PROB, "reinforce", beat);
1712
1747
  }
1713
- if (place && beat - last >= MIN_ONSET_GAP - _chunkXKSO2V5Icjs.BEAT_EPS) {
1748
+ if (place && beat - last >= MIN_ONSET_GAP - _chunkS5BKZZGMcjs.BEAT_EPS) {
1714
1749
  onsets.push(beat);
1715
1750
  last = beat;
1716
1751
  }
@@ -1731,12 +1766,12 @@ function assertWeightOverrides(overrides) {
1731
1766
  return;
1732
1767
  }
1733
1768
  if (typeof overrides !== "object" || overrides === null) {
1734
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
1735
- `countermelody weights must be an object of weight overrides; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, overrides)}`
1769
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1770
+ `countermelody weights must be an object of weight overrides; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, overrides)}`
1736
1771
  );
1737
1772
  }
1738
1773
  for (const [field, value] of Object.entries(overrides)) {
1739
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, value, `countermelody weights.${field}`);
1774
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, value, `countermelody weights.${field}`);
1740
1775
  }
1741
1776
  }
1742
1777
  function scoreCandidate(pitch, melPitch, melPrev, prevPitch, chord, center, weights) {
@@ -1751,7 +1786,7 @@ function scoreCandidate(pitch, melPitch, melPrev, prevPitch, chord, center, weig
1751
1786
  score += weights.dissonance;
1752
1787
  }
1753
1788
  }
1754
- if (chord && _chunkYPB3A3EYcjs.chordToneRole.call(void 0, pitch, chord) !== null) {
1789
+ if (chord && _chunk3R3QVKY5cjs.chordToneRole.call(void 0, pitch, chord) !== null) {
1755
1790
  score += weights.chordTone;
1756
1791
  }
1757
1792
  if (prevPitch !== void 0) {
@@ -1761,7 +1796,7 @@ function scoreCandidate(pitch, melPitch, melPrev, prevPitch, chord, center, weig
1761
1796
  if (dist > 0 && dist <= 2) {
1762
1797
  score += weights.stepwise;
1763
1798
  }
1764
- if (_chunkYPB3A3EYcjs.isForbiddenMelodicLeap.call(void 0, prevPitch, pitch)) {
1799
+ if (_chunk3R3QVKY5cjs.isForbiddenMelodicLeap.call(void 0, prevPitch, pitch)) {
1765
1800
  score += weights.forbiddenLeap;
1766
1801
  }
1767
1802
  if (melPitch !== void 0 && melPrev !== void 0 && ic !== void 0) {
@@ -1786,12 +1821,12 @@ function heldNoteBoundaries(melody, startBeat, endBeat, chordChangeBeats) {
1786
1821
  boundaries.add(onset);
1787
1822
  }
1788
1823
  for (const beat of chordChangeBeats) {
1789
- if (beat > startBeat + _chunkXKSO2V5Icjs.BEAT_EPS && beat < endBeat - _chunkXKSO2V5Icjs.BEAT_EPS) {
1824
+ if (beat > startBeat + _chunkS5BKZZGMcjs.BEAT_EPS && beat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
1790
1825
  boundaries.add(beat);
1791
1826
  }
1792
1827
  }
1793
1828
  const firstGrid = Math.floor(startBeat / GRID_STEP + 1) * GRID_STEP;
1794
- for (let beat = firstGrid; beat < endBeat - _chunkXKSO2V5Icjs.BEAT_EPS; beat += GRID_STEP) {
1829
+ for (let beat = firstGrid; beat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS; beat += GRID_STEP) {
1795
1830
  boundaries.add(beat);
1796
1831
  }
1797
1832
  return [...boundaries].sort((a, b) => a - b);
@@ -1804,8 +1839,8 @@ function boundaryContexts(melody, harmony, startBeat, endBeat, ts) {
1804
1839
  melodyVoice,
1805
1840
  otherVoices: melodyVoice === void 0 ? [] : [melodyVoice],
1806
1841
  chord: harmony.chordAt(boundary),
1807
- strongBeat: _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, boundary, ts),
1808
- atCounterOnset: Math.abs(boundary - startBeat) < _chunkXKSO2V5Icjs.BEAT_EPS
1842
+ strongBeat: _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, boundary, ts),
1843
+ atCounterOnset: Math.abs(boundary - startBeat) < _chunkS5BKZZGMcjs.BEAT_EPS
1809
1844
  };
1810
1845
  });
1811
1846
  }
@@ -1816,7 +1851,7 @@ function heldPitchSafety(pitch, contexts, prevPitch, key, profile, register, low
1816
1851
  if (melodyVoice !== void 0 && (register === "below" && pitch >= melodyVoice.pitch || register === "above" && pitch <= melodyVoice.pitch)) {
1817
1852
  return null;
1818
1853
  }
1819
- const result = _chunkYPB3A3EYcjs.evaluateSafety.call(void 0,
1854
+ const result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0,
1820
1855
  {
1821
1856
  profile,
1822
1857
  candidatePitch: pitch,
@@ -1838,51 +1873,51 @@ function heldPitchSafety(pitch, contexts, prevPitch, key, profile, register, low
1838
1873
  return worst;
1839
1874
  }
1840
1875
  function generateCounterMelody(opts) {
1841
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "countermelody options");
1876
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "countermelody options");
1842
1877
  const timeline = opts.timeline;
1843
1878
  const chordAt = timeline === void 0 ? opts.chordAt : (beat) => timeline.at(beat);
1844
1879
  if (chordAt === void 0) {
1845
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)("countermelody needs a timeline or a chordAt callback");
1880
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("countermelody needs a timeline or a chordAt callback");
1846
1881
  }
1847
1882
  const chordChangeBeats = timeline === void 0 ? _nullishCoalesce(opts.chordChangeBeats, () => ( [])) : timeline.segments.flatMap((segment) => [segment.startBeat, segment.endBeat]);
1848
1883
  const register = _nullishCoalesce(opts.register, () => ( "below"));
1849
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, opts.melody, "countermelody melody", { allowNonPositiveDuration: true });
1850
- const melody = _chunkTT6PKMPRcjs.createNoteEventIndex.call(void 0, _chunkXKSO2V5Icjs.soundingNotesOnly.call(void 0, opts.melody), {
1884
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, opts.melody, "countermelody melody", { allowNonPositiveDuration: true });
1885
+ const melody = _chunk35NBV2FTcjs.createNoteEventIndex.call(void 0, _chunkS5BKZZGMcjs.soundingNotesOnly.call(void 0, opts.melody), {
1851
1886
  tieBreak: register === "below" ? "highest" : "lowest"
1852
1887
  });
1853
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS2)), "ts"));
1854
- _chunkXKSO2V5Icjs.assertTimeSignature.call(void 0, ts);
1855
- const rhythm = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(opts.rhythm, () => ( "complement")), ["complement", "follow"], "rhythm");
1856
- const profile = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(opts.profile, () => ( "pop")), ["strict", "pop"], "safety profile");
1888
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS2)), "ts"));
1889
+ _chunkS5BKZZGMcjs.assertTimeSignature.call(void 0, ts);
1890
+ const rhythm = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(opts.rhythm, () => ( "complement")), ["complement", "follow"], "rhythm");
1891
+ const profile = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(opts.profile, () => ( "pop")), ["strict", "pop"], "safety profile");
1857
1892
  assertWeightOverrides(opts.weights);
1858
- const weights = _chunkYPB3A3EYcjs.profileWeights.call(void 0, profile, opts.weights);
1859
- const key = _chunkYPB3A3EYcjs.toKeyScale.call(void 0, opts.key);
1893
+ const weights = _chunk3R3QVKY5cjs.profileWeights.call(void 0, profile, opts.weights);
1894
+ const key = _chunk3R3QVKY5cjs.toKeyScale.call(void 0, opts.key);
1860
1895
  const draw = resolveContext(opts.ctx).part("countermelody");
1861
1896
  if (melody.notes.length === 0) {
1862
1897
  return [];
1863
1898
  }
1864
1899
  const spanStart = _nullishCoalesce(_optionalChain([melody, 'access', _27 => _27.notes, 'access', _28 => _28[0], 'optionalAccess', _29 => _29.note, 'access', _30 => _30.startBeat]), () => ( 0));
1865
1900
  const spanEnd = melody.notes.reduce((end, n) => Math.max(end, n.endBeat), spanStart);
1866
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, Math.ceil((spanEnd - spanStart) / GRID_STEP), "countermelody grid");
1901
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, Math.ceil((spanEnd - spanStart) / GRID_STEP), "countermelody grid");
1867
1902
  const meanPitch = melody.notes.reduce((sum, n) => sum + n.note.pitch, 0) / melody.notes.length;
1868
1903
  const defaultCenter = register === "below" ? meanPitch - REGISTER_OFFSET : meanPitch + REGISTER_OFFSET;
1869
- const low = _chunkXKSO2V5Icjs.clampToMidi.call(void 0,
1904
+ const low = _chunkS5BKZZGMcjs.clampToMidi.call(void 0,
1870
1905
  _nullishCoalesce(opts.pitchLow, () => ( Math.round(defaultCenter) - DEFAULT_HALF_RANGE)),
1871
1906
  "countermelody pitchLow"
1872
1907
  );
1873
- const high = _chunkXKSO2V5Icjs.clampToMidi.call(void 0,
1908
+ const high = _chunkS5BKZZGMcjs.clampToMidi.call(void 0,
1874
1909
  _nullishCoalesce(opts.pitchHigh, () => ( Math.round(defaultCenter) + DEFAULT_HALF_RANGE)),
1875
1910
  "countermelody pitchHigh"
1876
1911
  );
1877
1912
  if (low > high) {
1878
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
1913
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1879
1914
  `countermelody pitchLow must not exceed pitchHigh; received ${low} > ${high}`
1880
1915
  );
1881
1916
  }
1882
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, high - low + 1, "countermelody pitch candidates");
1883
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, chordChangeBeats.length, "chord change beats");
1917
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, high - low + 1, "countermelody pitch candidates");
1918
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, chordChangeBeats.length, "chord change beats");
1884
1919
  for (let index = 0; index < chordChangeBeats.length; index += 1) {
1885
- _chunkXKSO2V5Icjs.assertRange.call(void 0,
1920
+ _chunkS5BKZZGMcjs.assertRange.call(void 0,
1886
1921
  _nullishCoalesce(chordChangeBeats[index], () => ( Number.NaN)),
1887
1922
  0,
1888
1923
  Number.MAX_SAFE_INTEGER,
@@ -1892,7 +1927,7 @@ function generateCounterMelody(opts) {
1892
1927
  const center = (low + high) / 2;
1893
1928
  const onsets = rhythm === "follow" ? followOnsets(melody) : complementOnsets(melody, ts, spanStart, spanEnd, draw);
1894
1929
  const boundaryEstimate = onsets.length + Math.ceil((spanEnd - spanStart) / GRID_STEP) + melody.notes.length + chordChangeBeats.length;
1895
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, boundaryEstimate * (high - low + 1), "countermelody search");
1930
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, boundaryEstimate * (high - low + 1), "countermelody search");
1896
1931
  const jitter = Array.from(
1897
1932
  { length: high - low + 1 },
1898
1933
  (_, index) => draw.at("jitter", index) * TIE_BREAK_JITTER
@@ -1913,14 +1948,14 @@ function generateCounterMelody(opts) {
1913
1948
  const contexts = boundaryContexts(melody, { chordAt, chordChangeBeats }, beat, endBeat, ts);
1914
1949
  const chord = _nullishCoalesce(_optionalChain([contexts, 'access', _33 => _33[0], 'optionalAccess', _34 => _34.chord]), () => ( chordAt(beat)));
1915
1950
  const otherVoices = melodyVoice !== void 0 ? [melodyVoice] : [];
1916
- const candidates = _chunkYPB3A3EYcjs.enumerateSafePitches.call(void 0,
1951
+ const candidates = _chunk3R3QVKY5cjs.enumerateSafePitches.call(void 0,
1917
1952
  {
1918
1953
  profile,
1919
1954
  prevPitch,
1920
1955
  chord,
1921
1956
  key,
1922
1957
  otherVoices,
1923
- strongBeat: _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, beat, ts),
1958
+ strongBeat: _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, beat, ts),
1924
1959
  vocalLow: low,
1925
1960
  vocalHigh: high
1926
1961
  },
@@ -1947,7 +1982,7 @@ function generateCounterMelody(opts) {
1947
1982
  if (melPitch !== void 0) {
1948
1983
  if (prevPitch !== void 0 && melPrev !== void 0 && // Parallel octaves are the perfect-class-zero case of this predicate,
1949
1984
  // so a single check covers both parallel fifths and octaves.
1950
- _chunkYPB3A3EYcjs.createsParallelPerfect.call(void 0, prevPitch, candidate, melPrev, melPitch)) {
1985
+ _chunk3R3QVKY5cjs.createsParallelPerfect.call(void 0, prevPitch, candidate, melPrev, melPitch)) {
1951
1986
  continue;
1952
1987
  }
1953
1988
  }
@@ -1969,7 +2004,7 @@ function generateCounterMelody(opts) {
1969
2004
  Math.min(127, Math.round((_nullishCoalesce(_optionalChain([melNote, 'optionalAccess', _35 => _35.velocity]), () => ( DEFAULT_MELODY_VELOCITY))) - VELOCITY_DROP))
1970
2005
  );
1971
2006
  out.push({
1972
- pitch: _chunkXKSO2V5Icjs.clampToMidi.call(void 0, pitch),
2007
+ pitch: _chunkS5BKZZGMcjs.clampToMidi.call(void 0, pitch),
1973
2008
  startBeat: beat,
1974
2009
  durationBeat: endBeat - beat,
1975
2010
  velocity
@@ -2566,10 +2601,10 @@ function generateHiHatForBeat(ctx, sec) {
2566
2601
 
2567
2602
  // src/generate/drums/euclid.ts
2568
2603
  function euclideanRhythm(pulses, steps, rotation = 0) {
2569
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, steps, "euclidean steps");
2570
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, pulses, "euclidean pulses");
2571
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, rotation, "euclidean rotation");
2572
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, steps, "euclidean pattern steps");
2604
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, steps, "euclidean steps");
2605
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, pulses, "euclidean pulses");
2606
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, rotation, "euclidean rotation");
2607
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, steps, "euclidean pattern steps");
2573
2608
  const p = Math.max(0, Math.min(pulses, steps));
2574
2609
  const base = bjorklund(p, steps);
2575
2610
  const shift = (rotation % steps + steps) % steps;
@@ -2905,7 +2940,7 @@ function drumNoteOf(voice) {
2905
2940
  return Object.hasOwn(DRUM_NOTES, voice) ? DRUM_NOTES[voice] : void 0;
2906
2941
  }
2907
2942
  function drumVoiceOf(pitch) {
2908
- return VOICE_BY_NOTE.get(_chunkXKSO2V5Icjs.assertMidiPitch.call(void 0, pitch));
2943
+ return VOICE_BY_NOTE.get(_chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, pitch));
2909
2944
  }
2910
2945
  var ONSET_KEY_SCALE = 128;
2911
2946
  var HitList = (_class = class {constructor() { _class.prototype.__init.call(this); }
@@ -3216,12 +3251,12 @@ var KIT_ARTICULATIONS = Object.freeze([
3216
3251
  var DRUM_KIT = Object.freeze({
3217
3252
  kind: "percussion",
3218
3253
  name: "drum kit",
3219
- limbs: _chunkJ772DL3Bcjs.LIMBS,
3254
+ limbs: _chunkCGBADIO5cjs.LIMBS,
3220
3255
  reach: deepFreeze(reachByNote()),
3221
3256
  overdub: deepFreeze(OVERDUB_VOICES.map((voice) => DRUM_NOTES[voice])),
3222
3257
  articulations: KIT_ARTICULATIONS,
3223
3258
  // One stroke per limb, and one more per voice dubbed over them.
3224
- polyphony: _chunkJ772DL3Bcjs.LIMBS.length + OVERDUB_VOICES.length
3259
+ polyphony: _chunkCGBADIO5cjs.LIMBS.length + OVERDUB_VOICES.length
3225
3260
  });
3226
3261
 
3227
3262
  // src/generate/drums/vocabulary.ts
@@ -3232,8 +3267,8 @@ function isDrumPattern(material) {
3232
3267
  function assertDrumPattern(material, label) {
3233
3268
  material.strokes.forEach((stroke, index) => {
3234
3269
  if (typeof stroke !== "object" || stroke === null || typeof stroke.voice !== "string" || drumNoteOf(stroke.voice) === void 0) {
3235
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
3236
- `${label} strokes[${index}].voice must name a drum voice; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, _optionalChain([stroke, 'optionalAccess', _44 => _44.voice]))}`
3270
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
3271
+ `${label} strokes[${index}].voice must name a drum voice; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, _optionalChain([stroke, 'optionalAccess', _44 => _44.voice]))}`
3237
3272
  );
3238
3273
  }
3239
3274
  });
@@ -3425,21 +3460,21 @@ var DEFAULT_VELOCITY = 100;
3425
3460
  var DEFAULT_BPM2 = 120;
3426
3461
  var MAX_STROKES_PER_BAR = 64;
3427
3462
  function placeDrumPattern(opts) {
3428
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "drum pattern options");
3429
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, opts.bars, "drum pattern bars");
3430
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, opts.bars * MAX_STROKES_PER_BAR, "drum pattern hits", opts.budget);
3431
- const genre = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.genre, GENRES, "drum pattern genre");
3432
- const section = opts.section === void 0 ? void 0 : _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.section, PUBLIC_SECTIONS, "drum pattern section");
3433
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( FOUR_FOUR2)), "ts"));
3463
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "drum pattern options");
3464
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, opts.bars, "drum pattern bars");
3465
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, opts.bars * MAX_STROKES_PER_BAR, "drum pattern hits", opts.budget);
3466
+ const genre = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.genre, GENRES, "drum pattern genre");
3467
+ const section = opts.section === void 0 ? void 0 : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.section, PUBLIC_SECTIONS, "drum pattern section");
3468
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( FOUR_FOUR2)), "ts"));
3434
3469
  if (opts.velocity !== void 0) {
3435
- _chunkXKSO2V5Icjs.assertRange.call(void 0, opts.velocity, 1, 127, "drum pattern velocity");
3470
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, opts.velocity, 1, 127, "drum pattern velocity");
3436
3471
  }
3437
- const feel = opts.feel === void 0 ? "straight" : _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.feel, DRUM_FEELS, "feel");
3472
+ const feel = opts.feel === void 0 ? "straight" : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.feel, DRUM_FEELS, "feel");
3438
3473
  const resolved = resolveContext(opts.ctx);
3439
3474
  const bpm = _nullishCoalesce(resolved.bpm, () => ( DEFAULT_BPM2));
3440
3475
  const draw = resolved.part("drums");
3441
3476
  const baseVelocity = _nullishCoalesce(opts.velocity, () => ( DEFAULT_VELOCITY));
3442
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
3477
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
3443
3478
  const kit = resolved.instrument("drums");
3444
3479
  const swing = effectiveSwing(feel, feelSwingAmount(feel));
3445
3480
  const supplied = vocabularyOfKind(resolved.vocabulary, isDrumPattern);
@@ -3448,8 +3483,8 @@ function placeDrumPattern(opts) {
3448
3483
  });
3449
3484
  const dictionary = mergeVocabulary(DRUM_PATTERNS, supplied);
3450
3485
  if (selectVocabulary(dictionary, { ts }).length === 0) {
3451
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
3452
- `drum pattern ts names a meter no figure is written in: ${_chunkXKSO2V5Icjs.formatTimeSignature.call(void 0, ts)}. The built-in figures are written in 4/4; supply vocabulary in another meter through the context.`
3486
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
3487
+ `drum pattern ts names a meter no figure is written in: ${_chunkS5BKZZGMcjs.formatTimeSignature.call(void 0, ts)}. The built-in figures are written in 4/4; supply vocabulary in another meter through the context.`
3453
3488
  );
3454
3489
  }
3455
3490
  const track = new HitList();
@@ -3514,26 +3549,26 @@ function placeDrumPattern(opts) {
3514
3549
  }
3515
3550
  }
3516
3551
  const endBeat = opts.bars * barBeats;
3517
- return track.hits.filter((h) => h.startBeat < endBeat && (kit === void 0 || _chunkJ772DL3Bcjs.canSound.call(void 0, kit, h.pitch))).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
3552
+ return track.hits.filter((h) => h.startBeat < endBeat && (kit === void 0 || _chunkCGBADIO5cjs.canSound.call(void 0, kit, h.pitch))).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
3518
3553
  }
3519
3554
 
3520
3555
  // src/generate/drums/index.ts
3521
3556
  var MAX_HITS_PER_BAR = 128;
3522
3557
  var DEFAULT_BPM3 = 120;
3523
3558
  function generateDrums(opts) {
3524
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "drum options");
3525
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, opts.bars, "drum bars");
3526
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, opts.bars * MAX_HITS_PER_BAR, "drum hits", opts.budget);
3559
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "drum options");
3560
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, opts.bars, "drum bars");
3561
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, opts.bars * MAX_HITS_PER_BAR, "drum hits", opts.budget);
3527
3562
  if (opts.euclideanKick) {
3528
3563
  const steps = _nullishCoalesce(opts.euclideanKick.steps, () => ( 16));
3529
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, steps, "euclidean steps", 1, 16);
3530
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, opts.euclideanKick.pulses, "euclidean pulses");
3531
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, _nullishCoalesce(opts.euclideanKick.rotation, () => ( 0)), "euclidean rotation");
3564
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, steps, "euclidean steps", 1, 16);
3565
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, opts.euclideanKick.pulses, "euclidean pulses");
3566
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, _nullishCoalesce(opts.euclideanKick.rotation, () => ( 0)), "euclidean rotation");
3532
3567
  }
3533
- const publicStyle = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.style, GROOVE_STYLES, "drum style");
3534
- const publicSection = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.section, PUBLIC_SECTIONS, "drum section");
3568
+ const publicStyle = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.style, GROOVE_STYLES, "drum style");
3569
+ const publicSection = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.section, PUBLIC_SECTIONS, "drum section");
3535
3570
  if (opts.nextSection !== void 0) {
3536
- _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.nextSection, PUBLIC_SECTIONS, "drum nextSection");
3571
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.nextSection, PUBLIC_SECTIONS, "drum nextSection");
3537
3572
  }
3538
3573
  const track = new HitList();
3539
3574
  const resolved = resolveContext(opts.ctx);
@@ -3544,18 +3579,18 @@ function generateDrums(opts) {
3544
3579
  const difficulty = resolved.difficulty;
3545
3580
  const mapping = mapStyle(publicStyle);
3546
3581
  const style = mapping.style;
3547
- const feel = opts.feel === void 0 ? mapping.feel : _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.feel, DRUM_FEELS, "drum feel");
3548
- const role = opts.role === void 0 ? "full" : _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.role, DRUM_ROLES, "drum role");
3549
- const meters = _chunkXKSO2V5Icjs.resolveMeters.call(void 0, { ts: opts.ts }, "ts");
3582
+ const feel = opts.feel === void 0 ? mapping.feel : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.feel, DRUM_FEELS, "drum feel");
3583
+ const role = opts.role === void 0 ? "full" : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.role, DRUM_ROLES, "drum role");
3584
+ const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, { ts: opts.ts }, "ts");
3550
3585
  for (const change of meters) {
3551
3586
  if (change.ts.numerator !== 4 || change.ts.denominator !== 4) {
3552
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
3587
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
3553
3588
  `drum time signature must be 4/4 throughout; received ${change.ts.numerator}/${change.ts.denominator} at beat ${change.startBeat}`
3554
3589
  );
3555
3590
  }
3556
3591
  }
3557
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, meters);
3558
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
3592
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, meters);
3593
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
3559
3594
  const playMainVoices = role !== "fxOnly";
3560
3595
  const section = mapSection(publicSection);
3561
3596
  const swingAmount = feelSwingAmount(feel);
@@ -3748,7 +3783,7 @@ function underCeiling(hits, bpm, difficulty, exempt) {
3748
3783
  return kept;
3749
3784
  }
3750
3785
  function playableOn(kit, pitch) {
3751
- return kit === void 0 || _chunkJ772DL3Bcjs.canSound.call(void 0, kit, pitch);
3786
+ return kit === void 0 || _chunkCGBADIO5cjs.canSound.call(void 0, kit, pitch);
3752
3787
  }
3753
3788
 
3754
3789
  // src/generate/groove/index.ts
@@ -3763,24 +3798,24 @@ var MAX_METRIC_WEIGHT = 3;
3763
3798
  var MIN_VELOCITY = 1;
3764
3799
  var MAX_VELOCITY = 127;
3765
3800
  function humanize(events, opts = {}) {
3766
- const asked = _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
3767
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(asked.ts, () => ( DEFAULT_TS3)), "ts"));
3768
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, events, "humanize events", { allowNonPositiveDuration: true });
3769
- const sounding2 = _chunkXKSO2V5Icjs.dropSilentNotes.call(void 0, events);
3801
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
3802
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(asked.ts, () => ( DEFAULT_TS3)), "ts"));
3803
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, events, "humanize events", { allowNonPositiveDuration: true });
3804
+ const sounding2 = _chunkS5BKZZGMcjs.dropSilentNotes.call(void 0, events);
3770
3805
  const timing = _nullishCoalesce(asked.timing, () => ( DEFAULT_TIMING));
3771
3806
  const velocityJitter = _nullishCoalesce(asked.velocity, () => ( DEFAULT_VELOCITY_JITTER));
3772
3807
  const accent2 = _nullishCoalesce(asked.accent, () => ( DEFAULT_ACCENT));
3773
3808
  const baseVelocity = _nullishCoalesce(asked.baseVelocity, () => ( DEFAULT_BASE_VELOCITY));
3774
- _chunkXKSO2V5Icjs.assertRange.call(void 0, timing, 0, Number.MAX_SAFE_INTEGER, "humanize timing");
3775
- _chunkXKSO2V5Icjs.assertRange.call(void 0, velocityJitter, 0, 127, "humanize velocity jitter");
3776
- _chunkXKSO2V5Icjs.assertRange.call(void 0, accent2, 0, 127, "humanize accent");
3777
- _chunkXKSO2V5Icjs.assertRange.call(void 0, baseVelocity, 0, 127, "humanize base velocity");
3809
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, timing, 0, Number.MAX_SAFE_INTEGER, "humanize timing");
3810
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, velocityJitter, 0, 127, "humanize velocity jitter");
3811
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, accent2, 0, 127, "humanize accent");
3812
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, baseVelocity, 0, 127, "humanize base velocity");
3778
3813
  const ctx = resolveContext(asked.ctx);
3779
3814
  const draw = ctx.part(_nullishCoalesce(asked.part, () => ( DEFAULT_PART)));
3780
3815
  return sounding2.map((event) => {
3781
3816
  const timingOffset = draw.float(-timing, timing, "timing", event.startBeat, event.pitch);
3782
3817
  const startBeat = event.startBeat + timingOffset;
3783
- const weight = _chunkXKSO2V5Icjs.metricWeight.call(void 0, event.startBeat, ts);
3818
+ const weight = _chunkS5BKZZGMcjs.metricWeight.call(void 0, event.startBeat, ts);
3784
3819
  const accentBoost = weight / MAX_METRIC_WEIGHT * accent2;
3785
3820
  const velocityOffset = draw.float(
3786
3821
  -velocityJitter,
@@ -3809,18 +3844,18 @@ function quantizeToGrid(beat, barBeats, subdivision, slotsPerBar) {
3809
3844
  };
3810
3845
  }
3811
3846
  function extractGrooveTemplate(events, ts, subdivision = DEFAULT_GROOVE_SUBDIVISION) {
3812
- const meter = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts"));
3813
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, events, "groove source events", { allowNonPositiveDuration: true });
3814
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, subdivision, "groove subdivision");
3815
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, meter);
3847
+ const meter = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts"));
3848
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, events, "groove source events", { allowNonPositiveDuration: true });
3849
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, subdivision, "groove subdivision");
3850
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, meter);
3816
3851
  const slotsPerBar = Math.ceil(barBeats * subdivision);
3817
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, slotsPerBar, "groove template slots");
3818
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, slotsPerBar, "groove template slots");
3852
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, slotsPerBar, "groove template slots");
3853
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, slotsPerBar, "groove template slots");
3819
3854
  const offsetSums = new Array(slotsPerBar).fill(0);
3820
3855
  const velocitySums = new Array(slotsPerBar).fill(0);
3821
3856
  const counts = new Array(slotsPerBar).fill(0);
3822
3857
  const velocityCounts = new Array(slotsPerBar).fill(0);
3823
- for (const event of _chunkXKSO2V5Icjs.dropSilentNotes.call(void 0, events)) {
3858
+ for (const event of _chunkS5BKZZGMcjs.dropSilentNotes.call(void 0, events)) {
3824
3859
  const { quantizedBeat, slotIndex } = quantizeToGrid(
3825
3860
  event.startBeat,
3826
3861
  barBeats,
@@ -3850,24 +3885,24 @@ function extractGrooveTemplate(events, ts, subdivision = DEFAULT_GROOVE_SUBDIVIS
3850
3885
  return { subdivision, slotsPerBar, slots, ts: meter };
3851
3886
  }
3852
3887
  function applyGrooveTemplate(events, template, ts) {
3853
- const meter = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts"));
3854
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, events, "groove target events", { allowNonPositiveDuration: true });
3855
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, template.subdivision, "template subdivision");
3856
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, template.slotsPerBar, "template slotsPerBar");
3857
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, template.slots.length, "template slots");
3888
+ const meter = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts"));
3889
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, events, "groove target events", { allowNonPositiveDuration: true });
3890
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, template.subdivision, "template subdivision");
3891
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, template.slotsPerBar, "template slotsPerBar");
3892
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, template.slots.length, "template slots");
3858
3893
  if (template.slots.length !== template.slotsPerBar) {
3859
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)("template slots length must equal slotsPerBar");
3894
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("template slots length must equal slotsPerBar");
3860
3895
  }
3861
3896
  if (template.ts && (template.ts.numerator !== meter.numerator || template.ts.denominator !== meter.denominator)) {
3862
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
3863
- `Groove template meter ${_chunkXKSO2V5Icjs.formatTimeSignature.call(void 0, template.ts)} does not match apply-time meter ${_chunkXKSO2V5Icjs.formatTimeSignature.call(void 0, meter)}`
3897
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
3898
+ `Groove template meter ${_chunkS5BKZZGMcjs.formatTimeSignature.call(void 0, template.ts)} does not match apply-time meter ${_chunkS5BKZZGMcjs.formatTimeSignature.call(void 0, meter)}`
3864
3899
  );
3865
3900
  }
3866
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, meter);
3901
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, meter);
3867
3902
  const expectedSlots = Math.ceil(barBeats * template.subdivision);
3868
3903
  if (template.slotsPerBar !== expectedSlots) {
3869
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
3870
- `Groove template slotsPerBar ${template.slotsPerBar} does not match ${expectedSlots} slots per bar of ${_chunkXKSO2V5Icjs.formatTimeSignature.call(void 0, meter)} at subdivision ${template.subdivision}`
3904
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
3905
+ `Groove template slotsPerBar ${template.slotsPerBar} does not match ${expectedSlots} slots per bar of ${_chunkS5BKZZGMcjs.formatTimeSignature.call(void 0, meter)} at subdivision ${template.subdivision}`
3871
3906
  );
3872
3907
  }
3873
3908
  for (let index = 0; index < template.slots.length; index += 1) {
@@ -3875,12 +3910,12 @@ function applyGrooveTemplate(events, template, ts) {
3875
3910
  if (slot === void 0) {
3876
3911
  continue;
3877
3912
  }
3878
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, slot.timingOffset, `template slots[${index}].timingOffset`);
3913
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, slot.timingOffset, `template slots[${index}].timingOffset`);
3879
3914
  if (slot.velocity !== null && slot.velocity !== void 0) {
3880
- _chunkXKSO2V5Icjs.assertRange.call(void 0, slot.velocity, 0, 127, `template slots[${index}].velocity`);
3915
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, slot.velocity, 0, 127, `template slots[${index}].velocity`);
3881
3916
  }
3882
3917
  }
3883
- return _chunkXKSO2V5Icjs.dropSilentNotes.call(void 0, events).map((event) => {
3918
+ return _chunkS5BKZZGMcjs.dropSilentNotes.call(void 0, events).map((event) => {
3884
3919
  const { quantizedBeat, slotIndex } = quantizeToGrid(
3885
3920
  event.startBeat,
3886
3921
  barBeats,
@@ -3897,7 +3932,7 @@ function applyGrooveTemplate(events, template, ts) {
3897
3932
  // src/generate/harmonize/nct.ts
3898
3933
  function snapToPulse(beat, pulse2) {
3899
3934
  const snapped = Math.round(beat / pulse2) * pulse2;
3900
- return Math.abs(snapped - beat) <= _chunkQ6R3QAZDcjs.HUMANIZE_ADJACENCY ? snapped : beat;
3935
+ return Math.abs(snapped - beat) <= _chunkIFZDWIKMcjs.HUMANIZE_ADJACENCY ? snapped : beat;
3901
3936
  }
3902
3937
  var STEP_SEMITONES = 2;
3903
3938
  function isStep(a, b) {
@@ -3911,9 +3946,9 @@ function sameDirection(prev, note2, next) {
3911
3946
  return prev !== note2 && next !== note2 && note2 - prev > 0 === next - note2 > 0;
3912
3947
  }
3913
3948
  function classifyMelodyTones(melody, ts) {
3914
- const meter = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts"));
3915
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, melody, "melody notes", { allowNonPositiveDuration: true });
3916
- const pulse2 = _chunkXKSO2V5Icjs.pulseBeats.call(void 0, meter);
3949
+ const meter = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts"));
3950
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, melody, "melody notes", { allowNonPositiveDuration: true });
3951
+ const pulse2 = _chunkS5BKZZGMcjs.pulseBeats.call(void 0, meter);
3917
3952
  return melody.map((_, index) => {
3918
3953
  const role = roleOfNote(melody, index, meter, pulse2);
3919
3954
  return { noteIndex: index, role, ornamental: role !== "structural" };
@@ -3928,12 +3963,12 @@ function roleOfNote(melody, index, ts, pulse2) {
3928
3963
  }
3929
3964
  const intoNote = Math.abs(prev.startBeat + prev.durationBeat - note2.startBeat);
3930
3965
  const outOfNote = Math.abs(note2.startBeat + note2.durationBeat - next.startBeat);
3931
- if (intoNote > _chunkQ6R3QAZDcjs.HUMANIZE_ADJACENCY || outOfNote > _chunkQ6R3QAZDcjs.HUMANIZE_ADJACENCY) {
3966
+ if (intoNote > _chunkIFZDWIKMcjs.HUMANIZE_ADJACENCY || outOfNote > _chunkIFZDWIKMcjs.HUMANIZE_ADJACENCY) {
3932
3967
  return "structural";
3933
3968
  }
3934
- const weight = _chunkXKSO2V5Icjs.metricWeight.call(void 0, snapToPulse(note2.startBeat, pulse2), ts);
3935
- const weightPrev = _chunkXKSO2V5Icjs.metricWeight.call(void 0, snapToPulse(prev.startBeat, pulse2), ts);
3936
- const weightNext = _chunkXKSO2V5Icjs.metricWeight.call(void 0, snapToPulse(next.startBeat, pulse2), ts);
3969
+ const weight = _chunkS5BKZZGMcjs.metricWeight.call(void 0, snapToPulse(note2.startBeat, pulse2), ts);
3970
+ const weightPrev = _chunkS5BKZZGMcjs.metricWeight.call(void 0, snapToPulse(prev.startBeat, pulse2), ts);
3971
+ const weightNext = _chunkS5BKZZGMcjs.metricWeight.call(void 0, snapToPulse(next.startBeat, pulse2), ts);
3937
3972
  const subordinate = weight <= weightPrev && weight <= weightNext && note2.durationBeat <= prev.durationBeat && note2.durationBeat <= next.durationBeat;
3938
3973
  const leaning = weight > weightPrev && weight >= weightNext;
3939
3974
  if (leaning && prev.pitch === note2.pitch && note2.pitch - next.pitch >= 1 && isStep(note2.pitch, next.pitch)) {
@@ -3965,12 +4000,12 @@ var FALLBACK = {
3965
4000
  quality: "maj",
3966
4001
  secondaryDominant: false,
3967
4002
  base: 0,
3968
- pcs: _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, _chunkYPB3A3EYcjs.makeChord.call(void 0, 0, "maj"))
4003
+ pcs: _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, _chunk3R3QVKY5cjs.makeChord.call(void 0, 0, "maj"))
3969
4004
  };
3970
4005
  function defaultHarmonicRhythm(ts) {
3971
- const bar2 = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
4006
+ const bar2 = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
3972
4007
  const half = bar2 / 2;
3973
- return half % _chunkXKSO2V5Icjs.pulseBeats.call(void 0, ts) === 0 ? half : bar2;
4008
+ return half % _chunkS5BKZZGMcjs.pulseBeats.call(void 0, ts) === 0 ? half : bar2;
3974
4009
  }
3975
4010
  var DEFAULT_PLACEMENT = {
3976
4011
  transposeSearch: false,
@@ -3979,24 +4014,24 @@ var DEFAULT_PLACEMENT = {
3979
4014
  var DEFAULT_METER = { numerator: 4, denominator: 4 };
3980
4015
  var TIE_BREAK_JITTER2 = 1e-6;
3981
4016
  function cadencesThroughRaisedSeventh(key) {
3982
- return _chunkQ6R3QAZDcjs.isMinorKey.call(void 0, key) && _chunkYPB3A3EYcjs.scaleSystemOf.call(void 0, key) === "common-practice";
4017
+ return _chunkIFZDWIKMcjs.isMinorKey.call(void 0, key) && _chunk3R3QVKY5cjs.scaleSystemOf.call(void 0, key) === "common-practice";
3983
4018
  }
3984
4019
  function isKeyTone(pitch, key) {
3985
- return _chunkYPB3A3EYcjs.isScaleTone.call(void 0, pitch, key) || cadencesThroughRaisedSeventh(key) && _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, pitch) === _chunkYPB3A3EYcjs.leadingTonePcOf.call(void 0, key);
4020
+ return _chunk3R3QVKY5cjs.isScaleTone.call(void 0, pitch, key) || cadencesThroughRaisedSeventh(key) && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) === _chunk3R3QVKY5cjs.leadingTonePcOf.call(void 0, key);
3986
4021
  }
3987
4022
  function inferKey(melody) {
3988
- let best = _chunkYPB3A3EYcjs.majorKey.call(void 0, 0);
4023
+ let best = _chunk3R3QVKY5cjs.majorKey.call(void 0, 0);
3989
4024
  let bestScore = Number.NEGATIVE_INFINITY;
3990
4025
  const candidates = [];
3991
4026
  for (let tonic = 0; tonic < 12; tonic += 1) {
3992
- candidates.push(_chunkYPB3A3EYcjs.majorKey.call(void 0, tonic), _chunkYPB3A3EYcjs.minorKey.call(void 0, tonic));
4027
+ candidates.push(_chunk3R3QVKY5cjs.majorKey.call(void 0, tonic), _chunk3R3QVKY5cjs.minorKey.call(void 0, tonic));
3993
4028
  }
3994
4029
  for (const key of candidates) {
3995
- const tonic = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, key.rootPc);
4030
+ const tonic = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
3996
4031
  let score = 0;
3997
4032
  for (const n of melody) {
3998
4033
  const w = Math.max(0.25, n.durationBeat);
3999
- const pc = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, n.pitch);
4034
+ const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, n.pitch);
4000
4035
  if (isKeyTone(n.pitch, key)) {
4001
4036
  score += w;
4002
4037
  }
@@ -4031,7 +4066,7 @@ function emissionCost(seg, cand, melody, key) {
4031
4066
  let cost = cand.base * seg.weight;
4032
4067
  for (const { index, weight, strong } of seg.costNotes) {
4033
4068
  const note2 = melody[index];
4034
- if (!note2 || pcs.includes(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, note2.pitch))) {
4069
+ if (!note2 || pcs.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, note2.pitch))) {
4035
4070
  continue;
4036
4071
  }
4037
4072
  cost += (strong ? NON_CHORD_TONE_STRONG : NON_CHORD_TONE_WEAK) * weight;
@@ -4070,7 +4105,7 @@ function phraseEndBonus(prev, cur, tonicPc, seg, melody) {
4070
4105
  return 0;
4071
4106
  }
4072
4107
  const closing = melody[seg.closingIndex];
4073
- if (!closing || _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, closing.pitch) !== tonicPc) {
4108
+ if (!closing || _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, closing.pitch) !== tonicPc) {
4074
4109
  return 0;
4075
4110
  }
4076
4111
  const weight = Math.max(seg.weight, seg.beats);
@@ -4107,7 +4142,7 @@ function sameHarmony(a, b) {
4107
4142
  return a.rootPc === b.rootPc && a.quality === b.quality;
4108
4143
  }
4109
4144
  function harmonizeOnce(melody, key, candidates, segments, jitter, phraseEnds, articulated) {
4110
- const tonicPc = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, key.rootPc);
4145
+ const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
4111
4146
  const n = candidates.length;
4112
4147
  const candAt = (i) => _nullishCoalesce(candidates[i], () => ( FALLBACK));
4113
4148
  const seg0 = segments[0];
@@ -4169,13 +4204,13 @@ function gridBounds(segmentStart, hr, gridCount, ends) {
4169
4204
  }
4170
4205
  const last = segmentStart + gridCount * hr;
4171
4206
  for (const end of ends) {
4172
- if (end > segmentStart + _chunkXKSO2V5Icjs.BEAT_EPS && end < last - _chunkXKSO2V5Icjs.BEAT_EPS) {
4207
+ if (end > segmentStart + _chunkS5BKZZGMcjs.BEAT_EPS && end < last - _chunkS5BKZZGMcjs.BEAT_EPS) {
4173
4208
  bounds.push(end);
4174
4209
  }
4175
4210
  }
4176
4211
  bounds.sort((a, b) => a - b);
4177
4212
  return bounds.filter(
4178
- (beat, index) => index === 0 || beat - (_nullishCoalesce(bounds[index - 1], () => ( beat))) > _chunkXKSO2V5Icjs.BEAT_EPS
4213
+ (beat, index) => index === 0 || beat - (_nullishCoalesce(bounds[index - 1], () => ( beat))) > _chunkS5BKZZGMcjs.BEAT_EPS
4179
4214
  );
4180
4215
  }
4181
4216
  function closingNoteIndices(spans, ends) {
@@ -4184,7 +4219,7 @@ function closingNoteIndices(spans, ends) {
4184
4219
  let index = -1;
4185
4220
  let start = Number.NEGATIVE_INFINITY;
4186
4221
  for (const [i, span] of spans.entries()) {
4187
- if (span.startBeat < end - _chunkXKSO2V5Icjs.BEAT_EPS && span.startBeat >= start) {
4222
+ if (span.startBeat < end - _chunkS5BKZZGMcjs.BEAT_EPS && span.startBeat >= start) {
4188
4223
  start = span.startBeat;
4189
4224
  index = i;
4190
4225
  }
@@ -4227,7 +4262,7 @@ function phraseEndSegments(segments, ends) {
4227
4262
  for (const end of ends) {
4228
4263
  let index = -1;
4229
4264
  for (let s = 0; s < segments.length; s += 1) {
4230
- if ((_nullishCoalesce(_optionalChain([segments, 'access', _48 => _48[s], 'optionalAccess', _49 => _49.startBeat]), () => ( 0))) < end - _chunkXKSO2V5Icjs.BEAT_EPS) {
4265
+ if ((_nullishCoalesce(_optionalChain([segments, 'access', _48 => _48[s], 'optionalAccess', _49 => _49.startBeat]), () => ( 0))) < end - _chunkS5BKZZGMcjs.BEAT_EPS) {
4231
4266
  index = s;
4232
4267
  }
4233
4268
  }
@@ -4244,13 +4279,13 @@ function buildSegments(spans, melody, ts, grid, phraseEnds, budget) {
4244
4279
  const hr = grid.harmonicRhythm;
4245
4280
  const segmentStart = Math.floor(melodyStart / hr) * hr;
4246
4281
  const gridCount = Math.max(1, Math.ceil((melodyEnd - segmentStart) / hr));
4247
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, gridCount, "harmonic segments", budget);
4282
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, gridCount, "harmonic segments", budget);
4248
4283
  const innerEnds = phraseEnds.filter(
4249
- (end) => end > segmentStart + _chunkXKSO2V5Icjs.BEAT_EPS && end < melodyEnd - _chunkXKSO2V5Icjs.BEAT_EPS
4284
+ (end) => end > segmentStart + _chunkS5BKZZGMcjs.BEAT_EPS && end < melodyEnd - _chunkS5BKZZGMcjs.BEAT_EPS
4250
4285
  );
4251
4286
  const bounds = gridBounds(segmentStart, hr, gridCount, innerEnds);
4252
4287
  const segCount = bounds.length - 1;
4253
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, segCount, "harmonic segments", budget);
4288
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, segCount, "harmonic segments", budget);
4254
4289
  const segments = Array.from({ length: segCount }, (_, s) => {
4255
4290
  const startBeat = _nullishCoalesce(bounds[s], () => ( segmentStart));
4256
4291
  const endBeat = _nullishCoalesce(bounds[s + 1], () => ( startBeat + hr));
@@ -4271,7 +4306,7 @@ function buildSegments(spans, melody, ts, grid, phraseEnds, budget) {
4271
4306
  lastExclusive += 1;
4272
4307
  }
4273
4308
  memberships += Math.max(0, lastExclusive - first);
4274
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, memberships, "note-to-segment memberships", budget);
4309
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, memberships, "note-to-segment memberships", budget);
4275
4310
  for (let segment = first; segment < lastExclusive; segment += 1) {
4276
4311
  _optionalChain([segments, 'access', _50 => _50[segment], 'optionalAccess', _51 => _51.noteIndices, 'access', _52 => _52.push, 'call', _53 => _53(index)]);
4277
4312
  }
@@ -4295,7 +4330,7 @@ function buildSegments(spans, melody, ts, grid, phraseEnds, budget) {
4295
4330
  continue;
4296
4331
  }
4297
4332
  const weight = Math.max(0.25, overlap);
4298
- segment.costNotes.push({ index, weight, strong: _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, overlapStart, ts) });
4333
+ segment.costNotes.push({ index, weight, strong: _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, overlapStart, ts) });
4299
4334
  segment.weight += weight;
4300
4335
  if (span.startBeat >= closingStart) {
4301
4336
  closingStart = span.startBeat;
@@ -4317,7 +4352,7 @@ var UNSTABLE_QUALITIES = /* @__PURE__ */ new Set([
4317
4352
  "aug7"
4318
4353
  ]);
4319
4354
  function vocabularyBase(rootPc, quality, tonicPc) {
4320
- const above = (_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, rootPc) - tonicPc + 12) % 12;
4355
+ const above = (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc) - tonicPc + 12) % 12;
4321
4356
  const root = _nullishCoalesce(ROOT_WEIGHT_BY_SEMITONE[above], () => ( UNSTABLE_TRIAD));
4322
4357
  return UNSTABLE_QUALITIES.has(quality) ? Math.max(root, UNSTABLE_TRIAD) : root;
4323
4358
  }
@@ -4326,7 +4361,7 @@ var BORROWED_BASE = 0.5;
4326
4361
  var SECONDARY_DOMINANT_TARGETS = [2, 4, 5, 6];
4327
4362
  function secondaryDominantTargets(key) {
4328
4363
  const tonicizable = new Map(
4329
- _chunkYPB3A3EYcjs.tonicizableDegrees.call(void 0, key).map((degree) => [degree.degreeNumber, degree])
4364
+ _chunk3R3QVKY5cjs.tonicizableDegrees.call(void 0, key).map((degree) => [degree.degreeNumber, degree])
4330
4365
  );
4331
4366
  return SECONDARY_DOMINANT_TARGETS.map((degree) => tonicizable.get(degree)).filter(
4332
4367
  (degree) => degree !== void 0
@@ -4345,19 +4380,19 @@ function admittedCount(fraction, size) {
4345
4380
  return Math.max(0, Math.min(size, Math.ceil(fraction * size)));
4346
4381
  }
4347
4382
  function buildCandidates(key, harmonic) {
4348
- const tonicPc = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, key.rootPc);
4349
- const frame = _chunkYPB3A3EYcjs.heptatonicFrameOf.call(void 0, key);
4350
- const tones = _chunkYPB3A3EYcjs.scaleTonesInDegreeOrder.call(void 0, frame);
4383
+ const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
4384
+ const frame = _chunk3R3QVKY5cjs.heptatonicFrameOf.call(void 0, key);
4385
+ const tones = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, frame);
4351
4386
  const candidates = tones.map((rootPc, index) => {
4352
4387
  const degree = index + 1;
4353
- const quality = _chunkYPB3A3EYcjs.diatonicTriad.call(void 0, degree, frame).quality;
4388
+ const quality = _chunk3R3QVKY5cjs.diatonicTriad.call(void 0, degree, frame).quality;
4354
4389
  return {
4355
4390
  rootPc,
4356
4391
  quality,
4357
4392
  degree,
4358
4393
  secondaryDominant: false,
4359
4394
  base: vocabularyBase(rootPc, quality, tonicPc),
4360
- pcs: _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, _chunkYPB3A3EYcjs.makeChord.call(void 0, rootPc, quality))
4395
+ pcs: _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, _chunk3R3QVKY5cjs.makeChord.call(void 0, rootPc, quality))
4361
4396
  };
4362
4397
  });
4363
4398
  if (cadencesThroughRaisedSeventh(key)) {
@@ -4368,7 +4403,7 @@ function buildCandidates(key, harmonic) {
4368
4403
  degree: 5,
4369
4404
  secondaryDominant: false,
4370
4405
  base: vocabularyBase(rootPc, "maj", tonicPc),
4371
- pcs: _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, _chunkYPB3A3EYcjs.makeChord.call(void 0, rootPc, "maj"))
4406
+ pcs: _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, _chunk3R3QVKY5cjs.makeChord.call(void 0, rootPc, "maj"))
4372
4407
  });
4373
4408
  }
4374
4409
  const targets = secondaryDominantTargets(key);
@@ -4387,20 +4422,20 @@ function buildCandidates(key, harmonic) {
4387
4422
  secondaryDominant: true,
4388
4423
  targetDegree: target.degreeNumber,
4389
4424
  base: SECONDARY_DOMINANT_BASE,
4390
- pcs: _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, _chunkYPB3A3EYcjs.makeChord.call(void 0, rootPc, "dom7"))
4425
+ pcs: _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, _chunk3R3QVKY5cjs.makeChord.call(void 0, rootPc, "dom7"))
4391
4426
  });
4392
4427
  }
4393
- const parallel = _chunkQ6R3QAZDcjs.parallelKey.call(void 0, key);
4394
- const parallelTones = _chunkYPB3A3EYcjs.scaleTonesInDegreeOrder.call(void 0, parallel);
4428
+ const parallel = _chunkIFZDWIKMcjs.parallelKey.call(void 0, key);
4429
+ const parallelTones = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, parallel);
4395
4430
  const borrowed = [];
4396
4431
  for (let degree = 1; degree <= parallelTones.length; degree += 1) {
4397
- const chord = _chunkYPB3A3EYcjs.diatonicTriad.call(void 0, degree, parallel);
4398
- if (!_chunkQ6R3QAZDcjs.isDiatonic.call(void 0, chord, key)) {
4432
+ const chord = _chunk3R3QVKY5cjs.diatonicTriad.call(void 0, degree, parallel);
4433
+ if (!_chunkIFZDWIKMcjs.isDiatonic.call(void 0, chord, key)) {
4399
4434
  borrowed.push(chord);
4400
4435
  }
4401
4436
  }
4402
4437
  const borrowedRank = (chord) => {
4403
- const offset = BORROWED_ENTRY_ORDER.indexOf(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc - tonicPc));
4438
+ const offset = BORROWED_ENTRY_ORDER.indexOf(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - tonicPc));
4404
4439
  return offset < 0 ? BORROWED_ENTRY_ORDER.length : offset;
4405
4440
  };
4406
4441
  borrowed.sort((a, b) => borrowedRank(a) - borrowedRank(b));
@@ -4419,7 +4454,7 @@ function buildCandidates(key, harmonic) {
4419
4454
  // which of the two a phrase took was decided by the tie-break jitter
4420
4455
  // rather than by the melody.
4421
4456
  base: UNSTABLE_QUALITIES.has(chord.quality) ? Math.max(BORROWED_BASE, UNSTABLE_TRIAD) : BORROWED_BASE,
4422
- pcs: _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, chord)
4457
+ pcs: _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord)
4423
4458
  });
4424
4459
  }
4425
4460
  const seen = /* @__PURE__ */ new Set();
@@ -4435,26 +4470,26 @@ function buildCandidates(key, harmonic) {
4435
4470
 
4436
4471
  // src/generate/harmonize/index.ts
4437
4472
  function harmonizeMelody(opts) {
4438
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "harmonize options");
4439
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, opts.melody, "harmonize melody", {
4473
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "harmonize options");
4474
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, opts.melody, "harmonize melody", {
4440
4475
  allowNonPositiveDuration: true,
4441
4476
  budget: opts.budget
4442
4477
  });
4443
4478
  const phraseEnds = _nullishCoalesce(opts.phraseEnds, () => ( []));
4444
4479
  for (const end of phraseEnds) {
4445
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, end, "harmonize phrase end");
4480
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, end, "harmonize phrase end");
4446
4481
  }
4447
- const soundingMelody = _chunkXKSO2V5Icjs.soundingNotesOnly.call(void 0, opts.melody);
4448
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_METER)), "ts"));
4449
- _chunkXKSO2V5Icjs.assertTimeSignature.call(void 0, ts);
4482
+ const soundingMelody = _chunkS5BKZZGMcjs.soundingNotesOnly.call(void 0, opts.melody);
4483
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_METER)), "ts"));
4484
+ _chunkS5BKZZGMcjs.assertTimeSignature.call(void 0, ts);
4450
4485
  const requestedKey = _nullishCoalesce(opts.key, () => ( "infer"));
4451
- const resolvedKey = _chunkYPB3A3EYcjs.resolveKey.call(void 0,
4486
+ const resolvedKey = _chunk3R3QVKY5cjs.resolveKey.call(void 0,
4452
4487
  requestedKey === "infer" ? inferKey(soundingMelody) : requestedKey
4453
4488
  );
4454
4489
  const key = resolvedKey.scale;
4455
4490
  const placement = _nullishCoalesce(opts.placement, () => ( DEFAULT_PLACEMENT));
4456
4491
  const ctx = resolveContext(opts.ctx);
4457
- const reharmonize = _chunkXKSO2V5Icjs.assertOneOf.call(void 0,
4492
+ const reharmonize = _chunkS5BKZZGMcjs.assertOneOf.call(void 0,
4458
4493
  _nullishCoalesce(opts.reharmonize, () => ( "diatonic")),
4459
4494
  REHARMONIZE_STRENGTHS,
4460
4495
  "reharmonize"
@@ -4467,7 +4502,7 @@ function harmonizeMelody(opts) {
4467
4502
  const candAt = (i) => _nullishCoalesce(candidates[i], () => ( FALLBACK));
4468
4503
  const draw = ctx.part("harmony");
4469
4504
  const jitter = candidates.map((_, index) => draw.at("jitter", index) * TIE_BREAK_JITTER2);
4470
- const pulse2 = _chunkXKSO2V5Icjs.pulseBeats.call(void 0, ts);
4505
+ const pulse2 = _chunkS5BKZZGMcjs.pulseBeats.call(void 0, ts);
4471
4506
  const spans = soundingMelody.map((note2) => ({
4472
4507
  startBeat: snapToPulse(note2.startBeat, pulse2),
4473
4508
  endBeat: snapToPulse(note2.startBeat + note2.durationBeat, pulse2)
@@ -4480,7 +4515,7 @@ function harmonizeMelody(opts) {
4480
4515
  (end, span) => Math.max(end, span.endBeat),
4481
4516
  Number.NEGATIVE_INFINITY
4482
4517
  );
4483
- const hr = _chunkXKSO2V5Icjs.assertRange.call(void 0,
4518
+ const hr = _chunkS5BKZZGMcjs.assertRange.call(void 0,
4484
4519
  _nullishCoalesce(opts.harmonicRhythm, () => ( defaultHarmonicRhythm(ts))),
4485
4520
  Number.MIN_VALUE,
4486
4521
  Number.MAX_SAFE_INTEGER,
@@ -4509,7 +4544,7 @@ function harmonizeMelody(opts) {
4509
4544
  }
4510
4545
  const octaveShifts = placement.octaveSearch ? [0, -12, 12] : [0];
4511
4546
  const transposes = semitoneShifts.flatMap((s) => octaveShifts.map((o) => s + o));
4512
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0,
4547
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
4513
4548
  transposes.length * segments.length * candidates.length * candidates.length,
4514
4549
  "harmonization placement search",
4515
4550
  opts.budget
@@ -4555,8 +4590,8 @@ function harmonizeMelody(opts) {
4555
4590
  const melodyRoles = opts.melody.map((note2, noteIndex) => {
4556
4591
  const segIdx = segmentIndexAt(bounds, snapToPulse(note2.startBeat, pulse2));
4557
4592
  const cand = candAt(_nullishCoalesce(bestPath[segIdx], () => ( 0)));
4558
- const chord = _chunkYPB3A3EYcjs.makeChord.call(void 0, cand.rootPc, cand.quality);
4559
- return { noteIndex, role: _chunkR7B5N2JKcjs.roleOf.call(void 0, note2.pitch + bestTs, chord).role };
4593
+ const chord = _chunk3R3QVKY5cjs.makeChord.call(void 0, cand.rootPc, cand.quality);
4594
+ return { noteIndex, role: _chunkPM4XJE2Ycjs.roleOf.call(void 0, note2.pitch + bestTs, chord).role };
4560
4595
  });
4561
4596
  return { transposeSemitones: bestTs, key: resolvedKey, chords, melodyRoles };
4562
4597
  }
@@ -4575,15 +4610,15 @@ var MIN_TILE_SPAN = 1 / 256;
4575
4610
  var DEFAULT_TS4 = { numerator: 4, denominator: 4 };
4576
4611
  function isDownbeat(startBeat, barBeats) {
4577
4612
  const bar2 = startBeat / barBeats;
4578
- return Math.abs(bar2 - Math.round(bar2)) < _chunkXKSO2V5Icjs.BEAT_EPS;
4613
+ return Math.abs(bar2 - Math.round(bar2)) < _chunkS5BKZZGMcjs.BEAT_EPS;
4579
4614
  }
4580
4615
  function nearestChordTone(pitch, chord) {
4581
- const pcs = _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, chord);
4616
+ const pcs = _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord);
4582
4617
  for (let d = 0; d <= 12; d += 1) {
4583
- if (pcs.includes(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, pitch - d))) {
4618
+ if (pcs.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch - d))) {
4584
4619
  return pitch - d;
4585
4620
  }
4586
- if (pcs.includes(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, pitch + d))) {
4621
+ if (pcs.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch + d))) {
4587
4622
  return pitch + d;
4588
4623
  }
4589
4624
  }
@@ -4663,20 +4698,20 @@ function contourOffsets(contour, count) {
4663
4698
  return offsets;
4664
4699
  }
4665
4700
  function generateMotif(opts) {
4666
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "motif options");
4701
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "motif options");
4667
4702
  const contour = _nullishCoalesce(opts.contour, () => ( "arch"));
4668
- const bars = _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, opts.bars, "motif bars");
4669
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS4)), "ts")));
4703
+ const bars = _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, opts.bars, "motif bars");
4704
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS4)), "ts")));
4670
4705
  const totalBeats = bars * barBeats;
4671
4706
  const noteCount = Math.max(3, bars * 2);
4672
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, noteCount, "motif notes");
4707
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount, "motif notes");
4673
4708
  const beatsPerNote = totalBeats / noteCount;
4674
4709
  const ctx = resolveContextWith(opts.ctx, { ornament: opts.jitter });
4675
4710
  const jitterProb = _nullishCoalesce(ctx.ornament, () => ( 0));
4676
4711
  const draw = ctx.part("motif");
4677
- const key = _chunkYPB3A3EYcjs.toKeyScale.call(void 0, opts.key);
4678
- const chord = opts.chord ? _chunkYPB3A3EYcjs.toChordData.call(void 0, opts.chord) : null;
4679
- const tonic = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, key.rootPc) + 60;
4712
+ const key = _chunk3R3QVKY5cjs.toKeyScale.call(void 0, opts.key);
4713
+ const chord = opts.chord ? _chunk3R3QVKY5cjs.toChordData.call(void 0, opts.chord) : null;
4714
+ const tonic = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc) + 60;
4680
4715
  const offsets = contourOffsets(contour, noteCount);
4681
4716
  const notes = [];
4682
4717
  for (let i = 0; i < noteCount; i += 1) {
@@ -4684,13 +4719,13 @@ function generateMotif(opts) {
4684
4719
  if (draw.prob(jitterProb, "jitter", i)) {
4685
4720
  jitter = draw.prob(0.5, "direction", i) ? 1 : -1;
4686
4721
  }
4687
- let pitch = _chunkYPB3A3EYcjs.shiftByScaleDegrees.call(void 0, tonic, (_nullishCoalesce(offsets[i], () => ( 0))) + jitter, key);
4722
+ let pitch = _chunk3R3QVKY5cjs.shiftByScaleDegrees.call(void 0, tonic, (_nullishCoalesce(offsets[i], () => ( 0))) + jitter, key);
4688
4723
  const startBeat = i * beatsPerNote;
4689
4724
  if (chord && isDownbeat(startBeat, barBeats)) {
4690
4725
  pitch = nearestChordTone(pitch, chord);
4691
4726
  }
4692
4727
  notes.push({
4693
- pitch: _chunkXKSO2V5Icjs.clampToMidi.call(void 0, pitch, "generated motif pitch"),
4728
+ pitch: _chunkS5BKZZGMcjs.clampToMidi.call(void 0, pitch, "generated motif pitch"),
4694
4729
  startBeat,
4695
4730
  durationBeat: beatsPerNote
4696
4731
  });
@@ -4701,12 +4736,12 @@ function motifToNoteEvents(cell) {
4701
4736
  return assertCellNotes(cell, "motif cell notes").map((note2) => ({ ...note2 }));
4702
4737
  }
4703
4738
  function assertCellNotes(cell, name) {
4704
- const read = _chunkXKSO2V5Icjs.assertRecord.call(void 0, cell, "motif cell");
4705
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, read.notes, name);
4739
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, cell, "motif cell");
4740
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, read.notes, name);
4706
4741
  return read.notes;
4707
4742
  }
4708
4743
  function transformMotif(cell, t, amount, key) {
4709
- return transformCell(cell, t, amount, key === void 0 ? void 0 : _chunkYPB3A3EYcjs.toKeyScale.call(void 0, key));
4744
+ return transformCell(cell, t, amount, key === void 0 ? void 0 : _chunk3R3QVKY5cjs.toKeyScale.call(void 0, key));
4710
4745
  }
4711
4746
  function transformCell(cell, t, amount, key) {
4712
4747
  return assertInRange(inTimeOrder(transformUnchecked(cell, t, amount, key)));
@@ -4714,7 +4749,7 @@ function transformCell(cell, t, amount, key) {
4714
4749
  function assertInRange(cell) {
4715
4750
  for (const note2 of cell.notes) {
4716
4751
  if (note2.pitch < 0 || note2.pitch > 127) {
4717
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
4752
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
4718
4753
  `transformed motif pitch ${note2.pitch} is outside the MIDI range 0..127`
4719
4754
  );
4720
4755
  }
@@ -4723,18 +4758,18 @@ function assertInRange(cell) {
4723
4758
  }
4724
4759
  function transformUnchecked(cell, t, amount, key) {
4725
4760
  const notes = assertCellNotes(cell, "motif notes");
4726
- _chunkXKSO2V5Icjs.assertOneOf.call(void 0, t, MOTIF_TRANSFORMS, "motif transform");
4761
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, t, MOTIF_TRANSFORMS, "motif transform");
4727
4762
  if (amount !== void 0) {
4728
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, amount, "motif transform amount");
4763
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, amount, "motif transform amount");
4729
4764
  }
4730
4765
  if ((t === "transposeChromatic" || t === "transposeDiatonic" || t === "sequence") && amount !== void 0) {
4731
- _chunkXKSO2V5Icjs.assertInteger.call(void 0,
4766
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0,
4732
4767
  amount,
4733
4768
  `${t === "transposeChromatic" ? "chromatic" : "diatonic"} transform amount`
4734
4769
  );
4735
4770
  }
4736
4771
  if ((t === "augment" || t === "diminish") && amount !== void 0 && amount <= 0) {
4737
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)("time transform amount must be positive");
4772
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("time transform amount must be positive");
4738
4773
  }
4739
4774
  switch (t) {
4740
4775
  case "transposeChromatic": {
@@ -4752,7 +4787,7 @@ function transformUnchecked(cell, t, amount, key) {
4752
4787
  // notes a motif is written with — a blues lick, a semitone neighbour —
4753
4788
  // come through as themselves, and shifting by no degrees returns the
4754
4789
  // cell it was given.
4755
- pitch: key ? _chunkYPB3A3EYcjs.shiftByScaleDegrees.call(void 0, n.pitch, degrees, key) : n.pitch + degrees
4790
+ pitch: key ? _chunk3R3QVKY5cjs.shiftByScaleDegrees.call(void 0, n.pitch, degrees, key) : n.pitch + degrees
4756
4791
  }))
4757
4792
  };
4758
4793
  }
@@ -4798,13 +4833,13 @@ function scaleTime(cell, factor) {
4798
4833
  };
4799
4834
  }
4800
4835
  function developMotif(cell, timeline, key, bars, ts) {
4801
- const meter = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts"));
4802
- _chunkQ6R3QAZDcjs.assertChordTimeline.call(void 0, timeline);
4803
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, bars, "development bars");
4836
+ const meter = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts"));
4837
+ _chunkIFZDWIKMcjs.assertChordTimeline.call(void 0, timeline);
4838
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, bars, "development bars");
4804
4839
  const cellNotes = assertCellNotes(cell, "motif notes");
4805
- const scale = _chunkYPB3A3EYcjs.toKeyScale.call(void 0, key);
4840
+ const scale = _chunk3R3QVKY5cjs.toKeyScale.call(void 0, key);
4806
4841
  const span = cellSpan(cell);
4807
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, meter);
4842
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, meter);
4808
4843
  const totalBeats = bars * barBeats;
4809
4844
  const origin = cellOrigin(cellNotes);
4810
4845
  const out = [];
@@ -4813,7 +4848,7 @@ function developMotif(cell, timeline, key, bars, ts) {
4813
4848
  }
4814
4849
  const tileSpan = Math.max(span, MIN_TILE_SPAN);
4815
4850
  const tileCount = Math.ceil(totalBeats / tileSpan);
4816
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, tileCount * cellNotes.length, "developed motif notes");
4851
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, tileCount * cellNotes.length, "developed motif notes");
4817
4852
  for (let k = 0; k < tileCount; k += 1) {
4818
4853
  const offset = k * tileSpan;
4819
4854
  const taken = /* @__PURE__ */ new Map();
@@ -4825,8 +4860,8 @@ function developMotif(cell, timeline, key, bars, ts) {
4825
4860
  }
4826
4861
  const chord = timeline.at(startBeat);
4827
4862
  const structural = n.startBeat === origin || isDownbeat(startBeat, barBeats);
4828
- const chordTones = chord && structural ? _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, chord) : null;
4829
- const allows = chordTones ? (candidate) => chordTones.includes(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, candidate)) : (candidate) => _chunkYPB3A3EYcjs.isScaleTone.call(void 0, candidate, scale);
4863
+ const chordTones = chord && structural ? _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord) : null;
4864
+ const allows = chordTones ? (candidate) => chordTones.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, candidate)) : (candidate) => _chunk3R3QVKY5cjs.isScaleTone.call(void 0, candidate, scale);
4830
4865
  const direction = previous === void 0 ? 0 : n.pitch - previous;
4831
4866
  const pitch = developedPitch(n.pitch, allows, direction, taken);
4832
4867
  taken.set(pitch, n.pitch);
@@ -4837,6 +4872,1063 @@ function developMotif(cell, timeline, key, bars, ts) {
4837
4872
  return inTimeOrder({ notes: out });
4838
4873
  }
4839
4874
 
4875
+ // src/generate/plan/internal.ts
4876
+ var STRONG_WEIGHT = 2;
4877
+ function positionClass(beat, meters) {
4878
+ const weight = _chunkS5BKZZGMcjs.metricWeight.call(void 0, beat, meters);
4879
+ return weight >= STRONG_WEIGHT ? "strong" : weight > 0 ? "weak" : "off";
4880
+ }
4881
+
4882
+ // src/generate/plan/types.ts
4883
+ var COMPOSITION_PLAN_VERSION = 1;
4884
+ function tent(t, apex) {
4885
+ if (t <= apex) {
4886
+ return apex === 0 ? 1 : -1 + 2 * t / apex;
4887
+ }
4888
+ return apex === 1 ? 1 : 1 - 2 * (t - apex) / (1 - apex);
4889
+ }
4890
+ function plannedContourAt(shape, peakPosition, t) {
4891
+ switch (shape) {
4892
+ case "arch":
4893
+ return tent(t, peakPosition);
4894
+ case "ascending":
4895
+ return -1 + 2 * t;
4896
+ case "descending":
4897
+ return 1 - 2 * t;
4898
+ case "wave":
4899
+ return t < 0.5 ? tent(2 * t, 0.5) : tent(2 * t - 1, 0.5);
4900
+ case "static":
4901
+ return 0;
4902
+ }
4903
+ }
4904
+
4905
+ // src/generate/plan/validate.ts
4906
+ var MASS_TOLERANCE = 1e-9;
4907
+ function assertString(value, name) {
4908
+ if (typeof value !== "string") {
4909
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be a string; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, value)}`);
4910
+ }
4911
+ return value;
4912
+ }
4913
+ function assertSpanOrder(startBeat, endBeat, name) {
4914
+ if (endBeat < startBeat) {
4915
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
4916
+ `${name}.endBeat must be at least ${name}.startBeat; received ${endBeat} < ${startBeat}`
4917
+ );
4918
+ }
4919
+ }
4920
+ function assertNullable(value, name, validate) {
4921
+ if (value === void 0) {
4922
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be present; received undefined`);
4923
+ }
4924
+ return value === null ? null : validate(value, name);
4925
+ }
4926
+ function assertMassDistribution(value, length, name) {
4927
+ const shares = _chunkS5BKZZGMcjs.assertArray.call(void 0, value, name);
4928
+ if (shares.length !== length) {
4929
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must have length ${length}; received ${shares.length}`);
4930
+ }
4931
+ let sum = 0;
4932
+ for (let index = 0; index < shares.length; index += 1) {
4933
+ const share = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, shares[index], `${name}[${index}]`);
4934
+ if (share < 0) {
4935
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}[${index}] must be at least 0; received ${share}`);
4936
+ }
4937
+ sum += share;
4938
+ }
4939
+ if (Math.abs(sum - 1) > MASS_TOLERANCE) {
4940
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must sum to 1; received ${sum}`);
4941
+ }
4942
+ return shares;
4943
+ }
4944
+ function assertResolvedKeyField(value, name) {
4945
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
4946
+ try {
4947
+ _chunk3R3QVKY5cjs.resolveKey.call(void 0, read);
4948
+ } catch (error) {
4949
+ if (error instanceof _chunkS5BKZZGMcjs.InvalidInputError) {
4950
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be a valid key: ${error.message}`);
4951
+ }
4952
+ throw error;
4953
+ }
4954
+ return read;
4955
+ }
4956
+ function assertPlannedSection(value, name) {
4957
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
4958
+ assertString(read.label, `${name}.label`);
4959
+ const startBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.startBeat, `${name}.startBeat`);
4960
+ const endBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.endBeat, `${name}.endBeat`);
4961
+ assertSpanOrder(startBeat, endBeat, name);
4962
+ return read;
4963
+ }
4964
+ function assertPlannedPhrase(value, name, sectionCount, motifCount) {
4965
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
4966
+ const startBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.startBeat, `${name}.startBeat`);
4967
+ const endBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.endBeat, `${name}.endBeat`);
4968
+ assertSpanOrder(startBeat, endBeat, name);
4969
+ assertNullable(
4970
+ read.section,
4971
+ `${name}.section`,
4972
+ (v, n) => _chunkS5BKZZGMcjs.assertInteger.call(void 0, v, n, 0, Math.max(sectionCount - 1, 0))
4973
+ );
4974
+ assertNullable(read.cadence, `${name}.cadence`, (v, n) => _chunkS5BKZZGMcjs.assertOneOf.call(void 0, v, _chunkIFZDWIKMcjs.CADENCE_TYPES, n));
4975
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, read.shape, _chunkIFZDWIKMcjs.MELODIC_CONTOUR_SHAPES, `${name}.shape`);
4976
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, read.peakPosition, 0, 1, `${name}.peakPosition`);
4977
+ const register = _chunkS5BKZZGMcjs.assertRecord.call(void 0,
4978
+ read.register,
4979
+ `${name}.register`
4980
+ );
4981
+ _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, register.low, `${name}.register.low`);
4982
+ _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, register.high, `${name}.register.high`);
4983
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, register.mean, 0, 127, `${name}.register.mean`);
4984
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, read.onsetDensity, 0, Number.MAX_SAFE_INTEGER, `${name}.onsetDensity`);
4985
+ const motifs = _chunkS5BKZZGMcjs.assertArray.call(void 0, read.motifs, `${name}.motifs`);
4986
+ for (let index = 0; index < motifs.length; index += 1) {
4987
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0,
4988
+ motifs[index],
4989
+ `${name}.motifs[${index}]`,
4990
+ 0,
4991
+ Math.max(motifCount - 1, 0)
4992
+ );
4993
+ }
4994
+ return read;
4995
+ }
4996
+ function assertPlannedChord(value, name, keys) {
4997
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
4998
+ const startBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.startBeat, `${name}.startBeat`);
4999
+ const endBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.endBeat, `${name}.endBeat`);
5000
+ assertSpanOrder(startBeat, endBeat, name);
5001
+ const keyIndex = _chunkS5BKZZGMcjs.assertInteger.call(void 0, read.key, `${name}.key`, 0, Math.max(keys.length - 1, 0));
5002
+ const roman = assertString(read.roman, `${name}.roman`);
5003
+ try {
5004
+ _chunkIFZDWIKMcjs.romanToChord.call(void 0, roman, keys[keyIndex]);
5005
+ } catch (error) {
5006
+ if (error instanceof _chunkS5BKZZGMcjs.InvalidInputError) {
5007
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5008
+ `${name}.roman must be readable by romanToChord; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, roman)}: ${error.message}`
5009
+ );
5010
+ }
5011
+ throw error;
5012
+ }
5013
+ return read;
5014
+ }
5015
+ function assertPlannedMotifRelation(value, name) {
5016
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
5017
+ _chunkS5BKZZGMcjs.assertOneOf.call(void 0, read.kind, _chunkIFZDWIKMcjs.MOTIF_RELATION_KINDS, `${name}.kind`);
5018
+ _chunkS5BKZZGMcjs.assertFlag.call(void 0, read.sequence, `${name}.sequence`);
5019
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.semitones, `${name}.semitones`);
5020
+ if (read.kind === "tonalTransposition") {
5021
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.degrees, `${name}.degrees`);
5022
+ } else if (read.degrees !== void 0) {
5023
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.degrees, `${name}.degrees`);
5024
+ }
5025
+ const timeRatio = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.timeRatio, `${name}.timeRatio`);
5026
+ if (timeRatio <= 0) {
5027
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}.timeRatio must be positive; received ${timeRatio}`);
5028
+ }
5029
+ return read;
5030
+ }
5031
+ function assertPlannedMotif(value, name, ownIndex, motifCount, phraseCount) {
5032
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
5033
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, read.phrase, `${name}.phrase`, 0, Math.max(phraseCount - 1, 0));
5034
+ const startBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.startBeat, `${name}.startBeat`);
5035
+ const endBeat = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.endBeat, `${name}.endBeat`);
5036
+ assertSpanOrder(startBeat, endBeat, name);
5037
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, read.notes, `${name}.notes`);
5038
+ const from = assertNullable(
5039
+ read.from,
5040
+ `${name}.from`,
5041
+ (v, n) => _chunkS5BKZZGMcjs.assertInteger.call(void 0, v, n, 0, Math.max(motifCount - 1, 0))
5042
+ );
5043
+ if (from !== null && from >= ownIndex) {
5044
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5045
+ `${name}.from must be less than this motif's own index (${ownIndex}); received ${from}`
5046
+ );
5047
+ }
5048
+ const relation = assertNullable(read.relation, `${name}.relation`, assertPlannedMotifRelation);
5049
+ if (from === null && relation !== null) {
5050
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5051
+ `${name}.relation must be null for a root motif (from = null); received a relation`
5052
+ );
5053
+ }
5054
+ const rhythm = assertNullable(read.rhythm, `${name}.rhythm`, (v, n) => _chunkS5BKZZGMcjs.assertArray.call(void 0, v, n));
5055
+ if (rhythm !== null) {
5056
+ if (from !== null) {
5057
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}.rhythm must be null for a derived statement`);
5058
+ }
5059
+ if (rhythm.length !== read.notes - 1) {
5060
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5061
+ `${name}.rhythm must hold notes - 1 (${read.notes - 1}) gaps; received ${rhythm.length}`
5062
+ );
5063
+ }
5064
+ let total = 0;
5065
+ for (let index = 0; index < rhythm.length; index += 1) {
5066
+ const gap = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, rhythm[index], `${name}.rhythm[${index}]`);
5067
+ if (gap <= 0) {
5068
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}.rhythm[${index}] must be positive; received ${gap}`);
5069
+ }
5070
+ total += gap;
5071
+ }
5072
+ if (total >= endBeat - startBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
5073
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5074
+ `${name}.rhythm must sum to less than the statement's length (${endBeat - startBeat}); received ${total}`
5075
+ );
5076
+ }
5077
+ }
5078
+ return read;
5079
+ }
5080
+ function assertPlannedRhythm(value, name) {
5081
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
5082
+ assertMassDistribution(read.onsetLevels, 6, `${name}.onsetLevels`);
5083
+ assertMassDistribution(read.interOnsetShares, _chunkIFZDWIKMcjs.RHYTHM_IOI_BINS.length, `${name}.interOnsetShares`);
5084
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, read.syncopation, 0, 1, `${name}.syncopation`);
5085
+ return read;
5086
+ }
5087
+ function assertCompositionPlan(value, name = "composition plan") {
5088
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, name);
5089
+ if (read.planVersion !== COMPOSITION_PLAN_VERSION) {
5090
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5091
+ `${name}.planVersion must be ${COMPOSITION_PLAN_VERSION}; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, read.planVersion)}`
5092
+ );
5093
+ }
5094
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, read.seed, `${name}.seed`, 0, 4294967295);
5095
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0,
5096
+ read.algorithmVersion,
5097
+ `${name}.algorithmVersion`,
5098
+ _chunkCGBADIO5cjs.MIN_ALGORITHM_VERSION,
5099
+ _chunkCGBADIO5cjs.ALGORITHM_VERSION
5100
+ );
5101
+ const keys = _chunkS5BKZZGMcjs.assertArray.call(void 0, read.keys, `${name}.keys`);
5102
+ if (keys.length === 0) {
5103
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}.keys must hold at least one key; received an empty array`);
5104
+ }
5105
+ for (let index = 0; index < keys.length; index += 1) {
5106
+ assertResolvedKeyField(keys[index], `${name}.keys[${index}]`);
5107
+ }
5108
+ _chunkS5BKZZGMcjs.assertMeterMap.call(void 0, read.meters, `${name}.meters`);
5109
+ const span = _chunkS5BKZZGMcjs.assertRecord.call(void 0,
5110
+ read.span,
5111
+ `${name}.span`
5112
+ );
5113
+ const spanStart = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, span.startBeat, `${name}.span.startBeat`);
5114
+ const spanEnd = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, span.endBeat, `${name}.span.endBeat`);
5115
+ assertSpanOrder(spanStart, spanEnd, `${name}.span`);
5116
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, span.bars, 0, Number.MAX_SAFE_INTEGER, `${name}.span.bars`);
5117
+ const sections = _chunkS5BKZZGMcjs.assertArray.call(void 0, read.sections, `${name}.sections`);
5118
+ for (let index = 0; index < sections.length; index += 1) {
5119
+ assertPlannedSection(sections[index], `${name}.sections[${index}]`);
5120
+ }
5121
+ const phrases = _chunkS5BKZZGMcjs.assertArray.call(void 0, read.phrases, `${name}.phrases`);
5122
+ const motifs = _chunkS5BKZZGMcjs.assertArray.call(void 0, read.motifs, `${name}.motifs`);
5123
+ for (let index = 0; index < phrases.length; index += 1) {
5124
+ assertPlannedPhrase(
5125
+ phrases[index],
5126
+ `${name}.phrases[${index}]`,
5127
+ sections.length,
5128
+ motifs.length
5129
+ );
5130
+ }
5131
+ const harmony = _chunkS5BKZZGMcjs.assertArray.call(void 0, read.harmony, `${name}.harmony`);
5132
+ for (let index = 0; index < harmony.length; index += 1) {
5133
+ assertPlannedChord(harmony[index], `${name}.harmony[${index}]`, keys);
5134
+ }
5135
+ for (let index = 0; index < motifs.length; index += 1) {
5136
+ assertPlannedMotif(
5137
+ motifs[index],
5138
+ `${name}.motifs[${index}]`,
5139
+ index,
5140
+ motifs.length,
5141
+ phrases.length
5142
+ );
5143
+ }
5144
+ assertPlannedRhythm(read.rhythm, `${name}.rhythm`);
5145
+ return read;
5146
+ }
5147
+
5148
+ // src/generate/plan/timeline.ts
5149
+ function planTimeline(plan) {
5150
+ return planChordTimeline(assertCompositionPlan(plan));
5151
+ }
5152
+ function planChordTimeline(plan) {
5153
+ const spans = plan.harmony.map((chord) => {
5154
+ const key = plan.keys[chord.key];
5155
+ return _chunk3R3QVKY5cjs.spanFromChord.call(void 0, _chunkIFZDWIKMcjs.romanToChord.call(void 0, chord.roman, key), chord.startBeat);
5156
+ });
5157
+ return _chunkIFZDWIKMcjs.chordTimelineFromChords.call(void 0, spans, plan.span.endBeat);
5158
+ }
5159
+
5160
+ // src/generate/plan/harmony.ts
5161
+ var HARMONY_OK_KINDS = /* @__PURE__ */ new Set([
5162
+ "chordTone",
5163
+ "tension",
5164
+ "suspension",
5165
+ "appoggiatura",
5166
+ "anticipation",
5167
+ "passing",
5168
+ "neighbor"
5169
+ ]);
5170
+ var CADENCE_DEGREES = {
5171
+ authentic: [1, 3],
5172
+ plagal: [1, 3],
5173
+ half: [2, 5, 7],
5174
+ phrygian: [2, 5, 7],
5175
+ modal: [1]
5176
+ };
5177
+ function planKeyAt(plan) {
5178
+ const regions = [...plan.harmony].sort((a, b) => a.startBeat - b.startBeat).map((chord) => ({
5179
+ startBeat: chord.startBeat,
5180
+ endBeat: chord.endBeat,
5181
+ key: plan.keys[chord.key],
5182
+ confidence: 1
5183
+ }));
5184
+ return _chunkIFZDWIKMcjs.keyLookup.call(void 0, regions, plan.keys[0]);
5185
+ }
5186
+ function cadencePitchClasses(plan, timeline, cadence, beat) {
5187
+ if (cadence === "deceptive") {
5188
+ const chord = timeline.at(beat);
5189
+ return chord === null ? null : _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord);
5190
+ }
5191
+ const entry = plan.harmony.find((chord) => beat >= chord.startBeat && beat < chord.endBeat);
5192
+ const tones = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, _chunk3R3QVKY5cjs.scaleOf.call(void 0, plan.keys[_nullishCoalesce(_optionalChain([entry, 'optionalAccess', _59 => _59.key]), () => ( 0))]));
5193
+ return CADENCE_DEGREES[cadence].map((degree) => tones[degree - 1]).filter((pc) => pc !== void 0);
5194
+ }
5195
+ function planHarmonyMisfits(plan, timeline = planChordTimeline(plan)) {
5196
+ const keyAt = planKeyAt(plan);
5197
+ const scaleAt2 = (beat) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat));
5198
+ return (line) => {
5199
+ const analyzed = _chunkIFZDWIKMcjs.analyzeVoice.call(void 0, line, timeline.at, scaleAt2);
5200
+ return line.map((note2, index) => {
5201
+ const position = positionClass(note2.startBeat, plan.meters);
5202
+ if (position === "off") {
5203
+ return null;
5204
+ }
5205
+ const kinds = (_nullishCoalesce(_optionalChain([analyzed, 'access', _60 => _60[index], 'optionalAccess', _61 => _61.labels]), () => ( []))).map((label) => label.kind);
5206
+ if (kinds.some((kind) => HARMONY_OK_KINDS.has(kind))) {
5207
+ return null;
5208
+ }
5209
+ return position === "weak" && _chunk3R3QVKY5cjs.isScaleTone.call(void 0, note2.pitch, scaleAt2(note2.startBeat)) ? null : kinds;
5210
+ });
5211
+ };
5212
+ }
5213
+
5214
+ // src/generate/melody/pitch-dp.ts
5215
+ var NO_LEAP = 0;
5216
+ var LEAP_UP = 1;
5217
+ var LEAP_DOWN = 2;
5218
+ var LEAP_STATES = 3;
5219
+ var SEARCH_LABEL = "melody pitch search";
5220
+ var WIDEST_THIRD = 4;
5221
+ var LEAP_CONTINUATION_COST = 0.5;
5222
+ function intervalCost(size) {
5223
+ if (size === 0) {
5224
+ return 0.2;
5225
+ }
5226
+ if (size <= 2) {
5227
+ return 0;
5228
+ }
5229
+ if (size <= WIDEST_THIRD) {
5230
+ return 0.3;
5231
+ }
5232
+ if (size <= 7) {
5233
+ return 0.6;
5234
+ }
5235
+ return 1;
5236
+ }
5237
+ function leapOf(delta) {
5238
+ if (Math.abs(delta) <= WIDEST_THIRD) {
5239
+ return NO_LEAP;
5240
+ }
5241
+ return delta > 0 ? LEAP_UP : LEAP_DOWN;
5242
+ }
5243
+ function stepCost(from, to, leap, bothFixed) {
5244
+ const delta = to - from;
5245
+ const size = Math.abs(delta);
5246
+ if (!bothFixed && _chunk3R3QVKY5cjs.isForbiddenMelodicLeap.call(void 0, from, to)) {
5247
+ return Number.POSITIVE_INFINITY;
5248
+ }
5249
+ let cost = intervalCost(size);
5250
+ if (leap === LEAP_UP && delta > 0 || leap === LEAP_DOWN && delta < 0) {
5251
+ cost += LEAP_CONTINUATION_COST;
5252
+ }
5253
+ return cost;
5254
+ }
5255
+ function searchPitches(slots, budget, extra) {
5256
+ const first = slots[0];
5257
+ if (first === void 0) {
5258
+ return [];
5259
+ }
5260
+ let previous = _chunkS5BKZZGMcjs.allocateCandidateTable.call(void 0,
5261
+ first.candidates.length,
5262
+ LEAP_STATES,
5263
+ SEARCH_LABEL,
5264
+ budget
5265
+ ).fill(Number.POSITIVE_INFINITY);
5266
+ for (let j = 0; j < first.candidates.length; j += 1) {
5267
+ previous[j * LEAP_STATES + NO_LEAP] = first.cost(first.candidates[j]);
5268
+ }
5269
+ const backs = [];
5270
+ for (let k = 1; k < slots.length; k += 1) {
5271
+ const before = slots[k - 1];
5272
+ const slot = slots[k];
5273
+ const unary = slot.candidates.map((pitch) => slot.cost(pitch));
5274
+ const current = _chunkS5BKZZGMcjs.allocateCandidateTable.call(void 0,
5275
+ slot.candidates.length,
5276
+ LEAP_STATES,
5277
+ SEARCH_LABEL,
5278
+ budget
5279
+ ).fill(Number.POSITIVE_INFINITY);
5280
+ const back = _chunkS5BKZZGMcjs.allocateChoiceTable.call(void 0,
5281
+ slot.candidates.length,
5282
+ LEAP_STATES,
5283
+ SEARCH_LABEL,
5284
+ budget
5285
+ ).fill(-1);
5286
+ const bothFixed = before.fixed && slot.fixed;
5287
+ for (let state2 = 0; state2 < previous.length; state2 += 1) {
5288
+ const reached = previous[state2];
5289
+ if (reached === Number.POSITIVE_INFINITY) {
5290
+ continue;
5291
+ }
5292
+ const from = before.candidates[Math.floor(state2 / LEAP_STATES)];
5293
+ const leap = state2 % LEAP_STATES;
5294
+ for (let j = 0; j < slot.candidates.length; j += 1) {
5295
+ const to = slot.candidates[j];
5296
+ const step = stepCost(from, to, leap, bothFixed);
5297
+ if (step === Number.POSITIVE_INFINITY) {
5298
+ continue;
5299
+ }
5300
+ const total = reached + step + unary[j] + (extra ? extra(k, from, to) : 0);
5301
+ const index = j * LEAP_STATES + leapOf(to - from);
5302
+ if (total < current[index]) {
5303
+ current[index] = total;
5304
+ back[index] = state2;
5305
+ }
5306
+ }
5307
+ }
5308
+ backs.push(back);
5309
+ previous = current;
5310
+ }
5311
+ let best = -1;
5312
+ for (let state2 = 0; state2 < previous.length; state2 += 1) {
5313
+ if (previous[state2] < Number.POSITIVE_INFINITY && (best < 0 || previous[state2] < previous[best])) {
5314
+ best = state2;
5315
+ }
5316
+ }
5317
+ if (best < 0) {
5318
+ return null;
5319
+ }
5320
+ const pitches = new Array(slots.length);
5321
+ let state = best;
5322
+ for (let k = slots.length - 1; k >= 0; k -= 1) {
5323
+ pitches[k] = slots[k].candidates[Math.floor(state / LEAP_STATES)];
5324
+ if (k > 0) {
5325
+ state = backs[k - 1][state];
5326
+ }
5327
+ }
5328
+ return pitches;
5329
+ }
5330
+
5331
+ // src/generate/melody/derive.ts
5332
+ var VARIATION_STEP_COST = 0.2;
5333
+ var OCTAVE = 12;
5334
+ var LEVEL_TARGET_COST = 0.1;
5335
+ var LEVEL_PLAN_COST = 0.02;
5336
+ var LEVEL_REACH = 24;
5337
+ var TONAL_LEVEL_REACH = 14;
5338
+ function stretched(cell, timeRatio) {
5339
+ return timeRatio === 1 ? cell : transformMotif(cell, "augment", timeRatio);
5340
+ }
5341
+ function shaped(cell, relation) {
5342
+ switch (relation.kind) {
5343
+ case "repetition":
5344
+ case "tonalTransposition":
5345
+ return cell;
5346
+ case "transposition":
5347
+ return stretched(cell, relation.timeRatio);
5348
+ case "inversion":
5349
+ return stretched(transformMotif(cell, "invert"), relation.timeRatio);
5350
+ case "retrograde":
5351
+ return transformMotif(cell, "retrograde");
5352
+ case "retrogradeInversion":
5353
+ return transformMotif(transformMotif(cell, "invert"), "retrograde");
5354
+ case "augmentation":
5355
+ return transformMotif(cell, "augment", relation.timeRatio);
5356
+ case "diminution":
5357
+ return transformMotif(cell, "diminish", 1 / relation.timeRatio);
5358
+ }
5359
+ }
5360
+ function relationLevels(kind, low = -LEVEL_REACH, high = LEVEL_REACH) {
5361
+ const between = (from, to, skipZero) => {
5362
+ const levels = [];
5363
+ for (let level = Math.ceil(from); level <= to; level += 1) {
5364
+ if (!(skipZero && level === 0)) levels.push(level);
5365
+ }
5366
+ return levels;
5367
+ };
5368
+ switch (kind) {
5369
+ case "repetition":
5370
+ case "augmentation":
5371
+ case "diminution":
5372
+ return [-OCTAVE, 0, OCTAVE];
5373
+ case "transposition":
5374
+ return between(low, high, true);
5375
+ case "tonalTransposition":
5376
+ return between(-TONAL_LEVEL_REACH, TONAL_LEVEL_REACH, true);
5377
+ case "inversion":
5378
+ case "retrograde":
5379
+ case "retrogradeInversion":
5380
+ return between(low, high, false);
5381
+ }
5382
+ }
5383
+ function replayAt(source, relation, level, startBeat, key) {
5384
+ const head = source[0];
5385
+ const cell = shaped({ notes: source.map((n) => ({ ...n })) }, relation);
5386
+ const first = cell.notes[0];
5387
+ const offset = startBeat - first.startBeat;
5388
+ const shift = head.pitch + level - first.pitch;
5389
+ return cell.notes.map((n) => ({
5390
+ ...n,
5391
+ pitch: relation.kind === "tonalTransposition" ? _chunk3R3QVKY5cjs.shiftByScaleDegrees.call(void 0, n.pitch, level, key) : n.pitch + shift,
5392
+ startBeat: n.startBeat + offset
5393
+ }));
5394
+ }
5395
+ function clipStatement(notes, endBeat) {
5396
+ return notes.filter((n) => n.startBeat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS).map((n) => ({ ...n, durationBeat: Math.min(n.durationBeat, endBeat - n.startBeat) }));
5397
+ }
5398
+ function outsideCount(notes, frame) {
5399
+ return notes.filter((n) => n.pitch < frame.low || n.pitch > frame.high).length;
5400
+ }
5401
+ function nearerLevel(level, best, planned) {
5402
+ const distance = Math.abs(level - planned);
5403
+ const bestDistance = Math.abs(best - planned);
5404
+ return distance < bestDistance || distance === bestDistance && level < best;
5405
+ }
5406
+ function repairStatement(notes, forced, frame) {
5407
+ const slots = notes.map(
5408
+ (n, index) => forced[index] ? {
5409
+ candidates: frame.candidatesAt(n.startBeat),
5410
+ cost: frame.costAt(n.startBeat),
5411
+ fixed: false
5412
+ } : { candidates: [n.pitch], cost: () => 0, fixed: true }
5413
+ );
5414
+ const pitches = searchPitches(slots, frame.budget);
5415
+ if (pitches === null) {
5416
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(
5417
+ `no repair fits the statement into the register ${frame.low}..${frame.high}`,
5418
+ { at: frame.at }
5419
+ );
5420
+ }
5421
+ return notes.map((n, index) => ({ ...n, pitch: pitches[index] }));
5422
+ }
5423
+ function placeDerived(source, relation, startBeat, endBeat, key, frame, before) {
5424
+ const planned = relation.kind === "tonalTransposition" ? _nullishCoalesce(relation.degrees, () => ( 0)) : relation.semitones;
5425
+ const replay = (level) => clipStatement(replayAt(source, relation, level, startBeat, key), endBeat);
5426
+ const base = replay(0).map((n) => n.pitch);
5427
+ const levels = relationLevels(
5428
+ relation.kind,
5429
+ Math.max(-LEVEL_REACH, frame.low - Math.min(...base)),
5430
+ Math.min(LEVEL_REACH, frame.high - Math.max(...base))
5431
+ );
5432
+ let best = null;
5433
+ for (const level of levels) {
5434
+ const notes2 = replay(level);
5435
+ if (outsideCount(notes2, frame) > 0) {
5436
+ continue;
5437
+ }
5438
+ const distance = notes2.reduce((sum, n) => sum + Math.abs(n.pitch - frame.targetAt(n.startBeat)), 0) / notes2.length;
5439
+ const cost = frame.misfits(notes2, before) + LEVEL_TARGET_COST * distance + LEVEL_PLAN_COST * Math.abs(level - planned);
5440
+ if (best === null || cost < best.cost || cost === best.cost && nearerLevel(level, best.level, planned)) {
5441
+ best = { level, notes: notes2, cost };
5442
+ }
5443
+ }
5444
+ if (best !== null) {
5445
+ return best.notes;
5446
+ }
5447
+ let fallback = null;
5448
+ for (const level of relationLevels(relation.kind)) {
5449
+ const notes2 = replay(level);
5450
+ const outside = outsideCount(notes2, frame);
5451
+ if (fallback === null || outside < fallback.outside || outside === fallback.outside && nearerLevel(level, fallback.level, planned)) {
5452
+ fallback = { level, notes: notes2, outside };
5453
+ }
5454
+ }
5455
+ const notes = fallback.notes;
5456
+ return repairStatement(
5457
+ notes,
5458
+ notes.map((n) => n.pitch < frame.low || n.pitch > frame.high),
5459
+ frame
5460
+ );
5461
+ }
5462
+ function varyStatement(source, startBeat, frame) {
5463
+ const offset = startBeat - source[0].startBeat;
5464
+ const last = source.length - 1;
5465
+ const inside = (pitch) => pitch >= frame.low && pitch <= frame.high;
5466
+ const outer = [source[0].pitch, source[last].pitch];
5467
+ const shift = [0, OCTAVE, -OCTAVE].find((s) => outer.every((pitch) => inside(pitch + s)));
5468
+ const notes = source.map((n) => ({ ...n, startBeat: n.startBeat + offset }));
5469
+ const slots = notes.map(
5470
+ (n, index) => (index === 0 || index === last) && shift !== void 0 ? { candidates: [n.pitch + shift], cost: () => 0, fixed: true } : {
5471
+ candidates: frame.candidatesAt(n.startBeat),
5472
+ cost: frame.costAt(n.startBeat),
5473
+ fixed: false
5474
+ }
5475
+ );
5476
+ const pitches = searchPitches(
5477
+ slots,
5478
+ frame.budget,
5479
+ (index, from, to) => VARIATION_STEP_COST * Math.abs(
5480
+ to - from - (source[index].pitch - source[index - 1].pitch)
5481
+ )
5482
+ );
5483
+ if (pitches === null) {
5484
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(`no variation line fits the register ${frame.low}..${frame.high}`, {
5485
+ at: frame.at
5486
+ });
5487
+ }
5488
+ return notes.map((n, index) => ({ ...n, pitch: pitches[index] }));
5489
+ }
5490
+
5491
+ // src/generate/melody/index.ts
5492
+ var RHYTHM_SUBDIVISION = 4;
5493
+ var OFF_SCALE_COST = 1;
5494
+ var TARGET_COST = 0.1;
5495
+ var TIE_BREAK = 1e-6;
5496
+ var SEARCH_STATES_SQUARED = 9;
5497
+ function melodyContext(plan, input) {
5498
+ const fromPlan = { seed: plan.seed, algorithmVersion: plan.algorithmVersion };
5499
+ if (input === void 0) {
5500
+ return resolveContext(fromPlan);
5501
+ }
5502
+ if (typeof input === "number") {
5503
+ return resolveContext({ ...fromPlan, seed: input });
5504
+ }
5505
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, input, "ctx");
5506
+ if (read.rng !== void 0) {
5507
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5508
+ "ctx.rng cannot drive a melody: every onset and tie-break is drawn at an address of phrase and beat under a seed; pass a seed instead"
5509
+ );
5510
+ }
5511
+ return resolveContext({
5512
+ ...read,
5513
+ seed: _nullishCoalesce(read.seed, () => ( plan.seed)),
5514
+ algorithmVersion: _nullishCoalesce(read.algorithmVersion, () => ( plan.algorithmVersion))
5515
+ });
5516
+ }
5517
+ function chordEntryAt(plan, beat) {
5518
+ return plan.harmony.find((chord) => beat >= chord.startBeat && beat < chord.endBeat);
5519
+ }
5520
+ function scaleAt(scene, beat) {
5521
+ return scene.scales[_nullishCoalesce(_optionalChain([chordEntryAt, 'call', _62 => _62(scene.plan, beat), 'optionalAccess', _63 => _63.key]), () => ( 0))];
5522
+ }
5523
+ function targetPitch(phrase, beat) {
5524
+ const length = phrase.endBeat - phrase.startBeat;
5525
+ const t = length > 0 ? Math.min(Math.max((beat - phrase.startBeat) / length, 0), 1) : 0;
5526
+ const { low, high, mean } = phrase.register;
5527
+ return mean + (high - low) / 2 * plannedContourAt(phrase.shape, phrase.peakPosition, t);
5528
+ }
5529
+ function registerPitches(phrase) {
5530
+ const pitches = [];
5531
+ for (let pitch = phrase.register.low; pitch <= phrase.register.high; pitch += 1) {
5532
+ pitches.push(pitch);
5533
+ }
5534
+ return pitches;
5535
+ }
5536
+ function frameOf(scene, index) {
5537
+ const phrase = scene.plan.phrases[index];
5538
+ const { low, high } = phrase.register;
5539
+ const register = registerPitches(phrase);
5540
+ const draw = scene.ctx.part("melody");
5541
+ return {
5542
+ low,
5543
+ high,
5544
+ at: phrase.startBeat,
5545
+ budget: scene.budget,
5546
+ candidatesAt: (beat) => {
5547
+ const position = positionClass(beat, scene.plan.meters);
5548
+ const chord = scene.timeline.at(beat);
5549
+ const tones = position === "strong" && chord !== null ? _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord) : null;
5550
+ const scale = scaleAt(scene, beat);
5551
+ const candidates = position === "off" ? register : tones !== null ? register.filter((pitch) => tones.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch))) : register.filter((pitch) => _chunk3R3QVKY5cjs.isScaleTone.call(void 0, pitch, scale));
5552
+ if (candidates.length === 0) {
5553
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(
5554
+ `no ${position} pitch at beat ${beat} fits the register ${low}..${high}`,
5555
+ { at: phrase.startBeat }
5556
+ );
5557
+ }
5558
+ return candidates;
5559
+ },
5560
+ costAt: (beat) => {
5561
+ const off = positionClass(beat, scene.plan.meters) === "off";
5562
+ const scale = scaleAt(scene, beat);
5563
+ const target = targetPitch(phrase, beat);
5564
+ return (pitch) => {
5565
+ let cost = TARGET_COST * Math.abs(pitch - target);
5566
+ if (off && !_chunk3R3QVKY5cjs.isScaleTone.call(void 0, pitch, scale)) {
5567
+ cost += OFF_SCALE_COST;
5568
+ }
5569
+ return cost + draw.float(0, TIE_BREAK, index, "tie", beat, pitch);
5570
+ };
5571
+ },
5572
+ targetAt: (beat) => targetPitch(phrase, beat),
5573
+ misfits: (notes, before) => scene.harmonyMisfits([...before, ...notes]).slice(before.length).filter((kinds) => kinds !== null).length
5574
+ };
5575
+ }
5576
+ function membersOf(plan) {
5577
+ return plan.phrases.map((phrase, index) => {
5578
+ const found = new Set(phrase.motifs);
5579
+ plan.motifs.forEach((motif, m) => {
5580
+ if (motif.phrase === index) {
5581
+ found.add(m);
5582
+ }
5583
+ });
5584
+ return [...found].sort(
5585
+ (a, b) => (_nullishCoalesce(_optionalChain([plan, 'access', _64 => _64.motifs, 'access', _65 => _65[a], 'optionalAccess', _66 => _66.startBeat]), () => ( 0))) - (_nullishCoalesce(_optionalChain([plan, 'access', _67 => _67.motifs, 'access', _68 => _68[b], 'optionalAccess', _69 => _69.startBeat]), () => ( 0))) || a - b
5586
+ );
5587
+ });
5588
+ }
5589
+ function segmentsOf(scene, index) {
5590
+ const phrase = scene.plan.phrases[index];
5591
+ const segments = [];
5592
+ let cursor = phrase.startBeat;
5593
+ for (const m of scene.members[index]) {
5594
+ const motif = scene.plan.motifs[m];
5595
+ if (motif === void 0) {
5596
+ continue;
5597
+ }
5598
+ if (motif.startBeat > cursor + _chunkS5BKZZGMcjs.BEAT_EPS) {
5599
+ segments.push({ startBeat: cursor, endBeat: motif.startBeat, motif: null });
5600
+ }
5601
+ segments.push({ startBeat: motif.startBeat, endBeat: motif.endBeat, motif: m });
5602
+ cursor = Math.max(cursor, motif.endBeat);
5603
+ }
5604
+ if (phrase.endBeat > cursor + _chunkS5BKZZGMcjs.BEAT_EPS) {
5605
+ segments.push({ startBeat: cursor, endBeat: phrase.endBeat, motif: null });
5606
+ }
5607
+ return segments;
5608
+ }
5609
+ function notesAt(onsets, endBeat) {
5610
+ return onsets.map((startBeat, i) => ({
5611
+ pitch: 0,
5612
+ startBeat,
5613
+ durationBeat: (_nullishCoalesce(onsets[i + 1], () => ( endBeat))) - startBeat
5614
+ }));
5615
+ }
5616
+ function onsetSlots(scene, startBeat, endBeat) {
5617
+ const { meters } = scene.plan;
5618
+ const slots = [startBeat];
5619
+ let bar2 = _chunkS5BKZZGMcjs.barStartBeat.call(void 0, startBeat, meters);
5620
+ while (bar2 < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
5621
+ const barEnd = bar2 + _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, bar2, meters);
5622
+ for (let k = 0; bar2 + k / RHYTHM_SUBDIVISION < barEnd - _chunkS5BKZZGMcjs.BEAT_EPS; k += 1) {
5623
+ const beat = bar2 + k / RHYTHM_SUBDIVISION;
5624
+ if (beat > startBeat + _chunkS5BKZZGMcjs.BEAT_EPS && beat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
5625
+ slots.push(beat);
5626
+ }
5627
+ }
5628
+ bar2 = barEnd;
5629
+ }
5630
+ return slots;
5631
+ }
5632
+ function drawOnsets(scene, phraseIndex, startBeat, endBeat, count) {
5633
+ const slots = onsetSlots(scene, startBeat, endBeat);
5634
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, slots.length * Math.max(1, count - 1), "melody onset slots", scene.budget);
5635
+ if (count - 1 > slots.length - 1) {
5636
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(
5637
+ `${count} onsets do not fit the sixteenth grid of beats ${startBeat}..${endBeat}`,
5638
+ { at: scene.plan.phrases[phraseIndex].startBeat }
5639
+ );
5640
+ }
5641
+ const levels = slots.map((beat) => _chunkIFZDWIKMcjs.rhythmLevel.call(void 0, beat, scene.plan.meters));
5642
+ const perLevel = /* @__PURE__ */ new Map();
5643
+ for (const level of levels) {
5644
+ perLevel.set(level, (_nullishCoalesce(perLevel.get(level), () => ( 0))) + 1);
5645
+ }
5646
+ const levelWeight = levels.map(
5647
+ (level) => (_nullishCoalesce(scene.plan.rhythm.onsetLevels[level], () => ( 0))) / perLevel.get(level)
5648
+ );
5649
+ const draw = scene.ctx.part("melody");
5650
+ const onsets = [startBeat];
5651
+ let current = 0;
5652
+ for (let k = 1; k < count; k += 1) {
5653
+ const last = slots.length - 1 - (count - 1 - k);
5654
+ const candidates = [];
5655
+ for (let j = current + 1; j <= last; j += 1) candidates.push(j);
5656
+ const gapShare = (j) => _nullishCoalesce(scene.plan.rhythm.interOnsetShares[_chunkIFZDWIKMcjs.ioiBinIndex.call(void 0, slots[j] - slots[current])], () => ( 0));
5657
+ let weights = candidates.map((j) => levelWeight[j] * gapShare(j));
5658
+ if (!weights.some((w) => w > 0)) weights = candidates.map((j) => levelWeight[j]);
5659
+ if (!weights.some((w) => w > 0)) weights = candidates.map(() => 1);
5660
+ const total = weights.reduce((sum, w) => sum + w, 0);
5661
+ let target = draw.float(0, 1, phraseIndex, "onset", startBeat, k) * total;
5662
+ let pick = candidates.length - 1;
5663
+ for (let c = 0; c < candidates.length; c += 1) {
5664
+ target -= weights[c];
5665
+ if (target < 0) {
5666
+ pick = c;
5667
+ break;
5668
+ }
5669
+ }
5670
+ current = candidates[pick];
5671
+ onsets.push(slots[current]);
5672
+ }
5673
+ return notesAt(onsets, endBeat);
5674
+ }
5675
+ function placeRhythm(scene, motif) {
5676
+ const { rhythm, startBeat, endBeat, notes } = motif;
5677
+ if (rhythm === null) {
5678
+ return drawOnsets(scene, motif.phrase, startBeat, endBeat, notes);
5679
+ }
5680
+ const onsets = [startBeat];
5681
+ for (const gap of rhythm) {
5682
+ onsets.push(onsets.at(-1) + gap);
5683
+ }
5684
+ return notesAt(onsets, endBeat);
5685
+ }
5686
+ function searchedLine(rhythm, frame) {
5687
+ const slots = rhythm.map((note2) => ({
5688
+ candidates: frame.candidatesAt(note2.startBeat),
5689
+ cost: frame.costAt(note2.startBeat),
5690
+ fixed: false
5691
+ }));
5692
+ const pitches = searchPitches(slots, frame.budget);
5693
+ if (pitches === null) {
5694
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(`no pitch line fits the register ${frame.low}..${frame.high}`, {
5695
+ at: frame.at
5696
+ });
5697
+ }
5698
+ return rhythm.map((note2, i) => ({ ...note2, pitch: pitches[i] }));
5699
+ }
5700
+ function statementOf(scene, m) {
5701
+ const known = scene.statements.get(m);
5702
+ if (known !== void 0) {
5703
+ return known;
5704
+ }
5705
+ scene.inProgress.add(m);
5706
+ const motif = scene.plan.motifs[m];
5707
+ const frame = scene.frames[motif.phrase];
5708
+ let notes;
5709
+ if (motif.from === null) {
5710
+ if (motif.endBeat - motif.startBeat <= _chunkS5BKZZGMcjs.BEAT_EPS) {
5711
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(`root motif ${m} spans no time to place its notes in`, {
5712
+ at: frame.at
5713
+ });
5714
+ }
5715
+ notes = searchedLine(placeRhythm(scene, motif), frame);
5716
+ } else {
5717
+ const source = statementOf(scene, motif.from);
5718
+ notes = motif.relation === null ? varyStatement(source, motif.startBeat, frame) : placeDerived(
5719
+ source,
5720
+ motif.relation,
5721
+ motif.startBeat,
5722
+ motif.endBeat,
5723
+ scaleAt(scene, motif.startBeat),
5724
+ frame,
5725
+ lineBefore(scene, motif.phrase, motif.startBeat)
5726
+ );
5727
+ }
5728
+ scene.inProgress.delete(m);
5729
+ scene.statements.set(m, notes);
5730
+ return notes;
5731
+ }
5732
+ function freeNoteCount(scene, index, segment) {
5733
+ const phrase = scene.plan.phrases[index];
5734
+ const bars = _chunkIFZDWIKMcjs.barSpanOf.call(void 0, segment.startBeat, segment.endBeat, scene.plan.meters);
5735
+ return Math.max(1, Math.round(phrase.onsetDensity * bars));
5736
+ }
5737
+ function freeSpan(scene, index, segment) {
5738
+ const key = `${index}:${segment.startBeat}`;
5739
+ const known = scene.free.get(key);
5740
+ if (known !== void 0) {
5741
+ return known;
5742
+ }
5743
+ const rhythm = drawOnsets(
5744
+ scene,
5745
+ index,
5746
+ segment.startBeat,
5747
+ segment.endBeat,
5748
+ freeNoteCount(scene, index, segment)
5749
+ );
5750
+ const notes = searchedLine(rhythm, scene.frames[index]);
5751
+ scene.free.set(key, notes);
5752
+ return notes;
5753
+ }
5754
+ function lineBefore(scene, index, beat) {
5755
+ const line = [];
5756
+ for (const segment of segmentsOf(scene, index)) {
5757
+ if (segment.endBeat > beat + _chunkS5BKZZGMcjs.BEAT_EPS) {
5758
+ break;
5759
+ }
5760
+ if (segment.motif === null) {
5761
+ line.push(...freeSpan(scene, index, segment));
5762
+ } else if (!scene.inProgress.has(segment.motif)) {
5763
+ line.push(...statementOf(scene, segment.motif));
5764
+ }
5765
+ }
5766
+ return line.sort((a, b) => a.startBeat - b.startBeat);
5767
+ }
5768
+ function finalDownbeat(scene, index) {
5769
+ const phrase = scene.plan.phrases[index];
5770
+ const { meters } = scene.plan;
5771
+ let downbeat = _chunkS5BKZZGMcjs.barStartBeat.call(void 0, phrase.startBeat, meters);
5772
+ while (downbeat + _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, downbeat, meters) < phrase.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
5773
+ downbeat += _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, downbeat, meters);
5774
+ }
5775
+ return Math.max(downbeat, phrase.startBeat);
5776
+ }
5777
+ function heldNoteIndex(scene, index, line, downbeat) {
5778
+ const phrase = scene.plan.phrases[index];
5779
+ const sounding2 = line.findIndex(
5780
+ (note2) => note2.startBeat <= downbeat + _chunkS5BKZZGMcjs.BEAT_EPS && note2.startBeat + note2.durationBeat > downbeat + _chunkS5BKZZGMcjs.BEAT_EPS
5781
+ );
5782
+ return sounding2 >= 0 ? sounding2 : line.findIndex(
5783
+ (note2) => note2.startBeat >= downbeat - _chunkS5BKZZGMcjs.BEAT_EPS && note2.startBeat < phrase.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
5784
+ );
5785
+ }
5786
+ function repairCadence(scene, index, line, held) {
5787
+ const phrase = scene.plan.phrases[index];
5788
+ if (phrase.cadence === null) {
5789
+ return;
5790
+ }
5791
+ let target = held;
5792
+ for (let i = line.length - 1; target < 0 && i >= 0; i -= 1) {
5793
+ if (positionClass(line[i].startBeat, scene.plan.meters) !== "off") {
5794
+ target = i;
5795
+ }
5796
+ }
5797
+ if (target < 0) {
5798
+ return;
5799
+ }
5800
+ const note2 = line[target];
5801
+ const allowed = cadencePitchClasses(scene.plan, scene.timeline, phrase.cadence, note2.startBeat);
5802
+ if (allowed === null) {
5803
+ return;
5804
+ }
5805
+ const frame = scene.frames[index];
5806
+ const candidates = registerPitches(phrase).filter(
5807
+ (pitch) => allowed.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch))
5808
+ );
5809
+ if (candidates.length === 0) {
5810
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(
5811
+ `no pitch in the register ${frame.low}..${frame.high} can end the ${phrase.cadence} cadence`,
5812
+ { at: frame.at }
5813
+ );
5814
+ }
5815
+ if (allowed.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, note2.pitch))) {
5816
+ return;
5817
+ }
5818
+ const slots = line.map(
5819
+ (n, i) => i === target ? { candidates, cost: frame.costAt(n.startBeat), fixed: false } : { candidates: [n.pitch], cost: () => 0, fixed: true }
5820
+ );
5821
+ const pitches = searchPitches(slots, frame.budget);
5822
+ if (pitches === null) {
5823
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(`no cadence pitch joins its neighbours without an augmented step`, {
5824
+ at: frame.at
5825
+ });
5826
+ }
5827
+ note2.pitch = pitches[target];
5828
+ }
5829
+ function repickCutOnset(scene, index, line, held) {
5830
+ const note2 = line[held];
5831
+ const derived = scene.plan.motifs.some(
5832
+ (motif) => motif.from !== null && note2.startBeat >= motif.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && note2.startBeat < motif.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
5833
+ );
5834
+ if (scene.plan.phrases[index].cadence !== null || derived) {
5835
+ return;
5836
+ }
5837
+ const frame = scene.frames[index];
5838
+ const candidates = frame.candidatesAt(note2.startBeat);
5839
+ if (candidates.includes(note2.pitch)) {
5840
+ return;
5841
+ }
5842
+ const slots = line.map(
5843
+ (n, i) => i === held ? { candidates, cost: frame.costAt(n.startBeat), fixed: false } : { candidates: [n.pitch], cost: () => 0, fixed: true }
5844
+ );
5845
+ const pitches = searchPitches(slots, frame.budget);
5846
+ if (pitches === null) {
5847
+ throw new (0, _chunkS5BKZZGMcjs.NoSolutionError)(`no pitch at the final downbeat joins its neighbours`, {
5848
+ at: frame.at
5849
+ });
5850
+ }
5851
+ line[held] = { ...note2, pitch: pitches[held] };
5852
+ }
5853
+ function phraseLine(scene, index) {
5854
+ const line = [];
5855
+ for (const segment of segmentsOf(scene, index)) {
5856
+ line.push(
5857
+ ...segment.motif === null ? freeSpan(scene, index, segment) : statementOf(scene, segment.motif)
5858
+ );
5859
+ }
5860
+ return line.sort((a, b) => a.startBeat - b.startBeat);
5861
+ }
5862
+ function chargePitchSearch(scene) {
5863
+ const { plan } = scene;
5864
+ let estimate = 0;
5865
+ plan.phrases.forEach((phrase, index) => {
5866
+ let searched = 0;
5867
+ for (const segment of segmentsOf(scene, index)) {
5868
+ const motif = segment.motif === null ? void 0 : plan.motifs[segment.motif];
5869
+ if (motif === void 0) {
5870
+ searched += freeNoteCount(scene, index, segment);
5871
+ } else if (motif.relation === null) {
5872
+ searched += motif.notes;
5873
+ } else {
5874
+ estimate += motif.notes * relationLevels(motif.relation.kind).length;
5875
+ }
5876
+ }
5877
+ const register = Math.max(0, phrase.register.high - phrase.register.low + 1);
5878
+ estimate += searched * SEARCH_STATES_SQUARED * register * register;
5879
+ });
5880
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, estimate, "melody pitch search", scene.budget);
5881
+ }
5882
+ function generateMelody(plan, opts) {
5883
+ assertCompositionPlan(plan);
5884
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
5885
+ if (asked.budget !== void 0) {
5886
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, asked.budget, "budget", Number.MAX_SAFE_INTEGER);
5887
+ }
5888
+ const timeline = planChordTimeline(plan);
5889
+ const scene = {
5890
+ plan,
5891
+ ctx: melodyContext(plan, asked.ctx),
5892
+ budget: asked.budget,
5893
+ timeline,
5894
+ harmonyMisfits: planHarmonyMisfits(plan, timeline),
5895
+ scales: plan.keys.map((key) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, key)),
5896
+ members: membersOf(plan),
5897
+ frames: [],
5898
+ statements: /* @__PURE__ */ new Map(),
5899
+ free: /* @__PURE__ */ new Map(),
5900
+ inProgress: /* @__PURE__ */ new Set()
5901
+ };
5902
+ scene.frames = plan.phrases.map((_, index) => frameOf(scene, index));
5903
+ chargePitchSearch(scene);
5904
+ const melody = [];
5905
+ plan.phrases.forEach((_, index) => {
5906
+ const line = phraseLine(scene, index);
5907
+ const downbeat = finalDownbeat(scene, index);
5908
+ let held = heldNoteIndex(scene, index, line, downbeat);
5909
+ if (held >= 0) {
5910
+ line.length = held + 1;
5911
+ const note2 = line[held];
5912
+ if (note2.startBeat < downbeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
5913
+ const cut = downbeat - note2.startBeat;
5914
+ line[held] = { ...note2, durationBeat: cut };
5915
+ line.push({ ...note2, startBeat: downbeat, durationBeat: note2.durationBeat - cut });
5916
+ held += 1;
5917
+ repickCutOnset(scene, index, line, held);
5918
+ }
5919
+ }
5920
+ repairCadence(scene, index, line, held);
5921
+ if (held >= 0) {
5922
+ const note2 = line[held];
5923
+ const phraseEnd = plan.phrases[index].endBeat;
5924
+ line[held] = { ...note2, durationBeat: phraseEnd - note2.startBeat };
5925
+ }
5926
+ melody.push(...line);
5927
+ });
5928
+ melody.sort((a, b) => a.startBeat - b.startBeat);
5929
+ return motifToNoteEvents({ notes: melody });
5930
+ }
5931
+
4840
5932
  // src/generate/ornament/index.ts
4841
5933
  var ORNAMENT_STYLES = Object.freeze(["ghost", "flam", "drag", "slide", "accent"]);
4842
5934
  var DEFAULT_TS5 = { numerator: 4, denominator: 4 };
@@ -4849,7 +5941,7 @@ var MIN_VELOCITY2 = 1;
4849
5941
  var MAX_VELOCITY2 = 127;
4850
5942
  var SLIDE_MIN_SEMITONES = 1;
4851
5943
  function eligible(style, note2, previous, next, ts) {
4852
- const strong = _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, note2.startBeat, ts);
5944
+ const strong = _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, note2.startBeat, ts);
4853
5945
  switch (style) {
4854
5946
  case "ghost":
4855
5947
  return !strong;
@@ -4857,7 +5949,7 @@ function eligible(style, note2, previous, next, ts) {
4857
5949
  case "accent":
4858
5950
  return strong;
4859
5951
  case "drag":
4860
- return !strong && next !== void 0 && _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, next.startBeat, ts);
5952
+ return !strong && next !== void 0 && _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, next.startBeat, ts);
4861
5953
  case "slide":
4862
5954
  return previous !== void 0 && Math.abs(note2.pitch - previous.pitch) >= SLIDE_MIN_SEMITONES;
4863
5955
  }
@@ -4882,18 +5974,18 @@ function clampVelocity(velocity) {
4882
5974
  return Math.min(MAX_VELOCITY2, Math.max(MIN_VELOCITY2, Math.round(velocity)));
4883
5975
  }
4884
5976
  function ornament(notes, opts = {}) {
4885
- const asked = _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
4886
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, "ornament notes", { allowNonPositiveDuration: true });
4887
- const style = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(asked.style, () => ( DEFAULT_STYLE2)), ORNAMENT_STYLES, "ornament style");
4888
- const ts = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, _nullishCoalesce(asked.ts, () => ( DEFAULT_TS5)), "ts"));
4889
- _chunkXKSO2V5Icjs.assertTimeSignature.call(void 0, ts);
5977
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
5978
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "ornament notes", { allowNonPositiveDuration: true });
5979
+ const style = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(asked.style, () => ( DEFAULT_STYLE2)), ORNAMENT_STYLES, "ornament style");
5980
+ const ts = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, _nullishCoalesce(asked.ts, () => ( DEFAULT_TS5)), "ts"));
5981
+ _chunkS5BKZZGMcjs.assertTimeSignature.call(void 0, ts);
4890
5982
  if (asked.amount !== void 0) {
4891
- _chunkXKSO2V5Icjs.assertRange.call(void 0, asked.amount, 0, 1, "ornament amount");
5983
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, asked.amount, 0, 1, "ornament amount");
4892
5984
  }
4893
5985
  const ctx = resolveContextWith(asked.ctx, { ornament: asked.amount });
4894
5986
  const amount = _nullishCoalesce(ctx.ornament, () => ( DEFAULT_AMOUNT));
4895
5987
  const draw = ctx.part("ornament");
4896
- const sounding2 = _chunkXKSO2V5Icjs.dropSilentNotes.call(void 0, notes);
5988
+ const sounding2 = _chunkS5BKZZGMcjs.dropSilentNotes.call(void 0, notes);
4897
5989
  const ordered = [...sounding2].sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
4898
5990
  const previousOf = previousOnsets(ordered);
4899
5991
  const nextOf = nextOnsets(ordered);
@@ -4961,6 +6053,878 @@ function strokeGaps(ordered) {
4961
6053
  return gaps;
4962
6054
  }
4963
6055
 
6056
+ // src/generate/plan/derive.ts
6057
+ var PRESERVE_ASPECTS = [
6058
+ "form",
6059
+ "phraseLengths",
6060
+ "harmonicFunction",
6061
+ "harmonicRhythm",
6062
+ "motifRelations",
6063
+ "registerShape",
6064
+ "rhythm"
6065
+ ];
6066
+ var NEUTRAL_SHAPE = "arch";
6067
+ var NEUTRAL_PEAK_POSITION = 0.6;
6068
+ var SHAPE_KEEP_THRESHOLD = 0.5;
6069
+ var NEUTRAL_ONSET_LEVELS = Object.freeze([0, 1, 2, 3, 4, 5].map((level) => level / 15));
6070
+ var FUNCTION_DEGREES = {
6071
+ tonic: [1, 6, 3],
6072
+ subdominant: [4, 2],
6073
+ dominant: [5, 7]
6074
+ };
6075
+ var STRONG_WEIGHT2 = 2;
6076
+ var HEPTATONIC_DEGREES = 7;
6077
+ function mod12(value) {
6078
+ return (value % 12 + 12) % 12;
6079
+ }
6080
+ function lerp(weight, reference, neutral) {
6081
+ return weight * reference + (1 - weight) * neutral;
6082
+ }
6083
+ function readPreserve(value) {
6084
+ const read = value === void 0 ? {} : _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, "opts.preserve");
6085
+ const weights = {};
6086
+ for (const aspect of PRESERVE_ASPECTS) {
6087
+ const weight = read[aspect];
6088
+ weights[aspect] = weight === void 0 ? 1 : _chunkS5BKZZGMcjs.assertRange.call(void 0, weight, 0, 1, `opts.preserve.${aspect}`);
6089
+ }
6090
+ return weights;
6091
+ }
6092
+ function readRegister(value) {
6093
+ const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, value, "opts.register");
6094
+ const low = _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, read.low, "opts.register.low");
6095
+ const high = _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, read.high, "opts.register.high");
6096
+ if (low > high) {
6097
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
6098
+ `opts.register.low must not exceed opts.register.high; received ${low} > ${high}`
6099
+ );
6100
+ }
6101
+ return { low, high };
6102
+ }
6103
+ function rejectSuppliedRng(ctx) {
6104
+ if (typeof ctx === "object" && ctx !== null && ctx.rng !== void 0) {
6105
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
6106
+ "opts.ctx.rng is not accepted: a composition plan records its seed, not a source"
6107
+ );
6108
+ }
6109
+ }
6110
+ function plannedKeys(profile, requested) {
6111
+ const regions = profile.harmony.keys.map(
6112
+ ({ key }) => ({
6113
+ scale: { ...key.scale },
6114
+ tonic: { ...key.tonic },
6115
+ variant: key.variant
6116
+ })
6117
+ );
6118
+ const home = regions[0];
6119
+ if (requested === void 0) {
6120
+ return regions;
6121
+ }
6122
+ const target = _chunk3R3QVKY5cjs.resolveKey.call(void 0, requested);
6123
+ if (target.variant !== home.variant || target.scale.modeMask12 !== home.scale.modeMask12) {
6124
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
6125
+ "opts.key must be in the same mode as the reference's home key; a key change moves the tonic only"
6126
+ );
6127
+ }
6128
+ const step = _chunkS5BKZZGMcjs.spelledInterval.call(void 0,
6129
+ { letter: home.tonic.letter, alter: home.tonic.alter },
6130
+ { letter: target.tonic.letter, alter: target.tonic.alter }
6131
+ );
6132
+ const moved = regions.map(
6133
+ (key) => ({
6134
+ scale: {
6135
+ rootPc: mod12(key.scale.rootPc + step.semitones),
6136
+ modeMask12: key.scale.modeMask12
6137
+ },
6138
+ tonic: _chunkS5BKZZGMcjs.transposeByInterval.call(void 0, { letter: key.tonic.letter, alter: key.tonic.alter }, step),
6139
+ variant: key.variant
6140
+ })
6141
+ );
6142
+ moved[0] = target;
6143
+ return moved;
6144
+ }
6145
+ function nearestBoundary(beat, boundaries) {
6146
+ let best = beat;
6147
+ let bestDistance = Number.POSITIVE_INFINITY;
6148
+ for (const boundary of boundaries) {
6149
+ const distance = Math.abs(boundary - beat);
6150
+ if (distance < bestDistance - _chunkS5BKZZGMcjs.BEAT_EPS) {
6151
+ best = boundary;
6152
+ bestDistance = distance;
6153
+ }
6154
+ }
6155
+ return best;
6156
+ }
6157
+ function plannedSections(profile, weight, draw) {
6158
+ const sections = profile.form.sections;
6159
+ const boundaries = [profile.span.startBeat, profile.span.endBeat];
6160
+ for (const phrase of profile.form.phrases) {
6161
+ boundaries.push(phrase.startBeat, phrase.endBeat);
6162
+ }
6163
+ boundaries.sort((a, b) => a - b);
6164
+ const planned = [];
6165
+ sections.forEach((section, index) => {
6166
+ const keep = sections.length < 2 || draw.prob(weight, "form", index);
6167
+ const neighbour = index + 1 < sections.length ? index + 1 : index - 1;
6168
+ const startBeat = nearestBoundary(section.startBeat, boundaries);
6169
+ const endBeat = nearestBoundary(section.endBeat, boundaries);
6170
+ if (endBeat - startBeat > _chunkS5BKZZGMcjs.BEAT_EPS) {
6171
+ planned.push({
6172
+ label: keep ? section.label : _nullishCoalesce(_optionalChain([sections, 'access', _70 => _70[neighbour], 'optionalAccess', _71 => _71.label]), () => ( section.label)),
6173
+ startBeat,
6174
+ endBeat
6175
+ });
6176
+ }
6177
+ });
6178
+ return planned;
6179
+ }
6180
+ function beatAfterBars(startBeat, bars, meters) {
6181
+ let beat = startBeat;
6182
+ let left = bars;
6183
+ while (left > _chunkS5BKZZGMcjs.BEAT_EPS) {
6184
+ const step = Math.min(1, left);
6185
+ beat += step * _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, beat, meters);
6186
+ left -= step;
6187
+ }
6188
+ return beat;
6189
+ }
6190
+ function barsBetween(startBeat, endBeat, meters) {
6191
+ let beat = startBeat;
6192
+ let bars = 0;
6193
+ while (beat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
6194
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, beat, meters);
6195
+ const step = Math.min(_chunkS5BKZZGMcjs.barStartBeat.call(void 0, beat, meters) + barBeats, endBeat) - beat;
6196
+ bars += step / barBeats;
6197
+ beat += step;
6198
+ }
6199
+ return bars;
6200
+ }
6201
+ function spanSegments(profile, sections) {
6202
+ const { startBeat, endBeat } = profile.span;
6203
+ const cuts = [startBeat, endBeat];
6204
+ for (const section of sections) {
6205
+ for (const beat of [section.startBeat, section.endBeat]) {
6206
+ if (beat > startBeat + _chunkS5BKZZGMcjs.BEAT_EPS && beat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) cuts.push(beat);
6207
+ }
6208
+ }
6209
+ cuts.sort((a, b) => a - b);
6210
+ const segments = [];
6211
+ for (let index = 1; index < cuts.length; index += 1) {
6212
+ const from = cuts[index - 1];
6213
+ const to = cuts[index];
6214
+ if (to - from > _chunkS5BKZZGMcjs.BEAT_EPS) segments.push([from, to]);
6215
+ }
6216
+ return segments;
6217
+ }
6218
+ function plannedPhraseSpans(profile, sections, weight, draw) {
6219
+ const segments = spanSegments(profile, sections);
6220
+ const pieces = profile.form.phrases.map((phrase, source) => ({
6221
+ startBeat: phrase.startBeat,
6222
+ endBeat: phrase.endBeat,
6223
+ source,
6224
+ cadence: _nullishCoalesce(_optionalChain([phrase, 'access', _72 => _72.cadence, 'optionalAccess', _73 => _73.type]), () => ( null))
6225
+ }));
6226
+ const replaced = pieces.map((_, index) => !draw.prob(weight, "phraseLengths", index));
6227
+ const spans = [];
6228
+ for (const [segmentStart, segmentEnd] of segments) {
6229
+ const members = pieces.map((piece, index) => ({ piece, index })).filter(
6230
+ ({ piece }) => piece.startBeat >= segmentStart - _chunkS5BKZZGMcjs.BEAT_EPS && piece.startBeat < segmentEnd - _chunkS5BKZZGMcjs.BEAT_EPS
6231
+ );
6232
+ const laid = [];
6233
+ let cursor = segmentStart;
6234
+ for (const { piece, index } of members) {
6235
+ const lengths = [];
6236
+ if (replaced[index]) {
6237
+ const bars = barsBetween(piece.startBeat, piece.endBeat, profile.meters);
6238
+ const rounded = 2 ** Math.round(Math.log2(bars));
6239
+ const overflows = beatAfterBars(cursor, rounded, profile.meters) > segmentEnd + _chunkS5BKZZGMcjs.BEAT_EPS;
6240
+ let partStart = cursor;
6241
+ for (const part of overflows ? [rounded / 2, rounded / 2] : [rounded]) {
6242
+ const partEnd = beatAfterBars(partStart, part, profile.meters);
6243
+ lengths.push(partEnd - partStart);
6244
+ partStart = partEnd;
6245
+ }
6246
+ } else {
6247
+ lengths.push(piece.endBeat - piece.startBeat);
6248
+ }
6249
+ lengths.forEach((length, part) => {
6250
+ if (cursor >= segmentEnd - _chunkS5BKZZGMcjs.BEAT_EPS) return;
6251
+ const end = cursor + length;
6252
+ laid.push({
6253
+ startBeat: cursor,
6254
+ endBeat: Math.min(end, segmentEnd),
6255
+ source: piece.source,
6256
+ cadence: part === lengths.length - 1 ? piece.cadence : null
6257
+ });
6258
+ cursor = end;
6259
+ });
6260
+ }
6261
+ const last = laid.at(-1);
6262
+ if (last) {
6263
+ last.endBeat = segmentEnd;
6264
+ } else {
6265
+ laid.push({
6266
+ startBeat: segmentStart,
6267
+ endBeat: segmentEnd,
6268
+ source: _nullishCoalesce(_optionalChain([spans, 'access', _74 => _74.at, 'call', _75 => _75(-1), 'optionalAccess', _76 => _76.source]), () => ( (profile.form.phrases.length > 0 ? 0 : -1))),
6269
+ cadence: null
6270
+ });
6271
+ }
6272
+ spans.push(...laid);
6273
+ }
6274
+ return spans;
6275
+ }
6276
+ function sectionAt(sections, beat) {
6277
+ const index = sections.findIndex(
6278
+ (section) => beat >= section.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && beat < section.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
6279
+ );
6280
+ return index < 0 ? null : index;
6281
+ }
6282
+ function phraseHolding(phrases, startBeat, endBeat) {
6283
+ return phrases.findIndex(
6284
+ (phrase) => startBeat >= phrase.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && endBeat <= phrase.endBeat + _chunkS5BKZZGMcjs.BEAT_EPS
6285
+ );
6286
+ }
6287
+ function better(a, b) {
6288
+ for (let field = 0; field < a.length; field += 1) {
6289
+ if (a[field] !== b[field]) return a[field] > b[field];
6290
+ }
6291
+ return false;
6292
+ }
6293
+ function scheduleMotifs(candidates, meters) {
6294
+ const order = [...candidates].sort((a, b) => a.startBeat - b.startBeat || a.node - b.node);
6295
+ const count = order.length;
6296
+ const firstFrom = (from, beat) => {
6297
+ let low = from;
6298
+ let high = count;
6299
+ while (low < high) {
6300
+ const mid = low + high >> 1;
6301
+ if (order[mid].startBeat < beat - _chunkS5BKZZGMcjs.BEAT_EPS) low = mid + 1;
6302
+ else high = mid;
6303
+ }
6304
+ return low;
6305
+ };
6306
+ const next = order.map((candidate, index2) => firstFrom(index2 + 1, candidate.endBeat));
6307
+ const own = order.map(
6308
+ (candidate) => [
6309
+ candidate.notes,
6310
+ _chunkS5BKZZGMcjs.metricWeight.call(void 0, candidate.startBeat, meters) < STRONG_WEIGHT2 ? -1 : 0,
6311
+ 1
6312
+ ]
6313
+ );
6314
+ const taking = (index2) => {
6315
+ const rest = best[next[index2]];
6316
+ const mine = own[index2];
6317
+ return [mine[0] + rest[0], mine[1] + rest[1], mine[2] + rest[2]];
6318
+ };
6319
+ const best = new Array(count + 1).fill([0, 0, 0]);
6320
+ for (let index2 = count - 1; index2 >= 0; index2 -= 1) {
6321
+ const taken = taking(index2);
6322
+ const skipped = best[index2 + 1];
6323
+ best[index2] = better(taken, skipped) ? taken : skipped;
6324
+ }
6325
+ const chosen = [];
6326
+ let index = 0;
6327
+ while (index < count) {
6328
+ if (!better(best[index], taking(index))) {
6329
+ chosen.push(order[index]);
6330
+ index = next[index];
6331
+ } else {
6332
+ index += 1;
6333
+ }
6334
+ }
6335
+ return chosen.sort((a, b) => a.node - b.node);
6336
+ }
6337
+ function selectedDerivation(graph, parentEdge, selectedAt, node) {
6338
+ let plain = true;
6339
+ let semitones = 0;
6340
+ let steps = 0;
6341
+ for (let edge = parentEdge.get(node); edge !== void 0; edge = parentEdge.get(edge.from)) {
6342
+ const relation = edge.relation;
6343
+ steps += 1;
6344
+ plain &&= relation !== null && (relation.kind === "repetition" || relation.kind === "transposition" && Math.abs(relation.timeRatio - 1) <= _chunkS5BKZZGMcjs.BEAT_EPS);
6345
+ semitones += _nullishCoalesce(_optionalChain([relation, 'optionalAccess', _77 => _77.semitones]), () => ( 0));
6346
+ const from = selectedAt.get(edge.from);
6347
+ if (from === void 0) continue;
6348
+ if (steps === 1) {
6349
+ return { from, relation: relation === null ? null : { ...relation } };
6350
+ }
6351
+ if (!plain) {
6352
+ return { from: null, relation: null };
6353
+ }
6354
+ const gap = (_nullishCoalesce(_optionalChain([graph, 'access', _78 => _78.nodes, 'access', _79 => _79[node], 'optionalAccess', _80 => _80.startBeat]), () => ( 0))) - (_nullishCoalesce(_optionalChain([graph, 'access', _81 => _81.nodes, 'access', _82 => _82[edge.from], 'optionalAccess', _83 => _83.endBeat]), () => ( 0)));
6355
+ return {
6356
+ from,
6357
+ relation: {
6358
+ kind: semitones === 0 ? "repetition" : "transposition",
6359
+ sequence: gap >= -_chunkIFZDWIKMcjs.HUMANIZE_ADJACENCY && gap <= _chunkIFZDWIKMcjs.HUMANIZE_ADJACENCY,
6360
+ semitones,
6361
+ timeRatio: 1
6362
+ }
6363
+ };
6364
+ }
6365
+ return { from: null, relation: null };
6366
+ }
6367
+ function functionCandidates(fn, key) {
6368
+ if (_chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, key).length !== HEPTATONIC_DEGREES) {
6369
+ return null;
6370
+ }
6371
+ return FUNCTION_DEGREES[fn].map((degree) => _chunkIFZDWIKMcjs.chordToRoman.call(void 0, _chunk3R3QVKY5cjs.diatonicTriad.call(void 0, degree, key), key));
6372
+ }
6373
+ function plannedHarmony(profile, keys, preserve, draw) {
6374
+ const chords = profile.harmony.chords;
6375
+ const romans = chords.map((chord, index) => {
6376
+ if (chord.level !== "structural" || draw.prob(preserve.harmonicFunction, "harmonicFunction", index)) {
6377
+ return chord.roman;
6378
+ }
6379
+ const candidates = functionCandidates(chord.function, keys[chord.key]);
6380
+ if (candidates === null) {
6381
+ return chord.roman;
6382
+ }
6383
+ const pick = draw.range(0, candidates.length - 1, "harmonicFunction", index, "pick");
6384
+ return candidates[pick];
6385
+ });
6386
+ const starts = [];
6387
+ chords.forEach((chord, index) => {
6388
+ const keep = index === 0 || draw.prob(preserve.harmonicRhythm, "harmonicRhythm", index);
6389
+ const start = keep ? chord.startBeat : _chunkS5BKZZGMcjs.barStartBeat.call(void 0, chord.startBeat, profile.meters);
6390
+ starts.push(index === 0 ? start : Math.max(start, starts[index - 1]));
6391
+ });
6392
+ const planned = [];
6393
+ chords.forEach((chord, index) => {
6394
+ const next = chords[index + 1];
6395
+ const nextStart = starts[index + 1];
6396
+ let endBeat = chord.endBeat;
6397
+ if (next !== void 0 && nextStart !== void 0) {
6398
+ endBeat = Math.abs(chord.endBeat - next.startBeat) <= _chunkS5BKZZGMcjs.BEAT_EPS ? nextStart : Math.min(chord.endBeat, nextStart);
6399
+ }
6400
+ const startBeat = starts[index];
6401
+ if (endBeat - startBeat > _chunkS5BKZZGMcjs.BEAT_EPS) {
6402
+ planned.push({ startBeat, endBeat, key: chord.key, roman: romans[index] });
6403
+ }
6404
+ });
6405
+ return planned;
6406
+ }
6407
+ function plannedRhythm(profile, weight) {
6408
+ const reference = profile.melody.rhythm;
6409
+ return {
6410
+ onsetLevels: reference.onsetLevels.map(
6411
+ (share, level) => lerp(weight, share, NEUTRAL_ONSET_LEVELS[level])
6412
+ ),
6413
+ interOnsetShares: [...reference.interOnsetShares],
6414
+ syncopation: lerp(weight, reference.syncopation, 0)
6415
+ };
6416
+ }
6417
+ function deriveCompositionPlan(reference, opts) {
6418
+ const profile = _chunkIFZDWIKMcjs.assertReferenceProfile.call(void 0, reference, "reference");
6419
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
6420
+ const preserve = readPreserve(asked.preserve);
6421
+ const requestedRegister = asked.register === void 0 ? void 0 : readRegister(asked.register);
6422
+ rejectSuppliedRng(asked.ctx);
6423
+ const ctx = resolveContext(asked.ctx);
6424
+ const draw = ctx.part("plan");
6425
+ const melodyRegister = profile.melody.register;
6426
+ if (profile.melody.rhythm.onsets === 0 || melodyRegister === null) {
6427
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("reference must carry melody onsets to derive a plan from");
6428
+ }
6429
+ const keys = plannedKeys(profile, asked.key);
6430
+ const homeShift = mod12(
6431
+ keys[0].scale.rootPc - (_nullishCoalesce(_optionalChain([profile, 'access', _84 => _84.harmony, 'access', _85 => _85.keys, 'access', _86 => _86[0], 'optionalAccess', _87 => _87.key, 'access', _88 => _88.scale, 'access', _89 => _89.rootPc]), () => ( 0)))
6432
+ );
6433
+ const shift = homeShift >= 6 ? homeShift - 12 : homeShift;
6434
+ const source = { low: melodyRegister.low + shift, high: melodyRegister.high + shift };
6435
+ if (source.low < 0 || source.high > 127) {
6436
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
6437
+ `the reference melody range moved to the new key leaves the MIDI range; received ${source.low}..${source.high}`
6438
+ );
6439
+ }
6440
+ const target = _nullishCoalesce(requestedRegister, () => ( source));
6441
+ const scale = source.high === source.low ? 0 : (target.high - target.low) / (source.high - source.low);
6442
+ const offset = source.high === source.low ? (target.low + target.high) / 2 : target.low - source.low * scale;
6443
+ const mapPitch = (pitch) => (pitch + shift) * scale + offset;
6444
+ const neutralRegister = {
6445
+ low: target.low,
6446
+ high: target.high,
6447
+ mean: (target.low + target.high) / 2
6448
+ };
6449
+ const sections = plannedSections(profile, preserve.form, draw);
6450
+ const shapeWeight = preserve.registerShape;
6451
+ const spans = plannedPhraseSpans(profile, sections, preserve.phraseLengths, draw);
6452
+ const phrases = spans.map((span) => {
6453
+ const melody = _nullishCoalesce(_optionalChain([profile, 'access', _90 => _90.form, 'access', _91 => _91.phrases, 'access', _92 => _92[span.source], 'optionalAccess', _93 => _93.melody]), () => ( null));
6454
+ const register = melody ? {
6455
+ low: Math.round(lerp(shapeWeight, mapPitch(melody.low), neutralRegister.low)),
6456
+ high: Math.round(lerp(shapeWeight, mapPitch(melody.high), neutralRegister.high)),
6457
+ mean: lerp(shapeWeight, mapPitch(melody.mean), neutralRegister.mean)
6458
+ } : { ...neutralRegister };
6459
+ return {
6460
+ startBeat: span.startBeat,
6461
+ endBeat: span.endBeat,
6462
+ section: sectionAt(sections, span.startBeat),
6463
+ cadence: span.cadence,
6464
+ shape: melody && shapeWeight >= SHAPE_KEEP_THRESHOLD ? melody.shape : NEUTRAL_SHAPE,
6465
+ peakPosition: melody ? lerp(shapeWeight, melody.peakPosition, NEUTRAL_PEAK_POSITION) : NEUTRAL_PEAK_POSITION,
6466
+ register,
6467
+ onsetDensity: melody ? melody.onsetDensity : profile.melody.rhythm.onsetDensity,
6468
+ motifs: []
6469
+ };
6470
+ });
6471
+ const graph = profile.melody.graph;
6472
+ const noteCount = (node) => (_nullishCoalesce(_optionalChain([profile, 'access', _94 => _94.melody, 'access', _95 => _95.motifs, 'access', _96 => _96[_nullishCoalesce(_optionalChain([graph, 'access', _97 => _97.nodes, 'access', _98 => _98[node], 'optionalAccess', _99 => _99.motif]), () => ( -1))], 'optionalAccess', _100 => _100.intervals, 'access', _101 => _101.length]), () => ( 0))) + 1;
6473
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, graph.nodes.length * phrases.length, "plan motif selection", asked.budget);
6474
+ const candidates = [];
6475
+ graph.nodes.forEach((node, index) => {
6476
+ const phrase = phraseHolding(phrases, node.startBeat, node.endBeat);
6477
+ if (phrase >= 0) {
6478
+ candidates.push({
6479
+ node: index,
6480
+ phrase,
6481
+ startBeat: node.startBeat,
6482
+ endBeat: node.endBeat,
6483
+ notes: noteCount(index)
6484
+ });
6485
+ }
6486
+ });
6487
+ const selected = scheduleMotifs(candidates, profile.meters);
6488
+ const selectedAt = new Map(selected.map((candidate, index) => [candidate.node, index]));
6489
+ const parentEdge = new Map(graph.edges.map((edge) => [edge.to, edge]));
6490
+ const motifs = selected.map((candidate, index) => {
6491
+ const { from, relation } = selectedDerivation(graph, parentEdge, selectedAt, candidate.node);
6492
+ const keepRelation = draw.prob(preserve.motifRelations, "motifRelations", index);
6493
+ const keepRhythm = from === null && draw.prob(preserve.rhythm, "rhythm", index);
6494
+ const cell = profile.melody.motifs[_nullishCoalesce(_optionalChain([graph, 'access', _102 => _102.nodes, 'access', _103 => _103[candidate.node], 'optionalAccess', _104 => _104.motif]), () => ( -1))];
6495
+ _optionalChain([phrases, 'access', _105 => _105[candidate.phrase], 'optionalAccess', _106 => _106.motifs, 'access', _107 => _107.push, 'call', _108 => _108(index)]);
6496
+ return {
6497
+ phrase: candidate.phrase,
6498
+ startBeat: candidate.startBeat,
6499
+ endBeat: candidate.endBeat,
6500
+ notes: candidate.notes,
6501
+ rhythm: keepRhythm && cell !== void 0 ? cell.rhythm.map((ratio) => ratio * cell.unitBeats) : null,
6502
+ from,
6503
+ relation: keepRelation ? relation : null
6504
+ };
6505
+ });
6506
+ return {
6507
+ planVersion: COMPOSITION_PLAN_VERSION,
6508
+ seed: ctx.seed,
6509
+ algorithmVersion: ctx.algorithmVersion,
6510
+ keys,
6511
+ meters: profile.meters.map((entry) => ({
6512
+ startBeat: entry.startBeat,
6513
+ ts: entry.ts.grouping === void 0 ? { ...entry.ts } : { ...entry.ts, grouping: [...entry.ts.grouping] }
6514
+ })),
6515
+ span: { ...profile.span },
6516
+ sections,
6517
+ phrases,
6518
+ harmony: plannedHarmony(profile, keys, preserve, draw),
6519
+ motifs,
6520
+ rhythm: plannedRhythm(profile, preserve.rhythm)
6521
+ };
6522
+ }
6523
+
6524
+ // src/generate/plan/evaluate.ts
6525
+ var PEAK_POSITION_TOLERANCE = 0.2;
6526
+ var OUTLINE_POINTS = 8;
6527
+ var HELD_NOTE_BEATS = 1;
6528
+ function interiorBoundaries(plan) {
6529
+ const beats = /* @__PURE__ */ new Set();
6530
+ for (const phrase of plan.phrases) {
6531
+ for (const beat of [phrase.startBeat, phrase.endBeat]) {
6532
+ if (beat > plan.span.startBeat + _chunkS5BKZZGMcjs.BEAT_EPS && beat < plan.span.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS) {
6533
+ beats.add(beat);
6534
+ }
6535
+ }
6536
+ }
6537
+ return [...beats].sort((a, b) => a - b);
6538
+ }
6539
+ function restsOf(melody, plan) {
6540
+ const rests = [];
6541
+ let reach = plan.span.startBeat;
6542
+ for (const note2 of [...melody].sort((a, b) => a.startBeat - b.startBeat)) {
6543
+ if (note2.startBeat > reach + _chunkS5BKZZGMcjs.BEAT_EPS) {
6544
+ rests.push({ startBeat: reach, endBeat: note2.startBeat });
6545
+ }
6546
+ reach = Math.max(reach, note2.startBeat + note2.durationBeat);
6547
+ }
6548
+ if (plan.span.endBeat > reach + _chunkS5BKZZGMcjs.BEAT_EPS) {
6549
+ rests.push({ startBeat: reach, endBeat: plan.span.endBeat });
6550
+ }
6551
+ return rests;
6552
+ }
6553
+ function phraseBoundaryViolations(melody, plan) {
6554
+ const rests = restsOf(melody, plan);
6555
+ const violations = [];
6556
+ for (const beat of interiorBoundaries(plan)) {
6557
+ const pulse2 = _chunkS5BKZZGMcjs.pulseBeats.call(void 0, _chunkS5BKZZGMcjs.meterAt.call(void 0, beat, plan.meters));
6558
+ const held = melody.some(
6559
+ (note2) => note2.durationBeat >= HELD_NOTE_BEATS - _chunkS5BKZZGMcjs.BEAT_EPS && Math.abs(note2.startBeat + note2.durationBeat - beat) <= pulse2 + _chunkS5BKZZGMcjs.BEAT_EPS
6560
+ );
6561
+ const rested = rests.some(
6562
+ (rest) => rest.endBeat - rest.startBeat >= pulse2 - _chunkS5BKZZGMcjs.BEAT_EPS && rest.startBeat <= beat + pulse2 + _chunkS5BKZZGMcjs.BEAT_EPS && rest.endBeat >= beat - pulse2 - _chunkS5BKZZGMcjs.BEAT_EPS
6563
+ );
6564
+ if (!held && !rested) {
6565
+ violations.push({
6566
+ kind: "phraseBoundary",
6567
+ severity: "error",
6568
+ atBeat: beat,
6569
+ expected: `a note of at least ${HELD_NOTE_BEATS} beat(s) ending, or a rest of at least ${pulse2} beat(s), within ${pulse2} beat(s)`,
6570
+ actual: "neither",
6571
+ rationale: `the plan places a phrase boundary at beat ${beat}, which the candidate does not mark`
6572
+ });
6573
+ }
6574
+ }
6575
+ return violations;
6576
+ }
6577
+ function spanViolation(melody, plan) {
6578
+ const end = melody.reduce((max, note2) => Math.max(max, note2.startBeat + note2.durationBeat), 0);
6579
+ if (end <= plan.span.endBeat + _chunkS5BKZZGMcjs.BEAT_EPS) {
6580
+ return [];
6581
+ }
6582
+ return [
6583
+ {
6584
+ kind: "span",
6585
+ severity: "error",
6586
+ atBeat: plan.span.endBeat,
6587
+ expected: `ending by beat ${plan.span.endBeat}`,
6588
+ actual: `ending at beat ${end}`,
6589
+ rationale: "the candidate's last note runs past the plan's span"
6590
+ }
6591
+ ];
6592
+ }
6593
+ function phraseLines(melody, plan) {
6594
+ return plan.phrases.map(
6595
+ (phrase) => melody.flatMap(
6596
+ (note2, index) => note2.startBeat >= phrase.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && note2.startBeat < phrase.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS ? [index] : []
6597
+ )
6598
+ );
6599
+ }
6600
+ function cadenceViolations(melody, plan, timeline, lines) {
6601
+ const violations = [];
6602
+ plan.phrases.forEach((phrase, index) => {
6603
+ if (phrase.cadence === null) {
6604
+ return;
6605
+ }
6606
+ const last = _optionalChain([lines, 'access', _109 => _109[index], 'optionalAccess', _110 => _110.at, 'call', _111 => _111(-1)]);
6607
+ const note2 = last === void 0 ? void 0 : melody[last];
6608
+ const allowed = note2 === void 0 ? [] : cadencePitchClasses(plan, timeline, phrase.cadence, note2.startBeat);
6609
+ if (note2 !== void 0 && (allowed === null || allowed.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, note2.pitch)))) {
6610
+ return;
6611
+ }
6612
+ violations.push({
6613
+ kind: "cadence",
6614
+ severity: "error",
6615
+ atBeat: phrase.endBeat,
6616
+ expected: `a closing note on pitch class ${(_nullishCoalesce(allowed, () => ( []))).join(" or ")} for a ${phrase.cadence} cadence`,
6617
+ actual: note2 === void 0 ? "no note" : `pitch ${note2.pitch}`,
6618
+ rationale: `the phrase ending at beat ${phrase.endBeat} is planned to close on a ${phrase.cadence} cadence`
6619
+ });
6620
+ });
6621
+ return violations;
6622
+ }
6623
+ function harmonyViolations(melody, plan, timeline, lines) {
6624
+ const misfits = planHarmonyMisfits(plan, timeline);
6625
+ const violations = [];
6626
+ for (const line of lines) {
6627
+ const read = misfits(line.map((index) => melody[index]));
6628
+ read.forEach((kinds, at2) => {
6629
+ if (kinds === null) {
6630
+ return;
6631
+ }
6632
+ const note2 = melody[line[at2]];
6633
+ const derived = plan.motifs.some(
6634
+ (motif) => motif.from !== null && note2.startBeat >= motif.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && note2.startBeat < motif.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
6635
+ );
6636
+ const strong = positionClass(note2.startBeat, plan.meters) === "strong";
6637
+ violations.push({
6638
+ kind: "harmony",
6639
+ severity: derived ? "warning" : "error",
6640
+ atBeat: note2.startBeat,
6641
+ expected: strong ? "a chord tone or an ornamental tone" : "a chord tone, an ornamental tone, or a scale tone",
6642
+ actual: kinds.length === 0 ? "no harmonic label" : kinds.join(", "),
6643
+ rationale: derived ? `the note at beat ${note2.startBeat} sits in a derived statement, whose transformation takes precedence over the harmony` : `the note at beat ${note2.startBeat} does not fit the planned harmony`
6644
+ });
6645
+ });
6646
+ }
6647
+ return violations;
6648
+ }
6649
+ function notesInRange(melody, startBeat, endBeat) {
6650
+ return melody.filter(
6651
+ (note2) => note2.startBeat >= startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && note2.startBeat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
6652
+ );
6653
+ }
6654
+ function replayLevel(source, derived, statement, sourceEnd, plan, key, closing) {
6655
+ const relation = statement.relation;
6656
+ const planned = relation.kind === "tonalTransposition" ? _nullishCoalesce(relation.degrees, () => ( 0)) : relation.semitones;
6657
+ const { low, high } = plan.phrases[statement.phrase].register;
6658
+ const outside = (pitch) => pitch < low || pitch > high;
6659
+ const backward = relation.kind === "retrograde" || relation.kind === "retrogradeInversion";
6660
+ const cell = clipStatement(
6661
+ source.map((note2) => ({
6662
+ pitch: note2.pitch,
6663
+ startBeat: note2.startBeat,
6664
+ durationBeat: note2.durationBeat
6665
+ })),
6666
+ sourceEnd
6667
+ );
6668
+ const replays = relationLevels(relation.kind).map((level) => {
6669
+ const notes = clipStatement(
6670
+ replayAt(cell, relation, level, statement.startBeat, key),
6671
+ statement.endBeat
6672
+ );
6673
+ return { level, notes, outside: notes.filter((note2) => outside(note2.pitch)).length };
6674
+ });
6675
+ const fewestOutside = Math.min(...replays.map((replay) => replay.outside));
6676
+ let best = null;
6677
+ for (const { level, notes: expected, outside: away } of replays) {
6678
+ if (expected.length !== derived.length) {
6679
+ continue;
6680
+ }
6681
+ let forced = 0;
6682
+ let holds = true;
6683
+ for (let i = 0; holds && i < expected.length; i += 1) {
6684
+ const want = expected[i];
6685
+ const got = derived[i];
6686
+ if (i > 0) {
6687
+ const gap = got.startBeat - derived[i - 1].startBeat;
6688
+ holds = Math.abs(gap - (want.startBeat - expected[i - 1].startBeat)) <= _chunkS5BKZZGMcjs.BEAT_EPS;
6689
+ }
6690
+ if (!holds || got.pitch === want.pitch) {
6691
+ continue;
6692
+ }
6693
+ const origin = source[backward ? cell.length - 1 - i : i];
6694
+ forced += 1;
6695
+ holds = closing.has(got) || origin !== void 0 && closing.has(origin) || away === fewestOutside && outside(want.pitch);
6696
+ }
6697
+ const distance = Math.abs(level - planned);
6698
+ const nearer = best === null || distance < Math.abs(best.level - planned) || distance === Math.abs(best.level - planned) && level < best.level;
6699
+ if (holds && nearer) {
6700
+ best = { level, forced };
6701
+ }
6702
+ }
6703
+ return best;
6704
+ }
6705
+ function motifDerivationViolations(melody, plan, closing) {
6706
+ const keyAt = planKeyAt(plan);
6707
+ const errors = [];
6708
+ const warnings = [];
6709
+ for (const statement of plan.motifs) {
6710
+ if (statement.from === null) {
6711
+ continue;
6712
+ }
6713
+ const source = plan.motifs[statement.from];
6714
+ const sourceNotes = notesInRange(melody, source.startBeat, source.endBeat);
6715
+ const derivedNotes = notesInRange(melody, statement.startBeat, statement.endBeat);
6716
+ const relation = statement.relation;
6717
+ const rationale = `the statement at beat ${statement.startBeat} does not derive from its source the way the plan names`;
6718
+ if (sourceNotes.length === 0 || derivedNotes.length === 0) {
6719
+ errors.push({
6720
+ kind: "motifDerivation",
6721
+ severity: "error",
6722
+ atBeat: statement.startBeat,
6723
+ expected: relation === null ? "a variation" : relation.kind,
6724
+ actual: "no notes to compare",
6725
+ rationale
6726
+ });
6727
+ continue;
6728
+ }
6729
+ if (relation === null) {
6730
+ const similarity = _chunkIFZDWIKMcjs.melodicSimilarity.call(void 0, sourceNotes, derivedNotes);
6731
+ if (similarity < _chunkIFZDWIKMcjs.DEFAULT_VARIATION_THRESHOLD) {
6732
+ errors.push({
6733
+ kind: "motifDerivation",
6734
+ severity: "error",
6735
+ atBeat: statement.startBeat,
6736
+ expected: `a variation (melodicSimilarity >= ${_chunkIFZDWIKMcjs.DEFAULT_VARIATION_THRESHOLD})`,
6737
+ actual: `melodicSimilarity ${similarity.toFixed(3)}`,
6738
+ rationale
6739
+ });
6740
+ }
6741
+ continue;
6742
+ }
6743
+ const replay = replayLevel(
6744
+ sourceNotes,
6745
+ derivedNotes,
6746
+ statement,
6747
+ source.endBeat,
6748
+ plan,
6749
+ _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(statement.startBeat)),
6750
+ closing
6751
+ );
6752
+ const planned = relation.kind === "tonalTransposition" ? _nullishCoalesce(relation.degrees, () => ( 0)) : relation.semitones;
6753
+ if (replay === null) {
6754
+ errors.push({
6755
+ kind: "motifDerivation",
6756
+ severity: "error",
6757
+ atBeat: statement.startBeat,
6758
+ expected: relation.kind,
6759
+ actual: "no pitch level replays the source",
6760
+ rationale
6761
+ });
6762
+ } else if (replay.level !== planned || replay.forced > 0) {
6763
+ warnings.push({
6764
+ kind: "motifDisplaced",
6765
+ severity: "warning",
6766
+ atBeat: statement.startBeat,
6767
+ expected: `${relation.kind} at level ${planned} with every pitch replayed`,
6768
+ actual: `level ${replay.level}, ${replay.forced} excused note(s)`,
6769
+ rationale: `the statement at beat ${statement.startBeat} carries out its planned derivation at another pitch level or with notes excused`
6770
+ });
6771
+ }
6772
+ }
6773
+ return { errors, warnings };
6774
+ }
6775
+ function phraseAt(plan, beat) {
6776
+ return plan.phrases.find(
6777
+ (phrase) => beat >= phrase.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && beat < phrase.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
6778
+ );
6779
+ }
6780
+ function registerViolations(melody, plan) {
6781
+ const violations = [];
6782
+ for (const note2 of melody) {
6783
+ const phrase = phraseAt(plan, note2.startBeat);
6784
+ if (phrase === void 0) {
6785
+ continue;
6786
+ }
6787
+ if (note2.pitch < phrase.register.low || note2.pitch > phrase.register.high) {
6788
+ violations.push({
6789
+ kind: "register",
6790
+ severity: "error",
6791
+ atBeat: note2.startBeat,
6792
+ expected: `a pitch within [${phrase.register.low}, ${phrase.register.high}]`,
6793
+ actual: `pitch ${note2.pitch}`,
6794
+ rationale: `the note at beat ${note2.startBeat} falls outside its phrase's planned register`
6795
+ });
6796
+ }
6797
+ }
6798
+ return violations;
6799
+ }
6800
+ function planOutline(phrase) {
6801
+ const amplitude = (phrase.register.high - phrase.register.low) / 2;
6802
+ const outline = [];
6803
+ for (let k = 0; k < OUTLINE_POINTS; k += 1) {
6804
+ const t = (k + 0.5) / OUTLINE_POINTS;
6805
+ outline.push(
6806
+ phrase.register.mean + plannedContourAt(phrase.shape, phrase.peakPosition, t) * amplitude
6807
+ );
6808
+ }
6809
+ return outline;
6810
+ }
6811
+ function planContourPhrase(phrase) {
6812
+ return {
6813
+ shape: phrase.shape,
6814
+ low: phrase.register.low,
6815
+ high: phrase.register.high,
6816
+ outline: planOutline(phrase)
6817
+ };
6818
+ }
6819
+ function planRegisterPlan(plan) {
6820
+ const phrases = plan.phrases.map((phrase) => ({
6821
+ low: phrase.register.low,
6822
+ high: phrase.register.high,
6823
+ mean: phrase.register.mean,
6824
+ peakPosition: phrase.peakPosition
6825
+ }));
6826
+ let weighted = 0;
6827
+ let weight = 0;
6828
+ for (const phrase of plan.phrases) {
6829
+ const length = phrase.endBeat - phrase.startBeat;
6830
+ weighted += phrase.register.mean * length;
6831
+ weight += length;
6832
+ }
6833
+ return { phrases, mean: weight > 0 ? weighted / weight : null };
6834
+ }
6835
+ function planRhythmReading(plan) {
6836
+ const hasOnsets = plan.rhythm.onsetLevels.some((share) => share > 0);
6837
+ return {
6838
+ onsets: hasOnsets ? 1 : 0,
6839
+ onsetLevels: plan.rhythm.onsetLevels,
6840
+ barPositions: [],
6841
+ interOnsetShares: plan.rhythm.interOnsetShares,
6842
+ syncopation: plan.rhythm.syncopation
6843
+ };
6844
+ }
6845
+ function peakPositionWarnings(plan, readings) {
6846
+ const violations = [];
6847
+ plan.phrases.forEach((phrase, index) => {
6848
+ const reading = readings[index];
6849
+ if (reading == null) {
6850
+ return;
6851
+ }
6852
+ const drift = Math.abs(reading.peakPosition - phrase.peakPosition);
6853
+ if (drift > PEAK_POSITION_TOLERANCE) {
6854
+ violations.push({
6855
+ kind: "peakPosition",
6856
+ severity: "warning",
6857
+ atBeat: phrase.startBeat,
6858
+ expected: `a peak position within ${PEAK_POSITION_TOLERANCE} of ${phrase.peakPosition}`,
6859
+ actual: `${reading.peakPosition}`,
6860
+ rationale: `the phrase starting at beat ${phrase.startBeat} places its melodic peak further from the planned position than the tolerance allows`
6861
+ });
6862
+ }
6863
+ });
6864
+ return violations;
6865
+ }
6866
+ function lineMeanOf(melody) {
6867
+ let weighted = 0;
6868
+ let total = 0;
6869
+ for (const note2 of melody) {
6870
+ weighted += note2.pitch * note2.durationBeat;
6871
+ total += note2.durationBeat;
6872
+ }
6873
+ return total > 0 ? weighted / total : null;
6874
+ }
6875
+ function planDensity(plan) {
6876
+ let weighted = 0;
6877
+ let bars = 0;
6878
+ for (const phrase of plan.phrases) {
6879
+ const span = _chunkIFZDWIKMcjs.barSpanOf.call(void 0, phrase.startBeat, phrase.endBeat, plan.meters);
6880
+ weighted += phrase.onsetDensity * span;
6881
+ bars += span;
6882
+ }
6883
+ return { onsets: 1, onsetDensity: bars > 0 ? weighted / bars : 0 };
6884
+ }
6885
+ function evaluateComposition(melody, plan, opts) {
6886
+ assertCompositionPlan(plan, "evaluated plan");
6887
+ const { budget } = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "evaluate options");
6888
+ const notes = [
6889
+ ..._chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, melody, "evaluated melody", { budget, allowNonPositiveDuration: true })
6890
+ ].sort((a, b) => a.startBeat - b.startBeat);
6891
+ const timeline = planChordTimeline(plan);
6892
+ const lines = phraseLines(notes, plan);
6893
+ const closing = new Set(
6894
+ lines.flatMap((line) => line.length === 0 ? [] : [notes[line.at(-1)]])
6895
+ );
6896
+ const derivations = motifDerivationViolations(notes, plan, closing);
6897
+ const lineMean = lineMeanOf(notes);
6898
+ const readings = plan.phrases.map(
6899
+ (phrase) => _chunkIFZDWIKMcjs.phraseMelody.call(void 0, notes, phrase.startBeat, phrase.endBeat, _nullishCoalesce(lineMean, () => ( 0)), plan.meters, budget)
6900
+ );
6901
+ const violations = [
6902
+ ...spanViolation(notes, plan),
6903
+ ...phraseBoundaryViolations(notes, plan),
6904
+ ...cadenceViolations(notes, plan, timeline, lines),
6905
+ ...harmonyViolations(notes, plan, timeline, lines),
6906
+ ...registerViolations(notes, plan),
6907
+ ...derivations.errors,
6908
+ ...derivations.warnings,
6909
+ ...peakPositionWarnings(plan, readings)
6910
+ ];
6911
+ const rhythm = _chunkIFZDWIKMcjs.analyzeRhythm.call(void 0, notes, {
6912
+ meters: plan.meters,
6913
+ totalBeats: plan.span.endBeat,
6914
+ budget
6915
+ });
6916
+ const target = planRhythmReading(plan);
6917
+ const fit = {
6918
+ contour: _chunkIFZDWIKMcjs.contourSimilarity.call(void 0, plan.phrases.map(planContourPhrase), readings),
6919
+ register: _chunkIFZDWIKMcjs.registerSimilarity.call(void 0, planRegisterPlan(plan), { phrases: readings, mean: lineMean }),
6920
+ onset: _chunkIFZDWIKMcjs.onsetSimilarity.call(void 0, target, rhythm),
6921
+ duration: _chunkIFZDWIKMcjs.durationSimilarity.call(void 0, target, rhythm),
6922
+ syncopation: _chunkIFZDWIKMcjs.syncopationSimilarity.call(void 0, target, rhythm),
6923
+ density: _chunkIFZDWIKMcjs.densitySimilarity.call(void 0, planDensity(plan), rhythm)
6924
+ };
6925
+ return { violations, fit };
6926
+ }
6927
+
4964
6928
  // src/generate/progression/index.ts
4965
6929
  var DEFAULT_TS6 = { numerator: 4, denominator: 4 };
4966
6930
  var PROG_STYLES = Object.freeze(["minimal", "dance", "idol", "rock"]);
@@ -5147,12 +7111,12 @@ function progressions() {
5147
7111
  return PRESETS.map((p) => ({ ...p, degrees: [...p.degrees], styles: [...p.styles] }));
5148
7112
  }
5149
7113
  function progressionsByStyle(style) {
5150
- const named = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, style, PROG_STYLES, "style");
7114
+ const named = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, style, PROG_STYLES, "style");
5151
7115
  return progressions().filter((p) => p.styles.includes(named));
5152
7116
  }
5153
7117
  function degreeToRootPc(degree, key) {
5154
7118
  if (degree >= 1 && degree <= 7) {
5155
- const tones = _chunkYPB3A3EYcjs.scaleTonesInDegreeOrder.call(void 0, _chunkYPB3A3EYcjs.heptatonicFrameOf.call(void 0, key));
7119
+ const tones = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, _chunk3R3QVKY5cjs.heptatonicFrameOf.call(void 0, key));
5156
7120
  return _nullishCoalesce(tones[degree - 1], () => ( key.rootPc % 12));
5157
7121
  }
5158
7122
  const offset = _nullishCoalesce(BORROWED_OFFSET[degree], () => ( 0));
@@ -5160,10 +7124,10 @@ function degreeToRootPc(degree, key) {
5160
7124
  }
5161
7125
  function autoQuality(degree, key, harmonicDominant) {
5162
7126
  if (degree >= 1 && degree <= 7) {
5163
- if (harmonicDominant && _chunkQ6R3QAZDcjs.isMinorKey.call(void 0, key) && degree === 5) {
7127
+ if (harmonicDominant && _chunkIFZDWIKMcjs.isMinorKey.call(void 0, key) && degree === 5) {
5164
7128
  return "maj";
5165
7129
  }
5166
- return _chunkYPB3A3EYcjs.diatonicTriad.call(void 0, degree, _chunkYPB3A3EYcjs.heptatonicFrameOf.call(void 0, key)).quality;
7130
+ return _chunk3R3QVKY5cjs.diatonicTriad.call(void 0, degree, _chunk3R3QVKY5cjs.heptatonicFrameOf.call(void 0, key)).quality;
5167
7131
  }
5168
7132
  if (degree === 14) {
5169
7133
  return "dim";
@@ -5192,39 +7156,39 @@ function pickProgressionPreset(style, ctx = 0) {
5192
7156
  function presetFor(style, ctx) {
5193
7157
  const pool = PRESETS.filter((preset) => preset.styles.includes(style));
5194
7158
  if (pool.length === 0) {
5195
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`Unknown progression style: ${style}`);
7159
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown progression style: ${style}`);
5196
7160
  }
5197
7161
  const index = ctx.part("progression").range(0, pool.length - 1, "preset");
5198
7162
  return _nullishCoalesce(pool[index], () => ( PRESETS[0]));
5199
7163
  }
5200
7164
  function tonicizableRootPcs(key) {
5201
- return new Set(_chunkYPB3A3EYcjs.tonicizableDegrees.call(void 0, key).map((degree) => degree.rootPc));
7165
+ return new Set(_chunk3R3QVKY5cjs.tonicizableDegrees.call(void 0, key).map((degree) => degree.rootPc));
5202
7166
  }
5203
7167
  function canBeTonicized(span, tonicizable) {
5204
7168
  if (!tonicizable.has(span.rootPc)) {
5205
7169
  return false;
5206
7170
  }
5207
- return _chunkYPB3A3EYcjs.fifthPcOf.call(void 0, _chunkYPB3A3EYcjs.makeChord.call(void 0, span.rootPc, span.quality)) === (span.rootPc + 7) % 12;
7171
+ return _chunk3R3QVKY5cjs.fifthPcOf.call(void 0, _chunk3R3QVKY5cjs.makeChord.call(void 0, span.rootPc, span.quality)) === (span.rootPc + 7) % 12;
5208
7172
  }
5209
7173
  function generateProgression(opts) {
5210
- _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "progression options");
5211
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, opts.bars, "progression bars");
5212
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, opts.bars, "progression chords");
5213
- const key = _chunkYPB3A3EYcjs.toKeyScale.call(void 0, opts.key);
7174
+ _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "progression options");
7175
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, opts.bars, "progression bars");
7176
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, opts.bars, "progression chords");
7177
+ const key = _chunk3R3QVKY5cjs.toKeyScale.call(void 0, opts.key);
5214
7178
  const ctx = resolveContext(opts.ctx);
5215
7179
  let preset;
5216
7180
  if (opts.preset !== void 0) {
5217
7181
  if (opts.preset.degrees.length === 0) {
5218
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)("progression preset must name at least one degree");
7182
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("progression preset must name at least one degree");
5219
7183
  }
5220
7184
  preset = {
5221
7185
  id: _nullishCoalesce(opts.preset.id, () => ( "custom")),
5222
7186
  name: _nullishCoalesce(opts.preset.name, () => ( "Custom")),
5223
7187
  degrees: opts.preset.degrees.map((degree, index) => {
5224
- _chunkXKSO2V5Icjs.assertDegree.call(void 0, degree, `progression preset degrees[${index}]`);
7188
+ _chunkS5BKZZGMcjs.assertDegree.call(void 0, degree, `progression preset degrees[${index}]`);
5225
7189
  const supported = degree >= 1 && degree <= 7 || Object.values(BORROWED_DEGREES).includes(degree);
5226
7190
  if (!supported) {
5227
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
7191
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
5228
7192
  `progression preset degrees[${index}] is not a supported progression degree; received ${degree}`
5229
7193
  );
5230
7194
  }
@@ -5237,27 +7201,27 @@ function generateProgression(opts) {
5237
7201
  if (preset === void 0 && opts.presetId !== void 0) {
5238
7202
  preset = PRESETS.find((p) => p.id === opts.presetId);
5239
7203
  if (preset === void 0) {
5240
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`Unknown progression preset: ${opts.presetId}`);
7204
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown progression preset: ${opts.presetId}`);
5241
7205
  }
5242
7206
  }
5243
7207
  preset ??= presetFor(opts.style, ctx);
5244
- const ext = opts.ext === void 0 ? "auto" : _chunkXKSO2V5Icjs.assertOneOf.call(void 0, opts.ext, ["auto", ..._chunkYPB3A3EYcjs.chordQualities.call(void 0, )], "progression extension");
7208
+ const ext = opts.ext === void 0 ? "auto" : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, opts.ext, ["auto", ..._chunk3R3QVKY5cjs.chordQualities.call(void 0, )], "progression extension");
5245
7209
  const cycle = resolveCycle(
5246
- _nullishCoalesce(_optionalChain([preset, 'optionalAccess', _59 => _59.degrees]), () => ( [0])),
7210
+ _nullishCoalesce(_optionalChain([preset, 'optionalAccess', _112 => _112.degrees]), () => ( [0])),
5247
7211
  key,
5248
7212
  ext,
5249
- _optionalChain([preset, 'optionalAccess', _60 => _60.functional]) === "cadenceStrong"
7213
+ _optionalChain([preset, 'optionalAccess', _113 => _113.functional]) === "cadenceStrong"
5250
7214
  );
5251
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS6)));
7215
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, _nullishCoalesce(opts.ts, () => ( DEFAULT_TS6)));
5252
7216
  const chords = [];
5253
7217
  for (let bar2 = 0; bar2 < opts.bars; bar2 += 1) {
5254
7218
  const step = cycle[bar2 % cycle.length];
5255
7219
  const chord = {
5256
- rootPc: _nullishCoalesce(_optionalChain([step, 'optionalAccess', _61 => _61.rootPc]), () => ( 0)),
5257
- quality: _nullishCoalesce(_optionalChain([step, 'optionalAccess', _62 => _62.quality]), () => ( "maj")),
7220
+ rootPc: _nullishCoalesce(_optionalChain([step, 'optionalAccess', _114 => _114.rootPc]), () => ( 0)),
7221
+ quality: _nullishCoalesce(_optionalChain([step, 'optionalAccess', _115 => _115.quality]), () => ( "maj")),
5258
7222
  startBeat: bar2 * barBeats
5259
7223
  };
5260
- if (_optionalChain([step, 'optionalAccess', _63 => _63.degree]) !== void 0) {
7224
+ if (_optionalChain([step, 'optionalAccess', _116 => _116.degree]) !== void 0) {
5261
7225
  chord.degree = step.degree;
5262
7226
  }
5263
7227
  chords.push(chord);
@@ -5278,7 +7242,7 @@ function generateProgression(opts) {
5278
7242
  const targetsTonic = (next.rootPc - tonicPc + 12) % 12 === 0;
5279
7243
  const isLastTonicStatement = cur.rootPc === tonicPc && tonicStatements <= 1;
5280
7244
  const alreadySecondary = cur.rootPc === domRoot && cur.quality === "dom7";
5281
- const isResolutionTarget = _optionalChain([chords, 'access', _64 => _64[i - 1], 'optionalAccess', _65 => _65.secondaryDominant]) === true;
7245
+ const isResolutionTarget = _optionalChain([chords, 'access', _117 => _117[i - 1], 'optionalAccess', _118 => _118.secondaryDominant]) === true;
5282
7246
  const takesNoDominant = !canBeTonicized(next, tonicizable);
5283
7247
  if (targetsTonic || isLastTonicStatement || alreadySecondary || isResolutionTarget || takesNoDominant) {
5284
7248
  continue;
@@ -5305,7 +7269,7 @@ function commonToneCount(a, b) {
5305
7269
  return a.filter((pc) => set.has(pc)).length;
5306
7270
  }
5307
7271
  function triadQualityOf(chord) {
5308
- const semis = new Set(chord.intervals.map((interval) => _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, interval)));
7272
+ const semis = new Set(chord.intervals.map((interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval)));
5309
7273
  const hasThird = semis.has(4) ? "maj" : semis.has(3) ? "min" : void 0;
5310
7274
  if (hasThird === void 0) {
5311
7275
  return chord.quality;
@@ -5319,15 +7283,15 @@ function triadQualityOf(chord) {
5319
7283
  return hasThird;
5320
7284
  }
5321
7285
  function diatonicTriadsOf(key) {
5322
- const degrees = _chunkYPB3A3EYcjs.scaleTonesInDegreeOrder.call(void 0, key).length;
7286
+ const degrees = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, key).length;
5323
7287
  const triads = [];
5324
7288
  for (let degree = 1; degree <= degrees; degree += 1) {
5325
- triads.push(_chunkYPB3A3EYcjs.diatonicTriad.call(void 0, degree, key));
7289
+ triads.push(_chunk3R3QVKY5cjs.diatonicTriad.call(void 0, degree, key));
5326
7290
  }
5327
7291
  return triads;
5328
7292
  }
5329
7293
  function sameChord(a, b) {
5330
- return _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, a.rootPc) === _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, b.rootPc) && a.quality === b.quality;
7294
+ return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, a.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, b.rootPc) && a.quality === b.quality;
5331
7295
  }
5332
7296
  var THIRD_OFFSETS = [3, 4, 8, 9];
5333
7297
  var MAX_HINT_ALTER = 2;
@@ -5335,75 +7299,75 @@ function bareSpelling(note2) {
5335
7299
  return { letter: note2.letter, alter: note2.alter };
5336
7300
  }
5337
7301
  function spelledOnRoot(chord, root, tonic, key) {
5338
- const usable = _chunkXKSO2V5Icjs.noteToPitchClass.call(void 0, root) === _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc) && Math.abs(root.alter) <= MAX_HINT_ALTER;
7302
+ const usable = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, root) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) && Math.abs(root.alter) <= MAX_HINT_ALTER;
5339
7303
  const spelled = {
5340
7304
  ...chord,
5341
- rootSpelling: bareSpelling(usable ? root : _chunkYPB3A3EYcjs.spellPitchClass.call(void 0, chord.rootPc, tonic, key))
7305
+ rootSpelling: bareSpelling(usable ? root : _chunk3R3QVKY5cjs.spellPitchClass.call(void 0, chord.rootPc, tonic, key))
5342
7306
  };
5343
7307
  if (chord.bassPc !== void 0) {
5344
- spelled.bassSpelling = bareSpelling(_chunkYPB3A3EYcjs.spellPitchClass.call(void 0, chord.bassPc, tonic, key));
7308
+ spelled.bassSpelling = bareSpelling(_chunk3R3QVKY5cjs.spellPitchClass.call(void 0, chord.bassPc, tonic, key));
5345
7309
  }
5346
7310
  return spelled;
5347
7311
  }
5348
7312
  function spelledInKey(chord, tonic, key) {
5349
- return spelledOnRoot(chord, _chunkYPB3A3EYcjs.spellPitchClass.call(void 0, chord.rootPc, tonic, key), tonic, key);
7313
+ return spelledOnRoot(chord, _chunk3R3QVKY5cjs.spellPitchClass.call(void 0, chord.rootPc, tonic, key), tonic, key);
5350
7314
  }
5351
7315
  function tritoneSubstituteRoot(dominant, tonic, key) {
5352
- const substituteRootPc = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, dominant.rootPc + 6);
5353
- if (_chunkYPB3A3EYcjs.isScaleTone.call(void 0, substituteRootPc, key)) {
5354
- return _chunkYPB3A3EYcjs.spellPitchClass.call(void 0, substituteRootPc, tonic, key);
7316
+ const substituteRootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, dominant.rootPc + 6);
7317
+ if (_chunk3R3QVKY5cjs.isScaleTone.call(void 0, substituteRootPc, key)) {
7318
+ return _chunk3R3QVKY5cjs.spellPitchClass.call(void 0, substituteRootPc, tonic, key);
5355
7319
  }
5356
- const resolution = _chunkYPB3A3EYcjs.spellPitchClass.call(void 0, _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, dominant.rootPc + 5), tonic, key);
5357
- return _chunkXKSO2V5Icjs.transposeNote.call(void 0, resolution, 1);
7320
+ const resolution = _chunk3R3QVKY5cjs.spellPitchClass.call(void 0, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, dominant.rootPc + 5), tonic, key);
7321
+ return _chunkS5BKZZGMcjs.transposeNote.call(void 0, resolution, 1);
5358
7322
  }
5359
7323
  function substituteChord(chord, key, opts) {
5360
- _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
5361
- const source = _chunkYPB3A3EYcjs.toChordData.call(void 0, chord);
5362
- const { scale, tonic } = _chunkYPB3A3EYcjs.resolveKey.call(void 0, key);
5363
- const originalTriad = _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, _chunkYPB3A3EYcjs.makeChord.call(void 0, source.rootPc, triadQualityOf(source)));
7324
+ _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
7325
+ const source = _chunk3R3QVKY5cjs.toChordData.call(void 0, chord);
7326
+ const { scale, tonic } = _chunk3R3QVKY5cjs.resolveKey.call(void 0, key);
7327
+ const originalTriad = _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, _chunk3R3QVKY5cjs.makeChord.call(void 0, source.rootPc, triadQualityOf(source)));
5364
7328
  const candidates = [];
5365
- if (_chunkYPB3A3EYcjs.soundsDominantSeventh.call(void 0, source)) {
5366
- const substitute = _chunkYPB3A3EYcjs.makeChord.call(void 0, _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, source.rootPc + 6), "dom7");
7329
+ if (_chunk3R3QVKY5cjs.soundsDominantSeventh.call(void 0, source)) {
7330
+ const substitute = _chunk3R3QVKY5cjs.makeChord.call(void 0, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, source.rootPc + 6), "dom7");
5367
7331
  candidates.push({
5368
7332
  chord: spelledOnRoot(substitute, tritoneSubstituteRoot(source, tonic, scale), tonic, scale),
5369
7333
  type: "tritone"
5370
7334
  });
5371
7335
  }
5372
7336
  for (const triad of diatonicTriadsOf(scale)) {
5373
- const offset = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, triad.rootPc - source.rootPc);
5374
- if (THIRD_OFFSETS.includes(offset) && commonToneCount(originalTriad, _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, triad)) === 2) {
7337
+ const offset = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, triad.rootPc - source.rootPc);
7338
+ if (THIRD_OFFSETS.includes(offset) && commonToneCount(originalTriad, _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, triad)) === 2) {
5375
7339
  candidates.push({ chord: spelledInKey(triad, tonic, scale), type: "relative" });
5376
7340
  }
5377
7341
  }
5378
- const targetFunction = _chunkQ6R3QAZDcjs.functionOf.call(void 0, source, scale);
5379
- const parallel = _chunkQ6R3QAZDcjs.parallelKey.call(void 0, scale);
7342
+ const targetFunction = _chunkIFZDWIKMcjs.functionOf.call(void 0, source, scale);
7343
+ const parallel = _chunkIFZDWIKMcjs.parallelKey.call(void 0, scale);
5380
7344
  for (const triad of diatonicTriadsOf(parallel)) {
5381
- if (_chunkQ6R3QAZDcjs.functionOf.call(void 0, triad, scale) === targetFunction && !_chunkQ6R3QAZDcjs.isDiatonic.call(void 0, triad, scale)) {
7345
+ if (_chunkIFZDWIKMcjs.functionOf.call(void 0, triad, scale) === targetFunction && !_chunkIFZDWIKMcjs.isDiatonic.call(void 0, triad, scale)) {
5382
7346
  candidates.push({ chord: spelledInKey(triad, tonic, parallel), type: "borrowed" });
5383
7347
  }
5384
7348
  }
5385
7349
  for (const offset of THIRD_OFFSETS) {
5386
7350
  for (const quality of ["maj", "min"]) {
5387
- const mediant = _chunkYPB3A3EYcjs.makeChord.call(void 0, _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, source.rootPc + offset), quality);
5388
- if (commonToneCount(originalTriad, _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, mediant)) === 1 && !_chunkQ6R3QAZDcjs.isDiatonic.call(void 0, mediant, scale)) {
7351
+ const mediant = _chunk3R3QVKY5cjs.makeChord.call(void 0, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, source.rootPc + offset), quality);
7352
+ if (commonToneCount(originalTriad, _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, mediant)) === 1 && !_chunkIFZDWIKMcjs.isDiatonic.call(void 0, mediant, scale)) {
5389
7353
  candidates.push({ chord: spelledInKey(mediant, tonic, scale), type: "chromaticMediant" });
5390
7354
  }
5391
7355
  }
5392
7356
  }
5393
- const melodyPcs = _optionalChain([opts, 'optionalAccess', _66 => _66.melodyPcs, 'optionalAccess', _67 => _67.map, 'call', _68 => _68(_chunkXKSO2V5Icjs.pitchClassOf)]);
7357
+ const melodyPcs = _optionalChain([opts, 'optionalAccess', _119 => _119.melodyPcs, 'optionalAccess', _120 => _120.map, 'call', _121 => _121(_chunkS5BKZZGMcjs.pitchClassOf)]);
5394
7358
  const seen = /* @__PURE__ */ new Set();
5395
7359
  const results = [];
5396
7360
  for (const candidate of candidates) {
5397
7361
  if (sameChord(candidate.chord, source)) {
5398
7362
  continue;
5399
7363
  }
5400
- const dedupeKey = `${_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, candidate.chord.rootPc)}:${candidate.chord.quality}`;
7364
+ const dedupeKey = `${_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, candidate.chord.rootPc)}:${candidate.chord.quality}`;
5401
7365
  if (seen.has(dedupeKey)) {
5402
7366
  continue;
5403
7367
  }
5404
7368
  seen.add(dedupeKey);
5405
7369
  if (melodyPcs !== void 0) {
5406
- const pcs = new Set(_chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, candidate.chord));
7370
+ const pcs = new Set(_chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, candidate.chord));
5407
7371
  if (!melodyPcs.every((pc) => pcs.has(pc))) {
5408
7372
  continue;
5409
7373
  }
@@ -5411,65 +7375,65 @@ function substituteChord(chord, key, opts) {
5411
7375
  results.push({
5412
7376
  chord: candidate.chord,
5413
7377
  type: candidate.type,
5414
- roman: _chunkQ6R3QAZDcjs.chordToRoman.call(void 0, candidate.chord, scale),
5415
- function: _chunkQ6R3QAZDcjs.functionOf.call(void 0, candidate.chord, scale)
7378
+ roman: _chunkIFZDWIKMcjs.chordToRoman.call(void 0, candidate.chord, scale),
7379
+ function: _chunkIFZDWIKMcjs.functionOf.call(void 0, candidate.chord, scale)
5416
7380
  });
5417
7381
  }
5418
7382
  return results;
5419
7383
  }
5420
7384
  function modalInterchangePalette(key) {
5421
- const { scale, tonic } = _chunkYPB3A3EYcjs.resolveKey.call(void 0, key);
7385
+ const { scale, tonic } = _chunk3R3QVKY5cjs.resolveKey.call(void 0, key);
5422
7386
  const palette = [];
5423
7387
  const seen = /* @__PURE__ */ new Set();
5424
7388
  const add = (chord) => {
5425
- const dedupeKey = `${_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc)}:${chord.quality}`;
7389
+ const dedupeKey = `${_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc)}:${chord.quality}`;
5426
7390
  if (seen.has(dedupeKey)) {
5427
7391
  return;
5428
7392
  }
5429
7393
  seen.add(dedupeKey);
5430
7394
  palette.push({
5431
7395
  chord,
5432
- roman: _chunkQ6R3QAZDcjs.chordToRoman.call(void 0, chord, scale),
5433
- source: _chunkQ6R3QAZDcjs.borrowedSource.call(void 0, chord, scale)
7396
+ roman: _chunkIFZDWIKMcjs.chordToRoman.call(void 0, chord, scale),
7397
+ source: _chunkIFZDWIKMcjs.borrowedSource.call(void 0, chord, scale)
5434
7398
  });
5435
7399
  };
5436
- const parallel = _chunkQ6R3QAZDcjs.parallelKey.call(void 0, scale);
7400
+ const parallel = _chunkIFZDWIKMcjs.parallelKey.call(void 0, scale);
5437
7401
  for (const triad of diatonicTriadsOf(parallel)) {
5438
- if (!_chunkQ6R3QAZDcjs.isDiatonic.call(void 0, triad, scale) && _chunkQ6R3QAZDcjs.borrowedSource.call(void 0, triad, scale) !== null) {
7402
+ if (!_chunkIFZDWIKMcjs.isDiatonic.call(void 0, triad, scale) && _chunkIFZDWIKMcjs.borrowedSource.call(void 0, triad, scale) !== null) {
5439
7403
  add(spelledInKey(triad, tonic, parallel));
5440
7404
  }
5441
7405
  }
5442
- const neapolitan = _chunkYPB3A3EYcjs.makeChord.call(void 0, _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, scale.rootPc + 1), "maj");
5443
- if (!_chunkQ6R3QAZDcjs.isDiatonic.call(void 0, neapolitan, scale)) {
5444
- add(spelledOnRoot(neapolitan, _chunkXKSO2V5Icjs.transposeNote.call(void 0, tonic, 1), tonic, scale));
7406
+ const neapolitan = _chunk3R3QVKY5cjs.makeChord.call(void 0, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc + 1), "maj");
7407
+ if (!_chunkIFZDWIKMcjs.isDiatonic.call(void 0, neapolitan, scale)) {
7408
+ add(spelledOnRoot(neapolitan, _chunkS5BKZZGMcjs.transposeNote.call(void 0, tonic, 1), tonic, scale));
5445
7409
  }
5446
7410
  return palette;
5447
7411
  }
5448
7412
  function negativeHarmonyMirror(chord, key) {
5449
- const source = _chunkYPB3A3EYcjs.toChordData.call(void 0, chord);
5450
- const { scale, tonic } = _chunkYPB3A3EYcjs.resolveKey.call(void 0, key);
5451
- const tonicPc = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, scale.rootPc);
5452
- const mirror = (p) => _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, 2 * tonicPc + 7 - p);
5453
- const pcs = _chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, source).map(mirror);
7413
+ const source = _chunk3R3QVKY5cjs.toChordData.call(void 0, chord);
7414
+ const { scale, tonic } = _chunk3R3QVKY5cjs.resolveKey.call(void 0, key);
7415
+ const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc);
7416
+ const mirror = (p) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, 2 * tonicPc + 7 - p);
7417
+ const pcs = _chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, source).map(mirror);
5454
7418
  const bassPc = source.bassPc !== void 0 ? mirror(source.bassPc) : void 0;
5455
7419
  const pitches = bassPc !== void 0 ? [bassPc, ...pcs.map((pc) => pc + 12)] : pcs;
5456
- const detected = _chunkQ6R3QAZDcjs.detectChordBest.call(void 0, pitches);
7420
+ const detected = _chunkIFZDWIKMcjs.detectChordBest.call(void 0, pitches);
5457
7421
  if (detected) {
5458
7422
  if (bassPc === void 0 && detected.bassPc !== void 0) {
5459
- return spelledInKey(_chunkYPB3A3EYcjs.makeChord.call(void 0, detected.rootPc, detected.quality), tonic, scale);
7423
+ return spelledInKey(_chunk3R3QVKY5cjs.makeChord.call(void 0, detected.rootPc, detected.quality), tonic, scale);
5460
7424
  }
5461
7425
  return spelledInKey(detected, tonic, scale);
5462
7426
  }
5463
7427
  const quality = source.quality;
5464
- return spelledInKey(_chunkYPB3A3EYcjs.makeChord.call(void 0, mirror(source.rootPc), quality, bassPc), tonic, scale);
7428
+ return spelledInKey(_chunk3R3QVKY5cjs.makeChord.call(void 0, mirror(source.rootPc), quality, bassPc), tonic, scale);
5465
7429
  }
5466
7430
 
5467
7431
  // src/generate/rhythm/index.ts
5468
7432
  var DEFAULT_RHYTHM_VELOCITY = 96;
5469
7433
  function rhythmToNoteEvents(events, pitch, velocity = DEFAULT_RHYTHM_VELOCITY) {
5470
- _chunkXKSO2V5Icjs.assertMidiPitch.call(void 0, pitch, "pitch");
5471
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, velocity, "velocity", 0, 127);
5472
- return _chunkXKSO2V5Icjs.assertArray.call(void 0, events, "events").map((event) => ({
7434
+ _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, pitch, "pitch");
7435
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, velocity, "velocity", 0, 127);
7436
+ return _chunkS5BKZZGMcjs.assertArray.call(void 0, events, "events").map((event) => ({
5473
7437
  pitch,
5474
7438
  startBeat: event.position,
5475
7439
  durationBeat: event.duration,
@@ -5480,7 +7444,7 @@ var DEFAULT_SUBDIVISION = 2;
5480
7444
  var DEFAULT_DENSITY = 0.5;
5481
7445
  var DEFAULT_BARS = 1;
5482
7446
  function onsetWeightCurve(weight) {
5483
- _chunkXKSO2V5Icjs.assertInteger.call(void 0, weight, "weight", 0, 3);
7447
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0, weight, "weight", 0, 3);
5484
7448
  switch (weight) {
5485
7449
  case 3:
5486
7450
  return 1;
@@ -5493,20 +7457,20 @@ function onsetWeightCurve(weight) {
5493
7457
  }
5494
7458
  }
5495
7459
  function generateRhythm(ts, opts = {}) {
5496
- const asked = _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
5497
- const meter = _chunkXKSO2V5Icjs.meterAt.call(void 0, 0, _chunkXKSO2V5Icjs.toMeterData.call(void 0, ts, "ts"));
7460
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
7461
+ const meter = _chunkS5BKZZGMcjs.meterAt.call(void 0, 0, _chunkS5BKZZGMcjs.toMeterData.call(void 0, ts, "ts"));
5498
7462
  const bars = _nullishCoalesce(asked.bars, () => ( DEFAULT_BARS));
5499
7463
  const subdivision = _nullishCoalesce(asked.subdivision, () => ( DEFAULT_SUBDIVISION));
5500
7464
  const ctx = resolveContext(asked.ctx);
5501
7465
  const density = _nullishCoalesce(ctx.rhythmic, () => ( DEFAULT_DENSITY));
5502
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, bars, "rhythm bars");
5503
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, subdivision, "rhythm subdivision");
5504
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, meter);
7466
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, bars, "rhythm bars");
7467
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, subdivision, "rhythm subdivision");
7468
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, meter);
5505
7469
  const spanBeats = barBeats * bars;
5506
7470
  const step = 1 / subdivision;
5507
7471
  const slotsPerBar = Math.ceil(barBeats * subdivision);
5508
7472
  const slotCount = slotsPerBar * bars;
5509
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, slotCount, "rhythm grid slots");
7473
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, slotCount, "rhythm grid slots");
5510
7474
  const draw = ctx.part("rhythm");
5511
7475
  const positions = [];
5512
7476
  for (let bar2 = 0; bar2 < bars; bar2 += 1) {
@@ -5521,7 +7485,7 @@ function generateRhythm(ts, opts = {}) {
5521
7485
  positions.push(position);
5522
7486
  continue;
5523
7487
  }
5524
- const weight = _chunkXKSO2V5Icjs.metricWeight.call(void 0, position, meter);
7488
+ const weight = _chunkS5BKZZGMcjs.metricWeight.call(void 0, position, meter);
5525
7489
  const probability = onsetWeightCurve(weight) * density;
5526
7490
  if (draw.prob(probability, "onset", bar2, slot)) {
5527
7491
  positions.push(position);
@@ -5537,13 +7501,13 @@ function generateRhythm(ts, opts = {}) {
5537
7501
  return events;
5538
7502
  }
5539
7503
  function rhythmDensity(events, ts) {
5540
- _chunkXKSO2V5Icjs.assertArray.call(void 0, events, "events");
5541
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBar.call(void 0, ts);
7504
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, events, "events");
7505
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBar.call(void 0, ts);
5542
7506
  if (events.length === 0) {
5543
7507
  return 0;
5544
7508
  }
5545
7509
  const last = events[events.length - 1];
5546
- const spanBeats = (_nullishCoalesce(_optionalChain([last, 'optionalAccess', _69 => _69.position]), () => ( 0))) + (_nullishCoalesce(_optionalChain([last, 'optionalAccess', _70 => _70.duration]), () => ( 0)));
7510
+ const spanBeats = (_nullishCoalesce(_optionalChain([last, 'optionalAccess', _122 => _122.position]), () => ( 0))) + (_nullishCoalesce(_optionalChain([last, 'optionalAccess', _123 => _123.duration]), () => ( 0)));
5547
7511
  const bars = spanBeats / barBeats;
5548
7512
  return bars > 0 ? events.length / bars : 0;
5549
7513
  }
@@ -5617,5 +7581,11 @@ function rhythmDensity(events, ts) {
5617
7581
 
5618
7582
 
5619
7583
 
5620
- exports.GENRES = GENRES; exports.PROVENANCE_BASES = PROVENANCE_BASES; exports.fitsQuery = fitsQuery; exports.selectVocabulary = selectVocabulary; exports.pickVocabulary = pickVocabulary; exports.mergeVocabulary = mergeVocabulary; exports.vocabularyOfKind = vocabularyOfKind; exports.assertVocabulary = assertVocabulary; exports.MIN_DIFFICULTY = MIN_DIFFICULTY; exports.MAX_DIFFICULTY = MAX_DIFFICULTY; exports.sustainsStrokes = sustainsStrokes; exports.sustainsShift = sustainsShift; exports.resolveContext = resolveContext; exports.BAR_STEPS = BAR_STEPS; exports.BEAT_STEPS = BEAT_STEPS; exports.STEP_BEATS = STEP_BEATS; exports.gridMetricWeight = gridMetricWeight; exports.thin = thin; exports.double = double; exports.halfTime = halfTime; exports.doubleTime = doubleTime; exports.syncopate = syncopate; exports.ornamentBy = ornamentBy; exports.deform = deform; exports.withinCeiling = withinCeiling; exports.isLickMaterial = isLickMaterial; exports.BASS_LICKS = BASS_LICKS; exports.placeLicks = placeLicks; exports.BASS_STYLES = BASS_STYLES; exports.generateBassLine = generateBassLine; exports.imitate = imitate; exports.generateCounterMelody = generateCounterMelody; exports.FILL_TYPES = FILL_TYPES; exports.FILL_ARCHETYPES = FILL_ARCHETYPES; exports.isFillArchetype = isFillArchetype; exports.DRUM_NOTES = DRUM_NOTES; exports.drumVoiceOf = drumVoiceOf; exports.KICK_STEPS = KICK_STEPS; exports.KICK_FIGURES = KICK_FIGURES; exports.DRUM_KIT = DRUM_KIT; exports.isDrumPattern = isDrumPattern; exports.DRUM_PATTERNS = DRUM_PATTERNS; exports.placeDrumPattern = placeDrumPattern; exports.generateDrums = generateDrums; exports.humanize = humanize; exports.extractGrooveTemplate = extractGrooveTemplate; exports.applyGrooveTemplate = applyGrooveTemplate; exports.classifyMelodyTones = classifyMelodyTones; exports.harmonizeMelody = harmonizeMelody; exports.cellSpan = cellSpan; exports.generateMotif = generateMotif; exports.motifToNoteEvents = motifToNoteEvents; exports.transformMotif = transformMotif; exports.developMotif = developMotif; exports.ORNAMENT_STYLES = ORNAMENT_STYLES; exports.ornament = ornament; exports.BORROWED_DEGREES = BORROWED_DEGREES; exports.progressions = progressions; exports.progressionsByStyle = progressionsByStyle; exports.pickProgressionPreset = pickProgressionPreset; exports.generateProgression = generateProgression; exports.substituteChord = substituteChord; exports.modalInterchangePalette = modalInterchangePalette; exports.negativeHarmonyMirror = negativeHarmonyMirror; exports.rhythmToNoteEvents = rhythmToNoteEvents; exports.onsetWeightCurve = onsetWeightCurve; exports.generateRhythm = generateRhythm; exports.rhythmDensity = rhythmDensity;
5621
- //# sourceMappingURL=chunk-5KW7DNCJ.cjs.map
7584
+
7585
+
7586
+
7587
+
7588
+
7589
+
7590
+ exports.GENRES = GENRES; exports.PROVENANCE_BASES = PROVENANCE_BASES; exports.fitsQuery = fitsQuery; exports.selectVocabulary = selectVocabulary; exports.pickVocabulary = pickVocabulary; exports.mergeVocabulary = mergeVocabulary; exports.vocabularyOfKind = vocabularyOfKind; exports.assertVocabulary = assertVocabulary; exports.MIN_DIFFICULTY = MIN_DIFFICULTY; exports.MAX_DIFFICULTY = MAX_DIFFICULTY; exports.sustainsStrokes = sustainsStrokes; exports.sustainsShift = sustainsShift; exports.resolveContext = resolveContext; exports.BAR_STEPS = BAR_STEPS; exports.BEAT_STEPS = BEAT_STEPS; exports.STEP_BEATS = STEP_BEATS; exports.gridMetricWeight = gridMetricWeight; exports.thin = thin; exports.double = double; exports.halfTime = halfTime; exports.doubleTime = doubleTime; exports.syncopate = syncopate; exports.ornamentBy = ornamentBy; exports.deform = deform; exports.withinCeiling = withinCeiling; exports.isLickMaterial = isLickMaterial; exports.BASS_LICKS = BASS_LICKS; exports.placeLicks = placeLicks; exports.BASS_STYLES = BASS_STYLES; exports.generateBassLine = generateBassLine; exports.imitate = imitate; exports.generateCounterMelody = generateCounterMelody; exports.FILL_TYPES = FILL_TYPES; exports.FILL_ARCHETYPES = FILL_ARCHETYPES; exports.isFillArchetype = isFillArchetype; exports.DRUM_NOTES = DRUM_NOTES; exports.drumVoiceOf = drumVoiceOf; exports.KICK_STEPS = KICK_STEPS; exports.KICK_FIGURES = KICK_FIGURES; exports.DRUM_KIT = DRUM_KIT; exports.isDrumPattern = isDrumPattern; exports.DRUM_PATTERNS = DRUM_PATTERNS; exports.placeDrumPattern = placeDrumPattern; exports.generateDrums = generateDrums; exports.humanize = humanize; exports.extractGrooveTemplate = extractGrooveTemplate; exports.applyGrooveTemplate = applyGrooveTemplate; exports.classifyMelodyTones = classifyMelodyTones; exports.harmonizeMelody = harmonizeMelody; exports.cellSpan = cellSpan; exports.generateMotif = generateMotif; exports.motifToNoteEvents = motifToNoteEvents; exports.transformMotif = transformMotif; exports.developMotif = developMotif; exports.COMPOSITION_PLAN_VERSION = COMPOSITION_PLAN_VERSION; exports.assertCompositionPlan = assertCompositionPlan; exports.planTimeline = planTimeline; exports.generateMelody = generateMelody; exports.ORNAMENT_STYLES = ORNAMENT_STYLES; exports.ornament = ornament; exports.deriveCompositionPlan = deriveCompositionPlan; exports.evaluateComposition = evaluateComposition; exports.BORROWED_DEGREES = BORROWED_DEGREES; exports.progressions = progressions; exports.progressionsByStyle = progressionsByStyle; exports.pickProgressionPreset = pickProgressionPreset; exports.generateProgression = generateProgression; exports.substituteChord = substituteChord; exports.modalInterchangePalette = modalInterchangePalette; exports.negativeHarmonyMirror = negativeHarmonyMirror; exports.rhythmToNoteEvents = rhythmToNoteEvents; exports.onsetWeightCurve = onsetWeightCurve; exports.generateRhythm = generateRhythm; exports.rhythmDensity = rhythmDensity;
7591
+ //# sourceMappingURL=chunk-B2PW6EHN.cjs.map