<script>
(function () {
  var NAMES = ["김ㅌㅇ", "이ㅅㅇ", "김ㅈㅎ", "정ㅇㅈ", "ㄴㄴ", "ㄴ"];
  var KEY = "lighting_ratings_v1";
  var MEKEY = "lighting_me_v1";
  var THUMB_OUT = '<svg viewBox="0 0 24 24" width="13" height="13" aria-hidden="true"><path fill="currentColor" d="M9 21h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.58 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2zM9 9l4.34-4.34L12 10h9v2l-3 7H9V9zM1 9h4v12H1z"/></svg>';
  var THUMB_FILL = '<svg viewBox="0 0 24 24" width="13" height="13" aria-hidden="true"><path fill="currentColor" d="M2 21h4V9H2v12zM23 10c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z"/></svg>';

  var ME = "";
  try { ME = localStorage.getItem(MEKEY) || ""; } catch (e) {}
  if (NAMES.indexOf(ME) < 0) ME = "";

  var data = {};
  try { data = JSON.parse(localStorage.getItem(KEY) || "{}"); }
  catch (e) {
    try { localStorage.setItem(KEY + "_corrupt", localStorage.getItem(KEY) || ""); } catch (e2) {}
    data = {};
  }
  Object.keys(data).forEach(function (k) {
    if (k.charAt(0) === "_") { delete data[k]; return; }
    var v = data[k];
    if (v && typeof v === "object" && !v.s && !v.l) data[k] = { s: v, l: {} };
    else { data[k] = data[k] || {}; data[k].s = data[k].s || {}; data[k].l = data[k].l || {}; }
  });
  var saveBroken = false;
  function warnSave(on) {
    var b = document.getElementById("savewarn");
    if (!b) {
      b = document.createElement("div"); b.id = "savewarn";
      b.textContent = "저장이 되지 않고 있습니다. 시크릿 창인지 확인하고, 지금 맨 아래 내보내기로 백업하세요.";
      document.body.appendChild(b);
    }
    b.hidden = !on;
  }
  function save() {
    try {
      localStorage.setItem(KEY, JSON.stringify(data));
      if (localStorage.getItem(KEY) === null) throw new Error("verify");
      if (saveBroken) { saveBroken = false; warnSave(false); }
    } catch (e) {
      if (!saveBroken) { saveBroken = true; warnSave(true); }
    }
  }
  // 전당(hall_)은 본문 도판을 다시 쓴 것이다. 평가는 원본 키 하나로 모은다
  function baseKey(k) { return (k && k.indexOf("hall_") === 0) ? k.slice(5) : k; }
  function rec(k) { k = baseKey(k); if (!data[k]) data[k] = { s: {}, l: {} }; return data[k]; }
  function get(k) { k = baseKey(k); return data[k] || { s: {}, l: {} }; }
  function tidy(k) { k = baseKey(k); var r = data[k]; if (r && !Object.keys(r.s).length && !Object.keys(r.l).length) delete data[k]; }

  var figs = Array.prototype.slice.call(document.querySelectorAll("figure.shot[data-k]"));
  figs.forEach(function (f, i) { f._home = f.parentNode; f._ord = i; });
  var byBase = {};
  figs.forEach(function (f) {
    var b = baseKey(f.getAttribute("data-k"));
    (byBase[b] = byBase[b] || []).push(f);
  });
  function paintSame(fig) {                       // 전당과 본문이 같은 도판이면 둘 다 갱신
    var b = baseKey(fig.getAttribute("data-k"));
    (byBase[b] || [fig]).forEach(paint);
  }

  var pop = document.getElementById("pop");
  var bar = document.getElementById("ratebar");
  var elMe = document.getElementById("fme");
  var elName = document.getElementById("fname");
  var elCat = document.getElementById("fcat");
  var elStar = document.getElementById("fstar");
  var elSort = document.getElementById("fsort");
  var elCount = document.getElementById("fcount");
  var elOnly = document.getElementById("fonly");
  var elLike = document.getElementById("flike");
  var sv = document.getElementById("sortview");
  var svg_ = document.getElementById("sv-gallery");
  var svTitle = document.getElementById("sv-title");
  var svCount = document.getElementById("sv-count");
  var svEmpty = document.getElementById("sv-empty");

  var fName = "", fStar = 0, fOnly = false, fLike = false, fSort = "", fCat = "";
  var CATS = [{ label: "전체", value: "" }, { label: "펜던트", value: "p" }, { label: "플로어", value: "f" },
              { label: "테이블", value: "t" }, { label: "벽,천장", value: "w" }, { label: "포터블", value: "b" },
              { label: "전구,스트립", value: "l" }, { label: "분위기컷", value: "m" }];

  var SORTS = [
    { id: "", label: "없음" },
    { id: "like", label: "좋음 많은 순", title: "좋음 많은 순", score: function (r) { return fName ? (r.l[fName] ? 1 : 0) : Object.keys(r.l).length; }, unit: "좋음" },
    { id: "starsum", label: "별 갯수 많은 순", title: "별 갯수 많은 순", score: function (r) { if (fName) return r.s[fName] || 0; var t = 0; Object.keys(r.s).forEach(function (w) { t += r.s[w]; }); return t; }, unit: "별" },
    { id: "starppl", label: "별 한 사람 많은 순", title: "별 한 사람 많은 순", score: function (r) { return fName ? (r.s[fName] !== undefined ? 1 : 0) : Object.keys(r.s).length; }, unit: "명" }
  ];
  function sortDef(id) { for (var i = 0; i < SORTS.length; i++) if (SORTS[i].id === id) return SORTS[i]; return SORTS[0]; }
  function stars(n) { return "★★★".slice(0, n) + "☆☆☆".slice(0, 3 - n); }

  function paintMe() { elMe.textContent = ME ? ("내 이름: " + ME) : "내 이름 선택"; }

  function mkChips(host, items, getV, setV) {
    host.innerHTML = "";
    items.forEach(function (it) {
      var b = document.createElement("button");
      b.type = "button"; b.className = "chip"; b.textContent = it.label;
      b.setAttribute("aria-pressed", getV() === it.value ? "true" : "false");
      b.addEventListener("click", function () { setV(it.value); apply(); });
      host.appendChild(b);
    });
  }
  function buildChips() {
    mkChips(elName, [{ label: "전체", value: "" }].concat(NAMES.map(function (n) { return { label: n, value: n }; })),
      function () { return fName; }, function (v) { fName = v; });
    mkChips(elStar, [{ label: "전체", value: 0 }, { label: "★", value: 1 }, { label: "★★", value: 2 }, { label: "★★★", value: 3 }],
      function () { return fStar; }, function (v) { fStar = v; });
    mkChips(elCat, CATS, function () { return fCat; }, function (v) { fCat = v; });
    mkChips(elSort, SORTS.map(function (s) { return { label: s.label, value: s.id }; }),
      function () { return fSort; }, function (v) { fSort = v; });
  }

  function paint(fig) {
    var r = get(fig.getAttribute("data-k"));
    var lb = fig.querySelector(".like"), rb = fig.querySelector(".rate");
    if (lb) {
      var likers = Object.keys(r.l);
      lb.className = likers.length ? "like on" : "like";
      lb.innerHTML = likers.length ? THUMB_FILL : THUMB_OUT;
      if (likers.length) {
        var s = document.createElement("span");
        s.className = "who"; s.textContent = likers.join(" ");
        lb.appendChild(s);
      }
    }
    if (rb) {
      var who = Object.keys(r.s);
      if (!who.length) { rb.className = "rate"; rb.textContent = "☆"; }
      else {
        rb.className = "rate on"; rb.innerHTML = "";
        who.forEach(function (w, i) {
          var s2 = document.createElement("span");
          s2.className = "who";
          s2.textContent = (i ? " " : "") + "★".repeat(r.s[w]) + " " + w;
          rb.appendChild(s2);
        });
      }
    }
  }

  function match(k, fig) {
    if (fCat && fig && fig.getAttribute("data-c") !== fCat) return false;
    var r = get(k);
    if (!(fOnly || fLike || fName || fStar)) return true;
    if (fLike) {
      var lk = fName ? !!r.l[fName] : Object.keys(r.l).length > 0;
      if (!lk) return false;
      if (!fStar && !fOnly) return true;
    }
    if (fStar) {
      var ws = fName ? (r.s[fName] !== undefined ? [fName] : []) : Object.keys(r.s);
      return ws.some(function (w) { return r.s[w] === fStar; });
    }
    if (fName) return r.s[fName] !== undefined || !!r.l[fName];
    if (fOnly) return Object.keys(r.s).length > 0 || Object.keys(r.l).length > 0;
    return true;
  }

  function restoreHome() {
    figs.slice().sort(function (a, b) { return a._ord - b._ord; })
        .forEach(function (f) { f._home.appendChild(f); });
    figs.forEach(function (f) {
      var t = f.querySelector(".sv-rank");
      if (t) t.parentNode.removeChild(t);
    });
  }

  function apply() {
    buildChips();
    elOnly.setAttribute("aria-pressed", fOnly ? "true" : "false");
    elLike.setAttribute("aria-pressed", fLike ? "true" : "false");

    if (fSort) {
      var def = sortDef(fSort);
      restoreHome();
      var list = figs.filter(function (f) {
        var k = f.getAttribute("data-k");
        return match(k, f) && def.score(get(k)) > 0;
      }).map(function (f) { return { f: f, v: def.score(get(f.getAttribute("data-k"))), o: f._ord, b: baseKey(f.getAttribute("data-k")) }; });
      var seenB = {};
      list = list.filter(function (x) { if (seenB[x.b]) return false; seenB[x.b] = 1; return true; });
      list.sort(function (a, b) { return b.v - a.v || a.o - b.o; });
      figs.forEach(function (f) { f.classList.add("hide"); });
      list.forEach(function (x, i) {
        var cap = x.f.querySelector("figcaption .t");
        if (cap && !x.f.querySelector(".sv-rank")) {
          var tag = document.createElement("span");
          tag.className = "sv-rank";
          tag.textContent = (i + 1) + "위 " + x.v + def.unit;
          cap.parentNode.insertBefore(tag, cap);
        }
        x.f.classList.remove("hide");
        svg_.appendChild(x.f);
      });
      document.querySelectorAll("section.style-sec, header.part, .dblock").forEach(function (e) { e.classList.add("hide"); });
      sv.classList.remove("hide");
      svEmpty.hidden = list.length > 0;
      svTitle.textContent = def.title;
      svCount.textContent = list.length + " 개";
      elCount.textContent = list.length + " / " + figs.length + " 개 표시";
      syncTop();
      return;
    }

    sv.classList.add("hide");
    restoreHome();
    var shown = 0;
    figs.forEach(function (f) {
      var ok = match(f.getAttribute("data-k"), f);
      f.classList.toggle("hide", !ok);
      if (ok) shown++;
    });
    document.querySelectorAll(".dblock").forEach(function (b) {
      b.classList.toggle("hide", b.querySelectorAll("figure.shot:not(.hide)").length === 0);
    });
    document.querySelectorAll("section.style-sec").forEach(function (sec) {
      sec.classList.toggle("hide", sec.querySelectorAll("figure.shot:not(.hide)").length === 0);
    });
    document.querySelectorAll("header.part").forEach(function (h) {
      var any = false, n = h.nextElementSibling;
      while (n && !(n.tagName === "HEADER" && n.classList.contains("part"))) {
        if (n.classList.contains("style-sec") && !n.classList.contains("hide")) { any = true; break; }
        n = n.nextElementSibling;
      }
      h.classList.toggle("hide", !any);
    });
    var filtering = fOnly || fLike || fName || fStar || fCat;
    elCount.textContent = filtering ? (shown + " / " + figs.length + " 개 표시") : (figs.length + " 개");
  }

  function closePop() { pop.hidden = true; }
  function place(btn) {
    var b = btn.getBoundingClientRect(), w = 232, gap = 6;
    var left = b.left + window.scrollX;
    var maxL = window.scrollX + document.documentElement.clientWidth - w - 8;
    if (left > maxL) left = maxL;
    if (left < window.scrollX + 8) left = window.scrollX + 8;
    pop.style.left = left + "px";
    pop.style.top = (b.bottom + window.scrollY + gap) + "px";
    var ph = pop.offsetHeight;
    if (b.bottom + gap + ph > document.documentElement.clientHeight && b.top - gap - ph > 0) {
      pop.style.top = (b.top + window.scrollY - gap - ph) + "px";
    }
  }

  // 팀 코드 게이트 -> 내 이름 선택 (처음 한 번, 이후 이 브라우저에 기억됨)
  // 이름을 고르는 것이 곧 내부 인원 확인이다. 별도 코드는 두지 않는다
  function isAuthed() { return !!ME; }

  function openMe(btn, then) {
    pop.innerHTML = "";
    var t = document.createElement("div");
    t.className = "ttl"; t.textContent = "내 이름을 고르세요. 이 브라우저의 평가에 계속 쓰입니다";
    pop.appendChild(t);
    var row = document.createElement("div");
    row.className = "row";
    NAMES.forEach(function (w) {
      var b = document.createElement("button");
      b.type = "button"; b.textContent = w;
      b.setAttribute("aria-pressed", ME === w ? "true" : "false");
      b.addEventListener("click", function () {
        ME = w;
        try { localStorage.setItem(MEKEY, ME); } catch (e) {}
        document.dispatchEvent(new CustomEvent("lg-open"));
        paintMe(); closePop();
        if (then) then();
      });
      row.appendChild(b);
    });
    pop.appendChild(row);
    pop.hidden = false;
    place(btn);
  }

  function openStar(fig, btn) {
    var k = fig.getAttribute("data-k");
    function render() {
      pop.innerHTML = "";
      var t = document.createElement("div");
      t.className = "ttl"; t.textContent = "기억할만함, 별을 고르세요 (" + ME + ")";
      pop.appendChild(t);
      var row = document.createElement("div");
      row.className = "row stars";
      [1, 2, 3].forEach(function (v) {
        var b = document.createElement("button");
        b.type = "button"; b.textContent = stars(v);
        b.setAttribute("aria-pressed", get(k).s[ME] === v ? "true" : "false");
        b.addEventListener("click", function () {
          rec(k).s[ME] = v; save(); paintSame(fig); apply(); closePop();
        });
        row.appendChild(b);
      });
      pop.appendChild(row);
      var r = get(k), who = Object.keys(r.s);
      if (who.length) {
        var has = document.createElement("div");
        has.className = "has";
        who.forEach(function (w) {
          var s = document.createElement("span");
          var b1 = document.createElement("b"); b1.textContent = "★".repeat(r.s[w]);
          var x = document.createElement("i"); x.textContent = "×"; x.title = "삭제";
          x.addEventListener("click", function () {
            delete data[k].s[w]; tidy(k); save(); paintSame(fig); apply(); render();
          });
          s.appendChild(b1); s.appendChild(document.createTextNode(" " + w)); s.appendChild(x);
          has.appendChild(s);
        });
        pop.appendChild(has);
      }
      pop.hidden = false;
      place(btn);
    }
    render();
  }

  function toggleLike(fig) {
    var k = fig.getAttribute("data-k");
    var r = rec(k);
    if (r.l[ME]) delete r.l[ME]; else r.l[ME] = true;
    tidy(k); save(); paintSame(fig); apply();
  }

  document.addEventListener("click", function (e) {
    var t = e.target;
    var rb = t.closest ? t.closest("figure.shot .rate") : null;
    var lb = t.closest ? t.closest("figure.shot .like") : null;
    var me = t.closest ? t.closest("#fme") : null;
    if (me) { e.preventDefault(); openMe(me); return; }
    if (rb) {
      e.preventDefault(); e.stopPropagation();
      var fg = rb.closest("figure.shot");
      if (!ME) { openMe(rb, function () { openStar(fg, rb); }); } else { openStar(fg, rb); }
      return;
    }
    if (lb) {
      e.preventDefault(); e.stopPropagation();
      var fg2 = lb.closest("figure.shot");
      if (!ME) { openMe(lb, function () { toggleLike(fg2); }); } else { toggleLike(fg2); }
      return;
    }
    if (!pop.hidden && !pop.contains(e.target)) closePop();
  });
  document.addEventListener("keydown", function (e) { if (e.key === "Escape") closePop(); });
  window.addEventListener("resize", closePop);

  elOnly.addEventListener("click", function () { fOnly = !fOnly; apply(); });
  elLike.addEventListener("click", function () { fLike = !fLike; apply(); });
  document.getElementById("fclr").addEventListener("click", function () {
    if (!confirm("좋음과 별 표시를 전부 지웁니다.")) return;
    try { localStorage.setItem(KEY + "_bak", JSON.stringify(data)); } catch (e) {}
    data = {}; save(); figs.forEach(paint); apply();
  });
  document.getElementById("fexp").addEventListener("click", function () {
    var out = { _meta: { by: ME || "미지정", at: new Date().toISOString().slice(0, 16), authors: ME ? [ME] : [] } };
    Object.keys(data).forEach(function (k) {
      var r = data[k], e = { s: {}, l: {} };
      if (r.s[ME] !== undefined) e.s[ME] = r.s[ME];
      if (r.l[ME]) e.l[ME] = true;
      if (Object.keys(e.s).length || Object.keys(e.l).length) out[k] = e;
    });
    var s = JSON.stringify(out);
    if (navigator.clipboard) navigator.clipboard.writeText(s).then(
      function () { alert("평가 데이터를 복사했습니다. 대표에게 전달하세요."); },
      function () { prompt("복사하세요", s); });
    else prompt("복사하세요", s);
  });
  document.getElementById("fimp").addEventListener("click", function () {
    var s = prompt("전달받은 평가 데이터를 붙여넣으세요. 기존 것에 합쳐집니다.");
    if (!s) return;
    var inc; try { inc = JSON.parse(s); } catch (e) { alert("형식이 올바르지 않습니다."); return; }
    var authors = (inc._meta && inc._meta.authors) || [];
    authors.forEach(function (w) {
      if (NAMES.indexOf(w) < 0) return;
      Object.keys(data).forEach(function (k) { delete data[k].s[w]; delete data[k].l[w]; tidy(k); });
    });
    var bad = 0;
    Object.keys(inc).forEach(function (k) {
      if (k.charAt(0) === "_") return;
      if (!/^[a-z0-9_]{2,60}$/i.test(k)) { bad++; return; }
      var v = inc[k];
      if (v && !v.s && !v.l) v = { s: v, l: {} };
      if (!v || typeof v !== "object") { bad++; return; }
      var r = rec(k);
      Object.keys(v.s || {}).forEach(function (w) {
        var num = Math.round(Number(v.s[w]));
        if (NAMES.indexOf(w) < 0 || !(num >= 1 && num <= 3)) { bad++; return; }
        r.s[w] = num;
      });
      Object.keys(v.l || {}).forEach(function (w) { if (NAMES.indexOf(w) >= 0) r.l[w] = true; });
      tidy(k);
    });
    if (bad) alert("형식이 이상한 항목 " + bad + "건은 건너뛰었습니다.");
    save(); figs.forEach(paint); apply();
  });

  function syncTop() {
    var h = bar.offsetHeight;
    document.querySelectorAll(".sec-head, #sortview .sv-head").forEach(function (el) { el.style.top = h + "px"; });
  }
  window.addEventListener("storage", function (e) {
    if (e.key !== KEY) return;
    try { data = JSON.parse(e.newValue || "{}"); } catch (err) { return; }
    Object.keys(data).forEach(function (k) {
      var v = data[k];
      if (v && typeof v === "object" && !v.s && !v.l) data[k] = { s: v, l: {} };
      else { data[k].s = data[k].s || {}; data[k].l = data[k].l || {}; }
    });
    figs.forEach(paint); apply();
  });
  window.addEventListener("resize", syncTop);

  paintMe();
  if (isAuthed()) document.dispatchEvent(new CustomEvent("lg-open"));
  figs.forEach(paint);
  buildChips();
  apply();
  syncTop();
})();
</script>
<script>
(function () {
  // ===== 카피 방어. 내 이름을 고른 사람(팀원)은 전부 해제 =====
  var LOCKED = true;
  try { if (localStorage.getItem("lighting_me_v1")) LOCKED = false; } catch (e) {}
  function setLock(on) {
    LOCKED = on;
    document.documentElement.classList.toggle("locked", on);
  }
  document.addEventListener("lg-open", function () { setLock(false); });
  setLock(LOCKED);

  document.querySelectorAll("img").forEach(function (im) { im.setAttribute("draggable", "false"); });

  function guard(e) { if (LOCKED) { e.preventDefault(); e.stopPropagation(); return false; } }
  ["contextmenu", "selectstart", "dragstart", "copy", "cut"].forEach(function (ev) {
    document.addEventListener(ev, guard, true);
  });
  document.addEventListener("keydown", function (e) {
    if (!LOCKED) return;
    var k = (e.key || "").toLowerCase();
    if (e.key === "F12") { e.preventDefault(); return; }
    if ((e.ctrlKey || e.metaKey) && ["s", "u", "p", "c", "a"].indexOf(k) >= 0) { e.preventDefault(); return; }
    if ((e.ctrlKey || e.metaKey) && e.shiftKey && ["i", "j", "c", "k"].indexOf(k) >= 0) { e.preventDefault(); return; }
  }, true);
  window.addEventListener("beforeprint", function () {
    if (LOCKED) { document.documentElement.classList.add("noprint"); }
  });
  window.addEventListener("afterprint", function () {
    document.documentElement.classList.remove("noprint");
  });
})();
</script>
