미디어위키:Common.js 문서 원본 보기
←
미디어위키:Common.js
둘러보기로 이동
검색으로 이동
문서 편집 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다:
사용자
.
이 문서는 소프트웨어 인터페이스에 쓰이는 문서로, 부정 행위를 막기 위해 보호되어 있습니다.
이 문서는
관리자
만이 수정할 수 있습니다. 내용의 변경이 필요하다면
관리자 요청
에 편집 요청을 남겨 주세요.
모든 방문자에게 영향을 미칠 수 있기 때문에 이 자바스크립트 문서의 편집 권한이 없습니다.
문서의 원본을 보거나 복사할 수 있습니다.
/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */ /*<source lang="javascript"><nowiki>*/ /** [[틀:USERNAME]]에서 사용하는 바꿔치기 함수 * 작성자: [[사용자:Peremen|Peremen]] */ function UserNameReplace() { if (typeof(disableUsernameReplace) != 'undefined' && disableUsernameReplace) return; if (!document.getElementById('pt-userpage')) return; $("span.insertusername").each(function(i) { $(this).text(wgUserName) }) }; $(UserNameReplace); /** [[틀:제목]]에서 사용하는 제목 바꿔치기 함수 * 작성자: [[사용자:Peremen|Peremen]] */ function rewriteTitle() { if (typeof(disableTitleRewrite) != 'undefined' && disableTitleRewrite) return; if (!document.getElementById('title-meta')) return; $('h1.firstHeading').each(function(i) { $(this).html($("#title-meta").html()).css('text-align', $("#title-align").text()) }) } $(rewriteTitle); /* from en: */ var hasClass = (function() { var reCache = {}; return function(element, className) { return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className); }; })(); /* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */ /** 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"; function collapseTable(tableIndex) { var Button = document.getElementById("collapseButton" + tableIndex); var Table = document.getElementById("collapsibleTable" + tableIndex); if (!Table || !Button) { return false; } var Rows = Table.getElementsByTagName("tr"); if (Button.firstChild.data == collapseCaption) { for (var i = 1; i < Rows.length; i++) { Rows[i].style.display = "none"; } Button.firstChild.data = expandCaption; } else { for (var 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 = new Object(); var Tables = document.getElementsByTagName("table"); for (var i = 0; i < Tables.length; i++) { if (hasClass(Tables[i], "collapsible")) { 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.style.styleFloat = "right"; Button.style.cssFloat = "right"; Button.style.fontWeight = "normal"; Button.style.textAlign = "right"; Button.style.width = "6em"; ButtonLink.setAttribute("id", "collapseButton" + tableIndex); ButtonLink.setAttribute("href", "javascript:collapseTable(" + tableIndex + ");"); ButtonLink.appendChild(ButtonText); Button.appendChild(document.createTextNode("[")); Button.appendChild(ButtonLink); Button.appendChild(document.createTextNode("]")); var Header = Tables[i].getElementsByTagName("tr")[0].getElementsByTagName("th")[0]; /* only add button and increment count if there is a header row to work with */ if (Header) { Header.insertBefore(Button, Header.childNodes[0]); tableIndex++; } } } for (var i = 0; i < tableIndex; i++) { if (hasClass(NavigationBoxes[i], "collapsed") || (tableIndex >= autoCollapse && hasClass(NavigationBoxes[i], "autocollapse"))) { collapseTable(i); } } } $(createCollapseButtons); /* ([[위키백과:관리자 요청/2007년 5월#스크립트 추가 요청]]) */ /** Dynamic Navigation Bars (experimental) ************************************* * * Description: See [[:en:Wikipedia:NavFrame]]. * Maintainers: UNMAINTAINED */ // set up the words in your language var autoCollapse = 2; var collapseCaption = "숨기기"; var expandCaption = "보이기"; var NavigationBarHide = '[' + collapseCaption + ']'; var NavigationBarShow = '[' + expandCaption + ']'; // set up max count of Navigation Bars on page, // if there are more, all will be hidden // NavigationBarShowDefault = 0; // all bars will be hidden // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden var NavigationBarShowDefault = autoCollapse; // shows and hides content and picture (if available) of navigation bars // Parameters: // indexNavigationBar: the index of navigation bar to be toggled function toggleNavigationBar(indexNavigationBar) { var NavToggle = document.getElementById("NavToggle" + indexNavigationBar); var NavFrame = document.getElementById("NavFrame" + indexNavigationBar); if (!NavFrame || !NavToggle) { return false; } // if shown now if (NavToggle.firstChild.data == NavigationBarHide) { for ( var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { if (hasClass(NavChild, 'NavPic')) { NavChild.style.display = 'none'; } if (hasClass(NavChild, 'NavContent')) { NavChild.style.display = 'none'; } } NavToggle.firstChild.data = NavigationBarShow; // if hidden now } else if (NavToggle.firstChild.data == NavigationBarShow) { for ( var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { if (hasClass(NavChild, 'NavPic')) { NavChild.style.display = 'block'; } if (hasClass(NavChild, 'NavContent')) { NavChild.style.display = 'block'; } } NavToggle.firstChild.data = NavigationBarHide; } } // adds show/hide-button to navigation bars function createNavigationBarToggleButton() { var indexNavigationBar = 0; // iterate over all < div >-elements var divs = document.getElementsByTagName("div"); for (var i = 0; NavFrame = divs[i]; i++) { // if found a navigation bar if (hasClass(NavFrame, "NavFrame")) { indexNavigationBar++; var NavToggle = document.createElement("a"); NavToggle.className = 'NavToggle'; NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar); NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');'); var NavToggleText = document.createTextNode(NavigationBarHide); NavToggle.appendChild(NavToggleText); // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) for ( var j = 0; j < NavFrame.childNodes.length; j++ ) { if (hasClass(NavFrame.childNodes[j], "NavHead")) { NavFrame.childNodes[j].appendChild(NavToggle); } } NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar); } } // if more Navigation Bars found than Default: hide all if (NavigationBarShowDefault < indexNavigationBar) { for ( var i = 1; i <= indexNavigationBar; i++ ) { toggleNavigationBar(i); } } } $(createNavigationBarToggleButton); /** 대문의 탭을 "프로젝트"->"대문"으로 바꾸는 함수. * 작성자: [[사용자:Peremen|Peremen]] */ function MainPageRenameNamespaceTab() { var title = mw.config.get('wgPageName'); var hasMainPageTab = (title == '백괴게임:대문' || title == '백괴게임토론:대문'); if (hasMainPageTab) { $('#ca-nstab-project a').text("대문"); } var hasGameListTab = (title == '백괴게임:게임_목록' || title == '백괴게임토론:게임_목록'); if (hasGameListTab) { $('#ca-nstab-project a').text("게임 목록"); } $('#ca-nstab-main a').text("게임"); } $(MainPageRenameNamespaceTab); /** 임베드 플래시 무비 * 문서에 플래시 파일을 넣을 수 있게 합니다. [[틀:플래시]]를 참고하십시오. * 원작성자: [[:en:User:Olipro|Olipro]] */ function useFlash() { var flashOk; var contentTempHolder; $(embedFlashCheck); } function embedFlashMovie(flashOk) { mainbody = document.getElementById('bodyContent'); mainbody.innerHTML = contentTempHolder; spancheck = document.getElementsByTagName('span'); for (i = 0; i < spancheck.length; i++) { if (spancheck[i].getAttribute('id') != 'embedFlashDoc') { continue; } obj = spancheck[i].innerHTML.split('@'); flwidth = obj[0]; flheight = obj[1]; flfile = obj[2].replace('fullurl://', 'https://'); showFlash = ' '; if (flashOk) { showFlash = '<object width="' + flwidth + '" height="' + flheight + '"'; showFlash += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'; showFlash += 'codebase="http://fpdownload.macromedia.com/pub/'; showFlash += 'shockwave/cabs/flash/swflash.cab#version=8,0,0,0">'; showFlash += '<param name="movie" value="' + flfile + '" />'; showFlash += '<embed src="' + flfile + '" width="' + flwidth + '" height='; showFlash += '"' + flheight + '" type="application/x-shockwave-flash" '; showFlash += 'pluginspage="http://www.macromedia.com/go/getflashplayer" />'; showFlash += '</object>'; } else { showFlash = '<a class="plainlinks" href="javascript:embedFlashMovie(true)" onClick="embedFlashMovie(true)">' + flfile + '</a> (신뢰하는 경우 보려면 클릭하십시오.)'; } spancheck[i].innerHTML = showFlash; spancheck[i].style.display = 'inline'; } }; function embedFlashCheck() { if (!document.getElementById('embedFlashDoc')) { return; } mainbody = document.getElementById('bodyContent'); contentTempHolder = mainbody.innerHTML; if (typeof displayFlashOverride != 'undefined') { embedFlashMovie(displayFlashOverride); return; } askmessage = '<div align="center" id="askflash">이 게임에는 '; askmessage += '<a href="/wiki/백괴:플래시" class="plainlinks">플래시</a>가 들어있습니다.<br />'; askmessage += '컴퓨터에 해를 끼칠 수 있으므로 신뢰하는 경우에만 여십시오.<br />'; askmessage += '플래시가 포함된 게임을 보시겠습니까?<br><b> '; askmessage += '<a href="javascript:embedFlashMovie(true)" '; askmessage += 'onClick="embedFlashMovie(true)">예</a> | <a '; askmessage += 'href="https://game.uncyclopedia.kr/">아니오</a>'; mainbody.innerHTML = askmessage; } $(useFlash); /* userAgent */ /** source: http://www.gregoryvarghese.com/how-to-get-browser-name-and-version-via-javascript/ **/ function get_browser_info() { var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(M[1])) { tem = /\brv[ :]+(\d+)/g.exec(ua) || []; return { name: 'IE ', version: (tem[1] || '') }; } if (M[1] === 'Chrome') { tem = ua.match(/\bOPR\/(\d+)/) if (tem != null) { return { name: 'Opera', version: tem[1] }; } } M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?']; if ((tem = ua.match(/version\/(\d+)/i)) != null) { M.splice(1, 1, tem[1]); } return { name: M[0], version: M[1] }; } /** [[틀:CGI2|CGI2]]를 사용 가능하게 만드는 jquery 구문 * 작성자: [[사용자:BANIP|BANIP]] */ function useCGI2() { $(".cgilink").each(function() { // CGI2의 page속성과 data속성을 가져옴 var pagename = $(this).data("page"); var variables = JSON.parse($(this).data("var").replace(/\, *\]/, "]")); // 가져온 page데이터 속성을 조합해 url인스턴스 생성 var urlstr = window.location.origin + "/wiki/" + pagename + window.location.search; var url = new URL(urlstr); // 가져온 var속성으로 url 인스턴스의 searchparams를 씹고 뜯고 맛보고 즐기고 variables.forEach(function(variable) { Object.entries(variable).forEach(function(actionWrap) { var action = actionWrap[0]; var payload = actionWrap[1]; url.searchParams[action](payload[0], payload[1]); }) }) // cgilink에 a태그 추가 var children = $(this).html(); $(this).html("<a href=" + url.href + ">" + children + "</a>") }); } $(useCGI2); /** * 모바일 모드 자동 해제 * 사용자가 모바일 환경이면 자동으로 벡터 스킨으로 전환합니다. * 이 해제하고 싶으면 var execute를 true로 바꾸면 됩니다. 실행하고 싶으면 다시 true로 되돌려 놓아 주세요. * 작성자: [[사용자:BANIP|BANIP]] */ function offMobileEnviroment() { var execute = true; if (!execute) return; $("#mw-mf-display-toggle").each(function() { location.search += "&mobileaction=toggle_view_desktop" }) } $(offMobileEnviroment) /** mediawiki api를 통해 간단하게 문서들을 수집, 변경하는 함수. * 플러그인 코어에서 사용하기 위해 만들었습니다. * 작성자: [[사용자:BANIP|BANIP]] * 사용방법 *: var api = MediaWikiAPI(); .changeDocument() *: api.changeDocument(변경할 문서의 타이틀, 편집 요약, 변경할 문서의 내용) => 문서의 내용을 변경합니다. *: api.addDocument(변경할 문서의 타이틀, 편집 요약, 추가할 문서의 내용) => 문서에 새로운 내용을 추가합니다. *: api.getDocument(가져올 문서의 타이틀) => 문서의 모든 텍스트를 읽어옵니다. *: api.readDocument(가져올 문서의 타이틀) => 문서의 모든 텍스트를 jquery 객체로 읽어옵니다. * 영 좋지 않은 목적으로 사용 하면 안드로메다 경찰관이 잡아간다! */ function MediaWikiAPI() { var token; var getToken = function() { if (token != undefined) return token; $.ajax({ url: "/w/api.php?action=query&meta=tokens", success: function(v, i) { var datas = JSON.parse($(v).find("pre").text()); token = datas["query"]["tokens"]["csrftoken"]; }, async: false }) return token; } function changeDocument(title, summary, content) { $.ajax({ url: mw.util.wikiScript("api"), data: { format: 'json', action: 'edit', title: title, summary: summary, text: content, token: getToken(), }, dataType: 'json', type: 'POST', success: function(data) { if (data && data.edit && data.edit.result == 'Success') { window.location.reload(); // reload page if edit was successful } else if (data && data.error) { alert('Error: API returned error code "' + data.error.code + '": ' + data.error.info); } else { alert('Error: Unknown result from API.'); } }, error: function(xhr) { alert('Error: Request failed.'); } }); } function addDocument(title, summary, content) { originContent = getDocument(title) changeDocument(title, summary, originContent + content); } function getDocument(title) { function entityDecode(doc) { return $('<p></p>').html(doc).text(); } var originContent; $.ajax({ url: "/w/index.php?title=" + title + "&action=edit", success: function ajaxSucess(data) { originContent = $(data).find("textarea").html(); }, async: false }) return entityDecode(originContent); } function readDocument(title) { var doc; $.ajax({ url: "/wiki/" + title, success: function ajaxSucess(data) { doc = $(data).find("#mw-content-text"); }, async: false }) return doc; } return { getToken: getToken, changeDocument: changeDocument, addDocument: addDocument, getDocument: getDocument, readDocument: readDocument, } } /** [[틀:플러그인]]을 사용 가능하게 해 줍니다. 사용자의 허락을 맡고 사용자의 commonjs 편집을 허가 할 수 있는 문서입니다. * 작성자: [[사용자:BANIP|BANIP]] * [[백괴게임:관리자 요청/2018년 1월]]에서 BANIP님 요청으로 퍼왔습니다. */ function pluginCore() { // 사용자의 commonjs의 문서 이름을 획득 var commonjs = "사용자:" + mw.config.get("wgUserName") + "/common.js"; var plugins = {}, docPlugins = {}, uninstalledPlugins = {}, unupdatedPlugins = {}; var preloadedplugins = [], needPlugins = []; var api = MediaWikiAPI(); var jsdoc = api.getDocument(commonjs); //commonjs에서 특정 플러그인 제거 function removePluginByDoc(pluginTitle, doc) { var reg = new RegExp("\\/\\*\\* 플러그인 " + pluginTitle + "([\\s\\S]*)\\/\\* " + pluginTitle + " 끝 \\*\\/", "g"); doc = doc.replace(reg, ""); return doc } // 플러그인이 비어있는지 확인 function isPluginsEmpty(plugins) { return Object.keys(plugins).length === 0; } //플러그인의 모든 키 순회 function forEach(object, callback) { for (var key in object) { var variable = object[key]; callback(variable, key); } } // 문서에서 사용하는 플러그인들을 체크합니다. use-script클래스를 가진 모든 돔 요소를 조사하고 // 그 돔에 내장된 플러그인 데이터를 docPlugins에 추가합니다. var checkDocPlugin = (function(docPlugins) { function getPluginData($this) { return { name: $this.attr("data-name"), // 플러그인 이름 descript: $this.attr("data-descript"), // 플러그인 내용 version: $this.attr("data-version"), // 플러그인 이름 local: ($this.attr("data-local") == "true") ? true : false, creat: $this.attr("data-creat"), state: $this.attr("data-state"), link: $this.attr("data-link"), }; } function getAllPluginsName(plugins) { var pluginNames = []; forEach(plugins, function(plugin) { var pluginName = plugin.name; pluginNames.push(pluginName); }) return pluginNames; } var loadAllPlugins = (function(docPlugins) { $(".use-script").each(function() { const plugin = getPluginData($(this)); docPlugins[plugin.name] = plugin; }) })(docPlugins) var loadAllPlugins = (function(docPlugins) { if (!isPluginsEmpty(docPlugins)) { var subTitle = " " + getAllPluginsName(docPlugins).join(", ") + " 플러그인 가동중"; $("#siteSub").text(function(i, v) { return v + subTitle }); } })(docPlugins) })(docPlugins); // 사용자가 가지고 있는 플러그인들을 체크합니다. var checkHavePlugin = (function() { function getUserPlugins(jsdoc) { var userplugins = []; // plugins.---가 있는지 체크하는 정규식 var pluginreg = /JSON \=\> ([\S]+) = (\{.*\})/g; var nameMatch = pluginreg.exec(jsdoc); while (nameMatch) { userplugins.push(JSON.parse(nameMatch[2])); nameMatch = pluginreg.exec(jsdoc); } return userplugins; } function isSamePlugin(pluginFirst, pluginSecond) { return pluginFirst.name == pluginSecond.name } function isSameVersionPlugin(pluginFirst, plugiSecond) { return pluginFirst.version == plugiSecond.version } function addNeedPlugins(targetPlugins) { //global docPlugins, needPlugins for (var key in targetPlugins) { var pluginName = docPlugins[key].name; needPlugins.push(pluginName); } } if (!isPluginsEmpty(docPlugins)) { preloadedplugins = getUserPlugins(jsdoc); forEach(docPlugins, function(docplugin) { var isHavePlugin = false; forEach(preloadedplugins, function(myplugin) { if (!isSamePlugin(docplugin, myplugin)) return; if (!isSameVersionPlugin(docplugin, myplugin)) { unupdatedPlugins[docplugin.name] = docplugin; } isHavePlugin = true; }); if (!isHavePlugin) { uninstalledPlugins[docplugin.name] = docplugin; } }); addNeedPlugins(uninstalledPlugins); addNeedPlugins(unupdatedPlugins); } })(); function onPluginInstall() { function getPluginCode(plugin) { // html로 구성된 코드를 텍스트로 function entityDecode(doc) { return $('<p></p>').html(doc).text(); } function getDocHead(plugin) { var docHead = ""; var toJSONPlugin = Object.assign({}, plugin); toJSONPlugin.code = undefined; toJSONPlugin.link = undefined; docHead += "\n" docHead += "\n/** 플러그인 " + plugin["name"] + "***************************\n"; docHead += "* " + plugin["descript"] + "\n"; docHead += "* 버전 => " + plugin["version"] + "\n"; docHead += "* 작성자 : [[사용자:" + plugin["creat"] + "|" + plugin["creat"] + "]] \n"; docHead += "* JSON => " + plugin["name"] + " = " + JSON.stringify(toJSONPlugin) + "; \n"; docHead += "*/ \n"; docHead += "function plugin_" + plugin["name"] + "(){\n"; if (plugin.local) docHead += " if($(\"[data-name='" + plugin["name"] + "']\").length >= 1){\n"; return docHead; } function getDocFoot(plugin) { var docFoot = ""; if (plugin.local) docFoot += "\n }\n"; docFoot += "\n}\n"; docFoot += "$( plugin_" + plugin["name"] + " );\n"; docFoot += "/* " + plugin["name"] + " 끝 */\n\n"; return docFoot; } var docHead = getDocHead(plugin), docFoot = getDocFoot(plugin); return entityDecode(docHead + plugin["code"] + docFoot); } $(".install-button").text("설치중.."); $(".install-button").off("click"); var doc = ""; forEach(needPlugins, function(pluginName) { var plugin = docPlugins[pluginName]; jsdoc = removePluginByDoc(pluginName, jsdoc); doc += getPluginCode(plugin); }); api.changeDocument(commonjs, "플러그인 " + needPlugins + "설치", jsdoc + doc); } var checkinstalledPlugin = function() { function appendBox(plugin, status) { var pluginName = plugin.name; var box = $(".cloneable.p-box").clone().removeClass("cloneable"); var code = api.readDocument(plugin.state).find("pre.script").html(); docPlugins[pluginName].code = code; box.find(".p-status").html(status); box.find(".p-code").html(code.replace(/\s{1,}$/, "")); box.find(".p-name").text(pluginName); box.find(".p-descript").text(plugin["descript"]); if (status == "버전업") { var thisVersion; for (var key in preloadedplugins) { if (preloadedplugins[key].name == plugin["name"]) { thisVersion = preloadedplugins[key].version; } } box.find(".p-version").text(thisVersion + " => " + plugin["version"]); } else { box.find(".p-version").text(plugin["version"]); } box.find(".p-local").text(plugin["local"] == true ? "일부 문서만" : "문서 전체"); box.find(".p-creat").text(plugin["creat"]); $.ajax({ url: "/w/api.php?action=query&prop=revisions&rvdir=older&titles=" + plugin.state, success: function(v, i) { var datas = JSON.parse($(v).find("pre").text()); var titleKey = Object.keys(datas["query"]["pages"])[0]; var lastModified = datas["query"]["pages"][titleKey]["revisions"][0]["user"] + "(" + datas["query"]["pages"][titleKey]["revisions"][0]["timestamp"] + ")"; box.find(".p-last").text(lastModified); }, async: false }) $(".box-article").append(box); } if (isPluginsEmpty(docPlugins) || (isPluginsEmpty(unupdatedPlugins) && isPluginsEmpty(uninstalledPlugins))) return; var doc = $("#mw-content-text"); var setupMeta = api.readDocument("틀:플러그인/setup"); doc.html(setupMeta); forEach(uninstalledPlugins, function(uninstalledPlugin) { appendBox(uninstalledPlugin, "설치"); }); forEach(unupdatedPlugins, function(unupdatedPlugin) { appendBox(unupdatedPlugin, "버전업"); }); $(".install-button").on("click", onPluginInstall); } var showPluginTemplet = (function() { if (isPluginsEmpty(needPlugins)) { return; } if ($(".plugin-install").length >= 1) { $(".plugin-install").eq(0).closest("table").show(); $(".plugin-name").eq(0).text(needPlugins); $(".plugin-install").on("click", checkinstalledPlugin); } else { checkinstalledPlugin(); } })(); } $(pluginCore)
이 문서에서 사용한 틀:
리버티게임:연습장/안내문
(
원본 보기
)
미디어위키:Common.js
문서로 돌아갑니다.
둘러보기 메뉴
개인 도구
계정 만들기
로그인
어두운 모드
이름공간
메시지
토론
English
보기
읽기
원본 보기
역사 보기
더 보기
새로 고침
검색
둘러보기
대문
최근 바뀜
게임 목록
임의의 게임으로
커뮤니티
리버티게임 본진
도구
여기를 가리키는 문서
가리키는 글의 최근 바뀜
특수 문서 목록
문서 정보
축약된 URL 얻기