Benutzer:ExURLBot/Diffbaustelle.js
Zur Navigation springen
Zur Suche springen
Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.
- Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
- Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
- Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//Copy für Testzwecke von Benutzer:Schnark/js/diff.js <nowiki>
/*global mediaWiki, ve*/
(function ($, mw, libs) {
"use strict";
var l10n = {
en: {
'schnark-diff-button': 'Δ',
'schnark-diff-button-tooltip': 'improved diff',
'schnark-diff-tab-normal': 'D',
'schnark-diff-tab-normal-tooltip': 'normal diff',
'schnark-diff-tab-improved': 'Δ',
'schnark-diff-tab-improved-tooltip': 'improved diff',
'schnark-diff-tab-config': '⌨',
'schnark-diff-tab-config-tooltip': 'settings',
'schnark-diff-config-moves': 'Show moved blocks: ',
'schnark-diff-config-moves-normal': 'normal',
'schnark-diff-config-moves-nested': 'nested',
'schnark-diff-config-moves-none': 'no',
'schnark-diff-config-moves-simple': 'simple',
'schnark-diff-config-char-diff': 'Number of rounds for diff on character level: ',
'schnark-diff-config-word-diff-qual': 'Quality of diffs on character level (0–100): ',
'schnark-diff-config-recursion': 'Number of recursions: ',
'schnark-diff-config-too-short': 'Length of a short word: ',
'schnark-diff-config-small-region': 'Length of a small region: ',
'schnark-diff-config-min-moved-length': 'Minimal length for a moved block: ',
'schnark-diff-config-color-scheme': 'Color scheme: ',
'schnark-diff-config-color-scheme-classic': 'Classic (red/green)',
'schnark-diff-config-color-scheme-modern': 'Modern (yellow/blue)',
'schnark-diff-config-color-scheme-wiked': 'wikEd (yellow/blue, moves in gray)',
'schnark-diff-config-save': 'Save settings',
'schnark-diff-config-reset': 'Use defaults',
'schnark-diff-version': 'Version: $1/$2'
},
'en-gb': {
'schnark-diff-config-color-scheme': 'Colour scheme: ',
'schnark-diff-config-color-scheme-wiked': 'wikEd (yellow/blue, moves in grey)'
},
de: {
'schnark-diff-button-tooltip': 'Verbesserter Diff',
'schnark-diff-tab-normal-tooltip': 'Normaler Diff',
'schnark-diff-tab-improved-tooltip': 'Verbesserter Diff',
'schnark-diff-tab-config-tooltip': 'Einstellungen',
'schnark-diff-config-moves': 'Anzeige von Verschiebungen: ',
'schnark-diff-config-moves-nested': 'verschachtelt',
'schnark-diff-config-moves-none': 'gar nicht',
'schnark-diff-config-moves-simple': 'einfach',
'schnark-diff-config-char-diff': 'Anzahl der Durchgänge für Diff auf Zeichenebene: ',
'schnark-diff-config-word-diff-qual': 'Qualität des Diffs auf Zeichenebene (0–100): ',
'schnark-diff-config-recursion': 'Anzahl der Rekursionen: ',
'schnark-diff-config-too-short': 'Länge eines kurzen Worts: ',
'schnark-diff-config-small-region': 'Größe eines kleinen Bereichs: ',
'schnark-diff-config-min-moved-length': 'Minimale Läge eines verschobenen Blocks: ',
'schnark-diff-config-color-scheme': 'Farbschema: ',
'schnark-diff-config-color-scheme-classic': 'Klassisch (rot/grün)',
'schnark-diff-config-color-scheme-modern': 'Modern (gelb/blau)',
'schnark-diff-config-color-scheme-wiked': 'wikEd (gelb/blau, Verschiebungen grau)',
'schnark-diff-config-save': 'Einstellungen speichern',
'schnark-diff-config-reset': 'Standardwerte verwenden'
},
'de-ch': {
'schnark-diff-config-small-region': 'Grösse eines kleinen Bereichs: '
}
}, config = {
version: 5.1,
css: '.schnark-diff-button {padding: 0.2em 0.5em; margin: -1px 0.4em; display: inline-block;' +
'border: 1px solid #aaa; background-color:#fbfbfb; cursor: pointer;}' +
'.schnark-diff-buttons-top .schnark-diff-button {border-bottom-color: #a7d7f9;}' +
'.schnark-diff-buttons-bottom .schnark-diff-button {border-top-color: #a7d7f9;}' +
'.schnark-diff-button-selected {border-color: #a7d7f9; background-color: #fff;}' +
'.schnark-diff-buttons-top .schnark-diff-button-selected {border-bottom-color: #fff;}' +
'.schnark-diff-buttons-bottom .schnark-diff-button-selected {border-top-color: #fff;}' +
'.schnark-diff-div {padding: 0.5em; border: 1px solid #a7d7f9; background-color: #fff;}' +
'.schnark-diff-container {margin-top: 1em; margin-bottom: 1em;}',
cssSkin: {
monobook: '.schnark-diff-buttons-top .schnark-diff-button {border-bottom-color: #aaa;}' +
'.schnark-diff-buttons-bottom .schnark-diff-button {border-top-color: #aaa;}' +
'.schnark-diff-button-selected {border-color: #fabd23;}' +
'.schnark-diff-buttons-top .schnark-diff-button-selected {border-bottom-color: #fff;}' +
'.schnark-diff-buttons-bottom .schnark-diff-button-selected {border-top-color: #fff;}' +
'.schnark-diff-div {border-color: #aaa;}'
},
alwaysOnEdit: true,
instances: 0
}, colorSchemes = {
classic: {},
modern: {
ins: 'text-decoration: none; color: black; background-color: #a3d3ff;',
del: 'text-decoration: none; color: black; background-color: #ffe49c;',
movedIns: 'text-decoration: none; color: black; background-color: #e1ebf5;',
movedDel: 'text-decoration: none; color: black; background-color: #f2ead7;'
},
wiked: {
ins: 'text-decoration: none; color: black; background-color: #a3d3ff;',
del: 'text-decoration: none; color: black; background-color: #ffe49c;',
movedIns: 'text-decoration: none; color: black; background-color: #e1ebf5;',
movedDel: 'text-decoration: none; color: black; background-color: #f2ead7;',
movedFrom: 'color: #000; text-decoration: none; font-weight: bold; background-color: #ffe49c;',
movedTo: '#e8e8e8',
movedHover: 'color: #fff !important; background-color: #777 !important;',
blocks: [],
additional: '.enhanced-diff-moved-hover .enhanced-diff-equal {color: #fff; background-color: #777;}'
}
}, currentColorScheme, hasOwn = Object.prototype.hasOwnProperty;
function initL10N (l10n) {
var i, chain = mw.language.getFallbackLanguageChain();
for (i = chain.length - 1; i >= 0; i--) {
if (chain[i] in l10n) {
mw.messages.set(l10n[chain[i]]);
}
}
}
function loadDiffJs (callback) {
var load = true;
function callback2 (/*schnarkDiff*/) {
load = false;
mw.hook('userjs.load-script.diff-core').remove(callback2);
libs.schnarkDiff.config.set(
$('body').is('.rtl') ? {
movedLeft: '\u25b6',
movedRight: '\u25c0'
} : {
movedLeft: '\u25c0',
movedRight: '\u25b6'
}
);
callback(/*schnarkDiff*/);
}
mw.hook('userjs.load-script.diff-core').add(callback2);
if (load) {
//</nowiki>[[Benutzer:Schnark/js/diff.js/core.js]]<nowiki>
mw.loader.load('//de.wikipedia.org/w/index.php?title=Benutzer:Schnark/js/diff.js/core.js' +
'&action=raw&ctype=text/javascript');
}
}
function formatVersion (v) {
if (typeof v === 'number' && Math.floor(v) === v) {
return String(v) + '.0';
} else {
return String(v);
}
}
function enableColorScheme (n) {
var backup;
if (n === currentColorScheme) {
return;
}
if (currentColorScheme) {
colorSchemes[currentColorScheme].disabled = true;
}
currentColorScheme = n;
if ($.isPlainObject(colorSchemes[n])) {
backup = libs.schnarkDiff.style.get();
libs.schnarkDiff.style.set(colorSchemes[n]);
colorSchemes[n] = mw.util.addCSS(libs.schnarkDiff.getCSS());
libs.schnarkDiff.style.set(backup);
} else {
colorSchemes[n].disabled = false;
}
}
function getRevisionId ($a) {
var id = null;
$a.each(function () {
if (id === null) {
id = mw.util.getParamValue('oldid', $(this).attr('href'));
}
});
return id;
}
function getRevision (id, section, callback) {
if (callback === undefined) {
callback = section;
section = null;
}
if (!id) {
callback('');
return;
}
var data = {action: 'query', prop: 'revisions', revids: id, rvprop: 'content', indexpageids: '', format: 'json'};
if (section !== null) {
data.rvsection = section;
}
$.getJSON(mw.util.wikiScript('api'), data).always(function (json) {
try {
callback(json.query.pages[json.query.pageids[0]].revisions[0]['*']);
} catch (e) {
callback('');
}
});
}
function configHtml (idPrefix) {
var html = '';
html += mw.html.element('label', {'for': idPrefix + 'config-moves'}, mw.msg('schnark-diff-config-moves')) +
mw.html.element('select', {id: idPrefix + 'config-moves'}, new mw.html.Raw(
mw.html.element('option', {value: 1}, mw.msg('schnark-diff-config-moves-normal')) +
mw.html.element('option', {value: -1}, mw.msg('schnark-diff-config-moves-nested')) +
mw.html.element('option', {value: 0}, mw.msg('schnark-diff-config-moves-none')) +
mw.html.element('option', {value: 2}, mw.msg('schnark-diff-config-moves-simple'))
)) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-char-diff'}, mw.msg('schnark-diff-config-char-diff')) +
mw.html.element('input', {id: idPrefix + 'config-char-diff', size: 4, type: 'text'}) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-word-diff-qual'},
mw.msg('schnark-diff-config-word-diff-qual')) +
mw.html.element('input', {id: idPrefix + 'config-word-diff-qual', size: 4, type: 'text'}) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-recursion'}, mw.msg('schnark-diff-config-recursion')) +
mw.html.element('input', {id: idPrefix + 'config-recursion', size: 4, type: 'text'}) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-too-short'}, mw.msg('schnark-diff-config-too-short')) +
mw.html.element('input', {id: idPrefix + 'config-too-short', size: 4, type: 'text'}) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-small-region'},
mw.msg('schnark-diff-config-small-region')) +
mw.html.element('input', {id: idPrefix + 'config-small-region', size: 4, type: 'text'}) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-min-moved-length'},
mw.msg('schnark-diff-config-min-moved-length')) +
mw.html.element('input', {id: idPrefix + 'config-min-moved-length', size: 4, type: 'text'}) + '<br />';
html += mw.html.element('label', {'for': idPrefix + 'config-color-scheme'}, mw.msg('schnark-diff-config-color-scheme')) +
mw.html.element('select', {id: idPrefix + 'config-color-scheme'}, new mw.html.Raw(
mw.html.element('option', {value: 'classic'}, mw.msg('schnark-diff-config-color-scheme-classic')) +
mw.html.element('option', {value: 'modern'}, mw.msg('schnark-diff-config-color-scheme-modern')) +
mw.html.element('option', {value: 'wiked'}, mw.msg('schnark-diff-config-color-scheme-wiked'))
)) + '<br /><br />';
html += mw.html.element('button', {id: idPrefix + 'config-save'}, mw.msg('schnark-diff-config-save')) + ' ';
html += mw.html.element('button', {id: idPrefix + 'config-reset'}, mw.msg('schnark-diff-config-reset'));
html += mw.html.element('span', {style: 'float:right;'},
mw.msg('schnark-diff-version', formatVersion(config.version), formatVersion(libs.schnarkDiff.version)));
return html;
}
function EnhancedDiff (oldid, newid, $standardDiff, editData) {
config.instances++;
this.optionsPrefix = 'userjs-schnark-diff-';
this.oldid = oldid;
this.oldText = false;
this.newid = newid;
this.newText = false;
this.$standardDiff = $standardDiff;
this.idPrefix = 'schnark-diff-' + config.instances + '-';
if (editData) {
this.$container = editData.$container;
this.section = editData.section;
this.$textbox = editData.$textbox;
}
}
EnhancedDiff.prototype = {
getOldText: function (callback) {
var self = this;
if (this.oldText !== false) {
callback(this.oldText);
return;
}
if (this.oldid === 'conflict') {
mw.loader.using('jquery.textSelection', function () {
var text = $('#wpTextbox2').textSelection('getContents').replace(/\s+$/, '');
self.oldtext = text;
callback(text);
});
return;
}
if (this.newid === 'edit' || this.newid === 've') {
if (this.section === 'new' || this.oldid === 0) {
this.oldText = '';
callback('');
return;
}
}
getRevision(this.oldid, this.section || null, function (text) {
text = text.replace(/\s+$/, '');
self.oldText = text;
callback(text);
});
},
getNewText: function (callback) {
var self = this;
if (this.newid === 'edit') {
mw.loader.using('jquery.textSelection', function () {
callback(self.$textbox.textSelection('getContents').replace(/\s+$/, ''));
});
return;
}
if (this.newid === 've') {
ve.init.target.serialize(ve.init.target.getSurface().getDom(), function (wikitext) {
callback(wikitext);
});
return;
}
if (this.newText !== false) {
callback(this.newText);
return;
}
getRevision(this.newid, function (text) {
text = text.replace(/\s+$/, '');
self.newText = text;
callback(text);
});
},
getConfigDefault: function () {
var config = libs.schnarkDiff.config.get(['charDiff', 'wordDiffQual',
'recursion', 'tooShort', 'smallRegion', 'minMovedLength']);
config.indicateMoves = 1;
config.nested = true;
config.colorScheme = 'classic';
return config;
},
getConfigInterface: function () {
return {
charDiff: Number($('#' + this.idPrefix + 'config-char-diff').val()),
wordDiffQual: Number($('#' + this.idPrefix + 'config-word-diff-qual').val()) / 100,
recursion: Number($('#' + this.idPrefix + 'config-recursion').val()),
tooShort: Number($('#' + this.idPrefix + 'config-too-short').val()),
smallRegion: Number($('#' + this.idPrefix + 'config-small-region').val()),
minMovedLength: Number($('#' + this.idPrefix + 'config-min-moved-length').val()),
indicateMoves: Math.abs($('#' + this.idPrefix + 'config-moves').val()),
nested: $('#' + this.idPrefix + 'config-moves').val() < 0,
colorScheme: $('#' + this.idPrefix + 'config-color-scheme').val()
};
},
getConfig: function () {
var key, val, config = {}, defaults = this.getConfigDefault();
for (key in defaults) {
if (hasOwn.call(defaults, key)) {
val = mw.user.options.get(this.optionsPrefix + key);
if (val === null) {
val = defaults[key];
} else {
switch (typeof defaults[key]) {
case 'number':
val = Number(val);
if (isNaN(val)) {
val = defaults[key];
}
break;
case 'boolean':
val = val === 'true';
break;
}
}
config[key] = val;
}
}
return config;
},
setConfig: function (config) {
var moves;
$('#' + this.idPrefix + 'config-char-diff').val(config.charDiff);
$('#' + this.idPrefix + 'config-word-diff-qual').val(Math.round(config.wordDiffQual * 100));
$('#' + this.idPrefix + 'config-recursion').val(config.recursion);
$('#' + this.idPrefix + 'config-too-short').val(config.tooShort);
$('#' + this.idPrefix + 'config-small-region').val(config.smallRegion);
$('#' + this.idPrefix + 'config-min-moved-length').val(config.minMovedLength);
if (config.nested) {
moves = -1;
} else {
moves = config.indicateMoves;
}
$('#' + this.idPrefix + 'config-moves').val(moves);
$('#' + this.idPrefix + 'config-color-scheme').val(config.colorScheme);
},
applyConfig: function (config) {
this.configNested = config.nested;
enableColorScheme(config.colorScheme);
delete config.nested;
delete config.colorScheme;
libs.schnarkDiff.config.set(config);
},
saveConfig: function (config) {
var options = [], key, current = this.getConfig(), defaults = this.getConfigDefault();
for (key in config) {
if (hasOwn.call(config, key)) {
if (config[key] === current[key]) {
continue;
}
if (config[key] === defaults[key]) {
options.push(this.optionsPrefix + key);
} else {
options.push(this.optionsPrefix + key + '=' + config[key]);
}
}
}
if (options.length) {
$.post(mw.util.wikiScript('api'), {
action: 'options',
change: options.join('|'),
token: mw.user.tokens.get('csrfToken'),
format: 'json'
});
}
},
getDiff: function (callback) {
var self = this;
self.getOldText(function (oldText) {
self.getNewText(function (newText) {
var config = self.getConfigInterface(), defConf = libs.schnarkDiff.config.get();
self.applyConfig(config);
callback(libs.schnarkDiff.htmlDiff(oldText, newText, self.configNested));
libs.schnarkDiff.config.set(defConf);
});
});
},
buildInterface: function () {
var $enhancedDiff, $buttonBarTop, $panelContainer, $buttonBarBottom,
$panels, $panelOld, $panelNew, $panelConfig, $buttons, self = this;
$enhancedDiff = $(mw.html.element('div', {'class': 'schnark-diff-container'}));
$buttonBarTop = $('<div>').addClass('schnark-diff-buttons-top');
$panelContainer = $('<div>');
if (this.$standardDiff && this.$standardDiff.length === 1) {
this.$container = this.$standardDiff.wrap('<div>').parent();
$panelOld = $('<div>').addClass('schnark-diff-div').append(this.$standardDiff);
$panelContainer.append($panelOld);
$buttonBarTop.append(
$(mw.html.element('span', {
'class': 'schnark-diff-button', style: 'font-weight:bold;',
title: mw.msg('schnark-diff-tab-normal-tooltip')
}, mw.msg('schnark-diff-tab-normal')
)).click(function () {
$buttons.removeClass('schnark-diff-button-selected');
$(this).addClass('schnark-diff-button-selected');
$panels.hide();
$panelOld.show();
})
);
}
$panelNew = $(mw.html.element('div', {'class': 'schnark-diff-div'}, ''));
$panelNew.append($.createSpinner({size: 'large', type: 'block'}));
$panelContainer.append($panelNew);
$buttonBarTop.append($(mw.html.element('span', {
'class': 'schnark-diff-button schnark-diff-button-new', style: 'font-weight:bold;color:green;',
title: mw.msg('schnark-diff-tab-improved-tooltip')
}, mw.msg('schnark-diff-tab-improved'))
).click(function () {
$buttons.removeClass('schnark-diff-button-selected');
$(this).addClass('schnark-diff-button-selected');
$panels.hide();
$panelNew.show();
self.getDiff(function (html) {
$panelNew.html(html);
libs.schnarkDiff.addEvents($panelNew);
});
}));
$panelConfig = $('<div>').html(configHtml(this.idPrefix)).addClass('schnark-diff-div');
$panelContainer.append($panelConfig);
$buttonBarTop.append($(mw.html.element('span', {
'class': 'schnark-diff-button', style: 'font-weight:bold;',
title: mw.msg('schnark-diff-tab-config-tooltip')}, mw.msg('schnark-diff-tab-config'))
).click(function () {
$buttons.removeClass('schnark-diff-button-selected');
$(this).addClass('schnark-diff-button-selected');
$panels.hide();
$panelConfig.show();
}));
$panels = $panelContainer.find('.schnark-diff-div');
$buttons = $buttonBarTop.find('.schnark-diff-button');
$buttonBarBottom = $buttonBarTop
.clone(true)
.removeClass('schnark-diff-buttons-top')
.addClass('schnark-diff-buttons-bottom');
$buttons = $buttons.add($buttonBarBottom.find('.schnark-diff-button'));
$enhancedDiff.append($buttonBarTop)
.append($panelContainer)
.append($buttonBarBottom);
this.$firstButton = $buttons.first();
this.$enhancedDiff = $enhancedDiff;
this.$firstButton.click();
this.$container.append($enhancedDiff);
this.setConfig(this.getConfig());
$panelConfig.find('#' + this.idPrefix + 'config-save').click(function () {
self.saveConfig(self.getConfigInterface());
});
$panelConfig.find('#' + this.idPrefix + 'config-reset').click(function () {
self.setConfig(self.getConfigDefault());
});
},
showNew: function () {
var self = this, div;
if (this.$firstButton) {
this.$firstButton.click();
div = this.$enhancedDiff[0];
if (div.scrollIntoView) {
div.scrollIntoView();
}
} else {
loadDiffJs(function () {
self.buildInterface();
});
}
}
};
function getEnhancedDiffForDiff ($diff) {
if ($diff.hasClass('schnark-diff-wrapped-around')) {
return;
}
$diff.addClass('schnark-diff-wrapped-around');
var $old = $diff.find('#mw-diff-otitle1 a'),
$new = $diff.find('#mw-diff-ntitle1 a'),
$revdel = $diff.find('#mw-rev-suppressed-no-diff, #mw-rev-deleted-no-diff,' +
'#mw-rev-suppressed-unhide-diff, #mw-rev-deleted-unhide-diff'),
$textbox;
if ($new.length >= 1) {
if ($old.length === 0 || $revdel.length) { //no real diff shown
return;
}
return new EnhancedDiff(getRevisionId($old), getRevisionId($new), $diff);
}
$textbox = $('#wpTextbox1');
if ($textbox.length === 1) {
if ($('#wpTextbox2').length === 1) {
return new EnhancedDiff('conflict', 'edit', $diff, {$textbox: $textbox});
}
return new EnhancedDiff(mw.config.get('wgCurRevisionId'), 'edit', $diff, {
section: $('input[name="wpSection"]').val(),
$textbox: $textbox
});
}
if (window.ve) {
return new EnhancedDiff(mw.config.get('wgCurRevisionId'), 've', $diff);
}
}
function getEnhancedDiffWithoutDiff ($editform) {
if ($editform.hasClass('schnark-diff-added-to')) {
return;
}
$editform.addClass('schnark-diff-added-to');
var $div = $('<div>');
$editform.before($div);
return new EnhancedDiff(mw.config.get('wgCurRevisionId'), 'edit', false, {
$container: $div,
section: $('input[name="wpSection"]').val(),
$textbox: $('#wpTextbox1')
});
}
function getEnhancedDiff ($content, force) {
var $diff = $content.is('table.diff') ? $content : $content.find('table.diff'), $editform;
if ($diff.length === 1) {
return getEnhancedDiffForDiff($diff);
}
$editform = $content.find('#editform');
if ($editform.length === 1 && force) {
return getEnhancedDiffWithoutDiff($editform);
}
}
function run ($content) {
var enhancedDiff = getEnhancedDiff($content,
$.inArray(mw.config.get('wgAction'), ['edit', 'submit']) > -1 &&
config.alwaysOnEdit
), $diffButton;
if (!enhancedDiff) {
return;
}
if (!enhancedDiff.$standardDiff || enhancedDiff.$standardDiff.length === 0) {
$diffButton = $(mw.html.element('input', {
id: 'enhanced-diff-live-button', type: 'button',
value: mw.msg('schnark-diff-button'), title: mw.msg('schnark-diff-button-tooltip')
})
).click(function () {
enhancedDiff.showNew();
});
$('#wpDiff').after($diffButton);
} else {
loadDiffJs(function () {
enhancedDiff.buildInterface();
});
}
}
function init () {
initL10N(l10n);
mw.util.addCSS(config.css + (config.cssSkin[mw.config.get('skin')] || ''));
mw.hook('wikipage.diff').add(run);
//TODO aufräumen
mw.hook('wikipage.content').add(run);
mw.hook('wikipage.editform').add(function () {
run($(document));
});
mw.hook('ve.saveDialog.stateChanged').add(function () {
run($(document));
});
}
mw.hook('userjs.load-script.diff').fire(config);
mw.loader.using(['mediawiki.util', 'mediawiki.language', 'user.options', 'jquery.spinner'], init);
})(jQuery, mediaWiki, mediaWiki.libs);
//</nowki>