<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.you107657.duckdns.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadgets%2FcraftingScripts%2Fmain.js</id>
	<title>MediaWiki:Gadgets/craftingScripts/main.js - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.you107657.duckdns.org/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AGadgets%2FcraftingScripts%2Fmain.js"/>
	<link rel="alternate" type="text/html" href="https://wiki.you107657.duckdns.org/index.php?title=MediaWiki:Gadgets/craftingScripts/main.js&amp;action=history"/>
	<updated>2026-09-27T01:52:57Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.you107657.duckdns.org/index.php?title=MediaWiki:Gadgets/craftingScripts/main.js&amp;diff=12528&amp;oldid=prev</id>
		<title>imported&gt;Merge: merge.py</title>
		<link rel="alternate" type="text/html" href="https://wiki.you107657.duckdns.org/index.php?title=MediaWiki:Gadgets/craftingScripts/main.js&amp;diff=12528&amp;oldid=prev"/>
		<updated>2026-09-25T10:55:52Z</updated>

		<summary type="html">&lt;p&gt;merge.py&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 10:55, 25 September 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>imported&gt;Merge</name></author>
	</entry>
	<entry>
		<id>https://wiki.you107657.duckdns.org/index.php?title=MediaWiki:Gadgets/craftingScripts/main.js&amp;diff=4711&amp;oldid=prev</id>
		<title>imported&gt;Merge: merge.py</title>
		<link rel="alternate" type="text/html" href="https://wiki.you107657.duckdns.org/index.php?title=MediaWiki:Gadgets/craftingScripts/main.js&amp;diff=4711&amp;oldid=prev"/>
		<updated>2026-09-25T10:55:52Z</updated>

		<summary type="html">&lt;p&gt;merge.py&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;/**&lt;br /&gt;
 * Element animator&lt;br /&gt;
 *&lt;br /&gt;
 * Cycles through a set of elements (or &amp;quot;frames&amp;quot;) on a 2 second timer per frame&lt;br /&gt;
 * Add the &amp;quot;animated&amp;quot; class to the frame containing the elements to animate.&lt;br /&gt;
 * Optionally, add the &amp;quot;animated-active&amp;quot; class to the frame to display first.&lt;br /&gt;
 * Optionally, add the &amp;quot;animated-subframe&amp;quot; class to a frame, and the&lt;br /&gt;
 * &amp;quot;animated-active&amp;quot; class to a subframe within, in order to designate a set of&lt;br /&gt;
 * subframes which will only be cycled every time the parent frame is displayed.&lt;br /&gt;
 * Animations with the &amp;quot;animated-paused&amp;quot; class will be skipped each interval.&lt;br /&gt;
 */&lt;br /&gt;
( function() {&lt;br /&gt;
    var $content = $( &amp;#039;#mw-content-text&amp;#039; );&lt;br /&gt;
&lt;br /&gt;
    // Helper function: advance the &amp;quot;animated-active&amp;quot; class to the next sibling&lt;br /&gt;
    var advanceFrame = function( parentElem, parentSelector ) {&lt;br /&gt;
        var curFrame = parentElem.querySelector( parentSelector + &amp;#039; &amp;gt; .animated-active&amp;#039; );&lt;br /&gt;
        $( curFrame ).removeClass( &amp;#039;animated-active&amp;#039; );&lt;br /&gt;
        var $nextFrame = $( curFrame &amp;amp;&amp;amp; curFrame.nextElementSibling || parentElem.firstElementChild );&lt;br /&gt;
        return $nextFrame.addClass( &amp;#039;animated-active&amp;#039; );&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    // Check if the tab is hidden (stop animating if user is in another tab)&lt;br /&gt;
    var hidden;&lt;br /&gt;
    if ( typeof document.hidden !== &amp;#039;undefined&amp;#039; ) {&lt;br /&gt;
        hidden = &amp;#039;hidden&amp;#039;;&lt;br /&gt;
    } else if ( typeof document.msHidden !== &amp;#039;undefined&amp;#039; ) {&lt;br /&gt;
        hidden = &amp;#039;msHidden&amp;#039;;&lt;br /&gt;
    } else if ( typeof document.webkitHidden !== &amp;#039;undefined&amp;#039; ) {&lt;br /&gt;
        hidden = &amp;#039;webkitHidden&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Every 2 seconds, cycle through each .animated element&lt;br /&gt;
    setInterval( function() {&lt;br /&gt;
        // If the document is hidden, skip animating&lt;br /&gt;
        if ( hidden &amp;amp;&amp;amp; document[hidden] ) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // For each .animated container...&lt;br /&gt;
        $content.find( &amp;#039;.animated&amp;#039; ).each( function() {&lt;br /&gt;
            // Skip if .animated-paused is present&lt;br /&gt;
            if ( $( this ).hasClass( &amp;#039;animated-paused&amp;#039; ) ) {&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            // Advance the main frame&lt;br /&gt;
            var $nextFrame = advanceFrame( this, &amp;#039;.animated&amp;#039; );&lt;br /&gt;
&lt;br /&gt;
            // If the new active frame is itself a .animated-subframe, advance that too&lt;br /&gt;
            if ( $nextFrame.hasClass( &amp;#039;animated-subframe&amp;#039; ) ) {&lt;br /&gt;
                advanceFrame( $nextFrame[0], &amp;#039;.animated-subframe&amp;#039; );&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
    }, 2000 );&lt;br /&gt;
}() );&lt;br /&gt;
/**&lt;br /&gt;
 * Set minimum height for animations to prevent moving the page if the frames differ in height&lt;br /&gt;
 */&lt;br /&gt;
( function() {&lt;br /&gt;
    // Mark them visible for a moment to measure&lt;br /&gt;
    var $animated = $( &amp;#039;.animated&amp;#039; ).addClass( &amp;#039;animated-visible&amp;#039; );&lt;br /&gt;
&lt;br /&gt;
    var animateds = [];&lt;br /&gt;
    $animated.each( function() {&lt;br /&gt;
        animateds.push( {&lt;br /&gt;
            $: $( this ).find( &amp;#039;&amp;gt; .animated-subframe&amp;#039; ).addBack()&lt;br /&gt;
                .find( &amp;#039;&amp;gt; *:not(.animated-subframe)&amp;#039; ),&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    // Find max height among sibling frames&lt;br /&gt;
    $.each( animateds, function() {&lt;br /&gt;
        var minHeight = 0, differentHeights;&lt;br /&gt;
        this.$.each( function() {&lt;br /&gt;
            var height = this.offsetHeight;&lt;br /&gt;
            differentHeights = differentHeights || ( minHeight &amp;amp;&amp;amp; height !== minHeight );&lt;br /&gt;
            minHeight = Math.max( height, minHeight );&lt;br /&gt;
        } );&lt;br /&gt;
        if ( differentHeights ) {&lt;br /&gt;
            this.height = minHeight;&lt;br /&gt;
        }&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    // Apply min-height, then hide them again&lt;br /&gt;
    $animated.each( function( i ) {&lt;br /&gt;
        $( this ).css( &amp;#039;min-height&amp;#039;, animateds[i].height );&lt;br /&gt;
    } ).removeClass( &amp;#039;animated-visible&amp;#039; );&lt;br /&gt;
&lt;br /&gt;
    // Optional lazy-loading for all frames once the animation is in view&lt;br /&gt;
    var animatedObserver = new IntersectionObserver( function( entries ) {&lt;br /&gt;
        entries.forEach( function( entry ) {&lt;br /&gt;
            if ( entry.isIntersecting &amp;amp;&amp;amp; !entry.target.classList.contains( &amp;#039;animated-lazyloaded&amp;#039; ) ) {&lt;br /&gt;
                $( entry.target ).find( &amp;#039;img&amp;#039; ).attr( &amp;#039;loading&amp;#039;, &amp;#039;eager&amp;#039; );&lt;br /&gt;
                entry.target.classList.add( &amp;#039;animated-lazyloaded&amp;#039; );&lt;br /&gt;
                animatedObserver.unobserve( entry.target );&lt;br /&gt;
            }&lt;br /&gt;
        } );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    $animated.each( function() {&lt;br /&gt;
        animatedObserver.observe( this );&lt;br /&gt;
    } );&lt;br /&gt;
}() );&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function() {&lt;br /&gt;
    var hideTemplate = document.querySelector(&amp;#039;.hide-content-template&amp;#039;);&lt;br /&gt;
    if (hideTemplate) {&lt;br /&gt;
        // Hide all other content&lt;br /&gt;
        var bodyChildren = document.body.children;&lt;br /&gt;
        for (var i = 0; i &amp;lt; bodyChildren.length; i++) {&lt;br /&gt;
            var child = bodyChildren[i];&lt;br /&gt;
            if (!child.classList.contains(&amp;#039;hide-content-template&amp;#039;)) {&lt;br /&gt;
                child.style.display = &amp;#039;none&amp;#039;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Optionally, style the template container&lt;br /&gt;
        hideTemplate.style.position = &amp;#039;relative&amp;#039;;&lt;br /&gt;
        hideTemplate.style.zIndex = &amp;#039;1000&amp;#039;;&lt;br /&gt;
        hideTemplate.style.background = &amp;#039;white&amp;#039;;&lt;br /&gt;
        hideTemplate.style.padding = &amp;#039;20px&amp;#039;;&lt;br /&gt;
        hideTemplate.style.border = &amp;#039;2px solid #f00&amp;#039;;&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Creates Minecraft-style tooltips&lt;br /&gt;
 *&lt;br /&gt;
 * Replaces normal tooltips. Supports Minecraft [[formatting codes]] (except k), and a description with line breaks (/).&lt;br /&gt;
 */&lt;br /&gt;
( function() {&lt;br /&gt;
	var escapeChars = { &amp;#039;\\&amp;amp;&amp;#039;: &amp;#039;&amp;amp;#38;&amp;#039;, &amp;#039;&amp;lt;&amp;#039;: &amp;#039;&amp;amp;#60;&amp;#039;, &amp;#039;&amp;gt;&amp;#039;: &amp;#039;&amp;amp;#62;&amp;#039; };&lt;br /&gt;
	var escape = function( text ) {&lt;br /&gt;
		// &amp;quot;\&amp;quot; must be escaped first&lt;br /&gt;
		return text.replace( /\\\\/g, &amp;#039;&amp;amp;#92;&amp;#039; )&lt;br /&gt;
			.replace( /\\&amp;amp;|[&amp;lt;&amp;gt;]/g, function( char ) { return escapeChars[char]; } );&lt;br /&gt;
	};&lt;br /&gt;
	var $tooltip = $();&lt;br /&gt;
	var $win = $( window ), winWidth, winHeight, width, height;&lt;br /&gt;
	&lt;br /&gt;
	$( &amp;#039;#mw-content-text&amp;#039; ).on( {&lt;br /&gt;
		&amp;#039;mouseenter.minetip&amp;#039;: function( e ) {&lt;br /&gt;
			$tooltip.remove();&lt;br /&gt;
			&lt;br /&gt;
			var $elem = $( this ), title = $elem.attr( &amp;#039;data-minetip-title&amp;#039; );&lt;br /&gt;
			if ( title === undefined ) {&lt;br /&gt;
				title = $elem.attr( &amp;#039;title&amp;#039; );&lt;br /&gt;
				if ( title !== undefined ) {&lt;br /&gt;
					title = $.trim( title.replace( /&amp;amp;/g, &amp;#039;\\&amp;amp;&amp;#039; ) );&lt;br /&gt;
					$elem.attr( &amp;#039;data-minetip-title&amp;#039;, title );&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// No title or title only contains formatting codes&lt;br /&gt;
			if ( title === undefined || title !== &amp;#039;&amp;#039; &amp;amp;&amp;amp; title.replace( /&amp;amp;([0-9a-jl-qs-vyzr]|#[0-9a-fA-F]{6}|\$[0-9a-fA-F]{3})/g, &amp;#039;&amp;#039; ) === &amp;#039;&amp;#039; ) {&lt;br /&gt;
				// Find deepest child title&lt;br /&gt;
				var childElem = $elem[0], childTitle;&lt;br /&gt;
				do {&lt;br /&gt;
					if ( childElem.hasAttribute( &amp;#039;title&amp;#039; ) ) {&lt;br /&gt;
						childTitle = childElem.title;&lt;br /&gt;
					}&lt;br /&gt;
					childElem = childElem.firstChild;&lt;br /&gt;
				} while( childElem &amp;amp;&amp;amp; childElem.nodeType === 1 );&lt;br /&gt;
				if ( childTitle === undefined ) {&lt;br /&gt;
					return;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				// Append child title as title may contain formatting codes&lt;br /&gt;
				if ( !title ) {&lt;br /&gt;
					title = &amp;#039;&amp;#039;;&lt;br /&gt;
				}&lt;br /&gt;
				title += $.trim( childTitle.replace( /&amp;amp;/g, &amp;#039;\\&amp;amp;&amp;#039; ) );&lt;br /&gt;
				&lt;br /&gt;
				// Set the retrieved title as data for future use&lt;br /&gt;
				$elem.attr( &amp;#039;data-minetip-title&amp;#039;, title );&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			if ( !$elem.data( &amp;#039;minetip-ready&amp;#039; ) ) {&lt;br /&gt;
				// Remove title attributes so the native tooltip doesn&amp;#039;t get in the way&lt;br /&gt;
				$elem.find( &amp;#039;[title]&amp;#039; ).addBack().removeAttr( &amp;#039;title&amp;#039; );&lt;br /&gt;
				$elem.data( &amp;#039;minetip-ready&amp;#039;, true );&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			if ( title === &amp;#039;&amp;#039; ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			var content = &amp;#039;&amp;lt;span class=&amp;quot;minetip-title&amp;quot;&amp;gt;&amp;#039; + escape( title ) + &amp;#039;&amp;amp;r&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
			&lt;br /&gt;
			var description = $.trim( $elem.attr( &amp;#039;data-minetip-text&amp;#039; ) );&lt;br /&gt;
			if ( description ) {&lt;br /&gt;
				// Apply normal escaping plus &amp;quot;/&amp;quot;&lt;br /&gt;
				description = escape( description ).replace( /\\\//g, &amp;#039;&amp;amp;#47;&amp;#039; );&lt;br /&gt;
				content += &amp;#039;&amp;lt;span class=&amp;quot;minetip-description&amp;quot;&amp;gt;&amp;#039; + description.replace( /\//g, &amp;#039;&amp;lt;br&amp;gt;&amp;#039; ) + &amp;#039;&amp;amp;r&amp;lt;/span&amp;gt;&amp;#039;;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// Add classes for Minecraft formatting codes&lt;br /&gt;
			while ( content.search( /&amp;amp;(?:[0-9a-jl-qs-vyz]|#[0-9a-fA-F]{6}|\$[0-9a-fA-F]{3})/ ) &amp;gt; -1 ) {&lt;br /&gt;
				content = content.replace( /&amp;amp;([0-9a-jl-qs-vyz])(.*?)(&amp;amp;r|$)/g, &amp;#039;&amp;lt;span class=&amp;quot;format-$1&amp;quot;&amp;gt;$2&amp;lt;/span&amp;gt;&amp;amp;r&amp;#039; );&lt;br /&gt;
				content = content.replace( /&amp;amp;(?:#([0-9a-fA-F]{6})|\$([0-9a-fA-F]{3}))(.*?)(&amp;amp;r|$)/g, &amp;#039;&amp;lt;span class=&amp;quot;format-custom&amp;quot; style=&amp;quot;color: #$1$2;&amp;quot;&amp;gt;$3&amp;lt;/span&amp;gt;&amp;amp;r&amp;#039; );&lt;br /&gt;
			}&lt;br /&gt;
			// Remove reset formatting&lt;br /&gt;
			content = content.replace( /&amp;amp;r/g, &amp;#039;&amp;#039; );&lt;br /&gt;
			&lt;br /&gt;
			$tooltip = $( &amp;#039;&amp;lt;div id=&amp;quot;minetip-tooltip&amp;quot;&amp;gt;&amp;#039; );&lt;br /&gt;
			$tooltip.html( content ).appendTo( &amp;#039;body&amp;#039; );&lt;br /&gt;
			&lt;br /&gt;
			// Cache current window and tooltip size&lt;br /&gt;
			winWidth = $win.width();&lt;br /&gt;
			winHeight = $win.height();&lt;br /&gt;
			width = $tooltip.outerWidth( true );&lt;br /&gt;
			height = $tooltip.outerHeight( true );&lt;br /&gt;
			&lt;br /&gt;
			// Trigger a mouse movement to position the tooltip&lt;br /&gt;
			$elem.trigger( &amp;#039;mousemove&amp;#039;, e );&lt;br /&gt;
		},&lt;br /&gt;
		&amp;#039;mousemove.minetip&amp;#039;: function( e, trigger ) {&lt;br /&gt;
			if ( !$tooltip.length ) {&lt;br /&gt;
				$( this ).trigger( &amp;#039;mouseenter&amp;#039; );&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// Get event data from remote trigger&lt;br /&gt;
			e = trigger || e;&lt;br /&gt;
			&lt;br /&gt;
			// Get mouse position and add default offsets&lt;br /&gt;
			var top = e.clientY - 34;&lt;br /&gt;
			var left = e.clientX + 14;&lt;br /&gt;
			&lt;br /&gt;
			// If going off the right of the screen, go to the left of the cursor&lt;br /&gt;
			if ( left + width &amp;gt; winWidth ) {&lt;br /&gt;
				left -= width + 36;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// If now going off to the left of the screen, resort to going above the cursor&lt;br /&gt;
			if ( left &amp;lt; 0 ) {&lt;br /&gt;
				left = 0;&lt;br /&gt;
				top -= height - 22;&lt;br /&gt;
				&lt;br /&gt;
				// Go below the cursor if too high&lt;br /&gt;
				if ( top &amp;lt; 0 ) {&lt;br /&gt;
					top += height + 47;&lt;br /&gt;
				}&lt;br /&gt;
			// Don&amp;#039;t go off the top of the screen&lt;br /&gt;
			} else if ( top &amp;lt; 0 ) {&lt;br /&gt;
				top = 0;&lt;br /&gt;
			// Don&amp;#039;t go off the bottom of the screen&lt;br /&gt;
			} else if ( top + height &amp;gt; winHeight ) {&lt;br /&gt;
				top = winHeight - height;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			// Apply the positions&lt;br /&gt;
			$tooltip.css( { top: top, left: left } );&lt;br /&gt;
		},&lt;br /&gt;
		&amp;#039;mouseleave.minetip&amp;#039;: function() {&lt;br /&gt;
			if ( !$tooltip.length ) {&lt;br /&gt;
				return;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			$tooltip.remove();&lt;br /&gt;
			$tooltip = $();&lt;br /&gt;
		}&lt;br /&gt;
	}, &amp;#039;.minetip, .invslot-item&amp;#039; );&lt;br /&gt;
}() );&lt;/div&gt;</summary>
		<author><name>imported&gt;Merge</name></author>
	</entry>
</feed>