@real-music-packages/web-core 0.30.0 → 0.32.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.
- package/dist/chunk-ILIXNGPE.js +127 -0
- package/dist/chunk-ILIXNGPE.js.map +1 -0
- package/dist/index.d.ts +100 -1
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/scene/index.d.ts +39 -1
- package/dist/scene/index.js +330 -1
- package/dist/scene/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-N56UTMWA.js +0 -24
- package/dist/chunk-N56UTMWA.js.map +0 -1
package/dist/scene/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
STRING_COUNT,
|
|
3
|
+
buildPlacementMap,
|
|
2
4
|
intervalBySemitones
|
|
3
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-ILIXNGPE.js";
|
|
4
6
|
import {
|
|
5
7
|
getScaleDegree,
|
|
6
8
|
getStability,
|
|
@@ -1296,6 +1298,123 @@ var keyboardFactory = {
|
|
|
1296
1298
|
}
|
|
1297
1299
|
};
|
|
1298
1300
|
|
|
1301
|
+
// src/scene/layers/fretboard.ts
|
|
1302
|
+
var INLAY_FRETS = [3, 5, 7, 9, 12];
|
|
1303
|
+
var NOTE_NAMES = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
1304
|
+
function fretboardLayer() {
|
|
1305
|
+
let placement = /* @__PURE__ */ new Map();
|
|
1306
|
+
let visibleFrets = 12;
|
|
1307
|
+
let hands = { R: "#7b2436", L: "#c8a55b" };
|
|
1308
|
+
let showLabels = false;
|
|
1309
|
+
let rect = { x: 0, y: 0, w: 0, h: 0 };
|
|
1310
|
+
return {
|
|
1311
|
+
key: "fretboard",
|
|
1312
|
+
init(ctx, props) {
|
|
1313
|
+
hands = props.handColors ?? { R: ctx.theme.accent, L: ctx.theme.gold };
|
|
1314
|
+
showLabels = props.showLabels ?? false;
|
|
1315
|
+
const midis = (ctx.score?.notes ?? []).map((n) => n.pitchMidi);
|
|
1316
|
+
placement = buildPlacementMap(midis);
|
|
1317
|
+
let maxFret = 0;
|
|
1318
|
+
for (const p of placement.values()) maxFret = Math.max(maxFret, p.fret);
|
|
1319
|
+
visibleFrets = props.visibleFrets ?? Math.min(15, Math.max(5, maxFret + 1));
|
|
1320
|
+
const sb = ctx.safeBox;
|
|
1321
|
+
const height = props.height ?? 360;
|
|
1322
|
+
const bottomY = props.bottomY ?? sb.bottom;
|
|
1323
|
+
rect = { x: sb.left, y: bottomY - height, w: sb.w, h: height };
|
|
1324
|
+
},
|
|
1325
|
+
draw(ctx, tMs) {
|
|
1326
|
+
const c = ctx.ctx2d;
|
|
1327
|
+
const { x, y, w, h } = rect;
|
|
1328
|
+
const nutW = Math.max(6, w * 0.012);
|
|
1329
|
+
const boardX = x + nutW;
|
|
1330
|
+
const boardW = w - nutW;
|
|
1331
|
+
const fretW = boardW / visibleFrets;
|
|
1332
|
+
const stringGap = h / (STRING_COUNT - 1);
|
|
1333
|
+
const stringY = (s) => y + h - s * stringGap;
|
|
1334
|
+
const fretX = (f) => boardX + f * fretW;
|
|
1335
|
+
const dotX = (f) => f === 0 ? x + nutW / 2 : fretX(f) - fretW / 2;
|
|
1336
|
+
c.save();
|
|
1337
|
+
c.fillStyle = "#f1e7d6";
|
|
1338
|
+
c.fillRect(x, y, w, h);
|
|
1339
|
+
c.fillStyle = "#2a2420";
|
|
1340
|
+
c.fillRect(x, y, nutW, h);
|
|
1341
|
+
c.strokeStyle = "#b8a98c";
|
|
1342
|
+
c.lineWidth = 2;
|
|
1343
|
+
for (let f = 1; f <= visibleFrets; f++) {
|
|
1344
|
+
c.beginPath();
|
|
1345
|
+
c.moveTo(fretX(f), y);
|
|
1346
|
+
c.lineTo(fretX(f), y + h);
|
|
1347
|
+
c.stroke();
|
|
1348
|
+
}
|
|
1349
|
+
c.fillStyle = "rgba(60,50,40,0.28)";
|
|
1350
|
+
for (const f of INLAY_FRETS) {
|
|
1351
|
+
if (f > visibleFrets) continue;
|
|
1352
|
+
const cx = dotX(f);
|
|
1353
|
+
const r = Math.min(stringGap, fretW) * 0.18;
|
|
1354
|
+
if (f === 12) {
|
|
1355
|
+
c.beginPath();
|
|
1356
|
+
c.arc(cx, stringY(STRING_COUNT - 1) + stringGap * 0.5, r, 0, Math.PI * 2);
|
|
1357
|
+
c.fill();
|
|
1358
|
+
c.beginPath();
|
|
1359
|
+
c.arc(cx, stringY(0) - stringGap * 0.5, r, 0, Math.PI * 2);
|
|
1360
|
+
c.fill();
|
|
1361
|
+
} else {
|
|
1362
|
+
c.beginPath();
|
|
1363
|
+
c.arc(cx, y + h / 2, r, 0, Math.PI * 2);
|
|
1364
|
+
c.fill();
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
c.strokeStyle = "#5c5345";
|
|
1368
|
+
for (let s = 0; s < STRING_COUNT; s++) {
|
|
1369
|
+
c.lineWidth = 1 + (STRING_COUNT - 1 - s) * 0.5;
|
|
1370
|
+
c.beginPath();
|
|
1371
|
+
c.moveTo(x, stringY(s));
|
|
1372
|
+
c.lineTo(x + w, stringY(s));
|
|
1373
|
+
c.stroke();
|
|
1374
|
+
}
|
|
1375
|
+
const dotR = Math.min(stringGap, fretW) * 0.42;
|
|
1376
|
+
for (const n of ctx.score?.notes ?? []) {
|
|
1377
|
+
if (!(tMs >= n.onsetMs && tMs < n.onsetMs + n.durMs)) continue;
|
|
1378
|
+
const pos = placement.get(n.pitchMidi);
|
|
1379
|
+
if (!pos || pos.fret > visibleFrets) continue;
|
|
1380
|
+
const cx = dotX(pos.fret);
|
|
1381
|
+
const cy = stringY(pos.string);
|
|
1382
|
+
c.fillStyle = n.hand === "L" ? hands.L : hands.R;
|
|
1383
|
+
c.beginPath();
|
|
1384
|
+
c.arc(cx, cy, dotR, 0, Math.PI * 2);
|
|
1385
|
+
c.fill();
|
|
1386
|
+
if (showLabels) {
|
|
1387
|
+
c.fillStyle = "#fff";
|
|
1388
|
+
c.font = `${Math.round(dotR * 1.1)}px sans-serif`;
|
|
1389
|
+
c.textAlign = "center";
|
|
1390
|
+
c.textBaseline = "middle";
|
|
1391
|
+
c.fillText(NOTE_NAMES[n.pitchMidi % 12], cx, cy);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
c.restore();
|
|
1395
|
+
},
|
|
1396
|
+
dispose() {
|
|
1397
|
+
placement = /* @__PURE__ */ new Map();
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1401
|
+
var fretboardFactory = {
|
|
1402
|
+
key: "fretboard",
|
|
1403
|
+
create: fretboardLayer,
|
|
1404
|
+
validateProps(props) {
|
|
1405
|
+
const errs = [];
|
|
1406
|
+
if (props == null || typeof props !== "object") return ["fretboard: props must be an object"];
|
|
1407
|
+
const p = props;
|
|
1408
|
+
if (p.visibleFrets != null && (typeof p.visibleFrets !== "number" || p.visibleFrets < 1 || p.visibleFrets > 24))
|
|
1409
|
+
errs.push("fretboard.visibleFrets must be a number in 1..24");
|
|
1410
|
+
if (p.height != null && (typeof p.height !== "number" || p.height <= 0))
|
|
1411
|
+
errs.push("fretboard.height must be a positive number");
|
|
1412
|
+
if (p.bottomY != null && typeof p.bottomY !== "number") errs.push("fretboard.bottomY must be a number");
|
|
1413
|
+
if (p.showLabels != null && typeof p.showLabels !== "boolean") errs.push("fretboard.showLabels must be a boolean");
|
|
1414
|
+
return errs;
|
|
1415
|
+
}
|
|
1416
|
+
};
|
|
1417
|
+
|
|
1299
1418
|
// src/scene/layers/fallingNotes.ts
|
|
1300
1419
|
var DEFAULT_LEAD_MS = 2e3;
|
|
1301
1420
|
function rgba(color, a) {
|
|
@@ -4646,6 +4765,212 @@ var endCardFactory = {
|
|
|
4646
4765
|
}
|
|
4647
4766
|
};
|
|
4648
4767
|
|
|
4768
|
+
// src/scene/layers/imageReveal.ts
|
|
4769
|
+
var DEFAULTS11 = {
|
|
4770
|
+
mode: "pixelate",
|
|
4771
|
+
startMs: 0,
|
|
4772
|
+
durationMs: 6e3,
|
|
4773
|
+
difficulty: 0.5
|
|
4774
|
+
};
|
|
4775
|
+
function clamp017(x) {
|
|
4776
|
+
return x < 0 ? 0 : x > 1 ? 1 : x;
|
|
4777
|
+
}
|
|
4778
|
+
function fitRect(iW, iH, bx, by, bw, bh) {
|
|
4779
|
+
const scale = Math.min(bw / iW, bh / iH);
|
|
4780
|
+
const dw = iW * scale;
|
|
4781
|
+
const dh = iH * scale;
|
|
4782
|
+
return { dx: bx + (bw - dw) / 2, dy: by + (bh - dh) / 2, dw, dh };
|
|
4783
|
+
}
|
|
4784
|
+
function blockSizeAt(p, maxBlock) {
|
|
4785
|
+
return Math.max(1, Math.round(maxBlock * (1 - p) + 1 * p));
|
|
4786
|
+
}
|
|
4787
|
+
function tileHash(i) {
|
|
4788
|
+
let x = i * 2654435761 >>> 0;
|
|
4789
|
+
x ^= x << 13;
|
|
4790
|
+
x ^= x >>> 17;
|
|
4791
|
+
x ^= x << 5;
|
|
4792
|
+
return (x >>> 0) / 4294967295;
|
|
4793
|
+
}
|
|
4794
|
+
function tileHashSigned(i, salt) {
|
|
4795
|
+
return tileHash(i * 1013904223 + salt * 22695477 | 0) * 2 - 1;
|
|
4796
|
+
}
|
|
4797
|
+
function imageRevealLayer() {
|
|
4798
|
+
let mode = DEFAULTS11.mode;
|
|
4799
|
+
let startMs = DEFAULTS11.startMs;
|
|
4800
|
+
let durationMs = DEFAULTS11.durationMs;
|
|
4801
|
+
let difficulty = DEFAULTS11.difficulty;
|
|
4802
|
+
let image = null;
|
|
4803
|
+
let offscreen = null;
|
|
4804
|
+
let offCtx = null;
|
|
4805
|
+
let imgW = 0;
|
|
4806
|
+
let imgH = 0;
|
|
4807
|
+
function ensureOffscreen(w, h) {
|
|
4808
|
+
const needNew = !offscreen || offscreen.width !== w || offscreen.height !== h;
|
|
4809
|
+
if (needNew) {
|
|
4810
|
+
if (typeof OffscreenCanvas !== "undefined") {
|
|
4811
|
+
offscreen = new OffscreenCanvas(w, h);
|
|
4812
|
+
offCtx = offscreen.getContext("2d");
|
|
4813
|
+
} else {
|
|
4814
|
+
const el = typeof document !== "undefined" ? document.createElement("canvas") : null;
|
|
4815
|
+
if (!el) {
|
|
4816
|
+
offscreen = null;
|
|
4817
|
+
offCtx = null;
|
|
4818
|
+
return null;
|
|
4819
|
+
}
|
|
4820
|
+
el.width = w;
|
|
4821
|
+
el.height = h;
|
|
4822
|
+
offscreen = el;
|
|
4823
|
+
offCtx = el.getContext("2d");
|
|
4824
|
+
}
|
|
4825
|
+
}
|
|
4826
|
+
return offCtx;
|
|
4827
|
+
}
|
|
4828
|
+
return {
|
|
4829
|
+
key: "image-reveal",
|
|
4830
|
+
init(_ctx, props) {
|
|
4831
|
+
mode = props.mode ?? DEFAULTS11.mode;
|
|
4832
|
+
startMs = props.startMs ?? DEFAULTS11.startMs;
|
|
4833
|
+
durationMs = props.durationMs ?? DEFAULTS11.durationMs;
|
|
4834
|
+
difficulty = props.difficulty ?? DEFAULTS11.difficulty;
|
|
4835
|
+
image = props.image;
|
|
4836
|
+
const src = props.image;
|
|
4837
|
+
imgW = src["naturalWidth"] ?? src["displayWidth"] ?? src["width"] ?? 0;
|
|
4838
|
+
imgH = src["naturalHeight"] ?? src["displayHeight"] ?? src["height"] ?? 0;
|
|
4839
|
+
},
|
|
4840
|
+
draw(ctx, tMs) {
|
|
4841
|
+
if (!image || imgW === 0 || imgH === 0) return;
|
|
4842
|
+
const p = clamp017((tMs - startMs) / (durationMs > 0 ? durationMs : 1));
|
|
4843
|
+
const sb = ctx.safeBox;
|
|
4844
|
+
const fit = fitRect(imgW, imgH, sb.left, sb.top, sb.w, sb.h);
|
|
4845
|
+
const c = ctx.ctx2d;
|
|
4846
|
+
c.save();
|
|
4847
|
+
c.beginPath();
|
|
4848
|
+
c.rect(fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4849
|
+
c.clip();
|
|
4850
|
+
if (mode === "pixelate") {
|
|
4851
|
+
drawPixelate(c, image, fit, p, difficulty, imgW, imgH, ensureOffscreen);
|
|
4852
|
+
} else if (mode === "blur") {
|
|
4853
|
+
drawBlur(c, image, fit, p, difficulty, imgW, imgH, ensureOffscreen);
|
|
4854
|
+
} else {
|
|
4855
|
+
drawShuffle(c, image, fit, p, difficulty, imgW, imgH);
|
|
4856
|
+
}
|
|
4857
|
+
c.restore();
|
|
4858
|
+
},
|
|
4859
|
+
dispose() {
|
|
4860
|
+
image = null;
|
|
4861
|
+
offscreen = null;
|
|
4862
|
+
offCtx = null;
|
|
4863
|
+
}
|
|
4864
|
+
};
|
|
4865
|
+
}
|
|
4866
|
+
function drawPixelate(c, image, fit, p, difficulty, imgW, imgH, getOffCtx) {
|
|
4867
|
+
const maxBlock = Math.max(2, Math.round(fit.dw * (0.03125 + difficulty * 0.21875)));
|
|
4868
|
+
const blockSize = blockSizeAt(p, maxBlock);
|
|
4869
|
+
if (blockSize <= 1) {
|
|
4870
|
+
c.drawImage(image, 0, 0, imgW, imgH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4871
|
+
return;
|
|
4872
|
+
}
|
|
4873
|
+
const smallW = Math.max(1, Math.ceil(fit.dw / blockSize));
|
|
4874
|
+
const smallH = Math.max(1, Math.ceil(fit.dh / blockSize));
|
|
4875
|
+
const oc = getOffCtx(smallW, smallH);
|
|
4876
|
+
if (!oc) {
|
|
4877
|
+
c.drawImage(image, 0, 0, imgW, imgH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4878
|
+
return;
|
|
4879
|
+
}
|
|
4880
|
+
oc.clearRect(0, 0, smallW, smallH);
|
|
4881
|
+
oc.drawImage(image, 0, 0, imgW, imgH, 0, 0, smallW, smallH);
|
|
4882
|
+
const prev = c.imageSmoothingEnabled;
|
|
4883
|
+
c.imageSmoothingEnabled = false;
|
|
4884
|
+
const off = oc.canvas;
|
|
4885
|
+
c.drawImage(off, 0, 0, smallW, smallH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4886
|
+
c.imageSmoothingEnabled = prev;
|
|
4887
|
+
}
|
|
4888
|
+
function drawBlur(c, image, fit, p, difficulty, imgW, imgH, getOffCtx) {
|
|
4889
|
+
const maxBlur = 8 + difficulty * 72;
|
|
4890
|
+
const blurPx = maxBlur * (1 - p);
|
|
4891
|
+
const cAny = c;
|
|
4892
|
+
const hasFilter = "filter" in c && cAny["filter"] !== void 0;
|
|
4893
|
+
if (hasFilter && blurPx > 0) {
|
|
4894
|
+
const prev = cAny["filter"];
|
|
4895
|
+
cAny["filter"] = `blur(${blurPx.toFixed(1)}px)`;
|
|
4896
|
+
c.drawImage(image, 0, 0, imgW, imgH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4897
|
+
cAny["filter"] = prev ?? "none";
|
|
4898
|
+
} else if (blurPx > 0) {
|
|
4899
|
+
const passes = Math.min(6, Math.round(blurPx / 8));
|
|
4900
|
+
if (passes > 0) {
|
|
4901
|
+
let w = Math.max(1, Math.round(fit.dw / Math.pow(2, passes)));
|
|
4902
|
+
let h = Math.max(1, Math.round(fit.dh / Math.pow(2, passes)));
|
|
4903
|
+
const oc = getOffCtx(w, h);
|
|
4904
|
+
if (oc) {
|
|
4905
|
+
oc.clearRect(0, 0, w, h);
|
|
4906
|
+
oc.drawImage(image, 0, 0, imgW, imgH, 0, 0, w, h);
|
|
4907
|
+
c.drawImage(oc.canvas, 0, 0, w, h, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4908
|
+
} else {
|
|
4909
|
+
c.drawImage(image, 0, 0, imgW, imgH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4910
|
+
}
|
|
4911
|
+
} else {
|
|
4912
|
+
c.drawImage(image, 0, 0, imgW, imgH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4913
|
+
}
|
|
4914
|
+
} else {
|
|
4915
|
+
c.drawImage(image, 0, 0, imgW, imgH, fit.dx, fit.dy, fit.dw, fit.dh);
|
|
4916
|
+
}
|
|
4917
|
+
}
|
|
4918
|
+
function drawShuffle(c, image, fit, p, difficulty, imgW, imgH) {
|
|
4919
|
+
const cols = 8;
|
|
4920
|
+
const rows = 14;
|
|
4921
|
+
const tileW = fit.dw / cols;
|
|
4922
|
+
const tileH = fit.dh / rows;
|
|
4923
|
+
const srcTileW = imgW / cols;
|
|
4924
|
+
const srcTileH = imgH / rows;
|
|
4925
|
+
const maxOffX = tileW * difficulty * 1.5;
|
|
4926
|
+
const maxOffY = tileH * difficulty * 1.5;
|
|
4927
|
+
const ease = 1 - (1 - p) * (1 - p);
|
|
4928
|
+
for (let row = 0; row < rows; row++) {
|
|
4929
|
+
for (let col = 0; col < cols; col++) {
|
|
4930
|
+
const i = row * cols + col;
|
|
4931
|
+
const offX = tileHashSigned(i, 0) * maxOffX * (1 - ease);
|
|
4932
|
+
const offY = tileHashSigned(i, 1) * maxOffY * (1 - ease);
|
|
4933
|
+
const sx = col * srcTileW;
|
|
4934
|
+
const sy = row * srcTileH;
|
|
4935
|
+
const dxHome = fit.dx + col * tileW;
|
|
4936
|
+
const dyHome = fit.dy + row * tileH;
|
|
4937
|
+
const dx = dxHome + offX;
|
|
4938
|
+
const dy = dyHome + offY;
|
|
4939
|
+
c.drawImage(
|
|
4940
|
+
image,
|
|
4941
|
+
sx,
|
|
4942
|
+
sy,
|
|
4943
|
+
srcTileW,
|
|
4944
|
+
srcTileH,
|
|
4945
|
+
dx,
|
|
4946
|
+
dy,
|
|
4947
|
+
tileW,
|
|
4948
|
+
tileH
|
|
4949
|
+
);
|
|
4950
|
+
}
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
var VALID_MODES = ["pixelate", "shuffle", "blur"];
|
|
4954
|
+
var imageRevealFactory = {
|
|
4955
|
+
key: "image-reveal",
|
|
4956
|
+
create: imageRevealLayer,
|
|
4957
|
+
validateProps(props) {
|
|
4958
|
+
if (props == null || typeof props !== "object") return ["image-reveal: props must be an object"];
|
|
4959
|
+
const p = props;
|
|
4960
|
+
const errs = [];
|
|
4961
|
+
if (p["image"] == null) errs.push("image-reveal.image is required");
|
|
4962
|
+
if (p["mode"] != null && !VALID_MODES.includes(p["mode"]))
|
|
4963
|
+
errs.push(`image-reveal.mode must be one of: ${VALID_MODES.join(", ")}`);
|
|
4964
|
+
if (p["startMs"] != null && typeof p["startMs"] !== "number")
|
|
4965
|
+
errs.push("image-reveal.startMs must be a number");
|
|
4966
|
+
if (p["durationMs"] != null && (typeof p["durationMs"] !== "number" || p["durationMs"] <= 0))
|
|
4967
|
+
errs.push("image-reveal.durationMs must be a positive number");
|
|
4968
|
+
if (p["difficulty"] != null && (typeof p["difficulty"] !== "number" || p["difficulty"] < 0 || p["difficulty"] > 1))
|
|
4969
|
+
errs.push("image-reveal.difficulty must be a number in [0, 1]");
|
|
4970
|
+
return errs;
|
|
4971
|
+
}
|
|
4972
|
+
};
|
|
4973
|
+
|
|
4649
4974
|
// src/scene/registry.ts
|
|
4650
4975
|
var REGISTRY = /* @__PURE__ */ new Map();
|
|
4651
4976
|
function registerLayer(factory) {
|
|
@@ -4662,6 +4987,7 @@ registerLayer(captionFactory);
|
|
|
4662
4987
|
registerLayer(notationFactory);
|
|
4663
4988
|
registerLayer(scrollCursorFactory);
|
|
4664
4989
|
registerLayer(keyboardFactory);
|
|
4990
|
+
registerLayer(fretboardFactory);
|
|
4665
4991
|
registerLayer(fallingNotesFactory);
|
|
4666
4992
|
registerLayer(hookFactory);
|
|
4667
4993
|
registerLayer(revealFactory);
|
|
@@ -4693,6 +5019,7 @@ registerLayer(tensionGraphFactory);
|
|
|
4693
5019
|
registerLayer(textureFactory);
|
|
4694
5020
|
registerLayer(statCounterFactory);
|
|
4695
5021
|
registerLayer(endCardFactory);
|
|
5022
|
+
registerLayer(imageRevealFactory);
|
|
4696
5023
|
|
|
4697
5024
|
// src/scene/audioLayers.ts
|
|
4698
5025
|
function countInSchedule(opts) {
|
|
@@ -5503,6 +5830,7 @@ export {
|
|
|
5503
5830
|
followWindowStart,
|
|
5504
5831
|
fracSlotPoint,
|
|
5505
5832
|
frameRect,
|
|
5833
|
+
fretboardFactory,
|
|
5506
5834
|
functionColor,
|
|
5507
5835
|
functionalHarmonyFactory,
|
|
5508
5836
|
getKeyboardLayout,
|
|
@@ -5512,6 +5840,7 @@ export {
|
|
|
5512
5840
|
highlightIntensity,
|
|
5513
5841
|
hookFactory,
|
|
5514
5842
|
identityCamera,
|
|
5843
|
+
imageRevealFactory,
|
|
5515
5844
|
inRange,
|
|
5516
5845
|
intervalArcsFactory,
|
|
5517
5846
|
invLerp,
|