【科学工具箱】整合好玩实用的各种功能,不定时持续更新中...

6月新增功能:支持大部分网站视频、音频、图片等资源的下载,智能抠图去水印,新增二维码工具、新增m3u8视频下载

נכון ליום 26-06-2023. ראה הגרסה האחרונה.

אין להתקין סקריפט זה ישירות. זוהי ספריה עבור סקריפטים אחרים // @require https://update.sleazyfork.org/scripts/468541/1210977/%E3%80%90%E7%A7%91%E5%AD%A6%E5%B7%A5%E5%85%B7%E7%AE%B1%E3%80%91%E6%95%B4%E5%90%88%E5%A5%BD%E7%8E%A9%E5%AE%9E%E7%94%A8%E7%9A%84%E5%90%84%E7%A7%8D%E5%8A%9F%E8%83%BD%EF%BC%8C%E4%B8%8D%E5%AE%9A%E6%97%B6%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0%E4%B8%AD.js

// ==UserScript==
// @name         【科学工具箱】整合好玩实用的各种功能,不定时持续更新中...
// @version     14
// @author      Paladin-M
// @namespace Z3JlYXN5Zm9yaw==
// @description   6月新增功能:支持大部分网站视频、音频、图片等资源的下载,智能抠图去水印,新增二维码工具、新增m3u8视频下载
// @match        *://*/*
// @icon   data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAFySURBVDhPzdA/S0JhFMfxXxd6Ab0DjUywIashqPdQbbqVFaRDBWl/IW0JRKU9acsSGi1Qm4NKG6Jora2xqE3uc8/pPNf7aHsNDh8uZzjf+3DwNeNzXLN+6vLZHBliGg+sLT8hnm+A92uw03WQsV+Ho/1DwFv6nhtkQ2bF0YAEgmtLz0gUmmBZUplrsGFCPRHw2W1+1eVruTeYCKwuPiKeu3Nv0NIRQ99EA0WGSeNokA2KDiuOhZgmQ8n1dySKb+B8E6rwADZkJg0Uxq5rHHsGh7FDYzikAUyNvmAkVkNyoY4V+SaM+SriGnBKm64Sbf2S6jvjA0lMUxZTVLbSVMaGSHWcI6mhr0KkWZfMhsyq/4YZR5ShC2T41WJqQLEc05CZNHnBh+1Rv7SsigTytE3HSPOtBKpoUQ2qowpb0wFylT65QyLWlQSytEsn8oKmBGSJ6/J3j8yk9UbA8bRDbbY+JnK8Q0UJ3Ls3sM2Sx9H+GIDzA5wTVm/Huk5xAAAAAElFTkSuQmCC
// @require https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js
// @require  https://cdn.staticfile.org/toastr.js/2.1.4/toastr.min.js
// @require https://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js
// @require https://cdn.staticfile.org/sweetalert/2.1.2/sweetalert.min.js
// @require https://greasyfork.org/scripts/469053-jsqr/code/jsQR.js?version=1207999

// @require https://lib.baomitu.com/m3u8-parser/4.7.1/m3u8-parser.min.js
// @require https://greasyfork.org/scripts/468518-addqrcode/code/addqrcode.js?version=1204970




// @require https://cdn.staticfile.org/vue/2.6.1/vue.js
// @require https://greasyfork.org/scripts/468820-m3u8-hls/code/m3u8-hls.js?version=1206200
// @require https://greasyfork.org/scripts/468821-mux-mp4/code/mux-mp4.js?version=1206201
// @require https://greasyfork.org/scripts/469054-streamsaver/code/StreamSaver.js?version=1208001
// @require https://greasyfork.org/scripts/468813-downm3u8/code/downm3u8.js?version=1210548
// @require https://cdn.staticfile.org/hls.js/1.4.6/hls.min.js
// @license           End-User License Agreement
// @grant             unsafeWindow
// @grant             GM_xmlhttpRequest
// @grant             GM_setClipboard
// @grant             GM_setValue
// @grant             GM_getValue
// @grant             GM_deleteValue
// @grant             GM_openInTab
// @grant             GM_registerMenuCommand
// @grant             GM_unregisterMenuCommand
// @grant             GM.getValue
// @grant             GM.setValue
// @grant             GM_info
// @grant             GM_notification
// @grant             GM_getResourceText
// @grant             GM_openInTab
// @grant             GM_addStyle
// @grant             GM_download
// ==/UserScript==
 
  var numselected=0;
  
  function ADDimgdown() {
  	   if (GM_info.script.namespace!="Z3JlYXN5Zm9yaw=="){ 
return
}
  	  	  $(".data-down-ui").remove();
    // create thumbnail container
    var thumbnailContainer = $("<div>")
        .css({
            "position": "fixed",
            "top": "50%",
            "left": "50%",
            "transform": "translate(-50%, -50%)",
            "z-index": 99999999999999,
            "width": "80vw",
            "height": "80vh",
            "background-color": "#eee",
            "overflow": "auto",
            "text-align": "center"
        })
        .hide()
        .attr("class", "data-down-ui")
        .appendTo($("body"));

    // create media type switch buttons
    var switchBtnContainer = $("<div>")
        .css({
            "position": "absolute",
            "top": "0",
            "left": "0",
            "right": "0",
            "width": "100%",
            "background-color": "#fff",
            "padding": "10px",
            "text-align": "center",
            "box-shadow": "0 2px 5px rgba(0, 0, 0, 0.3)"
        })
        .appendTo(thumbnailContainer);

 

    var switchBtnVideo = $("<button>")
        .css({
            "margin-right": "10px"
        })
        .text("视频列表")
        .attr("data-down-button", "video")
        .attr("class", "data-down-button")
        .appendTo(switchBtnContainer);

    var switchBtnAudio = $("<button>")
        .css({
            "margin-right": "10px"
        })
        .text("音频列表")
        .attr("data-down-button", "audios")
       .attr("class", "data-down-button")
        .appendTo(switchBtnContainer);

    var switchBtnImage = $("<button>")
        .text("图片列表")
        .css({
            "margin-right": "10px"
        })
         .attr("data-down-button", "images")
        .attr("class", "data-down-button")
        .appendTo(switchBtnContainer);

     var switchBtnselected = $("<button>")
        .text("选择全部")
         .css({
            "margin-right": "10px"
        })
         .attr("data-down-button", "selected")
        .attr("class", "data-down-buttonselected")
        .appendTo(switchBtnContainer);

 var switchBtnsmall = $("<button>")
        .text("过滤小图片")
         .css({
            "margin-right": "10px"
        })
         .attr("data-down-button", "small")
        .attr("class", "data-down-buttonsmall")
        .appendTo(switchBtnContainer);

   var switchBtndown = $("<button>")
        .text("下载所选资源")
         .css({
            "margin-right": "10px"
        })
         .attr("data-down-button", "down")
        .attr("class", "data-down-down")
        .appendTo(switchBtnContainer);

 var switchBtnurl = $("<button>")
        .text("导出链接")
         .css({
            "margin-right": "10px"
        })
         .attr("data-down-button", "url")
        .attr("class", "data-down-url")
        .appendTo(switchBtnContainer);

 var switchBtnM3U8Video = $("<button>")
        .css({
            "margin-right": "10px"
        })
        .text("M3U8格式视频下载")
        .attr("data-down-button", "downm3u8")
        .attr("class", "data-down-button")
        .appendTo(switchBtnContainer);
switchBtnM3U8Video.click(function() {
 sectionm3u8menu(GM_getValue("m3u8url", ""));
});
    // create thumbnail list
    var thumbnailList = $("<div>")
        .css({
            "margin-top": "50px"
        })
        .attr("thumbnailList", "thumbnailList")
        .appendTo(thumbnailContainer);

    // create close button
    var closeBtn = $("<button>")
        .css({
            "position": "absolute",
            "top": "10px",
            "right": "10px",
            "background-color": "rgb(167 166 166)",
            "border": "1px solid rgb(204, 204, 204)",
            "padding": "5px",
            "font-size": "16px",
            	    "color": "aliceblue",
    "font-weight": "600",
        })
        .text("×")
        .appendTo(thumbnailContainer);
        	
        var mediaLinks = [];
        var mediaTypes = ["video", "audio", "img"];
 
 
 
  
       	if (location.hostname.includes('xiaohongshu.com')) {
 var imglistxhs = unsafeWindow.__INITIAL_STATE__; 
if (imglistxhs.note.note._value.hasOwnProperty('imageList')) { 
  var imageList = imglistxhs.note.note._rawValue.imageList;
  for (var i = 0; i < imageList.length; i++) {
    var image = imageList[i];
             mediaLinks.push({
                    "type": "img",
                    "src": "https://sns-img-bd.xhscdn.com/"+image.traceId+"?imageView2/2/w/1080/format/jpg",
                    	"width": image.width,
                    	"height": image.height,
                });
  }
}

if (imglistxhs.feed.feeds.hasOwnProperty('_rawValue')) { 
  var imageList =imglistxhs.feed.feeds._rawValue;
  for (var i = 0; i < imageList.length; i++) {
    var image = imageList[i];
             mediaLinks.push({
                    "type": "img",
                    "src": "https://sns-img-bd.xhscdn.com/"+image.noteCard.cover.traceId+"?imageView2/2/w/1080/format/jpg",
                    	"width": image.noteCard.cover.width,
                    	"height": image.noteCard.cover.height,
                });
  }
}
}

        // get all media links
        mediaTypes.forEach(function(mediaType) {
            $(mediaType).each(function() {
 let checkreturn=true;

        if (checkreturn) {
            	let src=$(this).attr("src");

          if ($(this).find('source').length > 0) {
$(this).find('source').each(function() {
	        if ($(this).attr('src')){
	        	let vsrc=$(this).attr('src');
	      vsrc=completeUrl(vsrc);
	      if (vsrc.includes('m3u8')) {
                mediaLinks.push({
                    "type": mediaType,
                    "src": vsrc,
                    "m3u8": vsrc,
                });
}else{
     mediaLinks.push({
                    "type": mediaType,
                    "src": vsrc
                });
}
}
});
        }
        if (src && mediaType!="img"){
if (src.includes('rgb(') || src.includes('linear-gradient')) {
src=false;
}
}
if (src){
            if (mediaType=="img"){
            	   src=src.replace(/webp/g, 'png');
            }
             let width = $(this).width();
             let height = $(this).height();
             src=completeUrl(src);

               if ($(this).attr('m3u8')){
               	     mediaLinks.push({
                    "type": mediaType,
                    "src": src,
                    	"m3u8": $(this).attr('m3u8'),
                    	"width": width,
                    	"height": height,
                });
        }else{
          mediaLinks.push({
                    "type": mediaType,
                    "src": src,
                    	"width": width,
                    	"height": height,
                });
        }

                	}
         	}
            });
        });



  $('canvas').each(function() {
        let canvas = $(this)[0];
    try {
 var imageData = canvas.toDataURL('image/png');
 let imageSize = getImageSize(imageData);
        let base64Image = imageData.split(',')[1];
       mediaLinks.push({
                    "type": "img",
                    "src": "data:image/png;base64,"+base64Image,
                    	"width":  imageSize.width,
                    	"height":  imageSize.height,
                });

    } catch (err) {
        console.error('获取某些图片失败:Failed to export canvas as PNG', err);
        // 使用其他方式导出图片
    }

    });
 // 获取图片大小的函数
    function getImageSize(imageData) {
        let image = new Image();
        image.src = imageData;
        let width = image.width;
        let height = image.height;
        return {
            width: width,
            height: height
        };
    }
        $('div, a, span, body').each(function() {
        	 let checkreturn=true;
if (window.location.href.includes('xiaohongshu.com')) {
checkreturn=false;
  }
          if (checkreturn) {    
  // 获取元素的计算样式
  var computedStyle = window.getComputedStyle(this);

  // 判断元素是否存在 background-image 样式
var backgroundImage = computedStyle.getPropertyValue('background-image');
if (backgroundImage !== 'none') {
    let matches = [...backgroundImage.matchAll(/url *\(['"]?([^'"\(\)]+)['"]?\)/g)];
    for (let i=0; i<matches.length; i++) {
        let src = matches[i][1];
        if (src.includes('rgb(') || src.includes('linear-gradient')) {
            continue;  // 跳过背景图中的线性渐变和 RGB 颜色值
        }
        let width = $(this).width();
        let height = $(this).height();
        src = src.replace(/webp/g, 'png');  // 替换图片格式
        src = completeUrl(src);  // 补全图片链接
        mediaLinks.push({
            "type": 'img',
            "src":src,
           	"width": width,
           	"height": height,
        });
    }
}

  // 判断元素是否存在 background: url() 样式
var backgroundUrl = computedStyle.getPropertyValue('background');
var matches = backgroundUrl.match(/url\(['"]?([^'"\(\)]*)['"]?\)/g);
if (matches) {
    for (let i=0; i<matches.length; i++) {
        let src = matches[i].replace(/url\(['"]*/, '').replace(/['"]*\)/, '');
        if (src.includes('rgb(') || src.includes('linear-gradient')) {
            continue; // 跳过背景图中的线性渐变和 RGB 颜色值
        }
        let width = $(this).width();
        let height = $(this).height();
        src = src.replace(/webp/g, 'png');  // 替换图片格式
        src = completeUrl(src);  // 补全图片链接
        mediaLinks.push({
            "type": 'img',
            "src":src,
            "width": width,
            "height": height,
        });
    }
}
  }
});

  // 去除重复项
mediaLinks = mediaLinks.filter(function(item, index, self) {
  return index === self.findIndex(function(t) {
    return t.src === item.src;
  });
});

        // generate thumbnail list
        var videonum=0;
        var audionum=0;
        var imgnum=0;

        mediaLinks.forEach(function(mediaLink, index, array) {
            var thumbnail = $("<div>")
                .css({
                    "display": "inline-block",
                    "margin": "10px",
                    "cursor": "pointer"
                })
              .attr("class", "data-down-list");

            if (mediaLink.type === "video") {
                var videoThumbnail = $("<video>")
                    .attr("src", mediaLink.src)
                    .attr("height", "120px")
                    .attr("controls", "controls");

			if (mediaLink.m3u8){
				 thumbnail.attr("data-url", mediaLink.m3u8);
				 thumbnail.attr("m3u8", mediaLink.m3u8);
				}else{
			 thumbnail.attr("data-url", mediaLink.src)
				}
                thumbnail.append(videoThumbnail);
                  videonum++
                 $('[data-down-button="video"]').text('视频列表('+videonum+')');
            }
            else if (mediaLink.type === "audio") {
                var audioThumbnail = $("<audio>")
                    .attr("src", mediaLink.src)
                    .attr("controls", "controls");
                thumbnail.attr("data-url", mediaLink.src)

                thumbnail.append(audioThumbnail);
                audionum++
                 $('[data-down-button="audios"]').text('音频列表('+audionum+')');
            }
            else {
                var imageThumbnail = $("<img>")
                    .attr("src", mediaLink.src)
                    .attr("data-width", mediaLink.width)
                    .attr("data-height", mediaLink.height)
                    .attr("height", "120px");
               thumbnail.attr("data-url", mediaLink.src)

                thumbnail.append(imageThumbnail);
                 imgnum++
                 $('[data-down-button="images"]').text('图片列表('+imgnum+')');
            }

            thumbnailList.append(thumbnail);

            // bind click event to thumbnails
            thumbnail.on("click", function() {
            	GM_setClipboard(mediaLink.src);
            	 
          
if (mediaLink.src && mediaLink.src.startsWith('blob:')) {
            if (mediaLink.m3u8 ){
            		GM_setClipboard(mediaLink.m3u8);
            	sectionm3u8menu(mediaLink.m3u8);
            	   toastr.success('该视频为特殊格式的m3u8视频。已跳转至下载页面。请在页面上继续操作', '', { positionClass: 'toast-bottom-right', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });
    /*        	if (confirm("此链接为加密链接?是否跳转到解析网站上破解下载?【补充说明:如果脚本提示跨域是否允许访问,请选择允许全部】")) {
            		let kw=encodeURIComponent(mediaLink.m3u8);
 
let hostname = new URL(mediaLink.m3u8).hostname; 
let date = new Date();
let timestamp = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}_${date.getHours().toString().padStart(2, '0')}-${date.getMinutes().toString().padStart(2, '0')}-${date.getSeconds().toString().padStart(2, '0')}`;
let filename = `${hostname}_${timestamp}.html`;

let vurl='https://tools.thatwind.com/tool/m3u8downloader#m3u8='+kw+'&referer='+kw+'&filename='+filename;
 GM_openInTab(vurl, {active: !0});
}
 */
        }else{
        toastr.error('此视频已经被该网站加密,暂时不能提供下载', '', { positionClass: 'toast-top-center', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });
        }
            }else{
                     toastr.success('已选择并复制了此资源链接!', '', { positionClass: 'toast-bottom-right', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });
            
            } 
    

        
            });
        });

        // show thumbnail container
        thumbnailContainer.show();
        
            // bind click event to switch buttons
    switchBtnVideo.on("click", function() {
        thumbnailList.find("div").hide();
        thumbnailList.find("video").parent().show();
    });

    switchBtnAudio.on("click", function() {
        thumbnailList.find("div").hide();
        thumbnailList.find("audio").parent().show();
    });

    switchBtnImage.on("click", function() {
        thumbnailList.find("div").hide();
        thumbnailList.find("img").parent().show();
    });

    // bind click event to close button
    closeBtn.on("click", function() {
        thumbnailContainer.hide();
        thumbnailList.empty();
    });
        // add custom styles
    GM_addStyle(`
        ::selection {
            background-color: #4285f4;
            color: #fff;
        }
    `);
    
    };



 

$("body").on('click', '.data-down-list', function() {
	if ($(this).hasClass('selected')) {
$(".data-down-buttonselected").removeClass("selected");
}
 $(this).toggleClass("selected");
 getallnum();
})

$("body").on('click', '.data-down-button', function() {
$(".data-down-button").removeClass("selected");
 $(this).toggleClass("selected");
   $(".data-down-buttonsmall").removeClass("selected");
    getallnum();

if ($(this).attr("data-down-button")=="video"){
	    toastr.success('说明:某些网页的视频下载地址被他们自己加密过所以下载不了!如果你能解密下载地址可以反馈我添加上去。过滤小图片可以过滤宽度或者高度小于120px的图片。有BUG和建议可以反馈我', '', { positionClass: 'toast-bottom-right', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });
}

})

$("body").on('click', '.data-down-buttonselected', function() {

  var list=false;
 $(".data-down-list").each(function(k,v){
if ($(this).hasClass('selected')) {
 list=true;
}
})
if (list){
	$(".data-down-list").removeClass("selected");
	$(this).removeClass("selected");
	$(this).text("选择全部");
}else{
$(".data-down-list").addClass("selected");
$(this).addClass("selected");

 getallnum();
}

})

function getallnum() {

	let selectedindex=0;

$(".data-down-list.selected").each(function(k,v){
if ($(this).is(':visible')){
	selectedindex++;
}
})

$(".data-down-buttonselected").text("选择全部("+selectedindex+")");
numselected=selectedindex;

}
$("body").on('click', '.data-down-buttonsmall', function() {
if ($(this).hasClass('selected')) {
  $(".data-down-list").find("img").each(function(k,v){
  	  $(this).parent().show();
  })

  $(this).removeClass("selected");
} else{
 $(".data-down-list").find("img").each(function(k,v){
if ($(this).attr('data-width')) {
let width=$(this).attr('data-width');
let height=$(this).attr('data-height');

if (width<120 || height<120){
	$(this).parent().hide();
}
}
})
$(this).addClass("selected");
}
 getallnum();
})
$("body").on('click', '.data-down-url', function() {
			 var urls = [];
			 let selectedindex=0;
	$(".data-down-list.selected").each(function(k,v){
if ($(this).is(':visible')){
	urls.push($(this).attr('data-url'));
	selectedindex++;
}
})
	let downstr='导出失败';
	if (selectedindex==0){
if ($(".data-down-list").length>0){
	downstr=downstr+",请选择需要导出的资源。点击屏幕中的资源即可选中";
}else{
downstr=downstr+",当前没有搜索到任何资源";
}
toastr.error(downstr, '', { positionClass: 'toast-top-center', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });

}

else{
	var myText = urls.join('\n\n');
GM_setClipboard(myText);


 

var container = document.createElement('div'); 
container.style.position = 'fixed';
container.style.top = '50%';
container.style.left = '50%';
container.style.transform = 'translate(-50%, -50%)';
container.style.maxWidth = '600px';
container.style.minWidth = '300px';
container.style.width = '80%';
container.style.maxHeight = '80%';
container.style.overflowY = 'auto';
container.style.backgroundColor = 'rgb(255, 255, 255)';
container.style.border = '1px solid rgb(204, 204, 204)';
container.style.borderRadius = '5px';
container.style.boxShadow = 'rgba(0, 0, 0, 0.2) 0px 2px 10px';
container.style.zIndex = '999999999999';
document.body.appendChild(container);


// 创建复制按钮
var copyButton = document.createElement('button');
copyButton.innerText = '复制';
copyButton.style.width = '50px';
copyButton.style.height = '25px';
copyButton.style.borderRadius = '5px';
copyButton.style.backgroundColor = '#6175bd';
copyButton.style.margin='8px 10px';
copyButton.style.border= 'none';
copyButton.style.marginRight= '10px';
copyButton.style.color= 'white';
copyButton.onclick = function() {
  myTextarea.select();
  document.execCommand('copy');
  alert('已复制到剪贴板');
};
container.appendChild(copyButton);

// 创建关闭按钮
var closeButton = document.createElement('button');
closeButton.innerText = '关闭';
closeButton.style.width = '50px';
closeButton.style.height = '25px';
closeButton.style.borderRadius = '5px';
closeButton.style.backgroundColor = '#6175bd';
closeButton.style.margin='8px 10px';
closeButton.style.border= 'none';
closeButton.style.marginRight= '10px';
closeButton.style.color= 'white';
closeButton.onclick = function() {
  container.style.display = 'none';
};
container.appendChild(closeButton);

// 创建文本框
var myTextarea = document.createElement('textarea');
var style = myTextarea.style;
style.width = '600px';
style.height = '700px';
style.resize = 'none';
style.textAlign = 'left';
style.display= 'inline-block';
style.caretColor='black';
myTextarea.value = myText;
container.appendChild(myTextarea);

// 将复制按钮和关闭按钮添加到文本框上方
container.insertBefore(copyButton, myTextarea);
container.insertBefore(closeButton, myTextarea);

}

	})
	$("body").on('click', '.data-down-down', function() {
		let selectedindex=0;

 var urls = [];
$(".data-down-list.selected").each(function(k,v){
if ($(this).is(':visible')){
	selectedindex++;
	urls.push($(this).attr('data-url'))
}
})
	let downstr='下载失败';
if (selectedindex==0){
if ($(".data-down-list").length>0){
	downstr=downstr+",请选择需要下载的资源。点击屏幕中的资源即可选中";
}else{
downstr=downstr+",当前没有搜索到任何资源";
}
	 toastr.error(downstr, '', { positionClass: 'toast-top-center', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });
	 	  return
	  }else{




urls.forEach(function(url, index) {
if (url.startsWith('data:image')){
	var blob = b64toBlob(url);
	url=URL.createObjectURL(blob);
}

 let fileName=getFileNameFromUrl(url);
   GM_download({
    url: url,
    name: fileName,
   saveAs: false,
    onload: function() {
      toastr.success("已下载"+(index+1)+"个资源,剩余"+(selectedindex-(index+1 ))+"...", '', { positionClass: 'toast-bottom-right', showDuration: 300, hideDuration: 1000, timeOut: 3000, extendedTimeOut: 1000, showEasing: 'swing', hideEasing: 'linear', showMethod: 'fadeIn', hideMethod: 'fadeOut' });

    },
    onerror: function(err) {
      console.error('第'+(index)+'个资源下载失败'+err , err);
    }
  });
});


	  }


	})

    $("<style>")
        .prop("type", "text/css")
        .html(`
	.data-down-ui .data-down-list:hover {
border: 2px solid #00BFFF;
box-shadow: 0 0 5px #00BFFF;
}
.data-down-ui .selected {
border: 2px solid #ed3f68;
box-shadow: 0 0 5px #ff8ef1;
}
.data-down-ui .data-down-button, .data-down-buttonselected, .data-down-buttonsmall, .data-down-down, .data-down-url{
border: none;
    border-radius: 10px;
    background-color: #6175bd;
    color: white;
    padding: 8px 10px;
    font-size: 15px;
}
 `)
        .appendTo("head");


 function completeUrl(url) {
if (url){

  if (/^https?:\/\//i.test(url)) {
    return url;
  }
  if (/^\/\//.test(url)) {
    if (location.protocol === 'https:') {
      return 'https:' + url;
}else{
 return 'http:' + url;
}
  }
    if (url.startsWith('data:')) {
    var commaIndex = url.indexOf(',');
    if (commaIndex !== -1) {
      var base64String = url.slice(commaIndex + 1);
      return url;
    }
  }
    var origin = window.location.origin;
if (url.indexOf('http') == -1){
if (url.startsWith('/')){
	  return origin + url;
}else{
	return origin +'/'+  url;
}
}

  return url;
  }
}

function b64toBlob(base64Data) {
  var byteString = atob(base64Data.split(',')[1]);
  var ab = new ArrayBuffer(byteString.length);
  var ia = new Uint8Array(ab);
  for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
  }
  return new Blob([ab], {type: 'image/jpeg'});
}

function getFileNameFromUrl(url) {
  var fileName = '';
  if (url.indexOf('?') >= 0) {
    url = url.split('?')[0]; // 去掉查询参数
  }
  var pos = url.lastIndexOf('/');
  if (pos < 0) {
    pos = url.lastIndexOf('\\');
  }
  if (pos >= 0) {
    fileName = url.substring(pos + 1);
  } else {
    fileName = url;
  }
  return fileName;
}




 
function extractM3u8Links() {
	if (GM_info.script.namespace!="Z3JlYXN5Zm9yaw=="){ 
return
}
  var m3u8Links = ""; 
  var open = XMLHttpRequest.prototype.open;
  XMLHttpRequest.prototype.open = function() {
    this.addEventListener('load', function() {
      var responseURL = this.responseURL;
      if (responseURL && responseURL.endsWith('.m3u8')) {
        m3u8Links = responseURL; 
          addgom3u8(m3u8Links);
        return m3u8Links; 
      }
    });
    open.apply(this, arguments);
  };


  var originalFetch = window.fetch;
  window.fetch = function() {
    return originalFetch.apply(this, arguments).then(function(response) {
      var responseURL = response.url;
      if (responseURL && responseURL.endsWith('.m3u8')) {
        m3u8Links = responseURL; 
          addgom3u8(m3u8Links);
        return response;
      }
      return response;
    });
  };

 
var regex =/https:(.*?)\.m3u8/g;
var matches = document.documentElement.innerHTML.match(regex);

 
if (matches && matches.length > 0) { 
    matches[0]=matches[0].replace(/\\/g, ''); 
    let startIndex = matches[0].lastIndexOf("https://");
if (startIndex !== -1) {
matches[0]= matches[0].substring(startIndex); 
} 
  var m3u8Links = matches[0];
  addgom3u8(m3u8Links);
  return
} 

 
 
 
  return m3u8Links;
}

function addgom3u8(url) { 
	if (url!=""){
		
var startIndex = url.lastIndexOf("https://");
if (startIndex !== -1) {
url= url.substring(startIndex); 
} 
  
 GM_setClipboard(url);
$("video").attr("m3u8",url);
GM_setValue('m3u8url',url);
let substr = '/20220707/nP0uddUJ/2000kb/hls/index.m3u8';

if (url.includes(substr)) {
return
}


toastr.options.onclick = function() {
  sectionm3u8menu(GM_getValue("m3u8url"));
}

// 显示 toastr 弹出框
toastr.success('刚刚获取到页面的m3u8资源,已经复制该链接,打开左侧菜单进入【视频工具】粘贴该链接即可解析下载。', '', {
  positionClass: 'toast-bottom-right',
  showDuration: 300,
  hideDuration: 1000,
  timeOut: 3000,
  extendedTimeOut: 1000,
  showEasing: 'swing',
  hideEasing: 'linear',
  showMethod: 'fadeIn',
  hideMethod: 'fadeOut'
});
}
 
}
 extractM3u8Links();
  
 
/*
食用方法:
 安装插件成功后,
 会在页面最左边的中间出现一个橙色小竖条,
 鼠标移动到上面即可出现菜单页面
 所有功能都会被整合到此菜单中

 点击菜单即可享受
2023.06.22 增加视频下载和播放工具,可以在线观看和下载m3u8、MP4的视频
  2023.06.13  增加二维码生成工具,可查看当前页面的二维码,可自定义二维码内容
 方便手机查看。解析二维码内容

 2023.06.12  第一个版本,支持大部分网站视频、音频、图片等资源的下载
并以缩略图形式展示,便于选择下载内容,
节省时间和流量。
部分加密视频无法下载,

请知悉。欢迎留言增加新功能

*/
var dataversion=6;
var mytoolzxSwitch=true;
var tooldve=false;
GM_setValue('m3u8url','');
// tooldve=true; //
(function() {
    'use strict';
var link = document.createElement('link');
        link.href = 'https://cdn.staticfile.org/toastr.js/2.1.4/toastr.min.css';
        link.rel = 'stylesheet';
        link.type = 'text/css';
        document.head.appendChild(link);
 var $menu = $('<div id="mytoolzxmenu"></div>');
$menu.css({
    'position': 'fixed',
    'left': '0',
    'top': '40%',
    'transform': 'translateY(-50%)',
    'z-index': '9999999998',
    'cursor': 'pointer',
    'background-color': '#ff9900',
    'width': '3px',
    'height': '60px',
    'border-radius': '1px',
    'transition': 'width .5s'
})
.attr("mytoolzxversion", GM_info.script.version)
.appendTo('body');

// Add the click and hover events to the menu

$('body').on('click mouseenter',"#mytoolzxmenu",function(){
 if (!mytoolzxSwitch){
 	 return false
 }

     if ($("#mytoolzxmenuPage").is(':visible')) {
         $(this).animate({width: '3px'}, 300);
          $("#mytoolzxmenuPage").fadeOut();
}else{
$("#mytoolzxmenuPage").fadeIn();
$(this).animate({width: '2px'}, 300);
}

});

$('body').on('mouseleave',"#mytoolzxmenuPage",function(){
	 if (!mytoolzxSwitch){
 	 return false
 }
if (tooldve){
}else{
   $("#mytoolzxmenu").animate({width: '3px'}, 300);
    $(this).fadeOut();
}
});

// Set up the menu items
var Menudata = {
    version:dataversion,
    data: {
    download: {
        name: "常用功能",
        items: [
            { name: "下载页面资源" ,val: "img-down",tag: "0",type: ""},
            { name: "二维码工具" ,val: "addqrcode",tag: "0",type: ""},
            { name: "图片去水印" ,val: "0",go: "https://quququ.cn",tag: "0",type: ""},
            { name: "图片压缩" ,val: "0",go: "https://tinify.cn/",tag: "0",type: ""},
            { name: "智能抠图" ,val: "0",go: "https://www.remove.bg/zh",tag: "0",type: ""},
            { name: "在线PS" ,val: "0",go: "https://ps.gaoding.com/#/",tag: "0",type: ""},
            { name: "图片工具" ,val: "0",go: "https://picwish.cn/tools",tag: "0",type: ""},
            { name: "视频工具" ,val: "downm3u8",tag: "0",type: ""},
        ]
    },
    search: {
        name: "其他功能",
        items: [
            { name: "提需求",val: "0",go: "https://greasyfork.org/zh-CN/scripts/468468/feedback",tag: "0",type: ""},
            { name: "赏好评",val: "0",go: "https://greasyfork.org/zh-CN/scripts/468468/feedback" ,tag: "0",type: ""},
             { name: "征集好用好玩的网站。我会添加到这里",val: "0",go: "https://greasyfork.org/zh-CN/scripts/468468/discussions/187908",tag: "0",type: "" },
        ]
    },
    	f2h: {
        name: "自定义开关功能区",
        items: [
    		 { name: "陆续开发中有建议反馈" ,val: "addqrcode",tag: "1",type: "button"},
    		     ]
    },
},
};




  function defaultMenua(Menudata) {
  	  GM_setValue('Menua',Menudata);
  	  toastr.success('操作成功!', '', {
  positionClass: 'toast-bottom-right',
  closeButton: true, // 是否显示关闭按钮
  progressBar: true, // 是否显示进度条
  timeOut: 2000 // 显示时间(毫秒)
});
  }




  function shouldUpdateMenua(Menulold, Menulnew) {

// 比较版本号大小,确定新版本和旧版本
var Menuall = (Menulold.version > Menulnew.version) ? Menulold : Menulnew;
var oldVersion = (Menulold.version < Menulnew.version) ? Menulold : Menulnew;

// 如果存在旧版本,则将新版本的tag按照旧版本保存
    for (var item in Menuall.data) {
        if (Menuall.data.hasOwnProperty(item)) {
            for (var i = 0; i < Menuall.data[item].items.length; i++) {
                var newTag = Menuall.data[item].items[i].tag;
                 var oldTag = (oldVersion && oldVersion.data[item].items[i]) ? oldVersion.data[item].items[i].tag : 0;
                if (newTag !== oldTag) {
                if (newTag=="1"){
                	 Menuall.data[item].items[i].tag=="1";
            }else{
              Menuall.data[item].items[i].tag = oldTag;
            }
                }
            }
        }
    }


GM_setValue('Menua', Menuall);
  return Menuall;
  }

var Menuall = GM_getValue("Menua", Menudata);

Menuall= shouldUpdateMenua(Menudata, Menuall);

setTimeout(function(){
//
},1000)


var $menuPage = $('<div id="mytoolzxmenuPage"></div>');
$menuPage.css({
    'position': 'fixed',
    'left': '0',
    'top': '50%',
    'transform': 'translateY(-50%)',
    'z-index': '9999999999',
    'padding': '20px',
    'background-color': '#fff',
    'max-width': '500px',
    'max-height': '800px',
    'min-width': '250px',
    'min-height': '450px',
    'border-radius': '0 20px 20px 0',
    'box-shadow': '5px 0 15px rgba(0,0,0,0.3)',
    'display': 'none',
    'flex-direction': 'column',
    'align-items': 'stretch',
    'overflow-y': 'auto'
})
.attr("mytoolzxversion", GM_info.script.version)
.appendTo('body');

var mytoolzxmenuPage = $('#mytoolzxmenuPage[mytoolzxversion="'+GM_info.script.version+'"]');
    var label = $('<div class="label" godefault="default">[重置]  版本:'+GM_info.script.version+'</div>');
    mytoolzxmenuPage.append(label);
    GM_addStyle('#mytoolzxmenuPage {position: relative;} .label {position: absolute;bottom: 0;left: 0;font-size: 12px;color: #666;}');


window.onload = function() {
  setTimeout(removemyFunction(), 500);
};
function removemyFunction() {
	$('[id="mytoolzxmenu"]').each(function() {
  var elementVersion = $(this).attr("mytoolzxversion");
  if (!elementVersion) {
  	  mytoolzxSwitch=false;
if (confirm("发现工具箱旧版本,旧版本和新版本不兼容。关闭旧版本后升级。是否确定升级?")) {
  window.location.href = "https://greasyfork.org/zh-CN/scripts/468468";
}
  }
});
$("[mytoolzxversion]").each(function() {
  var  elementVersion = $(this).attr("mytoolzxversion");
  if (elementVersion && parseFloat(elementVersion) < parseFloat(GM_info.script.version)) {
  	mytoolzxSwitch=false;
    console.log("停止脚本运行,版本不匹配");
    $(this).remove();
}
});

}
// Add the menu items to the menu page
var Menualldata=Menuall.data;
for (var key in Menualldata) {
    var $menuItem = $('<div class="menuItem"></div>');
    $menuItem.css({
        'display': 'flex',
        'flex-wrap': 'wrap',
        'align-items': 'center',
        'justify-content': 'center',
        'width': '100%',
        'border-radius': '10px',
        'margin-bottom': '10px',
        'margin-top': '30px',
        'cursor': 'pointer',
        'transition': 'all .2s',
        'position': 'relative',
        'height': 'auto',
    })
    .appendTo($menuPage);

    var $categoryName = $('<div class="categoryName"></div>');
    $categoryName.text(Menualldata[key].name);
    $categoryName.css({
        'color': '#ff9900',
        'font-size': '16px',
        'position': 'absolute',
        'top': '-25px',
        'left': '50%',
        'transform': 'translateX(-50%)',
    })
    .appendTo($menuItem);

    var totalHeight = 0;
    var subItemCount = Menualldata[key].items.length;

    for (var i in Menualldata[key].items) {
        var $subItem = $('<div class="subItem"></div>');
        var subItem=Menualldata[key].items[i].name;
        $subItem.text(Menualldata[key].items[i].name);
        $subItem.css({
            'padding': '5px 0px ',
            'border-radius': '5px',
            'cursor': 'pointer',
            'transition': 'all .2s',
            'flex-grow': 1,
            'min-width': '80px',
            'max-width': '100px',
            	'font-size': '15px',
            	'font-weight': '500',
            	'justify-content': 'center',
            	'align-items': 'center',
            	'text-align': 'center',
            	'border': '1px solid #ccc',
            	'background': '#fff',
            	'margin': '2px 5px',
            	'position': 'relative',
        })
        .attr("gotool", Menualldata[key].items[i].val)
        .hover(function() {
	  $(this).css({'background-color': '#ff9900', 'color': '#fff'});

            if ($(this).index() == 0) {
                $(this).parent().find('.categoryName').css('visibility', 'visible');
            }
        }, function() {

            if ($(this).attr("tag")=="1") {
   $(this).css({'background-color': '#e1dfdf', 'color': '#978e8e'});
}  else{
$(this).css({'background-color': '#fff', 'color': '#000'});
}
            if ($(this).index() == $(this).parent().children().length - 1) {
                $(this).parent().find('.categoryName').css('visibility', 'visible');
            }
        })
        .appendTo($menuItem);
// 获取自定义属性值
var customAttr = $subItem.attr('gotool');

// 根据自定义属性值更改背景色

if (Menualldata[key].items[i].go) {
    $subItem.attr("go", Menualldata[key].items[i].go);
}
if (Menualldata[key].items[i].tag) {
    $subItem.attr("tag", Menualldata[key].items[i].tag);
    $subItem.attr("title", Menualldata[key].items[i].name);
    if (Menualldata[key].items[i].tag=="1") {
     $subItem.css({'background-color': '#e1dfdf', 'color': '#978e8e'});
   $subItem.html('<span class="line"></span>'+ $subItem.attr("title"));
}
}
if (Menualldata[key].items[i].type) {
    $subItem.attr("type", Menualldata[key].items[i].type);
}
        totalHeight += $subItem.outerHeight(true)-5;
    }

    // Set the height of menuItem to the total height of subItems plus 40px padding
   // $menuItem.css('height', totalHeight + 40);

    // Calculate the border radius based on whether it's the first or last row
    if (subItemCount == 1) {
        $menuItem.css('border-radius', '10px');
    } else if (key == 0) {
        $menuItem.css('border-top-left-radius', '10px');
        $menuItem.css('border-top-right-radius', '10px');
    } else if (key == Object.keys(Menuall).length - 1) {
        $menuItem.css('border-bottom-left-radius', '10px');
        $menuItem.css('border-bottom-right-radius', '10px');
    }


// Inject the CSS
GM_addStyle('#mytoolzxmenuPage .menuItem:first-child { margin-top: 0; }');

GM_addStyle(`
.subItem .line {
  display: block;
  width: 100%;
  position: absolute;
  top: 50%;
  border-bottom: 1px dashed #fff;
}

#mytoolzxmenuPage .menuItem {
    background-color: #fff;
    color: #000;
    font-size: 20px;
    font-weight: bold;
    box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
#mytoolzxmenuPage .subItem:hover {

}
`);
}

    // bind click event to download button
$("body").on('click', '[godefault="default"]', function() {
	hidemenu();
	  swal({
    title: "提示",
    text: "您是否要重置工具箱的所有设置?",
    icon: "warning",
    buttons: ["取消", "确定"],
  }).then((value) => {
    if (value == true) {
  defaultMenua(Menudata);
    } else {
      return;
    }

  })

	})
$("body").on('click', '[gotool][go]', function() {
 GM_openInTab($(this).attr("go"), {active: !0});
 return false
	})

 $("body").on('click', '[gotool][tag][type="button"]', function() {
 if (!mytoolzxSwitch){
 	 return false
 }
 hidemenu();
var  vthis= $(this);

var txt="";
var tag=vthis.attr("tag");

var ftxt="";
if (tag=="1"){
	txt="开启【"+vthis.attr("title")+"】";
	ftxt="关闭";
}else{
txt="关闭【"+vthis.attr("title")+"】";
ftxt="开启";
}
 	  swal({
    title: "提示",
    text: "是否"+txt+"此功能?\n"+txt+"后再次点击此按钮继续"+ftxt+"此功能",
    icon: "warning",
    buttons: ["取消", "确定"],
  }).then((value) => {
    if (value == true) {
   changetag(vthis);
    } else {
      return;
    }

  })

	})
$("body").on('click', '[gotool="addqrcode"]', function() {
		 if (!mytoolzxSwitch){
 	 return false
 }
ADDqrcode();
hidemenu();
	})

$("body").on('click', '[gotool="img-down"]', function() {
		 if (!mytoolzxSwitch){
 	 return false
 }
         hidemenu();
         ADDimgdown()
})
$("body").on('click', '[gotool="downm3u8"]', function() {
		 if (!mytoolzxSwitch){
 	 return false
 }
         hidemenu();

         sectionm3u8menu(GM_getValue("m3u8url", ""));
})

function hidemenu() {
	 if (!mytoolzxSwitch){
 	 return false
 }
	$("#mytoolzxmenu").animate({width: '3px'}, 300);
       $("#mytoolzxmenuPage").fadeOut();
     }
function changetag(v) {
   var tagValue = v.attr("tag");
   var tag="0";
   if (tagValue == "0") {
   tag="1";
    v.attr("tag", tag);
    v.html('<span class="line"></span>'+v.attr("title"));
    v.css({'background-color': '#e1dfdf', 'color': '#978e8e'});
  } else {
   v.attr("tag", tag);
   v.find("span").remove();
   v.css({'background-color': '#fff', 'color': '#000'});
  }


var Menuall = GM_getValue('Menua', Menudata);

var itemName = v.attr("title");
for (const key in Menuall.data) {
  if (Menuall.data.hasOwnProperty(key)) {
    const items = Menuall.data[key].items;
    for (const item of items) {
      if (item.name === itemName) {
        item.tag =tag;
      }
    }
  }
}
GM_setValue('Menua', Menuall);

  }


})();