mandioca-tabs-mcp 0.2.11 → 0.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.mjs +76 -6
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -13362,6 +13362,8 @@ function normalizarFigura(crudo) {
13362
13362
  palanca: lista(crudo.palanca)
13363
13363
  };
13364
13364
  if (typeof crudo.acorde === "string" && crudo.acorde !== "") salida.acorde = crudo.acorde;
13365
+ if (typeof crudo.octava === "number" && crudo.octava !== SIN_OCTAVA) salida.octava = crudo.octava;
13366
+ if (typeof crudo.tempo === "number" && crudo.tempo > 0) salida.tempo = crudo.tempo;
13365
13367
  if (typeof crudo.textoSegundaTipografia === "string") salida.textoSegundaTipografia = crudo.textoSegundaTipografia;
13366
13368
  if (typeof crudo.acordeSegundaTipografia === "string") salida.acordeSegundaTipografia = crudo.acordeSegundaTipografia;
13367
13369
  return salida;
@@ -13415,6 +13417,7 @@ function normalizarPista(crudo) {
13415
13417
  balance: numero(crudo.balance, 8),
13416
13418
  // Ausente = 1 pentagrama, lo único que existía antes del 2026-11-09.
13417
13419
  ...typeof crudo.pentagramas === "number" && crudo.pentagramas > 1 ? { pentagramas: crudo.pentagramas } : {},
13420
+ ...typeof crudo.transposicion === "number" && crudo.transposicion !== 0 ? { transposicion: crudo.transposicion } : {},
13418
13421
  // Las marcas de la segunda tipografía (2026-10-19): sólo si están, como `acorde`.
13419
13422
  ...typeof crudo.nombreSegundaTipografia === "string" ? { nombreSegundaTipografia: crudo.nombreSegundaTipografia } : {},
13420
13423
  ...typeof crudo.nombreCortoSegundaTipografia === "string" ? { nombreCortoSegundaTipografia: crudo.nombreCortoSegundaTipografia } : {}
@@ -88629,6 +88632,7 @@ function leerOrtografia(xml) {
88629
88632
  function leerDelArchivo(xml) {
88630
88633
  const ortografia = /* @__PURE__ */ new Map();
88631
88634
  const bajos = /* @__PURE__ */ new Map();
88635
+ const matices = /* @__PURE__ */ new Map();
88632
88636
  let iParte = -1;
88633
88637
  for (const parte of xml.matchAll(/<part\b[^>]*>([\s\S]*?)<\/part>/g)) {
88634
88638
  iParte++;
@@ -88640,9 +88644,20 @@ function leerDelArchivo(xml) {
88640
88644
  let tic = 0;
88641
88645
  let ticAnterior = 0;
88642
88646
  let bajoPendiente = null;
88643
- for (const el of compas[1].matchAll(/<(note|backup|forward|attributes|harmony)\b[\s\S]*?<\/\1>/g)) {
88647
+ for (const el of compas[1].matchAll(/<(note|backup|forward|attributes|harmony|direction)\b[\s\S]*?<\/\1>/g)) {
88644
88648
  const bloque = el[0];
88645
88649
  const tipo = el[1];
88650
+ if (tipo === "direction") {
88651
+ const nombre = /<dynamics\b[^>]*>\s*<([a-z]+)\s*\/>/.exec(bloque)?.[1];
88652
+ if (nombre) {
88653
+ const pent2 = (entero(bloque, /<staff>\s*(\d+)\s*<\/staff>/) ?? 1) - 1;
88654
+ const clave2 = `${iParte}|${pent2}`;
88655
+ const lista2 = matices.get(clave2) ?? [];
88656
+ lista2.push({ compas: iCompas, tic: Math.round(tic * TICS_POR_NEGRA2 / divisiones), nombre });
88657
+ matices.set(clave2, lista2);
88658
+ }
88659
+ continue;
88660
+ }
88646
88661
  if (tipo === "attributes") {
88647
88662
  divisiones = entero(bloque, /<divisions>\s*(\d+)\s*<\/divisions>/) ?? divisiones;
88648
88663
  const transponer2 = /<transpose\b[^>]*>([\s\S]*?)<\/transpose>/.exec(bloque)?.[1];
@@ -88697,7 +88712,7 @@ function leerDelArchivo(xml) {
88697
88712
  }
88698
88713
  }
88699
88714
  }
88700
- return { ortografia, bajos };
88715
+ return { ortografia, bajos, matices };
88701
88716
  }
88702
88717
  var MODO_DE_ALTERACION, MODO_POR_ALTER, SEMITONOS, TICS_POR_NEGRA2, entero, HIJO_QUE_SE_MUEVE, ATRIBUTOS_DE_SALTO, NEGRAS_POR_FIGURA;
88703
88718
  var init_musicxmlEntrada = __esm({
@@ -88748,7 +88763,7 @@ function importarGp(bytes, opciones = {}) {
88748
88763
  const preparado = prepararMusicXml(xml);
88749
88764
  const score = _barrel_exports$1.ScoreLoader.loadScoreFromBytes(preparado.bytes);
88750
88765
  const leido = leerDelArchivo(preparado.xml);
88751
- const resultado = importarScore(score, opciones, { ortografia: leido.ortografia, bajos: leido.bajos });
88766
+ const resultado = importarScore(score, opciones, { ortografia: leido.ortografia, bajos: leido.bajos, matices: leido.matices });
88752
88767
  resultado.avisos.push(...preparado.correcciones);
88753
88768
  return resultado;
88754
88769
  }
@@ -88862,7 +88877,10 @@ function importarScore(score, opciones = {}, datos = {}) {
88862
88877
  // la destapó la comparación de píxeles, porque la mezcla no se dibuja: se oye.
88863
88878
  volumen: pista.playbackInfo?.volume ?? 16,
88864
88879
  balance: pista.playbackInfo?.balance ?? 8,
88865
- ...unInstrumento && pista.staves.length > 1 ? { pentagramas: pista.staves.length } : {}
88880
+ ...unInstrumento && pista.staves.length > 1 ? { pentagramas: pista.staves.length } : {},
88881
+ // ⛔ La transposición de lectura (`<transpose>` de un clarinete o un saxo) se perdía: el
88882
+ // instrumento se dibujaba en altura real en vez de como se lee (2026-11-09).
88883
+ ...pentagrama.displayTranspositionPitch ? { transposicion: pentagrama.displayTranspositionPitch } : {}
88866
88884
  });
88867
88885
  idDelInstrumento = idPista;
88868
88886
  for (const [indice, compasDeAlphaTab] of pentagrama.bars.entries()) {
@@ -88889,6 +88907,12 @@ function importarScore(score, opciones = {}, datos = {}) {
88889
88907
  }
88890
88908
  }
88891
88909
  const ticsDelCompas = 960 * 4 * (maestroDelCompas?.timeSignatureNumerator ?? 4) / (maestroDelCompas?.timeSignatureDenominator ?? 4);
88910
+ const temposAMitad = /* @__PURE__ */ new Map();
88911
+ if (pista.index === 0 && numeroDePentagrama === 0) {
88912
+ for (const a of maestroDelCompas?.tempoAutomations ?? []) {
88913
+ if (a.ratioPosition > 0) temposAMitad.set(Math.round(a.ratioPosition * ticsDelCompas), a.value);
88914
+ }
88915
+ }
88892
88916
  const pedalesDelCompas = /* @__PURE__ */ new Map();
88893
88917
  for (const marcador of compasDeAlphaTab.sustainPedals ?? []) {
88894
88918
  pedalesDelCompas.set(Math.round(marcador.ratioPosition * ticsDelCompas), marcador.pedalType + 1);
@@ -88924,7 +88948,10 @@ function importarScore(score, opciones = {}, datos = {}) {
88924
88948
  // `<harmony>` de MusicXML) y este traductor no los leía: «Am», «G7», todo afuera,
88925
88949
  // sin aviso. El bajo («C/E») lo lee `leerDelArchivo`, porque alphaTab lo tira.
88926
88950
  acorde: acordeDelGolpe(golpe, pentagrama, datos.bajos, pista.index, numeroDePentagrama, indice),
88927
- dinamica: golpe.dynamics,
88951
+ dinamica: maticeDelGolpe(datos.matices, pista.index, numeroDePentagrama, pista.staves.length, indice, golpe.displayStart) ?? golpe.dynamics,
88952
+ // ⛔ El 8va / 8vb / 15ma se perdía: la notación salía una octava corrida (2026-11-09).
88953
+ octava: golpe.ottava,
88954
+ tempo: tempoDelGolpe(golpe, voz.index === 0 ? temposAMitad : void 0),
88928
88955
  // ═══════════════════════════════════════════════════════════════════
88929
88956
  // ★★★ LOS SIGNOS DE GUITAR PRO — hasta hoy se perdían TODOS en silencio
88930
88957
  // ═══════════════════════════════════════════════════════════════════
@@ -89112,6 +89139,24 @@ function acordeDelGolpe(golpe, pentagrama, bajos, parte, numeroDePentagrama, com
89112
89139
  const bajo = bajos?.get(`${parte}|${numeroDePentagrama}|${compas}|${golpe.displayStart}`) ?? "";
89113
89140
  return bajo && !nombre.endsWith(bajo) ? nombre + bajo : nombre;
89114
89141
  }
89142
+ function tempoDelGolpe(golpe, delMaestro) {
89143
+ if (golpe.displayStart === 0) return void 0;
89144
+ const propio = golpe.automations?.find((a) => a.type === _barrel_exports$4.AutomationType.Tempo)?.value;
89145
+ return propio ?? delMaestro?.get(golpe.displayStart);
89146
+ }
89147
+ function maticeDelGolpe(matices, parte, pentagrama, pentagramas, compas, tic) {
89148
+ if (!matices || matices.size === 0) return void 0;
89149
+ let lista2 = matices.get(`${parte}|${pentagrama}`);
89150
+ for (let otro = 0; otro < pentagramas && !lista2?.length; otro++) lista2 = matices.get(`${parte}|${otro}`);
89151
+ if (!lista2?.length) return void 0;
89152
+ let vigente = "f";
89153
+ for (const m of lista2) {
89154
+ if (m.compas < compas || m.compas === compas && m.tic <= tic) vigente = m.nombre;
89155
+ else break;
89156
+ }
89157
+ const valor = _barrel_exports$4.DynamicValue[vigente.toUpperCase()];
89158
+ return typeof valor === "number" ? valor : void 0;
89159
+ }
89115
89160
  function normalizarTuplet(valor) {
89116
89161
  return valor === void 0 || valor <= 0 ? 1 : valor;
89117
89162
  }
@@ -89133,6 +89178,11 @@ function formatoQueNecesita(documento) {
89133
89178
  for (const pista of documento.pistas.values()) {
89134
89179
  const pentagramas = pista.get("pentagramas");
89135
89180
  if (typeof pentagramas === "number" && pentagramas > 1) return 5;
89181
+ const transposicion = pista.get("transposicion");
89182
+ if (typeof transposicion === "number" && transposicion !== 0) return 5;
89183
+ }
89184
+ for (const figura of documento.figuras.values()) {
89185
+ if (figura.get("octava") !== void 0 || figura.get("tempo") !== void 0) return 5;
89136
89186
  }
89137
89187
  return 4;
89138
89188
  }
@@ -90017,7 +90067,7 @@ var VERSION_DEL_CONECTOR;
90017
90067
  var init_version = __esm({
90018
90068
  "apps/mcp/src/version.ts"() {
90019
90069
  "use strict";
90020
- VERSION_DEL_CONECTOR = true ? "0.2.11" : null;
90070
+ VERSION_DEL_CONECTOR = true ? "0.2.13" : null;
90021
90071
  }
90022
90072
  });
90023
90073
 
@@ -97962,6 +98012,7 @@ function proyectar(documento, opciones = {}) {
97962
98012
  score.album = marcado(cabecera.get("album") ?? "", marcasDe(cabecera, "album"));
97963
98013
  const tempoDeCabecera = documento.cabecera.get("tempo") || 120;
97964
98014
  score.stylesheet.hideDynamics = documento.cabecera.get("mostrarMatices") === false;
98015
+ score.stylesheet.barNumberDisplay = _barrel_exports$4.BarNumberDisplay.AllBars;
97965
98016
  const estiloDeLaObra = documento.leerEstilo();
97966
98017
  aplicarEstiloAlDibujo(score, ajustes, estiloDeLaObra);
97967
98018
  score.stylesheet.firstSystemTrackNameMode = _barrel_exports$4.TrackNameMode.FullName;
@@ -98042,6 +98093,7 @@ function proyectar(documento, opciones = {}) {
98042
98093
  if (lista2) lista2.push(nota);
98043
98094
  else notasPorFigura.set(nota.figuraId, [nota]);
98044
98095
  }
98096
+ const temposAMitad = [];
98045
98097
  const pistasEnOrden = [...documento.pistasEnOrden()];
98046
98098
  const canales = canalesDeLasPistas(
98047
98099
  pistasEnOrden.map(({ datos }) => normalizarPista(datos).tipo)
@@ -98063,6 +98115,7 @@ function proyectar(documento, opciones = {}) {
98063
98115
  const valores = [...pista.afinacion].reverse();
98064
98116
  pentagrama.stringTuning = _barrel_exports$4.Tuning.findTuning(valores) ?? new _barrel_exports$4.Tuning("", valores, false);
98065
98117
  pentagrama.capo = pista.capo;
98118
+ pentagrama.displayTranspositionPitch = pista.transposicion ?? 0;
98066
98119
  pentagrama.showTablature = pista.tipo === "trastes";
98067
98120
  pentagrama.showStandardNotation = true;
98068
98121
  pentagrama.isPercussion = pista.tipo === "percusion";
@@ -98071,6 +98124,8 @@ function proyectar(documento, opciones = {}) {
98071
98124
  track.playbackInfo.secondaryChannel = 9;
98072
98125
  track.percussionArticulations = KIT.map((pieza) => {
98073
98126
  const art = new _barrel_exports$4.InstrumentArticulation();
98127
+ art.elementType = pieza.nombre;
98128
+ art.id = pieza.indice;
98074
98129
  art.outputMidiNumber = pieza.midi;
98075
98130
  art.staffLine = pieza.linea;
98076
98131
  art.noteHeadDefault = pieza.cabeza === "x" ? _barrel_exports$4.MusicFontSymbol.NoteheadXBlack : _barrel_exports$4.MusicFontSymbol.NoteheadBlack;
@@ -98125,6 +98180,8 @@ function proyectar(documento, opciones = {}) {
98125
98180
  const golpe = new _barrel_exports$4.Beat();
98126
98181
  golpe.duration = figura.valor;
98127
98182
  golpe.dots = figura.puntillos;
98183
+ if (figura.octava !== void 0) golpe.ottava = figura.octava;
98184
+ if (figura.tempo !== void 0) temposAMitad.push({ compas: indiceDeCompas2, tiempo: figura.tiempo, valor: figura.tempo, tics: ticsDelCompas });
98128
98185
  if (figura.tupletNumerador > 1) {
98129
98186
  golpe.tupletNumerator = figura.tupletNumerador;
98130
98187
  golpe.tupletDenominator = figura.tupletDenominador;
@@ -98271,6 +98328,19 @@ function proyectar(documento, opciones = {}) {
98271
98328
  });
98272
98329
  }
98273
98330
  }
98331
+ const yaPuestos = /* @__PURE__ */ new Set();
98332
+ for (const t of temposAMitad.sort((a, b) => a.compas - b.compas || a.tiempo - b.tiempo)) {
98333
+ const clave = `${t.compas}|${t.tiempo}`;
98334
+ const maestro = score.masterBars[t.compas];
98335
+ if (!maestro || yaPuestos.has(clave) || t.tics <= 0) continue;
98336
+ yaPuestos.add(clave);
98337
+ const automatizacion = new _barrel_exports$4.Automation();
98338
+ automatizacion.isLinear = false;
98339
+ automatizacion.type = _barrel_exports$4.AutomationType.Tempo;
98340
+ automatizacion.value = t.valor;
98341
+ automatizacion.ratioPosition = t.tiempo / t.tics;
98342
+ maestro.tempoAutomations.push(automatizacion);
98343
+ }
98274
98344
  const { saltosDeRenglon } = documento.leerPresentacion();
98275
98345
  if (saltosDeRenglon.size > 0) {
98276
98346
  maestros.forEach((maestro, indice) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mandioca-tabs-mcp",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Conector MCP de Mandioca Tabs: tu IA lee y escribe la partitura que tienes abierta en tabs.mandioca-records.com.",
5
5
  "type": "module",
6
6
  "bin": {