// ==UserScript==
// @name Iwara Custom Sort
// @version 1.0.5
// @description Automatically sort teaser images on /videos, /images, /subscriptions, /users, /playlist, and sidebars using customizable sort function. Can load and sort multiple pages at once.
// @match http://ecchi.iwara.tv/*
// @match https://ecchi.iwara.tv/*
// @match http://www.iwara.tv/*
// @match https://www.iwara.tv/*
// @name:ja Iwara Custom ソート
// @run-at document-end
// @grant GM.setValue
// @grant GM.getValue
// @grant GM.deleteValue
// @grant GM.listValues
// @license AGPL-3.0-or-later
// @description:ja /videos、/images、/subscriptions、/users、/playlistとサイドバーのサムネイルを自動的にソートします。ソート方法はカスタマイズすることができます、一度に複数のページを読み込んでソートすることができます。
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js#sha384-hmoGfyRv5Xg6BFqj6C1jQJ0y5HEpsJSc6VpsKkj0NgyiPevl9FNVNxEFpxKFNUaX
// @require https://unpkg.com/[email protected]/dist/loglevel.min.js#sha384-7gGuWfek8Ql6j/uNDFrS0BCe4x2ZihD4B68w9Eu580OVHJBV+bl3rZmEWC7q5/Gj
// @require https://unpkg.com/[email protected]/bundles/rxjs.umd.min.js#sha384-+VJt6dSQYKxS5YwAGX+zSPDqOcLAUx2tCjV8jSWnyJH8hWTgrHSZAt1106u1VmLn
// @require https://unpkg.com/[email protected]/mithril.min.js#sha384-vo9crXih40MlEv6JWHqS7SsPiFp+76csaWQFOF2UU0/xI58Jm/ZvK/1UtpaicJT9
// @namespace https://greasyfork.org/users/245195
// ==/UserScript==
/* jshint esversion: 6 */
(() => {
const __webpack_modules__ = {
923(module, exports, __webpack_require__) {
let __WEBPACK_AMD_DEFINE_RESULT__;
!(function (globals) {
let messages; let predicates; let functions; let assert; let not; let maybe; let collections; let hasOwnProperty; let toString; let keys; let slice; let isArray; let neginf; let posinf; let haveSymbols; let haveMaps; let haveSets;
function assigned(data) { return data != null; }
function number(data) { return typeof data === 'number' && data > neginf && data < posinf; }
function integer(data) { return typeof data === 'number' && data % 1 == 0; }
function greater(lhs, rhs) { return number(lhs) && lhs > rhs; }
function less(lhs, rhs) { return number(lhs) && lhs < rhs; }
function greaterOrEqual(lhs, rhs) { return number(lhs) && lhs >= rhs; }
function lessOrEqual(lhs, rhs) { return number(lhs) && lhs <= rhs; }
function string(data) { return typeof data === 'string'; }
function nonEmptyString(data) { return string(data) && data !== ''; }
function object(data) { return toString.call(data) === '[object Object]'; }
function some(data, predicate) {
for (const key in data) if (hasOwnProperty.call(data, key) && predicate(key, data[key])) return !0;
return !1;
}
function instanceStrict(data, prototype) { try { return data instanceof prototype; } catch (error) { return !1; } }
function like(data, archetype) {
let name;
for (name in archetype) {
if (hasOwnProperty.call(archetype, name)) {
if (!1 === hasOwnProperty.call(data, name) || typeof data[name] !== typeof archetype[name]) return !1;
if (object(data[name]) && !1 === like(data[name], archetype[name])) return !1;
}
}
return !0;
}
function arrayLike(data) { return assigned(data) && data.length >= 0; }
function iterable(data) { return haveSymbols ? assigned(data) && isFunction(data[Symbol.iterator]) : arrayLike(data); }
function contains(data, value) {
let iterator; let iteration;
if (!assigned(data)) return !1;
if (haveSets && instanceStrict(data, Set)) return data.has(value);
if (string(data)) return data.indexOf(value) !== -1;
if (haveSymbols && data[Symbol.iterator] && isFunction(data.values)) {
iterator = data.values();
do { if ((iteration = iterator.next()).value === value) return !0; } while (!iteration.done);
return !1;
}
return some(data, ((key, dataValue) => dataValue === value));
}
function containsKey(data, key) { return !!assigned(data) && (haveMaps && instanceStrict(data, Map) ? data.has(key) : !(iterable(data) && !number(+key)) && !!data[key]); }
function isFunction(data) { return typeof data === 'function'; }
function forEach(object, action) { for (const key in object)hasOwnProperty.call(object, key) && action(key, object[key]); }
function testArray(data, result) {
let i;
for (i = 0; i < data.length; i += 1) if (data[i] === result) return result;
return !result;
}
function testObject(data, result) {
let key; let value;
for (key in data) {
if (hasOwnProperty.call(data, key)) {
if (object(value = data[key]) && testObject(value, result) === result) return result;
if (value === result) return result;
}
}
return !result;
}
function mixin(target, source) { return forEach(source, ((key, value) => { target[key] = value; })), target; }
function assertModifier(predicate, defaultMessage) {
return function () {
const args = arguments; const argCount = predicate.l || predicate.length; const message = args[argCount]; const ErrorType = args[argCount + 1];
return assertImpl(predicate.apply(null, args), nonEmptyString(message) ? message : defaultMessage.replace('{a}', messageFormatter(args[0])).replace('{e}', messageFormatter(args[1])).replace('{e2}', messageFormatter(args[2])).replace('{t}', (() => {
const arg = args[1];
return arg && arg.name ? arg.name : arg;
})), isFunction(ErrorType) ? ErrorType : TypeError), args[0];
};
}
function messageFormatter(arg) { return function () { return string(arg) ? `"${arg.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"` : arg && !0 !== arg && arg.constructor && !instanceStrict(arg, RegExp) && typeof arg !== 'number' ? arg.constructor.name : arg; }; }
function assertImpl(value, message, ErrorType) {
if (value) return value;
throw new (ErrorType || Error)(message || 'assert failed');
}
function notModifier(predicate) {
const modifiedPredicate = function () { return notImpl(predicate.apply(null, arguments)); };
return modifiedPredicate.l = predicate.length, modifiedPredicate;
}
function notImpl(value) { return !value; }
function ofModifier(target, type, predicate) {
const modifiedPredicate = function () {
let collection; let args;
if (collection = arguments[0], target === 'maybe' && not.assigned(collection)) return !0;
if (!type(collection)) return !1;
collection = coerceCollection(type, collection), args = slice.call(arguments, 1);
try { collection.forEach(((item) => { if ((target !== 'maybe' || assigned(item)) && !predicate.apply(null, [item].concat(args))) throw 0; })); } catch (ignore) { return !1; }
return !0;
};
return modifiedPredicate.l = predicate.length, modifiedPredicate;
}
function coerceCollection(type, collection) {
switch (type) {
case arrayLike: return slice.call(collection);
case object: return keys(collection).map(((key) => collection[key]));
default: return collection;
}
}
function createModifiedPredicates(modifier, object) { return createModifiedFunctions([modifier, predicates, object, '']); }
function createModifiedFunctions(args) {
let modifier; let messageModifier; let object;
return modifier = args.shift(), messageModifier = args.pop(), object = args.pop(), forEach(args.pop(), ((key, fn) => {
let message = messages[key];
message && messageModifier && (message = message.replace('to', `${messageModifier}to`)), Object.defineProperty(object, key, {
configurable: !1,
enumerable: !0,
writable: !1,
value: modifier.apply(null, args.concat(fn, message)),
});
})), object;
}
function createModifiedModifier(modifier, modified, messageModifier) { return createModifiedFunctions([modifier, modified, {}, messageModifier]); }
function createOfModifiers(base, modifier) { collections.forEach(((key) => { base[key].of = createModifiedModifier(modifier, predicates[key].of); })); }
messages = {}, predicates = {}, [
{
n: 'equal',
f(lhs, rhs) { return lhs === rhs; },
s: 'equal {e}',
}, {
n: 'undefined',
f(data) { return void 0 === data; },
s: 'be undefined',
}, {
n: 'null',
f(data) { return data === null; },
s: 'be null',
}, {
n: 'assigned',
f: assigned,
s: 'be assigned',
}, {
n: 'primitive',
f(data) {
let type;
switch (data) { case null: case void 0: case !1: case !0: return !0; }
return (type = typeof data) === 'string' || type === 'number' || haveSymbols && type === 'symbol';
},
s: 'be primitive type',
}, {
n: 'contains',
f: contains,
s: 'contain {e}',
}, {
n: 'in',
f(value, data) { return contains(data, value); },
s: 'be in {e}',
}, {
n: 'containsKey',
f: containsKey,
s: 'contain key {e}',
}, {
n: 'keyIn',
f(key, data) { return containsKey(data, key); },
s: 'be key in {e}',
}, {
n: 'zero',
f(data) { return data === 0; },
s: 'be 0',
}, {
n: 'one',
f(data) { return data === 1; },
s: 'be 1',
}, {
n: 'infinity',
f(data) { return data === neginf || data === posinf; },
s: 'be infinity',
}, {
n: 'number',
f: number,
s: 'be Number',
}, {
n: 'integer',
f: integer,
s: 'be integer',
}, {
n: 'float',
f(data) { return number(data) && data % 1 != 0; },
s: 'be non-integer number',
}, {
n: 'even',
f(data) { return typeof data === 'number' && data % 2 == 0; },
s: 'be even number',
}, {
n: 'odd',
f(data) { return integer(data) && data % 2 != 0; },
s: 'be odd number',
}, {
n: 'greater',
f: greater,
s: 'be greater than {e}',
}, {
n: 'less',
f: less,
s: 'be less than {e}',
}, {
n: 'between',
f(data, x, y) {
if (x < y) return greater(data, x) && data < y;
return less(data, x) && data > y;
},
s: 'be between {e} and {e2}',
}, {
n: 'greaterOrEqual',
f: greaterOrEqual,
s: 'be greater than or equal to {e}',
}, {
n: 'lessOrEqual',
f: lessOrEqual,
s: 'be less than or equal to {e}',
}, {
n: 'inRange',
f(data, x, y) {
if (x < y) return greaterOrEqual(data, x) && data <= y;
return lessOrEqual(data, x) && data >= y;
},
s: 'be in the range {e} to {e2}',
}, {
n: 'positive',
f(data) { return greater(data, 0); },
s: 'be positive number',
}, {
n: 'negative',
f(data) { return less(data, 0); },
s: 'be negative number',
}, {
n: 'string',
f: string,
s: 'be String',
}, {
n: 'emptyString',
f(data) { return data === ''; },
s: 'be empty string',
}, {
n: 'nonEmptyString',
f: nonEmptyString,
s: 'be non-empty string',
}, {
n: 'match',
f(data, regex) { return string(data) && !!data.match(regex); },
s: 'match {e}',
}, {
n: 'boolean',
f(data) { return !1 === data || !0 === data; },
s: 'be Boolean',
}, {
n: 'object',
f: object,
s: 'be Object',
}, {
n: 'emptyObject',
f(data) { return object(data) && !some(data, (() => !0)); },
s: 'be empty object',
}, {
n: 'nonEmptyObject',
f(data) { return object(data) && some(data, (() => !0)); },
s: 'be non-empty object',
}, {
n: 'instanceStrict',
f: instanceStrict,
s: 'be instanceof {t}',
}, {
n: 'thenable',
f(data) { return assigned(data) && isFunction(data.then); },
s: 'be promise-like',
}, {
n: 'instance',
f(data, prototype) { try { return instanceStrict(data, prototype) || data.constructor.name === prototype.name || toString.call(data) === `[object ${prototype.name}]`; } catch (error) { return !1; } },
s: 'be {t}',
}, {
n: 'like',
f: like,
s: 'be like {e}',
}, {
n: 'array',
f(data) { return isArray(data); },
s: 'be Array',
}, {
n: 'emptyArray',
f(data) { return isArray(data) && data.length === 0; },
s: 'be empty array',
}, {
n: 'nonEmptyArray',
f(data) { return isArray(data) && data.length > 0; },
s: 'be non-empty array',
}, {
n: 'arrayLike',
f: arrayLike,
s: 'be array-like',
}, {
n: 'iterable',
f: iterable,
s: 'be iterable',
}, {
n: 'date',
f(data) { return instanceStrict(data, Date) && integer(data.getTime()); },
s: 'be valid Date',
}, {
n: 'function',
f: isFunction,
s: 'be Function',
}, {
n: 'hasLength',
f(data, length) { return assigned(data) && data.length === length; },
s: 'have length {e}',
}, {
n: 'throws',
f(data) {
if (!isFunction(data)) return !1;
try { data(); } catch (error) { return !0; }
return !1;
},
s: 'throw',
},
].map(((data) => {
const {
n,
} = data;
messages[n] = `assert failed: expected {a} to ${data.s}`, predicates[n] = data.f;
})), functions = {
map: function map(data, predicates) {
let result;
result = isArray(data) ? [] : {};
if (isFunction(predicates))forEach(data, ((key, value) => { result[key] = predicates(value); }));
else {
isArray(predicates) || assert.object(predicates);
const dataKeys = keys(data || {});
forEach(predicates, ((key, predicate) => { dataKeys.some(((dataKey, index) => dataKey === key && (dataKeys.splice(index, 1), !0))), isFunction(predicate) ? not.assigned(data) ? result[key] = !!predicate.m : result[key] = predicate(data[key]) : result[key] = map(data[key], predicate); }));
}
return result;
},
all(data) {
if (isArray(data)) return testArray(data, !1);
return assert.object(data), testObject(data, !1);
},
any(data) {
if (isArray(data)) return testArray(data, !0);
return assert.object(data), testObject(data, !0);
},
}, collections = ['array', 'arrayLike', 'iterable', 'object'], hasOwnProperty = Object.prototype.hasOwnProperty, toString = Object.prototype.toString, keys = Object.keys, slice = Array.prototype.slice, isArray = Array.isArray, neginf = Number.NEGATIVE_INFINITY, posinf = Number.POSITIVE_INFINITY, haveSymbols = typeof Symbol === 'function', haveMaps = typeof Map === 'function', haveSets = typeof Set === 'function', functions = mixin(functions, predicates), assert = createModifiedPredicates(assertModifier, assertImpl), not = createModifiedPredicates(notModifier, notImpl), maybe = createModifiedPredicates(((predicate) => {
const modifiedPredicate = function () { return !!not.assigned(arguments[0]) || predicate.apply(null, arguments); };
return modifiedPredicate.l = predicate.length, modifiedPredicate.m = !0, modifiedPredicate;
}), ((value) => {
if (!1 === assigned(value)) return !0;
return value;
})), assert.not = createModifiedModifier(assertModifier, not, 'not '), assert.maybe = createModifiedModifier(assertModifier, maybe, 'maybe '), collections.forEach(((key) => { predicates[key].of = createModifiedFunctions([ofModifier.bind(null, null), predicates[key], predicates, {}, '']); })), createOfModifiers(assert, assertModifier), createOfModifiers(not, notModifier), collections.forEach(((key) => { maybe[key].of = createModifiedFunctions([ofModifier.bind(null, 'maybe'), predicates[key], predicates, {}, '']), assert.maybe[key].of = createModifiedModifier(assertModifier, maybe[key].of), assert.not[key].of = createModifiedModifier(assertModifier, not[key].of); })), (function (functions) { void 0 === (__WEBPACK_AMD_DEFINE_RESULT__ = function () { return functions; }.call(exports, __webpack_require__, exports, module)) || (module.exports = __WEBPACK_AMD_DEFINE_RESULT__); }(mixin(functions, {
assert,
not,
maybe,
})));
}());
},
780: (module) => {
const createAbortError = () => {
const error = new Error('Delay aborted');
return error.name = 'AbortError', error;
};
const createDelay = ({
clearTimeout: defaultClear, setTimeout: set, willResolve,
}) => (ms, {
value, signal,
} = {}) => {
if (signal && signal.aborted) return Promise.reject(createAbortError());
let timeoutId; let settle; let rejectFn;
const clear = defaultClear || clearTimeout; const signalListener = () => { clear(timeoutId), rejectFn(createAbortError()); };
const delayPromise = new Promise((resolve, reject) => { settle = () => { signal && signal.removeEventListener('abort', signalListener), willResolve ? resolve(value) : reject(value); }, rejectFn = reject, timeoutId = (set || setTimeout)(settle, ms); });
return signal && signal.addEventListener('abort', signalListener, {
once: !0,
}), delayPromise.clear = () => { clear(timeoutId), timeoutId = null, settle(); }, delayPromise;
};
const
delay = createDelay({
willResolve: !0,
});
delay.reject = createDelay({
willResolve: !1,
}), delay.range = (minimum, maximum, options) => delay(((minimum, maximum) => Math.floor(Math.random() * (maximum - minimum + 1) + minimum))(minimum, maximum), options), delay.createWithTimers = ({
clearTimeout, setTimeout,
}) => {
const delay = createDelay({
clearTimeout,
setTimeout,
willResolve: !0,
});
return delay.reject = createDelay({
clearTimeout,
setTimeout,
willResolve: !1,
}), delay;
}, module.exports = delay, module.exports.default = delay;
},
};
const
__webpack_module_cache__ = {};
function __webpack_require__(moduleId) {
if (__webpack_module_cache__[moduleId]) return __webpack_module_cache__[moduleId].exports;
const module = __webpack_module_cache__[moduleId] = {
exports: {},
};
return __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__), module.exports;
}
__webpack_require__.n = (module) => {
const getter = module && module.__esModule ? () => module.default : () => module;
return __webpack_require__.d(getter, {
a: getter,
}), getter;
}, __webpack_require__.d = (exports, definition) => {
for (const key in definition) {
__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key) && Object.defineProperty(exports, key, {
enumerable: !0,
get: definition[key],
});
}
}, __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop), (() => {
const external_log_namespaceObject = log;
const delay = __webpack_require__(780);
const delay_default = __webpack_require__.n(delay);
const check_types = __webpack_require__(923);
const getTeaserContainers = (node) => Array.from(node.querySelectorAll('.views-responsive-grid, .node-playlist .field-name-field-videos')).filter((grid) => grid.querySelector('.node-teaser, .node-sidebar_teaser, .node-wide_teaser')); const src_assert = (value, message) => { (0, check_types.assert)(value, message); };
const tapNonNull = (x) => (src_assert(x), x); const
external_m_namespaceObject = m;
const external_m_default = __webpack_require__.n(external_m_namespaceObject);
const external_rxjs_namespaceObject = rxjs; const external_rxjs_operators_namespaceObject = rxjs.operators; const
external_Swal_namespaceObject = Swal;
const external_Swal_default = __webpack_require__.n(external_Swal_namespaceObject);
const classAttr = (classNames) => classNames.map((x) => `.${x}`).join(''); const forwardTo = (observer) => (value) => { observer.next(value); };
const partial = (f, ...headArgs) => (...b) => f(...headArgs, ...b); const tapIs = (constructor, x) => (src_assert(x instanceof constructor), x); const getPageParam = (URL_) => ((URL_, name) => {
const param = URL_.searchParams.get(name);
return param ? Number.parseInt(param, 10) : 0;
})(URL_, 'page');
const reloadImage = (image) => {
const {
src,
} = image;
image.src = '', image.src = src;
};
const
removeEmbeddedPage = (page) => { page.src = '', page.remove(); };
const isNone = function (fa) { return fa._tag === 'None'; };
const none = {
_tag: 'None',
};
const some = function (a) {
return {
_tag: 'Some',
value: a,
};
};
function fromNullable(a) { return a == null ? none : some(a); }
const getOrElse = function (onNone) { return function (ma) { return isNone(ma) ? onNone() : ma.value; }; };
const map_ = function (fa, f) { return isNone(fa) ? none : some(f(fa.value)); };
const map = function (f) { return function (fa) { return map_(fa, f); }; };
const getTeaserValue = (info, condition) => {
const sortParamPairs = [['index', info.initialIndex], ['views', info.viewCount], ['likes', info.likeCount], ['ratio', Math.min(info.likeCount / Math.max(1, info.viewCount), 1)], ['image', info.imageFactor], ['gallery', info.galleryFactor], ['private', info.privateFactor]];
return new Function(...sortParamPairs.map(([name]) => name), `return (${condition})`)(...sortParamPairs.map((pair) => pair[1]));
};
const changeAnchorPageParam = (anchor, value) => ((anchor, key, value) => {
const newURL = new URL(anchor.href, window.location.href);
newURL.searchParams.set(key, value), anchor.href = newURL.href;
})(anchor, 'page', value.toString());
const adjustPageAnchors = (container, pageCount) => {
const currentPage = getPageParam(new URL(window.location.href));
if (currentPage > 0) {
const previousPageAnchor = container.querySelector('.pager-previous a');
changeAnchorPageParam(tapNonNull(previousPageAnchor), Math.max(0, currentPage - pageCount));
}
const nextPage = currentPage + pageCount;
{ const nextPageAnchor = container.querySelector('.pager-next a'); const lastPageAnchor = container.querySelector('.pager-last a');
lastPageAnchor && getPageParam(new URL(lastPageAnchor.href, window.location.href)) < nextPage ? (tapNonNull(nextPageAnchor).remove(), lastPageAnchor.remove()) : nextPageAnchor && changeAnchorPageParam(nextPageAnchor, nextPage); }
const currentPageAnchors = Array.from(container.querySelectorAll('.pager-item a')).filter(({
href,
}) => {
const page = getPageParam(new URL(href, window.location.href));
return page >= currentPage && page < nextPage;
});
if (currentPageAnchors.length > 0) {
((currentPageItems) => {
const parentItem = document.createElement('li');
currentPageItems[0].before(parentItem), currentPageItems[0].style.marginLeft = '0';
const groupList = document.createElement('ul');
groupList.style.display = 'inline', groupList.style.backgroundColor = 'hsla(0, 0%, 75%, 50%)', currentPageItems.forEach(({
classList,
}) => classList.replace('pager-item', 'pager-current')), groupList.append(...currentPageItems), parentItem.append(groupList);
})([...Array.from(container.querySelectorAll('.pager-current')), ...currentPageAnchors.map((anchor) => tapNonNull(anchor.parentElement))]);
}
};
const getBrokenImages = () => getTeaserContainers(document).flatMap((container) => Array.from(container.querySelectorAll('img'))).filter((img) => img.complete && img.naturalWidth === 0); const createPreloadPage = (createContainer, parentPageId, url) => {
const container = createContainer();
return container.src = url.toString(), container.style.display = 'hidden', container.classList.add(parentPageId), container;
};
const createPreloadUrl = (startURL, page) => {
const preloadURL = new URL('', startURL);
return preloadURL.searchParams.set('page', page.toString()), preloadURL;
};
const preloadUrlStream = (startURL, pageCount$) => pageCount$.pipe((0, external_rxjs_operators_namespaceObject.scan)((max, value) => Math.max(max, value), 1), (0, external_rxjs_operators_namespaceObject.scan)(([, last], current) => [last, current], [1, 1]), (0, external_rxjs_operators_namespaceObject.mergeMap)(([last, current]) => (0, external_rxjs_namespaceObject.from)([...Array(current - last).keys()].map((i) => getPageParam(startURL) + last + i))), (0, external_rxjs_operators_namespaceObject.map)(partial(createPreloadUrl, startURL))); const trySortTeasers = (condition$) => condition$.pipe((0, external_rxjs_operators_namespaceObject.map)((condition) => [getTeaserContainers(document), condition]), (0, external_rxjs_operators_namespaceObject.mergeMap)((x) => (0, external_rxjs_namespaceObject.of)(x).pipe((0, external_rxjs_operators_namespaceObject.tap)(([containers, condition]) => containers.forEach((container) => ((container, condition) => {
const teaserDivs = Array.from(container.querySelectorAll('.node-teaser, .node-sidebar_teaser, .node-wide_teaser')); const sortedTeaserCount = container.dataset.sortedTeaserCount ? parseInt(container.dataset.sortedTeaserCount, 10) : 0;
teaserDivs.filter(({
dataset,
}) => !dataset.initialIndex).forEach(({
dataset,
}, index) => { dataset.initialIndex = (sortedTeaserCount + index).toString(); }), container.dataset.sortedTeaserCount = teaserDivs.length.toString();
const getNearbyNumber = (element) => {
return str = tapIs(Text, element.nextSibling).wholeText.replace(/,/g, ''), Number.parseFloat(str) * (str.includes('k') ? 1e3 : 1);
};
const nearbyNumberOrZero = (element) => (function (a, ab, bc, cd, de, ef, fg, gh, hi, ij, jk, kl, lm, mn, no, op, pq, qr, rs, st) {
switch (arguments.length) {
case 1: return a;
case 2: return ab(a);
case 3: return bc(ab(a));
case 4: return cd(bc(ab(a)));
case 5: return de(cd(bc(ab(a))));
case 6: return ef(de(cd(bc(ab(a)))));
case 7: return fg(ef(de(cd(bc(ab(a))))));
case 8: return gh(fg(ef(de(cd(bc(ab(a)))))));
case 9: return hi(gh(fg(ef(de(cd(bc(ab(a))))))));
case 10: return ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))));
case 11: return jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))));
case 12: return kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))));
case 13: return lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))));
case 14: return mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))));
case 15: return no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))));
case 16: return op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))));
case 17: return pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))));
case 18: return qr(pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))));
case 19: return rs(qr(pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))))));
case 20: return st(rs(qr(pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))))));
}
}(fromNullable(element), map(getNearbyNumber), getOrElse(() => 0)));
const divValuePairs = teaserDivs.map((div) => ({
initialIndex: parseInt(tapNonNull(div.dataset.initialIndex), 10),
viewCount: nearbyNumberOrZero(div.querySelector('.glyphicon-eye-open')),
likeCount: nearbyNumberOrZero(div.querySelector('.glyphicon-heart')),
imageFactor: div.querySelector('.field-type-image') ? 1 : 0,
galleryFactor: div.querySelector('.glyphicon-th-large') ? 1 : 0,
privateFactor: div.querySelector('.private-video') ? 1 : 0,
})).map((info, index) => [teaserDivs[index], getTeaserValue(info, condition)]);
divValuePairs.sort((itemA, itemB) => itemB[1] - itemA[1]), teaserDivs.forEach((div) => div.after(document.createElement('span'))), teaserDivs.map((div) => tapNonNull(div.nextSibling)).forEach((anchor, index) => anchor.replaceWith(divValuePairs[index][0]));
})(container, condition))), (0, external_rxjs_operators_namespaceObject.catchError)((error) => (external_Swal_default().fire('Sorting Failed', `An error accured while sorting: ${error.toString()}`), external_log_namespaceObject.error(error), external_rxjs_namespaceObject.EMPTY)))), (0, external_rxjs_operators_namespaceObject.map)(([containers]) => ({
containersCount: containers.length,
})));
const initParent = async () => {
if (getTeaserContainers(document).length === 0) return;
const defaultCondition = '(Math.asinh(ratio * 15) / 15 / (private * 1.8 + 1) + Math.log(likes) / 230) / (image + 8)'; const initialCondition = tapNonNull(await GM.getValue('sortValue', defaultCondition)); const pageCount = tapNonNull(await GM.getValue('pageCount', 1)); const haveMorePages = document.querySelector('.pager') && !document.querySelector('#comments');
haveMorePages && document.querySelectorAll('.pager').forEach((pager) => adjustPageAnchors(pager, pageCount));
const sortComponent = new class {
constructor(initialCondition, defaultCondition, initialPageCount) {
this.conditionInputInput$ = new external_rxjs_namespaceObject.Subject(), this.conditionInputChange$ = new external_rxjs_namespaceObject.Subject(), this.conditionInputKeydown$ = new external_rxjs_namespaceObject.Subject(), this.sortButtonClick$ = new external_rxjs_namespaceObject.Subject(), this.resetDefaultButtonClick$ = new external_rxjs_namespaceObject.Subject(), this.pageCountInputInput$ = new external_rxjs_namespaceObject.Subject(), this.pageCountInputChange$ = new external_rxjs_namespaceObject.Subject(), this.conditionInputEnterDown$ = this.conditionInputKeydown$.pipe((0, external_rxjs_operators_namespaceObject.filter)((e) => e.key === 'Enter')), this.conditionChange$ = (0, external_rxjs_namespaceObject.merge)(this.conditionInputChange$, this.conditionInputEnterDown$, this.sortButtonClick$), this.sort$ = (0, external_rxjs_namespaceObject.merge)(this.sortButtonClick$, this.conditionInputEnterDown$, this.resetDefaultButtonClick$).pipe((0, external_rxjs_operators_namespaceObject.map)(() => this.state.condition)), this.condition$ = this.conditionChange$.pipe((0, external_rxjs_operators_namespaceObject.startWith)(void 0), (0, external_rxjs_operators_namespaceObject.map)(() => this.state.condition)), this.pageCount$ = this.pageCountInputChange$.pipe((0, external_rxjs_operators_namespaceObject.startWith)(void 0), (0, external_rxjs_operators_namespaceObject.map)(() => this.state.pageCount)), this.defaultCondition = defaultCondition, this.state = {
condition: initialCondition,
pageCount: initialPageCount,
loadedPageCount: 0,
}, (0, external_rxjs_namespaceObject.merge)(this.conditionInputInput$.pipe((0, external_rxjs_operators_namespaceObject.pluck)('currentTarget'), (0, external_rxjs_operators_namespaceObject.map)(partial(tapIs, HTMLInputElement)), (0, external_rxjs_operators_namespaceObject.pluck)('value'), (0, external_rxjs_operators_namespaceObject.tap)((value) => { this.state.condition = value; })), (0, external_rxjs_namespaceObject.merge)(this.conditionChange$, this.resetDefaultButtonClick$.pipe((0, external_rxjs_operators_namespaceObject.tap)(() => { this.state.condition = defaultCondition; }))).pipe((0, external_rxjs_operators_namespaceObject.map)(() => this.state.condition), (0, external_rxjs_operators_namespaceObject.tap)((value) => GM.setValue('sortValue', value))), this.pageCountInputInput$.pipe((0, external_rxjs_operators_namespaceObject.pluck)('currentTarget'), (0, external_rxjs_operators_namespaceObject.map)(partial(tapIs, HTMLInputElement)), (0, external_rxjs_operators_namespaceObject.map)((input) => Number.parseInt(input.value, 10)), (0, external_rxjs_operators_namespaceObject.tap)((pageCount) => { this.state.pageCount = pageCount; })), this.pageCountInputChange$.pipe((0, external_rxjs_operators_namespaceObject.tap)(() => GM.setValue('pageCount', this.state.pageCount)))).subscribe();
}
view() {
const commonStyle = {
margin: '5px 2px',
};
const uiChildren = {
conditionInput: external_m_default()(`input${classAttr(['form-control', 'input-sm'])}`, {
maxLength: 1e4,
size: 65,
value: this.state.condition,
style: commonStyle,
list: 'iwara-custom-sort-conditions',
oninput: forwardTo(this.conditionInputInput$),
onchange: forwardTo(this.conditionInputChange$),
onkeydown: forwardTo(this.conditionInputKeydown$),
}),
conditionDatalist: external_m_default()('datalist', {
id: 'iwara-custom-sort-conditions',
}, [
[['Default Condition', this.defaultCondition], ['Original Order', '-index'], ['Reversed Original Order', 'index']].map(([name, value]) => external_m_default()('option', {
value,
}, name)),
]),
resetDefaultButton: external_m_default()(`button${classAttr(['btn', 'btn-sm', 'btn-info'])}`, {
style: commonStyle,
onclick: forwardTo(this.resetDefaultButtonClick$),
}, 'Default'),
sortButton: external_m_default()(`button${classAttr(['btn', 'btn-sm', 'btn-primary'])}`, {
style: commonStyle,
onclick: forwardTo(this.sortButtonClick$),
}, 'Sort'),
label1: external_m_default()(`label${classAttr(['text-primary'])}`, {
style: commonStyle,
}, 'load'),
pageCountInput: external_m_default()(`input${classAttr(['form-control', 'input-sm'])}`, {
type: 'number',
value: this.state.pageCount,
min: 1,
max: 500,
step: 1,
style: {
width: '7rem',
...commonStyle,
},
oninput: forwardTo(this.pageCountInputInput$),
onchange: forwardTo(this.pageCountInputChange$),
}),
label2: external_m_default()(`label${classAttr(['text-primary'])}`, {
style: commonStyle,
}, 'pages. '),
statusLabel: external_m_default()(`label${classAttr(['text-primary'])}`, {
style: commonStyle,
}, this.state.loadedPageCount < this.state.pageCount ? `${this.state.loadedPageCount} of ${this.state.pageCount} pages done` : 'All pages done'),
};
return external_m_default()(`div${classAttr(['form-inline', 'container'])}`, {
style: {
display: 'inline-block',
},
}, Object.values(uiChildren));
}
addLoadedPageCount() { this.state.loadedPageCount += 1, external_m_default().redraw(); }
}(initialCondition, defaultCondition, pageCount);
const preloadUrl$ = (haveMorePages ? sortComponent.pageCount$ : (0, external_rxjs_namespaceObject.of)(1)).pipe(partial(preloadUrlStream, new URL(window.location.href))); const channel = new BroadcastChannel('iwara custom sort'); const parentPageId = `t-${performance.now().toString()}`; const pageLoad$ = (0, external_rxjs_namespaceObject.fromEvent)(channel, 'message').pipe((0, external_rxjs_operators_namespaceObject.pluck)('data'), (0, external_rxjs_operators_namespaceObject.filter)((data) => data.parentPageId === parentPageId)); const teaserPageLoad$ = pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.filter)((message) => message.hasTeasers)); const pageFromUrl = new Map(); const unsortedTeasers$ = teaserPageLoad$.pipe((0, external_rxjs_operators_namespaceObject.mapTo)(void 0), (0, external_rxjs_operators_namespaceObject.startWith)(void 0)); const allStreams = {
logPageLoad$: pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
reloadBrokenImages$: unsortedTeasers$.pipe((0, external_rxjs_operators_namespaceObject.mergeMap)(() => (0, external_rxjs_namespaceObject.timer)(0, 8e3).pipe((0, external_rxjs_operators_namespaceObject.take)(2))), (0, external_rxjs_operators_namespaceObject.auditTime)(6e3), (0, external_rxjs_operators_namespaceObject.map)(getBrokenImages), (0, external_rxjs_operators_namespaceObject.tap)((images) => images.forEach(reloadImage)), (0, external_rxjs_operators_namespaceObject.map)((images) => `Reload ${images.length} broken image(s)`), (0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
sortTeasers$: (0, external_rxjs_namespaceObject.merge)(unsortedTeasers$.pipe((0, external_rxjs_operators_namespaceObject.withLatestFrom)(sortComponent.condition$), (0, external_rxjs_operators_namespaceObject.map)(([, condition]) => condition), (0, external_rxjs_operators_namespaceObject.tap)(() => sortComponent.addLoadedPageCount())), sortComponent.sort$).pipe(trySortTeasers, (0, external_rxjs_operators_namespaceObject.map)((result) => `${result.containersCount} containers sorted`), (0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
removeLoadedPage$: pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.map)(({
url,
}) => ({
url,
container: pageFromUrl.get(url),
})), (0, external_rxjs_operators_namespaceObject.tap)(({
url,
}) => pageFromUrl.delete(url)), (0, external_rxjs_operators_namespaceObject.pluck)('container'), (0, external_rxjs_operators_namespaceObject.map)(tapNonNull), (0, external_rxjs_operators_namespaceObject.tap)(removeEmbeddedPage)),
addHiddenPreload$: (0, external_rxjs_namespaceObject.zip)(preloadUrl$, teaserPageLoad$.pipe((0, external_rxjs_operators_namespaceObject.scan)((countDown) => (countDown > 0 ? countDown - 1 : countDown), 5), (0, external_rxjs_operators_namespaceObject.map)((countDown) => (countDown > 0 ? 2 : 1)), (0, external_rxjs_operators_namespaceObject.startWith)(2), (0, external_rxjs_operators_namespaceObject.mergeMap)((createPageCount) => (0, external_rxjs_namespaceObject.of)(...Array.from({
length: createPageCount,
}, () => {}))))).pipe((0, external_rxjs_operators_namespaceObject.map)(([url]) => [
url, () => {
return userAgent = window.navigator.userAgent, document.createElement(userAgent.indexOf('Firefox') > -1 ? 'embed' : 'iframe');
},
]), (0, external_rxjs_operators_namespaceObject.map)(([url, createContainer]) => [url.toString(), createPreloadPage(createContainer, parentPageId, url)]), (0, external_rxjs_operators_namespaceObject.tap)((entry) => pageFromUrl.set(...entry)), (0, external_rxjs_operators_namespaceObject.tap)(([, container]) => document.body.append(container))),
};
(0, external_rxjs_namespaceObject.merge)(...Object.values(allStreams)).subscribe();
const sortComponentContainer = document.createElement('div');
tapNonNull(document.querySelector('#user-links')).after(sortComponentContainer), external_m_default().mount(sortComponentContainer, sortComponent), external_log_namespaceObject.debug(await GM.listValues());
};
const
initialize = async () => {
const isParent = window === window.parent;
external_log_namespaceObject.debug(`${isParent ? 'Parent' : 'Child'}: ${window.location.href}`), await (isParent ? initParent() : (async () => {
const teaserContainers = getTeaserContainers(document);
const channel = new BroadcastChannel('iwara custom sort');
const hasTeasers = teaserContainers.length > 0;
const message = {
url: window.location.href,
parentPageId: Array.from(tapNonNull(window.frameElement).classList).filter((x) => x.startsWith('t-'))[0],
hasTeasers,
};
hasTeasers && (await delay_default()(500), ((children, parents) => {
for (let i = 0, j = 0; i < parents.length && j < children.length; i += 1) {
const parent = parents[i]; const
child = children[j];
parent.className === child.className && (child.className = '', parent.append(child), j += 1);
}
})(teaserContainers, getTeaserContainers(window.parent.document))), channel.postMessage(message);
})());
};
(async () => {
external_log_namespaceObject.setLevel('debug');
try { await initialize(); } catch (error) { external_log_namespaceObject.error(error); }
})();
})();
})();