NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Adopt a HANDJOB
// @namespace http://tampermonkey.net/
// @version 0.1.2
// @description Download at-risk torrents released by HANDJOB
// @author OTMOP
// @license MIT
// @copyright 2020, OTMOP and HANDJOB
// @icon https://ptpimg.me/6uob9q.png
// @match https://passthepopcorn.me/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant unsafeWindow
// @run-at document-end
// ==/UserScript==
/* CHANGELOG
0.1.2
- Added option to include or ignore trumpable torrents
- Added option to search only for DVDRip encodes
0.1.1
- Minor style tweaks
- Refined some option names
- Added option to include previously downloaded (but not snatched or leeching) torrents in the search
- Users can now repeat the search without reloading the page
- Added help icon tooltips to explain each option
*/
(() => {
const PRIMARY_COLOUR = "#3498db";
// eslint-disable-next-line no-undef
const savedOptions = GM_getValue("adopt-options") || {};
let TORRENT_CAP = savedOptions.torrentCap || 20;
const IGNORE_ZERO_SEEDERS = true;
let INCLUDE_TRUMPABLE = savedOptions.includeTrumpable || false;
let INCLUDE_DOWNLOADED = savedOptions.includeDownloaded || false;
let MAX_SEEDERS = savedOptions.maxSeeders || 2;
let SEARCH_DELAY = savedOptions.searchDelay || 1000;
let SEARCH_PAGE_OFFSET = savedOptions.searchOffset || 10;
let DOWNLOAD_DELAY = savedOptions.downloadDelay || 1000;
let RESOLUTION = savedOptions.resolutions || "anysd"; // null, anysd, anyhd, 480p, 576p, 720p, 1080p
let AuthKey, TorrentPass;
const modal = injectElements();
class Stats {
constructor() {
this.form = document.querySelector("#handjob__adopt-modal fieldset");
this.form.querySelector("#handjob__adopt-input--resolution").value = RESOLUTION;
if (INCLUDE_DOWNLOADED === true)
this.form.querySelector("#handjob__adopt-input--include-downloaded").checked = true;
if (INCLUDE_TRUMPABLE === true)
this.form.querySelector("#handjob__adopt-input--include-trumpable").checked = true;
this.button = document.querySelector("#handjob__adopt-submit-button");
this.closeButton = document.querySelector("#handjob__adopt-close-button");
this.closeButton.addEventListener("click", () => modal.classList.add("hidden"));
this.searchDisplay = document.querySelector("#handjob__adopt-download-status-pages span");
this.foundDisplay = document.querySelector("#handjob__adopt-download-status-found span");
this.torrentsDisplay = document.querySelector("#handjob__adopt-download-status-torrents span");
this.activeTaskDisplay = document.querySelector("#handjob__adopt-download-active-task span");
this.activeTaskIcon = document.querySelector("#handjob__adopt-download-active-task .handjob__adopt-icon");
this.percentDisplay = document.querySelector(".handjob__adopt-loader-percent");
this.loader = document.querySelector(".handjob__adopt-loader");
this.tasks = [];
this.Reset();
this.Refresh();
}
Reset() {
this.tasks = [];
this.searching = true;
this.pagesSearched = 0;
this.found = 0;
this.downloaded = 0;
this.percent = 0;
this.button.disabled = "";
this.closeButton.disabled = "";
this.loader.style.borderTop = "";
}
loadOptions() {
const dl = !!this.form.querySelector("#handjob__adopt-input--include-downloaded").checked;
INCLUDE_DOWNLOADED = savedOptions.includeDownloaded = dl;
const trumpable = !!this.form.querySelector("#handjob__adopt-input--include-trumpable").checked;
INCLUDE_TRUMPABLE = savedOptions.includeTrumpable = trumpable;
const cap = parseInt(this.form.querySelector("#handjob__adopt-input--torrent-cap").value, 10);
TORRENT_CAP = savedOptions.torrentCap = cap ? cap : TORRENT_CAP;
const res = this.form.querySelector("#handjob__adopt-input--resolution").value;
RESOLUTION = savedOptions.resolutions = res == "any" ? "" : !res ? RESOLUTION : res;
if (savedOptions.resolutions === "") savedOptions.resolutions = "any";
const offset = parseInt(this.form.querySelector("#handjob__adopt-input--search-offset").value, 10);
SEARCH_PAGE_OFFSET = savedOptions.searchOffset = offset ? offset : SEARCH_PAGE_OFFSET;
const maxSeeders = parseInt(this.form.querySelector("#handjob__adopt-input--max-seeders").value, 10);
MAX_SEEDERS = savedOptions.maxSeeders = maxSeeders ? maxSeeders : MAX_SEEDERS;
const searchDelay = parseInt(this.form.querySelector("#handjob__adopt-input--search-delay").value, 10);
SEARCH_DELAY = savedOptions.searchDelay = searchDelay ? searchDelay : SEARCH_DELAY;
const downloadDelay = parseInt(this.form.querySelector("#handjob__adopt-input--download-delay").value, 10);
DOWNLOAD_DELAY = savedOptions.downloadDelay = downloadDelay ? downloadDelay : DOWNLOAD_DELAY;
// eslint-disable-next-line no-undef
GM_setValue("adopt-options", savedOptions);
}
AddPageSearched() {
this.pagesSearched++;
this.Refresh();
}
AddFound(num) {
this.found += num;
this.Refresh();
}
AddDownloaded() {
this.downloaded++;
this.Refresh();
}
AddTask(task) {
switch (task.type) {
case "error":
this.activeTaskIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><path d="M9 1.03c-4.42 0-8 3.58-8 8s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zM10 13H8v-2h2v2zm0-3H8V5h2v5z"/></svg>`;
this.activeTaskIcon.className = "handjob__adopt-icon icon-error";
break;
case "success":
this.activeTaskIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>`;
this.activeTaskIcon.className = "handjob__adopt-icon icon-success";
}
this.tasks.push(task);
const changeTask = () => {
if (task) this.activeTaskDisplay.innerHTML = task.text;
this.activeTaskDisplay.removeEventListener("transitionend", changeTask);
this.activeTaskDisplay.classList.remove("hide-task");
};
this.activeTaskDisplay.addEventListener("transitionend", changeTask);
this.activeTaskDisplay.classList.add("hide-task");
}
Start() {
this.Reset();
this.loadOptions();
this.loader.classList.remove("paused");
this.button.disabled = true;
this.closeButton.disabled = true;
}
End() {
this.loader.classList.add("paused");
this.closeButton.disabled = "";
this.button.disabled = "";
}
Refresh() {
if (this.downloaded >= 1) {
this.searching = false;
this.loader.style.borderTop = "16px solid #ef7017";
}
if (this.searching) {
this.percent = Math.round((100 / TORRENT_CAP) * this.found);
if (this.percent > 100) this.percent = 100;
} else {
this.percent = Math.round((100 / TORRENT_CAP) * this.downloaded);
}
this.searchDisplay.innerHTML = this.pagesSearched;
this.torrentsDisplay.innerHTML = this.downloaded;
this.foundDisplay.innerHTML = this.found;
if (this.percent !== null) this.percentDisplay.innerHTML = this.percent + "%";
}
}
class Torrent {
constructor(json) {
this.torrentid = json.TorrentId;
this.filename = json.ReleaseName;
}
Download() {
return new Promise((resolve, reject) => {
fetch(this.GenerateDL())
.then(res => res.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = this.filename + ".torrent";
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
setTimeout(() => {
resolve(this.filename + " downloaded");
}, DOWNLOAD_DELAY);
})
.catch(err => {
console.log(err);
});
});
}
GenerateDL() {
const root = `https://passthepopcorn.me/torrents.php?`;
return root + `action=download&id=${this.torrentid}&authkey=${AuthKey}&torrent_pass=${TorrentPass}`;
}
}
const stats = new Stats();
let torrents = [];
function getSearchURL() {
let search = "https://passthepopcorn.me/torrents.php?action=advanced&encoding=MKV&format=x264";
if (RESOLUTION === "dvd") search += "&media=DVD&resolution=anysd";
else if (RESOLUTION) search += "&resolution=" + RESOLUTION;
search += "&filelist=handjob&order_by=seeders&order_way=asc&grouping=0";
return search;
}
function getTorrentResults(resultsPage = SEARCH_PAGE_OFFSET) {
return new Promise((resolve, reject) => {
stats.AddTask({ type: "info", text: "Downloading results from page " + resultsPage });
const url = getSearchURL() + "&page=" + resultsPage;
fetch(url)
.then(res => res.text())
.then(raw => {
stats.AddPageSearched();
const parse = new DOMParser();
const dom = parse.parseFromString(raw, "text/html");
const script = Array.from(dom.querySelectorAll("#content script")).find(
x => !x.src && /var PageData/i.test(x.innerHTML)
);
if (!script) return reject(torrents);
const jsonString = script.textContent.match(/(?:var PageData\s*=\s*)([\w\W]*)(?:;\s*)$/);
const json = JSON.parse(jsonString[1]);
if (json.Movies.length === 0) return reject(torrents);
if (!AuthKey) AuthKey = json.AuthKey;
if (!TorrentPass) TorrentPass = json.TorrentPass;
const results = json.Movies.map(result => {
const torrentResult = result.GroupingQualities[0].Torrents[0];
if (INCLUDE_TRUMPABLE === false)
if (/torrent-info__trumpable/i.test(torrentResult.Title)) return null;
if (INCLUDE_DOWNLOADED === true) {
if (torrentResult.ColorType && torrentResult.ColorType !== "downloaded") return null;
} else if (torrentResult.ColorType) return null;
if (IGNORE_ZERO_SEEDERS === true && torrentResult.Seeders == 0) return null;
if (torrentResult.Seeders > MAX_SEEDERS) return null;
return new Torrent(torrentResult);
}).filter(x => x);
stats.AddFound(results.length);
if (results.length === 0) resultsPage += 5;
else resultsPage++;
torrents.push(...results);
if (torrents.length < TORRENT_CAP) {
setTimeout(() => {
resolve(getTorrentResults(resultsPage));
}, SEARCH_DELAY);
} else resolve(torrents);
});
});
}
function runDownloader() {
modal.classList.remove("hidden");
stats.AddTask({ type: "info", text: "Waiting to begin..." });
const cb = () =>
getTorrentResults()
.catch(torrents => {
if (torrents.length > 1) {
stats.AddTask({ type: "error", text: "No results in search page" });
return torrents;
} else {
stats.Reset();
throw "No torrents found. Try adjusting search page offset!";
}
})
.then(res => {
res = res.slice(0, TORRENT_CAP);
let i = 0;
const downloadTorrent = (torrent = res[i]) =>
new Promise((resolve, reject) => {
stats.AddTask({ type: "info", text: "Downloading torrent file for " + torrent.filename });
torrent.Download().then(() => {
stats.AddDownloaded();
i++;
if (res[i]) return resolve(downloadTorrent(res[i]));
else return resolve();
});
});
downloadTorrent().then(() => {
stats.End();
stats.AddTask({ type: "success", text: "All downloads complete" });
torrents = [];
});
})
.catch(err => {
stats.AddTask({ type: "error", text: err });
stats.End();
});
stats.button.addEventListener("click", () => {
stats.Start();
cb();
});
}
function injectElements() {
const css = `
#handjob__adopt-modal.hidden {
opacity: 0;
pointer-events: none;
}
.handjob__adopt-toolbar {
width: 100%;
background-color: ${PRIMARY_COLOUR};
color: white;
font-family: Roboto,Verdana, sans-serif;
font-size: 24px;
text-align: center;
padding: 8px;
border-radius: 4px;
margin-top: -44px;
margin-bottom: 20px;
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
text-transform: uppercase;
font-weight: bold;
}
#handjob__adopt-download-active-task span {
transition: opacity 100ms ease-in-out;
}
#handjob__adopt-download-active-task span.hide-task {
opacity: 0;
}
#handjob__adopt-modal {
display: flex;
position: fixed;
z-index: 9999;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.3);
justify-content: center;
align-items: center;
opacity: 1;
transition: opacity 500ms ease-in-out;
}
.handjob__adopt-loader-container {
position: relative;
width: 120px;
height: 120px;
}
.handjob__adopt-loader {
width: 100%;
height: 100%;
border: 16px solid #030303;
border-radius: 50%;
border-top: 16px solid ${PRIMARY_COLOUR};
transition: border-top 500ms ease-in-out;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
.handjob__adopt-loader.paused{
-webkit-animation-play-state:paused;
-moz-animation-play-state:paused;
-o-animation-play-state:paused;
animation-play-state:paused;
}
.handjob__adopt-loader-percent {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
font-size: 24px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
#handjob__adopt-modal-inner {
width: 800px;
min-height: 200px;
background-color: #EFEFEF;
border-radius: 10px;
display: flex;
align-items: center;
flex-flow: column;
padding: 20px;
}
#handjob__adopt-download-status {
font-family: Inconsolata, monospace;
margin-top: 24px;
color: #3c3c3c;
font-size: 14px;
width: 100%;
display: flex;
flex-flow: column;
align-items: flex-end;
}
#handjob__adopt-download-status-top {
width: 100%;
display: flex;
justify-content: space-between;
}
#handjob__adopt-download-status-pages {
}
#handjob__adopt-download-status-torrents {
}
#handjob__adopt-download-active-task {
width: 100%;
display: flex;
align-items: center;
border-radius: 4px;
padding: 16px;
margin-top: 16px;
max-width: 100%;
outline: none;
text-decoration: none;
transition-property: box-shadow,opacity;
overflow-wrap: break-word;
position: relative;
white-space: normal;
transition: box-shadow .28s cubic-bezier(.4,0,.2,1);
will-change: box-shadow;
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
}
#handjob__adopt-download-active-task svg {
margin-right: 16px;
}
.handjob__adopt-btn {
font-family: Roboto, Arial, sans-serif;
text-transform: uppercase;
display: inline-block;
margin-bottom: 0;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
border-top-color: transparent;
border-right-color: transparent;
border-bottom-color: transparent;
border-left-color: transparent;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
border-radius: 4px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.handjob__adopt-btn:focus {
outline: none;
}
.handjob__adopt-btn.disabled, .handjob__adopt-btn[disabled] {
cursor: not-allowed;
pointer-events: none;
filter: alpha(opacity=65);
opacity: .65;
-webkit-box-shadow: none;
box-shadow: none;
}
.handjob__adopt-btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.handjob__adopt-btn-error {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
.handjob__adopt-btn-error:hover {
color: #fff;
background-color: #c9302c;
background-image: none;
border-color: #ac2925;
}
.handjob__adopt-btn-error:active {
color: #fff;
background-color: #c9302c;
background-image: none;
border-color: #ac2925;
}
.handjob__adopt-btn-primary:hover {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.handjob__adopt-btn-primary:active {
color: #fff;
background-color: #286090;
background-image: none;
border-color: #204d74;
}
#handjob__adopt-actions {
margin-top: 24px;
}
#handjob__adopt-actions button:not(:last-child) {
margin-right: 16px;
}
#handjob__adopt-modal fieldset {
width: 100%;
margin-bottom: 16px;
border-radius: 4px;
}
#handjob__adopt-input--torrent-cap,
#handjob__adopt-input--search-offset,
#handjob__adopt-input--max-seeders {
max-width: 50px;
text-align: center;
}
#handjob__adopt-input--search-delay,
#handjob__adopt-input--download-delay {
max-width: 75px;
text-align: center;
}
#handjob__adopt-input--resolution {
max-width: 200px;
}
#handjob__adopt-modal table {
color: #000;
}
#handjob__adopt-modal table td {
padding: 8px 16px;
}
.handjob__adopt-icon {
min-width: 18px;
min-height: 18px;
}
.handjob__adopt-icon.icon-error svg {
fill: red;
}
.handjob__adopt-icon.icon-success svg {
fill: #009688;
}
.handjob__adopt-switch {
position: relative;
display: inline-block;
width: 30px;
height: 17px;
}
.handjob__adopt-switch input {
opacity: 0;
width: 0;
height: 0;
}
.handjob__adopt-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.handjob__adopt-slider:before {
position: absolute;
content: "";
height: 13px;
width: 13px;
left: 2px;
bottom: 2px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .handjob__adopt-slider {
background-color: #2196F3;
}
input:focus + .handjob__adopt-slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .handjob__adopt-slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
/* Rounded sliders */
.handjob__adopt-slider.handjob__adopt-round {
border-radius: 17px;
}
.handjob__adopt-slider.handjob__adopt-round:before {
border-radius: 50%;
}
.handjob__adopt-input-container {
display: inline-flex;
align-items: center;
}
.handjob__adopt-help-icon {
position: relative;
margin-left: 16px;
cursor: pointer;
}
.handjob__adopt-help-icon:before {
pointer-events: none;
content: "";
position: absolute;
right: -16px;
transition: opacity 150ms ease-in-out;
opacity: 0;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-right: 5px solid ${PRIMARY_COLOUR};
top: 6px;
}
.handjob__adopt-help-icon:hover:before {
opacity: 1;
}
.handjob__adopt-help-icon:after {
content: attr(data-help-message);
position: absolute;
background-color: ${PRIMARY_COLOUR};
opacity: 0;
transition: opacity 150ms ease-in-out;
white-space: nowrap;
padding: 4px 8px;
color: white;
border-radius: 4px;
margin-left: 16px;
pointer-events: none;
}
.handjob__adopt-help-icon:hover:after {
opacity: 1;
}
.handjob__adopt-help-icon path {
fill: ${PRIMARY_COLOUR};
}
`;
const styleInsert = document.createElement("style");
styleInsert.innerHTML = css;
document.head.appendChild(styleInsert);
const insertNode = document.createElement("li");
insertNode.className = "user-info-bar__item";
const activate = insertNode.appendChild(document.createElement("a"));
activate.style.cursor = "pointer";
activate.textContent = "Adopt a HANDJOB";
const insertionPoint = document.querySelector("#userinfo_minor");
insertionPoint.appendChild(insertNode);
activate.addEventListener("click", runDownloader);
const modal = document.createElement("div");
const helpIcon = message => {
return `<div class="handjob__adopt-help-icon" data-help-message="${message}"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></svg></div>`;
};
modal.id = "handjob__adopt-modal";
modal.className = "hidden";
const modalInner = modal.appendChild(document.createElement("div"));
modalInner.innerHTML = `
<div class="handjob__adopt-toolbar">Adopt A HANDJOB</div>
<fieldset>
<table>
<tr>
<td>Starting Search Page: </td>
<td>
<div class="handjob__adopt-input-container">
<input type="number" min="1" id="handjob__adopt-input--search-offset" value="${SEARCH_PAGE_OFFSET}">
${helpIcon(
"Starting search results page. Increase this if it takes a long while for a first match"
)}
</div>
</td>
</tr>
<tr>
<td>Max Seeders: </td>
<td>
<div class="handjob__adopt-input-container">
<input type="number" id="handjob__adopt-input--max-seeders" value="${MAX_SEEDERS}">
${helpIcon("Max no. of seeders a downloaded torrent can have")}
</div>
</td>
</tr>
<tr>
<td>Torrents Cap: </td>
<td>
<div class="handjob__adopt-input-container">
<input type="number" id="handjob__adopt-input--torrent-cap" value="${TORRENT_CAP}">
${helpIcon("Keep searching until this many torrents have been found")}
</div>
</td>
</tr>
<tr>
<td>Resolutions: </td>
<td>
<div class="handjob__adopt-input-container">
<select id="handjob__adopt-input--resolution">
<option value="any">Any</option>
<option value="dvd">Only DVDRip</option>
<option value="anysd">Any Standard Definition</option>
<option value="anyhd">Any High Definition</option>
<option value="480p">480p</option>
<option value="576p">576p</option>
<option value="720p">720p</option>
<option value="1080p">1080p</option>
</select>
${helpIcon("Resolutions of torrents to download")}
<div>
</td>
</tr>
<tr>
<td>Include Downloaded Torrents?</td>
<td>
<div class="handjob__adopt-input-container">
<label class="handjob__adopt-switch">
<input type="checkbox" id="handjob__adopt-input--include-downloaded">
<span class="handjob__adopt-slider handjob__adopt-round"></span>
</label>
${helpIcon(
"Include torrents that you've downloaded before (but are not seeding or leeching)"
)}
</div>
</td>
</tr>
<tr>
<td>Include Trumpable Torrents?</td>
<td>
<div class="handjob__adopt-input-container">
<label class="handjob__adopt-switch">
<input type="checkbox" id="handjob__adopt-input--include-trumpable">
<span class="handjob__adopt-slider handjob__adopt-round"></span>
</label>
${helpIcon("Include torrents that are marked as trumpable")}
</div>
</td>
</tr>
<tr>
<td>Search Request Delay (ms): </td>
<td>
<div class="handjob__adopt-input-container">
<input type="number" step="100" id="handjob__adopt-input--search-delay" value="${SEARCH_DELAY}">
${helpIcon("Number of milliseconds to wait between requests for search result pages")}
</div>
</td>
</tr>
<tr>
<td>Download Request Delay (ms): </td>
<td>
<div class="handjob__adopt-input-container">
<input type="number" step="100" id="handjob__adopt-input--download-delay" value="${DOWNLOAD_DELAY}">
${helpIcon("Number of milliseconds to wait between requests for torrent downloads")}
</div>
</td>
</tr>
</table>
</fieldset>
<div class="handjob__adopt-loader-container">
<div class="handjob__adopt-loader paused"></div>
<div class="handjob__adopt-loader-percent"></div>
</div>
<div id="handjob__adopt-download-status">
<div id="handjob__adopt-download-status-top">
<div style="display: flex; flex-flow: column;">
<div id="handjob__adopt-download-status-pages">Search pages scanned: <span></span></div>
<div id="handjob__adopt-download-status-found">Eligible torrents found: <span></span></div>
</div>
<div id="handjob__adopt-download-status-torrents">Torrents downloaded: <span></span></div>
</div>
<div id="handjob__adopt-download-active-task">
<div class="handjob__adopt-icon"></div>
<span></span>
</div>
<div id="handjob__adopt-actions">
<button id="handjob__adopt-close-button" class="handjob__adopt-btn handjob__adopt-btn-error">Close</button>
<button id="handjob__adopt-submit-button" class="handjob__adopt-btn handjob__adopt-btn-primary">Find Torrents</button>
<div>
</div>
`;
modalInner.id = "handjob__adopt-modal-inner";
document.querySelector("#extra2").appendChild(modal);
return modal;
}
})();