Tags Translator Ver2
Trans Tags Ver2 Src » Tags Translator Ver2
[[iframe http://topia.wikidot.com/trans-tags-ver2/code/1 style="border: none; box-shadow: 1px 1px 3px #aaa; height: 0px; width: 100%;" class="html-block-iframe"]]
<head> <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0"/> <script src="4" defer></script> <script src="3" defer></script> <script src="2" defer></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"> <link rel="stylesheet" href="5"> </head> <body> <div class="content"> <div class="checkwrap"></div> <div class="areawrap"> <textarea id="area" spellcheck="false" disabled></textarea> <div id="pred"></div> </div> <div id="wrap"></div> <hr /> <div id="admin"> <h1>admin</h1> </div> </div> </body>
if(window != window.parent) {//based on C-take's resizing iframe method var site = `http://${document.referrer.split("http://")[1].split("/")[0]}/`; var _wrap = document.createElement("div"); document.body.appendChild(_wrap); var _old= 0; var url = location.href.replace(/^.*\//,'/'); (function() { var _new = _wrap.getBoundingClientRect().top; if(_new !== _old){ var iframe = document.createElement("iframe"); var _rand = String(Math.floor(Math.random() * 10000)); _wrap.innerHTML = ''; iframe.src = `${site}common--javascript/resize-iframe.html?${_rand}#${_new}${url}`; iframe.style.display = "none"; _wrap.appendChild(iframe); _old = _new; } setTimeout(arguments.callee, 50); })(); } var checkwrap = document.querySelector('.checkwrap'); var area = document.querySelector('#area'); var pred = document.querySelector('#pred'); pred.classList.add('hidden'); var wrap = document.querySelector('#wrap'); var admin = document.querySelector('#admin'); var adminBox = title => { var awrap = document.createElement('div'); var header = document.createElement('h2'); var content= document.createElement('div'); awrap.classList.add('adminitem'); awrap.dataset.title = title.toLowerCase().replace(/\s/g, '_'); header.innerHTML = title; admin.appendChild(awrap); awrap.appendChild(header); awrap.appendChild(content); return content; }; var box; var status_wrap = adminBox('Status'); var status_area = document.createElement('textarea'); status_area.readOnly = true; status_wrap.appendChild(status_area); var dfmt = new Intl.DateTimeFormat('en', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }); var _ttStatusArray = []; var ttStatus = class { constructor(label, ...lines) { _ttStatusArray.push(this); this.date = dfmt.format( new Date ); this.label = label; this.update(...lines); } update(...lines) { this.lines = lines; status_area.value = _ttStatusArray .map(s => { var c = s.lines.map(v => ` ${v}\n`).join(''); return `${s.date}: [${s.label}]\n${c}--------`; }) .join('\n'); } }; var main = async () => { var Byte2Str = (n, pre=4) => { var _ = n, lv = 0, p = ['', 'K', 'M', 'G', 'T', 'P']; while(_ > 1024) { _ /= 1024; lv++; if(5 < lv) throw new Error('too big!'); } return `${_.toPrecision(pre)} ${p[lv]}B`;; }; var loading = new ttStatus('init'); var cb = (() => { var loaded = []; return (langs, l) => { loaded.push(l); loading.update( ...langs .map(v => `${ (v + ' ').slice(0, 5) }: ${ -1 < loaded.indexOf(v) ? 'Loaded' : 'Now loading...' }`) ); } })(); var init = await tagInit(cb, (l, e) => {new ttStatus('error', `loading error: [${l}]`)}); var bytes = await Fetch.getAllBytes(); new ttStatus('init', `${Byte2Str(bytes)} transferred`); area.disabled = false; var _predictions = Object.keys(init.tags); console.log(init); var getItems = () => EXEC(area.value, /(?:^|\s*)([^\s,]+)(?:,?\s*|$)/g); var _viewTA_flag; var ClickEvent = e => { if(e.target.__item__) { var range = document.createRange(); range.selectNode(e.target); window.getSelection().removeAllRanges(); window.getSelection().addRange(range); return; } var _box = e.target.__area__ ? e.target : e.target.parent?.__area__ ? e.target.parent : null; if(!e.target.__focus__) { for(var k in box) { box[k].__area__.remove(); [...box[k].children] .filter(v => v != box[k].__area__) .forEach(s => s.removeAttribute('style')); } } else return; if(!_box) return (_viewTA_flag = null); if(_viewTA_flag && _viewTA_flag == _box) return (_viewTA_flag = null); _viewTA_flag = _box; var span = [..._box.children] .filter(v => v != _box.__area__); span.forEach(s => (s.style.display = 'none')); _box.appendChild(_box.__area__); _box.__area__.value = span.map(v => v.innerText).join(' '); _box.__area__.focus(); _box.__area__.select(); }; box = ['__ORIGIN__', ...init.lang].reduce((p, v) => { var div = document.createElement('div'); var ta = document.createElement('textarea'); wrap.appendChild(div); div.__area__ = ta; ta.__focus__ = true; ta.readOnly = true; div.dataset.lang = v; p[v] = div; var _w = document.createElement('div'); var input = document.createElement('input'); input.type = 'checkbox'; input.id = v; input.checked = true; var label = document.createElement('label'); label.htmlFor = v; if(v == '__ORIGIN__') { label.dataset.origin = true; label.dataset.len = Object.keys(init.tags) .map(k => init.tags[k]) .filter((v, i, a) => a.indexOf(v) == i) .length; }else { label.dataset.len = Object.keys(init.ltag[v]).length; } _w.appendChild(input); _w.appendChild(label); checkwrap.appendChild(_w); input.onchange = e => { box[e.target.id].classList.toggle('hidden'); }; return p; }, {}); var Check = () => { localStorage.setItem('tagTransVer2', area.value); var items = getItems().map(v => v[1]); for(var k in box) { box[k].innerHTML = ''; for(var v of items) { var span = document.createElement('span'); var res = init.tags[v]?.[k]; span.__item__ = true; span.innerText = res || v; res ? (span.title = init.tags[v].__ORIGIN__) : span.classList.add('unknown'); box[k].appendChild(span); } } }; var Predict = () => { var items = getItems() .map(v => {return {i: [v.index, v.index + v[1].length], value: v[1]}}); var sels = area.selectionStart; var curs = items.find(v => v.i[0] < sels && sels <= v.i[1]); pred.classList.add('hidden'); if(curs) { var r = new RegExp(`^${curs.value.replace(/(\.)/g, '\\$1')}`); var preds = _predictions .filter(v => v.match(r) && v != curs.value) .sort().slice(0, 5); if(preds.length) (pred.innerHTML = ''); else return pred.classList.add('hidden'); var bef = area.value.slice(0, curs.i[0]); var aft = area.value.slice(curs.i[1]); for(var p of preds) { var a = document.createElement('a'); a.innerHTML = p; a.__val__ = p; pred.appendChild(a); a.onclick = e => { var v = e.target.__val__.trim(); area.value = bef + v + aft; area.setSelectionRange(curs.i[0], curs.i[0] + v.length); area.focus(); Check(); }; } pred.classList.remove('hidden'); var pos = getCaretPosition(area); var x = pos.left + pred.clientWidth; pred.style.top = pos.top; pred.style.left = x < area.clientWidth ? pos.left : area.clientWidth - pred.clientWidth; } }; var bug_fix = adminBox('Logs Of Manual Modifications'); var bfarea = document.createElement('textarea'); bfarea.readOnly = true; for(var l in init.bug) { bfarea.value += `[ ${l} ]\n`; for(var b of init.bug[l]) { bfarea.value += ` ${b}\n`; } bfarea.value += '\n'; } bug_fix.appendChild(bfarea); var missing_tags = adminBox('Missing Tags'); var mtagsel = document.createElement('select'); var mtagleft = document.createElement('button'); mtagleft.innerText = '<'; var mtagind = document.createElement('input'); var mtagright = document.createElement('button'); mtagright.innerText = '>'; var mtaglen = document.createElement('span'); mtaglen.innerText = ' - '; mtagind.type = 'number'; mtagind.step = 2; mtagind.min = 0; mtagind.max = 4; mtagind.value = 4; mtagleft.onclick = e => { var n = Number(mtagind.value) - 2; mtagind.value = n < 0 ? 0 : n; MTag(); }; mtagright.onclick = e => { var n = Number(mtagind.value) + 2; mtagind.value = 4 < n ? 4 : n; MTag(); }; for(var l of ['', ...init.lang]) { var opt = document.createElement('option'); opt.innerHTML = l || '-- select --'; opt.value = l; mtagsel.appendChild(opt); } var mtagarea = document.createElement('textarea'); mtagarea.readOnly = true; missing_tags.appendChild(mtagsel); missing_tags.appendChild(mtagleft); missing_tags.appendChild(mtagind); missing_tags.appendChild(mtagright); missing_tags.appendChild(mtaglen); missing_tags.appendChild(mtagarea); var _MTagCache = {}; var MTag = e => { var lang = mtagsel.value; if(lang == '') { mtaglen.innerText = ' - '; mtagarea.value = ''; return; } var obj = _MTagCache[lang] || Object.keys(init.tags) .map(k => init.tags[k]) .filter(v => !v[lang]) .filter((v, i, a) => a.indexOf(v) == i); _MTagCache[lang] = obj; mtaglen.innerText = obj.length; mtagarea.value = JSON.stringify(obj, null, parseInt(mtagind.value)) }; // Event ['click', 'focus', 'input'].forEach(e => area.addEventListener(e, Predict)); area.addEventListener('input', Check); Predict(); document.addEventListener('click', ClickEvent); [mtagsel, mtagind].forEach(e => e.addEventListener('change', MTag)); // sample area.value = localStorage.getItem('tagTransVer2') || 'automate bâtiment connaissance daevite document espace-temps euclide historique humanoïde'; Check(); }; try { main(); }catch(e) { new ttStatus('error', e + ''); throw e; }
var Tags = {}; var AllTags = {}; var LangTags = {}; var BugFix = {}; var BugReport = (lang, msg) => { BugFix[lang] = BugFix[lang] || []; BugFix[lang].push(msg); console.log(`[ ${lang} ]: ${msg}`); }; var Text = lang => (new Fetch(SRC_URL[lang])).text(); var combine = (p, v) => Object.assign(p, v); var toOBJ = (main, other) => { return (p, v) => { var _1 = main.map(x => v[x]).find(v => v); var _2 = other.map(x => v[x]).find(v => v); p[_1.trim()] = _2.trim(); return p; }; }; var FindTag = (name, lang) => { var tags = Object.keys(Tags).map(k => Tags[k]); for(var tag of tags) { var tgt = Object.keys(tag).find(k => lang ? tag[k] == name && k == lang : tag[k] == name); if(tgt) return tag; } return; }; var FindAllTags = name => { var res = [], tags = Object.keys(Tags).map(k => Tags[k]); for(var tag of tags) { var tgt = Object.keys(tag).find(k => tag[k] == name); tgt && res.push(tag); } return res; }; var UpdateTags = (lang, obj, debug=false) => { var nonlower = -1 < ['JP'].indexOf(lang); return error_cb => { try { if(debug) return console.log(lang, obj); LangTags[lang] = LangTags[lang] || {}; for(var t in obj) { var _t = (nonlower ? t : t.toLowerCase()).trim(); var _v = (nonlower ? obj[t] : obj[t].toLowerCase()).trim(); Tags[_t] = Tags[_t] || FindTag(_t) || FindTag(_v) || {__ORIGIN__: _t}; Tags[_t][lang] = _v; AllTags[_t] = Tags[_t]; AllTags[_v] = Tags[_t]; LangTags[lang][_t] = Tags[_t]; } }catch(e) { error_cb && error_cb(lang, e); throw e; } } }; var getINTtags = async () => { var t = await Text('INT'); var str = t.replace(/\/{2}|\*{2}/g, ''); // document.body.innerHTML = `<pre>${str}</pre>`; return () => { var ary = str.split(/\n\+ [^\n]+/) .map(v => v.split('\n') .map(v => v.trim()) .filter(v => v && v.match(/^\|{2}.+?\|{2}$/)) .map(v => v.split('||').map(v => v.trim()).slice(1, -1))) .filter(v => v.length); var res = [].concat( ...ary.map(items => { var label = items.shift() .map(v => ({PT: 'PTBR', ZH: 'ZHTR'})[v] || v); return items.map(item => item.map((v, i) => v ? {[label[i]]: v} : {}).reduce(combine)); }) ).map(o => (o.EN && (o.EN = o.EN.match(/\[.+? (.+?)\]/)[1]), o)); var ary = []; for(var x of res) { delete x.Description; var tgt = Object.keys(x) .map(k => { var t = FindTag(x[k], k); return t && t[k] == x[k] && t; }) .filter((v, i, a) => v && a.indexOf(v) == i); tgt = tgt.filter(v => { var n = v.__ORIGIN__; if(n == 'inscribed' || n == 'inscription') return 0; if(n == 'oryginał' || n == '原创') return 0; if(n == 'structure' || n == 'building') return 0; if(n == 'essay' || n == 'guide') return 0; return 1; }); if(1 < tgt.length) { console.log(tgt); var abs = x.EN ? tgt.find(v => v.__ORIGIN__ != x.EN) : tgt[0]; var oth = tgt.filter(v => abs != v); var oth_clone = oth .map(v => v && { ...v, __ORIGIN__: abs.__ORIGIN__ }); oth.forEach(v => { var n = v.__ORIGIN__; for(var k in AllTags[n]) { if(k == '__ORIGIN__') continue; var t = AllTags[n][k]; AllTags[t] = abs; LangTags[k][t] = abs; } }); for(var k in x) { AllTags[x[k]] = abs; LangTags[k] = LangTags[k] || {}; LangTags[k][x[k]] = abs; } var _x = x; if([ 'unclassed', 'guide', 'explained', 'workbench', 'co-authored', 'archived', 'goi-format', 'joke', 'neutralized', 'safe', 'thaumiel', 'goi2019', 'visual', 'telepathic', ].indexOf(x.EN) > -1) { BugReport('INT', `Set Origin: ${x.EN}`); _x = {...x, __ORIGIN__: x.EN}; } Object.assign(abs, ...oth_clone, _x); console.log(abs); } var obj = Object.keys(x) .map(k => FindTag(x[k], k)) .find(v => v); if(obj) { Object.assign(obj, x); ary.push(obj); for(var k in obj) { var tag = obj[k]; AllTags[tag] = obj; if(k == '__ORIGIN__') continue; LangTags[k] = LangTags[k] || {}; LangTags[k][tag] = obj; } } } return ary; } }; var tagInit = async (callback, error_callback) => { var langs = ['RU', ...Object.keys(getTags)]; var promise = Object.keys(getTags).map(async k => { var r = await getTags[k](); callback(langs, k); return r; }); var _int = getINTtags(); await Promise.all([_int, ...promise]); for(var fn of promise) (await fn)(error_callback); try { var int = (await _int)(); }catch(e) { error_callback && error_callback('INT (RU)', e); throw e; } console.log(int); var RU = int.filter(v => v.RU) .reduce((p, v) => (p[v.__ORIGIN__] = v, p), {}); var obj_RU = Object.keys(RU) .map(v => v && {[v]: RU[v].RU}) .reduce(combine); UpdateTags('RU', obj_RU)(); callback(langs, 'RU'); return { tags: AllTags, lang: langs, ltag: LangTags, bug: BugFix }; }; var getTags = {}; // KO getTags.KO = async (debug=false) => { var t = await Text('KO'); var obj = EXEC(t, /\n\|{2,6} ?(?:(.+?) ?\|{2}.*?|)\[\*\/system:page\-tags\/tag\/(.+?) /g) .reduce(toOBJ([1, 2], [2]), {}); return UpdateTags('KO', obj, debug); }; // CN getTags.CN = async (debug=false) => { var t = await Text('CN'); var tabview = new TAB_VIEWS(t.replace(/\/{2}|\*{2}/g, '')); var obj = tabview.getAllTabs() .map(v => [ ...EXEC(v, /\[\S*?\/system:page-tags\/tag\/.*? (.+?)\](?: ?\((?:\[\S*?\/system:page-tags\/tag\/.*? (.+?)\]|(.+?))\) ?|)/g) ].reduce(toOBJ([3, 2, 1], [1]), {})) .reduce(combine); // fix if(obj['os-tecnotaumaturgos']) { BugReport('CN', 'Incorrect Translation: os-tecnotaumaturgos -> tecnotaumaturgos'); obj['tecnotaumaturgos'] = obj['os-tecnotaumaturgos']; delete obj['os-tecnotaumaturgos']; } return UpdateTags('CN', obj, debug); }; // FR getTags.FR = async (debug=false) => { var t = await Text('FR'); var tabviews = new TAB_VIEWS(t); var obj = tabviews.getAllTabs() .map(t => EXEC(t, /(?:\*{2}|) ?\[\/system:page-tags\/tag\/.+? (.+?)] ?(?:\*{2}|) *(?:(?:\- )?\(\*{2}[a-z]+ :\*{2} "(.+?)"|)/ig) .reduce(toOBJ([2, 1], [1]), {})) .reduce(combine); // fix if(obj['adaptative']) { BugReport('FR', 'Incorrect Translation: adaptative -> adaptive'); obj['adaptive'] = obj['adaptative']; delete obj['adaptative']; } if(obj['五行结社']) { BugReport('FR', 'Incorrect Translation: 五行结社 -> 五行結社'); obj['五行結社'] = obj['五行结社']; delete obj['五行结社']; } if(obj['负号部队']) { BugReport('FR', 'Incorrect Translation: 负号部队 -> 負号部隊'); obj['負号部隊'] = obj['负号部队']; delete obj['负号部队']; } return UpdateTags('FR', obj, debug); }; // PL getTags.PL = async (debug=false) => { var t = await Text('PL'); var obj = EXEC(t, /(?:\*{2}|) ?\[\/system:page-tags\/tag\/(.+?) .+?] ?(?:\*{2}|) (?:\((.+?)\)|)/ig) .map(v => (v[1] = v[1].replace(/#pages/, ''), v)) .reduce(toOBJ([2, 1], [1]), {}); return UpdateTags('PL', obj, debug); }; // ES getTags.ES = async (debug=false) => { var t = await Text('ES'); //var str = t.replace(/\/{2}|\*{2}/g, ''); //document.body.innerHTML = `<pre>${str}</pre>` var tabs = new TAB_VIEWS(t.replace(/\/{2}|\*{2}/g, '')).getAllTabs(); var main = EXEC(tabs.select('Etiquetas Principales'), /\[\/system:page-tags\/tag\/.+? (.+?)\](?: [\-|\–] (\S+?) ?[\-|\–|\n]|)/g); var attr = EXEC(tabs.select('Etiquetas Atributivas'), /\[\/system:page-tags\/tag\/.+? (.+?)\] \((.+?)\)/g); var other = EXEC(tabs.select('Otras'), /\[\/system:page-tags\/tag\/.+? (.+?)\] (?:(?:[\-|\–] |)\((.+?)\)|[\-|\–] ([^\sA-Z]+?) ?\n|)/g); var obj = [main, attr, other].map(v => v.reduce(toOBJ([3, 2, 1], [1]), {})) .reduce(combine); return UpdateTags('ES', obj, debug); }; // JP getTags.JP = async (debug=false) => { var t = await Text('JP'); var tabviews = new TAB_VIEWS(t); var obj = tabviews.getAllTabs() .filter(v => [ '使用されていないタグ', '廃止されたタグ' ].indexOf(v.title) < 0) .map(v => EXEC(v, /\*{2}\[{3}.+?\|(.+?)\]{3}\*{2}(?: \/{2}\((.+?)\)\/{2}|)/g) .reduce(toOBJ([2, 1], [1]), {})) .reduce(combine); return UpdateTags('JP', obj, debug); }; // DE getTags.DE = async (debug=false) => { var t = await Text('DE'); var tabs = new TAB_VIEWS(t).getAllTabs(); var tags = tabs.select('Tags - Alphabetisch nach DE'); var obj = EXEC(tags, /\n(\S+?) \- ([^\s\[]+)/g) .reduce(toOBJ([1], [2]), {}); return UpdateTags('DE', obj, debug); }; // IT getTags.IT = async (debug=false) => { var t = await Text('IT'); var tabs = new TAB_VIEWS(t).getAllTabs(); var obj = EXEC(tabs.select('Traduzione dei tag'), /\n\|{2} ?(.+?) ?\|{2} ?(.*?) ?\|{2}/g) .reduce(toOBJ([1], [2, 1]), {}); return UpdateTags('IT', obj, debug); }; // UA getTags.UA = async (debug=false) => { var t = await Text('UA'); var obj = EXEC(t, /\*{2}(.+?)\*{2} \((.+?)\) /g) .reduce(toOBJ([2], [1]), {}); return UpdateTags('UA', obj, debug); }; // PTBR getTags.PTBR = async (debug=false) => { var t = await Text('PTBR'); var tab = new TAB_VIEWS(t).getAllTabs().select('Tags Traduzidas'); var obj = EXEC(tab, /\n(.+?) \- \[{3}\/system:page-tags\/tag\/.+?\|(.+?)\]{3}/g) .reduce(toOBJ([1], [2]), {}); return UpdateTags('PTBR', obj, debug); }; // ZHTR getTags.ZHTR = async (debug=false) => { var t = await Text('ZHTR'); var obj = EXEC(t.replace(/\/{2}|\*{2}/g, ''), /\[\*?\/system\:page-tags\/tag\/(.+?) .+?](?: ?- ?\((.+?)\)|)/g) .reduce(toOBJ([2, 1], [1]), {}); return UpdateTags('ZHTR', obj, debug); }; // VN getTags.VN = async (debug=false) => { var t = await Text('VN'); var obj = [ ...EXEC(t, /\n(.+?): \*{2}(.+?)\*{2}/g), ...EXEC(t, /\n.+? \((.+?)\) \*{2}(.+?)\*{2}/g) ].reduce(toOBJ([1], [2]), {}); // fix if(obj['shinano-chuo-simbun']) { BugReport('VN', 'Incorrect Format: shinano-chuo-simbun -> 信濃中央新聞'); obj['信濃中央新聞'] = obj['shinano-chuo-simbun']; delete obj['shinano-chuo-simbun']; } return UpdateTags('VN', obj, debug); };
var sleep = ms => new Promise(r => setTimeout(r, ms)); var SITE_ID = { KO : 486864, CN : 530812, FR : 464696, PL : 647733, ES : 560484, JP : 578002, DE : 1269857, IT : 530167, UA : 1398197, PTBR: 783633, ZHTR: 3947998, VN : 836589, INT : 1427610, }; var SRC_URL = Object.keys(SITE_ID) .map((v, i) => [v, i + 1]) .reduce((p, v) => { p[ v[0] ] = `/local--code_/trans-tags-ver2-src/${v[1]}`; return p; }, {}); var _FetchStock = []; var Fetch = class { constructor(url, option={}) { this.fetch = Fetch._retry(url, option); _FetchStock.push(this); } async request() { return (await this.fetch).clone(); } async getBytes() { var buf = await this.arrayBuffer(); var u8a = new Uint8Array(buf); return u8a.length; } static async _retry(url, option, interval = 250) { try { return await fetch(url); }catch(e) { await sleep(interval); return await Fetch._retry(url, interval); } } static async getAllBytes() { return (await Promise.all( _FetchStock.map(f => f.getBytes()) )) .reduce((a, b) => a + b); } }; ['text', 'json', 'blob', 'arrayBuffer', 'formData'] .forEach(m => { Fetch.prototype[m] = async function() { return await (await this.request())[m](); }; }); // var STRIP = str => str.replace(/\[\!--[\s\S]+?--\]/g, ''); var EXEC = (str, reg) => { var _ = [], x; if(!reg.flags.match('g')) throw new Error('Group Flag Required'); while(x = reg.exec(str)) _.push(x); return _; }; var rTABVIEW = /\[{2}tabview\]{2}([\s\S]+?)\[{2}\/tabview\]{2}/g; var rTAB = /\[{2}tab(| .+?)\]{2}([\s\S]+?)\[{2}\/tab\]{2}/g; var TAB = class { constructor(title, content) { this.title = title; this.content = content; } toString() { return this.content; } }; var TAB_VIEW = class extends Array { constructor(str='') { super(); this.push( ...EXEC(str, rTAB).map(v => new TAB(v[1].trim(), v[2].trim())) ); } select(title) { return this.find(v => v.title == title); } selectAll(title) { return this.filter(v => v.title == title); } }; var TAB_VIEWS = class extends Array { constructor(str='') { super(); this.push( ...EXEC(str, rTABVIEW).map(v => new TAB_VIEW(v[1])) ); } getAllTabs() { var tv = new TAB_VIEW; this.map(v => v.map(v => tv.push(v))); return tv; } }; var rATTR = /(class|style|data\-[\da-z\-_\.\:]+)(?:\="(.+?)"|) ?/ig; var DIV = class { constructor(content, attr) { this.content = content; this._attr = attr.trim() || ''; } get attr() { return EXEC(this._attr, rATTR) .reduce((p, v) => (p[ v[1] ] = v[2], p), {}); } get class() { return (this.attr.class || '').split(' ').filter(v => v); } hasClass(name) { return !!this.class.find(v => v == name); } style(reg) { return !!(this.attr.style || '').match(reg); } toString() { return this.content.trim(); } }; var rDIVLIST_ST = /\[{2}div( .+?)?\]{2}/g; var rDIVLIST_ED = /\[{2}\/div\]{2}/g; var DIV_LIST = class { constructor(str) { var _str = (str || '').replace(/\[\!\-{2}[\s\S]*?\-{2}\]/g, ''); var divs = EXEC(_str, rDIVLIST_ST) .map(v => (v.st = true, v)); divs.push( ...EXEC(_str, rDIVLIST_ED) ) divs = divs.sort((a, b) => a.index > b.index ? 1 : -1); var st = divs.shift(), ed, i_st = 1, i_ed = 0, tags = [], next = false; if(st && !st.st) throw new Error('no'); for(var t of divs) { next && (next = false, st = t) t.st ? i_st++ : (i_ed++, ed = t); if(i_st == i_ed) { var cont = _str.slice(st[0].length + st.index, ed.index); var d = new DIV(cont, st[1]); tags.push(d); if(1 < i_st) { d.children = new DIV_LIST(cont); for(var c of d.children.tags) (c.parent = d, tags.push(c)); } next = true; i_st = i_ed = 0; } } this.tags = tags; } getDivsByClass(name) { return this.tags.filter(v => v.hasClass(name)); } getDivsByStyle(name) { return this.tags.filter(v => v.style(name)); } }; var getCaretPosition = textarea => { var div = document.createElement('div'); document.body.appendChild(div); var styles = getComputedStyle(textarea); div.style.whiteSpace = 'pre-wrap'; div.style.wordWrap = 'break-word'; div.style.position = 'absolute'; div.style.visibility = 'hidden'; ['direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'borderStyle', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing', 'tabSize', 'MozTabSize'] .forEach(p => (div.style[p] = styles[p])); if(window.mozInnerScreenX != null) { textarea.scrollHeight > parseInt(styles.height) && (div.style.overflowY = 'scroll'); }else { div.style.overflow = 'hidden'; } var i = textarea.selectionStart - 1; div.textContent = textarea.value.substring(0, i) + '\u200b'; var span = document.createElement('span'); div.appendChild(span); span.style.display = 'inline-block'; span.textContent = textarea.value.substring(i, i + 1) || '.'; var res = { top: (span.offsetTop + span.offsetHeight + parseInt(styles.borderTopWidth)) - textarea.scrollTop, left: span.offsetLeft + parseInt(styles.borderLeftWidth) }; div.remove(); return res; };
::-webkit-scrollbar { display: none; } span { color: #3f3; display: block; font-family: Courier, monospace; font-size: .8em; font-style: italic; } textarea::-webkit-scrollbar { display: block; width: 11px; height: 11px; } textarea::-webkit-scrollbar-thumb { background: rgba(50, 50, 50, 0.6); } textarea::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.05); } textarea:hover::-webkit-scrollbar-thumb { background: rgba(50, 50, 50, 0.75); border-radius: 3px; } body { background: rgb(70, 70, 70); font-family: sans-serif; margin: 0 .75em; } .content { padding: .75em .35em; } .checkwrap { padding: 0.5em 0; } .checkwrap > div { display: inline-block; padding: 0.15em; width: 4.15em; } .checkwrap > div > input { display: none; } .checkwrap > div > input:checked + label { background: rgb(76, 139, 245); } .checkwrap > div > input:checked + label[data-origin] { background: rgb(245, 139, 76); } .checkwrap > div > label { background: rgba(0, 0, 0, .2); border-radius: 2.5em; box-shadow: 0 1px 1px rgba(255, 255, 255, .15), inset 0 0 0 1px rgba(0, 0, 0, .5), inset 0 0 3px #333, inset 1px 1px 3px #333; cursor: pointer; display: inline-block; font-family: Courier, monospace; height: 2.5em; overflow: hidden; padding: 0.1em; position: relative; transition: .25s all; width: 100%; } .checkwrap > div > label::before { align-items: center; background: rgb(70, 70, 70); border-radius: 50%; box-shadow: 0 1px 1px rgba(255, 255, 255, .15), inset 0 0 0 1px rgba(0, 0, 0, .5), inset 0 0 3px #333, inset 1px 1px 3px #333; box-sizing: border-box; color: #ddd; content: attr(for); display: flex; font-size: .5em; font-weight: bold; height: 2.5rem; justify-content: center; left: 1px; position: absolute; text-align: center; transition: all .2s; vertical-align: middle; width: 2.5rem; } .checkwrap > div > label:hover::before, .checkwrap > div > input:checked + label::before { color: rgb(76, 139, 245); text-shadow: 0 0 3px rgb(102, 204, 255), 0 0 2px #000; } .checkwrap > div > label[data-origin]:hover::before, .checkwrap > div > input:checked + label[data-origin]::before { color: rgb(245, 139, 76); text-shadow: 0 0 3px rgb(255, 204, 102), 0 0 2px #000; } .checkwrap > div > input:checked + label::before { box-shadow: 0 1px 1px rgba(255, 255, 255, .15), inset 0 0 0 1px rgba(0, 0, 0, .5), inset 0 0 3px #555, inset 1px 1px 3px #555; left: calc(100% - 2.5rem - 1px); } .checkwrap > div > label[data-origin]::before { content: '__'; } .checkwrap > div > label::after { align-items: center; content: attr(data-len); color: transparent; display: flex; font-size: .6em; height: 2.5rem; padding: 0 0 0 0.2em; transition: .25s all; } .checkwrap > div > input:checked + label::after { color: #fff; } .areawrap { position: relative; } textarea#area { box-shadow: 1px 1px 3px #000; flex-grow: 1; font-family: sans-serif; font-size: 16px; height: 150px; } input[type="number"], select, button { background: rgba(255, 255, 255, .1); border: none; box-shadow: 1px 1px 3px #555; color: #3f3; cursor: pointer; margin: .2em; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; -moz-appearance:textfield; } button:hover { background: rgba(255, 255, 255, .15); } option { background: rgba(70, 70, 70, .8); } textarea { appearance: none; -webkit-appearance: none; -moz-appearance: none; background: rgba(255, 255, 255, .1); color: #3f3; border: none; border-radius: 0; box-shadow: 1px 1px 3px #555; display: block; margin: 0; padding: 1em; resize: none; transition: all .25s; width: 100%; } input:focus, select:focus, textarea:focus { outline: 1px solid #4c8bf5; } div#pred { background: rgba(70, 70, 70, .9); border: 1px dashed #aaa; display: flex; flex-wrap: wrap; font-size: .7em; margin: .5em 0; padding: .5em; position: absolute; text-align: center; width: 12em; } div#pred.hidden { display: none; } div#pred > * { align-items: center; display: flex; flex-grow: 1; height: 2em; justify-content: center; vertical-align: middle; } div#pred > a { background: rgba(255, 255, 255, .1); border: 1px dashed #aaa; border-radius: 3px; color: #3f3; cursor: pointer; font-family: Courier, monospace; font-size: .8em; margin: 0.25em; padding: 0.25em 0.5em; transition: all .25s; word-break: break-word; width: 7em; } div#pred > a:hover { background: rgba(255, 255, 255, .2); } div#pred > pre { font-family: Courier, monospace; font-size: .8em; margin: 0.25em; padding: calc(0.25em + 1px) 0.5em; white-space: pre-wrap; } div#wrap > div { background: rgba(255, 255, 255, .1); box-shadow: 1px 1px 3px #000; cursor: pointer; font-size: .7em; margin: 1em 0; padding: 0.5em; } div#wrap > div::before { color: #999; content: attr(data-lang); display: block; font-weight: bold; padding: 0.75em 0; text-align: center; } div#wrap > div.hidden { display: none; } div#wrap > div > textarea { font-family: sans-serif; font-size: 16px; width: 100%; } div#wrap > div span { border: 1px solid #ddd; border-radius: 3px; color: #eee; display: inline-block; margin: 0.25em; padding: 0.25em 0.5em; } div#wrap > div span::before { content: '\f058'; color: lightgreen; font: normal normal normal 14px/1 FontAwesome; font-size: inherit; padding: 0 0.25em 0 0; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; transform: translate(0, 0); } div#wrap > div span.unknown::before { content: '\f057'; color: lightcoral; } /* admin */ div#admin { background: rgba(255, 255, 255, .1); box-shadow: 1px 1px 3px #000; padding: .25em .5em; } h1, h2 { color: #3d3; font-family: "Trebuchet MS", Trebuchet, Verdana, Arial, Helvetica; font-weight: bold; margin: 0.6em 0; padding: 0; } h1 { font-size: 1.7em; } h2 { font-size: 1.3em; } .adminitem { background: rgba(255, 255, 255, .1); border: 1px dashed #aaa; border-radius: 0.5em; margin: 0.5em 0; padding: 0 0.5em 0.5em; } .adminitem textarea { font-family: Courier, monospace; font-size: .5em; height: 18em; } .adminitem[data-title="status"] textarea { font-size: .4em; height: 200px; } .adminitem input[type="number"], .adminitem button { font-family: Courier, monospace; text-align: center; } .adminitem input[type="number"] { pointer-events: none; }
- INT (RU): http://scp-int.wikidot.com/tag-guide
- -RU wiki has its own tag guide page; However, the wiki prohibits cross-site [[include]], so the tool can't access the page.
- KO: http://scpko.wikidot.com/translate:tags
- CN: http://scp-wiki-cn.wikidot.com/tag-guide
- FR: http://fondationscp.wikidot.com/guide-des-tags
- PL: http://scp-pl.wikidot.com/tag-guide
- ES: http://lafundacionscp.wikidot.com/tag-guide
- JP: http://scp-jp.wikidot.com/tag-list
- DE: http://scp-wiki-de.wikidot.com/tag-guide
- IT: http://fondazionescp.wikidot.com/tag-guide
- UA: http://scp-ukrainian.wikidot.com/tag-guide
- PTBR: http://scp-pt-br.wikidot.com/tag-guide
- ZHTR: http://scp-zh-tr.wikidot.com/tag-guide
- VN: http://scp-vn.wikidot.com/tag-guide-for-translator
TH: The wiki usually uses English tags.
CS: The wiki doesn't have a tag guide page and an official tagging rule.






