pervert-monkey 1.0.12 → 1.0.15

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 (56) hide show
  1. package/dist/core/pervertmonkey.core.es.d.ts +85 -30
  2. package/dist/core/pervertmonkey.core.es.js +250 -114
  3. package/dist/core/pervertmonkey.core.es.js.map +1 -1
  4. package/dist/core/pervertmonkey.core.umd.js +250 -114
  5. package/dist/core/pervertmonkey.core.umd.js.map +1 -1
  6. package/dist/userscripts/3hentai.user.js +4 -11
  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 +3 -4
  10. package/dist/userscripts/ebalka.user.js +13 -5
  11. package/dist/userscripts/eporner.user.js +21 -41
  12. package/dist/userscripts/erome.user.js +9 -8
  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 +14 -6
  17. package/dist/userscripts/namethatporn.user.js +8 -14
  18. package/dist/userscripts/nhentai.user.js +5 -13
  19. package/dist/userscripts/obmenvsem.user.js +10 -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 +12 -30
  23. package/dist/userscripts/xhamster.user.js +12 -24
  24. package/dist/userscripts/xvideos.user.js +34 -6
  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 +60 -0
  28. package/src/core/data-handler/data-filter.ts +22 -96
  29. package/src/core/data-handler/data-manager.ts +75 -26
  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 +2 -1
  33. package/src/core/jabroni-config/scheme-selectors-mapping.ts +12 -0
  34. package/src/core/parsers/thumb-data-parser.ts +10 -16
  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 -6
  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 +4 -6
  41. package/src/userscripts/scripts/ebalka.ts +11 -3
  42. package/src/userscripts/scripts/eporner.ts +20 -39
  43. package/src/userscripts/scripts/erome.ts +9 -7
  44. package/src/userscripts/scripts/eroprofile.ts +5 -13
  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 +12 -6
  48. package/src/userscripts/scripts/namethatporn.ts +8 -15
  49. package/src/userscripts/scripts/nhentai.ts +6 -13
  50. package/src/userscripts/scripts/obmenvsem.ts +9 -3
  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 +14 -29
  54. package/src/userscripts/scripts/xhamster.ts +14 -17
  55. package/src/userscripts/scripts/xvideos.ts +33 -4
  56. package/src/utils/parsers/index.ts +19 -0
@@ -14,6 +14,42 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
14
14
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
15
15
 
16
16
  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, _a2, _i3, _n3, _t2, _e3, _s3, _l3, _b;
17
+ class DataFilterFn {
18
+ constructor(handle, deps = [], name, $preDefine) {
19
+ __publicField(this, "tag");
20
+ this.handle = handle;
21
+ this.deps = deps;
22
+ this.name = name;
23
+ this.$preDefine = $preDefine;
24
+ this.tag = `filter-${name}`;
25
+ }
26
+ static from(options, name) {
27
+ if (typeof options === "function") {
28
+ const deps = [name];
29
+ return new DataFilterFn(options, deps, name);
30
+ }
31
+ return new DataFilterFn(
32
+ options.handle,
33
+ options.deps,
34
+ name,
35
+ options.$preDefine
36
+ );
37
+ }
38
+ renderFn(state) {
39
+ const tag = this.tag;
40
+ return () => {
41
+ var _a3;
42
+ const preDefined = (_a3 = this.$preDefine) == null ? void 0 : _a3.call(this, state);
43
+ return (a2) => {
44
+ const condition = this.handle(a2, state, preDefined);
45
+ return {
46
+ condition,
47
+ tag
48
+ };
49
+ };
50
+ };
51
+ }
52
+ }
17
53
  function chunks(arr, size) {
18
54
  return Array.from(
19
55
  { length: Math.ceil(arr.length / size) },
@@ -397,6 +433,20 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
397
433
  const num = Number(n);
398
434
  return Number.isSafeInteger(num) ? num : or2;
399
435
  }
436
+ function parseNumberWithLetter(str) {
437
+ var _a3;
438
+ const multipliers = { k: 1e3, m: 1e6 };
439
+ const match = str.trim().match(/([\d., ]+)(\w)?/);
440
+ if (!match) return 0;
441
+ const s1 = match[1].replace(/,/g, ".").replace(/[ ]/g, "");
442
+ const s2 = s1.split(".").filter(Boolean).length < 3 ? s1 : s1.replace(".", "");
443
+ const num = parseFloat(s2);
444
+ const suffix = (_a3 = match[2]) == null ? void 0 : _a3.toLowerCase();
445
+ if (suffix && suffix in multipliers) {
446
+ return num * multipliers[suffix];
447
+ }
448
+ return num;
449
+ }
400
450
  function parseDataParams(str) {
401
451
  const paramsStr = decodeURI(str.trim()).split(";");
402
452
  return paramsStr.reduce(
@@ -418,13 +468,54 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
418
468
  function parseCssUrl(s) {
419
469
  return s.replace(/url\("|"\).*/g, "");
420
470
  }
421
- const _DataFilter = class _DataFilter {
471
+ function createTextFilter(filterName, dataPropName, positive) {
472
+ const filterNameValue = `${filterName}Words`;
473
+ return {
474
+ handle(el2, state, searchFilter) {
475
+ if (!Object.hasOwn(state, filterName) || !state[filterName]) return false;
476
+ return !(searchFilter == null ? void 0 : searchFilter(el2[dataPropName]));
477
+ },
478
+ $preDefine: (state) => {
479
+ const r = new RegexFilter(state[filterNameValue]);
480
+ if (positive) return (s) => r.hasEvery(s);
481
+ return (s) => r.hasNone(s);
482
+ },
483
+ deps: [filterNameValue]
484
+ };
485
+ }
486
+ const filterDuration = {
487
+ handle(el2, state, notInRange) {
488
+ if (!state.filterDuration) return false;
489
+ return !!(notInRange == null ? void 0 : notInRange(el2.duration));
490
+ },
491
+ $preDefine: (state) => {
492
+ const from = state.filterDurationFrom;
493
+ const to2 = state.filterDurationTo;
494
+ function notInRange(d2) {
495
+ return d2 < from || d2 > to2;
496
+ }
497
+ return notInRange;
498
+ },
499
+ deps: ["filterDurationFrom", "filterDurationTo"]
500
+ };
501
+ const defaultDataFilterFns = {
502
+ filterDuration,
503
+ filterExclude: createTextFilter("filterExclude", "title", false),
504
+ filterInclude: createTextFilter("filterInclude", "title", true),
505
+ filterUploaderExclude: createTextFilter("filterUploaderExclude", "uploader", false),
506
+ filterUploaderInclude: createTextFilter("filterUploaderInclude", "uploader", true),
507
+ filterHD: (el2, state) => state.filterHD && !el2.hd,
508
+ filterNonHD: (el2, state) => state.filterNonHD && el2.hd,
509
+ filterPrivate: (el2, state) => state.filterPrivate && el2.private,
510
+ filterPublic: (el2, state) => state.filterPublic && !el2.private
511
+ };
512
+ class DataFilter {
422
513
  constructor(rules) {
423
514
  __publicField(this, "filters", /* @__PURE__ */ new Map());
424
- __publicField(this, "customDataSelectorFns", {});
515
+ __publicField(this, "customDataFilterFns", {});
425
516
  __publicField(this, "filterMapping", {});
426
517
  this.rules = rules;
427
- this.registerFilters(rules.customDataSelectorFns);
518
+ this.registerFilters(rules.customDataFilterFns);
428
519
  this.applyCSSFilters();
429
520
  }
430
521
  static isFiltered(el2) {
@@ -438,87 +529,30 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
438
529
  }
439
530
  registerFilters(customFilters) {
440
531
  customFilters.forEach((o) => {
441
- if (typeof o === "string") {
442
- this.customDataSelectorFns[o] = _DataFilter.customDataSelectorFnsDefault[o];
443
- this.registerFilter(o);
444
- } else {
445
- const k2 = Object.keys(o)[0];
446
- this.customDataSelectorFns[k2] = o[k2];
447
- this.registerFilter(k2);
448
- }
532
+ const isStr = typeof o === "string";
533
+ const k2 = isStr ? o : Object.keys(o)[0];
534
+ this.customDataFilterFns[k2] = isStr ? defaultDataFilterFns[o] : o[k2];
535
+ this.registerFilter(k2);
449
536
  });
450
537
  }
451
- customSelectorParser(name, selector) {
452
- if ("handle" in selector) {
453
- return selector;
454
- } else {
455
- return { handle: selector, deps: [name] };
456
- }
457
- }
458
538
  registerFilter(customSelectorName) {
459
539
  var _a3;
460
- const handler = this.customSelectorParser(
461
- customSelectorName,
462
- this.customDataSelectorFns[customSelectorName]
540
+ const dataFilterFn = DataFilterFn.from(
541
+ this.customDataFilterFns[customSelectorName],
542
+ customSelectorName
463
543
  );
464
- const tag = `filter-${customSelectorName}`;
465
- (_a3 = [customSelectorName, ...handler.deps || []]) == null ? void 0 : _a3.forEach((name) => {
544
+ (_a3 = [customSelectorName, ...dataFilterFn.deps]) == null ? void 0 : _a3.forEach((name) => {
466
545
  Object.assign(this.filterMapping, { [name]: customSelectorName });
467
546
  });
468
- const fn2 = () => {
469
- var _a4;
470
- const preDefined = (_a4 = handler.$preDefine) == null ? void 0 : _a4.call(handler, this.rules.store.state);
471
- return (v2) => {
472
- const condition = handler.handle(v2, this.rules.store.state, preDefined);
473
- return {
474
- condition,
475
- tag
476
- };
477
- };
478
- };
479
- this.filters.set(customSelectorName, fn2);
547
+ this.filters.set(customSelectorName, dataFilterFn.renderFn(this.rules.store.state));
480
548
  }
481
549
  selectFilters(filters) {
482
550
  const selectedFilters = Object.keys(filters).filter((k2) => k2 in this.filterMapping).map((k2) => this.filterMapping[k2]).map((k2) => this.filters.get(k2));
483
551
  return selectedFilters;
484
552
  }
485
- };
486
- __publicField(_DataFilter, "customDataSelectorFnsDefault", {
487
- filterDuration: {
488
- handle(el2, state, notInRange) {
489
- if (!state.filterDuration) return false;
490
- return notInRange(el2.duration);
491
- },
492
- $preDefine: (state) => {
493
- const from = state.filterDurationFrom;
494
- const to2 = state.filterDurationTo;
495
- function notInRange(d2) {
496
- return d2 < from || d2 > to2;
497
- }
498
- return notInRange;
499
- },
500
- deps: ["filterDurationFrom", "filterDurationTo"]
501
- },
502
- filterExclude: {
503
- handle(el2, state, searchFilter) {
504
- if (!state.filterExclude) return false;
505
- return !searchFilter.hasNone(el2.title);
506
- },
507
- $preDefine: (state) => new RegexFilter(state.filterExcludeWords),
508
- deps: ["filterExcludeWords"]
509
- },
510
- filterInclude: {
511
- handle(el2, state, searchFilter) {
512
- if (!state.filterInclude) return false;
513
- return !searchFilter.hasEvery(el2.title);
514
- },
515
- $preDefine: (state) => new RegexFilter(state.filterIncludeWords),
516
- deps: ["filterIncludeWords"]
517
- }
518
- });
519
- let DataFilter = _DataFilter;
553
+ }
520
554
  class DataManager {
521
- constructor(rules, parentHomogenity) {
555
+ constructor(rules, containerHomogenity) {
522
556
  __publicField(this, "data", /* @__PURE__ */ new Map());
523
557
  __publicField(this, "lazyImgLoader", new LazyImgLoader(
524
558
  (target) => !DataFilter.isFiltered(target)
@@ -529,9 +563,9 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
529
563
  if (filtersToApply.length === 0) return;
530
564
  const iterator2 = this.data.values().drop(offset);
531
565
  let finished = false;
566
+ const updates = [];
532
567
  await new Promise((resolve) => {
533
568
  function runBatch(deadline) {
534
- const updates = [];
535
569
  while (deadline.timeRemaining() > 0) {
536
570
  const { value, done } = iterator2.next();
537
571
  finished = !!done;
@@ -541,13 +575,6 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
541
575
  updates.push({ e: value.element, tag, condition });
542
576
  }
543
577
  }
544
- if (updates.length > 0) {
545
- requestAnimationFrame(() => {
546
- updates.forEach((u) => {
547
- u.e.classList.toggle(u.tag, u.condition);
548
- });
549
- });
550
- }
551
578
  if (!finished) {
552
579
  requestIdleCallback(runBatch);
553
580
  } else {
@@ -556,6 +583,28 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
556
583
  }
557
584
  requestIdleCallback(runBatch);
558
585
  });
586
+ const parents = new Set(updates.map((u) => u.e.parentElement));
587
+ requestAnimationFrame(() => {
588
+ const revertDisplayStyle = [...parents].map((p) => {
589
+ const display = p == null ? void 0 : p.style.display;
590
+ if (!display) return void 0;
591
+ p.style.display = "none";
592
+ p.style.contain = "layout style paint";
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.tag, u.condition);
603
+ });
604
+ revertDisplayStyle.forEach((f) => {
605
+ f == null ? void 0 : f();
606
+ });
607
+ });
559
608
  });
560
609
  __publicField(this, "filterAll", async (offset) => {
561
610
  const keys = Array.from(this.dataFilter.filters.keys());
@@ -569,13 +618,17 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
569
618
  const dataOffset = this.data.size;
570
619
  const fragment = document.createDocumentFragment();
571
620
  const parent = container || this.rules.container;
572
- const homogenity = !!this.parentHomogenity;
621
+ const homogenity = !!this.containerHomogenity;
622
+ if (parent) {
623
+ parent.style.contain = "layout style paint";
624
+ parent.style.willChange = "contents";
625
+ }
573
626
  for (const thumbElement of thumbs) {
574
627
  const url = this.rules.thumbDataParser.getUrl(thumbElement);
575
628
  if (!url || this.data.has(url) || parent !== container && (parent == null ? void 0 : parent.contains(thumbElement)) || homogenity && !checkHomogenity(
576
629
  parent,
577
630
  thumbElement.parentElement,
578
- this.parentHomogenity
631
+ this.containerHomogenity
579
632
  )) {
580
633
  if (removeDuplicates) thumbElement.remove();
581
634
  continue;
@@ -590,26 +643,45 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
590
643
  }
591
644
  this.filterAll(dataOffset).then(() => {
592
645
  requestAnimationFrame(() => {
593
- parent.appendChild(fragment);
646
+ parent == null ? void 0 : parent.appendChild(fragment);
594
647
  });
595
648
  });
596
649
  });
597
650
  this.rules = rules;
598
- this.parentHomogenity = parentHomogenity;
651
+ this.containerHomogenity = containerHomogenity;
599
652
  this.dataFilter = new DataFilter(this.rules);
600
653
  }
601
654
  sortBy(key, direction = true) {
602
655
  if (this.data.size < 2) return;
603
- let sorted = this.data.values().toArray().sort((a2, b2) => {
604
- return a2[key] - b2[key];
656
+ const elements = this.data.values().toArray().filter((e) => e.element.parentElement !== null).map((e) => e);
657
+ const containers = new Set(elements.map((e) => e.element.parentElement));
658
+ containers.forEach((c) => {
659
+ c.style.contain = "layout style paint";
660
+ c.style.willChange = "contents";
605
661
  });
606
- if (!direction) sorted = sorted.reverse();
607
- const container = sorted[0].element.parentElement;
608
- container.style.visibility = "hidden";
609
- sorted.forEach((s) => {
610
- container.append(s.element);
662
+ const elementsByContainers = /* @__PURE__ */ new Map();
663
+ containers.forEach((c) => {
664
+ elementsByContainers.set(c, []);
611
665
  });
612
- container.style.visibility = "visible";
666
+ elements.forEach((e) => {
667
+ const parent = e.element.parentElement;
668
+ const container = elementsByContainers.get(parent);
669
+ container == null ? void 0 : container.push(e);
670
+ });
671
+ const dir = direction ? -1 : 1;
672
+ for (const [container, items] of elementsByContainers) {
673
+ items.sort((a2, b2) => (a2[key] - b2[key]) * dir);
674
+ const domNodes = items.map((e) => e.element);
675
+ const display = container.style.display;
676
+ container.style.display = "none";
677
+ container.replaceChildren(...domNodes);
678
+ requestAnimationFrame(() => {
679
+ container.style.display = display;
680
+ requestAnimationFrame(() => {
681
+ container.style.willChange = "auto";
682
+ });
683
+ });
684
+ }
613
685
  }
614
686
  }
615
687
  var extendStatics = function(d2, b2) {
@@ -2987,7 +3059,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2987
3059
  return paginationStrategy;
2988
3060
  }
2989
3061
  class ThumbDataParser {
2990
- constructor(strategy = "manual", selectors = {}, callback, stringsMeltInTitle = true) {
3062
+ constructor(strategy = "manual", selectors = {}, callback) {
2991
3063
  __publicField(this, "thumbDataSelectors", []);
2992
3064
  __publicField(this, "defaultThumbDataSelectors", [
2993
3065
  { name: "title", type: "string", selector: "[class *= title],[title]" },
@@ -2997,11 +3069,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
2997
3069
  selector: "[class *= uploader], [class *= user], [class *= name]"
2998
3070
  },
2999
3071
  { name: "duration", type: "duration", selector: "[class *= duration]" }
3072
+ // { name: 'views', type: 'float', selector: '[class *= view]' },
3000
3073
  ]);
3001
3074
  this.strategy = strategy;
3002
3075
  this.selectors = selectors;
3003
3076
  this.callback = callback;
3004
- this.stringsMeltInTitle = stringsMeltInTitle;
3005
3077
  this.preprocessCustomThumbDataSelectors();
3006
3078
  }
3007
3079
  autoParseText(thumb) {
@@ -3040,10 +3112,14 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3040
3112
  if (type === "duration") {
3041
3113
  return timeToSeconds(querySelectorText(thumb, selector));
3042
3114
  }
3115
+ if (type === "float") {
3116
+ const value = querySelectorText(thumb, selector);
3117
+ return parseNumberWithLetter(value);
3118
+ }
3043
3119
  return Number.parseInt(querySelectorText(thumb, selector));
3044
3120
  }
3045
3121
  static create(o = {}) {
3046
- return new ThumbDataParser(o.strategy, o.selectors, o.callback, o.stringsMeltInTitle);
3122
+ return new ThumbDataParser(o.strategy, o.selectors, o.callback);
3047
3123
  }
3048
3124
  getThumbData(thumb) {
3049
3125
  var _a3;
@@ -3051,19 +3127,11 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
3051
3127
  return this.autoParseText(thumb);
3052
3128
  }
3053
3129
  if (this.strategy === "auto-select") {
3054
- this.thumbDataSelectors = this.defaultThumbDataSelectors;
3130
+ this.thumbDataSelectors.push(...this.defaultThumbDataSelectors);
3055
3131
  }
3056
3132
  const thumbData = Object.fromEntries(
3057
3133
  this.thumbDataSelectors.map((s) => [s.name, this.getThumbDataWith(thumb, s)])
3058
3134
  );
3059
- if (this.stringsMeltInTitle) {
3060
- Object.entries(thumbData).forEach(([k2, v2]) => {
3061
- if (typeof v2 === "string" && k2 !== "title") {
3062
- thumbData.title = `${thumbData.title} ${k2}:${v2}`;
3063
- delete thumbData[k2];
3064
- }
3065
- });
3066
- }
3067
3135
  (_a3 = this.callback) == null ? void 0 : _a3.call(this, thumb, thumbData);
3068
3136
  return thumbData;
3069
3137
  }
@@ -9593,7 +9661,7 @@ Expected function or array of functions, received type ${typeof t}.`
9593
9661
  }
9594
9662
  const DefaultScheme = [
9595
9663
  {
9596
- title: "Text Filter",
9664
+ title: "Title Filter",
9597
9665
  collapsed: true,
9598
9666
  content: [
9599
9667
  { filterExclude: false, label: "exclude" },
@@ -9612,6 +9680,26 @@ Expected function or array of functions, received type ${typeof t}.`
9612
9680
  }
9613
9681
  ]
9614
9682
  },
9683
+ {
9684
+ title: "Uploader Filter",
9685
+ collapsed: true,
9686
+ content: [
9687
+ { filterUploaderExclude: false, label: "exclude" },
9688
+ {
9689
+ filterUploaderExcludeWords: "",
9690
+ label: "keywords",
9691
+ watch: "filterUploaderExclude",
9692
+ placeholder: "word, f:full_word, r:RegEx..."
9693
+ },
9694
+ { filterUploaderInclude: false, label: "include" },
9695
+ {
9696
+ filterUploaderIncludeWords: "",
9697
+ label: "keywords",
9698
+ watch: "filterUploaderInclude",
9699
+ placeholder: "word, f:full_word, r:RegEx..."
9700
+ }
9701
+ ]
9702
+ },
9615
9703
  {
9616
9704
  title: "Duration Filter",
9617
9705
  collapsed: true,
@@ -9633,6 +9721,7 @@ Expected function or array of functions, received type ${typeof t}.`
9633
9721
  },
9634
9722
  {
9635
9723
  title: "Sort By",
9724
+ collapsed: true,
9636
9725
  content: [
9637
9726
  {
9638
9727
  "sort by views": () => {
@@ -9644,8 +9733,29 @@ Expected function or array of functions, received type ${typeof t}.`
9644
9733
  }
9645
9734
  ]
9646
9735
  },
9736
+ {
9737
+ title: "Sort By Duration",
9738
+ collapsed: true,
9739
+ content: [
9740
+ {
9741
+ "sort by duration": () => {
9742
+ }
9743
+ }
9744
+ ]
9745
+ },
9746
+ {
9747
+ title: "Sort By Views",
9748
+ collapsed: true,
9749
+ content: [
9750
+ {
9751
+ "sort by views": () => {
9752
+ }
9753
+ }
9754
+ ]
9755
+ },
9647
9756
  {
9648
9757
  title: "Privacy Filter",
9758
+ collapsed: true,
9649
9759
  content: [
9650
9760
  { filterPrivate: false, label: "private" },
9651
9761
  { filterPublic: false, label: "public" },
@@ -9653,6 +9763,13 @@ Expected function or array of functions, received type ${typeof t}.`
9653
9763
  } }
9654
9764
  ]
9655
9765
  },
9766
+ {
9767
+ title: "HD Filter",
9768
+ content: [
9769
+ { filterHD: false, label: "hd" },
9770
+ { filterNonHD: false, label: "non-hd" }
9771
+ ]
9772
+ },
9656
9773
  {
9657
9774
  title: "Advanced",
9658
9775
  collapsed: true,
@@ -9672,6 +9789,11 @@ Expected function or array of functions, received type ${typeof t}.`
9672
9789
  {
9673
9790
  writeHistory: false,
9674
9791
  label: "write history"
9792
+ },
9793
+ {
9794
+ reset: () => {
9795
+ localStorage.removeItem("state_acephale");
9796
+ }
9675
9797
  }
9676
9798
  ]
9677
9799
  },
@@ -9697,7 +9819,8 @@ Expected function or array of functions, received type ${typeof t}.`
9697
9819
  __publicField(this, "destroy$", new Subject());
9698
9820
  __publicField(this, "directionalEventObservable$");
9699
9821
  __publicField(this, "eventsMap", {
9700
- "sort by duration": (direction) => this.dataManager.sortBy("duration", direction)
9822
+ "sort by duration": (direction) => this.dataManager.sortBy("duration", direction),
9823
+ "sort by views": (direction) => this.dataManager.sortBy("views", direction)
9701
9824
  });
9702
9825
  this.store = store;
9703
9826
  this.dataManager = dataManager;
@@ -9728,13 +9851,22 @@ Expected function or array of functions, received type ${typeof t}.`
9728
9851
  setupStoreListeners() {
9729
9852
  var _a3;
9730
9853
  (_a3 = this.directionalEventObservable$) == null ? void 0 : _a3.subscribe((e) => {
9731
- this.eventsMap[e.type](e.direction);
9854
+ var _a4, _b2;
9855
+ (_b2 = (_a4 = this.eventsMap)[e.type]) == null ? void 0 : _b2.call(_a4, e.direction);
9732
9856
  });
9733
9857
  this.store.stateSubject.pipe(takeUntil(this.destroy$)).subscribe((a2) => {
9734
9858
  this.dataManager.applyFilters(a2);
9735
9859
  });
9736
9860
  }
9737
9861
  }
9862
+ function getSelectorFnsFromScheme(xs2) {
9863
+ const keys = xs2.flatMap((s) => {
9864
+ const schemeBlock = DefaultScheme.find((e) => e.title === s);
9865
+ if (!schemeBlock) return [];
9866
+ return schemeBlock.content.flatMap((c) => Object.keys(c));
9867
+ });
9868
+ return keys.filter((k2) => k2 in defaultDataFilterFns);
9869
+ }
9738
9870
  class Rules {
9739
9871
  constructor(options) {
9740
9872
  __publicField(this, "thumb", {});
@@ -9749,12 +9881,8 @@ Expected function or array of functions, received type ${typeof t}.`
9749
9881
  __publicField(this, "paginationStrategyOptions", {});
9750
9882
  __publicField(this, "paginationStrategy");
9751
9883
  __publicField(this, "dataManager");
9752
- __publicField(this, "dataHomogenity");
9753
- __publicField(this, "customDataSelectorFns", [
9754
- "filterInclude",
9755
- "filterExclude",
9756
- "filterDuration"
9757
- ]);
9884
+ __publicField(this, "containerHomogenity");
9885
+ __publicField(this, "customDataFilterFns", []);
9758
9886
  __publicField(this, "animatePreview");
9759
9887
  __publicField(this, "storeOptions");
9760
9888
  __publicField(this, "schemeOptions", []);
@@ -9776,7 +9904,8 @@ Expected function or array of functions, received type ${typeof t}.`
9776
9904
  this.paginationStrategy = getPaginationStrategy(this.paginationStrategyOptions);
9777
9905
  this.store = this.createStore();
9778
9906
  this.gui = this.createGui();
9779
- this.dataManager = new DataManager(this, this.dataHomogenity);
9907
+ this.hookDataFilterFns();
9908
+ this.dataManager = new DataManager(this, this.containerHomogenity);
9780
9909
  this.inputController = new JabronioGuiController(this.store, this.dataManager);
9781
9910
  this.reset();
9782
9911
  }
@@ -9795,6 +9924,12 @@ Expected function or array of functions, received type ${typeof t}.`
9795
9924
  get observable() {
9796
9925
  return this.intersectionObservable || this.paginationStrategy.getPaginationElement();
9797
9926
  }
9927
+ hookDataFilterFns() {
9928
+ const defaultFilterFns = getSelectorFnsFromScheme(
9929
+ this.schemeOptions.filter((s) => typeof s === "string")
9930
+ );
9931
+ this.customDataFilterFns.push(...defaultFilterFns);
9932
+ }
9798
9933
  createStore() {
9799
9934
  const config2 = { ...StoreStateDefault, ...this.storeOptions };
9800
9935
  this.store = new Up(config2);
@@ -9850,7 +9985,7 @@ Expected function or array of functions, received type ${typeof t}.`
9850
9985
  });
9851
9986
  this.mutationObservers = [];
9852
9987
  this.paginationStrategy = getPaginationStrategy(this.paginationStrategyOptions);
9853
- this.dataManager = new DataManager(this, this.dataHomogenity);
9988
+ this.dataManager = new DataManager(this, this.containerHomogenity);
9854
9989
  this.inputController.dispose();
9855
9990
  this.inputController = new JabronioGuiController(this.store, this.dataManager);
9856
9991
  this.resetInfiniteScroller();
@@ -9898,6 +10033,7 @@ Expected function or array of functions, received type ${typeof t}.`
9898
10033
  exports2.parseDataParams = parseDataParams;
9899
10034
  exports2.parseHtml = parseHtml;
9900
10035
  exports2.parseIntegerOr = parseIntegerOr;
10036
+ exports2.parseNumberWithLetter = parseNumberWithLetter;
9901
10037
  exports2.parseUrl = parseUrl;
9902
10038
  exports2.querySelectorLast = querySelectorLast;
9903
10039
  exports2.querySelectorLastNumber = querySelectorLastNumber;