'
+ '
' + T.t + '
'
// 폰트 16px 고정 — iOS 는 16px 미만 입력 포커스 시 자동 확대(더블탭 줌 봉인과 별개 경로)
+ '
'
+ '
'
+ ''
+ '
';
document.body.appendChild(ov);
var inp = ov.querySelector('input');
// input 중 값 강제 치환 금지 — 한글/일어 IME 조합 중 value 재대입은 조합을 파괴한다(textarea clamp 캐논 동형).
// 길이는 maxlength 속성, 위생(제어문자·공백 정규화·140 코드포인트)은 제출 시 1회.
setTimeout(function () { try { inp.focus(); } catch (e) {} }, 30);
ov.querySelector('[data-x]').addEventListener('click', function (e) { e.preventDefault(); ov.remove(); }); // click 시점 제거 — pointerdown 제거는 릴리즈 click 이 하부 요소에 착탄(고스트클릭, 2026-07-25 실보고)
ov.querySelector('[data-ok]').addEventListener('click', function (e) { // click 시점(고스트클릭 봉합)
e.preventDefault();
var v = String(inp.value || '').replace(/[\u0000-\u001f\u007f\u200b-\u200f\u2028\u2029\ufeff]/g, '').replace(/\s+/g, ' ').trim();
v = Array.from(v).slice(0, 140).join('');
if (!v) return;
_lb_set_initials(v);
ov.remove();
cb(v);
});
}
P.leaderboard = {
// enable({ metric, unit, max, higher_better, min_play_s }) — 아키타입이 완주 배관 전에 1회 호출.
enable: function (o) {
o = o || {};
_lb.metric = String(o.metric || '').slice(0, 24);
_lb.unit = String(o.unit || '').slice(0, 8);
_lb.max = typeof o.max === 'number' && isFinite(o.max) ? o.max : 1e12;
_lb.hb = o.higher_better !== false;
_lb.min_play_s = typeof o.min_play_s === 'number' ? Math.max(0, o.min_play_s) : 3;
_lb.t0 = (performance && performance.now) ? performance.now() : Date.now();
_lb.submitted = false;
// 오버플로 메뉴에 "전체 리더보드 열기" 항목 — 활성 게임에서 종료 전에도 언제든 순위 확인
// (사용자 요청 2026-07-22). show()(인자 없음)는 GET 으로 전체 top-N 을 새로 받아 렌더한다.
if (!_lb.menu_added && P.menu) {
_lb.menu_added = true;
P.menu.add({
label: ['게임 순위', 'ゲームランキング', 'Game Ranking'],
svg: '