Link Copy

링크 복사

As of 2022-09-19. See the latest version.

  1. // ==UserScript==
  2. // @name Link Copy
  3. // @version 1.0
  4. // @description 링크 복사
  5. // @author DandyClubs
  6. // @include /naughtyblog\.org/
  7. // @include /maxjav\.com/
  8. // @include /(8kcosplay\.com|blogjav\.net)/
  9. // @include /top-modelz\.org/
  10. // @include /wetholefans\.com/
  11. // @include /pornchil\.com\/.*/
  12. // @include /pornrips\.cc/
  13. // @include /javpink\.com/
  14. // @include /siteripbb\.org/
  15. // @include /javfree\.me/
  16. // @include /pornobunny\.org/
  17. // @include /adult-porno\.org/
  18. // @include /pornrip\.cc/
  19. // @include /fhdporn\.video/
  20. // @include /asianscan\.biz/
  21. // @include /sharepornlink\.com\/.*/
  22. // @include /javarchive\.com/
  23. // @include /0xxx\.ws/
  24. // @include /hpjav\.tv/
  25. // @include /kbjme\.com\/\d+/
  26. // @include /av18plus\.com/
  27. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
  28. // @require https://greasyfork.org/scripts/451572-rootdomain/code/RootDomain.js?version=1095109
  29. // @require https://greasyfork.org/scripts/451573-copy-link-common-library/code/Copy%20Link%20Common%20Library.js?version=1095463
  30. // @require https://greasyfork.org/scripts/451574-key-press/code/Key%20Press.js?version=1095111
  31. // @grant GM_addStyle
  32. // @grant GM_setValue
  33. // @grant GM_getValue
  34. // @grant GM_deleteValue
  35. // @grant GM_listValues
  36. // @grant GM_setClipboard
  37. // @grant window.close
  38. // @grant GM_xmlhttpRequest
  39. // @run-at document-body
  40. // @noframes
  41. // @license MIT
  42. // @namespace https://greasyfork.org/users/15621
  43. // ==/UserScript==
  44.  
  45.  
  46. (function() { var css = document.createElement('link'); css.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css'; css.rel = 'stylesheet'; css.type = 'text/css'; document.getElementsByTagName('head')[0].appendChild(css); })();
  47.  
  48. GM_addStyle (`
  49. @import url('https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@600&family=Noto+Sans+KR:wght@600&family=Noto+Sans:wght@600&display=swap');
  50.  
  51. .CloseIcon, .CopyIcon, .Minus, .GetTitle {
  52. text-align: center;
  53. cursor: pointer;
  54. color: dodgerblue !important;
  55. background-color:transparent !important;
  56. font-style: initial !important;
  57. }
  58. .IconSet {
  59. word-spacing: .5rem;
  60. white-space : nowrap;
  61. background-color:transparent !important;
  62. }
  63.  
  64. .CopyNotice {
  65. font-family: 'Nanum Gothic', 'M PLUS Rounded 1c', 'Noto Sans', sans-serif !important;
  66. margin-left: auto;
  67. margin-right: auto;
  68. border-radius: 4px;
  69. color: white !important;
  70. background: rgba(255, 110, 0, 0.75) !important;
  71. padding: .25em 1em;
  72. white-space: pre;
  73. text-shadow: initial !important;
  74. text-align: left;
  75. line-height: 1.25em;
  76. font-weight: initial !important;
  77. font-style: initial !important;
  78. display: -webkit-box;
  79. -webkit-line-clamp: 15;
  80. -webkit-box-orient: vertical;
  81. overflow: hidden;
  82. text-overflow: ellipsis;
  83. }
  84. .CenterBox {
  85. right: 50%;
  86. left: auto;
  87. top: 1px;
  88. margin: 0 auto;
  89. max-width: max-content;
  90. position: fixed !important;
  91. word-spacing: .5rem;
  92. padding: .25em;
  93. font-style: initial !important;
  94. text-align: center;
  95. color: dodgerblue !important;
  96. background-color:transparent !important;
  97. }
  98. .ToTop {
  99. font-style: initial !important;
  100. text-align: center;
  101. cursor: pointer;
  102. padding: .25em !important;
  103. border-radius: .25em !important;
  104. -webkit-box-sizing: border-box !important;
  105. box-sizing: border-box !important;
  106. background-color: rgba(255,255,255,0.5) !important;
  107. }
  108. .State {
  109. display: inline-block;
  110. font-weight: bold;
  111. text-align: right;
  112. vertical-align: middle;
  113. font-family: 'Noto Sans', sans-serif !important;
  114. background-color:transparent !important;
  115. font-style: italic !important;
  116. width: 5ch;
  117. }
  118.  
  119. .CopyButton, .ClearButton {
  120. font-style: initial !important;
  121. background-color:transparent !important;
  122. word-spacing: .5rem;
  123. cursor: pointer;
  124. }
  125. `);
  126.  
  127. var CopyLinks = []
  128. var AllCopyLinks = []
  129. var TmpLinksDB = []
  130. var CopyLinksBackup, MakeIconTimer
  131. const PageURL = window.location !== window.parent.location ? document.referrer : document.location.href;
  132. const RootDomain = extractRootDomain(PageURL)
  133. console.log('RootDomain: ', RootDomain)
  134.  
  135. var RootDomainDB = JSON.parse(GM_getValue(RootDomain, '[]'))
  136. console.log(RootDomainDB)
  137.  
  138. var GetState, searchDB
  139. GetState = RootDomainDB
  140. //console.log(GetState)
  141.  
  142. var MakerCfg = false
  143. var CfgReleaseDate = false
  144. var Maker = '', ReleaseDate = ''
  145.  
  146. var GetDPI, DefaultFontSize
  147. var Target, DownloadArea, CopyTitle, CopyOffSetArea, InfoArea, Resolution = '', TitleLast = '', Series ='', Title, ID = '', TitleID, CopyTitleTmp, InfoTitleTmp, CoverImage, MatchWebRegExp, Gallery
  148. var UrlTitle = ''
  149. const SkipFilter = new RegExp('keep2share\.cc\/pr\/|demosaic|upgrade|javascript|SKIP|pixhost\.to\/gallery\/|imgchili\.net\/show|#$|^\/|^(?=.*' + window.location.origin + ')(?!.*\\?site).*$', 'i')
  150. console.log(SkipFilter)
  151.  
  152. const SkipClassNames = ['adead_link', 'autohyperlink', 'social-icon']
  153. const JapaneseChar = /[\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\uff00-\uff9f\u4e00-\u9faf\u3400-\u4dbf]/g
  154. const SearchID = /([a-zA-Z]{2,11}-?\d{2,6}[a-zA-Z]?|\d{2,4}[a-zA-Z]{2,7}-?\d{3,6}[a-zA-Z]?|[a-zA-Z]{1,2}-?\d{2}-?\d{2}|[a-zA-Z]{2,7}-?[a-zA-Z]{1,2}\d{2})(.*)/
  155. const SearchFC2ID = /(^FC2.+\d{6})(.*)/
  156. const SearchIDRegExp = /^(\[\s?)?(?=([a-zA-Z]{2,11}-?\d{2,6}[a-zA-Z]?|\d{2,4}[a-zA-Z]{2,7}-?\d{3,6}[a-zA-Z]?|[a-zA-Z]{1,2}-?\d{2}-?\d{2}|[a-zA-Z]{2,7}-?[a-zA-Z]{1,2}\d{2}))(?!(C_\d+|file\d+))(.*)$/
  157. const K2SRegExp = /(.*k2s\.cc\/file\/)(.*\/?)/
  158.  
  159. async function Start() {
  160. GetDPI = window.devicePixelRatio
  161. DefaultFontSize = getDefaultFontSize()
  162. console.log('GetDPI: ', GetDPI, 'DefaultFontSize: ', DefaultFontSize)
  163.  
  164. document.querySelector("body").insertAdjacentHTML('afterbegin', '<div class="CenterBox" style="display: none"></>')
  165. document.querySelector("div.CenterBox").insertAdjacentHTML('beforeend', '<i class="ToTop fa-solid fa-circle-chevron-up"></>')
  166. document.querySelector("div.CenterBox").insertAdjacentHTML('beforeend', '&nbsp;<i class="ClearButton far fa-minus-square"></>')
  167. document.querySelector("div.CenterBox").insertAdjacentHTML('beforeend', '&nbsp;<i class="CopyButton fas fa-paste"></>')
  168. document.querySelector("div.CenterBox").insertAdjacentHTML('beforeend', '<i class="State"></>')
  169. document.querySelector(".ToTop").onclick = () => window.scrollTo({ top: 0, behavior: 'smooth' })
  170. console.log('Link Copy Start!')
  171. let CneterBoxFontSize = Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem'
  172. let CenterBoxZIndex = getMaxZIndex() + 1
  173. let StateFontSize = Number(((1/(GetDPI/1.5))*0.65*(16/DefaultFontSize)).toFixed(2)) + 'rem'
  174. let StateLineHeight = Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem'
  175.  
  176. document.querySelector('.CenterBox').style.cssText = `font-size: ${CneterBoxFontSize}; z-index: ${CenterBoxZIndex}; display: block;`
  177. document.querySelector('.State').style.cssText = `font-size: ${StateFontSize}; line-height: ${StateLineHeight}`
  178. document.querySelector('.State').textContent = ' ' + GetState.length
  179.  
  180. document.querySelector('.ClearButton').addEventListener("click", async function(event){
  181. event.preventDefault()
  182. event.stopPropagation()
  183. event.stopImmediatePropagation()
  184. await ClearUrls()
  185. }, true)
  186.  
  187. document.querySelector('.CopyButton').addEventListener("click", async function(event){
  188. event.preventDefault()
  189. event.stopPropagation()
  190. event.stopImmediatePropagation()
  191. await ClipPaste()
  192. }, true)
  193.  
  194. if(/naughtyblog\.org\/.+/.test(PageURL)){
  195. CopyOffSetArea = document.querySelector('.post-title.entry-title')
  196. CopyTitle = CopyOffSetArea.innerText
  197.  
  198. DownloadArea = document.querySelectorAll('div#download, div#downloadhidden')
  199. CoverImage = document.querySelector('div.post-content-single p a') ? document.querySelector('div.post-content-single p a').href : ''
  200. let MatchCast, InfoAreaCast, Title, Cast, SearchCast, SearchTitle, SearchWeb, FirstMatchCast, FirstMatchWeb, InfoCast, SearchWebPoint, SearchCastPoint, Released, ReleasedEn, Episode
  201. //CopyTitle에서 MatchWeb 찾기
  202. let MatchWebPoint = CopyTitle.search(/\s-\s/)
  203. console.log('MatchWebPoint: ' + MatchWebPoint)
  204. let MatchWeb = MatchWebPoint !== -1 ? CopyTitle.substr(0, MatchWebPoint).replace(/\s/g, '') : CopyTitle
  205. MatchWebRegExp = new RegExp(MatchWeb.replaceAll("'", ""), 'i')
  206. console.log('MatchWeb: ' + MatchWeb)
  207.  
  208. InfoArea = document.querySelector('div.post-content-single').innerText.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '\n').replace(/^(\s?(UPDATED|EARLY LEAK)\s?)/gim,'').split(/\n/)
  209. InfoArea = InfoArea.filter(function(e){return e})
  210. InfoArea = InfoArea.filter((element) => !/^(http|Size|Download|Watch online|Spare links)/i.test(element));
  211. console.log('InfoArea: ', InfoArea)
  212. InfoAreaCast = document.querySelector('div.post-content-single p strong').innerText.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '\n').replace(/^(\s?(UPDATED|EARLY LEAK)\s?)/gim,'').split(/\n/)
  213. InfoAreaCast = InfoAreaCast.filter(function(e){return e})
  214. console.log(InfoAreaCast)
  215.  
  216. if(CopyTitle.match(/Updates/i)){
  217. CoverImage = ''
  218. MutilSubTitle(MatchWeb, MatchWebPoint, InfoAreaCast, DownloadArea)
  219. }
  220. else if(!CopyTitle.match(/Updates/i) && InfoAreaCast.length > 1 ){
  221. console.log('Mutil SubTitle....')
  222. MutilSubTitle(MatchWeb, MatchWebPoint, InfoAreaCast, DownloadArea)
  223. }
  224.  
  225. else if(!CopyTitle.match(/SITERIP|OnlyFans|Collection/i)){
  226. //CopyTitle에서 배우명 찾기
  227. MatchCast = MatchWebPoint !== -1 ? CopyTitle.substr(MatchWebPoint + 3).split(/&|\s|,|:/) : CopyTitle.match(/.+/)
  228. MatchCast = MatchCast ? MatchCast.filter(function(e){return e}) : []
  229. MatchCast = MatchCast ? MatchCast.filter((entry) => isNaN(entry)) : []//숫자 및 단일글자 제거
  230. MatchCast = MatchCast ? MatchCast.filter((entry) => entry.length > 1) : []//숫자 및 단일글자 제거
  231. console.log('MatchCast: ' + MatchCast)
  232. let MatchTitle = MatchWebPoint !== -1 ? CopyTitle.substr(MatchWebPoint+3) : CopyTitle
  233. console.log('MatchTitle: ' + MatchTitle)
  234. for (let i = 0; i < InfoArea.length; i++) {
  235. if(!Cast){
  236. Cast = InfoArea[i].match(/Cast\s?:/) ? InfoArea[i].match(/Cast\s?:(.+)/).pop() : ''
  237. console.log('Cast: ', Cast)
  238. }
  239. //배우명 작품타이틀 찾기
  240. if(!FirstMatchCast && InfoArea[i].match(/-/g) && !Cast){
  241. //배우명 찾기
  242. SearchCastPoint = InfoArea[i].search(/\s-\s/)
  243. console.log('SearchCastPoint: ' + SearchCastPoint)
  244. SearchCast = SearchCastPoint !== -1 ? InfoArea[i].substr(0, SearchCastPoint).split(/\&|\s|,/) : new Array(InfoArea[i])
  245. SearchCast = SearchCast ? SearchCast.filter(function(e){return e}) : ''//빈 배열값 제거
  246. SearchCast = SearchCast ? SearchCast.filter((entry) => isNaN(entry)) : ''//숫자 제거
  247. SearchCast = SearchCast ? SearchCast.filter((entry) => entry.length > 1) : ''//단일글자 제거
  248. console.log('SearchCast: ' + SearchCast)
  249. MatchCast = MatchCast ? MatchCast.find((val) => {
  250. console.log('SearchingCast: ' + val)
  251. return SearchCast.includes(val)
  252. })
  253. :''
  254. console.log('MatchCast: ' + MatchCast)
  255. //배우명 없는 경우 작품 타이틀로 찾기
  256. if(!MatchCast && !SearchTitle){
  257. SearchTitle = SearchCastPoint !== -1 ? InfoArea[i].substr(SearchCastPoint + 3) : InfoArea[i]
  258. SearchTitle = InfoArea[i].toLowerCase().includes(SearchTitle.toLowerCase()) ? InfoArea[i] : ''
  259. console.log('SearchTitle: ' + SearchTitle)
  260. }
  261. FirstMatchCast = MatchCast ? MatchCast : ''
  262. SearchTitle = SearchTitle ? SearchTitle : ''
  263. InfoCast = MatchCast && !InfoCast ? InfoArea[i] : ''
  264. console.log('FirstMatchCast: ' + FirstMatchCast)
  265. console.log('InfoCast: ' + InfoCast)
  266. }
  267. //MatchWeb 찾기
  268. if(!InfoArea[i].match(/^http/) && !FirstMatchWeb){
  269. SearchWebPoint = InfoArea[i].match(/(.+)(\.\d+\.\d+.\d+\.)(.+)/) ? InfoArea[i].match(/(.+)(\.\d+\.\d+.\d+\.)(.+)/)
  270. : InfoArea[i].match(/(.+)(\.\d{4}\.)(.+)/) ? InfoArea[i].match(/(.+)(\.\d{4}\.)(.+)/) : ''
  271. console.log('SearchWebPoint:', InfoArea[i], InfoArea[i].match(/(.+)(\.\d+\.\d+.\d+\.)(.+)/), InfoArea[i].match(/(.+)(\.\d{4}\.)(.+)/))
  272. if(SearchWebPoint){
  273. SearchWeb = SearchWebPoint[1] && MatchWeb.toLowerCase().match(SearchWebPoint[1].toLowerCase()) ? MatchWeb
  274. : (MatchWeb.replace(/\!|'/g, '').toLowerCase()).match(SearchWebPoint[1].toLowerCase()) ? MatchWeb
  275. : (MatchWeb.replace(/-|\s|\./g, '').toLowerCase()).match(SearchWebPoint[1].toLowerCase()) ? SearchWebPoint[1]
  276. : (MatchWeb.toLowerCase()).match(SearchWebPoint[1].replace(/-|\s/g, '').toLowerCase()) ? SearchWebPoint[1]
  277. : MatchWeb + '(' + SearchWebPoint[1] + ')'
  278. console.log('SearchWeb: ' + SearchWeb)
  279. FirstMatchWeb = SearchWeb ? SearchWeb
  280. : ''
  281. console.log('FirstMatchWeb 1st: ' + FirstMatchWeb)
  282. }
  283. else{
  284. FirstMatchWeb = CopyTitle === InfoArea[i] ? MatchWeb
  285. : InfoArea[i].match(MatchWeb) ? InfoArea[i].match(MatchWeb) : ''
  286. var EpisodeTmp = InfoArea[i].match(/^(?!.*S\d+)(?=.*E\d{2,5}).*$/) ? '.' + InfoArea[i].match(/E\d{2,5}/) : ''
  287. InfoCast = InfoCast && EpisodeTmp && InfoCast.match(/^(?!.*S\d+)(?=.*E\d{2,5}).*$/) ? InfoCast.replace(/-?\s?E\d{2,5}$/, '').trim() : InfoCast
  288. console.log('FirstMatchWeb 2nd: ', FirstMatchWeb, '\nEpisode: ', Episode)
  289. }
  290. }
  291. if(!Released){
  292. Released = InfoArea[i].match(/(.+)(\.\d+\.\d+.\d+\.)(.+)/) ? InfoArea[i].match(/(\.\d+\.\d+.\d+\.)/).pop() : ''
  293. console.log('Released: ', Released)
  294. }
  295. if(!Episode){
  296. Episode = InfoArea[i].match(/^(?!.*S\d+)(?=.*E\d{2,5}).*$/) ? '.' + InfoArea[i].match(/E\d{2,5}/)
  297. : EpisodeTmp ? EpisodeTmp
  298. : ''
  299. }
  300.  
  301. if(!ReleasedEn){
  302. ReleasedEn = InfoArea[i].match(/Released:(.+)/i) ? InfoArea[i].match(/Released:(.+)/i).pop() : ''
  303. console.log('ReleasedEn: ', ReleasedEn)
  304. ReleasedEn = ReleasedEn ? '.' + ReleasedEn.trim().replace(/,/g, '').replace(/\s/g, '.') + '.' : ''
  305. ReleasedEn = ReleasedEn && ReleasedEn.split('.')[1].match(/^[a-zA-Z]/) ? ReleasedEn.replace(ReleasedEn.split('.')[1], getNumericMonth(ReleasedEn.split('.')[1])) : ''
  306. }
  307.  
  308. if(FirstMatchCast && FirstMatchWeb && Released){
  309. CopyTitle = Released && InfoCast ? FirstMatchWeb + Episode + Released + InfoCast
  310. : Released && !InfoCast && MatchTitle ? FirstMatchWeb + Episode + Released + MatchTitle
  311. : FirstMatchWeb + Episode + Released + InfoCast
  312. console.log('All Match: ' + CopyTitle)
  313. break
  314. }
  315. else if(FirstMatchCast && FirstMatchWeb && ReleasedEn){
  316. CopyTitle = InfoCast ? FirstMatchWeb + Episode + ReleasedEn + InfoCast
  317. : !InfoCast && FirstMatchCast ? FirstMatchWeb + Episode + ReleasedEn + FirstMatchCast
  318. : FirstMatchWeb + Episode + ReleasedEn + (InfoCast ? InfoCast : FirstMatchCast)
  319. console.log('Some Match: ' + CopyTitle)
  320. }
  321. else if(!FirstMatchCast && !FirstMatchWeb && Released){
  322. if(CopyTitle === InfoArea[i]){
  323. console.log('Same Title: ' + CopyTitle, InfoArea[i])
  324. }
  325. }
  326. else if(MatchCast == MatchTitle && FirstMatchWeb && Released){
  327. InfoCast = InfoCast ? InfoCast : Cast ? '(' + Cast.trim() + ')' : ''
  328. CopyTitle = FirstMatchWeb + Episode + Released + InfoCast
  329. console.log('MatchCast == MatchTitle: ' + CopyTitle)
  330. }
  331. else if(!FirstMatchCast && MatchWeb && FirstMatchWeb && Released && MatchCast){
  332. CopyTitle = MatchWeb + "(" + FirstMatchWeb + ")" + Episode + Released + MatchCast.join(' ')
  333. console.log('MatchWeb VS FirstMatchWeb: ' + CopyTitle, InfoArea[i])
  334. }
  335. else if(i == InfoArea.length -1){
  336. console.log( MatchWeb, SearchWeb, Released, ReleasedEn, FirstMatchCast, Episode, InfoCast )
  337. InfoCast = InfoCast ? InfoCast : Cast ? '(' + Cast.trim() + ')' : ''
  338. console.log('InfoCast: ', InfoCast)
  339. Released = Released ? Released : ReleasedEn ? ReleasedEn : ''
  340. CopyTitle = MatchWeb && Released && SearchWebPoint && InfoCast ? MatchWeb + '(' + SearchWebPoint[1] + ')' + Episode + Released + InfoCast
  341. : MatchWeb && Released && InfoCast ? MatchWeb + Episode + Released + InfoCast
  342. : MatchWeb && Released && FirstMatchCast ? MatchWeb + Episode + Released + FirstMatchCast
  343. : SearchWeb && !Released && SearchWebPoint && SearchWeb&& InfoCast ? SearchWeb + SearchWebPoint[2] + Episode + InfoCast
  344. : MatchWeb && Episode && MatchTitle && InfoCast ? MatchWeb + Episode + MatchTitle + InfoCast
  345. : MatchWeb && SearchTitle && !InfoCast && Released ? MatchWeb + Episode + Released + SearchTitle
  346. : MatchWeb && MatchTitle && !InfoCast && Released ? MatchWeb + Episode + Released + MatchTitle
  347. : MatchWeb && Released && InfoCast ? MatchWeb + Episode + Released + InfoCast
  348. : SearchWeb && InfoCast ? SearchWeb + Episode + InfoCast
  349. : CopyTitle + InfoCast
  350. console.log('End : ', CopyTitle)
  351. }
  352. }
  353.  
  354. CopyTitle = CopyTitle.replace(/(S\d+):(E\d+)/i, '$1$2')
  355. CopyTitle = byteLengthOf(CopyTitle, 250)
  356. CopyTitle = FilenameConvert(CopyTitle) + Resolution
  357.  
  358. console.log('CopyTitle: ' + CopyTitle)
  359. let LinkDB = []
  360. for (let i = 0; i < DownloadArea.length; i++) {
  361. let Links = MatchRegex(DownloadArea[i], new RegExp('1080p', 'i'), 'href')
  362. console.log('1080p: ', Links)
  363. if(Links?.length > 0){
  364. LinkDB.push(...Links)
  365. }
  366. else if(!Links?.length){
  367. Links = MatchRegex(DownloadArea[i], new RegExp('2160p', 'i'), 'href')
  368. console.log('2160p: ', Links)
  369. if(Links?.length > 0){
  370. LinkDB.push(...Links)
  371. }
  372. else if(!Links?.length){
  373. Links = MatchRegex(DownloadArea[i], new RegExp('720p', 'i'), 'href')
  374. console.log('720p: ', Links)
  375. if(Links?.length > 0){
  376. LinkDB.push(...Links)
  377. }
  378. else if(!Links?.length){
  379. Links = MatchRegex(DownloadArea[i], new RegExp(MatchWeb + '|' + MatchCast, 'i'), 'href')
  380. console.log('Links: ', Links)
  381. LinkDB.push(...Links)
  382. }
  383. }
  384. }
  385. }
  386. LinkDB = LinkDB?.length > 0 ? LinkDB.map((entry) => entry.outerHTML) : ''
  387. console.log('LinkDB: ', LinkDB)
  388. let container = document.createElement("div")
  389.  
  390. LinkDB.forEach((el, i) => {
  391. const fragment = document.createRange().createContextualFragment(el);
  392. console.log(fragment.children[0]);
  393. container.appendChild(fragment.children[0]);
  394. })
  395. container.classList.add("DownloadArea")
  396. document.body.appendChild(container);
  397. DownloadArea = document.querySelectorAll('div.DownloadArea')
  398. console.log('DownloadArea: ', DownloadArea)
  399. }
  400. if(!document.querySelector('.GetTitle')){
  401. document.querySelector("div#main-content.main-content-single div div.post-content-single p strong").insertAdjacentHTML('afterend', '&nbsp;&nbsp;<i class="GetTitle fas fa-paste"></>')
  402. }
  403. document.querySelector('.GetTitle').addEventListener("click", async function(event){
  404. event.preventDefault()
  405. event.target.style.setProperty('color', 'Orange', 'important')
  406. updateClipboard(CopyTitle)
  407. }, true)
  408. }
  409.  
  410. else if(/maxjav.com\/\d+/.test(PageURL) && window.top === window.self){
  411. CopyOffSetArea = document.querySelector('div#content > div > .title')
  412. CopyTitle = CopyOffSetArea.innerText
  413. CopyTitle = CopyTitle.match(/\[?.*Subtitle\]?(.+)/) ? CopyTitle.match(/\[.+Subtitle\](.+)/).pop() : CopyTitle
  414. CopyTitle = CopyTitle.replace(/amp;/g, '').replace(/(\s)?\/(\s)?/g, '/').replace(/(-|–)\sHD/, '').replace(/amp;|\(\s?ブルーレイ版\s?\)|\(ブルーレイディスク版\)|:/g, '').trim()
  415. console.log(CopyTitle)
  416. if(!CopyTitle.match(/^Collection/)){
  417. InfoArea = document.querySelector('div#content > div > .entry > p').innerText.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '\n').split(/\n\n|\n/)
  418. InfoArea = InfoArea.filter(function(e){return e})//빈 배열값 제거
  419. console.log(InfoArea)
  420. //Series = InfoArea.find(InfoSearch => InfoSearch.match(/シリーズ:?.*/)) ? InfoArea.find(InfoSearch => InfoSearch.match(/シリーズ:?.*/)).replace(/シリーズ:?/, '').trim() : ''
  421. for (let i = 0; i < InfoArea.length; i++) {
  422. if(!Title){
  423. console.log(CopyTitle.match(SearchID))
  424. CopyTitleTmp = CopyTitle.match(SearchIDRegExp) ? CopyTitle.match(SearchID).pop().trim() : ''
  425. InfoTitleTmp = InfoArea[i].match(SearchIDRegExp) ? InfoArea[i].match(SearchID).pop().trim() : ''
  426. console.log('CopyTitleTmp: ', CopyTitleTmp, '\nInfoTitleTmp: ', InfoTitleTmp)
  427. //CopyTitleTmp.match(/[\u3040-\u309f\u30a0-\u30ff]/g) 일본어 히라가나 카타가나 찾기
  428. if(CopyTitleTmp && InfoTitleTmp){
  429. Title = CopyTitleTmp.toLowerCase() === InfoTitleTmp.toLowerCase() ? CopyTitleTmp
  430. : (CopyTitleTmp.match(JapaneseChar) || []).length >= (InfoArea[i].match(JapaneseChar) || []).length ? CopyTitleTmp
  431. : (CopyTitleTmp.match(JapaneseChar) || []).length < (InfoArea[i].match(JapaneseChar) || []).length ? InfoTitleTmp
  432. : CopyTitleTmp
  433. Title = Title.trim() + ' '
  434. console.log('Title 1st: ' + Title)
  435. }
  436. else{
  437. Title = CopyTitleTmp && (CopyTitle.match(JapaneseChar) || []).length >= (InfoArea[i].match(JapaneseChar) || []).length ? CopyTitleTmp
  438. : InfoTitleTmp && InfoTitleTmp.match(JapaneseChar) && (CopyTitle.match(JapaneseChar) || []).length <= (InfoArea[i].match(JapaneseChar) || []).length ? InfoTitleTmp
  439. : (CopyTitle.match(JapaneseChar) || []).length < (InfoArea[i].match(JapaneseChar) || []).length ? InfoArea[i]
  440. : CopyTitle.match(JapaneseChar) ? CopyTitle
  441. : InfoArea[i].match(JapaneseChar) ? InfoArea[i]
  442. : CopyTitle
  443.  
  444. Title = Title.trim() + ' '
  445. Title = mbConvertKana(Title, 'rans')
  446. console.log('Title 2nd: ' + Title)
  447. }
  448. }
  449. if(!ID){
  450. console.log(CopyTitle.match(SearchID), InfoArea[i].match(SearchID))
  451. let TitleID = CopyTitle.match(SearchIDRegExp) ? CopyTitle.match(SearchID)[1] : CopyTitle.match(SearchFC2ID) ? CopyTitle.match(SearchFC2ID)[1] : ''
  452. let InfoID = InfoArea[i].match(SearchIDRegExp) ? InfoArea[i].match(SearchID)[1] : InfoArea[i].match(SearchFC2ID) ? InfoArea[i].match(SearchFC2ID)[1] : ''
  453. if(TitleID && InfoID && TitleID.replace(/-/g, '').trim().toLowerCase() === InfoID.replace(/-/g, '').trim().toLowerCase()){
  454. ID = TitleID.match(/-/g) && InfoID.match(/-/g) ? TitleID
  455. : TitleID.match(/-/g) ? TitleID
  456. : InfoID.match(/-/g) ? InfoID.match(/-/g)
  457. : TitleID
  458. }
  459. else{
  460. ID = TitleID ? TitleID : InfoID
  461. }
  462. console.log('ID: ' + ID)
  463. if(ID){
  464. ID = ID.trim() + ' '
  465. }
  466. }
  467. if(CfgReleaseDate && !ReleaseDate && InfoArea[i].match(/Release Date:/)){
  468. ReleaseDate = InfoArea[i].match(/Release Date:(.+)/)[1].replace(/\//g, '-').trim()
  469. }
  470. if(MakerCfg && !Maker && InfoArea[i].match(/(Maker|Studio)\s?:(.+)/)){
  471. Maker = InfoArea[i].match(/(Maker|Studio)\s?:(.+)/)[2].replace(/(\s)?\/(\s)?/g, '/').trim()
  472. }
  473. if(Title && ID && ReleaseDate){
  474. break
  475. }
  476. }
  477. Maker = Maker ? '[' + Maker + '] ' : ''
  478. ReleaseDate = ReleaseDate ? '(' + ReleaseDate + ') ' : ''
  479.  
  480. Title = Maker + ID + ReleaseDate + Title
  481.  
  482. if(byteLengthOfCheck(Title) > 250){
  483.  
  484. let TitleLast = getLastText(Title)
  485.  
  486. if(typeof TitleLast == 'undefined' || !TitleLast || TitleLast.length === 0 || TitleLast === "" || !/[^\s]/.test(TitleLast) || /^\s*$/.test(TitleLast) || TitleLast.replace(/\s/g,"") === ""){
  487. CopyTitle = byteLengthOf(Title, 250).trim()
  488. }
  489. else{
  490. Title = Title.split(TitleLast)[0].trim()
  491. Title = byteLengthOf(Title, 250 - byteLengthOfCheck(TitleLast))
  492. console.log('Title: ', Title, TitleLast)
  493. CopyTitle = (Title + TitleLast).trim()
  494. }
  495. }
  496. else CopyTitle = Title.trim()
  497.  
  498. console.log('Last Title: ' + CopyTitle)
  499.  
  500. }
  501. //CopyTitle = CopyOffSetArea.textContent.replace(/\s–\s(UltraHD|Full|HD|SD)/, '').trim()
  502. DownloadArea = document.querySelectorAll('div#content > div > div.entry p')
  503. CoverImage = DownloadArea[0].querySelector('p img') ? DownloadArea[0].querySelector('p img').src : ''
  504. }
  505.  
  506. else if(/javpink\.com\/\?p/.test(PageURL)){
  507. CopyOffSetArea = document.querySelector('.item > .title')
  508. Title = CopyOffSetArea.textContent.trim()
  509. DownloadArea = document.querySelectorAll('.item > .content')
  510. CoverImage = DownloadArea[0].querySelector('p img') ? DownloadArea[0].querySelector('p img').src : ''
  511.  
  512. for (let i = 0; i < DownloadArea.length; i++) {
  513. InfoArea = DownloadArea[i].innerText.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '\n').split(/\n\n|\n/)
  514. }
  515. InfoArea = InfoArea.filter(function(e){return e})//빈 배열값 제거
  516. console.log(InfoArea)
  517. Series = InfoArea.find(InfoSearch => InfoSearch.match(/シリーズ:?.*/)) ? InfoArea.find(InfoSearch => InfoSearch.match(/シリーズ:?.*/)).replace(/シリーズ:?/, '').trim() : ''
  518.  
  519. Title = mbConvertKana(Title, 'rans')
  520. if(byteLengthOfCheck(Title) > 250){
  521. let TitleLast = getLastText(Title)
  522.  
  523. if(typeof TitleLast == 'undefined' || !TitleLast || TitleLast.length === 0 || TitleLast === "" || !/[^\s]/.test(TitleLast) || /^\s*$/.test(TitleLast) || TitleLast.replace(/\s/g,"") === ""){
  524. CopyTitle = byteLengthOf(Title, 250).trim()
  525. }
  526. else{
  527. Title = Title.split(TitleLast)[0].trim()
  528. Title = byteLengthOf(Title, 250 - (byteLengthOfCheck(TitleLast)))
  529. console.log('Title: ', Title, TitleLast)
  530. CopyTitle = (Title + TitleLast).trim()
  531. }
  532. }
  533. else CopyTitle = Title.trim()
  534. }
  535.  
  536. else if(/top-modelz.org\/.+/.test(PageURL)){
  537. CopyOffSetArea = document.querySelector('.news-detalis h2')
  538. Title = CopyOffSetArea.textContent.trim()
  539. DownloadArea = document.querySelectorAll('div#content div#l-content div#dle-content div.news-block div.newspad')
  540. CoverImage = DownloadArea[0].querySelector('p img') ? DownloadArea[0].querySelector('p img').src : ''
  541. for (let i = 0; i < DownloadArea.length; i++) {
  542. InfoArea = DownloadArea[i].innerText.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '\n').split(/\n\n|\n/)
  543. }
  544. InfoArea = InfoArea.filter(function(e){return e})//빈 배열값 제거
  545. console.log(InfoArea)
  546. let Released
  547. for (let i = 0; i < InfoArea.length; i++) {
  548. if(!Released){
  549. Released = InfoArea[i].match(/\d+-\d+-\d+/) ? InfoArea[i].match(/\d+-\d+-\d+/) + ' ' : ''
  550. }
  551. if(Released){
  552. break
  553. }
  554. }
  555. CopyTitle = Released ? Released + Title : Title
  556. CopyTitle = CopyTitle
  557. CopyTitle = byteLengthOf(CopyTitle, 250)
  558. }
  559.  
  560. else if(/(8kcosplay\.com|blogjav\.net|javfree\.me)\/\d+/.test(PageURL)){
  561. CopyOffSetArea = document.querySelector('.entry-title')
  562. if(/javfree\.me/.test(PageURL)){
  563. DownloadArea = document.querySelectorAll('.entry-content')
  564.  
  565. //CoverImage = DownloadArea[0].querySelector('p img') ? DownloadArea[0].querySelector('p img').src : ''
  566. }
  567. else{
  568. DownloadArea = document.querySelectorAll('.entry-content > p')
  569. CoverImage = DownloadArea[0].querySelector('p img') ? DownloadArea[0].querySelector('p img').src : ''
  570. }
  571.  
  572. Title = CopyOffSetArea.textContent.replace(/\[([a-zA-Z]{2,11}-?\d{2,6}[a-zA-Z]?|\d{2,4}[a-zA-Z]{2,7}-?\d{3,6}[a-zA-Z]?|[a-zA-Z]{1,2}-?\d{2}-?\d{2}|[a-zA-Z]{2,7}-?[a-zA-Z]{1,2}\d{2})\]/, '$1')
  573. ID = Title.match(SearchFC2ID) ? Title.match(SearchFC2ID)[1] : ''
  574. console.log('ID: ', ID)
  575. Title = Title.replace(ID, '').trim()
  576. Title = Title.split(/\s/).filter(function(e){return e})
  577. console.log('Title: ', Title)
  578. if(Title[0].match(/UNCENSORED/)){
  579. Title.shift()
  580. Title = Title.join(' ')
  581. }
  582. else{
  583. Title = Title.join(' ')
  584. }
  585. for (let i = 0; i < DownloadArea.length; i++) {
  586. InfoArea = DownloadArea[i].innerText.replace(/(?:(?:\r\n|\r|\n)\s*){2}/gm, '\n').split(/\n\n|\n/)
  587. }
  588.  
  589. InfoArea = InfoArea.filter(function(e){return e})//빈 배열값 제거
  590. console.log('InfoArea: ', InfoArea)
  591. Series = InfoArea.find(InfoSearch => InfoSearch.match(/シリーズ:?.*/)) ? InfoArea.find(InfoSearch => InfoSearch.match(/シリーズ:?.*/)).replace(/シリーズ:?/, '').trim() : ''
  592. console.log('Series: ', Series)
  593. Title = mbConvertKana(Title, 'rans')
  594. console.log(Title, ID)
  595. if(byteLengthOfCheck(Title) > 250 - byteLengthOfCheck(ID)){
  596. let TitleLast = getLastText(Title)
  597. if(typeof TitleLast == 'undefined' || !TitleLast || TitleLast.length === 0 || TitleLast === "" || !/[^\s]/.test(TitleLast) || /^\s*$/.test(TitleLast) || TitleLast.replace(/\s/g,"") === ""){
  598. CopyTitle = ID + byteLengthOf(Title, 250 - byteLengthOfCheck(ID)).trim()
  599. }
  600. else{
  601. Title = Title.split(TitleLast)[0].trim()
  602. Title = byteLengthOf(Title, 250 - (byteLengthOfCheck(ID) + byteLengthOfCheck(TitleLast)))
  603. CopyTitle = (ID + Title + TitleLast).trim()
  604. if(byteLengthOfCheck(CopyTitle) > 250){
  605. console.log('CopyTitle length: ', byteLengthOfCheck(CopyTitle))
  606. }
  607. }
  608. }
  609. else CopyTitle = ID + Title.trim()
  610. console.log('CopyTitle: ', CopyTitle)
  611. }
  612.  
  613. else if(/wetholefans.com\/.+/.test(PageURL)){
  614. CopyOffSetArea = document.querySelector('.post-title #news-title h1')
  615. console.log(parseFloat(window.getComputedStyle(CopyOffSetArea).fontSize))
  616. //console.log('CopyOffSetArea: ' + CopyOffSetArea)
  617. Resolution = !Resolution && CopyOffSetArea && CopyOffSetArea.innerText.match(/[0-9]{3,4}p/) ? ' ' + CopyOffSetArea.innerText.match(/[0-9]{3,4}p/)[0] : ''
  618. console.log(Resolution)
  619. CopyTitle = CopyOffSetArea.innerText.replace(/\((UltraHD|Full|HD|SD).+/, '').replace(/\s+/g, ' ').trim()
  620. CopyTitle = capitalize(CopyTitle)
  621. DownloadArea = CopyOffSetArea.closest('.story').querySelectorAll('.quote')
  622. let SearchLinks
  623. DownloadArea.forEach((LinkEntry) => {
  624. SearchLinks = LinkEntry.querySelectorAll('a')
  625. })
  626. console.log(SearchLinks)
  627. for (let i = 0; i < SearchLinks.length; i++) {
  628. if(!ReleaseDate){
  629. ReleaseDate = SearchLinks[i].textContent.match(/(.+)(\.\d+\.\d+.\d+\.)(.+)/) ? SearchLinks[i].textContent.match(/(\.\d+\.\d+.\d+\.)/).pop() : ''
  630. }
  631. else{
  632. break
  633. }
  634. }
  635. let MatchWebPoint = CopyTitle.search(/\s-\s/)
  636. let MatchWeb = MatchWebPoint !== -1 ? CopyTitle.substr(0, MatchWebPoint).replace(/\s/g, '') : CopyTitle
  637. CopyTitle = ReleaseDate ? MatchWeb + ReleaseDate + CopyTitle.substr(MatchWebPoint+3) : CopyTitle
  638. console.log(CopyTitle)
  639. CopyTitle = CopyTitle.replace(/\*/g, '*').replace(/\?/g, '?')
  640. CopyTitle = byteLengthOf(CopyTitle, 250)
  641.  
  642. }
  643.  
  644. else{
  645. if(/(pornchil\.com\/)(?!$).*$/.test(PageURL)){
  646. CopyOffSetArea = document.querySelector('.inside-article > .entry-content').querySelector('strong > span')
  647. DownloadArea = document.querySelectorAll('.inside-article > div.entry-content')
  648. console.log(CopyOffSetArea)
  649. }
  650. else if(/javarchive\.com\/\d{4,6}/.test(PageURL)){
  651. CopyOffSetArea = document.querySelector('div.news > div.first_des') || document.querySelector('.menudd > h1')
  652. DownloadArea = document.querySelectorAll('.link_archive_innew')
  653. CoverImage = document.querySelector('div.category_news_phai_chinh > div.news > div.fisrst_sc img:not([src^="data"])') ? document.querySelector('div.category_news_phai_chinh > div.news > div.fisrst_sc img').getAttribute('src') : document.querySelector('div.category_news_phai_chinh > div.news > div.fisrst_sc img').getAttribute('data-src')
  654. console.log(CopyOffSetArea, DownloadArea, CoverImage)
  655. }
  656. else if(/kbjme\.com\/\d+/.test(PageURL)){
  657. CopyOffSetArea = document.querySelector('.article_container h1')
  658. DownloadArea = document.querySelectorAll('div.article_container div.context div#post_content')
  659. console.log(DownloadArea)
  660. document.querySelector('.article_container a').href = '#'
  661. document.querySelector('.article_container a').removeAttribute('target')
  662. }
  663. else if(/hpjav.tv\/(ja\/)?\d+/.test(PageURL)){
  664. CopyOffSetArea = document.querySelector('section div ol li.active')
  665. CoverImage = document.querySelector('#JKDiv_0') ? GetBackGroundUrl(document.querySelector('#JKDiv_0')) : ''
  666. let AddElementArea = document.querySelector('div#down_server')
  667. let observer = new MutationObserver(function(mutations) {
  668. if (document.querySelector('ul.pricing-table')) {
  669. DownloadArea = document.querySelectorAll('ul.pricing-table')
  670. console.log('DownloadArea: ', DownloadArea)
  671. if(DownloadArea){
  672. observer.disconnect()
  673. window.scrollTo({ top: 0, behavior: 'auto' })
  674. DownloadArea.forEach((LinkEntry) => {
  675. LinkEntry.querySelectorAll('a').forEach((aEntry) => {
  676. if( RootDomain !== (extractRootDomain(aEntry.href))){
  677. aEntry.classList.remove("dbtn")
  678. aEntry.removeAttribute('type')
  679. aEntry.textContent = aEntry.href
  680. aEntry.insertAdjacentHTML('beforebegin', '<img src=https://www.google.com/s2/favicons?domain=' + extractRootDomain(aEntry.href) +' ></>')
  681. }
  682. })
  683. })
  684. keyvent.down('ctrl alt a')
  685. }
  686. }
  687. })
  688. observer.observe(AddElementArea, { attributes: true, childList: true, subtree: true });
  689. await sleep(1000)
  690. document.querySelector('#download_div.btn.btn-info').click()
  691. }
  692. else if(/0xxx\.ws\/articles\/\d+/.test(PageURL)){
  693. CopyOffSetArea = document.querySelector('div.container table#detail-table tbody tr td.taj:not(.levo)')
  694. DownloadArea = document.querySelectorAll('div.container table#detail-table tbody tr td.dlinks.taj')
  695. console.log(DownloadArea)
  696. window.addEventListener('scroll', scrollToTop)
  697. }
  698. else if(/pornrips\.cc\/.+/.test(PageURL)){
  699. CopyOffSetArea = document.querySelector('div#dle-content article div.head h1.title')
  700. DownloadArea = document.querySelectorAll('div#dle-content article div.story_cont .screenshots, div#dle-content article div.story_cont div.links')
  701. console.log(DownloadArea)
  702. }
  703. else if(/siteripbb\.org\/.+/.test(PageURL)){
  704. CopyOffSetArea = document.querySelector('.entry-title')
  705. DownloadArea = document.querySelectorAll('div.entry-content')
  706. console.log(DownloadArea)
  707. }
  708. else if(/fhdporn\.video\/.+/.test(PageURL)){
  709. CopyOffSetArea = document.querySelector('h1.post-title')
  710. DownloadArea = document.querySelectorAll('div.post-content')
  711. console.log(DownloadArea)
  712. }
  713. else if(/av18plus\.com/.test(PageURL)){
  714. CopyOffSetArea = document.querySelector('article.post > h1#post-title')
  715. DownloadArea = CopyOffSetArea ? CopyOffSetArea.closest('article').querySelectorAll('p') : ''
  716. console.log(DownloadArea)
  717. }
  718. else if(/siteripbb\.org\/.+/.test(PageURL)){
  719. CopyOffSetArea = document.querySelector('.entry-title')
  720. DownloadArea = document.querySelectorAll('div.entry-content')
  721. console.log(DownloadArea)
  722. }
  723. else if(/asianscan\.biz\/.*\.html/.test(PageURL)){
  724. CopyOffSetArea = document.querySelector('div div.content div#dle-content div.mainf3')
  725. DownloadArea = document.querySelectorAll('div.content div#dle-content div.sscn div.quote')
  726. console.log(DownloadArea)
  727. }
  728. else if(/adult-porno\.org\/.+/.test(PageURL)){
  729. CopyOffSetArea = document.querySelector('div.full-in h1')
  730. DownloadArea = document.querySelectorAll('div.quote')
  731. console.log(DownloadArea)
  732. Resolution = !Resolution && CopyOffSetArea && CopyOffSetArea.innerText.match(/[0-9]{3,4}p/) ? ' ' + CopyOffSetArea.innerText.match(/[0-9]{3,4}p/)[0] : ''
  733. }
  734. else if(/(sharepornlink\.com\/)(?!($|page))(.*)$/.test(PageURL)){
  735. CopyOffSetArea = document.querySelector('.main-title.title')
  736. DownloadArea = document.querySelectorAll('div.text p')
  737. console.log(DownloadArea)
  738. Resolution = !Resolution && CopyOffSetArea && CopyOffSetArea.innerText.match(/[0-9]{3,4}p/) ? ' ' + CopyOffSetArea.innerText.match(/[0-9]{3,4}p/)[0] : ''
  739. }
  740. else if(/pornobunny\.org\/.+/.test(PageURL)){
  741. CopyOffSetArea = document.querySelector('.titlesf')
  742. document.querySelector('a.quote-hider-trigger').click()
  743. let AddElementArea = document.querySelector('div.sstory')
  744. let observer = new MutationObserver(function(mutations) {
  745. mutations.forEach(function(mutation) {
  746. for (var i = 0; i < mutation.addedNodes.length; i++) {
  747. if (mutation.addedNodes[i].nodeType === Node.ELEMENT_NODE) {
  748. if (mutation.addedNodes[i].classList.contains('quote')) {
  749. DownloadArea = document.querySelectorAll('div.quote')
  750. console.log('DownloadArea: ', DownloadArea)
  751. if(DownloadArea){
  752. observer.disconnect()
  753. window.scrollTo({ top: 0, behavior: 'auto' })
  754. }
  755. }
  756. }
  757. }
  758. })
  759. });
  760. observer.observe(AddElementArea, { childList: true, subtree: true });
  761. Resolution = !Resolution && CopyOffSetArea && CopyOffSetArea.innerText.match(/[0-9]{3,4}p/) ? ' ' + CopyOffSetArea.innerText.match(/[0-9]{3,4}p/)[0] : ''
  762. }
  763. else if(/pornrip\.cc\/.+\.html/.test(PageURL)){
  764. CopyOffSetArea = document.querySelector('.title.ularge')
  765. let AddElementArea = document.querySelector('article.main-article section.post-content')
  766. let observer = new MutationObserver(function(mutations) {
  767. mutations.forEach(function(mutation) {
  768. for (var i = 0; i < mutation.addedNodes.length; i++) {
  769. console.log(mutation.addedNodes[i])
  770. if (mutation.addedNodes[i].nodeName === 'A') {
  771. DownloadArea = document.querySelectorAll('article.main-article > section.post-content > div > div.su-spoiler > div.su-spoiler-content')
  772. console.log('DownloadArea: ', DownloadArea)
  773. if(DownloadArea){
  774. observer.disconnect()
  775. window.scrollTo({ top: 0, behavior: 'auto' })
  776. document.querySelectorAll('a').forEach((aEntry) => {
  777. if(/\?site.+$/.test(aEntry.href)){
  778. aEntry.setAttribute('href', aEntry.href.replace(/\?site.+$/, ''))
  779. }
  780. })
  781. break
  782. }
  783. }
  784. }
  785. })
  786. });
  787. observer.observe(AddElementArea, { childList: true, subtree: true })
  788. Resolution = !Resolution && CopyOffSetArea && CopyOffSetArea.innerText.match(/[0-9]{3,4}p/) ? ' ' + CopyOffSetArea.innerText.match(/[0-9]{3,4}p/)[0] : ''
  789. }
  790. if(CopyOffSetArea){
  791. //console.log('InnerText: ', getDirectInnerText(CopyOffSetArea))
  792. CopyTitle = getDirectInnerText(CopyOffSetArea).replace('–', '-').replace(/\s+/g, ' ').replace(/\[(UltraHD|FullHD|HD).+\].*/, '').replace(/^Japanese porn -|6000Kbps FHD/, '').trim()
  793. CopyTitle = CopyTitle.match(/(–\sSiterip)\s–.+/) ? CopyTitle.match(/(.+Siterip)\s–.+/)[1] : CopyTitle
  794. CopyTitle = capitalize(CopyTitle)
  795. if(byteLengthOfCheck(CopyTitle) > 250){
  796. let TitleLast = getLastText(CopyTitle)
  797.  
  798. if(typeof TitleLast == 'undefined' || !TitleLast || TitleLast.length === 0 || TitleLast === "" || !/[^\s]/.test(TitleLast) || /^\s*$/.test(TitleLast) || TitleLast.replace(/\s/g,"") === ""){
  799. Title = byteLengthOf(CopyTitle, 250).trim()
  800. }
  801. else{
  802. Title = CopyTitle.split(TitleLast)[0].trim()
  803. Title = byteLengthOf(Title, 250 - (byteLengthOfCheck(TitleLast)))
  804. console.log('Title: ', Title, TitleLast)
  805. Title = (Title + TitleLast).trim()
  806. }
  807. CopyTitle = Title.trim()
  808. }
  809. else CopyTitle = CopyTitle.trim()
  810. }
  811. }
  812. }
  813.  
  814.  
  815. $(document).ready(async function() {
  816. if(!document.querySelector("div.CenterBox")){
  817. await Start()
  818. }
  819.  
  820. if(CopyOffSetArea && !document.querySelector(".IconSet")){
  821. CopyOffSetArea.insertAdjacentHTML('afterend', '<div class="IconSet" style="top: auto; left: auto; max-width: max-content; visibility:hidden; position: absolute;"></>')
  822. document.querySelector(".IconSet").insertAdjacentHTML('beforeend', '<i class="CopyIcon far fa-clone" style ="color: dodgerblue !important; visibility:hidden;"></>')
  823. document.querySelector(".IconSet").insertAdjacentHTML('beforeend', '&nbsp;<i class="CloseIcon fa-solid fa-square-xmark" style ="color: dodgerblue !important; visibility:hidden"></>')
  824. document.querySelector(".IconSet").insertAdjacentHTML('beforeend', '&nbsp;<i class="Minus fa-solid fa-magnifying-glass-minus" style ="color: dodgerblue !important; visibility:hidden;"></>')
  825. document.body.insertAdjacentHTML('beforeend', '<div class="CopyNotice" style="display: none;"></>')
  826. document.querySelector(".IconSet").style.visibility = "hidden"
  827. if(document.hidden){
  828. document.querySelector(".CopyIcon").style.visibility = "hidden"
  829. }
  830. let IconSetZIndex = MaxZIndexFromPoint('.IconSet') + 1
  831. let IconSetFontSize = Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem'
  832. //document.querySelector('.IconSet').style.cssText = `font-size: ${CneterBoxFontSize}; z-index: ${CenterBoxZIndex}; display: block;`
  833. Object.assign(document.querySelector('.IconSet').style, {fontSize: IconSetFontSize, zIndex: IconSetZIndex});
  834.  
  835. }
  836.  
  837. if(CopyOffSetArea){
  838. console.log('Make Icon')
  839. MakeIconTimer = setTimeout(() => MakeIcon(GetDPI), 2000)
  840.  
  841. document.querySelector('.CopyIcon').addEventListener("click", async function(event){
  842. event.preventDefault()
  843. event.stopPropagation()
  844. event.stopImmediatePropagation()
  845. let TitlePostion = getElementOffset(CopyOffSetArea)
  846. let TitleHeight = Math.max(TitlePostion.height, parseFloat(window.getComputedStyle(CopyOffSetArea).fontSize))
  847. let FixTop = Number((TitlePostion.top + TitlePostion.height).toFixed(2))
  848. let FixLeft = Number((TitlePostion.left + 2).toFixed(2))
  849. if(/pornchil.com/.test(PageURL)){
  850. FixLeft = getElementOffset(document.querySelector(".entry-content > h6")).left
  851. }
  852. else if(/pornrips\.cc/.test(PageURL)){
  853. FixLeft = getElementOffset(document.querySelector(".meta_date > .masha_index")).left
  854. }
  855. else if(/naughtyblog/.test(PageURL)){
  856. FixTop = getElementOffset(document.querySelector(".post-title.entry-title")).top + getElementOffset(document.querySelector(".post-title.entry-title")).height
  857. }
  858. $('.CopyNotice').css({
  859. "fontSize": Number(((1/(GetDPI/1.5))*0.6*(16/DefaultFontSize)).toFixed(2)) + 'rem',
  860. "top": FixTop + window.scrollY
  861. ,"left": FixLeft + window.scrollX
  862. , "position": "absolute",
  863. "z-index": getMaxZIndex() + 1
  864. })
  865. event.target.style = "color: Orange !important;"
  866. await CopyLink()
  867. $('.CopyNotice').slideToggle('fast', 'linear')
  868. await sleep(3000)
  869. $('.CopyNotice').slideToggle('slow')
  870. });
  871.  
  872.  
  873. document.querySelector('.CloseIcon').addEventListener("click", function(event){
  874. event.preventDefault()
  875. event.stopPropagation()
  876. event.stopImmediatePropagation()
  877. window.close()
  878. }, true)
  879.  
  880. document.querySelector('.Minus').addEventListener("click", async function(event){
  881. event.preventDefault()
  882. event.stopPropagation()
  883. event.stopImmediatePropagation()
  884. event.target.style = "color: Orange !important;";
  885. //event.target.style.setProperty('font-size', Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem', 'important');
  886. RemoveDB(listToDo(DownloadArea))
  887. CheckDB(listToDo(DownloadArea))
  888. }, true)
  889.  
  890. window.addEventListener("resize", function(e) {
  891. console.log(e.type)
  892. //GetDPI = window.devicePixelRatio
  893. //DefaultFontSize = getDefaultFontSize()
  894. //console.log('GetDPI: ', GetDPI, 'DefaultFontSize: ', DefaultFontSize)
  895. //document.querySelector('.CenterBox').style.setProperty('font-size', Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem', 'important');
  896. //document.querySelector('.State').style.setProperty('font-size', Number(((1/(GetDPI/1.5))*0.65*(16/DefaultFontSize)).toFixed(2)) + 'rem', 'important');
  897. //document.querySelector('.State').style.setProperty('line-height', Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem', 'important');
  898. //document.querySelector('.CenterBox').style.setProperty('z-index', getMaxZIndex() + 1)
  899. //document.querySelector(".IconSet").style.setProperty('z-index', MaxZIndexFromPoint('.IconSet') + 1)
  900. MakeIcon(GetDPI)
  901. })
  902. }
  903.  
  904. })
  905.  
  906. document.addEventListener("visibilitychange", async function() {
  907. //console.log("window is active!" )
  908. RootDomainDB = JSON.parse(GM_getValue(RootDomain, '[]'))
  909. GetState = RootDomainDB
  910. if(document.querySelector('.CenterBox')){
  911. document.querySelector('.State').textContent = ' ' + GetState.length
  912. document.querySelector('.ClearButton').style = "color: dodgerblue !important;";
  913. document.querySelector('.CopyButton').style = "color: dodgerblue !important;";
  914. }
  915. })
  916.  
  917.  
  918. function sleep(ms) {
  919. return new Promise(resolve => setTimeout(resolve, ms));
  920. }
  921.  
  922. function getLastText(Text) {
  923. let byteCheck = '', SearchCharPoint, TitleLastTmp
  924. let ArrayDB = Text.split(/\s/).filter(function(e){return e})//빈 배열값 제거
  925. let SeriesExp = new RegExp(Series + '.*')
  926. let ModelNameExp = new RegExp(/\((?!.*\().*\)/)
  927. let ModelName
  928.  
  929. //console.log(JapaneseChar.test([ArrayDB.length -1]) , ArrayDB[ArrayDB.length -1], ArrayDB[ArrayDB.length -2] + ' ' + ArrayDB[ArrayDB.length -1])
  930. if(ModelNameExp.test(Text)){
  931. console.log('Model Name: ', Text.match(ModelNameExp)[0])
  932. ModelName = Text.match(ModelNameExp) ? Text.match(ModelNameExp)[0] : ''
  933. Text = Text.replace(ModelNameExp, '').trim()
  934. console.log(Text)
  935. }
  936. if(Series && SeriesExp.test(Text)){
  937. console.log(Series, SeriesExp)
  938. //console.log(Text.match(SeriesExp))
  939. TitleLastTmp = Text.match(SeriesExp) ? Text.match(SeriesExp).pop() : ''
  940. }
  941. else if(/朝までハシゴ酒/.test(Text)){
  942. TitleLastTmp = Text.match(/朝までハシゴ酒.*/)[0]
  943. }
  944. else if(/\d+/.test(ArrayDB[ArrayDB.length -1])){
  945. console.log(ArrayDB[ArrayDB.length -1])
  946. if(/ファイル\d+/.test(ArrayDB[ArrayDB.length -1])){
  947. TitleLastTmp = ArrayDB[ArrayDB.length - 2] + ' ' + ArrayDB[ArrayDB.length - 1]
  948. console.log('1st Match:' , TitleLastTmp)
  949. }
  950. else if(JapaneseChar.test(ArrayDB[ArrayDB.length -1])){
  951. TitleLastTmp = ArrayDB[ArrayDB.length -1]
  952. console.log('2nd Match:' , TitleLastTmp)
  953. }
  954. else if(byteLengthOfCheck(ArrayDB[ArrayDB.length -1]) < 100) {
  955. TitleLastTmp = ArrayDB[ArrayDB.length - 2] + ' ' + ArrayDB[ArrayDB.length - 1]
  956. console.log('3th Match:' , TitleLastTmp)
  957. }
  958. }
  959. console.log('TitleLastTmp: ', TitleLastTmp, /\d+/.test(ArrayDB[ArrayDB.length -1]), byteLengthOfCheck(TitleLastTmp))
  960. if(typeof TitleLastTmp == 'undefined' || !TitleLastTmp || TitleLastTmp.length === 0 || TitleLastTmp === "" || !/[^\s]/.test(TitleLastTmp) || /^\s*$/.test(TitleLastTmp) || TitleLastTmp.replace(/\s/g,"") === ""){
  961. byteCheck = ''
  962. }
  963. else if(TitleLastTmp.match(/\d+/)){
  964. if(SearchChar(TitleLastTmp, '】')){
  965. SearchCharPoint = Text.lastIndexOf("【")
  966. TitleLastTmp = Text.substring(SearchCharPoint)
  967. console.log('TitleLastTmp: ', TitleLastTmp)
  968. }
  969. else if(SearchChar(TitleLastTmp, '、') && TitleLastTmp.length <= 10 ){
  970. SearchCharPoint = TitleLastTmp.lastIndexOf("、")
  971. TitleLastTmp = TitleLastTmp.substring(SearchCharPoint + 1)
  972. console.log('TitleLastTmp: ', TitleLastTmp)
  973. }
  974. byteCheck = TitleLastTmp
  975. console.log('byteCheck: ', byteCheck)
  976. let FlagPoint = getFlag(byteCheck)
  977. if (byteLengthOfCheck(byteCheck) >= 100){
  978. console.log('CheckFlag: ', byteCheck, byteLengthOfCheck(byteCheck))
  979. let byteCheckTmp = byteCheck.substring(FlagPoint[0])
  980. if(!JapaneseChar.test(byteCheckTmp)){
  981. byteCheckTmp = byteCheck.substring(FlagPoint[1])
  982. }
  983. if(byteLengthOfCheck(byteCheckTmp) > 250 - byteLengthOfCheck(ID)){
  984. byteCheckTmp = ''
  985. }
  986. byteCheck = byteCheckTmp
  987. }
  988. if(!/\d+|【.*】$/.test(byteCheck)){
  989. byteCheck = ''
  990. }
  991. console.log('TitleLast: ' , byteCheck)
  992. }
  993. if(ModelName) {
  994. byteCheck = byteCheck + ModelName
  995. }
  996. return byteCheck
  997. }
  998.  
  999. async function CollectionCoverImage(CoverImage){
  1000. RootDomainDB = JSON.parse(GM_getValue(RootDomain, '[]'))
  1001. if(CoverImage){
  1002. await UpdateDB(CoverImage, FilenameConvert(CopyTitle) + Resolution)
  1003. await GM_setValue(RootDomain, JSON.stringify(RootDomainDB))
  1004. }
  1005. GetState = RootDomainDB
  1006. document.querySelector('.State').textContent = ' ' + GetState.length
  1007. return CoverImage
  1008. }
  1009.  
  1010. async function CollectionLinks(DownloadArea){
  1011. RootDomainDB = JSON.parse(GM_getValue(RootDomain, '[]'))
  1012. var CollectionATag = []
  1013. DownloadArea.forEach((LinkEntry) => {
  1014. LinkEntry.querySelectorAll('a').forEach((aEntry) => {
  1015. if(/\?site.+$/.test(aEntry.href)){
  1016. aEntry.setAttribute('href', aEntry.href.replace(/\?site.+$/, ''))
  1017. }
  1018. CollectionATag.push(aEntry)
  1019. })
  1020. })
  1021. console.log('CollectionATag: ', CollectionATag )
  1022. CollectionATag = CollectionATag.filter(el => SkipClassNames.some(Skip => !el.classList.contains(Skip))) // SkipClass
  1023.  
  1024. CollectionATag = CollectionATag.filter(el => !SkipFilter.test(el.href)) // SkipFilter
  1025.  
  1026. CollectionATag = CollectionATag.filter(el => ![...el.children].some(e => e.matches('img'))) // LinkItemsChilren
  1027.  
  1028.  
  1029. if(/blogjav/.test(RootDomain)){
  1030. CollectionATag = CollectionATag.filter(el => !el.textContent.match(/\.(mp4|mkv)$/i)) // Skip mp4 mkv
  1031. }
  1032. else if(/javarchive/.test(RootDomain)){
  1033. let RemainCount = CollectionATag.filter(el => !el.textContent.match(/k2s\.cc|part\d\.rar/i)) // Skip k2s part
  1034. console.log('RemainCount:', RemainCount?.length)
  1035. if(RemainCount?.length){
  1036. CollectionATag = CollectionATag.filter(el => !el.textContent.match(/k2s\.cc|part\d\.rar/i)) // Skip k2s part
  1037. }
  1038. else{
  1039. CollectionATag = CollectionATag.filter(el => !el.textContent.match(/k2s\.cc/i)) // Skip k2s
  1040. }
  1041. }
  1042. console.log('CollectionATag: ', CollectionATag )
  1043. let SkipLink, SkipClass, LinkItemsChilren
  1044. for (let i = 0; i < CollectionATag.length; i++) {
  1045. Target = CollectionATag[i].href
  1046. if(/naughtyblog.org/.test(RootDomain)){
  1047. if(CollectionATag[i].textContent.match(/SD\.mp4/gi)){
  1048. continue
  1049. }
  1050. else if(!CopyTitle.match(/SITERIP|OnlyFans|Updates|Collection/)){
  1051. Resolution = CollectionATag[i].textContent.match(/[0-9]{3,4}p/) ? '.XXX.' + CollectionATag[i].textContent.match(/[0-9]{3,4}p/)[0] : ''
  1052. }
  1053. }
  1054. if(/blogjav.net/.test(RootDomain)){
  1055. if(Target.match(/\.mp4(\.html)?$/gi)){
  1056. continue
  1057. }
  1058. }
  1059. if(Target){
  1060. if(CopyTitle){
  1061. CopyTitle = FilenameConvert(CopyTitle)
  1062. //CopyLinks += Target + "#Title=" + encodeURI(CopyTitle) + Resolution + "\n"
  1063. UrlTitle = CopyTitle + Resolution
  1064. //console.log('RootDomainDB: ', RootDomainDB)
  1065. //await GM_setValue(Target, "#Title=" + encodeURI(CopyTitle) + Resolution)
  1066. }
  1067. CopyLinks += Target + "\n"
  1068.  
  1069. await UpdateDB(Target, UrlTitle)
  1070. }
  1071. }
  1072. await GM_setValue(RootDomain, JSON.stringify(RootDomainDB))
  1073. GetState = RootDomainDB
  1074. document.querySelector('.State').textContent = ' ' + GetState.length
  1075. console.log(CopyLinks)
  1076. if(CopyLinks?.length){
  1077. return CopyLinks.split("\n").filter((item, i, allItems) => { return i === allItems.indexOf(item)}).join("\n")
  1078. }
  1079. else return null
  1080. }
  1081.  
  1082.  
  1083. async function UpdateDB(Target, UrlTitle){
  1084. if(Target.match(K2SRegExp)){
  1085. Target = Target.match(K2SRegExp)[1] + Target.match(K2SRegExp)[2].slice(0, 18)
  1086. }
  1087. searchDB = RootDomainDB.find( ({ U }) => U === Target )
  1088. console.log(RootDomainDB, searchDB)
  1089. if(searchDB){
  1090. searchDB.T = UrlTitle
  1091. }
  1092. else{
  1093. RootDomainDB.push({U : Target , T : UrlTitle})
  1094. }
  1095. //console.log(RootDomainDB)
  1096. return RootDomainDB
  1097. }
  1098.  
  1099.  
  1100. async function RemoveDB(listToDelete){
  1101. RootDomainDB = RootDomainDB.filter( item => (!listToDelete.includes(item.U)) );
  1102. await GM_setValue(RootDomain, JSON.stringify(RootDomainDB))
  1103. GetState = RootDomainDB
  1104. document.querySelector('.State').textContent = ' ' + GetState.length
  1105. }
  1106.  
  1107. async function CheckDB(listTo){
  1108. if(GetState.length > 0){
  1109. let Check = RootDomainDB.some( item => (listTo.includes(item.U)))
  1110. console.log('CheckDB: ', RootDomainDB, listTo, Check)
  1111. if(Check){
  1112. document.querySelector('.Minus').style.visibility = "visible"
  1113. }
  1114. else{
  1115. document.querySelector('.Minus').style.visibility = "hidden"
  1116. }
  1117. }
  1118. }
  1119.  
  1120. async function CopyLink(){
  1121. var CopyNoticeData = ''
  1122. console.log('CopyLinks: ', CopyLinks, TmpLinksDB, !CopyLinks?.length, !TmpLinksDB?.length)
  1123. if(!CopyLinks?.length && !TmpLinksDB?.length){
  1124. CopyNoticeData = FilenameConvert(CopyTitle) + "\n"
  1125. AllCopyLinks = await CollectionLinks(DownloadArea)
  1126. console.log('AllCopyLinks: ', AllCopyLinks)
  1127. if(AllCopyLinks){
  1128. if(CoverImage){
  1129. AllCopyLinks += await CollectionCoverImage(CoverImage)
  1130. }
  1131. JDownloader(AllCopyLinks, FilenameConvert(CopyTitle) + Resolution)
  1132. //updateClipboard(AllCopyLinks)
  1133. CopyNoticeData += AllCopyLinks
  1134. document.querySelector('.CopyNotice').textContent = CopyNoticeData
  1135. }
  1136. else{
  1137. document.querySelector('.CopyNotice').textContent = 'Empty Links'
  1138. }
  1139. }
  1140. else if(TmpLinksDB?.length > 0){
  1141. console.log('TmpLinksDB: ', TmpLinksDB)
  1142.  
  1143. for (let i = 0; i < TmpLinksDB.length; i++) {
  1144. UpdateDB(TmpLinksDB[i].U, TmpLinksDB[i].T)
  1145. CopyLinks += TmpLinksDB[i].U + '\n'
  1146. //await GM_setValue(TmpLinksDB[i].Key, TmpLinksDB[i].Value)
  1147. }
  1148. await GM_setValue(RootDomain, JSON.stringify(RootDomainDB))
  1149. GetState = RootDomainDB
  1150. //console.log(GetState)
  1151. document.querySelector('.State').textContent = ' ' + GetState.length
  1152. console.log(TmpLinksDB)
  1153. JDownloaderDB(TmpLinksDB)
  1154. //console.log(JdownloaderData)
  1155.  
  1156. //updateClipboard(CopyLinks)
  1157. CopyNoticeData = CopyLinks
  1158. document.querySelector('.CopyNotice').textContent = CopyNoticeData
  1159. }
  1160. await CheckDB(listToDo(DownloadArea))
  1161. CopyLinks = []
  1162. AllCopyLinks = []
  1163. }
  1164.  
  1165.  
  1166. function listToDo(Area) {
  1167. let List = [], CheckList = []
  1168. let Target
  1169. try {
  1170. Area.forEach((LinkEntry) => {
  1171. LinkEntry.querySelectorAll('a').forEach((aEntry) => {
  1172. if(CheckList.indexOf(aEntry) === -1){
  1173. CheckList.push(aEntry)
  1174. }
  1175. })
  1176. })
  1177. for (let i = 0; i < CheckList.length; i++) {
  1178. let SkipLink = SkipFilter.test(CheckList[i].href)
  1179. let LinkItemsChilren = [...CheckList[i].children].filter(e => e.matches('img'))
  1180. if(SkipLink || LinkItemsChilren?.length){
  1181. continue
  1182. }
  1183. Target = CheckList[i].href.replace(/\?site.+/, '')
  1184. if(Target.match(K2SRegExp)){
  1185. Target = Target.match(K2SRegExp)[1] + Target.match(K2SRegExp)[2].slice(0, 18)
  1186. }
  1187. if(List.indexOf(Target) === -1){
  1188. List.push(Target)
  1189. }
  1190. }
  1191. if(CoverImage){
  1192. List.push(CoverImage)
  1193. }
  1194. return List
  1195. } catch (err){
  1196. console.log(err)
  1197. return List
  1198. }
  1199.  
  1200. }
  1201.  
  1202. async function MutilSubTitle(MatchWeb, MatchWebPoint, InfoAreaCast, DownloadArea) {
  1203. let AreadyAdd = [], CastName, CastNameDB = [], CastFirstTitle, CastLastTitle
  1204. for (let i = 0; i < InfoAreaCast.length; i++) {
  1205. let MatchPoint = InfoAreaCast[i].search(/\s?-\s/)
  1206. console.log('MatchPoint: ', MatchPoint)
  1207. console.log(MatchWeb, InfoAreaCast[i].substr(0, MatchPoint).replace(/\s/g, ''))
  1208. if(MatchPoint !== -1 && MatchWeb !== InfoAreaCast[i].substr(0, MatchPoint).replace(/\s/g, '')){
  1209. CastName = MatchPoint !== -1 ? InfoAreaCast[i].substr(0, MatchPoint).replace(/\s?(,|&|aka.*)\s?/gi, '&').replace(/\s{2}/g, ' ').trim().replace(/\s/g, '.') : ''
  1210. console.log('CastName: ' , CastName)
  1211. if(CastName.match(/&/)){
  1212. CastNameDB = CastName.split('&')
  1213. CastName = CastNameDB[0] + '(.+)\?' + CastNameDB.pop()
  1214. }
  1215. }
  1216. else{
  1217. CastName = ''
  1218. }
  1219. console.log('CastName: ' , CastName)
  1220. console.log(MatchPoint, InfoAreaCast[i].lastIndexOf(' - '))
  1221. CastFirstTitle = MatchPoint !== -1 ? InfoAreaCast[i].slice(MatchPoint + 1, InfoAreaCast[i].length).replace(/\s-\s.*/, '').split(' ') : []
  1222. CastFirstTitle = CastFirstTitle?.length > 0 ? CastFirstTitle.filter((entry) => isNaN(entry)) : []//숫자 및 단일글자 제거
  1223. CastFirstTitle = CastFirstTitle?.length > 0 ? CastFirstTitle.filter((entry) => entry.length > 1) : []//숫자 및 단일글자 제거
  1224. CastFirstTitle = CastFirstTitle?.length > 0 ? CastFirstTitle.shift().trim() : ''
  1225. CastLastTitle = MatchPoint !== -1 ? InfoAreaCast[i].slice(MatchPoint + 1, InfoAreaCast[i].length).replace(/\s-\s.*/, '').split(' ') : []
  1226. //CastLastTitle = MatchPoint !== -1 ? InfoAreaCast[i].slice(MatchPoint + 1, InfoAreaCast[i].lastIndexOf(' - ')).replace(/\s-\s.*/, '').split(' ') : []
  1227. CastLastTitle = CastLastTitle?.length > 0 ? CastLastTitle.filter((entry) => isNaN(entry)) : []//숫자 및 단일글자 제거
  1228. CastLastTitle = CastLastTitle?.length > 0 ? CastLastTitle.filter((entry) => entry.length > 1) : []//숫자 및 단일글자 제거
  1229. CastLastTitle = CastLastTitle?.length > 0 ? CastLastTitle.pop().trim() : ''
  1230. console.log('Cast First & Last Title: ', CastFirstTitle, CastLastTitle)
  1231. DownloadArea = document.querySelectorAll('div#download')
  1232. DownloadArea.forEach((LinkEntry) => {
  1233. let Links
  1234. if(CastName){
  1235. Links = MatchRegex(LinkEntry, new RegExp(CastName + '.*' + CastFirstTitle + '.*' + CastLastTitle, 'i'), 'href')
  1236. if(!Links?.length){
  1237. Links = MatchRegex(LinkEntry, new RegExp(CastName, 'i'), 'href')
  1238. if(!Links?.length){
  1239. console.log('Links Empty...')
  1240. return
  1241. }
  1242. }
  1243. }
  1244. else{
  1245. Links = MatchRegex(LinkEntry, new RegExp(CastFirstTitle + '.*' + CastLastTitle, 'i'), 'href')
  1246. if(!Links?.length){
  1247. Links = MatchRegex(LinkEntry, new RegExp(CastFirstTitle, 'i'), 'href')
  1248. if(!Links?.length){
  1249. console.log('Links Empty...')
  1250. return
  1251. }
  1252. }
  1253. }
  1254. Links = Links.filter( ( el ) => !AreadyAdd.includes( el )) //이미 추가된 링크 제외
  1255. // 링크가 6개 이상일때 짝수인덱스 값만 가져오기
  1256. if(Links?.length >= 6){
  1257. var filtered = Links.filter(function(element, index, array) {
  1258. return (index % 2 === 0);
  1259. });
  1260. Links = filtered
  1261. }
  1262. console.log('Links: ', Links)
  1263.  
  1264. for (let j = 0; j < Links.length; j++) {
  1265. let LinkText = Links[j].innerText.search(MatchWebRegExp) ? Links[j].innerText.substr(Links[j].innerText.search(MatchWebRegExp)) : Links[j].innerText
  1266. console.log('LinkText: ', LinkText)
  1267.  
  1268. let Released = LinkText.match(/(.+)(\.\d+\.\d+.\d+\.)(.+)/) ? LinkText.match(/(\.\d+\.\d+.\d+\.)/).pop()
  1269. : MatchWebPoint !== -1 && LinkText.match(new RegExp(MatchWeb + '\\.\\d{4}\\.')) ? LinkText.match(new RegExp(MatchWeb + '\(\\.\\d{4}\\.\)')).pop()
  1270. : ''
  1271. console.log('Released: ', Released)
  1272. let Episode = LinkText.match(/E\d{2,5}/i) ? '.' + LinkText.match(/E\d{2,5}/i) + '.' : ''
  1273. Resolution = LinkText.match(/[0-9]{3,4}p/) ? '.XXX.' + LinkText.match(/[0-9]{3,4}p/)[0] : ''
  1274. let CastTitle = InfoAreaCast[i].substr(MatchPoint + 3) && Episode ? '- ' + InfoAreaCast[i].substr(MatchPoint + 3).replace(/-\sE\d{2,5}/i, '').trim()
  1275. : InfoAreaCast[i].substr(MatchPoint + 3) && !Episode ? '- ' + InfoAreaCast[i].substr(MatchPoint + 3)
  1276. : ''
  1277. console.log('CastTitle: ', CastTitle)
  1278. let CastRegExp = LinkText.match(CastFirstTitle) && LinkText.match(CastLastTitle) ? new RegExp(MatchWeb + Episode + Released + CastName + '.*(' + CastFirstTitle + ')?(.*' + CastLastTitle + ')?', 'i') : ''
  1279. console.log('CastRegExp: ', CastRegExp)
  1280. let Cast = LinkText.match(CastRegExp)
  1281. console.log('Cast: ', Cast)
  1282. Title = CastRegExp && Cast && Cast.length > 1 && Episode ? MatchWeb + Episode + Released + Cast.pop().replace(/\./g, ' ') + CastTitle
  1283. : Episode || Released ? MatchWeb + Episode + Released + InfoAreaCast[i]
  1284. : MatchWeb + ' ' + Released + InfoAreaCast[i]
  1285. Title = Title.replace(/(S\d+):(E\d+)/i, '$1$2')
  1286. Title = FilenameConvert(Title)
  1287. //CopyLinks += Links[j].href + "\n"
  1288. let U = Links[j].href
  1289. let T = Title + Resolution
  1290. console.log(Title, Links[j])
  1291. TmpLinksDB.push({U, T})
  1292. AreadyAdd.push(Links[j])
  1293. }
  1294. if(CoverImage){
  1295. let U = CoverImage
  1296. let T = FilenameConvert(CopyTitle) + Resolution
  1297. TmpLinksDB.push({U, T})
  1298. }
  1299. })
  1300. }
  1301. }
  1302.  
  1303. async function ClearUrls(){
  1304. document.querySelector('.ClearButton').style = "color: White !important;";
  1305. //document.querySelector('.ClearButton').style.setProperty('font-size', Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem', 'important');
  1306. await GM_deleteValue(RootDomain)
  1307. RootDomainDB = JSON.parse(GM_getValue(RootDomain, '[]'))
  1308. GetState = RootDomainDB
  1309. //console.log(GetState)
  1310. if(document.querySelector('.Minus')){
  1311. document.querySelector('.Minus').style.visibility = "hidden"
  1312. }
  1313. document.querySelector('.State').textContent = ' ' + 0
  1314. }
  1315.  
  1316. async function ClipPaste(){
  1317. document.querySelector('.CopyButton').style = "color: White !important;";
  1318. //document.querySelector('.CopyButton').style.setProperty('font-size', Number(((1/(GetDPI/1.5))*(16/DefaultFontSize)).toFixed(2)) + 'rem', 'important');
  1319. var ClipPasteData = JSON.parse(GM_getValue(RootDomain, '[]'))
  1320. JDownloaderDB(ClipPasteData)
  1321. //updateClipboard(ClipPasteData)
  1322. }
  1323.  
  1324.  
  1325. function MakeIcon(GetDPI) {
  1326. clearTimeout(MakeIconTimer)
  1327. if(CopyOffSetArea){
  1328. let ModArea = CopyOffSetArea
  1329. let OffSetArea
  1330. let IconSet = document.querySelector(".IconSet")
  1331. //console.log(ModArea, ModArea.nodeType)
  1332. if(/kbjme\.com/.test(RootDomain)){
  1333. OffSetArea = ModArea.closest('.article_container')
  1334. OffSetArea.style.setProperty('position', 'relative')
  1335. }
  1336. else if(/javarchive\.com/.test(RootDomain)){
  1337. OffSetArea = ModArea.closest('.category_news_phai_chinh').querySelector('.menudd')
  1338. OffSetArea.style.setProperty('position', 'relative')
  1339. }
  1340. else if(/pornchil\.com/.test(RootDomain)){
  1341. OffSetArea = ModArea.closest('.entry-content')
  1342. OffSetArea.style.setProperty('position', 'relative')
  1343. }
  1344. else if(/top-modelz\.org/.test(RootDomain)){
  1345. OffSetArea = ModArea.closest('.newspad')
  1346. OffSetArea.style.setProperty('position', 'relative')
  1347. }
  1348. else{
  1349. OffSetArea = ModArea
  1350. OffSetArea.parentElement.style.setProperty('position', 'relative')
  1351. }
  1352. var GetViewProperty = window.document.defaultView.getComputedStyle(ModArea, null)
  1353. var GetPadding = GetViewProperty.getPropertyValue('padding') || 0
  1354. var verticalalign = GetViewProperty.getPropertyValue('vertical-align') || 'middle'
  1355. var lineheight = GetViewProperty.getPropertyValue('line-height') || '1rem'
  1356. var Top = GetViewProperty.getPropertyValue('top') || 'auto'
  1357. var DisPlay = GetViewProperty.getPropertyValue('display') || 'auto'
  1358. let IconHeight = parseFloat(window.getComputedStyle(IconSet).fontSize)
  1359. let FontHeight = parseFloat(window.getComputedStyle(OffSetArea).fontSize)
  1360. let OffSetAreaElementOffset = getRelativeOffset(OffSetArea)
  1361. let OffSetAreatNodeTextElementOffset = getNodeTextElementOffset(OffSetArea)
  1362. let IconSetElementOffset = getRelativeOffset(IconSet)
  1363.  
  1364. if(/javfree|blogjav|javpink|wetholefans/.test(PageURL)){
  1365. $('.IconSet').css({
  1366. "top": OffSetAreaElementOffset.top - IconSetElementOffset.height ,
  1367. "left": OffSetAreaElementOffset.width - IconSetElementOffset.width/2
  1368. })
  1369. }
  1370. else if(/naughtyblog|pornrip\.cc/.test(PageURL)) {
  1371. $('.IconSet').css({
  1372. "top": OffSetAreaElementOffset.top,
  1373. "left": OffSetAreaElementOffset.width - IconSetElementOffset.width
  1374. })
  1375. }
  1376. else if(/pornrips\.cc/.test(PageURL)) {
  1377. let PostDate = OffSetArea.parentElement.querySelector('.meta_date > .masha_index')
  1378. $('.IconSet').css({
  1379. "top": OffSetAreaElementOffset.top - OffSetAreatNodeTextElementOffset.top + IconSetElementOffset.height*3/2,
  1380. "left": getElementOffset(PostDate).left + OffSetAreatNodeTextElementOffset.width/2
  1381. })
  1382. }
  1383. else if(/javarchive/.test(PageURL)) {
  1384. $('.IconSet').css({
  1385. "top": OffSetAreaElementOffset.top + OffSetAreaElementOffset.height - IconSetElementOffset.height/2,
  1386. "left": OffSetAreaElementOffset.left + OffSetAreaElementOffset.width - IconSetElementOffset.width
  1387. })
  1388. }
  1389. else if(/kbjme\.com/.test(PageURL)) {
  1390. //document.querySelector("div.container div#blogname.third a img").addEventListener("load",function() {
  1391. $('.IconSet').css({
  1392. "top": getElementOffset(IconSet).height*3/2,
  1393. "left": OffSetAreaElementOffset.right - OffSetAreaElementOffset.width + IconSetElementOffset.width
  1394. })
  1395. //})
  1396. }
  1397. else if(/maxjav\.com/.test(PageURL)) {
  1398. $('.IconSet').css({
  1399. "top": OffSetAreaElementOffset.top + IconSetElementOffset.height/2,
  1400. "left": OffSetAreaElementOffset.left + OffSetAreaElementOffset.width - IconSetElementOffset.width
  1401. })
  1402. }
  1403. else if(/0xxx\.ws\/articles\/\d+|top-modelz\.org/.test(PageURL)) {
  1404. //console.log((getElementOffset(OffSetArea).top - getNodeTextElementOffset(OffSetArea).top)/2)
  1405. $('.IconSet').css({
  1406. "top": Math.abs((OffSetAreaElementOffset.top - OffSetAreatNodeTextElementOffset.top)/2),
  1407. "right": IconHeight
  1408. })
  1409. }
  1410. else if(/hpjav\.tv/.test(PageURL)) {
  1411. $('.IconSet').css({
  1412. "top": OffSetAreaElementOffset.top - Math.abs(FontHeight - IconHeight)/2,
  1413. "left": OffSetAreaElementOffset.width + IconHeight
  1414. })
  1415. }
  1416.  
  1417. else if(/8kcosplay\.com|fhdporn/.test(PageURL)){
  1418. $('.IconSet').css({
  1419. "top": OffSetAreaElementOffset.top - IconHeight,
  1420. "left": OffSetAreaElementOffset.width - IconSetElementOffset.width
  1421. })
  1422. }
  1423. else if(/av18plus\.com/.test(PageURL)){
  1424. $('.IconSet').css({
  1425. "top": OffSetAreaElementOffset.top - IconHeight,
  1426. "left": OffSetAreaElementOffset.width - IconSetElementOffset.width
  1427. })
  1428. }
  1429. else if(/pornchil\.com|asianscan/.test(PageURL)){
  1430. $('.IconSet').css({
  1431. "top": 0,
  1432. "left": OffSetAreaElementOffset.width - IconHeight
  1433. })
  1434. }
  1435. else {
  1436. $('.IconSet').css({
  1437. "top": OffSetAreaElementOffset.top,
  1438. "left": OffSetAreaElementOffset.width + IconHeight,
  1439. })
  1440. }
  1441. IconSet.style.visibility = "visible"
  1442. document.querySelector('.CopyIcon').style.visibility = "visible"
  1443. document.querySelector(".CloseIcon").style.visibility = "visible"
  1444. if(DownloadArea){
  1445. CheckDB(listToDo(DownloadArea))
  1446. }
  1447. //console.log(getElementOffset(OffSetArea), getNodeTextElementOffset(OffSetArea), getElementOffset(IconSet), getRelativeOffset(OffSetArea), getRelativeOffset(IconSet), FontHeight, IconHeight )
  1448. }
  1449. }
  1450.  
  1451.  
  1452. function JDownloader(JdownloaderData, PackageName){
  1453. //console.log(PackageName + '\n' + JdownloaderData)
  1454. $.post("http://127.0.0.1:9666/flash/add", {
  1455. urls: JdownloaderData,
  1456. referer: PageURL,
  1457. package: PackageName
  1458. })
  1459. //}
  1460. }
  1461.  
  1462. function JDownloaderDB(LinksDB){
  1463. //console.log(LinksDB)
  1464. let uniqueTitle = [...new Set(LinksDB.map( x => x.T ))]
  1465. //console.log(uniqueTitle)
  1466. uniqueTitle.forEach(x => JDownloader(GetMatchLinks(x, LinksDB), x))
  1467. }
  1468.  
  1469. function GetMatchLinks(text, LinksDB){
  1470. try {
  1471. return LinksDB.filter(u => text.includes(u.T)).map(l => l.U).join('\n')
  1472. } catch(err) {
  1473. console.log(err, text, LinksDB)
  1474. }
  1475. }
  1476.  
  1477. function scrollToTop() {
  1478.  
  1479. window.scrollTo({ top: 0, behavior: 'auto' })
  1480. window.removeEventListener('scroll', scrollToTop)
  1481.  
  1482. }
  1483.