Greasy Fork is available in English.

GreasyFork Search

Søk med GoogleGreasyForkogSleazyForkøvre skrift

  1. // ==UserScript==
  2. // @name GreasyFork Search
  3. // @name:zh-CN GreasyFork Search
  4. // @description:zh-CN 使用谷歌搜索GreasyFork和SleazyFork上的脚本
  5. // @name:ar GreasyFork Search
  6. // @description:ar البحث باستخدام جوجلGreasyForkوSleazyForkالنص العلوي
  7. // @name:bg GreasyFork Search
  8. // @description:bg Търсете с GoogleGreasyForkиSleazyForkгорен скрипт
  9. // @name:cs GreasyFork Search
  10. // @description:cs Hledejte pomocí GoogleGreasyForkaSleazyForkhorní písmo
  11. // @name:da GreasyFork Search
  12. // @description:da Søg ved hjælp af GoogleGreasyForkogSleazyForkøverste skrift
  13. // @name:de GreasyFork Search
  14. // @description:de Suchen Sie mit GoogleGreasyForkUndSleazyForkOberschrift
  15. // @name:el GreasyFork Search
  16. // @description:el Αναζήτηση χρησιμοποιώντας το GoogleGreasyForkκαιSleazyForkπάνω σενάριο
  17. // @name:en GreasyFork Search
  18. // @description:en Search using GoogleGreasyForkandSleazyForkupper script
  19. // @name:eo GreasyFork Search
  20. // @description:eo Serĉu per GugloGreasyForkkajSleazyForksupra manuskripto
  21. // @name:es GreasyFork Search
  22. // @description:es Buscar usando GoogleGreasyForkySleazyForkguión superior
  23. // @name:fi GreasyFork Search
  24. // @description:fi Hae Googlen avullaGreasyForkjaSleazyForkylempi kirjoitus
  25. // @name:fr GreasyFork Search
  26. // @description:fr Rechercher avec GoogleGreasyForketSleazyForkécriture supérieure
  27. // @name:he GreasyFork Search
  28. // @description:he חפש באמצעות גוגלGreasyForkוSleazyForkכתב עליון
  29. // @name:hr GreasyFork Search
  30. // @description:hr Pretražujte pomoću GoogleaGreasyForkiSleazyForkgornja skripta
  31. // @name:hu GreasyFork Search
  32. // @description:hu Keressen a Google segítségévelGreasyForkésSleazyForkfelső szkript
  33. // @name:id GreasyFork Search
  34. // @description:id Cari menggunakan GoogleGreasyForkDanSleazyForkskrip atas
  35. // @name:it GreasyFork Search
  36. // @description:it Cerca utilizzando GoogleGreasyForkESleazyForkscrittura superiore
  37. // @name:ja GreasyFork Search
  38. // @description:ja Googleを使って検索するGreasyForkそしてSleazyFork上的脚本
  39. // @name:ka GreasyFork Search
  40. // @description:ka ძიება Google-ის გამოყენებითGreasyForkდაSleazyForkზედა დამწერლობა
  41. // @name:ko GreasyFork Search
  42. // @description:ko Google을 사용하여 검색GreasyFork그리고SleazyFork상적 각본
  43. // @name:nl GreasyFork Search
  44. // @description:nl Zoek met GoogleGreasyForkEnSleazyForkbovenste schrift
  45. // @name:nb GreasyFork Search
  46. // @description:nb Søk med GoogleGreasyForkogSleazyForkøvre skrift
  47. // @name:pl GreasyFork Search
  48. // @description:pl Szukaj za pomocą GoogleGreasyForkISleazyForkgórny skrypt
  49. // @name:pt-BR GreasyFork Search
  50. // @description:pt-BR Pesquise usando o GoogleGreasyForkeSleazyForkscript superior
  51. // @name:ro GreasyFork Search
  52. // @description:ro Căutați folosind GoogleGreasyForkşiSleazyForkscriptul superior
  53. // @name:ru GreasyFork Search
  54. // @description:ru Поиск с помощью GoogleGreasyForkиSleazyForkверхний сценарий
  55. // @name:sk GreasyFork Search
  56. // @description:sk Hľadajte pomocou GoogleGreasyForkaSleazyForkhorné písmo
  57. // @name:sr GreasyFork Search
  58. // @description:sr Претражујте помоћу Гоогле-аGreasyForkиSleazyForkгорње писмо
  59. // @name:sv GreasyFork Search
  60. // @description:sv Sök med GoogleGreasyForkochSleazyForkövre skrift
  61. // @name:th GreasyFork Search
  62. // @description:th ค้นหาโดยใช้ GoogleGreasyForkและSleazyForkสคริปต์ด้านบน
  63. // @name:tr GreasyFork Search
  64. // @description:tr Google’ı kullanarak arama yapınGreasyForkVeSleazyForküst yazı
  65. // @name:ug GreasyFork Search
  66. // @description:ug Google نى ئىشلىتىپ ئىزدەشGreasyForkۋەSleazyForkئۈستى قوليازما
  67. // @name:uk GreasyFork Search
  68. // @description:uk Пошук за допомогою GoogleGreasyForkіSleazyForkверхній скрипт
  69. // @name:vi GreasyFork Search
  70. // @description:vi Tìm kiếm bằng GoogleGreasyForkVàSleazyForkchữ viết trên
  71. // @name:zh-TW GreasyFork Search
  72. // @description:zh-TW 使用谷歌搜尋GreasyFork和SleazyFork上體文字
  73. // @name:zh-HK GreasyFork Search
  74. // @description:zh-HK 使用谷歌搜尋GreasyFork和SleazyFork上體文字
  75. // @name:fr-CA GreasyFork Search
  76. // @description:fr-CA Rechercher avec GoogleGreasyForketSleazyForkécriture supérieure
  77. // @namespace https://github.com/ChinaGodMan/UserScripts
  78. // @version 0.6.5.23
  79. // @description To search scripts using Google Search
  80. // @author CY Fung , 人民的勤务员 <china.qinwuyuan@gmail.com>
  81. // @match https://greatest.deepsurf.us/*
  82. // @match https://sleazyfork.org/*
  83. // @icon data:image/png;base64,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
  84. // @iconbak https://greatest.deepsurf.us/vite/assets/blacklogo96-CxYTSM_T.png
  85. // @require https://fastly.jsdelivr.net/npm/jstat@1.9.6/dist/jstat.min.js
  86. // @grant none
  87. // @license MIT
  88.  
  89. // ==/UserScript==
  90.  
  91.  
  92.  
  93. (() => {
  94.  
  95.  
  96.  
  97. function jacobi(a) {
  98. var n = a.length
  99. var trial = n * n * 2
  100. var e = jStat.identity(n, n)
  101. var ev = []
  102. var i, j, p, q, maxim, s
  103. let vaildResult = false
  104. outer: while (trial-- > 0) {
  105. maxim = a[0][1]
  106. p = 0
  107. q = 1
  108. for (i = 0; i < n; i++) {
  109. for (j = 0; j < n; j++) {
  110. if (i != j) {
  111. let t = Math.abs(a[i][j])
  112. if (maxim < t) {
  113. maxim = t
  114. p = i
  115. q = j
  116. }
  117. }
  118. }
  119. }
  120.  
  121. s = jStat.identity(n, n)
  122.  
  123. let tanValue = 2 * a[p][q] / (a[p][p] - a[q][q])
  124.  
  125. let cosTwoTheta = Math.sqrt(1 / (1 + tanValue * tanValue))
  126. let cosTheta = Math.sqrt(.5 * (1 + cosTwoTheta))
  127. let sinTheta = Math.sqrt(.5 * (1 - cosTwoTheta))
  128.  
  129. s[p][p] = cosTheta
  130. s[p][q] = -sinTheta
  131. s[q][p] = sinTheta
  132. s[q][q] = cosTheta
  133.  
  134. e = jStat.multiply(e, s)
  135. a = jStat.multiply(jStat.multiply(jStat.transpose(s), a), s)
  136.  
  137. for (i = 0; i < n; i++) {
  138. for (j = i + 1; j < n; j++) {
  139. if (Math.abs(a[i][j]) > .0004) {
  140. continue outer
  141. }
  142. }
  143. }
  144.  
  145. vaildResult = true
  146. break
  147. }
  148. if (!vaildResult) {
  149. console.warn('The matrix is not symmetric.')
  150. return null
  151. }
  152. for (i = 0; i < n; i++) ev.push(a[i][i])
  153. //returns both the eigenvalue and eigenmatrix
  154. return [e, ev]
  155. }
  156.  
  157.  
  158.  
  159. function getVN(A) {
  160. // normalized the matrix values such that det(A) will be a finite value close to 1.0
  161. // vn = sqrt( ( column_vector_1 ^2 + column_vector_2 ^2 + ... + column_vector_n ^2 ) / n )
  162. let vn = 0
  163. const AT = jStat.transpose(A)
  164. let N = AT.length
  165. for (let i = 0; i < N; i++) {
  166. vn += jStat.dot(AT[i], AT[i])
  167. }
  168. vn = Math.sqrt(vn / N)
  169. return vn
  170. }
  171.  
  172. function subtractLambdaFromDiagonal(matrix, lambda) {
  173. // A - lambda I
  174. return matrix.map((row, rowIndex) => row.map((val, colIndex) => rowIndex === colIndex ? val - lambda : val))
  175. }
  176.  
  177.  
  178. function eigenvalueNewton(A, lambda0) {
  179. const N = A.length
  180. const epsilon = 1e-5 // epsilon is applied on the normalized scale of lambda
  181. const maxTrial = 8
  182.  
  183. function f(lambda) {
  184. return jStat.det(subtractLambdaFromDiagonal(A, lambda))
  185. }
  186.  
  187. function fPrime(lambda) {
  188. return (f(lambda + epsilon) - f(lambda)) / epsilon
  189. }
  190.  
  191. let x_k = lambda0
  192. let positiveSign = 0
  193. let negativeSign = 0
  194. for (let i = 0; i < maxTrial; i++) {
  195. const fx = f(x_k)
  196. const fxPrime = fPrime(x_k)
  197. const diff = fx / fxPrime
  198. if (isNaN(diff)) return x_k // ignore f/f'
  199. const x_k1 = x_k - diff
  200. if ((diff > 0 ? diff : -diff) < epsilon) {
  201. return x_k1
  202. }
  203. x_k = x_k1
  204. if (fx > 0) positiveSign = 1
  205. else if (fx < 0) negativeSign = 1
  206. }
  207. return positiveSign && negativeSign ? x_k : lambda0 // avoid diverging iterations
  208. }
  209.  
  210. function vectorNorm(v) {
  211. // Math.sqrt(v dot v), same as jStat.norm(jStat.transpose(v))
  212. let s = 0
  213. for (const k of v) s += k[0] * k[0]
  214. return Math.sqrt(s)
  215. }
  216.  
  217. function isUnitVector(v, tol = 0.01) {
  218. // Check if it is likely a unit vector
  219. let s = 0
  220. for (const k of v) {
  221. s += k[0] * k[0]
  222. if (s > 1 + tol) return false
  223. }
  224. return s > 1 - tol
  225. }
  226.  
  227. jStat.jacobiOri = jStat.jacobi
  228. // https://www.statskingdom.com/pca-calculator.html
  229. jStat.jacobi = function (C) {
  230.  
  231. const vn = getVN(C)
  232. C = jStat.multiply(C, 1 / vn)
  233. let r1 = jacobi(C)
  234. // let r0 = JSON.parse(JSON.stringify(r1))
  235. // r0[1] = r0[1].map(v => vn * v);
  236. let A = C
  237. let eigenvectors = r1[0]
  238. let eigenvalues = r1[1]
  239. const iterationCount = 4
  240.  
  241. for (let i = 0; i < eigenvalues.length; i++) {
  242. let q, m
  243. q = jStat.transpose(eigenvectors[i])
  244. if (!isUnitVector(q)) break
  245. eigenvalues[i] = eigenvalueNewton(A, eigenvalues[i]) // refine eigenvalues obtained in jacobiOri
  246.  
  247. // inverse power method (A-lambda I) y_k = b_{k-1}
  248. // b_k = y_k / norm(y_k)
  249. let M = subtractLambdaFromDiagonal(A, eigenvalues[i])
  250. for (let j = 0; j < iterationCount; j++) {
  251. m = jStat.transpose(jStat.gauss_elimination(M, q))
  252. m = jStat.multiply(m, 1 / vectorNorm(m))
  253. if (!isUnitVector(m)) break // avoid Inf / NaN error
  254. q = m
  255. }
  256. eigenvectors[i] = jStat.transpose(q)
  257.  
  258. }
  259. r1[1] = r1[1].map(v => vn * v)
  260. return r1
  261. }
  262.  
  263.  
  264.  
  265. })()
  266.  
  267.  
  268. jStat.PCA = function PCA(X) {
  269. var m = X.length
  270. var n = X[0].length
  271. var i = 0
  272. var j, temp1
  273. var u = []
  274. var D = []
  275. var result = []
  276. var temp2 = []
  277. var Y = []
  278. var Bt = []
  279. var B = []
  280. var C = []
  281. var V = []
  282. var Vt = []
  283. for (i = 0; i < m; i++) {
  284. u[i] = jStat.sum(X[i]) / n
  285. }
  286. for (i = 0; i < n; i++) {
  287. B[i] = []
  288. for (j = 0; j < m; j++) {
  289. B[i][j] = X[j][i] - u[j]
  290. }
  291. }
  292. B = jStat.transpose(B)
  293. for (i = 0; i < m; i++) {
  294. C[i] = []
  295. for (j = 0; j < m; j++) {
  296. C[i][j] = (jStat.dot([B[i]], [B[j]])) / (n - 1)
  297. }
  298. }
  299. result = jStat.jacobi(C)
  300. V = result[0]
  301. D = result[1]
  302.  
  303. Vt = jStat.transpose(V)
  304.  
  305.  
  306. let vd = []
  307. for (i = 0; i < D.length; i++) {
  308. vd[i] = {
  309. Vt: Vt[i],
  310. D: D[i],
  311. k: D[i] * D[i]
  312. }
  313. }
  314.  
  315. vd.sort((a, b) => {
  316. return b.k - a.k
  317. })
  318.  
  319. Vt = vd.map(e => e.Vt)
  320. D = vd.map(e => e.D)
  321.  
  322.  
  323.  
  324. V = null
  325.  
  326.  
  327. Bt = jStat.transpose(B)
  328.  
  329. let pcs_11 = []
  330. let pt_11 = [1, 1]
  331. for (i = 0; i < m; i++) {
  332.  
  333.  
  334. pcs_11[i] = jStat.dot([Vt[i]], [pt_11])
  335. if (pcs_11[i] < 0) Vt[i] = jStat.multiply(Vt[i], -1)
  336. pcs_11[i] = jStat.dot([Vt[i]], [pt_11])
  337. }
  338.  
  339.  
  340.  
  341.  
  342.  
  343. for (i = 0; i < m; i++) {
  344. Y[i] = []
  345. for (j = 0; j < Bt.length; j++) {
  346. Y[i][j] = jStat.dot([Vt[i]], [Bt[j]])
  347. }
  348. }
  349. return [X, D, Vt, Y]
  350. };
  351.  
  352. (function () {
  353. 'use strict'
  354.  
  355. let input = document.querySelector('form input[name="q"]')
  356. if (!(input instanceof HTMLInputElement)) return
  357. let form = input.closest('form')
  358. if (!(form instanceof HTMLFormElement)) return
  359.  
  360.  
  361. let locales = [...document.querySelectorAll('select#language-selector-locale > option')].map(x => x.value)
  362.  
  363. document.head.appendChild(document.createElement('style')).textContent = `
  364.  
  365.  
  366. @keyframes rs1tmAnimation {
  367. 0% {
  368. background-position-x: 3px;
  369. }
  370. 100% {
  371. background-position-x: 4px;
  372. }
  373. }
  374.  
  375. form.rs1tm{
  376. position: fixed;
  377. top:-300px;
  378. left:-300px;
  379. width: 1px;
  380. height: 1px;
  381. contain: strict;
  382. display: flex;
  383. overflow: hidden;
  384. animation: rs1tmAnimation 1ms linear 1ms 1 normal forwards;
  385. }
  386.  
  387. `
  388. document.addEventListener('animationstart', (evt) => {
  389.  
  390. if (evt.animationName === 'rs1tmAnimation') {
  391. const target = evt.target
  392. target && target.parentNode && target.remove()
  393. }
  394.  
  395. }, true)
  396.  
  397. window.callback947 = function (rainijpolynomialRegressionJs) {
  398. if (!rainijpolynomialRegressionJs) return
  399. const { PolynomialFeatures, PolynomialRegressor, RegressionError } = rainijpolynomialRegressionJs
  400. if (!PolynomialFeatures || !PolynomialRegressor || !RegressionError) return
  401.  
  402. console.log(rainijpolynomialRegressionJs)
  403. }
  404.  
  405. form.addEventListener('submit', function (evt) {
  406.  
  407. try {
  408.  
  409.  
  410. let form = evt.target
  411. if (!(form instanceof HTMLFormElement)) return
  412. let input = form.querySelector('input[name="q"]')
  413. if (!(input instanceof HTMLInputElement)) return
  414.  
  415. if (form.classList.contains('rs1tm')) return
  416.  
  417. let value = input.value
  418. const lang = document.documentElement.lang || ''
  419.  
  420. let useLang = false
  421.  
  422.  
  423. let u = 0
  424. let isGoogleSearch = false
  425.  
  426. let sites = []
  427.  
  428. const split = value.split(/\s+/)
  429. let forceLang = 'all'
  430. let reformedSplit = []
  431. for (const s of split) {
  432.  
  433. if (!isGoogleSearch && /^[a-z][a-z0-9_-]{2,}(\.[a-z][a-z0-9_-]{2,})*(\.[a-z-]{2,4})+$/.test(s)) {
  434. if (/\.(js|css|html|htm|xml|img|svg|txt|php|cgi|xhtml|ini|vue|xhr|ajax)$/.test(s)) {
  435. reformedSplit.push(s)
  436. } else {
  437. sites.push(s)
  438. }
  439. } else if (s === 'js') {
  440. forceLang = 'js'; reformedSplit.push(s)
  441. } else if (s === 'css') {
  442. forceLang = 'css'; reformedSplit.push(s)
  443. } else if (s === 'user.js') {
  444. forceLang = 'js'
  445. } else if (s === 'user.css') {
  446. forceLang = 'css'
  447. } else if (s === '"js"') {
  448. reformedSplit.push('js')
  449. } else if (s === '"css"') {
  450. reformedSplit.push('css')
  451. } else if (u === 0 && s === 'g') {
  452. isGoogleSearch = true
  453. } else if (locales.indexOf(s) >= 0 || s === lang) {
  454. useLang = s
  455. } else {
  456. reformedSplit.push(s)
  457. }
  458. u++
  459. }
  460. console.log(sites)
  461.  
  462. value = reformedSplit.join(' ')
  463.  
  464. let onlySite = ''
  465.  
  466. if (sites.length === 1 && sites[0]) {
  467. onlySite = sites[0]
  468. }
  469.  
  470. /*
  471. if (!isGoogleSearch && onlySite && /\.\w+\.\w+/.test(onlySite)) {
  472. alert('Greasy Fork only lists eTLD+1.');
  473. evt.preventDefault();
  474. evt.stopImmediatePropagation();
  475. evt.stopPropagation();
  476. return;
  477. }
  478. */
  479.  
  480.  
  481. if (isGoogleSearch && value) {
  482. let q = value.replace('g ', '')
  483.  
  484. let m = '-inurl%3A%22%2Fusers%2F%22+-inurl%3A%22%2Fdiscussions%22-inurl%3A%22%2Fstats%22+-inurl%3A%22%2Ffeedback%22+-inurl%3A%22%2Fcode%22+-inurl%3A%22q%3D%22+-inurl%3A%22%2Fby-site%2F%22+inurl%3A%22%2Fscripts%2F%22+site%3A'
  485. var currentUrl = window.location.origin
  486. var index1 = currentUrl.indexOf('sleazyfork')
  487. var index2 = currentUrl.indexOf('greasyfork')//搜索
  488. if (index2 !== -1) {
  489. m = m + 'greatest.deepsurf.us'
  490. }
  491. if (index1 !== -1) {
  492. m = m + 'sleazyfork.org'
  493. }
  494. let lr = useLang ? `&lr=lang_${useLang}` : ''
  495. evt.preventDefault()
  496. evt.stopImmediatePropagation()
  497. evt.stopPropagation()
  498.  
  499. location.href = `https://www.google.com/search?q=${encodeURIComponent(q)}+${m}${lr}`
  500.  
  501. } else if (!isGoogleSearch && (value || onlySite)) {
  502.  
  503.  
  504. let newForm = document.createElement('form')
  505. newForm.className = 'rs1tm'
  506. const copyAttr = (x) => {
  507. let t = form.getAttribute(x)
  508. if (typeof t === 'string') newForm.setAttribute(x, t)
  509. }
  510. copyAttr('action')
  511. copyAttr('accept-charset')
  512. copyAttr('method')
  513. newForm.innerHTML = '<input name="q" type="hidden" value="" /><input name="site" type="hidden" /><input name="language" type="hidden" value="all" /><input name="sort" type="hidden" />'
  514.  
  515.  
  516. const nq = newForm.querySelector('input[name="q"]')
  517. const language = newForm.querySelector('input[name="language"]')
  518. const site = newForm.querySelector('input[name="site"]')
  519. const sort = newForm.querySelector('input[name="sort"]')
  520.  
  521. value = value.replace(/\s+/g, ' ')
  522. site.value = onlySite
  523.  
  524. if (form.getAttribute('action') === `/${lang}/scripts` && useLang && useLang !== lang) {
  525. form.setAttribute('action', `/${useLang}/scripts`)
  526. }
  527.  
  528.  
  529. if (site.value === '') site.remove()
  530.  
  531. nq.value = value
  532.  
  533. language.value = forceLang
  534.  
  535. if (language.value === '') language.remove()
  536.  
  537.  
  538. sort.value = 'updated'
  539.  
  540. let sorting = document.querySelector('#script-list-sort')
  541. if (sorting) {
  542. let sorts1 = {
  543. nil: 0,
  544. daily_installs: 0,
  545. total_installs: 0,
  546. ratings: 0,
  547. created: 0,
  548. updated: 0,
  549. name: 0
  550. }
  551. let sorts2 = {
  552. daily_installs: 0,
  553. total_installs: 0,
  554. ratings: 0,
  555. created: 0,
  556. updated: 0,
  557. name: 0
  558. }
  559. const allOptions = sorting.querySelectorAll('.list-option')
  560. const sorts = allOptions.length === 6 ? (sorts2) : (sorts1)
  561. const keys = Object.keys(sorts)
  562.  
  563. if (allOptions.length === keys.length) {
  564.  
  565.  
  566. for (const key of keys) {
  567. let e = `.list-option:not(.list-current) a[href$="sort=${key}"]`
  568. if (key === 'nil') {
  569. e = '.list-option:not(.list-current) a[href]:not([href*="sort="])'
  570. e = sorting.querySelector(e)
  571. } else {
  572. e = sorting.querySelector(e)
  573. }
  574.  
  575. if (e) {
  576. sorts[key] = 1
  577. }
  578.  
  579. }
  580.  
  581.  
  582.  
  583. let p = Object.entries(sorts).filter(r => !r[1])
  584. if (p.length === 1) {
  585. sort.value = p[0][0]
  586. }
  587.  
  588. }
  589.  
  590. }
  591.  
  592.  
  593.  
  594.  
  595. if (sort.value === '') sort.remove()
  596.  
  597. evt.preventDefault()
  598. evt.stopImmediatePropagation()
  599. evt.stopPropagation()
  600.  
  601. form.parentNode.insertBefore(newForm, form)
  602. newForm.submit()
  603. Promise.resolve().then(() => {
  604. newForm.remove()
  605. })
  606.  
  607.  
  608. } else {
  609. evt.preventDefault()
  610. evt.stopImmediatePropagation()
  611. evt.stopPropagation()
  612. }
  613.  
  614. } catch (e) {
  615. console.log(e)
  616.  
  617. evt.preventDefault()
  618. evt.stopImmediatePropagation()
  619. evt.stopPropagation()
  620. }
  621.  
  622. })
  623.  
  624. // Your code here...
  625. })();
  626.  
  627. (() => {
  628.  
  629. function prettyMatrix(A) {
  630. let w = ''
  631. for (let i = 0; i < A.length; i++) {
  632. for (let j = 0; j < A[i].length; j++) {
  633. w += A[i][j].toFixed(4) + '\t'
  634. }
  635. w += '\n\t'
  636. }
  637. return '[\n\t' + w.trim() + '\n]'
  638. }
  639.  
  640.  
  641. requestAnimationFrame(() => {
  642.  
  643. setTimeout(() => {
  644.  
  645. if ((location.search.includes('sort=updated') || location.search.includes('sort=created')) && location.pathname.endsWith('/scripts')) { } else return
  646. let items = document.querySelectorAll('[data-script-id][data-script-daily-installs][data-script-total-installs]')
  647.  
  648. let data = [...items].map(e => ({
  649. id: parseInt(e.getAttribute('data-script-id')),
  650. daily: parseInt(e.getAttribute('data-script-daily-installs')),
  651. total: parseInt(e.getAttribute('data-script-total-installs'))
  652. })).filter(e => e.id && !isNaN(e.daily) && !isNaN(e.total))
  653.  
  654. const daily = data.map(d => d.daily)
  655. const total = data.map(d => d.total)
  656. dailyMean = jStat.mean(daily)
  657. dailySD = jStat.stdev(daily, true)
  658. totalMean = jStat.mean(total)
  659. totalSD = jStat.stdev(total, true)
  660.  
  661. const uDaily = jStat.multiply(jStat.subtract(daily, dailyMean), 1 / dailySD)
  662. const uTotal = jStat.multiply(jStat.subtract(total, totalMean), 1 / totalSD)
  663.  
  664. let dataA = data.map((d, i) => [uDaily[i], uTotal[i]])
  665.  
  666. // dataA = dataA.slice(0, 4)
  667. // console.log(dataA)
  668.  
  669. let matrixA = jStat.transpose(dataA)
  670.  
  671.  
  672. const result = jStat.PCA(matrixA)
  673. const [X, D, Vt, Y] = result
  674.  
  675.  
  676.  
  677. let q = null
  678. let qSet = null
  679. if (location.search.includes('q=')) {
  680. q = new URLSearchParams(location.search)
  681. q = q.get('q')
  682.  
  683. }
  684.  
  685. function makeQA(q) {
  686. let qSet = new Set()
  687. q.replace(/_-/g, ' ').replace(/\b\S+\b/g, (_) => {
  688. qSet.add(_.toLowerCase())
  689. })
  690. return qSet
  691. }
  692.  
  693. if (q) {
  694. qSet = makeQA(q)
  695. }
  696.  
  697. let mr = new Map()
  698. let u = 0
  699. for (const d of data) {
  700. d.pcaScore = Y[0][u++]
  701. let elm = document.querySelector(`[data-script-id="${d.id}"]`)
  702. if (elm) {
  703.  
  704. let order = 0
  705. order -= Math.floor(d.pcaScore * 1000)
  706.  
  707. let u1 = 0, u2 = 0
  708.  
  709. if (qSet) {
  710.  
  711. const pSet = qSet
  712.  
  713. let elp = elm.querySelector('.script-link')
  714. if (elp) {
  715. let t = elp.textContent
  716.  
  717. t.replace(/_-/g, ' ').replace(/\b\S+\b/g, (_) => {
  718. if (pSet.has(_.toLowerCase())) u1++
  719. })
  720.  
  721.  
  722. }
  723.  
  724.  
  725.  
  726. let elq = elm.querySelector('.script-description')
  727.  
  728. if (elq) {
  729. let t = elq.textContent
  730.  
  731. t.replace(/_-/g, ' ').replace(/\b\S+\b/g, (_) => {
  732. if (pSet.has(_.toLowerCase())) u2++
  733. })
  734.  
  735.  
  736. }
  737.  
  738.  
  739. }
  740.  
  741.  
  742. if (u1 && u2) order -= 30000
  743. else if (u1) order -= 20000
  744. else if (u2) order -= 10000
  745.  
  746.  
  747. mr.set(d.id, order)
  748. // elm.style.order = order;
  749. // elm.parentNode.style.display = 'flex';
  750.  
  751.  
  752. // elm.parentNode.style.flexDirection = 'column';
  753.  
  754.  
  755. }
  756. }
  757.  
  758. /*
  759. let lists = [...new Set([...document.querySelectorAll(`[data-script-id]`)].map(p => p.parentNode))];
  760. for (const list of lists) {
  761. let m = [...list.childNodes].map(e => ({
  762. element: e,
  763. order: mr.get(e instanceof HTMLElement ? (+e.getAttribute('data-script-id') || '') : '') || 0
  764. }));
  765. m.sort((a, b) => {
  766. return Math.round(a.order - b.order)
  767. });
  768. let newNodes = m.map(e => e.element);
  769. list.replaceChildren(...newNodes);
  770. }
  771. */
  772.  
  773. // console.log(prettyMatrix(X))
  774.  
  775. // console.log(prettyMatrix(Y))
  776.  
  777.  
  778.  
  779.  
  780.  
  781. }, 300)
  782.  
  783. })
  784.  
  785.  
  786.  
  787. })()