Jump to content

MediaWiki:Common.js

From EthernalRO Wiki
Revision as of 16:09, 26 January 2026 by Slicer (talk | contribs)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
var tocImgHid = "/w/skins/common/images/Arr_r.png";
var tocImgSho = "/w/skins/common/images/Arr_d.png";

function tocTree() {
  mw.util.addCSS(
    "a.toctogHidden img, a.toctogShown img, a.toctogNull img {width:12px;height:12px;} #toc li a {padding-right:3px;} a.toctogNull img {visibility:hidden;}"
  );

  var toc = document.getElementById("toc");
  if (!toc) return;
  var li = toc.getElementsByTagName("li");
  for (var i = 0; i < li.length; i++) {
    var cul = li[i].getElementsByTagName("ul");
    var a = document.createElement("a");
    if (cul.length == 0) {
      a.setAttribute("class", "toctogNull");
    } else {
      a.setAttribute("class", "toctogShown");
      a.setAttribute("id", "toctog-a-" + i);
      a.setAttribute("href", 'javascript:tocTreeToggle("' + i + '");');
    }
    var img = document.createElement("img");
    img.setAttribute("src", tocImgHid);
    img.setAttribute("id", "toctog-i-" + i);
    a.appendChild(img);
    li[i].insertBefore(a, li[i].firstChild);
    if (cul.length != 0) tocTreeToggle(i);
  }
}
$(tocTree);

function tocTreeToggle(id) {
  var a = document.getElementById("toctog-a-" + id);
  var img = document.getElementById("toctog-i-" + id);
  var cul = a.parentNode.getElementsByTagName("ul");
  var disp;
  if (a.getAttribute("class") == "toctogShown") {
    disp = "none";
    a.setAttribute("class", "toctogHidden");
    img.setAttribute("src", tocImgHid);
  } else {
    disp = "block";
    a.setAttribute("class", "toctogShown");
    img.setAttribute("src", tocImgSho);
  }
  for (var j = 0; j < cul.length; j++) {
    if (cul[j].parentNode == a.parentNode) cul[j].style.display = disp;
  }
}

/**
 * Collapsible tables *********************************************************
 *
 * Description: Allows tables to be collapsed, showing only the header. See
 *              [[Wikipedia:NavFrame]].
 * Maintainers: [[User:R. Koot]]
 */

var autoCollapse = 2;
var collapseCaption = "hide";
var expandCaption = "show";

window.collapseTable = function (tableIndex) {
  var Button = document.getElementById("collapseButton" + tableIndex);
  var Table = document.getElementById("collapsibleTable" + tableIndex);

  if (!Table || !Button) {
    return false;
  }

  var Rows = Table.rows;
  var i;

  if (Button.firstChild.data === collapseCaption) {
    for (i = 1; i < Rows.length; i++) {
      Rows[i].style.display = "none";
    }
    Button.firstChild.data = expandCaption;
  } else {
    for (i = 1; i < Rows.length; i++) {
      Rows[i].style.display = Rows[0].style.display;
    }
    Button.firstChild.data = collapseCaption;
  }
};

function createCollapseButtons() {
  var tableIndex = 0;
  var NavigationBoxes = {};
  var Tables = document.getElementsByTagName("table");
  var i;

  function handleButtonLink(index, e) {
    window.collapseTable(index);
    e.preventDefault();
  }

  for (i = 0; i < Tables.length; i++) {
    if ($(Tables[i]).hasClass("collapsible")) {
      /* only add button and increment count if there is a header row to work with */
      var HeaderRow = Tables[i].getElementsByTagName("tr")[0];
      if (!HeaderRow) continue;
      var Header = HeaderRow.getElementsByTagName("th")[0];
      if (!Header) continue;

      NavigationBoxes[tableIndex] = Tables[i];
      Tables[i].setAttribute("id", "collapsibleTable" + tableIndex);

      var Button = document.createElement("span");
      var ButtonLink = document.createElement("a");
      var ButtonText = document.createTextNode(collapseCaption);

      Button.className =
        "collapseButton"; /* Styles are declared in Common.css */

      ButtonLink.style.color = Header.style.color;
      ButtonLink.setAttribute("id", "collapseButton" + tableIndex);
      ButtonLink.setAttribute("href", "#");
      $(ButtonLink).on(
        "click",
        $.proxy(handleButtonLink, ButtonLink, tableIndex)
      );
      ButtonLink.appendChild(ButtonText);

      Button.appendChild(document.createTextNode("["));
      Button.appendChild(ButtonLink);
      Button.appendChild(document.createTextNode("]"));

      Header.insertBefore(Button, Header.firstChild);
      tableIndex++;
    }
  }

  for (i = 0; i < tableIndex; i++) {
    if (
      $(NavigationBoxes[i]).hasClass("collapsed") ||
      (tableIndex >= autoCollapse &&
        $(NavigationBoxes[i]).hasClass("autocollapse"))
    ) {
      window.collapseTable(i);
    } else if ($(NavigationBoxes[i]).hasClass("innercollapse")) {
      var element = NavigationBoxes[i];
      while ((element = element.parentNode)) {
        if ($(element).hasClass("outercollapse")) {
          window.collapseTable(i);
          break;
        }
      }
    }
  }
}

$(createCollapseButtons);

/** Test if an element has a certain class **************************************
 *
 * Description: Uses regular expressions and caching for better performance.
 * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
 */

var hasClass = (function () {
  var reCache = {};
  return function (element, className) {
    return (
      reCache[className]
        ? reCache[className]
        : (reCache[className] = new RegExp(
            "(?:\\s|^)" + className + "(?:\\s|$)"
          ))
    ).test(element.className);
  };
})();

/** Hideable notes  *********************************************************
 * This is based off of code from Wikipedia's Common.js (http://en.wikipedia.org/wiki/MediaWiki:Common.js)
 */

function showNotes(spanIndex) {
  var Button = document.getElementById("showNoteLink" + spanIndex);
  var Span = document.getElementById("showNotes" + spanIndex);

  if (!Span || !Button) {
    return false;
  }

  if (Button.firstChild.data == "[show]") {
    Span.style.display = "inline";
    Button.firstChild.data = " [hide]";
  } else {
    Span.style.display = "none";
    Button.firstChild.data = "[show]";
  }
}

function createShowNotesLinks() {
  var spanIndex = 0;
  var Spans = document.getElementsByTagName("span");
  var CurrentSpan = new Object();

  for (var i = 0; i < Spans.length; i++) {
    if (hasClass(Spans[i], "hiddenNotes")) {
      CurrentSpan = Spans[i];
      CurrentSpan.setAttribute("id", "showNotes" + spanIndex);

      var Button = document.createElement("span");
      var ButtonLink = document.createElement("a");
      var ButtonText = document.createTextNode("[show]");

      ButtonLink.setAttribute("id", "showNoteLink" + spanIndex);
      ButtonLink.setAttribute("href", "javascript:");
      addHandler(
        ButtonLink,
        "click",
        new Function(
          "evt",
          "showNotes(" + spanIndex + " ); return killEvt( evt );"
        )
      );
      ButtonLink.appendChild(ButtonText);

      Button.appendChild(document.createTextNode(" "));
      Button.appendChild(ButtonLink);

      CurrentSpan.parentNode.insertBefore(Button, CurrentSpan.nextSibling);
      CurrentSpan.style.display = "none";

      spanIndex++;
    }
  }
}

$(createShowNotesLinks);

/* Any JavaScript here will be loaded for all users on every page load. */

/* Test if an element has a certain class **************************************
 * Note: this is straight out of Wikipedia's Common.js (http://en.wikipedia.org/wiki/MediaWiki:Common.js)
 */

var hasClass = (function () {
  var reCache = {};
  return function (element, className) {
    return (
      reCache[className]
        ? reCache[className]
        : (reCache[className] = new RegExp(
            "(?:\\s|^)" + className + "(?:\\s|$)"
          ))
    ).test(element.className);
  };
})();

// Navi Copy JQuery Code by Kaddy!
$(document).ready(
  $(".navi-copy").each(function (index, element) {
    if ($("#navi-copy-textarea").attr("exists") != "true") {
      txtdiv =
        '<textarea style="height:1px;width:1px; position:absolute;left:-1000px;" id="navi-copy-textarea" exists="true">Filler Text</textarea><style>.navi-copy-text { cursor:pointer; color:#2899e8; padding:1px; display:inline-block; } .navi-copy-text:hover { color:#c1a1f1; } .navi-copied { text-align:center; border:1px dotted #2899e8; border-radius:3px; color:#2899e8; display:inline-block; } .navi-copy {  display:inline-block; } </style>';
      $("body").append(txtdiv);
    }
    var map = $(element).children().get(0).innerHTML;
    var x = $(element).children().get(1).innerHTML;
    var y = $(element).children().get(2).innerHTML;
    var newhtml =
      '<div class="navi-copy-text" title="Click here to copy to the clipboard, then paste in game" onclick="CopyNaviLink(this, \'' +
      map +
      "','" +
      x +
      "','" +
      y +
      "');\">(" +
      map +
      " " +
      x +
      ", " +
      y +
      ')</div><div class="navi-copied" style="display:none;">Paste ingame</div>';
    $(element).html(newhtml);
  })
);
function CopyNaviLink(ele, map, x, y) {
  element = $(ele);
  sibling = element.siblings();
  width = element.width();
  height = element.height() + 0;
  sibling.css("width", width);
  sibling.css("height", height);
  element.css("display", "none");
  sibling.css("display", "inline-block");
  setTimeout(function () {
    sibling.fadeOut().delay(300).css("display", "none");
    element.css("display", "inline-block");
  }, 1400);
  var ClipBoardText = "/navi " + map + " " + x + "/" + y;
  var textarea = document.getElementById("navi-copy-textarea");
  $("#navi-copy-textarea").text(ClipBoardText);
  $("#navi-copy-textarea").select();
  document.execCommand("copy");
}

/* NaviMap mouseover preview, original credit: Hazyforest @ hazyforest.com */

Navi_Map_JS = {
  abbey01: [400, 400],
  abbey02: [300, 300],
  abbey03: [240, 240],
  abyss_01: [300, 300],
  abyss_02: [300, 300],
  abyss_03: [200, 200],
  abyss_04: [340, 340],
  air_if: [200, 200],
  airplane: [300, 300],
  airplane_01: [300, 300],
  airport: [300, 120],
  alb2trea: [140, 140],
  alb_ship: [200, 200],
  alberta: [280, 280],
  alberta_in: [200, 200],
  alde_alche: [200, 200],
  alde_dun01: [320, 320],
  alde_dun02: [300, 300],
  alde_dun03: [300, 300],
  alde_dun04: [300, 300],
  alde_gld: [320, 320],
  aldeba_in: [260, 260],
  aldebaran: [280, 280],
  ama_dun01: [240, 240],
  ama_dun02: [240, 240],
  ama_dun03: [240, 240],
  ama_fild01: [400, 400],
  ama_in01: [200, 200],
  ama_in02: [240, 200],
  ama_test: [100, 132],
  amatsu: [316, 316],
  amicitia1: [300, 300],
  amicitia2: [300, 300],
  ant_d02_i: [300, 300],
  anthell01: [300, 300],
  anthell02: [300, 300],
  aru_gld: [400, 400],
  arug_que01: [200, 200],
  ayo_dun01: [300, 300],
  ayo_dun02: [300, 300],
  ayo_fild01: [360, 360],
  ayo_fild02: [360, 300],
  ayo_in01: [200, 200],
  ayo_in02: [200, 200],
  ayothaya: [320, 320],
  ba_2whs01: [320, 320],
  ba_2whs02: [360, 360],
  ba_bath: [320, 320],
  ba_chess: [48, 48],
  ba_go: [104, 100],
  ba_in01: [400, 400],
  ba_lib: [320, 320],
  ba_lost: [320, 360],
  ba_maison: [400, 400],
  ba_pw01: [300, 300],
  ba_pw02: [300, 300],
  ba_pw03: [300, 300],
  beach_dun: [300, 300],
  beach_dun2: [300, 300],
  beach_dun3: [300, 300],
  bif_fild01: [400, 400],
  bif_fild02: [400, 400],
  bl_death: [400, 400],
  bl_grass: [400, 400],
  bl_ice: [300, 300],
  bl_lava: [300, 300],
  bra_dun01: [240, 240],
  bra_dun02: [300, 300],
  bra_fild01: [400, 400],
  bra_in01: [220, 200],
  brasilis: [400, 400],
  c_tower1: [400, 400],
  c_tower2: [300, 300],
  c_tower2_: [300, 300],
  c_tower3: [260, 260],
  c_tower3_: [260, 260],
  c_tower4: [216, 216],
  cave: [200, 200],
  clock_01: [300, 300],
  cmd_fild01: [400, 400],
  cmd_fild02: [400, 400],
  cmd_fild03: [400, 400],
  cmd_fild04: [400, 400],
  cmd_fild06: [400, 400],
  cmd_fild07: [400, 400],
  cmd_fild08: [400, 400],
  cmd_fild09: [400, 400],
  cmd_in01: [200, 200],
  cmd_in02: [240, 240],
  com_d02_i: [300, 300],
  comodo: [360, 380],
  conch_in: [200, 120],
  dali: [200, 200],
  dali02: [200, 200],
  dew_dun01: [360, 360],
  dew_dun02: [320, 320],
  dew_fild01: [400, 400],
  dew_in01: [60, 60],
  dewata: [340, 340],
  dic_dun01: [400, 256],
  dic_dun02: [240, 240],
  dic_dun03: [240, 240],
  dic_fild01: [300, 300],
  dic_fild02: [300, 400],
  dic_in01: [400, 300],
  dicastes01: [400, 400],
  dicastes02: [240, 360],
  e_tower: [300, 300],
  ecl_fild01: [320, 360],
  ecl_hub01: [200, 180],
  ecl_in01: [100, 120],
  ecl_in02: [200, 140],
  ecl_in03: [280, 116],
  ecl_tdun01: [120, 120],
  ecl_tdun02: [120, 100],
  ecl_tdun03: [100, 100],
  ecl_tdun04: [60, 60],
  eclage: [400, 400],
  ein_d02_i: [300, 300],
  ein_dun01: [300, 300],
  ein_dun02: [300, 300],
  ein_dun03: [300, 300],
  ein_fild01: [400, 400],
  ein_fild03: [400, 400],
  ein_fild04: [400, 400],
  ein_fild05: [400, 400],
  ein_fild06: [400, 400],
  ein_fild07: [400, 400],
  ein_fild08: [400, 400],
  ein_fild09: [400, 400],
  ein_in01: [300, 300],
  einbech: [300, 300],
  einbroch: [340, 380],
  gef_d01_i: [300, 300],
  gef_dun00: [200, 200],
  gef_dun01: [300, 300],
  gef_dun02: [260, 260],
  gef_dun03: [240, 240],
  gef_fild00: [400, 400],
  gef_fild01: [400, 400],
  gef_fild02: [400, 400],
  gef_fild03: [400, 400],
  gef_fild04: [380, 380],
  gef_fild05: [380, 380],
  gef_fild06: [400, 400],
  gef_fild07: [380, 380],
  gef_fild08: [380, 380],
  gef_fild09: [400, 400],
  gef_fild10: [400, 400],
  gef_fild11: [400, 400],
  gef_fild13: [400, 400],
  gef_tower: [200, 200],
  gefenia01: [300, 300],
  gefenia02: [300, 300],
  gefenia03: [300, 300],
  gefenia04: [300, 300],
  geffen: [240, 240],
  geffen_in: [200, 200],
  gl_cas01: [400, 400],
  gl_cas01_: [400, 400],
  gl_cas02: [200, 200],
  gl_cas02_: [200, 200],
  gl_church: [312, 312],
  gl_chyard: [300, 300],
  gl_chyard_: [300, 300],
  gl_dun01: [300, 300],
  gl_dun02: [300, 300],
  gl_in01: [200, 200],
  gl_knt01: [300, 300],
  gl_knt02: [300, 300],
  gl_prison: [200, 200],
  gl_prison1: [200, 200],
  gl_sew01: [280, 280],
  gl_sew02: [316, 316],
  gl_sew03: [340, 300],
  gl_sew04: [300, 300],
  gl_step: [240, 240],
  glast_01: [400, 400],
  gon_dun01: [300, 300],
  gon_dun02: [300, 300],
  gon_dun03: [240, 300],
  gon_fild01: [400, 400],
  gon_in: [200, 120],
  gonryun: [300, 300],
  grademk: [200, 200],
  gw_fild01: [400, 400],
  gw_fild02: [400, 400],
  har_in01: [120, 120],
  harboro1: [400, 360],
  harboro2: [360, 340],
  hu_fild01: [400, 400],
  hu_fild02: [400, 400],
  hu_fild03: [400, 400],
  hu_fild04: [400, 400],
  hu_fild05: [400, 400],
  hu_fild06: [400, 400],
  hu_in01: [400, 400],
  hugel: [268, 280],
  icas_in: [280, 320],
  ice_d03_i: [300, 300],
  ice_dun01: [300, 300],
  ice_dun02: [300, 300],
  ice_dun03: [300, 300],
  ice_dun04: [200, 200],
  icecastle: [300, 300],
  in_moc_16: [200, 200],
  in_orcs01: [200, 200],
  in_rogue: [400, 400],
  in_sphinx1: [300, 300],
  in_sphinx2: [300, 300],
  in_sphinx3: [240, 240],
  in_sphinx4: [240, 240],
  in_sphinx5: [200, 200],
  int_land: [140, 140],
  itemmall: [200, 100],
  iz_ac01: [220, 200],
  iz_ac02: [240, 240],
  iz_d04_i: [280, 300],
  iz_d05_i: [280, 280],
  iz_dun00: [400, 400],
  iz_dun01: [300, 300],
  iz_dun02: [400, 400],
  iz_dun03: [300, 300],
  iz_dun04: [280, 300],
  iz_dun05: [280, 280],
  iz_int: [80, 80],
  izlu2dun: [216, 232],
  izlude: [268, 300],
  izlude_in: [200, 200],
  jawaii: [340, 360],
  jawaii_in: [200, 140],
  job3_gen01: [100, 100],
  job3_guil01: [160, 100],
  job3_rune01: [160, 100],
  job4_bio: [64, 60],
  job4_mag: [240, 240],
  job4_tro: [100, 100],
  job_duncer: [140, 172],
  jor_ab01: [300, 300],
  jor_ab02: [300, 300],
  jor_back1: [400, 400],
  jor_back2: [400, 400],
  jor_back3: [400, 400],
  jor_dun01: [300, 300],
  jor_dun02: [300, 300],
  jor_dun03: [120, 120],
  jor_nest: [300, 300],
  jor_que: [300, 300],
  jor_tail: [320, 300],
  jupe_area1: [164, 300],
  jupe_area2: [164, 300],
  jupe_cave: [232, 100],
  jupe_core: [300, 300],
  jupe_core2: [300, 300],
  jupe_ele: [100, 124],
  jupe_ele_r: [100, 160],
  jupe_gate: [100, 200],
  juperos_01: [300, 300],
  juperos_02: [300, 300],
  kh_dun01: [240, 240],
  kh_dun02: [240, 240],
  kh_mansion: [100, 100],
  kh_rossi: [300, 300],
  kh_school: [200, 200],
  kh_vila: [200, 200],
  lasa_dun01: [220, 220],
  lasa_dun02: [220, 220],
  lasa_dun03: [320, 320],
  lasa_dun_q: [320, 320],
  lasa_fild01: [400, 400],
  lasa_fild02: [400, 400],
  lasa_in01: [200, 120],
  lasa_sea: [220, 220],
  lasagna: [400, 400],
  lhz_airport: [300, 120],
  lhz_d_n2: [96, 64],
  lhz_dun01: [300, 300],
  lhz_dun02: [300, 300],
  lhz_dun03: [280, 280],
  lhz_dun04: [300, 300],
  lhz_dun_n: [280, 280],
  lhz_fild01: [400, 400],
  lhz_fild02: [400, 400],
  lhz_fild03: [400, 400],
  lhz_in01: [300, 280],
  lhz_in02: [300, 300],
  lhz_in03: [280, 280],
  lighthalzen: [400, 360],
  lou_dun01: [300, 300],
  lou_dun02: [300, 300],
  lou_dun03: [300, 300],
  lou_fild01: [400, 400],
  lou_in01: [200, 200],
  lou_in02: [300, 200],
  louyang: [360, 360],
  ma_dun01: [200, 200],
  ma_fild01: [400, 400],
  ma_fild02: [400, 400],
  ma_in01: [200, 200],
  ma_scene01: [340, 360],
  mag_dun01: [260, 260],
  mag_dun02: [260, 260],
  mag_dun03: [260, 260],
  mal_dun01: [260, 260],
  mal_in01: [200, 240],
  mal_in02: [200, 120],
  malangdo: [360, 380],
  malaya: [400, 400],
  man_fild01: [400, 400],
  man_fild02: [400, 400],
  man_fild03: [400, 400],
  man_in01: [400, 300],
  manuk: [400, 400],
  mid_camp: [400, 400],
  mid_campin: [400, 200],
  mjo_dun01: [280, 340],
  mjo_dun02: [400, 400],
  mjo_dun03: [340, 280],
  mjolnir_01: [400, 400],
  mjolnir_02: [400, 400],
  mjolnir_03: [400, 400],
  mjolnir_04: [400, 400],
  mjolnir_05: [400, 400],
  mjolnir_06: [400, 400],
  mjolnir_07: [400, 400],
  mjolnir_08: [400, 400],
  mjolnir_09: [400, 400],
  mjolnir_10: [400, 400],
  mjolnir_11: [400, 400],
  mjolnir_12: [400, 400],
  moc_fild01: [400, 400],
  moc_fild02: [400, 360],
  moc_fild03: [320, 360],
  moc_fild07: [400, 400],
  moc_fild11: [400, 400],
  moc_fild12: [320, 400],
  moc_fild13: [340, 400],
  moc_fild16: [400, 400],
  moc_fild17: [400, 400],
  moc_fild18: [400, 400],
  moc_fild19: [200, 200],
  moc_fild20: [400, 400],
  moc_fild21: [400, 400],
  moc_fild22: [400, 400],
  moc_fild22b: [400, 400],
  moc_para01: [200, 200],
  moc_pryd01: [200, 200],
  moc_pryd02: [200, 200],
  moc_pryd03: [200, 200],
  moc_pryd04: [200, 200],
  moc_pryd05: [232, 232],
  moc_pryd06: [204, 204],
  moc_prydb1: [200, 200],
  moc_prydn1: [232, 232],
  moc_prydn2: [204, 204],
  moc_ruins: [200, 200],
  monk_in: [200, 200],
  monk_test: [400, 400],
  mora: [240, 240],
  moro_cav: [100, 100],
  moro_vol: [400, 400],
  morocc: [320, 320],
  morocc_in: [200, 200],
  moscovia: [400, 400],
  mosk_dun01: [300, 300],
  mosk_dun02: [300, 300],
  mosk_dun03: [300, 300],
  mosk_fild01: [200, 200],
  mosk_fild02: [300, 300],
  mosk_in: [300, 300],
  nameless_i: [340, 340],
  nameless_in: [200, 200],
  nameless_n: [340, 340],
  nif_dun01: [300, 300],
  nif_dun02: [300, 300],
  nif_fild01: [400, 400],
  nif_fild02: [400, 400],
  nif_in: [200, 200],
  niflheim: [400, 300],
  nyd_dun01: [300, 300],
  nyd_dun02: [260, 400],
  odin_past: [400, 400],
  odin_tem01: [400, 400],
  odin_tem02: [400, 400],
  odin_tem03: [400, 400],
  orcsdun01: [200, 200],
  orcsdun02: [200, 200],
  "ordeal_3-1": [300, 300],
  "ordeal_3-2": [308, 308],
  "ordeal_3-3": [300, 300],
  "ordeal_3-4": [308, 308],
  oz_dun01: [300, 300],
  oz_dun02: [300, 300],
  paramk: [200, 200],
  pay_arche: [200, 200],
  pay_d03_i: [300, 300],
  pay_dun00: [200, 200],
  pay_dun01: [300, 300],
  pay_dun02: [300, 300],
  pay_dun03: [300, 300],
  pay_dun04: [240, 240],
  pay_fild01: [400, 400],
  pay_fild02: [300, 404],
  pay_fild03: [416, 300],
  pay_fild04: [400, 400],
  pay_fild06: [400, 400],
  pay_fild07: [400, 400],
  pay_fild08: [280, 400],
  pay_fild09: [400, 400],
  pay_fild10: [400, 400],
  pay_gld: [400, 400],
  payon: [300, 360],
  payon_in01: [200, 200],
  payon_in02: [100, 100],
  payon_in03: [200, 200],
  prontera: [312, 392],
  prt_cas: [400, 356],
  prt_cas_q: [180, 200],
  prt_church: [200, 200],
  prt_evt_in: [60, 60],
  prt_fild00: [400, 400],
  prt_fild01: [400, 400],
  prt_fild02: [400, 400],
  prt_fild03: [400, 300],
  prt_fild04: [400, 400],
  prt_fild05: [400, 400],
  prt_fild06: [380, 340],
  prt_fild07: [400, 400],
  prt_fild08: [400, 400],
  prt_fild09: [400, 400],
  prt_fild10: [360, 320],
  prt_fild11: [380, 320],
  prt_gld: [320, 320],
  prt_in: [300, 200],
  prt_lib: [160, 120],
  prt_lib_q: [160, 120],
  prt_maze01: [200, 200],
  prt_maze02: [200, 200],
  prt_maze03: [200, 200],
  prt_monk: [400, 300],
  prt_mz03_i: [200, 200],
  prt_pri00: [200, 200],
  prt_prison: [300, 300],
  prt_q: [312, 392],
  prt_sewb1: [320, 320],
  prt_sewb2: [200, 200],
  prt_sewb3: [200, 200],
  prt_sewb4: [200, 200],
  pub_cat: [200, 160],
  que_dan02: [120, 60],
  que_god01: [300, 140],
  que_job01: [160, 100],
  que_ng: [200, 200],
  que_rachel: [340, 340],
  que_swat: [360, 360],
  que_thor: [200, 100],
  que_thr: [200, 100],
  ra_fild01: [400, 400],
  ra_fild03: [400, 400],
  ra_fild04: [400, 400],
  ra_fild05: [400, 400],
  ra_fild06: [400, 400],
  ra_fild08: [400, 400],
  ra_fild10: [400, 400],
  ra_fild11: [400, 400],
  ra_fild12: [400, 400],
  ra_in01: [400, 400],
  ra_san01: [280, 280],
  ra_san02: [300, 300],
  ra_san03: [300, 300],
  ra_san04: [240, 240],
  que_san04: [240, 240],
  ra_san05: [300, 300],
  ra_temin: [340, 340],
  ra_temple: [240, 240],
  ra_temsky: [200, 200],
  rachel: [300, 300],
  rag_fes: [400, 400],
  rag_fes_a: [400, 400],
  rebel_in: [220, 100],
  rgsr_in: [260, 260],
  rockmi1: [400, 400],
  rockmi2: [140, 140],
  rockrdg1: [400, 400],
  rockrdg2: [400, 400],
  s_atelier: [200, 140],
  sch_gld: [400, 400],
  slabw01: [300, 180],
  sp_cor: [300, 320],
  sp_os: [400, 400],
  sp_rudus: [400, 400],
  sp_rudus2: [400, 400],
  sp_rudus3: [400, 400],
  sp_rudus4: [400, 400],
  spl_fild01: [400, 400],
  spl_fild02: [400, 400],
  spl_fild03: [400, 400],
  spl_in01: [400, 400],
  spl_in02: [300, 300],
  splendide: [400, 400],
  star_frst: [200, 200],
  star_in: [200, 200],
  tha_scene01: [400, 400],
  tha_t01: [300, 300],
  tha_t02: [300, 300],
  tha_t03: [280, 280],
  tha_t04: [280, 280],
  tha_t05: [240, 240],
  tha_t06: [240, 240],
  tha_t07: [140, 200],
  tha_t08: [140, 200],
  tha_t09: [180, 180],
  tha_t10: [180, 180],
  tha_t11: [180, 180],
  tha_t12: [180, 180],
  thana_boss: [280, 280],
  thana_step: [240, 400],
  thor_camp: [300, 360],
  thor_v01: [300, 300],
  thor_v02: [240, 240],
  thor_v03: [300, 300],
  tra_fild: [200, 200],
  treasure01: [200, 200],
  treasure02: [200, 200],
  treasure_n1: [200, 200],
  treasure_n2: [200, 200],
  tur_d03_i: [248, 248],
  tur_d04_i: [200, 200],
  tur_dun01: [300, 300],
  tur_dun02: [300, 300],
  tur_dun03: [248, 248],
  tur_dun04: [200, 200],
  tur_dun05: [100, 100],
  tur_dun06: [100, 100],
  turbo_room: [200, 200],
  um_fild01: [400, 400],
  um_fild02: [400, 400],
  um_fild03: [400, 400],
  um_fild04: [400, 400],
  um_in: [200, 140],
  umbala: [280, 344],
  un_bk_q: [400, 400],
  un_bunker: [400, 400],
  un_myst: [400, 220],
  ve_fild01: [400, 400],
  ve_fild02: [400, 400],
  ve_fild03: [400, 400],
  ve_fild04: [400, 400],
  ve_fild05: [400, 400],
  ve_fild06: [400, 400],
  ve_fild07: [400, 400],
  ve_in: [400, 400],
  ve_in02: [100, 100],
  veins: [400, 400],
  ver_eju: [300, 300],
  ver_tunn: [120, 100],
  verus01: [300, 300],
  verus02: [300, 300],
  verus03: [280, 280],
  verus04: [280, 280],
  wolfvill: [300, 300],
  xmas: [300, 360],
  xmas_dun01: [260, 260],
  xmas_dun02: [260, 260],
  xmas_fild01: [280, 280],
  xmas_in: [200, 200],
  x_prt_evt: [135, 135],
  y_airport: [300, 120],
  yggdrasil01: [300, 300],
  yuno: [400, 400],
  yuno_fild01: [400, 400],
  yuno_fild02: [400, 400],
  yuno_fild03: [400, 400],
  yuno_fild04: [400, 400],
  yuno_fild06: [400, 400],
  yuno_fild07: [400, 400],
  yuno_fild08: [400, 400],
  yuno_fild09: [400, 400],
  yuno_fild11: [400, 400],
  yuno_fild12: [400, 400],
  yuno_in01: [200, 200],
  yuno_in02: [200, 240],
  yuno_in03: [260, 216],
  yuno_in04: [200, 140],
  yuno_pre: [140, 140],
  "1@sara": [300, 360],
  "1@os_a": [400, 400],
  "1@bamn": [400, 400],
  "1@nyr": [240, 240],
  "2@nyr": [240, 240],
  "1@exse": [84, 94],
  "1@iwp": [400, 400],
  NULL: [300, 300],
};

function isMobile() {
  return /Mobi|Android|iPhone|iPad|iPod|IEMobile|Opera Mini/i.test(
    navigator.userAgent
  );
}

function CopyNaviLinkH(ele) {
  if (isMobile()) return;
  const element = typeof ele === "string" ? document.querySelector(ele) : ele;
  const sibling = element.parentElement.querySelector(".naviCopied");

  sibling.style.width = element.offsetWidth + "px";
  sibling.style.height = element.offsetHeight + "px";

  element.style.display = "none";
  sibling.style.display = "inline-block";

  setTimeout(() => {
    element.style.display = "inline-block";
    sibling.style.display = "none";
  }, 2000);

  const textToCopy = element.dataset.navi || "";

  if (navigator.clipboard && navigator.clipboard.writeText) {
    navigator.clipboard.writeText(textToCopy).catch((err) => {
      console.error("Failed to copy text: ", err);
    });
  } else {
    // Fallback
    const textarea = document.createElement("textarea");
    textarea.value = textToCopy;
    textarea.style.position = "fixed"; // Prevent scrolling jump
    textarea.style.top = "-9999px";
    document.body.appendChild(textarea);
    textarea.focus();
    textarea.select();
    try {
      document.execCommand("copy");
    } catch (err) {
      console.error("Fallback copy failed: ", err);
    }
    document.body.removeChild(textarea);
  }
}

function DisplayNaviMark(ele, mapName, posX, posY) {
  const element = typeof ele === "string" ? document.querySelector(ele) : ele;
  const map = element.querySelector(".naviMap");
  const dot = map.querySelector(".naviDot");

  const mapData = Navi_Map_JS[mapName] || Navi_Map_JS["NULL"] || [300, 300];
  const [mapWidth, mapHeight] = mapData;

  const hasValidMap = !!Navi_Map_JS[mapName];

  //if the map is valid and the positions aren't both -1 - this is to allow a secondary usage of this display method
  if (hasValidMap && posX != -1 && posY != -1) {
    // Position the dot only if mapName is valid
    dot.style.display = "block";
    dot.style.left = ((posX / mapWidth) * 100).toFixed(2) + "%";
    dot.style.top = (100 - (posY / mapHeight) * 100).toFixed(2) + "%";
  } else {
    dot.style.display = "none";
  }

  // Make map visible
  map.style.visibility = "visible";

  // Position map relative to the viewport
  const rect = element.getBoundingClientRect();
  const mapWidthPx = map.offsetWidth;
  const mapHeightPx = map.offsetHeight;
  const gap = 8;

  // Default: above the link
  let left = rect.left + rect.width / 2 - mapWidthPx / 2;
  let top = rect.top - mapHeightPx - gap;

  // If not enough space above, place below
  if (top < 0) {
    top = rect.bottom + gap;
  }

  // Clamp horizontally within viewport
  const minLeft = 8;
  const maxLeft = document.documentElement.clientWidth - mapWidthPx - 8;
  if (left < minLeft) left = minLeft;
  if (left > maxLeft) left = maxLeft;

  // Apply fixed positioning
  map.style.position = "fixed";
  map.style.left = left + "px";
  map.style.top = top + "px";
}

function DisplayAllNaviMarks(ele, mapName) {
  const element = typeof ele === "string" ? document.querySelector(ele) : ele;
  const map = element.querySelector(".naviMap");
  const dots = map.querySelectorAll(".naviPoiDot"); // updated selector

  const mapData = Navi_Map_JS[mapName] || Navi_Map_JS["NULL"] || [300, 300];
  const [mapWidth, mapHeight] = mapData;

  const hasValidMap = !!Navi_Map_JS[mapName];

  // Position each dot if map is valid
  dots.forEach((dot) => {
    const posX = parseFloat(dot.getAttribute("data-x"));
    const posY = parseFloat(dot.getAttribute("data-y"));

    if (hasValidMap && posX !== -1 && posY !== -1) {
      dot.style.display = "block";
      dot.style.left = ((posX / mapWidth) * 100).toFixed(2) + "%";
      dot.style.top = (100 - (posY / mapHeight) * 100).toFixed(2) + "%";
    } else {
      dot.style.display = "none";
    }
  });

  // Make map visible
  map.style.visibility = "visible";

  // Position map relative to the viewport
  const rect = element.getBoundingClientRect();
  const mapWidthPx = map.offsetWidth;
  const mapHeightPx = map.offsetHeight;
  const gap = 8;

  let left = rect.left + rect.width / 2 - mapWidthPx / 2;
  let top = rect.top - mapHeightPx - gap;

  if (top < 0) {
    top = rect.bottom + gap;
  }

  const minLeft = 8;
  const maxLeft = document.documentElement.clientWidth - mapWidthPx - 8;
  if (left < minLeft) left = minLeft;
  if (left > maxLeft) left = maxLeft;

  map.style.position = "fixed";
  map.style.left = left + "px";
  map.style.top = top + "px";
}

function DisplayAllMapLegendMarks() {
  const elements = document.querySelectorAll("span.mapLegend.poi");

  elements.forEach((element) => {
    const mapName = element.getAttribute("data-map");
    const map = element.querySelector(".legendMap"); // <-- FIXED
    if (!map) return;

    const dots = map.querySelectorAll(".mapLegendDot");

    const mapData = Navi_Map_JS[mapName] || Navi_Map_JS["NULL"] || [300, 300];
    const [mapWidth, mapHeight] = mapData;
    const hasValidMap = !!Navi_Map_JS[mapName];

    dots.forEach((dot) => {
      const posX = parseFloat(dot.getAttribute("data-x"));
      const posY = parseFloat(dot.getAttribute("data-y"));

      if (hasValidMap && posX !== -1 && posY !== -1) {
        dot.style.display = "block";
        dot.style.left = ((posX / mapWidth) * 100).toFixed(2) + "%";
        dot.style.top = (100 - (posY / mapHeight) * 100).toFixed(2) + "%";
      } else {
        dot.style.display = "none";
      }
    });
/*
    const rect = element.getBoundingClientRect();
    const mapWidthPx = map.offsetWidth;
    const mapHeightPx = map.offsetHeight;
    const gap = 8;

    let left = rect.left + rect.width / 2 - mapWidthPx / 2;
    let top = rect.top - mapHeightPx - gap;

    if (top < 0) {
      top = rect.bottom + gap;
    }

    const minLeft = 8;
    const maxLeft = document.documentElement.clientWidth - mapWidthPx - 8;
    if (left < minLeft) left = minLeft;
    if (left > maxLeft) left = maxLeft;

    map.style.position = "fixed";
    map.style.left = left + "px";
    map.style.top = top + "px";*/
  });
}

$(document).ready(function () {

DisplayAllMapLegendMarks();

  // Copy link click
document.body.addEventListener("click", (e) => {
  const clickable = e.target.closest(".naviClickable, .naviPoi");
  if (!clickable) return;

  e.preventDefault();

  // For legacy naviClickable → use existing copy handler
  if (clickable.classList.contains("naviClickable")) {
    CopyNaviLinkH(clickable);
  }
  // For new naviPoi → use its data-navi directly
  else if (clickable.classList.contains("naviPoi")) {
    const link = clickable.getAttribute("data-navi");
    if (link) {
      navigator.clipboard.writeText(link).catch(() => {});
    }
  }
});

// Show dot(s) on mouseenter
document.body.addEventListener(
  "mouseenter",
  (e) => {
    const block = e.target.closest(".naviBlock");
    if (!block) return;

    const mapName = block.dataset.map;

    // New system: multiple dots
    if (block.querySelector(".naviPoiDot")) {
      DisplayAllNaviMarks(block, mapName);
    }
    // Legacy system: single dot
    else {
      const posX = parseInt(block.dataset.x, 10);
      const posY = parseInt(block.dataset.y, 10);
      DisplayNaviMark(block, mapName, posX, posY);
    }
  },
  true
);

// Hide map on mouseleave
document.body.addEventListener(
  "mouseleave",
  (e) => {
    const block = e.target.closest(".naviBlock");
    if (block) {
      const map = block.querySelector(".naviMap");
      map.style.visibility = "hidden";
    }
  },
  true
);

// Touchstart (mobile hover simulation)
document.body.addEventListener(
  "touchstart",
  (e) => {
    const clickable = e.target.closest(".naviClickable, .naviPoi");
    if (!clickable) return;

    e.preventDefault(); // prevent simulated hover on this element

    const block = clickable.closest(".naviBlock");
    const map = block.querySelector(".naviMap");
    if (!map) return;

    const mapName = block.dataset.map;

    // Show appropriate dots
    if (block.querySelector(".naviPoiDot")) {
      DisplayAllNaviMarks(block, mapName);
    } else {
      const posX = parseInt(block.dataset.x, 10);
      const posY = parseInt(block.dataset.y, 10);
      DisplayNaviMark(block, mapName, posX, posY);
    }

    // Hide again after delay
    setTimeout(() => (map.style.visibility = "hidden"), 1500);
  },
  false
);

  /* Citizen Wiki Main Page Search Button */

  /* End Citizen Wiki Main Page Search Button */

  $(".card_tooltip").on("mouseenter", function () {
    const tooltipSpan = $(this).find("span");
    const rect = this.getBoundingClientRect();
    const tooltipHeight = tooltipSpan.outerHeight();

    // Calculate available space
    const spaceAbove = rect.top;
    const spaceBelow = $(window).height() - rect.bottom;

    // Toggle the tooltip's position based on available space
    if (spaceBelow >= tooltipHeight) {
      tooltipSpan.css({
        top: "100%",
        marginTop: "8px",
        bottom: "auto",
        maxHeight: "",
      });
    } else if (spaceAbove >= tooltipHeight) {
      tooltipSpan.css({
        top: "auto",
        bottom: "100%",
        marginTop: "",
        marginBottom: "8px",
        maxHeight: "",
      });
    } else {
      // Default to bottom position with a reduced height if space is limited
      tooltipSpan.css({
        top: "100%",
        marginTop: "8px",
        bottom: "auto",
        maxHeight: `${spaceBelow - 10}px`,
        overflowY: "auto",
      });
    }
  });
});