[{"articleStyle":4,"cacheFirst":false,"customOrder":5,"enableJs":true,"enabled":true,"enabledCookieJar":true,"lastUpdateTime":1787293735191,"loadWithBaseUrl":true,"loginUi":"[{\"name\": \"🖼 背景图片链接\", \"type\": \"text\", \"key\": \"ft_bg\", \"hint\": \"粘贴图片 URL，留空则清除背景图\"}, {\"name\": \"🎚 黑色区域透明度\", \"type\": \"text\", \"key\": \"ft_alpha\", \"hint\": \"0-100，越大越透明，0=不透明纯黑\", \"default\": \"0\"}, {\"name\": \"✅ 保存设置\", \"type\": \"button\", \"action\": \"var b=String(result['🖼 背景图片链接']||'').trim();var a=String(result['🎚 黑色区域透明度']||'').trim();java.put('ft_bg',b);if(a!='')java.put('ft_alpha',a);java.put('ft_msg','✅ 设置已保存');java.toast('✅ 设置已保存');\", \"style\": {\"layout_flexGrow\": 1, \"layout_flexBasisPercent\": 1}}]","loginUrl":"function login(){}","preload":false,"preloadJs":"window.__java=java;window.__source=source;window.__cache=cache;","ruleArticles":".anime-card","ruleContent":"@js:\nvar key = '';\nvar doc = org.jsoup.Jsoup.parse(result);\nvar playBox = doc.select(\".detail-anime-play\").first();\n\nif (playBox == null) {\n    \"未获取到播放列表\";\n} else {\n    function cleanText(str) {\n        return String(str || \"\").replace(\/\\s+\/g, \"\").trim();\n    }\n\n    function fullUrl(href) {\n        href = String(href || \"\").trim().replace(\/\\s+\/g, \"\");\n        if (href.indexOf(\"http\") == 0) return href;\n        if (href.indexOf(\"\/\/\") == 0) return \"https:\" + href;\n        if (href.indexOf(\"\/\") == 0) return \"https:\/\/acgfta.com\" + href;\n        return \"https:\/\/acgfta.com\/\" + href;\n    }\n\n    function esc(str) {\n        return String(str || \"\")\n            .replace(\/&\/g, \"&amp;\")\n            .replace(\/<\/g, \"&lt;\")\n            .replace(\/>\/g, \"&gt;\")\n            .replace(\/\"\/g, \"&quot;\")\n            .replace(\/'\/g, \"&#39;\");\n    }\n\n    function jsEsc(str) {\n        return String(str || \"\")\n            .replace(\/\\\\\/g, \"\\\\\\\\\")\n            .replace(\/'\/g, \"\\\\'\")\n            .replace(\/\"\/g, \"\\\\\\\"\")\n            .replace(\/\\n\/g, \"\")\n            .replace(\/\\r\/g, \"\");\n    }\n\n    var lines = playBox.select(\".anime-episode\");\n    var firstUrl = \"\";\n\n    for (var i = 0; i < lines.size(); i++) {\n        var firstEp = lines.get(i).select(\"a.btn-episode\").first();\n        if (firstEp != null) {\n            firstUrl = fullUrl(firstEp.attr(\"href\"));\n            break;\n        }\n    }\n\n    var coverEl = doc.select(\"img.anime-cover\").first();\n    var coverUrl = coverEl != null ? coverEl.attr(\"data-src\") : \"\";\n    if (coverUrl != \"\") coverUrl = fullUrl(coverUrl);\n    var titleEl = doc.select(\".detail-anime-title\").first();\n    var titleText = titleEl != null ? titleEl.text().trim() : \"\";\n    var infoPs = doc.select(\".detail-anime-info p\");\n    var yearText = \"\";\n    var langText = \"\";\n    for (var k = 0; k < infoPs.size(); k++) {\n        var pText = infoPs.get(k).text().trim();\n        if (pText.indexOf(\"年份\") >= 0) yearText = pText.replace(\"年份：\", \"\").trim();\n        else if (pText.indexOf(\"语言\") >= 0) langText = pText.replace(\"语言：\", \"\").trim();\n    }\n    var introEl = doc.select(\".detail-anime-intro\").first();\n    var introText = introEl != null ? introEl.text().trim() : \"\";\n\n    var detailBlock = \"\";\n    detailBlock += \"<div class='anime-detail'>\";\n    detailBlock += \"<div class='detail-top'>\";\n    if (coverUrl != \"\") {\n        detailBlock += \"<img src='\" + jsEsc(coverUrl) + \"' onerror=\\\"this.src='\/template\/ft-v2\/images\/img-error.jpg'\\\">\";\n    }\n    detailBlock += \"<div class='detail-info'>\";\n    detailBlock += \"<h5>\" + esc(titleText) + \"<\/h5>\";\n    detailBlock += \"<p>年份：\" + esc(yearText) + \"<\/p>\";\n    detailBlock += \"<p>语言：\" + esc(langText) + \"<\/p>\";\n    detailBlock += \"<\/div><\/div>\";\n    detailBlock += \"<div class='detail-intro'><p>\" + esc(introText) + \"<\/p><\/div>\";\n    detailBlock += \"<\/div>\";\n\n    var html = \"\";\n\n    html += \"<style>\";\n    html += \"*{box-sizing:border-box;}\";\n    html += \":root{--bg-alpha:1;color-scheme:light;}\";\n    html += \".tip-bar{position:sticky;top:0;z-index:99;background:rgba(79,140,255,.95);color:#fff;padding:9px 12px;border-radius:10px;text-align:center;font-size:13px;font-weight:700;margin-bottom:10px;box-shadow:0 4px 12px rgba(0,0,0,.2);}\";\n    html += \".gesture-tip{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);background:rgba(0,0,0,.7);color:#fff;padding:8px 16px;border-radius:8px;font-size:14px;z-index:10;pointer-events:none;display:none;}\";\n    html += \".skip-bar{margin:10px 0;padding:10px;background:rgba(255,255,255,var(--bg-alpha));border-radius:12px;border:1px solid #e5e7eb;box-shadow:0 2px 8px rgba(0,0,0,.05);}\";\n    html += \".skip-title{font-size:13px;font-weight:700;color:#111827;margin-bottom:8px;}\";\n    html += \".skip-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;}\";\n    html += \".skip-row label{font-size:12px;color:#6b7280;}\";\n    html += \".skip-row input{width:64px;padding:5px 8px;border:1px solid #d1d5db;border-radius:8px;font-size:13px;text-align:center;background:rgba(255,255,255,var(--bg-alpha));}\";\n    html += \".skip-row button{background:#4f8cff;color:#fff;border:none;padding:6px 12px;border-radius:8px;font-size:13px;font-weight:700;}\";\n    html += \"body.dark-mode .skip-bar{background:rgba(30,30,30,var(--bg-alpha));border-color:#444;}\";\n    html += \"body.dark-mode .skip-title{color:#e0e0e0;}\";\n    html += \"body.dark-mode .skip-row label{color:#aaa;}\";\n    html += \"body.dark-mode .skip-row input{background:rgba(30,30,30,var(--bg-alpha));color:#e0e0e0;border-color:#444;}\";\n    html += \".play-wrap{padding:10px;background:rgba(245,246,250,var(--bg-alpha));border-radius:16px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Arial,sans-serif;}\";\n    html += \".player-box{position:relative;width:100%;aspect-ratio:16\/9;background:rgba(0,0,0,var(--bg-alpha));border-radius:16px;overflow:hidden;margin-bottom:12px;box-shadow:0 8px 22px rgba(0,0,0,.25);}\";\n    html += \".player-box video{width:100%;height:100%;background:rgba(0,0,0,var(--bg-alpha));display:block;}\";\n    html += \".player-loading{position:absolute;left:0;top:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:#ddd;background:rgba(0,0,0,calc(var(--bg-alpha)*.55));font-size:14px;z-index:2;}\";\n    \/\/ 已移除全屏按钮样式\n    html += \".now-playing{background:rgba(255,255,255,var(--bg-alpha));border-radius:10px;padding:10px;margin-bottom:10px;font-weight:700;color:#111827;font-size:14px;text-align:center;box-shadow:0 2px 8px rgba(0,0,0,.05);}\";\n    html += \".line-tabs{display:flex;gap:8px;overflow-x:auto;padding:2px 0 10px;margin:0 0 8px;}\";\n    html += \".line-tabs button{flex:0 0 auto;border:none;padding:8px 14px;border-radius:999px;background:rgba(238,242,255,var(--bg-alpha));color:#374151;font-size:14px;font-weight:700;}\";\n    html += \".line-tabs button.active{background:#4f8cff;color:#fff;box-shadow:0 5px 14px rgba(79,140,255,.32);}\";\n    html += \".line-panel{display:none;}\";\n    html += \".line-panel.active{display:block;}\";\n    html += \".episode-box{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;}\";\n    html += \".episode-box button{width:100%;padding:10px 6px;text-align:center;background:rgba(255,255,255,var(--bg-alpha));color:#222;border-radius:12px;border:1px solid #e5e7eb;font-size:14px;font-weight:650;box-shadow:0 2px 8px rgba(0,0,0,.05);position:relative;transition:all .15s;}\";\n    html += \".episode-box button.active{background:#4f8cff;color:#fff;border-color:#4f8cff;box-shadow:0 5px 14px rgba(79,140,255,.4);}\";\n    html += \".episode-box button.watched{background:rgba(219,234,254,var(--bg-alpha));border-color:#93c5fd;}\";\n    html += \".episode-box button:active{transform:scale(.97);}\";\n    html += \"@media(max-width:360px){.episode-box{grid-template-columns:repeat(3,1fr);}}\";\n    html += \".history-bar{display:flex;justify-content:flex-end;gap:8px;padding:4px 0;}\";\n    html += \".history-bar button{background:rgba(255,255,255,var(--bg-alpha));border:1px solid #d1d5db;padding:4px 10px;border-radius:6px;font-size:12px;color:#6b7280;}\";\n    html += \".anime-detail{margin-top:12px;background:rgba(255,255,255,var(--bg-alpha));border-radius:12px;padding:12px;box-shadow:0 2px 8px rgba(0,0,0,.05);}\";\n    html += \".detail-top{display:flex;gap:10px;align-items:center;margin-bottom:8px;}\";\n    html += \".detail-top img{width:80px;height:112px;object-fit:cover;border-radius:8px;flex-shrink:0;}\";\n    html += \".detail-info h5{font-size:16px;font-weight:700;margin:0 0 4px;}\";\n    html += \".detail-info p{font-size:13px;color:#555;margin:2px 0;}\";\n    html += \".detail-intro{font-size:13px;color:#333;line-height:1.5;max-height:200px;overflow-y:auto;}\";\n    html += \"html,body{background-color:#fff;}\";\n    html += \"body.dark-mode{background-color:rgba(0,0,0,var(--bg-alpha));color-scheme:dark;}\";\n    html += \"body.dark-mode .play-wrap{background:rgba(18,18,18,var(--bg-alpha));}\";\n    html += \"body.dark-mode .now-playing{background:rgba(30,30,30,var(--bg-alpha));color:#e0e0e0;}\";\n    html += \"body.dark-mode .line-tabs button{background:rgba(42,42,42,var(--bg-alpha));color:#e0e0e0;}\";\n    html += \"body.dark-mode .line-tabs button.active{background:#4f8cff;color:#fff;}\";\n    html += \"body.dark-mode .episode-box button{background:rgba(30,30,30,var(--bg-alpha));color:#e0e0e0;border-color:rgba(68,68,68,var(--bg-alpha));}\";\n    html += \"body.dark-mode .episode-box button.active{background:#4f8cff;color:#fff;}\";\n    html += \"body.dark-mode .episode-box button.watched{background:rgba(30,58,95,var(--bg-alpha));}\";\n    html += \"body.dark-mode .anime-detail{background:rgba(30,30,30,var(--bg-alpha));color:#e0e0e0;}\";\n    html += \"body.dark-mode .detail-info p{color:#ccc;}\";\n    html += \"body.dark-mode .detail-intro{color:#bbb;}\";\n    html += \"body.dark-mode .history-bar button{background:transparent;border-color:#444;color:#aaa;}\";\n    \/\/ 全屏时播放器布局调整\n    html += \"#playerBox:fullscreen{aspect-ratio:auto;width:100vw;height:100vh;border-radius:0;display:flex;align-items:center;justify-content:center;background:#000;}\";\n    html += \"#playerBox:-webkit-full-screen{aspect-ratio:auto;width:100vw;height:100vh;border-radius:0;display:flex;align-items:center;justify-content:center;background:#000;}\";\n    html += \"#playerBox:fullscreen video{width:100%;height:100%;object-fit:contain;}\";\n    html += \"#playerBox:-webkit-full-screen video{width:100%;height:100%;object-fit:contain;}\";\n    html += \"<\/style>\";\n\n    html += \"<div class='play-wrap'>\";\n    html += \"<div id='tipBar' class='tip-bar' style='display:none'><\/div>\";\n\n    html += \"<div id='playerBox' class='player-box'>\";\n    html += \"<div id='playerLoading' class='player-loading'>加载中...<\/div>\";\n    html += \"<video id='videoPlayer' controls playsinline webkit-playsinline x5-playsinline preload='auto'><\/video>\";\n    \/\/ 已移除全屏按钮\n    html += \"<div id='gestureTip' class='gesture-tip'><\/div>\";\n    html += \"<\/div>\";\n\n    html += \"<div class='skip-bar'>\";\n    html += \"<div class='skip-title'>⚙ 播放设置（仅本剧，重新进入仍生效）<\/div>\";\n    html += \"<div class='skip-row'>\";\n    html += \"<label>片头(秒)<\/label><input id='skipOp' type='number' min='0' step='1' placeholder='0'>\";\n    html += \"<label>片尾(秒)<\/label><input id='skipEd' type='number' min='0' step='1' placeholder='0'>\";\n    html += \"<label>速度<\/label><input id='speedInput' type='number' min='0.5' max='3' step='0.1' placeholder='1.0'>\";\n    html += \"<button type='button' onclick='saveSkip()'>💾 保存<\/button>\";\n    html += \"<\/div>\";\n    html += \"<\/div>\";\n\n    html += detailBlock;\n\n    html += \"<div id='nowPlaying' class='now-playing'>正在播放：-<\/div>\";\n\n    html += \"<div class='line-tabs'>\";\n    for (var t = 0; t < lines.size(); t++) {\n        var tabName = String(lines.get(t).attr(\"id\") || \"\").trim();\n        if (tabName.length == 0) tabName = \"线路\" + (t + 1);\n        html += \"<button type='button' id='tab_\" + t + \"' class='\" + (t == 0 ? \"active\" : \"\") + \"' onclick='showLine(\" + t + \")'>\" + esc(tabName) + \"<\/button>\";\n    }\n    html += \"<\/div>\";\n\n    for (var x = 0; x < lines.size(); x++) {\n        var line = lines.get(x);\n        html += \"<div id='panel_\" + x + \"' class='line-panel \" + (x == 0 ? \"active\" : \"\") + \"'>\";\n        html += \"<div class='episode-box'>\";\n        var episodes = line.select(\"a.btn-episode\");\n        for (var j = 0; j < episodes.size(); j++) {\n            var ep = episodes.get(j);\n            var title = cleanText(ep.text());\n            var url = fullUrl(ep.attr(\"href\"));\n            html += \"<button type='button' id='ep_\" + x + \"_\" + j + \"' data-url='\" + jsEsc(url) + \"' onclick=\\\"changePlay('\" + jsEsc(url) + \"','ep_\" + x + \"_\" + j + \"')\\\">\" + esc(title) + \"<\/button>\";\n        }\n        html += \"<\/div>\";\n        html += \"<\/div>\";\n    }\n\n    html += \"<div class='history-bar'>\";\n    html += \"<button onclick='clearHistory()'>🗑 清除本剧历史<\/button>\";\n    html += \"<\/div>\";\n    html += \"<\/div>\";\n\n    html += \"<script>\";\n    var ftBg = java.get('ft_bg');\n    if (ftBg == null) ftBg = '';\n    var ftAlpha = java.get('ft_alpha');\n    if (ftAlpha == null) ftAlpha = '0';\n\n    html += \"var settings = {backgroundImage: '\" + jsEsc(ftBg) + \"', alpha: '\" + jsEsc(ftAlpha) + \"'};\";\n    html += \"document.body.style.backgroundColor='#fff';\";\n    html += \"if(settings.backgroundImage) { document.body.style.backgroundImage = 'url(' + settings.backgroundImage + ')'; document.body.style.backgroundSize = 'cover'; document.body.style.backgroundAttachment = 'fixed'; }\";\n    html += \"var alpha = parseFloat(settings.alpha); if(isNaN(alpha)) alpha = 0; alpha = Math.max(0, Math.min(100, alpha)); document.documentElement.style.setProperty('--bg-alpha', (1 - alpha \/ 100).toFixed(3));\";\n    html += \"var playbackRate = 1;\";\n\n    html += \"var firstPlayUrl='\" + jsEsc(firstUrl) + \"';\";\n    html += \"var currentLine=0, currentIdx=0, currentTitle='';\";\n    html += \"var isRestoring=false;\";\n    html += \"function getStorageKey(){try{var p=document.location.pathname;if(p.slice(-1)=='\/')p=p.slice(0,-1);if(!p)p='index';return 'acgfta_history_'+encodeURIComponent(p);}catch(e){return 'acgfta_history_default';}}\";\n    html += \"function getHistory(){try{var d=localStorage.getItem(getStorageKey());return d?JSON.parse(d):{};}catch(e){return{};}}\";\n    html += \"function saveHistory(){\";\n    html += \"if(isRestoring) return;\";\n    html += \"var h={line:currentLine, index:currentIdx, title:currentTitle, time:0};\";\n    html += \"var video=document.getElementById('videoPlayer');\";\n    html += \"if(video)h.time=video.currentTime||0;\";\n    html += \"try{localStorage.setItem(getStorageKey(),JSON.stringify(h));}catch(e){}\";\n    html += \"}\";\n    html += \"function clearHistory(){\";\n    html += \"localStorage.removeItem(getStorageKey());\";\n    html += \"document.getElementById('nowPlaying').textContent='正在播放：-';\";\n    html += \"alert('本剧历史已清除');\";\n    html += \"}\";\n    html += \"function updateNowPlaying(){\";\n    html += \"var label=document.getElementById('nowPlaying');\";\n    html += \"if(!label)return;\";\n    html += \"var lineName='线路'+(currentLine+1);\";\n    html += \"var tab=document.getElementById('tab_'+currentLine);\";\n    html += \"if(tab)lineName=tab.innerText.trim();\";\n    html += \"label.textContent='正在播放：'+lineName+' - '+(currentTitle||'未知');\";\n    html += \"}\";\n    html += \"function markWatched(id){\";\n    html += \"var btn=document.getElementById(id);\";\n    html += \"if(btn&&!btn.classList.contains('watched')){\";\n    html += \"btn.classList.add('watched');\";\n    html += \"}\";\n    html += \"}\";\n    html += \"function showLine(index){\";\n    html += \"var tabs=document.querySelectorAll('.line-tabs button');\";\n    html += \"var panels=document.querySelectorAll('.line-panel');\";\n    html += \"for(var i=0;i<tabs.length;i++){tabs[i].classList.remove('active');}\";\n    html += \"for(var j=0;j<panels.length;j++){panels[j].classList.remove('active');}\";\n    html += \"document.getElementById('tab_'+index).classList.add('active');\";\n    html += \"document.getElementById('panel_'+index).classList.add('active');\";\n    html += \"}\";\n    html += \"function setActive(id){\";\n    html += \"var eps=document.querySelectorAll('.episode-box button');\";\n    html += \"for(var i=0;i<eps.length;i++){eps[i].classList.remove('active');}\";\n    html += \"var now=document.getElementById(id);\";\n    html += \"if(now){now.classList.add('active');markWatched(id);}\";\n    html += \"}\";\n    html += \"function getM3u8FromText(txt){\";\n    html += \"var m=txt.match(\/var\\\\s+player_aaaa\\\\s*=\\\\s*(\\\\{[\\\\s\\\\S]*?\\\\})<\\\\\/script>\/);\";\n    html += \"if(!m){m=txt.match(\/var\\\\s+player_aaaa\\\\s*=\\\\s*(\\\\{[\\\\s\\\\S]*?\\\\})\/);}\";\n    html += \"if(m){\";\n    html += \"try{\";\n    html += \"var obj=JSON.parse(m[1]);\";\n    html += \"if(obj&&obj.url)return obj.url;\";\n    html += \"}catch(e){\";\n    html += \"var u=m[1].match(\/\\\"url\\\"\\\\s*:\\\\s*\\\"([^\\\"]+)\\\"\/);\";\n    html += \"if(u)return u[1].replace(\/\\\\\\\\\\\\\/\/g,'\/');\";\n    html += \"}\";\n    html += \"}\";\n    html += \"var nuxt=txt.match(\/__NUXT__\\\\s*=\\\\s*(\\\\{[\\\\s\\\\S]*?\\\\});?\\\\s*<\\\\\/script>\/);\";\n    html += \"if(nuxt){\";\n    html += \"try{\";\n    html += \"var data=JSON.parse(nuxt[1]);\";\n    html += \"var state=data.state||data;\";\n    html += \"if(state.player_aaaa&&state.player_aaaa.url)return state.player_aaaa.url;\";\n    html += \"}catch(e){}\";\n    html += \"}\";\n    html += \"var direct=txt.match(\/https?:\\\\\/\\\\\/[^\\\\s\\\"']+\\\\.m3u8[^\\\\s\\\"']*\/i);\";\n    html += \"return direct ? direct[0] : '';\";\n    html += \"}\";\n    html += \"function playM3u8(m3u8){\";\n    html += \"var video=document.getElementById('videoPlayer');\";\n    html += \"var loading=document.getElementById('playerLoading');\";\n    html += \"if(!m3u8){loading.innerHTML='未获取到播放地址';return;}\";\n    html += \"loading.style.display='none';\";\n    html += \"if(window.Hls && Hls.isSupported()){\";\n    html += \"  if(video._hls) video._hls.destroy();\";\n    html += \"  var hls=new Hls();\";\n    html += \"  video._hls=hls;\";\n    html += \"  hls.loadSource(m3u8);\";\n    html += \"  hls.attachMedia(video);\";\n    html += \"  hls.on(Hls.Events.MANIFEST_PARSED,function(){video.playbackRate = playbackRate; video.play().catch(function(){});});\";\n    html += \"  hls.on(Hls.Events.ERROR,function(event,data){if(data.fatal){loading.style.display='flex';loading.innerHTML='播放失败：'+data.type;}});\";\n    html += \"} else if(video.canPlayType('application\/vnd.apple.mpegurl')){\";\n    html += \"  video.src=m3u8;\";\n    html += \"  video.addEventListener('loadedmetadata',function(){video.playbackRate = playbackRate; video.play().catch(function(){});});\";\n    html += \"} else {\";\n    html += \"  loading.style.display='flex';\";\n    html += \"  loading.innerHTML='当前环境不支持HLS播放';\";\n    html += \"}\";\n    html += \"}\";\n    html += \"function changePlay(playUrl,id){\";\n    html += \"if(!isRestoring) saveHistory();\";\n    html += \"setActive(id);\";\n    html += \"var parts=id.split('_');\";\n    html += \"if(parts.length===3){\";\n    html += \"  currentLine=parseInt(parts[1]);\";\n    html += \"  currentIdx=parseInt(parts[2]);\";\n    html += \"}\";\n    html += \"var btn=document.getElementById(id);\";\n    html += \"currentTitle=btn?btn.innerText.trim():'';\";\n    html += \"updateNowPlaying();\";\n    html += \"var loading=document.getElementById('playerLoading');\";\n    html += \"loading.style.display='flex';\";\n    html += \"loading.innerHTML='加载中...';\";\n    html += \"fetch(playUrl, {headers: {'Referer': 'https:\/\/acgfta.com\/'}}).then(function(res){return res.text();}).then(function(txt){\";\n    html += \"var m3u8=getM3u8FromText(txt);\";\n    html += \"playM3u8(m3u8);\";\n    html += \"saveHistory();\";\n    html += \"}).catch(function(err){\";\n    html += \"loading.innerHTML='请求失败：'+err.message;\";\n    html += \"});\";\n    html += \"window.scrollTo(0,0);\";\n    html += \"}\";\n    html += \"var video=document.getElementById('videoPlayer');\";\n    html += \"video.addEventListener('timeupdate',function(){\";\n    html += \"if(video.currentTime && !isRestoring) saveHistory();\";\n    html += \"});\";\n    html += \"function restoreHistory(){\";\n    html += \"var h=getHistory();\";\n    html += \"if(!h.line && h.line!==0)return false;\";\n    html += \"isRestoring=true;\";\n    html += \"showLine(h.line);\";\n    html += \"var histId='ep_'+h.line+'_'+h.index;\";\n    html += \"var btn=document.getElementById(histId);\";\n    html += \"if(btn){\";\n    html += \"  changePlay(btn.getAttribute('data-url'), histId);\";\n    html += \"  var vid=document.getElementById('videoPlayer');\";\n    html += \"  if(h.time && vid){\";\n    html += \"    vid.addEventListener('loadedmetadata',function(){\";\n    html += \"      this.currentTime=h.time;\";\n    html += \"    }, {once: true});\";\n    html += \"  }\";\n    html += \"  isRestoring=false;\";\n    html += \"  return true;\";\n    html += \"}\";\n    html += \"isRestoring=false;\";\n    html += \"return false;\";\n    html += \"}\";\n    html += \"setTimeout(function(){\";\n    html += \"  if(!restoreHistory()) changePlay(firstPlayUrl,'ep_0_0');\";\n    html += \"}, 100);\";\n    html += \"var J=(typeof window.__java!=='undefined')?window.__java:null;\";\n    html += \"function showTip(t){var b=document.getElementById('tipBar');if(!b)return;b.textContent=t;b.style.display='block';clearTimeout(b._t);b._t=setTimeout(function(){b.style.display='none';},3500);}\";\n    html += \"function applySettings(){\";\n    html += \"try{\";\n    html += \"if(!J||!J.get)return;\";\n    html += \"var msg=J.get('ft_msg');\";\n    html += \"if(msg){J.toast(msg);showTip(msg);J.put('ft_msg','');}\";\n    html += \"var b=J.get('ft_bg')||'';\";\n    html += \"var a=parseFloat(J.get('ft_alpha')||'0');if(isNaN(a))a=0;a=Math.max(0,Math.min(100,a));\";\n    html += \"document.documentElement.style.setProperty('--bg-alpha',(1-a\/100).toFixed(3));\";\n    html += \"document.body.style.backgroundColor='#fff';\";\n    html += \"if(b){document.body.style.backgroundImage='url('+b+')';document.body.style.backgroundSize='cover';document.body.style.backgroundAttachment='fixed';}else{document.body.style.backgroundImage='';document.body.style.backgroundSize='';document.body.style.backgroundAttachment='';}\";\n    html += \"}catch(e){}\";\n    html += \"}\";\n    html += \"setInterval(applySettings,2000);\";\n    html += \"document.addEventListener('visibilitychange',function(){if(!document.hidden)applySettings();});\";\n    html += \"var skipOp=0,skipEd=0;\";\n    html += \"function loadSkip(){try{var d=localStorage.getItem(getStorageKey()+'_skip');if(d){var o=JSON.parse(d);skipOp=parseInt(o.op)||0;skipEd=parseInt(o.ed)||0;var sp=parseFloat(o.speed);if(!(sp>0))sp=1;playbackRate=sp;var v=document.getElementById('videoPlayer');if(v)v.playbackRate=sp;var io=document.getElementById('skipOp'),ie=document.getElementById('skipEd'),is=document.getElementById('speedInput');if(io)io.value=skipOp||'';if(ie)ie.value=skipEd||'';if(is)is.value=sp===1?'':sp;}}catch(e){}}\";\n    html += \"function saveSkip(){var io=document.getElementById('skipOp'),ie=document.getElementById('skipEd'),is=document.getElementById('speedInput');var op=io?(parseInt(io.value)||0):0,ed=ie?(parseInt(ie.value)||0):0,sp=is?parseFloat(is.value):1;if(op<0)op=0;if(ed<0)ed=0;if(!(sp>0)||isNaN(sp))sp=1;skipOp=op;skipEd=ed;playbackRate=sp;var v=document.getElementById('videoPlayer');if(v)v.playbackRate=sp;try{localStorage.setItem(getStorageKey()+'_skip',JSON.stringify({op:op,ed:ed,speed:sp}));}catch(e){}showTip('⏭ 已保存：片头 '+op+' 秒 \/ 片尾 '+ed+' 秒 \/ 速度 '+sp+'x');}\";\n    html += \"function skipCheck(){var v=document.getElementById('videoPlayer');if(!v||!v.duration||!isFinite(v.duration))return;try{if(skipOp>0&&v.currentTime<skipOp&&!v.seeking){v.currentTime=skipOp;}if(skipEd>0&&v.currentTime>=v.duration-skipEd&&v.currentTime<v.duration){v.currentTime=v.duration;}}catch(e){}}\";\n    html += \"var vp=document.getElementById('videoPlayer');vp.addEventListener('timeupdate',skipCheck);\";\n    html += \"loadSkip();\";\n    \/\/ 已移除 toggleFullscreen 函数，保留自动横屏逻辑\n    html += \"function lockLandscape(){if(screen.orientation&&screen.orientation.lock){screen.orientation.lock('landscape').catch(function(){});}}\";\n    html += \"function unlockOrientation(){if(screen.orientation&&screen.orientation.unlock){screen.orientation.unlock();}}\";\n    html += \"document.addEventListener('fullscreenchange',function(){if(document.fullscreenElement){lockLandscape();}else{unlockOrientation();}});\";\n    html += \"document.addEventListener('webkitfullscreenchange',function(){if(document.webkitFullscreenElement){lockLandscape();}else{unlockOrientation();}});\";\n    \/\/ 手势功能\n    html += \"var gestureTip=document.getElementById('gestureTip');\";\n    html += \"var startX=0,startY=0,seekStartTime=0,pendingSeekDelta=0;\";\n    html += \"var longPressTimer=null,longPressTriggered=false,tempRateActive=false,originalRate=1;\";\n    html += \"function formatTime(sec){if(!isFinite(sec)||sec<0)sec=0;var m=Math.floor(sec\/60),s=Math.floor(sec%60);return (m<10?'0'+m:m)+':'+(s<10?'0'+s:s);}\";\n    html += \"function showGestureTip(msg){gestureTip.textContent=msg;gestureTip.style.display='block';}\";\n    html += \"function hideGestureTip(){gestureTip.style.display='none';}\";\n    html += \"document.addEventListener('touchstart',function(e){if(e.target!==vp&&e.target!==document.getElementById('playerBox'))return;if(e.touches.length!==1)return;startX=e.touches[0].clientX;startY=e.touches[0].clientY;seekStartTime=vp.currentTime||0;pendingSeekDelta=0;longPressTriggered=false;tempRateActive=false;clearTimeout(longPressTimer);longPressTimer=setTimeout(function(){longPressTriggered=true;tempRateActive=true;originalRate=playbackRate;playbackRate=Math.min(3,playbackRate+0.5);vp.playbackRate=playbackRate;showGestureTip('临时速度 '+playbackRate.toFixed(1)+'x，上下滑调整');},500);});\";\n    html += \"document.addEventListener('touchmove',function(e){if(e.target!==vp&&e.target!==document.getElementById('playerBox'))return;if(e.touches.length!==1)return;var dx=e.touches[0].clientX-startX;var dy=e.touches[0].clientY-startY;if(longPressTriggered){if(Math.abs(dy)>Math.abs(dx)){var delta=-dy;var steps=Math.round(delta\/30);if(steps!==0){var newRate=playbackRate+steps*0.1;newRate=Math.max(0.5,Math.min(3,newRate));newRate=Math.round(newRate*10)\/10;if(newRate!==playbackRate){playbackRate=newRate;vp.playbackRate=playbackRate;showGestureTip('临时速度 '+playbackRate.toFixed(1)+'x');}}}}else{if(Math.abs(dx)>Math.abs(dy)&&isFinite(vp.duration)){pendingSeekDelta=dx\/10;var target=seekStartTime+pendingSeekDelta;target=Math.max(0,Math.min(vp.duration,target));showGestureTip('进度 '+formatTime(target)+' \/ '+formatTime(vp.duration));}}});\";\n    html += \"document.addEventListener('touchend',function(e){if(e.target!==vp&&e.target!==document.getElementById('playerBox'))return;clearTimeout(longPressTimer);if(tempRateActive){playbackRate=originalRate;vp.playbackRate=playbackRate;showGestureTip('已恢复速度 '+playbackRate.toFixed(1)+'x');tempRateActive=false;longPressTriggered=false;setTimeout(hideGestureTip,500);}else{if(pendingSeekDelta!==0&&isFinite(vp.duration)){var target=seekStartTime+pendingSeekDelta;target=Math.max(0,Math.min(vp.duration,target));vp.currentTime=target;}longPressTriggered=false;pendingSeekDelta=0;hideGestureTip();}});\";\n    html += \"<\/script>\";\n\n    html;\n}","ruleImage":".anime-cover@data-src","ruleLink":".stretched-link@href","ruleNextPage":"a[aria-label=Next]@href","ruleTitle":".stretched-link@text","searchUrl":"https:\/\/acgfta.com\/search.html?wd={{key}}","showWebLog":false,"singleUrl":false,"sortUrl":"主页::https:\/\/acgfta.com\/\n最近更新::https:\/\/acgfta.com\/ft\/recent.html\n剧场版::https:\/\/acgfta.com\/ft\/top-movie.html","sourceComment":"\/\/梦不觉\n\/\/2026.08.13 增加背景图设置，增加片头片尾跳过和加速播放。\n\/\/2026.08.11","sourceGroup":"影视","sourceIcon":"https:\/\/acgfta.com\/template\/ft-v2\/icon\/ft-logo-f.png","sourceName":"饭团动漫","sourceUrl":"https:\/\/acgfta.com\/","style":"<style>\n.ad-warning {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 4px;\n  margin-bottom: 8px;\n  padding: 6px 12px;\n  background: #fff3cd;\n  border: 1px solid #ffc107;\n  border-radius: 8px;\n  color: #856404;\n  font-size: 13px;\n  font-weight: 500;\n  line-height: 1.4;\n}\n<\/style>\n<div class=\"ad-warning\">⚠️ 注意：请勿相信视频内的任何广告，后果自行承担<\/div>","type":0}]