<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>https://wiki.glasscannon.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ozzy</id>
		<title>GlassCannon Wiki — энциклопедия игр Blizzard - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.glasscannon.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Ozzy"/>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Ozzy"/>
		<updated>2026-04-11T07:14:32Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.2</generator>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=Module:Vertical_header&amp;diff=22948</id>
		<title>Module:Vertical header</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=Module:Vertical_header&amp;diff=22948"/>
				<updated>2022-09-28T22:30:53Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: Новая страница: «local p = {}  function p.cell(frame) 	local text = frame.args.text 	local sortPadding = frame.args.sortPadding 	local vertAlign = frame.args.vertAlign 	local maxW…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
function p.cell(frame)&lt;br /&gt;
	local text = frame.args.text&lt;br /&gt;
	local sortPadding = frame.args.sortPadding&lt;br /&gt;
	local vertAlign = frame.args.vertAlign&lt;br /&gt;
	local maxWidth = frame.args.maxWidth&lt;br /&gt;
	local noBold = frame.args.noBold&lt;br /&gt;
	local style = frame.args.style:gsub(&amp;quot;\&amp;quot;&amp;quot;, &amp;quot;&amp;amp;quot;&amp;quot;)&lt;br /&gt;
	local cellStyle = frame.args.cellstyle:gsub(&amp;quot;\&amp;quot;&amp;quot;, &amp;quot;&amp;amp;quot;&amp;quot;)&lt;br /&gt;
	local wikiText = &amp;quot;class = \&amp;quot;nowrap&amp;quot;&lt;br /&gt;
	local normalAlign = &amp;quot;&amp;quot;&lt;br /&gt;
	-- local stupidIEAlign = &amp;quot;&amp;quot;&lt;br /&gt;
	local rows = 1&lt;br /&gt;
	local width = 0&lt;br /&gt;
	if maxWidth ~= &amp;quot;&amp;quot; then&lt;br /&gt;
		width = maxWidth&lt;br /&gt;
	else&lt;br /&gt;
		for eachMatch in text:gmatch(&amp;quot;&amp;lt;[bB][rR] */? *&amp;gt;&amp;quot;) do&lt;br /&gt;
			rows = rows + 1&lt;br /&gt;
		end&lt;br /&gt;
		width = rows * 0.875&lt;br /&gt;
		width = width .. &amp;quot;em&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	if sortPadding == &amp;quot;&amp;quot; then&lt;br /&gt;
		wikiText = wikiText .. &amp;quot; unsortable&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	wikiText = wikiText .. &amp;quot;\&amp;quot; style=\&amp;quot;line-height:99%;vertical-align:&amp;quot; .. vertAlign .. &amp;quot;;padding:&amp;quot;&lt;br /&gt;
	if sortPadding == &amp;quot;&amp;quot; then&lt;br /&gt;
		wikiText = wikiText .. &amp;quot;.4em&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		wikiText = wikiText .. &amp;quot;21px&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	wikiText = wikiText .. &amp;quot; .4em .2em;background-position:50% .4em !important;&amp;quot;&lt;br /&gt;
	wikiText = wikiText .. &amp;quot;min-width:&amp;quot; .. width .. &amp;quot;;max-width:&amp;quot; .. width .. &amp;quot;;width:&amp;quot; .. width .. &amp;quot;;overflow:hidden;&amp;quot; .. cellStyle .. &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
	wikiText = wikiText .. &amp;quot; | &amp;lt;div style=\&amp;quot;&amp;quot; .. frame:preprocess(&amp;quot;{{writing-mode|v1}}{{Transform-rotate|180}}&amp;quot;) .. &amp;quot;-ms-transform: none \ ;padding-left:1px;text-align:&amp;quot;&lt;br /&gt;
	if vertAlign == &amp;quot;top&amp;quot; then&lt;br /&gt;
		normalAlign = &amp;quot;right&amp;quot;&lt;br /&gt;
		-- stupidIEAlign = &amp;quot;left&amp;quot;&lt;br /&gt;
	elseif vertAlign == &amp;quot;middle&amp;quot; then&lt;br /&gt;
		normalAlign = &amp;quot;center&amp;quot;&lt;br /&gt;
		-- stupidIEAlign = &amp;quot;center&amp;quot;&lt;br /&gt;
	else&lt;br /&gt;
		normalAlign = &amp;quot;left&amp;quot;&lt;br /&gt;
		-- stupidIEAlign = &amp;quot;right&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
	wikiText = wikiText .. normalAlign .. &amp;quot;;&amp;quot; -- text-align:&amp;quot; .. stupidIEAlign .. &amp;quot; \ ;&amp;quot;&lt;br /&gt;
	wikiText = wikiText .. style .. &amp;quot;\&amp;quot;&amp;gt;&amp;quot;&lt;br /&gt;
	if noBold == &amp;quot;&amp;quot; then&lt;br /&gt;
		wikiText = wikiText .. text&lt;br /&gt;
	else&lt;br /&gt;
		wikiText = wikiText .. frame:preprocess(&amp;quot;{{nobold|1=&amp;quot; .. text .. &amp;quot;}}&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	wikiText = wikiText .. &amp;quot;&amp;lt;/div&amp;gt;&amp;quot;&lt;br /&gt;
	return wikiText&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=13340</id>
		<title>Заглавная страница</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=%D0%97%D0%B0%D0%B3%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&amp;diff=13340"/>
				<updated>2021-07-04T20:47:36Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Добро пожаловать на GlassCannon Wiki! Всего в нашей энциклопедии сейчас {{NUMBEROFARTICLES}} статей. Перед редактированием, пожалуйста, ознакомьтесь с [[Принципы GlassCannon Wiki|принципами нашей Wiki]].&lt;br /&gt;
&lt;br /&gt;
* [[Дорожная карта]] &lt;br /&gt;
* [[Статьи-источники]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 16%;&amp;quot;| &amp;lt;pic src=&amp;quot;/Icon-Blizzard-Entertainment.jpg&amp;quot; width=90% /&amp;gt; &amp;lt;br&amp;gt;&amp;lt;div style=&amp;quot;font-size:16px;&amp;quot;&amp;gt;Общее&amp;lt;/div&amp;gt;&lt;br /&gt;
! style=&amp;quot;width: 16%;&amp;quot;| [[Файл:Icon-Game-Diablo.jpg|frameless|135px|link=Diablo]] &amp;lt;br&amp;gt;&amp;lt;div style=&amp;quot;font-size:16px;&amp;quot;&amp;gt;[[Diablo]]&amp;lt;/div&amp;gt;&lt;br /&gt;
! style=&amp;quot;width: 17%;&amp;quot;| [[Файл:Icon-Game-Diablo-2.jpg|frameless|135px|link=Diablo II]] &amp;lt;br&amp;gt;&amp;lt;div style=&amp;quot;font-size:16px;&amp;quot;&amp;gt;[[Diablo II]]&amp;lt;/div&amp;gt;&lt;br /&gt;
! style=&amp;quot;width: 17%;&amp;quot;| [[Файл:Icon-Game-Diablo-3.jpg|frameless|135px|link=Diablo III]] &amp;lt;br&amp;gt;&amp;lt;div style=&amp;quot;font-size:16px;&amp;quot;&amp;gt;[[Diablo III]]&amp;lt;/div&amp;gt;&lt;br /&gt;
! style=&amp;quot;width: 17%;&amp;quot;| [[Файл:Icon-Game-Diablo-4.jpg|frameless|135px|link=Diablo IV]] &amp;lt;br&amp;gt;&amp;lt;div style=&amp;quot;font-size:16px;&amp;quot;&amp;gt;[[Diablo IV]]&amp;lt;/div&amp;gt;&lt;br /&gt;
! style=&amp;quot;width: 17%;&amp;quot;| [[Файл:Icon-Game-Diablo-Immortal.jpg|frameless|135px|link=Diablo Immortal]] &amp;lt;br&amp;gt;&amp;lt;div style=&amp;quot;font-size:16px;&amp;quot;&amp;gt;[[Diablo Immortal]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;vertical-align: top;&amp;quot;|&lt;br /&gt;
* [[Файл:Blizzard-icon.webp|20px|link=Blizzard Entertainment]] [[Blizzard Entertainment]]&lt;br /&gt;
* [[Файл:Blizzard-North-icon.webp|20px|link=Blizzard Entertainment]] [[Blizzard North]]&lt;br /&gt;
* Неанонсированные игры&lt;br /&gt;
** [[Diablo III (Blizzard North)]]&lt;br /&gt;
** [[Diablo Junior]]&lt;br /&gt;
** [[Starblo]]&lt;br /&gt;
** [[Hades]]&lt;br /&gt;
** [[Fenris]]&lt;br /&gt;
* Отмененные игры&lt;br /&gt;
** [[WarCraft Adventures: Lord of the Clans]]&lt;br /&gt;
** [[Shattered Nations]]&lt;br /&gt;
** [[StarCraft: Ghost]]&lt;br /&gt;
** [[Titan]]&lt;br /&gt;
* [[Файл:Battlenet-icon.webp|20px|link=Battle.net]] [[Battle.net]]&lt;br /&gt;
* [[BattleTag]]&lt;br /&gt;
* [[Файл:BlizzCon-icon.webp|20px|link=BlizzCon]]  [[BlizzCon]]&lt;br /&gt;
&lt;br /&gt;
| style=&amp;quot;vertical-align: top;&amp;quot;|&lt;br /&gt;
* [[История версий Diablo|История версий]]&lt;br /&gt;
* [[Diablo: Hellfire]]&lt;br /&gt;
* [[Файл:Diablo-4-Classes-icon.svg|20px|link=Классы (Diablo)]] [[Классы (Diablo)|Классы]]&lt;br /&gt;
** [[Воин (Diablo)|Воин]]&lt;br /&gt;
** [[Разбойница (Diablo)|Разбойница]]&lt;br /&gt;
** [[Волшебник (Diablo)|Волшебник]]&lt;br /&gt;
** [[Монах (Diablo)|Монах]]&lt;br /&gt;
** [[Варвар (Diablo)|Варвар]]&lt;br /&gt;
** [[Бард (Diablo)|Бард]]&lt;br /&gt;
* [[Экипировка (Diablo)|Экипировка]]&lt;br /&gt;
* [[Святилища (Diablo)|Святилища]]&lt;br /&gt;
* [[Файл:Monsters-icon.webp|20px|link=Бестиарий (Diablo)]] [[Бестиарий (Diablo)|Бестиарий]]&lt;br /&gt;
** [[Боссы (Diablo)|Боссы]]  &lt;br /&gt;
* [[Уровни сложности (Diablo)|Уровни сложности]]&lt;br /&gt;
* [[Игрок против игрока (Diablo)|Игрок против игрока]]&lt;br /&gt;
* [[Модификации (Diablo)|Модификации]]&lt;br /&gt;
* [[Саундтрек (Diablo)|Саундтрек]]&lt;br /&gt;
* [[Системные требования (Diablo)|Системные требования]]&lt;br /&gt;
* [[Титры (Diablo)|Титры]]&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;vertical-align: top;&amp;quot;|&lt;br /&gt;
* [[The Arreat Summit|Руководство]]&lt;br /&gt;
* [[История версий Diablo II|История версий]]&lt;br /&gt;
* [[Diablo II: Lord of Destruction]]&lt;br /&gt;
* [[Diablo II: Salvation]]&lt;br /&gt;
* [[Diablo II: Resurrected]]&lt;br /&gt;
* [[Файл:Diablo-4-Classes-icon.svg|20px|link=Классы (Diablo II)]] [[Классы (Diablo II)|Классы]]&lt;br /&gt;
** [[Амазонка (Diablo II)|Амазонка]]&lt;br /&gt;
** [[Ассасин (Diablo II)|Ассасин]]&lt;br /&gt;
** [[Варвар (Diablo II)|Варвар]]&lt;br /&gt;
** [[Волшебница (Diablo II)|Волшебница]]&lt;br /&gt;
** [[Друид (Diablo II)|Друид]]&lt;br /&gt;
** [[Некромант (Diablo II)|Некромант]]&lt;br /&gt;
** [[Паладин (Diablo II)|Паладин]]&lt;br /&gt;
* [[Экипировка (Diablo II)|Экипировка]]&lt;br /&gt;
** [[Комплектные предметы (Diablo II)|Комплектные предметы]]&lt;br /&gt;
** [[Уникальные предметы (Diablo II)|Уникальные предметы]]&lt;br /&gt;
** [[Самоцветы (Diablo II)|Самоцветы]]&lt;br /&gt;
** [[Руны (Diablo II)|Руны]]&lt;br /&gt;
*** [[Рунные слова (Diablo II)|Рунные слова]]&lt;br /&gt;
* [[Файл:Monsters-icon.webp|20px|link=Бестиарий (Diablo II)]] [[Бестиарий (Diablo II)|Бестиарий]]&lt;br /&gt;
** [[Боссы (Diablo II)|Боссы]]  &lt;br /&gt;
* [[Уровни сложности (Diablo II)|Уровни сложности]]&lt;br /&gt;
* [[Героический режим (Diablo II)|Героический режим]]&lt;br /&gt;
* [[Игрок против игрока (Diablo II)|Игрок против игрока]]&lt;br /&gt;
* [[Наемники (Diablo II)|Наемники]]&lt;br /&gt;
* [[Сезоны (Diablo II)|Сезоны]]&lt;br /&gt;
* [[Кампания (Diablo II)|Кампания]]&lt;br /&gt;
** [[Акт I (Diablo II)|Акт I]]&lt;br /&gt;
** [[Акт II (Diablo II)|Акт II]]&lt;br /&gt;
** [[Акт III (Diablo II)|Акт III]]&lt;br /&gt;
** [[Акт IV (Diablo II)|Акт IV]]&lt;br /&gt;
** [[Акт V (Diablo II)|Акт V]]&lt;br /&gt;
** [[The Secret Cow Level (Diablo II)|The Secret Cow Level]]&lt;br /&gt;
* [[Модификации (Diablo II)|Модификации]]&lt;br /&gt;
* [[Саундтрек (Diablo II)|Саундтрек]]&lt;br /&gt;
* [[Системные требования (Diablo II)|Системные требования]]&lt;br /&gt;
* [[Титры (Diablo II)|Титры]]&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;vertical-align: top;&amp;quot;|&lt;br /&gt;
* [[История версий Diablo III|История версий]]&lt;br /&gt;
* [[Diablo III: Reaper of Souls]]&lt;br /&gt;
* [[Diablo III: The King in the North]]&lt;br /&gt;
* [[Diablo III: Возвращение некроманта]]&lt;br /&gt;
* [[Файл:Diablo-4-Classes-icon.svg|20px|link=Классы (Diablo III)]] [[Классы (Diablo III)|Классы]]&lt;br /&gt;
** [[Файл:Diablo-3-Barbarian-icon.webp|20px|link=Варвар (Diablo III)]] [[Варвар (Diablo III)|Варвар]]&lt;br /&gt;
** [[Файл:Diablo-3-Crusader-icon.webp|20px|link=Крестоносец (Diablo III)]] [[Крестоносец (Diablo III)|Крестоносец]]&lt;br /&gt;
** [[Файл:Diablo-3-Demon-Hunter-icon.webp|20px|link=Охотник на демонов (Diablo III)]] [[Охотник на демонов (Diablo III)|Охотник на демонов]]&lt;br /&gt;
** [[Файл:Diablo-3-Monk-icon.webp|20px|link=Монах (Diablo III)]] [[Монах (Diablo III)|Монах]]&lt;br /&gt;
** [[Файл:Diablo-3-Necromancer-icon.webp|20px|link=Некромант (Diablo III)]] [[Некромант (Diablo III)|Некромант]]&lt;br /&gt;
** [[Файл:Diablo-3-Witch-Doctor-icon.webp|20px|link=Колдун (Diablo III)]] [[Колдун (Diablo III)|Колдун]]&lt;br /&gt;
** [[Файл:Diablo-3-Wizard-icon.webp|20px|link=Чародей (Diablo IV)]] [[Чародей (Diablo III)|Чародей]]&lt;br /&gt;
* [[Экипировка (Diablo III)|Экипировка]]&lt;br /&gt;
** [[Комплектные предметы (Diablo III)|Комплектные предметы]]&lt;br /&gt;
** [[Легендарные предметы (Diablo III)|Легендарные предметы]]&lt;br /&gt;
** [[Бесплотные предметы (Diablo III)|Бесплотные предметы]]&lt;br /&gt;
** [[Самоцветы (Diablo III)|Самоцветы]]&lt;br /&gt;
* [[Файл:Monsters-icon.webp|20px|link=Бестиарий (Diablo III)]] [[Бестиарий (Diablo III)|Бестиарий]]&lt;br /&gt;
** [[Боссы (Diablo III)|Боссы]] &lt;br /&gt;
* [[Уровни сложности (Diablo III)|Уровни сложности]]&lt;br /&gt;
* [[Героический режим (Diablo III)|Героический режим]]&lt;br /&gt;
* [[Сезоны (Diablo III)|Сезоны]]&lt;br /&gt;
** [[Сезонные завоевания (Diablo III)|Сезонные завоевания]]&lt;br /&gt;
* [[Рейтинговые таблицы (Diablo III)|Рейтинговые таблицы]]&lt;br /&gt;
* [[Уровни совершенствования (Diablo III)|Уровни совершенствования]]&lt;br /&gt;
* [[Адское устройство (Diablo III)|Адское устройство]]&lt;br /&gt;
* [[Достижения (Diablo III)|Достижения]]&lt;br /&gt;
* [[Игрок против игрока (Diablo III)|Игрок против игрока]]&lt;br /&gt;
** [[Бои без правил (Diablo III)|Бои без правил]]&lt;br /&gt;
** [[Арена (Diablo III)|Арена]]&lt;br /&gt;
* [[Порталы дерзаний (Diablo III)|Порталы дерзаний]]&lt;br /&gt;
* [[Коллекция (Diablo III)|Коллекция]]&lt;br /&gt;
** [[Крылья (Diablo III)|Крылья]]&lt;br /&gt;
** [[Питомцы (Diablo III)|Питомцы]]&lt;br /&gt;
** [[Флаги (Diablo III)|Флаги]]&lt;br /&gt;
** [[Рамки для портрета (Diablo III)|Рамки для портрета]]&lt;br /&gt;
** [[Знамя (Diablo III)|Знамена]]&lt;br /&gt;
* [[Режим приключений (Diablo III)|Режим приключений]]&lt;br /&gt;
** [[Поручения (Diablo III)|Поручения]]&lt;br /&gt;
** [[Нефалемские порталы (Diablo III)|Нефалемские порталы]]&lt;br /&gt;
** [[Комплектные подземелья (Diablo III)|Комплектные подземелья]]&lt;br /&gt;
* [[Ремесленники (Diablo III)|Ремесленники]]&lt;br /&gt;
** [[Кузнец (Diablo III)|Кузнец]]&lt;br /&gt;
** [[Ювелир (Diablo III)|Ювелир]]&lt;br /&gt;
** [[Гадалка (Diablo III)|Гадалка]]&lt;br /&gt;
** [[Куб Канаи (Diablo III)|Куб Канаи]]&lt;br /&gt;
* [[Спутники (Diablo III)|Спутники]]&lt;br /&gt;
** [[Храмовник (Diablo III)|Храмовник]]&lt;br /&gt;
** [[Негодяй (Diablo III)|Негодяй]]&lt;br /&gt;
** [[Заклинательница (Diablo III)|Заклинательница]]&lt;br /&gt;
* [[Кампания (Diablo III)|Кампания]]&lt;br /&gt;
* [[Клан (Diablo III)|Клан]]&lt;br /&gt;
* [[Саундтрек (Diablo III)|Саундтрек]]&lt;br /&gt;
* [[Системные требования (Diablo III)|Системные требования]]&lt;br /&gt;
* [[Титры (Diablo III)|Титры]]&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;vertical-align: top;&amp;quot;|&lt;br /&gt;
* [[История версий Diablo IV|История версий]]&lt;br /&gt;
* [[Файл:Diablo-4-Classes-icon.svg|20px|link=Классы (Diablo IV)]] [[Классы (Diablo IV)|Классы]]&lt;br /&gt;
** [[Файл:Diablo-4-Barbarian-icon.webp|20px|link=Варвар (Diablo IV)]] [[Варвар (Diablo IV)|Варвар]]&lt;br /&gt;
** [[Файл:Diablo-4-Druid-icon.webp|20px|link=Друид (Diablo IV)]] [[Друид (Diablo IV)|Друид]]&lt;br /&gt;
** [[Файл:Diablo-4-Sorceress-icon.webp|20px|link=Волшебница (Diablo IV)]] [[Волшебница (Diablo IV)|Волшебница]]&lt;br /&gt;
** [[Файл:Diablo-4-Rogue-icon.webp|20px|link=Разбойница (Diablo IV)]] [[Разбойница (Diablo IV)|Разбойница]]&lt;br /&gt;
* [[Умения (Diablo IV)|Умения]]&lt;br /&gt;
* [[Таланты (Diablo IV)|Таланты]]&lt;br /&gt;
* [[Экипировка (Diablo IV)|Экипировка]]&lt;br /&gt;
** [[Легендарные предметы (Diablo IV)|Легендарные предметы]]&lt;br /&gt;
** [[Комплектные предметы (Diablo IV)|Комплектные предметы]]&lt;br /&gt;
** [[Мифические предметы (Diablo IV)|Мифические предметы]]&lt;br /&gt;
** [[Руны (Diablo IV)|Руны]]&lt;br /&gt;
** [[Самоцветы (Diablo IV)|Самоцветы]]&lt;br /&gt;
* [[Святилища (Diablo IV)|Святилища]]&lt;br /&gt;
* [[Файл:Diablo-4-World-icon.svg|20px|link=Регионы (Diablo IV)]] [[Регионы (Diablo IV)|Регионы]]&lt;br /&gt;
** [[Скосглен (Diablo IV)|Скосглен]]&lt;br /&gt;
** [[Расколотые вершины (Diablo IV)|Расколотые вершины]]&lt;br /&gt;
** [[Бесплодная степь (Diablo IV)|Бесплодная степь]]&lt;br /&gt;
** [[Хавезар (Diablo IV)|Хавезар]]&lt;br /&gt;
** [[Кеджистан (Diablo IV)|Кеджистан]]&lt;br /&gt;
* [[Подземелья (Diablo IV)|Подземелья]]&lt;br /&gt;
** [[Drowning Caverns (Diablo IV)|Drowning Caverns]]&lt;br /&gt;
** [[Corbach Crypts (Diablo IV)|Corbach Crypts]]&lt;br /&gt;
** [[Garan Hold Dungeon (Diablo IV)|Garan Hold Dungeon]]&lt;br /&gt;
** [[Domhainne Tunnels (Diablo IV)|Domhainne Tunnels]]&lt;br /&gt;
* [[Файл:Monsters-icon.webp|20px|link=Бестиарий (Diablo IV)]] [[Бестиарий (Diablo IV)|Бестиарий]]&lt;br /&gt;
** [[Боссы (Diablo IV)|Боссы]]  &lt;br /&gt;
*** [[Ашава]] &lt;br /&gt;
*** [[Дюриэль]] &lt;br /&gt;
*** [[Tomb Lord]]&lt;br /&gt;
*** [[Merinth of the Deep]]&lt;br /&gt;
* [[Транспорт (Diablo IV)|Транспорт]]&lt;br /&gt;
* [[Лагеря (Diablo IV)|Лагеря]]&lt;br /&gt;
* [[Героический режим (Diablo IV)|Героический режим]]&lt;br /&gt;
* [[Достижения (Diablo IV)|Достижения]]&lt;br /&gt;
* [[Игрок против игрока (Diablo IV)|Игрок против игрока]]&lt;br /&gt;
* [[Клан (Diablo IV)|Клан]]&lt;br /&gt;
* [[Сезоны (Diablo IV)|Сезоны]]&lt;br /&gt;
* [[Саундтрек (Diablo IV)|Саундтрек]]&lt;br /&gt;
* [[Системные требования (Diablo IV)|Системные требования]]&lt;br /&gt;
* [[Титры (Diablo IV)|Титры]]&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;vertical-align: top;&amp;quot;|&lt;br /&gt;
* [[История версий Diablo Immortal|История версий]]&lt;br /&gt;
* [[Файл:Diablo-4-Classes-icon.svg|20px|link=Классы (Diablo Immortal)]] [[Классы (Diablo Immortal)|Классы]]&lt;br /&gt;
** [[Файл:Diablo-Immortal-Barbarian-icon.webp|20px|link=Варвар (Diablo Immortal)]] [[Варвар (Diablo Immortal)|Варвар]]&lt;br /&gt;
** [[Файл:Diablo-Immortal-Crusader-icon.webp|20px|link=Крестоносец (Diablo Immortal)]] [[Крестоносец (Diablo Immortal)|Крестоносец]]&lt;br /&gt;
** [[Файл:Diablo-Immortal-Demon-Hunter-icon.webp|20px|link=Охотник на демонов (Diablo Immortal)]] [[Охотник на демонов (Diablo Immortal)|Охотник на демонов]]&lt;br /&gt;
** [[Файл:Diablo-Immortal-Monk-icon.webp|20px|link=Монах (Diablo Immortal)]] [[Монах (Diablo Immortal)|Монах]]&lt;br /&gt;
** [[Файл:Diablo-Immortal-Necromancer-icon.webp|20px|link=Некромант (Diablo Immortal)]] [[Некромант (Diablo Immortal)|Некромант]]&lt;br /&gt;
** [[Файл:Diablo-Immortal-Wizard-icon.webp|20px|link=Чародей (Diablo Immortal)]] [[Чародей (Diablo Immortal)|Чародей]]&lt;br /&gt;
* [[Экипировка (Diablo Immortal)|Экипировка]]&lt;br /&gt;
** [[Легендарные предметы (Diablo Immortal)|Легендарные предметы]]&lt;br /&gt;
** [[Легендарные самоцветы (Diablo Immortal)|Легендарные самоцветы]]&lt;br /&gt;
** [[Руны (Diablo Immortal)|Руны]]&lt;br /&gt;
* [[Древние порталы (Diablo Immortal)|Древние порталы]]&lt;br /&gt;
* [[Святилища (Diablo Immortal)|Святилища]]&lt;br /&gt;
* [[Талисманы (Diablo Immortal)|Талисманы]]&lt;br /&gt;
* [[Уровни совершенствования (Diablo Immortal)|Уровни совершенствования]]&lt;br /&gt;
* [[Гильдии (Diablo Immortal)|Гильдии]]&lt;br /&gt;
* [[Файл:Monsters-icon.webp|20px|link=Бестиарий (Diablo Immortal)]] [[Бестиарий (Diablo Immortal)|Бестиарий]]&lt;br /&gt;
** [[Боссы (Diablo Immortal)|Боссы]] &lt;br /&gt;
* [[Города (Diablo Immortal)|Города]]&lt;br /&gt;
** [[Вестмарш (Diablo Immortal)|Вестмарш]]&lt;br /&gt;
* [[Файл:Diablo-4-World-icon.svg|20px|link=Открытые зоны (Diablo Immortal)]] [[Открытые зоны (Diablo Immortal)|Открытые зоны]]&lt;br /&gt;
** [[Библиотека Золтуна Кулла (Diablo Immortal)|Библиотека Золтуна Кулла]]&lt;br /&gt;
** [[Гиблый остров (Diablo Immortal)|Гиблый остров]]&lt;br /&gt;
** [[Темнолесье (Diablo Immortal)|Темнолесье]]&lt;br /&gt;
** [[Море Шассар (Diablo Immortal)|Море Шассар]]&lt;br /&gt;
** [[Мерзлая тундра (Diablo Immortal)|Мерзлая тундра]]&lt;br /&gt;
** [[Пик Завейн (Diablo Immortal)|Пик Завейн]]&lt;br /&gt;
** [[Вортем (Diablo Immortal)|Вортем]]&lt;br /&gt;
** [[Эшволдское кладбище (Diablo Immortal)|Эшволдское кладбище]]&lt;br /&gt;
* [[Подземелья (Diablo Immortal)|Подземелья]]&lt;br /&gt;
** [[Mad King's Breach (Diablo Immortal)|Mad King's Breach]]&lt;br /&gt;
** [[Заброшенная башня (Diablo Immortal)|Заброшенная башня]]&lt;br /&gt;
** [[Гробница Фахира (Diablo Immortal)|Гробница Фахира]]&lt;br /&gt;
** [[Destruction's End (Diablo Immortal)|Destruction's End]]&lt;br /&gt;
** [[Temple of Namari (Diablo Immortal)|Temple of Namari]]&lt;br /&gt;
** [[Kikuras Rapids (Diablo Immortal)|Kikuras Rapids]]&lt;br /&gt;
** [[Court of Madness (Diablo Immortal)|Court of Madness]]&lt;br /&gt;
** [[Пещера отголосков (Diablo Immortal)|Пещера отголосков]]&lt;br /&gt;
** [[Испытание Киона (Diablo Immortal)|Испытание Киона]]&lt;br /&gt;
* [[Боевой пропуск (Diablo Immortal)|Боевой пропуск]]&lt;br /&gt;
* [[Клан (Diablo Immortal)|Клан]]&lt;br /&gt;
* [[Игрок против игрока (Diablo Immortal)|Игрок против игрока]]&lt;br /&gt;
* [[Саундтрек (Diablo Immortal)|Саундтрек]]&lt;br /&gt;
* [[Системные требования (Diablo Immortal)|Системные требования]]&lt;br /&gt;
* [[Титры (Diablo Immortal)|Титры]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12337</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12337"/>
				<updated>2021-06-08T23:48:29Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'red',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				'vertical-align': 'middle',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				display: 'inline-block',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12336</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12336"/>
				<updated>2021-06-08T23:45:30Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'red',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				'vertical-align': 'middle',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12335</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12335"/>
				<updated>2021-06-08T23:43:43Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'red',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				vertical-align: 'middle',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12334</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12334"/>
				<updated>2021-06-08T23:42:46Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'red',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0,&lt;br /&gt;
				//vertical-align: 'middle'&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12333</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12333"/>
				<updated>2021-06-08T23:41:35Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'red',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0,&lt;br /&gt;
				vertical-align: 'middle'&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12326</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12326"/>
				<updated>2021-06-08T23:24:23Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'red',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12325</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12325"/>
				<updated>2021-06-08T23:23:14Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'yellow',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
/*&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
*/		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12324</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12324"/>
				<updated>2021-06-08T23:22:11Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'yellow',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			/*&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
			*/&lt;br /&gt;
&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B0_(Diablo_II)&amp;diff=12320</id>
		<title>Амазонка (Diablo II)</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B0_(Diablo_II)&amp;diff=12320"/>
				<updated>2021-06-08T23:12:41Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
{{Класс (Diablo II)&lt;br /&gt;
| название       = Амазонка&lt;br /&gt;
| иллюстрация    = Diablo-2-Amazon-01.gif&lt;br /&gt;
| экипировка     = Луки амазонок, копья амазонок, дротики амазонок&lt;br /&gt;
| стихии         = Физический урон, молния, яд, холод, огонь, магический урон&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Амазонка''' {{en|Amazon}} — один из [[Классы (Diablo II)|классов]] персонажей в [[Diablo II]].&lt;br /&gt;
&lt;br /&gt;
Аскари, известные также как амазонки, родом с островов Сковос, группы покрытых непроходимыми джунглями островов на Двух морях. Представители этого матриархального племени — могучие воительницы, которые путешествуют по миру, занимаясь наемным трудом и искореняя силы зла.&lt;br /&gt;
&lt;br /&gt;
Наносите врагам колющие удары копьями и дротиками. Поражайте демонов шквалом стрел, орудуя луком не хуже сестер-разбойниц Незримого Ока. Избегайте смертоносных ударов, полагаясь на свою нечеловеческую ловкость. Амазонка всю жизнь готовилась к жестокой кузне войны и виртуозно владеет искусством боя.&lt;br /&gt;
&lt;br /&gt;
This powerful woman warrior belongs to nomadic bands who roam the plains near the South Sea. The wandering of these groups often brings them into conflict with other peoples, so the Amazon is accustomed to fighting to defend her own. This lifestyle has made her fiercely independent and able to weather severe hardship and travel. While her skill with the bow rivals that of the Rogues, the Amazon is also adept in the use of spears and other throwing weapons, as well as in hand to hand combat. The Amazon is much sought after as a mercenary, in which type of service she will be loyal as long as her own ends are also served.&lt;br /&gt;
&lt;br /&gt;
== История ==&lt;br /&gt;
&lt;br /&gt;
The Amazons are women warriors who hail from a group of islands in the Twin Seas, near the border of the Great Ocean. Only the permanently snow-covered peak of Mount Karcheus breaks the expanses of lush forests on the islands.&lt;br /&gt;
&lt;br /&gt;
The Amazon people are a relatively isolated culture. Adapting over the centuries to their tropical milieu, they have built magnificent cities in the forest canopy. These cities are an architectural phenomenon and a source of great pride to the Amazon people. They do not follow the teachings of the Zakarum, but instead practice a polytheistic religion that adheres to the strict principles of Order. Their oracles long ago predicted the Dark Exile, and they have been preparing to combat it ever since. Amazons regard the destruction of the Three Prime Evils as their destiny, ushering in a new era when mortal men and women can at long last take their rightful place in the universe, no longer merely playthings for the beings of the Outer Realms.&lt;br /&gt;
&lt;br /&gt;
The Amazons are a seafaring people, one of the first to have made trade contact with both the Kingdoms of the West and with Kejhistan in the East. Their prominence in the world's trade establishment has afforded their warriors the reputation they currently enjoy as cunning strategists and skilled combatants. They are much sought after as mercenaries, being both expert soldiers as well as extremely loyal - as long as the assignment does not conflict with their strict sense of ethics.&lt;br /&gt;
&lt;br /&gt;
Their pantheon of gods consists of a well-defined hierarchy, each member upholding some segment of the balance of Order. It is this strong sense of order that drives the Amazon people to achieve greatness in even the smallest of their endeavors. Their prime deity is Athulua who, with her consort, Kethryes, rules over the seasons and the weather. Under these Goddesses are a wide assortment of lesser deities, each responsible for his or her own sphere of influence among the Amazon people's daily life. The Amazons believe this pantheon is the remnant of the original inhabitants that settled the islands centuries ago. According to ancient records, they share the same names as these gods, although aspects of their personalities seem to have evolved over the centuries.&lt;br /&gt;
&lt;br /&gt;
In the Amazon culture, only the women serve as warriors, their intrinsic superior dexterity and lithe body structures are better suited to combat in the dense rainforest environs of the islands. Their society is far from stratified, however, as men are responsible for any number of positions in the community, government, and clergy, as well as merchant and agricultural occupations.&lt;br /&gt;
&lt;br /&gt;
Traits and Abilities:&lt;br /&gt;
&lt;br /&gt;
While more than competent in hand-to-hand combat, training in the jungles of her native islands has shaped the Amazon's skill with the bow and missile weapons into one of unparalleled excellence. With the bow, her only rivals are the Sisters of the Sightless Eye. But, unlike her sisters in arms, the Amazon is also highly adept in the use of spears and other thrown weapons. The powers they possess are a combination of Prime magic, Holy magic and ingenious weapon construction.&lt;br /&gt;
&lt;br /&gt;
== Умения ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto; border: none;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Дротики и копья&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Пассивные и магические навыки&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Луки и арбалеты&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center; background: #0f0000&amp;quot;| &lt;br /&gt;
&amp;lt;div class=&amp;quot;imageMapHighlighter&amp;quot;&amp;gt;&amp;lt;imagemap&amp;gt;&lt;br /&gt;
Файл:D2-SkillTree-Amazon.png&lt;br /&gt;
rect 16 13 64 61 [[Выпад (Diablo II)]]&lt;br /&gt;
rect 16 149 64 197 [[Прокалывание (Diablo II)]]&lt;br /&gt;
rect 16 285 64 333 [[Лучшая защита (Diablo II)]]&lt;br /&gt;
rect 85 81 133 130 [[Мощный удар (Diablo II)]]&lt;br /&gt;
rect 85 217 133 265 [[Заряженный удар (Diablo II)]]&lt;br /&gt;
rect 85 353 133 401 [[Удар молнии (Diablo II)]]&lt;br /&gt;
rect 154 81 202 130 [[Отравленный дротик (Diablo II)]]&lt;br /&gt;
rect 154 149 202 197 [[Разряд молнии (Diablo II)]]&lt;br /&gt;
rect 154 217 202 265 [[Чумной дротик (Diablo II)]]&lt;br /&gt;
rect 154 353 202 401 [[Неистовство молний (Diablo II)]]&lt;br /&gt;
&lt;br /&gt;
rect 247 13 295 61 [[Внутреннее зрение (Diablo II)]]&lt;br /&gt;
rect 247 149 295 197 [[Замедление снарядов (Diablo II)]]&lt;br /&gt;
rect 247 285 295 333 [[Двойник (Diablo II)]]&lt;br /&gt;
rect 247 353 295 401 [[Валькирия (Diablo II)]]&lt;br /&gt;
rect 316 81 364 130 [[Уклонение (Diablo II)]]&lt;br /&gt;
rect 316 149 364 197 [[Ускользание (Diablo II)]]&lt;br /&gt;
rect 316 285 364 333 [[Избежание (Diablo II)]]&lt;br /&gt;
rect 385 13 433 61 [[Критический удар (Diablo II)]]&lt;br /&gt;
rect 385 217 433 265 [[Пронзание (Diablo II)]]&lt;br /&gt;
rect 385 353 433 401 [[Пробивание (Diablo II)]]&lt;br /&gt;
&lt;br /&gt;
rect 478 81 526 130 [[Морозная стрела (Diablo II)]]&lt;br /&gt;
rect 478 217 526 265 [[Ледяная стрела (умение амазонки, Diablo II)]]&lt;br /&gt;
rect 478 353 526 401 [[Замораживающая стрела (Diablo II)]]&lt;br /&gt;
rect 547 13 595 61 [[Магическая стрела (Diablo II)]]&lt;br /&gt;
rect 547 81 595 130 [[Залп (Diablo II)]]&lt;br /&gt;
rect 547 217 595 265 [[Самонаводящаяся стрела (Diablo II)]]&lt;br /&gt;
rect 547 285 595 333 [[Обстрел (Diablo II)]]&lt;br /&gt;
rect 616 13 664 61 [[Огненная стрела (умение амазонки, Diablo II)]]&lt;br /&gt;
rect 616 149 664 197 [[Взрывная стрела (Diablo II)]]&lt;br /&gt;
rect 616 285 664 333 [[Обжигающая стрела (Diablo II)]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Экипировка ==&lt;br /&gt;
&lt;br /&gt;
=== Комплекты ===&lt;br /&gt;
&lt;br /&gt;
== Интересные факты ==&lt;br /&gt;
* Амазонку в англоязычной версии озвучила [[Джессика Штраус]].&lt;br /&gt;
&lt;br /&gt;
== Медиа ==&lt;br /&gt;
=== Скриншоты ===&lt;br /&gt;
&lt;br /&gt;
=== Иллюстрации ===&lt;br /&gt;
&amp;lt;gallery heights=&amp;quot;200px&amp;quot;&amp;gt;&lt;br /&gt;
Файл:Diablo-2-Amazon-artwork-01.jpg|&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Иллюстрация амазонки ([[Kris Renkewitz]])|alt=Амазонка в Diablo 2&amp;lt;/div&amp;gt;&lt;br /&gt;
Файл:Diablo-2-Amazon-artwork-02.jpg|&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Иллюстрация амазонки|alt=Амазонка в Diablo 2&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{примечания}}&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://classic.battle.net/diablo2exp/classes/amazon.shtml Страница амазонки на официальном сайте игры]&lt;br /&gt;
&lt;br /&gt;
{{Классы (Diablo II)}}&lt;br /&gt;
[[Категория:Классы (Diablo II)]]&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12319</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12319"/>
				<updated>2021-06-08T23:11:25Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		//importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
		mw.loader.load( '/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12318</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12318"/>
				<updated>2021-06-08T23:10:39Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Код MediaWiki:Common.js безусловно загружается всем пользователям на всех страницах. Во избежание&lt;br /&gt;
 * отправки лишних запросов по возможности не используйте здесь mw.loader.using с модулями, которые&lt;br /&gt;
 * не загружаются по умолчанию (см.&lt;br /&gt;
 * [[Обсуждение MediaWiki:Common.js#Список модулей, загружаемых по умолчанию]]). В таком случае&lt;br /&gt;
 * лучше создать скрытый гаджет, загружаемый по умолчанию, и добавить ему нужные модули в качестве&lt;br /&gt;
 * зависимостей.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Локальная функция загрузки скриптов с поддержкой указания проекта&lt;br /&gt;
 */&lt;br /&gt;
var importScript_ = importScript;&lt;br /&gt;
importScript = function ( page, proj ) {&lt;br /&gt;
	if ( !proj ) {&lt;br /&gt;
		importScript_( page );&lt;br /&gt;
	} else {&lt;br /&gt;
		if ( proj.indexOf( '.' ) === -1 ) {&lt;br /&gt;
			proj += '.wikipedia.org';&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) +&lt;br /&gt;
				'&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Настройка обработки «е» и «ё» при сортировке в таблицах&lt;br /&gt;
 */&lt;br /&gt;
mw.config.set( 'tableSorterCollation', { 'Ё': 'Е', 'ё': 'е' } );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот&lt;br /&gt;
 * список не стоит. При необходимости добавить много сообщений во много языков можно использовать&lt;br /&gt;
 * механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы&lt;br /&gt;
 * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.&lt;br /&gt;
 */&lt;br /&gt;
var expandCaption, collapseCaption, zeroSectionTip;&lt;br /&gt;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {&lt;br /&gt;
	expandCaption = 'show';&lt;br /&gt;
	collapseCaption = 'hide';&lt;br /&gt;
	zeroSectionTip = 'Edit lead section';&lt;br /&gt;
} else {&lt;br /&gt;
	expandCaption = 'показать';&lt;br /&gt;
	collapseCaption = 'скрыть';&lt;br /&gt;
	zeroSectionTip = 'Править преамбулу';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * [[ВП:Сворачиваемые блоки]]&lt;br /&gt;
 */&lt;br /&gt;
// Число раскрытых по умолчанию навигационных (и не только) шаблонов, если им задан параметр&lt;br /&gt;
// autocollapse. Участники могут переопределять это значение в личных JS.&lt;br /&gt;
var NavigationBarShowDefault;&lt;br /&gt;
if ( typeof NavigationBarShowDefault === 'undefined' ) {&lt;br /&gt;
	NavigationBarShowDefault = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// table.collapsible&lt;br /&gt;
// collapsibleTablesItrIdx - временное решние, чтобы не дублировались id,&lt;br /&gt;
// если во время срабатывания хука 'wikipage.content' добавляются новые сворачиваемые блоки&lt;br /&gt;
var collapsibleTablesItrIdx = 0;&lt;br /&gt;
	&lt;br /&gt;
function collapsibleTables( $content ) {&lt;br /&gt;
	var $btn,&lt;br /&gt;
		$a,&lt;br /&gt;
		tblIdx = collapsibleTablesItrIdx,&lt;br /&gt;
		navboxCount = 0,&lt;br /&gt;
		notNavboxCount = 0,&lt;br /&gt;
		colTables = [],&lt;br /&gt;
		$Tables = $content.find( 'table' );&lt;br /&gt;
&lt;br /&gt;
	$Tables.each( function ( i, table ) {&lt;br /&gt;
		if ( $( table ).hasClass( 'collapsible' ) ) {&lt;br /&gt;
			var $table = $( this ),&lt;br /&gt;
				$row = $table.find( 'tr' ).first(),&lt;br /&gt;
				$cell = $row.find( 'th' ).first();&lt;br /&gt;
			if ( !$cell.length ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			$table.attr( 'id', 'collapsibleTable' + tblIdx );&lt;br /&gt;
			$btn = $( '&amp;lt;span&amp;gt;' ).addClass( 'collapseButton' );&lt;br /&gt;
			$a = $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
				.attr( 'id', 'collapseButton' + tblIdx )&lt;br /&gt;
				.attr( 'href', 'javascript:collapseTable(' + tblIdx + ');' )&lt;br /&gt;
				// Изменяем цвет ссылки, только если цвет текста в навбоксе нестандартный&lt;br /&gt;
				.css( 'color', $cell.css( 'color' ) === $( '.mw-body' ).css( 'color' ) ? 'auto' :&lt;br /&gt;
					$cell.css( 'color' ) )&lt;br /&gt;
				.text( collapseCaption );&lt;br /&gt;
			$btn&lt;br /&gt;
				.append( '[' )&lt;br /&gt;
				.append( $a )&lt;br /&gt;
				.append( ']' );&lt;br /&gt;
			if ( $cell.contents().length ) {&lt;br /&gt;
				$btn.insertBefore( $cell.contents().first() );&lt;br /&gt;
			} else {&lt;br /&gt;
				$btn.appendTo( $cell );&lt;br /&gt;
			}&lt;br /&gt;
			// hasClass( 'navbox' ) — временное решение для навшаблонов, ещё не переведённых&lt;br /&gt;
			// на {{Навигационная таблица}} (также ниже)&lt;br /&gt;
			if ( $table.hasClass( 'navbox-inner' ) || $table.hasClass( 'navbox' ) ) {&lt;br /&gt;
				navboxCount++;&lt;br /&gt;
			} else {&lt;br /&gt;
				notNavboxCount++;&lt;br /&gt;
			}&lt;br /&gt;
			colTables[tblIdx++] = $table;&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
	for ( var i = collapsibleTablesItrIdx; i &amp;lt; tblIdx; i++ ) {&lt;br /&gt;
		if ( colTables[i].hasClass( 'collapsed' ) ||&lt;br /&gt;
			( colTables[i].hasClass( 'autocollapse' ) &amp;amp;&amp;amp;&lt;br /&gt;
				( ( ( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &amp;amp;&amp;amp;&lt;br /&gt;
						navboxCount &amp;gt; NavigationBarShowDefault ) ||&lt;br /&gt;
					( !( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &amp;amp;&amp;amp;&lt;br /&gt;
						notNavboxCount &amp;gt; NavigationBarShowDefault ) ) ) )&lt;br /&gt;
		{&lt;br /&gt;
			collapseTable( i );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	collapsibleTablesItrIdx = tblIdx;&lt;br /&gt;
	// Нужно переписать код на &amp;quot;mw-collapsible&amp;quot;, и заменить использование хука на &amp;quot;wikipage.collapsibleContent&amp;quot;&lt;br /&gt;
	mw.hook( 'common.collapsibleContent' ).fire( colTables );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( collapsibleTables );&lt;br /&gt;
&lt;br /&gt;
function collapseTable( idx ) {&lt;br /&gt;
	var $table = $( '#collapsibleTable' + idx ),&lt;br /&gt;
		$rows = $table.children().children( 'tr' ),&lt;br /&gt;
		$btn = $( '#collapseButton' + idx );&lt;br /&gt;
	if ( !$table.length || !$rows.length || !$btn.length ) {&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var isExpanded = ( $btn.text() === collapseCaption ),&lt;br /&gt;
		cssDisplay = isExpanded ? 'none' : $rows.first().css( 'display' );&lt;br /&gt;
&lt;br /&gt;
	$btn.text( isExpanded ? expandCaption : collapseCaption );&lt;br /&gt;
	$rows.slice( 1 ).each( function () {&lt;br /&gt;
		$( this ).css( 'display', cssDisplay );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// div.NavFrame&lt;br /&gt;
var navFrameExpandCaption = '[' + expandCaption + ']',&lt;br /&gt;
	navFrameCollapseCaption = '[' + collapseCaption + ']';&lt;br /&gt;
&lt;br /&gt;
// Изолируем код из глобальной области видимости&lt;br /&gt;
( function () {&lt;br /&gt;
	function collapsibleDivs( $content ) {&lt;br /&gt;
		var navFrameIndex = 0,&lt;br /&gt;
			navFrames = [],&lt;br /&gt;
			i;&lt;br /&gt;
&lt;br /&gt;
		$content.find( 'div' ).each( function () {&lt;br /&gt;
			var $div = $( this );&lt;br /&gt;
			if ( $div.hasClass( 'NavFrame' ) ) {&lt;br /&gt;
				var $btn = $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
					.addClass( 'NavToggle' )&lt;br /&gt;
					.attr( 'href', 'javascript:' )&lt;br /&gt;
					.text( navFrameCollapseCaption )&lt;br /&gt;
					.click( navToggleClickHandler );&lt;br /&gt;
				$div.children( '.NavHead' ).append( $btn );&lt;br /&gt;
				navFrames[ navFrameIndex++ ] = $div;&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		for ( i = 0; i &amp;lt; navFrameIndex; i++ ) {&lt;br /&gt;
			if ( navFrames[ i ].hasClass( 'collapsed' ) ||&lt;br /&gt;
				( navFrameIndex &amp;gt; NavigationBarShowDefault &amp;amp;&amp;amp;&lt;br /&gt;
					!navFrames[ i ].hasClass( 'expanded' )&lt;br /&gt;
				)&lt;br /&gt;
			) {&lt;br /&gt;
				toggleDiv( navFrames[ i ] );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( collapsibleDivs );&lt;br /&gt;
&lt;br /&gt;
	function navToggleClickHandler() {&lt;br /&gt;
		var $btn = $( this );&lt;br /&gt;
		toggleDiv( $btn.closest( '.NavFrame' ), $btn );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function toggleDiv( $div, $btn ) {&lt;br /&gt;
		$btn = $btn || $div.find( '.NavToggle' ).first();&lt;br /&gt;
		if ( !$div.length || !$btn.length ) return false;&lt;br /&gt;
		var isExpanded = ( $btn.text() === navFrameCollapseCaption );&lt;br /&gt;
		$btn.text( isExpanded ? navFrameExpandCaption : navFrameCollapseCaption );&lt;br /&gt;
		$div.children( '.NavContent, .NavPic' ).each( function () {&lt;br /&gt;
			$( this ).css( 'display', isExpanded ? 'none' : 'block' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Загрузка скриптов через систему подгаджетов&lt;br /&gt;
	 */&lt;br /&gt;
	var namespaceNumber = mw.config.get( 'wgNamespaceNumber' );&lt;br /&gt;
&lt;br /&gt;
	// Скрипты для служебных страниц&lt;br /&gt;
	if ( namespaceNumber === -1 ) {&lt;br /&gt;
		var specialGadgets = [&lt;br /&gt;
			'Abusefilter',&lt;br /&gt;
			'Block',&lt;br /&gt;
			'Log',&lt;br /&gt;
			'Movepage',&lt;br /&gt;
			'Newpages',&lt;br /&gt;
			'Search',&lt;br /&gt;
			'Upload'&lt;br /&gt;
		];&lt;br /&gt;
		var canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' );&lt;br /&gt;
		if ( specialGadgets.indexOf( canonicalSpecialPageName ) &amp;gt; -1 ) {&lt;br /&gt;
			mw.loader.load( 'ext.gadget.common-special-' + canonicalSpecialPageName.toLowerCase() );&lt;br /&gt;
		}&lt;br /&gt;
	} else {&lt;br /&gt;
		// Скрипты для действий&lt;br /&gt;
		var action = mw.config.get( 'wgAction' );&lt;br /&gt;
		var actionGadgets = {&lt;br /&gt;
			'edit': [ 'ext.gadget.common-action-edit', 'ext.gadget.wikificator', 'ext.gadget.summaryButtons' ]&lt;br /&gt;
		};&lt;br /&gt;
		actionGadgets[ 'submit' ] = actionGadgets[ 'edit' ];&lt;br /&gt;
&lt;br /&gt;
		if ( actionGadgets[ action ] ) {&lt;br /&gt;
			mw.loader.load( actionGadgets[ action ] );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Скрипты для пространств&lt;br /&gt;
		var namespaceGadgets = {&lt;br /&gt;
			6: [ 'ext.gadget.common-namespace-file' ]&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		if ( namespaceGadgets[ namespaceNumber ] ) {&lt;br /&gt;
			mw.loader.load( namespaceGadgets[ namespaceNumber ] );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}() );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Старые коды&lt;br /&gt;
 */&lt;br /&gt;
if ( navigator.platform.indexOf( 'Win' ) !== -1 ) {&lt;br /&gt;
	mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
		mw.util.addCSS( '.IPA, .Unicode { font-family: &amp;quot;Arial Unicode MS&amp;quot;, &amp;quot;Lucida Sans Unicode&amp;quot;; }' );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Дополнительный функционал для заглавной страницы&lt;br /&gt;
 */&lt;br /&gt;
if ( mw.config.get( 'wgIsMainPage' ) &amp;amp;&amp;amp; mw.config.get( 'wgAction' ) === 'view' ) {&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			var el = mw.util.addPortletLink(&lt;br /&gt;
				'p-lang',&lt;br /&gt;
				mw.config.get( 'wgArticlePath' ).replace( /\$1/, 'Википедия:Список_Википедий' ),&lt;br /&gt;
				'Полный список',&lt;br /&gt;
				'interwiki-completelist'&lt;br /&gt;
			);&lt;br /&gt;
			if ( el ) {&lt;br /&gt;
				el.style.fontWeight = 'bold';&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			$( '#p-wikibase-otherprojects li.wb-otherproject-link a' ).each( function () {&lt;br /&gt;
				var $link = $( this ),&lt;br /&gt;
					url = $link.attr( 'href' ).replace( '/Main_Page', mw.util.wikiUrlencode( '/Заглавная_страница' ) );&lt;br /&gt;
				if ( $link.parent().hasClass( 'wb-otherproject-mediawiki' ) ) {&lt;br /&gt;
					url = $link.attr( 'href' ) + '/ru';&lt;br /&gt;
				}&lt;br /&gt;
				$link.attr( 'href', url );&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
	&lt;br /&gt;
	// Закрываем меню при клике за его пределами&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
		var $items =  $( '.main-footer-menuToggle' ),&lt;br /&gt;
			$target;&lt;br /&gt;
			&lt;br /&gt;
		document.body.addEventListener( 'click', function ( event ) {&lt;br /&gt;
		    $target = $( event.target ).parents( '.main-footer-menuToggle' )[0];&lt;br /&gt;
		    $items.each( function () {&lt;br /&gt;
		        if( this !== $target &amp;amp;&amp;amp; !$( this ).hasClass( 'mw-collapsible-toggle-collapsed' ) ) {&lt;br /&gt;
		            $( this ).click();&lt;br /&gt;
		        }&lt;br /&gt;
		    } );&lt;br /&gt;
		}, true );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.executeJS' ).each( function () {&lt;br /&gt;
		var names = $( this ).data( 'scriptnames' );&lt;br /&gt;
		if (names) {&lt;br /&gt;
			names.split( ' ' ).forEach( function ( name ) {&lt;br /&gt;
				name = name.replace( /[^\w_-]/g, '' );&lt;br /&gt;
				if ( name ) {&lt;br /&gt;
					importScript( 'MediaWiki:Script/' + name + '.js' );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом&lt;br /&gt;
	 * purgelink и именем страницы в атрибуте data-pagename, например как в шаблоне {{очистить кэш}})&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.purgelink a' ).click( function ( e ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );&lt;br /&gt;
			new mw.Api().post( {&lt;br /&gt;
				action: 'purge',&lt;br /&gt;
				titles: pageName&lt;br /&gt;
			} ).then( function () {&lt;br /&gt;
				var url = mw.util.getUrl( pageName );&lt;br /&gt;
				if ( e.ctrlKey ) {&lt;br /&gt;
					if ( !window.open( url ) ) {&lt;br /&gt;
						location.assign( url );&lt;br /&gt;
					}&lt;br /&gt;
				} else {&lt;br /&gt;
					location.assign( url );&lt;br /&gt;
				}&lt;br /&gt;
			}, function () {&lt;br /&gt;
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );&lt;br /&gt;
			} );&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
// По какой-то причине фикс для FlaggedRevs работает только при использовании then(), но не done().&lt;br /&gt;
mw.loader.using( 'ext.visualEditor.desktopArticleTarget.init' ).then( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Исправление поведения FlaggedRevs в сочетании с визуальным редактором, чтобы&lt;br /&gt;
	 * в стабилизированных статьях на правку в визреде открывалась последняя версия, что&lt;br /&gt;
	 * соответствует поведению обычного редактора. См. [[phab:T165283]],&lt;br /&gt;
	 * [[Википедия:Форум/Архив/Общий/2017/12#Серьёзная проблема с анонимными правками в стабилизированных статьях]].&lt;br /&gt;
	 */&lt;br /&gt;
	runAsEarlyAsPossible( function () {&lt;br /&gt;
		function fixEditLinksForStableRevs( removeClickHandlers ) {&lt;br /&gt;
			if ( $( '#ca-view.selected' ).length ) {&lt;br /&gt;
				// При выходе из визреда (сохранении или переключении) ссылки работают правильно&lt;br /&gt;
				// и убирать обработчики событий нет нужды — только исправить URL’ы на случай&lt;br /&gt;
				// открытия правки в новой вкладке.&lt;br /&gt;
				if ( removeClickHandlers ) {&lt;br /&gt;
					$( '#ca-ve-edit, .mw-editsection-visualeditor' ).off( 'click' );&lt;br /&gt;
				}&lt;br /&gt;
				$( '#ca-ve-edit a, .mw-editsection-visualeditor' ).each( function () {&lt;br /&gt;
					var href = $( this ).attr( 'href' );&lt;br /&gt;
					if ( !/[?&amp;amp;]stable=0/.test( href ) ) {&lt;br /&gt;
						$( this ).attr( 'href',&lt;br /&gt;
							href&lt;br /&gt;
								.replace( /&amp;amp;veaction=edit/, '&amp;amp;stable=0&amp;amp;veaction=edit' )&lt;br /&gt;
								.replace( /&amp;amp;oldid=\d+/,  '' )&lt;br /&gt;
						);&lt;br /&gt;
					}&lt;br /&gt;
				} );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Не включаем сюда проверку на наличие #ca-view.selected, чтобы не вычёркивать случай,&lt;br /&gt;
		// когда визред открыт без Ajax и по выходу из него нужно заменить URL’ы в ссылках.&lt;br /&gt;
		if ( $( '#ca-current' ).length &amp;amp;&amp;amp; !/[?&amp;amp;](oldid|diff)=\d+/.test( location.search ) ) {&lt;br /&gt;
			fixEditLinksForStableRevs( true );&lt;br /&gt;
		&lt;br /&gt;
			mw.hook( 've.deactivationComplete' ).add( function () {&lt;br /&gt;
				fixEditLinksForStableRevs( false );&lt;br /&gt;
			} );&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * Поддержка Викификатора в новом режиме вики-текста aka 2017 wikitext editor&lt;br /&gt;
	 */&lt;br /&gt;
	mw.libs.ve.addPlugin( function () {&lt;br /&gt;
		return mw.loader.using( 'ext.gadget.wikificator' );&lt;br /&gt;
	} );&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * {{TOC hidden}}&lt;br /&gt;
 */&lt;br /&gt;
function TOChidden() {&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc &amp;gt; #toctogglecheckbox' ).prop('checked', true );&lt;br /&gt;
	$( '.tochidden-wrapper' ).attr( &amp;quot;class&amp;quot;, &amp;quot;toc-wrapper&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ] ).done( function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться не более одного раза на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки.&lt;br /&gt;
	 * Короткие (до 15 ссылок, если общее число символов не менее 3000) списки примечаний обтекаются&lt;br /&gt;
	 * только справа.&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.reflist.columns' ).each( function () {&lt;br /&gt;
		var clear = 'both',&lt;br /&gt;
			$refs = $( this ).find( 'ol.references &amp;gt; li' );&lt;br /&gt;
		if ( $refs.length &amp;lt;= 10 ) return;&lt;br /&gt;
		if ( $refs.length &amp;lt;= 15 &amp;amp;&amp;amp; $refs.text().length &amp;lt; 3000 ) {&lt;br /&gt;
			clear = 'left';&lt;br /&gt;
		}&lt;br /&gt;
		$( this )&lt;br /&gt;
			.prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.addBack()&lt;br /&gt;
			.first()&lt;br /&gt;
			.prev()&lt;br /&gt;
			.css( 'clear', clear );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		//importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
		mw.loader.load( '/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * imgToggle&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент div.img_toggle&lt;br /&gt;
	if ( $( 'div.img_toggle' ).length ) {&lt;br /&gt;
		mw.loader.load( 'ext.gadget.imgToggle' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Авторазбиение списков на колонки. Будет работать только для однострочных списков. 35em&lt;br /&gt;
	 * (из Mediawiki:Common.css) является предварительным числом, а фактическое будет посчитано исходя&lt;br /&gt;
	 * из ширины элементов. Должно использоваться только для UL внутри DIV. Пример использования —&lt;br /&gt;
	 * шаблон {{Wikidata/SisterCities}}.&lt;br /&gt;
	 */&lt;br /&gt;
	$(&amp;quot;div.autocolumns&amp;quot;).each(function(d, div) {&lt;br /&gt;
		var parentWidth = $(div).parent()[0].offsetWidth;&lt;br /&gt;
		if (!parentWidth) return;&lt;br /&gt;
&lt;br /&gt;
		var maxWidth = 0;&lt;br /&gt;
		var elements = 0;&lt;br /&gt;
		$(div).find(&amp;quot;ul&amp;gt;li&amp;quot;).each(function(l, li) {&lt;br /&gt;
			elements++;&lt;br /&gt;
			var jLi = $(li);&lt;br /&gt;
			if (jLi.children().length != jLi.contents().length)&lt;br /&gt;
				jLi.wrapInner(document.createElement(&amp;quot;span&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
			var liWidth = 0;&lt;br /&gt;
			jLi.children().each(function(c, child) {&lt;br /&gt;
				liWidth += child.offsetWidth;&lt;br /&gt;
			});&lt;br /&gt;
			if (liWidth &amp;gt; maxWidth)&lt;br /&gt;
				maxWidth = liWidth;&lt;br /&gt;
		});&lt;br /&gt;
		if ( maxWidth === 0 ) return;&lt;br /&gt;
		// UL/LI bullet width + padding&lt;br /&gt;
		maxWidth += 22.5 * 2;&lt;br /&gt;
&lt;br /&gt;
		var maxColumns = &amp;quot;&amp;quot; + Math.ceil( elements / 5 );&lt;br /&gt;
		$(div).css({&amp;quot;-moz-columns&amp;quot;: maxWidth + &amp;quot;px &amp;quot; + maxColumns, &amp;quot;columns&amp;quot; : maxWidth + &amp;quot;px &amp;quot; + maxColumns});&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
// A high frequency of errors come from old scripts referencing addPortletLink.&lt;br /&gt;
// Can be removed when https://global-search.toolforge.org/?q=%5B%5E%5C.%5DaddPortletLink%5C%28&amp;amp;regex=1&amp;amp;namespaces=&amp;amp;title=.*%5C.js has no nl.wikipedia results.&lt;br /&gt;
window.addPortletLink = function () {&lt;br /&gt;
	// @todo: Please Translate&lt;br /&gt;
	mw.notify('One of your user scripts is broken. Please inspect your error console and remove.');&lt;br /&gt;
	mw.log.warn('addPortletLink is deprecated. Please use mw.util.addPortletLink')&lt;br /&gt;
};&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B0_(Diablo_II)&amp;diff=12317</id>
		<title>Амазонка (Diablo II)</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B0_(Diablo_II)&amp;diff=12317"/>
				<updated>2021-06-08T23:08:00Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
{{Класс (Diablo II)&lt;br /&gt;
| название       = Амазонка&lt;br /&gt;
| иллюстрация    = Diablo-2-Amazon-01.gif&lt;br /&gt;
| экипировка     = Луки амазонок, копья амазонок, дротики амазонок&lt;br /&gt;
| стихии         = Физический урон, молния, яд, холод, огонь, магический урон&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Амазонка''' {{en|Amazon}} — один из [[Классы (Diablo II)|классов]] персонажей в [[Diablo II]].&lt;br /&gt;
&lt;br /&gt;
Аскари, известные также как амазонки, родом с островов Сковос, группы покрытых непроходимыми джунглями островов на Двух морях. Представители этого матриархального племени — могучие воительницы, которые путешествуют по миру, занимаясь наемным трудом и искореняя силы зла.&lt;br /&gt;
&lt;br /&gt;
Наносите врагам колющие удары копьями и дротиками. Поражайте демонов шквалом стрел, орудуя луком не хуже сестер-разбойниц Незримого Ока. Избегайте смертоносных ударов, полагаясь на свою нечеловеческую ловкость. Амазонка всю жизнь готовилась к жестокой кузне войны и виртуозно владеет искусством боя.&lt;br /&gt;
&lt;br /&gt;
This powerful woman warrior belongs to nomadic bands who roam the plains near the South Sea. The wandering of these groups often brings them into conflict with other peoples, so the Amazon is accustomed to fighting to defend her own. This lifestyle has made her fiercely independent and able to weather severe hardship and travel. While her skill with the bow rivals that of the Rogues, the Amazon is also adept in the use of spears and other throwing weapons, as well as in hand to hand combat. The Amazon is much sought after as a mercenary, in which type of service she will be loyal as long as her own ends are also served.&lt;br /&gt;
&lt;br /&gt;
== История ==&lt;br /&gt;
&lt;br /&gt;
The Amazons are women warriors who hail from a group of islands in the Twin Seas, near the border of the Great Ocean. Only the permanently snow-covered peak of Mount Karcheus breaks the expanses of lush forests on the islands.&lt;br /&gt;
&lt;br /&gt;
The Amazon people are a relatively isolated culture. Adapting over the centuries to their tropical milieu, they have built magnificent cities in the forest canopy. These cities are an architectural phenomenon and a source of great pride to the Amazon people. They do not follow the teachings of the Zakarum, but instead practice a polytheistic religion that adheres to the strict principles of Order. Their oracles long ago predicted the Dark Exile, and they have been preparing to combat it ever since. Amazons regard the destruction of the Three Prime Evils as their destiny, ushering in a new era when mortal men and women can at long last take their rightful place in the universe, no longer merely playthings for the beings of the Outer Realms.&lt;br /&gt;
&lt;br /&gt;
The Amazons are a seafaring people, one of the first to have made trade contact with both the Kingdoms of the West and with Kejhistan in the East. Their prominence in the world's trade establishment has afforded their warriors the reputation they currently enjoy as cunning strategists and skilled combatants. They are much sought after as mercenaries, being both expert soldiers as well as extremely loyal - as long as the assignment does not conflict with their strict sense of ethics.&lt;br /&gt;
&lt;br /&gt;
Their pantheon of gods consists of a well-defined hierarchy, each member upholding some segment of the balance of Order. It is this strong sense of order that drives the Amazon people to achieve greatness in even the smallest of their endeavors. Their prime deity is Athulua who, with her consort, Kethryes, rules over the seasons and the weather. Under these Goddesses are a wide assortment of lesser deities, each responsible for his or her own sphere of influence among the Amazon people's daily life. The Amazons believe this pantheon is the remnant of the original inhabitants that settled the islands centuries ago. According to ancient records, they share the same names as these gods, although aspects of their personalities seem to have evolved over the centuries.&lt;br /&gt;
&lt;br /&gt;
In the Amazon culture, only the women serve as warriors, their intrinsic superior dexterity and lithe body structures are better suited to combat in the dense rainforest environs of the islands. Their society is far from stratified, however, as men are responsible for any number of positions in the community, government, and clergy, as well as merchant and agricultural occupations.&lt;br /&gt;
&lt;br /&gt;
Traits and Abilities:&lt;br /&gt;
&lt;br /&gt;
While more than competent in hand-to-hand combat, training in the jungles of her native islands has shaped the Amazon's skill with the bow and missile weapons into one of unparalleled excellence. With the bow, her only rivals are the Sisters of the Sightless Eye. But, unlike her sisters in arms, the Amazon is also highly adept in the use of spears and other thrown weapons. The powers they possess are a combination of Prime magic, Holy magic and ingenious weapon construction.&lt;br /&gt;
&lt;br /&gt;
== Умения ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto; border: none;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Дротики и копья&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Пассивные и магические навыки&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Луки и арбалеты&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center; background: #0f0000&amp;quot;| &lt;br /&gt;
&amp;lt;div class=&amp;quot;imageMapHighlighter&amp;quot; data-list_classes=&amp;quot;&amp;quot; data-area_mark=&amp;quot;{}&amp;quot; data-area_mark_file=&amp;quot;&amp;quot;&amp;gt;&amp;lt;imagemap&amp;gt;&lt;br /&gt;
Файл:D2-SkillTree-Amazon.png&lt;br /&gt;
rect 16 13 64 61 [[Выпад (Diablo II)]]&lt;br /&gt;
rect 16 149 64 197 [[Прокалывание (Diablo II)]]&lt;br /&gt;
rect 16 285 64 333 [[Лучшая защита (Diablo II)]]&lt;br /&gt;
rect 85 81 133 130 [[Мощный удар (Diablo II)]]&lt;br /&gt;
rect 85 217 133 265 [[Заряженный удар (Diablo II)]]&lt;br /&gt;
rect 85 353 133 401 [[Удар молнии (Diablo II)]]&lt;br /&gt;
rect 154 81 202 130 [[Отравленный дротик (Diablo II)]]&lt;br /&gt;
rect 154 149 202 197 [[Разряд молнии (Diablo II)]]&lt;br /&gt;
rect 154 217 202 265 [[Чумной дротик (Diablo II)]]&lt;br /&gt;
rect 154 353 202 401 [[Неистовство молний (Diablo II)]]&lt;br /&gt;
&lt;br /&gt;
rect 247 13 295 61 [[Внутреннее зрение (Diablo II)]]&lt;br /&gt;
rect 247 149 295 197 [[Замедление снарядов (Diablo II)]]&lt;br /&gt;
rect 247 285 295 333 [[Двойник (Diablo II)]]&lt;br /&gt;
rect 247 353 295 401 [[Валькирия (Diablo II)]]&lt;br /&gt;
rect 316 81 364 130 [[Уклонение (Diablo II)]]&lt;br /&gt;
rect 316 149 364 197 [[Ускользание (Diablo II)]]&lt;br /&gt;
rect 316 285 364 333 [[Избежание (Diablo II)]]&lt;br /&gt;
rect 385 13 433 61 [[Критический удар (Diablo II)]]&lt;br /&gt;
rect 385 217 433 265 [[Пронзание (Diablo II)]]&lt;br /&gt;
rect 385 353 433 401 [[Пробивание (Diablo II)]]&lt;br /&gt;
&lt;br /&gt;
rect 478 81 526 130 [[Морозная стрела (Diablo II)]]&lt;br /&gt;
rect 478 217 526 265 [[Ледяная стрела (умение амазонки, Diablo II)]]&lt;br /&gt;
rect 478 353 526 401 [[Замораживающая стрела (Diablo II)]]&lt;br /&gt;
rect 547 13 595 61 [[Магическая стрела (Diablo II)]]&lt;br /&gt;
rect 547 81 595 130 [[Залп (Diablo II)]]&lt;br /&gt;
rect 547 217 595 265 [[Самонаводящаяся стрела (Diablo II)]]&lt;br /&gt;
rect 547 285 595 333 [[Обстрел (Diablo II)]]&lt;br /&gt;
rect 616 13 664 61 [[Огненная стрела (умение амазонки, Diablo II)]]&lt;br /&gt;
rect 616 149 664 197 [[Взрывная стрела (Diablo II)]]&lt;br /&gt;
rect 616 285 664 333 [[Обжигающая стрела (Diablo II)]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Экипировка ==&lt;br /&gt;
&lt;br /&gt;
=== Комплекты ===&lt;br /&gt;
&lt;br /&gt;
== Интересные факты ==&lt;br /&gt;
* Амазонку в англоязычной версии озвучила [[Джессика Штраус]].&lt;br /&gt;
&lt;br /&gt;
== Медиа ==&lt;br /&gt;
=== Скриншоты ===&lt;br /&gt;
&lt;br /&gt;
=== Иллюстрации ===&lt;br /&gt;
&amp;lt;gallery heights=&amp;quot;200px&amp;quot;&amp;gt;&lt;br /&gt;
Файл:Diablo-2-Amazon-artwork-01.jpg|&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Иллюстрация амазонки ([[Kris Renkewitz]])|alt=Амазонка в Diablo 2&amp;lt;/div&amp;gt;&lt;br /&gt;
Файл:Diablo-2-Amazon-artwork-02.jpg|&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Иллюстрация амазонки|alt=Амазонка в Diablo 2&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{примечания}}&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://classic.battle.net/diablo2exp/classes/amazon.shtml Страница амазонки на официальном сайте игры]&lt;br /&gt;
&lt;br /&gt;
{{Классы (Diablo II)}}&lt;br /&gt;
[[Категория:Классы (Diablo II)]]&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12316</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12316"/>
				<updated>2021-06-08T23:04:43Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Код MediaWiki:Common.js безусловно загружается всем пользователям на всех страницах. Во избежание&lt;br /&gt;
 * отправки лишних запросов по возможности не используйте здесь mw.loader.using с модулями, которые&lt;br /&gt;
 * не загружаются по умолчанию (см.&lt;br /&gt;
 * [[Обсуждение MediaWiki:Common.js#Список модулей, загружаемых по умолчанию]]). В таком случае&lt;br /&gt;
 * лучше создать скрытый гаджет, загружаемый по умолчанию, и добавить ему нужные модули в качестве&lt;br /&gt;
 * зависимостей.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Локальная функция загрузки скриптов с поддержкой указания проекта&lt;br /&gt;
 */&lt;br /&gt;
var importScript_ = importScript;&lt;br /&gt;
importScript = function ( page, proj ) {&lt;br /&gt;
	if ( !proj ) {&lt;br /&gt;
		importScript_( page );&lt;br /&gt;
	} else {&lt;br /&gt;
		if ( proj.indexOf( '.' ) === -1 ) {&lt;br /&gt;
			proj += '.wikipedia.org';&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) +&lt;br /&gt;
				'&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Настройка обработки «е» и «ё» при сортировке в таблицах&lt;br /&gt;
 */&lt;br /&gt;
mw.config.set( 'tableSorterCollation', { 'Ё': 'Е', 'ё': 'е' } );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот&lt;br /&gt;
 * список не стоит. При необходимости добавить много сообщений во много языков можно использовать&lt;br /&gt;
 * механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы&lt;br /&gt;
 * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.&lt;br /&gt;
 */&lt;br /&gt;
var expandCaption, collapseCaption, zeroSectionTip;&lt;br /&gt;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {&lt;br /&gt;
	expandCaption = 'show';&lt;br /&gt;
	collapseCaption = 'hide';&lt;br /&gt;
	zeroSectionTip = 'Edit lead section';&lt;br /&gt;
} else {&lt;br /&gt;
	expandCaption = 'показать';&lt;br /&gt;
	collapseCaption = 'скрыть';&lt;br /&gt;
	zeroSectionTip = 'Править преамбулу';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * [[ВП:Сворачиваемые блоки]]&lt;br /&gt;
 */&lt;br /&gt;
// Число раскрытых по умолчанию навигационных (и не только) шаблонов, если им задан параметр&lt;br /&gt;
// autocollapse. Участники могут переопределять это значение в личных JS.&lt;br /&gt;
var NavigationBarShowDefault;&lt;br /&gt;
if ( typeof NavigationBarShowDefault === 'undefined' ) {&lt;br /&gt;
	NavigationBarShowDefault = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// table.collapsible&lt;br /&gt;
// collapsibleTablesItrIdx - временное решние, чтобы не дублировались id,&lt;br /&gt;
// если во время срабатывания хука 'wikipage.content' добавляются новые сворачиваемые блоки&lt;br /&gt;
var collapsibleTablesItrIdx = 0;&lt;br /&gt;
	&lt;br /&gt;
function collapsibleTables( $content ) {&lt;br /&gt;
	var $btn,&lt;br /&gt;
		$a,&lt;br /&gt;
		tblIdx = collapsibleTablesItrIdx,&lt;br /&gt;
		navboxCount = 0,&lt;br /&gt;
		notNavboxCount = 0,&lt;br /&gt;
		colTables = [],&lt;br /&gt;
		$Tables = $content.find( 'table' );&lt;br /&gt;
&lt;br /&gt;
	$Tables.each( function ( i, table ) {&lt;br /&gt;
		if ( $( table ).hasClass( 'collapsible' ) ) {&lt;br /&gt;
			var $table = $( this ),&lt;br /&gt;
				$row = $table.find( 'tr' ).first(),&lt;br /&gt;
				$cell = $row.find( 'th' ).first();&lt;br /&gt;
			if ( !$cell.length ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			$table.attr( 'id', 'collapsibleTable' + tblIdx );&lt;br /&gt;
			$btn = $( '&amp;lt;span&amp;gt;' ).addClass( 'collapseButton' );&lt;br /&gt;
			$a = $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
				.attr( 'id', 'collapseButton' + tblIdx )&lt;br /&gt;
				.attr( 'href', 'javascript:collapseTable(' + tblIdx + ');' )&lt;br /&gt;
				// Изменяем цвет ссылки, только если цвет текста в навбоксе нестандартный&lt;br /&gt;
				.css( 'color', $cell.css( 'color' ) === $( '.mw-body' ).css( 'color' ) ? 'auto' :&lt;br /&gt;
					$cell.css( 'color' ) )&lt;br /&gt;
				.text( collapseCaption );&lt;br /&gt;
			$btn&lt;br /&gt;
				.append( '[' )&lt;br /&gt;
				.append( $a )&lt;br /&gt;
				.append( ']' );&lt;br /&gt;
			if ( $cell.contents().length ) {&lt;br /&gt;
				$btn.insertBefore( $cell.contents().first() );&lt;br /&gt;
			} else {&lt;br /&gt;
				$btn.appendTo( $cell );&lt;br /&gt;
			}&lt;br /&gt;
			// hasClass( 'navbox' ) — временное решение для навшаблонов, ещё не переведённых&lt;br /&gt;
			// на {{Навигационная таблица}} (также ниже)&lt;br /&gt;
			if ( $table.hasClass( 'navbox-inner' ) || $table.hasClass( 'navbox' ) ) {&lt;br /&gt;
				navboxCount++;&lt;br /&gt;
			} else {&lt;br /&gt;
				notNavboxCount++;&lt;br /&gt;
			}&lt;br /&gt;
			colTables[tblIdx++] = $table;&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
	for ( var i = collapsibleTablesItrIdx; i &amp;lt; tblIdx; i++ ) {&lt;br /&gt;
		if ( colTables[i].hasClass( 'collapsed' ) ||&lt;br /&gt;
			( colTables[i].hasClass( 'autocollapse' ) &amp;amp;&amp;amp;&lt;br /&gt;
				( ( ( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &amp;amp;&amp;amp;&lt;br /&gt;
						navboxCount &amp;gt; NavigationBarShowDefault ) ||&lt;br /&gt;
					( !( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &amp;amp;&amp;amp;&lt;br /&gt;
						notNavboxCount &amp;gt; NavigationBarShowDefault ) ) ) )&lt;br /&gt;
		{&lt;br /&gt;
			collapseTable( i );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	collapsibleTablesItrIdx = tblIdx;&lt;br /&gt;
	// Нужно переписать код на &amp;quot;mw-collapsible&amp;quot;, и заменить использование хука на &amp;quot;wikipage.collapsibleContent&amp;quot;&lt;br /&gt;
	mw.hook( 'common.collapsibleContent' ).fire( colTables );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( collapsibleTables );&lt;br /&gt;
&lt;br /&gt;
function collapseTable( idx ) {&lt;br /&gt;
	var $table = $( '#collapsibleTable' + idx ),&lt;br /&gt;
		$rows = $table.children().children( 'tr' ),&lt;br /&gt;
		$btn = $( '#collapseButton' + idx );&lt;br /&gt;
	if ( !$table.length || !$rows.length || !$btn.length ) {&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var isExpanded = ( $btn.text() === collapseCaption ),&lt;br /&gt;
		cssDisplay = isExpanded ? 'none' : $rows.first().css( 'display' );&lt;br /&gt;
&lt;br /&gt;
	$btn.text( isExpanded ? expandCaption : collapseCaption );&lt;br /&gt;
	$rows.slice( 1 ).each( function () {&lt;br /&gt;
		$( this ).css( 'display', cssDisplay );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// div.NavFrame&lt;br /&gt;
var navFrameExpandCaption = '[' + expandCaption + ']',&lt;br /&gt;
	navFrameCollapseCaption = '[' + collapseCaption + ']';&lt;br /&gt;
&lt;br /&gt;
// Изолируем код из глобальной области видимости&lt;br /&gt;
( function () {&lt;br /&gt;
	function collapsibleDivs( $content ) {&lt;br /&gt;
		var navFrameIndex = 0,&lt;br /&gt;
			navFrames = [],&lt;br /&gt;
			i;&lt;br /&gt;
&lt;br /&gt;
		$content.find( 'div' ).each( function () {&lt;br /&gt;
			var $div = $( this );&lt;br /&gt;
			if ( $div.hasClass( 'NavFrame' ) ) {&lt;br /&gt;
				var $btn = $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
					.addClass( 'NavToggle' )&lt;br /&gt;
					.attr( 'href', 'javascript:' )&lt;br /&gt;
					.text( navFrameCollapseCaption )&lt;br /&gt;
					.click( navToggleClickHandler );&lt;br /&gt;
				$div.children( '.NavHead' ).append( $btn );&lt;br /&gt;
				navFrames[ navFrameIndex++ ] = $div;&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
		for ( i = 0; i &amp;lt; navFrameIndex; i++ ) {&lt;br /&gt;
			if ( navFrames[ i ].hasClass( 'collapsed' ) ||&lt;br /&gt;
				( navFrameIndex &amp;gt; NavigationBarShowDefault &amp;amp;&amp;amp;&lt;br /&gt;
					!navFrames[ i ].hasClass( 'expanded' )&lt;br /&gt;
				)&lt;br /&gt;
			) {&lt;br /&gt;
				toggleDiv( navFrames[ i ] );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( collapsibleDivs );&lt;br /&gt;
&lt;br /&gt;
	function navToggleClickHandler() {&lt;br /&gt;
		var $btn = $( this );&lt;br /&gt;
		toggleDiv( $btn.closest( '.NavFrame' ), $btn );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function toggleDiv( $div, $btn ) {&lt;br /&gt;
		$btn = $btn || $div.find( '.NavToggle' ).first();&lt;br /&gt;
		if ( !$div.length || !$btn.length ) return false;&lt;br /&gt;
		var isExpanded = ( $btn.text() === navFrameCollapseCaption );&lt;br /&gt;
		$btn.text( isExpanded ? navFrameExpandCaption : navFrameCollapseCaption );&lt;br /&gt;
		$div.children( '.NavContent, .NavPic' ).each( function () {&lt;br /&gt;
			$( this ).css( 'display', isExpanded ? 'none' : 'block' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Загрузка скриптов через систему подгаджетов&lt;br /&gt;
	 */&lt;br /&gt;
	var namespaceNumber = mw.config.get( 'wgNamespaceNumber' );&lt;br /&gt;
&lt;br /&gt;
	// Скрипты для служебных страниц&lt;br /&gt;
	if ( namespaceNumber === -1 ) {&lt;br /&gt;
		var specialGadgets = [&lt;br /&gt;
			'Abusefilter',&lt;br /&gt;
			'Block',&lt;br /&gt;
			'Log',&lt;br /&gt;
			'Movepage',&lt;br /&gt;
			'Newpages',&lt;br /&gt;
			'Search',&lt;br /&gt;
			'Upload'&lt;br /&gt;
		];&lt;br /&gt;
		var canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' );&lt;br /&gt;
		if ( specialGadgets.indexOf( canonicalSpecialPageName ) &amp;gt; -1 ) {&lt;br /&gt;
			mw.loader.load( 'ext.gadget.common-special-' + canonicalSpecialPageName.toLowerCase() );&lt;br /&gt;
		}&lt;br /&gt;
	} else {&lt;br /&gt;
		// Скрипты для действий&lt;br /&gt;
		var action = mw.config.get( 'wgAction' );&lt;br /&gt;
		var actionGadgets = {&lt;br /&gt;
			'edit': [ 'ext.gadget.common-action-edit', 'ext.gadget.wikificator', 'ext.gadget.summaryButtons' ]&lt;br /&gt;
		};&lt;br /&gt;
		actionGadgets[ 'submit' ] = actionGadgets[ 'edit' ];&lt;br /&gt;
&lt;br /&gt;
		if ( actionGadgets[ action ] ) {&lt;br /&gt;
			mw.loader.load( actionGadgets[ action ] );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Скрипты для пространств&lt;br /&gt;
		var namespaceGadgets = {&lt;br /&gt;
			6: [ 'ext.gadget.common-namespace-file' ]&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		if ( namespaceGadgets[ namespaceNumber ] ) {&lt;br /&gt;
			mw.loader.load( namespaceGadgets[ namespaceNumber ] );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}() );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Старые коды&lt;br /&gt;
 */&lt;br /&gt;
if ( navigator.platform.indexOf( 'Win' ) !== -1 ) {&lt;br /&gt;
	mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
		mw.util.addCSS( '.IPA, .Unicode { font-family: &amp;quot;Arial Unicode MS&amp;quot;, &amp;quot;Lucida Sans Unicode&amp;quot;; }' );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Дополнительный функционал для заглавной страницы&lt;br /&gt;
 */&lt;br /&gt;
if ( mw.config.get( 'wgIsMainPage' ) &amp;amp;&amp;amp; mw.config.get( 'wgAction' ) === 'view' ) {&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			var el = mw.util.addPortletLink(&lt;br /&gt;
				'p-lang',&lt;br /&gt;
				mw.config.get( 'wgArticlePath' ).replace( /\$1/, 'Википедия:Список_Википедий' ),&lt;br /&gt;
				'Полный список',&lt;br /&gt;
				'interwiki-completelist'&lt;br /&gt;
			);&lt;br /&gt;
			if ( el ) {&lt;br /&gt;
				el.style.fontWeight = 'bold';&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			$( '#p-wikibase-otherprojects li.wb-otherproject-link a' ).each( function () {&lt;br /&gt;
				var $link = $( this ),&lt;br /&gt;
					url = $link.attr( 'href' ).replace( '/Main_Page', mw.util.wikiUrlencode( '/Заглавная_страница' ) );&lt;br /&gt;
				if ( $link.parent().hasClass( 'wb-otherproject-mediawiki' ) ) {&lt;br /&gt;
					url = $link.attr( 'href' ) + '/ru';&lt;br /&gt;
				}&lt;br /&gt;
				$link.attr( 'href', url );&lt;br /&gt;
			} );&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
	&lt;br /&gt;
	// Закрываем меню при клике за его пределами&lt;br /&gt;
	mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
		var $items =  $( '.main-footer-menuToggle' ),&lt;br /&gt;
			$target;&lt;br /&gt;
			&lt;br /&gt;
		document.body.addEventListener( 'click', function ( event ) {&lt;br /&gt;
		    $target = $( event.target ).parents( '.main-footer-menuToggle' )[0];&lt;br /&gt;
		    $items.each( function () {&lt;br /&gt;
		        if( this !== $target &amp;amp;&amp;amp; !$( this ).hasClass( 'mw-collapsible-toggle-collapsed' ) ) {&lt;br /&gt;
		            $( this ).click();&lt;br /&gt;
		        }&lt;br /&gt;
		    } );&lt;br /&gt;
		}, true );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.executeJS' ).each( function () {&lt;br /&gt;
		var names = $( this ).data( 'scriptnames' );&lt;br /&gt;
		if (names) {&lt;br /&gt;
			names.split( ' ' ).forEach( function ( name ) {&lt;br /&gt;
				name = name.replace( /[^\w_-]/g, '' );&lt;br /&gt;
				if ( name ) {&lt;br /&gt;
					importScript( 'MediaWiki:Script/' + name + '.js' );&lt;br /&gt;
				}&lt;br /&gt;
			} );&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом&lt;br /&gt;
	 * purgelink и именем страницы в атрибуте data-pagename, например как в шаблоне {{очистить кэш}})&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.purgelink a' ).click( function ( e ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );&lt;br /&gt;
			new mw.Api().post( {&lt;br /&gt;
				action: 'purge',&lt;br /&gt;
				titles: pageName&lt;br /&gt;
			} ).then( function () {&lt;br /&gt;
				var url = mw.util.getUrl( pageName );&lt;br /&gt;
				if ( e.ctrlKey ) {&lt;br /&gt;
					if ( !window.open( url ) ) {&lt;br /&gt;
						location.assign( url );&lt;br /&gt;
					}&lt;br /&gt;
				} else {&lt;br /&gt;
					location.assign( url );&lt;br /&gt;
				}&lt;br /&gt;
			}, function () {&lt;br /&gt;
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );&lt;br /&gt;
			} );&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
// По какой-то причине фикс для FlaggedRevs работает только при использовании then(), но не done().&lt;br /&gt;
mw.loader.using( 'ext.visualEditor.desktopArticleTarget.init' ).then( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Исправление поведения FlaggedRevs в сочетании с визуальным редактором, чтобы&lt;br /&gt;
	 * в стабилизированных статьях на правку в визреде открывалась последняя версия, что&lt;br /&gt;
	 * соответствует поведению обычного редактора. См. [[phab:T165283]],&lt;br /&gt;
	 * [[Википедия:Форум/Архив/Общий/2017/12#Серьёзная проблема с анонимными правками в стабилизированных статьях]].&lt;br /&gt;
	 */&lt;br /&gt;
	runAsEarlyAsPossible( function () {&lt;br /&gt;
		function fixEditLinksForStableRevs( removeClickHandlers ) {&lt;br /&gt;
			if ( $( '#ca-view.selected' ).length ) {&lt;br /&gt;
				// При выходе из визреда (сохранении или переключении) ссылки работают правильно&lt;br /&gt;
				// и убирать обработчики событий нет нужды — только исправить URL’ы на случай&lt;br /&gt;
				// открытия правки в новой вкладке.&lt;br /&gt;
				if ( removeClickHandlers ) {&lt;br /&gt;
					$( '#ca-ve-edit, .mw-editsection-visualeditor' ).off( 'click' );&lt;br /&gt;
				}&lt;br /&gt;
				$( '#ca-ve-edit a, .mw-editsection-visualeditor' ).each( function () {&lt;br /&gt;
					var href = $( this ).attr( 'href' );&lt;br /&gt;
					if ( !/[?&amp;amp;]stable=0/.test( href ) ) {&lt;br /&gt;
						$( this ).attr( 'href',&lt;br /&gt;
							href&lt;br /&gt;
								.replace( /&amp;amp;veaction=edit/, '&amp;amp;stable=0&amp;amp;veaction=edit' )&lt;br /&gt;
								.replace( /&amp;amp;oldid=\d+/,  '' )&lt;br /&gt;
						);&lt;br /&gt;
					}&lt;br /&gt;
				} );&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Не включаем сюда проверку на наличие #ca-view.selected, чтобы не вычёркивать случай,&lt;br /&gt;
		// когда визред открыт без Ajax и по выходу из него нужно заменить URL’ы в ссылках.&lt;br /&gt;
		if ( $( '#ca-current' ).length &amp;amp;&amp;amp; !/[?&amp;amp;](oldid|diff)=\d+/.test( location.search ) ) {&lt;br /&gt;
			fixEditLinksForStableRevs( true );&lt;br /&gt;
		&lt;br /&gt;
			mw.hook( 've.deactivationComplete' ).add( function () {&lt;br /&gt;
				fixEditLinksForStableRevs( false );&lt;br /&gt;
			} );&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * Поддержка Викификатора в новом режиме вики-текста aka 2017 wikitext editor&lt;br /&gt;
	 */&lt;br /&gt;
	mw.libs.ve.addPlugin( function () {&lt;br /&gt;
		return mw.loader.using( 'ext.gadget.wikificator' );&lt;br /&gt;
	} );&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * {{TOC hidden}}&lt;br /&gt;
 */&lt;br /&gt;
function TOChidden() {&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc &amp;gt; #toctogglecheckbox' ).prop('checked', true );&lt;br /&gt;
	$( '.tochidden-wrapper' ).attr( &amp;quot;class&amp;quot;, &amp;quot;toc-wrapper&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ] ).done( function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться не более одного раза на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки.&lt;br /&gt;
	 * Короткие (до 15 ссылок, если общее число символов не менее 3000) списки примечаний обтекаются&lt;br /&gt;
	 * только справа.&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.reflist.columns' ).each( function () {&lt;br /&gt;
		var clear = 'both',&lt;br /&gt;
			$refs = $( this ).find( 'ol.references &amp;gt; li' );&lt;br /&gt;
		if ( $refs.length &amp;lt;= 10 ) return;&lt;br /&gt;
		if ( $refs.length &amp;lt;= 15 &amp;amp;&amp;amp; $refs.text().length &amp;lt; 3000 ) {&lt;br /&gt;
			clear = 'left';&lt;br /&gt;
		}&lt;br /&gt;
		$( this )&lt;br /&gt;
			.prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.addBack()&lt;br /&gt;
			.first()&lt;br /&gt;
			.prev()&lt;br /&gt;
			.css( 'clear', clear );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * imgToggle&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент div.img_toggle&lt;br /&gt;
	if ( $( 'div.img_toggle' ).length ) {&lt;br /&gt;
		mw.loader.load( 'ext.gadget.imgToggle' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Авторазбиение списков на колонки. Будет работать только для однострочных списков. 35em&lt;br /&gt;
	 * (из Mediawiki:Common.css) является предварительным числом, а фактическое будет посчитано исходя&lt;br /&gt;
	 * из ширины элементов. Должно использоваться только для UL внутри DIV. Пример использования —&lt;br /&gt;
	 * шаблон {{Wikidata/SisterCities}}.&lt;br /&gt;
	 */&lt;br /&gt;
	$(&amp;quot;div.autocolumns&amp;quot;).each(function(d, div) {&lt;br /&gt;
		var parentWidth = $(div).parent()[0].offsetWidth;&lt;br /&gt;
		if (!parentWidth) return;&lt;br /&gt;
&lt;br /&gt;
		var maxWidth = 0;&lt;br /&gt;
		var elements = 0;&lt;br /&gt;
		$(div).find(&amp;quot;ul&amp;gt;li&amp;quot;).each(function(l, li) {&lt;br /&gt;
			elements++;&lt;br /&gt;
			var jLi = $(li);&lt;br /&gt;
			if (jLi.children().length != jLi.contents().length)&lt;br /&gt;
				jLi.wrapInner(document.createElement(&amp;quot;span&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
			var liWidth = 0;&lt;br /&gt;
			jLi.children().each(function(c, child) {&lt;br /&gt;
				liWidth += child.offsetWidth;&lt;br /&gt;
			});&lt;br /&gt;
			if (liWidth &amp;gt; maxWidth)&lt;br /&gt;
				maxWidth = liWidth;&lt;br /&gt;
		});&lt;br /&gt;
		if ( maxWidth === 0 ) return;&lt;br /&gt;
		// UL/LI bullet width + padding&lt;br /&gt;
		maxWidth += 22.5 * 2;&lt;br /&gt;
&lt;br /&gt;
		var maxColumns = &amp;quot;&amp;quot; + Math.ceil( elements / 5 );&lt;br /&gt;
		$(div).css({&amp;quot;-moz-columns&amp;quot;: maxWidth + &amp;quot;px &amp;quot; + maxColumns, &amp;quot;columns&amp;quot; : maxWidth + &amp;quot;px &amp;quot; + maxColumns});&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
// A high frequency of errors come from old scripts referencing addPortletLink.&lt;br /&gt;
// Can be removed when https://global-search.toolforge.org/?q=%5B%5E%5C.%5DaddPortletLink%5C%28&amp;amp;regex=1&amp;amp;namespaces=&amp;amp;title=.*%5C.js has no nl.wikipedia results.&lt;br /&gt;
window.addPortletLink = function () {&lt;br /&gt;
	// @todo: Please Translate&lt;br /&gt;
	mw.notify('One of your user scripts is broken. Please inspect your error console and remove.');&lt;br /&gt;
	mw.log.warn('addPortletLink is deprecated. Please use mw.util.addPortletLink')&lt;br /&gt;
};&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12315</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12315"/>
				<updated>2021-06-08T23:02:50Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12314</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12314"/>
				<updated>2021-06-08T23:01:18Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	var $execJS = $( '.executeJS' );&lt;br /&gt;
	if ( $execJS.length ) {&lt;br /&gt;
		$execJS.each( function () {&lt;br /&gt;
	        $.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {&lt;br /&gt;
	            sc = $.trim( sc.replace( /[^\w ]/g, '' ) );&lt;br /&gt;
	            if ( sc ) {&lt;br /&gt;
	                importScript( 'MediaWiki:Script/' + sc + '.js' );&lt;br /&gt;
	            }&lt;br /&gt;
	        } );&lt;br /&gt;
	    } );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ], function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.references-small.columns' ).each( function () {&lt;br /&gt;
		$( this ).after( '&amp;lt;div class=&amp;quot;temporaryDiv&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' ).next().prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.last().prev().css( 'clear', 'both' );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	// Этот элемент нужен на случай, если примечания — последний элемент (потребность в next()&lt;br /&gt;
	// возникает из-за невключительности prevUntil() jQuery)&lt;br /&gt;
	$( '.temporaryDiv' ).remove();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12313</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12313"/>
				<updated>2021-06-08T23:00:24Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	var $execJS = $( '.executeJS' );&lt;br /&gt;
	if ( $execJS.length ) {&lt;br /&gt;
		$execJS.each( function () {&lt;br /&gt;
	        $.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {&lt;br /&gt;
	            sc = $.trim( sc.replace( /[^\w ]/g, '' ) );&lt;br /&gt;
	            if ( sc ) {&lt;br /&gt;
	                importScript( 'MediaWiki:Script/' + sc + '.js' );&lt;br /&gt;
	            }&lt;br /&gt;
	        } );&lt;br /&gt;
	    } );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ], function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.references-small.columns' ).each( function () {&lt;br /&gt;
		$( this ).after( '&amp;lt;div class=&amp;quot;temporaryDiv&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' ).next().prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.last().prev().css( 'clear', 'both' );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	// Этот элемент нужен на случай, если примечания — последний элемент (потребность в next()&lt;br /&gt;
	// возникает из-за невключительности prevUntil() jQuery)&lt;br /&gt;
	$( '.temporaryDiv' ).remove();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B0_(Diablo_II)&amp;diff=12312</id>
		<title>Амазонка (Diablo II)</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=%D0%90%D0%BC%D0%B0%D0%B7%D0%BE%D0%BD%D0%BA%D0%B0_(Diablo_II)&amp;diff=12312"/>
				<updated>2021-06-08T22:57:46Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
&lt;br /&gt;
{{Класс (Diablo II)&lt;br /&gt;
| название       = Амазонка&lt;br /&gt;
| иллюстрация    = Diablo-2-Amazon-01.gif&lt;br /&gt;
| экипировка     = Луки амазонок, копья амазонок, дротики амазонок&lt;br /&gt;
| стихии         = Физический урон, молния, яд, холод, огонь, магический урон&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Амазонка''' {{en|Amazon}} — один из [[Классы (Diablo II)|классов]] персонажей в [[Diablo II]].&lt;br /&gt;
&lt;br /&gt;
Аскари, известные также как амазонки, родом с островов Сковос, группы покрытых непроходимыми джунглями островов на Двух морях. Представители этого матриархального племени — могучие воительницы, которые путешествуют по миру, занимаясь наемным трудом и искореняя силы зла.&lt;br /&gt;
&lt;br /&gt;
Наносите врагам колющие удары копьями и дротиками. Поражайте демонов шквалом стрел, орудуя луком не хуже сестер-разбойниц Незримого Ока. Избегайте смертоносных ударов, полагаясь на свою нечеловеческую ловкость. Амазонка всю жизнь готовилась к жестокой кузне войны и виртуозно владеет искусством боя.&lt;br /&gt;
&lt;br /&gt;
This powerful woman warrior belongs to nomadic bands who roam the plains near the South Sea. The wandering of these groups often brings them into conflict with other peoples, so the Amazon is accustomed to fighting to defend her own. This lifestyle has made her fiercely independent and able to weather severe hardship and travel. While her skill with the bow rivals that of the Rogues, the Amazon is also adept in the use of spears and other throwing weapons, as well as in hand to hand combat. The Amazon is much sought after as a mercenary, in which type of service she will be loyal as long as her own ends are also served.&lt;br /&gt;
&lt;br /&gt;
== История ==&lt;br /&gt;
&lt;br /&gt;
The Amazons are women warriors who hail from a group of islands in the Twin Seas, near the border of the Great Ocean. Only the permanently snow-covered peak of Mount Karcheus breaks the expanses of lush forests on the islands.&lt;br /&gt;
&lt;br /&gt;
The Amazon people are a relatively isolated culture. Adapting over the centuries to their tropical milieu, they have built magnificent cities in the forest canopy. These cities are an architectural phenomenon and a source of great pride to the Amazon people. They do not follow the teachings of the Zakarum, but instead practice a polytheistic religion that adheres to the strict principles of Order. Their oracles long ago predicted the Dark Exile, and they have been preparing to combat it ever since. Amazons regard the destruction of the Three Prime Evils as their destiny, ushering in a new era when mortal men and women can at long last take their rightful place in the universe, no longer merely playthings for the beings of the Outer Realms.&lt;br /&gt;
&lt;br /&gt;
The Amazons are a seafaring people, one of the first to have made trade contact with both the Kingdoms of the West and with Kejhistan in the East. Their prominence in the world's trade establishment has afforded their warriors the reputation they currently enjoy as cunning strategists and skilled combatants. They are much sought after as mercenaries, being both expert soldiers as well as extremely loyal - as long as the assignment does not conflict with their strict sense of ethics.&lt;br /&gt;
&lt;br /&gt;
Their pantheon of gods consists of a well-defined hierarchy, each member upholding some segment of the balance of Order. It is this strong sense of order that drives the Amazon people to achieve greatness in even the smallest of their endeavors. Their prime deity is Athulua who, with her consort, Kethryes, rules over the seasons and the weather. Under these Goddesses are a wide assortment of lesser deities, each responsible for his or her own sphere of influence among the Amazon people's daily life. The Amazons believe this pantheon is the remnant of the original inhabitants that settled the islands centuries ago. According to ancient records, they share the same names as these gods, although aspects of their personalities seem to have evolved over the centuries.&lt;br /&gt;
&lt;br /&gt;
In the Amazon culture, only the women serve as warriors, their intrinsic superior dexterity and lithe body structures are better suited to combat in the dense rainforest environs of the islands. Their society is far from stratified, however, as men are responsible for any number of positions in the community, government, and clergy, as well as merchant and agricultural occupations.&lt;br /&gt;
&lt;br /&gt;
Traits and Abilities:&lt;br /&gt;
&lt;br /&gt;
While more than competent in hand-to-hand combat, training in the jungles of her native islands has shaped the Amazon's skill with the bow and missile weapons into one of unparalleled excellence. With the bow, her only rivals are the Sisters of the Sightless Eye. But, unlike her sisters in arms, the Amazon is also highly adept in the use of spears and other thrown weapons. The powers they possess are a combination of Prime magic, Holy magic and ingenious weapon construction.&lt;br /&gt;
&lt;br /&gt;
== Умения ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;margin-left: auto; margin-right: auto; border: none;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Дротики и копья&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Пассивные и магические навыки&lt;br /&gt;
! style=&amp;quot;width: 225px;&amp;quot; | Луки и арбалеты&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; style=&amp;quot;text-align:center; background: #0f0000&amp;quot;| &lt;br /&gt;
&amp;lt;div class=&amp;quot;imageMapHighlighter&amp;quot;&amp;gt;&amp;lt;imagemap&amp;gt;&lt;br /&gt;
Файл:D2-SkillTree-Amazon.png&lt;br /&gt;
rect 16 13 64 61 [[Выпад (Diablo II)]]&lt;br /&gt;
rect 16 149 64 197 [[Прокалывание (Diablo II)]]&lt;br /&gt;
rect 16 285 64 333 [[Лучшая защита (Diablo II)]]&lt;br /&gt;
rect 85 81 133 130 [[Мощный удар (Diablo II)]]&lt;br /&gt;
rect 85 217 133 265 [[Заряженный удар (Diablo II)]]&lt;br /&gt;
rect 85 353 133 401 [[Удар молнии (Diablo II)]]&lt;br /&gt;
rect 154 81 202 130 [[Отравленный дротик (Diablo II)]]&lt;br /&gt;
rect 154 149 202 197 [[Разряд молнии (Diablo II)]]&lt;br /&gt;
rect 154 217 202 265 [[Чумной дротик (Diablo II)]]&lt;br /&gt;
rect 154 353 202 401 [[Неистовство молний (Diablo II)]]&lt;br /&gt;
&lt;br /&gt;
rect 247 13 295 61 [[Внутреннее зрение (Diablo II)]]&lt;br /&gt;
rect 247 149 295 197 [[Замедление снарядов (Diablo II)]]&lt;br /&gt;
rect 247 285 295 333 [[Двойник (Diablo II)]]&lt;br /&gt;
rect 247 353 295 401 [[Валькирия (Diablo II)]]&lt;br /&gt;
rect 316 81 364 130 [[Уклонение (Diablo II)]]&lt;br /&gt;
rect 316 149 364 197 [[Ускользание (Diablo II)]]&lt;br /&gt;
rect 316 285 364 333 [[Избежание (Diablo II)]]&lt;br /&gt;
rect 385 13 433 61 [[Критический удар (Diablo II)]]&lt;br /&gt;
rect 385 217 433 265 [[Пронзание (Diablo II)]]&lt;br /&gt;
rect 385 353 433 401 [[Пробивание (Diablo II)]]&lt;br /&gt;
&lt;br /&gt;
rect 478 81 526 130 [[Морозная стрела (Diablo II)]]&lt;br /&gt;
rect 478 217 526 265 [[Ледяная стрела (умение амазонки, Diablo II)]]&lt;br /&gt;
rect 478 353 526 401 [[Замораживающая стрела (Diablo II)]]&lt;br /&gt;
rect 547 13 595 61 [[Магическая стрела (Diablo II)]]&lt;br /&gt;
rect 547 81 595 130 [[Залп (Diablo II)]]&lt;br /&gt;
rect 547 217 595 265 [[Самонаводящаяся стрела (Diablo II)]]&lt;br /&gt;
rect 547 285 595 333 [[Обстрел (Diablo II)]]&lt;br /&gt;
rect 616 13 664 61 [[Огненная стрела (умение амазонки, Diablo II)]]&lt;br /&gt;
rect 616 149 664 197 [[Взрывная стрела (Diablo II)]]&lt;br /&gt;
rect 616 285 664 333 [[Обжигающая стрела (Diablo II)]]&lt;br /&gt;
desc none&lt;br /&gt;
&amp;lt;/imagemap&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Экипировка ==&lt;br /&gt;
&lt;br /&gt;
=== Комплекты ===&lt;br /&gt;
&lt;br /&gt;
== Интересные факты ==&lt;br /&gt;
* Амазонку в англоязычной версии озвучила [[Джессика Штраус]].&lt;br /&gt;
&lt;br /&gt;
== Медиа ==&lt;br /&gt;
=== Скриншоты ===&lt;br /&gt;
&lt;br /&gt;
=== Иллюстрации ===&lt;br /&gt;
&amp;lt;gallery heights=&amp;quot;200px&amp;quot;&amp;gt;&lt;br /&gt;
Файл:Diablo-2-Amazon-artwork-01.jpg|&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Иллюстрация амазонки ([[Kris Renkewitz]])|alt=Амазонка в Diablo 2&amp;lt;/div&amp;gt;&lt;br /&gt;
Файл:Diablo-2-Amazon-artwork-02.jpg|&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;Иллюстрация амазонки|alt=Амазонка в Diablo 2&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{примечания}}&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* [http://classic.battle.net/diablo2exp/classes/amazon.shtml Страница амазонки на официальном сайте игры]&lt;br /&gt;
&lt;br /&gt;
{{Классы (Diablo II)}}&lt;br /&gt;
[[Категория:Классы (Diablo II)]]&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12311</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12311"/>
				<updated>2021-06-08T22:49:14Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот&lt;br /&gt;
 * список не стоит. При необходимости добавить много сообщений во много языков можно использовать&lt;br /&gt;
 * механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы&lt;br /&gt;
 * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.&lt;br /&gt;
 */&lt;br /&gt;
var expandCaption, collapseCaption, zeroSectionTip;&lt;br /&gt;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {&lt;br /&gt;
	expandCaption = 'show';&lt;br /&gt;
	collapseCaption = 'hide';&lt;br /&gt;
	zeroSectionTip = 'Edit lead section';&lt;br /&gt;
} else {&lt;br /&gt;
	expandCaption = 'показать';&lt;br /&gt;
	collapseCaption = 'скрыть';&lt;br /&gt;
	zeroSectionTip = 'Править преамбулу';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	var $execJS = $( '.executeJS' );&lt;br /&gt;
	if ( $execJS.length ) {&lt;br /&gt;
		$execJS.each( function () {&lt;br /&gt;
	        $.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {&lt;br /&gt;
	            sc = $.trim( sc.replace( /[^\w ]/g, '' ) );&lt;br /&gt;
	            if ( sc ) {&lt;br /&gt;
	                importScript( 'MediaWiki:Script/' + sc + '.js' );&lt;br /&gt;
	            }&lt;br /&gt;
	        } );&lt;br /&gt;
	    } );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом&lt;br /&gt;
	 * purgelink и именем страницы в параметре data-pagename, например как в шаблоне {{очистить кэш}})&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.purgelink a' ).click( function ( e ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );&lt;br /&gt;
			new mw.Api().post( {&lt;br /&gt;
				action: 'purge',&lt;br /&gt;
				titles: pageName&lt;br /&gt;
			} ).then( function () {&lt;br /&gt;
				var url = mw.util.getUrl( pageName );&lt;br /&gt;
				if ( e.ctrlKey ) {&lt;br /&gt;
					if ( !window.open( url ) ) {&lt;br /&gt;
						location.assign( url );&lt;br /&gt;
		            }&lt;br /&gt;
		        } else {&lt;br /&gt;
					location.assign( url );&lt;br /&gt;
		        }&lt;br /&gt;
			}, function () {&lt;br /&gt;
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );&lt;br /&gt;
			} );&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * {{TOC hidden}}&lt;br /&gt;
 */&lt;br /&gt;
function TOChidden() {&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc' ).addClass( 'tochidden' );&lt;br /&gt;
	$( '.tochidden-wrapper .togglelink' ).text( mw.msg( 'showtoc' ) );&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc &amp;gt; ul' ).css( 'display', 'none' );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ], function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.references-small.columns' ).each( function () {&lt;br /&gt;
		$( this ).after( '&amp;lt;div class=&amp;quot;temporaryDiv&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' ).next().prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.last().prev().css( 'clear', 'both' );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	// Этот элемент нужен на случай, если примечания — последний элемент (потребность в next()&lt;br /&gt;
	// возникает из-за невключительности prevUntil() jQuery)&lt;br /&gt;
	$( '.temporaryDiv' ).remove();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Авторазбиение списков на колонки. Будет работать только для однострочных списков. 35em&lt;br /&gt;
	 * (из Mediawiki:Common.css) является предварительным числом, а фактическое будет посчитано исходя&lt;br /&gt;
	 * из ширины элементов. Должно использоваться только для UL внутри DIV. Пример использования —&lt;br /&gt;
	 * шаблон {{Wikidata/SisterCities}}.&lt;br /&gt;
	 */&lt;br /&gt;
	$(&amp;quot;div.autocolumns&amp;quot;).each(function(d, div) {&lt;br /&gt;
		var parentWidth = $(div).parent()[0].offsetWidth;&lt;br /&gt;
		if (!parentWidth) return;&lt;br /&gt;
&lt;br /&gt;
		var maxWidth = 0;&lt;br /&gt;
		var elements = 0;&lt;br /&gt;
		$(div).find(&amp;quot;ul&amp;gt;li&amp;quot;).each(function(l, li) {&lt;br /&gt;
			elements++;&lt;br /&gt;
			var jLi = $(li);&lt;br /&gt;
			if (jLi.children().length != jLi.contents().length)&lt;br /&gt;
				jLi.wrapInner(document.createElement(&amp;quot;span&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
			var liWidth = 0;&lt;br /&gt;
			jLi.children().each(function(c, child) {&lt;br /&gt;
				liWidth += child.offsetWidth;&lt;br /&gt;
			});&lt;br /&gt;
			if (liWidth &amp;gt; maxWidth)&lt;br /&gt;
				maxWidth = liWidth;&lt;br /&gt;
		});&lt;br /&gt;
		if ( maxWidth == 0 ) return;&lt;br /&gt;
		// UL/LI bullet width + padding&lt;br /&gt;
		maxWidth += 22.5 * 2;&lt;br /&gt;
&lt;br /&gt;
		var maxColumns = &amp;quot;&amp;quot; + Math.ceil( elements / 5 );&lt;br /&gt;
		$(div).css({&amp;quot;-moz-columns&amp;quot;: maxWidth + &amp;quot;px &amp;quot; + maxColumns, &amp;quot;columns&amp;quot; : maxWidth + &amp;quot;px &amp;quot; + maxColumns});&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12310</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12310"/>
				<updated>2021-06-08T22:48:26Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Локальная функция загрузки скриптов с поддержкой указания проекта&lt;br /&gt;
 */&lt;br /&gt;
var importScript_ = importScript;&lt;br /&gt;
importScript = function ( page, proj ) {&lt;br /&gt;
	if ( !proj ) {&lt;br /&gt;
		importScript_( page );&lt;br /&gt;
	} else {&lt;br /&gt;
		if ( proj.indexOf( '.' ) === -1 ) {&lt;br /&gt;
			proj += '.wikipedia.org';&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) +&lt;br /&gt;
				'&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот&lt;br /&gt;
 * список не стоит. При необходимости добавить много сообщений во много языков можно использовать&lt;br /&gt;
 * механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы&lt;br /&gt;
 * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.&lt;br /&gt;
 */&lt;br /&gt;
var expandCaption, collapseCaption, zeroSectionTip;&lt;br /&gt;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {&lt;br /&gt;
	expandCaption = 'show';&lt;br /&gt;
	collapseCaption = 'hide';&lt;br /&gt;
	zeroSectionTip = 'Edit lead section';&lt;br /&gt;
} else {&lt;br /&gt;
	expandCaption = 'показать';&lt;br /&gt;
	collapseCaption = 'скрыть';&lt;br /&gt;
	zeroSectionTip = 'Править преамбулу';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	var $execJS = $( '.executeJS' );&lt;br /&gt;
	if ( $execJS.length ) {&lt;br /&gt;
		$execJS.each( function () {&lt;br /&gt;
	        $.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {&lt;br /&gt;
	            sc = $.trim( sc.replace( /[^\w ]/g, '' ) );&lt;br /&gt;
	            if ( sc ) {&lt;br /&gt;
	                importScript( 'MediaWiki:Script/' + sc + '.js' );&lt;br /&gt;
	            }&lt;br /&gt;
	        } );&lt;br /&gt;
	    } );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом&lt;br /&gt;
	 * purgelink и именем страницы в параметре data-pagename, например как в шаблоне {{очистить кэш}})&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.purgelink a' ).click( function ( e ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );&lt;br /&gt;
			new mw.Api().post( {&lt;br /&gt;
				action: 'purge',&lt;br /&gt;
				titles: pageName&lt;br /&gt;
			} ).then( function () {&lt;br /&gt;
				var url = mw.util.getUrl( pageName );&lt;br /&gt;
				if ( e.ctrlKey ) {&lt;br /&gt;
					if ( !window.open( url ) ) {&lt;br /&gt;
						location.assign( url );&lt;br /&gt;
		            }&lt;br /&gt;
		        } else {&lt;br /&gt;
					location.assign( url );&lt;br /&gt;
		        }&lt;br /&gt;
			}, function () {&lt;br /&gt;
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );&lt;br /&gt;
			} );&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * {{TOC hidden}}&lt;br /&gt;
 */&lt;br /&gt;
function TOChidden() {&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc' ).addClass( 'tochidden' );&lt;br /&gt;
	$( '.tochidden-wrapper .togglelink' ).text( mw.msg( 'showtoc' ) );&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc &amp;gt; ul' ).css( 'display', 'none' );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ], function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.references-small.columns' ).each( function () {&lt;br /&gt;
		$( this ).after( '&amp;lt;div class=&amp;quot;temporaryDiv&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' ).next().prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.last().prev().css( 'clear', 'both' );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	// Этот элемент нужен на случай, если примечания — последний элемент (потребность в next()&lt;br /&gt;
	// возникает из-за невключительности prevUntil() jQuery)&lt;br /&gt;
	$( '.temporaryDiv' ).remove();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Авторазбиение списков на колонки. Будет работать только для однострочных списков. 35em&lt;br /&gt;
	 * (из Mediawiki:Common.css) является предварительным числом, а фактическое будет посчитано исходя&lt;br /&gt;
	 * из ширины элементов. Должно использоваться только для UL внутри DIV. Пример использования —&lt;br /&gt;
	 * шаблон {{Wikidata/SisterCities}}.&lt;br /&gt;
	 */&lt;br /&gt;
	$(&amp;quot;div.autocolumns&amp;quot;).each(function(d, div) {&lt;br /&gt;
		var parentWidth = $(div).parent()[0].offsetWidth;&lt;br /&gt;
		if (!parentWidth) return;&lt;br /&gt;
&lt;br /&gt;
		var maxWidth = 0;&lt;br /&gt;
		var elements = 0;&lt;br /&gt;
		$(div).find(&amp;quot;ul&amp;gt;li&amp;quot;).each(function(l, li) {&lt;br /&gt;
			elements++;&lt;br /&gt;
			var jLi = $(li);&lt;br /&gt;
			if (jLi.children().length != jLi.contents().length)&lt;br /&gt;
				jLi.wrapInner(document.createElement(&amp;quot;span&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
			var liWidth = 0;&lt;br /&gt;
			jLi.children().each(function(c, child) {&lt;br /&gt;
				liWidth += child.offsetWidth;&lt;br /&gt;
			});&lt;br /&gt;
			if (liWidth &amp;gt; maxWidth)&lt;br /&gt;
				maxWidth = liWidth;&lt;br /&gt;
		});&lt;br /&gt;
		if ( maxWidth == 0 ) return;&lt;br /&gt;
		// UL/LI bullet width + padding&lt;br /&gt;
		maxWidth += 22.5 * 2;&lt;br /&gt;
&lt;br /&gt;
		var maxColumns = &amp;quot;&amp;quot; + Math.ceil( elements / 5 );&lt;br /&gt;
		$(div).css({&amp;quot;-moz-columns&amp;quot;: maxWidth + &amp;quot;px &amp;quot; + maxColumns, &amp;quot;columns&amp;quot; : maxWidth + &amp;quot;px &amp;quot; + maxColumns});&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12309</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12309"/>
				<updated>2021-06-08T22:47:19Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; * Код MediaWiki:Common.js безусловно загружается всем пользователям на всех страницах.&lt;br /&gt;
 * Во избежание отправки лишних запросов по возможности не используйте здесь mw.loader.using&lt;br /&gt;
 * с модулями, которые не загружаются по умолчанию (см.&lt;br /&gt;
 * [[w:Обсуждение MediaWiki:Common.js#Список модулей, загружаемых по умолчанию]]). В таком случае&lt;br /&gt;
 * лучше создать скрытый гаджет, загружаемый по умолчанию, и добавить ему нужные модули в качестве&lt;br /&gt;
 * зависимостей.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Локальная функция загрузки скриптов с поддержкой указания проекта&lt;br /&gt;
 */&lt;br /&gt;
var importScript_ = importScript;&lt;br /&gt;
importScript = function ( page, proj ) {&lt;br /&gt;
	if ( !proj ) {&lt;br /&gt;
		importScript_( page );&lt;br /&gt;
	} else {&lt;br /&gt;
		if ( proj.indexOf( '.' ) === -1 ) {&lt;br /&gt;
			proj += '.wikipedia.org';&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) +&lt;br /&gt;
				'&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот&lt;br /&gt;
 * список не стоит. При необходимости добавить много сообщений во много языков можно использовать&lt;br /&gt;
 * механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы&lt;br /&gt;
 * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.&lt;br /&gt;
 */&lt;br /&gt;
var expandCaption, collapseCaption, zeroSectionTip;&lt;br /&gt;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {&lt;br /&gt;
	expandCaption = 'show';&lt;br /&gt;
	collapseCaption = 'hide';&lt;br /&gt;
	zeroSectionTip = 'Edit lead section';&lt;br /&gt;
} else {&lt;br /&gt;
	expandCaption = 'показать';&lt;br /&gt;
	collapseCaption = 'скрыть';&lt;br /&gt;
	zeroSectionTip = 'Править преамбулу';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	var $execJS = $( '.executeJS' );&lt;br /&gt;
	if ( $execJS.length ) {&lt;br /&gt;
		$execJS.each( function () {&lt;br /&gt;
	        $.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {&lt;br /&gt;
	            sc = $.trim( sc.replace( /[^\w ]/g, '' ) );&lt;br /&gt;
	            if ( sc ) {&lt;br /&gt;
	                importScript( 'MediaWiki:Script/' + sc + '.js' );&lt;br /&gt;
	            }&lt;br /&gt;
	        } );&lt;br /&gt;
	    } );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом&lt;br /&gt;
	 * purgelink и именем страницы в параметре data-pagename, например как в шаблоне {{очистить кэш}})&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.purgelink a' ).click( function ( e ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );&lt;br /&gt;
			new mw.Api().post( {&lt;br /&gt;
				action: 'purge',&lt;br /&gt;
				titles: pageName&lt;br /&gt;
			} ).then( function () {&lt;br /&gt;
				var url = mw.util.getUrl( pageName );&lt;br /&gt;
				if ( e.ctrlKey ) {&lt;br /&gt;
					if ( !window.open( url ) ) {&lt;br /&gt;
						location.assign( url );&lt;br /&gt;
		            }&lt;br /&gt;
		        } else {&lt;br /&gt;
					location.assign( url );&lt;br /&gt;
		        }&lt;br /&gt;
			}, function () {&lt;br /&gt;
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );&lt;br /&gt;
			} );&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * {{TOC hidden}}&lt;br /&gt;
 */&lt;br /&gt;
function TOChidden() {&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc' ).addClass( 'tochidden' );&lt;br /&gt;
	$( '.tochidden-wrapper .togglelink' ).text( mw.msg( 'showtoc' ) );&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc &amp;gt; ul' ).css( 'display', 'none' );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ], function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.references-small.columns' ).each( function () {&lt;br /&gt;
		$( this ).after( '&amp;lt;div class=&amp;quot;temporaryDiv&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' ).next().prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.last().prev().css( 'clear', 'both' );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	// Этот элемент нужен на случай, если примечания — последний элемент (потребность в next()&lt;br /&gt;
	// возникает из-за невключительности prevUntil() jQuery)&lt;br /&gt;
	$( '.temporaryDiv' ).remove();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Авторазбиение списков на колонки. Будет работать только для однострочных списков. 35em&lt;br /&gt;
	 * (из Mediawiki:Common.css) является предварительным числом, а фактическое будет посчитано исходя&lt;br /&gt;
	 * из ширины элементов. Должно использоваться только для UL внутри DIV. Пример использования —&lt;br /&gt;
	 * шаблон {{Wikidata/SisterCities}}.&lt;br /&gt;
	 */&lt;br /&gt;
	$(&amp;quot;div.autocolumns&amp;quot;).each(function(d, div) {&lt;br /&gt;
		var parentWidth = $(div).parent()[0].offsetWidth;&lt;br /&gt;
		if (!parentWidth) return;&lt;br /&gt;
&lt;br /&gt;
		var maxWidth = 0;&lt;br /&gt;
		var elements = 0;&lt;br /&gt;
		$(div).find(&amp;quot;ul&amp;gt;li&amp;quot;).each(function(l, li) {&lt;br /&gt;
			elements++;&lt;br /&gt;
			var jLi = $(li);&lt;br /&gt;
			if (jLi.children().length != jLi.contents().length)&lt;br /&gt;
				jLi.wrapInner(document.createElement(&amp;quot;span&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
			var liWidth = 0;&lt;br /&gt;
			jLi.children().each(function(c, child) {&lt;br /&gt;
				liWidth += child.offsetWidth;&lt;br /&gt;
			});&lt;br /&gt;
			if (liWidth &amp;gt; maxWidth)&lt;br /&gt;
				maxWidth = liWidth;&lt;br /&gt;
		});&lt;br /&gt;
		if ( maxWidth == 0 ) return;&lt;br /&gt;
		// UL/LI bullet width + padding&lt;br /&gt;
		maxWidth += 22.5 * 2;&lt;br /&gt;
&lt;br /&gt;
		var maxColumns = &amp;quot;&amp;quot; + Math.ceil( elements / 5 );&lt;br /&gt;
		$(div).css({&amp;quot;-moz-columns&amp;quot;: maxWidth + &amp;quot;px &amp;quot; + maxColumns, &amp;quot;columns&amp;quot; : maxWidth + &amp;quot;px &amp;quot; + maxColumns});&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12308</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12308"/>
				<updated>2021-06-08T22:37:46Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/**&lt;br /&gt;
 * Код MediaWiki:Common.js безусловно загружается всем пользователям на всех страницах.&lt;br /&gt;
 * Во избежание отправки лишних запросов по возможности не используйте здесь mw.loader.using&lt;br /&gt;
 * с модулями, которые не загружаются по умолчанию (см.&lt;br /&gt;
 * [[w:Обсуждение MediaWiki:Common.js#Список модулей, загружаемых по умолчанию]]). В таком случае&lt;br /&gt;
 * лучше создать скрытый гаджет, загружаемый по умолчанию, и добавить ему нужные модули в качестве&lt;br /&gt;
 * зависимостей.&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Локальная функция загрузки скриптов с поддержкой указания проекта&lt;br /&gt;
 */&lt;br /&gt;
var importScript_ = importScript;&lt;br /&gt;
importScript = function ( page, proj ) {&lt;br /&gt;
	if ( !proj ) {&lt;br /&gt;
		importScript_( page );&lt;br /&gt;
	} else {&lt;br /&gt;
		if ( proj.indexOf( '.' ) === -1 ) {&lt;br /&gt;
			proj += '.wikipedia.org';&lt;br /&gt;
		}&lt;br /&gt;
		mw.loader.using( 'mediawiki.util' ).done( function () {&lt;br /&gt;
			mw.loader.load( '//' + proj + '/w/index.php?title=' + mw.util.wikiUrlencode( page ) +&lt;br /&gt;
				'&amp;amp;action=raw&amp;amp;ctype=text/javascript' );&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Часто те или иные манипуляции со страницей нужно выполнить как можно раньше, но нет гарантии, что&lt;br /&gt;
 * к моменту выполнения кода нужный участок DOM готов, а событие полной загрузки страницы происходит&lt;br /&gt;
 * слишком поздно. В этой функции проверяется наличие элемента $testElement и в случае успеха&lt;br /&gt;
 * функция-колбэк выполняется, иначе же её выполнение поручается другой функции. Если элемент&lt;br /&gt;
 * в $testElement имеет содержимое, правильнее указать следующий за ним элемент, чтобы быть&lt;br /&gt;
 * уверенным, что он загрузился до конца. Имейте в виду, что разные скины часто используют разные&lt;br /&gt;
 * названия классов и идентификаторов.&lt;br /&gt;
 */&lt;br /&gt;
function runAsEarlyAsPossible( callback, $testElement, func ) {&lt;br /&gt;
	func = func || $;&lt;br /&gt;
	$testElement = $testElement || $( '#footer' );&lt;br /&gt;
&lt;br /&gt;
	if ( $testElement.length ) {&lt;br /&gt;
		callback();&lt;br /&gt;
	} else {&lt;br /&gt;
		func( callback );&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Настройка обработки «е» и «ё» при сортировке в таблицах&lt;br /&gt;
 */&lt;br /&gt;
mw.config.set( 'tableSorterCollation', { 'Ё': 'Е', 'ё': 'е' } );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Строки. Иноязычный интерфейс предположительно включают весьма редко, поэтому раздувать этот&lt;br /&gt;
 * список не стоит. При необходимости добавить много сообщений во много языков можно использовать&lt;br /&gt;
 * механизм системных сообщений (= страниц в пространстве MediaWiki, у которых могут быть суффиксы&lt;br /&gt;
 * типа /en). См., как их получение реализовано в MediaWiki:Gadget-sidebarRelated.js.&lt;br /&gt;
 */&lt;br /&gt;
var expandCaption, collapseCaption, zeroSectionTip;&lt;br /&gt;
if ( mw.config.get( 'wgUserLanguage' ) === 'en' ) {&lt;br /&gt;
	expandCaption = 'show';&lt;br /&gt;
	collapseCaption = 'hide';&lt;br /&gt;
	zeroSectionTip = 'Edit lead section';&lt;br /&gt;
} else {&lt;br /&gt;
	expandCaption = 'показать';&lt;br /&gt;
	collapseCaption = 'скрыть';&lt;br /&gt;
	zeroSectionTip = 'Править преамбулу';&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * [[ВП:Сворачиваемые блоки]]&lt;br /&gt;
 */&lt;br /&gt;
// Число раскрытых по умолчанию навигационных (и не только) шаблонов, если им задан параметр&lt;br /&gt;
// autocollapse. Участники могут переопределять это значение в личных JS.&lt;br /&gt;
var NavigationBarShowDefault;&lt;br /&gt;
if ( typeof NavigationBarShowDefault === 'undefined' ) {&lt;br /&gt;
	NavigationBarShowDefault = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// table.collapsible&lt;br /&gt;
function collapsibleTables( $content ) {&lt;br /&gt;
	var $btn,&lt;br /&gt;
		$a,&lt;br /&gt;
		tblIdx = 0,&lt;br /&gt;
		navboxCount = 0,&lt;br /&gt;
		notNavboxCount = 0,&lt;br /&gt;
		colTables = [],&lt;br /&gt;
		$Tables = $content.find( 'table' );&lt;br /&gt;
&lt;br /&gt;
	$Tables.each( function( i, table ) {&lt;br /&gt;
		if ( $( table ).hasClass( 'collapsible' ) ) {&lt;br /&gt;
			var $table = $( this ),&lt;br /&gt;
				$row = $table.find( 'tr' ).first(),&lt;br /&gt;
				$cell = $row.find( 'th' ).first();&lt;br /&gt;
			if ( !$cell.length ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			$table.attr( 'id', 'collapsibleTable' + tblIdx );&lt;br /&gt;
			$btn = $( '&amp;lt;span&amp;gt;' ).addClass( 'collapseButton' );&lt;br /&gt;
			$a = $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
				.attr( 'id', 'collapseButton' + tblIdx )&lt;br /&gt;
				.attr( 'href', 'javascript:collapseTable(' + tblIdx + ');' )&lt;br /&gt;
				// Изменяем цвет ссылки, только если цвет текста в навбоксе нестандартный&lt;br /&gt;
				.css( 'color', $cell.css( 'color' ) === $( '.mw-body' ).css( 'color' ) ? 'auto' :&lt;br /&gt;
					$cell.css( 'color' ) )&lt;br /&gt;
				.text( collapseCaption );&lt;br /&gt;
			$btn&lt;br /&gt;
				.append( '[' )&lt;br /&gt;
				.append( $a )&lt;br /&gt;
				.append( ']' );&lt;br /&gt;
			if ( $cell.contents().length ) {&lt;br /&gt;
				$btn.insertBefore( $cell.contents().first() );&lt;br /&gt;
			} else {&lt;br /&gt;
				$btn.appendTo( $cell );&lt;br /&gt;
			}&lt;br /&gt;
			// hasClass( 'navbox' ) — временное решение для навшаблонов, ещё не переведённых&lt;br /&gt;
			// на {{Навигационная таблица}} (также ниже)&lt;br /&gt;
			if ( $table.hasClass( 'navbox-inner' ) || $table.hasClass( 'navbox' ) ) {&lt;br /&gt;
				navboxCount++;&lt;br /&gt;
			} else {&lt;br /&gt;
				notNavboxCount++;&lt;br /&gt;
			}&lt;br /&gt;
			colTables[tblIdx++] = $table;&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
	for ( var i = 0; i &amp;lt; tblIdx; i++ ) {&lt;br /&gt;
		if ( colTables[i].hasClass( 'collapsed' ) ||&lt;br /&gt;
			( colTables[i].hasClass( 'autocollapse' ) &amp;amp;&amp;amp;&lt;br /&gt;
				( ( ( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &amp;amp;&amp;amp;&lt;br /&gt;
						navboxCount &amp;gt; NavigationBarShowDefault ) ||&lt;br /&gt;
					( !( colTables[i].hasClass( 'navbox-inner' ) || colTables[i].hasClass( 'navbox' ) ) &amp;amp;&amp;amp;&lt;br /&gt;
						notNavboxCount &amp;gt; NavigationBarShowDefault ) ) ) )&lt;br /&gt;
		{&lt;br /&gt;
			collapseTable( i );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( collapsibleTables );&lt;br /&gt;
&lt;br /&gt;
function collapseTable( idx ) {&lt;br /&gt;
	var $table = $( '#collapsibleTable' + idx ),&lt;br /&gt;
		$rows = $table.children().children( 'tr' ),&lt;br /&gt;
		$btn = $( '#collapseButton' + idx );&lt;br /&gt;
	if ( !$table.length || !$rows.length || !$btn.length ) {&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	var isExpanded = ( $btn.text() === collapseCaption ),&lt;br /&gt;
		cssDisplay = isExpanded ? 'none' : $rows.first().css( 'display' );&lt;br /&gt;
&lt;br /&gt;
	$btn.text( isExpanded ? expandCaption : collapseCaption );&lt;br /&gt;
	$rows.slice( 1 ).each( function() {&lt;br /&gt;
		$( this ).css( 'display', cssDisplay );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// div.NavFrame&lt;br /&gt;
var navFrameExpandCaption = '[' + expandCaption + ']',&lt;br /&gt;
	navFrameCollapseCaption = '[' + collapseCaption + ']';&lt;br /&gt;
&lt;br /&gt;
function collapsibleDivs( $content ) {&lt;br /&gt;
	var navIdx = 0,&lt;br /&gt;
		colNavs = [],&lt;br /&gt;
		i,&lt;br /&gt;
		$Divs = $content.find( 'div' );&lt;br /&gt;
&lt;br /&gt;
	$Divs.each( function( i, div ) {&lt;br /&gt;
		if ( $( div ).hasClass( 'NavFrame' ) ) {&lt;br /&gt;
			var $navFrame = $( this );&lt;br /&gt;
			$navFrame.attr( 'id', 'NavFrame' + navIdx );&lt;br /&gt;
			var $a = $( '&amp;lt;a&amp;gt;' )&lt;br /&gt;
				.addClass( 'NavToggle' )&lt;br /&gt;
				.attr( 'id', 'NavToggle' + navIdx )&lt;br /&gt;
				.attr( 'href', 'javascript:collapseDiv(' + navIdx + ');' )&lt;br /&gt;
				.text( navFrameCollapseCaption );&lt;br /&gt;
			$navFrame.children( '.NavHead' ).append( $a );&lt;br /&gt;
			colNavs[navIdx++] = $navFrame;&lt;br /&gt;
		}&lt;br /&gt;
	} );&lt;br /&gt;
	for ( i = 0; i &amp;lt; navIdx; i++ ) {&lt;br /&gt;
		if ( colNavs[i].hasClass( 'collapsed' ) ||&lt;br /&gt;
			( navIdx &amp;gt; NavigationBarShowDefault &amp;amp;&amp;amp;&lt;br /&gt;
				!colNavs[i].hasClass( 'expanded' )&lt;br /&gt;
			)&lt;br /&gt;
		) {&lt;br /&gt;
			collapseDiv( i );&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( collapsibleDivs );&lt;br /&gt;
&lt;br /&gt;
function collapseDiv( idx ) {&lt;br /&gt;
	var $div = $( '#NavFrame' + idx ),&lt;br /&gt;
		$btn = $( '#NavToggle' + idx );&lt;br /&gt;
	if ( !$div.length || !$btn.length ) {&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
	var isExpanded = ( $btn.text() === navFrameCollapseCaption );&lt;br /&gt;
	$btn.text( isExpanded ? navFrameExpandCaption : navFrameCollapseCaption );&lt;br /&gt;
	$div.children( '.NavContent, .NavPic' ).each( function() {&lt;br /&gt;
		$( this ).css( 'display', isExpanded ? 'none' : 'block' );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Загрузка скриптов через систему подгаджетов&lt;br /&gt;
 */&lt;br /&gt;
// Изолируем код из глобальной области видимости&lt;br /&gt;
( function () {&lt;br /&gt;
	var namespaceNumber = mw.config.get( 'wgNamespaceNumber' );&lt;br /&gt;
&lt;br /&gt;
	// Скрипты для служебных страниц&lt;br /&gt;
	if ( namespaceNumber === -1 ) {&lt;br /&gt;
		var specialGadgets = [&lt;br /&gt;
			'Abusefilter',&lt;br /&gt;
			'Log',&lt;br /&gt;
			'Movepage',&lt;br /&gt;
			'Newpages',&lt;br /&gt;
			'Search',&lt;br /&gt;
			'Upload'&lt;br /&gt;
		];&lt;br /&gt;
		var specialLocalGadgets = [&lt;br /&gt;
			'Block'&lt;br /&gt;
		];&lt;br /&gt;
		var canonicalSpecialPageName = mw.config.get( 'wgCanonicalSpecialPageName' );&lt;br /&gt;
		if ( specialGadgets.indexOf( canonicalSpecialPageName ) &amp;gt; -1 ) {&lt;br /&gt;
			mw.loader.load( '//ru.wikipedia.org/w/load.php?modules=ext.gadget.common-special-' + canonicalSpecialPageName.toLowerCase() + '&amp;amp;only=scripts');&lt;br /&gt;
		}&lt;br /&gt;
		if ( specialLocalGadgets.indexOf( canonicalSpecialPageName ) &amp;gt; -1 ) {&lt;br /&gt;
			mw.loader.load( 'ext.gadget.common-special-' + canonicalSpecialPageName.toLowerCase() );&lt;br /&gt;
		}&lt;br /&gt;
	} else {&lt;br /&gt;
		// Скрипты для действий&lt;br /&gt;
		var action = mw.config.get( 'wgAction' );&lt;br /&gt;
		var actionGadgets = {&lt;br /&gt;
			'edit': [ 'ext.gadget.common-action-edit', 'ext.gadget.wikificator', 'ext.gadget.summaryButtons' ]&lt;br /&gt;
		};&lt;br /&gt;
		actionGadgets[ 'submit' ] = actionGadgets[ 'edit' ];&lt;br /&gt;
		// Удалить после исчезновения ссылки «Редактировать с инструментом переезда на новый парсер» в сайдбаре&lt;br /&gt;
		actionGadgets[ 'parsermigration-edit' ] = actionGadgets[ 'edit' ];&lt;br /&gt;
&lt;br /&gt;
		if ( actionGadgets[ action ] ) {&lt;br /&gt;
			mw.loader.load( actionGadgets[ action ] );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Скрипты для пространств&lt;br /&gt;
		var namespaceGadgets = {&lt;br /&gt;
			6: [ '//ru.wikipedia.org/w/load.php?modules=ext.gadget.common-namespace-file&amp;amp;only=scripts' ]&lt;br /&gt;
		};&lt;br /&gt;
&lt;br /&gt;
		if ( namespaceGadgets[ namespaceNumber ] ) {&lt;br /&gt;
			mw.loader.load( namespaceGadgets[ namespaceNumber ] );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		/**&lt;br /&gt;
		 * Сортировка интервик&lt;br /&gt;
		 */&lt;br /&gt;
		$( function () { $( function () {&lt;br /&gt;
			if ( mw.config.get( 'wgUserName' ) &amp;amp;&amp;amp;&lt;br /&gt;
				// Нестрогое сравнение, потому что формат значений постоянно скачет, см. [[phab:T54542]]&lt;br /&gt;
				( mw.user.options.get( 'compact-language-links' ) != 1 &amp;amp;&amp;amp;&lt;br /&gt;
					( ( mw.config.get( 'wgLangPrefs' ) === null ? false : true ) ||&lt;br /&gt;
						( mw.config.get( 'wgAddLangHints' ) === null ? false :&lt;br /&gt;
							mw.config.get( 'wgAddLangHints' ) ) ||&lt;br /&gt;
						( mw.config.get( 'wgUseUserLanguage' ) === null ? false :&lt;br /&gt;
							mw.config.get( 'wgUseUserLanguage' ) ) ) ) )&lt;br /&gt;
			{&lt;br /&gt;
				importScript( 'MediaWiki:Interwiki-links.js' );&lt;br /&gt;
			}&lt;br /&gt;
		} ); } );&lt;br /&gt;
	}&lt;br /&gt;
}() );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Старые коды&lt;br /&gt;
 */&lt;br /&gt;
if ( navigator.platform.indexOf( 'Win' ) !== -1 ) {&lt;br /&gt;
	mw.loader.using( 'mediawiki.util', function () {&lt;br /&gt;
		mw.util.addCSS( '.IPA, .Unicode { font-family: &amp;quot;Arial Unicode MS&amp;quot;, &amp;quot;Lucida Sans Unicode&amp;quot;; }' );&lt;br /&gt;
	} );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Дополнительный функционал для заглавной страницы&lt;br /&gt;
 */&lt;br /&gt;
if ( mw.config.get( 'wgIsMainPage' ) &amp;amp;&amp;amp; mw.config.get( 'wgAction' ) === 'view' ) {&lt;br /&gt;
	runAsEarlyAsPossible( function () {&lt;br /&gt;
		if ( window.scrollY === 0 ) {&lt;br /&gt;
			$( '#searchInput' ).focus();&lt;br /&gt;
		}&lt;br /&gt;
	}, $( '#searchInput' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Выполнение скриптов из пространства MediaWiki, указанных в URL&lt;br /&gt;
 * См. также https://www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL&lt;br /&gt;
 */&lt;br /&gt;
var withJS = location.href.match( /[&amp;amp;?]withjs=((mediawiki:)?([^&amp;amp;#]+))/i );&lt;br /&gt;
if ( withJS ) {&lt;br /&gt;
	importScript_( 'MediaWiki:' + withJS[3] );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, который нужно выполнить как можно раньше. Он выполняется, если загружен подвал страницы,&lt;br /&gt;
 * иначе же ждёт наступления события wikipage.content (см. выше определение runAsEarlyAsPossible&lt;br /&gt;
 * и ниже про wikipage.content).&lt;br /&gt;
 */&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * {{выполнить скрипт}}&lt;br /&gt;
	 */&lt;br /&gt;
	var $execJS = $( '.executeJS' );&lt;br /&gt;
	if ( $execJS.length ) {&lt;br /&gt;
		$execJS.each( function () {&lt;br /&gt;
	        $.each( $( this ).data( 'scriptnames' ).split( ' ' ), function ( i, sc ) {&lt;br /&gt;
	            sc = $.trim( sc.replace( /[^\w ]/g, '' ) );&lt;br /&gt;
	            if ( sc ) {&lt;br /&gt;
	                importScript( 'MediaWiki:Script/' + sc + '.js' );&lt;br /&gt;
	            }&lt;br /&gt;
	        } );&lt;br /&gt;
	    } );&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/**&lt;br /&gt;
	 * Чтобы ссылки на очистку кэша не требовали подтверждения (они должны быть помещены в тег с классом&lt;br /&gt;
	 * purgelink и именем страницы в параметре data-pagename, например как в шаблоне {{очистить кэш}})&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.purgelink a' ).click( function ( e ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {&lt;br /&gt;
			var pageName = $( this ).parent( '.purgelink' ).data( 'pagename' ) || mw.config.get( 'wgPageName' );&lt;br /&gt;
			new mw.Api().post( {&lt;br /&gt;
				action: 'purge',&lt;br /&gt;
				titles: pageName&lt;br /&gt;
			} ).then( function () {&lt;br /&gt;
				var url = mw.util.getUrl( pageName );&lt;br /&gt;
				if ( e.ctrlKey ) {&lt;br /&gt;
					if ( !window.open( url ) ) {&lt;br /&gt;
						location.assign( url );&lt;br /&gt;
		            }&lt;br /&gt;
		        } else {&lt;br /&gt;
					location.assign( url );&lt;br /&gt;
		        }&lt;br /&gt;
			}, function () {&lt;br /&gt;
				mw.notify( 'Не удалось очистить кэш.', { type: 'error' } );&lt;br /&gt;
			} );&lt;br /&gt;
			e.preventDefault();&lt;br /&gt;
		} );&lt;br /&gt;
	} );&lt;br /&gt;
}, $( '#footer' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * {{TOC hidden}}&lt;br /&gt;
 */&lt;br /&gt;
function TOChidden() {&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc' ).addClass( 'tochidden' );&lt;br /&gt;
	$( '.tochidden-wrapper .togglelink' ).text( mw.msg( 'showtoc' ) );&lt;br /&gt;
	$( '.tochidden-wrapper &amp;gt; #toc &amp;gt; ul' ).css( 'display', 'none' );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
runAsEarlyAsPossible( function () {&lt;br /&gt;
	if ( $( '.tochidden-wrapper' ).length ) {&lt;br /&gt;
		mw.loader.using( [ 'mediawiki.cookie' ], function () {&lt;br /&gt;
			if ( mw.cookie.get( 'hidetoc' ) === null ) {&lt;br /&gt;
				$.when( mw.loader.using( [ 'mediawiki.toc' ] ), $.ready ).then( TOChidden );&lt;br /&gt;
			}&lt;br /&gt;
		} );&lt;br /&gt;
	}&lt;br /&gt;
}, $( '#toc' ), mw.hook( 'wikipage.content' ).add );&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Код, выполняемый по событию wikipage.content (его обработчики выполняются раньше колбэков для $,&lt;br /&gt;
 * хотя в глубине это одно и то же событие, просто колбэк, инициирующий wikipage.content, становится&lt;br /&gt;
 * в очередь раньше). Так как wikipage.content инициируется после обновления страницы в результате&lt;br /&gt;
 * Ajax-запросов (например, гаджетом быстрого предпросмотра), не добавляйте сюда коды, которые&lt;br /&gt;
 * должны гарантированно выполниться один раз на странице.&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Отключение обтекания раздела примечаний, если в нём есть колонки&lt;br /&gt;
	 */&lt;br /&gt;
	$( '.references-small.columns' ).each( function () {&lt;br /&gt;
		$( this ).after( '&amp;lt;div class=&amp;quot;temporaryDiv&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;' ).next().prevUntil( 'h1, h2, h3, h4, h5, h6' )&lt;br /&gt;
			.last().prev().css( 'clear', 'both' );&lt;br /&gt;
	} );&lt;br /&gt;
&lt;br /&gt;
	// Этот элемент нужен на случай, если примечания — последний элемент (потребность в next()&lt;br /&gt;
	// возникает из-за невключительности prevUntil() jQuery)&lt;br /&gt;
	$( '.temporaryDiv' ).remove();&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Авторазбиение списков на колонки. Будет работать только для однострочных списков. 35em&lt;br /&gt;
	 * (из Mediawiki:Common.css) является предварительным числом, а фактическое будет посчитано исходя&lt;br /&gt;
	 * из ширины элементов. Должно использоваться только для UL внутри DIV. Пример использования —&lt;br /&gt;
	 * шаблон {{Wikidata/SisterCities}}.&lt;br /&gt;
	 */&lt;br /&gt;
	$(&amp;quot;div.autocolumns&amp;quot;).each(function(d, div) {&lt;br /&gt;
		var parentWidth = $(div).parent()[0].offsetWidth;&lt;br /&gt;
		if (!parentWidth) return;&lt;br /&gt;
&lt;br /&gt;
		var maxWidth = 0;&lt;br /&gt;
		var elements = 0;&lt;br /&gt;
		$(div).find(&amp;quot;ul&amp;gt;li&amp;quot;).each(function(l, li) {&lt;br /&gt;
			elements++;&lt;br /&gt;
			var jLi = $(li);&lt;br /&gt;
			if (jLi.children().length != jLi.contents().length)&lt;br /&gt;
				jLi.wrapInner(document.createElement(&amp;quot;span&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
			var liWidth = 0;&lt;br /&gt;
			jLi.children().each(function(c, child) {&lt;br /&gt;
				liWidth += child.offsetWidth;&lt;br /&gt;
			});&lt;br /&gt;
			if (liWidth &amp;gt; maxWidth)&lt;br /&gt;
				maxWidth = liWidth;&lt;br /&gt;
		});&lt;br /&gt;
		if ( maxWidth == 0 ) return;&lt;br /&gt;
		// UL/LI bullet width + padding&lt;br /&gt;
		maxWidth += 22.5 * 2;&lt;br /&gt;
&lt;br /&gt;
		var maxColumns = &amp;quot;&amp;quot; + Math.ceil( elements / 5 );&lt;br /&gt;
		$(div).css({&amp;quot;-moz-columns&amp;quot;: maxWidth + &amp;quot;px &amp;quot; + maxColumns, &amp;quot;columns&amp;quot; : maxWidth + &amp;quot;px &amp;quot; + maxColumns});&lt;br /&gt;
	});&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Кнопки описания правок для визуального редактора&lt;br /&gt;
 */&lt;br /&gt;
mw.hook( 've.activationComplete' ).add( function () {&lt;br /&gt;
	mw.loader.load( 'ext.gadget.summaryButtons' );&lt;br /&gt;
} );&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12307</id>
		<title>MediaWiki:Imagemap-Highlight.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Imagemap-Highlight.js&amp;diff=12307"/>
				<updated>2021-06-08T22:27:28Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: Новая страница: «$(function() {  	var 		//add this class to all elements created by the script. the reason is that we call the script again on 		//window resize, and use the class…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;$(function() {&lt;br /&gt;
&lt;br /&gt;
	var&lt;br /&gt;
		//add this class to all elements created by the script. the reason is that we call the script again on&lt;br /&gt;
		//window resize, and use the class to remove all the &amp;quot;artefacts&amp;quot; we created in the previous run.&lt;br /&gt;
		myClassName = 'imageMapHighlighterArtefacts',&lt;br /&gt;
		liHighlightClass = 'liHighlighting',&lt;br /&gt;
		specialAreaMark = 'area_mark',&lt;br /&gt;
		specialLiClassesMark = 'list_classes',&lt;br /&gt;
		specialAreaMarkFile = 'area_mark_file',&lt;br /&gt;
		// &amp;quot;2d context&amp;quot; attributes used for highlighting.&lt;br /&gt;
		areaHighLighting = {&lt;br /&gt;
			fillStyle: 'rgba(0,0,0,0.35)',&lt;br /&gt;
			strokeStyle: 'yellow',&lt;br /&gt;
			lineJoin: 'round',&lt;br /&gt;
			lineWidth: 2&lt;br /&gt;
		},&lt;br /&gt;
		//every imagemap that wants highlighting, should reside in a div of this 'class':&lt;br /&gt;
		hilightDivMarker = '.imageMapHighlighter',&lt;br /&gt;
		// specifically for wikis - redlinks tooltip adds this message&lt;br /&gt;
		ru = mw &amp;amp;&amp;amp; mw.config &amp;amp;&amp;amp; mw.config.get('wgUserLanguage') == 'ru',&lt;br /&gt;
		expandLegend = ru ? 'показать ссылки текстом' : 'show links as text',&lt;br /&gt;
		collapseLegend = ru ? 'скрыть ссылки текстом' : 'hide links as text',&lt;br /&gt;
		files = [];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function drawMarker(context, areas) { // this is where the magic is done.&lt;br /&gt;
&lt;br /&gt;
		function drawPoly(coords) {&lt;br /&gt;
			context.moveTo(coords.shift(), coords.shift());&lt;br /&gt;
			while (coords.length)&lt;br /&gt;
				context.lineTo(coords.shift(), coords.shift());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		for (var i in areas) {&lt;br /&gt;
			var coords = areas[i].coords.split(',');&lt;br /&gt;
			context.beginPath();&lt;br /&gt;
			switch (areas[i].shape) {&lt;br /&gt;
				case 'rect':&lt;br /&gt;
					drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[&lt;br /&gt;
						3], coords[2], coords[1]]);&lt;br /&gt;
					break;&lt;br /&gt;
				case 'circle':&lt;br /&gt;
					context.arc(coords[0], coords[1], coords[2], 0, Math.PI * 2);&lt;br /&gt;
					break; //x,y,r,startAngle,endAngle&lt;br /&gt;
				case 'poly':&lt;br /&gt;
					drawPoly(coords);&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			context.closePath();&lt;br /&gt;
			context.stroke();&lt;br /&gt;
			context.fill();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function mouseAction(e) {&lt;br /&gt;
		var $this = $(this),&lt;br /&gt;
			activate = e.type == 'mouseover',&lt;br /&gt;
			caption = $this.text(),&lt;br /&gt;
			ol = $this.parent(),&lt;br /&gt;
			context = ol.data('context'),&lt;br /&gt;
			special = ol.data(specialAreaMark),&lt;br /&gt;
			specialFile = ol.data(specialAreaMarkFile); //read JSON file addition&lt;br /&gt;
&lt;br /&gt;
		if (specialFile) {&lt;br /&gt;
			if (files[specialFile]) {&lt;br /&gt;
				$.extend(special, files[specialFile]);&lt;br /&gt;
				always(activate, caption, context, ol, special, $this);&lt;br /&gt;
			} else {&lt;br /&gt;
				$.get(mw.util.wikiScript(), {&lt;br /&gt;
						title: specialFile,&lt;br /&gt;
						action: 'raw'&lt;br /&gt;
					})&lt;br /&gt;
					.done(function(data) {&lt;br /&gt;
						files[specialFile] = JSON.parse(data);&lt;br /&gt;
						$.extend(special, files[specialFile]);&lt;br /&gt;
					})&lt;br /&gt;
					.always(function() {&lt;br /&gt;
						always(activate, caption, context, ol, special, $this);&lt;br /&gt;
					});&lt;br /&gt;
			}&lt;br /&gt;
		} else&lt;br /&gt;
			always(activate, caption, context, ol, special, $this);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function always(activate, caption, context, ol, special, $this) {&lt;br /&gt;
		$this.toggleClass(liHighlightClass, activate); // mark/unmark the list item. &lt;br /&gt;
&lt;br /&gt;
		context.clearRect(0, 0, context.canvas.width, context.canvas.height); // prepare for a new day.&lt;br /&gt;
&lt;br /&gt;
		ol.find('li')&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var $li = $(this);&lt;br /&gt;
				var licap = $li.text();&lt;br /&gt;
				var param;&lt;br /&gt;
				if (activate &amp;amp;&amp;amp; licap === caption) { // highlight!!!&lt;br /&gt;
					param = special &amp;amp;&amp;amp; (special.hover &amp;amp;&amp;amp; special.hover[licap]&lt;br /&gt;
						|| getblocks(special, licap)) || areaHighLighting;&lt;br /&gt;
				} else {&lt;br /&gt;
					param = special &amp;amp;&amp;amp; special.nover &amp;amp;&amp;amp; (special.nover[licap] || special.nover&lt;br /&gt;
						.default);&lt;br /&gt;
				}&lt;br /&gt;
				if (param) {&lt;br /&gt;
					$.extend(context, param);&lt;br /&gt;
					drawMarker(context, $li.data('areas'));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function getblocks(special, licap) {&lt;br /&gt;
		if (special.hoverblocks) {&lt;br /&gt;
			if (special.hoverblocks[licap])&lt;br /&gt;
				return special.hoverblocks[licap].value;&lt;br /&gt;
			for (var key in special.hoverblocks)&lt;br /&gt;
				if (special.hoverblocks[key] &amp;amp;&amp;amp; special.hoverblocks[key].list.indexOf(licap) &amp;gt;=0 )&lt;br /&gt;
					return special.hoverblocks[key].value;&lt;br /&gt;
		}&lt;br /&gt;
		if (special.hover)&lt;br /&gt;
			return special.hover.default;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	function handleOneMap() {&lt;br /&gt;
		var img = $(this),&lt;br /&gt;
			w = img.width(),&lt;br /&gt;
			h = img.height(),&lt;br /&gt;
			infoIcon = img.next(),&lt;br /&gt;
			parent = img.parent(),&lt;br /&gt;
			map = img.siblings('map:first'),&lt;br /&gt;
			dims = {&lt;br /&gt;
				position: 'absolute',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px',&lt;br /&gt;
				border: 0,&lt;br /&gt;
				top: 0,&lt;br /&gt;
				left: 0&lt;br /&gt;
			},&lt;br /&gt;
			specialHighlight = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMark),&lt;br /&gt;
			specialLiClasses = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialLiClassesMark),&lt;br /&gt;
			specialHover = img.closest(hilightDivMarker)&lt;br /&gt;
			.data(specialAreaMarkFile);&lt;br /&gt;
&lt;br /&gt;
		if (!('area', map)&lt;br /&gt;
			.length)&lt;br /&gt;
			return; //not an imagemap. inside &amp;quot;each&amp;quot; anonymous function, 'return' means &amp;quot;continue&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
		var jcanvas = $('&amp;lt;canvas&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims)&lt;br /&gt;
			.attr({&lt;br /&gt;
				width: w,&lt;br /&gt;
				height: h&lt;br /&gt;
			});&lt;br /&gt;
		var bgimg = $('&amp;lt;img&amp;gt;', {&lt;br /&gt;
				'class': myClassName,&lt;br /&gt;
				src: img.attr('src')&lt;br /&gt;
			})&lt;br /&gt;
			.css(dims); //completely inert image. this is what we see.&lt;br /&gt;
		var context = $.extend(jcanvas[0].getContext(&amp;quot;2d&amp;quot;), areaHighLighting);&lt;br /&gt;
&lt;br /&gt;
		// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,&lt;br /&gt;
		// the canvas above it, and the original image on top,&lt;br /&gt;
		// so canvas won't steal the mouse events.&lt;br /&gt;
		// pack them all TIGHTLY in a newly minted &amp;quot;relative&amp;quot; div, so when page chnage&lt;br /&gt;
		// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.&lt;br /&gt;
		var div = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.css({&lt;br /&gt;
				position: 'relative',&lt;br /&gt;
				width: w + 'px',&lt;br /&gt;
				height: h + 'px'&lt;br /&gt;
			});&lt;br /&gt;
		img.before(div); // put the div just above the image, and ...&lt;br /&gt;
		div.append(bgimg) // place the background image in the div&lt;br /&gt;
			.append(jcanvas) // and the canvas. both are &amp;quot;absolute&amp;quot;, so they don't occupy space in the div&lt;br /&gt;
			.append(img); // now yank the original image from the window and place it on the div.&lt;br /&gt;
		img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it. &lt;br /&gt;
		// the original, now transparent image is creating our mouse events&lt;br /&gt;
&lt;br /&gt;
		infoIcon.css({&lt;br /&gt;
			position: 'relative'&lt;br /&gt;
		}); // set position to info icon&lt;br /&gt;
		var ol = $('&amp;lt;ol&amp;gt;', {&lt;br /&gt;
				'class': myClassName&lt;br /&gt;
			})&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.data(specialAreaMark, specialHighlight)&lt;br /&gt;
			.data(specialAreaMarkFile, specialHover)&lt;br /&gt;
			.data('context', context);&lt;br /&gt;
		var oldiv = $('&amp;lt;div&amp;gt;')&lt;br /&gt;
			.html(ol)&lt;br /&gt;
			.css({&lt;br /&gt;
				clear: 'both',&lt;br /&gt;
				margin: 0,&lt;br /&gt;
				listStyle: 'none',&lt;br /&gt;
				maxWidth: w + 'px',&lt;br /&gt;
				position: 'relative'&lt;br /&gt;
			})&lt;br /&gt;
			.attr({&lt;br /&gt;
				'data-expandtext': expandLegend,&lt;br /&gt;
				'data-collapsetext': collapseLegend&lt;br /&gt;
			});&lt;br /&gt;
&lt;br /&gt;
		// ol below image parent, hr below ol. original caption pushed below hr.&lt;br /&gt;
		var $hr = $('&amp;lt;hr&amp;gt;', { 'class': myClassName }).css('clear', 'both');&lt;br /&gt;
		parent.after($hr).after(oldiv);&lt;br /&gt;
		$hr.clone().insertBefore($(oldiv));&lt;br /&gt;
		&lt;br /&gt;
		var lis = {}; //collapse areas with same caption to one list item&lt;br /&gt;
		var someli; // select arbitrary one&lt;br /&gt;
		$('area', map)&lt;br /&gt;
			.each(function() {&lt;br /&gt;
				var text = this.title;&lt;br /&gt;
				var li = lis[text]; // title already met? use the same li&lt;br /&gt;
				if (!li) { //no? create a new one.&lt;br /&gt;
					var href = this.href;&lt;br /&gt;
					lis[text] = li = $('&amp;lt;li&amp;gt;', {&lt;br /&gt;
							'class': myClassName&lt;br /&gt;
						})&lt;br /&gt;
						.append($('&amp;lt;a&amp;gt;', {&lt;br /&gt;
							href: href,&lt;br /&gt;
							text: text&lt;br /&gt;
						}))&lt;br /&gt;
						.on('mouseover mouseout', mouseAction)&lt;br /&gt;
						.data('areas', [])&lt;br /&gt;
						.addClass(specialLiClasses &amp;amp;&amp;amp; (specialLiClasses[text] ||&lt;br /&gt;
							specialLiClasses['default']))&lt;br /&gt;
						.appendTo(ol);&lt;br /&gt;
					if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses[text + ' super'])&lt;br /&gt;
						li.find('a')&lt;br /&gt;
							.addClass(specialLiClasses[text + ' super']);&lt;br /&gt;
				}&lt;br /&gt;
				li.data('areas')&lt;br /&gt;
					.push(this); //add the area to the li&lt;br /&gt;
				someli = li; // whichever - we just want one...&lt;br /&gt;
				$(this)&lt;br /&gt;
					.on('mouseover mouseout', function(e) {&lt;br /&gt;
						li.trigger(e);&lt;br /&gt;
					});&lt;br /&gt;
			});&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.order) {&lt;br /&gt;
			specialLiClasses.order.forEach(function(elem) {&lt;br /&gt;
				if (elem.dir === 'before') {&lt;br /&gt;
					$(elem.what).insertBefore($(elem.where));&lt;br /&gt;
				} else {&lt;br /&gt;
					$(elem.what).insertAfter($(elem.where));&lt;br /&gt;
				}&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (specialLiClasses &amp;amp;&amp;amp; specialLiClasses.todefault) {&lt;br /&gt;
			specialLiClasses.todefault.forEach(function(elem) {&lt;br /&gt;
				$(elem).addClass(specialLiClasses.default);&lt;br /&gt;
			});&lt;br /&gt;
		}&lt;br /&gt;
		if (someli) {&lt;br /&gt;
			someli.trigger('mouseout');&lt;br /&gt;
		}&lt;br /&gt;
		oldiv.addClass('mw-collapsed')&lt;br /&gt;
			.makeCollapsible();&lt;br /&gt;
		ol.attr('style', ol.attr('style')&lt;br /&gt;
			.replace('none', 'disc'));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	function init() {&lt;br /&gt;
		mw.util.addCSS('li.' + myClassName +&lt;br /&gt;
			'{white-space:nowrap; font-size:88.36%;}\n' + //css for li element&lt;br /&gt;
			'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.&lt;br /&gt;
			'.rtl li.' + myClassName + '{float: right; margin-left: 1.5em;}\n' +&lt;br /&gt;
			'.ltr li.' + myClassName + '{float: left; margin-right: 1.5em;}\n' +&lt;br /&gt;
			hilightDivMarker + ' .mw-collapsible-toggle {float: none}');&lt;br /&gt;
		$(hilightDivMarker + ' img')&lt;br /&gt;
			.each(handleOneMap);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	//has at least one &amp;quot;imagehighlight&amp;quot; div, and canvas-capable browser:&lt;br /&gt;
	if ( $(hilightDivMarker).length &amp;amp;&amp;amp; $('&amp;lt;canvas&amp;gt;')[0].getContext ) {&lt;br /&gt;
		mw.loader.using(['jquery.makeCollapsible', 'mediawiki.util'])&lt;br /&gt;
			.done(init);&lt;br /&gt;
	}&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	<entry>
		<id>https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12306</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.glasscannon.ru/index.php?title=MediaWiki:Common.js&amp;diff=12306"/>
				<updated>2021-06-08T22:26:34Z</updated>
		
		<summary type="html">&lt;p&gt;Ozzy: Новая страница: «/* Размещённый здесь код JavaScript будет загружаться пользователям при обращении к каждой ст…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Размещённый здесь код JavaScript будет загружаться пользователям при обращении к каждой странице */&lt;br /&gt;
mw.hook( 'wikipage.content' ).add( function () {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Imagemap Highlight&lt;br /&gt;
	 */&lt;br /&gt;
	// На странице есть как минимум один элемент .imageMapHighlighter, а браузер поддерживает &amp;lt;canvas&amp;gt;&lt;br /&gt;
	if ( $( '.imageMapHighlighter' ).length &amp;amp;&amp;amp; $( '&amp;lt;canvas&amp;gt;' )[ 0 ].getContext ) {&lt;br /&gt;
		importScript( 'MediaWiki:Imagemap-Highlight.js' );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
});&lt;/div&gt;</summary>
		<author><name>Ozzy</name></author>	</entry>

	</feed>