var CUNICULUM_INFO_PAGES = {
  reglas: [
    [
      ['gold', '[CUNICULUM] Reglas - pagina 1/2'],
      ['yellow', '1. Respeta claims, bases, cofres, maquinas y construcciones ajenas.'],
      ['yellow', '2. No uses xray, exploits, duplicaciones ni automatizaciones abusivas.'],
      ['yellow', '3. Nether esta habilitado; The End sigue bloqueado hasta apertura oficial.'],
      ['yellow', '4. PvP global existe, pero spawn y zonas protegidas no son arenas.'],
      ['gray', 'Usa /reglas 2 para continuar.']
    ],
    [
      ['gold', '[CUNICULUM] Reglas - pagina 2/2'],
      ['yellow', '5. No abuses de mobs, granjas, chunk loaders ni entidades si causan lag.'],
      ['yellow', '6. Si juegas en equipo, acuerden permisos y zonas antes de construir.'],
      ['yellow', '7. Reporta bugs, perdidas y abusos al staff con pruebas claras.'],
      ['yellow', '8. El staff puede intervenir claims o zonas si hay abuso o riesgo tecnico.'],
      ['gray', 'Usa /ayuda para una guia rapida.']
    ]
  ],
  comandos: [
    [
      ['gold', '[CUNICULUM] Comandos - pagina 1/5'],
      ['yellow', '/reglas [pagina]: normas basicas del servidor.'],
      ['yellow', '/ayuda [pagina]: guia corta para empezar y resolver dudas.'],
      ['yellow', '/comandos [pagina]: esta lista paginada.'],
      ['yellow', '/spawn: volver al lobby seguro; puedes salir usando el portal al Overworld.'],
      ['yellow', '/mostrar: enseña en el chat el item que tienes en la mano.'],
      ['yellow', '/ftbquests o libro de misiones: ruta RPG y progresion.'],
      ['gray', 'Usa /comandos 2 para teleport, homes, rtp y claims.']
    ],
    [
      ['gold', '[CUNICULUM] Comandos - pagina 2/5'],
      ['yellow', '/tpa <jugador>: pedir teleport a otro jugador.'],
      ['yellow', '/tpaccept y /tpdeny: aceptar o rechazar una peticion TPA.'],
      ['yellow', '/sethome <nombre>: guardar casa si tu limite de homes lo permite.'],
      ['yellow', '/home <nombre>: volver a una casa guardada.'],
      ['yellow', '/back: volver al punto anterior si tu rango lo permite. /rtp: viaje aleatorio solo a Overworld; quedate quieto durante la espera.'],
      ['gray', 'Usa /comandos 3 para claims/chunks o /claims.']
    ],
    [
      ['gold', '[CUNICULUM] Comandos - pagina 3/5'],
      ['yellow', '/claims o /chunks: guia clara de chunks reclamados.'],
      ['yellow', '/openpac-claims: abrir/gestionar claims de Open Parties and Claims.'],
      ['yellow', '/openpac-parties: gestionar party/grupo para compartir claims.'],
      ['yellow', 'Staff: /claimtp <chunk_x> <chunk_z> [dimension] permite revisar un claim por coordenadas.'],
      ['yellow', 'Los limites de claims dependen de rango; Madriguero y creadores empiezan con 9.'],
      ['yellow', 'Owner/Admin tienen modo staff de OPAC por permiso; no es para uso normal.'],
      ['gray', 'Usa /comandos 4 para party/equipo o /equipo.']
    ],
    [
      ['gold', '[CUNICULUM] Comandos - pagina 4/5'],
      ['yellow', '/equipo, /team o /teams: guia de FTB Teams y acceso a su interfaz.'],
      ['yellow', 'Los claims se gestionan con Open Parties and Claims; para compartir claims usa /openpac-parties.'],
      ['yellow', 'Por defecto, miembros de la party de OPAC pueden construir, interactuar y usar los claims compartidos.'],
      ['yellow', 'El limite de claims lo define FTB Ranks mediante permisos OPAC; si cambia, reloguea.'],
      ['yellow', 'Roles sociales activos: tiktok, youtuber, kick, twitch y facebook.'],
      ['yellow', 'Si cambias de rango y sigues viendo limite viejo, sal y entra para recalcular OPAC.'],
      ['gray', 'Usa /comandos 5 para login y skins.']
    ],
    [
      ['gold', '[CUNICULUM] Comandos - pagina 5/5'],
      ['yellow', '/register <clave>: registrar tu cuenta no-premium la primera vez.'],
      ['yellow', '/login <clave>: entrar cuando el servidor te pida iniciar sesion.'],
      ['yellow', '/online <clave>: activar auto-login premium si tu cuenta es premium.'],
      ['yellow', '/skin refresh: recargar tu skin actual.'],
      ['yellow', '/skin set mojang <nick>: usar la skin oficial de un nickname premium.'],
      ['yellow', '/skin set ely_by <nick>: usar una skin de Ely.by.'],
      ['gray', 'Usa /ayuda 4 si necesitas explicacion de login y skins.']
    ]
  ],
  ayuda: [
    [
      ['gold', '[CUNICULUM] Ayuda - pagina 1/4'],
      ['yellow', 'Empieza leyendo la Bitacora de CUNICULUM y sigue FTB Quests.'],
      ['yellow', 'Consigue refugio, comida, cama y reclama tu base cuanto antes.'],
      ['yellow', 'Usa /comandos para ver comandos basicos y /reglas para normas.'],
      ['yellow', 'Usa /mostrar para compartir tu item actual en el chat con vista al pasar el mouse.'],
      ['yellow', 'Si un comando no funciona, puede depender de rango, cooldown o permisos.'],
      ['gray', 'Usa /ayuda 2 para claims y team.']
    ],
    [
      ['gold', '[CUNICULUM] Ayuda - pagina 2/4'],
      ['yellow', 'Para proteger una base usa Open Parties and Claims desde Xaero o /openpac-claims.'],
      ['yellow', 'Para jugar con amigos en claims usa /openpac-parties; FTB Teams queda como equipo/interfaz social.'],
      ['yellow', 'Al entrar a una party de OPAC, los claims de party se comparten con sus miembros autorizados.'],
      ['yellow', 'La config default busca que miembros de la misma party OPAC puedan usar sus claims compartidos.'],
      ['yellow', 'Los claims protegen interacciones, bloques y acceso segun permisos de OPAC.'],
      ['gray', 'Usa /ayuda 3 para soporte y problemas comunes.']
    ],
    [
      ['gold', '[CUNICULUM] Ayuda - pagina 3/4'],
      ['yellow', 'Si mueres, busca tu tumba antes de seguir explorando.'],
      ['yellow', 'Si OPAC no actualiza tus claims tras un rango, sal y vuelve a entrar.'],
      ['yellow', 'Owner/Admin deben usar permisos staff de OPAC solo para soporte o abusos.'],
      ['yellow', 'Si quedas atrapado, desincronizado o con bug, avisa a Helper/Moderador.'],
      ['yellow', 'No intervengas claims de otros ni fuerces chunks sin necesidad.'],
      ['gray', 'Usa /ayuda 4 para login y skins.']
    ],
    [
      ['gold', '[CUNICULUM] Ayuda - pagina 4/4'],
      ['yellow', 'Al entrar, sigue solo el mensaje de DirectAuth: /register o /login.'],
      ['yellow', 'Si eres premium, tras iniciar sesion usa /online <clave> para auto-login.'],
      ['yellow', 'Las skins se intentan cargar automaticamente desde tu nickname.'],
      ['yellow', 'Si no aparece, usa /skin refresh o /skin set mojang <nickname>.'],
      ['yellow', 'Si usas launcher con skins propias externas, puede ignorar la skin del servidor.'],
      ['gray', 'Usa /comandos 5 para ver la lista corta de comandos de login/skins.']
    ]
  ],
  discord: [
    [
      ['gold', '[CUNICULUM] Discord oficial'],
      ['yellow', 'Haz clic en el enlace para unirte al Discord:'],
      ['aqua', 'https://discord.gg/qR3mdGr9', {
        underlined: true,
        clickEvent: {
          action: 'open_url',
          value: 'https://discord.gg/qR3mdGr9'
        },
        hoverEvent: {
          action: 'show_text',
          contents: 'Abrir Discord de CUNICULUM'
        }
      }]
    ]
  ],
  equipo: [
    [
      ['gold', '[CUNICULUM] Equipo / Parties'],
      ['yellow', 'La interfaz real de FTB Teams se abre desde el boton Mi equipo del inventario o con la tecla Abrir interfaz de equipos.'],
      ['yellow', 'FTB Teams usa accion cliente ftbteams:open_gui; no existe comando server puro para forzar esa pantalla.'],
      ['aqua', '/help ftbteams', {
        underlined: true,
        clickEvent: { action: 'run_command', value: '/help ftbteams' },
        hoverEvent: { action: 'show_text', contents: 'Ver comandos reales de FTB Teams' }
      }],
      ['yellow', 'Flujo recomendado: crea party con /openpac-parties, invita amigos y luego reclamen chunks desde OPAC/Xaero.'],
      ['gray', 'Atajos: /claims, /chunks, /comandos 3 y /comandos 4.']
    ]
  ],
  claims: [
    [
      ['gold', '[CUNICULUM] Claims y chunks'],
      ['yellow', 'Los claims de grupo pertenecen a la party de OPAC. Si dos jugadores estan en la misma party, comparten uso dentro de esos claims.'],
      ['yellow', 'Permisos por defecto: miembros del mismo grupo deben poder usar sus claims; otros jugadores quedan bloqueados por OPAC.'],
      ['yellow', 'Gestionar/reclamar chunks: /openpac-claims'],
      ['yellow', 'Gestionar grupos/party: /openpac-parties'],
      ['yellow', 'Ver sintaxis exacta instalada: /help openpac-claims'],
      ['yellow', 'Staff: /claimtp <chunk_x> <chunk_z> [dimension] o /claimtp block <x> <z> [dimension].'],
      ['gray', 'Normal: 9 chunks por party/grupo basico. Owner/Admin tienen limites altos por rango. Comparte acceso desde OPAC/party.']
    ]
  ]
};

function cuniculumInfoServer(ctx) {
  try {
    return ctx.getSource().getServer();
  } catch (ignored) {
  }

  try {
    return ctx.source.server;
  } catch (ignored) {
  }

  return null;
}

function cuniculumInfoPlayerName(ctx) {
  var candidates = [];

  try {
    candidates.push(ctx.source.player.username);
  } catch (ignored) {
  }

  try {
    var player = ctx.getSource().getPlayer();
    candidates.push(player.username);
    candidates.push(player.getGameProfile().getName());
  } catch (ignored) {
  }

  for (var i = 0; i < candidates.length; i++) {
    var candidateName = String(candidates[i] || '');
    if (/^[A-Za-z0-9_]{1,16}$/.test(candidateName)) {
      return candidateName;
    }
  }

  return '';
}

function cuniculumInfoPage(rawPage, maxPages) {
  var parsed = parseInt(String(rawPage || '1'), 10);
  if (!Number.isFinite(parsed) || parsed < 1) {
    return 1;
  }

  if (parsed > maxPages) {
    return maxPages;
  }

  return parsed;
}

function cuniculumInfoTell(server, playerName, color, text, extra) {
  var component = { text: text, color: color, italic: false };
  if (extra) {
    for (var key in extra) {
      component[key] = extra[key];
    }
  }

  var payload = JSON.stringify(component);
  if (playerName) {
    server.runCommandSilent(`tellraw ${playerName} ${payload}`);
    return;
  }

  try {
    server.tell(text);
  } catch (ignored) {
  }
}

function cuniculumInfoStackId(stack) {
  if (!stack) {
    return '';
  }

  var values = [];
  try { values.push(stack.id); } catch (ignored) { }
  try { values.push(stack.item); } catch (ignored) { }
  try { values.push(stack.getId()); } catch (ignored) { }
  try { values.push(stack.getItem()); } catch (ignored) { }
  try { values.push(stack.toString()); } catch (ignored) { }

  for (var i = 0; i < values.length; i++) {
    var text = String(values[i] || '').toLowerCase();
    var match = text.match(/[a-z0-9_.-]+:[a-z0-9_./-]+/i);
    if (match && match[0] !== 'minecraft:air') {
      return match[0];
    }
  }

  return '';
}

function cuniculumInfoStackCount(stack) {
  var values = [];
  try { values.push(stack.count); } catch (ignored) { }
  try { values.push(stack.getCount()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    var count = Math.floor(Number(values[i] || 0));
    if (count > 0) {
      return Math.min(99, count);
    }
  }
  return 1;
}

function cuniculumInfoShortItemName(itemId) {
  var vanillaNames = {
    'minecraft:wooden_sword': 'Espada de madera',
    'minecraft:stone_sword': 'Espada de piedra',
    'minecraft:iron_sword': 'Espada de hierro',
    'minecraft:golden_sword': 'Espada de oro',
    'minecraft:diamond_sword': 'Espada de diamante',
    'minecraft:netherite_sword': 'Espada de netherita',
    'minecraft:wooden_axe': 'Hacha de madera',
    'minecraft:stone_axe': 'Hacha de piedra',
    'minecraft:iron_axe': 'Hacha de hierro',
    'minecraft:golden_axe': 'Hacha de oro',
    'minecraft:diamond_axe': 'Hacha de diamante',
    'minecraft:netherite_axe': 'Hacha de netherita',
    'minecraft:bow': 'Arco',
    'minecraft:crossbow': 'Ballesta',
    'minecraft:trident': 'Tridente',
    'minecraft:shield': 'Escudo'
  };
  if (vanillaNames[itemId]) {
    return vanillaNames[itemId];
  }
  var path = String(itemId || 'item').split(':').pop().replace(/[_.-]+/g, ' ');
  var words = path.split(/\s+/);
  for (var i = 0; i < words.length; i++) {
    if (!words[i]) {
      continue;
    }
    words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);
  }
  return words.join(' ') || String(itemId || 'item');
}

function cuniculumInfoJsonText(component) {
  if (!component) {
    return '';
  }
  if (typeof component === 'string') {
    return component;
  }
  var text = '';
  try { text += component.text || ''; } catch (ignored) { }
  try { text += component.translate || ''; } catch (ignored) { }
  try {
    var extra = component.extra || component.with || component.siblings || [];
    for (var i = 0; i < extra.length; i++) {
      text += cuniculumInfoJsonText(extra[i]);
    }
  } catch (ignoredExtra) {
  }
  return String(text || '').trim();
}

function cuniculumInfoParseCustomName(raw) {
  var text = String(raw || '');
  var customMatch = text.match(/custom_name='([^']+)'/i) || text.match(/custom_name=\\\"([^\\\"]+)\\\"/i);
  if (customMatch) {
    try {
      var parsed = JSON.parse(customMatch[1].replace(/\\"/g, '"'));
      var parsedText = cuniculumInfoJsonText(parsed);
      if (parsedText && parsedText.length <= 80 && parsedText.indexOf('item.') !== 0) {
        return parsedText;
      }
    } catch (ignoredJson) {
      var plain = customMatch[1].replace(/[{}"']/g, '').replace(/text:/i, '').trim();
      if (plain && plain.length <= 80) {
        return plain;
      }
    }
  }

  var literalMatches = text.match(/literal\{([^{}]{1,80})\}/g);
  if (literalMatches && literalMatches.length) {
    var last = literalMatches[literalMatches.length - 1].replace(/^literal\{|\}$/g, '').trim();
    if (last && last.indexOf('item.') !== 0) {
      return last;
    }
  }

  return '';
}

function cuniculumInfoCustomName(stack) {
  var rawValues = [];
  try { rawValues.push(stack.toString()); } catch (ignored) { }
  try { rawValues.push(stack.displayName); } catch (ignoredDisplay) { }
  try { rawValues.push(stack.hoverName); } catch (ignoredHover) { }
  try { rawValues.push(stack.getDisplayName()); } catch (ignoredGetDisplay) { }
  try { rawValues.push(stack.getHoverName()); } catch (ignoredGetHover) { }

  for (var i = 0; i < rawValues.length; i++) {
    var customName = cuniculumInfoParseCustomName(rawValues[i]);
    if (customName) {
      return customName;
    }
  }

  return '';
}

function cuniculumInfoStackLabel(stack, itemId) {
  var customName = cuniculumInfoCustomName(stack);
  if (customName) {
    return customName;
  }

  return cuniculumInfoShortItemName(itemId);
}

function cuniculumInfoRoman(value) {
  var romans = ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'];
  var number = Math.max(1, Math.floor(Number(value || 1)));
  return number < romans.length ? romans[number] : String(number);
}

function cuniculumInfoPrettyId(id) {
  return cuniculumInfoShortItemName(String(id || '').split(':').pop());
}

function cuniculumInfoEnchantName(id) {
  var names = {
    'minecraft:sharpness': 'Filo',
    'minecraft:smite': 'Castigo',
    'minecraft:bane_of_arthropods': 'Perdicion de los artropodos',
    'minecraft:knockback': 'Empuje',
    'minecraft:fire_aspect': 'Aspecto igneo',
    'minecraft:looting': 'Botin',
    'minecraft:sweeping_edge': 'Filo arrasador',
    'minecraft:efficiency': 'Eficiencia',
    'minecraft:fortune': 'Fortuna',
    'minecraft:silk_touch': 'Toque de seda',
    'minecraft:unbreaking': 'Irrompibilidad',
    'minecraft:mending': 'Reparacion',
    'minecraft:power': 'Poder',
    'minecraft:punch': 'Retroceso',
    'minecraft:flame': 'Llama',
    'minecraft:infinity': 'Infinidad',
    'minecraft:quick_charge': 'Carga rapida',
    'minecraft:piercing': 'Perforacion',
    'minecraft:multishot': 'Multidisparo',
    'minecraft:protection': 'Proteccion',
    'minecraft:projectile_protection': 'Proteccion contra proyectiles',
    'minecraft:blast_protection': 'Proteccion contra explosiones',
    'minecraft:fire_protection': 'Proteccion contra el fuego',
    'minecraft:thorns': 'Espinas',
    'minecraft:feather_falling': 'Caida de pluma',
    'extraspellattributes:warding': 'Defensa magica'
  };
  return names[id] || cuniculumInfoShortItemName(id);
}

function cuniculumInfoEnchantMap(stack) {
  var raw = '';
  try { raw += ' ' + stack.toString(); } catch (ignored) { }
  try { raw += ' ' + stack.components; } catch (ignoredComponents) { }
  try { raw += ' ' + stack.enchantments; } catch (ignoredEnchantments) { }
  var map = {};

  try {
    var enchants = stack.enchantments;
    for (var key in enchants) {
      var level = Math.max(1, Math.floor(Number(enchants[key] || 1)));
      if (String(key || '').indexOf(':') > 0) {
        map[String(key).toLowerCase()] = level;
      }
    }
  } catch (ignoredObject) {
  }

  try {
    var entryIterator = stack.enchantments.entrySet().iterator();
    while (entryIterator.hasNext()) {
      var entry = entryIterator.next();
      var entryKey = String(entry.getKey ? entry.getKey() : entry.key || '').toLowerCase();
      var entryValue = Math.max(1, Math.floor(Number(entry.getValue ? entry.getValue() : entry.value || 1)));
      if (entryKey.indexOf(':') > 0) {
        map[entryKey] = entryValue;
      }
    }
  } catch (ignoredJavaMap) {
  }

  var patterns = [
    /"([a-z0-9_.-]+:[a-z0-9_./-]+)"\s*[:=]\s*([0-9]+)/gi,
    /([a-z0-9_.-]+:[a-z0-9_./-]+)\s*(?:=>|[:=])\s*([0-9]+)/gi,
    /id\s*[:=]\s*"?([a-z0-9_.-]+:[a-z0-9_./-]+)"?[^\\n\\r{}\\[\\]]{0,60}(?:lvl|level)\s*[:=]\s*([0-9]+)/gi
  ];
  for (var p = 0; p < patterns.length; p++) {
    var regex = patterns[p];
    var match = null;
    while ((match = regex.exec(raw)) !== null) {
      var id = String(match[1] || '').toLowerCase();
      var level = Math.max(1, Math.floor(Number(match[2] || 1)));
      if (!id || id.indexOf(':') < 0) {
        continue;
      }
      if (id.indexOf('attribute') >= 0 || id.indexOf('custom_name') >= 0 || id.indexOf('damage') >= 0 || id.indexOf('rarity') >= 0 || id.indexOf('repair_cost') >= 0) {
        continue;
      }
      if (id.indexOf('minecraft:') !== 0 && id.indexOf('extraspellattributes:') !== 0 && id.indexOf('spell') < 0 && id.indexOf('enchant') < 0) {
        continue;
      }
      map[id] = Math.max(map[id] || 0, level);
    }
  }

  return map;
}

function cuniculumInfoEnchantLines(stack) {
  var map = cuniculumInfoEnchantMap(stack);
  var lines = [];
  for (var id in map) {
    lines.push('- ' + cuniculumInfoEnchantName(id) + ' ' + cuniculumInfoRoman(map[id]));
  }
  return lines;
}

function cuniculumInfoShowItemHover(stack, itemId, count, label) {
  var contents = {
    id: itemId,
    count: count
  };
  var components = {};
  var customName = cuniculumInfoCustomName(stack);
  if (customName) {
    components['minecraft:custom_name'] = JSON.stringify({ text: customName, italic: false });
  }
  var enchantMap = cuniculumInfoEnchantMap(stack);
  var hasEnchant = false;
  for (var enchantId in enchantMap) {
    hasEnchant = true;
    break;
  }
  if (hasEnchant) {
    components['minecraft:enchantments'] = {
      levels: enchantMap,
      show_in_tooltip: true
    };
  }
  var hasComponents = false;
  for (var key in components) {
    hasComponents = true;
    break;
  }
  if (hasComponents) {
    contents.components = components;
  }

  return {
    action: 'show_item',
    contents: contents
  };
}

function cuniculumInfoItemHover(stack, itemId, count, label) {
  var lines = [
    label,
    'ID: ' + itemId,
    'Cantidad: ' + count
  ];
  var enchants = cuniculumInfoEnchantLines(stack);
  if (enchants.length) {
    lines.push('Encantamientos:');
    for (var i = 0; i < enchants.length; i++) {
      lines.push(enchants[i]);
    }
  }
  return { text: lines.join('\n'), color: 'gray', italic: false };
}

function cuniculumInfoMainHand(player) {
  var values = [];
  try { values.push(player.mainHandItem); } catch (ignored) { }
  try { values.push(player.getMainHandItem()); } catch (ignored) { }
  try { values.push(player.getInventory().getSelected()); } catch (ignored) { }
  for (var i = 0; i < values.length; i++) {
    var id = cuniculumInfoStackId(values[i]);
    if (id) {
      return values[i];
    }
  }
  return null;
}

function cuniculumInfoShowHeld(ctx) {
  var server = cuniculumInfoServer(ctx);
  var playerName = cuniculumInfoPlayerName(ctx);
  var player = null;
  try { player = ctx.getSource().getPlayer(); } catch (ignored) { }
  if (!server || !playerName || !player) {
    return 0;
  }

  var stack = cuniculumInfoMainHand(player);
  var itemId = cuniculumInfoStackId(stack);
  if (!itemId) {
    server.runCommandSilent('tellraw ' + playerName + ' ' + JSON.stringify({ text: '[CUNICULUM] Debes tener un item en la mano para usar /mostrar.', color: 'red', italic: false }));
    return 0;
  }

  var count = cuniculumInfoStackCount(stack);
  var label = cuniculumInfoStackLabel(stack, itemId);
  var payload = [
    { text: '[', color: 'gray', italic: false },
    { text: playerName, color: 'yellow', italic: false },
    { text: '] muestra ', color: 'gray', italic: false },
    {
      text: '[' + label + (count > 1 ? ' x' + count : '') + ']',
      color: 'aqua',
      italic: false,
      hoverEvent: cuniculumInfoShowItemHover(stack, itemId, count, label)
    }
  ];
  server.runCommandSilent('tellraw @a ' + JSON.stringify(payload));
  return 1;
}

function cuniculumInfoRun(ctx, key, rawPage) {
  var server = cuniculumInfoServer(ctx);
  var playerName = cuniculumInfoPlayerName(ctx);
  var pages = CUNICULUM_INFO_PAGES[key] || CUNICULUM_INFO_PAGES.ayuda;
  var page = cuniculumInfoPage(rawPage, pages.length);
  if (!server) {
    return 0;
  }

  var lines = pages[page - 1];
  for (var i = 0; i < lines.length; i++) {
    cuniculumInfoTell(server, playerName, lines[i][0], lines[i][1], lines[i][2]);
  }

  return 1;
}

ServerEvents.commandRegistry(event => {
  var commands = event.commands;
  var args = event.arguments;
  var pageArg = () => commands.argument('pagina', args.STRING.create(event));

  event.register(commands.literal('reglas')
    .executes(ctx => cuniculumInfoRun(ctx, 'reglas', '1'))
    .then(pageArg().executes(ctx => cuniculumInfoRun(ctx, 'reglas', args.STRING.getResult(ctx, 'pagina')))));

  event.register(commands.literal('comandos')
    .executes(ctx => cuniculumInfoRun(ctx, 'comandos', '1'))
    .then(pageArg().executes(ctx => cuniculumInfoRun(ctx, 'comandos', args.STRING.getResult(ctx, 'pagina')))));

  event.register(commands.literal('ayuda')
    .executes(ctx => cuniculumInfoRun(ctx, 'ayuda', '1'))
    .then(pageArg().executes(ctx => cuniculumInfoRun(ctx, 'ayuda', args.STRING.getResult(ctx, 'pagina')))));

  event.register(commands.literal('discord')
    .executes(ctx => cuniculumInfoRun(ctx, 'discord', '1')));

  event.register(commands.literal('mostrar')
    .executes(ctx => cuniculumInfoShowHeld(ctx)));

  event.register(commands.literal('equipo')
    .executes(ctx => cuniculumInfoRun(ctx, 'equipo', '1')));

  event.register(commands.literal('team')
    .executes(ctx => cuniculumInfoRun(ctx, 'equipo', '1')));

  event.register(commands.literal('teams')
    .executes(ctx => cuniculumInfoRun(ctx, 'equipo', '1')));

  event.register(commands.literal('claims')
    .executes(ctx => cuniculumInfoRun(ctx, 'claims', '1')));

  event.register(commands.literal('chunks')
    .executes(ctx => cuniculumInfoRun(ctx, 'claims', '1')));
});

