// ==UserScript==
// @name Edupage 文件拦截并下载 + 课表生成器
// @namespace http://tampermonkey.net/
// @version 1.5
// @description 拦截 currenttt.js 与 maindbi.js 请求,每次拦截后弹窗询问用户是否下载,并提供生成课表的功能
// @author schweigen
// @license GPL-3.0
// @match https://freshman.edupage.org/*
// @grant GM_registerMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function () {
"use strict";
// 用于避免重复下载(如果你希望每次拦截都询问,可以移除此重复检查)
const downloadedFiles = {};
// 初始化拦截模式状态,默认为关闭
let interceptEnabled = GM_getValue('interceptEnabled', false);
// 生成课表的 HTML(已经更新为你给出的最新版本)
const timetableHTML = `<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>课表生成器</title>
<style>
/* 引入苹果风格的字体 */
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap');
body {
font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #f9f9f9;
margin: 0;
padding: 0;
color: #333;
}
h1 {
text-align: center;
color: #00C8FF; /* 蓝色标题 */
margin-top: 30px;
font-weight: 600;
font-size: 2.5em;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 20px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
margin-top: 30px;
}
/* 调整后的textarea样式 */
.code-block {
position: relative;
background-color: #f0f8ff;
border-radius: 15px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin-bottom: 30px;
overflow-x: auto;
}
.code-block textarea {
width: 100%;
height: 200px; /* 将高度调整为200px */
border: none;
background: transparent;
resize: vertical;
font-size: 14px;
line-height: 1.5;
font-family: 'SF Mono', 'Roboto Mono', 'Courier New', monospace;
color: #555;
padding: 0;
margin: 0;
outline: none;
}
button {
display: block;
width: 100%;
padding: 15px;
background-color: #00C8FF; /* 蓝色按钮 */
color: #fff;
border: none;
border-radius: 15px;
font-size: 18px;
font-weight: 600;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.3s ease;
margin-bottom: 30px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
}
button:hover {
background-color: #00AEEF; /* 悬停时颜色变浅 */
transform: translateY(-2px);
}
.button-text {
position: relative;
z-index: 1;
}
.bubble {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 105, 180, 0.6);
animation: bubbleAnimation 1s ease-out;
pointer-events: none;
}
@keyframes bubbleAnimation {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 0;
}
}
table {
width: 100%;
border-collapse: collapse;
background-color: #fff;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin-bottom: 30px;
}
th, td {
padding: 15px;
text-align: center;
font-size: 16px;
color: #555;
}
th {
background-color: #00C8FF;
color: #fff;
font-weight: 600;
}
tr:nth-child(even) {
background-color: #fafafa;
}
.copy-button {
position: absolute;
top: 10px;
right: 10px;
background-color: #00C8FF;
color: #fff;
border: none;
cursor: pointer;
padding: 6px 10px;
font-size: 14px;
border-radius: 12px;
transition: background-color 0.3s ease, transform 0.3s ease;
display: inline-block;
width: auto;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.copy-button:hover {
background-color: #00AEEF;
transform: translateY(-2px);
}
.toast {
position: fixed;
bottom: -100px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.8);
color: #fff;
padding: 12px 20px;
border-radius: 25px;
font-size: 16px;
transition: bottom 0.5s ease;
z-index: 1000;
}
.toast.show {
bottom: 50px;
}
@keyframes bounceIn {
0% {
transform: scale(0.3);
opacity: 0;
}
50% {
transform: scale(1.05);
opacity: 0.7;
}
70% {
transform: scale(0.9);
opacity: 0.9;
}
100% {
transform: scale(1);
opacity: 1;
}
}
.animated {
animation: bounceIn 0.8s both;
}
.icon {
width: 24px;
height: 24px;
vertical-align: middle;
margin-right: 10px;
}
.message {
font-style: italic;
background: linear-gradient(45deg, #ff7e5f, #feb47b);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-size: 1.2em;
margin-top: 10px;
}
</style>
<!-- 引入 anime.js 库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
</head>
<body>
<!-- 添加烟花特效的 canvas 元素 -->
<canvas class="fireworks" style="position: fixed; left: 0; top: 0; z-index: 99999999; pointer-events: none;"></canvas>
<div class="container">
<h1>🌟 课表生成器 🌟</h1>
<!-- 添加输入数据的标题 -->
<h2>🔢 输入数据</h2>
<!-- currenttt.js 拖拽或手动输入 -->
<div class="code-block">
<textarea id="jsonInput" placeholder="请输入或拖拽 currenttt.js 数据"></textarea>
</div>
<!-- maindbi.js 拖拽或手动输入 -->
<div class="code-block">
<textarea id="maindbiInput" placeholder="请输入或拖拽 maindbi.js 数据"></textarea>
</div>
<div class="code-block">
<textarea id="subjectMapInput" placeholder="请输入科目对应关系">
# 请按照以下格式添加科目对应关系:
# 科目ID=科目名称
# 例如:
FeP-VWL=经济
FeP-W-Mathe=数学
FeP-Deutsch=德语
FeP-Englisch=英语
noteninfo=Noteninfo
Fep-Tutorium Mathe=数学辅导
</textarea>
</div>
<button onclick="generateTimetable()">
<span class="button-text">生成课表</span>
</button>
<h2>📅 课表</h2>
<table id="timetable">
<tr>
<th>日期</th>
<th>时间</th>
<th>科目</th>
<th>教师</th>
<th>教室</th>
</tr>
</table>
<h2>📊 课程统计</h2>
<div id="statistics"></div>
<h2>📝 Markdown格式</h2>
<div class="code-block" id="markdownOutputContainer">
<button class="copy-button" onclick="copyToClipboard('markdownOutput', 'markdown')">复制</button>
<pre id="markdownOutput"></pre>
</div>
<h2>📆 ICS格式</h2>
<div class="code-block" id="icsOutputContainer">
<button class="copy-button" onclick="copyToClipboard('icsOutput', 'ics')">复制</button>
<pre id="icsOutput"></pre>
</div>
</div>
<div id="toast" class="toast">已复制到剪贴板</div>
<script>
function generateTimetable() {
const jsonInput = document.getElementById('jsonInput').value;
const maindbiInput = document.getElementById('maindbiInput').value;
const subjectMapInput = document.getElementById('subjectMapInput').value;
try {
const timetableData = JSON.parse(jsonInput);
const maindbiData = JSON.parse(maindbiInput);
const timetable = document.getElementById('timetable');
// 清空表格内容
timetable.innerHTML = '';
timetable.innerHTML = '<tr><th>日期</th><th>时间</th><th>科目</th><th>教师</th><th>教室</th></tr>';
const courses = timetableData.r.ttitems.filter(item => item.type === 'card' && !item.removed);
const teachers = maindbiData.r.tables.find(table => table.id === 'teachers').data_rows;
const subjects = maindbiData.r.tables.find(table => table.id === 'subjects').data_rows;
const classrooms = maindbiData.r.tables.find(table => table.id === 'classrooms').data_rows;
// 创建教师、科目和教室的映射表
const teacherMap = new Map(teachers.map(teacher => [teacher.id, teacher.short]));
const subjectMap = new Map(subjects.map(subject => [subject.id, subject.name]));
const classroomMap = new Map(classrooms.map(classroom => [classroom.id, classroom.name]));
// 创建自定义科目映射表
const customSubjectMap = new Map();
const lines = subjectMapInput.split('\\n');
lines.forEach(line => {
const [key, value] = line.split('=');
if (key && value) {
customSubjectMap.set(key.trim().toLowerCase(), value.trim());
}
});
// 定义左、右教室列表
const leftClassrooms = ['105','106','107','108','109','203','204','205','206','207','223','311','307','310','308','309'];
const rightClassrooms = ['202', '222a', '212', '201', '305', '304', '303', '302', '301'];
const lunchBreakStart = '11:45';
const lunchBreakEnd = '12:45';
let finalCourses = [];
function timeToMinutes(timeStr) {
const [hours, minutes] = timeStr.split(':').map(Number);
return hours * 60 + minutes;
}
courses.forEach(course => {
const startTimeMinutes = timeToMinutes(course.starttime);
const endTimeMinutes = timeToMinutes(course.endtime);
const lunchStartMinutes = timeToMinutes(lunchBreakStart);
const lunchEndMinutes = timeToMinutes(lunchBreakEnd);
// 如果课程跨越午休时间段,我们将其拆分
if (startTimeMinutes < lunchEndMinutes && endTimeMinutes > lunchStartMinutes) {
// 午休前
if (startTimeMinutes < lunchStartMinutes) {
finalCourses.push({
date: course.date,
starttime: course.starttime,
endtime: lunchBreakStart,
subjectid: course.subjectid,
teacherids: course.teacherids,
classroomid: course.classroomids[0]
});
}
// 午休后
if (endTimeMinutes > lunchEndMinutes) {
finalCourses.push({
date: course.date,
starttime: lunchBreakEnd,
endtime: course.endtime,
subjectid: course.subjectid,
teacherids: course.teacherids,
classroomid: course.classroomids[0]
});
}
} else {
finalCourses.push({
date: course.date,
starttime: course.starttime,
endtime: course.endtime,
subjectid: course.subjectid,
teacherids: course.teacherids,
classroomid: course.classroomids[0]
});
}
});
// 排序 finalCourses
finalCourses.sort((a, b) => {
if (a.date === b.date) {
return a.starttime.localeCompare(b.starttime);
}
return a.date.localeCompare(b.date);
});
// 合并相邻、相同课程
const mergedCourses = [];
for (let i = 0; i < finalCourses.length; i++) {
const current = finalCourses[i];
if (mergedCourses.length === 0) {
mergedCourses.push({ ...current });
continue;
}
const last = mergedCourses[mergedCourses.length - 1];
// 检查是否可以合并
if (
last.date === current.date &&
last.endtime === current.starttime &&
last.subjectid === current.subjectid &&
JSON.stringify(last.teacherids) === JSON.stringify(current.teacherids) &&
last.classroomid === current.classroomid
) {
// 合并时间
last.endtime = current.endtime;
} else {
mergedCourses.push({ ...current });
}
}
let markdownOutput = '| 日期 | 时间 | 科目 | 教师 | 教室 |\\n| ---- | ---- | ---- | ---- | ---- |\\n';
let icsOutput = 'BEGIN:VCALENDAR\\nVERSION:2.0\\nPRODID:-//Example Corp.//CalDAV Client//EN\\nCALSCALE:GREGORIAN\\n';
// 定义节次时间段
const periods = [
{ start: '08:30', end: '09:15' },
{ start: '09:15', end: '10:00' },
{ start: '10:15', end: '11:00' },
{ start: '11:00', end: '11:45' },
{ start: '12:45', end: '13:30' },
{ start: '13:30', end: '14:15' },
{ start: '14:30', end: '15:15' },
{ start: '15:15', end: '16:00' },
{ start: '16:15', end: '17:00' },
{ start: '17:00', end: '17:45' },
{ start: '18:00', end: '18:45' },
{ start: '18:45', end: '19:30' },
];
// 统计科目节次数
const subjectPeriodCounts = {};
let totalPeriods = 0;
mergedCourses.forEach(course => {
let subjectName = subjectMap.get(course.subjectid) || '';
subjectName = subjectName.trim().toLowerCase();
if (customSubjectMap.has(subjectName)) {
subjectName = customSubjectMap.get(subjectName);
}
const teacherNames = course.teacherids.map(id => teacherMap.get(id) || '').join(', ');
let classroomName = classroomMap.get(course.classroomid) || '无教室';
// 根据左、右教室来确定后缀
let classroomSide = '';
if (classroomName === '306') {
classroomSide = '前';
} else {
const leftClassrooms = ['105','106','107','108','109','203','204','205','206','207','223','311','307','310','308','309'];
const rightClassrooms = ['202', '222a', '212', '201', '305', '304', '303', '302', '301'];
if (leftClassrooms.includes(classroomName)) {
classroomSide = '左';
} else if (rightClassrooms.includes(classroomName)) {
classroomSide = '右';
} else if (classroomName.startsWith('0') || classroomName.startsWith('1')) {
// 你可以根据需求再细化规则
classroomSide = '右';
}
}
if (classroomSide) {
classroomName += classroomSide;
}
// 计算课程覆盖了多少节次
const courseStart = timeToMinutes(course.starttime);
const courseEnd = timeToMinutes(course.endtime);
let periodsCovered = 0;
for (let i = 0; i < periods.length; i++) {
const periodStart = timeToMinutes(periods[i].start);
const periodEnd = timeToMinutes(periods[i].end);
if (courseEnd > periodStart && courseStart < periodEnd) {
periodsCovered++;
}
}
if (!subjectPeriodCounts[subjectName]) {
subjectPeriodCounts[subjectName] = 0;
}
subjectPeriodCounts[subjectName] += periodsCovered;
totalPeriods += periodsCovered;
const row = timetable.insertRow();
row.insertCell().textContent = course.date;
row.insertCell().textContent = \`\${course.starttime}-\${course.endtime}\`;
row.insertCell().textContent = subjectName;
row.insertCell().textContent = teacherNames;
row.insertCell().textContent = classroomName;
markdownOutput += \`| \${course.date} | \${course.starttime}-\${course.endtime} | \${subjectName} | \${teacherNames} | \${classroomName} |\\n\`;
const startDateTime = \`\${course.date.replace(/-/g, '')}T\${course.starttime.replace(':', '')}00\`;
const endDateTime = \`\${course.date.replace(/-/g, '')}T\${course.endtime.replace(':', '')}00\`;
icsOutput += 'BEGIN:VEVENT\\n';
icsOutput += \`DTSTART;TZID=Europe/Berlin:\${startDateTime}\\n\`;
icsOutput += \`DTEND;TZID=Europe/Berlin:\${endDateTime}\\n\`;
icsOutput += \`SUMMARY:\${subjectName} \${teacherNames}\\n\`;
icsOutput += \`LOCATION:\${classroomName || '网课'}\\n\`;
icsOutput += 'DESCRIPTION:\\n';
icsOutput += 'END:VEVENT\\n';
});
icsOutput += 'END:VCALENDAR\\n';
document.getElementById('markdownOutput').textContent = markdownOutput;
document.getElementById('icsOutput').textContent = icsOutput;
timetable.classList.add('animated');
let statisticsHtml = '<ul>';
const sortedSubjects = Object.keys(subjectPeriodCounts).sort((a, b) => subjectPeriodCounts[b] - subjectPeriodCounts[a]);
sortedSubjects.forEach(subject => {
statisticsHtml += \`<li>\${subject}: \${subjectPeriodCounts[subject]} 节课</li>\`;
});
statisticsHtml += \`<li><strong>总共: \${totalPeriods} 节课</strong></li>\`;
statisticsHtml += '</ul>';
let message = '';
if (totalPeriods <= 25) {
message = "尊嘟假嘟,这么少!你是想退休吗?";
} else if (totalPeriods >= 40) {
message = "恭喜您,您的课程数已经突破天际!是不是在训练成为课程超人?";
} else if (totalPeriods >= 25 && totalPeriods < 40) {
message = "接招吧!半径为2.5格的课程表水花!";
}
statisticsHtml += \`<div class="message">\${message}</div>\`;
document.getElementById('statistics').innerHTML = statisticsHtml;
} catch (error) {
alert(\`错误: \${error.message}\`);
console.error(error);
}
}
function copyToClipboard(elementId, format) {
const element = document.getElementById(elementId);
const textArea = document.createElement("textarea");
textArea.value = element.textContent;
document.body.appendChild(textArea);
textArea.select();
document.execCommand("copy");
document.body.removeChild(textArea);
const toast = document.getElementById('toast');
toast.textContent = \`\${format.toUpperCase()} 格式已复制到剪贴板\`;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
// 全局拖拽
document.addEventListener('dragover', function(e) {
e.preventDefault();
});
document.addEventListener('drop', function(e) {
e.preventDefault();
const files = e.dataTransfer.files;
if (!files || !files.length) return;
// 处理多个文件
for (let i = 0; i < files.length; i++) {
const file = files[i];
const reader = new FileReader();
reader.onload = function(event) {
// 根据文件名或内容,判断该放哪一个输入框
const content = event.target.result;
// ① 根据文件名判断
const lowerName = file.name.toLowerCase();
if (lowerName.includes('maindbi')) {
document.getElementById('maindbiInput').value = content;
} else if (lowerName.includes('currenttt')) {
document.getElementById('jsonInput').value = content;
} else {
// ② 若文件名不含 maindbi 或 currenttt,尝试判断内容
try {
const jsonObj = JSON.parse(content);
// 如果包含 tables 则认为是maindbi.js
if (jsonObj?.r?.tables) {
document.getElementById('maindbiInput').value = content;
}
// 如果包含 ttitems 则认为是currenttt.js
else if (jsonObj?.r?.ttitems) {
document.getElementById('jsonInput').value = content;
} else {
// 可能是未知文件,或者结构不一样
alert('无法识别文件类型: ' + file.name);
}
} catch (ex) {
alert('文件不是合法的JSON,无法解析: ' + file.name);
}
}
};
reader.readAsText(file);
}
});
document.querySelector('button').addEventListener('click', function(event) {
const button = event.currentTarget;
const rect = button.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const bubbleSize = Math.random() * 50 + 20;
const bubble = document.createElement('span');
bubble.classList.add('bubble');
bubble.style.left = \`\${x - bubbleSize / 2}px\`;
bubble.style.top = \`\${y - bubbleSize / 2}px\`;
bubble.style.width = \`\${bubbleSize}px\`;
bubble.style.height = \`\${bubbleSize}px\`;
button.appendChild(bubble);
bubble.addEventListener('animationend', () => {
bubble.remove();
});
});
</script>
<!-- 烟花特效代码(删除了圆圈效果,仅保留颗粒效果) -->
<script>
function updateCoords(e) {
pointerX = (e.clientX || e.touches[0].clientX) - canvasEl.getBoundingClientRect().left;
pointerY = (e.clientY || e.touches[0].clientY) - canvasEl.getBoundingClientRect().top;
}
function setParticuleDirection(e) {
var t = anime.random(0, 360) * Math.PI / 180,
a = anime.random(50, 180),
n = [-1, 1][anime.random(0, 1)] * a;
return {
x: e.x + n * Math.cos(t),
y: e.y + n * Math.sin(t)
};
}
function createParticule(e, t) {
var a = {};
a.x = e;
a.y = t;
a.color = colors[anime.random(0, colors.length - 1)];
a.radius = anime.random(16, 32);
a.endPos = setParticuleDirection(a);
a.draw = function() {
ctx.beginPath();
ctx.arc(a.x, a.y, a.radius, 0, 2 * Math.PI, true);
ctx.fillStyle = a.color;
ctx.fill();
};
return a;
}
function renderParticule(e) {
for (var t = 0; t < e.animatables.length; t++)
e.animatables[t].target.draw();
}
function animateParticules(e, t) {
var particules = [];
for (var i = 0; i < numberOfParticules; i++)
particules.push(createParticule(e, t));
anime.timeline().add({
targets: particules,
x: function(e) {
return e.endPos.x;
},
y: function(e) {
return e.endPos.y;
},
radius: 0.1,
duration: anime.random(1200, 1800),
easing: "easeOutExpo",
update: renderParticule
});
}
function debounce(fn, delay) {
var timer;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
}
}
var canvasEl = document.querySelector(".fireworks");
if (canvasEl) {
var ctx = canvasEl.getContext("2d"),
numberOfParticules = 30,
pointerX = 0,
pointerY = 0,
tap = "mousedown",
colors = ["#FF1461", "#18FF92", "#5A87FF", "#FBF38C"],
setCanvasSize = debounce(function() {
canvasEl.width = 2 * window.innerWidth;
canvasEl.height = 2 * window.innerHeight;
canvasEl.style.width = window.innerWidth + "px";
canvasEl.style.height = window.innerHeight + "px";
canvasEl.getContext("2d").scale(2, 2);
}, 500),
render = anime({
duration: Infinity,
update: function() {
ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
}
});
document.addEventListener(tap, function(e) {
if (e.target.id !== "sidebar" && e.target.id !== "toggle-sidebar" && e.target.nodeName !== "A" && e.target.nodeName !== "IMG") {
render.play();
updateCoords(e);
animateParticules(pointerX, pointerY);
}
}, false);
setCanvasSize();
window.addEventListener("resize", setCanvasSize, false);
}
</script>
</body>
</html>`;
// 注册菜单命令
function updateMenu() {
GM_registerMenuCommand(
interceptEnabled ? "关闭拦截模式" : "开启拦截模式",
toggleInterceptMode
);
// 新增“生成课表”菜单项
GM_registerMenuCommand("生成课表", openTimetablePage);
}
// 切换拦截模式
function toggleInterceptMode() {
interceptEnabled = !interceptEnabled;
GM_setValue('interceptEnabled', interceptEnabled);
alert(interceptEnabled ? "拦截模式已开启" : "拦截模式已关闭");
updateMenu();
}
// 打开课表生成器页面
function openTimetablePage() {
const blob = new Blob([timetableHTML], { type: 'text/html' });
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
}
// 初始化菜单
updateMenu();
// 根据 URL 固定重命名文件
function getFixedFilename(url) {
if (url.includes("currenttt.js")) {
return "currenttt.js";
}
if (url.includes("maindbi.js")) {
return "maindbi.js";
}
return url.split("/").pop();
}
// 弹窗询问后下载文件
function promptAndDownload(url, text) {
// 如果拦截模式关闭,则不执行任何操作
if (!interceptEnabled) {
return;
}
const filename = getFixedFilename(url);
// 如果已经下载过,就不再重复提示(如果希望每次都提示,可以将这段判断删除)
if (downloadedFiles[filename]) {
return;
}
if (confirm("是否下载文件 " + filename + " ?")) {
const blob = new Blob([text], { type: "application/javascript" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
downloadedFiles[filename] = true;
}
}
// 拦截 XMLHttpRequest 请求
const originalXHRopen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
this._interceptUrl = url;
return originalXHRopen.apply(this, arguments);
};
const originalXHRsend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function (body) {
this.addEventListener("load", function () {
if (
this._interceptUrl &&
(this._interceptUrl.includes("currenttt.js") || this._interceptUrl.includes("maindbi.js"))
) {
promptAndDownload(this._interceptUrl, this.responseText);
}
});
return originalXHRsend.apply(this, arguments);
};
// 拦截 fetch 请求
const originalFetch = window.fetch;
window.fetch = function (...args) {
return originalFetch.apply(this, args).then(response => {
if (
response.url &&
(response.url.includes("currenttt.js") || response.url.includes("maindbi.js"))
) {
response.clone().text().then(text => {
promptAndDownload(response.url, text);
});
}
return response;
});
};
})();