pervert-monkey 1.0.13 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/core/pervertmonkey.core.es.d.ts +90 -36
  2. package/dist/core/pervertmonkey.core.es.js +258 -129
  3. package/dist/core/pervertmonkey.core.es.js.map +1 -1
  4. package/dist/core/pervertmonkey.core.umd.js +258 -129
  5. package/dist/core/pervertmonkey.core.umd.js.map +1 -1
  6. package/dist/userscripts/3hentai.user.js +4 -5
  7. package/dist/userscripts/camgirlfinder.user.js +2 -2
  8. package/dist/userscripts/camwhores.user.js +7 -16
  9. package/dist/userscripts/e-hentai.user.js +8 -8
  10. package/dist/userscripts/ebalka.user.js +18 -10
  11. package/dist/userscripts/eporner.user.js +24 -41
  12. package/dist/userscripts/erome.user.js +13 -16
  13. package/dist/userscripts/eroprofile.user.js +5 -14
  14. package/dist/userscripts/javhdporn.user.js +6 -5
  15. package/dist/userscripts/missav.user.js +10 -4
  16. package/dist/userscripts/motherless.user.js +13 -6
  17. package/dist/userscripts/namethatporn.user.js +10 -16
  18. package/dist/userscripts/nhentai.user.js +5 -13
  19. package/dist/userscripts/obmenvsem.user.js +11 -4
  20. package/dist/userscripts/pornhub.user.js +14 -6
  21. package/dist/userscripts/spankbang.user.js +28 -7
  22. package/dist/userscripts/thisvid.user.js +15 -33
  23. package/dist/userscripts/xhamster.user.js +13 -18
  24. package/dist/userscripts/xvideos.user.js +33 -5
  25. package/package.json +1 -1
  26. package/src/core/data-handler/data-filter-fn-defaults.ts +52 -0
  27. package/src/core/data-handler/data-filter-fn.ts +62 -0
  28. package/src/core/data-handler/data-filter.ts +31 -103
  29. package/src/core/data-handler/data-manager.ts +91 -28
  30. package/src/core/jabroni-config/default-scheme.ts +54 -5
  31. package/src/core/jabroni-config/index.ts +1 -0
  32. package/src/core/jabroni-config/jabroni-gui-controller.ts +1 -1
  33. package/src/core/jabroni-config/scheme-selectors-mapping.ts +12 -0
  34. package/src/core/parsers/thumb-data-parser.ts +15 -19
  35. package/src/core/rules/index.ts +15 -9
  36. package/src/userscripts/index.ts +1 -1
  37. package/src/userscripts/scripts/3hentai.ts +3 -4
  38. package/src/userscripts/scripts/camgirlfinder.ts +1 -1
  39. package/src/userscripts/scripts/camwhores.ts +5 -14
  40. package/src/userscripts/scripts/e-hentai.ts +12 -12
  41. package/src/userscripts/scripts/ebalka.ts +16 -8
  42. package/src/userscripts/scripts/eporner.ts +23 -39
  43. package/src/userscripts/scripts/erome.ts +13 -17
  44. package/src/userscripts/scripts/eroprofile.ts +4 -12
  45. package/src/userscripts/scripts/javhdporn.ts +7 -8
  46. package/src/userscripts/scripts/missav.ts +10 -4
  47. package/src/userscripts/scripts/motherless.ts +13 -7
  48. package/src/userscripts/scripts/namethatporn.ts +10 -17
  49. package/src/userscripts/scripts/nhentai.ts +6 -13
  50. package/src/userscripts/scripts/obmenvsem.ts +14 -4
  51. package/src/userscripts/scripts/pornhub.ts +13 -4
  52. package/src/userscripts/scripts/spankbang.ts +29 -5
  53. package/src/userscripts/scripts/thisvid.ts +16 -31
  54. package/src/userscripts/scripts/xhamster.ts +13 -18
  55. package/src/userscripts/scripts/xvideos.ts +32 -3
  56. package/src/utils/dom/dom-observers.ts +3 -3
  57. package/src/utils/dom/index.ts +1 -1
  58. package/src/utils/parsers/index.ts +5 -2
@@ -11,6 +11,43 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
11
11
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
12
12
  var _i2, _n2, _t, _e2, _s2, _l2, _o2, _d, _p2, _g, _C_instances, r_fn, R_fn, b_fn, u_fn, m_fn, a_fn, P_fn, E_fn, S_fn, O_fn, k_fn, x_fn, h_fn, f_fn, T_fn, A_fn, y_fn, w_fn, c_fn, C_fn, _a, _i3, _n3, _t2, _e3, _s3, _l3, _b;
13
13
  import { GM_addStyle } from "vite-plugin-monkey/dist/client";
14
+ const _DataFilterFn = class _DataFilterFn {
15
+ constructor(handle, deps = [], name, $preDefine) {
16
+ this.handle = handle;
17
+ this.deps = deps;
18
+ this.name = name;
19
+ this.$preDefine = $preDefine;
20
+ this.name = _DataFilterFn.setPrefix(name);
21
+ }
22
+ static setPrefix(name) {
23
+ return `${_DataFilterFn.prefix}${name}`;
24
+ }
25
+ static from(options, name) {
26
+ if (typeof options === "function") {
27
+ const deps = [name];
28
+ return new _DataFilterFn(options, deps, name);
29
+ }
30
+ return new _DataFilterFn(
31
+ options.handle,
32
+ options.deps,
33
+ name,
34
+ options.$preDefine
35
+ );
36
+ }
37
+ renderFn(state) {
38
+ const name = this.name;
39
+ return () => {
40
+ var _a3;
41
+ const preDefined = (_a3 = this.$preDefine) == null ? void 0 : _a3.call(this, state);
42
+ return (a2) => {
43
+ const condition = this.handle(a2, state, preDefined);
44
+ return { condition, name };
45
+ };
46
+ };
47
+ }
48
+ };
49
+ __publicField(_DataFilterFn, "prefix", "filter-");
50
+ let DataFilterFn = _DataFilterFn;
14
51
  function chunks(arr, size) {
15
52
  return Array.from(
16
53
  { length: Math.ceil(arr.length / size) },
@@ -81,10 +118,10 @@ function sanitizeStr(s) {
81
118
  }
82
119
  function waitForElementToAppear(parent, selector, callback) {
83
120
  const observer = new MutationObserver((_mutations) => {
84
- const el2 = parent.querySelector(selector);
85
- if (el2) {
121
+ const e = parent.querySelector(selector);
122
+ if (e) {
86
123
  observer.disconnect();
87
- callback(el2);
124
+ callback(e);
88
125
  }
89
126
  });
90
127
  observer.observe(document.body, { childList: true, subtree: true });
@@ -183,7 +220,7 @@ function removeClassesAndDataAttributes(element, keyword) {
183
220
  });
184
221
  }
185
222
  function getCommonParents(elements) {
186
- const parents = Array.from(elements).map((el2) => el2.parentElement).filter((parent) => parent !== null);
223
+ const parents = Array.from(elements).map((e) => e.parentElement).filter((parent) => parent !== null);
187
224
  return [...new Set(parents)];
188
225
  }
189
226
  function findNextSibling(e) {
@@ -397,9 +434,11 @@ function parseIntegerOr(n, or2) {
397
434
  function parseNumberWithLetter(str) {
398
435
  var _a3;
399
436
  const multipliers = { k: 1e3, m: 1e6 };
400
- const match = str.trim().match(/^([\d.]+)(\w)?$/);
437
+ const match = str.trim().match(/([\d., ]+)(\w)?/);
401
438
  if (!match) return 0;
402
- const num = parseFloat(match[1]);
439
+ const s1 = match[1].replace(/,/g, ".").replace(/[ ]/g, "");
440
+ const s2 = s1.split(".").filter(Boolean).length < 3 ? s1 : s1.replace(".", "");
441
+ const num = parseFloat(s2);
403
442
  const suffix = (_a3 = match[2]) == null ? void 0 : _a3.toLowerCase();
404
443
  if (suffix && suffix in multipliers) {
405
444
  return num * multipliers[suffix];
@@ -427,107 +466,92 @@ function parseDataParams(str) {
427
466
  function parseCssUrl(s) {
428
467
  return s.replace(/url\("|"\).*/g, "");
429
468
  }
430
- const _DataFilter = class _DataFilter {
469
+ function createTextFilter(filterName, dataPropName, positive) {
470
+ const filterNameValue = `${filterName}Words`;
471
+ return {
472
+ handle(e, state, searchFilter) {
473
+ if (!Object.hasOwn(state, filterName) || !state[filterName]) return false;
474
+ return !(searchFilter == null ? void 0 : searchFilter(e[dataPropName]));
475
+ },
476
+ $preDefine: (state) => {
477
+ const r = new RegexFilter(state[filterNameValue]);
478
+ if (positive) return (s) => r.hasEvery(s);
479
+ return (s) => r.hasNone(s);
480
+ },
481
+ deps: [filterNameValue]
482
+ };
483
+ }
484
+ const filterDuration = {
485
+ handle(e, state, notInRange) {
486
+ if (!state.filterDuration) return false;
487
+ return !!(notInRange == null ? void 0 : notInRange(e.duration));
488
+ },
489
+ $preDefine: (state) => {
490
+ const from = state.filterDurationFrom;
491
+ const to2 = state.filterDurationTo;
492
+ function notInRange(d2) {
493
+ return d2 < from || d2 > to2;
494
+ }
495
+ return notInRange;
496
+ },
497
+ deps: ["filterDurationFrom", "filterDurationTo"]
498
+ };
499
+ const defaultDataFilterFns = {
500
+ filterDuration,
501
+ filterExclude: createTextFilter("filterExclude", "title", false),
502
+ filterInclude: createTextFilter("filterInclude", "title", true),
503
+ filterUploaderExclude: createTextFilter("filterUploaderExclude", "uploader", false),
504
+ filterUploaderInclude: createTextFilter("filterUploaderInclude", "uploader", true),
505
+ filterHD: (e, state) => state.filterHD && !e.hd,
506
+ filterNonHD: (e, state) => state.filterNonHD && e.hd,
507
+ filterPrivate: (e, state) => state.filterPrivate && e.private,
508
+ filterPublic: (e, state) => state.filterPublic && !e.private
509
+ };
510
+ class DataFilter {
431
511
  constructor(rules) {
432
512
  __publicField(this, "filters", /* @__PURE__ */ new Map());
433
- __publicField(this, "customDataSelectorFns", {});
434
513
  __publicField(this, "filterMapping", {});
514
+ __publicField(this, "customDataFilterFns", {});
435
515
  this.rules = rules;
436
- this.registerFilters(rules.customDataSelectorFns);
437
- this.applyCSSFilters();
516
+ this.registerFilters(rules.customDataFilterFns);
517
+ this.createCssFilters();
438
518
  }
439
- static isFiltered(el2) {
440
- return el2.className.includes("filter-");
519
+ static isFiltered(e) {
520
+ return e.className.includes(DataFilterFn.prefix);
441
521
  }
442
- applyCSSFilters(wrapper) {
522
+ createCssFilters(wrapper) {
443
523
  this.filters.forEach((_2, name) => {
444
- const cssRule = `.filter-${name} { display: none !important; }`;
524
+ const className = DataFilterFn.setPrefix(name);
525
+ const cssRule = `.${className} { display: none !important; }`;
445
526
  GM_addStyle(wrapper ? wrapper(cssRule) : cssRule);
446
527
  });
447
528
  }
448
529
  registerFilters(customFilters) {
449
530
  customFilters.forEach((o) => {
450
- if (typeof o === "string") {
451
- this.customDataSelectorFns[o] = _DataFilter.customDataSelectorFnsDefault[o];
452
- this.registerFilter(o);
453
- } else {
454
- const k2 = Object.keys(o)[0];
455
- this.customDataSelectorFns[k2] = o[k2];
456
- this.registerFilter(k2);
457
- }
531
+ const isStr = typeof o === "string";
532
+ const k2 = isStr ? o : Object.keys(o)[0];
533
+ this.customDataFilterFns[k2] = isStr ? defaultDataFilterFns[o] : o[k2];
534
+ this.registerFilter(k2);
458
535
  });
459
536
  }
460
- customSelectorParser(name, selector) {
461
- if ("handle" in selector) {
462
- return selector;
463
- } else {
464
- return { handle: selector, deps: [name] };
465
- }
466
- }
467
537
  registerFilter(customSelectorName) {
468
- var _a3;
469
- const handler = this.customSelectorParser(
470
- customSelectorName,
471
- this.customDataSelectorFns[customSelectorName]
538
+ const dataFilterFn = DataFilterFn.from(
539
+ this.customDataFilterFns[customSelectorName],
540
+ customSelectorName
472
541
  );
473
- const tag = `filter-${customSelectorName}`;
474
- (_a3 = [customSelectorName, ...handler.deps || []]) == null ? void 0 : _a3.forEach((name) => {
542
+ dataFilterFn.deps.push(customSelectorName);
543
+ dataFilterFn.deps.forEach((name) => {
475
544
  Object.assign(this.filterMapping, { [name]: customSelectorName });
476
545
  });
477
- const fn2 = () => {
478
- var _a4;
479
- const preDefined = (_a4 = handler.$preDefine) == null ? void 0 : _a4.call(handler, this.rules.store.state);
480
- return (v2) => {
481
- const condition = handler.handle(v2, this.rules.store.state, preDefined);
482
- return {
483
- condition,
484
- tag
485
- };
486
- };
487
- };
488
- this.filters.set(customSelectorName, fn2);
546
+ this.filters.set(customSelectorName, dataFilterFn.renderFn(this.rules.store.state));
489
547
  }
490
548
  selectFilters(filters) {
491
549
  const selectedFilters = Object.keys(filters).filter((k2) => k2 in this.filterMapping).map((k2) => this.filterMapping[k2]).map((k2) => this.filters.get(k2));
492
550
  return selectedFilters;
493
551
  }
494
- };
495
- __publicField(_DataFilter, "customDataSelectorFnsDefault", {
496
- filterDuration: {
497
- handle(el2, state, notInRange) {
498
- if (!state.filterDuration) return false;
499
- return notInRange(el2.duration);
500
- },
501
- $preDefine: (state) => {
502
- const from = state.filterDurationFrom;
503
- const to2 = state.filterDurationTo;
504
- function notInRange(d2) {
505
- return d2 < from || d2 > to2;
506
- }
507
- return notInRange;
508
- },
509
- deps: ["filterDurationFrom", "filterDurationTo"]
510
- },
511
- filterExclude: {
512
- handle(el2, state, searchFilter) {
513
- if (!state.filterExclude) return false;
514
- return !searchFilter.hasNone(el2.title);
515
- },
516
- $preDefine: (state) => new RegexFilter(state.filterExcludeWords),
517
- deps: ["filterExcludeWords"]
518
- },
519
- filterInclude: {
520
- handle(el2, state, searchFilter) {
521
- if (!state.filterInclude) return false;
522
- return !searchFilter.hasEvery(el2.title);
523
- },
524
- $preDefine: (state) => new RegexFilter(state.filterIncludeWords),
525
- deps: ["filterIncludeWords"]
526
- }
527
- });
528
- let DataFilter = _DataFilter;
552
+ }
529
553
  class DataManager {
530
- constructor(rules, parentHomogenity) {
554
+ constructor(rules, containerHomogenity) {
531
555
  __publicField(this, "data", /* @__PURE__ */ new Map());
532
556
  __publicField(this, "lazyImgLoader", new LazyImgLoader(
533
557
  (target) => !DataFilter.isFiltered(target)
@@ -538,25 +562,18 @@ class DataManager {
538
562
  if (filtersToApply.length === 0) return;
539
563
  const iterator2 = this.data.values().drop(offset);
540
564
  let finished = false;
565
+ const updates = [];
541
566
  await new Promise((resolve) => {
542
567
  function runBatch(deadline) {
543
- const updates = [];
544
568
  while (deadline.timeRemaining() > 0) {
545
569
  const { value, done } = iterator2.next();
546
570
  finished = !!done;
547
571
  if (done) break;
548
572
  for (const f of filtersToApply) {
549
- const { tag, condition } = f()(value);
550
- updates.push({ e: value.element, tag, condition });
573
+ const { name, condition } = f()(value);
574
+ updates.push({ e: value.element, name, condition });
551
575
  }
552
576
  }
553
- if (updates.length > 0) {
554
- requestAnimationFrame(() => {
555
- updates.forEach((u) => {
556
- u.e.classList.toggle(u.tag, u.condition);
557
- });
558
- });
559
- }
560
577
  if (!finished) {
561
578
  requestIdleCallback(runBatch);
562
579
  } else {
@@ -565,7 +582,31 @@ class DataManager {
565
582
  }
566
583
  requestIdleCallback(runBatch);
567
584
  });
585
+ const parents = [...new Set(updates.map((u) => u.e.parentElement))].filter(
586
+ (_2) => _2 !== null
587
+ );
588
+ requestAnimationFrame(() => {
589
+ const revertDisplayStyle = parents.map((p) => {
590
+ const display = p.style.display;
591
+ p.style.display = "none";
592
+ this.layoutStylePaint(p);
593
+ p.style.willChange = "contents";
594
+ return () => {
595
+ p.style.display = display;
596
+ requestAnimationFrame(() => {
597
+ p.style.willChange = "auto";
598
+ });
599
+ };
600
+ });
601
+ updates.forEach((u) => {
602
+ u.e.classList.toggle(u.name, u.condition);
603
+ });
604
+ revertDisplayStyle.forEach((f) => {
605
+ f == null ? void 0 : f();
606
+ });
607
+ });
568
608
  });
609
+ __publicField(this, "layoutStylePaintEnabled", false);
569
610
  __publicField(this, "filterAll", async (offset) => {
570
611
  const keys = Array.from(this.dataFilter.filters.keys());
571
612
  const filters = Object.fromEntries(
@@ -578,13 +619,13 @@ class DataManager {
578
619
  const dataOffset = this.data.size;
579
620
  const fragment = document.createDocumentFragment();
580
621
  const parent = container || this.rules.container;
581
- const homogenity = !!this.parentHomogenity;
622
+ const homogenity = !!this.containerHomogenity;
582
623
  for (const thumbElement of thumbs) {
583
624
  const url = this.rules.thumbDataParser.getUrl(thumbElement);
584
625
  if (!url || this.data.has(url) || parent !== container && (parent == null ? void 0 : parent.contains(thumbElement)) || homogenity && !checkHomogenity(
585
626
  parent,
586
627
  thumbElement.parentElement,
587
- this.parentHomogenity
628
+ this.containerHomogenity
588
629
  )) {
589
630
  if (removeDuplicates) thumbElement.remove();
590
631
  continue;
@@ -598,27 +639,55 @@ class DataManager {
598
639
  fragment.append(thumbElement);
599
640
  }
600
641
  this.filterAll(dataOffset).then(() => {
642
+ if (!parent) return;
643
+ parent.style.willChange = "contents";
601
644
  requestAnimationFrame(() => {
602
- parent.appendChild(fragment);
645
+ parent == null ? void 0 : parent.appendChild(fragment);
646
+ requestAnimationFrame(() => {
647
+ parent.style.willChange = "auto";
648
+ });
603
649
  });
604
650
  });
605
651
  });
606
652
  this.rules = rules;
607
- this.parentHomogenity = parentHomogenity;
653
+ this.containerHomogenity = containerHomogenity;
608
654
  this.dataFilter = new DataFilter(this.rules);
609
655
  }
656
+ layoutStylePaint(e) {
657
+ if (!this.layoutStylePaintEnabled) return;
658
+ e.style.contain = "layout style paint";
659
+ }
610
660
  sortBy(key, direction = true) {
611
661
  if (this.data.size < 2) return;
612
- let sorted = this.data.values().toArray().sort((a2, b2) => {
613
- return a2[key] - b2[key];
662
+ const elements = this.data.values().toArray().filter((e) => e.element.parentElement !== null).map((e) => e);
663
+ const containers = new Set(elements.map((e) => e.element.parentElement));
664
+ containers.forEach((c) => {
665
+ this.layoutStylePaint(c);
666
+ c.style.willChange = "contents";
614
667
  });
615
- if (!direction) sorted = sorted.reverse();
616
- const container = sorted[0].element.parentElement;
617
- container.style.visibility = "hidden";
618
- sorted.forEach((s) => {
619
- container.append(s.element);
668
+ const elementsByContainers = /* @__PURE__ */ new Map();
669
+ containers.forEach((c) => {
670
+ elementsByContainers.set(c, []);
620
671
  });
621
- container.style.visibility = "visible";
672
+ elements.forEach((e) => {
673
+ const parent = e.element.parentElement;
674
+ const container = elementsByContainers.get(parent);
675
+ container == null ? void 0 : container.push(e);
676
+ });
677
+ const dir = direction ? -1 : 1;
678
+ for (const [container, items] of elementsByContainers) {
679
+ items.sort((a2, b2) => (a2[key] - b2[key]) * dir);
680
+ const domNodes = items.map((e) => e.element);
681
+ const display = container.style.display;
682
+ container.style.display = "none";
683
+ container.replaceChildren(...domNodes);
684
+ requestAnimationFrame(() => {
685
+ container.style.display = display;
686
+ requestAnimationFrame(() => {
687
+ container.style.willChange = "auto";
688
+ });
689
+ });
690
+ }
622
691
  }
623
692
  }
624
693
  var extendStatics = function(d2, b2) {
@@ -2996,7 +3065,7 @@ function getPaginationStrategy(options) {
2996
3065
  return paginationStrategy;
2997
3066
  }
2998
3067
  class ThumbDataParser {
2999
- constructor(strategy = "manual", selectors = {}, callback, stringsMeltInTitle = true) {
3068
+ constructor(strategy = "manual", selectors = {}, callback) {
3000
3069
  __publicField(this, "thumbDataSelectors", []);
3001
3070
  __publicField(this, "defaultThumbDataSelectors", [
3002
3071
  { name: "title", type: "string", selector: "[class *= title],[title]" },
@@ -3006,17 +3075,19 @@ class ThumbDataParser {
3006
3075
  selector: "[class *= uploader], [class *= user], [class *= name]"
3007
3076
  },
3008
3077
  { name: "duration", type: "duration", selector: "[class *= duration]" }
3078
+ // { name: 'views', type: 'float', selector: '[class *= view]' },
3009
3079
  ]);
3010
3080
  this.strategy = strategy;
3011
3081
  this.selectors = selectors;
3012
3082
  this.callback = callback;
3013
- this.stringsMeltInTitle = stringsMeltInTitle;
3014
3083
  this.preprocessCustomThumbDataSelectors();
3015
3084
  }
3016
3085
  autoParseText(thumb) {
3017
3086
  var _a3;
3018
- const title = sanitizeStr(thumb.innerText);
3019
- const duration = timeToSeconds(((_a3 = title.match(/\d+m|\d+:\d+/)) == null ? void 0 : _a3[0]) || "");
3087
+ let title = sanitizeStr(thumb.innerText);
3088
+ const durationStr = ((_a3 = title.match(/(\d+:\d+:?\d+?)|\d+m/)) == null ? void 0 : _a3[0]) || "";
3089
+ const duration = timeToSeconds(durationStr);
3090
+ title = title.replaceAll(durationStr, "");
3020
3091
  return { title, duration };
3021
3092
  }
3022
3093
  getUrl(thumb) {
@@ -3056,7 +3127,7 @@ class ThumbDataParser {
3056
3127
  return Number.parseInt(querySelectorText(thumb, selector));
3057
3128
  }
3058
3129
  static create(o = {}) {
3059
- return new ThumbDataParser(o.strategy, o.selectors, o.callback, o.stringsMeltInTitle);
3130
+ return new ThumbDataParser(o.strategy, o.selectors, o.callback);
3060
3131
  }
3061
3132
  getThumbData(thumb) {
3062
3133
  var _a3;
@@ -3064,19 +3135,11 @@ class ThumbDataParser {
3064
3135
  return this.autoParseText(thumb);
3065
3136
  }
3066
3137
  if (this.strategy === "auto-select") {
3067
- this.thumbDataSelectors = this.defaultThumbDataSelectors;
3138
+ this.thumbDataSelectors.push(...this.defaultThumbDataSelectors);
3068
3139
  }
3069
3140
  const thumbData = Object.fromEntries(
3070
3141
  this.thumbDataSelectors.map((s) => [s.name, this.getThumbDataWith(thumb, s)])
3071
3142
  );
3072
- if (this.stringsMeltInTitle) {
3073
- Object.entries(thumbData).forEach(([k2, v2]) => {
3074
- if (typeof v2 === "string" && k2 !== "title") {
3075
- thumbData.title = `${thumbData.title} ${k2}:${v2}`;
3076
- delete thumbData[k2];
3077
- }
3078
- });
3079
- }
3080
3143
  (_a3 = this.callback) == null ? void 0 : _a3.call(this, thumb, thumbData);
3081
3144
  return thumbData;
3082
3145
  }
@@ -9606,7 +9669,7 @@ function Wp(t, e = []) {
9606
9669
  }
9607
9670
  const DefaultScheme = [
9608
9671
  {
9609
- title: "Text Filter",
9672
+ title: "Title Filter",
9610
9673
  collapsed: true,
9611
9674
  content: [
9612
9675
  { filterExclude: false, label: "exclude" },
@@ -9625,6 +9688,26 @@ const DefaultScheme = [
9625
9688
  }
9626
9689
  ]
9627
9690
  },
9691
+ {
9692
+ title: "Uploader Filter",
9693
+ collapsed: true,
9694
+ content: [
9695
+ { filterUploaderExclude: false, label: "exclude" },
9696
+ {
9697
+ filterUploaderExcludeWords: "",
9698
+ label: "keywords",
9699
+ watch: "filterUploaderExclude",
9700
+ placeholder: "word, f:full_word, r:RegEx..."
9701
+ },
9702
+ { filterUploaderInclude: false, label: "include" },
9703
+ {
9704
+ filterUploaderIncludeWords: "",
9705
+ label: "keywords",
9706
+ watch: "filterUploaderInclude",
9707
+ placeholder: "word, f:full_word, r:RegEx..."
9708
+ }
9709
+ ]
9710
+ },
9628
9711
  {
9629
9712
  title: "Duration Filter",
9630
9713
  collapsed: true,
@@ -9646,6 +9729,7 @@ const DefaultScheme = [
9646
9729
  },
9647
9730
  {
9648
9731
  title: "Sort By",
9732
+ collapsed: true,
9649
9733
  content: [
9650
9734
  {
9651
9735
  "sort by views": () => {
@@ -9657,8 +9741,29 @@ const DefaultScheme = [
9657
9741
  }
9658
9742
  ]
9659
9743
  },
9744
+ {
9745
+ title: "Sort By Duration",
9746
+ collapsed: true,
9747
+ content: [
9748
+ {
9749
+ "sort by duration": () => {
9750
+ }
9751
+ }
9752
+ ]
9753
+ },
9754
+ {
9755
+ title: "Sort By Views",
9756
+ collapsed: true,
9757
+ content: [
9758
+ {
9759
+ "sort by views": () => {
9760
+ }
9761
+ }
9762
+ ]
9763
+ },
9660
9764
  {
9661
9765
  title: "Privacy Filter",
9766
+ collapsed: true,
9662
9767
  content: [
9663
9768
  { filterPrivate: false, label: "private" },
9664
9769
  { filterPublic: false, label: "public" },
@@ -9666,6 +9771,13 @@ const DefaultScheme = [
9666
9771
  } }
9667
9772
  ]
9668
9773
  },
9774
+ {
9775
+ title: "HD Filter",
9776
+ content: [
9777
+ { filterHD: false, label: "hd" },
9778
+ { filterNonHD: false, label: "non-hd" }
9779
+ ]
9780
+ },
9669
9781
  {
9670
9782
  title: "Advanced",
9671
9783
  collapsed: true,
@@ -9685,6 +9797,11 @@ const DefaultScheme = [
9685
9797
  {
9686
9798
  writeHistory: false,
9687
9799
  label: "write history"
9800
+ },
9801
+ {
9802
+ reset: () => {
9803
+ localStorage.removeItem("state_acephale");
9804
+ }
9688
9805
  }
9689
9806
  ]
9690
9807
  },
@@ -9742,13 +9859,22 @@ class JabronioGuiController {
9742
9859
  setupStoreListeners() {
9743
9860
  var _a3;
9744
9861
  (_a3 = this.directionalEventObservable$) == null ? void 0 : _a3.subscribe((e) => {
9745
- this.eventsMap[e.type](e.direction);
9862
+ var _a4, _b2;
9863
+ (_b2 = (_a4 = this.eventsMap)[e.type]) == null ? void 0 : _b2.call(_a4, e.direction);
9746
9864
  });
9747
9865
  this.store.stateSubject.pipe(takeUntil(this.destroy$)).subscribe((a2) => {
9748
9866
  this.dataManager.applyFilters(a2);
9749
9867
  });
9750
9868
  }
9751
9869
  }
9870
+ function getSelectorFnsFromScheme(xs2) {
9871
+ const keys = xs2.flatMap((s) => {
9872
+ const schemeBlock = DefaultScheme.find((e) => e.title === s);
9873
+ if (!schemeBlock) return [];
9874
+ return schemeBlock.content.flatMap((c) => Object.keys(c));
9875
+ });
9876
+ return keys.filter((k2) => k2 in defaultDataFilterFns);
9877
+ }
9752
9878
  class Rules {
9753
9879
  constructor(options) {
9754
9880
  __publicField(this, "thumb", {});
@@ -9763,12 +9889,8 @@ class Rules {
9763
9889
  __publicField(this, "paginationStrategyOptions", {});
9764
9890
  __publicField(this, "paginationStrategy");
9765
9891
  __publicField(this, "dataManager");
9766
- __publicField(this, "dataHomogenity");
9767
- __publicField(this, "customDataSelectorFns", [
9768
- "filterInclude",
9769
- "filterExclude",
9770
- "filterDuration"
9771
- ]);
9892
+ __publicField(this, "containerHomogenity");
9893
+ __publicField(this, "customDataFilterFns", []);
9772
9894
  __publicField(this, "animatePreview");
9773
9895
  __publicField(this, "storeOptions");
9774
9896
  __publicField(this, "schemeOptions", []);
@@ -9790,7 +9912,8 @@ class Rules {
9790
9912
  this.paginationStrategy = getPaginationStrategy(this.paginationStrategyOptions);
9791
9913
  this.store = this.createStore();
9792
9914
  this.gui = this.createGui();
9793
- this.dataManager = new DataManager(this, this.dataHomogenity);
9915
+ this.hookDataFilterFns();
9916
+ this.dataManager = new DataManager(this, this.containerHomogenity);
9794
9917
  this.inputController = new JabronioGuiController(this.store, this.dataManager);
9795
9918
  this.reset();
9796
9919
  }
@@ -9809,6 +9932,12 @@ class Rules {
9809
9932
  get observable() {
9810
9933
  return this.intersectionObservable || this.paginationStrategy.getPaginationElement();
9811
9934
  }
9935
+ hookDataFilterFns() {
9936
+ const defaultFilterFns = getSelectorFnsFromScheme(
9937
+ this.schemeOptions.filter((s) => typeof s === "string")
9938
+ );
9939
+ this.customDataFilterFns.push(...defaultFilterFns);
9940
+ }
9812
9941
  createStore() {
9813
9942
  const config2 = { ...StoreStateDefault, ...this.storeOptions };
9814
9943
  this.store = new Up(config2);
@@ -9864,7 +9993,7 @@ class Rules {
9864
9993
  });
9865
9994
  this.mutationObservers = [];
9866
9995
  this.paginationStrategy = getPaginationStrategy(this.paginationStrategyOptions);
9867
- this.dataManager = new DataManager(this, this.dataHomogenity);
9996
+ this.dataManager = new DataManager(this, this.containerHomogenity);
9868
9997
  this.inputController.dispose();
9869
9998
  this.inputController = new JabronioGuiController(this.store, this.dataManager);
9870
9999
  this.resetInfiniteScroller();