@yam8d/m8-sdk 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -705,7 +705,7 @@ var D = (e) => {
705
705
  down: I.Down,
706
706
  left: I.Left,
707
707
  right: I.Right
708
- }, re = I.Up | I.Down | I.Left | I.Right, ie = 24, ae = 150, L = .1, oe = (e) => e === "up" || e === "down" ? "vertical" : "horizontal", se = (e) => {
708
+ }, re = I.Up | I.Down | I.Left | I.Right | I.Edit | I.Opt | I.Shift, ie = 24, ae = 150, L = .1, oe = (e) => e === "up" || e === "down" ? "vertical" : "horizontal", se = (e) => {
709
709
  switch (e) {
710
710
  case "up": return "down";
711
711
  case "down": return "up";
@@ -835,22 +835,22 @@ var D = (e) => {
835
835
  y(), e.protocol.eventBus.off("key", k), A();
836
836
  }
837
837
  };
838
- }, z = (e) => e?.trim().toLowerCase() ?? "", B = /\.m[a-z0-9]{2}$/i, me = (e) => [
838
+ }, z = (e) => e?.trim().toLowerCase() ?? "", me = /\.m[a-z0-9]{2}$/i, he = (e) => [
839
839
  e.viewName ?? "",
840
840
  e.viewTitle ?? "",
841
841
  e.cursorPos?.x ?? "",
842
842
  e.cursorPos?.y ?? "",
843
843
  e.textUnderCursor ?? "",
844
844
  e.currentLine ?? ""
845
- ].join("|"), he = (e) => e.textUnderCursor?.trim() || e.currentLine?.trim() || null, ge = (e) => {
845
+ ].join("|"), ge = (e) => e.textUnderCursor?.trim() || e.currentLine?.trim() || null, _e = (e) => {
846
846
  let t = z(e.viewName), n = z(e.viewTitle);
847
847
  return t.includes("load") || t.includes("save") || n.includes("load") || n.includes("save");
848
- }, _e = (e) => z(e) === "/..", ve = (e) => !!e?.trim().startsWith("/"), ye = (e) => !!e && !ve(e) && B.test(e.trim()), be = (e) => {
848
+ }, ve = (e) => z(e) === "/..", ye = (e) => !!e?.trim().startsWith("/"), be = (e) => !!e && !ye(e) && me.test(e.trim()), xe = (e) => {
849
849
  let t = e?.trim() ?? "";
850
850
  if (!t) return [];
851
- let n = z(t), r = z(t.replace(B, ""));
851
+ let n = z(t), r = z(t.replace(me, ""));
852
852
  return Array.from(new Set([n, r].filter(Boolean)));
853
- }, xe = (e) => _e(e) ? "parent" : ve(e) ? /^\/[^/]+$/.test(e.trim()) ? "dir" : "other" : ye(e) ? "file" : "other", Se = (e, t) => {
853
+ }, Se = (e) => ve(e) ? "parent" : ye(e) ? /^\/[^/]+$/.test(e.trim()) ? "dir" : "other" : be(e) ? "file" : "other", Ce = (e, t) => {
854
854
  let n = (t) => e[t]?.trim() ?? "", r = t.cursorPos?.y ?? null, i = z(t.viewTitle), a = 0, o = e.length - 1;
855
855
  if (r !== null && n(r)) {
856
856
  for (a = r; a > 0 && n(a - 1);) --a;
@@ -863,7 +863,7 @@ var D = (e) => {
863
863
  row: e,
864
864
  text: t,
865
865
  key: z(t),
866
- kind: xe(t)
866
+ kind: Se(t)
867
867
  });
868
868
  }
869
869
  let c = t.textUnderCursor?.trim();
@@ -874,7 +874,7 @@ var D = (e) => {
874
874
  hasParent: s.some((e) => e.kind === "parent"),
875
875
  consistent: !c || r === null || n(r).includes(c)
876
876
  };
877
- }, Ce = (e, t) => {
877
+ }, we = (e, t) => {
878
878
  if (t.length === 0) return {
879
879
  order: e,
880
880
  consistent: !0
@@ -908,26 +908,26 @@ var D = (e) => {
908
908
  order: i,
909
909
  consistent: !0
910
910
  };
911
- }, we = (e) => e.split(/[^a-z0-9]+/).filter((e) => e.length >= 3), Te = /* @__PURE__ */ new Set([
911
+ }, Te = (e) => e.split(/[^a-z0-9]+/).filter((e) => e.length >= 3), Ee = /* @__PURE__ */ new Set([
912
912
  "load",
913
913
  "save",
914
914
  "select",
915
915
  "create",
916
916
  "directory",
917
917
  "new"
918
- ]), Ee = (e, t) => ({
919
- target: we(z(e).replace(B, "")),
920
- title: we(z(t)).filter((e) => !Te.has(e))
921
- }), De = (e, t) => {
918
+ ]), De = (e, t) => ({
919
+ target: Te(z(e).replace(me, "")),
920
+ title: Te(z(t)).filter((e) => !Ee.has(e))
921
+ }), Oe = (e, t) => {
922
922
  let n = e.replace(/^\//, "");
923
923
  if (n.length < 3) return 0;
924
924
  let r = (e) => e.includes(n) || n.includes(e);
925
925
  return t.target.some(r) ? 2 : +!!t.title.some(r);
926
- }, V = (e) => new Promise((t) => setTimeout(t, e)), Oe = ({ getKeySink: e, store: t, debugLog: n, getScreenLines: r }) => {
926
+ }, B = (e) => new Promise((t) => setTimeout(t, e)), ke = ({ getKeySink: e, store: t, debugLog: n, getScreenLines: r }) => {
927
927
  let i = () => !!e(), a = (t) => {
928
928
  e()?.sendKeys(t);
929
929
  }, o = async (e, t = 50) => {
930
- a(e), await V(t), a(0), await V(t);
930
+ a(e), await B(t), a(0), await B(t);
931
931
  }, s = (e, n = 500) => new Promise((r) => {
932
932
  let i = !1, a = null, o = null, s = (e) => {
933
933
  i || (i = !0, o !== null && clearTimeout(o), a?.(), r(e));
@@ -965,21 +965,21 @@ var D = (e) => {
965
965
  }),
966
966
  getFileBrowserSnapshot: c,
967
967
  waitForFileBrowserSnapshotChange: (e, n = 500) => new Promise((r) => {
968
- let i = !1, a = null, o = null, s = null, l = null, u = null, d = null, f = me(e), p = (e) => {
968
+ let i = !1, a = null, o = null, s = null, l = null, u = null, d = null, f = he(e), p = (e) => {
969
969
  i || (i = !0, d !== null && clearTimeout(d), a?.(), o?.(), s?.(), l?.(), u?.(), r(e));
970
970
  }, m = () => {
971
971
  let e = c();
972
- me(e) !== f && p(e);
972
+ he(e) !== f && p(e);
973
973
  }, h = c();
974
- me(h) === f ? (a = t.sub("textUnderCursor", m), o = t.sub("currentLine", m), s = t.sub("cursorPos", m), l = t.sub("viewName", m), u = t.sub("viewTitle", m), d = setTimeout(() => {
974
+ he(h) === f ? (a = t.sub("textUnderCursor", m), o = t.sub("currentLine", m), s = t.sub("cursorPos", m), l = t.sub("viewName", m), u = t.sub("viewTitle", m), d = setTimeout(() => {
975
975
  p(c());
976
976
  }, n)) : p(h);
977
977
  }),
978
978
  getScreenLines: r
979
979
  };
980
- }, H = (e, t) => {
980
+ }, V = (e, t) => {
981
981
  t === void 0 ? console.log("[M8SDK browseFile]", e) : console.log("[M8SDK browseFile]", e, t);
982
- }, ke = 8, Ae = 8, je = 64, Me = 512, Ne = () => ({
982
+ }, Ae = 8, je = 8, Me = 64, Ne = 512, Pe = () => ({
983
983
  order: [],
984
984
  kinds: /* @__PURE__ */ new Map(),
985
985
  names: /* @__PURE__ */ new Map(),
@@ -989,40 +989,40 @@ var D = (e) => {
989
989
  sorted: !1,
990
990
  visited: /* @__PURE__ */ new Set(),
991
991
  rejected: /* @__PURE__ */ new Set()
992
- }), Pe = (e) => e === "up" ? "down" : "up", Fe = (e) => {
992
+ }), Fe = (e) => e === "up" ? "down" : "up", Ie = (e) => {
993
993
  let { hasBus: t, pressAndRelease: n, getFileBrowserSnapshot: r, waitForFileBrowserSnapshotChange: i, getScreenLines: a } = e, o = /* @__PURE__ */ new Map(), s = null, c = null;
994
994
  return async (e, l = !0) => {
995
995
  if (!t()) return !1;
996
996
  let u = z(e);
997
997
  if (!u) return !1;
998
- let d = B.test(u), f = Ee(e, r().viewTitle);
999
- H("start", {
998
+ let d = me.test(u), f = De(e, r().viewTitle);
999
+ V("start", {
1000
1000
  targetText: e,
1001
1001
  normalizedTarget: u,
1002
1002
  exact: l
1003
1003
  });
1004
- let p = () => ge(r()), m = async (e, t = 350) => {
1004
+ let p = () => _e(r()), m = async (e, t = 350) => {
1005
1005
  let a = r();
1006
1006
  await n(e, 35);
1007
1007
  let o = await i(a, t);
1008
1008
  return {
1009
- changed: me(o) !== me(a),
1009
+ changed: he(o) !== he(a),
1010
1010
  snapshot: o
1011
1011
  };
1012
1012
  }, h = (e) => e === "up" ? I.Up : I.Down, g = (e) => I.Opt | h(e), _ = async () => {
1013
1013
  let e = r();
1014
- H("apply alphabetical sort"), await n(I.Shift | I.Opt, 35), await V(180), await i(e, 300);
1015
- }, v = (e) => ye(e) ? be(e).some((e) => l ? e === u : e.includes(u)) : !1, y = (e) => {
1014
+ V("apply alphabetical sort"), await n(I.Shift | I.Opt, 35), await B(180), await i(e, 300);
1015
+ }, v = (e) => be(e) ? xe(e).some((e) => l ? e === u : e.includes(u)) : !1, y = (e) => {
1016
1016
  let t = e.trim();
1017
- return d ? t : t.replace(B, "");
1017
+ return d ? t : t.replace(me, "");
1018
1018
  }, b = (e) => z(y(e)), x = y(e), S = async () => {
1019
1019
  for (let e = 0;; e += 1) {
1020
- let t = Se(a(), r());
1020
+ let t = Ce(a(), r());
1021
1021
  if (t.consistent || e >= 2) return t;
1022
- await V(40);
1022
+ await B(40);
1023
1023
  }
1024
1024
  }, C = (e, t) => {
1025
- let n = t.entries.map((e) => e.key), i = Ce(e.order, n);
1025
+ let n = t.entries.map((e) => e.key), i = we(e.order, n);
1026
1026
  e.order = i.order, i.consistent || (e.top = !1, e.bottom = !1);
1027
1027
  for (let n of t.entries) e.kinds.set(n.key, n.kind), e.names.set(n.key, n.text);
1028
1028
  let a = z(r().viewName);
@@ -1031,10 +1031,10 @@ var D = (e) => {
1031
1031
  let e = o.get(a);
1032
1032
  (e === void 0 || n.length < e) && o.set(a, n.length);
1033
1033
  }
1034
- n.length < Math.max(Ae, o.get(a) ?? 0) && (e.top = !0, e.bottom = !0);
1034
+ n.length < Math.max(je, o.get(a) ?? 0) && (e.top = !0, e.bottom = !0);
1035
1035
  }, w = async (e, t, n) => {
1036
1036
  let r = (await m(g(n), 280)).changed, i = r, a = !1;
1037
- if (!r && s !== !0) for (let e = 0; e < ke; e += 1) {
1037
+ if (!r && s !== !0) for (let e = 0; e < Ae; e += 1) {
1038
1038
  if (!(await m(h(n), 250)).changed) {
1039
1039
  a = !0;
1040
1040
  break;
@@ -1042,11 +1042,11 @@ var D = (e) => {
1042
1042
  i = !0, s = !1;
1043
1043
  }
1044
1044
  else r || (a = !0);
1045
- if (a && (n === "up" ? e.top = !0 : e.bottom = !0, H("end of list", { direction: n })), !i) return null;
1045
+ if (a && (n === "up" ? e.top = !0 : e.bottom = !0, V("end of list", { direction: n })), !i) return null;
1046
1046
  let o = await S();
1047
1047
  C(e, o);
1048
1048
  let c = t.cursorKey ? e.order.indexOf(t.cursorKey) : -1, l = o.cursorKey ? e.order.indexOf(o.cursorKey) : -1, u = Math.abs(l - c);
1049
- return r && c >= 0 && l >= 0 && u > 0 && u < ke && (s = !0), o;
1049
+ return r && c >= 0 && l >= 0 && u > 0 && u < Ae && (s = !0), o;
1050
1050
  }, T = (e, t, n) => {
1051
1051
  if (n === "/..") return "up";
1052
1052
  let r = e.order.indexOf(n), i = t.cursorKey ? e.order.indexOf(t.cursorKey) : -1;
@@ -1060,7 +1060,7 @@ var D = (e) => {
1060
1060
  let t = n.row - r.cursorRow;
1061
1061
  if (t === 0) return r;
1062
1062
  let i = t < 0 ? "up" : "down";
1063
- if (!(await m(Math.abs(t) >= ke ? g(i) : h(i), 250)).changed) return null;
1063
+ if (!(await m(Math.abs(t) >= Ae ? g(i) : h(i), 250)).changed) return null;
1064
1064
  r = await S(), C(e, r);
1065
1065
  continue;
1066
1066
  }
@@ -1068,17 +1068,17 @@ var D = (e) => {
1068
1068
  let o = await w(e, r, i);
1069
1069
  if (o) r = o;
1070
1070
  else if (a) return null;
1071
- else a = !0, i = Pe(i);
1071
+ else a = !0, i = Fe(i);
1072
1072
  }
1073
1073
  return null;
1074
1074
  }, D = async (e, t) => {
1075
1075
  let n = t.cursorRow ?? 0, i = t.entries.filter((t) => t.kind === "file" && !e.rejected.has(t.key) && v(t.text)).sort((e, t) => Math.abs(e.row - n) - Math.abs(t.row - n))[0];
1076
1076
  if (!i) return "none";
1077
- let a = await E(e, i.key, t), o = he(r());
1078
- return a && v(o) ? (H("match found", {
1077
+ let a = await E(e, i.key, t), o = ge(r());
1078
+ return a && v(o) ? (V("match found", {
1079
1079
  entry: o,
1080
1080
  y: a.cursorRow
1081
- }), await m(I.Edit, 500), "found") : (H("match not reachable", { candidate: i.text }), e.rejected.add(i.key), "failed");
1081
+ }), await m(I.Edit, 500), "found") : (V("match not reachable", { candidate: i.text }), e.rejected.add(i.key), "failed");
1082
1082
  }, O = (e) => e.order.filter((t) => e.kinds.get(t) === "file").map((t) => {
1083
1083
  let n = e.names.get(t) ?? "";
1084
1084
  return {
@@ -1089,7 +1089,7 @@ var D = (e) => {
1089
1089
  if (!e.sorted) return;
1090
1090
  let t = O(e);
1091
1091
  if (t.some((e, n) => n > 0 && (t[n - 1].ci > e.ci || t[n - 1].raw > e.raw))) {
1092
- e.sorted = !1, H("listing is not alphabetical, order hints disabled");
1092
+ e.sorted = !1, V("listing is not alphabetical, order hints disabled");
1093
1093
  return;
1094
1094
  }
1095
1095
  let n = e.order.map((t) => {
@@ -1109,20 +1109,20 @@ var D = (e) => {
1109
1109
  let n = t.cursorKey ? e.order.indexOf(t.cursorKey) : -1, r = null;
1110
1110
  for (let [i, a] of e.kinds) {
1111
1111
  if (a !== "dir" || e.visited.has(i)) continue;
1112
- let o = t.entries.find((e) => e.key === i), s = e.order.indexOf(i), c = o && t.cursorRow !== null ? Math.abs(o.row - t.cursorRow) : 100 + (n >= 0 && s >= 0 ? Math.abs(s - n) : 500), l = De(i, f) * 1e4 - c;
1112
+ let o = t.entries.find((e) => e.key === i), s = e.order.indexOf(i), c = o && t.cursorRow !== null ? Math.abs(o.row - t.cursorRow) : 100 + (n >= 0 && s >= 0 ? Math.abs(s - n) : 500), l = Oe(i, f) * 1e4 - c;
1113
1113
  (!r || l > r.rank) && (r = {
1114
1114
  key: i,
1115
1115
  rank: l
1116
1116
  });
1117
1117
  }
1118
1118
  return r?.key ?? null;
1119
- }, N = async (e, t) => await E(e, "/..", t) ? (H("navigate to parent directory"), (await m(I.Edit, 500)).changed && p()) : (H("parent directory entry unreachable"), !1), P = async (e) => {
1120
- if (e > je || !p()) return H("search aborted", {
1119
+ }, N = async (e, t) => await E(e, "/..", t) ? (V("navigate to parent directory"), (await m(I.Edit, 500)).changed && p()) : (V("parent directory entry unreachable"), !1), P = async (e) => {
1120
+ if (e > Me || !p()) return V("search aborted", {
1121
1121
  depth: e,
1122
1122
  active: p()
1123
1123
  }), "aborted";
1124
- let t = Ne(), n = await S();
1125
- C(t, n), H("search directory", {
1124
+ let t = Pe(), n = await S();
1125
+ C(t, n), V("search directory", {
1126
1126
  depth: e,
1127
1127
  entries: n.entries.length,
1128
1128
  complete: t.top && t.bottom
@@ -1130,7 +1130,7 @@ var D = (e) => {
1130
1130
  for (let r = 0;; r += 1) {
1131
1131
  let i = await D(t, n);
1132
1132
  if (i === "found") return "found";
1133
- if (i === "failed" && (n = await S(), C(t, n)), k(t), A(t) && (H("rest of listing is past the target", { depth: e }), t.bottom = !0), t.top && t.bottom || r >= Me) break;
1133
+ if (i === "failed" && (n = await S(), C(t, n)), k(t), A(t) && (V("rest of listing is past the target", { depth: e }), t.bottom = !0), t.top && t.bottom || r >= Ne) break;
1134
1134
  let a = await w(t, n, j(t, n));
1135
1135
  a && (n = a);
1136
1136
  }
@@ -1138,10 +1138,10 @@ var D = (e) => {
1138
1138
  let r = M(t, n);
1139
1139
  if (!r) break;
1140
1140
  if (t.visited.add(r), !await E(t, r, n)) {
1141
- H("directory unreachable", { directory: r }), n = await S(), C(t, n);
1141
+ V("directory unreachable", { directory: r }), n = await S(), C(t, n);
1142
1142
  continue;
1143
1143
  }
1144
- H("enter directory", {
1144
+ V("enter directory", {
1145
1145
  directory: r,
1146
1146
  depth: e
1147
1147
  });
@@ -1160,12 +1160,12 @@ var D = (e) => {
1160
1160
  if (!p()) return console.warn("[M8SDK] browseFile requires a file browser view (load/save)"), !1;
1161
1161
  if (a().length === 0) return console.warn("[M8SDK] browseFile needs the screen reader, which is not available"), !1;
1162
1162
  let F = await P(0);
1163
- return F !== "found" && H("search failed", {
1163
+ return F !== "found" && V("search failed", {
1164
1164
  targetText: e,
1165
1165
  outcome: F
1166
1166
  }), F === "found";
1167
1167
  };
1168
- }, Ie = (e) => {
1168
+ }, Le = (e) => {
1169
1169
  if (!e) return null;
1170
1170
  let t = e.trim();
1171
1171
  if (t === "--") return 0;
@@ -1173,7 +1173,7 @@ var D = (e) => {
1173
1173
  if (!n) return null;
1174
1174
  let r = parseInt(n[0], 16);
1175
1175
  return Number.isNaN(r) ? null : r;
1176
- }, Le = (e) => {
1176
+ }, Re = (e) => {
1177
1177
  if (!e) return null;
1178
1178
  let t = e.trim();
1179
1179
  if (t === "--") return 0;
@@ -1181,11 +1181,11 @@ var D = (e) => {
1181
1181
  if (!n) return null;
1182
1182
  let r = Number.parseInt(n[0], 10);
1183
1183
  return Number.isNaN(r) ? null : r;
1184
- }, Re = /[+-]?\d+\.\d+/g, ze = (e) => {
1184
+ }, ze = /[+-]?\d+\.\d+/g, Be = (e) => {
1185
1185
  if (!e) return [];
1186
1186
  let t = [];
1187
- Re.lastIndex = 0;
1188
- let n = Re.exec(e);
1187
+ ze.lastIndex = 0;
1188
+ let n = ze.exec(e);
1189
1189
  for (; n !== null;) {
1190
1190
  let r = n[0], i = r.startsWith("-"), a = i || r.startsWith("+") ? r.slice(1) : r, o = a.indexOf("."), s = a.slice(0, o), c = a.slice(o + 1), l = Number.parseInt(s || "0", 10), u = Number.parseInt(c || "0", 10), d = 10 ** c.length, f = d > 0 ? 100 / d : 1, p = l * 100 + u * 100 / d;
1191
1191
  !Number.isNaN(l) && !Number.isNaN(u) && t.push({
@@ -1196,16 +1196,16 @@ var D = (e) => {
1196
1196
  decScale: d,
1197
1197
  tickHundredths: f,
1198
1198
  ticks: (i ? -1 : 1) * Math.round(p / f)
1199
- }), n = Re.exec(e);
1199
+ }), n = ze.exec(e);
1200
1200
  }
1201
1201
  return t;
1202
- }, Be = (e, t) => {
1202
+ }, Ve = (e, t) => {
1203
1203
  if (e.length <= 1) return 0;
1204
1204
  let n = t?.trim() ?? "";
1205
1205
  if (!n) return 0;
1206
1206
  let r = e.findIndex((e) => e.raw === n || e.raw.replace(/^[+-]/, "") === n || `${e.negative ? "-" : ""}${e.intDigits}` === n || e.intDigits === n || e.decDigits === n);
1207
1207
  return r >= 0 ? r : 0;
1208
- }, Ve = (e, t) => {
1208
+ }, He = (e, t) => {
1209
1209
  if (!e) return null;
1210
1210
  let n = t?.trim() ?? "";
1211
1211
  if (!n) return null;
@@ -1219,13 +1219,13 @@ var D = (e) => {
1219
1219
  if (r && !t) return "dec";
1220
1220
  }
1221
1221
  return null;
1222
- }, He = (e, t) => t.length === 1 ? e.raw === t || e.raw.replace(/^[+-]/, "") === t : e.raw === t || e.raw.replace(/^[+-]/, "") === t || `${e.negative ? "-" : ""}${e.intDigits}` === t || e.intDigits === t || e.decDigits === t, Ue = (e, t, n) => {
1222
+ }, Ue = (e, t) => t.length === 1 ? e.raw === t || e.raw.replace(/^[+-]/, "") === t : e.raw === t || e.raw.replace(/^[+-]/, "") === t || `${e.negative ? "-" : ""}${e.intDigits}` === t || e.intDigits === t || e.decDigits === t, We = (e, t, n) => {
1223
1223
  let r = n?.trim() ?? "";
1224
- return !r || !e[t] || He(e[t], r) ? !1 : e.some((e, n) => n !== t && He(e, r));
1225
- }, U = (e, t) => {
1224
+ return !r || !e[t] || Ue(e[t], r) ? !1 : e.some((e, n) => n !== t && Ue(e, r));
1225
+ }, H = (e, t) => {
1226
1226
  let n = Math.round(e * t), r = n < 0 ? "-" : "", i = Math.abs(n), a = Math.floor(i / 100);
1227
1227
  return `${r}${a}.${(i - a * 100).toString().padStart(2, "0")}`;
1228
- }, We = [
1228
+ }, Ge = [
1229
1229
  "C-",
1230
1230
  "C#",
1231
1231
  "D-",
@@ -1238,35 +1238,35 @@ var D = (e) => {
1238
1238
  "A-",
1239
1239
  "A#",
1240
1240
  "B-"
1241
- ], W = (e) => {
1241
+ ], U = (e) => {
1242
1242
  if (!e) return null;
1243
1243
  let t = e.trim().toUpperCase().match(/([A-G][#-][0-9A-F])/);
1244
1244
  if (!t) return null;
1245
- let n = t[1], r = n.slice(0, 2), i = Number.parseInt(n.slice(2, 3), 16), a = We.indexOf(r);
1245
+ let n = t[1], r = n.slice(0, 2), i = Number.parseInt(n.slice(2, 3), 16), a = Ge.indexOf(r);
1246
1246
  return a < 0 || Number.isNaN(i) ? null : {
1247
1247
  label: n,
1248
1248
  noteName: r,
1249
1249
  octave: i,
1250
1250
  semitoneIndex: i * 12 + a
1251
1251
  };
1252
- }, Ge = (e) => {
1252
+ }, Ke = (e) => {
1253
1253
  let { store: t, debugLog: n, hasBus: r, sendKeys: i, pressAndRelease: a, waitForTextUnderCursorChange: o, waitForCurrentLineChange: s } = e;
1254
1254
  return async (e) => {
1255
1255
  if (!r() || !Number.isFinite(e)) return !1;
1256
1256
  let c = 0, l = 1, u = [], d = () => {
1257
- let e = ze(t.get("currentLine"));
1257
+ let e = Be(t.get("currentLine"));
1258
1258
  if (u = e, !e.length) return null;
1259
1259
  c = Math.min(c, e.length - 1);
1260
1260
  let n = e[c];
1261
1261
  return n.tickHundredths > 0 && (l = n.tickHundredths), n;
1262
- }, f = ze(t.get("currentLine"));
1262
+ }, f = Be(t.get("currentLine"));
1263
1263
  if (!f.length) return console.warn("[M8SDK] Could not find a float value like \"440.00\" or \"-10.69\" on the current line:", t.get("currentLine")), !1;
1264
- c = Be(f, t.get("textUnderCursor")), f.length > 1 && n("[M8SDK] Multiple float values on line, editing:", f[c]?.raw);
1264
+ c = Ve(f, t.get("textUnderCursor")), f.length > 1 && n("[M8SDK] Multiple float values on line, editing:", f[c]?.raw);
1265
1265
  let p = f[c];
1266
1266
  l = p.tickHundredths;
1267
1267
  let m = Math.round(Math.round(e * 100) / l);
1268
- if (p.ticks === m) return n("[M8SDK] Already at target float value:", U(m, l)), !0;
1269
- n("[M8SDK] Setting float value from", U(p.ticks, l), "to", U(m, l)), await a(I.Edit), await V(80);
1268
+ if (p.ticks === m) return n("[M8SDK] Already at target float value:", H(m, l)), !0;
1269
+ n("[M8SDK] Setting float value from", H(p.ticks, l), "to", H(m, l)), await a(I.Edit), await B(80);
1270
1270
  let h = () => ({
1271
1271
  upDown: {
1272
1272
  mag: null,
@@ -1280,17 +1280,17 @@ var D = (e) => {
1280
1280
  full: h(),
1281
1281
  int: h(),
1282
1282
  dec: h()
1283
- }, _ = p.decScale, v = Date.now(), y = Ve(p, t.get("textUnderCursor")) ?? "int";
1283
+ }, _ = p.decScale, v = Date.now(), y = He(p, t.get("textUnderCursor")) ?? "int";
1284
1284
  n("[M8SDK] Float cursor focus:", y);
1285
1285
  let b = !1, x = !1, S = p.ticks, C = null, w = p.ticks, T = Math.abs(p.ticks - m), E = 0, D = !1, O = !1, k = (e, t) => {
1286
1286
  let n = e === "upDown" ? I.Up : I.Right, r = e === "upDown" ? I.Down : I.Left;
1287
1287
  return I.Edit | (t >= 0 ? n : r);
1288
1288
  }, A = async (e, n, r) => {
1289
1289
  let a = g[y][e], o = k(e, n * a.bias), c = t.get("currentLine");
1290
- for (let e = 0; e < r; e++) i(o), await V(22);
1290
+ for (let e = 0; e < r; e++) i(o), await B(22);
1291
1291
  await s(c, 350);
1292
1292
  }, ee = async (e) => {
1293
- let n = () => Ve(d(), t.get("textUnderCursor"));
1293
+ let n = () => He(d(), t.get("textUnderCursor"));
1294
1294
  if (n() === e) return y = e, !0;
1295
1295
  let r = t.get("textUnderCursor"), i = e === "dec" ? I.Right : I.Left, s = e === "dec" ? I.Left : I.Right;
1296
1296
  if (await a(i, 35), await o(r, 250), n() === e) return y = e, !0;
@@ -1304,7 +1304,7 @@ var D = (e) => {
1304
1304
  console.warn("[M8SDK] Float value no longer parseable while editing:", t.get("currentLine")), O = !0;
1305
1305
  break;
1306
1306
  }
1307
- if (Ue(u, c, t.get("textUnderCursor"))) {
1307
+ if (We(u, c, t.get("textUnderCursor"))) {
1308
1308
  console.warn("[M8SDK] Float cursor drifted to another field, aborting to avoid editing the wrong value"), x = !0, O = !0;
1309
1309
  break;
1310
1310
  }
@@ -1323,7 +1323,7 @@ var D = (e) => {
1323
1323
  if (C = S, S = e.ticks, y !== "full" && !b) {
1324
1324
  let e = i >= _ ? "int" : "dec";
1325
1325
  if (e !== y && !await ee(e)) {
1326
- if (Ue(u, c, t.get("textUnderCursor"))) {
1326
+ if (We(u, c, t.get("textUnderCursor"))) {
1327
1327
  console.warn("[M8SDK] Float cursor drifted to another field, aborting to avoid editing the wrong value"), x = !0, O = !0;
1328
1328
  break;
1329
1329
  }
@@ -1341,7 +1341,7 @@ var D = (e) => {
1341
1341
  }
1342
1342
  let P = N.ticks - k;
1343
1343
  if (P === 0) {
1344
- E += 1, E >= 4 && (console.warn(`[M8SDK] Float value stopped reacting at ${U(N.ticks, l)} (target ${U(m, l)} may be out of range)`), O = !0);
1344
+ E += 1, E >= 4 && (console.warn(`[M8SDK] Float value stopped reacting at ${H(N.ticks, l)} (target ${H(m, l)} may be out of range)`), O = !0);
1345
1345
  continue;
1346
1346
  }
1347
1347
  E = 0;
@@ -1365,9 +1365,9 @@ var D = (e) => {
1365
1365
  }
1366
1366
  x || await a(I.Edit);
1367
1367
  let j = d(), M = !!j && j.ticks === m;
1368
- return n(`[M8SDK] Float setting ${M ? "succeeded" : "failed"}: "${j?.raw ?? "N/A"}" (${j ? U(j.ticks, l) : "N/A"})`), M;
1368
+ return n(`[M8SDK] Float setting ${M ? "succeeded" : "failed"}: "${j?.raw ?? "N/A"}" (${j ? H(j.ticks, l) : "N/A"})`), M;
1369
1369
  };
1370
- }, Ke = {
1370
+ }, qe = {
1371
1371
  song: [
1372
1372
  {
1373
1373
  to: "project",
@@ -1386,15 +1386,68 @@ var D = (e) => {
1386
1386
  keys: [20, 0]
1387
1387
  }
1388
1388
  ],
1389
- project: [{
1390
- to: "song",
1391
- dir: "down",
1392
- keys: [48, 0]
1393
- }, {
1394
- to: "chain",
1395
- dir: "down",
1396
- keys: [48, 0]
1397
- }],
1389
+ project: [
1390
+ {
1391
+ to: "song",
1392
+ dir: "down",
1393
+ keys: [48, 0],
1394
+ back: !0
1395
+ },
1396
+ {
1397
+ to: "chain",
1398
+ dir: "down",
1399
+ keys: [48, 0],
1400
+ back: !0
1401
+ },
1402
+ {
1403
+ to: "midisettings",
1404
+ via: "button",
1405
+ cursor: [14, 11],
1406
+ label: "SETTINGS",
1407
+ keys: [1, 0],
1408
+ weight: 2
1409
+ },
1410
+ {
1411
+ to: "midimapping",
1412
+ via: "button",
1413
+ cursor: [23, 11],
1414
+ label: "MAPPINGS",
1415
+ keys: [1, 0],
1416
+ weight: 2
1417
+ },
1418
+ {
1419
+ to: "renderaudio",
1420
+ via: "button",
1421
+ cursor: [14, 15],
1422
+ label: "RENDER",
1423
+ keys: [1, 0],
1424
+ weight: 2
1425
+ },
1426
+ {
1427
+ to: "instrumentpool",
1428
+ via: "button",
1429
+ cursor: [14, 17],
1430
+ label: "VIEW INST. POOL",
1431
+ keys: [1, 0],
1432
+ weight: 2
1433
+ },
1434
+ {
1435
+ to: "timestats",
1436
+ via: "button",
1437
+ cursor: [14, 19],
1438
+ label: "VIEW TIME STATS",
1439
+ keys: [1, 0],
1440
+ weight: 2
1441
+ },
1442
+ {
1443
+ to: "systemsettings",
1444
+ via: "button",
1445
+ cursor: [14, 20],
1446
+ label: "SETTINGS",
1447
+ keys: [1, 0],
1448
+ weight: 2
1449
+ }
1450
+ ],
1398
1451
  mixer: [
1399
1452
  {
1400
1453
  to: "effectsettings",
@@ -1405,38 +1458,95 @@ var D = (e) => {
1405
1458
  to: "song",
1406
1459
  dir: "up",
1407
1460
  keys: [80, 0],
1408
- weight: 10
1461
+ weight: 10,
1462
+ back: !0
1409
1463
  },
1410
1464
  {
1411
1465
  to: "chain",
1412
1466
  dir: "up",
1413
1467
  keys: [80, 0],
1414
- weight: 10
1468
+ weight: 10,
1469
+ back: !0
1415
1470
  },
1416
1471
  {
1417
1472
  to: "phrase",
1418
1473
  dir: "up",
1419
1474
  keys: [80, 0],
1420
- weight: 10
1475
+ weight: 10,
1476
+ back: !0
1421
1477
  },
1422
1478
  {
1423
1479
  to: "inst",
1424
1480
  dir: "up",
1425
1481
  keys: [80, 0],
1426
- weight: 10
1482
+ weight: 10,
1483
+ back: !0
1427
1484
  },
1428
1485
  {
1429
1486
  to: "table",
1430
1487
  dir: "up",
1431
1488
  keys: [80, 0],
1432
- weight: 10
1489
+ weight: 10,
1490
+ back: !0
1491
+ },
1492
+ {
1493
+ to: "mixeq",
1494
+ via: "button",
1495
+ cursor: [28, 17],
1496
+ keys: [
1497
+ 64,
1498
+ 0,
1499
+ 20,
1500
+ 0
1501
+ ],
1502
+ weight: 2
1503
+ },
1504
+ {
1505
+ to: "mixscope",
1506
+ via: "button",
1507
+ cursor: [28, 17],
1508
+ keys: [20, 0],
1509
+ weight: 2
1510
+ },
1511
+ {
1512
+ to: "limiterscope",
1513
+ via: "button",
1514
+ cursor: [28, 18],
1515
+ keys: [20, 0],
1516
+ weight: 2
1517
+ }
1518
+ ],
1519
+ effectsettings: [
1520
+ {
1521
+ to: "mixer",
1522
+ dir: "up",
1523
+ keys: [80, 0]
1524
+ },
1525
+ {
1526
+ to: "modfxeq",
1527
+ via: "button",
1528
+ cursor: [22, 6],
1529
+ label: "EQ",
1530
+ keys: [1, 0],
1531
+ weight: 2
1532
+ },
1533
+ {
1534
+ to: "delayeq",
1535
+ via: "button",
1536
+ cursor: [22, 11],
1537
+ label: "EQ",
1538
+ keys: [1, 0],
1539
+ weight: 2
1540
+ },
1541
+ {
1542
+ to: "reverbeq",
1543
+ via: "button",
1544
+ cursor: [22, 17],
1545
+ label: "EQ",
1546
+ keys: [1, 0],
1547
+ weight: 2
1433
1548
  }
1434
1549
  ],
1435
- effectsettings: [{
1436
- to: "mixer",
1437
- dir: "up",
1438
- keys: [80, 0]
1439
- }],
1440
1550
  inst: [
1441
1551
  {
1442
1552
  to: "table",
@@ -1458,6 +1568,20 @@ var D = (e) => {
1458
1568
  dir: "down",
1459
1569
  keys: [48, 0],
1460
1570
  weight: 10
1571
+ },
1572
+ {
1573
+ to: "loadinstrument",
1574
+ via: "button",
1575
+ cursor: [23, 5],
1576
+ label: "LOAD",
1577
+ keys: [1, 0],
1578
+ weight: 2
1579
+ },
1580
+ {
1581
+ to: "instrumentpool",
1582
+ dir: "left",
1583
+ keys: [144, 0],
1584
+ back: !0
1461
1585
  }
1462
1586
  ],
1463
1587
  table: [
@@ -1547,71 +1671,199 @@ var D = (e) => {
1547
1671
  {
1548
1672
  to: "inst",
1549
1673
  dir: "down",
1550
- keys: [48, 0]
1674
+ keys: [48, 0],
1675
+ back: !0
1551
1676
  },
1552
1677
  {
1553
1678
  to: "table",
1554
1679
  dir: "down",
1680
+ keys: [48, 0],
1681
+ back: !0
1682
+ }
1683
+ ],
1684
+ instrumentpool: [
1685
+ {
1686
+ to: "instmods",
1687
+ dir: "down",
1555
1688
  keys: [48, 0]
1689
+ },
1690
+ {
1691
+ to: "inst",
1692
+ dir: "right",
1693
+ keys: [20, 0]
1694
+ },
1695
+ {
1696
+ to: "phrase",
1697
+ dir: "left",
1698
+ keys: [144, 0],
1699
+ weight: 4
1556
1700
  }
1557
1701
  ],
1558
- instrumentpool: [{
1559
- to: "instmods",
1560
- dir: "down",
1561
- keys: [48, 0]
1702
+ systemsettings: [
1703
+ {
1704
+ to: "themesettings",
1705
+ via: "button",
1706
+ cursor: [16, 7],
1707
+ label: "EDIT THEME",
1708
+ keys: [1, 0],
1709
+ weight: 2
1710
+ },
1711
+ {
1712
+ to: "project",
1713
+ via: "exit",
1714
+ keys: [2, 0]
1715
+ },
1716
+ {
1717
+ to: "project",
1718
+ dir: "up",
1719
+ keys: [80, 0],
1720
+ weight: 2
1721
+ }
1722
+ ],
1723
+ midisettings: [{
1724
+ to: "project",
1725
+ via: "exit",
1726
+ keys: [2, 0]
1727
+ }, {
1728
+ to: "project",
1729
+ dir: "up",
1730
+ keys: [80, 0],
1731
+ weight: 3
1732
+ }],
1733
+ midimapping: [{
1734
+ to: "project",
1735
+ via: "exit",
1736
+ keys: [2, 0]
1737
+ }, {
1738
+ to: "project",
1739
+ dir: "up",
1740
+ keys: [80, 0],
1741
+ weight: 3
1742
+ }],
1743
+ renderaudio: [{
1744
+ to: "project",
1745
+ via: "exit",
1746
+ keys: [2, 0]
1747
+ }, {
1748
+ to: "project",
1749
+ dir: "up",
1750
+ keys: [80, 0],
1751
+ weight: 3
1752
+ }],
1753
+ timestats: [{
1754
+ to: "project",
1755
+ via: "exit",
1756
+ keys: [2, 0]
1757
+ }, {
1758
+ to: "project",
1759
+ dir: "up",
1760
+ keys: [80, 0],
1761
+ weight: 3
1762
+ }],
1763
+ loadproject: [{
1764
+ to: "project",
1765
+ via: "exit",
1766
+ keys: [2, 0]
1767
+ }],
1768
+ themesettings: [{
1769
+ to: "systemsettings",
1770
+ via: "exit",
1771
+ keys: [2, 0]
1772
+ }],
1773
+ mixeq: [{
1774
+ to: "mixer",
1775
+ via: "exit",
1776
+ keys: [2, 0]
1777
+ }, {
1778
+ to: "mixer",
1779
+ dir: "left",
1780
+ keys: [144, 0],
1781
+ weight: 3
1782
+ }],
1783
+ mixscope: [{
1784
+ to: "mixer",
1785
+ via: "exit",
1786
+ keys: [2, 0]
1787
+ }, {
1788
+ to: "mixer",
1789
+ dir: "left",
1790
+ keys: [144, 0],
1791
+ weight: 3
1792
+ }],
1793
+ limiterscope: [{
1794
+ to: "mixer",
1795
+ via: "exit",
1796
+ keys: [2, 0]
1797
+ }, {
1798
+ to: "mixer",
1799
+ dir: "left",
1800
+ keys: [144, 0],
1801
+ weight: 3
1802
+ }],
1803
+ modfxeq: [{
1804
+ to: "effectsettings",
1805
+ via: "exit",
1806
+ keys: [2, 0]
1807
+ }],
1808
+ delayeq: [{
1809
+ to: "effectsettings",
1810
+ via: "exit",
1811
+ keys: [2, 0]
1812
+ }],
1813
+ reverbeq: [{
1814
+ to: "effectsettings",
1815
+ via: "exit",
1816
+ keys: [2, 0]
1817
+ }],
1818
+ loadinstrument: [{
1819
+ to: "inst",
1820
+ via: "exit",
1821
+ keys: [2, 0]
1562
1822
  }]
1563
- }, qe = { views: [
1564
- "chain",
1565
- "effectsettings",
1566
- "groove",
1567
- "instmods",
1568
- "inst",
1569
- "instrumentpool",
1570
- "mixer",
1571
- "phrase",
1572
- "project",
1573
- "scale",
1574
- "song",
1575
- "table",
1576
- "mixeq",
1577
- "limiterscope",
1578
- "mixscope",
1579
- "modfxeq",
1580
- "delayeq",
1581
- "reverbeq",
1582
- "loadinstrument",
1583
- "selectsavedirectory",
1584
- "createdirectory",
1585
- "systemsettings"
1586
- ] }, Je = (e) => {
1823
+ }, Je = { views: /* @__PURE__ */ "chain.effectsettings.groove.instmods.inst.instrumentpool.mixer.phrase.project.scale.song.table.mixeq.limiterscope.mixscope.modfxeq.delayeq.reverbeq.loadinstrument.selectsavedirectory.createdirectory.systemsettings.midisettings.midimapping.renderaudio.timestats.themesettings.loadproject".split(".") }, Ye = (e) => {
1587
1824
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map();
1588
1825
  for (let [r, i] of Object.entries(e)) {
1589
1826
  let e = r.toLowerCase(), a = [], o = /* @__PURE__ */ new Map();
1590
- for (let e of i) e.dir && a.push({
1591
- to: e.to,
1592
- dir: e.dir,
1593
- weight: e.weight
1594
- }), e.keys?.length && o.set(e.to, e.keys.slice());
1827
+ for (let t of i) {
1828
+ let n = t.via ?? "shift";
1829
+ if (n === "shift" && !t.dir || n === "button" && !t.cursor) continue;
1830
+ let r = t.keys?.slice() ?? [];
1831
+ a.push({
1832
+ from: e,
1833
+ to: t.to.toLowerCase(),
1834
+ dir: t.dir,
1835
+ weight: t.weight,
1836
+ kind: n,
1837
+ keys: r,
1838
+ cursor: t.cursor ? {
1839
+ x: t.cursor[0],
1840
+ y: t.cursor[1]
1841
+ } : void 0,
1842
+ label: t.label,
1843
+ back: t.back
1844
+ }), n === "shift" && r.length && o.set(t.to, r);
1845
+ }
1595
1846
  t.set(e, a), o.size && n.set(e, o);
1596
1847
  }
1848
+ for (let e of [...t.values()]) for (let n of e) t.has(n.to) || t.set(n.to, []);
1597
1849
  return {
1598
1850
  graph: t,
1599
1851
  edgeKeys: n
1600
1852
  };
1601
- }, Ye = null, Xe = null, Ze = () => (Ye ??= Je(Ke), Ye), Qe = () => {
1602
- if (!Xe) {
1603
- let e = Array.isArray(qe.views) ? qe.views : [];
1604
- Xe = new Set(e.map((e) => String(e).trim().toLowerCase()).filter((e) => !!e));
1853
+ }, Xe = null, Ze = null, Qe = () => (Xe ??= Ye(qe), Xe), $e = () => {
1854
+ if (!Ze) {
1855
+ let e = Array.isArray(Je.views) ? Je.views : [];
1856
+ Ze = new Set(e.map((e) => String(e).trim().toLowerCase()).filter((e) => !!e));
1605
1857
  }
1606
- return Xe;
1607
- }, $e = 50, et = {
1858
+ return Ze;
1859
+ }, et = 50, tt = {
1608
1860
  x: 0,
1609
1861
  y: 0,
1610
1862
  w: 1,
1611
1863
  h: 1
1612
- }, tt = class {
1864
+ }, nt = class {
1613
1865
  constructor() {
1614
- this.assemblies = [], this.selectionRectSamples = [], this.lastCursor = et, this.lastSelectionCursor = null, this.lastCursorColor = null, this.lastSelectionMode = !1, this.lastSelectionSeenAt = 0, this.ASSEMBLY_TIMEOUT = 100, this.SELECTION_SAMPLE_WINDOW = 50, this.SELECTION_HOLD_DURATION = 150;
1866
+ this.assemblies = [], this.selectionRectSamples = [], this.lastCursor = tt, this.lastSelectionCursor = null, this.lastCursorColor = null, this.lastSelectionMode = !1, this.lastSelectionSeenAt = 0, this.ASSEMBLY_TIMEOUT = 100, this.SELECTION_SAMPLE_WINDOW = 50, this.SELECTION_HOLD_DURATION = 150;
1615
1867
  }
1616
1868
  processRect(e) {
1617
1869
  if (!e) return {
@@ -1803,7 +2055,7 @@ var D = (e) => {
1803
2055
  ].filter((e) => e.foundVert || e.foundTip).length >= 2;
1804
2056
  }
1805
2057
  buildCursorFromAssembly(e) {
1806
- if (!e.tr || !e.bl || !e.br) return et;
2058
+ if (!e.tr || !e.bl || !e.br) return tt;
1807
2059
  let t = e.tr.x - e.tl.x - 1, n = e.bl.y - e.tl.y - 1;
1808
2060
  return {
1809
2061
  x: e.tl.x + 1,
@@ -1820,19 +2072,19 @@ var D = (e) => {
1820
2072
  h: 1
1821
2073
  }, this.lastSelectionCursor = null, this.lastSelectionMode = !1, this.lastSelectionSeenAt = 0;
1822
2074
  }
1823
- }, nt = (e) => e ? `#${[
2075
+ }, rt = (e) => e ? `#${[
1824
2076
  e.r,
1825
2077
  e.g,
1826
2078
  e.b
1827
2079
  ].map((e) => e.toString(16).padStart(2, "0")).join("")}` : null;
1828
- function rt(e, t) {
1829
- let n = new tt();
2080
+ function it(e, t) {
2081
+ let n = new nt();
1830
2082
  class r {
1831
2083
  constructor() {
1832
2084
  this.rowChars = /* @__PURE__ */ new Map(), this.timer = null, this.knownViews = [], this.earlyAccepted = !1;
1833
2085
  }
1834
2086
  init() {
1835
- this.knownViews = Array.from(Qe());
2087
+ this.knownViews = Array.from($e());
1836
2088
  }
1837
2089
  normForCompare(e) {
1838
2090
  return e = e.includes("live") ? "song" : e, e.toLowerCase().trim().replace(/[{}]/g, "0");
@@ -1876,7 +2128,7 @@ function rt(e, t) {
1876
2128
  bg: e.background
1877
2129
  }), this.tryEarlyAccept(o), this.timer && clearTimeout(this.timer), this.timer = setTimeout(() => {
1878
2130
  this.emitStable();
1879
- }, $e)));
2131
+ }, et)));
1880
2132
  }
1881
2133
  reset() {
1882
2134
  this.rowChars.clear(), this.timer &&= (clearTimeout(this.timer), null), this.earlyAccepted = !1;
@@ -1955,7 +2207,7 @@ function rt(e, t) {
1955
2207
  let e = this.grid.get(i), a = [], o = [];
1956
2208
  for (let n = 0; n < t; n += 1) {
1957
2209
  let t = e?.get(n);
1958
- a.push(nt(t?.fg)), o.push(nt(t?.bg));
2210
+ a.push(rt(t?.fg)), o.push(rt(t?.bg));
1959
2211
  }
1960
2212
  n.push(a), r.push(o);
1961
2213
  }
@@ -1982,7 +2234,7 @@ function rt(e, t) {
1982
2234
  if (!e) return;
1983
2235
  Date.now() < s && console.log(`[rect] type=${e.type} pos=(${e.pos.x},${e.pos.y}) size=${e.size.width}x${e.size.height}`);
1984
2236
  let { cellW: r, cellH: i, offX: a, offY: o } = t.get("cellMetrics"), { cursor: c, cursorColor: l, selectionMode: u } = n.processRect(e);
1985
- l && nt(l) !== nt(t.get("cursorColor")) && t.set("cursorColor", l);
2237
+ l && rt(l) !== rt(t.get("cursorColor")) && t.set("cursorColor", l);
1986
2238
  let { x: d, y: f, w: p, h: m } = c, h = Math.round((d - a) / r), g = Math.round((f - o) / i), _ = t.get("cursorPos"), v = t.get("selectionMode");
1987
2239
  if (u) {
1988
2240
  let e = t.get("cursorRect");
@@ -2038,7 +2290,7 @@ function rt(e, t) {
2038
2290
  }
2039
2291
  //#endregion
2040
2292
  //#region src/engine/host/hostState.ts
2041
- var it = (e) => {
2293
+ var at = (e) => {
2042
2294
  let t = e.get("macroStatus");
2043
2295
  return {
2044
2296
  viewName: e.get("viewName"),
@@ -2060,13 +2312,13 @@ var it = (e) => {
2060
2312
  macroCurrentStep: t.currentStep,
2061
2313
  macroSequenceLength: t.sequenceLength
2062
2314
  };
2063
- }, at = (e, t, n) => {
2315
+ }, ot = (e, t, n) => {
2064
2316
  let r = e.get("cellMetrics");
2065
2317
  return {
2066
2318
  x: t * r.cellW + r.offX + r.cellW / 2,
2067
2319
  y: n * r.cellH + r.offY + r.cellH / 2
2068
2320
  };
2069
- }, ot = (e) => te({
2321
+ }, st = (e) => te({
2070
2322
  left: e.includes("left"),
2071
2323
  right: e.includes("right"),
2072
2324
  up: e.includes("up"),
@@ -2075,12 +2327,12 @@ var it = (e) => {
2075
2327
  play: e.includes("play"),
2076
2328
  opt: e.includes("opt"),
2077
2329
  edit: e.includes("edit")
2078
- }), st = ({ io: e, editors: t, setValueFloat: n, browseFile: r, navigateToView: i, navigateTo: a, enableMidiTransport: o, getScreenCellColors: s }) => {
2330
+ }), ct = ({ io: e, editors: t, setValueFloat: n, browseFile: r, navigateToView: i, navigateTo: a, enableMidiTransport: o, getScreenCellColors: s }) => {
2079
2331
  let { debugLog: c, hasBus: l, sendKeys: u, pressAndRelease: d, store: f, getScreenLines: p } = e, m = (e, t, n) => async (...r) => l() ? n(...r) : (console.warn(`[M8SDK] ${e}: no bus connection`), t);
2080
2332
  return {
2081
- navigateToView: m("navigateToView", !1, async (e) => (c("[M8SDK] Executing navigateToView:", e), await i(e), !0)),
2333
+ navigateToView: m("navigateToView", !1, async (e) => (c("[M8SDK] Executing navigateToView:", e), i(e))),
2082
2334
  navigateTo: m("navigateTo", void 0, async (e, t) => {
2083
- await a(at(f, e, t));
2335
+ await a(ot(f, e, t));
2084
2336
  }),
2085
2337
  setValueToHex: m("setValueToHex", !1, async (e) => (c("[M8SDK] Executing setValueToHex:", e), t.setValueToHex(e))),
2086
2338
  setValueToInt: m("setValueToInt", !1, async (e) => (c("[M8SDK] Executing setValueToInt:", e), t.setValueToInt(e))),
@@ -2096,15 +2348,15 @@ var it = (e) => {
2096
2348
  exact: t
2097
2349
  }), r(e, t))),
2098
2350
  sendKeyDown: m("sendKeyDown", void 0, async (e) => {
2099
- c("[M8SDK] Executing sendKeyDown:", e), u(ot(e));
2351
+ c("[M8SDK] Executing sendKeyDown:", e), u(st(e));
2100
2352
  }),
2101
2353
  sendKeyUp: m("sendKeyUp", void 0, async () => {
2102
2354
  c("[M8SDK] Executing sendKeyUp"), u(0);
2103
2355
  }),
2104
2356
  sendKeyPress: m("sendKeyPress", void 0, async (e) => {
2105
- c("[M8SDK] Executing sendKeyPress:", e), await d(ot(e));
2357
+ c("[M8SDK] Executing sendKeyPress:", e), await d(st(e));
2106
2358
  }),
2107
- getState: async () => it(f),
2359
+ getState: async () => at(f),
2108
2360
  getScreen: async () => ({
2109
2361
  width: 40,
2110
2362
  height: 24,
@@ -2118,7 +2370,7 @@ var it = (e) => {
2118
2370
  }),
2119
2371
  enableMidiTransport: async () => o()
2120
2372
  };
2121
- }, ct = 6, lt = (e) => {
2373
+ }, lt = 6, ut = (e) => {
2122
2374
  let t = null, n = 0, r = null, i = null, a = (e) => performance.timeOrigin + e, o = (t) => {
2123
2375
  let o = t.data;
2124
2376
  if (!o || o.length === 0) return;
@@ -2129,7 +2381,7 @@ var it = (e) => {
2129
2381
  let e = s - r;
2130
2382
  e > 0 && e < 200 && (i = i == null ? e : i * .9 + e * .1);
2131
2383
  }
2132
- r = s, n += 1, n % ct === 0 && e({
2384
+ r = s, n += 1, n % lt === 0 && e({
2133
2385
  kind: "clock",
2134
2386
  ticks: n,
2135
2387
  at: s,
@@ -2197,7 +2449,7 @@ var it = (e) => {
2197
2449
  t?.removeEventListener("midimessage", o), t = null;
2198
2450
  }
2199
2451
  };
2200
- }, ut = (e, t) => {
2452
+ }, dt = (e, t) => {
2201
2453
  let n = [], r = e, i = t;
2202
2454
  for (; r !== i;) {
2203
2455
  let e = i - r, t = Math.abs(e), a = e > 0 ? 1 : -1;
@@ -2210,7 +2462,7 @@ var it = (e) => {
2210
2462
  } else break;
2211
2463
  }
2212
2464
  return n;
2213
- }, dt = (e, t) => {
2465
+ }, ft = (e, t) => {
2214
2466
  let n = [], r = e;
2215
2467
  for (; r !== t;) {
2216
2468
  let e = t - r, i = e > 0 ? 1 : -1;
@@ -2224,13 +2476,13 @@ var it = (e) => {
2224
2476
  if (n.length > 2048) break;
2225
2477
  }
2226
2478
  return n;
2227
- }, ft = (e) => {
2479
+ }, pt = (e) => {
2228
2480
  let { store: t, debugLog: n, hasBus: r, sendKeys: i, pressAndRelease: a, waitForTextUnderCursorChange: o } = e;
2229
2481
  return {
2230
2482
  setValueToHex: async (e) => {
2231
2483
  if (!r()) return !1;
2232
2484
  e = Math.max(0, Math.min(255, e));
2233
- let s = t.get("textUnderCursor"), c = Ie(s), l = s?.trim() === "--";
2485
+ let s = t.get("textUnderCursor"), c = Le(s), l = s?.trim() === "--";
2234
2486
  if (c === null) return console.warn("[M8SDK] Could not parse current value under cursor:", s), !1;
2235
2487
  if (c === e && !l) return n("[M8SDK] Already at target value:", e.toString(16).padStart(2, "0").toUpperCase()), !0;
2236
2488
  n(`[M8SDK] Setting value from "${s?.trim() ?? "N/A"}" (${c.toString(16).padStart(2, "0").toUpperCase()}) to ${e.toString(16).padStart(2, "0").toUpperCase()}`);
@@ -2239,18 +2491,18 @@ var it = (e) => {
2239
2491
  n("[M8SDK] Initial value is \"--\", pressing edit to recall last value");
2240
2492
  let e = s;
2241
2493
  await a(I.Edit), await o(e, 250);
2242
- let r = t.get("textUnderCursor"), i = Ie(r);
2494
+ let r = t.get("textUnderCursor"), i = Le(r);
2243
2495
  if (n(`[M8SDK] After edit press, value is now: "${r?.trim() ?? "N/A"}" (${i?.toString(16).padStart(2, "0").toUpperCase() ?? "N/A"})`), i === null) return console.warn("[M8SDK] Failed to read value after edit press on \"--\""), await a(I.Edit), !1;
2244
2496
  u = i;
2245
2497
  } else {
2246
2498
  let e = s;
2247
2499
  await a(I.Edit), await o(e, 250);
2248
2500
  }
2249
- let d = ut(u, e);
2501
+ let d = dt(u, e);
2250
2502
  n(`[M8SDK] Precalculated ${d.length / 2} key presses from ${u.toString(16).padStart(2, "0").toUpperCase()} to ${e.toString(16).padStart(2, "0").toUpperCase()}`);
2251
- for (let e of d) i(e), await V(30);
2503
+ for (let e of d) i(e), await B(30);
2252
2504
  await o(s, 250);
2253
- let f = t.get("textUnderCursor"), p = Ie(f);
2505
+ let f = t.get("textUnderCursor"), p = Le(f);
2254
2506
  if (p !== e) {
2255
2507
  n("[M8SDK] Precomputation missed target, falling back to iterative mode");
2256
2508
  let r = p ?? u, i = Date.now();
@@ -2264,10 +2516,10 @@ var it = (e) => {
2264
2516
  await a(t);
2265
2517
  }
2266
2518
  await o(l, 250);
2267
- let u = Ie(t.get("textUnderCursor"));
2519
+ let u = Le(t.get("textUnderCursor"));
2268
2520
  u !== null && (r = u, n(`[M8SDK] Iterative: current value: ${r.toString(16).padStart(2, "0").toUpperCase()}`));
2269
2521
  }
2270
- p = Ie(t.get("textUnderCursor"));
2522
+ p = Le(t.get("textUnderCursor"));
2271
2523
  }
2272
2524
  await a(I.Edit);
2273
2525
  let m = p === e;
@@ -2276,7 +2528,7 @@ var it = (e) => {
2276
2528
  setValueToInt: async (e) => {
2277
2529
  if (!r()) return !1;
2278
2530
  e = Math.floor(e);
2279
- let n = t.get("textUnderCursor"), i = Le(n);
2531
+ let n = t.get("textUnderCursor"), i = Re(n);
2280
2532
  if (i === null) return console.warn("[M8SDK] Could not parse current integer value under cursor:", n), !1;
2281
2533
  if (i === e) return !0;
2282
2534
  await a(I.Edit), await o(n, 250);
@@ -2291,7 +2543,7 @@ var it = (e) => {
2291
2543
  await a(I.Edit | e, 35);
2292
2544
  }
2293
2545
  await o(d, 250);
2294
- let p = Le(t.get("textUnderCursor"));
2546
+ let p = Re(t.get("textUnderCursor"));
2295
2547
  if (p === null || p === s) break;
2296
2548
  let m = Math.abs(p - e);
2297
2549
  m < l && (l = m, c = p);
@@ -2311,12 +2563,12 @@ var it = (e) => {
2311
2563
  await a(I.Edit | e, 35);
2312
2564
  }
2313
2565
  await o(i, 250);
2314
- let l = Le(t.get("textUnderCursor"));
2566
+ let l = Re(t.get("textUnderCursor"));
2315
2567
  if (l === null || l === s) break;
2316
2568
  s = l;
2317
2569
  }
2318
2570
  }
2319
- return await a(I.Edit), Le(t.get("textUnderCursor")) === e;
2571
+ return await a(I.Edit), Re(t.get("textUnderCursor")) === e;
2320
2572
  },
2321
2573
  setNote: async (e) => {
2322
2574
  if (!r()) return !1;
@@ -2331,19 +2583,19 @@ var it = (e) => {
2331
2583
  let i = t.get("textUnderCursor")?.trim().toUpperCase();
2332
2584
  return n("[M8SDK] setNote special value result:", i), i === s;
2333
2585
  }
2334
- let c = W(e);
2586
+ let c = U(e);
2335
2587
  if (!c) return console.warn("[M8SDK] Invalid note format. Expected like C-1, C#1, D#A, ---, OFF:", e), !1;
2336
2588
  let l = t.get("textUnderCursor");
2337
2589
  (l?.trim() === "---" || l?.trim().toUpperCase() === "OFF") && (n("[M8SDK] Initial note is \"---\" or \"OFF\", priming with edit key"), await a(I.Edit), await o(l, 250), l = t.get("textUnderCursor"));
2338
- let u = W(l);
2590
+ let u = U(l);
2339
2591
  if (!u) return console.warn("[M8SDK] Could not parse current note under cursor:", l), !1;
2340
2592
  if (u.semitoneIndex === c.semitoneIndex) return !0;
2341
2593
  await a(I.Edit), await o(l, 250);
2342
- let d = dt(u.semitoneIndex, c.semitoneIndex);
2594
+ let d = ft(u.semitoneIndex, c.semitoneIndex);
2343
2595
  if (d.length > 0) {
2344
- for (let e of d) i(e), await V(25);
2596
+ for (let e of d) i(e), await B(25);
2345
2597
  await o(l, 280);
2346
- let e = W(t.get("textUnderCursor"));
2598
+ let e = U(t.get("textUnderCursor"));
2347
2599
  if (e?.semitoneIndex === c.semitoneIndex) return await a(I.Edit), !0;
2348
2600
  u = e ?? u;
2349
2601
  }
@@ -2355,19 +2607,19 @@ var it = (e) => {
2355
2607
  if (e === 0) break;
2356
2608
  let n = Math.abs(e) >= 12, r = e > 0, i = n ? r ? I.Up : I.Down : r ? I.Right : I.Left, s = n ? r ? I.Down : I.Up : r ? I.Left : I.Right, l = u, d = Math.abs(l.semitoneIndex - c.semitoneIndex), p = t.get("textUnderCursor");
2357
2609
  await a(I.Edit | i, 35), await o(p, 250);
2358
- let m = W(t.get("textUnderCursor"));
2610
+ let m = U(t.get("textUnderCursor"));
2359
2611
  if (!m || m.label === l.label) break;
2360
2612
  if (u = m, Math.abs(u.semitoneIndex - c.semitoneIndex) > d) {
2361
2613
  let e = t.get("textUnderCursor");
2362
2614
  await a(I.Edit | s, 35), await o(e, 250);
2363
- let n = W(t.get("textUnderCursor"));
2615
+ let n = U(t.get("textUnderCursor"));
2364
2616
  n && (u = n);
2365
2617
  break;
2366
2618
  }
2367
2619
  if (f.has(u.label)) break;
2368
2620
  f.add(u.label);
2369
2621
  }
2370
- return await a(I.Edit), W(t.get("textUnderCursor"))?.semitoneIndex === c.semitoneIndex;
2622
+ return await a(I.Edit), U(t.get("textUnderCursor"))?.semitoneIndex === c.semitoneIndex;
2371
2623
  },
2372
2624
  setValueToString: async (e, i = !0, s = !1) => {
2373
2625
  if (!r()) return !1;
@@ -2416,7 +2668,7 @@ var it = (e) => {
2416
2668
  return await a(I.Edit), !1;
2417
2669
  }
2418
2670
  };
2419
- }, pt = ({ bus: e, store: t, cancelOnKeydown: n = !1 }) => {
2671
+ }, mt = ({ bus: e, store: t, cancelOnKeydown: n = !1 }) => {
2420
2672
  let r = [], i = null, a = !1, o = () => {
2421
2673
  a && u("preempted by keyboard");
2422
2674
  }, s = () => {
@@ -2442,8 +2694,8 @@ var it = (e) => {
2442
2694
  });
2443
2695
  } else c(), i = null, t.set("macroStatus", { running: !1 });
2444
2696
  }
2445
- function u(e) {
2446
- (a || r.length !== 0 || t.get("macroStatus").running) && (r = [], i = null, c(), t.set("macroStatus", { running: !1 }));
2697
+ function u(n) {
2698
+ (a || r.length !== 0 || t.get("macroStatus").running) && (i && e.commands.sendKeys(0), r = [], i = null, c(), t.set("macroStatus", { running: !1 }));
2447
2699
  }
2448
2700
  return {
2449
2701
  start: (n) => {
@@ -2464,7 +2716,7 @@ var it = (e) => {
2464
2716
  r = [], i = null, c();
2465
2717
  }
2466
2718
  };
2467
- }, mt = () => ({
2719
+ }, ht = () => ({
2468
2720
  viewName: null,
2469
2721
  viewTitle: null,
2470
2722
  minimapKey: null,
@@ -2487,9 +2739,9 @@ var it = (e) => {
2487
2739
  },
2488
2740
  systemInfo: null,
2489
2741
  macroStatus: { running: !1 }
2490
- }), ht = (e = {}) => {
2742
+ }), gt = (e = {}) => {
2491
2743
  let t = {
2492
- ...mt(),
2744
+ ...ht(),
2493
2745
  ...e
2494
2746
  }, n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Set();
2495
2747
  return {
@@ -2512,8 +2764,8 @@ var it = (e) => {
2512
2764
  }),
2513
2765
  snapshot: () => ({ ...t })
2514
2766
  };
2515
- }, gt = () => 0, _t = () => 1;
2516
- function vt(e, t, n, r = gt, i = _t) {
2767
+ }, _t = () => 0, vt = () => 1;
2768
+ function yt(e, t, n, r = _t, i = vt) {
2517
2769
  let a = t.trim(), o = n.trim();
2518
2770
  if (!e.has(a) || !e.has(o)) return null;
2519
2771
  let s = /* @__PURE__ */ new Set([a]), c = /* @__PURE__ */ new Map(), l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map();
@@ -2535,12 +2787,13 @@ function vt(e, t, n, r = gt, i = _t) {
2535
2787
  for (; n !== a;) {
2536
2788
  let r = c.get(n);
2537
2789
  if (!r) break;
2538
- t.unshift(r.viaDir), e.unshift(r.prev), n = r.prev;
2790
+ t.unshift(r.via), e.unshift(r.prev), n = r.prev;
2539
2791
  }
2540
2792
  return {
2541
2793
  pages: e,
2542
- directions: t,
2543
- cost: t.length
2794
+ directions: t.map((e) => e.dir),
2795
+ edges: t,
2796
+ cost: l.get(o) ?? t.length
2544
2797
  };
2545
2798
  }
2546
2799
  s.delete(t);
@@ -2549,7 +2802,7 @@ function vt(e, t, n, r = gt, i = _t) {
2549
2802
  let n = e.weight ?? i(t, e.to, e.dir), a = (l.get(t) ?? Infinity) + n;
2550
2803
  a < (l.get(e.to) ?? Infinity) && (c.set(e.to, {
2551
2804
  prev: t,
2552
- viaDir: e.dir
2805
+ via: e
2553
2806
  }), l.set(e.to, a), u.set(e.to, a + r(e.to, o)), s.has(e.to) || s.add(e.to));
2554
2807
  }
2555
2808
  }
@@ -2557,7 +2810,7 @@ function vt(e, t, n, r = gt, i = _t) {
2557
2810
  }
2558
2811
  //#endregion
2559
2812
  //#region src/engine/viewNavigation.ts
2560
- var yt = 20, bt = (e, t) => {
2813
+ var bt = 20, xt = 700, St = 80, Ct = 4e3, wt = 120, Tt = (e, t) => {
2561
2814
  let n = !!t?.shift, r = I.Shift, i = {
2562
2815
  up: (n ? r : 0) | I.Up,
2563
2816
  down: (n ? r : 0) | I.Down,
@@ -2567,96 +2820,203 @@ var yt = 20, bt = (e, t) => {
2567
2820
  n && a.push(r);
2568
2821
  for (let t of e) a.push(i[t], n ? r : 0);
2569
2822
  return a.push(0), a;
2570
- }, xt = ({ store: e, runner: t }) => {
2571
- let n = Qe(), r = null, i = 0, a = null, o = (e) => {
2572
- let t = (e || "").toLowerCase();
2573
- if (n.has(t)) return t;
2574
- for (let e of n) if (e.toLowerCase() === t) return e;
2575
- return console.warn("Target not in viewlist", { goal: t }), t;
2576
- }, s = (e) => {
2577
- let t = (e || "").toLowerCase(), r = "";
2578
- for (let e of n) t.startsWith(e) && e.length > r.length && (r = e);
2579
- return r;
2580
- }, c = (t) => {
2581
- let { graph: n } = Ze(), r = e.get("viewName") || "", i = [], a = [];
2582
- for (let e of n.keys()) {
2583
- let n = s(e);
2584
- n && (n === r && i.push(e), n === t && a.push(e));
2823
+ }, Et = (e) => [{
2824
+ from: e,
2825
+ to: "",
2826
+ kind: "exit",
2827
+ keys: [I.Opt, 0]
2828
+ }, {
2829
+ from: e,
2830
+ to: "",
2831
+ kind: "shift",
2832
+ dir: "up",
2833
+ keys: [I.Shift | I.Up, 0]
2834
+ }], Dt = (e) => `${e.kind}:${e.dir ?? ""}:${e.keys.join(",")}:${e.cursor ? `${e.cursor.x},${e.cursor.y}` : ""}`, Ot = (e) => e[e.length - 1] === 0 ? e.slice() : [...e, 0], kt = "#goal", At = (e, t) => `${e}<${t}`, jt = (e) => new Promise((t) => setTimeout(t, e)), Mt = ({ store: e, runner: t, getScreenLines: n, moveCursor: r }) => {
2835
+ let i = $e(), a = null, o = 0, s = null, c = 0, l = /* @__PURE__ */ new Map(), u = "", d = e.get("viewName") || "", f = e.sub("viewName", () => {
2836
+ let t = e.get("viewName") || "";
2837
+ t && t !== d && (d && (u = d), d = t);
2838
+ }), p = null, m = null, h = () => {
2839
+ m && clearTimeout(m), m = null;
2840
+ }, g = (e) => {
2841
+ let t = (e || "").toLowerCase().trim();
2842
+ return i.has(t) || console.warn("Target not in viewlist", { goal: t }), t;
2843
+ }, _ = (e, t) => `${e.from}<${t}|${Dt(e)}`, v = (e, t) => {
2844
+ let n = /* @__PURE__ */ new Map();
2845
+ for (let t of Qe().graph.get(e) ?? []) {
2846
+ if (t.kind === "button" && !r) continue;
2847
+ let e = Dt(t);
2848
+ n.set(e, [...n.get(e) ?? [], t]);
2585
2849
  }
2586
- if (!a.length) return null;
2587
- if (!i.length) return {
2588
- pages: ["unknown", "fallback"],
2589
- directions: ["up"],
2590
- cost: 1
2591
- };
2592
- let o = null;
2593
- for (let e of i) for (let t of a) {
2594
- let r = vt(n, e, t);
2595
- r && (!o || r.cost < o.cost) && (o = r);
2850
+ let i = [];
2851
+ for (let r of n.values()) {
2852
+ if (l.get(_(r[0], "*")) === e) continue;
2853
+ let n = l.get(_(r[0], t));
2854
+ if (n !== void 0) {
2855
+ n !== e && i.push({
2856
+ ...r[0],
2857
+ to: n
2858
+ });
2859
+ continue;
2860
+ }
2861
+ let a = r.find((e) => e.back && e.to === t);
2862
+ if (a) {
2863
+ i.push(a);
2864
+ continue;
2865
+ }
2866
+ let o = r.filter((e) => !e.back);
2867
+ i.push(...o.length ? o : r);
2596
2868
  }
2597
- return o;
2598
- }, l = (e, t, n) => {
2599
- let r = Ze().edgeKeys.get(e.toLowerCase())?.get(t);
2600
- return r?.length ? r[r.length - 1] === 0 ? r.slice() : [...r, 0] : bt([n], { shift: !0 });
2601
- }, u = () => {
2602
- if (r = null, i = 0, a) {
2603
- let e = a;
2604
- a = null, e();
2869
+ return i;
2870
+ }, y = (e, t, n) => {
2871
+ let r = /* @__PURE__ */ new Map([[kt, []]]), i = [[e, t]];
2872
+ for (r.set(At(e, t), []); i.length;) {
2873
+ let [e, t] = i.shift(), a = r.get(At(e, t));
2874
+ if (e === n) a.push({
2875
+ to: kt,
2876
+ weight: 0,
2877
+ nav: {
2878
+ from: e,
2879
+ to: e,
2880
+ kind: "shift",
2881
+ keys: []
2882
+ }
2883
+ });
2884
+ else for (let n of v(e, t)) {
2885
+ let t = At(n.to, e);
2886
+ a.push({
2887
+ to: t,
2888
+ weight: n.weight,
2889
+ nav: n
2890
+ }), r.has(t) || (r.set(t, []), i.push([n.to, e]));
2891
+ }
2892
+ }
2893
+ return r;
2894
+ }, b = (e, t) => {
2895
+ let n = yt(y(e, u, t), At(e, u), kt);
2896
+ if (n?.edges.length) return n.edges[0].nav;
2897
+ let r = Qe().graph.get(e) ?? [];
2898
+ return r.length && !r.some((e) => e.kind === "exit") ? null : Et(e).find((e) => !l.has(_(e, u)) && !l.has(_(e, "*"))) ?? null;
2899
+ }, x = (e) => {
2900
+ let t = e.cursor;
2901
+ if (!e.label || !n) return t;
2902
+ let r = null, i = n();
2903
+ for (let n = 4; n < i.length; n++) {
2904
+ let a = (i[n] ?? "").slice(0, 33);
2905
+ for (let i = a.indexOf(e.label); i >= 0; i = a.indexOf(e.label, i + 1)) {
2906
+ let e = Math.hypot(i - t.x, (n - t.y) * 1.5);
2907
+ (!r || e < r.d) && (r = {
2908
+ x: i,
2909
+ y: n,
2910
+ d: e
2911
+ });
2912
+ }
2913
+ }
2914
+ return r ? {
2915
+ x: r.x,
2916
+ y: r.y
2917
+ } : t;
2918
+ }, S = (t) => {
2919
+ let n = e.get("cursorPos"), r = e.get("cursorRect");
2920
+ if (!n || n.y !== t.y) return !1;
2921
+ let i = r ? Math.max(1, Math.round(r.w / e.get("cellMetrics").cellW)) : 1;
2922
+ return t.x >= n.x && t.x < n.x + i;
2923
+ }, C = (e) => {
2924
+ if (a = null, o = 0, p = null, h(), s) {
2925
+ let t = s;
2926
+ s = null, t(e);
2605
2927
  }
2606
- }, d = () => {
2607
- let n = r, a = e.get("viewName") || "";
2608
- if (!n || !a) {
2609
- u();
2928
+ }, w = (e) => {
2929
+ if (!p) return;
2930
+ let { edge: t, from: n, prev: r } = p, i = !!e && e !== n;
2931
+ l.set(_(t, i ? r : "*"), i ? e : n), p = null, h(), e && e !== n && t.to && e !== t.to ? console.log("Navigation step landed elsewhere", {
2932
+ from: n,
2933
+ expected: t.to,
2934
+ reached: e
2935
+ }) : (!e || e === n) && console.log("Navigation step blocked", {
2936
+ from: n,
2937
+ to: t.to || "?",
2938
+ kind: t.kind,
2939
+ dir: t.dir
2940
+ }), E();
2941
+ }, T = async (n, i) => {
2942
+ let a = x(n.edge);
2943
+ S(a) || (await Promise.race([r(a.x, a.y), jt(Ct)]), await jt(wt)), i === c && p === n && (e.get("viewName") !== n.from || !S(a) ? (console.warn("Navigation: button not reached", {
2944
+ from: n.from,
2945
+ to: n.edge.to,
2946
+ cell: a,
2947
+ cursor: e.get("cursorPos")
2948
+ }), w(e.get("viewName") === n.from ? n.from : e.get("viewName") || "")) : (n.phase = "keys", t.cancel("navigation button"), t.start(Ot(n.edge.keys))));
2949
+ }, E = () => {
2950
+ let n = a, r = e.get("viewName") || "";
2951
+ if (!n) return;
2952
+ if (!r) {
2953
+ console.warn("Navigation aborted: no view name (a dialog?)", { goal: n }), C(!1);
2610
2954
  return;
2611
2955
  }
2612
- if (a === n) {
2956
+ if (r === n) {
2613
2957
  console.log("Navigation complete:", {
2614
2958
  goal: n,
2615
- steps: i
2616
- }), u();
2959
+ steps: o
2960
+ }), C(!0);
2617
2961
  return;
2618
2962
  }
2619
- if (i >= yt) {
2963
+ if (o >= bt) {
2620
2964
  console.warn("Navigation aborted: max steps reached", {
2621
- startTitle: a,
2965
+ startTitle: r,
2622
2966
  goalTitle: n,
2623
- steps: i
2624
- }), u();
2967
+ steps: o
2968
+ }), C(!1);
2625
2969
  return;
2626
2970
  }
2627
- let o = c(n);
2628
- if (!o) console.warn("No path found (iterative)", {
2629
- startTitle: a,
2630
- goalTitle: n,
2631
- step: i
2632
- }), u();
2633
- else if (o.pages.length > 1) {
2634
- let e = o.pages[0], r = o.pages[1], c = o.directions[0], u = l(e, r, c);
2635
- i += 1, console.log("Navigation step", {
2636
- step: i,
2637
- from: a,
2638
- to: s(r),
2639
- dir: c,
2640
- goal: n,
2641
- frames: u
2642
- }), t.cancel("iterative navigation step"), t.start(u);
2971
+ let i = b(r, n);
2972
+ if (!i) {
2973
+ console.warn("No path found", {
2974
+ startTitle: r,
2975
+ goalTitle: n,
2976
+ step: o
2977
+ }), C(!1);
2978
+ return;
2643
2979
  }
2644
- }, f = () => {
2645
- r && e.get("viewName") && !e.get("macroStatus").running && d();
2646
- }, p = e.sub("viewName", f), m = e.sub("macroStatus", f);
2980
+ o += 1, console.log("Navigation step", {
2981
+ step: o,
2982
+ from: r,
2983
+ to: i.to || "?",
2984
+ kind: i.kind,
2985
+ dir: i.dir,
2986
+ goal: n
2987
+ });
2988
+ let s = {
2989
+ from: r,
2990
+ prev: u,
2991
+ edge: i,
2992
+ phase: i.kind === "button" ? "cursor" : "keys"
2993
+ };
2994
+ if (p = s, i.kind === "button") {
2995
+ T(s, c);
2996
+ return;
2997
+ }
2998
+ let l = i.keys.length ? Ot(i.keys) : Tt([i.dir], { shift: !0 });
2999
+ t.cancel("iterative navigation step"), t.start(l);
3000
+ }, D = () => {
3001
+ if (p?.phase !== "keys") return;
3002
+ let n = e.get("macroStatus").running, r = e.get("viewName") || "", i = !!r && r !== p.from;
3003
+ (!n || i) && (h(), m = n ? setTimeout(() => {
3004
+ t.cancel("navigation: no release echo"), t.start([0]), w(e.get("viewName") || "");
3005
+ }, xt) : setTimeout(() => w(e.get("viewName") || ""), i ? St : xt));
3006
+ }, O = e.sub("viewName", D), k = e.sub("macroStatus", D);
2647
3007
  return {
2648
3008
  navigateToView: (t) => new Promise((n) => {
2649
- let s = o(t);
2650
- s ? (a?.(), a = n, r = s, i = 0, console.log("Starting iterative navigation", {
2651
- goal: s,
3009
+ let r = g(t);
3010
+ r ? (C(!1), c += 1, l = /* @__PURE__ */ new Map(), s = n, a = r, o = 0, console.log("Starting iterative navigation", {
3011
+ goal: r,
2652
3012
  from: e.get("viewName") || "unknown"
2653
- }), d()) : n();
3013
+ }), E()) : n(!1);
2654
3014
  }),
2655
3015
  dispose: () => {
2656
- p(), m(), u();
3016
+ f(), O(), k(), c += 1, C(!1);
2657
3017
  }
2658
3018
  };
2659
- }, St = /* @__PURE__ */ new Set([
3019
+ }, Nt = /* @__PURE__ */ new Set([
2660
3020
  "macroStatus",
2661
3021
  "deviceModel",
2662
3022
  "fontMode",
@@ -2664,31 +3024,33 @@ var yt = 20, bt = (e, t) => {
2664
3024
  "titleColor",
2665
3025
  "backgroundColor",
2666
3026
  "minimapKey"
2667
- ]), Ct = (e, t = {}) => {
2668
- let n = t.store ?? ht(), r = (...e) => {
3027
+ ]), Pt = (e, t = {}) => {
3028
+ let n = t.store ?? gt(), r = (...e) => {
2669
3029
  t.debug && console.log(...e);
2670
3030
  }, i = /* @__PURE__ */ new Map(), a = (e, t) => {
2671
3031
  for (let n of [...i.get(e) ?? []]) n(t);
2672
- }, o = rt(e.protocol.eventBus, n), s = pt({
3032
+ }, o = it(e.protocol.eventBus, n), s = mt({
2673
3033
  bus: e,
2674
3034
  store: n,
2675
3035
  cancelOnKeydown: t.cancelMacroOnKeydown
2676
3036
  }), c = pe({
2677
3037
  bus: e,
2678
3038
  store: n
2679
- }), l = xt({
3039
+ }), l = Mt({
2680
3040
  store: n,
2681
- runner: s
2682
- }), u = lt((e) => a("transport", e)), d = Oe({
3041
+ runner: s,
3042
+ getScreenLines: o.getScreenLines,
3043
+ moveCursor: (e, t) => c.navigateTo(ot(n, e, t))
3044
+ }), u = ut((e) => a("transport", e)), d = ke({
2683
3045
  getKeySink: () => e.commands,
2684
3046
  store: n,
2685
3047
  debugLog: r,
2686
3048
  getScreenLines: o.getScreenLines
2687
- }), f = st({
3049
+ }), f = ct({
2688
3050
  io: d,
2689
- editors: ft(d),
2690
- setValueFloat: Ge(d),
2691
- browseFile: Fe(d),
3051
+ editors: pt(d),
3052
+ setValueFloat: Ke(d),
3053
+ browseFile: Ie(d),
2692
3054
  navigateToView: (e) => l.navigateToView(e),
2693
3055
  navigateTo: (e) => c.navigateTo(e),
2694
3056
  enableMidiTransport: () => u.enable(),
@@ -2718,7 +3080,7 @@ var yt = 20, bt = (e, t) => {
2718
3080
  };
2719
3081
  (!_ || _.textUnderCursor !== e.textUnderCursor || _.currentLine !== e.currentLine) && (_ = e, r("[M8SDK] Text updated:", e.textUnderCursor, e.currentLine), a("textUpdated", e));
2720
3082
  }
2721
- [...e].some((e) => St.has(e)) && a("stateChanged", it(n));
3083
+ [...e].some((e) => Nt.has(e)) && a("stateChanged", at(n));
2722
3084
  }, y = n.subAll((e) => {
2723
3085
  p.add(e), m || (m = !0, queueMicrotask(v));
2724
3086
  }), b = (e) => {
@@ -2731,7 +3093,7 @@ var yt = 20, bt = (e, t) => {
2731
3093
  macro: s,
2732
3094
  navigateTo: (e) => c.navigateTo(e),
2733
3095
  navigateToView: (e) => l.navigateToView(e),
2734
- getState: () => it(n),
3096
+ getState: () => at(n),
2735
3097
  getScreenLines: o.getScreenLines,
2736
3098
  getScreenCellColors: o.getScreenCellColors,
2737
3099
  on: (e, t) => {
@@ -2744,7 +3106,7 @@ var yt = 20, bt = (e, t) => {
2744
3106
  e.protocol.eventBus.off("key", b), y(), l.dispose(), c.dispose(), s.dispose(), u.disable(), o.dispose(), i.clear();
2745
3107
  }
2746
3108
  };
2747
- }, G = {
3109
+ }, W = {
2748
3110
  version: "1.0",
2749
3111
  description: "Semantic mapping of M8 tracker views: defines the structure of each grid view so cursor position + line text can be interpreted as typed field values.",
2750
3112
  notes: {
@@ -2911,7 +3273,7 @@ var yt = 20, bt = (e, t) => {
2911
3273
  },
2912
3274
  relativeCommands: { description: "Relative commands add to the instrument parameter's current value (01-7F add, 80-FF subtract) and keep accumulating until a note is triggered with a RET command or with an instrument number in the I column; that resets every parameter to the instrument's own value." }
2913
3275
  }
2914
- }, wt = {
3276
+ }, Ft = {
2915
3277
  version: "1.0",
2916
3278
  description: "Layouts of the non-grid ('parameter') views: which text at which column is an instrument type, name, parameter, option or action. Column positions were measured on the manual's screenshots (font mode 0, 40 columns) and cross-checked with the phrase view grid; descriptions come from the manual.",
2917
3279
  notes: {
@@ -2931,23 +3293,23 @@ var yt = 20, bt = (e, t) => {
2931
3293
  EXTERN: "external",
2932
3294
  MIDI: "midiout"
2933
3295
  }
2934
- }, Tt = wt.views, Et = wt.instrumentTypes, Dt = wt.instrumentTypeNames, Ot = {};
2935
- for (let [e, t] of Object.entries(Tt)) {
3296
+ }, It = Ft.views, Lt = Ft.instrumentTypes, Rt = Ft.instrumentTypeNames, zt = {};
3297
+ for (let [e, t] of Object.entries(It)) {
2936
3298
  let { extends: n, ...r } = t;
2937
- Ot[e] = n ? {
2938
- ...Tt[n],
3299
+ zt[e] = n ? {
3300
+ ...It[n],
2939
3301
  ...r
2940
3302
  } : r;
2941
3303
  }
2942
- function kt(e) {
2943
- return Ot[e] ?? null;
3304
+ function Bt(e) {
3305
+ return zt[e] ?? null;
2944
3306
  }
2945
- var K = (e, t, n) => t >= e.length ? "" : e.slice(t, t + n);
2946
- function At(e, t) {
2947
- let n = e.width ?? e.text?.length ?? 1, r = K(t, e.x, n);
3307
+ var G = (e, t, n) => t >= e.length ? "" : e.slice(t, t + n);
3308
+ function Vt(e, t) {
3309
+ let n = e.width ?? e.text?.length ?? 1, r = G(t, e.x, n);
2948
3310
  return e.text == null ? e.regex != null && new RegExp(e.regex, "i").test(r) : r.toUpperCase() === e.text.toUpperCase();
2949
3311
  }
2950
- function jt(e, t) {
3312
+ function Ht(e, t) {
2951
3313
  let n = e.sections;
2952
3314
  if (!n) return null;
2953
3315
  for (let e of t) {
@@ -2956,52 +3318,52 @@ function jt(e, t) {
2956
3318
  }
2957
3319
  return null;
2958
3320
  }
2959
- function Mt(e, t, n) {
3321
+ function Ut(e, t, n) {
2960
3322
  let r = e.zones?.find((e) => e.id === t);
2961
3323
  if (!e.slotLabel || !r) return null;
2962
3324
  let i = RegExp(`^${e.slotLabel}$`, "i");
2963
3325
  for (let e of n) {
2964
- let t = K(e, r.labelX, r.labelWidth).trim();
3326
+ let t = G(e, r.labelX, r.labelWidth).trim();
2965
3327
  if (i.test(t)) return t.toUpperCase();
2966
3328
  }
2967
3329
  return null;
2968
3330
  }
2969
- function Nt(e) {
3331
+ function Wt(e) {
2970
3332
  let t = e.toUpperCase().replace(/[^A-Z]/g, "");
2971
3333
  if (!t) return null;
2972
- let n = Object.keys(Dt).find((e) => t.startsWith(e));
2973
- return n ? Dt[n] : null;
3334
+ let n = Object.keys(Rt).find((e) => t.startsWith(e));
3335
+ return n ? Rt[n] : null;
2974
3336
  }
2975
- function Pt(e) {
3337
+ function Gt(e) {
2976
3338
  for (let t of e) if (t.toUpperCase().startsWith("TYPE")) {
2977
- let e = K(t, 8, 13).trim();
3339
+ let e = G(t, 8, 13).trim();
2978
3340
  return e ? {
2979
3341
  text: e,
2980
- key: Nt(e)
3342
+ key: Wt(e)
2981
3343
  } : null;
2982
3344
  }
2983
3345
  return null;
2984
3346
  }
2985
- function Ft(e) {
2986
- let t = Et[e];
3347
+ function Kt(e) {
3348
+ let t = Lt[e];
2987
3349
  return t ? {
2988
3350
  name: t.name,
2989
3351
  description: t.description
2990
3352
  } : null;
2991
3353
  }
2992
- function It(e, t, n) {
3354
+ function qt(e, t, n) {
2993
3355
  let r = t.replace(/^MOD\d$/, "MOD#").replace(/^CC[A-J]$/, "CC#");
2994
3356
  if (e.vocabulary) return e.vocabulary[r] ?? null;
2995
3357
  if (e.vocabularyFrom !== "instrumentTypes") return null;
2996
- let i = n ? [n, "common"] : ["common", ...Object.keys(Et).filter((e) => e !== "common")];
3358
+ let i = n ? [n, "common"] : ["common", ...Object.keys(Lt).filter((e) => e !== "common")];
2997
3359
  for (let e of i) {
2998
- let t = Et[e]?.params[r];
3360
+ let t = Lt[e]?.params[r];
2999
3361
  if (t) return t;
3000
3362
  }
3001
3363
  return null;
3002
3364
  }
3003
- var Lt = (e) => e.toLowerCase().replace(/[^a-z0-9]+(.)?/g, (e, t) => t ? t.toUpperCase() : "").replace(/^[^a-z]+/, ""), Rt = /^[A-Z][A-Z0-9.:#/ -]*$/;
3004
- function zt(e, t, n) {
3365
+ var Jt = (e) => e.toLowerCase().replace(/[^a-z0-9]+(.)?/g, (e, t) => t ? t.toUpperCase() : "").replace(/^[^a-z]+/, ""), Yt = /^[A-Z][A-Z0-9.:#/ -]*$/;
3366
+ function Xt(e, t, n) {
3005
3367
  if (e.kind === "browser") {
3006
3368
  let r = n.entryText?.trim() || t.trim();
3007
3369
  return r ? {
@@ -3039,17 +3401,17 @@ function zt(e, t, n) {
3039
3401
  }]
3040
3402
  };
3041
3403
  }
3042
- for (let r of e.rows ?? []) if (!(r.section && n.section && r.section !== n.section) && r.match.every((e) => At(e, t))) return {
3404
+ for (let r of e.rows ?? []) if (!(r.section && n.section && r.section !== n.section) && r.match.every((e) => Vt(e, t))) return {
3043
3405
  rowId: r.id,
3044
3406
  cells: r.cells
3045
3407
  };
3046
3408
  let r = e.zones ?? [], i = [];
3047
3409
  return r.forEach((a, o) => {
3048
- let s = K(t, a.labelX, a.labelWidth).trim().toUpperCase();
3049
- if (!Rt.test(s)) return;
3050
- let c = r[o + 1], l = c != null && K(t, c.labelX - 1, 1).trim() === "" && Rt.test(K(t, c.labelX, c.labelWidth).trim().toUpperCase()), u = c && l ? Math.max(1, c.labelX - 1 - a.x) : a.width;
3051
- if (!K(t, a.x, u).trim()) return;
3052
- let d = It(e, s, n.instrumentKey), f = Lt(s) || a.id, p = i.some((e) => e.key === f) ? `${f}${a.id[0].toUpperCase()}${a.id.slice(1)}` : f;
3410
+ let s = G(t, a.labelX, a.labelWidth).trim().toUpperCase();
3411
+ if (!Yt.test(s)) return;
3412
+ let c = r[o + 1], l = c != null && G(t, c.labelX - 1, 1).trim() === "" && Yt.test(G(t, c.labelX, c.labelWidth).trim().toUpperCase()), u = c && l ? Math.max(1, c.labelX - 1 - a.x) : a.width;
3413
+ if (!G(t, a.x, u).trim()) return;
3414
+ let d = qt(e, s, n.instrumentKey), f = Jt(s) || a.id, p = i.some((e) => e.key === f) ? `${f}${a.id[0].toUpperCase()}${a.id.slice(1)}` : f;
3053
3415
  i.push({
3054
3416
  x: a.x,
3055
3417
  width: u,
@@ -3071,19 +3433,19 @@ function zt(e, t, n) {
3071
3433
  cells: i
3072
3434
  };
3073
3435
  }
3074
- var q = {
3436
+ var K = {
3075
3437
  hexValue: null,
3076
3438
  numericValue: null,
3077
3439
  values: null,
3078
3440
  text: null
3079
3441
  };
3080
- function Bt(e) {
3442
+ function Zt(e) {
3081
3443
  return /^[0-9A-F]{2}$/i.test(e) ? "hex" : /^[0-9A-F]{2}:[0-9A-F]{2}$/i.test(e) ? "hexPair" : /^[+-]?\d+([.,]\d+)?$/.test(e) ? "float" : /^[0-9A-F]{2}\S/i.test(e) ? "hexOption" : "text";
3082
3444
  }
3083
- function Vt(e, t) {
3445
+ function Qt(e, t) {
3084
3446
  let n = e.trim();
3085
- if (!n) return q;
3086
- switch (t === "auto" ? Bt(n) : t) {
3447
+ if (!n) return K;
3448
+ switch (t === "auto" ? Zt(n) : t) {
3087
3449
  case "hex": {
3088
3450
  let e = /^([0-9A-F]{2})/i.exec(n), t = e ? parseInt(e[1], 16) : null;
3089
3451
  return {
@@ -3096,7 +3458,7 @@ function Vt(e, t) {
3096
3458
  case "hexOption": {
3097
3459
  let e = /^([0-9A-F]{2})\s?(.*)$/i.exec(n);
3098
3460
  if (!e) return {
3099
- ...q,
3461
+ ...K,
3100
3462
  text: n
3101
3463
  };
3102
3464
  let t = parseInt(e[1], 16);
@@ -3110,7 +3472,7 @@ function Vt(e, t) {
3110
3472
  case "hexPair": {
3111
3473
  let e = /^([0-9A-F]{2}):([0-9A-F]{2})/i.exec(n);
3112
3474
  if (!e) return {
3113
- ...q,
3475
+ ...K,
3114
3476
  text: n
3115
3477
  };
3116
3478
  let t = [parseInt(e[1], 16), parseInt(e[2], 16)];
@@ -3124,7 +3486,7 @@ function Vt(e, t) {
3124
3486
  case "decimal": {
3125
3487
  let e = parseInt(n, 10);
3126
3488
  return Number.isNaN(e) ? {
3127
- ...q,
3489
+ ...K,
3128
3490
  text: n
3129
3491
  } : {
3130
3492
  hexValue: null,
@@ -3136,7 +3498,7 @@ function Vt(e, t) {
3136
3498
  case "decimalPair": {
3137
3499
  let e = /^(\d+):(\d+)/.exec(n);
3138
3500
  if (!e) return {
3139
- ...q,
3501
+ ...K,
3140
3502
  text: n
3141
3503
  };
3142
3504
  let t = [parseInt(e[1], 10), parseInt(e[2], 10)];
@@ -3150,7 +3512,7 @@ function Vt(e, t) {
3150
3512
  case "float": {
3151
3513
  let e = parseFloat(n.replace(",", "."));
3152
3514
  return Number.isNaN(e) ? {
3153
- ...q,
3515
+ ...K,
3154
3516
  text: n
3155
3517
  } : {
3156
3518
  hexValue: null,
@@ -3160,12 +3522,12 @@ function Vt(e, t) {
3160
3522
  };
3161
3523
  }
3162
3524
  default: return {
3163
- ...q,
3525
+ ...K,
3164
3526
  text: n
3165
3527
  };
3166
3528
  }
3167
3529
  }
3168
- function Ht(e, t) {
3530
+ function $t(e, t) {
3169
3531
  if (!e || !t) return null;
3170
3532
  let n = t.toUpperCase().trim();
3171
3533
  if (e[n]) return e[n];
@@ -3174,28 +3536,28 @@ function Ht(e, t) {
3174
3536
  }
3175
3537
  //#endregion
3176
3538
  //#region src/fxCommands.ts
3177
- var Ut = G.fxCommands, Wt = G.instrumentFx.types, Gt = Object.entries(Wt).filter(([, e]) => e.verified).map(([e]) => e);
3178
- function Kt(e) {
3179
- let t = Gt.filter((t) => Wt[t].commands.includes(e));
3180
- return t.length === 0 || t.length === Gt.length ? null : t;
3539
+ var en = W.fxCommands, tn = W.instrumentFx.types, nn = Object.entries(tn).filter(([, e]) => e.verified).map(([e]) => e);
3540
+ function rn(e) {
3541
+ let t = nn.filter((t) => tn[t].commands.includes(e));
3542
+ return t.length === 0 || t.length === nn.length ? null : t;
3181
3543
  }
3182
- function qt(e) {
3544
+ function an(e) {
3183
3545
  let t = e.toUpperCase();
3184
3546
  for (let e of [
3185
3547
  "sequencer",
3186
3548
  "instrument",
3187
3549
  "mixer"
3188
3550
  ]) {
3189
- let n = Ut[e][t];
3551
+ let n = en[e][t];
3190
3552
  if (n) return {
3191
3553
  description: n.description,
3192
3554
  category: e,
3193
3555
  relative: n.relative === !0,
3194
- instrumentTypes: e === "instrument" ? Kt(t) : null,
3556
+ instrumentTypes: e === "instrument" ? rn(t) : null,
3195
3557
  slot: null
3196
3558
  };
3197
3559
  }
3198
- let n = /^([A-Z]{2})([1-4])$/.exec(t), r = n ? Ut.modulation[n[1]] : void 0;
3560
+ let n = /^([A-Z]{2})([1-4])$/.exec(t), r = n ? en.modulation[n[1]] : void 0;
3199
3561
  if (n && r) return {
3200
3562
  description: r.description.replace("modulator N", `modulator ${n[2]}`),
3201
3563
  category: "modulation",
@@ -3204,25 +3566,25 @@ function qt(e) {
3204
3566
  slot: Number(n[2])
3205
3567
  };
3206
3568
  }
3207
- function J(e) {
3208
- return qt(e)?.relative === !0;
3569
+ function q(e) {
3570
+ return an(e)?.relative === !0;
3209
3571
  }
3210
- function Jt(e) {
3211
- let t = Wt[e.toLowerCase()];
3572
+ function on(e) {
3573
+ let t = tn[e.toLowerCase()];
3212
3574
  return t ? {
3213
3575
  type: e.toLowerCase(),
3214
3576
  verified: t.verified,
3215
3577
  commands: [...t.commands]
3216
3578
  } : null;
3217
3579
  }
3218
- var Yt = G.instrumentFx.relativeCommands.description, Y = (e) => e.toString(16).toUpperCase().padStart(2, "0"), X = (e) => e > 127 ? e - 256 : e, Xt = (e) => `${e > 0 ? "+" : e < 0 ? "−" : "±"}${Math.abs(e)}`;
3219
- function Zt(e, t) {
3220
- return J(e) && t > 127 ? `${Y(t)} (${X(t)})` : Y(t);
3580
+ var sn = W.instrumentFx.relativeCommands.description, J = (e) => e.toString(16).toUpperCase().padStart(2, "0"), Y = (e) => e.toString(16).toUpperCase(), cn = (e) => e === 1 ? "once" : e === 2 ? "twice" : `${e} times`, X = (e) => e > 127 ? e - 256 : e, ln = (e) => `${e > 0 ? "+" : e < 0 ? "−" : "±"}${Math.abs(e)}`;
3581
+ function un(e, t) {
3582
+ return q(e) && t > 127 ? `${J(t)} (${X(t)})` : J(t);
3221
3583
  }
3222
- function Qt(e) {
3223
- return e > 127 ? `−${Y(256 - e)}` : `+${Y(e)}`;
3584
+ function dn(e) {
3585
+ return e > 127 ? `−${J(256 - e)}` : `+${J(e)}`;
3224
3586
  }
3225
- var $t = [
3587
+ var fn = [
3226
3588
  "C-",
3227
3589
  "C#",
3228
3590
  "D-",
@@ -3236,16 +3598,16 @@ var $t = [
3236
3598
  "A#",
3237
3599
  "B-"
3238
3600
  ];
3239
- function en(e) {
3601
+ function pn(e) {
3240
3602
  let t = /^([A-G])([#-])(\d)$/.exec((e ?? "").trim().toUpperCase());
3241
3603
  if (!t) return null;
3242
- let n = $t.indexOf(`${t[1]}${t[2]}`);
3604
+ let n = fn.indexOf(`${t[1]}${t[2]}`);
3243
3605
  return n < 0 ? null : Number(t[3]) * 12 + n;
3244
3606
  }
3245
- function tn(e) {
3246
- return `${$t[(e % 12 + 12) % 12]}${Math.floor(e / 12)}`;
3607
+ function mn(e) {
3608
+ return `${fn[(e % 12 + 12) % 12]}${Math.floor(e / 12)}`;
3247
3609
  }
3248
- var nn = [
3610
+ var hn = [
3249
3611
  "C",
3250
3612
  "C#",
3251
3613
  "D",
@@ -3258,27 +3620,46 @@ var nn = [
3258
3620
  "A",
3259
3621
  "A#",
3260
3622
  "B"
3261
- ];
3262
- function rn(e, t, n = {}) {
3623
+ ], gn = 6;
3624
+ function _n(e) {
3625
+ return e === gn ? "one row per step" : gn % e === 0 ? `${gn / e} rows per step` : e % gn === 0 ? `one row every ${e / gn} steps` : "";
3626
+ }
3627
+ function vn(e, t) {
3628
+ if (e === 0) return `${t} moves one row each time the instrument is triggered`;
3629
+ if (e <= 251) {
3630
+ let n = _n(e);
3631
+ return `${t} moves one row every ${e} tick${e === 1 ? "" : "s"}${n ? ` (${n})` : ""}`;
3632
+ }
3633
+ return [
3634
+ "octave map: the octave played picks the table row (instrument tables only)",
3635
+ "velocity map: the velocity played picks the table row (instrument tables only)",
3636
+ "note map: the note played picks the table row (instrument tables only)",
3637
+ `${t} moves one row every 5 ms (200 Hz)`
3638
+ ][e - 252] ?? null;
3639
+ }
3640
+ function yn(e, t, n = {}) {
3263
3641
  let r = e.toUpperCase(), i = t >> 4, a = t & 15, o = (e) => `${e} tick${e === 1 ? "" : "s"}`;
3264
3642
  switch (r) {
3265
3643
  case "ARP": {
3266
- let e = en(n.note), t = `+${i} and +${a} semitones`;
3267
- return e == null ? `plays the note, then ${t}` : `${t}: ${tn(e)} ${tn(e + i)} ${tn(e + a)}`;
3644
+ let e = pn(n.note), t = `+${i} and +${a} semitones`;
3645
+ return e == null ? `plays the note, then ${t}` : `${t}: ${mn(e)} ${mn(e + i)} ${mn(e + a)}`;
3268
3646
  }
3269
3647
  case "ARC": return `arp mode ${i}, speed ${o(a)}`;
3270
3648
  case "CHA": return n.inTable ? `everything left of it plays with probability ${t}/255 (00 never, FF always)` : `${i}/15 chance for what is left of it, ${a}/15 for what is right (0 never, F always)`;
3271
- case "DEL": return `delays this row by ${o(t)}`;
3649
+ case "DEL": return n.inTable ? `holds the table's playhead for ${o(t)}` : `delays this row by ${o(t)}`;
3272
3650
  case "KIL": return `stops the note after ${o(t)}`;
3273
3651
  case "OFF": return `note off after ${o(t)}`;
3274
3652
  case "PSL": return `portamento over ${o(t)}`;
3275
- case "GRV": return `track uses groove ${Y(t)}`;
3276
- case "GGR": return `all tracks use groove ${Y(t)}`;
3277
- case "INS": return `switches to instrument ${Y(t)}`;
3278
- case "TBL": return `instrument uses table ${Y(t)}`;
3279
- case "TBX": return t === 0 ? "stops the auxiliary table" : `plays table ${Y(t)} alongside the instrument table`;
3280
- case "THO": return `table jumps to position ${a.toString(16).toUpperCase()}`;
3281
- case "HOP": return n.inTable ? `jumps to row ${a.toString(16).toUpperCase()}, ${i} time${i === 1 ? "" : "s"}` : t === 255 ? "stops this track" : `jumps to row ${a.toString(16).toUpperCase()} of the next phrase`;
3653
+ case "GRV": return `track uses groove ${J(t)}`;
3654
+ case "GGR": return `all tracks use groove ${J(t)}`;
3655
+ case "INS": return `switches to instrument ${J(t)}`;
3656
+ case "TBL": return `instrument uses table ${J(t)}`;
3657
+ case "TBX": return t === 0 ? "stops the auxiliary table" : `plays table ${J(t)} alongside the instrument table`;
3658
+ case "THO": return n.inTable ? `every column of the table jumps to row ${Y(a)}` : `the instrument's table jumps to row ${Y(a)} (the aux table when a TBX is on this step)`;
3659
+ case "HOP": return n.inTable ? a === n.row ? i === 0 ? `this column stops on row ${Y(a)}` : `holds this column on row ${Y(a)} ${cn(i)}` : i === 0 ? `always jumps back to row ${Y(a)}: the rows in between loop` : `jumps to row ${Y(a)} ${cn(i)}, then the column runs on past it` : t === 255 ? "stops this track" : `jumps to row ${Y(a)} of the next phrase`;
3660
+ case "REP": return !n.inTable || t === 0 ? null : `plays the command above it ${t} more time${t === 1 ? "" : "s"}, one row each`;
3661
+ case "RTO": return n.inTable ? `repeats the relative command above it until it has added ${t > 127 ? `${J(t)} (${X(t)})` : J(t)} in total` : null;
3662
+ case "RMX": return `tracks to its left (selection ${Y(i)}) jump to phrase row ${Y(a)}`;
3282
3663
  case "RND": return `randomises the previous FX: left range ${i}, right range ${a} (0 none, F full)`;
3283
3664
  case "RNL": return `randomises the FX to its left: left range ${i}, right range ${a} (0 none, F full)`;
3284
3665
  case "RET": return a === 0 ? `single retrig after ${o(i)}` : `retrigs every ${o(a)}, volume ${i < 8 ? "falls" : "rises"} on each retrig (ramp ${i})`;
@@ -3287,51 +3668,47 @@ function rn(e, t, n = {}) {
3287
3668
  case "PBN": return t < 128 ? `pitch slides up by ${t}` : `pitch slides down by ${256 - t}`;
3288
3669
  case "SCA":
3289
3670
  case "SCG": {
3290
- let e = nn[i];
3671
+ let e = hn[i];
3291
3672
  return `${r === "SCA" ? "track" : "song"} scale ${a.toString(16).toUpperCase()}${e ? `, key ${e}` : ""}`;
3292
3673
  }
3293
- case "SNG": return `moves the song position by ${Xt(X(t))} row(s)`;
3294
- case "SED": return `random seed ${Y(t)}`;
3295
- case "NXT": return `plays instrument ${Y(t)} on the next track`;
3674
+ case "SNG": return `moves the song position by ${ln(X(t))} row(s)`;
3675
+ case "SED": return `random seed ${J(t)}`;
3676
+ case "NXT": return `plays instrument ${J(t)} on the next track`;
3296
3677
  case "MTT": {
3678
+ if (n.inTable) return "no effect in a table";
3297
3679
  let e = X(t);
3298
- return e === 0 ? "no timing shift" : `shifts the row by ${Xt(e)}/8 tick`;
3680
+ return e < 0 && n.row === 0 ? "no effect: a row cannot be moved earlier on the first step" : e === 0 ? "no timing shift" : `shifts the row by ${ln(e)}/8 tick`;
3299
3681
  }
3300
3682
  case "TPO": return `${t} BPM`;
3301
- case "TSP": return `transposes the song by ${Xt(X(t))} semitones`;
3302
- case "TIC": return t === 0 ? "table advances on each instrument trigger" : t <= 251 ? `table advances every ${o(t)}` : {
3303
- 252: "octave map: playing octave picks the table row",
3304
- 253: "velocity map",
3305
- 254: "note map",
3306
- 255: "table advances at 200 Hz"
3307
- }[t] ?? null;
3683
+ case "TSP": return `transposes the song by ${ln(X(t))} semitones`;
3684
+ case "TIC": return vn(t, n.inTable ? "this column" : "the instrument's table");
3308
3685
  case "XRZ": return t > 0 ? "reverb freeze on" : "reverb freeze off";
3309
3686
  }
3310
- if (J(r)) {
3687
+ if (q(r)) {
3311
3688
  let e = X(t);
3312
- return r === "PIT" ? e === 0 ? "no change" : `${Xt(e)} semitones` : e === 0 ? "no change" : Xt(e);
3689
+ return r === "PIT" ? e === 0 ? "no change" : `${ln(e)} semitones` : e === 0 ? "no change" : ln(e);
3313
3690
  }
3314
3691
  return null;
3315
3692
  }
3316
- function an(e, t, n) {
3693
+ function bn(e, t, n) {
3317
3694
  let r = e + t & 255;
3318
3695
  return n != null && (t < 128 ? r < e || r > n : r > e || r < n) && (r = n), {
3319
3696
  value: r,
3320
3697
  atLimit: n != null && r === n
3321
3698
  };
3322
3699
  }
3323
- function on(e, t, n, r = !1) {
3700
+ function xn(e, t, n, r = !1) {
3324
3701
  let i = null, a = null, o = null, s = null, c = r, l = !1, u = null, d = "none", f = Math.min(n, e.length - 1);
3325
3702
  for (let n = 0; n <= f; n += 1) {
3326
3703
  let f = e[n].fields[`fx${t}cmd`], p = e[n].fields[`fx${t}val`];
3327
3704
  if (d = "none", f && !f.isEmpty) {
3328
3705
  let e = f.rawValue.toUpperCase(), t = p && !p.isEmpty ? p.hexValue : null;
3329
- e === "REP" ? t ? !i && !r ? d = "orphan" : (d = c ? "repChange" : "rep", c || (u = n), c = !0, o = t, a != null && ({value: a, atLimit: l} = an(a, o, s))) : (d = "repStop", c = !1, o = null, l = !1) : e === "RTO" ? (d = "rto", s = t) : (d = c ? "replace" : "set", i = {
3706
+ e === "REP" ? t ? !i && !r ? d = "orphan" : (d = c ? "repChange" : "rep", c || (u = n), c = !0, o = t, a != null && ({value: a, atLimit: l} = bn(a, o, s))) : (d = "repStop", c = !1, o = null, l = !1) : e === "RTO" ? (d = "rto", s = t) : (d = c ? "replace" : "set", i = {
3330
3707
  cmd: e,
3331
3708
  value: t,
3332
3709
  step: n
3333
3710
  }, a = t, c = !1, o = null, s = null, l = !1, u = null);
3334
- } else c && (d = "continue", a != null && o != null && ({value: a, atLimit: l} = an(a, o, s)));
3711
+ } else c && (d = "continue", a != null && o != null && ({value: a, atLimit: l} = bn(a, o, s)));
3335
3712
  }
3336
3713
  return {
3337
3714
  lane: t,
@@ -3347,20 +3724,20 @@ function on(e, t, n, r = !1) {
3347
3724
  carried: c && !i
3348
3725
  };
3349
3726
  }
3350
- function sn(e) {
3351
- let t = e.source, n = (e) => e == null ? "??" : t ? Zt(t.cmd, e) : Y(e), r = e.increment == null ? "" : Qt(e.increment), i = e.atLimit && e.limit != null ? `, held at the RTO limit ${Y(e.limit)}` : "";
3727
+ function Sn(e) {
3728
+ let t = e.source, n = (e) => e == null ? "??" : t ? un(t.cmd, e) : J(e), r = e.increment == null ? "" : dn(e.increment), i = e.atLimit && e.limit != null ? `, held at the RTO limit ${J(e.limit)}` : "";
3352
3729
  switch (e.event) {
3353
3730
  case "rep":
3354
3731
  case "repChange": return e.carried ? `REP ${r} per step continues the repeat from the previous phrase` : `${e.event === "rep" ? "repeats" : "now repeats"} ${t?.cmd} from ${n(t?.value ?? null)} (step ${t?.step.toString(16).toUpperCase()}), ${r} per step → ${n(e.value)} on this step${i}`;
3355
3732
  case "continue": return e.carried ? "REP from a previous phrase is still active in this lane (^^)" : `REP still active: ${t?.cmd} reaches ${n(e.value)} on this step (${r} per step since step ${e.repStartStep?.toString(16).toUpperCase()})${i}`;
3356
3733
  case "repStop": return t ? `REP00 stops the repeat of ${t.cmd}` : "REP00 stops the repeat";
3357
3734
  case "orphan": return "REP has no earlier command in this lane of the phrase to repeat";
3358
- case "rto": return e.active && e.limit != null ? `sets the value the running REP stops at (${Y(e.limit)})` : "sets the stop value for a REP";
3735
+ case "rto": return e.active && e.limit != null ? `sets the value the running REP stops at (${J(e.limit)})` : "sets the stop value for a REP";
3359
3736
  case "replace": return t ? `replaces the running REP (${t.cmd} is no longer repeated)` : null;
3360
3737
  default: return null;
3361
3738
  }
3362
3739
  }
3363
- function cn(e) {
3740
+ function Cn(e) {
3364
3741
  let t = e.fields.inst;
3365
3742
  return t && !t.isEmpty ? "instrument" : [
3366
3743
  1,
@@ -3371,10 +3748,10 @@ function cn(e) {
3371
3748
  return n != null && !n.isEmpty && n.rawValue.toUpperCase() === "RET";
3372
3749
  }) ? "ret" : null;
3373
3750
  }
3374
- function ln(e, t, n = null) {
3751
+ function wn(e, t, n = null) {
3375
3752
  let r = {}, i = null, a = null, o = Math.min(t, e.length - 1);
3376
3753
  for (let t = 0; t <= o; t += 1) {
3377
- let o = cn(e[t]);
3754
+ let o = Cn(e[t]);
3378
3755
  if (o) {
3379
3756
  for (let e of Object.keys(r)) delete r[e];
3380
3757
  i = t, a = o;
@@ -3384,8 +3761,8 @@ function ln(e, t, n = null) {
3384
3761
  2,
3385
3762
  3
3386
3763
  ]) {
3387
- let s = on(e, o, t, n === o), c = s.source;
3388
- if (!c || s.carried || !J(c.cmd)) continue;
3764
+ let s = xn(e, o, t, n === o), c = s.source;
3765
+ if (!c || s.carried || !q(c.cmd)) continue;
3389
3766
  let l = null, u = !1;
3390
3767
  if (s.event === "set" || s.event === "replace" ? l = c.value : (s.event === "rep" || s.event === "repChange" || s.event === "continue") && (l = s.value, u = !0), l == null) continue;
3391
3768
  let d = r[c.cmd];
@@ -3401,21 +3778,21 @@ function ln(e, t, n = null) {
3401
3778
  }
3402
3779
  return r;
3403
3780
  }
3404
- var un = (e) => e === 0 ? "±00" : `${e > 0 ? "+" : "−"}${Y(Math.abs(e))}`;
3405
- function dn(e) {
3781
+ var Tn = (e) => e === 0 ? "±00" : `${e > 0 ? "+" : "−"}${J(Math.abs(e))}`;
3782
+ function En(e) {
3406
3783
  if (e.resetStep == null) return "the start of this phrase (earlier state unknown)";
3407
3784
  let t = e.resetStep.toString(16).toUpperCase();
3408
3785
  return e.resetBy === "ret" ? `the RET on step ${t}` : `the instrument number on step ${t}`;
3409
3786
  }
3410
- var fn = "stays until a note with an instrument number (I) or a RET resets it";
3411
- function pn(e) {
3412
- if (!e || e.count <= 1) return `relative: ${fn}`;
3413
- let t = e.viaRep ? ", including REP repeats" : "", n = e.total === 0 ? "has had no net effect" : `has moved by ${un(e.total)}`;
3414
- return `relative: ${e.cmd} ${n} over ${e.count} steps since ${dn(e)}${t}; ${fn}`;
3787
+ var Dn = "stays until a note with an instrument number (I) or a RET resets it";
3788
+ function On(e) {
3789
+ if (!e || e.count <= 1) return `relative: ${Dn}`;
3790
+ let t = e.viaRep ? ", including REP repeats" : "", n = e.total === 0 ? "has had no net effect" : `has moved by ${Tn(e.total)}`;
3791
+ return `relative: ${e.cmd} ${n} over ${e.count} steps since ${En(e)}${t}; ${Dn}`;
3415
3792
  }
3416
- function mn(e) {
3793
+ function kn(e) {
3417
3794
  let t = Object.values(e).filter((e) => e.total !== 0);
3418
- return t.length ? `triggers the instrument again: resets the relative changes still in force (${t.map((e) => `${e.cmd} ${un(e.total)}`).join(", ")})` : null;
3795
+ return t.length ? `triggers the instrument again: resets the relative changes still in force (${t.map((e) => `${e.cmd} ${Tn(e.total)}`).join(", ")})` : null;
3419
3796
  }
3420
3797
  //#endregion
3421
3798
  //#region src/scaleInsight.ts
@@ -3432,7 +3809,7 @@ var Z = [
3432
3809
  "A",
3433
3810
  "A#",
3434
3811
  "B"
3435
- ], hn = [
3812
+ ], An = [
3436
3813
  {
3437
3814
  name: "Major (Ionian)",
3438
3815
  steps: [
@@ -3650,7 +4027,7 @@ var Z = [
3650
4027
  11
3651
4028
  ]
3652
4029
  }
3653
- ], gn = [
4030
+ ], jn = [
3654
4031
  "the root",
3655
4032
  "a minor 2nd",
3656
4033
  "a major 2nd",
@@ -3664,26 +4041,26 @@ var Z = [
3664
4041
  "a minor 7th",
3665
4042
  "a major 7th"
3666
4043
  ];
3667
- function _n(e) {
4044
+ function Mn(e) {
3668
4045
  let t = e.replace(/[-\s]/g, "").toUpperCase();
3669
4046
  return Z.includes(t) ? t : null;
3670
4047
  }
3671
- function vn(e) {
4048
+ function Nn(e) {
3672
4049
  let t = Z.indexOf(e);
3673
- return t <= 0 ? t === 0 ? "the first row (the scale root)" : e : `${gn[t]} (+${t} semitones above C)`;
4050
+ return t <= 0 ? t === 0 ? "the first row (the scale root)" : e : `${jn[t]} (+${t} semitones above C)`;
3674
4051
  }
3675
- function yn(e) {
4052
+ function Pn(e) {
3676
4053
  let t = new Set(e);
3677
4054
  if (t.size === 0) return [];
3678
4055
  let n = [];
3679
- for (let e of hn) if (e.steps.length === t.size) for (let r = 0; r < 12; r += 1) e.steps.every((e) => t.has((e + r) % 12)) && n.push({
4056
+ for (let e of An) if (e.steps.length === t.size) for (let r = 0; r < 12; r += 1) e.steps.every((e) => t.has((e + r) % 12)) && n.push({
3680
4057
  root: r,
3681
4058
  name: e.name
3682
4059
  });
3683
4060
  return n.sort((e, t) => e.root - t.root), n.map((e) => e.root === 0 ? e.name : `${e.name} from ${Z[e.root]}`);
3684
4061
  }
3685
- function bn(e) {
3686
- let t = e.filter((e) => e.enabled === !0), n = t.map((e) => e.interval), r = yn(t.map((e) => e.semitone)), i = e.filter((e) => e.enabled === !0 && e.offset != null && e.offset !== 0).map((e) => ({
4062
+ function Fn(e) {
4063
+ let t = e.filter((e) => e.enabled === !0), n = t.map((e) => e.interval), r = Pn(t.map((e) => e.semitone)), i = e.filter((e) => e.enabled === !0 && e.offset != null && e.offset !== 0).map((e) => ({
3687
4064
  interval: e.interval,
3688
4065
  offset: e.offset
3689
4066
  }));
@@ -3692,47 +4069,47 @@ function bn(e) {
3692
4069
  enabled: n,
3693
4070
  shapes: r,
3694
4071
  detuned: i,
3695
- summary: xn({
4072
+ summary: In({
3696
4073
  enabled: n,
3697
4074
  shapes: r,
3698
4075
  detuned: i
3699
4076
  }).join(" — ")
3700
4077
  };
3701
4078
  }
3702
- function xn(e) {
4079
+ function In(e) {
3703
4080
  let { enabled: t, shapes: n, detuned: r } = e;
3704
4081
  if (!t.length) return ["no notes enabled"];
3705
4082
  let i = n[0] ?? `${t.length} notes, custom scale`;
3706
- return r.length && (i += `; detuned: ${r.map((e) => `${e.interval} ${Sn(e.offset)}`).join(", ")}`), [t.join(" "), i];
4083
+ return r.length && (i += `; detuned: ${r.map((e) => `${e.interval} ${Ln(e.offset)}`).join(", ")}`), [t.join(" "), i];
3707
4084
  }
3708
- function Sn(e) {
4085
+ function Ln(e) {
3709
4086
  return `${e > 0 ? "+" : e < 0 ? "−" : ""}${Math.abs(e).toFixed(2)} st`;
3710
4087
  }
3711
4088
  //#endregion
3712
4089
  //#region src/viewContext.ts
3713
- var Cn = /* @__PURE__ */ new Set([
4090
+ var Rn = /* @__PURE__ */ new Set([
3714
4091
  "--",
3715
4092
  "---",
3716
4093
  "---00",
3717
4094
  "----",
3718
4095
  "-"
3719
4096
  ]);
3720
- function wn(e) {
3721
- return !e || Cn.has(e) || /^-+$/.test(e);
4097
+ function zn(e) {
4098
+ return !e || Rn.has(e) || /^-+$/.test(e);
3722
4099
  }
3723
- function Tn(e) {
4100
+ function Bn(e) {
3724
4101
  let t = e.trim();
3725
- if (!t || wn(t)) return null;
4102
+ if (!t || zn(t)) return null;
3726
4103
  let n = parseInt(t, 16);
3727
4104
  return Number.isNaN(n) ? null : n;
3728
4105
  }
3729
- function En(e, t, n) {
4106
+ function Vn(e, t, n) {
3730
4107
  return t >= e.length ? "" : e.slice(t, Math.min(t + n, e.length));
3731
4108
  }
3732
- function Dn(e) {
3733
- return On(e);
4109
+ function Hn(e) {
4110
+ return Un(e);
3734
4111
  }
3735
- function On(e) {
4112
+ function Un(e) {
3736
4113
  if (!e) return {
3737
4114
  viewId: null,
3738
4115
  isUnsaved: !1,
@@ -3745,7 +4122,7 @@ function On(e) {
3745
4122
  marker: r
3746
4123
  };
3747
4124
  }
3748
- function kn(e) {
4125
+ function Wn(e) {
3749
4126
  return e.length > 0 && /^[^a-zA-Z0-9 ]/.test(e[0]) ? {
3750
4127
  line: e.slice(1),
3751
4128
  offset: 1
@@ -3754,12 +4131,12 @@ function kn(e) {
3754
4131
  offset: 0
3755
4132
  };
3756
4133
  }
3757
- function An(e, t) {
3758
- let n = En(t, e.x, e.width).trim();
4134
+ function Gn(e, t) {
4135
+ let n = Vn(t, e.x, e.width).trim();
3759
4136
  n.includes("^") && (e.type === "fxCommand" || e.type === "fxValue") && (n = "");
3760
- let r = wn(n);
4137
+ let r = zn(n);
3761
4138
  if (e.format) {
3762
- let t = r ? null : Vt(n, e.format), i = e.type === "name" || e.type === "fileEntry", a = t?.text != null && !i ? t.text.toUpperCase() : t?.text ?? null;
4139
+ let t = r ? null : Qt(n, e.format), i = e.type === "name" || e.type === "fileEntry", a = t?.text != null && !i ? t.text.toUpperCase() : t?.text ?? null;
3763
4140
  return {
3764
4141
  key: e.key,
3765
4142
  label: e.label,
@@ -3774,8 +4151,8 @@ function An(e, t) {
3774
4151
  values: t?.values ?? null,
3775
4152
  parts: e.parts,
3776
4153
  unit: e.unit,
3777
- valueDescription: !r && Ht(e.options, a ?? n) || void 0,
3778
- fileKind: e.type === "fileEntry" ? jn(n) : void 0
4154
+ valueDescription: !r && $t(e.options, a ?? n) || void 0,
4155
+ fileKind: e.type === "fileEntry" ? Kn(n) : void 0
3779
4156
  };
3780
4157
  }
3781
4158
  let i = [
@@ -3795,7 +4172,7 @@ function An(e, t) {
3795
4172
  if (a.includes(e.type)) {
3796
4173
  let e = parseInt(n, 10);
3797
4174
  o = Number.isNaN(e) ? null : e;
3798
- } else o = Tn(n);
4175
+ } else o = Bn(n);
3799
4176
  }
3800
4177
  return {
3801
4178
  key: e.key,
@@ -3807,20 +4184,20 @@ function An(e, t) {
3807
4184
  meta: e.meta
3808
4185
  };
3809
4186
  }
3810
- function jn(e) {
4187
+ function Kn(e) {
3811
4188
  if (e === "/..") return "parent";
3812
4189
  if (e.startsWith("/")) return "directory";
3813
4190
  let t = /\.([a-z0-9]+)$/i.exec(e)?.[1]?.toLowerCase();
3814
4191
  return t === "m8i" ? "instrumentPreset" : t === "wav" ? "sample" : t?.startsWith("m8") ? "m8file" : "file";
3815
4192
  }
3816
- function Mn(e, t) {
3817
- let n = En(e, t.x, t.width).trim();
4193
+ function qn(e, t) {
4194
+ let n = Vn(e, t.x, t.width).trim();
3818
4195
  if (!n) return null;
3819
- if (t.parse === "hex") return Tn(n);
4196
+ if (t.parse === "hex") return Bn(n);
3820
4197
  let r = parseInt(n, 10);
3821
4198
  return Number.isNaN(r) ? null : r;
3822
4199
  }
3823
- function Nn(e, t) {
4200
+ function Jn(e, t) {
3824
4201
  for (let n of e) if (t >= n.x && t < n.x + n.width) return n;
3825
4202
  let n = null, r = 2;
3826
4203
  for (let i of e) {
@@ -3829,9 +4206,9 @@ function Nn(e, t) {
3829
4206
  }
3830
4207
  return n;
3831
4208
  }
3832
- function Pn(e, t) {
4209
+ function Yn(e, t) {
3833
4210
  let n = {};
3834
- for (let r of e.columns ?? []) n[r.key] = An(r, t);
4211
+ for (let r of e.columns ?? []) n[r.key] = Gn(r, t);
3835
4212
  for (let e of Object.keys(n)) {
3836
4213
  let t = /^fx(\d)cmd$/.exec(e)?.[1], r = t ? n[`fx${t}val`] : void 0;
3837
4214
  r && n[e].isEmpty && (n[`fx${t}val`] = {
@@ -3840,27 +4217,27 @@ function Pn(e, t) {
3840
4217
  });
3841
4218
  }
3842
4219
  return {
3843
- rowIndex: e.rowField ? Mn(t, e.rowField) : null,
4220
+ rowIndex: e.rowField ? qn(t, e.rowField) : null,
3844
4221
  rowKey: e.rowField?.key ?? "row",
3845
4222
  rowId: null,
3846
4223
  fields: n
3847
4224
  };
3848
4225
  }
3849
- var Fn = (e) => e.replace(/\s+/g, ""), In = 1, Q = (e) => e.slice(1);
3850
- function Ln(e, t) {
4226
+ var Xn = (e) => e.replace(/\s+/g, ""), Zn = 1, Q = (e) => e.slice(1);
4227
+ function Qn(e, t) {
3851
4228
  if (!t || !e.cursorPos || !e.currentLine) return !1;
3852
4229
  let n = t.lines[e.cursorPos.y];
3853
- return n != null && Fn(n) === Fn(e.currentLine);
4230
+ return n != null && Xn(n) === Xn(e.currentLine);
3854
4231
  }
3855
- var Rn = 16, zn = 4, Bn = 21;
3856
- function Vn(e, t) {
3857
- let n = G.views[e];
4232
+ var $n = 16, er = 4, tr = 21;
4233
+ function nr(e, t) {
4234
+ let n = W.views[e];
3858
4235
  if (n?.type !== "grid" || !n.rowField) return [];
3859
- let r = [], i = Math.min(Bn, t.lines.length - 1);
3860
- for (let e = zn; e <= i; e += 1) {
4236
+ let r = [], i = Math.min(tr, t.lines.length - 1);
4237
+ for (let e = er; e <= i; e += 1) {
3861
4238
  let i = Q(t.lines[e] ?? ""), a = n.rowField;
3862
- if (i.length <= a.x + a.width || !Hn(i[a.x + a.width])) continue;
3863
- let o = Pn(n, i);
4239
+ if (i.length <= a.x + a.width || !rr(i[a.x + a.width])) continue;
4240
+ let o = Yn(n, i);
3864
4241
  o.rowIndex != null && r.push({
3865
4242
  ...o,
3866
4243
  screenRow: e
@@ -3868,11 +4245,11 @@ function Vn(e, t) {
3868
4245
  }
3869
4246
  return r;
3870
4247
  }
3871
- var Hn = (e) => e === " " || /^[^a-zA-Z0-9-]$/.test(e);
3872
- function Un(e, t) {
3873
- let n = G.views[e];
4248
+ var rr = (e) => e === " " || /^[^a-zA-Z0-9-]$/.test(e);
4249
+ function ir(e, t) {
4250
+ let n = W.views[e];
3874
4251
  if (n?.type !== "grid") return null;
3875
- let r = Vn(e, t), i = (e) => !!e && e !== " " && Hn(e);
4252
+ let r = nr(e, t), i = (e) => !!e && e !== " " && rr(e);
3876
4253
  if (e === "song") return {
3877
4254
  tracks: (n.columns ?? []).filter((e) => e.type === "chainRef").map((e) => r.find((n) => i(Q(t.lines[n.screenRow] ?? "")[e.x - 1]))?.rowIndex ?? null),
3878
4255
  row: null
@@ -3886,25 +4263,25 @@ function Un(e, t) {
3886
4263
  row: null
3887
4264
  };
3888
4265
  }
3889
- function Wn(e, t, n, r) {
4266
+ function ar(e, t, n, r) {
3890
4267
  let i = (t.cursorPos?.y ?? -1) - r;
3891
4268
  if (i < 0) return null;
3892
4269
  let a = [], o = null;
3893
- for (let t = 0; t < Rn; t += 1) {
4270
+ for (let t = 0; t < $n; t += 1) {
3894
4271
  let r = n.lines[i + t];
3895
4272
  if (r == null) return null;
3896
- let s = Q(r), c = Pn(e, s);
4273
+ let s = Q(r), c = Yn(e, s);
3897
4274
  if (c.rowIndex !== t) return null;
3898
4275
  a.push(c);
3899
4276
  let l = s.indexOf("^^");
3900
- o == null && l >= 0 && (o = Gn(e, l));
4277
+ o == null && l >= 0 && (o = or(e, l));
3901
4278
  }
3902
4279
  return {
3903
4280
  steps: a,
3904
4281
  carriedRepLane: o
3905
4282
  };
3906
4283
  }
3907
- function Gn(e, t) {
4284
+ function or(e, t) {
3908
4285
  let n = [];
3909
4286
  for (let r = 1; r <= 3; r += 1) {
3910
4287
  let i = e.columns?.find((e) => e.key === `fx${r}cmd`), a = e.columns?.find((e) => e.key === `fx${r}val`);
@@ -3918,8 +4295,8 @@ function Gn(e, t) {
3918
4295
  let r = Math.min(...n.map((e) => e.dist)), i = n.filter((e) => e.dist === r);
3919
4296
  return r <= 1 && i.length === 1 ? i[0].lane : null;
3920
4297
  }
3921
- function Kn(e) {
3922
- let t = _n(e.fields.interval?.rawValue ?? "");
4298
+ function sr(e) {
4299
+ let t = Mn(e.fields.interval?.rawValue ?? "");
3923
4300
  if (!t) return null;
3924
4301
  let n = e.fields.en?.rawValue.toUpperCase(), r = parseFloat(e.fields.offset?.rawValue ?? "");
3925
4302
  return {
@@ -3929,15 +4306,15 @@ function Kn(e) {
3929
4306
  offset: Number.isNaN(r) ? null : r
3930
4307
  };
3931
4308
  }
3932
- function qn(e, t) {
4309
+ function cr(e, t) {
3933
4310
  let n = /* @__PURE__ */ new Map();
3934
4311
  for (let r of t.lines) {
3935
- let t = Pn(e, Q(r)), i = Kn(t), a = t.fields.en?.rawValue.toUpperCase();
4312
+ let t = Yn(e, Q(r)), i = sr(t), a = t.fields.en?.rawValue.toUpperCase();
3936
4313
  !i || a !== "ON" && a !== "OFF" && a !== "--" || n.has(i.interval) || n.set(i.interval, i);
3937
4314
  }
3938
4315
  return n.size === Z.length ? Z.map((e) => n.get(e)) : null;
3939
4316
  }
3940
- function Jn(e, t, n, r) {
4317
+ function lr(e, t, n, r) {
3941
4318
  let i = {
3942
4319
  ...r,
3943
4320
  isGridView: !1,
@@ -3954,40 +4331,40 @@ function Jn(e, t, n, r) {
3954
4331
  resetsRelative: null,
3955
4332
  scaleNote: null,
3956
4333
  scale: null
3957
- }, a = e.cursorPos, o = a ? a.x - 1 : 0, s = a && Ln(e, t) ? t : null, c = s && a ? Q(s.lines[a.y] ?? "") : e.currentLine ?? "";
4334
+ }, a = e.cursorPos, o = a ? a.x - 1 : 0, s = a && Qn(e, t) ? t : null, c = s && a ? Q(s.lines[a.y] ?? "") : e.currentLine ?? "";
3958
4335
  if (!c.trim()) return i;
3959
- let l = s && a ? s.lines.slice(0, a.y + 1).reverse().map(Q) : [c], u = r.viewName === "inst" ? Pt(s ? s.lines.map(Q) : [c]) : null, d = {
4336
+ let l = s && a ? s.lines.slice(0, a.y + 1).reverse().map(Q) : [c], u = r.viewName === "inst" ? Gt(s ? s.lines.map(Q) : [c]) : null, d = {
3960
4337
  instrumentKey: u?.key ?? null,
3961
4338
  entryText: e.textUnderCursor
3962
4339
  };
3963
4340
  if (!s && a && n.kind == null) for (let e = 0; e <= Math.min(o, 24); e += 1) {
3964
4341
  let t = " ".repeat(e) + c;
3965
- if (zt(n, t, {
4342
+ if (Xt(n, t, {
3966
4343
  ...d,
3967
- section: jt(n, [t])
4344
+ section: Ht(n, [t])
3968
4345
  }).cells.some((e) => o >= e.x && o < e.x + e.width)) {
3969
4346
  c = t;
3970
4347
  break;
3971
4348
  }
3972
4349
  }
3973
- let f = jt(n, s ? l : [c]), { rowId: p, cells: m } = zt(n, c, {
4350
+ let f = Ht(n, s ? l : [c]), { rowId: p, cells: m } = Xt(n, c, {
3974
4351
  ...d,
3975
4352
  section: f
3976
4353
  }), h = {};
3977
- for (let e of m) h[e.key] = An(e, c);
4354
+ for (let e of m) h[e.key] = Gn(e, c);
3978
4355
  let g = {
3979
4356
  rowIndex: null,
3980
4357
  rowKey: "param",
3981
4358
  rowId: p,
3982
4359
  fields: h
3983
- }, _ = null, v = a ? Nn(m, o) : null;
4360
+ }, _ = null, v = a ? Jn(m, o) : null;
3984
4361
  v && (_ = {
3985
4362
  ...h[v.key],
3986
4363
  viewName: r.viewName,
3987
4364
  rowIndex: null
3988
4365
  });
3989
4366
  let y = v?.meta?.zone;
3990
- return s && typeof y == "string" && (f = Mt(n, y, l) ?? f), {
4367
+ return s && typeof y == "string" && (f = Ut(n, y, l) ?? f), {
3991
4368
  ...i,
3992
4369
  section: f,
3993
4370
  instrumentType: u,
@@ -3996,10 +4373,10 @@ function Jn(e, t, n, r) {
3996
4373
  lineText: c.trim()
3997
4374
  };
3998
4375
  }
3999
- function Yn(e, t) {
4376
+ function ur(e, t) {
4000
4377
  let n = e.viewName;
4001
4378
  if (!n) return null;
4002
- let r = G.views[n] ?? null, i = r?.type === "grid", a = r?.title ?? null, o = r?.description ?? null, { viewId: s, isUnsaved: c } = On(e.viewTitle), l = {
4379
+ let r = W.views[n] ?? null, i = r?.type === "grid", a = r?.title ?? null, o = r?.description ?? null, { viewId: s, isUnsaved: c } = Un(e.viewTitle), l = {
4003
4380
  viewName: n,
4004
4381
  viewTitle: a,
4005
4382
  viewDescription: o,
@@ -4018,8 +4395,8 @@ function Yn(e, t) {
4018
4395
  resetsRelative: null,
4019
4396
  scaleNote: null,
4020
4397
  scale: null
4021
- }, d = r?.type === "parameter" ? kt(n) : null;
4022
- if (d) return Jn(e, t, d, l);
4398
+ }, d = r?.type === "parameter" ? Bt(n) : null;
4399
+ if (d) return lr(e, t, d, l);
4023
4400
  if (!i || !r) return {
4024
4401
  ...u,
4025
4402
  isGridView: !1,
@@ -4033,11 +4410,11 @@ function Yn(e, t) {
4033
4410
  row: null,
4034
4411
  activeField: null
4035
4412
  };
4036
- let { line: p } = kn(f), m = e.cursorPos ? e.cursorPos.x - 1 : 0, h = Pn(r, p), g = n === "scale" && !_n(h.fields.interval?.rawValue ?? "") ? kt(n) : null;
4037
- if (g) return Jn(e, t, g, l);
4413
+ let { line: p } = Wn(f), m = e.cursorPos ? e.cursorPos.x - 1 : 0, h = Yn(r, p), g = n === "scale" && !Mn(h.fields.interval?.rawValue ?? "") ? Bt(n) : null;
4414
+ if (g) return lr(e, t, g, l);
4038
4415
  let _ = null;
4039
4416
  if (e.cursorPos) {
4040
- let e = Nn(r.columns ?? [], m);
4417
+ let e = Jn(r.columns ?? [], m);
4041
4418
  if (e) {
4042
4419
  let t = h.fields[e.key];
4043
4420
  t && (_ = {
@@ -4048,20 +4425,20 @@ function Yn(e, t) {
4048
4425
  }
4049
4426
  }
4050
4427
  let v = null, y = null, b = null, x = null, S = null, C = null;
4051
- if (Ln(e, t)) {
4428
+ if (Qn(e, t)) {
4052
4429
  if (n === "phrase" && h.rowIndex != null) {
4053
- let n = Wn(r, e, t, h.rowIndex);
4430
+ let n = ar(r, e, t, h.rowIndex);
4054
4431
  if (n) {
4055
4432
  v = n.steps, y = n.carriedRepLane;
4056
4433
  let e = _ ? /^fx(\d)(cmd|val)$/.exec(_.key)?.[1] : void 0;
4057
- e && (b = on(v, Number(e), h.rowIndex, y === Number(e))), x = ln(v, h.rowIndex, y), h.rowIndex > 0 && cn(h) && (S = ln(v, h.rowIndex - 1, y));
4434
+ e && (b = xn(v, Number(e), h.rowIndex, y === Number(e))), x = wn(v, h.rowIndex, y), h.rowIndex > 0 && Cn(h) && (S = wn(v, h.rowIndex - 1, y));
4058
4435
  }
4059
4436
  } else if (n === "scale") {
4060
- let e = qn(r, t);
4061
- e && (C = bn(e));
4437
+ let e = cr(r, t);
4438
+ e && (C = Fn(e));
4062
4439
  }
4063
4440
  }
4064
- let w = n === "scale" ? Kn(h) : null;
4441
+ let w = n === "scale" ? sr(h) : null;
4065
4442
  return {
4066
4443
  ...u,
4067
4444
  isGridView: !0,
@@ -4077,25 +4454,25 @@ function Yn(e, t) {
4077
4454
  scale: C
4078
4455
  };
4079
4456
  }
4080
- function Xn(e) {
4081
- if (e.isParameterView) return ir(e);
4457
+ function dr(e) {
4458
+ if (e.isParameterView) return br(e);
4082
4459
  if (e.viewName === "scale") {
4083
- let t = ar(e);
4460
+ let t = xr(e);
4084
4461
  if (t) return t;
4085
4462
  }
4086
4463
  if (!e.activeField) return $(["location", e.viewTitle ?? e.viewName]);
4087
- let { activeField: t, row: n } = e, r = $(["field", `${t.label}: ${sr(t)}`]), i = (t.type === "fxCommand" || t.type === "fxValue") && n ? Qn(e, t, n) : tr(e, t), a = i.length > 0;
4464
+ let { activeField: t, row: n } = e, r = $(["field", `${t.label}: ${Cr(t)}`]), i = (t.type === "fxCommand" || t.type === "fxValue") && n ? pr(e, t, n) : [...gr(e, t), ..._r(e, t)], a = i.length > 0;
4088
4465
  if (t.type === "fxCommand" && !t.isEmpty) {
4089
- let e = a && /^(REP|RTO)$/i.test(t.rawValue) ? void 0 : qt(t.rawValue);
4466
+ let e = a && /^(REP|RTO)$/i.test(t.rawValue) ? void 0 : an(t.rawValue);
4090
4467
  e && r.push({
4091
4468
  kind: "fxInfo",
4092
- text: `(${$n(e)})`
4469
+ text: `(${mr(e)})`
4093
4470
  });
4094
4471
  }
4095
4472
  if (t.type === "fxValue" && n) {
4096
4473
  let e = t.key.replace("val", "cmd"), i = n.fields[e];
4097
4474
  if (i && !i.isEmpty) {
4098
- let e = a && /^(REP|RTO)$/i.test(i.rawValue) ? void 0 : qt(i.rawValue), t = e ? `${i.rawValue} (${$n(e)})` : i.rawValue;
4475
+ let e = a && /^(REP|RTO)$/i.test(i.rawValue) ? void 0 : an(i.rawValue), t = e ? `${i.rawValue} (${mr(e)})` : i.rawValue;
4099
4476
  r.push({
4100
4477
  kind: "fxTarget",
4101
4478
  text: `for ${t}`
@@ -4114,8 +4491,8 @@ function Xn(e) {
4114
4491
  }
4115
4492
  return r;
4116
4493
  }
4117
- function Zn(e) {
4118
- return Xn(e).map((e) => e.text).join(" — ");
4494
+ function fr(e) {
4495
+ return dr(e).map((e) => e.text).join(" — ");
4119
4496
  }
4120
4497
  function $(...e) {
4121
4498
  return e.flatMap(([e, t]) => t ? [{
@@ -4123,32 +4500,33 @@ function $(...e) {
4123
4500
  text: t
4124
4501
  }] : []);
4125
4502
  }
4126
- function Qn(e, t, n) {
4503
+ function pr(e, t, n) {
4127
4504
  let r = /^fx(\d)/.exec(t.key)?.[1];
4128
4505
  if (!r) return [];
4129
4506
  let i = n.fields[`fx${r}cmd`], a = n.fields[`fx${r}val`];
4130
4507
  if (!i || i.isEmpty) {
4131
4508
  if (e.fxLane?.event !== "continue") return [];
4132
- let t = e.fxLane.source?.cmd, n = t && J(t) ? pn(e.relativeFx?.[t]) : null;
4133
- return $(["fxLane", sn(e.fxLane)], ["relative", n]);
4509
+ let t = e.fxLane.source?.cmd, n = t && q(t) ? On(e.relativeFx?.[t]) : null;
4510
+ return $(["fxLane", Sn(e.fxLane)], ["relative", n]);
4134
4511
  }
4135
- let o = i.rawValue.toUpperCase(), s = e.fxLane && e.fxLane.event !== "none" && e.fxLane.event !== "set" ? sn(e.fxLane) : null;
4136
- if (o === "REP" || o === "RTO") {
4137
- let t = e.fxLane?.source?.cmd, n = o === "REP" && e.fxLane?.active && t && J(t) ? pn(e.relativeFx?.[t]) : null;
4512
+ let o = i.rawValue.toUpperCase(), s = e.fxLane && e.fxLane.event !== "none" && e.fxLane.event !== "set" ? Sn(e.fxLane) : null;
4513
+ if ((o === "REP" || o === "RTO") && e.viewName !== "table") {
4514
+ let t = e.fxLane?.source?.cmd, n = o === "REP" && e.fxLane?.active && t && q(t) ? On(e.relativeFx?.[t]) : null;
4138
4515
  return $(["fxLane", s], ["relative", n]);
4139
4516
  }
4140
4517
  if (!a || a.isEmpty || a.hexValue == null) return $(["fxLane", s]);
4141
- let c = t.type === "fxCommand" ? `value ${Zt(o, a.hexValue)}: ` : "", l = rn(o, a.hexValue, {
4518
+ let c = t.type === "fxCommand" ? `value ${un(o, a.hexValue)}: ` : "", l = yn(o, a.hexValue, {
4142
4519
  note: n.fields.note?.isEmpty ? null : n.fields.note?.rawValue,
4143
- inTable: e.viewName === "table"
4520
+ inTable: e.viewName === "table",
4521
+ row: n.rowIndex
4144
4522
  }), u = null;
4145
- return J(o) ? u = pn(e.relativeFx?.[o]) : o === "RET" && e.resetsRelative && (u = mn(e.resetsRelative)), $(["meaning", l ? `${c}${l}` : null], ["fxLane", s], ["relative", u]);
4523
+ return q(o) ? u = On(e.relativeFx?.[o]) : o === "RET" && e.resetsRelative && (u = kn(e.resetsRelative)), $(["meaning", l ? `${c}${l}` : null], ["fxLane", s], ["relative", u]);
4146
4524
  }
4147
- function $n(e) {
4525
+ function mr(e) {
4148
4526
  let t = e.description.replace(/\.$/, "");
4149
- return e.instrumentTypes ? `${t}; offered by ${e.instrumentTypes.map((e) => er[e] ?? e).join(", ")} instruments` : t;
4527
+ return e.instrumentTypes ? `${t}; offered by ${e.instrumentTypes.map((e) => hr[e] ?? e).join(", ")} instruments` : t;
4150
4528
  }
4151
- var er = {
4529
+ var hr = {
4152
4530
  sampler: "Sampler",
4153
4531
  macrosynth: "Macrosynth",
4154
4532
  fmsynth: "FM Synth",
@@ -4157,14 +4535,17 @@ var er = {
4157
4535
  external: "External",
4158
4536
  midiout: "MIDI Out"
4159
4537
  };
4160
- function tr(e, t) {
4161
- return t.type !== "instrumentRef" || t.isEmpty || !e.resetsRelative ? [] : $(["relative", mn(e.resetsRelative)]);
4538
+ function gr(e, t) {
4539
+ return t.type !== "instrumentRef" || t.isEmpty || !e.resetsRelative ? [] : $(["relative", kn(e.resetsRelative)]);
4540
+ }
4541
+ function _r(e, t) {
4542
+ return e.viewName !== "table" || t.key !== "volume" || t.isEmpty || t.hexValue == null || t.hexValue > 127 ? [] : $(["meaning", `plays at ${Math.round(t.hexValue / 127 * 100)}% of the step's velocity`]);
4162
4543
  }
4163
- var nr = {
4544
+ var vr = {
4164
4545
  MODFX: "ModFX",
4165
4546
  DELAY: "Delay",
4166
4547
  REVERB: "Reverb"
4167
- }, rr = {
4548
+ }, yr = {
4168
4549
  parent: "goes up to the parent directory",
4169
4550
  directory: "directory: [EDIT] opens it",
4170
4551
  instrumentPreset: "instrument preset: [EDIT] selects it",
@@ -4172,30 +4553,30 @@ var nr = {
4172
4553
  m8file: "M8 file: [EDIT] selects it",
4173
4554
  file: "file: [EDIT] selects it"
4174
4555
  };
4175
- function ir(e) {
4556
+ function br(e) {
4176
4557
  let t = `${e.viewTitle ?? e.viewName}${e.viewId ? ` ${e.viewId}` : ""}`, n = e.activeField;
4177
4558
  if (!n) return $(["location", t], ["line", e.lineText]);
4178
- let r = e.instrumentType?.key ? Ft(e.instrumentType.key) : null;
4179
- return $(["field", `${n.label}: ${sr(n)}`], ["optionInfo", n.valueDescription], ["fieldInfo", n.description], ["fileInfo", n.fileKind && rr[n.fileKind]], ["instrument", e.instrumentType && `${r?.name ?? e.instrumentType.text} instrument`], ["section", e.section && (nr[e.section] ?? e.section)], ["location", t]);
4559
+ let r = e.instrumentType?.key ? Kt(e.instrumentType.key) : null;
4560
+ return $(["field", `${n.label}: ${Cr(n)}`], ["optionInfo", n.valueDescription], ["fieldInfo", n.description], ["fileInfo", n.fileKind && yr[n.fileKind]], ["instrument", e.instrumentType && `${r?.name ?? e.instrumentType.text} instrument`], ["section", e.section && (vr[e.section] ?? e.section)], ["location", t]);
4180
4561
  }
4181
- function ar(e) {
4562
+ function xr(e) {
4182
4563
  let t = `${e.viewTitle ?? e.viewName}${e.viewId ? ` ${e.viewId}` : ""}`, n = e.activeField, r = e.scaleNote;
4183
4564
  if (!n || !r) return e.lineText ? $(["location", t], ["line", e.lineText]) : null;
4184
4565
  let { interval: i, enabled: a, offset: o } = r, s;
4185
4566
  if (n.key === "offset") {
4186
- let e = o == null ? `detune of ${i}` : o === 0 ? `${i} is not detuned` : `${i} is detuned by ${Sn(o)}`;
4567
+ let e = o == null ? `detune of ${i}` : o === 0 ? `${i} is not detuned` : `${i} is detuned by ${Ln(o)}`;
4187
4568
  s = $(["field", `${n.label}: ${n.rawValue || "(empty)"}`], ["meaning", e], ["meaning", a === !1 ? "(note is OFF)" : null]);
4188
4569
  } else {
4189
4570
  let e = a === !0 ? "is in" : a === !1 ? "is not in" : "is not yet set in";
4190
- s = $(["field", `${n.label}: ${n.key === "en" ? n.rawValue.toUpperCase() || "(unset)" : i}`], ["meaning", i], ["meaning", vn(i)], ["meaning", `${e} the scale`]);
4571
+ s = $(["field", `${n.label}: ${n.key === "en" ? n.rawValue.toUpperCase() || "(unset)" : i}`], ["meaning", i], ["meaning", Nn(i)], ["meaning", `${e} the scale`]);
4191
4572
  }
4192
4573
  if (e.scale) {
4193
- let [t, n] = xn(e.scale);
4574
+ let [t, n] = In(e.scale);
4194
4575
  s.push(...$(["scale", `Scale: ${t}`], ["scale", n]));
4195
4576
  }
4196
4577
  return [...s, ...$(["location", `${t} row ${i}`])];
4197
4578
  }
4198
- function or(e) {
4579
+ function Sr(e) {
4199
4580
  let t = e.unit ?? "";
4200
4581
  if (e.values && e.parts) {
4201
4582
  let n = e.hexValue != null, r = e.values.map((e) => n ? e.toString(16).toUpperCase().padStart(2, "0") : String(e)), i = e.parts.map((e, n) => `${e} ${r[n] ?? "?"}${t}`).join(", ");
@@ -4203,7 +4584,7 @@ function or(e) {
4203
4584
  }
4204
4585
  return e.hexValue == null ? e.numericValue == null ? e.text ?? e.rawValue : `${e.rawValue}${t}` : `${e.rawValue.slice(0, 2)}h (dec ${e.hexValue})${e.text ? ` ${e.text}` : ""}`;
4205
4586
  }
4206
- function sr(e) {
4587
+ function Cr(e) {
4207
4588
  if (e.isEmpty) return "(empty)";
4208
4589
  let t = e.type === "name" || e.type === "fileEntry" ? e : {
4209
4590
  ...e,
@@ -4230,26 +4611,26 @@ function sr(e) {
4230
4611
  case "fileEntry": return t.text ?? t.rawValue;
4231
4612
  case "name": return `"${t.rawValue}"`;
4232
4613
  case "option": return t.hexValue != null && t.text ? `${t.rawValue.slice(0, 2)} ${t.text}` : t.text ?? t.rawValue;
4233
- case "parameter": return or(t);
4234
- case "noteInterval": return `Interval ${_n(t.rawValue) ?? t.rawValue}`;
4614
+ case "parameter": return Sr(t);
4615
+ case "noteInterval": return `Interval ${Mn(t.rawValue) ?? t.rawValue}`;
4235
4616
  case "semitoneOffset": return t.isEmpty ? "(empty)" : `${t.rawValue} st`;
4236
4617
  default: return t.rawValue;
4237
4618
  }
4238
4619
  }
4239
4620
  //#endregion
4240
4621
  //#region src/client.ts
4241
- var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4622
+ var wr = "yam8d-external-app", Tr = 3e3, Er = (e) => {
4242
4623
  let t = e.remoteHandle();
4243
4624
  return {
4244
4625
  call: (e, ...n) => t.call(e, ...n),
4245
4626
  on: (e, n) => (t.addEventListener(e, n), () => t.removeEventListener(e, n)),
4246
4627
  close: () => e.close()
4247
4628
  };
4248
- }, dr = (e) => ({
4629
+ }, Dr = (e) => ({
4249
4630
  call: (t, ...n) => e.methods[t](...n),
4250
4631
  on: (t, n) => e.on(t, n),
4251
4632
  close: () => e.dispose()
4252
- }), fr = (e) => {
4633
+ }), Or = (e) => {
4253
4634
  let t = [];
4254
4635
  return {
4255
4636
  messenger: {
@@ -4263,21 +4644,21 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4263
4644
  for (let e of t.splice(0)) e();
4264
4645
  }
4265
4646
  };
4266
- }, pr = () => {
4647
+ }, kr = () => {
4267
4648
  if (typeof window > "u") return !1;
4268
4649
  try {
4269
4650
  return window.parent !== window;
4270
4651
  } catch {
4271
4652
  return !0;
4272
4653
  }
4273
- }, mr = (e) => e instanceof DOMException && (e.name === "NotFoundError" || e.name === "AbortError"), hr = () => {
4654
+ }, Ar = (e) => e instanceof DOMException && (e.name === "NotFoundError" || e.name === "AbortError"), jr = () => {
4274
4655
  let e = typeof navigator > "u" ? null : navigator;
4275
4656
  return {
4276
4657
  serial: !!e && "serial" in e,
4277
4658
  usb: !!e && "usb" in e,
4278
4659
  midi: !!e && "requestMIDIAccess" in e
4279
4660
  };
4280
- }, gr = () => ({
4661
+ }, Mr = () => ({
4281
4662
  viewName: null,
4282
4663
  viewTitle: null,
4283
4664
  minimapKey: null,
@@ -4294,9 +4675,9 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4294
4675
  fontMode: null,
4295
4676
  systemInfo: null,
4296
4677
  macroRunning: !1
4297
- }), _r = class {
4678
+ }), Nr = class {
4298
4679
  constructor(e = {}) {
4299
- this.backend = null, this.backendUnsubscribers = [], this.device = null, this._mode = null, this.audio = null, this.connecting = null, this.stateCallbacks = /* @__PURE__ */ new Set(), this.viewCallbacks = /* @__PURE__ */ new Set(), this.cursorCallbacks = /* @__PURE__ */ new Set(), this.textCallbacks = /* @__PURE__ */ new Set(), this.keyCallbacks = /* @__PURE__ */ new Set(), this.transportCallbacks = /* @__PURE__ */ new Set(), this.connectionCallbacks = /* @__PURE__ */ new Set(), this._state = gr(), this._screen = null, this.screenRefreshing = !1, this.screenDirty = !1, this.config = e;
4680
+ this.backend = null, this.backendUnsubscribers = [], this.device = null, this._mode = null, this.audio = null, this.connecting = null, this.stateCallbacks = /* @__PURE__ */ new Set(), this.viewCallbacks = /* @__PURE__ */ new Set(), this.cursorCallbacks = /* @__PURE__ */ new Set(), this.textCallbacks = /* @__PURE__ */ new Set(), this.keyCallbacks = /* @__PURE__ */ new Set(), this.transportCallbacks = /* @__PURE__ */ new Set(), this.connectionCallbacks = /* @__PURE__ */ new Set(), this._state = Mr(), this._screen = null, this.screenRefreshing = !1, this.screenDirty = !1, this.config = e;
4300
4681
  }
4301
4682
  get state() {
4302
4683
  return this._state;
@@ -4318,11 +4699,11 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4318
4699
  }
4319
4700
  async resolveMode() {
4320
4701
  let e = this.config.mode ?? "auto";
4321
- if (e === "standalone" || e === "auto" && !pr()) {
4702
+ if (e === "standalone" || e === "auto" && !kr()) {
4322
4703
  await this.startStandalone();
4323
4704
  return;
4324
4705
  }
4325
- let t = typeof window < "u" && window.name === "yam8d-external-app", n = e === "host" || t ? null : this.config.handshakeTimeoutMs ?? lr;
4706
+ let t = typeof window < "u" && window.name === "yam8d-external-app", n = e === "host" || t ? null : this.config.handshakeTimeoutMs ?? Tr;
4326
4707
  await this.handshake(n) || (this.config.debug && console.log("[M8 SDK] No yam8d host answered, switching to standalone mode"), await this.startStandalone());
4327
4708
  }
4328
4709
  async handshake(r) {
@@ -4334,10 +4715,10 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4334
4715
  this.config.debug && (i = t(i, (e, ...t) => {
4335
4716
  console.log("[M8 SDK]", e, ...t);
4336
4717
  }));
4337
- let a = fr(i), o = e(a.messenger, { ping: async () => "pong" }), s, c = new Promise((e) => {
4718
+ let a = Or(i), o = e(a.messenger, { ping: async () => "pong" }), s, c = new Promise((e) => {
4338
4719
  r !== null && (s = setTimeout(() => e(null), r));
4339
4720
  }), l = await Promise.race([o, c]);
4340
- return clearTimeout(s), l ? (this._mode = "host", await this.attach(ur(l)), l.localHandle().emit("ready", void 0), !0) : (a.dispose(), !1);
4721
+ return clearTimeout(s), l ? (this._mode = "host", await this.attach(Er(l)), l.localHandle().emit("ready", void 0), !0) : (a.dispose(), !1);
4341
4722
  }
4342
4723
  async startStandalone() {
4343
4724
  if (this._mode = "standalone", this.config.autoConnect !== !1) try {
@@ -4363,14 +4744,14 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4363
4744
  });
4364
4745
  break;
4365
4746
  } catch (r) {
4366
- if (a = r, t && !mr(r) && (i = await ee(() => n.connect({
4747
+ if (a = r, t && !Ar(r) && (i = await ee(() => n.connect({
4367
4748
  transport: e,
4368
4749
  prompt: !1
4369
4750
  }), { maxAttempts: 2 }), i)) break;
4370
4751
  }
4371
4752
  if (!i) throw a;
4372
- let o = Ct(i, { debug: this.config.debug });
4373
- this.device = i, await this.attach(dr(o)), i.commands.resetScreen();
4753
+ let o = Pt(i, { debug: this.config.debug });
4754
+ this.device = i, await this.attach(Dr(o)), i.commands.resetScreen();
4374
4755
  let s = i;
4375
4756
  i.closed.then(() => {
4376
4757
  this.device === s && (this.config.debug && console.log("[M8 SDK] Device connection ended"), this.device = null, this.detach());
@@ -4520,7 +4901,7 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4520
4901
  }, e;
4521
4902
  }
4522
4903
  async captureSnapshot() {
4523
- let [e, t] = await Promise.all([this.fetchState(), this.getScreen()]), n = Yn(e, t);
4904
+ let [e, t] = await Promise.all([this.fetchState(), this.getScreen()]), n = ur(e, t);
4524
4905
  return {
4525
4906
  capturedAt: Date.now(),
4526
4907
  state: {
@@ -4533,8 +4914,8 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4533
4914
  deviceModel: e.deviceModel
4534
4915
  },
4535
4916
  semantic: n,
4536
- description: n ? Zn(n) : null,
4537
- descriptionParts: n ? Xn(n) : null,
4917
+ description: n ? fr(n) : null,
4918
+ descriptionParts: n ? dr(n) : null,
4538
4919
  screen: t
4539
4920
  };
4540
4921
  }
@@ -4563,23 +4944,23 @@ var cr = "yam8d-external-app", lr = 3e3, ur = (e) => {
4563
4944
  this.audio?.disconnect(), this.closeDevice(), this.detach(), this.stateCallbacks.clear(), this.viewCallbacks.clear(), this.cursorCallbacks.clear(), this.textCallbacks.clear(), this.keyCallbacks.clear(), this.transportCallbacks.clear(), this.connectionCallbacks.clear();
4564
4945
  }
4565
4946
  getSemanticContext() {
4566
- return Yn(this._state, this._screen);
4947
+ return ur(this._state, this._screen);
4567
4948
  }
4568
4949
  describeContext() {
4569
- let e = Yn(this._state, this._screen);
4570
- return e ? Zn(e) : null;
4950
+ let e = ur(this._state, this._screen);
4951
+ return e ? fr(e) : null;
4571
4952
  }
4572
4953
  describeContextParts() {
4573
- let e = Yn(this._state, this._screen);
4574
- return e ? Xn(e) : null;
4954
+ let e = ur(this._state, this._screen);
4955
+ return e ? dr(e) : null;
4575
4956
  }
4576
4957
  };
4577
- async function vr(e = {}) {
4578
- let t = new _r(e);
4958
+ async function Pr(e = {}) {
4959
+ let t = new Nr(e);
4579
4960
  return await t.connect(), t;
4580
4961
  }
4581
- function yr(e = {}) {
4582
- let t = new _r(e);
4962
+ function Fr(e = {}) {
4963
+ let t = new Nr(e);
4583
4964
  return {
4584
4965
  client: t,
4585
4966
  connect: async () => {
@@ -4587,10 +4968,10 @@ function yr(e = {}) {
4587
4968
  }
4588
4969
  };
4589
4970
  }
4590
- var br = {
4591
- createM8Client: vr,
4592
- createM8ClientSync: yr
4593
- }, xr = [
4971
+ var Ir = {
4972
+ createM8Client: Pr,
4973
+ createM8ClientSync: Fr
4974
+ }, Lr = [
4594
4975
  {
4595
4976
  role: "background",
4596
4977
  label: "BACKGROUND"
@@ -4643,7 +5024,7 @@ var br = {
4643
5024
  role: "meterPeak",
4644
5025
  label: "METER PEAK"
4645
5026
  }
4646
- ], Sr = "themesettings", Cr = (e) => e.replace(/\s+/g, "").toUpperCase(), wr = (e) => Math.max(0, Math.min(255, Math.round(e))).toString(16).padStart(2, "0"), Tr = (e, t, n) => `#${wr(e)}${wr(t)}${wr(n)}`, Er = (e, t, n) => {
5027
+ ], Rr = "themesettings", zr = (e) => e.replace(/\s+/g, "").toUpperCase(), Br = (e) => Math.max(0, Math.min(255, Math.round(e))).toString(16).padStart(2, "0"), Vr = (e, t, n) => `#${Br(e)}${Br(t)}${Br(n)}`, Hr = (e, t, n) => {
4647
5028
  let r = e / 256 * 6, i = t / 255, a = n / 255, o = Math.floor(r) % 6, s = r - Math.floor(r), c = a * (1 - i), l = a * (1 - s * i), u = a * (1 - (1 - s) * i), [d, f, p] = [
4648
5029
  [
4649
5030
  a,
@@ -4676,14 +5057,14 @@ var br = {
4676
5057
  l
4677
5058
  ]
4678
5059
  ][o];
4679
- return Tr(d * 255, f * 255, p * 255);
4680
- }, Dr = new Map(xr.map(({ role: e, label: t }) => [Cr(t), e]));
4681
- function Or(e) {
5060
+ return Vr(d * 255, f * 255, p * 255);
5061
+ }, Ur = new Map(Lr.map(({ role: e, label: t }) => [zr(t), e]));
5062
+ function Wr(e) {
4682
5063
  let t = "rgb", n = null, r = {};
4683
5064
  for (let i of e.lines) {
4684
5065
  let e = i.replace(/[{}]/g, "0"), a = /^\s*MODE\s+([A-Z])\s+([A-Z])\s+([A-Z])\b/i.exec(e);
4685
5066
  if (a) {
4686
- t = Cr(a.slice(1).join("")) === "HSV" ? "hsv" : "rgb";
5067
+ t = zr(a.slice(1).join("")) === "HSV" ? "hsv" : "rgb";
4687
5068
  continue;
4688
5069
  }
4689
5070
  let o = /^\s*THEME\s+NAME\s+(\S.*?)\s*$/i.exec(e);
@@ -4694,23 +5075,23 @@ function Or(e) {
4694
5075
  }
4695
5076
  let s = /^\s*([A-Z][A-Z:/. ]*?)\s+([0-9A-F]{2})\s+([0-9A-F]{2})\s+([0-9A-F]{2})(?:\s|$)/i.exec(e);
4696
5077
  if (!s) continue;
4697
- let c = Dr.get(Cr(s[1]));
5078
+ let c = Ur.get(zr(s[1]));
4698
5079
  if (!c || r[c]) continue;
4699
5080
  let [l, u, d] = s.slice(2, 5).map((e) => parseInt(e, 16));
4700
- r[c] = t === "hsv" ? Er(l, u, d) : Tr(l, u, d);
5081
+ r[c] = t === "hsv" ? Hr(l, u, d) : Vr(l, u, d);
4701
5082
  }
4702
- return xr.some(({ role: e }) => !r[e]) ? null : {
5083
+ return Lr.some(({ role: e }) => !r[e]) ? null : {
4703
5084
  colors: r,
4704
5085
  mode: t,
4705
5086
  name: n
4706
5087
  };
4707
5088
  }
4708
- var kr = (e) => e ? Tr(e.r, e.g, e.b) : void 0;
4709
- function Ar(e) {
4710
- let t = {}, n = kr(e.backgroundColor), r = kr(e.titleColor);
5089
+ var Gr = (e) => e ? Vr(e.r, e.g, e.b) : void 0;
5090
+ function Kr(e) {
5091
+ let t = {}, n = Gr(e.backgroundColor), r = Gr(e.titleColor);
4711
5092
  return n && (t.background = n), r && (t.textTitles = r), t;
4712
5093
  }
4713
5094
  //#endregion
4714
- export { I as M8KeyMask, j as M8_AUDIO_CAPTURE_CONSTRAINTS, xr as M8_THEME_ROLES, Sr as M8_THEME_VIEW, Yt as RELATIVE_FX_RULE, In as SCREEN_MARGIN, cr as YAM8D_FRAME_NAME, F as createM8Audio, vr as createM8Client, yr as createM8ClientSync, A as createM8Connection, Ct as createM8Engine, br as default, Zn as describeContext, Xn as describeContextParts, sr as formatFieldValue, hr as getDeviceSupport, Jt as getInstrumentFxCommands, P as getM8InputStream, Yn as getSemanticContext, qt as lookupFxCommand, Ar as observeThemeColors, Vn as parseGridScreen, Or as parseThemeScreen, Dn as parseViewTitle, te as pressKeys, Un as readPlayPositions };
5095
+ export { I as M8KeyMask, j as M8_AUDIO_CAPTURE_CONSTRAINTS, Lr as M8_THEME_ROLES, Rr as M8_THEME_VIEW, sn as RELATIVE_FX_RULE, Zn as SCREEN_MARGIN, wr as YAM8D_FRAME_NAME, F as createM8Audio, Pr as createM8Client, Fr as createM8ClientSync, A as createM8Connection, Pt as createM8Engine, Ir as default, fr as describeContext, dr as describeContextParts, Cr as formatFieldValue, jr as getDeviceSupport, on as getInstrumentFxCommands, P as getM8InputStream, ur as getSemanticContext, an as lookupFxCommand, Kr as observeThemeColors, nr as parseGridScreen, Wr as parseThemeScreen, Hn as parseViewTitle, te as pressKeys, ir as readPlayPositions };
4715
5096
 
4716
5097
  //# sourceMappingURL=index.js.map