MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
Allow Restore default filters to expand to its label width |
Retain an explicit Visual editor choice alongside source-first editing |
||
| (4 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
/* Source editing is the primary entry point; VisualEditor remains explicit. */ | |||
(function () { | |||
'use strict'; | |||
function sourceFirst() { | |||
var source = document.getElementById('ca-edit'); | |||
var visual = document.getElementById('ca-ve-edit'); | |||
// Keep an explicit opt-in link even when native preferences hide it. | |||
var existingVisuals = Array.from(document.querySelectorAll('#ca-ve-edit')); | |||
if (existingVisuals.length > 1) { | |||
existingVisuals.filter(function (item) { return item.dataset.sourceFirstFallback === '1'; }).forEach(function (item) { item.remove(); }); | |||
visual = document.getElementById('ca-ve-edit'); | |||
} | |||
if (source && !visual && document.documentElement.classList.contains('ve-available') && mw.config.get('wgPageContentModel') === 'wikitext') { | |||
var sourceAnchor = source.querySelector('a'); | |||
if (sourceAnchor) { | |||
visual = document.createElement('li'); visual.id = 'ca-ve-edit'; visual.className = source.className.replace(/\bselected\b/g, ''); | |||
visual.dataset.sourceFirstFallback = '1'; | |||
var visualAnchor = document.createElement('a'); | |||
var visualUrl = new URL(sourceAnchor.href, location.href); | |||
visualUrl.searchParams.delete('action'); visualUrl.searchParams.set('veaction', 'edit'); | |||
visualAnchor.href = visualUrl.href; | |||
var visualLabel = document.createElement('span'); visualLabel.textContent = 'Visual editor'; | |||
visualAnchor.appendChild(visualLabel); visual.appendChild(visualAnchor); source.after(visual); | |||
} | |||
} | |||
if (source && visual && source.parentElement === visual.parentElement) { | |||
if (visual.compareDocumentPosition(source) & 4) source.parentElement.insertBefore(source, visual); | |||
var link = visual.querySelector('a'); | |||
if (link) { | |||
var language = mw.config.get('wgUserLanguage') || 'en'; | |||
var labels = {es:'Editor visual', ru:'\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440', pl:'Edytor wizualny'}; | |||
var label = labels[language.split('-')[0]] || 'Visual editor'; | |||
var text = link.querySelector('span') || link; | |||
if (text.textContent !== label) text.textContent = label; | |||
} | |||
} | |||
document.querySelectorAll('.mw-editsection').forEach(function (section) { | |||
var visualLink = section.querySelector('a.mw-editsection-visualeditor'); | |||
var sourceLink = Array.from(section.querySelectorAll('a[href]')).find(function (a) { | |||
var url = new URL(a.href, location.href); | |||
return url.searchParams.get('action') === 'edit'; | |||
}); | |||
if (!visualLink || !sourceLink || visualLink.parentElement !== sourceLink.parentElement) return; | |||
if (visualLink.compareDocumentPosition(sourceLink) & 4) { | |||
visualLink.before(sourceLink); | |||
var divider = section.querySelector('.mw-editsection-divider'); | |||
if (divider) sourceLink.after(divider); | |||
} | |||
}); | |||
if (!document.documentElement.classList.contains('gd-source-first')) document.documentElement.classList.add('gd-source-first'); | |||
} | |||
$(function () { | |||
sourceFirst(); | |||
var views = document.getElementById('p-views'); | |||
if (views) new MutationObserver(sourceFirst).observe(views, {childList:true, subtree:true}); | |||
new MutationObserver(sourceFirst).observe(document.documentElement, {attributes:true, attributeFilter:['class']}); | |||
}); | |||
mw.hook('wikipage.content').add(sourceFirst); | |||
}()); | |||
/* Use the physical device width instead of Vector legacy's 1120px canvas. */ | /* Use the physical device width instead of Vector legacy's 1120px canvas. */ | ||
(function () { | (function () { | ||
| Line 569: | Line 630: | ||
(function () { | (function () { | ||
'use strict'; | 'use strict'; | ||
var namespace = mw.config.get('wgNamespaceNumber'); | |||
var contentModel = mw.config.get('wgPageContentModel') || 'wikitext'; | |||
var codePage = ['javascript', 'css', 'sanitized-css', 'Scribunto', 'json'].indexOf(contentModel) !== -1; | |||
var metaDefault = [8, 10, 828].indexOf(namespace) !== -1 || codePage; | |||
if ((!metaDefault && namespace !== 0) || mw.config.get('wgAction') !== 'view') { return; } | |||
var heading = document.getElementById('firstHeading'); | var heading = document.getElementById('firstHeading'); | ||
if (!heading || document.getElementById('gd-content-status')) { return; } | if (!heading || document.getElementById('gd-content-status')) { return; } | ||
| Line 575: | Line 640: | ||
var spanish = selectedLanguage ? selectedLanguage[1] === 'spa' : (mw.config.get('wgExpandedActiveLanguage') === 'spa' || mw.config.get('wgUserLanguage') === 'es'); | var spanish = selectedLanguage ? selectedLanguage[1] === 'spa' : (mw.config.get('wgExpandedActiveLanguage') === 'spa' || mw.config.get('wgUserLanguage') === 'es'); | ||
var labels = {"community content (undeveloped/unreviewed)": "contenido de la comunidad (sin desarrollar/sin revisar)", "community content": "contenido de la comunidad", "base content": "contenido base", "Change content classification": "Cambiar la clasificación del contenido", "Content classification": "Clasificación del contenido", "Cancel": "Cancelar", "Saving...": "Guardando…", "Classification changed in this draft. Save changes to publish it.": "La clasificación se ha cambiado en este borrador. Guarda los cambios para publicarla.", "Could not change classification in this draft. No changes were published.": "No se pudo cambiar la clasificación del borrador. No se ha publicado ningún cambio.", "Content classification saved.": "Clasificación del contenido guardada.", "Could not save. Reload the page and try again.": "No se pudo guardar. Recarga la página e inténtalo de nuevo."}; | var labels = {"community content (undeveloped/unreviewed)": "contenido de la comunidad (sin desarrollar/sin revisar)", "community content": "contenido de la comunidad", "base content": "contenido base", "Change content classification": "Cambiar la clasificación del contenido", "Content classification": "Clasificación del contenido", "Cancel": "Cancelar", "Saving...": "Guardando…", "Classification changed in this draft. Save changes to publish it.": "La clasificación se ha cambiado en este borrador. Guarda los cambios para publicarla.", "Could not change classification in this draft. No changes were published.": "No se pudo cambiar la clasificación del borrador. No se ha publicado ningún cambio.", "Content classification saved.": "Clasificación del contenido guardada.", "Could not save. Reload the page and try again.": "No se pudo guardar. Recarga la página e inténtalo de nuevo."}; | ||
labels['meta content'] = 'contenido meta'; | |||
function tr(text) {return spanish ? (labels[text] || text) : text;} | function tr(text) {return spanish ? (labels[text] || text) : text;} | ||
var states = [ | var states = [ | ||
{key: 'pending', label: tr('community content (undeveloped/unreviewed)'), category: 'Wiki content status - pending review'}, | {key: 'pending', label: tr('community content (undeveloped/unreviewed)'), category: 'Wiki content status - pending review'}, | ||
{key: 'reviewed', label: tr('community content'), category: 'Wiki content status - reviewed community'}, | {key: 'reviewed', label: tr('community content'), category: 'Wiki content status - reviewed community'}, | ||
{key: 'base', label: tr('base content'), category: 'Wiki content status - base'} | {key: 'base', label: tr('base content'), category: 'Wiki content status - base'}, | ||
{key: 'meta', label: tr('meta content'), category: 'Wiki content status - meta'} | |||
]; | ]; | ||
var categories = mw.config.get('wgCategories') || []; | var categories = mw.config.get('wgCategories') || []; | ||
var selected = states.filter(function (state) { return categories.indexOf(state.category) !== -1; })[0]; | var selected = states.filter(function (state) { return categories.indexOf(state.category) !== -1; })[0]; | ||
if (!selected) { | if (!selected) { | ||
selected = categories.some(function (name) { return /\(base content\)$/i.test(name); }) ? states[2] : states[0]; | selected = metaDefault ? states[3] : (categories.some(function (name) { return /\(base content\)$/i.test(name); }) ? states[2] : states[0]); | ||
} | } | ||
var staff = (mw.config.get('wgUserGroups') || []).some(function (group) { | var staff = (mw.config.get('wgUserGroups') || []).some(function (group) { | ||
return ['sysop', 'bureaucrat'].indexOf(group) !== -1; | return ['sysop', 'bureaucrat'].indexOf(group) !== -1; | ||
}); | }); | ||
// Code models cannot safely contain wikitext status categories. | |||
staff = staff && contentModel === 'wikitext'; | |||
var badge = document.createElement(staff ? 'button' : 'span'); | var badge = document.createElement(staff ? 'button' : 'span'); | ||
badge.id = 'gd-content-status'; | badge.id = 'gd-content-status'; | ||
| Line 641: | Line 710: | ||
} | } | ||
function replaceStatusCategory(text, state) { | function replaceStatusCategory(text, state) { | ||
return text.replace(/\[\[\s*Category\s*:\s*Wiki[ _]content[ _]status[ _]-[ _](?:pending[ _]review|reviewed[ _]community|base)\s*(?:\|[^\]]*)?\]\]/gi, '').replace(/\s+$/, '') + '\n[[Category:' + state.category + ']]\n'; | return text.replace(/\[\[\s*Category\s*:\s*Wiki[ _]content[ _]status[ _]-[ _](?:pending[ _]review|reviewed[ _]community|base|meta)\s*(?:\|[^\]]*)?\]\]/gi, '').replace(/\s+$/, '') + '\n[[Category:' + state.category + ']]\n'; | ||
} | } | ||
var publishedState = selected; | var publishedState = selected; | ||
| Line 696: | Line 765: | ||
var revision = page.revisions[0]; | var revision = page.revisions[0]; | ||
var text = revision.slots.main.content; | var text = revision.slots.main.content; | ||
text = text.replace(/\[\[\s*Category\s*:\s*Wiki[ _]content[ _]status[ _]-[ _](?:pending[ _]review|reviewed[ _]community|base)\s*(?:\|[^\]]*)?\]\]/gi, ''); | text = text.replace(/\[\[\s*Category\s*:\s*Wiki[ _]content[ _]status[ _]-[ _](?:pending[ _]review|reviewed[ _]community|base|meta)\s*(?:\|[^\]]*)?\]\]/gi, ''); | ||
text = text.replace(/\s+$/, '') + '\n[[Category:' + state.category + ']]\n'; | text = text.replace(/\s+$/, '') + '\n[[Category:' + state.category + ']]\n'; | ||
return api.postWithEditToken({action: 'edit', title: page.title, text: text, | return api.postWithEditToken({action: 'edit', title: page.title, text: text, | ||
| Line 874: | Line 943: | ||
(function () { | (function () { | ||
function nativeInfoboxAudio() { | function nativeInfoboxAudio() { | ||
if (document.documentElement.classList.contains('ve-active')) return; | |||
document.querySelectorAll('.portable-infobox td[data-source="audio"], .portable-infobox td[data-source="fullaudio"], .expanded-ve-infobox div[data-source="audio"] > .pi-data-value, .expanded-ve-infobox div[data-source="fullaudio"] > .pi-data-value').forEach(function (cell) { | document.querySelectorAll('.portable-infobox td[data-source="audio"], .portable-infobox td[data-source="fullaudio"], .expanded-ve-infobox div[data-source="audio"] > .pi-data-value, .expanded-ve-infobox div[data-source="fullaudio"] > .pi-data-value').forEach(function (cell) { | ||
if (cell.querySelector('audio.expanded-native-audio')) { return; } | if (cell.querySelector('audio.expanded-native-audio')) { return; } | ||
| Line 1,093: | Line 1,163: | ||
var serial = 0; | var serial = 0; | ||
function enhance(root) { | function enhance(root) { | ||
if (document.documentElement.classList.contains('ve-active')) return; | |||
(root || document).querySelectorAll('.portable-infobox .pi-image .gallery').forEach(function (gallery) { | (root || document).querySelectorAll('.portable-infobox .pi-image .gallery').forEach(function (gallery) { | ||
if (gallery.dataset.profileTabs) return; | if (gallery.dataset.profileTabs) return; | ||
| Line 1,178: | Line 1,249: | ||
}); | }); | ||
} | } | ||
var queued=false;new MutationObserver(function(){if(! | var queued=false; | ||
function toolbarChanged(records){ | |||
var selector='.ve-ui-toolbar, .wikiEditor-ui-toolbar'; | |||
return records.some(function(record){ | |||
var target=record.target; | |||
if(target.nodeType===1 && target.closest(selector))return true; | |||
return Array.from(record.addedNodes).some(function(node){return node.nodeType===1 && (node.matches(selector)||node.querySelector(selector));}); | |||
}); | |||
} | |||
new MutationObserver(function(records){ | |||
if(queued||!toolbarChanged(records))return; | |||
queued=true;requestAnimationFrame(function(){queued=false;update();}); | |||
}).observe(document.body,{childList:true,subtree:true});update(); | |||
}()); | }()); | ||
/* Confirm Escape exits, including unchanged VisualEditor/source sessions. */ | /* Confirm Escape exits, including unchanged VisualEditor/source sessions. */ | ||
| Line 1,233: | Line 1,316: | ||
'use strict'; | 'use strict'; | ||
function containTables() { | function containTables() { | ||
if (document.documentElement.classList.contains('ve-active')) return; | |||
document.querySelectorAll('#mw-content-text .mw-parser-output table.wikitable').forEach(function (table) { | document.querySelectorAll('#mw-content-text .mw-parser-output table.wikitable').forEach(function (table) { | ||
if (table.closest('.portable-infobox, .infobox, .ve-ce-surface, [contenteditable="true"]')) return; | if (table.closest('.portable-infobox, .infobox, .ve-ce-surface, [contenteditable="true"]')) return; | ||
| Line 1,340: | Line 1,424: | ||
(function(){ | (function(){ | ||
var style=document.createElement('style');style.id='expanded-gallery-layout-v2';style.textContent="\n#bodyContent .portable-infobox > .pi-title {margin:0!important;min-height:0!important;padding:.5rem 1rem!important;line-height:1.4!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery {display:flow-root;padding-top:1rem;box-sizing:border-box;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs {display:flex;margin:0 1rem 1rem!important;overflow:hidden!important;align-items:stretch;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button {display:flex!important;align-items:center!important;justify-content:center!important;flex:1 0 auto!important;min-width:max-content!important;margin:0!important;padding:.5rem .7rem!important;line-height:1.4!important;white-space:nowrap!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs.expanded-gallery-stacked {flex-direction:column!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs.expanded-gallery-stacked button {flex:none!important;min-width:0!important;width:100%!important;white-space:normal!important;}\n";document.head.appendChild(style); | var style=document.createElement('style');style.id='expanded-gallery-layout-v2';style.textContent="\n#bodyContent .portable-infobox > .pi-title {margin:0!important;min-height:0!important;padding:.5rem 1rem!important;line-height:1.4!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery {display:flow-root;padding-top:1rem;box-sizing:border-box;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs {display:flex;margin:0 1rem 1rem!important;overflow:hidden!important;align-items:stretch;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button {display:flex!important;align-items:center!important;justify-content:center!important;flex:1 0 auto!important;min-width:max-content!important;margin:0!important;padding:.5rem .7rem!important;line-height:1.4!important;white-space:nowrap!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs.expanded-gallery-stacked {flex-direction:column!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs.expanded-gallery-stacked button {flex:none!important;min-width:0!important;width:100%!important;white-space:normal!important;}\n";document.head.appendChild(style); | ||
function arrange(){document.querySelectorAll('.expanded-profile-gallery-tabs').forEach(function(t){t.classList.remove('expanded-gallery-stacked');var needed=Array.from(t.children).reduce(function(n,b){return n+b.getBoundingClientRect().width;},0);t.classList.toggle('expanded-gallery-stacked',needed>t.clientWidth+1);});} | function arrange(){if(document.documentElement.classList.contains('ve-active'))return;document.querySelectorAll('.expanded-profile-gallery-tabs').forEach(function(t){t.classList.remove('expanded-gallery-stacked');var needed=Array.from(t.children).reduce(function(n,b){return n+b.getBoundingClientRect().width;},0);t.classList.toggle('expanded-gallery-stacked',needed>t.clientWidth+1);});} | ||
var pending=false;function schedule(){if(pending)return;pending=true;requestAnimationFrame(function(){pending=false;arrange();});} | var pending=false;function schedule(){if(pending)return;pending=true;requestAnimationFrame(function(){pending=false;arrange();});} | ||
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',schedule);else schedule(); | if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',schedule);else schedule(); | ||
| Line 1,347: | Line 1,431: | ||
(function(){var s=document.createElement('style');s.id='expanded-gallery-title-width-fix';s.textContent="\n/* Preserve the infobox's full-width title: its parent has 1rem side padding. */\n#bodyContent .portable-infobox > .pi-title {margin:0 -1rem!important;width:auto!important;}\n";document.head.appendChild(s);}()); | (function(){var s=document.createElement('style');s.id='expanded-gallery-title-width-fix';s.textContent="\n/* Preserve the infobox's full-width title: its parent has 1rem side padding. */\n#bodyContent .portable-infobox > .pi-title {margin:0 -1rem!important;width:auto!important;}\n";document.head.appendChild(s);}()); | ||
(function(){var s=document.createElement('style');s.id='expanded-restore-filter-width-fix';s.textContent="\n/* Let Restore default filters use its complete label width. */\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters .mw-rcfilters-ui-row {grid-template-columns:minmax(0,1fr) max-content!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-resetButton .oo-ui-buttonElement-button {white-space:nowrap!important;}\n@media(max-width:720px){\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters .mw-rcfilters-ui-row {grid-template-columns:minmax(0,1fr)!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset {grid-column:1!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-resetButton .oo-ui-buttonElement-button {white-space:normal!important;}\n}\n";document.head.appendChild(s);}()); | (function(){var s=document.createElement('style');s.id='expanded-restore-filter-width-fix';s.textContent="\n/* Let Restore default filters use its complete label width. */\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters .mw-rcfilters-ui-row {grid-template-columns:minmax(0,1fr) max-content!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-resetButton .oo-ui-buttonElement-button {white-space:nowrap!important;}\n@media(max-width:720px){\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters .mw-rcfilters-ui-row {grid-template-columns:minmax(0,1fr)!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset {grid-column:1!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-resetButton .oo-ui-buttonElement-button {white-space:normal!important;}\n}\n";document.head.appendChild(s);}()); | ||
(function(){var s=document.createElement("style");s.id="expanded-meta-content-status";s.textContent="\n/* Meta classification uses the Auto difficulty face. */\n#firstHeading .gd-content-status[data-status=\"meta\"] {background-image:url(\"https://geometrydashwiki.com/images/e/e8/Auto.png\");}\n";document.head.appendChild(s);}()); | |||
/* Resume read-view enhancements after VisualEditor closes. */ | |||
mw.hook("ve.deactivationComplete").add(function(){mw.hook("wikipage.content").fire($("#mw-content-text"));window.dispatchEvent(new Event("resize"));}); | |||
Latest revision as of 00:23, 17 October 2026
/* Source editing is the primary entry point; VisualEditor remains explicit. */
(function () {
'use strict';
function sourceFirst() {
var source = document.getElementById('ca-edit');
var visual = document.getElementById('ca-ve-edit');
// Keep an explicit opt-in link even when native preferences hide it.
var existingVisuals = Array.from(document.querySelectorAll('#ca-ve-edit'));
if (existingVisuals.length > 1) {
existingVisuals.filter(function (item) { return item.dataset.sourceFirstFallback === '1'; }).forEach(function (item) { item.remove(); });
visual = document.getElementById('ca-ve-edit');
}
if (source && !visual && document.documentElement.classList.contains('ve-available') && mw.config.get('wgPageContentModel') === 'wikitext') {
var sourceAnchor = source.querySelector('a');
if (sourceAnchor) {
visual = document.createElement('li'); visual.id = 'ca-ve-edit'; visual.className = source.className.replace(/\bselected\b/g, '');
visual.dataset.sourceFirstFallback = '1';
var visualAnchor = document.createElement('a');
var visualUrl = new URL(sourceAnchor.href, location.href);
visualUrl.searchParams.delete('action'); visualUrl.searchParams.set('veaction', 'edit');
visualAnchor.href = visualUrl.href;
var visualLabel = document.createElement('span'); visualLabel.textContent = 'Visual editor';
visualAnchor.appendChild(visualLabel); visual.appendChild(visualAnchor); source.after(visual);
}
}
if (source && visual && source.parentElement === visual.parentElement) {
if (visual.compareDocumentPosition(source) & 4) source.parentElement.insertBefore(source, visual);
var link = visual.querySelector('a');
if (link) {
var language = mw.config.get('wgUserLanguage') || 'en';
var labels = {es:'Editor visual', ru:'\u0412\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440', pl:'Edytor wizualny'};
var label = labels[language.split('-')[0]] || 'Visual editor';
var text = link.querySelector('span') || link;
if (text.textContent !== label) text.textContent = label;
}
}
document.querySelectorAll('.mw-editsection').forEach(function (section) {
var visualLink = section.querySelector('a.mw-editsection-visualeditor');
var sourceLink = Array.from(section.querySelectorAll('a[href]')).find(function (a) {
var url = new URL(a.href, location.href);
return url.searchParams.get('action') === 'edit';
});
if (!visualLink || !sourceLink || visualLink.parentElement !== sourceLink.parentElement) return;
if (visualLink.compareDocumentPosition(sourceLink) & 4) {
visualLink.before(sourceLink);
var divider = section.querySelector('.mw-editsection-divider');
if (divider) sourceLink.after(divider);
}
});
if (!document.documentElement.classList.contains('gd-source-first')) document.documentElement.classList.add('gd-source-first');
}
$(function () {
sourceFirst();
var views = document.getElementById('p-views');
if (views) new MutationObserver(sourceFirst).observe(views, {childList:true, subtree:true});
new MutationObserver(sourceFirst).observe(document.documentElement, {attributes:true, attributeFilter:['class']});
});
mw.hook('wikipage.content').add(sourceFirst);
}());
/* Use the physical device width instead of Vector legacy's 1120px canvas. */
(function () {
var viewport = document.querySelector('meta[name="viewport"]');
if (!viewport) {
viewport = document.createElement('meta');
viewport.name = 'viewport';
document.head.appendChild(viewport);
}
viewport.content = 'width=device-width, initial-scale=1';
}());
/* Any JavaScript here will be loaded for all users on every page load. */
/***************************/
/* Interface Modification **/
/***************************/
/* [[MediaWiki:Custom-Category:Games]] */
$(function () {
var config = {
targetCategory: 'Games (base content)',
sourceContent: 'MediaWiki:Custom-Category:Games',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the content list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-Category:Gameplay]] */
$(function () {
var config = {
targetCategory: 'Gameplay (base content)',
sourceContent: 'MediaWiki:Custom-Category:Gameplay',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the content list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-Category:Rewards]] */
$(function () {
var config = {
targetCategory: 'Rewards (base content)',
sourceContent: 'MediaWiki:Custom-Category:Rewards',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the content list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-Category:Rooms]] */
$(function () {
var config = {
targetCategory: 'Rooms (base content)',
sourceContent: 'MediaWiki:Custom-Category:Rooms',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the content list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-Category:LevelEditing]] */
$(function () {
var config = {
targetCategory: 'Level editing (base content)',
sourceContent: 'MediaWiki:Custom-Category:LevelEditing',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the content list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-Category:AccountFeatures]] */
$(function () {
var config = {
targetCategory: 'Account features (base content)',
sourceContent: 'MediaWiki:Custom-Category:AccountFeatures',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the content list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-Category:Updates]] */
$(function () {
var config = {
targetCategory: 'Updates (base content)',
sourceContent: 'MediaWiki:Custom-Category:Updates',
insertionPoint: '#mw-normal-catlinks'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-page-list" style="font-weight:normal;">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the page list from ' + config.sourceContent);
});
});
/***************************/
/* [[MediaWiki:Custom-MainLevels]] */
$(function () {
var config = {
targetCategory: 'Main levels (base content)',
sourceContent: 'MediaWiki:Custom-MainLevels',
insertionPoint: '#mw-content-text'
};
// Initial checks: Run only on page views (not edit mode) and for existing pages
if (mw.config.get('wgAction') !== 'view' || mw.config.get('wgArticleId') === 0) return;
// Category check: Verify if the article belongs to the target category
var categories = mw.config.get('wgCategories');
if (categories.indexOf(config.targetCategory) === -1) return;
// Load and inject content
var api = new mw.Api();
api.get({
action: 'parse',
page: config.sourceContent,
prop: 'text',
disablelimitreport: true,
disableeditsection: true
}).done(function (data) {
if (data && data.parse && data.parse.text) {
var insertHtml = data.parse.text['*'];
// Wrap in a div for styling and append
$(config.insertionPoint).append(
$('<div id="custom-category-footer">')
.html(insertHtml)
);
}
}).fail(function () {
console.error('Failed to load the footer from ' + config.sourceContent);
});
});
/***************************/
/* [[Template:USERNAME]] */
$(function () {
mw.config.get('wgUserName');
if (mw.config.get('wgUserName') !== null) ('span.username-insert').text(mw.config.get('wgUserName'));
});
/***************************/
/* [[Template:Discord]] (DiscordCompact.js v0.0.2 - https://support.wiki.gg/wiki/DiscordCompact) */
$(function () {
var widget = $("#content #discord-compact-widget");
// Cancel when no widget detected
if (!widget.length) return;
// Ensure that ID is not blank
var id = widget.attr("data-id");
if (id === "") throw new Error("DiscordCompact has a blank server id!");
// Ensure that ID consists only of numbers with 17 character minimum
if (!new RegExp("^[0-9]{17}[0-9]+$").test(id)) throw new Error("DiscordCompact has an invalid server id!");
var apiBase = "https://discord.com/api/guilds/" + id;
// Get information about the server, such as online member count and invite url, as well as limits of the server existing at all or having widgets disabled
$.ajax(apiBase + "/widget.json").fail(function(req) {
if (!req.responseJSON) throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.json (status: " + req.status);
switch (req.responseJSON.code) {
case 10004:
throw new Error("DiscordCompact has a valid server id, but no such server exists!");
case 50004:
throw new Error("DiscordCompact has a valid server id, but that server has widgets disabled!");
default:
throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.json (status: " + req.status + "; code: " + req.responseJSON.code + ")");
}
}).done(function(res) {
const inviteURL = res.instant_invite;
// Warn when unable to retrieve invite URL
if (inviteURL == null) console.warn("DiscordCompact cannot get an invite URL; does this server have an invite channel set in Widget settings?");
// Generate widget image
$.ajax({url: apiBase + "/widget.png?style=banner2", xhrFields: {responseType: "blob"}}).fail(function(req) {
if (!req.responseJSON) throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.png! (status: " + req.status);
throw new Error("DiscordCompact encountered an unknown error whilst fetching widget.png! (status: " + req.status + "; code: " + req.responseJSON.code + ")");
}).done(function(blob) {
// Convert the image data into base64, preventing having to make the client request it a second time
const imageReader = new FileReader();
imageReader.readAsDataURL(blob);
imageReader.onloadend = function() {
const b64Data = imageReader.result;
// Convert the widget into a selectable link
widget.replaceWith(function() {
return $("<a>", {
id: widget.attr("id"),
class: widget.attr("class"),
style: widget.attr("style"),
alt: "Discord server widget",
href: inviteURL
});
});
// Select the widget
widget = $("#discord-compact-widget");
// CSS
widget.css("display", "block");
widget.css("max-height", "76px");
widget.css("max-width", "320px");
// Create image
const widgetImage = document.createElement("img");
widgetImage.src = b64Data;
widgetImage.style.width = "100%";
widgetImage.style.height = "100%";
widgetImage.style.borderRadius = "4px";
widget.append(widgetImage);
// Prevent image dragging
widget.on("dragstart", function(e) {e.preventDefault();});
// Console message
console.log("DiscordCompact loaded successfully!");
};
});
});
});
/***************************/
/* [[Template:Discord]] (DiscordWidget.js - https://support.wiki.gg/wiki/DiscordWidget) */
$(function () {
'use strict';
var mconfig = mw.config.get([
'wgContentLanguage',
'wgUserLanguage',
'wgUserName'
]);
if (window.DiscordIntegratorLoaded) {
return;
}
window.DiscordIntegratorLoaded = true;
// Main object, @static
var DiscordIntegrator = {
// Initialising
init: function() {
mw.hook('wikipage.content').add($.proxy(this.insertToContent, this));
},
//Finding the designated places in content in which to place the widget and placing it
insertToContent: function($content) {
$content.find('.DiscordIntegrator:not(.loaded)').each($.proxy(function(cabbage, el) {
el = $(el);
el.html(this.generateContent(el.data())).addClass('loaded');
}, this));
},
// Determines the theme of the widget, @param {string} config Configured theme, @return {string} 'light' or 'dark' depending on the wiki theme and configuration
determineTheme: function(config) {
// If explicitly configured to light or dark
if (config === 'dark') {
return 'dark';
}
if (config === 'light') {
return 'light';
}
// If not configured, try to determine based on wiki theme (set by themeToggle):
return $(':root').hasClass('view-dark') ? 'dark' : 'light';
},
// Generate widget content from an object, @return {string} content of the widget
generateContent: function(config) {
if (!config.id || !String(config.id).match(/\d{17,19}/)) {
return "Error: ID of the widget is malformed or not supplied, please see <a href='https://support.wiki.gg/wiki/DiscordWidget' title='the instructions'>the instructions</a> for how to find your server's ID. Please make sure you are not inserting <strong>the DiscordIntegrator template</strong> when asked for <strong>your widget ID</strong>.";
}
if (
(
config.loggedIn === true ||
Boolean(config['logged-in']) === true &&
config['logged-in'] !== 'false' &&
config['logged-in'] !== '{{{loggedIn}}}'
) && !mconfig.wgUserName
) {
return "Please <a href='/Special:UserLogin' title='log in'>log in</a> to see this widget.";
}
var username = config.username === '@disabled' ?
'' :
config.username === '@function' &&
typeof window.DiscordIntegratorGetUsername === 'function' ?
window.DiscordIntegratorGetUsername() :
config.username || mconfig.wgUserName;
return mw.html.element('iframe', {
src: 'https://discord.com/widget?id=' + config.id +
'&theme=' + this.determineTheme(config.theme) +
'&username=' + encodeURIComponent(username),
width: config.width || '100%',
height: config.height || '400px',
style: 'max-width:100%;',
allowtransparency: 'true',
frameborder: '0',
title: "Discord server widget"
});
}
};
DiscordIntegrator.init();
});
/***************************/
/* CSS classes for daytime periods */
$(function() {
'use strict';
var currentTime = new Date().getHours();
if (0 <= currentTime && currentTime < 6) {
if (document.body) {document.body.classList.add('night');}
}
else if (6 <= currentTime && currentTime < 12) {
if (document.body) {document.body.classList.add('morning');}
}
else if (12 <= currentTime && currentTime < 18) {
if (document.body) {document.body.classList.add('afternoon');}
}
else {
if (document.body) {document.body.classList.add('evening');}
}
});
/* Geometry Dash Expanded Wiki footer: source attribution, licensing, and local contact. */
mw.loader.using('mediawiki.util').then(function () {
$(function () {
var footer = document.querySelector('#footer');
var information = document.querySelector('#footer-info');
if (!footer || !information || document.getElementById('footer-info-ewiki-sources')) return;
function link(text, href) {
var element = document.createElement('a');
element.textContent = text;
element.href = href;
return element;
}
var sources = document.createElement('li');
sources.id = 'footer-info-ewiki-sources';
sources.append('Imported material is adapted from the ',
link('Official Wiki', 'https://geometrydash.wiki.gg/'),
' and, where applicable, the ',
link('Geometry Dash Fandom', 'https://geometry-dash.fandom.com/'),
' and ', link('Geometry Dash Fan Fandom', 'https://geometry-dash-fan.fandom.com/'),
' wikis. Source and contributor links are recorded in import edit summaries.');
var license = document.createElement('li');
license.id = 'footer-info-ewiki-license';
license.append('Imported wiki text retains its original licensing, including ',
link('Creative Commons Attribution-ShareAlike 4.0', 'https://creativecommons.org/licenses/by-sa/4.0/'),
'. Images and separately licensed code may have different terms. ',
link('Sources and licensing', mw.util.getUrl('Project:Copyrights')), '.');
var independent = document.createElement('li');
independent.id = 'footer-info-ewiki-independent';
independent.textContent = 'Geometry Dash Expanded Wiki is an independent community wiki and is not affiliated with wiki.gg or RobTop Games.';
information.append(sources, license, independent);
var places = document.querySelector('#footer-places');
if (places && !document.getElementById('footer-places-ewiki-contact')) {
var contact = document.createElement('li');
contact.id = 'footer-places-ewiki-contact';
contact.appendChild(link('Contact Geometry Dash Expanded Wiki', 'mailto:admin@geometrydashwiki.com'));
places.appendChild(contact);
}
var footerIcons = document.getElementById('footer-icons');
if (footerIcons) {
if (!document.getElementById('footer-ewiki-licenseico')) {
var licenseBadge = document.createElement('li');
licenseBadge.id = 'footer-ewiki-licenseico';
var licenseLink = link('', 'https://creativecommons.org/licenses/by-sa/4.0/');
licenseLink.className = 'gd-footer-badge';
licenseLink.title = 'Creative Commons Attribution-ShareAlike 4.0';
var licenseImage = document.createElement('img');
licenseImage.src = '/resources/assets/licenses/cc-by-sa.png';
licenseImage.alt = 'Creative Commons Attribution-ShareAlike';
licenseImage.width = 132; licenseImage.height = 47;
licenseLink.appendChild(licenseImage); licenseBadge.appendChild(licenseLink);
footerIcons.prepend(licenseBadge);
}
var poweredLink = footerIcons.querySelector('#footer-poweredbyico a');
if (poweredLink) {
poweredLink.className = 'gd-footer-badge';
var poweredImage = document.createElement('img');
poweredImage.src = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCA4OSAzMSI+Cgk8cGF0aCBmaWxsPSIjZmZmIiBkPSJtNDEuOTE2IDI0LjQxLS4wMS04LjE0NmgtMS4xMjNsLTIuODY1IDUuMzk0LTIuOTE3LTUuMzk0aC0xLjEyNXY4LjE0NmgxLjN2LTUuMzNsMi40MTQgNC4zOTloLjYxMWwyLjQxNS00LjQ3LjAxIDUuMzk1aDEuMjl6bTYuOTE5LTMuMDcyYTMuNyAzLjcgMCAwIDAtLjM2My0xLjY4MkEyLjY4IDIuNjggMCAwIDAgNDYgMTguMTI0YTIuNzYgMi43NiAwIDAgMC0yLjUyNSAxLjU0MyAzLjUgMy41IDAgMCAwLS4zNzIgMS42MzRjLS4wMS41Ny4xMjMgMS4xMy4zODMgMS42NDIuMjQ1LjQ3NS42MjIuODY5IDEuMDg2IDEuMTM1YTMuNDMgMy40MyAwIDAgMCAyLjkzMi4xNTEgMi40IDIuNCAwIDAgMCAuOTU1LS43NTZsLS43MDMtLjg5NmExLjk0IDEuOTQgMCAwIDEtMS41MjQuNjc1IDEuODQgMS44NCAwIDAgMS0xLjIxMy0uNCAxLjcyIDEuNzIgMCAwIDEtLjYwNC0xLjA4OWg0LjM5N3EuMDIxLS4yOC4wMjEtLjQzem0tMi44MzYtMi4wNDlhMS40OCAxLjQ4IDAgMCAxIDEuMDcuNDE5Yy4yOTUuMjk0LjQ3Ny42OC41MTYgMS4wOTRoLTMuMTgyYy4wNDMtLjQxNy4yMzEtLjgwNi41My0xLjFBMS41IDEuNSAwIDAgMSA0NiAxOS4yODltOC4wNjEtMy41MTh2My4xODlhMi4xIDIuMSAwIDAgMC0uNzg3LS42MyAyLjQgMi40IDAgMCAwLTEuMDE4LS4yMDkgMi42OSAyLjY5IDAgMCAwLTIuNDYzIDEuNTEzIDMuOTcgMy45NyAwIDAgMCAwIDMuMzM0IDIuNjggMi42OCAwIDAgMCAyLjQ2MyAxLjUyNGMuMzY0LjAwNC43MjQtLjA3MSAxLjA1Ni0uMjIxYTIuMDYgMi4wNiAwIDAgMCAuODAzLS42NjR2LjgwM2gxLjI2di04LjYzaC0xLjMxOXptLTEuNjQ2IDcuNDc1Yy0uMy4wMDUtLjU5NS0uMDc3LS44NS0uMjM1YTEuNjUgMS42NSAwIDAgMS0uNTk5LS42ODEgMi41IDIuNSAwIDAgMSAwLTIuMDQ5Yy4xMzItLjI3OC4zNC0uNTE0LjU5OC0uNjgxYTEuNjMgMS42MyAwIDAgMSAxLjcgMGMuMjYuMTY3LjQ2Ny40MDMuNTk5LjY4MWEyLjUgMi41IDAgMCAxIDAgMi4wNDkgMS42NiAxLjY2IDAgMCAxLS41OTguNjgxIDEuNTYgMS41NiAwIDAgMS0uODUuMjM1bTQuNDcxIDEuMTYzaDEuMzF2LTYuMjE1aC0xLjMxMXptNC45NjMtNi4yODRhNC4zIDQuMyAwIDAgMC0xLjMxMy4xOTggMy4xIDMuMSAwIDAgMC0xLjA1NS41N2wuNTE1IDEuMDU1YTIuMiAyLjIgMCAwIDEgLjc3Mi0uNDU0Yy4yOTctLjEwOC42MTEtLjE2My45MjgtLjE2M2ExLjQyIDEuNDIgMCAwIDEgMS4wNDUuMzUyIDEuMzUgMS4zNSAwIDAgMSAuMzUyIDEuMDAxdi4wOTNoLTEuNDU0YTIuNiAyLjYgMCAwIDAtMS43NjkuNTA3IDEuNzIgMS43MiAwIDAgMC0uNTYxIDEuMzQ0IDEuNzYgMS43NiAwIDAgMCAuOTg2IDEuNjI0Yy4zNDQuMTY0LjcyMi4yNDQgMS4xMDIuMjM0LjM3LjAxLjczOC0uMDY0IDEuMDc1LS4yMTZhMS41NyAxLjU3IDAgMCAwIC42ODgtLjYyMnYuNzYyaDEuMjR2LTMuNjQ0YTIuNyAyLjcgMCAwIDAtLjY1Ni0xLjk4NCAyLjU1IDIuNTUgMCAwIDAtMS44OTUtLjY1OG0tLjE3OSA1LjMwN2ExLjIgMS4yIDAgMCAxLS43ODYtLjIzNC43Ny43NyAwIDAgMS0uMjg0LS42M3EwLS44MiAxLjEzNC0uODJoMS4zNTJ2LjcxNWExLjMzIDEuMzMgMCAwIDEtLjU0LjcxNiAxLjU3IDEuNTcgMCAwIDEtLjg3Ny4yNXptMTMuNzYtNy4xNy0xLjg3NiA2LjIyNy0xLjg1Ny02LjIyN2gtMS4yNjJsLTEuOSA2LjE5Mi0xLjgyNi02LjE5MmgtMS40MTdsMi40MzUgOC4xNDdoMS40NTdsMS44NDctNi4wMjkgMS44MTYgNi4wMjloMS40NWwyLjQzNS04LjE0N3ptMi4xMzEgOC4xNDdoMS4zMTJ2LTYuMjE1SDc3LjU2em03LjA1NCAwaDEuNTk1TDgzLjY0NyAyMC44bDIuMzQ2LTIuNjA3aC0xLjU3OWwtMi43MiAyLjc5NFYxNS43OGgtMS4zMXY4LjYzMWgxLjMxdi0xLjY0MmwuOTc3LTEuMDI0em0yLjE4MyAwaDEuMzEydi02LjIxNWgtMS4zMTN2Ni4yMTV6bS0yOS4yNTItNy4wMzZhLjgyLjgyIDAgMCAwIC42MDQtLjIzNS44LjggMCAwIDAgLjIzNS0uNTg2LjcuNyAwIDAgMC0uMjQyLS41NDUuODYuODYgMCAwIDAtLjU5OC0uMjE3Ljg0Ljg0IDAgMCAwLS41OTguMjI3Ljc4Ljc4IDAgMCAwLS4xNzguODc0LjguOCAwIDAgMCAuMTc4LjI1OC44NC44NCAwIDAgMCAuNTk4LjIyN3ptMjAuNjc2IDBhLjgyLjgyIDAgMCAwIC42MDQtLjIzNS44LjggMCAwIDAgLjIzNS0uNTg2LjcuNyAwIDAgMC0uMjQyLS41NDUuODYuODYgMCAwIDAtLjU5OC0uMjE3Ljg0Ljg0IDAgMCAwLS41OTguMjI3Ljc4Ljc4IDAgMCAwIDAgMS4xMzIuODQuODQgMCAwIDAgLjU5OC4yMjd6bTkuMjM2IDBhLjgyLjgyIDAgMCAwIC42MDQtLjIzNS44LjggMCAwIDAgLjIzNC0uNTg2LjcuNyAwIDAgMC0uMjQxLS41NDUuODYuODYgMCAwIDAtLjU5OC0uMjE3Ljg0Ljg0IDAgMCAwLS41OTguMjI3Ljc4Ljc4IDAgMCAwIDAgMS4xMzIuODQuODQgMCAwIDAgLjU5OC4yMjd6TTM2LjEzNiA5LjkxNmMuNDE2LjAwNy44My0uMDUzIDEuMjI3LS4xNzdhMi41IDIuNSAwIDAgMCAuODg5LS40OTggMi4xNCAyLjE0IDAgMCAwIC41NDQtLjc2MiAyLjUgMi41IDAgMCAwIC4xODQtLjk3NCAyLjYgMi42IDAgMCAwLS4xNy0uOTY4IDEuOSAxLjkgMCAwIDAtLjUyNS0uNzQ1IDIuNCAyLjQgMCAwIDAtLjg4Ni0uNDc3IDQuMiA0LjIgMCAwIDAtMS4yNTgtLjE3aC0yLjI3OXY3LjU3NGgxLjA4N1Y5LjkxNnptLTEuMTg3LTMuOTE0aDEuMTg4Yy4yNjEtLjAwNS41MjIuMDMuNzczLjEwMy4yMDIuMDU5LjM4OS4xNi41NDkuMjk4LjE0NS4xMjguMjU3LjI4OS4zMjcuNDY5LjA3NS4yMDIuMTEyLjQxNi4xMDguNjMuMDAxLjIxNi0uMDM5LjQyOS0uMTE3LjYzYTEuMyAxLjMgMCAwIDEtLjMzNi40ODdjLS4xNi4xNDItLjM0OC4yNS0uNTUxLjMxNy0uMjQ0LjA4LS41LjEyLS43NTcuMTE3aC0xLjE4NHptNS45OTMgMS40N2MtLjMwOC4xMi0uNTg2LjMxLS44MTMuNTUtLjIzLjI1LS40MDYuNTQ2LS41MTUuODY4YTMuNzQgMy43NCAwIDAgMCAwIDIuMjg4Yy4xMS4zMjMuMjg0LjYxOS41MTUuODcuMjI3LjI0Mi41MDQuNDMuODEzLjU1MWEzLjA1IDMuMDUgMCAwIDAgMi4xMzQgMGMuMzA2LS4xMjIuNTgyLS4zMS44MDctLjU1YTIuNSAyLjUgMCAwIDAgLjUxMi0uODcxIDMuNzQgMy43NCAwIDAgMCAwLTIuMjg4IDIuNSAyLjUgMCAwIDAtLjUxMi0uODY4IDIuMiAyLjIgMCAwIDAtLjgwNy0uNTUgMy4wNSAzLjA1IDAgMCAwLTIuMTM0IDBtLS4wOTUgNC4wMjNhMi40IDIuNCAwIDAgMS0uMzgzLTEuNDU3IDIuNDMgMi40MyAwIDAgMSAuMzgzLTEuNDU2IDEuMzUgMS4zNSAwIDAgMSAxLjE2My0uNTIyIDEuMzMgMS4zMyAwIDAgMSAxLjE1LjUyMmMuMjc3LjQzMy40MS45NDMuMzggMS40NTZhMi40MyAyLjQzIDAgMCAxLS4zOCAxLjQ1NyAxLjM0IDEuMzQgMCAwIDEtMS4xNS41MTcgMS4zNSAxLjM1IDAgMCAxLTEuMTYzLS41MTdtNS45NjUgMS4yMjRoLjc1NWEuMjM1LjIzNSAwIDAgMCAuMjI4LS4xOWwxLjE2NS0zLjUzMXEuMDQxLS4xMjUuMDY4LS4yNTRsLjA1My0uMjU2cS4wMjcuMTI3LjA1OS4yNTNjLjAzMi4xMjYuMDQ1LjE2OC4wNzIuMjUybDEuMTQ2IDMuNTM2YS4yMS4yMSAwIDAgMCAuMi4xOWguNzkybDEuNzMxLTUuMzU2aC0uNzU1YS4zLjMgMCAwIDAtLjI5LjJsLTEuMDAzIDMuMzRhOSA5IDAgMCAwLS4xNjQuNzU2IDEzIDEzIDAgMCAwLS4xOTYtLjc1NEw0OS42IDcuNTQzYS4yNy4yNyAwIDAgMC0uMS0uMTQuMy4zIDAgMCAwLS4xODMtLjA1NWgtLjQzYS4yNzUuMjc1IDAgMCAwLS4yNzUuMTk1bC0xLjA4NyAzLjM2LS4xMTIuMzg2cS0uMDUyLjE4NS0uMS4zN2ExMyAxMyAwIDAgMC0uMTUzLS43NTRsLS45ODYtMy4zNDFhLjMuMyAwIDAgMC0uMTAzLS4xNDIuMzIuMzIgMCAwIDAtLjE5OS0uMDU5aC0uNzl6bTguMjQtNS4yMzVjLS4zLjEzLS41Ny4zMjEtLjc5MS41NjJhMi41IDIuNSAwIDAgMC0uNDk5Ljg0IDMgMyAwIDAgMC0uMTc0IDEuMDQyYy0uMDA4LjQxOS4wNTcuODM2LjE5MiAxLjIzMi4xMTQuMzMzLjI5Ny42NC41MzYuODk4LjIzLjI0LjUxLjQyOS44Mi41NDhhMi44IDIuOCAwIDAgMCAxLjAyNy4xODhxLjI5NCAwIC41ODYtLjA0Ny4yOTctLjA0Ni41NzgtLjE1YTIuNyAyLjcgMCAwIDAgLjUyMy0uMjU4cS4yNDMtLjE1NS40MjctLjM3OGwtLjI4NS0uMzYzYS4yLjIgMCAwIDAtLjE4NC0uMDk1LjQ0LjQ0IDAgMCAwLS4yMjIuMDggNSA1IDAgMCAxLS4zMDguMTc0cS0uMjEuMTA2LS40MzMuMTc1YTIgMiAwIDAgMS0uNTk5LjA3OSAxLjggMS44IDAgMCAxLS42Ny0uMTE4IDEuMyAxLjMgMCAwIDEtLjUxNi0uMzU4IDEuNyAxLjcgMCAwIDEtLjMzNy0uNjA0IDMgMyAwIDAgMS0uMTQtLjg1NWgzLjUzNmEuMi4yIDAgMCAwIC4xODctLjA3OS42NS42NSAwIDAgMCAuMDUtLjMxMiAyLjkgMi45IDAgMCAwLS4xNjgtMS4wMjEgMi4wNCAyLjA0IDAgMCAwLTEuMTgyLTEuMjIgMi41IDIuNSAwIDAgMC0uODk3LS4xNjIgMi42IDIuNiAwIDAgMC0xLjA1Ny4yMDJtMS42MzQuNjM2YTEuMjEgMS4yMSAwIDAgMSAuNjgxLjc1MXEuMDk0LjI4Ni4wOS41ODdoLTIuODQ2YTEuODIgMS44MiAwIDAgMSAuNDctMS4wNTYgMS41OCAxLjU4IDAgMCAxIDEuNjA1LS4yODJtMy43OTQgNC41OTlWOS4zNThxLjA5MS0uMjQzLjIyLS40Ny4xMS0uMTk1LjI3NC0uMzQ5LjE1Mi0uMTQxLjM0Ni0uMjE1Yy4xNDEtLjA1Mi4yOTEtLjA3Ny40NDEtLjA3NHEuMTYxLS4wMDEuMzE5LjAzMS4xMDguMDI3LjIyLjAzMmEuMTYuMTYgMCAwIDAgLjE2OC0uMTQybC4wNy0uNzVhLjguOCAwIDAgMC0uMjczLS4xMTYgMS40IDEuNCAwIDAgMC0uMzMtLjAzOCAxLjM1IDEuMzUgMCAwIDAtLjg4Ni4zMDYgMi40IDIuNCAwIDAgMC0uNjIyLjgzOWwtLjA2NC0uNzgxYS4zNi4zNiAwIDAgMC0uMDgyLS4yMTEuMzMuMzMgMCAwIDAtLjIyNC0uMDZoLS41NzR2NS4zNTloMS4wMDJ6bTMuNzk4LTUuMjM1Yy0uMy4xMy0uNTcuMzIxLS43OTIuNTYyYTIuNSAyLjUgMCAwIDAtLjQ5OC44NCAzIDMgMCAwIDAtLjE3NSAxLjA0MiAzLjYgMy42IDAgMCAwIC4xOTIgMS4yMzJjLjExNC4zMzMuMjk3LjY0LjUzNi44OTguMjMuMjQuNTEuNDI5LjgyMS41NDhhMi44IDIuOCAwIDAgMCAxLjAyNi4xODhxLjI5NCAwIC41ODYtLjA0Ny4yOTYtLjA0Ni41NzgtLjE1YTIuNyAyLjcgMCAwIDAgLjUyMy0uMjU4IDEuOSAxLjkgMCAwIDAgLjQyNy0uMzc4bC0uMjg1LS4zNjNhLjIuMiAwIDAgMC0uMTg0LS4wOTUuNDQuNDQgMCAwIDAtLjIyMS4wOCA1IDUgMCAwIDEtLjMwOS4xNzRxLS4yMS4xMDYtLjQzMi4xNzVhMiAyIDAgMCAxLS42LjA3OSAxLjggMS44IDAgMCAxLS42Ny0uMTE4IDEuMyAxLjMgMCAwIDEtLjUxNS0uMzU4IDEuNyAxLjcgMCAwIDEtLjMzOC0uNjA0IDMgMyAwIDAgMS0uMTQtLjg1NWgzLjUzNmEuMi4yIDAgMCAwIC4xODgtLjA3OWMuMDQtLjEuMDU2LS4yMDguMDQ0LS4zMTVhMi45IDIuOSAwIDAgMC0uMTY5LTEuMDIyIDIuMSAyLjEgMCAwIDAtLjQ2OS0uNzUxIDIgMiAwIDAgMC0uNzEzLS40NyAyLjUgMi41IDAgMCAwLS44OTctLjE2IDIuNiAyLjYgMCAwIDAtMS4wNTMuMjA1em0xLjYzMy42MzZhMS4yIDEuMiAwIDAgMSAuNjgxLjc1MXEuMDk0LjI4Ni4wOS41ODdoLTIuODQ3YTEuODIgMS44MiAwIDAgMSAuNDctMS4wNTYgMS41OCAxLjU4IDAgMCAxIDEuNjA0LS4yODJ6bTcuMjU5IDQuNTk5VjQuOTM2aC0xLjAwM1Y3Ljg4YTEuODMgMS44MyAwIDAgMC0xLjQ0Ni0uNjEyIDIuMSAyLjEgMCAwIDAtLjk2NS4yMTRjLS4yODIuMTQtLjUzLjM0LS43MjguNTg2YTIuNyAyLjcgMCAwIDAtLjQ1OS44ODQgMy43IDMuNyAwIDAgMC0uMTU4IDEuMTA2Yy0uMDA2LjM5Ni4wNDIuNzkuMTQyIDEuMTczLjA4LjMwOS4yMi42LjQxLjg1Ny4xNjYuMjI0LjM4NS40MDQuNjM3LjUyNS4yNi4xMjEuNTQ0LjE4MS44MzIuMTc3cS4yNy4wMDUuNTMyLS4wNi4yNDUtLjA2LjQ3LS4xODEuMjIyLS4xMi40MTUtLjI4NS4xOTgtLjE3LjM2NS0uMzcybC4wOS42MjlhLjI0Ni4yNDYgMCAwIDAgLjI2My4yaC42MDN6bS0yLjk2Ni0uODQyYTEgMSAwIDAgMS0uNDExLS4zNDQgMS43IDEuNyAwIDAgMS0uMjYtLjU5OSAzLjcgMy43IDAgMCAxLS4wODktLjg3NiAyLjQ2IDIuNDYgMCAwIDEgLjM5LTEuNDk5IDEuMyAxLjMgMCAwIDEgMS4xMTUtLjUyIDEuNiAxLjYgMCAwIDEgLjY2NS4xMzZjLjIyMi4xMDcuNDEzLjI2OC41NTQuNDY5djIuNTYyYTIuMiAyLjIgMCAwIDEtLjYyMi41NzggMS41IDEuNSAwIDAgMS0uNzg3LjIwMyAxLjM1IDEuMzUgMCAwIDEtLjU1NS0uMTFtNy43NDcuODQyYS4yMzQuMjM0IDAgMCAwIC4yNTMtLjIxMWwuMDQ4LS40NmMuMTcuMjIzLjM4MS40MS42MjUuNTQ3LjI3My4xNC41NzcuMjA5Ljg4NC4xOThhMi4wNiAyLjA2IDAgMCAwIDEuNjgyLS43OTVjLjIwOS0uMjczLjM2NS0uNTgyLjQ2LS45MTMuMTEtLjM4NC4xNjUtLjc4Mi4xNi0xLjE4MmE0IDQgMCAwIDAtLjE0LTEuMDk1IDIuNCAyLjQgMCAwIDAtLjQwMy0uODIgMS44IDEuOCAwIDAgMC0uNjQxLS41MiAxLjkgMS45IDAgMCAwLS44NDctLjE4MiAyIDIgMCAwIDAtLjk2OC4yMjcgMi43IDIuNyAwIDAgMC0uNzU4LjYxMnYtMy4xOWgtMS4wMDR2Ny43ODR6bTIuNzMtNC4xOTJjLjI2My40Mi4zODUuOTEzLjM0NyAxLjQwNy4wNC41NDktLjA5NyAxLjEtLjM5IDEuNTYyYTEuMzMgMS4zMyAwIDAgMS0xLjEyNS41MTcgMS42IDEuNiAwIDAgMS0uNjU1LS4xMzUgMS40NiAxLjQ2IDAgMCAxLS41NTQtLjQ2OVY4Ljg2MWEyLjMgMi4zIDAgMCAxIC42MTItLjU4N2MuMjM1LS4xMzkuNTA1LS4yMS43NzktLjIwMmExLjE3IDEuMTcgMCAwIDEgLjk4Ny40NTVtNy4wNzQtMS4xNjRoLS43OTZhLjMuMyAwIDAgMC0uMjkuMmwtMS4zNCAzLjI2MnEtLjA0OC4xMTctLjA5LjI0NWwtLjA3OS4yNDVhNCA0IDAgMCAwLS4xNDItLjQ4bC0xLjM4Ny0zLjI3MmEuMy4zIDAgMCAwLS4zMDEtLjJoLS44NzNsMi4yMDUgNS4wMjktLjk4MiAyLjEyNmguNzQ3YS4zNS4zNSAwIDAgMCAuMjI4LS4wNjEuNDQuNDQgMCAwIDAgLjExNy0uMTc3eiIvPgoJPHBhdGggZmlsbD0idXJsKCNwKSIgZD0iTTguMjg0IDYuMTE2QTQuNTUgNC41NSAwIDAgMCA5LjYxIDkuMjRhMy41IDMuNSAwIDAgMCAyLjMxNC45MjMgMS4wNyAxLjA3IDAgMCAwIC43MzYtLjMzIDMuNTEgMy41MSAwIDAgMCAuODIxLTMuMzczYy0uNjIzLTIuMTYtMi4zNS0zLjM1LTQuNDU3LTQuMzg0YTkuNCA5LjQgMCAwIDAtLjc0MSA0LjAzOHoiIG9wYWNpdHk9Ii42NSIvPgoJPHBhdGggZmlsbD0idXJsKCNpKSIgZD0iTTUuMTU1IDkuMjVhNC41IDQuNSAwIDAgMCAyLjQyMiAyLjM3NGMuODA2LjI5MyAxLjY5LjI4IDIuNDg4LS4wMzcuMjU0LS4xMTcuNDUyLS4zMjcuNTU1LS41ODZhMy41MSAzLjUxIDAgMCAwLS41Mi0zLjQzYy0xLjQxLTEuNzUtMy40NS0yLjE5LTUuNzk1LTIuMzM1YTkuNCA5LjQgMCAwIDAgLjg1IDQuMDEzIiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjaCkiIGQ9Ik0zLjQ2NSAxMy4zNDVhNC40OCA0LjQ4IDAgMCAwIDMuMTQzIDEuMjYyIDMuNSAzLjUgMCAwIDAgMi4yODYtLjk5IDEuMSAxLjEgMCAwIDAgLjI4OC0uNzU2QTMuNTIgMy41MiAwIDAgMCA3LjM5IDkuODljLTEuOTYtMS4wOC00LjAyLS43MDUtNi4yNDMuMDdhOS40IDkuNCAwIDAgMCAyLjMxOCAzLjM4NCIgb3BhY2l0eT0iLjY1Ii8+Cgk8cGF0aCBmaWxsPSJ1cmwoI2cpIiBkPSJNMy40NjIgMTcuNzgxYzEuMDkuNDI5IDIuMy40MTQgMy4zODMtLjA0MWEzLjUyIDMuNTIgMCAwIDAgMS43MzQtMS43OTMgMS4xIDEuMSAwIDAgMC0uMDItLjgxIDMuNDkgMy40OSAwIDAgMC0yLjc4Ni0yLjA1NGMtMi4yMzEtLjIzNi0zLjk4MS44OTctNS43NDcgMi40NjJhOS40IDkuNCAwIDAgMCAzLjQzNiAyLjIzNiIgb3BhY2l0eT0iLjY1Ii8+Cgk8cGF0aCBmaWxsPSJ1cmwoI2YpIiBkPSJNNS4xNDggMjEuODc3YTQuNSA0LjUgMCAwIDAgMy4xMS0xLjMzOCAzLjUzIDMuNTMgMCAwIDAgLjkyLTIuMzIzIDEuMSAxLjEgMCAwIDAtLjMyOC0uNzQgMy40OCAzLjQ4IDAgMCAwLTMuMzU3LS44MjhjLTIuMTUuNjMzLTMuMzQgMi4zNi00LjM2NSA0LjQ4NGE5LjMgOS4zIDAgMCAwIDQuMDIuNzQ1IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjZSkiIGQ9Ik04LjI2NyAyNS4wMTlhNC41IDQuNSAwIDAgMCAyLjM2NC0yLjQzOGMuMjkyLS44MS4yOC0xLjctLjAzNi0yLjVhMS4wOCAxLjA4IDAgMCAwLS41ODYtLjU1OCAzLjQ5IDMuNDkgMCAwIDAtMy40MTcuNTI2Yy0xLjc0IDEuNDEtMi4xOCAzLjQ2LTIuMzI1IDUuODIxYTkuMyA5LjMgMCAwIDAgNC0uODUxIiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjZCkiIGQ9Ik0xMi4zNDUgMjYuNzJhNC41MyA0LjUzIDAgMCAwIDEuMjU0LTMuMTU3IDMuNTMgMy41MyAwIDAgMC0uOTg3LTIuMjk2IDEuMDggMS4wOCAwIDAgMC0uNzUyLS4yOSAzLjQ5IDMuNDkgMCAwIDAtMi45NTIgMS44Yy0xLjA3IDEuOTctLjY5NyA0LjA0LjA3IDYuMjdhOS4zIDkuMyAwIDAgMCAzLjM2Ny0yLjMyNyIgb3BhY2l0eT0iLjY1Ii8+Cgk8cGF0aCBmaWxsPSJ1cmwoI2MpIiBkPSJNMTYuNzY0IDI2LjcyNGMuNDI3LTEuMS40MTItMi4zMi0uMDQxLTMuNGEzLjUyIDMuNTIgMCAwIDAtMS43ODUtMS43NDMgMS4wOCAxLjA4IDAgMCAwLS44MDYuMDJjLS41NTQuMjUtMS4wMy42MzktMS4zOTIgMS4xM3MtLjU4NCAxLjA3LS42NTQgMS42N2MtLjIzNCAyLjI0Ljg5NSA0IDIuNDU1IDUuNzY3YTkuMzUgOS4zNSAwIDAgMCAyLjIyMy0zLjQ0NCIgb3BhY2l0eT0iLjY1Ii8+Cgk8cGF0aCBmaWxsPSJ1cmwoI2IpIiBkPSJNMjAuODQgMjUuMDMxYy0uMDIyLTEuMTgtLjUtMi4zLTEuMzMyLTMuMTI1YTMuNSAzLjUgMCAwIDAtMi4zMTQtLjkyNCAxLjA3IDEuMDcgMCAwIDAtLjczNi4zMyAzLjUxIDMuNTEgMCAwIDAtLjgyMSAzLjM3MmMuNjMgMi4xNiAyLjM1IDMuMzUgNC40NjQgNC4zODRhOS40IDkuNCAwIDAgMCAuNzM5LTQuMDM3IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjYSkiIGQ9Ik0yMy45NjYgMjEuODk3YTQuNSA0LjUgMCAwIDAtMi40MjEtMi4zNzUgMy41IDMuNSAwIDAgMC0yLjQ4OS4wMzcgMS4wOCAxLjA4IDAgMCAwLS41NTUuNTg2IDMuNTEgMy41MSAwIDAgMCAuNTI1IDMuNDMyYzEuNDEgMS43NSAzLjQ1IDIuMTkgNS43OTUgMi4zMzVhOS40IDkuNCAwIDAgMC0uODU1LTQuMDE1IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjbykiIGQ9Ik0yNS42NTkgMTcuODAxYTQuNDggNC40OCAwIDAgMC0zLjE0Mi0xLjI2M2MtLjg1Ny4wNC0xLjY3LjM5MS0yLjI4NS45OWExLjEgMS4xIDAgMCAwLS4yODkuNzU2IDMuNTIgMy41MiAwIDAgMCAxLjc5MiAyLjk3YzEuOTYgMS4wOCA0LjAyLjcwNCA2LjI0NC0uMDdhOS40IDkuNCAwIDAgMC0yLjMyLTMuMzgzIiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjbikiIGQ9Ik0yNS42NjMgMTMuMzY1YTQuNDggNC40OCAwIDAgMC0zLjM4Ny4wNDEgMy41MiAzLjUyIDAgMCAwLTEuNzM0IDEuNzkzYy0uMDk4LjI2My0uMDkuNTUzLjAyMS44MWEzLjQ5IDMuNDkgMCAwIDAgMi43ODYgMi4wNTZjMi4yMy4yMzQgMy45OC0uOSA1Ljc0Ni0yLjQ2M2E5LjMgOS4zIDAgMCAwLTMuNDMyLTIuMjM3IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjbSkiIGQ9Ik0yMy45NzcgOS4yNjZhNC41IDQuNSAwIDAgMC0zLjEwOSAxLjMzOCAzLjUzIDMuNTMgMCAwIDAtLjkyIDIuMzI1Yy4wMTEuMjguMTI5LjU0NS4zMy43NGEzLjQ4IDMuNDggMCAwIDAgMy4zNTcuODI4YzIuMTUtLjYzMyAzLjM0LTIuMzYgNC4zNjQtNC40ODVhOS4zIDkuMyAwIDAgMC00LjAyMi0uNzQ2IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjbCkiIGQ9Ik0yMC44NTggNi4xMjdhNC41MiA0LjUyIDAgMCAwLTIuMzY0IDIuNDMyYy0uMjkyLjgxLS4yNzkgMS43LjAzNiAyLjUuMTE2LjI1Ni4zMjYuNDU2LjU4Ny41NTlhMy40OSAzLjQ5IDAgMCAwIDMuNDE3LS41MjdjMS43NC0xLjQxIDIuMTgtMy40NiAyLjMyNC01LjgyYTkuMyA5LjMgMCAwIDAtNCAuODU2IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjaykiIGQ9Ik0xNi43OCA0LjQyNmE0LjU1IDQuNTUgMCAwIDAtMS4yNTcgMy4xNTdjLjAzOC44Ni4zODggMS42OC45ODUgMi4yOTYuMjA0LjE5LjQ3NC4yOTUuNzUzLjI5YTMuNDkgMy40OSAwIDAgMCAyLjk1Ny0xLjhjMS4wNy0xLjk3LjY5Ni00LjA0LS4wNy02LjI3MmE5LjMgOS4zIDAgMCAwLTMuMzY4IDIuMzI5IiBvcGFjaXR5PSIuNjUiLz4KCTxwYXRoIGZpbGw9InVybCgjaikiIGQ9Ik0xMi4zNjQgNC40MjJhNC41NSA0LjU1IDAgMCAwIC4wNDEgMy40MDEgMy41IDMuNSAwIDAgMCAxLjc4NSAxLjc0MWMuMjYuMDk4LjU1LjA5LjgwNS0uMDJhMy41NCAzLjU0IDAgMCAwIDEuMzkzLTEuMTNjLjM2LS40OS41ODQtMS4wNy42NTQtMS42Ny4yMzUtMi4yNC0uODk1LTQtMi40NTUtNS43NjdhOS4zNSA5LjM1IDAgMCAwLTIuMjIzIDMuNDQ1IiBvcGFjaXR5PSIuNjUiLz4KCTxkZWZzPgoJCTxsaW5lYXJHcmFkaWVudCBpZD0icCIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIiIHkyPSIxLjAwNCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMwQTAwQjIiLz4KCQkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0icmVkIi8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGRkMwMCIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJpIiB4MT0iLTIuMzUiIHgyPSIyOS4zMTIiIHkxPSIzMC4zMjEiIHkyPSIxLjAwNCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMwQTAwQjIiLz4KCQkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0icmVkIi8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGRkMwMCIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJoIiB4MT0iLTIuMzUiIHgyPSIyOS4zMTIiIHkxPSIzMC4zMiIgeTI9IjEuMDA0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzBBMDBCMiIvPgoJCQk8c3RvcCBvZmZzZXQ9Ii41IiBzdG9wLWNvbG9yPSJyZWQiLz4KCQkJPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZGQzAwIi8+CgkJPC9saW5lYXJHcmFkaWVudD4KCQk8bGluZWFyR3JhZGllbnQgaWQ9ImciIHgxPSItMi4zNSIgeDI9IjI5LjMxMiIgeTE9IjMwLjMyIiB5Mj0iMS4wMDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMEEwMEIyIi8+CgkJCTxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9InJlZCIvPgoJCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkZDMDAiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iZiIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIiIHkyPSIxLjAwNCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMwQTAwQjIiLz4KCQkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0icmVkIi8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGRkMwMCIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJlIiB4MT0iLTIuMzUiIHgyPSIyOS4zMTIiIHkxPSIzMC4zMiIgeTI9IjEuMDA0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzBBMDBCMiIvPgoJCQk8c3RvcCBvZmZzZXQ9Ii41IiBzdG9wLWNvbG9yPSJyZWQiLz4KCQkJPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZGQzAwIi8+CgkJPC9saW5lYXJHcmFkaWVudD4KCQk8bGluZWFyR3JhZGllbnQgaWQ9ImQiIHgxPSItMi4zNSIgeDI9IjI5LjMxMiIgeTE9IjMwLjMyIiB5Mj0iMS4wMDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMEEwMEIyIi8+CgkJCTxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9InJlZCIvPgoJCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkZDMDAiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYyIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIxIiB5Mj0iMS4wMDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMEEwMEIyIi8+CgkJCTxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9InJlZCIvPgoJCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkZDMDAiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iYiIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIiIHkyPSIxLjAwNCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMwQTAwQjIiLz4KCQkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0icmVkIi8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGRkMwMCIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJhIiB4MT0iLTIuMzUiIHgyPSIyOS4zMTIiIHkxPSIzMC4zMiIgeTI9IjEuMDA0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzBBMDBCMiIvPgoJCQk8c3RvcCBvZmZzZXQ9Ii41IiBzdG9wLWNvbG9yPSJyZWQiLz4KCQkJPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZGQzAwIi8+CgkJPC9saW5lYXJHcmFkaWVudD4KCQk8bGluZWFyR3JhZGllbnQgaWQ9Im8iIHgxPSItMi4zNSIgeDI9IjI5LjMxMiIgeTE9IjMwLjMyIiB5Mj0iMS4wMDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMEEwMEIyIi8+CgkJCTxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9InJlZCIvPgoJCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkZDMDAiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0ibiIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIiIHkyPSIxLjAwNCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMwQTAwQjIiLz4KCQkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0icmVkIi8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGRkMwMCIvPgoJCTwvbGluZWFyR3JhZGllbnQ+CgkJPGxpbmVhckdyYWRpZW50IGlkPSJtIiB4MT0iLTIuMzUiIHgyPSIyOS4zMTIiIHkxPSIzMC4zMiIgeTI9IjEuMDA0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CgkJCTxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iIzBBMDBCMiIvPgoJCQk8c3RvcCBvZmZzZXQ9Ii41IiBzdG9wLWNvbG9yPSJyZWQiLz4KCQkJPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkZGQzAwIi8+CgkJPC9saW5lYXJHcmFkaWVudD4KCQk8bGluZWFyR3JhZGllbnQgaWQ9ImwiIHgxPSItMi4zNSIgeDI9IjI5LjMxMiIgeTE9IjMwLjMyIiB5Mj0iMS4wMDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMEEwMEIyIi8+CgkJCTxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9InJlZCIvPgoJCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkZDMDAiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iayIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIxIiB5Mj0iMS4wMDQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KCQkJPHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjMEEwMEIyIi8+CgkJCTxzdG9wIG9mZnNldD0iLjUiIHN0b3AtY29sb3I9InJlZCIvPgoJCQk8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkZDMDAiLz4KCQk8L2xpbmVhckdyYWRpZW50PgoJCTxsaW5lYXJHcmFkaWVudCBpZD0iaiIgeDE9Ii0yLjM1IiB4Mj0iMjkuMzEyIiB5MT0iMzAuMzIiIHkyPSIxLjAwNCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgoJCQk8c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiMwQTAwQjIiLz4KCQkJPHN0b3Agb2Zmc2V0PSIuNSIgc3RvcC1jb2xvcj0icmVkIi8+CgkJCTxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGRkMwMCIvPgoJCTwvbGluZWFyR3JhZGllbnQ+Cgk8L2RlZnM+Cjwvc3ZnPgo=";
poweredImage.alt = 'Powered by MediaWiki';
poweredImage.width = 132; poweredImage.height = 46;
poweredLink.replaceChildren(poweredImage);
}
}
});
});
/* Staff content classification: persisted as dedicated hidden categories. */
(function () {
'use strict';
var namespace = mw.config.get('wgNamespaceNumber');
var contentModel = mw.config.get('wgPageContentModel') || 'wikitext';
var codePage = ['javascript', 'css', 'sanitized-css', 'Scribunto', 'json'].indexOf(contentModel) !== -1;
var metaDefault = [8, 10, 828].indexOf(namespace) !== -1 || codePage;
if ((!metaDefault && namespace !== 0) || mw.config.get('wgAction') !== 'view') { return; }
var heading = document.getElementById('firstHeading');
if (!heading || document.getElementById('gd-content-status')) { return; }
var selectedLanguage = /(?:^|;\s*)gdwiki-language=(eng|spa|rus|pol)(?:;|$)/.exec(document.cookie);
var spanish = selectedLanguage ? selectedLanguage[1] === 'spa' : (mw.config.get('wgExpandedActiveLanguage') === 'spa' || mw.config.get('wgUserLanguage') === 'es');
var labels = {"community content (undeveloped/unreviewed)": "contenido de la comunidad (sin desarrollar/sin revisar)", "community content": "contenido de la comunidad", "base content": "contenido base", "Change content classification": "Cambiar la clasificación del contenido", "Content classification": "Clasificación del contenido", "Cancel": "Cancelar", "Saving...": "Guardando…", "Classification changed in this draft. Save changes to publish it.": "La clasificación se ha cambiado en este borrador. Guarda los cambios para publicarla.", "Could not change classification in this draft. No changes were published.": "No se pudo cambiar la clasificación del borrador. No se ha publicado ningún cambio.", "Content classification saved.": "Clasificación del contenido guardada.", "Could not save. Reload the page and try again.": "No se pudo guardar. Recarga la página e inténtalo de nuevo."};
labels['meta content'] = 'contenido meta';
function tr(text) {return spanish ? (labels[text] || text) : text;}
var states = [
{key: 'pending', label: tr('community content (undeveloped/unreviewed)'), category: 'Wiki content status - pending review'},
{key: 'reviewed', label: tr('community content'), category: 'Wiki content status - reviewed community'},
{key: 'base', label: tr('base content'), category: 'Wiki content status - base'},
{key: 'meta', label: tr('meta content'), category: 'Wiki content status - meta'}
];
var categories = mw.config.get('wgCategories') || [];
var selected = states.filter(function (state) { return categories.indexOf(state.category) !== -1; })[0];
if (!selected) {
selected = metaDefault ? states[3] : (categories.some(function (name) { return /\(base content\)$/i.test(name); }) ? states[2] : states[0]);
}
var staff = (mw.config.get('wgUserGroups') || []).some(function (group) {
return ['sysop', 'bureaucrat'].indexOf(group) !== -1;
});
// Code models cannot safely contain wikitext status categories.
staff = staff && contentModel === 'wikitext';
var badge = document.createElement(staff ? 'button' : 'span');
badge.id = 'gd-content-status';
badge.className = 'gd-content-status';
badge.textContent = selected.label;
badge.dataset.status = selected.key;
if (staff) {
badge.type = 'button';
badge.setAttribute('aria-haspopup', 'dialog');
badge.setAttribute('aria-expanded', 'false');
badge.title = tr('Change content classification');
}
heading.appendChild(badge);
document.documentElement.classList.add('gd-content-status-ready');
// Non-staff badges have no click handler or interactive controls.
if (!staff) { return; }
var panel;
badge.addEventListener('click', function () {
if (panel) { close(); return; }
panel = document.createElement('div');
panel.className = 'gd-content-status-menu';
panel.setAttribute('role', 'dialog');
panel.setAttribute('aria-label', tr('Content classification'));
var title = document.createElement('strong');
title.textContent = tr('Content classification');
panel.appendChild(title);
states.forEach(function (state) {
var button = document.createElement('button');
button.type = 'button';
button.textContent = state.label;
button.disabled = state.key === selected.key;
button.addEventListener('click', function () { save(state); });
panel.appendChild(button);
});
var cancel = document.createElement('button');
cancel.type = 'button'; cancel.textContent = tr('Cancel');
cancel.addEventListener('click', close); panel.appendChild(cancel);
document.body.appendChild(panel);
var rect = badge.getBoundingClientRect();
panel.style.left = Math.max(8, Math.min(rect.left, window.innerWidth - panel.offsetWidth - 8)) + 'px';
panel.style.top = Math.max(8, Math.min(rect.bottom + 8, window.innerHeight - panel.offsetHeight - 8)) + 'px';
badge.setAttribute('aria-expanded', 'true');
panel.addEventListener('keydown', function (event) { if (event.key === 'Escape') { close(); } });
cancel.focus();
});
function close() {
if (panel) { panel.remove(); panel = null; }
badge.setAttribute('aria-expanded', 'false'); badge.focus();
}
function applyBadge(state) {
selected = state; badge.textContent = state.label; badge.dataset.status = state.key;
}
function replaceStatusCategory(text, state) {
return text.replace(/\[\[\s*Category\s*:\s*Wiki[ _]content[ _]status[ _]-[ _](?:pending[ _]review|reviewed[ _]community|base|meta)\s*(?:\|[^\]]*)?\]\]/gi, '').replace(/\s+$/, '') + '\n[[Category:' + state.category + ']]\n';
}
var publishedState = selected;
mw.hook('ve.activationComplete').add(function () { publishedState = selected; });
mw.hook('ve.deactivationComplete').add(function () {
applyBadge(publishedState); close();
});
function save(state) {
var editorActive = document.documentElement.classList.contains('ve-active');
var target = window.ve && ve.init && ve.init.target;
var surface = editorActive && target && target.getSurface && target.getSurface();
var textbox = document.getElementById('wpTextbox1');
if (editorActive || textbox) {
try {
if (surface && surface.getMode() === 'visual') {
var model = surface.getModel();
var fragment = model.getFragment();
var items = model.getDocument().getMetaList().getItemsInGroup('mwCategory').slice();
items.forEach(function (item) {
var category = item.getAttribute('category').replace(/_/g, ' ').replace(/^Category:/i, '');
if (states.some(function (entry) { return entry.category === category; })) {
fragment.removeMeta(item);
}
});
fragment.insertMeta({type: 'mwCategory', attributes: {category: 'Category:' + state.category, sortkey: ''}});
} else if (surface && surface.getMode() === 'source') {
var sourceModel = surface.getModel();
var text = sourceModel.getDocument().data.getText(true);
sourceModel.getFragment().selectAll().insertContent(replaceStatusCategory(text, state));
} else if (textbox) {
textbox.value = replaceStatusCategory(textbox.value, state);
textbox.dispatchEvent(new Event('input', {bubbles: true}));
textbox.dispatchEvent(new Event('change', {bubbles: true}));
} else {
throw new Error('Editor is not ready');
}
applyBadge(state); close();
mw.notify(tr('Classification changed in this draft. Save changes to publish it.'));
} catch (error) {
mw.notify(tr('Could not change classification in this draft. No changes were published.'), {type: 'error'});
}
return;
}
var currentPanel = panel;
Array.prototype.forEach.call(currentPanel.querySelectorAll('button'), function (button) { button.disabled = true; });
var status = document.createElement('p'); status.setAttribute('role', 'status');
status.textContent = tr('Saving...'); currentPanel.appendChild(status);
mw.loader.using('mediawiki.api').then(function () {
var api = new mw.Api();
return api.get({action: 'query', prop: 'revisions', rvprop: 'ids|timestamp|content', rvslots: 'main',
titles: mw.config.get('wgPageName'), curtimestamp: 1, formatversion: 2}).then(function (data) {
var page = data.query.pages[0];
if (page.missing || !page.revisions) { throw new Error('Page could not be read.'); }
var revision = page.revisions[0];
var text = revision.slots.main.content;
text = text.replace(/\[\[\s*Category\s*:\s*Wiki[ _]content[ _]status[ _]-[ _](?:pending[ _]review|reviewed[ _]community|base|meta)\s*(?:\|[^\]]*)?\]\]/gi, '');
text = text.replace(/\s+$/, '') + '\n[[Category:' + state.category + ']]\n';
return api.postWithEditToken({action: 'edit', title: page.title, text: text,
baserevid: revision.revid, basetimestamp: revision.timestamp, starttimestamp: data.curtimestamp,
nocreate: 1, assertuser: mw.config.get('wgUserName'), watchlist: 'nochange',
summary: 'Set content classification: ' + state.label}).then(function () {
selected = state; badge.textContent = state.label; badge.dataset.status = state.key;
close(); mw.notify(tr('Content classification saved.'));
});
});
}).catch(function () {
if (panel !== currentPanel) { return; }
status.textContent = tr('Could not save. Reload the page and try again.');
Array.prototype.forEach.call(currentPanel.querySelectorAll('button'), function (button) {
button.disabled = button.textContent === selected.label;
});
});
}
}());
/* Expanded Wiki Wraith browser-tab icon. */
(function () {
document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"]').forEach(function (link) { link.remove(); });
var icon = document.createElement('link');
icon.rel = 'icon';
icon.type = 'image/x-icon';
icon.href = "https://geometrydashwiki.com/images/7/74/ExpandedWiki.ico";
document.head.appendChild(icon);
}());
/* Keep Togglebox click targets attached to their wrapped headings. */
mw.hook('wikipage.content').add(function ($content) {
mw.loader.using('jquery.makeCollapsible').then(function () {
$content.find('.tabber.mw-collapsible').each(function () {
var $box = $(this);
$box.makeCollapsible();
var $heading = $box.children('.mw-heading').first();
var $toggle = $box.children('.mw-collapsible-toggle').first();
if ($heading.length && $toggle.length) { $heading.append($toggle); }
});
});
});
/* Multiple-file uploads on Special:Upload. */
(function () {
'use strict';
if (mw.config.get('wgCanonicalSpecialPageName') !== 'Upload') { return; }
mw.loader.using(['mediawiki.api', 'mediawiki.util']).then(function () {
$(function () {
var source = document.getElementById('wpUploadFile');
var form = source && source.closest('form');
if (!form || document.getElementById('expanded-multiple-upload')) { return; }
if (new URLSearchParams(location.search).has('wpForReUpload')) { return; }
var sourceRow = source.closest('tr') || source.parentElement;
var toggle = document.createElement(sourceRow.tagName === 'TR' ? 'tr' : 'div');
toggle.id = 'expanded-multiple-upload';
var label = document.createElement(sourceRow.tagName === 'TR' ? 'td' : 'span');
label.textContent = 'Upload multiple files: ';
var controls = document.createElement(sourceRow.tagName === 'TR' ? 'td' : 'span');
toggle.append(label, controls);
['Yes', 'No'].forEach(function (name) {
var item = document.createElement('label');
var radio = document.createElement('input');
radio.type = 'radio'; radio.name = 'expandedMultiple'; radio.value = name;
radio.checked = name === 'No';
item.append(radio, document.createTextNode(' ' + name + ' '));
controls.appendChild(item);
});
sourceRow.before(toggle);
var multi = document.createElement('input');
multi.type = 'file'; multi.multiple = true; multi.hidden = true;
multi.setAttribute('aria-label', 'Source filenames');
source.after(multi);
var destination = document.getElementById('wpDestFile');
var destinationRow = destination && (destination.closest('tr') || destination.parentElement);
var nativeSubmit = form.querySelector('[name="wpUpload"]');
if (!nativeSubmit) { toggle.remove(); multi.remove(); return; }
var button = nativeSubmit.cloneNode(true);
button.id = 'expanded-upload-files'; button.removeAttribute('name');
if (button.tagName === 'INPUT') { button.value = 'Upload files'; }
else { button.textContent = 'Upload files'; }
function setVisible(element, visible) {
element.hidden = !visible;
element.style.setProperty('display', visible ? '' : 'none', 'important');
}
setVisible(button, false);
nativeSubmit.after(button);
var results = document.createElement('div');
results.setAttribute('aria-live', 'polite'); form.after(results);
var busy = false;
controls.addEventListener('change', function () {
var enabled = controls.querySelector('input:checked').value === 'Yes';
setVisible(source, !enabled); setVisible(multi, enabled);
if (destinationRow) { setVisible(destinationRow, !enabled); }
setVisible(nativeSubmit, !enabled); setVisible(button, enabled);
});
form.addEventListener('submit', function (event) {
if (controls.querySelector('input:checked').value === 'Yes') {
event.preventDefault(); button.click();
}
});
window.addEventListener('beforeunload', function (event) {
if (busy) { event.preventDefault(); event.returnValue = ''; }
});
button.addEventListener('click', async function (event) {
event.preventDefault();
if (busy) { return; }
var files = Array.from(multi.files);
if (!files.length) { mw.notify('Choose at least one file.', {type: 'error'}); return; }
var license = document.getElementById('wpLicense');
var option = license && license.options[license.selectedIndex];
if (!option || !option.value || option.value === '-') {
mw.notify('Choose a license before uploading.', {type: 'error'}); return;
}
var licenseText = option.title;
if (!licenseText || licenseText.indexOf('{{') < 0) {
if (!/^[\w :.-]+$/.test(option.value)) {
mw.notify('Could not read the selected license.', {type: 'error'}); return;
}
licenseText = '{{' + option.value + '}}';
}
var description = document.getElementById('wpUploadDescription');
var text = (description ? description.value : '') + '\n\n== Licensing ==\n' + licenseText;
var watch = document.getElementById('wpWatchthis');
var ignore = document.getElementById('wpIgnoreWarning');
var params = {text: text, watchlist: watch && watch.checked ? 'watch' : 'nochange',
assertuser: mw.config.get('wgUserName')};
if (ignore && ignore.checked) { params.ignorewarnings = 1; }
busy = true; button.disabled = true;
var inputs = Array.from(form.querySelectorAll('input, select, textarea, button'));
var disabled = inputs.map(function (el) { return el.disabled; });
inputs.forEach(function (el) { el.disabled = true; });
results.replaceChildren();
var status = document.createElement('p'); results.appendChild(status);
var list = document.createElement('ul'); results.appendChild(list);
var ready = 0, failed = 0;
var api = new mw.Api();
try {
for (var i = 0; i < files.length; i++) {
var file = files[i];
status.textContent = 'Uploading ' + (i + 1) + '/' + files.length + ': ' + file.name;
var row = document.createElement('li');
row.textContent = file.name + ': uploading…'; list.appendChild(row);
try {
var data = await new Promise(function (resolve, reject) {
api.upload(file, Object.assign({}, params, {filename: file.name}))
.done(resolve).fail(function (code, details) {
reject({code: code, details: details});
});
});
var upload = data.upload;
if (!upload || upload.result !== 'Success') {
throw {code: 'upload-warning', details: data};
}
row.replaceChildren(document.createTextNode('Uploaded: '));
var link = document.createElement('a');
link.href = mw.util.getUrl('File:' + upload.filename);
link.textContent = upload.filename; row.appendChild(link); ready++;
} catch (error) {
failed++;
var details = error.details || {};
var warnings = details.upload && details.upload.warnings;
var message = details.error && details.error.info;
row.textContent = file.name + ': Failed — ' +
(warnings ? JSON.stringify(warnings) : message || error.code || 'Upload failed.');
}
}
status.textContent = 'Upload complete: ' + ready + ' uploaded, ' + failed + ' failed.';
} finally {
inputs.forEach(function (el, index) { el.disabled = disabled[index]; });
busy = false; button.disabled = false;
}
});
});
});
}());
/* Use native browser audio controls in infoboxes. */
(function () {
function nativeInfoboxAudio() {
if (document.documentElement.classList.contains('ve-active')) return;
document.querySelectorAll('.portable-infobox td[data-source="audio"], .portable-infobox td[data-source="fullaudio"], .expanded-ve-infobox div[data-source="audio"] > .pi-data-value, .expanded-ve-infobox div[data-source="fullaudio"] > .pi-data-value').forEach(function (cell) {
if (cell.querySelector('audio.expanded-native-audio')) { return; }
var original = cell.querySelector('audio');
if (!original) { return; }
var sources = Array.prototype.slice.call(original.querySelectorAll('source'));
if (!original.getAttribute('src') && !sources.length) { return; }
var audio = document.createElement('audio');
audio.className = 'expanded-native-audio';
audio.controls = true;
audio.preload = 'metadata';
audio.setAttribute('aria-label', (cell.getAttribute('data-source') || cell.parentElement.getAttribute('data-source')) === 'fullaudio' ? 'Full audio' : 'Audio');
if (original.getAttribute('src')) { audio.src = original.getAttribute('src'); }
sources.forEach(function (source) {
var copy = document.createElement('source');
copy.src = source.getAttribute('src');
if (source.getAttribute('type')) { copy.type = source.getAttribute('type'); }
audio.appendChild(copy);
});
original.pause();
cell.replaceChildren(audio);
});
}
mw.hook('wikipage.content').add(nativeInfoboxAudio);
$(function () {
nativeInfoboxAudio();
var content = document.getElementById('mw-content-text');
if (content) {
new MutationObserver(nativeInfoboxAudio).observe(content, { childList: true, subtree: true });
}
});
}());
if (mw.config.get('wgPageName') === 'Main_Page' && mw.config.get('wgAction') === 'view') {
var mainPageHeading = document.getElementById('firstHeading');
if (mainPageHeading) { mainPageHeading.style.setProperty('display', 'none', 'important'); }
}
/* Unified recovery shortcut: core drafts and VisualEditor session autosave. */
mw.loader.using(['mediawiki.storage', 'mediawiki.util']).then(function () {
$(function () {
'use strict';
var item = mw.util.addPortletLink('p-personal', mw.util.getUrl('Special:EditRecovery'),
'\u2692', 'pt-expanded-edit-recovery', 'Restore unsaved edits');
if (!item) return;
var checking = false;
var panel;
function visualDraft() {
try {
var state = JSON.parse(mw.storage.session.get('ve-docstate'));
var request = state && state.request;
if (!request || !request.pageName || !/^(source|visual)$/.test(request.mode)) return null;
if (!mw.storage.session.get('ve-dochtml')) return null;
return request;
} catch (error) { return null; }
}
function placeRecovery() {
var controls = document.querySelector('#p-personal .gd-header-controls');
if (controls && item.parentNode !== controls) controls.insertBefore(item, controls.firstChild);
}
item.querySelector('a').setAttribute('aria-label', 'Edit recovery');
var personal = document.getElementById('p-personal');
if (personal) new MutationObserver(placeRecovery).observe(personal, {childList:true, subtree:true});
placeRecovery();
function showVisualDraft(draft) {
if (mw.config.get('wgCanonicalSpecialPageName') !== 'EditRecovery') return;
if (!panel) {
panel = document.createElement('section');
panel.id = 'expanded-visual-edit-recovery';
panel.style.cssText = 'padding:1rem;margin:1rem 0;border:1px solid currentColor;border-radius:12px;';
var heading = document.createElement('h2');
heading.textContent = 'VisualEditor and source-mode drafts';
panel.appendChild(heading);
var description = document.createElement('p');
description.textContent = 'These drafts are kept separately from classic-editor drafts. Reopen the same editor to restore your unsaved changes.';
panel.appendChild(description);
var list = document.createElement('ul');
panel.appendChild(list);
document.getElementById('mw-content-text').appendChild(panel);
}
var list = panel.querySelector('ul');
list.replaceChildren();
panel.hidden = !draft;
if (!draft) return;
var params = {veaction: draft.mode === 'source' ? 'editsource' : 'edit'};
if (draft.section !== null && draft.section !== undefined && draft.section !== '') params.section = draft.section;
var li = document.createElement('li');
var link = document.createElement('a');
link.href = mw.util.getUrl(draft.pageName, params);
link.textContent = draft.pageName.replace(/_/g, ' ') + ' — Recover ' + (draft.mode === 'source' ? 'source-mode' : 'visual') + ' draft';
// Same-tab navigation preserves VisualEditor's session storage.
li.appendChild(link);
list.appendChild(li);
}
function coreDrafts() {
if (!window.indexedDB || !indexedDB.databases) return Promise.resolve([]);
return indexedDB.databases().then(function (databases) {
var name = mw.config.get('wgDBname') + '_editRecovery';
if (!databases.some(function (db) {return db.name === name;})) return [];
return new Promise(function (resolve) {
var open = indexedDB.open(name);
open.onerror = function () { resolve([]); };
open.onblocked = function () { resolve([]); };
open.onsuccess = function () {
var db = open.result;
if (!db.objectStoreNames.contains('unsaved-page-data')) { db.close(); resolve([]); return; }
var read = db.transaction('unsaved-page-data', 'readonly').objectStore('unsaved-page-data').getAll();
read.onsuccess = function () {
var drafts = read.result.filter(function (draft) { return draft.expiry > Date.now() / 1000; });
db.close(); resolve(drafts);
};
read.onerror = function () { db.close(); resolve([]); };
};
});
}).catch(function () { return []; });
}
function refresh() {
if (checking) return;
checking = true;
var visual = visualDraft();
showVisualDraft(visual);
coreDrafts().then(function (drafts) {
var count = drafts.length + (visual ? 1 : 0);
item.hidden = !count;
item.style.setProperty('display', count ? 'inline-flex' : 'none', 'important');
item.classList.toggle('expanded-recovery-pending', !!count);
item.querySelector('a').textContent = '\u2692';
item.querySelector('a').title = count ? count + ' unsaved draft(s) available for recovery' : 'No unsaved drafts';
checking = false;
}, function () { checking = false; });
}
item.hidden = true;
item.style.setProperty('display', 'none', 'important');
refresh();
// Autosave writes do not emit storage events in the tab that made them.
setInterval(function () { if (!document.hidden) refresh(); }, 3000);
window.addEventListener('focus', refresh);
window.addEventListener('storage', refresh);
document.addEventListener('visibilitychange', refresh);
});
});
/* Accurate article totals. */
$(function () {
var counter = document.querySelector('.expanded-article-count a');
if (!counter) { return; }
mw.loader.using('mediawiki.api').then(function () {
var api = new mw.Api(), count = 0;
function next(continuation) {
return api.get(Object.assign({action: 'query', list: 'allpages', apnamespace: 0,
apfilterredir: 'nonredirects', aplimit: 'max', formatversion: 2}, continuation || {}))
.then(function (data) {
count += data.query.allpages.length;
if (data.continue) { return next(data.continue); }
counter.textContent = count.toLocaleString();
counter.title = 'Non-redirect article pages in the main namespace';
});
}
next().catch(function () {});
});
});
/* Public account information on user pages; labels support English, Spanish and Russian. */
$(function () {
if (mw.config.get('wgNamespaceNumber') !== 2 || mw.config.get('wgTitle').indexOf('/') !== -1) { return; }
var target = document.querySelector('#mw-content-text');
if (!target || document.querySelector('.expanded-user-info')) { return; }
var language = (mw.config.get('wgUserLanguage') || 'en').split('-')[0];
var labels = {
en: ['Member of groups', 'Number of edits', 'Registration time'],
es: ['Miembro de los grupos', 'Número de ediciones', 'Fecha de registro'],
ru: ['Группы участника', 'Количество правок', 'Дата регистрации']
};
var text = labels[language] || labels.en;
mw.loader.using('mediawiki.api').then(function () {
var api = new mw.Api();
return api.get({action: 'query', list: 'users', ususers: mw.config.get('wgTitle'),
usprop: 'groups|implicitgroups|registration|editcount', formatversion: 2}).then(function (data) {
var user = data.query.users[0];
if (user.missing || user.invalid || !user.userid) { return; }
var groups = [...new Set((user.groups || []).concat(user.implicitgroups || []))].filter(function (g) { return g !== '*'; });
return api.get({action: 'query', meta: 'allmessages', ammessages: groups.map(function (g) {return 'group-' + g;}).join('|'),
amlang: mw.config.get('wgUserLanguage') || 'en', formatversion: 2}).then(function (messages) {
var groupMessages = {}; messages.query.allmessages.forEach(function (m) { groupMessages[m.name] = m; });
var names = groups.map(function (g) { var message = groupMessages['group-' + g]; return message && !message.missing ? message.content : g; });
var card = document.createElement('div'); card.className = 'expanded-user-info';
function line(label, value) {
var row = document.createElement('p'), heading = document.createElement('strong');
heading.textContent = label + ': '; row.appendChild(heading); row.appendChild(document.createTextNode(value)); card.appendChild(row);
}
var groupText = typeof Intl.ListFormat === 'function' ? new Intl.ListFormat(language, {type: 'conjunction'}).format(names) : names.join(', ');
line(text[0], groupText);
var row = document.createElement('p'), heading = document.createElement('strong'), link = document.createElement('a');
heading.textContent = text[1] + ': '; link.href = mw.util.getUrl('Special:Contributions/' + user.name);
link.textContent = Number(user.editcount || 0).toLocaleString(language); row.appendChild(heading); row.appendChild(link); card.appendChild(row);
if (user.registration) {
line(text[2], new Intl.DateTimeFormat(language, {year:'numeric', month:'short', day:'numeric', hour:'numeric', minute:'2-digit',timeZone:'UTC',timeZoneName:'short'}).format(new Date(user.registration)));
}
target.insertBefore(card, target.firstChild);
});
});
}).catch(function () {});
});
/* Load template UI colours with the editor script while site.styles refreshes. */
(function () {
if (document.getElementById("gd-ve-template-theme")) return;
var style = document.createElement("style");
style.id = "gd-ve-template-theme";
style.textContent = "\n/* VisualEditor template contexts, insertion, editing and parameter help. */\nhtml.ve-active .oo-ui-popupWidget:has(.ve-ui-mwTransclusionContextItem) .oo-ui-popupWidget-popup {\n background:#98562f; color:#fff; border:3px solid #fff; border-radius:12px;\n box-shadow:inset 0 0 0 2px #171717,0 0 0 2px #171717,0 4px 12px #0006;\n}\nhtml.ve-active .oo-ui-popupWidget:has(.ve-ui-mwTransclusionContextItem) .oo-ui-popupWidget-body,\nhtml.ve-active .ve-ui-mwTransclusionContextItem { background:#98562f; color:#fff; border-radius:9px; }\nhtml.ve-active .ve-ui-mwTransclusionContextItem .ve-ui-linearContextItem-head { background:#b17d60; color:#fff; padding:10px 12px; border-radius:9px 9px 0 0; }\nhtml.ve-active .ve-ui-mwTransclusionContextItem .ve-ui-linearContextItem-body { padding:10px 12px; color:#fff; }\nhtml.ve-active .ve-ui-mwTransclusionContextItem a { color:#23eeee; }\nhtml.ve-active .ve-ui-mwTransclusionContextItem .oo-ui-labelElement-label { color:#fff; }\nhtml.ve-active .ve-ui-mwTransclusionContextItem .oo-ui-iconElement-icon { background-color:#fff; }\nhtml.ve-active .oo-ui-popupWidget:has(.ve-ui-mwTransclusionContextItem) .oo-ui-popupWidget-anchor:before { border-bottom-color:#fff; border-top-color:#fff; }\nhtml.ve-active .oo-ui-popupWidget:has(.ve-ui-mwTransclusionContextItem) .oo-ui-popupWidget-anchor:after { border-bottom-color:#b17d60; border-top-color:#98562f; }\nhtml.ve-active .oo-ui-window:has(> .oo-ui-window-frame > .ve-ui-mwTemplateDialog) > .oo-ui-window-frame {\n border:3px solid #fff; border-radius:14px; overflow:hidden; box-sizing:border-box;\n box-shadow:0 0 0 3px #171717,0 10px 35px #0008;\n}\nhtml.ve-active .ve-ui-mwTemplateDialog,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-window-body,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-window-foot,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-panelLayout,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-bookletLayout-stackLayout,\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTwoPaneTransclusionDialogLayout-stackLayout {\n background:#98562f; color:#fff; font-family:\"Nunito\",Arial,sans-serif;\n}\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-window-head,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-processDialog-navigation { background:#b17d60; color:#fff; border-color:#c99972; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-processDialog-title { color:#fff; font-family:Pusab,\"Nunito\",Arial,sans-serif; text-shadow:1px 1px #111,-1px -1px #111; }\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTwoPaneTransclusionDialogLayout-outlinePanel,\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTwoPaneTransclusionDialogLayout-sidebar-container,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-menuLayout-menu { background:#7c4327; color:#fff; border-color:#c99972; }\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTransclusionOutlineTemplateWidget,\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTransclusionOutlineParameterWidget { background:transparent; color:#fff; border-color:#b77f58; }\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTransclusionOutlineParameterWidget:hover { background:#98562f; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-optionWidget-selected { background-color:#a56b47; color:#fff; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-labelElement-label,\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwParameterPage-label,\nhtml.ve-active .ve-ui-mwTemplateDialog h2,\nhtml.ve-active .ve-ui-mwTemplateDialog h3 { color:#fff; }\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwParameterPage-undocumentedLabel,\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwTemplatePage-description { color:#ffe38b; }\nhtml.ve-active .ve-ui-mwTemplateDialog a { color:#20eeee; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-inputWidget-input { background:#713d24 !important; color:#fff !important; border:1px solid #c99972 !important; border-radius:6px; box-shadow:none; font-family:\"Nunito\",Arial,sans-serif; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-inputWidget-input::placeholder { color:#dfc6b8 !important; opacity:1; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-inputWidget-input:focus { border-color:#ffcc00 !important; outline:2px solid #ffcc00; outline-offset:1px; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-iconElement-icon,\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-indicatorElement-indicator { background-color:#fff; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-checkboxInputWidget input + span { border-color:#fff; background:#713d24; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-checkboxInputWidget input:checked + span { background:#86c914; border-color:#a6e334; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button,\nhtml.ve-active .ve-ui-mwTransclusionContextItem .oo-ui-buttonElement-framed > .oo-ui-buttonElement-button {\n background:#12d9df !important; color:#fff !important; border:2px solid #fff !important; border-radius:8px;\n box-shadow:inset 0 0 0 1px #171717,0 0 0 1px #171717; padding:.35rem .8rem;\n}\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-buttonElement-framed .oo-ui-labelElement-label,\nhtml.ve-active .ve-ui-mwTransclusionContextItem .oo-ui-buttonElement-framed .oo-ui-labelElement-label { color:#fff; font-family:Pusab,\"Nunito\",Arial,sans-serif; text-shadow:1px 1px #111,-1px -1px #111; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-flaggedElement-primary > .oo-ui-buttonElement-button { background:#93dc17 !important; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-processDialog-actions-safe .oo-ui-buttonElement-button { background:#12d9df !important; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-widget-disabled > .oo-ui-buttonElement-button { background:#947560 !important; opacity:.65; cursor:default; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-buttonElement-button:focus-visible,\nhtml.ve-active .ve-ui-mwTransclusionContextItem .oo-ui-buttonElement-button:focus-visible { outline:3px solid #ffcc00; outline-offset:3px; }\nhtml.ve-active .ve-ui-mwTemplateDialog .oo-ui-messageWidget { background:#7c4327; border-color:#c99972; color:#fff; }\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwFloatingHelpElement .oo-ui-popupWidget-popup,\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwFloatingHelpElement .oo-ui-popupWidget-body { background:#98562f; color:#fff; border-color:#c99972; }\nhtml.ve-active .ve-ui-mwTemplateDialog .ve-ui-mwFloatingHelpElement > .oo-ui-buttonElement > .oo-ui-buttonElement-button { background:#12d9df; color:#fff; border-color:#fff; }\n";
document.head.appendChild(style);
}());
/* Captioned profile gallery tabs */
(function () {
'use strict';
var style = document.createElement('style');
style.id = 'expanded-profile-gallery-style';
style.textContent = "#bodyContent .portable-infobox .expanded-profile-gallery {width:100%;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs {display:flex;margin:1rem;border-radius:2rem;overflow:hidden;background:#ca946c;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button {flex:1;min-width:0;padding:.5rem .7rem;border:0;background:transparent;color:white;font:inherit;font-weight:bold;cursor:pointer;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button[aria-selected=\"true\"] {background:#d3a582;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button:focus-visible {outline:2px solid white;outline-offset:-3px;}\n#bodyContent .portable-infobox .expanded-profile-gallery-panel[hidden] {display:none!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-panel img {display:block;width:100%;height:auto;max-width:100%;border-radius:0;}";
document.head.appendChild(style);
var serial = 0;
function enhance(root) {
if (document.documentElement.classList.contains('ve-active')) return;
(root || document).querySelectorAll('.portable-infobox .pi-image .gallery').forEach(function (gallery) {
if (gallery.dataset.profileTabs) return;
var boxes = Array.from(gallery.querySelectorAll('.gallerybox'));
if (boxes.length < 2) return;
gallery.dataset.profileTabs = '1';
var wrap = document.createElement('div');
wrap.className = 'expanded-profile-gallery';
var tabs = document.createElement('div');
tabs.className = 'expanded-profile-gallery-tabs';
tabs.setAttribute('role', 'tablist');
tabs.setAttribute('aria-label', 'Profile images');
wrap.appendChild(tabs);
var buttons = [], panels = [];
function select(index, focus) {
buttons.forEach(function (button, i) {
button.setAttribute('aria-selected', String(i === index));
button.tabIndex = i === index ? 0 : -1;
panels[i].hidden = i !== index;
});
if (focus) buttons[index].focus();
}
boxes.forEach(function (box, i) {
var id = 'expanded-profile-image-' + (++serial);
var caption = box.querySelector('.gallerytext');
var button = document.createElement('button');
button.type = 'button'; button.id = id + '-tab';
button.textContent = caption && caption.textContent.trim() || 'Image ' + (i + 1);
button.setAttribute('role', 'tab'); button.setAttribute('aria-controls', id);
var panel = document.createElement('div');
panel.id = id; panel.className = 'expanded-profile-gallery-panel';
panel.setAttribute('role', 'tabpanel'); panel.setAttribute('aria-labelledby', button.id);
var thumb = box.querySelector('.thumb');
if (thumb) while (thumb.firstChild) panel.appendChild(thumb.firstChild);
var image = panel.querySelector('img');
var link = panel.querySelector('a.mw-file-description');
if (image && link) {
var path = new URL(link.href, location.href).pathname;
var file = decodeURIComponent(path).match(/\/File:(.+)$/);
if (file) {
image.removeAttribute('srcset');
image.src = mw.util.getUrl('Special:Redirect/file/' + file[1]);
}
}
button.addEventListener('click', function () { select(i, false); });
button.addEventListener('keydown', function (event) {
var next;
if (event.key === 'ArrowRight') next = (i + 1) % boxes.length;
if (event.key === 'ArrowLeft') next = (i + boxes.length - 1) % boxes.length;
if (event.key === 'Home') next = 0;
if (event.key === 'End') next = boxes.length - 1;
if (next !== undefined) { event.preventDefault(); select(next, true); }
});
buttons.push(button); panels.push(panel); tabs.appendChild(button); wrap.appendChild(panel);
});
select(0, false); gallery.replaceWith(wrap);
});
}
mw.loader.using('mediawiki.util').then(function () {
enhance(document);
mw.hook('wikipage.content').add(function (content) { enhance(content[0] || content); });
});
}());
/* Keep modern gallery styles in sync with site controls. */
(function(){var s=document.createElement("style");s.id="expanded-gallery-consistency";s.textContent="/* Consistent gallery cards across current and legacy MediaWiki gallery markup. */\n#bodyContent .gallery .gallerybox {flex-direction:column;box-sizing:border-box;min-width:0;}\n#bodyContent .gallery .gallerybox > .thumb {display:flex;align-items:center;justify-content:center;flex:1 1 auto;width:100%!important;height:auto!important;border:0;background:none;}\n#bodyContent .gallery .gallerybox > .thumb > span,\n#bodyContent .gallery .gallerybox > .thumb > a {display:block;width:100%;}\n#bodyContent .gallery .gallerybox > .thumb img {width:100%;height:auto;max-width:100%;object-fit:contain;}\n#bodyContent .gallery .gallerybox > .gallerytext,\n#bodyContent .gallery .gallerybox > .gallerytextwrapper .gallerytext {display:block;flex:0 0 auto;width:auto;margin:1rem 0 0;padding:0 1rem;border:0;outline:0;box-shadow:none;border-radius:var(--custom-border-radius-small);line-height:inherit;text-align:center;font-size:.8rem;color:var(--wiki-content-text-color);background:var(--wiki-content-background-color--secondary);}\n#bodyContent .gallery .gallerybox > .gallerytextwrapper {position:static;display:block!important;flex:0 0 auto;width:100%!important;height:auto;max-height:none;margin:0;padding:0;background:none;}\n#bodyContent .gallery .gallerybox > .gallerytext:empty,\n#bodyContent .gallery .gallerybox > .gallerytextwrapper:has(> .gallerytext:empty) {display:none!important;}\n#bodyContent figure[typeof~=\"mw:File/Thumb\"]:has(> figcaption:empty),\n#bodyContent figure[typeof~=\"mw:File/Frame\"]:has(> figcaption:empty) {padding:0;border:0;outline:0;box-shadow:none;background:transparent;}\n#bodyContent figure > figcaption:empty {display:none!important;}\n#bodyContent .thumbinner:has(> .thumbcaption:empty) {padding:0;border:0;outline:0;box-shadow:none;background:transparent;}\n#bodyContent .thumbcaption:empty {display:none!important;}\n#bodyContent figure:has(> figcaption:empty) > a::after {display:none!important;content:none!important;}\n#bodyContent figure:has(> figcaption:empty) img {background:transparent;border:0;border-radius:0;outline:0;box-shadow:none;}\n";document.head.appendChild(s);}());
/* VisualEditor toolbar layout and find panel repair. */
(function(){var s=document.createElement("style");s.id="expanded-editor-toolbar-fix";s.textContent="\n/* Editor toolbar dialogs must span the toolbar, not shrink as flex items. */\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar > .oo-ui-toolbar-bar > .oo-ui-windowManager {flex:0 0 100%!important;width:100%!important;min-width:0;max-width:100%;box-sizing:border-box;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .ve-ui-toolbarDialog {width:100%!important;max-width:100%;box-sizing:border-box;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar > .oo-ui-toolbar-bar {background:#98562f;color:#fff;border:2px solid #fff;border-radius:10px;box-shadow:0 0 0 2px #171717;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-tool-link,\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-popupToolGroup-handle {color:#fff;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-iconElement-icon,\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-indicatorElement-indicator {background-color:transparent!important;filter:brightness(0) invert(1);}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-tool-link:hover,\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-popupToolGroup-handle:hover {background:#b17d60;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-popupToolGroup-tools {background:#98562f;color:#fff;border-color:#c99972;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .ve-ui-toolbarDialog .oo-ui-window-frame,\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .ve-ui-toolbarDialog .oo-ui-window-body {background:#98562f;color:#fff;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .ve-ui-toolbarDialog .oo-ui-inputWidget-input {background:#713d24;color:#fff;border:1px solid #c99972;border-radius:5px;font-family:Nunito,Arial,sans-serif;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-flaggedElement-primary .oo-ui-buttonElement-button {background:#93dc17;color:#fff;border:2px solid #fff;border-radius:7px;box-shadow:inset 0 0 0 1px #171717;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .oo-ui-widget-disabled .oo-ui-buttonElement-button {background:#947560;opacity:.65;}\n\nhtml.ve-active body.skin-vector-legacy .ve-ui-surface {display:block!important;width:100%!important;min-width:0;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-surface > .ve-ce-surface {width:100%!important;min-width:0;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar.ve-ui-toolbar-floating {top:var(--wikigg-header-scroll-height,64px)!important;}\n\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .ve-ui-toolbarDialog .oo-ui-buttonElement-framed .oo-ui-buttonElement-button {background:#b17d60;color:#fff;border-color:#c99972;}\nhtml.ve-active body.skin-vector-legacy .ve-ui-toolbar .ve-ui-toolbarDialog .oo-ui-buttonElement-active .oo-ui-buttonElement-button {background:#c27b35;}\n";document.head.appendChild(s);}());
/* Editor checkbox hit targets and discoverable native Find and Replace. */
(function(){
'use strict';
var style=document.createElement('style');style.id='expanded-editor-controls';style.textContent="\n/* Align native checkbox hit targets with their visible squares. */\n.oo-ui-checkboxInputWidget.oo-ui-checkboxInputWidget {position:relative!important;display:inline-block!important;flex:0 0 auto!important;width:1.25rem!important;height:1.25rem!important;min-width:1.25rem!important;min-height:1.25rem!important;box-sizing:border-box;vertical-align:middle;}\n.oo-ui-checkboxInputWidget.oo-ui-checkboxInputWidget input[type=\"checkbox\"] {position:absolute!important;inset:0!important;display:block!important;width:100%!important;height:100%!important;margin:0!important;padding:0!important;opacity:0!important;z-index:2;pointer-events:auto!important;transform:none!important;cursor:pointer;}\n.oo-ui-checkboxInputWidget.oo-ui-checkboxInputWidget input[type=\"checkbox\"] + span {position:absolute!important;inset:0!important;width:100%!important;height:100%!important;margin:0!important;box-sizing:border-box!important;pointer-events:none!important;}\n.ve-ui-toolbar > .oo-ui-toolbar-bar > .oo-ui-windowManager {flex:0 0 100%!important;width:100%!important;min-width:0;box-sizing:border-box;}\n.ve-ui-toolbar .ve-ui-toolbarDialog {width:100%!important;max-width:100%;box-sizing:border-box;}\n.ve-ui-surface {display:block!important;min-width:0;}\n.ve-ui-surface > .ve-ce-surface {width:100%!important;min-width:0;}\n.ve-ui-toolbar.ve-ui-toolbar-floating {top:var(--wikigg-header-scroll-height,64px)!important;}\n.expanded-editor-search-group {display:inline-flex;align-items:center;flex:0 0 auto;margin:.2rem;}\n.expanded-editor-search-group button {padding:.45rem .65rem;border:2px solid #fff;border-radius:7px;background:#12d9df;color:#fff;box-shadow:inset 0 0 0 1px #171717;font:700 14px/1.5 Nunito,Arial,sans-serif;cursor:pointer;white-space:nowrap;}\n.expanded-editor-search-group button:focus-visible {outline:2px solid #ffcc00;outline-offset:2px;}\n.wikiEditor-ui-toolbar .expanded-search-labelled .oo-ui-labelElement-label {display:inline!important;width:auto!important;min-width:0!important;height:auto!important;white-space:nowrap;}\n";document.head.appendChild(style);
function update(){
document.querySelectorAll('.ve-ui-toolbar').forEach(function(toolbar){
if(toolbar.querySelector('.expanded-editor-search-group'))return;
var nativeLink=toolbar.querySelector('.oo-ui-tool-name-findAndReplace .oo-ui-tool-link');
var tools=toolbar.querySelector(':scope > .oo-ui-toolbar-bar > .oo-ui-toolbar-tools');
if(!nativeLink||!tools)return;
var group=document.createElement('div');group.className='expanded-editor-search-group';
var button=document.createElement('button');button.type='button';button.textContent='Find and replace';button.setAttribute('aria-haspopup','dialog');button.title='Find and replace (Ctrl+F)';
button.addEventListener('click',function(){var target=window.ve&&ve.init&&ve.init.target;var surface=target&&target.getSurface();if(surface&&surface.executeCommand('findAndReplace'))return;nativeLink.dispatchEvent(new MouseEvent('mousedown',{bubbles:true,button:0,buttons:1}));nativeLink.dispatchEvent(new MouseEvent('mouseup',{bubbles:true,button:0}));});group.appendChild(button);tools.appendChild(group);
});
document.querySelectorAll('.wikiEditor-ui-toolbar a[title="Search and replace"]').forEach(function(button){
if(button.parentElement.classList.contains('expanded-search-labelled'))return;
var label=button.querySelector('.oo-ui-labelElement-label');if(label){label.textContent='Find and replace';button.parentElement.classList.add('expanded-search-labelled');}
});
}
var queued=false;
function toolbarChanged(records){
var selector='.ve-ui-toolbar, .wikiEditor-ui-toolbar';
return records.some(function(record){
var target=record.target;
if(target.nodeType===1 && target.closest(selector))return true;
return Array.from(record.addedNodes).some(function(node){return node.nodeType===1 && (node.matches(selector)||node.querySelector(selector));});
});
}
new MutationObserver(function(records){
if(queued||!toolbarChanged(records))return;
queued=true;requestAnimationFrame(function(){queued=false;update();});
}).observe(document.body,{childList:true,subtree:true});update();
}());
/* Confirm Escape exits, including unchanged VisualEditor/source sessions. */
(function () {
'use strict';
var pending = false;
function visible(element) {
var rect = element.getBoundingClientRect();
var style = getComputedStyle(element);
return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
}
function openLayer() {
return Array.from(document.querySelectorAll('.oo-ui-dialog.oo-ui-window-active.oo-ui-window-ready, .oo-ui-popupToolGroup-active, .oo-ui-popupWidget-popup, .oo-ui-menuSelectWidget:not(.oo-ui-element-hidden), .cm-tooltip-autocomplete, .ui-dialog, [role="dialog"][aria-modal="true"]')).some(visible);
}
document.addEventListener('keydown', function (event) {
if (event.key !== 'Escape' || event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) return;
if (pending) {
if (!openLayer()) { event.preventDefault(); event.stopImmediatePropagation(); }
return;
}
if (openLayer()) return;
var target = window.ve && ve.init && (ve.init.articleTarget || ve.init.target);
if (!target || !target.active || !document.documentElement.classList.contains('ve-active')) return;
event.preventDefault();
event.stopImmediatePropagation();
pending = true;
var focus = document.activeElement;
function finish(accepted) {
pending = false;
if (accepted) {
if (typeof target.tryTeardown === 'function') target.tryTeardown(true, 'escape-confirmed');
else if (typeof target.deactivate === 'function') target.deactivate(true, 'escape-confirmed');
} else if (focus && focus.isConnected && typeof focus.focus === 'function') {
focus.focus({preventScroll:true});
}
}
var answer;
try {
answer = OO.ui.confirm('Are you sure you want to exit the editor?', {
title: 'Exit editor?',
actions: [
{action:'reject', label:'Keep editing', flags:'safe'},
{action:'accept', label:'Exit editor', flags:['primary','destructive']}
]
});
} catch (error) {
answer = window.confirm('Are you sure you want to exit the editor?');
}
Promise.resolve(answer).then(finish, function () { pending = false; });
}, true);
}());
/* Contain wide comparison tables throughout the wiki. */
(function () {
'use strict';
function containTables() {
if (document.documentElement.classList.contains('ve-active')) return;
document.querySelectorAll('#mw-content-text .mw-parser-output table.wikitable').forEach(function (table) {
if (table.closest('.portable-infobox, .infobox, .ve-ce-surface, [contenteditable="true"]')) return;
if (table.parentElement.classList.contains('expanded-wide-table')) return;
if (table.parentElement.closest('table.wikitable')) return;
var wrapper = document.createElement('div');
wrapper.className = 'expanded-wide-table';
wrapper.style.cssText = 'display:block;width:100%;max-width:100%;min-width:0;overflow-x:auto;box-sizing:border-box;';
wrapper.tabIndex = 0;
wrapper.setAttribute('role', 'region');
wrapper.setAttribute('aria-label', table.caption ? table.caption.textContent.trim() : 'Scrollable comparison table');
table.parentNode.insertBefore(wrapper, table);
wrapper.appendChild(table);
});
}
$(containTables);
mw.hook('wikipage.content').add(containTables);
var scheduled = false;
$(function () {
var root = document.getElementById('mw-content-text');
if (!root) return;
new MutationObserver(function () {
if (scheduled) return;
scheduled = true;
requestAnimationFrame(function () { scheduled = false; containTables(); });
}).observe(root, {childList:true, subtree:true});
});
}());
/* Editor popup theme: load alongside editor customisations. */
(function(){var s=document.createElement("style");s.id="expanded-editor-popup-theme";s.textContent="\n/* Theme editor popovers as well as modal dialogs; preserve native sizing. */\nhtml.ve-active .oo-ui-popupWidget .oo-ui-popupWidget-popup {\n background:#98562f !important; color:#fff !important;\n border:3px solid #fff !important; border-radius:14px !important;\n outline:3px solid #171717; box-shadow:0 4px 12px #0008 !important;\n font-family:Nunito,Arial,sans-serif;\n}\nhtml.ve-active .oo-ui-popupWidget .oo-ui-popupWidget-body,\nhtml.ve-active .oo-ui-popupWidget .oo-ui-popupWidget-footer { background:#98562f !important; color:#fff !important; }\nhtml.ve-active .oo-ui-popupWidget .oo-ui-popupWidget-head { background:#b17d60 !important; color:#fff !important; border-radius:10px 10px 0 0; }\nhtml.ve-active .oo-ui-popupWidget .oo-ui-popupWidget-body p,\nhtml.ve-active .oo-ui-popupWidget .oo-ui-popupWidget-body li,\nhtml.ve-active .oo-ui-popupWidget .oo-ui-labelElement-label { color:#fff !important; }\nhtml.ve-active .oo-ui-popupWidget a:not(.oo-ui-buttonElement-button) { color:#00ffff !important; }\nhtml.ve-active .oo-ui-popupWidget .oo-ui-iconElement-icon,\nhtml.ve-active .oo-ui-popupWidget .oo-ui-indicatorElement-indicator { background-color:transparent !important; }\nhtml.ve-active .oo-ui-popupToolGroup-tools,\nhtml.ve-active .oo-ui-menuSelectWidget { background:#98562f !important; color:#fff !important; border-color:#fff !important; }\nhtml.ve-active .oo-ui-popupToolGroup-tools .oo-ui-tool-title,\nhtml.ve-active .oo-ui-menuOptionWidget { color:#fff !important; }\nhtml.ve-active .oo-ui-menuOptionWidget.oo-ui-optionWidget-highlighted,\nhtml.ve-active .oo-ui-popupToolGroup-tools .oo-ui-tool-link:hover,\nhtml.ve-active .ve-ui-toolbar .oo-ui-tool-active > .oo-ui-tool-link { background:#b17d60 !important; color:#fff !important; }\nhtml.ve-active .oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor:before { border-bottom-color:#fff !important; }\nhtml.ve-active .oo-ui-popupWidget-anchored-top .oo-ui-popupWidget-anchor:after { border-bottom-color:#98562f !important; }\nhtml.ve-active .oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor:before { border-top-color:#fff !important; }\nhtml.ve-active .oo-ui-popupWidget-anchored-bottom .oo-ui-popupWidget-anchor:after { border-top-color:#98562f !important; }\n";document.head.appendChild(s);}());
/* Header dropdown sizing. */
(function(){var s=document.createElement("style");s.id="expanded-header-dropdown-sizing";s.textContent="\n/* Space the language selector after the logo and match Appearance's 32px height. */\n#p-personal > #gd-language-menu { left:72px !important; top:11px !important; height:32px !important; }\n#p-personal > #gd-language-menu > summary { height:32px !important; min-height:32px !important; box-sizing:border-box; padding-top:0 !important; padding-bottom:0 !important; }\n#p-personal > #gd-language-menu .gd-language-options { top:38px; }\n@media(max-width:720px) {\n #p-personal > #gd-language-menu {left:64px !important;}\n #p-personal > #gd-language-menu > summary {width:auto; min-width:44px;}\n #p-personal > #gd-language-menu .gd-language-options {top:52px;}\n}\n";document.head.appendChild(s);}());
(function(){var s=document.createElement("style");s.id="expanded-mobile-utilities-style";s.textContent="/* Mobile utility menu retains the original preference link and Echo widgets. */\n#gd-mobile-utilities[hidden] {display:none !important;}\n@media(min-width:721px) {#gd-mobile-utilities {display:none !important;}}\n@media(max-width:720px) {\n #p-personal #gd-mobile-utilities {position:relative;flex:0 0 auto;}\n #p-personal #gd-mobile-utilities > summary {display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:40px;height:32px;padding:0;list-style:none;font:700 28px/1 Arial,sans-serif;color:#fff;cursor:pointer;}\n #p-personal #gd-mobile-utilities > summary::after {display:none !important;}\n #p-personal #gd-mobile-utilities > summary::-webkit-details-marker {display:none;}\n #p-personal #gd-mobile-utilities:not([open]) > .gd-mobile-utilities-panel {display:none !important;}\n #p-personal #gd-mobile-utilities > .gd-mobile-utilities-panel {position:fixed;right:8px;top:58px;z-index:1001;display:flex;align-items:center;gap:12px;padding:12px;background:#03052f;border:2px solid #fff;border-radius:12px;box-shadow:0 5px 18px #0008;overflow:visible;}\n #p-personal .gd-mobile-utilities-panel > .gd-header-notification {display:flex !important;float:none;margin:0 !important;}\n #p-personal .gd-mobile-utilities-panel > .gd-header-icon {display:flex !important;align-items:center;justify-content:center;min-width:40px;min-height:40px;}\n #p-personal #gd-mobile-utilities.gd-mobile-utilities-unread > summary::before {content:'';position:absolute;top:3px;right:4px;width:8px;height:8px;background:#ffcf00;border:1px solid #03052f;border-radius:50%;}\n}\n";document.head.appendChild(s);}());
/* Group preferences and the original Echo widgets on narrow screens. */
$(function () {
'use strict';
var media = window.matchMedia('(max-width:720px)');
var menu, panel, summary;
var moved = [];
var scheduled = false;
function update() {
var controls = document.querySelector('#p-personal .gd-header-controls');
if (!controls) return;
if (!media.matches) {
moved.forEach(function (entry) {
if (entry.marker.parentNode) entry.marker.parentNode.insertBefore(entry.node, entry.marker);
entry.marker.remove();
});
moved = [];
if (menu) { menu.open = false; menu.hidden = true; }
return;
}
var candidates = Array.from(controls.children).filter(function (node) {
return node.matches('a.gd-header-icon') && /Special:(?:Preferences|MyLanguage\/Preferences)/i.test(decodeURIComponent(node.href)) ||
node.id === 'pt-notifications-alert' || node.id === 'pt-notifications-notice';
});
if (!menu && candidates.length) {
menu = document.createElement('details');
menu.id = 'gd-mobile-utilities';
menu.className = 'gd-header-menu';
summary = document.createElement('summary');
summary.textContent = '\u22ef';
summary.title = 'More: preferences and notifications';
summary.setAttribute('aria-label', 'More: preferences and notifications');
panel = document.createElement('div');
panel.className = 'gd-mobile-utilities-panel';
panel.setAttribute('role', 'group');
panel.setAttribute('aria-label', 'Preferences and notifications');
menu.append(summary, panel);
var account = controls.querySelector('.gd-account-group');
controls.insertBefore(menu, account || null);
}
if (!menu) return;
candidates.forEach(function (node) {
var marker = document.createComment('Mobile utility original position');
node.parentNode.insertBefore(marker, node);
moved.push({node:node, marker:marker});
panel.appendChild(node);
});
menu.hidden = !moved.length;
var unread = Array.from(panel.querySelectorAll('[data-counter-num]')).some(function (node) {
return Number(node.getAttribute('data-counter-num')) > 0;
});
menu.classList.toggle('gd-mobile-utilities-unread', unread);
summary.setAttribute('aria-label', 'More: preferences and notifications' + (unread ? ' (unread notifications)' : ''));
}
function schedule() {
if (scheduled) return;
scheduled = true;
requestAnimationFrame(function () { scheduled = false; update(); });
}
var personal = document.getElementById('p-personal');
if (personal) new MutationObserver(schedule).observe(personal, {childList:true, subtree:true, attributes:true, attributeFilter:['data-counter-num']});
media.addEventListener('change', update);
document.addEventListener('click', function (event) {
if (menu && menu.open && !menu.contains(event.target) &&
!event.target.closest('.mw-echo-ui-overlay, .oo-ui-popupWidget')) menu.open = false;
});
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape' && menu && menu.open) { menu.open = false; summary.focus(); }
});
update();
});
(function(){var s=document.createElement("style");s.id="expanded-mobile-header-correction";s.textContent="/* Mobile-only spacing and control resets; desktop is deliberately untouched. */\n@media(max-width:720px) {\n #p-personal { --gd-mobile-control-height:32px; --gd-mobile-control-gap:12px; }\n #p-personal .gd-header-bar-logo {left:12px !important;}\n #p-personal > #gd-language-menu {left:56px !important;top:11px !important;}\n #p-personal .gd-header-controls {gap:var(--gd-mobile-control-gap) !important;max-width:calc(100vw - 112px) !important;}\n #p-personal .gd-header-controls > .gd-header-menu > summary,\n #p-personal .gd-account-menu > summary,\n #p-personal > #gd-language-menu > summary {\n height:var(--gd-mobile-control-height) !important;min-height:var(--gd-mobile-control-height) !important;\n max-height:var(--gd-mobile-control-height) !important;box-sizing:border-box;margin:0 !important;\n padding-top:0 !important;padding-bottom:0 !important;\n }\n #p-personal .gd-header-controls > .gd-header-menu:not(.gd-account-menu):not(#gd-mobile-utilities) > summary {\n width:auto !important;min-width:32px !important;max-width:none !important;\n padding-left:8px !important;padding-right:8px !important;font-size:14px !important;gap:6px;\n }\n /* The previous generic mobile rule turned every menu into a moon. */\n #p-personal .gd-header-controls > .gd-header-menu > summary::before {content:none !important;display:none !important;}\n #p-personal #gd-mobile-utilities > summary {width:32px !important;min-width:32px !important;max-width:32px !important;padding:0 !important;font:700 28px/1 Arial,sans-serif !important;}\n #p-personal #gd-mobile-utilities.gd-mobile-utilities-unread > summary::before {content:'' !important;display:block !important;}\n #p-personal .gd-header-controls > *,\n #p-personal .gd-account-group,\n #p-personal .gd-account-talk-link,\n #p-personal .gd-account-menu {border-left:0 !important;border-right:0 !important;}\n #p-personal .gd-account-group {gap:0;}\n #p-personal .gd-account-talk-link {height:32px !important;min-height:32px !important;padding:0 4px !important;}\n #p-personal #gd-mobile-utilities .gd-mobile-utilities-panel {gap:0 !important;}\n #p-personal #gd-mobile-utilities .gd-mobile-utilities-panel > * {border:0 !important;margin:0 !important;padding:0 !important;min-height:40px;box-sizing:content-box;}\n #p-personal #gd-mobile-utilities .gd-mobile-utilities-panel > * + * {border-left:1px solid #ffffff40 !important;margin-left:12px !important;padding-left:12px !important;}\n}\n";document.head.appendChild(s);}());
(function(){var s=document.createElement("style");s.id="expanded-infobox-gallery-fixes";s.textContent="\n/* Keep gallery captions on one line and let longer labels use more space. */\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs {align-items:stretch;overflow-x:auto !important;overflow-y:hidden !important;scrollbar-width:thin;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button {flex:1 0 auto !important;min-width:max-content !important;white-space:nowrap !important;overflow-wrap:normal !important;word-break:normal !important;line-height:1.25 !important;padding:.35rem .55rem !important;}\n";document.head.appendChild(s);}());
(function(){
var style=document.createElement('style');style.id='expanded-gallery-layout-v2';style.textContent="\n#bodyContent .portable-infobox > .pi-title {margin:0!important;min-height:0!important;padding:.5rem 1rem!important;line-height:1.4!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery {display:flow-root;padding-top:1rem;box-sizing:border-box;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs {display:flex;margin:0 1rem 1rem!important;overflow:hidden!important;align-items:stretch;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs button {display:flex!important;align-items:center!important;justify-content:center!important;flex:1 0 auto!important;min-width:max-content!important;margin:0!important;padding:.5rem .7rem!important;line-height:1.4!important;white-space:nowrap!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs.expanded-gallery-stacked {flex-direction:column!important;}\n#bodyContent .portable-infobox .expanded-profile-gallery-tabs.expanded-gallery-stacked button {flex:none!important;min-width:0!important;width:100%!important;white-space:normal!important;}\n";document.head.appendChild(style);
function arrange(){if(document.documentElement.classList.contains('ve-active'))return;document.querySelectorAll('.expanded-profile-gallery-tabs').forEach(function(t){t.classList.remove('expanded-gallery-stacked');var needed=Array.from(t.children).reduce(function(n,b){return n+b.getBoundingClientRect().width;},0);t.classList.toggle('expanded-gallery-stacked',needed>t.clientWidth+1);});}
var pending=false;function schedule(){if(pending)return;pending=true;requestAnimationFrame(function(){pending=false;arrange();});}
if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',schedule);else schedule();
window.addEventListener('resize',schedule);new MutationObserver(schedule).observe(document.body||document.documentElement,{childList:true,subtree:true});if(document.fonts)document.fonts.ready.then(schedule);
}());
(function(){var s=document.createElement('style');s.id='expanded-gallery-title-width-fix';s.textContent="\n/* Preserve the infobox's full-width title: its parent has 1rem side padding. */\n#bodyContent .portable-infobox > .pi-title {margin:0 -1rem!important;width:auto!important;}\n";document.head.appendChild(s);}());
(function(){var s=document.createElement('style');s.id='expanded-restore-filter-width-fix';s.textContent="\n/* Let Restore default filters use its complete label width. */\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters .mw-rcfilters-ui-row {grid-template-columns:minmax(0,1fr) max-content!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-resetButton .oo-ui-buttonElement-button {white-space:nowrap!important;}\n@media(max-width:720px){\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-wrapper-filters .mw-rcfilters-ui-row {grid-template-columns:minmax(0,1fr)!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-cell-reset {grid-column:1!important;}\n#bodyContent .mw-rcfilters-ui-filterTagMultiselectWidget-resetButton .oo-ui-buttonElement-button {white-space:normal!important;}\n}\n";document.head.appendChild(s);}());
(function(){var s=document.createElement("style");s.id="expanded-meta-content-status";s.textContent="\n/* Meta classification uses the Auto difficulty face. */\n#firstHeading .gd-content-status[data-status=\"meta\"] {background-image:url(\"https://geometrydashwiki.com/images/e/e8/Auto.png\");}\n";document.head.appendChild(s);}());
/* Resume read-view enhancements after VisualEditor closes. */
mw.hook("ve.deactivationComplete").add(function(){mw.hook("wikipage.content").fire($("#mw-content-text"));window.dispatchEvent(new Event("resize"));});