// ==UserScript== // @name Move Training Pets To Top // @namespace https://hollymcfarland.com // @version 1.0 // @description At the three battledome training areas in Neopia, move pets currently in a course or waiting for input to the top of the list // @author monorail // @match https://www.neopets.com/pirates/academy.phtml?type=status // @match https://www.neopets.com/island/training.phtml?type=status // @match https://www.neopets.com/island/fight_training.phtml?type=status // @icon https://www.google.com/s2/favicons?sz=64&domain=neopets.com // @grant none // ==/UserScript== /* Note that this has not been tested in the Secret Ninja Training School, simply because I don't have any pets even close to level 250. But the DOM looks the same at the Swashbuckling Academy and the Mystery Island Training School so, I assume it'll work there too? If someone let me know I'd appreciate it haha */ (function() { 'use strict'; function getPairs(iter) { /* Given an iterable (something that can be converted to an array, anyway), return an array of two-length arrays containing each element once, in the same order e.g. getPairs([1, 2, 3, 4, 5, 6]) => [[1, 2], [3, 4], [5, 6]] */ // The function getting mapped here behaves differently depending on the parity // of the index. // Odd index => Empty array // Even index => Array of array(!!) of the element at that index and the one after it // Then because it's getting _flat_mapped, the whole thing is flattened by one level. // Empty arrays disappear and the arrays of arrays become just two-length arrays // https://stackoverflow.com/a/57851980/2114129 return [...iter].flatMap((_, i, a) => i % 2 ? [] : [a.slice(i, i + 2)]); } // Table that shows each pet const statusTable = document.querySelector(".content > p:nth-child(6) > table:nth-child(1) > tbody:nth-child(1)"); for (let [header, pet] of getPairs(statusTable.children)) { // Each "pet" here refers to a