JanitorAI Token Filter

Filters character cards on JanitorAI by token count

当前为 2025-04-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name JanitorAI Token Filter
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.9
  5. // @description Filters character cards on JanitorAI by token count
  6. // @author You
  7. // @match https://janitorai.com/*
  8. // @grant none
  9. // @license FFA
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. let MIN_TOKENS = 2000;
  16.  
  17. function parseTokens(tokenText) {
  18. try {
  19. let cleanText = tokenText.replace(/<!--[\s\S]*?-->/g, '').replace('tokens', '').trim();
  20. if (cleanText.includes('k')) {
  21. return parseFloat(cleanText.replace('k', '')) * 1000;
  22. }
  23. return parseInt(cleanText, 10) || 0;
  24. } catch (error) {
  25. return 0;
  26. }
  27. }
  28.  
  29. function filterCards() {
  30. const cards = document.querySelectorAll('.chakra-stack.css-1s5evre');
  31. cards.forEach(card => {
  32. const tokenElement = card.querySelector('.chakra-text.css-jccmq6');
  33. if (!tokenElement) return;
  34.  
  35. const tokenCount = parseTokens(tokenElement.textContent);
  36. const parentContainer = card.closest('.css-1sxhvxh');
  37. if (parentContainer) {
  38. parentContainer.style.display = tokenCount < MIN_TOKENS ? 'none' : '';
  39. }
  40. });
  41. }
  42.  
  43. function createTokenSelector() {
  44. const select = document.createElement('select');
  45. select.id = 'token-filter-select';
  46. select.style.position = 'fixed';
  47. select.style.top = '10px';
  48. select.style.left = '10px';
  49. select.style.zIndex = '99999';
  50. select.style.padding = '4px 8px';
  51. select.style.backgroundColor = '#4a4a4a'; // Темно-серый фон
  52. select.style.border = '1px solid #666'; // Чуть светлее серая граница
  53. select.style.borderRadius = '4px';
  54. select.style.fontSize = '12px';
  55. select.style.color = '#fff'; // Белый текст для контраста
  56. select.style.cursor = 'pointer';
  57.  
  58. const options = [500, 1000, 1500, 2000, 2500, 3000, 4000, 5000];
  59. options.forEach(value => {
  60. const option = document.createElement('option');
  61. option.value = value;
  62. option.text = `${value} tokens`;
  63. if (value === MIN_TOKENS) option.selected = true;
  64. select.appendChild(option);
  65. });
  66.  
  67. select.addEventListener('change', (e) => {
  68. MIN_TOKENS = parseInt(e.target.value);
  69. filterCards();
  70. });
  71.  
  72. const appendSelector = () => {
  73. if (document.body) {
  74. document.body.appendChild(select);
  75. } else {
  76. setTimeout(appendSelector, 500);
  77. }
  78. };
  79. appendSelector();
  80. }
  81.  
  82. function initialize() {
  83. createTokenSelector();
  84. filterCards();
  85. }
  86.  
  87. const tryInitialize = () => {
  88. if (document.body) {
  89. initialize();
  90. const observer = new MutationObserver(() => {
  91. setTimeout(filterCards, 500);
  92. });
  93. observer.observe(document.body, { childList: true, subtree: true });
  94. } else {
  95. setTimeout(tryInitialize, 1000);
  96. }
  97. };
  98.  
  99. tryInitialize();
  100. })();