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

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

Tính đến 26-06-2023. Xem phiên bản mới nhất.

Script này sẽ không được không được cài đặt trực tiếp. Nó là một thư viện cho các script khác để bao gồm các chỉ thị meta // @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);

  }


})();