Iwara Custom Sort

Automatically sort teaser images on /videos, /images, /subscriptions, /users, /playlist, and sidebars using customizable sort function. Can load and sort multiple pages at once.

当前为 2020-09-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Iwara Custom Sort
  3. // @version 1.0.6
  4. // @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.
  5. // @match http://ecchi.iwara.tv/*
  6. // @match https://ecchi.iwara.tv/*
  7. // @match http://www.iwara.tv/*
  8. // @match https://www.iwara.tv/*
  9. // @name:ja Iwara Custom ソート
  10. // @run-at document-end
  11. // @grant GM.setValue
  12. // @grant GM.getValue
  13. // @grant GM.deleteValue
  14. // @grant GM.listValues
  15. // @license AGPL-3.0-or-later
  16. // @description:ja /videos、/images、/subscriptions、/users、/playlistとサイドバーのサムネイルを自動的にソートします。ソート方法はカスタマイズすることができます、一度に複数のページを読み込んでソートすることができます。
  17. // @require https://cdn.jsdelivr.net/npm/sweetalert2@10.3.5/dist/sweetalert2.all.min.js#sha384-hmoGfyRv5Xg6BFqj6C1jQJ0y5HEpsJSc6VpsKkj0NgyiPevl9FNVNxEFpxKFNUaX
  18. // @require https://unpkg.com/loglevel@1.7.0/dist/loglevel.min.js#sha384-7gGuWfek8Ql6j/uNDFrS0BCe4x2ZihD4B68w9Eu580OVHJBV+bl3rZmEWC7q5/Gj
  19. // @require https://unpkg.com/rxjs@6.6.3/bundles/rxjs.umd.min.js#sha384-+VJt6dSQYKxS5YwAGX+zSPDqOcLAUx2tCjV8jSWnyJH8hWTgrHSZAt1106u1VmLn
  20. // @require https://unpkg.com/mithril@2.0.4/mithril.min.js#sha384-vo9crXih40MlEv6JWHqS7SsPiFp+76csaWQFOF2UU0/xI58Jm/ZvK/1UtpaicJT9
  21. // @namespace https://gf.qytechs.cn/users/245195
  22. // ==/UserScript==
  23.  
  24. /* jshint esversion: 6 */
  25.  
  26. (() => {
  27. const __webpack_modules__ = {
  28. 923(module, exports, __webpack_require__) {
  29. let __WEBPACK_AMD_DEFINE_RESULT__;
  30. !(function (globals) {
  31. 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;
  32. function assigned(data) { return data != null; }
  33.  
  34. function number(data) { return typeof data === 'number' && data > neginf && data < posinf; }
  35.  
  36. function integer(data) { return typeof data === 'number' && data % 1 == 0; }
  37.  
  38. function greater(lhs, rhs) { return number(lhs) && lhs > rhs; }
  39.  
  40. function less(lhs, rhs) { return number(lhs) && lhs < rhs; }
  41.  
  42. function greaterOrEqual(lhs, rhs) { return number(lhs) && lhs >= rhs; }
  43.  
  44. function lessOrEqual(lhs, rhs) { return number(lhs) && lhs <= rhs; }
  45.  
  46. function string(data) { return typeof data === 'string'; }
  47.  
  48. function nonEmptyString(data) { return string(data) && data !== ''; }
  49.  
  50. function object(data) { return toString.call(data) === '[object Object]'; }
  51.  
  52. function some(data, predicate) {
  53. for (const key in data) if (hasOwnProperty.call(data, key) && predicate(key, data[key])) return !0;
  54. return !1;
  55. }
  56.  
  57. function instanceStrict(data, prototype) { try { return data instanceof prototype; } catch (error) { return !1; } }
  58.  
  59. function like(data, archetype) {
  60. let name;
  61. for (name in archetype) {
  62. if (hasOwnProperty.call(archetype, name)) {
  63. if (!1 === hasOwnProperty.call(data, name) || typeof data[name] !== typeof archetype[name]) return !1;
  64. if (object(data[name]) && !1 === like(data[name], archetype[name])) return !1;
  65. }
  66. }
  67.  
  68. return !0;
  69. }
  70.  
  71. function arrayLike(data) { return assigned(data) && data.length >= 0; }
  72.  
  73. function iterable(data) { return haveSymbols ? assigned(data) && isFunction(data[Symbol.iterator]) : arrayLike(data); }
  74.  
  75. function contains(data, value) {
  76. let iterator; let iteration;
  77. if (!assigned(data)) return !1;
  78. if (haveSets && instanceStrict(data, Set)) return data.has(value);
  79. if (string(data)) return data.indexOf(value) !== -1;
  80. if (haveSymbols && data[Symbol.iterator] && isFunction(data.values)) {
  81. iterator = data.values();
  82. do { if ((iteration = iterator.next()).value === value) return !0; } while (!iteration.done);
  83.  
  84. return !1;
  85. }
  86.  
  87. return some(data, ((key, dataValue) => dataValue === value));
  88. }
  89.  
  90. function containsKey(data, key) { return !!assigned(data) && (haveMaps && instanceStrict(data, Map) ? data.has(key) : !(iterable(data) && !number(+key)) && !!data[key]); }
  91.  
  92. function isFunction(data) { return typeof data === 'function'; }
  93.  
  94. function forEach(object, action) { for (const key in object)hasOwnProperty.call(object, key) && action(key, object[key]); }
  95.  
  96. function testArray(data, result) {
  97. let i;
  98. for (i = 0; i < data.length; i += 1) if (data[i] === result) return result;
  99. return !result;
  100. }
  101.  
  102. function testObject(data, result) {
  103. let key; let value;
  104. for (key in data) {
  105. if (hasOwnProperty.call(data, key)) {
  106. if (object(value = data[key]) && testObject(value, result) === result) return result;
  107. if (value === result) return result;
  108. }
  109. }
  110.  
  111. return !result;
  112. }
  113.  
  114. function mixin(target, source) { return forEach(source, ((key, value) => { target[key] = value; })), target; }
  115.  
  116. function assertModifier(predicate, defaultMessage) {
  117. return function () {
  118. const args = arguments; const argCount = predicate.l || predicate.length; const message = args[argCount]; const ErrorType = args[argCount + 1];
  119. 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}', (() => {
  120. const arg = args[1];
  121. return arg && arg.name ? arg.name : arg;
  122. })), isFunction(ErrorType) ? ErrorType : TypeError), args[0];
  123. };
  124. }
  125.  
  126. 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; }; }
  127.  
  128. function assertImpl(value, message, ErrorType) {
  129. if (value) return value;
  130. throw new (ErrorType || Error)(message || 'assert failed');
  131. }
  132.  
  133. function notModifier(predicate) {
  134. const modifiedPredicate = function () { return notImpl(predicate.apply(null, arguments)); };
  135.  
  136. return modifiedPredicate.l = predicate.length, modifiedPredicate;
  137. }
  138.  
  139. function notImpl(value) { return !value; }
  140.  
  141. function ofModifier(target, type, predicate) {
  142. const modifiedPredicate = function () {
  143. let collection; let args;
  144. if (collection = arguments[0], target === 'maybe' && not.assigned(collection)) return !0;
  145. if (!type(collection)) return !1;
  146. collection = coerceCollection(type, collection), args = slice.call(arguments, 1);
  147. try { collection.forEach(((item) => { if ((target !== 'maybe' || assigned(item)) && !predicate.apply(null, [item].concat(args))) throw 0; })); } catch (ignore) { return !1; }
  148.  
  149. return !0;
  150. };
  151.  
  152. return modifiedPredicate.l = predicate.length, modifiedPredicate;
  153. }
  154.  
  155. function coerceCollection(type, collection) {
  156. switch (type) {
  157. case arrayLike: return slice.call(collection);
  158. case object: return keys(collection).map(((key) => collection[key]));
  159. default: return collection;
  160. }
  161. }
  162.  
  163. function createModifiedPredicates(modifier, object) { return createModifiedFunctions([modifier, predicates, object, '']); }
  164.  
  165. function createModifiedFunctions(args) {
  166. let modifier; let messageModifier; let object;
  167. return modifier = args.shift(), messageModifier = args.pop(), object = args.pop(), forEach(args.pop(), ((key, fn) => {
  168. let message = messages[key];
  169. message && messageModifier && (message = message.replace('to', `${messageModifier}to`)), Object.defineProperty(object, key, {
  170. configurable: !1,
  171. enumerable: !0,
  172. writable: !1,
  173. value: modifier.apply(null, args.concat(fn, message)),
  174. });
  175. })), object;
  176. }
  177.  
  178. function createModifiedModifier(modifier, modified, messageModifier) { return createModifiedFunctions([modifier, modified, {}, messageModifier]); }
  179.  
  180. function createOfModifiers(base, modifier) { collections.forEach(((key) => { base[key].of = createModifiedModifier(modifier, predicates[key].of); })); }
  181.  
  182. messages = {}, predicates = {}, [
  183. {
  184. n: 'equal',
  185. f(lhs, rhs) { return lhs === rhs; },
  186. s: 'equal {e}',
  187. }, {
  188. n: 'undefined',
  189. f(data) { return void 0 === data; },
  190. s: 'be undefined',
  191. }, {
  192. n: 'null',
  193. f(data) { return data === null; },
  194. s: 'be null',
  195. }, {
  196. n: 'assigned',
  197. f: assigned,
  198. s: 'be assigned',
  199. }, {
  200. n: 'primitive',
  201. f(data) {
  202. let type;
  203. switch (data) { case null: case void 0: case !1: case !0: return !0; }
  204.  
  205. return (type = typeof data) === 'string' || type === 'number' || haveSymbols && type === 'symbol';
  206. },
  207. s: 'be primitive type',
  208. }, {
  209. n: 'contains',
  210. f: contains,
  211. s: 'contain {e}',
  212. }, {
  213. n: 'in',
  214. f(value, data) { return contains(data, value); },
  215. s: 'be in {e}',
  216. }, {
  217. n: 'containsKey',
  218. f: containsKey,
  219. s: 'contain key {e}',
  220. }, {
  221. n: 'keyIn',
  222. f(key, data) { return containsKey(data, key); },
  223. s: 'be key in {e}',
  224. }, {
  225. n: 'zero',
  226. f(data) { return data === 0; },
  227. s: 'be 0',
  228. }, {
  229. n: 'one',
  230. f(data) { return data === 1; },
  231. s: 'be 1',
  232. }, {
  233. n: 'infinity',
  234. f(data) { return data === neginf || data === posinf; },
  235. s: 'be infinity',
  236. }, {
  237. n: 'number',
  238. f: number,
  239. s: 'be Number',
  240. }, {
  241. n: 'integer',
  242. f: integer,
  243. s: 'be integer',
  244. }, {
  245. n: 'float',
  246. f(data) { return number(data) && data % 1 != 0; },
  247. s: 'be non-integer number',
  248. }, {
  249. n: 'even',
  250. f(data) { return typeof data === 'number' && data % 2 == 0; },
  251. s: 'be even number',
  252. }, {
  253. n: 'odd',
  254. f(data) { return integer(data) && data % 2 != 0; },
  255. s: 'be odd number',
  256. }, {
  257. n: 'greater',
  258. f: greater,
  259. s: 'be greater than {e}',
  260. }, {
  261. n: 'less',
  262. f: less,
  263. s: 'be less than {e}',
  264. }, {
  265. n: 'between',
  266. f(data, x, y) {
  267. if (x < y) return greater(data, x) && data < y;
  268. return less(data, x) && data > y;
  269. },
  270. s: 'be between {e} and {e2}',
  271. }, {
  272. n: 'greaterOrEqual',
  273. f: greaterOrEqual,
  274. s: 'be greater than or equal to {e}',
  275. }, {
  276. n: 'lessOrEqual',
  277. f: lessOrEqual,
  278. s: 'be less than or equal to {e}',
  279. }, {
  280. n: 'inRange',
  281. f(data, x, y) {
  282. if (x < y) return greaterOrEqual(data, x) && data <= y;
  283. return lessOrEqual(data, x) && data >= y;
  284. },
  285. s: 'be in the range {e} to {e2}',
  286. }, {
  287. n: 'positive',
  288. f(data) { return greater(data, 0); },
  289. s: 'be positive number',
  290. }, {
  291. n: 'negative',
  292. f(data) { return less(data, 0); },
  293. s: 'be negative number',
  294. }, {
  295. n: 'string',
  296. f: string,
  297. s: 'be String',
  298. }, {
  299. n: 'emptyString',
  300. f(data) { return data === ''; },
  301. s: 'be empty string',
  302. }, {
  303. n: 'nonEmptyString',
  304. f: nonEmptyString,
  305. s: 'be non-empty string',
  306. }, {
  307. n: 'match',
  308. f(data, regex) { return string(data) && !!data.match(regex); },
  309. s: 'match {e}',
  310. }, {
  311. n: 'boolean',
  312. f(data) { return !1 === data || !0 === data; },
  313. s: 'be Boolean',
  314. }, {
  315. n: 'object',
  316. f: object,
  317. s: 'be Object',
  318. }, {
  319. n: 'emptyObject',
  320. f(data) { return object(data) && !some(data, (() => !0)); },
  321. s: 'be empty object',
  322. }, {
  323. n: 'nonEmptyObject',
  324. f(data) { return object(data) && some(data, (() => !0)); },
  325. s: 'be non-empty object',
  326. }, {
  327. n: 'instanceStrict',
  328. f: instanceStrict,
  329. s: 'be instanceof {t}',
  330. }, {
  331. n: 'thenable',
  332. f(data) { return assigned(data) && isFunction(data.then); },
  333. s: 'be promise-like',
  334. }, {
  335. n: 'instance',
  336. f(data, prototype) { try { return instanceStrict(data, prototype) || data.constructor.name === prototype.name || toString.call(data) === `[object ${prototype.name}]`; } catch (error) { return !1; } },
  337. s: 'be {t}',
  338. }, {
  339. n: 'like',
  340. f: like,
  341. s: 'be like {e}',
  342. }, {
  343. n: 'array',
  344. f(data) { return isArray(data); },
  345. s: 'be Array',
  346. }, {
  347. n: 'emptyArray',
  348. f(data) { return isArray(data) && data.length === 0; },
  349. s: 'be empty array',
  350. }, {
  351. n: 'nonEmptyArray',
  352. f(data) { return isArray(data) && data.length > 0; },
  353. s: 'be non-empty array',
  354. }, {
  355. n: 'arrayLike',
  356. f: arrayLike,
  357. s: 'be array-like',
  358. }, {
  359. n: 'iterable',
  360. f: iterable,
  361. s: 'be iterable',
  362. }, {
  363. n: 'date',
  364. f(data) { return instanceStrict(data, Date) && integer(data.getTime()); },
  365. s: 'be valid Date',
  366. }, {
  367. n: 'function',
  368. f: isFunction,
  369. s: 'be Function',
  370. }, {
  371. n: 'hasLength',
  372. f(data, length) { return assigned(data) && data.length === length; },
  373. s: 'have length {e}',
  374. }, {
  375. n: 'throws',
  376. f(data) {
  377. if (!isFunction(data)) return !1;
  378. try { data(); } catch (error) { return !0; }
  379.  
  380. return !1;
  381. },
  382. s: 'throw',
  383. },
  384. ].map(((data) => {
  385. const {
  386. n,
  387. } = data;
  388.  
  389. messages[n] = `assert failed: expected {a} to ${data.s}`, predicates[n] = data.f;
  390. })), functions = {
  391. map: function map(data, predicates) {
  392. let result;
  393. result = isArray(data) ? [] : {};
  394. if (isFunction(predicates))forEach(data, ((key, value) => { result[key] = predicates(value); }));
  395. else {
  396. isArray(predicates) || assert.object(predicates);
  397. const dataKeys = keys(data || {});
  398. 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); }));
  399. }
  400.  
  401. return result;
  402. },
  403. all(data) {
  404. if (isArray(data)) return testArray(data, !1);
  405. return assert.object(data), testObject(data, !1);
  406. },
  407. any(data) {
  408. if (isArray(data)) return testArray(data, !0);
  409. return assert.object(data), testObject(data, !0);
  410. },
  411. }, 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) => {
  412. const modifiedPredicate = function () { return !!not.assigned(arguments[0]) || predicate.apply(null, arguments); };
  413.  
  414. return modifiedPredicate.l = predicate.length, modifiedPredicate.m = !0, modifiedPredicate;
  415. }), ((value) => {
  416. if (!1 === assigned(value)) return !0;
  417. return value;
  418. })), 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, {
  419. assert,
  420. not,
  421. maybe,
  422. })));
  423. }());
  424. },
  425. 780: (module) => {
  426. const createAbortError = () => {
  427. const error = new Error('Delay aborted');
  428. return error.name = 'AbortError', error;
  429. };
  430.  
  431. const createDelay = ({
  432. clearTimeout: defaultClear, setTimeout: set, willResolve,
  433. }) => (ms, {
  434. value, signal,
  435. } = {}) => {
  436. if (signal && signal.aborted) return Promise.reject(createAbortError());
  437. let timeoutId; let settle; let rejectFn;
  438. const clear = defaultClear || clearTimeout; const signalListener = () => { clear(timeoutId), rejectFn(createAbortError()); };
  439.  
  440. const delayPromise = new Promise((resolve, reject) => { settle = () => { signal && signal.removeEventListener('abort', signalListener), willResolve ? resolve(value) : reject(value); }, rejectFn = reject, timeoutId = (set || setTimeout)(settle, ms); });
  441. return signal && signal.addEventListener('abort', signalListener, {
  442. once: !0,
  443. }), delayPromise.clear = () => { clear(timeoutId), timeoutId = null, settle(); }, delayPromise;
  444. };
  445.  
  446. const
  447. delay = createDelay({
  448. willResolve: !0,
  449. });
  450.  
  451. delay.reject = createDelay({
  452. willResolve: !1,
  453. }), delay.range = (minimum, maximum, options) => delay(((minimum, maximum) => Math.floor(Math.random() * (maximum - minimum + 1) + minimum))(minimum, maximum), options), delay.createWithTimers = ({
  454. clearTimeout, setTimeout,
  455. }) => {
  456. const delay = createDelay({
  457. clearTimeout,
  458. setTimeout,
  459. willResolve: !0,
  460. });
  461.  
  462. return delay.reject = createDelay({
  463. clearTimeout,
  464. setTimeout,
  465. willResolve: !1,
  466. }), delay;
  467. }, module.exports = delay, module.exports.default = delay;
  468. },
  469. };
  470.  
  471. const
  472. __webpack_module_cache__ = {};
  473.  
  474. function __webpack_require__(moduleId) {
  475. if (__webpack_module_cache__[moduleId]) return __webpack_module_cache__[moduleId].exports;
  476. const module = __webpack_module_cache__[moduleId] = {
  477. exports: {},
  478. };
  479.  
  480. return __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__), module.exports;
  481. }
  482.  
  483. __webpack_require__.n = (module) => {
  484. const getter = module && module.__esModule ? () => module.default : () => module;
  485. return __webpack_require__.d(getter, {
  486. a: getter,
  487. }), getter;
  488. }, __webpack_require__.d = (exports, definition) => {
  489. for (const key in definition) {
  490. __webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key) && Object.defineProperty(exports, key, {
  491. enumerable: !0,
  492. get: definition[key],
  493. });
  494. }
  495. }, __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop), (() => {
  496. const external_log_namespaceObject = log;
  497. const delay = __webpack_require__(780);
  498. const delay_default = __webpack_require__.n(delay);
  499. const check_types = __webpack_require__(923);
  500.  
  501. 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); };
  502.  
  503. const
  504. tapNonNull = (x) => (src_assert(x), x);
  505.  
  506. function function_pipe(a, ab, bc, cd, de, ef, fg, gh, hi, ij, jk, kl, lm, mn, no, op, pq, qr, rs, st) {
  507. switch (arguments.length) {
  508. case 1: return a;
  509. case 2: return ab(a);
  510. case 3: return bc(ab(a));
  511. case 4: return cd(bc(ab(a)));
  512. case 5: return de(cd(bc(ab(a))));
  513. case 6: return ef(de(cd(bc(ab(a)))));
  514. case 7: return fg(ef(de(cd(bc(ab(a))))));
  515. case 8: return gh(fg(ef(de(cd(bc(ab(a)))))));
  516. case 9: return hi(gh(fg(ef(de(cd(bc(ab(a))))))));
  517. case 10: return ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))));
  518. case 11: return jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))));
  519. case 12: return kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))));
  520. case 13: return lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))));
  521. case 14: return mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))));
  522. case 15: return no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))));
  523. case 16: return op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))));
  524. case 17: return pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))));
  525. case 18: return qr(pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))));
  526. case 19: return rs(qr(pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a))))))))))))))))));
  527. case 20: return st(rs(qr(pq(op(no(mn(lm(kl(jk(ij(hi(gh(fg(ef(de(cd(bc(ab(a)))))))))))))))))));
  528. }
  529. }
  530.  
  531. const isNone = function (fa) { return fa._tag === 'None'; };
  532.  
  533. const Option_none = {
  534. _tag: 'None',
  535. };
  536.  
  537. const Option_some = function (a) {
  538. return {
  539. _tag: 'Some',
  540. value: a,
  541. };
  542. };
  543.  
  544. function fromNullable(a) { return a == null ? Option_none : Option_some(a); }
  545.  
  546. const getOrElse = function (onNone) { return function (ma) { return isNone(ma) ? onNone() : ma.value; }; };
  547.  
  548. const map_ = function (fa, f) { return isNone(fa) ? Option_none : Option_some(f(fa.value)); };
  549.  
  550. const map = function (f) { return function (fa) { return map_(fa, f); }; };
  551.  
  552. function compare(x, y) { return x < y ? -1 : x > y ? 1 : 0; }
  553.  
  554. function strictEqual(a, b) { return a === b; }
  555.  
  556. const ordNumber = {
  557. equals: strictEqual,
  558. compare,
  559. };
  560.  
  561. function fromCompare(compare) {
  562. const optimizedCompare = function (x, y) { return x === y ? 0 : compare(x, y); };
  563.  
  564. return {
  565. equals(x, y) { return optimizedCompare(x, y) === 0; },
  566. compare: optimizedCompare,
  567. };
  568. }
  569.  
  570. const contramap = function (f) { return function (fa) { return fromCompare(((x, y) => fa.compare(f(x), f(y)))); }; };
  571.  
  572. contramap(((date) => date.valueOf()));
  573. const ReadonlyArray_filter = function (predicate) { return function (fa) { return fa.filter(predicate); }; };
  574.  
  575. const Array_filter = ReadonlyArray_filter;
  576. const external_m_namespaceObject = m;
  577. const external_m_default = __webpack_require__.n(external_m_namespaceObject);
  578. const external_rxjs_namespaceObject = rxjs; const external_rxjs_operators_namespaceObject = rxjs.operators; const
  579. external_Swal_namespaceObject = Swal;
  580.  
  581. const external_Swal_default = __webpack_require__.n(external_Swal_namespaceObject);
  582. const classAttr = (classNames) => classNames.map((x) => `.${x}`).join(''); const forwardTo = (observer) => (value) => { observer.next(value); };
  583.  
  584. const partial = (f, ...headArgs) => (...restArgs) => f(...headArgs, ...restArgs); const tapIs = (constructor, x) => (src_assert(x instanceof constructor), x); const getPageParam = (URL_) => ((URL_, name) => {
  585. const param = URL_.searchParams.get(name);
  586. return param ? Number.parseInt(param, 10) : 0;
  587. })(URL_, 'page');
  588.  
  589. const reloadImage = (image) => {
  590. const {
  591. src,
  592. } = image;
  593.  
  594. image.src = '', image.src = src;
  595. };
  596.  
  597. const removeEmbeddedPage = (page) => { page.src = '', page.remove(); };
  598.  
  599. const getTeaserValue = (info, condition) => {
  600. 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]];
  601. return new Function(...sortParamPairs.map(([name]) => name), `return (${condition})`)(...sortParamPairs.map((pair) => pair[1]));
  602. };
  603.  
  604. const changeAnchorPageParam = (anchor, value) => ((anchor, key, value) => {
  605. const newURL = new URL(anchor.href, window.location.href);
  606. newURL.searchParams.set(key, value), anchor.href = newURL.href;
  607. })(anchor, 'page', value.toString());
  608.  
  609. const groupPageItems = (pageItems) => {
  610. const group = document.createElement('li');
  611. pageItems[0].before(group), pageItems[0].style.marginLeft = '0', pageItems.forEach((item) => { item.classList.replace('pager-item', 'pager-current'); });
  612. const groupList = external_m_default()('ul', {
  613. style: {
  614. display: 'inline',
  615. backgroundColor: 'hsla(0, 0%, 75%, 50%)',
  616. },
  617. oncreate(vnode) { vnode.dom.append(...pageItems); },
  618. });
  619.  
  620. external_m_default().render(group, groupList);
  621. };
  622.  
  623. const adjustPager = (adjust$) => adjust$.pipe((0, external_rxjs_operators_namespaceObject.tap)(({
  624. container, pageCount,
  625. }) => {
  626. const currentPage = getPageParam(new URL(window.location.href)); const nextPage = currentPage + pageCount;
  627. let predicate; [
  628. ...[() => [tapNonNull(container.querySelector('.pager-previous a')), Math.max(0, currentPage - pageCount)]].filter(() => currentPage > 0), ...(() => {
  629. const nextPageAnchor = container.querySelector('.pager-next a'); const lastPageAnchor = container.querySelector('.pager-last a');
  630. if (lastPageAnchor) {
  631. const reachedLastPage = getPageParam(new URL(lastPageAnchor.href, window.location.href)) < nextPage; const display = reachedLastPage ? 'none' : '';
  632. if (lastPageAnchor.style.display = display, src_assert(nextPageAnchor), nextPageAnchor.style.display = display, !reachedLastPage) return [() => [nextPageAnchor, nextPage]];
  633. } else if (nextPageAnchor) return [() => [nextPageAnchor, nextPage]];
  634. return [];
  635. })(),
  636. ].forEach((getArgs) => changeAnchorPageParam(...getArgs())), function_pipe(Array.from(container.querySelectorAll('.pager-item a')), Array_filter((anchor) => {
  637. const page = getPageParam(new URL(anchor.href, window.location.href));
  638. return page >= currentPage && page < nextPage;
  639. }), (predicate = (currentPageAnchors) => currentPageAnchors.length > 0, function (a) { return predicate(a) ? Option_some(a) : Option_none; }), map((anchors) => [...Array.from(container.querySelectorAll('.pager-current')), ...anchors.map((anchor) => tapNonNull(anchor.parentElement))]), map(groupPageItems));
  640. }));
  641.  
  642. const getBrokenImages = () => getTeaserContainers(document).flatMap((container) => Array.from(container.querySelectorAll('img'))).filter((img) => img.complete && img.naturalWidth === 0); const createPreloadPage = (createContainer, parentPageId, url) => {
  643. const container = createContainer();
  644. return container.src = url.toString(), container.style.display = 'none', container.classList.add(parentPageId), container;
  645. };
  646.  
  647. const createPreloadUrl = (startURL, page) => {
  648. const preloadURL = new URL('', startURL);
  649. return preloadURL.searchParams.set('page', page.toString()), preloadURL;
  650. };
  651.  
  652. 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) => {
  653. 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;
  654. teaserDivs.filter(({
  655. dataset,
  656. }) => !dataset.initialIndex).forEach(({
  657. dataset,
  658. }, index) => { dataset.initialIndex = (sortedTeaserCount + index).toString(); }), container.dataset.sortedTeaserCount = teaserDivs.length.toString();
  659.  
  660. const getNearbyNumber = (element) => {
  661. return str = tapIs(Text, element.nextSibling).wholeText.replace(/,/g, ''), Number.parseFloat(str) * (str.includes('k') ? 1e3 : 1);
  662. };
  663.  
  664. const nearbyNumberOrZero = (element) => function_pipe(fromNullable(element), map(getNearbyNumber), getOrElse(() => 0)); const divValuePairs = teaserDivs.map((div) => ({
  665. initialIndex: parseInt(tapNonNull(div.dataset.initialIndex), 10),
  666. viewCount: nearbyNumberOrZero(div.querySelector('.glyphicon-eye-open')),
  667. likeCount: nearbyNumberOrZero(div.querySelector('.glyphicon-heart')),
  668. imageFactor: div.querySelector('.field-type-image') ? 1 : 0,
  669. galleryFactor: div.querySelector('.glyphicon-th-large') ? 1 : 0,
  670. privateFactor: div.querySelector('.private-video') ? 1 : 0,
  671. })).map((info, index) => [teaserDivs[index], getTeaserValue(info, condition)]);
  672.  
  673. 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]));
  674. })(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]) => ({
  675. containersCount: containers.length,
  676. })));
  677.  
  678. const initParent = async () => {
  679. if (getTeaserContainers(document).length === 0) return;
  680. 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'); const sortComponent = new class {
  681. constructor(initialCondition, defaultCondition, initialPageCount) {
  682. 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 = {
  683. condition: initialCondition,
  684. pageCount: initialPageCount,
  685. loadedPageCount: 0,
  686. }, (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();
  687. }
  688.  
  689. view() {
  690. const commonStyle = {
  691. margin: '5px 2px',
  692. };
  693.  
  694. const uiChildren = {
  695. conditionInput: external_m_default()(`input${classAttr(['form-control', 'input-sm'])}`, {
  696. size: 65,
  697. value: this.state.condition,
  698. style: commonStyle,
  699. list: 'iwara-custom-sort-conditions',
  700. oninput: forwardTo(this.conditionInputInput$),
  701. onchange: forwardTo(this.conditionInputChange$),
  702. onkeydown: forwardTo(this.conditionInputKeydown$),
  703. }),
  704. conditionDatalist: external_m_default()('datalist', {
  705. id: 'iwara-custom-sort-conditions',
  706. }, [
  707. [['Default Condition', this.defaultCondition], ['Original Order', '-index'], ['Reversed Original Order', 'index']].map(([name, value]) => external_m_default()('option', {
  708. value,
  709. }, name)),
  710. ]),
  711. resetDefaultButton: external_m_default()(`button${classAttr(['btn', 'btn-sm', 'btn-info'])}`, {
  712. style: commonStyle,
  713. onclick: forwardTo(this.resetDefaultButtonClick$),
  714. }, 'Default'),
  715. sortButton: external_m_default()(`button${classAttr(['btn', 'btn-sm', 'btn-primary'])}`, {
  716. style: commonStyle,
  717. onclick: forwardTo(this.sortButtonClick$),
  718. }, 'Sort'),
  719. label1: external_m_default()(`label${classAttr(['text-primary'])}`, {
  720. style: commonStyle,
  721. }, 'load'),
  722. pageCountInput: external_m_default()(`input${classAttr(['form-control', 'input-sm'])}`, {
  723. type: 'number',
  724. value: this.state.pageCount,
  725. min: 1,
  726. max: 500,
  727. step: 1,
  728. style: {
  729. width: '7rem',
  730. ...commonStyle,
  731. },
  732. oninput: forwardTo(this.pageCountInputInput$),
  733. onchange: forwardTo(this.pageCountInputChange$),
  734. }),
  735. label2: external_m_default()(`label${classAttr(['text-primary'])}`, {
  736. style: commonStyle,
  737. }, 'pages. '),
  738. statusLabel: external_m_default()(`label${classAttr(['text-primary'])}`, {
  739. style: commonStyle,
  740. }, this.state.loadedPageCount < this.state.pageCount ? `${this.state.loadedPageCount} of ${this.state.pageCount} pages done` : 'All pages done'),
  741. };
  742.  
  743. return external_m_default()(`div${classAttr(['form-inline', 'container'])}`, {
  744. style: {
  745. display: 'inline-block',
  746. },
  747. }, Object.values(uiChildren));
  748. }
  749.  
  750. addLoadedPageCount() { this.state.loadedPageCount += 1, external_m_default().redraw(); }
  751. }(initialCondition, defaultCondition, pageCount);
  752.  
  753. 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 clonedClass = 'iwara-custom-sort-cloned'; const allStreams = {
  754. adjustPager$: sortComponent.pageCount$.pipe((0, external_rxjs_operators_namespaceObject.mergeMap)((count) => (0, external_rxjs_namespaceObject.from)(document.querySelectorAll(`.pager:not(.${clonedClass})`)).pipe((0, external_rxjs_operators_namespaceObject.tap)((pager) => { pager.style.display = 'none'; }), (0, external_rxjs_operators_namespaceObject.map)((pager) => {
  755. const clonedPager = tapIs(HTMLElement, pager.cloneNode(!0));
  756. return clonedPager.style.display = '', [pager, clonedPager];
  757. }), (0, external_rxjs_operators_namespaceObject.tap)(([pager, clonedPager]) => {
  758. const sibling = pager.previousElementSibling;
  759. sibling && sibling.matches(`.${clonedClass}`) ? sibling.replaceWith(clonedPager) : pager.before(clonedPager);
  760. }), (0, external_rxjs_operators_namespaceObject.tap)(([, clonedPager]) => { clonedPager.classList.add(clonedClass); }), (0, external_rxjs_operators_namespaceObject.map)(([, clonedPager]) => ({
  761. container: clonedPager,
  762. pageCount: count,
  763. })))), adjustPager),
  764. logPageLoad$: pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.tap)(external_log_namespaceObject.info)),
  765. 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)),
  766. 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)),
  767. removeLoadedPage$: pageLoad$.pipe((0, external_rxjs_operators_namespaceObject.map)(({
  768. url,
  769. }) => ({
  770. url,
  771. container: pageFromUrl.get(url),
  772. })), (0, external_rxjs_operators_namespaceObject.tap)(({
  773. url,
  774. }) => pageFromUrl.delete(url)), (0, external_rxjs_operators_namespaceObject.pluck)('container'), (0, external_rxjs_operators_namespaceObject.map)(tapNonNull), (0, external_rxjs_operators_namespaceObject.tap)(removeEmbeddedPage)),
  775. 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({
  776. length: createPageCount,
  777. }, () => {}))))).pipe((0, external_rxjs_operators_namespaceObject.map)(([url]) => [
  778. url, () => {
  779. return userAgent = window.navigator.userAgent, document.createElement(userAgent.indexOf('Firefox') > -1 ? 'embed' : 'iframe');
  780. },
  781. ]), (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))),
  782. };
  783.  
  784. (0, external_rxjs_namespaceObject.merge)(...Object.values(allStreams)).subscribe();
  785. const sortComponentContainer = document.createElement('div');
  786. tapNonNull(document.querySelector('#user-links')).after(sortComponentContainer), external_m_default().mount(sortComponentContainer, sortComponent), external_log_namespaceObject.debug(await GM.listValues());
  787. };
  788.  
  789. const
  790. initialize = async () => {
  791. const isParent = window === window.parent;
  792. external_log_namespaceObject.debug(`${isParent ? 'Parent' : 'Child'}: ${window.location.href}`), await (isParent ? initParent() : (async () => {
  793. const teaserContainers = getTeaserContainers(document);
  794. const channel = new BroadcastChannel('iwara-custom-sort');
  795. const hasTeasers = teaserContainers.length > 0;
  796. const message = {
  797. url: window.location.href,
  798. parentPageId: Array.from(tapNonNull(window.frameElement).classList).filter((x) => x.startsWith('t-'))[0],
  799. hasTeasers,
  800. };
  801.  
  802. hasTeasers && (await delay_default()(500), ((children, parents) => {
  803. for (let i = 0, j = 0; i < parents.length && j < children.length; i += 1) {
  804. const parent = parents[i]; const
  805. child = children[j];
  806.  
  807. parent.className === child.className && (child.className = '', parent.append(child), j += 1);
  808. }
  809. })(teaserContainers, getTeaserContainers(window.parent.document))), channel.postMessage(message);
  810. })());
  811. };
  812.  
  813. (async () => {
  814. external_log_namespaceObject.setLevel('debug');
  815. try { await initialize(); } catch (error) { external_log_namespaceObject.error(error); }
  816. })();
  817. })();
  818. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址