<commit_before>// ==UserScript==
// @name        NamuFix
// @namespace   http://litehell.info/
// @description 나무위키 편집 인터페이스 등을 개선합니다.
// @include     http://namu.wiki/*
// @include     https://namu.wiki/*
// @version     150810.5
// @namespace   http://litehell.info/
// @downloadURL https://raw.githubusercontent.com/LiteHell/NamuFix/master/NamuFix.user.js
// @require     https://raw.githubusercontent.com/LiteHell/NamuFix/master/FlexiColorPicker.js
// @require     https://raw.githubusercontent.com/Caligatio/jsSHA/v2.0.1/src/sha512.js
// @grant       GM_addStyle
// @grant       GM_xmlhttpRequest
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_listValues
// @run-at      document-end
// ==/UserScript==
var showNotification = function(text) {
  if (!("Notification" in unsafeWindow)) {
    alert(text);
    return;
  }
  var makeNoti = function(permission) {
    if (permission === "granted") {
      var notification = new Notification(text);
    }
  };
  if (Notification.permission === "granted") {
    makeNoti("granted");
  } else if (Notification.permission !== 'denied') {
    Notification.requestPermission(makeNoti);
  }
}
GM_addStyle("em{font-style: italic;}");
GM_xmlhttpRequest({
  method: "GET",
  url: "https://raw.githubusercontent.com/LiteHell/NamuFix/master/NamuFix.css",
  onload: function(res) {
    GM_addStyle(res.responseText);
  }
});

function nOu(a) {
  return typeof a === 'undefined' || a == null;
}

function formatDateTime(t) {
  var d = new Date(t);
  return d.getFullYear() + '년 ' + (d.getMonth() + 1) + '월 ' + d.getDate() + '일 ' + d.getHours() + '시 ' + d.getMinutes() + '분 ' + d.getSeconds() + '초';
}

var ENV = {};
ENV.IsEditing = /https?:\/\/namu\.wiki\/edit\/(.+?)/.test(location.href);
ENV.Discussing = /https?:\/\/namu\.wiki\/topic\/(.+?)/.test(location.href);
ENV.IsDocument = /https?:\/\/namu\.wiki\/w\/(.+)/.test(location.href); //&& document.querySelector('p.wiki-edit-date');
if (document.querySelector("input[name=section]"))
  ENV.section = document.querySelector("input[name=section]").value;
if (ENV.IsEditing)
  ENV.docTitle = document.querySelector("h1.title > a").innerHTML;
else if (ENV.IsDocument)
  ENV.docTitle = document.querySelector("h1.title").innerHTML;
if (nOu(ENV.section))
  ENV.section = -2;

var SET = new function() {
  var discards = ['save', 'load'];
  this.save = function() {
    for (var i in this) {
      if (discards.indexOf(i) != -1) continue;
      GM_setValue('SET_' + i, this[i]);
    }
  };
  this.load = function() {
    var sets = GM_listValues();
    for (var i = 0; i < sets.length; i++) {
      var now = sets[i];
      if (now.indexOf('SET_') != 0) continue;
      if (discards.indexOf(now) != -1) continue;
      this[now.substring(4)] = GM_getValue(now);
    }
    for (var i in this) {
      if (sets.indexOf('SET_' + i) == -1 && discards.indexOf(i) == -1) {
        delete this[i];
      }
    }
  };
};
SET.load();

var NEWindow = function() {
  var wi = document.createElement('div');
  var wiHead = document.createElement('div');
  var wiContainer = document.createElement('div');
  var wiFoot = document.createElement('div');

  wi.className = 'NamaEditor NEWindowRoot';
  wiHead.className = 'NamaEditor NEWindowHead';
  wiContainer.className = 'NamaEditor NEWindowContainer';
  wiFoot.className = 'NamaEditor NEWindowFoot';

  wi.appendChild(wiHead);
  wi.appendChild(wiContainer);
  wi.appendChild(wiFoot);

  var wrapper = document.createElement('div');
  wrapper.style.background = 'rgba(0,0,0,0.5)';
  wrapper.style.zIndex = '9999';
  wrapper.style.position = 'fixed';
  wrapper.style.left = '0px';
  wrapper.style.top = '0px';
  wrapper.style.height = '100%';
  wrapper.style.width = '100%';

  wrapper.appendChild(wi);
  document.body.appendChild(wrapper);
  var r = {
    title: function(text) {
      wiHead.innerHTML = text;
      return r;
    },
    content: function(callback) {
      callback(wiContainer);
      return r;
    },
    foot: function(callback) {
      callback(wiFoot);
      return r;
    },
    button: function(label, onclick) {
      var btn = document.createElement('button');
      btn.setAttribute('type', 'button');
      btn.innerHTML = label;
      btn.addEventListener('click', onclick);
      wiFoot.appendChild(btn);
      return r;
    },
    close: function() {
      wrapper.parentNode.removeChild(wrapper);
      return undefined;
    }
  };
  return r;
}
var Watcher = new function() {
  SET.load();
  if (nOu(SET.dwHashes)) {
    SET.dwHashes = {};
    SET.save();
  }
  var docs = Object.keys(SET.dwHashes);
  docs = docs.sort();
  var docIndex = 0;

  function SHA512(str) {
    var shaObj = new jsSHA("SHA-512", "TEXT");
    shaObj.update(str);
    return shaObj.getHash("HEX");
  }
  this.runWorker = function(r) {
    SET.load();
    var workerFunc = function() {
      if (docs.length <= docIndex) {
        SET.load();
        docs = Object.keys(SET.dwHashes);
        docs = docs.sort();
        docIndex = 0;
      }
      var dNow = docs[docIndex++];
      GM_xmlhttpRequest({
        url: 'https://namu.wiki/raw/' + dNow,
        method: "GET",
        onload: function(res) {
          var dcNow = 'ERR';
          if (res.status == 404) {
            dcNow = '--NOTFOUND';
          } else {
            dcNow = SHA512(res.responseText);
          }
          SET.load();
          if (SET.dwHashes[dNow] != dcNow) {
            if (dcNow != '--NOTFOUND') showNotification('변경 사항 감지됨 : ' + dNow);
            else showNotification('문서가 삭제됨(또는 존재하지 않음) : ' + dNow);
            SET.dwHashes[dNow] = dcNow;
            SET.save();
          }
        }
      });
    };
    setInterval(workerFunc, 2900);
  };
  this.add = function(r) {
    SET.load();
    if (Object.keys(SET.dwHashes).indexOf(r) == -1)
      SET.dwHashes[r] = '';
    SET.save();
  };
  this.remove = function(r) {
    SET.load();
    if (Object.keys(SET.dwHashes).indexOf(r) != -1)
      delete SET.dwHashes[r];
    SET.save();
  };
  this.contains = function(r) {
    SET.load();<commit_msg>딜레이 올림<commit_after>// ==UserScript==
// @name        NamuFix
// @namespace   http://litehell.info/
// @description 나무위키 편집 인터페이스 등을 개선합니다.
// @include     http://namu.wiki/*
// @include     https://namu.wiki/*
// @version     150810.5
// @namespace   http://litehell.info/
// @downloadURL https://raw.githubusercontent.com/LiteHell/NamuFix/master/NamuFix.user.js
// @require     https://raw.githubusercontent.com/LiteHell/NamuFix/master/FlexiColorPicker.js
// @require     https://raw.githubusercontent.com/Caligatio/jsSHA/v2.0.1/src/sha512.js
// @grant       GM_addStyle
// @grant       GM_xmlhttpRequest
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_listValues
// @run-at      document-end
// ==/UserScript==
var showNotification = function(text) {
  if (!("Notification" in unsafeWindow)) {
    alert(text);
    return;
  }
  var makeNoti = function(permission) {
    if (permission === "granted") {
      var notification = new Notification(text);
    }
  };
  if (Notification.permission === "granted") {
    makeNoti("granted");
  } else if (Notification.permission !== 'denied') {
    Notification.requestPermission(makeNoti);
  }
}
GM_addStyle("em{font-style: italic;}");
GM_xmlhttpRequest({
  method: "GET",
  url: "https://raw.githubusercontent.com/LiteHell/NamuFix/master/NamuFix.css",
  onload: function(res) {
    GM_addStyle(res.responseText);
  }
});

function nOu(a) {
  return typeof a === 'undefined' || a == null;
}

function formatDateTime(t) {
  var d = new Date(t);
  return d.getFullYear() + '년 ' + (d.getMonth() + 1) + '월 ' + d.getDate() + '일 ' + d.getHours() + '시 ' + d.getMinutes() + '분 ' + d.getSeconds() + '초';
}

var ENV = {};
ENV.IsEditing = /https?:\/\/namu\.wiki\/edit\/(.+?)/.test(location.href);
ENV.Discussing = /https?:\/\/namu\.wiki\/topic\/(.+?)/.test(location.href);
ENV.IsDocument = /https?:\/\/namu\.wiki\/w\/(.+)/.test(location.href); //&& document.querySelector('p.wiki-edit-date');
if (document.querySelector("input[name=section]"))
  ENV.section = document.querySelector("input[name=section]").value;
if (ENV.IsEditing)
  ENV.docTitle = document.querySelector("h1.title > a").innerHTML;
else if (ENV.IsDocument)
  ENV.docTitle = document.querySelector("h1.title").innerHTML;
if (nOu(ENV.section))
  ENV.section = -2;

var SET = new function() {
  var discards = ['save', 'load'];
  this.save = function() {
    for (var i in this) {
      if (discards.indexOf(i) != -1) continue;
      GM_setValue('SET_' + i, this[i]);
    }
  };
  this.load = function() {
    var sets = GM_listValues();
    for (var i = 0; i < sets.length; i++) {
      var now = sets[i];
      if (now.indexOf('SET_') != 0) continue;
      if (discards.indexOf(now) != -1) continue;
      this[now.substring(4)] = GM_getValue(now);
    }
    for (var i in this) {
      if (sets.indexOf('SET_' + i) == -1 && discards.indexOf(i) == -1) {
        delete this[i];
      }
    }
  };
};
SET.load();

var NEWindow = function() {
  var wi = document.createElement('div');
  var wiHead = document.createElement('div');
  var wiContainer = document.createElement('div');
  var wiFoot = document.createElement('div');

  wi.className = 'NamaEditor NEWindowRoot';
  wiHead.className = 'NamaEditor NEWindowHead';
  wiContainer.className = 'NamaEditor NEWindowContainer';
  wiFoot.className = 'NamaEditor NEWindowFoot';

  wi.appendChild(wiHead);
  wi.appendChild(wiContainer);
  wi.appendChild(wiFoot);

  var wrapper = document.createElement('div');
  wrapper.style.background = 'rgba(0,0,0,0.5)';
  wrapper.style.zIndex = '9999';
  wrapper.style.position = 'fixed';
  wrapper.style.left = '0px';
  wrapper.style.top = '0px';
  wrapper.style.height = '100%';
  wrapper.style.width = '100%';

  wrapper.appendChild(wi);
  document.body.appendChild(wrapper);
  var r = {
    title: function(text) {
      wiHead.innerHTML = text;
      return r;
    },
    content: function(callback) {
      callback(wiContainer);
      return r;
    },
    foot: function(callback) {
      callback(wiFoot);
      return r;
    },
    button: function(label, onclick) {
      var btn = document.createElement('button');
      btn.setAttribute('type', 'button');
      btn.innerHTML = label;
      btn.addEventListener('click', onclick);
      wiFoot.appendChild(btn);
      return r;
    },
    close: function() {
      wrapper.parentNode.removeChild(wrapper);
      return undefined;
    }
  };
  return r;
}
var Watcher = new function() {
  SET.load();
  if (nOu(SET.dwHashes)) {
    SET.dwHashes = {};
    SET.save();
  }
  var docs = Object.keys(SET.dwHashes);
  docs = docs.sort();
  var docIndex = 0;

  function SHA512(str) {
    var shaObj = new jsSHA("SHA-512", "TEXT");
    shaObj.update(str);
    return shaObj.getHash("HEX");
  }
  this.runWorker = function(r) {
    SET.load();
    var workerFunc = function() {
      if (docs.length <= docIndex) {
        SET.load();
        docs = Object.keys(SET.dwHashes);
        docs = docs.sort();
        docIndex = 0;
      }
      var dNow = docs[docIndex++];
      GM_xmlhttpRequest({
        url: 'https://namu.wiki/raw/' + dNow,
        method: "GET",
        onload: function(res) {
          var dcNow = 'ERR';
          if (res.status == 404) {
            dcNow = '--NOTFOUND';
          } else {
            dcNow = SHA512(res.responseText);
          }
          SET.load();
          if (SET.dwHashes[dNow] != dcNow) {
            if (dcNow != '--NOTFOUND') showNotification('변경 사항 감지됨 : ' + dNow);
            else showNotification('문서가 삭제됨(또는 존재하지 않음) : ' + dNow);
            SET.dwHashes[dNow] = dcNow;
            SET.save();
          }
        }
      });
    };
    setInterval(workerFunc, 5000);
  };
  this.add = function(r) {
    SET.load();
    if (Object.keys(SET.dwHashes).indexOf(r) == -1)
      SET.dwHashes[r] = '';
    SET.save();
  };
  this.remove = function(r) {
    SET.load();
    if (Object.keys(SET.dwHashes).indexOf(r) != -1)
      delete SET.dwHashes[r];
    SET.save();
  };
  this.contains = function(r) {
    SET.load();
{'fraction_non_alphanumeric': 0.1782669866754945, 'fraction_numerical': 0.01009683025738641, 'mean_word_length': 2.7204433497536944, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1624921', 'n_tokens_mistral': 4346, 'n_tokens_neox': 4303, 'n_words': 778}