// ==UserScript== // @name 火箭按钮 // @description 一个常驻所有网页的悬浮「瑞士军刀」——单击平滑返回顶部,悬停展开快捷菜单,并能挂载插件扩展能力(内置 GitHub 下载加速、划词翻译、定时提醒,也可导入用户插件)。 // @match *://* // @include * // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant GM_addValueChangeListener // @grant GM_removeValueChangeListener // @grant GM_openInTab // @grant unsafeWindow // @run-at document-end // @license All Rights Reserved // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAACxUlEQVR4nO3dMW8SYRzH8duKg5Nuhdo3UNib+hoUlqeNielm1LVLt7obEyOkATqQmG6Y6FSXGh3VOBjQNlUDDQ+yOPEGzjwrPFdLwD6/g+8n+U+Xu3ue+6YJhaZEEQDgf7tX+5o1tVbXN+5Y6PUtHLN/srpZb8e+ccdCr2/hGIJoMQTRYgiixRAkjK1qe8PUWo2xqbebiUHq7abvHHet0PtJPVNrbyc9+EnHXSv0flLPEESLIYgWQxAthiBaDEG0GIJoMQTRYgiixRBEiyFIGFvV05vuTcGxOWjtzCzIQWvHdw9379D7l+Pe/Nuc0YOf/Cen1Qi9fzkEEUMQMQQRQxAxBEl5kAcvv8ftHz3vuGMEueIgjw9P4t/9vnceHRJkagQRQxAxBBFDkJQE2X11Gr/+2Bmboy/dxCDumO+c3eYpQaYN8uzoLPHBTzruWgS5JIKIIYgYgoghSIpeZb351Bmbt/94leU7x12LIJfE7yFiCCKGIGIIIoYgc/CJ4befPe/wieEM8Jm6GIKIIYgYgoghiBiCBLJUrHzIFMu/Ruf2k3fDUEHcvX1rcmuN5l2mVO5kSpV4dNb3joPEcOPu7VuTW2s07wgihiBiCCKGIAFcv/viRqZYrnqnVB6mKMgwaR9uj1FaLN3ZX/VvMHk0g1QSx+0xSguCiCGIGIKIIYgYgoghiBiCiCGIGIKIIYiYa8XnWd8ncBfN+t7xmam1zke/T+p++fOfh0/fx7MYdy3Pd1adu3tPul63x2gR2Vxh264U4plMrsD/XJyWJYgWSxAtliBaLEG0WIJosQTRYgmixRJEiyWIFksQLZYgWixBtFiCaLEE0WIJosUSRIsliJZ+Lr/RW8k3RsfmCs0LHnzTd467Vuj9zK3BrcJqUhB3LPT6Fs6AIFoGBNEyIIiWAUG09JbXsr1cvuud5bXF/CM2AIiu1F+d56Qeo24SAwAAAABJRU5ErkJggg== // @version 0.8.161 // @author flowsaro.com // @namespace https://docs.scriptcat.org/ // @noframes // @require data:application/javascript,unsafeWindow.__rbVueHad%20%3D%20'Vue'%20in%20unsafeWindow%3B%20unsafeWindow.__rbVuePrev%20%3D%20unsafeWindow.Vue%3B // @require https://unpkg.com/vue@3/dist/vue.global.prod.js // @require data:application/javascript,if%20(unsafeWindow.__rbVueHad)%20%7B%20try%20%7B%20unsafeWindow.Vue%20%3D%20unsafeWindow.__rbVuePrev%3B%20%7D%20catch%20%7B%7D%20%7D%20else%20%7B%20try%20%7B%20delete%20unsafeWindow.Vue%3B%20%7D%20catch%20%7B%7D%20%7D%20try%20%7B%20delete%20unsafeWindow.__rbVuePrev%3B%20%7D%20catch%20%7B%7D%20try%20%7B%20delete%20unsafeWindow.__rbVueHad%3B%20%7D%20catch%20%7B%7D // ==/UserScript== /* ==UserConfig== general: githubAccel: title: 开启 GitHub 加速链接功能 description: 关闭后,GitHub 页面将不显示镜像加速下载按钮 type: checkbox default: true backTop: title: 开启返回顶部按钮 description: 关闭后,所有页面(包括 GitHub)都不显示返回顶部按钮 type: checkbox default: true alwaysShow: title: 总是显示返回顶部按钮 description: 开启后按钮不随滚动自动隐藏,始终显示在页面上 type: checkbox default: false noBtnBg: title: 不显示按钮背景 description: 开启后按钮背景/边框/阴影透明,仅保留图标与点击区域 type: checkbox default: false iconScale: title: 图标大小倍率(1x = 26px,范围 0.6 ~ 4) description: 允许小数(截断 1 位),范围 0.6 ~ 4;面板内可用「2倍」/「默认」快捷按钮 type: number default: 1 btnAnim: title: 按钮图标动画 description: 可选:none(无)/ breathe(呼吸)/ spin(旋转)/ pulse(脉冲)/ ripple(涟漪,从按钮边缘往外扩散的水波)。GIF 动图不受影响;系统开启「减少动态效果」时自动禁用 type: text default: none btnRotate: title: 按钮旋转角度(0 ~ 360 度) description: 主按钮图标的旋转角度,超出范围自动收敛到 0 ~ 360 type: number default: 0 btnMirror: title: 水平镜像主按钮 description: 把图标左右翻转。可与「旋转角度」叠加(先镜像再旋转,所以调好的角度不会被镜像翻反) type: checkbox default: false btnOpacity: title: 按钮不透明度(0.3 ~ 1) description: 平时按这个值淡在页面上(0.3 是最淡的档,再淡就难找了);鼠标悬停 / 拖动 / 打开面板时会自动回到完全不透明。触摸端不生效 —— 那边没有悬停这层补偿,淡着只会更难点中 type: number default: 1 quickMenu: title: 启用快捷菜单 description: 开启后鼠标悬停按钮自动展开快捷菜单(触摸端双击),显示已绑定的快捷功能插件。⚠️ 只控制悬停/双击:插件主动弹出的菜单(如选中文字后的快捷翻译)不受此开关限制,想彻底关闭请解绑槽位或禁用该插件 type: checkbox default: false menuSlots: title: 快捷菜单槽位数量(2 ~ 8) description: 快捷菜单可容纳的功能数量,超出范围自动收敛到 2 ~ 8 type: number default: 4 customIcon: title: 自定义按钮图标(base64) description: 填写 data:image/...;base64,... 或纯 base64 字符串,留空使用脚本默认图标 type: textarea default: '' disabledSites: title: 不显示返回顶部按钮的站点 description: 每行填写一个域名,例如 baidu.com type: textarea default: '' ==/UserConfig== */ (()=>{"use strict";const e=Vue,t=(0,e.defineComponent)({inheritAttrs:!1,__name:"Button",props:{size:{default:46},dragging:{type:Boolean,default:!1},transparent:{type:Boolean,default:!1},variant:{default:"glass"},round:{type:Boolean,default:!1}},setup(t){const n=t,r=(0,e.useAttrs)(),o=(0,e.ref)(!1),i=(0,e.computed)(()=>{const{style:e,...t}=r;return t}),a=(0,e.computed)(()=>{const e=r.style;return e?{...e}:void 0}),s=(0,e.computed)(()=>({width:n.size+"px",height:n.size+"px",borderRadius:n.round?"50%":Math.round(.3*n.size)+"px"}));return(t,r)=>((0,e.openBlock)(),(0,e.createElementBlock)("button",(0,e.mergeProps)(i.value,{class:["flex items-center justify-center p-0 box-border select-none cursor-grab touch-none",n.transparent?"bg-transparent border border-transparent shadow-none":"border-surface bg-btn shadow-btn hover:bg-btn-hover hover:shadow-btn-hover"],style:[s.value,a.value],onMouseenter:r[0]||(r[0]=e=>o.value=!0),onMouseleave:r[1]||(r[1]=e=>o.value=!1)}),[(0,e.renderSlot)(t.$slots,"default")],16))}}),n=(0,e.defineComponent)({inheritAttrs:!1,__name:"Panel",props:{radius:{default:14},padding:{default:"14px 6px"},variant:{default:"glass"}},setup(t){const n=t,r=(0,e.useAttrs)(),o=(0,e.computed)(()=>{const{style:e,...t}=r;return t}),i=(0,e.computed)(()=>{const e=r.style;return e?{...e}:void 0}),a=(0,e.computed)(()=>({borderRadius:n.radius+"px",padding:n.padding,borderColor:"var(--sc-surface-border)"}));return(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",(0,e.mergeProps)(o.value,{class:"box-border bg-panel border rounded-xl shadow-panel text-primary backdrop-blur-[10px] backdrop-saturate-150",style:[a.value,i.value]}),[(0,e.renderSlot)(t.$slots,"default")],16))}}),r={class:"flex items-center gap-1 p-1 mb-3 rounded-xl bg-subtle-btn"},o=["onClick"],i={class:"text-xs"},a=(0,e.defineComponent)({__name:"Tabs",props:{items:{},modelValue:{}},emits:["update:modelValue"],setup(t,{emit:n}){const a=t,s=n,l=(0,e.ref)(""),c=(0,e.computed)(()=>a.modelValue||l.value||a.items[0]?.key||"");return(n,u)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",null,[(0,e.createElementVNode)("div",r,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(t.items,t=>((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:t.key,type:"button",class:(0,e.normalizeClass)(["flex-1 px-3 py-1.5 text-xs rounded-lg cursor-pointer whitespace-nowrap transition-colors",t.key===c.value?"bg-panel text-primary shadow-sm border-surface font-medium":"text-secondary hover:bg-white/10 hover:text-primary border border-transparent"]),onClick:e=>{return n=t.key,void(void 0!==a.modelValue?s("update:modelValue",n):l.value=n);var n}},(0,e.toDisplayString)(t.label),11,o))),128))]),(0,e.createElementVNode)("div",i,[(0,e.renderSlot)(n.$slots,c.value)])]))}}),s=(0,e.defineComponent)({__name:"CopyButton",props:{label:{default:"复制"}},emits:["copy"],setup(t,{emit:n}){const r=n,o=(0,e.ref)(!1);let i=null;function a(){r("copy"),o.value=!0,i&&clearTimeout(i),i=setTimeout(()=>{o.value=!1},1500)}return(n,r)=>((0,e.openBlock)(),(0,e.createElementBlock)("button",{type:"button",class:(0,e.normalizeClass)(["shrink-0 text-xs px-2.5 py-0.5 rounded-md cursor-pointer transition-colors duration-200",o.value?"bg-save-btn text-white border border-save-border":"bg-subtle-btn text-primary border-surface"]),onClick:a},(0,e.toDisplayString)(o.value?"✓ 已复制":t.label),3))}});const l=["data-toast-id"],c={class:"flex items-center gap-1.5 mb-1"},u=["src"],d={class:"flex items-center gap-1 ml-auto shrink-0"},p=["onClick"],f=["title","onClick"],h={class:"flex-1 min-w-0 text-sm leading-[1.5] break-words whitespace-pre-wrap"},g={key:0,class:"text-[11px] leading-snug text-secondary/80 mt-1 break-words whitespace-pre-wrap"},m=(0,e.defineComponent)({__name:"ToastHost",props:{toasts:{},align:{}},emits:["close","copy","clear-plugin"],setup(t,{emit:n}){const r=t,o=(0,e.computed)(()=>"bottom"===r.align),i=n,a=(0,e.computed)(()=>function(e,t,n=2,r=3){const o=e.filter(e=>"high"===e.severity).slice(0,n);return[...e.filter(e=>"high"!==e.severity).slice(0,r),...o]}(r.toasts,r.align));function m(e){if(!e.pluginId||"high"===e.severity)return 0;const t=r.toasts.filter(t=>t.pluginId===e.pluginId&&"high"!==t.severity).length;return t>=2?t:0}const v=(0,e.ref)(new Set);(0,e.watch)(a,(e,t)=>{const n=new Set(t.map(e=>e.id)),r=new Set(b),o=e.filter(e=>r.has(e.id)&&!n.has(e.id));o.length&&(v.value=new Set([...v.value,...o.map(e=>e.id)]),setTimeout(()=>{v.value=new Set([...v.value].filter(e=>!o.some(t=>t.id===e)))},400))});let b=[];(0,e.watch)(()=>r.toasts,e=>{b=e.map(e=>e.id)},{immediate:!0});let y=0;const w=(0,e.ref)(0);function x(e){return a.value[0]?.id===e.id&&Date.now(){if(e.length&&e[0].id!==t[0]?.id){const e=Date.now();w.value=e-y>=1e3?e+800:0,y=e}});const k={info:"var(--color-accent)",success:"var(--color-success)",warning:"var(--color-warning)",error:"var(--color-danger)"};const S=(0,e.computed)(()=>o.value?{position:"relative",width:"300px","--sc-toast-from-y":Math.max(0,(B.value||46)-23)+"px"}:{position:"relative",width:"300px",height:N.value+"px",transition:"height .2s ease"}),E=(0,e.ref)({});function C(e){let t=0;for(let n=0;n div[data-toast-id]:not(.toast-leave-active)")),n={};t.forEach(e=>{const t=Number(e.dataset.toastId);Number.isFinite(t)&&(n[t]=e.offsetHeight||0)}),E.value=n;const r=t[0];r&&(B.value=r.offsetHeight||0,z&&r!==D&&(D&&z.unobserve(D),z.observe(r),D=r)),N.value=function(){const e=a.value;if(!e.length)return 0;const t=e[e.length-1];return C(e.length-1)+(E.value[t.id]??46)}()}function V(e,t){const n=a.value.length,r=0===t,i=C(t),s={boxShadow:"var(--sc-shadow-toast)"};return o.value?{position:r?"relative":"absolute",left:"0",right:"0",top:"auto",bottom:i+"px",zIndex:n-t,...s}:{position:r?"relative":"absolute",left:r?"auto":"0",right:r?"auto":"0",top:r?"auto":"0",marginTop:i+"px",zIndex:n-t,...s}}function L(e){return{color:k[e]||k.info}}const T={scrollbarWidth:"thin",scrollbarColor:"rgba(255,255,255,0.2) transparent"},A=(0,e.ref)();let z=null,D=null;(0,e.onMounted)(()=>{const e=A.value?.$el?.getRootNode();if(e&&e!==document){const t=document.createElement("style");t.textContent="@keyframes sc-toast-in{0%{opacity:0;filter:blur(4px);transform:translate(52px,var(--sc-toast-from-y,0px)) scale(0.9)}60%{opacity:1;filter:blur(0);transform:translate(-6px,0) scale(1.02)}100%{opacity:1;filter:blur(0);transform:translate(0,0) scale(1)}}@keyframes sc-toast-out{from{opacity:1;filter:blur(0)}to{opacity:0;filter:blur(5px);transform:translateX(-14px)}}.toast-enter-active{animation:sc-toast-in .32s cubic-bezier(0.22,1,0.36,1)}.toast-leave-active{animation:sc-toast-out .22s ease;position:absolute!important}.no-enter.toast-enter-active{animation:none!important}@keyframes sc-busy-dot{0%,80%,100%{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}.sc-busy{display:inline-flex;align-items:center;gap:2px;height:10px}.sc-busy>i{width:3px;height:3px;border-radius:50%;background:currentColor;opacity:.25;animation:sc-busy-dot 1.1s ease-in-out infinite}.sc-busy>i:nth-child(2){animation-delay:.18s}.sc-busy>i:nth-child(3){animation-delay:.36s}.toast-body::-webkit-scrollbar{width:6px}.toast-body::-webkit-scrollbar-track{background:transparent}.toast-body::-webkit-scrollbar-thumb{background:rgba(255,255,255,0.15);border-radius:3px}",e.appendChild(t)}z=new ResizeObserver(()=>M()),M()});let I=null;return(0,e.watch)(()=>r.toasts,(e,t)=>{I&&clearTimeout(I),e.length((0,e.openBlock)(),(0,e.createBlock)(e.TransitionGroup,{ref_key:"hostRef",ref:A,tag:"div",class:"toast-host relative w-[300px]",name:"toast",style:(0,e.normalizeStyle)(S.value)},{default:(0,e.withCtx)(()=>[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(a.value,(r,o)=>{return(0,e.openBlock)(),(0,e.createElementBlock)("div",{key:r.id,"data-toast-id":r.id,class:(0,e.normalizeClass)(["w-[300px] min-h-[46px] box-border p-2 rounded-[10px] bg-panel border-surface backdrop-blur-[10px] backdrop-saturate-150 text-[13px] leading-[1.5] text-primary flex flex-col transition-[margin-top,bottom,box-shadow] duration-200",{"no-enter":v.value.has(r.id)}]),style:(0,e.normalizeStyle)(V(0,o))},[(0,e.createCommentVNode)(" 标题左 / 操作按钮组右(两端对齐) "),(0,e.createElementVNode)("div",c,[r.icon?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:r.icon,class:"w-4 h-4 object-contain rounded-sm shrink-0",alt:""},null,8,u)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("span",{class:"font-semibold text-xs shrink-0",style:(0,e.normalizeStyle)(L(r.type))},(0,e.toDisplayString)(r.title||(b=r.type,{info:"提示",success:"成功",warning:"警告",error:"错误"}[b]||"提示")),5),(0,e.createCommentVNode)(" 进行中标记:标题后的循环动画(三点跳动),任务结束时由插件用 busy:false 停掉 "),r.busy?((0,e.openBlock)(),(0,e.createElementBlock)("span",{key:1,class:"sc-busy shrink-0",style:(0,e.normalizeStyle)(L(r.type)),"aria-hidden":"true"},[...n[0]||(n[0]=[(0,e.createElementVNode)("i",null,null,-1),(0,e.createElementVNode)("i",null,null,-1),(0,e.createElementVNode)("i",null,null,-1)])],4)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("div",d,[m(r)?((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"text-[10px] px-1.5 py-0.5 rounded-md border border-danger/40 text-danger cursor-pointer transition-colors hover:text-danger hover:bg-danger/15",title:"清空该插件的通知(同一插件的普通通知一起清,进行中任务不会被清空)",onClick:e=>function(e){x(e)||e.pluginId&&i("clear-plugin",e.pluginId)}(r)}," 清空("+(0,e.toDisplayString)(m(r))+"条) ",9,p)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("button",{type:"button",class:"w-5 h-5 flex items-center justify-center rounded-md border-none bg-transparent text-sm cursor-pointer text-secondary leading-none transition-colors hover:text-primary hover:bg-white/15",title:a.value.length>1?"关闭这条":"关闭",onClick:e=>function(e){x(e)||i("close",e.id)}(r)}," × ",8,f)])]),(0,e.createElementVNode)("div",{class:"toast-body flex items-start gap-2 max-h-[160px] overflow-y-auto overflow-x-hidden",style:T},[(0,e.createElementVNode)("div",h,(0,e.toDisplayString)(r.text),1),r.copyable?((0,e.openBlock)(),(0,e.createBlock)(s,{key:0,onCopy:e=>t.$emit("copy",r)},null,8,["onCopy"])):(0,e.createCommentVNode)("v-if",!0)]),(0,e.createCommentVNode)(" 次要说明文字:正文下方的小号灰字(如「剩余 12:34 · 取消会直接结束任务」) "),r.note?((0,e.openBlock)(),(0,e.createElementBlock)("div",g,(0,e.toDisplayString)(r.note),1)):(0,e.createCommentVNode)("v-if",!0)],14,l);var b}),128))]),_:1},8,["style"]))}});class v{constructor(e,t,n){this.bus=e,this.load=t,this.save=n,this.records=new Map,this.reload()}reload(){this.records.clear();for(const e of this.load())this.records.set(e.manifest.id,e)}list(){return[...this.records.values()]}get(e){return this.records.get(e)}install(e){if(!String(e||"").trim())return{ok:!1,error:"插件内容为空"};if(!/\/\/\s*==Plugin==/.test(e))return{ok:!1,error:"缺少 ==Plugin== 头"};const t=function(e){const t=e.match(/\/\/\s*==Plugin==\s*([\s\S]*?)\/\/\s*==\/Plugin==/);if(!t)return null;const n=t[1],r=e=>{const t=n.match(new RegExp(`//\\s*@${e}\\s+(.+)`,"i"));return t?t[1].trim():void 0},o=r("id"),i=r("name");if(!o||!i)return null;const a="feature"===r("type")?"feature":"shortcut",s=(r("permissions")||r("permission")||"").split(",").map(e=>e.trim()).filter(e=>["selection","clipboard","storage","ui","menu","network","dom","broadcast"].includes(e)),l="true"===r("menuOnSelection");return{id:o,name:i,version:r("version")||"0.0.1",type:a,icon:r("icon"),permissions:s,description:r("description"),builtin:"true"===r("builtin"),...l?{menuOnSelection:!0}:{}}}(e);if(!t)return{ok:!1,error:"插件头格式错误(@id、@name 为必填字段)"};const n={manifest:t,code:e,installedAt:Date.now()};return this.records.set(t.id,n),this.persist(),this.bus.emit("plugin-installed",n),{ok:!0,record:n}}installBuiltin(e,t,n){const r={manifest:e,code:t,installedAt:Date.now()};return n&&(r.init=n),this.records.set(e.id,r),this.bus.emit("plugin-installed",r),r}uninstall(e){const t=this.records.delete(e);return t&&(this.persist(),this.bus.emit("plugin-uninstalled",e)),t}persist(){this.save(this.list())}}class b{constructor(){this.handlers=new Map}on(e,t){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t),()=>this.off(e,t)}off(e,t){this.handlers.get(e)?.delete(t)}emit(e,t){this.handlers.get(e)?.forEach(n=>{try{n(t)}catch(t){console.warn(`[plugin-core] event "${e}" handler error:`,t)}})}clear(){this.handlers.clear()}}class y{constructor(e){this.mode="soft",this.error=null,this.handlers=new Set,this.fn=null,this.code=e}run(e){try{const t=this.code.trim(),n=t.endsWith(";")?t.slice(0,-1).trim():t;this.fn=new Function("ctx","emit",`return (${n});`);const r=e=>this.dispatch(e);if(!this.fn)return;const o=this.fn(e,r);"function"==typeof o&&o(e,r)}catch(e){this.error=e instanceof Error?e.message:String(e),console.warn("[plugin-core] 插件主体执行失败:",e)}}send(e){this.dispatch(e)}onMessage(e){return this.handlers.add(e),()=>this.handlers.delete(e)}activate(){this.send({type:"activate"})}deactivate(){this.send({type:"deactivate"})}dispose(){this.send({type:"dispose"}),this.handlers.clear(),this.fn=null,this.code=""}dispatch(e){this.handlers.forEach(t=>{try{t(e)}catch(e){console.warn("[plugin-core] 插件消息处理错误:",e)}})}}class w{constructor(e,t,n){this.settings=[],this.initError=null,this.executor=null,this.onActivate=null,this.onDeactivate=null,this.disposeCbs=[],this.eventCbs=new Map,this.selectionCbs=[],this.manifest={...e.manifest},this.caps=t,this.uiHooks=n,this.mode="soft";const r=this.createCtx();if(e.init)try{e.init(r)}catch(e){this.initError=e instanceof Error?e.message:String(e),console.warn(`[plugin-core] 插件 ${this.manifest.id} 主体执行失败:`,e)}else{const t=new y(e.code);this.executor=t,t.run(r),t.error&&(this.initError=t.error)}}createCtx(){const e=this.manifest,t=t=>e.permissions.includes(t);return{manifest:{...e},getSelectedText:t("selection")?()=>this.caps.getSelectedText():void 0,getPageUrl:t("selection")?()=>this.caps.getPageUrl():void 0,readClipboard:t("clipboard")?()=>this.caps.readClipboard():void 0,copyText:t("clipboard")?e=>this.caps.copyText(e):void 0,getValue:t("storage")?(e,t)=>this.caps.getValue(e,t):void 0,setValue:t("storage")?(e,t)=>this.caps.setValue(e,t):void 0,getState:t("storage")?(e,t)=>this.caps.getState(e,t):void 0,setState:t("storage")?(e,t)=>this.caps.setState(e,t):void 0,openPanel:t("ui")?e=>this.caps.openPanel(e):void 0,closePanel:t("ui")?()=>this.caps.closePanel():void 0,openMenu:t("menu")?()=>this.caps.openMenu():void 0,closeMenu:t("menu")?()=>this.caps.closeMenu():void 0,toast:(e,n)=>{const r=n?.title?this.manifest.name+" "+n.title:this.manifest.name,o={...n,title:r,icon:this.manifest.icon};return o.broadcast&&!t("broadcast")&&delete o.broadcast,!o.severity||t("severity")&&this.manifest.builtin||delete o.severity,this.caps.toast(e,o)},dismissToast:e=>this.caps.dismissToast(e),updateToast:(e,t)=>this.caps.updateToast(e,t),httpRequest:t("network")?(e,t)=>this.caps.httpRequest(e,t):void 0,ui:{render:(t,n)=>{try{this.uiHooks.render(t,n)}catch(t){console.warn(`[plugin-core] 插件 ${e.id} UI 渲染失败:`,t)}},close:()=>this.uiHooks.close()},onActivate:e=>{this.onActivate=e},onDeactivate:e=>{this.onDeactivate=e},onEvent:(e,t)=>{this.eventCbs.set(e,t)},onSelectionChange:e=>{this.selectionCbs.push(e)},onDispose:e=>{this.disposeCbs.push(e)},declareSettings:e=>{this.settings=Array.isArray(e)?e:[]}}}activate(...e){if(this.onActivate)try{this.onActivate(...e)}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} activate 失败:`,e)}}deactivate(){if(this.onDeactivate)try{this.onDeactivate()}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} deactivate 失败:`,e)}}emitEvent(e,t){const n=this.eventCbs.get(e);if(n)try{n(t)}catch(t){console.warn(`[plugin-core] 插件 ${this.manifest.id} 事件 ${e} 处理失败:`,t)}}emitSelectionChange(e){this.selectionCbs.forEach(t=>{try{t(e)}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} selection 回调失败:`,e)}})}dispose(){this.disposeCbs.forEach(e=>{try{e()}catch(e){console.warn(`[plugin-core] 插件 ${this.manifest.id} dispose 回调失败:`,e)}}),this.disposeCbs=[],this.eventCbs.clear(),this.selectionCbs=[],this.executor?.dispose()}}const x="plugins",k="menuBindings",S="disabledPlugins",E="toastList";function C(e){if(!e||"object"!=typeof e)return null;const t=e;return"number"!=typeof t.id||"string"!=typeof t.text?null:{id:t.id,text:t.text,opts:t.opts&&"object"==typeof t.opts?t.opts:{},at:"number"==typeof t.at?t.at:Date.now()}}function B(e,t){const n=e.opts.timeout??2500;return 0===n?0:Math.max(0,n-(t-e.at))}class N{constructor(e,t=[]){this.runtimes=new Map,this.bindings=[],this.disabledIds=[],this.listeners=new Map,this.errors=[],this.MAX_PLUGIN_ERRORS=3,this.storageUnwatchers=[],this.knownBroadcasts=new Set,this.broadcastSeq=0,this.broadcastUnwatch=null,this.legacyCbs=new Map,this.deps=e,this.registry=new v(new b,()=>this.loadRecords(),e=>this.saveRecords(e)),this.bindings=this.loadBindings(),this.disabledIds=this.loadDisabled();for(const e of t){const t=this.registry.get(e.manifest.id);t&&!t.manifest.builtin&&this.registry.uninstall(e.manifest.id),this.registry.installBuiltin({...e.manifest,builtin:!0},e.code||"",e.init)}this.startStorageSync(),this.startBroadcastSync()}on(e,t){let n=this.listeners.get(e);return n||(n=new Set,this.listeners.set(e,n)),n.add(t),()=>{n?.delete(t)}}emit(e,...t){const n=this.listeners.get(e);if(n)for(const r of n)try{r(...t)}catch(t){console.warn(`[plugin] 事件 "${e}" 订阅者抛错:`,t)}}notifyChanged(){this.emit("changed")}get storage(){return this.deps.storage}loadRecords(){const e=this.storage.get(x,[]);return Array.isArray(e)?e:[]}saveRecords(e){try{this.storage.set(x,e)}catch(e){this.deps.log?.("保存插件记录失败:",e)}}loadBindings(){const e=this.storage.get(k,[]);return Array.isArray(e)?e.map(String):[]}loadDisabled(){const e=this.storage.get(S,[]);return Array.isArray(e)?e.map(String):[]}saveDisabled(){this.storage.set(S,this.disabledIds)}saveBindings(){this.storage.set(k,this.bindings)}startStorageSync(){for(const e of[x,k,S])try{const t=this.storage.watch(e,()=>{this.syncFromStorage(e)});this.storageUnwatchers.push(t)}catch{}}syncFromStorage(e){if(e===x)this.registry.reload(),this.preheatFeatures();else if(e===k)this.bindings=this.loadBindings();else if(e===S){this.disabledIds=this.loadDisabled();for(const[e,t]of this.runtimes)this.isEnabled(e)||(t.dispose(),this.runtimes.delete(e))}this.notifyChanged()}disposeStorageSync(){for(const e of this.storageUnwatchers)try{e()}catch{}this.storageUnwatchers=[]}readBroadcastList(){const e=this.storage.get(E,[]);if(!Array.isArray(e))return[];const t=Date.now();return e.map(C).filter(e=>null!==e&&!function(e,t){const n=e.opts.timeout??2500;return 0!==n&&t-e.at>=n}(e,t))}writeBroadcastList(e){try{this.storage.set(E,e)}catch{}}alignBroadcasts(e){const t=new Set(e.map(e=>e.id)),n=Date.now();for(const t of e)this.knownBroadcasts.has(t.id)||(this.knownBroadcasts.add(t.id),this.emit("toast",t.text,{...t.opts,timeout:B(t,n),broadcastId:t.id}));for(const e of Array.from(this.knownBroadcasts))t.has(e)||(this.knownBroadcasts.delete(e),this.emit("toastDismissed",e))}startBroadcastSync(){try{const e=this.storage.watch(E,()=>{this.alignBroadcasts(this.readBroadcastList())});this.broadcastUnwatch=()=>{try{e()}catch{}}}catch{this.broadcastUnwatch=null}}syncBroadcasts(){this.alignBroadcasts(this.readBroadcastList())}dismissBroadcast(e){const t=this.readBroadcastList();t.some(t=>t.id===e)&&this.writeBroadcastList(t.filter(t=>t.id!==e))}clearBroadcasts(e){const t=this.readBroadcastList(),n=t.filter(t=>!(t=>"high"!==t.opts.severity&&(void 0===e||t.opts.pluginId===e))(t));n.length!==t.length&&this.writeBroadcastList(n)}install(e){const t=this.registry.install(e);if(t.ok&&t.record){const e=t.record.manifest.id,n=this.runtimes.get(e);return n&&(n.dispose(),this.runtimes.delete(e)),this.errors=this.errors.filter(t=>t.id!==e),this.notifyChanged(),{ok:!0,id:e,type:t.record.manifest.type}}return{ok:!1,error:t.error}}uninstall(e){const t=this.registry.get(e);if(t?.manifest.builtin)return!1;this.runtimes.get(e)?.dispose(),this.runtimes.delete(e);try{this.storage.set("plugin:"+e+".settings","")}catch{}const n=this.registry.uninstall(e);this.emit("pluginUninstalled",e);let r=!1;for(let t=0;t'+t+"")}(t.manifest.name):""}getBindingName(e){const t=this.bindings[e];return t?this.getPluginName(t):""}getPluginName(e){return this.registry.get(e)?.manifest.name||e}getSelectionMenuPlugins(){return this.list().filter(e=>"shortcut"===e.manifest.type&&!0===e.manifest.menuOnSelection&&this.isEnabled(e.manifest.id)).map(e=>e.manifest.id)}activateSlot(e){const t=this.bindings[e];t&&this.activate(t)}activate(e){this.isEnabled(e)&&this.getRuntime(e)?.activate()}collectError(e,t){const n=this.errors.find(n=>n.id===e&&n.message===t);n?n.count++:(this.errors.push({id:e,message:t,count:1}),this.errors.length>this.MAX_PLUGIN_ERRORS&&this.errors.shift())}getPluginErrors(){return this.errors.map(e=>({id:e.id,name:this.registry.get(e.id)?.manifest.name||e.id,message:e.message,count:e.count}))}clearPluginError(e){this.errors=this.errors.filter(t=>t.id!==e)}getSettings(e){const t=this.getRuntime(e);return t?.settings||[]}getPluginSetting(e,t){const n=this.storage.get("plugin:"+e+".settings",{});if(n&&"object"==typeof n)return t in n?n[t]:void 0}setPluginSetting(e,t,n){const r=this.storage.get("plugin:"+e+".settings",{}),o=r&&"object"==typeof r?r:{};o[t]=n,this.storage.set("plugin:"+e+".settings",o)}preheatFeatures(){this.registry.list().forEach(e=>{"feature"===e.manifest.type&&this.isEnabled(e.manifest.id)&&this.getRuntime(e.manifest.id)})}isEnabled(e){return!this.disabledIds.includes(e)}setEnabled(e,t){t?this.disabledIds=this.disabledIds.filter(t=>t!==e):this.disabledIds.includes(e)||(this.disabledIds.push(e),this.runtimes.get(e)?.dispose(),this.runtimes.delete(e)),this.saveDisabled(),this.notifyChanged()}getRuntime(e){const t=this.runtimes.get(e);if(t)return t;const n=this.registry.get(e);if(!n)return;const r=new w(n,this.createCaps(e),this.createUiHooks(e));return this.runtimes.set(e,r),r.initError&&this.collectError(e,r.initError),r}handleSelectionChange(e){this.registry.list().forEach(t=>{"shortcut"===t.manifest.type&&t.manifest.permissions.includes("selection")&&this.isEnabled(t.manifest.id)&&this.getRuntime(t.manifest.id)?.emitSelectionChange(e)})}createCaps(e){const{storage:t,http:n,clipboard:r,getSelectedText:o,getPageUrl:i}=this.deps;return{getSelectedText:async()=>o?.()??"",getPageUrl:()=>i?.()??"",readClipboard:async()=>{if(!r)return"";try{return await r.read()}catch{return""}},copyText:async e=>{if(r)try{await r.write(e)}catch{}},getValue:(n,r)=>{const o=t.get("plugin:"+e+".settings",{});return o&&"object"==typeof o&&n in o?o[n]:r},setValue:(n,r)=>{const o=t.get("plugin:"+e+".settings",{}),i=o&&"object"==typeof o?o:{};i[n]=r,t.set("plugin:"+e+".settings",i)},getState:(n,r)=>t.get("plugin:"+e+".state."+n,r),setState:(n,r)=>{t.set("plugin:"+e+".state."+n,r)},openPanel:async t=>(this.emit("panelRender",{kind:"panel",spec:{type:"panel",title:this.panelTitle(e),body:t.body??[]},pluginId:e}),{ok:!0}),closePanel:async()=>{this.emit("panelRender",{kind:"close",spec:null,pluginId:e})},openMenu:()=>{const t=this.listeners.get("menuRequest");if(!t||0===t.size)return{ok:!1};let n={ok:!1},r=!0;for(const o of t){const t=r;r=!1;try{if(t){const t=o(e);n=t&&"object"==typeof t?t:{ok:!1}}else o(e)}catch{}}return n},closeMenu:()=>this.emit("menuCloseRequest"),toast:(t,n)=>{let r={...n,pluginId:e};if(n?.broadcast){const e=1e3*Date.now()+this.broadcastSeq++%1e3;this.knownBroadcasts.add(e);const{broadcast:n,...o}=r,i=this.readBroadcastList();for(i.push({id:e,text:t,opts:o,at:Date.now()});i.length>30;)i.shift();this.writeBroadcastList(i),r={...o,broadcastId:e}}const o=this.listeners.get("toast");if(!o||0===o.size)return 0;let i=0,a=!0;for(const e of o)try{a?(i=e(t,r)??0,a=!1):e(t,r)}catch{}return i},dismissToast:e=>this.emit("dismissToast",e),updateToast:(e,t)=>{const n=this.listeners.get("toastUpdate");if(!n||0===n.size)return!1;let r=!1;for(const o of n)try{!0===o(e,t)&&(r=!0)}catch{}return r},httpRequest:(e,t)=>n?n.request(e,t):Promise.resolve({ok:!1,status:0,text:""})}}createUiHooks(e){return{render:(t,n)=>{const r="panel"===t&&n&&"panel"===n.type?{...n,title:this.panelTitle(e)}:n;this.emit("panelRender",{kind:t,spec:r,pluginId:e})},close:()=>{this.emit("panelRender",{kind:"close",spec:null,pluginId:e})}}}panelTitle(e){return this.getPluginName(e)}disposeAll(){if(this.runtimes.forEach(e=>e.dispose()),this.runtimes.clear(),this.disposeStorageSync(),this.broadcastUnwatch){try{this.broadcastUnwatch()}catch{}this.broadcastUnwatch=null}}registerLegacy(e,t){this.legacyCbs.get(e)&&this.offLegacy(e),this.legacyCbs.set(e,t),this.on(e,t)}offLegacy(e){const t=this.legacyCbs.get(e);if(!t)return;const n=this.listeners.get(e);n?.delete(t),this.legacyCbs.delete(e)}onPanelRender(e){this.registerLegacy("panelRender",e)}onMenuRequest(e){this.registerLegacy("menuRequest",e)}onPluginUninstalled(e){this.registerLegacy("pluginUninstalled",e)}onToast(e){this.registerLegacy("toast",e)}onDismissToast(e){this.registerLegacy("dismissToast",e)}onToastUpdate(e){this.registerLegacy("toastUpdate",e)}onToastDismissed(e){this.registerLegacy("toastDismissed",e)}onChanged(e){this.on("changed",e)}}function M(e){const t={fontSize:"13px",lineHeight:"1.5"};return"bold"===e?.weight&&(t.fontWeight="600"),"sm"===e?.size&&(t.fontSize="12px"),"lg"===e?.size&&(t.fontSize="15px"),"secondary"===e?.color&&(t.color="var(--color-secondary)"),"accent"===e?.color&&(t.color="var(--color-accent)"),"danger"===e?.color&&(t.color="var(--color-danger)"),t}function V(t,n){return t.map((t,r)=>(0,e.h)("div",{style:r?{marginTop:"6px"}:void 0},[z(t,n)]))}const L="w-full min-w-0 box-border px-2 py-1 text-xs border-surface rounded-lg bg-input text-primary font-[inherit] select-text transition-shadow sc-field",T="px-3 py-1.5 text-xs border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer font-[inherit] transition-colors hover:bg-white/15 active:scale-[0.97]",A="px-3 py-1.5 text-xs border border-save-border rounded-lg bg-save-btn text-white font-medium cursor-pointer font-[inherit] shadow-sm transition hover:opacity-90 active:scale-[0.97]";function z(t,r){switch(t.type){case"panel":return(0,e.h)(n,{variant:"glass",style:{width:"100%",padding:"12px"}},()=>(t.body||[]).map(e=>z(e,r)));case"text":return(0,e.h)("span",{style:M(t.style)},t.content);case"button":{const n=("primary"===t.variant?A:T)+(t.full?" w-full":"");return(0,e.h)("button",{type:"button",class:n,onClick:()=>r(t.event||"")},t.label)}case"list":return(0,e.h)("div",{class:"flex flex-col gap-1"},(t.items||[]).map(e=>z(e,r)));case"row":return(0,e.h)("div",{class:"flex items-center gap-1.5"},(t.items||[]).map(e=>z(e,r)));case"fieldset":return(0,e.h)("fieldset",{class:"border-surface rounded-xl p-3 min-w-0 bg-subtle-btn"},[t.legend?(0,e.h)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"},t.legend):null,...V(t.body||[],r)]);case"divider":return(0,e.h)("hr",{class:"border-0 border-t border-seam my-2"});case"badge":return(0,e.h)("span",{class:"inline-block px-2 py-0.5 text-[11px] rounded-[10px] bg-subtle-btn text-secondary"},t.text);case"image":return(0,e.h)("img",{src:t.src,class:"max-w-full rounded-md block",style:t.width?{width:t.width,height:"auto"}:void 0});case"link":return(0,e.h)("a",{href:t.href,target:"_blank",rel:"noopener noreferrer",class:"text-accent no-underline"},t.label);case"icon":return(0,e.h)("span",{class:"text-base"},t.name);case"input":return(0,e.h)("input",{value:t.value||"",placeholder:t.placeholder||"",onInput:e=>r(t.event||"",e.target.value),onKeydown:t.submitEvent?e=>{"Enter"===e.key&&(e.preventDefault(),r(t.submitEvent,e.target.value))}:void 0,class:L});case"textarea":return(0,e.h)("textarea",{value:t.value||"",placeholder:t.placeholder||"",onInput:e=>r(t.event||"",e.target.value),onKeydown:t.submitEvent?e=>{"Enter"!==e.key||e.shiftKey||(e.preventDefault(),r(t.submitEvent,e.target.value))}:void 0,class:`${L} min-h-[96px] resize-y`});case"checkbox":return(0,e.h)("label",{class:"flex items-center gap-1.5 text-[13px]"},[(0,e.h)("input",{type:"checkbox",checked:!!t.checked,onChange:e=>r(t.event||"",e.target.checked)}),(0,e.h)("span",t.label)]);case"select":return(0,e.h)("select",{value:t.value??"",onChange:e=>r(t.event||"",e.target.value),class:L},(t.options||[]).map(t=>(0,e.h)("option",{value:t.value},t.label)));case"tabs":return(0,e.h)("div",{},[(0,e.h)("div",{class:"flex flex-wrap gap-1 mb-1.5"},(t.tabs||[]).map((t,n)=>(0,e.h)("button",{onClick:()=>r("tab",n),class:"px-2.5 py-0.5 text-xs rounded-md border-surface bg-subtle-btn text-primary cursor-pointer"},()=>t.label))),...V(t.tabs&&t.tabs[0]?t.tabs[0].body:[],r)]);case"component":return(0,e.h)("div",{class:"text-danger text-xs"},`组件 ${t.name} 未支持`);default:return(0,e.h)("span",{},"")}}function D(e,t){const n=(65535&e)+(65535&t);return(e>>16)+(t>>16)+(n>>16)<<16|65535&n}function I(e,t,n,r,o,i){return D((a=D(D(t,e),D(r,i)))<<(s=o)|a>>>32-s,n);var a,s}function _(e,t,n,r,o,i,a){return I(t&n|~t&r,e,t,o,i,a)}function $(e,t,n,r,o,i,a){return I(t&r|n&~r,e,t,o,i,a)}function R(e,t,n,r,o,i,a){return I(t^n^r,e,t,o,i,a)}function P(e,t,n,r,o,i,a){return I(n^(t|~r),e,t,o,i,a)}function U(e,t){let[n,r,o,i]=e;n=_(n,r,o,i,t[0],7,-680876936),i=_(i,n,r,o,t[1],12,-389564586),o=_(o,i,n,r,t[2],17,606105819),r=_(r,o,i,n,t[3],22,-1044525330),n=_(n,r,o,i,t[4],7,-176418897),i=_(i,n,r,o,t[5],12,1200080426),o=_(o,i,n,r,t[6],17,-1473231341),r=_(r,o,i,n,t[7],22,-45705983),n=_(n,r,o,i,t[8],7,1770035416),i=_(i,n,r,o,t[9],12,-1958414417),o=_(o,i,n,r,t[10],17,-42063),r=_(r,o,i,n,t[11],22,-1990404162),n=_(n,r,o,i,t[12],7,1804603682),i=_(i,n,r,o,t[13],12,-40341101),o=_(o,i,n,r,t[14],17,-1502002290),r=_(r,o,i,n,t[15],22,1236535329),n=$(n,r,o,i,t[1],5,-165796510),i=$(i,n,r,o,t[6],9,-1069501632),o=$(o,i,n,r,t[11],14,643717713),r=$(r,o,i,n,t[0],20,-373897302),n=$(n,r,o,i,t[5],5,-701558691),i=$(i,n,r,o,t[10],9,38016083),o=$(o,i,n,r,t[15],14,-660478335),r=$(r,o,i,n,t[4],20,-405537848),n=$(n,r,o,i,t[9],5,568446438),i=$(i,n,r,o,t[14],9,-1019803690),o=$(o,i,n,r,t[3],14,-187363961),r=$(r,o,i,n,t[8],20,1163531501),n=$(n,r,o,i,t[13],5,-1444681467),i=$(i,n,r,o,t[2],9,-51403784),o=$(o,i,n,r,t[7],14,1735328473),r=$(r,o,i,n,t[12],20,-1926607734),n=R(n,r,o,i,t[5],4,-378558),i=R(i,n,r,o,t[8],11,-2022574463),o=R(o,i,n,r,t[11],16,1839030562),r=R(r,o,i,n,t[14],23,-35309556),n=R(n,r,o,i,t[1],4,-1530992060),i=R(i,n,r,o,t[4],11,1272893353),o=R(o,i,n,r,t[7],16,-155497632),r=R(r,o,i,n,t[10],23,-1094730640),n=R(n,r,o,i,t[13],4,681279174),i=R(i,n,r,o,t[0],11,-358537222),o=R(o,i,n,r,t[3],16,-722521979),r=R(r,o,i,n,t[6],23,76029189),n=R(n,r,o,i,t[9],4,-640364487),i=R(i,n,r,o,t[12],11,-421815835),o=R(o,i,n,r,t[15],16,530742520),r=R(r,o,i,n,t[2],23,-995338651),n=P(n,r,o,i,t[0],6,-198630844),i=P(i,n,r,o,t[7],10,1126891415),o=P(o,i,n,r,t[14],15,-1416354905),r=P(r,o,i,n,t[5],21,-57434055),n=P(n,r,o,i,t[12],6,1700485571),i=P(i,n,r,o,t[3],10,-1894986606),o=P(o,i,n,r,t[10],15,-1051523),r=P(r,o,i,n,t[1],21,-2054922799),n=P(n,r,o,i,t[8],6,1873313359),i=P(i,n,r,o,t[15],10,-30611744),o=P(o,i,n,r,t[6],15,-1560198380),r=P(r,o,i,n,t[13],21,1309151649),n=P(n,r,o,i,t[4],6,-145523070),i=P(i,n,r,o,t[11],10,-1120210379),o=P(o,i,n,r,t[2],15,718787259),r=P(r,o,i,n,t[9],21,-343485551),e[0]=D(n,e[0]),e[1]=D(r,e[1]),e[2]=D(o,e[2]),e[3]=D(i,e[3])}function q(e){const t=[];for(let n=0;n<64;n+=4)t[n>>2]=e.charCodeAt(n)+(e.charCodeAt(n+1)<<8)+(e.charCodeAt(n+2)<<16)+(e.charCodeAt(n+3)<<24);return t}const j="0123456789abcdef".split("");function G(e){let t="";for(let n=0;n<4;n++)t+=j[e>>8*n+4&15]+j[e>>8*n&15];return t}const O=function(e){return function(e){const t=e.length,n=[1732584193,-271733879,-1732584194,271733878];let r;for(r=64;r<=t;r+=64)U(n,q(e.substring(r-64,r)));e=e.substring(r-64);const o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;r>2]|=e.charCodeAt(r)<<(r%4<<3);if(o[r>>2]|=128<<(r%4<<3),r>55)for(U(n,o),r=0;r<16;r++)o[r]=0;return o[14]=8*t,U(n,o),n}(function(e){const t=encodeURIComponent(e),n=[];for(let e=0;e=0?e.slice(0,r).trim():"";const i=(r>=0?e.slice(r+1):e).trim();if(i){if(!o)try{o=new URL(i).hostname.replace(/^www\./,"")}catch{o=i.slice(0,20)}o&&t.push({name:o,value:i})}}return t}const W={w:900,h:700};const X=[{name:"gh-proxy.com",url:"https://gh-proxy.com"},{name:"gh-proxy.org",url:"https://gh-proxy.org"},{name:"ghproxy.com",url:"https://mirror.ghproxy.com"}],K=["⚡ 闪电五连鞭模式启动!{n} 个下载链接已加速~","🚀 引擎点火,{n} 个链接原地起飞~","🔥 火力全开!{n} 个下载链接全部加速~","🛸 虫洞已开启,{n} 个链接光速抵达~","🥋 一鞭三连!{n} 个下载链接已乖乖加速~","⚡ 闪电五连鞭模式启动!下载链接已加速~","🚀 引擎点火,这条链接起飞了~","🔥 火力全开!下载链接已加速~","🛸 虫洞已开启,下载链接光速抵达~","🥋 一鞭定音!下载链接已加速~"].join("\n");function Z(e,t){const n=e.filter(e=>e.includes("{n}")),r=e.filter(e=>!e.includes("{n}")),o=t>1?n:r;return function(e){return e[Math.floor(Math.random()*e.length)]}(o.length?o:e).split("{n}").join(String(t))}const Q=6e4,ee=180,te=[{max:6e5,emoji:"😅"},{max:36e5,emoji:"😬"},{max:1/0,emoji:"😔"}],ne="atCountdown:",re="📌 手动关闭会导致当前任务直接结束且不再通知",oe="📌 手动关闭会删除这条倒计时(任务已结束)",ie={一:1,二:2,三:3,四:4,五:5,六:6,日:0,天:0},ae={秒:1e3,秒钟:1e3,s:1e3,sec:1e3,分:6e4,分钟:6e4,m:6e4,min:6e4,小时:36e5,h:36e5};function se(e,t){return e>=0&&e<=23&&t>=0&&t<=59}function le(e){return(e<10?"0":"")+e}function ce(e){return String(e||"").replace(/\\n/g,"\n").split(/\n+/).map(e=>e.trim()).filter(Boolean)}var ue=function(){var e=function(e,t){var n=e,r=u[t],o=null,i=0,a=null,s=[],l={},c=function(e,t){o=function(e){for(var t=new Array(e),n=0;n=7&&h(e),null==a&&(a=v(n,r,s)),m(a,t)},d=function(e,t){for(var n=-1;n<=7;n+=1)if(!(e+n<=-1||i<=e+n))for(var r=-1;r<=7;r+=1)t+r<=-1||i<=t+r||(o[e+n][t+r]=0<=n&&n<=6&&(0==r||6==r)||0<=r&&r<=6&&(0==n||6==n)||2<=n&&n<=4&&2<=r&&r<=4)},p=function(){for(var e=8;e>r&1);o[Math.floor(r/3)][r%3+i-8-3]=a}for(r=0;r<18;r+=1){a=!e&&1==(t>>r&1);o[r%3+i-8-3][Math.floor(r/3)]=a}},g=function(e,t){for(var n=r<<3|t,a=y.getBCHTypeInfo(n),s=0;s<15;s+=1){var l=!e&&1==(a>>s&1);s<6?o[s][8]=l:s<8?o[s+1][8]=l:o[i-15+s][8]=l}for(s=0;s<15;s+=1){l=!e&&1==(a>>s&1);s<8?o[8][i-s-1]=l:s<9?o[8][15-s-1+1]=l:o[8][15-s-1]=l}o[i-8][8]=!e},m=function(e,t){for(var n=-1,r=i-1,a=7,s=0,l=y.getMaskFunction(t),c=i-1;c>0;c-=2)for(6==c&&(c-=1);;){for(var u=0;u<2;u+=1)if(null==o[r][c-u]){var d=!1;s>>a&1)),l(r,c-u)&&(d=!d),o[r][c-u]=d,-1==(a-=1)&&(s+=1,a=7)}if((r+=n)<0||i<=r){r-=n,n=-n;break}}},v=function(e,t,n){for(var r=k.getRSBlocks(e,t),o=S(),i=0;i8*s)throw"code length overflow. ("+o.getLengthInBits()+">"+8*s+")";for(o.getLengthInBits()+4<=8*s&&o.put(0,4);o.getLengthInBits()%8!=0;)o.putBit(!1);for(;!(o.getLengthInBits()>=8*s||(o.put(236,8),o.getLengthInBits()>=8*s));)o.put(17,8);return function(e,t){for(var n=0,r=0,o=0,i=new Array(t.length),a=new Array(t.length),s=0;s=0?p.getAt(f):0}}var h=0;for(u=0;ur)&&(e=r,t=n)}return t}())},l.createTableTag=function(e,t){e=e||2;var n="";n+='',n+="";for(var r=0;r";for(var o=0;o';n+=""}return n+="",n+="
"},l.createSvgTag=function(e,t,n,r){var o={};"object"==typeof arguments[0]&&(e=(o=arguments[0]).cellSize,t=o.margin,n=o.alt,r=o.title),e=e||2,t=void 0===t?4*e:t,(n="string"==typeof n?{text:n}:n||{}).text=n.text||null,n.id=n.text?n.id||"qrcode-description":null,(r="string"==typeof r?{text:r}:r||{}).text=r.text||null,r.id=r.text?r.id||"qrcode-title":null;var i,a,s,c,u=l.getModuleCount()*e+2*t,d="";for(c="l"+e+",0 0,"+e+" -"+e+",0 0,-"+e+"z ",d+=''+b(r.text)+"":"",d+=n.text?''+b(n.text)+"":"",d+='',d+='":t+=">";break;case"&":t+="&";break;case'"':t+=""";break;default:t+=r}}return t};return l.createASCII=function(e,t){if((e=e||1)<2)return function(e){e=void 0===e?2:e;var t,n,r,o,i,a=1*l.getModuleCount()+2*e,s=e,c=a-e,u={"██":"█","█ ":"▀"," █":"▄"," ":" "},d={"██":"▀","█ ":"▀"," █":" "," ":" "},p="";for(t=0;t=c?d[i]:u[i];p+="\n"}return a%2&&e>0?p.substring(0,p.length-a-1)+Array(a+1).join("▀"):p.substring(0,p.length-1)}(t);e-=1,t=void 0===t?2*e:t;var n,r,o,i,a=l.getModuleCount()*e+2*t,s=t,c=a-t,u=Array(e+1).join("██"),d=Array(e+1).join(" "),p="",f="";for(n=0;n>>8),t.push(255&a)):t.push(r)}}return t}};var t,n,r,o,i,a=1,s=2,l=4,c=8,u={L:1,M:0,Q:3,H:2},d=0,p=1,f=2,h=3,g=4,m=5,v=6,b=7,y=(t=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],n=1335,r=7973,i=function(e){for(var t=0;0!=e;)t+=1,e>>>=1;return t},(o={}).getBCHTypeInfo=function(e){for(var t=e<<10;i(t)-i(n)>=0;)t^=n<=0;)t^=r<5&&(n+=3+i-5)}for(r=0;r=256;)t-=255;return e[t]}};return r}();function x(e,t){if(void 0===e.length)throw e.length+"/"+t;var n=function(){for(var n=0;n>>7-t%8&1)},put:function(e,t){for(var r=0;r>>t-r-1&1))},getLengthInBits:function(){return t},putBit:function(n){var r=Math.floor(t/8);e.length<=r&&e.push(0),n&&(e[r]|=128>>>t%8),t+=1}};return n},E=function(e){var t=a,n=e,r={getMode:function(){return t},getLength:function(e){return n.length},write:function(e){for(var t=n,r=0;r+2>>8&255)+(255&r),e.put(r,13),n+=2}if(n>>8)},writeBytes:function(e,n,r){n=n||0,r=r||e.length;for(var o=0;o0&&(t+=","),t+=e[n];return t+="]"}};return t},V=function(e){var t=e,n=0,r=0,o=0,i={read:function(){for(;o<8;){if(n>=t.length){if(0==o)return-1;throw"unexpected end of file./"+o}var e=t.charAt(n);if(n+=1,"="==e)return o=0,-1;e.match(/^\s$/)||(r=r<<6|a(e.charCodeAt(0)),o+=6)}var i=r>>>o-8&255;return o-=8,i}},a=function(e){if(65<=e&&e<=90)return e-65;if(97<=e&&e<=122)return e-97+26;if(48<=e&&e<=57)return e-48+52;if(43==e)return 62;if(47==e)return 63;throw"c:"+e};return i},L=function(e,t,n){for(var r=function(e,t){var n=e,r=t,o=new Array(e*t),i={setPixel:function(e,t,r){o[t*n+e]=r},write:function(e){e.writeString("GIF87a"),e.writeShort(n),e.writeShort(r),e.writeByte(128),e.writeByte(0),e.writeByte(0),e.writeByte(0),e.writeByte(0),e.writeByte(0),e.writeByte(255),e.writeByte(255),e.writeByte(255),e.writeString(","),e.writeShort(0),e.writeShort(0),e.writeShort(n),e.writeShort(r),e.writeByte(0);var t=a(2);e.writeByte(2);for(var o=0;t.length-o>255;)e.writeByte(255),e.writeBytes(t,o,255),o+=255;e.writeByte(t.length-o),e.writeBytes(t,o,t.length-o),e.writeByte(0),e.writeString(";")}},a=function(e){for(var t=1<>>t!=0)throw"length over";for(;c+t>=8;)l.writeByte(255&(e<>>=8-c,u=0,c=0;u|=e<0&&l.writeByte(u)}});p.write(t,r);var f=0,h=String.fromCharCode(o[f]);for(f+=1;f=6;)i(e>>>t-6),t-=6},o.flush=function(){if(t>0&&(i(e<<6-t),e=0,t=0),n%3!=0)for(var o=3-n%3,a=0;a>6,128|63&r):r<55296||r>=57344?t.push(224|r>>12,128|r>>6&63,128|63&r):(n++,r=65536+((1023&r)<<10|1023&e.charCodeAt(n)),t.push(240|r>>18,128|r>>12&63,128|r>>6&63,128|63&r))}return t}(e)};const de=ue;function pe(e,t){try{if("undefined"==typeof document)return null;const n=e.getModuleCount(),r=2*t,o=n*t+2*r,i=document.createElement("canvas");i.width=o,i.height=o;const a=i.getContext("2d");if(!a)return null;a.fillStyle="#ffffff",a.fillRect(0,0,o,o),a.fillStyle="#000000";for(let o=0;o32)&&(!/^[a-f0-9]{8,}$/i.test(e)&&!/\d{6,}/.test(e))}function Ne(e){const t=e?.parentElement;if(!t||!t.children)return 1;const n=String(e.tagName||"");let r=0;for(let o=0;o{e&&-1===n.indexOf(e)&&n.push(e)},o=ke(e),i=t?.body||e.parentElement,a=Se(e,"id");a&&Be(a)&&r("#"+xe(a));for(const t of ge){const n=Se(e,t);n&&r(`${o}[${t}="${xe(n)}"]`)}const s=Se(e,"type");!s||"input"!==o&&"button"!==o||r(`${o}[type="${xe(s)}"]`);const l=Se(e,"class");(function(e){if(!e)return!1;const t=e.split(/\s+/).filter(Boolean);return!(!t.length||t.length>2)&&t.every(e=>e.length<=40&&!/[a-f0-9]{8,}/i.test(e)&&!/[-_]{2,}/.test(e))})(l)&&r(o+l.split(/\s+/).filter(Boolean).map(e=>"."+e).join(""));const c=ye(e.textContent);if(c&&/[0-9A-Za-z一-龥]/.test(c)&&(Me(e)||c.length<=24))for(const e of function(e){const t=[],n=e=>{const n=e.trim();n.length>=2&&-1===t.indexOf(n)&&t.push(n)};if(!e)return t;n(e.slice(0,40));const r=e.match(ze);r&&"number"==typeof r.index&&(n(e.slice(0,r.index)),n(e.slice(r.index+r[0].length,r.index+r[0].length+40)));e.length>20&&n(e.slice(0,20));return t}(c))r(fe+e);const u=function(e,t){const n=[];let r=e;for(let e=0;r&&e<4&&r!==t;e+=1){const e=ke(r);if(!e)break;const t=Ne(r);if(n.unshift(t>1?`${e}:nth-of-type(${t})`:e),r=r.parentElement,r&&"html"===String(r.tagName||"").toLowerCase())break}return n.join(" > ")}(e,i);return u&&r(u),n}function Le(e){if(!e||"function"!=typeof e.querySelector)return!1;try{return Boolean(e.querySelector("a,button,[role=button],input,textarea,select,[onclick]"))}catch{return!1}}const Te="rb-flow-run";function Ae(){try{const e=globalThis?.sessionStorage;e&&"function"==typeof e.removeItem&&e.removeItem(Te)}catch{}}const ze=/\d{1,2}:\d{2}(:\d{2})?/;function De(e){return("input"===e.t?"填写":"submit"===e.t?"提交":"点击")+(e.label?`「${e.label}」`:"(未命名元素)")}function Ie(e){const t=ye(e?.textContent);if(t&&t.length<=24&&/[0-9A-Za-z一-龥]/.test(t))return t;const n=Se(e,"aria-label")||Se(e,"placeholder")||Se(e,"title");if(n)return String(n).slice(0,24);const r=Se(e,"type");if("input"===ke(e)&&-1!==["submit","button","reset"].indexOf(r)){const t=Se(e,"value");if(t)return String(t).slice(0,24)}const o=Se(e,"name");if(o)return`${ke(e)}[${o}]`;const i=Se(e,"id");return i&&Be(i)?"#"+i:ke(e)||"元素"}function _e(e,t){if(!t)return[];try{const n=e.querySelectorAll?Array.from(e.querySelectorAll("*")):[],r=[];let o=0;for(const e of n){const n=ye(e?.textContent);n&&-1!==n.indexOf(t)&&r.push({el:e,len:n.length,anchor:"A"===String(e?.tagName||"").toUpperCase(),idx:o++})}return r.sort((e,t)=>e.len!==t.len?e.len-t.len:e.anchor!==t.anchor?e.anchor?-1:1:t.idx-e.idx),r.map(e=>{const t=e.el;if(t&&function(e){const t=String(e?.tagName||"").toUpperCase();return-1!==["SPAN","B","I","EM","STRONG","SMALL","FONT","U","S","MARK","SUB","SUP"].indexOf(t)}(t)){let e=t.parentElement;for(;e&&!Me(e)&&!$e(e);)e=e?.parentElement;if(e&&(Me(e)||$e(e)))return e}return t})}catch{}return[]}function $e(e){try{const t=String(Se(e,"class")||"").toLowerCase();return/button|btn|menu|command|toggle|clickable|action/.test(t)}catch{return!1}}function Re(e,t){if(0===t.indexOf(fe))return _e(e,t.slice(5));try{const n=e.querySelector?e.querySelector(t):null;return n?[n]:[]}catch{return[]}}function Pe(e){try{return!e||"function"!=typeof e.getClientRects||e.getClientRects().length>0}catch{return!0}}function Ue(e,t){if(!e||!t)return null;let n=null;for(const r of e.cand||[]){const e=Re(t,r);for(const t of e){if(Pe(t))return t;n||(n=t)}}return n}function qe(e={}){const t=e.doc??("undefined"!=typeof document?document:void 0),n=e.wait??(e=>new Promise(t=>setTimeout(()=>t(),e))),r=e.timeoutMs??he,o=e.log??(()=>{});let i=!1;function a(e,n){return new Promise(r=>{let o=!1,i=null,a=null;const s=e=>{if(!o){o=!0,i&&clearInterval(i);try{a?.disconnect()}catch{}r(e)}},l=()=>{let t=!1;try{t=Boolean(e())}catch{}t&&s(!0)},c=t?.defaultView;if(c&&"function"==typeof c.MutationObserver&&t?.body)try{a=new c.MutationObserver(()=>l()),a.observe(t.body,{childList:!0,subtree:!0,characterData:!0})}catch{a=null}i=setInterval(l,100),l(),setTimeout(()=>s(!1),Math.max(1,n))})}function s(e,n){try{const r=t?.defaultView,o=r&&r.Event||("undefined"!=typeof Event?Event:void 0);if(!o||"function"!=typeof e.dispatchEvent)return;e.dispatchEvent(new o(n,{bubbles:!0}))}catch{}}function l(e,n){try{e.focus?.()}catch{}const r=String(e.tagName||"").toUpperCase();if("SELECT"===r){try{e.value=n}catch{return!1}return s(e,"change"),String(e.value??"")===n}if("INPUT"===r||"TEXTAREA"===r){let r;try{let t=Object.getPrototypeOf(e);for(;t&&!r;)r=Object.getOwnPropertyDescriptor(t,"value"),t=Object.getPrototypeOf(t)}catch{r=void 0}try{r&&r.set?r.set.call(e,n):e.value=n}catch{e.value=n}return s(e,"input"),s(e,"change"),String(e.value??"")===n||(function(e,n){try{if(e.focus?.(),"function"==typeof e.setSelectionRange){const t=String(e.value??"").length;try{e.setSelectionRange(0,t)}catch{}}return Boolean(t?.execCommand?.("insertText",!1,n))}catch{return!1}}(e,n),String(e.value??"")===n)}try{const r=t?.defaultView,o=r?.getSelection?.();return o&&"function"==typeof o.selectAllChildren&&o.selectAllChildren(e),t?.execCommand?.("delete"),Boolean(t?.execCommand?.("insertText",!1,n))}catch{return!1}}function c(e){try{e.focus?.()}catch{}try{const t=e?.form||("function"==typeof e?.closest?e.closest("form"):null);if(t&&"function"==typeof t.requestSubmit)return void t.requestSubmit();if(t&&"function"==typeof t.submit)return void t.submit()}catch{}!function(e,n){try{const r=t?.defaultView,o=r&&r.KeyboardEvent||("undefined"!=typeof KeyboardEvent?KeyboardEvent:void 0);if(!o||"function"!=typeof e.dispatchEvent)return;e.dispatchEvent(new o("keydown",{key:n,bubbles:!0,cancelable:!0}))}catch{}}(e,"Enter")}function u(e){try{e.scrollIntoView?.({block:"center"})}catch{}let n=null;try{"A"===String(e?.tagName||"").toUpperCase()&&"_blank"===Se(e,"target")&&(n="_blank",e.setAttribute?.("target","_self"))}catch{}try{!function(e){const n=t?.defaultView,r=n||("undefined"!=typeof window?window:void 0),o=r&&r.MouseEvent||("undefined"!=typeof MouseEvent?MouseEvent:void 0),i=r&&r.PointerEvent||("undefined"!=typeof PointerEvent?PointerEvent:void 0);let a=0,l=0;try{if("function"==typeof e.getBoundingClientRect){const t=e.getBoundingClientRect();t&&"number"==typeof t.left&&"number"==typeof t.top&&(a=t.left+(t.width||0)/2,l=t.top+(t.height||0)/2)}}catch{}const c={bubbles:!0,cancelable:!0,composed:!0,clientX:a,clientY:l,button:0,view:r},u=Object.assign({},c,{pointerId:1,pointerType:"mouse",isPrimary:!0}),d=(t,n)=>{try{0===t.indexOf("pointer")&&i?e.dispatchEvent(new i(t,n)):o?e.dispatchEvent(new o(t,n)):e.dispatchEvent(new(r&&r.Event?r.Event:Event)(t,{bubbles:!0,cancelable:!0}))}catch{s(e,t)}};d("pointerdown",u),d("mousedown",c),d("pointerup",u),d("mouseup",c),d("click",c);try{const t=String(e?.tagName||"").toUpperCase();"A"!==t&&"BUTTON"!==t||"function"!=typeof e.click||e.click()}catch{}}(e)}finally{try{n&&e.setAttribute?.("target",n)}catch{}}}return{abort(){i=!0},runAll:async function(e,s){if(i=!1,!t)return{ok:!1,done:0,error:"当前环境没有 document(无法操作页面)"};if(!e||!e.length)return{ok:!1,done:0,error:"这条流程还没有步骤"};for(let d=s?.from??0;d0&&await n(f);let h=null;const g=await a(()=>(h=Ue(p,t),Boolean(h)),r);if(s?.onStep?.(d,e.length),!g||!h)return{ok:!1,done:d,error:`第 ${d+1} 步没找到元素(${De(p)})|诊断:${(p.cand||[]).length} 个候选都没命中(首选 ${p.cand?.[0]||"无"}),等了 ${Math.round(r/1e3)}s`};try{if("input"===p.t){if(!l(h,String(p.value??""))){const e=String(h?.value??"").slice(0,20);return{ok:!1,done:d,error:`第 ${d+1} 步填不进去(${De(p)})|诊断:写进去了又被页面的脚本改回「${e||"(空)"}」—— 这类输入框要先手动点一下它再重播`}}}else"submit"===p.t?c(h):u(h)}catch(e){return{ok:!1,done:d,error:`第 ${d+1} 步执行出错(${De(p)}):${String(e?.message||e)}`}}if(o("已完成第 "+(d+1)+"/"+e.length+" 步:"+De(p)),i)return{ok:!1,done:d+1,aborted:!0,error:"已手动停止"};await n(120)}return{ok:!0,done:e.length}},waitFor:a,resolveStep:e=>Ue(e,t)}}function je(e){try{return new URL(e).hostname.replace(/^www\./,"")}catch{return e}}const Ge={id:"com.flowsaro.flow",name:"步骤录制",version:"0.1.14",type:"shortcut",permissions:["dom","storage","ui","severity","clipboard"],builtin:!0},Oe="data:image/svg+xml;utf8,"+encodeURIComponent('译'),Fe=[{manifest:{id:"com.flowsaro.github-accel",name:"GitHub 下载加速",version:"1.2.0",type:"feature",permissions:["dom","storage"],icon:"data:image/svg+xml;utf8,"+encodeURIComponent('GH'),description:"GitHub Release/仓库下载链接添加镜像加速按钮(注入型插件,仅 GitHub 站点;镜像列表可在设置面板配置,加速完成会弹一次通知)",builtin:!0},init:function(e){const t=e;if(t.declareSettings([{key:"mirrors",label:"镜像列表(每行一个,格式:名称 URL;留空使用默认)",type:"textarea",placeholder:"gh-proxy.com https://gh-proxy.com\ngh-proxy.org https://gh-proxy.org\nghproxy.com https://mirror.ghproxy.com"},{key:"notify",label:"加速完成后弹通知",type:"checkbox",default:!0},{key:"hypeTexts",label:"加速完成通知文案(每行一条,{n} 代表链接数量;清空则恢复默认)",type:"textarea",default:K,placeholder:K}]),!/(^|\.)github\.com$/.test(location.hostname))return;if(!document.body)return;let n=X,r=X[0];function o(){const e=function(e){const t=[];for(const n of String(e||"").split("\n")){const e=n.trim();if(!e)continue;const r=e.split(/\s+/),o=r[r.length-1];if(!/^https?:\/\//.test(o))continue;let i=r.length>1?r.slice(0,-1).join(" "):o;try{1===r.length&&(i=new URL(o).hostname.replace(/^www\./,""))}catch{}t.push({name:i,url:o})}return t}(String(t.getValue("mirrors","")||""));n=e.length?e:X,n.some(e=>e.url===r.url)||(r=n[0])}o();let i=!1;function a(e){if(i)return;if(!1===t.getValue("notify",!0))return;i=!0;const n=function(e){const t=String(e||"").split("\n").map(e=>e.trim()).filter(Boolean);return t.length?t:K.split("\n")}(String(t.getValue("hypeTexts",K)||""));t.toast(Z(n,e),{type:"success"})}function s(e,t){return e.url.replace(/\/+$/,"")+"/"+t}function l(){document.querySelectorAll(".gh-mirror-menu.open").forEach(e=>e.classList.remove("open"))}function c(e){e.querySelectorAll("li").forEach(e=>{const t=e.getAttribute("data-mirror-url")===r.url;e.classList.toggle("selected",t),e.textContent=(t?"✓ ":"")+e.getAttribute("data-mirror-name")})}function u(e){if(e.getAttribute("data-mirror-split"))return;e.setAttribute("data-mirror-split","1");const t=document.createElement("span");t.className="gh-mirror-split";const o=document.createElement("a");o.className="split-main",o.setAttribute("data-original-href",e.href),o.href=s(r,e.href),o.textContent="下载",o.title="通过 "+r.name+" 下载",o.target="_blank",o.rel="noopener noreferrer",o.setAttribute("data-mirror-split","1");const i=document.createElement("button");i.type="button",i.className="split-arrow",i.textContent="▾",i.title="选择镜像下载",i.setAttribute("aria-label","选择镜像下载");const a=document.createElement("ul");a.className="gh-mirror-menu",n.forEach(t=>{const n=document.createElement("li");n.setAttribute("data-mirror-url",t.url),n.setAttribute("data-mirror-name",t.name),n.addEventListener("click",n=>{n.stopPropagation(),window.open(s(t,e.href),"_blank"),r=t,document.querySelectorAll(".gh-mirror-split .split-main").forEach(e=>{const t=e,n=t.getAttribute("data-original-href");n&&(t.href=s(r,n),t.title="通过 "+r.name+" 下载")}),c(a),a.classList.remove("open")}),a.appendChild(n)}),c(a),i.addEventListener("click",e=>{e.stopPropagation();const t=a.classList.contains("open");l(),t||a.classList.add("open")}),t.appendChild(o),t.appendChild(i),t.appendChild(a),e.parentNode.insertBefore(t,e.nextSibling);const u=e.parentElement;e.href.includes("archive/refs/heads")&&u&&"LI"===u.tagName&&u.classList.add("gh-mirror-li")}let d=null,p=null;function f(){d&&clearTimeout(d),d=setTimeout(()=>{p&&p.disconnect();const e=document.querySelectorAll("a[href*='releases/download']:not([data-mirror-split]), a[href*='archive/refs/heads']:not([data-mirror-split])");e.forEach(u),p&&document.body&&p.observe(document.body,{childList:!0,subtree:!0}),e.length&&a(e.length)},250)}!function(){const e=document.createElement("style");e.textContent='.gh-mirror-split{position:relative;display:inline-flex;align-items:stretch;margin-left:8px;vertical-align:middle;flex-shrink:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif}.gh-mirror-split a,.gh-mirror-split button{font-size:12px;line-height:20px;padding:3px 12px;border:1px solid var(--color-border-default,#d0d7de);background-color:var(--color-btn-bg,#f6f8fa);color:var(--color-fg-default,#24292f);cursor:pointer;text-decoration:none !important;white-space:nowrap;box-shadow:var(--color-btn-shadow,0 1px 0 rgba(27,31,36,0.04));box-sizing:border-box}.gh-mirror-split a:hover,.gh-mirror-split a:active,.gh-mirror-split a:focus,.gh-mirror-split button:hover{text-decoration:none !important;background-color:var(--color-btn-hover-bg,#f3f4f6);border-color:var(--color-btn-hover-border,#d0d7de)}.gh-mirror-split .split-main{border-radius:6px 0 0 6px;border-right:none}.gh-mirror-split .split-arrow{border-radius:0 6px 6px 0;padding-left:8px;padding-right:8px}.gh-mirror-menu{position:absolute;right:0;top:calc(100% + 4px);min-width:160px;margin:0;padding:4px 0;list-style:none;background-color:var(--color-canvas-overlay,#fff);border:1px solid var(--color-border-default,#d0d7de);border-radius:6px;box-shadow:var(--color-shadow-large,0 8px 24px rgba(140,149,159,0.2));z-index:999999;display:none}.gh-mirror-menu.open{display:block}.gh-mirror-menu li{padding:4px 12px;font-size:12px;cursor:pointer;color:var(--color-fg-default,#24292f);white-space:nowrap}.gh-mirror-menu li:hover{background-color:var(--color-accent-subtle,#ddf4ff);color:var(--color-accent-fg,#0969da)}.gh-mirror-menu li.selected{color:var(--color-accent-fg,#0969da);font-weight:600}li.gh-mirror-li{display:flex !important;align-items:center}',document.head.appendChild(e)}(),p=new MutationObserver(f),p.observe(document.body,{childList:!0,subtree:!0}),f(),document.addEventListener("click",l);let h=null;try{"function"==typeof GM_addValueChangeListener&&(h=GM_addValueChangeListener("sc:plugin:com.flowsaro.github-accel.settings",()=>{o(),document.querySelectorAll(".gh-mirror-split").forEach(e=>e.remove()),f()}))}catch{}t.onDispose(()=>{if(p&&p.disconnect(),d&&clearTimeout(d),document.removeEventListener("click",l),null!=h&&"function"==typeof GM_removeValueChangeListener)try{GM_removeValueChangeListener(h)}catch{}})}},{manifest:{id:"com.flowsaro.translate",name:"快捷翻译",version:"0.9.11",type:"shortcut",permissions:["selection","network","storage","ui"],menuOnSelection:!0,icon:Oe,description:"选中文本后自动弹出快捷菜单,点图标即翻译(结果以通知展示,单词附带词典信息);无选中时点图标弹出手动翻译面板,翻译结果直接展示在面板里(可选源/目标语言,未选时按字符集自动猜源语言)。有道词典接口主源,单词与句子一个接口(英文单词自带音标/释义/例句);有道不可用或目标语言非中英时自动回退 MyMemory(可配 API Key 提升配额)",builtin:!0},init:function(e){const t=e,n=[{label:"中文",value:"zh-CN"},{label:"English",value:"en"},{label:"日本語",value:"ja"},{label:"한국어",value:"ko"},{label:"Français",value:"fr"},{label:"Deutsch",value:"de"},{label:"Español",value:"es"},{label:"Русский",value:"ru"}],r=[{label:"自动检测",value:"auto"},...n],o="auto",i=o,a="zh-CN",s=[[/[\u3040-\u30ff]/,"ja"],[/[\uac00-\ud7af]/,"ko"],[/[\u0600-\u06ff]/,"ar"],[/[\u0400-\u04ff]/,"ru"],[/[\u4e00-\u9fa5]/,"zh-CN"],[/[\u0900-\u097f]/,"hi"]];function l(e,t,n){const r=t&&t!==o?t:function(e){for(const[t,n]of s)if(t.test(e))return n;return"en"}(e);return{from:r,to:r===n?"zh-CN"===n?"en":"zh-CN":n}}t.declareSettings([{key:"apiKey",label:"MyMemory API Key(可选,提升每日配额)",type:"text",placeholder:"留空使用匿名接口"},{key:"sourceLang",label:"默认源语言(划词翻译始终自动检测,此项只作用于手动输入)",type:"select",default:i,options:r},{key:"targetLang",label:"默认目标语言(划词与手动输入共用;与源语言相同时自动换向)",type:"select",default:a,options:n}]);let c="";t.onEvent("manual-input",e=>{c="string"==typeof e?e:""}),t.onEvent("manual-src",e=>{"string"==typeof e&&e&&t.setValue("sourceLang",e)}),t.onEvent("manual-dst",e=>{"string"==typeof e&&e&&t.setValue("targetLang",e)}),t.onEvent("manual-go",e=>{const n=("string"==typeof e?e:c).trim();if(!n)return void t.toast("先输入要翻译的内容",{type:"warning"});if(M)return;const{from:r,to:o}=l(n,t.getValue("sourceLang",i),t.getValue("targetLang",a));!async function(e,n,r){M=!0;const o=t.toast("翻译中…",{type:"info",timeout:0});let i;try{t.openPanel(V({busy:!0})),i=await B(e,n,r),t.dismissToast(o)}finally{M=!1}i.ok?t.openPanel(V({result:i.result,infoLines:i.infoLines})):t.openPanel(V({error:i.error}))}(n,r,o)}),t.onActivate(async()=>{const e=(await t.getSelectedText()||"").trim();if(!e)return c="",void t.openPanel(V());const{from:n,to:r}=l(e,o,t.getValue("targetLang",a));!async function(e,n,r){t.closePanel();const o=t.toast("翻译中…",{type:"info",timeout:0}),i=await B(e,n,r);if(t.dismissToast(o),!i.ok)return void t.toast(i.error,{type:"error"});t.toast(i.result,{type:"success",copyable:!0,timeout:0,...i.infoLines.length?{note:i.infoLines.join("\n")}:{}})}(e,n,r)});const u=1e4,d=500,p="Mk6hqtUp33DGGtoS63tTJbMUYjRrG1Lu";function f(e){const t=String(e||"").toLowerCase();return t.startsWith("zh")?"zh-CHS":t}function h(e,t){const n=e=>"zh-CHS"===e?"c":e.slice(0,1),r=n(f(e))+n(f(t));return[r,"new"+r,r+"_new","longchao-"+r]}function g(e,t){const n="webdict",r=e+n,o=String(r.length%10),i={q:e,t:o,client:"web",sign:O("web"+e+o+p+O(r)),keyfrom:n};return t&&(i.le=t),new URLSearchParams(i).toString()}function m(e){const t=String(e||"").trim().toLowerCase();return t?t.startsWith("zh")?"zh-CN":/^[a-z]{2}$/.test(t)?t:"":""}function v(e){return String(e??"").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/�?39;/g,"'").replace(/'/gi,"'").replace(/ /g," ").replace(/&/g,"&").replace(/<[^>]*>/g,"").replace(/\s+/g," ").trim()}function b(e,t){const n=v(e);return n.length>t?n.slice(0,t-1).trimEnd()+"…":n}function y(e){const t=String(e||"").toLowerCase();let n="";for(let e=0;e=33&&r<=47||r>=58&&r<=64||r>=91&&r<=96||r>=123&&r<=126||(n+=t[e]))}return n}function w(e){if("string"==typeof e)return e.trim();if(Array.isArray(e))return e.map(w).filter(Boolean).join(" ");if(e&&"object"==typeof e){const t=e;if(void 0!==t.l)return w(t.l);if(void 0!==t.i)return w(t.i);if("string"==typeof t["#tran"])return t["#tran"].trim();if("string"==typeof t.tran)return t.tran.trim();if("string"==typeof t["#text"])return t["#text"].trim();if("string"==typeof t.text)return t.text.trim()}return""}function x(e){const t=e?.word??e,n=Array.isArray(t)?t:[t],r=[];let o="";const i=e=>{if(!e)return;const t="string"==typeof e.pos&&e.pos.trim()?e.pos.trim()+" ":"";"string"==typeof e["#text"]&&e["#text"].trim()&&(o||(o=e["#text"].trim()));const n=w(e.i);if(/^(☞|参见|见\s)/.test(n))return;n&&!o&&(o=n);const i="string"==typeof e["#tran"]?e["#tran"].trim():"";i?r.push(t+i):n&&r.push(t+n)};for(const e of n)if(e&&"object"==typeof e){i(e);for(const t of Array.isArray(e.trs)?e.trs:[]){i(t);for(const e of t&&t.tr||[])i(e&&e.l)}for(const t of Array.isArray(e.tr)?e.tr:[])i(t&&t.l)}return{main:o,lines:r}}function k(e){const t=e?.word??e,n=Array.isArray(t)?t[0]:t,r=[];let o="";for(const e of n?.sense||[]){for(const t of e?.phrList||[]){const e=String(t?.jmsy||"").trim();e&&(o||(o=e.replace(/^【[^】]*】\s*/,"")),r.push(e));for(const e of t?.ljT||[]){const t=String(e||"").trim();t&&r.push(t)}}for(const t of e?.sents||[]){const e=String(t?.sentTrans||"").trim();e&&r.push(e)}}return{main:o,lines:r}}function S(e,t,n){const r=[];t&&r.push("/"+t+"/");const o=new Set;for(const e of n){const t=b(e,80);if(t&&!o.has(t)&&(o.add(t),r.push(t),o.size>=3))break}const i=((e.blng_sents_part||{})["sentence-pair"]||[])[0];return i&&i.sentence&&i["sentence-translation"]&&r.push("例 "+b(i.sentence,60)+" · "+b(i["sentence-translation"],60)),r}function E(e,t,n){const r=e.fanyi;if(!r||"string"!=typeof r.tran||!r.tran.trim())return null;const o=function(e){const t=/^([a-z-]+)2([a-z-]+)$/i.exec(String(e||"").trim());return t?{from:m(t[1]),to:m(t[2])}:{from:"",to:""}}(String(r.type||""));return o.to!==t||n&&"auto"!==n&&o.from&&o.from!==n?null:{translation:v(r.tran),infoLines:[]}}async function C(e,n,r){const o=function(e,t){const n=f(e),r=f(t);return n&&r&&n!==r?"zh-CHS"!==n&&"zh-CHS"!==r?null:{le:"zh-CHS"===n?r:n,dicts:h(e,t)}:null}(r,n);if(!o)return null;if(e.length>d)return null;try{const i=await t.httpRequest(function(e){const t=[...e,"web_trans","simple","blng_sents_part","fanyi"];return"https://dict.youdao.com/jsonapi_s?doctype=json&jsonversion=4&dicts="+encodeURIComponent(JSON.stringify({count:String(t.length),dicts:t.map(e=>[e])}))}(o.dicts),{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},data:g(e,o.le),timeout:u});if(!i.ok)return null;const a=JSON.parse(i.text);return a&&"object"==typeof a&&function(e,t){const n=e.meta||{},r=String(e.input??n.input??"").trim();return!r||y(r)===y(t)}(a,e)?E(a,n,r)||function(e,t,n,r){const o=e,i=(o.web_trans||{})["web-translation"]||[],a=i.find(e=>e&&("true"===e["@same"]||e.key===t)),s=String((a?.trans||[])[0]?.value||"").trim(),l=String((i[0]?.trans||[])[0]?.value||"").trim(),c=h(n,r);let u="";const d=[];for(const e of c){const t=o[e];if(!t)continue;const n="newjc"===e||"jc"===e?k(t):x(t);if(n.main||n.lines.length){u=n.main,d.push(...n.lines);break}}const p=v((u||s||l).replace(/^[a-z]{1,8}\.\s*/,""));return p?{translation:p,infoLines:S(e,String(((o.simple||{}).word||[{}])[0]?.phone||((o.simple||{}).word||[{}])[0]?.usphone||"").trim(),d)}:null}(a,e,r,n):null}catch{return null}}async function B(e,n,r){const o=await C(e,r,n);if(o)return{ok:!0,result:o.translation,infoLines:o.infoLines};if(e.length>N)return{ok:!1,error:"这段文字太长,备用翻译一次最多 "+N+" 字符"};try{const o=await t.httpRequest(function(e,n,r){let o="https://api.mymemory.translated.net/get?q="+encodeURIComponent(e)+"&langpair="+n+"|"+r;const i=t.getValue("apiKey","");i&&(o+="&de="+encodeURIComponent(i));return o}(e,n,r));if(!o.ok)return{ok:!1,error:"翻译失败("+o.status+")"};const i=JSON.parse(o.text),a=Number(i&&i.responseStatus||200);if(a>=400)return{ok:!1,error:"备用翻译没能处理这次请求("+a+")"};const s=v(i&&i.responseData&&i.responseData.translatedText||"");return s?{ok:!0,result:s,infoLines:[]}:{ok:!1,error:"未获取到翻译结果"}}catch{return{ok:!1,error:"翻译失败,请检查网络"}}}const N=500;let M=!1;function V(e){const o=[{type:"text",content:"输入单词或句子即可翻译:",style:{color:"secondary",size:"sm"}},{type:"row",items:[{type:"select",value:t.getValue("sourceLang",i),options:r,event:"manual-src"},{type:"text",content:"→",style:{color:"secondary"}},{type:"select",value:t.getValue("targetLang",a),options:n,event:"manual-dst"}]},{type:"textarea",event:"manual-input",submitEvent:"manual-go",value:c,placeholder:"输入要翻译的单词或句子…(回车翻译,Shift+回车换行)"},{type:"button",label:e?.busy?"翻译中…":"翻译",event:"manual-go",variant:"primary",full:!0}];if(e?.error&&o.push({type:"fieldset",legend:"翻译失败",body:[{type:"text",content:e.error,style:{color:"danger",size:"sm"}}]}),e?.result){const t=[{type:"text",content:e.result,style:{weight:"bold",size:"lg"}}];for(const n of e.infoLines||[])t.push({type:"text",content:n,style:{color:"secondary",size:"sm"}});e.infoLines?.length||t.push({type:"text",content:"(🔍 无法找到相关的词典信息)",style:{color:"secondary",size:"sm"}}),o.push({type:"fieldset",legend:"翻译结果",body:t})}return{type:"panel",body:o}}}},{manifest:{id:"com.flowsaro.ask-ai",name:"问 AI",version:"0.3.4",type:"shortcut",permissions:["selection","storage","ui"],menuOnSelection:!0,icon:"data:image/svg+xml;utf8,"+encodeURIComponent('AI'),description:"选中文字后点图标,打开配置好的 AI 站点并把文字按 URL 模板带过去(站点可配置:名称|网址模板,{q} 为占位;无选中时点图标弹面板手动输入)",builtin:!0},init:function(e){const t=e;function n(){const e=J(String(t.getValue("prompts",H)||""));return e.length?e:J(H)}t.declareSettings([{key:"sites",label:"站点列表(每行一条:名称|网址模板,{q} 代表要问的文字;留空用内置候选)",type:"textarea",default:F,placeholder:F},{key:"defaultSite",label:"默认站点(填站点列表里的名称;留空用第一条)",type:"text",default:"",placeholder:"例如 DeepSeek"},{key:"prompts",label:"人设/提示词模板(每行一条:名称|模板,{q} 代表要问的内容;留空用内置候选)",type:"textarea",default:H,placeholder:H},{key:"defaultPrompt",label:"默认人设(只作用于面板,且是每次打开面板时的初始值;面板里临时切的人设不会改这里。划词直发一律原样发送。填人设列表里的名称,留空用「直接发送」)",type:"text",default:"",placeholder:"例如 详细解释"},{key:"openMode",label:"打开方式(弹出窗口不占标签栏,且固定复用一个窗口)",type:"select",default:"tab",options:[{label:"新标签页(默认)",value:"tab"},{label:"弹出窗口",value:"popup"}]},{key:"popupSize",label:"弹出窗口尺寸(宽x高,如 900x700;写错则用默认)",type:"text",default:`${W.w}x${W.h}`,placeholder:"900x700"}]);let r=null;function o(){const e=n(),o=r??String(t.getValue("defaultPrompt","")||"").trim();return e.find(e=>e.name===o)||e[0]}function i(e){const t=String(e.value||"");return"{q}"===t.trim()?"(不加人设,原样发送)":t.includes("{q}")?t.split("{q}").join("〔要问的内容〕"):`${t}(没写 {q},你的文字不会被带过去)`}function a(){return String(t.getValue("openMode","tab")||"tab")}let s=null;function l(e){const n=function(){try{if("undefined"!=typeof unsafeWindow&&unsafeWindow)return unsafeWindow}catch{}return"undefined"!=typeof window?window:void 0}();if(!n)return!1;const r=a();try{if("popup"!==r)return!!n.open(e,"_blank");const{w:o,h:i}=function(e){const t=String(e||"").match(/(\d{2,4})\s*[xX*×,,\s]\s*(\d{2,4})/);if(!t)return W;const n=Number(t[1]),r=Number(t[2]);return n>=320&&n<=3e3&&r>=300&&r<=2e3?{w:n,h:r}:W}(String(t.getValue("popupSize","")||"")),a=`popup=yes,width=${o},height=${i},menubar=no,toolbar=no,location=no,status=no`;if(s&&!s.closed)try{return s.location.href=e,s.focus(),!0}catch{s=null}const l=n.open("about:blank","rocket-btn-ask-ai",a);if(!l)return!1;try{l.opener=null}catch{}l.location.href=e,s=l;try{l.focus()}catch{}return!0}catch{return!1}}function c(){const e=J(String(t.getValue("sites",F)||""));return e.length?e:J(F)}function u(){const e=c(),n=String(t.getValue("defaultSite","")||"").trim();return e.find(e=>e.name===n)||e[0]}function d(e,n,r){const o=String(e||"").trim();if(!o)return void t.toast("先选中文字,或先输入要问的内容",{type:"warning"});const i=function(e,t){return e.value.includes("{q}")?e.value.split("{q}").join(t):e.value}(r,o),a=i.length>Y?i.slice(0,Y):i,s=n.value.includes("{q}"),c=r.value.includes("{q}"),u=function(e,t){return e.split("{q}").join(encodeURIComponent(t))}(n.value,a);if(!l(u))return void t.toast("新标签页被浏览器拦下了",{type:"warning",note:"请在地址栏右侧允许本站弹出窗口后重试"});const d=[];s||d.push("该站点模板里没有 {q} 占位,内容没能带过去(可在设置里改)"),c||d.push("人设模板里没有 {q} 占位,选中的文字没能带过去(可在设置里改人设)"),a.length({label:e.name,value:e.name})),event:"ask-site"},{type:"select",value:a(),options:[{label:"新标签页",value:"tab"},{label:"弹出窗口",value:"popup"}],event:"ask-mode"}]},{type:"select",value:o().name,options:n().map(e=>({label:e.name,value:e.name})),event:"ask-prompt"},{type:"textarea",event:"ask-input",submitEvent:"ask-go",value:p,placeholder:"输入要问的问题…(回车提问,Shift+回车换行)"},{type:"button",label:"提问",event:"ask-go",variant:"primary",full:!0},{type:"text",content:`站点模板:${e.value}${e.value.includes("{q}")?"":"(没写 {q},内容不会被带过去)"}`,style:{color:"secondary",size:"sm"}},{type:"text",content:`人设模板(仅本次面板用):${i(o())}`,style:{color:"secondary",size:"sm"}}]}}t.onEvent("ask-input",e=>{p="string"==typeof e?e:""}),t.onEvent("ask-site",e=>{"string"==typeof e&&e&&t.setValue("defaultSite",e),f()}),t.onEvent("ask-mode",e=>{"tab"!==e&&"popup"!==e||t.setValue("openMode",e)}),t.onEvent("ask-go",e=>{d(("string"==typeof e?e:p).trim(),u(),o())}),t.onEvent("ask-prompt",e=>{"string"==typeof e&&e&&(r=e),f()}),t.onActivate(async()=>{p="",r=null;const e=(await t.getSelectedText()||"").trim();e?(t.closePanel(),d(e,u(),n().find(e=>"直接发送"===e.name)||{name:"直接发送",value:"{q}"})):t.openPanel(h())})}},{manifest:{id:"com.flowsaro.qrcode",name:"二维码",version:"1.3.2",type:"shortcut",permissions:["selection","ui"],menuOnSelection:!0,icon:"data:image/svg+xml;utf8,"+encodeURIComponent(''),description:"选中文字点图标,面板直接显示二维码;无选中时默认把当前网址转成码。出码后点「重新编辑」可换任意内容。纯本地生成(不联网,内容不出本机),上限约 2900 字节(中文约 970 字),超长会如实提示",builtin:!0},init:function(e){const t=e;let n="",r=null,o="edit",i=null,a="manual";function s(e){if("selection"===a)return"扫一扫,查看选中的文字";if("page"===a){let t="";try{t=new URL(e).hostname.replace(/^www\./,"")}catch{}return t?`扫一扫,打开这个网页(${t})`:"扫一扫,打开这个网页"}return"扫一扫,查看这段内容"}function l(e){e?(e!==i&&(r=function(e){const t=de.stringToBytes(e).length;for(let n=1;n<=40;n++)try{const r=de(n,"M");r.addData(e),r.make();const o=Math.max(3,Math.ceil(240/r.getModuleCount()));return{dataUrl:pe(r,o)??r.createDataURL(o,2*o),text:e,bytes:t,chars:e.length}}catch{}return{error:"内容太长,生成不了二维码(上限约 2,900 字节,中文约 970 字)",text:e,bytes:t,chars:e.length}}(e),i=e),o=r.dataUrl?"result":"edit"):(r=null,i=null,o="edit"),t.openPanel(c())}function c(){if("result"===o&&r?.dataUrl)return{type:"panel",body:[{type:"text",content:s(r.text),style:{weight:"bold",size:"sm"}},{type:"image",src:r.dataUrl,width:"100%"},{type:"text",content:`内容 ${r.chars} 字 / ${r.bytes} 字节`+(r.bytes>500?",二维码较密,建议凑近扫":""),style:{color:"secondary",size:"sm"}},{type:"button",label:"重新编辑",event:"qr-edit",full:!0}]};const e=[{type:"text",content:"输入内容,点「生成」转成二维码(选中文字或当前网址会直接出码):",style:{color:"secondary",size:"sm"}}];return r?.error&&e.push({type:"text",content:r.error,style:{color:"danger",size:"sm"}}),e.push({type:"textarea",event:"qr-input",submitEvent:"qr-go",value:n,placeholder:"输入要生成二维码的内容…"},{type:"button",label:"生成",event:"qr-go",variant:"primary",full:!0}),{type:"panel",body:e}}t.onEvent("qr-input",e=>{const t="string"==typeof e?e:"";t!==n&&(n=t,a="manual")}),t.onEvent("qr-go",e=>{const r=("string"==typeof e?e:n).trim();r?setTimeout(()=>l(r),0):t.toast("先选中文字,或先输入要生成的内容",{type:"warning"})}),t.onEvent("qr-edit",()=>{o="edit",t.openPanel(c())}),t.onActivate(async()=>{const e=(await t.getSelectedText()||"").trim(),r="function"==typeof t.getPageUrl?(t.getPageUrl()||"").trim():"",o=e||r;a=e?"selection":r?"page":"manual",n=o,setTimeout(()=>l(o),0)})}},{manifest:{id:"com.flowsaro.reminder",name:"提醒助手",version:"1.12.0",type:"feature",permissions:["storage","broadcast","severity"],icon:"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='0.9em' font-size='90'%3E%E2%8F%B0%3C/text%3E%3C/svg%3E",description:"按固定时间弹提醒:支持每 N 分钟/小时循环、每天 HH:MM、每周X HH:MM、一次性 YYYY-MM-DD HH:MM,以及从保存时刻起算的倒计时(如 30 分钟,只支持一条);提醒内容由「|」后的文本自定义,所有打开的标签页同步弹出;迟到的提醒会补发,并在次要文字里说明原定时刻与延迟多久",builtin:!0},init:function(e){const t=e;t.declareSettings([{key:"reminders",label:"提醒列表(每行一条:规则|通知内容,支持安排多个计划分行输入)",type:"textarea",placeholder:"每 45 分钟|⏰ 到点啦:起来喝水\n09:30|📅 到点啦:晨会\n每周一,周五 18:00|💼 到点啦:写周报\n2026-09-20 15:00|✅ 该交材料了",default:""},{key:"countdowns",label:"倒计时(一次性,只支持一条):一条「时长|通知内容」,从保存那一刻起算,只响一次",type:"textarea",placeholder:"30 分钟|🥢 泡面好了",default:""},{key:"schedLate",label:"定点提醒(每日/每周/一次性):迟到多久之内仍然补发(分钟,0 = 只报准点)",type:"text",placeholder:String(ee),default:String(ee)},{key:"intervalToast",label:"周期提醒(每 N 分钟/小时):通知自动关闭秒数(0 = 不自动关闭)",type:"text",placeholder:"8",default:String(8)},{key:"schedToast",label:"定点提醒(每日/每周/一次性):通知自动关闭秒数(0 = 不自动关闭)",type:"text",placeholder:"0",default:"0"}]);let n=null,r=null,o=null,i=[],a=[],s=[];const l=new Map;let c=[];const u=new Map,d=new Map,p=new Map;function f(e){const n=p.get(e);return void 0!==n?n:String(t.getState(e,""))}function h(e,n){!function(e,t){if(p.set(e,t),p.size>200){const e=p.keys().next().value;void 0!==e&&p.delete(e)}}(e,n),t.setState(e,n)}function g(){const e=String(t.getValue("reminders","")||"").replace(/\\n/g,"\n");if(e===r)return;r=e;const n=[],o=[];ce(e).forEach(e=>{const t=function(e){const t=e.indexOf("|");if(t<0)return{line:e,error:"缺少「|」分隔符"};const n=e.slice(0,t).trim(),r=e.slice(t+1).trim();if(!n)return{line:e,error:"「|」左边的时间规则是空的"};if(!r)return{line:e,error:"「|」右边的提醒内容是空的"};let o;if(o=n.match(/^(\d{4})-(\d{1,2})-(\d{1,2})[ T](\d{1,2}):(\d{2})$/),o)return se(+o[4],+o[5])?{type:"once",key:"once|"+n+"|"+r,content:r,y:+o[1],mo:+o[2]-1,d:+o[3],h:+o[4],mi:+o[5],line:e}:{line:e,error:"时间超出范围(小时 0-23,分钟 0-59)"};if(o=n.match(/^每天\s*(\d{1,2}):(\d{2})$/)||n.match(/^(\d{1,2}):(\d{2})$/),o)return se(+o[1],+o[2])?{type:"daily",key:"daily|"+n+"|"+r,content:r,h:+o[1],mi:+o[2]}:{line:e,error:"时间超出范围(小时 0-23,分钟 0-59)"};if(o=n.match(/^(?:每)?周(周?[一二三四五六日天](?:[,,、]周?[一二三四五六日天])*)\s+(\d{1,2}):(\d{2})$/),o){if(!se(+o[2],+o[3]))return{line:e,error:"时间超出范围(小时 0-23,分钟 0-59)"};const t=o[1].split(/[,,、]/).map(e=>ie[e.replace(/^周/,"").trim()]).filter(e=>void 0!==e);return t.length?{type:"weekly",key:"weekly|"+n+"|"+r,content:r,days:t,h:+o[2],mi:+o[3]}:{line:e,error:"没看懂星期写法「"+o[1]+"」(示例:每周一,周五 18:00)"}}if(o=n.match(/^每\s*(\d+)\s*(秒|秒钟|分钟|小时|分)?$/)||n.match(/^(\d+)\s*(秒|秒钟|分钟|小时|分|s|sec|m|min|h)$/i),o){const t=String(o[2]||"分钟").toLowerCase(),i=(ae[t]||0)*+o[1];return i?ie.key));c.forEach(e=>{a.has(e)||u.set(e,0)}),a.forEach(e=>u.delete(e)),c=n.map(e=>e.key),m(o,[],"提醒规则","格式:规则|内容。规则支持:每 N 分钟/小时、HH:MM、每周X HH:MM、YYYY-MM-DD HH:MM","badRulesSig")}function m(e,n,r,o,i){const a=e.map(e=>e.line+" → "+e.error).concat(n.map(e=>e+" → 超出条数上限")).join("\n");if(a===String(t.getState(i,"")))return;if(t.setState(i,a),!a)return;const s=[];e.length&&(s.push("有 "+e.length+" 条"+r+"没被识别,已忽略:"+v(e.map(e=>e.line))),e.forEach(e=>{console.warn("[提醒助手] 无法识别的"+r+":「"+e.line+"」原因:"+e.error)})),n.length&&(s.push(r+"只支持一条,已忽略后面 "+n.length+" 条:"+v(n)),n.forEach(e=>{console.warn("[提醒助手]"+r+"只支持一条,已忽略:「"+e+"」")})),t.toast(s.join(";")+"。"+o,{type:"warning",timeout:0})}function v(e){const t=e.slice(0,2).map(e=>"「"+e+"」").join("");return e.length>2?t+" 等 "+e.length+" 条":t}function b(){const e=String(t.getValue("countdowns","")||"").replace(/\\n/g,"\n");if(e===o)return;o=e;const n=[],r=[];ce(e).forEach(e=>{const t=function(e){const t=e.indexOf("|");if(t<0)return{line:e,error:"缺少「|」分隔符"};const n=e.slice(0,t).trim(),r=e.slice(t+1).trim();if(!n)return{line:e,error:"「|」左边的时长是空的"};if(!r)return{line:e,error:"「|」右边的提醒内容是空的"};if(/^每/.test(n))return{line:e,error:"倒计时是一次性的,「每 …」这类循环写法请写到「提醒列表」里"};const o=n.match(/^(\d+)\s*(秒|秒钟|分钟|小时|分|s|sec|m|min|h)\s*(?:后|以后|之后)?$/i);if(!o)return{line:e,error:"没看懂时长写法「"+n+"」(示例:30 分钟、2 小时、45m)"};const i=(ae[String(o[2]).toLowerCase()]||0)*+o[1];return i?ie.line);a=i;const u=new Set(i.map(e=>e.key));s.forEach(e=>{u.has(e)||l.set(e,0)}),u.forEach(e=>l.delete(e)),s=i.map(e=>e.key),m(r,c,"倒计时","格式:时长|内容,只支持一条。时长支持 N 秒/分钟/小时(如 30 分钟、2 小时、45m)","badCdSig")}function y(e,n){const r=parseInt(String(t.getValue(e,n)),10);return isNaN(r)||r<0?n:r}function w(){const e=parseInt(String(t.getValue("schedLate",String(ee))),10);return isNaN(e)||e<0?108e5:6e4*e}function x(e){if(e<=6e4)return"";for(const t of te)if(e<=t.max)return t.emoji;return""}function k(e,t){const n=new Date(e),r=le(n.getHours())+":"+le(n.getMinutes());return t?le(n.getMonth()+1)+"-"+le(n.getDate())+" "+r:r}function S(e,t,n){const r=x(n);if(!r)return"";const o=function(e){const t=Math.max(0,Math.round(e/1e3));if(t<60)return t+" 秒";const n=Math.round(t/60);if(n<60)return n+" 分钟";const r=Math.floor(n/60),o=n%60;if(r<24)return o?r+" 小时 "+o+" 分钟":r+" 小时";const i=Math.floor(r/24),a=r%24;return a?i+" 天 "+a+" 小时":i+" 天"}(n);return"interval"===e.type?r+" 延迟 "+o+"(页面休眠或标签页被节流)":"daily"===e.type||"weekly"===e.type?r+" 补发:原定 "+k(t,!1)+",迟到 "+o:r+" 补发:原定 "+k(t,!0)+",迟到 "+o}function E(e,n,r){const o="interval"===e.type?y("intervalToast",8):y("schedToast",0),i=S(e,n,r);t.toast(e.content,{type:"warning",timeout:1e3*o,broadcast:!0,...i?{note:i}:null})}function C(e,n,r){if(rw()?(h(o,"missed"),function(e,n){t.toast("「"+e+"」已错过(原定 "+k(n,!0)+"),不会再补发,可以从设置里删掉它",{type:"warning",timeout:0})}(e.line,n),!1):(h(o,"done"),E(e,n,i),!0)}function B(e){return"nextAt:"+e}const N="lastFired:";function M(e,t){return function(e){const t=Math.max(0,Math.ceil(e/1e3)),n=Math.floor(t/3600),r=Math.floor(t%3600/60),o=t%60;return n>0?n+":"+le(r)+":"+le(o):le(r)+":"+le(o)}(t)+" ➡️ "+e.content}function V(e,n,r){const i=t.toast(n,{type:"info",severity:"high",busy:!0,timeout:0,note:r,onClose:()=>function(e){const n="fired:"+e.key;"done"===f(n)?(t.setValue("countdowns",""),o=""):h(n,"cancel");d.delete(e.key)}(e)});"number"==typeof i&&i>0&&d.set(e.key,i)}function L(e,n,r){const o=M(e,n-r),i=d.get(e.key);void 0!==i?t.updateToast(i,{text:o})||(d.delete(e.key),V(e,o,re)):V(e,o,re)}function T(e,n){const r=ne+e.key,o=Number(t.getState(r,0));if(!Number.isFinite(o)||o<=0)return t.setState(r,n+e.ms),void L(e,n+e.ms,n);const i="fired:"+e.key,a=f(i);if("cancel"!==a)return n>=o?("done"!==a&&h(i,"done"),L(e,o,n),void function(e,n,r){const o=d.get(e.key);if(void 0===o)return;const i=r-n,a=i>6e4?"📌 "+x(i)+" 已于 "+k(n,!0)+" 到点 · "+oe.slice(2):oe;t.updateToast(o,{text:M(e,0),note:a,type:"success",busy:!1})||d.delete(e.key)}(e,o,n)):void L(e,o,n);!function(e){const n=d.get(e.key);void 0!==n&&(t.dismissToast(n),d.delete(e.key))}(e)}function A(){if(g(),b(),function(){if(!l.size)return;const e=new Set(a.map(e=>e.key));l.forEach((n,r)=>{if(e.has(r))return void l.delete(r);if(n+1<2)return void l.set(r,n+1);l.delete(r),t.setState(ne+r,""),t.setState("fired:"+r,""),p.delete("fired:"+r);const o=d.get(r);void 0!==o&&(t.dismissToast(o),d.delete(r))})}(),function(){if(!u.size)return;const e=new Set(i.map(e=>e.key));u.forEach((n,r)=>{e.has(r)?u.delete(r):n+1<2?u.set(r,n+1):(u.delete(r),t.setState(B(r),""),t.setState(N+r,""),t.setState("fired:"+r,""),p.delete("fired:"+r))})}(),!i.length&&!a.length)return;const e=new Date,n=e.getTime();a.forEach(e=>T(e,n)),i.forEach(r=>{if("interval"===r.type)return void function(e,n){const r=Number(t.getState(B(e.key),0));if(!Number.isFinite(r)||r<=0)return void t.setState(B(e.key),n+e.ms);if(ni&&(i=a),t.setState(B(e.key),i);const s=Number(t.getState(N+e.key,0));Number.isFinite(s)&&s>=r||(t.setState(N+e.key,r),o<=12e4&&E(e,r,o))}(r,n);if("once"===r.type)return void C(r,new Date(r.y,r.mo,r.d,r.h,r.mi,0).getTime(),n);if(!("daily"===r.type||-1!==r.days.indexOf(e.getDay())))return;const o=new Date(e.getFullYear(),e.getMonth(),e.getDate(),r.h,r.mi,0).getTime(),i=n-o;var a,s,l;i<0||i>w()||(a="fired:"+r.key,s=(l=e).getFullYear()+"-"+le(l.getMonth()+1)+"-"+le(l.getDate()),f(a)!==s&&(h(a,s),1)&&E(r,o,i))})}g(),b(),A(),n=setInterval(A,5e3);let z=null;try{"function"==typeof GM_addValueChangeListener&&(z=GM_addValueChangeListener("sc:plugin:com.flowsaro.reminder.settings",()=>{r=null,o=null,A()}))}catch{}t.onDispose(()=>{if(n&&(clearInterval(n),n=null),null!=z&&"function"==typeof GM_removeValueChangeListener){try{GM_removeValueChangeListener(z)}catch{}z=null}i=[],a=[]})}},{manifest:{...Ge,icon:"data:image/svg+xml;utf8,"+encodeURIComponent('步'),description:"把你在页面上做的一串动作录下来,以后一键重放:点图标打开面板 → 「开始录制」后正常点击与填写 → 关掉那条任务卡即可保存;播放时会按录好的顺序重新点一遍。录的是「意图」(多候选选择器)而不是页面快照,所以页面小改版仍能命中;密码框不记录。M1 只在当前这一个页面里录、在它自己的站点里放,暂不支持跨页跳转与定时",builtin:!0},init:function(e){const t=e,n="undefined"!=typeof document?document:void 0;let r=!1,o=[],i=null,a=null,s=new Map,l=0,c=null,u=null,d=null,p=null,f="";const h=()=>t.getState("index",[])||[],g=e=>t.setState("index",e),m=e=>t.getState("flow."+e,null),v=e=>t.setState("flow."+e.id,e),b=()=>{const e=Number(t.getValue("waitMs",he));return Number.isFinite(e)&&e>0?e:he};function y(e){const t=e?.target;if(!t)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();if(e!==n){const t=e?.host;if(0===(t&&"string"==typeof t.id?t.id:"").indexOf("app-"))return null}}return t}function w(e){if(Ce(e))return!0;const t=String(e?.tagName||"").toUpperCase();if("TEXTAREA"===t)return!0;if("INPUT"!==t)return!1;const n=Ee(e);return!n||-1!==be.indexOf(n)}function x(e){return"password"===Ee(e)}function k(){t.setState("recording",{site:we(),steps:o}),null!==c&&t.updateToast(c,{text:`🔴 录制中:已录 ${o.length} 步`})}function S(e){const t=Date.now();o.length&&l&&(e.gap=Math.min(t-l,1e4)),l=t,o.push(e),k()}function E(e){if(!r)return;if(x(e))return void t.toast("密码输入框不会记录(出于安全考虑,密码不会被保存)",{type:"warning"});const i=function(e){const t=String(e?.tagName||"").toUpperCase();return"INPUT"===t||"TEXTAREA"===t||"SELECT"===t?String(e?.value??""):ye(e?.textContent)}(e);if(!i)return;const a=Ve(e,n),c=a[0]||"",u=Ie(e),d=o[o.length-1];if(d&&"input"===d.t&&(d.cand?.[0]||"")===c)return d.value=i,d.label=u,d.cand=a,s.set(c,i),l=Date.now(),void k();s.get(c)!==i&&(s.set(c,i),S({t:"input",cand:a,label:u,value:i}))}function C(){if(!r||!i)return;const e=i;try{if(n&&"function"==typeof n.contains&&!n.contains(e))return void(i=null)}catch{}E(e)}function B(e){if(!r)return;const t=y(e);if(!t||"function"!=typeof t.closest)return;if(C(),function(e){return w(e)||"SELECT"===String(e?.tagName||"").toUpperCase()}(t))return;const o=t.closest(me);let i=o||t;if(o&&o!==t&&Le(o)&&(i=t),!ye(i.textContent)){let e=i.parentElement,t=null;for(;e&&e!==n?.body&&!t;)ye(e.textContent)?t=e:e=e.parentElement;t&&!Le(t)&&(i=t)}const a="function"==typeof t.matches&&Boolean(t.matches(me));i===t&&!a&&Le(t)||function(e){if(!e)return!1;if(Ce(e))return!0;if(Me(e))return!0;if(Se(e,"onclick")||Se(e,"role"))return!0;if(Se(e,"aria-label")||Se(e,"title")||Se(e,"placeholder"))return!0;if(Se(e,"tabindex"))return!0;try{if("function"==typeof e.matches&&e.matches("[tabindex]"))return!0}catch{}try{const t="function"==typeof getComputedStyle?getComputedStyle:globalThis?.getComputedStyle;if("function"==typeof t&&"pointer"===t(e)?.cursor)return!0}catch{}try{const t=String(Se(e,"class")||"").toLowerCase();if(/button|btn|menu|command|toggle|clickable|action/.test(t))return!0}catch{}if(ye(e.textContent))return!0;if("INPUT"===String(e?.tagName||"").toUpperCase()){const t=Ee(e);if("submit"===t||"button"===t||"reset"===t)return!0}return!1}(i)&&i&&i!==n.body&&S({t:"click",cand:Ve(i,n),label:Ie(i)})}function N(e){if(!r)return;if("Enter"!==String(e?.key||"")||e?.shiftKey)return;const t=y(e);if(!t)return;const i=Ve(t,n)[0]||"";if(!w(t)&&"SELECT"!==String(t.tagName||"").toUpperCase()&&i!==a)return;C();const s=Ve(t,n),l=o[o.length-1];l&&"submit"===l.t&&(l.cand?.[0]||"")===s[0]||S({t:"submit",cand:s,label:Ie(t)})}function M(e){if(!r)return;const s=y(e);if(!s)return;if(x(s))return void t.toast("密码输入框不会记录(出于安全考虑,密码不会被保存)",{type:"warning"});if("SELECT"===String(s.tagName||"").toUpperCase())return;const l=Ve(s,n),c=l[0]||"",u=o[o.length-1],d=Boolean(u&&"click"===u.t&&(u.cand?.[0]||"")===c);c===a||d||S({t:"click",cand:l,label:Ie(s)}),a=c,i=s,E(s)}function V(e){if(!r)return;const t=y(e);t&&(x(t)||(i=t,E(t)))}function L(e){if(!r)return;y(e)}function T(){r||(we().startsWith("http")?(r=!0,o=[],s=new Map,i=null,a=null,l=0,p=null,t.setState("recording",{site:we(),steps:[]}),n?.addEventListener?.("click",B,!0),n?.addEventListener?.("input",M,!0),n?.addEventListener?.("change",V,!0),n?.addEventListener?.("focusin",L,!0),n?.addEventListener?.("keydown",N,!0),c=t.toast("🔴 录制中:0 步(在页面上正常点击/填写)",{title:"步骤录制",type:"info",timeout:0,severity:"high",busy:!0,note:"📌 点 ✕ 结束录制;密码框不会被记录",onClose:()=>{!function(e=!1){if(c=null,!r)return;if(C(),r=!1,n?.removeEventListener?.("click",B,!0),n?.removeEventListener?.("input",M,!0),n?.removeEventListener?.("change",V,!0),n?.removeEventListener?.("focusin",L,!0),n?.removeEventListener?.("keydown",N,!0),i=null,t.setState("recording",null),!o.length)return void t.toast("没有录到任何步骤(点图标重新开始)",{type:"warning"});const a=Date.now(),s=we(),l="f"+a.toString(36),u=`${je(s)} 流程 ${h().filter(e=>e.site===s).length+1}`,d={v:1,id:l,name:u,site:s,steps:o,updatedAt:a};v(d);const f=h().filter(e=>e.id!==l);f.unshift({id:l,name:u,site:s,steps:d.steps.length,updatedAt:a}),g(f),p=l,o=[],e||t.toast(`已保存「${u}」(${d.steps.length} 步)`,{type:"success"})}(!0)}})):t.toast("这个页面不支持录制(不是普通网页)",{type:"warning"}))}async function A(e,n=0,r=!1){if(d)return void t.toast("正在回放中(想停止就点掉那条任务卡的 ✕)",{type:"warning"});const o=we();if(e.site&&e.site!==o)return void t.toast(`这条流程属于 ${je(e.site)},当前页面是 ${je(o)},没有执行`,{type:"error",note:"请到它自己的站点里打开面板再播放"});t.setState("run",{flowId:e.id,step:0,at:Date.now()}),d=qe({timeoutMs:b(),log:(...e)=>function(...e){try{"function"==typeof t.log&&t.log(...e)}catch{}}("[flow]",...e)});const i=r?"▶️ 继续回放":"▶️ 回放",a=r?"(页面跳转后自动接上)":"";u=t.toast(`${i}「${e.name}」:第 ${n+1}/${e.steps.length} 步${a}`,{title:"步骤回放",type:"info",timeout:0,severity:"high",busy:!0,note:"📌 点 ✕ 立即停止回放",onClose:()=>{d?.abort(),Ae()}});const s=await d.runAll(e.steps,{from:n,onStep:(n,r)=>{null!==u&&t.updateToast(u,{text:`${i}「${e.name}」:第 ${n+1}/${r} 步`}),t.setState("run",{flowId:e.id,step:n+1,at:Date.now()}),function(e){try{const t=globalThis?.sessionStorage;t&&"function"==typeof t.setItem&&t.setItem(Te,JSON.stringify(e))}catch{}}({flowId:e.id,next:n+1,at:Date.now()})}});d=null,t.setState("run",null),Ae(),null!==u&&t.dismissToast(u),u=null,s.ok?t.toast(`「${e.name}」回放完成(${s.done} 步)`,{type:"success"}):t.toast(s.error||"回放失败",{type:s.aborted?"info":"error",...s.aborted?null:{copyable:!0},note:s.aborted?void 0:"在第 "+(s.done+1)+" 步停下:可以在面板里删掉这一步再播"})}function z(){return p?m(p):null}t.declareSettings([{key:"waitMs",label:"每一步找不到元素时,最多等多久再放弃(毫秒,默认 8000)",type:"text",default:String(he),placeholder:String(he)}]);const D=new Set;function I(e,n){const r="input"===e.t&&e.value?` → ${e.value.slice(0,20)}`:"",o=Number(e.gap)>=1e3?` ⏱${(Number(e.gap)/1e3).toFixed(1)}s`:"",i=function(e){const t=(e.cand||[])[0]||"";return t.startsWith("#")||/\[(data-|name=|aria-label=|placeholder=|role=|title=|type=)/.test(t)?"":t.startsWith(fe)?"⚠️ 靠文案定位(文案变了就失效)":/^[a-z]+\./i.test(t)?"⚠️ 靠样式名定位(改版可能失效)":"⚠️ 只能靠位置定位(最容易失效,建议重录)"}(e),a="flow-del-"+n;return D.has(a)||(D.add(a),t.onEvent(a,()=>function(e){const n=$();!n||e<0||e>=n.steps.length||(n.steps.splice(e,1),n.updatedAt=Date.now(),v(n),g(h().map(e=>e.id===n.id?{...e,steps:n.steps.length}:e)),t.openPanel(_()))}(n))),{type:"row",items:[{type:"text",content:`${n+1}. ${De(e)}${r}${o} ${i}`.trimEnd(),style:{size:"sm"}},{type:"button",label:"删除",event:a}]}}function _(){const e=[],t=we();if(r)return e.push({type:"text",content:`录制中:已录 ${o.length} 步(关掉那条常驻任务卡即结束录制)`,style:{weight:"bold"}},{type:"text",content:"密码框不记录;输入框以「填写」记录,点击只记录有语义的元素",style:{color:"secondary",size:"sm"}}),{type:"panel",body:e};const n=h();n.length?e.push({type:"select",event:"flow-pick",value:p||n[0].id,options:n.map(e=>({label:`${e.name}(${je(e.site)} · ${e.steps} 步)`,value:e.id}))}):e.push({type:"text",content:`当前站点(${je(t)})还没有流程。点下面的按钮,然后在页面上正常操作就会录下来。`,style:{color:"secondary",size:"sm"}});const i=z()||(n.length?m(n[0].id):null);return i&&(e.push({type:"divider"}),e.push({type:"text",content:`「${i.name}」共 ${i.steps.length} 步`,style:{weight:"bold",size:"sm"}}),i.site&&i.site!==t&&e.push({type:"text",content:`这条流程属于 ${je(i.site)},要播放请先打开那个站点`,style:{color:"danger",size:"sm"}}),i.steps.length||e.push({type:"text",content:"(还没有步骤)",style:{color:"secondary",size:"sm"}}),i.steps.forEach((t,n)=>e.push(I(t,n))),e.push({type:"button",label:"▶️ 播放这条流程",event:"flow-play",variant:"primary",full:!0},{type:"button",label:"删除整条流程",event:"flow-drop",full:!0})),e.push({type:"divider"},{type:"button",label:"🔴 开始录制",event:"flow-rec",variant:"primary",full:!0},{type:"fieldset",legend:"JSON(导出 / 导入)",body:[{type:"text",content:"导出会把当前流程复制成 JSON(方便备份或在别的机器上导入);粘贴一份 JSON 到这里再点导入即可。",style:{color:"secondary",size:"sm"}},{type:"textarea",event:"flow-json",value:f,placeholder:"粘贴流程 JSON…"},{type:"row",items:[{type:"button",label:"导出当前流程",event:"flow-export"},{type:"button",label:"导入",event:"flow-import",variant:"primary"}]}]}),{type:"panel",body:e}}function $(){const e=h();return z()||(e.length?m(e[0].id):null)}t.onEvent("flow-pick",e=>{p="string"==typeof e?e:null,t.openPanel(_())}),t.onEvent("flow-rec",()=>{T()}),t.onEvent("flow-play",()=>{const e=$();e?A(e):t.toast("先录一条流程",{type:"warning"})}),t.onEvent("flow-drop",()=>{const e=$();e&&(t.setState("flow."+e.id,null),g(h().filter(t=>t.id!==e.id)),p=null,t.toast(`已删除「${e.name}」`,{type:"success"}),t.openPanel(_()))}),t.onEvent("flow-json",e=>{f="string"==typeof e?e:""}),t.onEvent("flow-export",()=>{const e=$();if(!e)return void t.toast("没有可导出的流程",{type:"warning"});const n=(r=e,JSON.stringify(r,null,2));var r;f=n,t.copyText?.(n),t.toast(`已复制「${e.name}」的 JSON(${e.steps.length} 步)`,{type:"success",copyable:!0,note:"到别的机器上粘贴进这里的输入框再点「导入」"}),t.openPanel(_())}),t.onEvent("flow-import",()=>{const e=function(e){let t;try{t=JSON.parse(String(e||""))}catch{return{error:"不是合法的 JSON(可以从面板点「导出」复制一份看看格式)"}}if(!t||"object"!=typeof t)return{error:"内容不是一条流程(应该是一个对象)"};const n=t;if(1!==n.v)return{error:"格式版本不认识(只支持 v1)"};if(!Array.isArray(n.steps))return{error:"缺少 steps(步骤数组)"};const r=[];for(let e=0;e"string"==typeof e):[];if(!o.length)return{error:`第 ${e+1} 步没有可以定位的选择器(cand 是空的)`};r.push({t:t.t,cand:o,..."string"==typeof t.label?{label:t.label}:null,..."string"==typeof t.value?{value:t.value}:null,...t.masked?{masked:!0}:null,..."number"==typeof t.gap&&Number.isFinite(t.gap)?{gap:t.gap}:null})}return{flow:{v:1,id:String(n.id||""),name:String(n.name||""),site:String(n.site||""),steps:r,updatedAt:Number(n.updatedAt)||0}}}(f);if(!e.flow)return void t.toast(e.error||"导入失败",{type:"error"});const n=e.flow,r=Date.now(),o=n.id||"f"+r.toString(36),i=n.site||we(),a={v:1,id:o,name:n.name||`${je(i)} 流程`,site:i,steps:n.steps,updatedAt:r};v(a);const s=h().filter(e=>e.id!==o);s.unshift({id:o,name:a.name,site:i,steps:a.steps.length,updatedAt:r}),g(s),p=o,t.toast(`已导入「${a.name}」(${a.steps.length} 步,属于 ${je(i)})`,{type:"success",note:i===we()?void 0:"要播放它请先打开这个站点"}),t.openPanel(_())}),function(){const e=function(){try{const e=globalThis?.sessionStorage;if(!e||"function"!=typeof e.getItem)return null;const t=e.getItem(Te);if(!t)return null;const n=JSON.parse(t),r=String(n.flowId||""),o=Number(n.next),i=Number(n.at);return!r||!Number.isFinite(o)||o<0||!Number.isFinite(i)?null:{flowId:r,next:o,at:i}}catch{return null}}();if(!e)return;if(Ae(),Date.now()-e.at>9e4)return;const t=m(e.flowId);!t||!t.steps.length||e.next<=0||e.next>=t.steps.length||t.site&&t.site!==we()||(p=t.id,A(t,e.next,!0))}(),t.onActivate(async()=>{d?t.toast("正在回放中(停止请关掉那条常驻任务卡)",{type:"warning"}):await t.openPanel(_())}),t.onDispose(()=>{r&&(r=!1,n?.removeEventListener?.("click",B,!0),n?.removeEventListener?.("input",M,!0),n?.removeEventListener?.("change",V,!0),n?.removeEventListener?.("focusin",L,!0),n?.removeEventListener?.("keydown",N,!0)),d?.abort(),null!==c&&t.dismissToast(c),null!==u&&t.dismissToast(u)})}}];const He="sc:",Ye={get(e,t){try{if("function"!=typeof GM_getValue)return t;const n=GM_getValue(He+e,"");return n?JSON.parse(String(n)):t}catch{return t}},set(e,t){try{if("function"!=typeof GM_setValue)return;GM_setValue(He+e,JSON.stringify(t))}catch{}},watch(e,t){if("function"!=typeof GM_addValueChangeListener)return()=>{};try{const n=GM_addValueChangeListener(He+e,(e,n,r)=>{t(r)});return()=>{if("function"==typeof GM_removeValueChangeListener)try{GM_removeValueChangeListener(n)}catch{}}}catch{return()=>{}}}};const Je={request:async(e,t)=>{try{return await async function(e,t){const n=new AbortController,r=setTimeout(()=>n.abort(),t?.timeout||1e4);try{const r=await fetch(e,{method:t?.method||"GET",headers:t?.headers,body:t?.data,signal:n.signal});return{ok:r.ok,status:r.status,text:await r.text()}}finally{clearTimeout(r)}}(e,t)}catch(n){if("AbortError"===n?.name||"function"!=typeof GM_xmlhttpRequest)return{ok:!1,status:0,text:""};const r=await async function(e,t){let n=!1;const r=e=>{const t=e.effectiveDirective||e.violatedDirective||"";"connect-src"!==t&&"default-src"!==t||(n=!0)},o="undefined"!=typeof document?document:void 0;o?.addEventListener("securitypolicyviolation",r,!0);const i=new AbortController,a=setTimeout(()=>i.abort(),t);try{return await fetch(e,{method:"HEAD",mode:"no-cors",cache:"no-store",signal:i.signal}),"blocked"}catch{return n?"blocked":(await new Promise(e=>setTimeout(e,100)),n?"blocked":"down")}finally{clearTimeout(a),o?.removeEventListener("securitypolicyviolation",r,!0)}}(e,Math.min(t?.timeout||1e4,5e3));return"down"===r?{ok:!1,status:0,text:""}:function(e,t){return new Promise(n=>{if("function"==typeof GM_xmlhttpRequest)try{GM_xmlhttpRequest({method:t?.method||"GET",url:e,headers:t?.headers,data:t?.data,timeout:t?.timeout||1e4,overrideMimeType:"text/plain; charset=utf-8",onload:e=>n({ok:e.status>=200&&e.status<300,status:e.status,text:e.responseText||""}),onerror:()=>n({ok:!1,status:0,text:""}),ontimeout:()=>n({ok:!1,status:0,text:""})})}catch{n({ok:!1,status:0,text:""})}else n({ok:!1,status:0,text:""})})}(e,t)}}};let We=null;function Xe(){return We||(We=function(e,t=[]){return new N(e,t)}({storage:Ye,http:Je,clipboard:{read:async()=>{try{return await(navigator.clipboard?.readText())||""}catch{return""}},write:async e=>{try{await(navigator.clipboard?.writeText(e))}catch{}}},getSelectedText:()=>window.getSelection()?.toString()||"",getPageUrl:()=>window.location.href,log:(...e)=>console.log("[plugin]",...e)},Fe)),We}function Ke(){return GM_info.script.icon}function Ze(e){const t=(e||"").trim();if(!t)return Ke();const n=t.match(/data:([^;,]+);base64,\s*([A-Za-z0-9+/=]+)/i);if(n)return`data:${n[1]};base64,${n[2]}`;const r=t.replace(/\s+/g,"");return/^[A-Za-z0-9+/=]+$/.test(r)?`data:${o=r,o.startsWith("R0lGOD")?"image/gif":o.startsWith("UklGR")?"image/webp":"image/png"};base64,${r}`:t.startsWith("data:")?t:"data:image/png;base64,"+r;var o}const Qe=2147483646,et="builtin:refresh",tt='',nt="data:image/svg+xml;utf8,"+encodeURIComponent(''+tt+''),rt="data:image/svg+xml;utf8,"+encodeURIComponent(''+tt+''),ot=[{id:et,name:"刷新网页",icon:nt,run:()=>location.reload()},{id:"builtin:incognito",name:"隐身打开",icon:rt,run:()=>"function"!=typeof GM_openInTab?{text:"当前脚本管理器不支持隐身打开",note:"需要脚本猫 1.2 及以上;Tampermonkey 与 Firefox 不支持此参数(详见脚本说明文档)",type:"warning",timeout:8e3}:(GM_openInTab(location.href,{incognito:!0,active:!0}),{text:"已在隐身窗口打开这个页面",note:"没看到新窗口、或新窗口没有隐身标识?请在扩展管理页勾选「允许在隐身模式下运行」",type:"info",timeout:8e3})}];function it(e){if(e)return ot.find(t=>t.id===e)}function at(t,n,r){const o=r?r(GM_getValue(t,n)):GM_getValue(t,n),i=(0,e.ref)(o);try{const o=GM_addValueChangeListener(t,(e,t,o)=>{i.value=r?r(o):o??n});(0,e.onScopeDispose)(()=>{try{GM_removeValueChangeListener(o)}catch{}})}catch{}return i}function st(e){return t=>null==t?e:Boolean(t)}function lt(e){return t=>null==t?e:String(t)}function ct(){return e=>{const t=parseFloat(String(e??1));if(isNaN(t))return 1;const n=Math.floor(10*t)/10;return Math.min(4,Math.max(.6,n))}}function ut(){return e=>{const t=parseFloat(String(e??1));if(isNaN(t))return 1;const n=Math.round(20*t)/20;return Math.min(1,Math.max(.3,n))}}function dt(){return e=>Math.min(8,Math.max(2,parseInt(String(e??4),10)||4))}function pt(){return e=>Ze(String(e||""))}function ft(){return e=>Array.isArray(e)?e.join("\n"):null==e?"":String(e)}const ht="app.welcomeShown";const gt="app.selectionMenuHintAt";function mt(e,t){const n=Date.now();return!(n-(Number(GM_getValue(e,0))||0)String(e??1)),b=at("general.menuSlots","4",e=>String(e??4)),y=at("general.quickMenu",!1,st(!1)),w=at("general.btnAnim","none",lt("none")),x=at("general.btnOpacity",1,ut()),k=at("general.btnMirror",!1,st(!1)),S=at("general.btnRotate",0,e=>{const t=parseFloat(String(e??0));return isNaN(t)?0:Math.min(360,Math.max(0,Math.round(t)))});(0,e.watch)(S,e=>i("rotate-change",e)),(0,e.watch)(x,e=>{const t=Number(e);i("opacity-change",isNaN(t)?1:t)}),(0,e.watch)(w,e=>i("anim-change",e)),(0,e.watch)(m,e=>i("bg-change",e)),(0,e.watch)(k,e=>i("mirror-change",e)),(0,e.watch)(v,e=>{const t=parseFloat(String(e));i("scale-change",isNaN(t)?1:t)});const E=(0,e.ref)(""),C=at("general.customIcon","",lt("")),B=(0,e.ref)("");const N=at("general.iconList",[],function(e){try{let t=[];if(Array.isArray(e))t=e.map(String).filter(Boolean);else{const n=null==e?"":String(e),r=n?JSON.parse(n):[];Array.isArray(r)&&(t=r.filter(e=>"string"==typeof e&&e.trim()))}return t.includes(s)||t.push(s),t.length>12&&(t=t.slice(0,11).concat(s)),t}catch{return[s]}}),M=(0,e.ref)(N.value.includes(C.value)?C.value:null),V=(0,e.ref)(!1),L=(0,e.ref)(!1),T=(0,e.ref)(null);function A(e){return function(e){const t=e.match(/base64,([A-Za-z0-9+/=]+)/),n=t?t[1]:e,r=n.endsWith("==")?2:n.endsWith("=")?1:0;return Math.floor(3*n.length/4)-r}(e)>51200?(B.value="图片超过 50KB,无法添加",!1):!N.value.includes(e)&&N.value.length>=12?(B.value="图标列表最多 12 个",!1):(B.value="",e===s||(N.value.includes(e)?N.value=[e,...N.value.filter(t=>t!==e)]:N.value.unshift(e),GM_setValue("general.iconList",JSON.stringify(N.value))),!0)}function z(){const e=E.value.trim();if(!e)return;const t=Ze(e);A(t)&&(M.value=t,E.value="",i("icon-change",t))}(0,e.watch)(C,e=>{e&&N.value.includes(e)&&(M.value=e)});const D=(0,e.ref)(null);function I(){D.value?.click()}function _(e){const t=e.target,n=t.files?.[0];if(t.value="",!n)return;if(n.size>51200)return void(B.value="图片不能超过 50KB");const r=new FileReader;r.onload=()=>{const e=String(r.result||"");if(!e)return;const t=Ze(e);A(t),M.value=t,i("icon-change",t)},r.readAsDataURL(n)}function $(){const e=T.value;e&&(L.value=e.scrollHeight>e.clientHeight+2)}const R=at("general.disabledSites","",ft()),P=(0,e.computed)(()=>{const e=o.btnSize??46,t=o.anchor.x+e+20,n=Qe,r=Math.max(0,window.innerHeight-p.value-12);return{right:t+"px",bottom:Math.min(o.anchor.y,r)+"px",zIndex:n}});function U(){const e=location.hostname,t=R.value.split("\n").map(e=>e.trim()).filter(Boolean);t.includes(e)||t.push(e),R.value=t.join("\n")}const q=(0,e.ref)("general"),j=[{key:"general",label:"常规"},{key:"menu",label:"快捷菜单"},{key:"plugin",label:"插件管理"}],G=Xe(),O=(0,e.ref)([]),F=(0,e.ref)([]),H=(0,e.ref)(""),Y=(0,e.ref)(!1),J=(0,e.ref)(""),W=(0,e.ref)(null),X=(0,e.ref)(null),K=(0,e.ref)(new Set),Z=(0,e.computed)(()=>Math.min(8,Math.max(2,parseInt(b.value,10)||4)));function Q(){O.value=G.list();const e=Z.value,t=G.getBindings();F.value=[];for(let n=0;n{J.value=String(r.result||""),H.value=""},r.readAsText(n)}const ne=(0,e.computed)(()=>G.getPluginErrors());function re(e){return G.getSettings(e)}const oe=(0,e.ref)({});function ie(e,t){return e+"::"+t}function ae(e,t){const n=ie(e,t.key);if(n in oe.value)return oe.value[n];const r=G.getPluginSetting(e,t.key);return void 0!==r?r:t.default??""}function se(e,t,n){oe.value={...oe.value,[ie(e,t)]:n}}function le(e,t,n){G.setPluginSetting(e,t,n);const r=ie(e,t);if(r in oe.value){const e={...oe.value};delete e[r],oe.value=e}}function ce(){Object.keys(oe.value).forEach(e=>{const t=e.indexOf("::");t<0||le(e.slice(0,t),e.slice(t+1),oe.value[e])})}function ue(e){return G.isEnabled(e)}function de(){const e=J.value.trim();if(!e)return;const t=G.install(e);Y.value=t.ok,H.value=t.ok?"shortcut"===t.type?`安装成功:${t.id}(快捷功能,请到「快捷菜单」标签绑定槽位后使用)`:`安装成功:${t.id}`:`安装失败:${t.error||"未知错误"}`,t.ok&&(J.value=""),Q()}function pe(e){return K.value.has(e)}function fe(e){const t=new Set(F.value.filter((t,n)=>n!==e&&t)),n=ot.filter(e=>!t.has(e.id)).map(e=>({id:e.id,label:e.name})),r=O.value.filter(e=>"shortcut"===e.manifest.type&&!t.has(e.manifest.id)).map(e=>({id:e.manifest.id,label:e.manifest.name})),o=[];return n.length&&o.push({label:"内置功能",options:n}),r.length&&o.push({label:"插件",options:r}),o}function he(){const e=E.value.trim();let t="";e?t=Ze(e):M.value?t=M.value:N.value.length&&(t=N.value[0]),GM_setValue("general.githubAccel",f.value),GM_setValue("general.backTop",h.value),GM_setValue("general.alwaysShow",g.value),GM_setValue("general.noBtnBg",m.value),GM_setValue("general.iconScale",function(e){const t=parseFloat(e);if(isNaN(t))return 1;const n=Math.floor(10*t)/10;return Math.min(4,Math.max(.6,n))}(v.value)),GM_setValue("general.menuSlots",Math.min(8,Math.max(2,parseInt(b.value,10)||4))),GM_setValue("general.quickMenu",y.value),GM_setValue("general.btnAnim",w.value),GM_setValue("general.btnRotate",S.value),GM_setValue("general.btnOpacity",ut()(x.value)),GM_setValue("general.btnMirror",k.value),GM_setValue("general.customIcon",t),GM_setValue("general.iconList",JSON.stringify(N.value)),GM_setValue("general.disabledSites",R.value);const n=Z.value;for(let e=0;eG.uninstall(e)),K.value=new Set,ce(),function(){const e=new Set(F.value.filter(Boolean)),t=O.value.filter(t=>"shortcut"===t.manifest.type&&ue(t.manifest.id)&&!e.has(t.manifest.id));t.length&&mt("app.shortcutHintAt",432e5)&&i("hint",{text:`「${t.map(e=>e.manifest.name).join("、")}」还没放进快捷菜单,装了也找不到入口`,note:"长按按钮 → 设置 → 快捷菜单 → 槽位绑定选中它(保存后选中文字就会自动亮出菜单)"})}(),i("saved",t),i("close")}function ge(e){const t=d.value?.$el;t&&(e.composedPath().includes(t)||(ce(),i("close")))}return(0,e.onMounted)(()=>{p.value=d.value?.$el.offsetHeight??0,Q(),o.initialTab&&(q.value=o.initialTab),(0,e.nextTick)($),setTimeout(()=>{document.addEventListener("mousedown",ge)},0)}),(0,e.watch)(N,()=>{(0,e.nextTick)($)}),(0,e.watch)(q,t=>{"icon"===t&&(0,e.nextTick)($)}),(0,e.onUnmounted)(()=>{ce(),document.removeEventListener("mousedown",ge)}),(t,r)=>((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(n),{ref_key:"panelRef",ref:d,class:"fixed w-[300px] max-w-[80vw] h-[520px] flex flex-col box-border",style:(0,e.normalizeStyle)(P.value)},{default:(0,e.withCtx)(()=>[(0,e.createElementVNode)("div",vt,[c.value?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:c.value,class:"w-7 h-7 shrink-0 object-contain",alt:l.value},null,8,bt)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("div",yt,[(0,e.createElementVNode)("strong",wt,(0,e.toDisplayString)(l.value+"设置"),1),(0,e.createElementVNode)("span",xt,"v"+(0,e.toDisplayString)(u.value),1)]),(0,e.createCommentVNode)(" ml-auto 把 ✕ 推到标题栏最右(关闭按钮的惯例位置):标题块没有 flex-1,\n 缺了它 ✕ 会紧贴标题文字悬在半空 —— 与插件面板头部(PluginPanelHost)同一模式 "),(0,e.createElementVNode)("button",{type:"button",class:"ml-auto w-6 h-6 flex items-center justify-center rounded-md text-secondary text-lg leading-none transition-colors hover:text-primary hover:bg-white/15",title:"关闭",onClick:r[0]||(r[0]=e=>t.$emit("close"))}," × ")]),(0,e.createCommentVNode)(" 可滚动内容区 "),(0,e.createElementVNode)("div",kt,[(0,e.createVNode)((0,e.unref)(a),{modelValue:q.value,"onUpdate:modelValue":r[23]||(r[23]=e=>q.value=e),items:j},{general:(0,e.withCtx)(()=>[(0,e.createCommentVNode)(" 插件加载错误通知(如 CSP 拦截) "),ne.value.length?((0,e.openBlock)(),(0,e.createElementBlock)("div",St,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(ne.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t.id,class:"flex items-start gap-2 p-2 px-2.5 mb-1.5 text-xs leading-[1.5] rounded-lg bg-warning/15 border border-warning/40 text-warning"},[(0,e.createElementVNode)("span",Et,[(0,e.createElementVNode)("b",null,(0,e.toDisplayString)(t.name),1),(0,e.createTextVNode)(" 加载失败:"+(0,e.toDisplayString)(t.message),1),t.count>1?((0,e.openBlock)(),(0,e.createElementBlock)("span",Ct,"(×"+(0,e.toDisplayString)(t.count)+")",1)):(0,e.createCommentVNode)("v-if",!0)]),(0,e.createElementVNode)("button",{type:"button",class:"shrink-0 border-none bg-transparent text-sm cursor-pointer text-inherit leading-none",onClick:e=>{return n=t.id,void G.clearPluginError(n);var n}}," × ",8,Bt)]))),128))])):(0,e.createCommentVNode)("v-if",!0),(0,e.createCommentVNode)(" 主按钮设置 "),(0,e.createElementVNode)("label",Nt,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[1]||(r[1]=t=>(0,e.isRef)(g)?g.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(g)]]),r[25]||(r[25]=(0,e.createTextVNode)(" 关闭智能隐藏 ",-1))]),(0,e.createElementVNode)("fieldset",Mt,[r[34]||(r[34]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 图标设置 ",-1)),(0,e.createCommentVNode)(" 外观开关:两个小勾选框并排,省一行 "),(0,e.createElementVNode)("div",Vt,[(0,e.createElementVNode)("label",Lt,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[2]||(r[2]=t=>(0,e.isRef)(m)?m.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(m)]]),r[26]||(r[26]=(0,e.createTextVNode)(" 只显示图标 ",-1))]),(0,e.createElementVNode)("label",Tt,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[3]||(r[3]=t=>(0,e.isRef)(k)?k.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(k)]]),r[27]||(r[27]=(0,e.createTextVNode)(" 水平镜像 ",-1))])]),(0,e.createElementVNode)("div",At,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[4]||(r[4]=t=>(0,e.isRef)(v)?v.value=t:null),type:"number",min:"0.6",max:"4",step:"0.1",title:"图标倍率(1x = 26px,最大 4x)",class:"flex-[0_0_52px] w-[52px] p-[5px_6px] text-xs leading-[1.5] border-surface rounded-lg bg-input text-primary transition-shadow sc-field"},null,512),[[e.vModelText,(0,e.unref)(v)]]),r[28]||(r[28]=(0,e.createElementVNode)("span",{class:"text-secondary whitespace-nowrap"},"倍",-1)),(0,e.createElementVNode)("button",{type:"button",class:"flex-1 text-xs px-2.5 py-1 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"设为 2x",onClick:r[5]||(r[5]=e=>v.value="2")}," 2倍 "),(0,e.createElementVNode)("button",{type:"button",class:"flex-1 text-xs px-2.5 py-1 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"重置为默认大小",onClick:r[6]||(r[6]=e=>v.value="1")}," 默认 ")]),(0,e.createCommentVNode)(" 按钮图标动画 "),(0,e.createElementVNode)("label",zt,[r[30]||(r[30]=(0,e.createElementVNode)("span",{class:"shrink-0"},"按钮动画",-1)),(0,e.withDirectives)((0,e.createElementVNode)("select",{"onUpdate:modelValue":r[7]||(r[7]=t=>(0,e.isRef)(w)?w.value=t:null),class:"flex-1 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary select-text transition-shadow sc-field",title:"图标动画(GIF 动图不受影响;系统开启减少动态效果时自动禁用)"},[...r[29]||(r[29]=[(0,e.createElementVNode)("option",{value:"none"},"无",-1),(0,e.createElementVNode)("option",{value:"breathe"},"呼吸",-1),(0,e.createElementVNode)("option",{value:"spin"},"旋转",-1),(0,e.createElementVNode)("option",{value:"pulse"},"脉冲",-1),(0,e.createElementVNode)("option",{value:"ripple"},"涟漪",-1)])],512),[[e.vModelSelect,(0,e.unref)(w)]])]),(0,e.createCommentVNode)(" 按钮透明度:平时淡着,交互时自动回到不透明 "),(0,e.createElementVNode)("label",Dt,[r[31]||(r[31]=(0,e.createElementVNode)("span",{class:"shrink-0"},"不透明度",-1)),(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[8]||(r[8]=t=>(0,e.isRef)(x)?x.value=t:null),type:"number",min:"0.3",max:"1",step:"0.05",class:"w-16 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary transition-shadow sc-field",title:"0.3 ~ 1:平时按这个值淡在页面上",onInput:r[9]||(r[9]=e=>i("opacity-change",Number(e.target.value)))},null,544),[[e.vModelText,(0,e.unref)(x),void 0,{number:!0}]]),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"半透明",onClick:r[10]||(r[10]=e=>x.value=.6)}," 0.6 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"完全不透明(默认)",onClick:r[11]||(r[11]=e=>x.value=1)}," 默认 ")]),r[35]||(r[35]=(0,e.createElementVNode)("p",{class:"mb-2 -mt-1 px-2 -mx-2 text-[11px] text-secondary leading-snug"}," 平时按这个值淡在页面上;鼠标移到按钮上或拖动时会自动变清晰。 设置面板打开期间按你调的值显示(方便边调边看),触摸端不生效 —— 那边淡着只会更难点中 ",-1)),(0,e.createCommentVNode)(" 按钮旋转角度:固定刻度 + 可输入 "),(0,e.createElementVNode)("label",It,[r[32]||(r[32]=(0,e.createElementVNode)("span",{class:"shrink-0"},"旋转",-1)),(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[12]||(r[12]=t=>(0,e.isRef)(S)?S.value=t:null),type:"number",min:"0",max:"360",step:"15",class:"w-16 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary transition-shadow sc-field",title:"主按钮旋转角度(0-360°)"},null,512),[[e.vModelText,(0,e.unref)(S),void 0,{number:!0}]]),r[33]||(r[33]=(0,e.createElementVNode)("span",{class:"text-secondary text-xs"},"°",-1)),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:r[13]||(r[13]=e=>S.value=0)}," 0 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:r[14]||(r[14]=e=>S.value=90)}," 90 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:r[15]||(r[15]=e=>S.value=180)}," 180 "),(0,e.createElementVNode)("button",{type:"button",class:"text-[11px] px-1.5 py-0.5 border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:r[16]||(r[16]=e=>S.value=270)}," 270 ")]),(0,e.createElementVNode)("div",_t,[(0,e.withDirectives)((0,e.createElementVNode)("textarea",{"onUpdate:modelValue":r[17]||(r[17]=e=>E.value=e),rows:"5",placeholder:"data:image/png;base64,...",class:"flex-1 h-16 min-h-0 max-h-24 w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field"},null,512),[[e.vModelText,E.value]]),(0,e.createElementVNode)("div",{class:"flex flex-col gap-1.5 shrink-0"},[(0,e.createElementVNode)("button",{type:"button",class:"w-8 h-8 shrink-0 text-base leading-none border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"添加到图标列表",onClick:z}," + "),(0,e.createElementVNode)("button",{type:"button",class:"w-8 h-8 shrink-0 text-sm leading-none border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",title:"上传图片并转 base64",onClick:I}," 🖼 ")]),(0,e.createElementVNode)("input",{ref_key:"fileInputRef",ref:D,type:"file",accept:"image/*",style:{display:"none"},onChange:_},null,544)]),(0,e.unref)(N).length?((0,e.openBlock)(),(0,e.createElementBlock)("div",$t,[(0,e.createElementVNode)("div",{ref_key:"listRef",ref:T,class:"flex flex-wrap gap-1 p-1",style:(0,e.normalizeStyle)({maxHeight:V.value?"none":"36px",overflow:"hidden"})},[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)((0,e.unref)(N),t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t,class:"relative"},[(0,e.createElementVNode)("img",{src:t,class:"w-8 h-8 p-1 object-contain rounded-lg bg-input cursor-pointer block border-surface transition-transform hover:scale-110",style:(0,e.normalizeStyle)(t===M.value?{borderColor:"var(--color-save-border)"}:void 0),title:t.slice(0,60),onClick:e=>function(e){M.value=e,i("icon-change",e)}(t)},null,12,Rt),t!==(0,e.unref)(s)?((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"absolute -top-1 -right-1 w-[13px] h-[13px] leading-none text-[10px] p-0 border-none rounded-full bg-black/60 text-white cursor-pointer flex items-center justify-center",title:"从列表移除",onClick:(0,e.withModifiers)(e=>function(e){e!==s&&(B.value="",N.value=N.value.filter(t=>t!==e),M.value===e&&(M.value=N.value[0],i("icon-change",M.value)))}(t),["stop"])}," × ",8,Pt)):(0,e.createCommentVNode)("v-if",!0)]))),128))],4),V.value||L.value?((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"mt-1.5 text-[11px] px-2 py-0.5 border-surface rounded-md bg-subtle-btn text-secondary cursor-pointer",onClick:r[18]||(r[18]=e=>V.value=!V.value)},(0,e.toDisplayString)(V.value?"收起":"展开全部("+(0,e.unref)(N).length+")"),1)):(0,e.createCommentVNode)("v-if",!0)])):(0,e.createCommentVNode)("v-if",!0),B.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",Ut,(0,e.toDisplayString)(B.value),1)):(0,e.createCommentVNode)("v-if",!0)]),(0,e.createElementVNode)("fieldset",qt,[r[36]||(r[36]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 在以下站点禁用 ",-1)),(0,e.createCommentVNode)(" 站点(禁用返回按钮) "),(0,e.createElementVNode)("div",{class:"flex justify-between items-baseline p-0 pb-[5px]"},[(0,e.createElementVNode)("button",{type:"button",class:"!mt-0 !pt-0 text-xs px-2.5 pb-[3px] border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:U}," 添加当前网站 ")]),(0,e.withDirectives)((0,e.createElementVNode)("textarea",{"onUpdate:modelValue":r[19]||(r[19]=t=>(0,e.isRef)(R)?R.value=t:null),rows:"3",placeholder:"例如:baidu.com",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field"},null,512),[[e.vModelText,(0,e.unref)(R)]])])]),menu:(0,e.withCtx)(()=>[(0,e.createElementVNode)("fieldset",jt,[r[39]||(r[39]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 快捷菜单设置 ",-1)),(0,e.createElementVNode)("label",Gt,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[20]||(r[20]=t=>(0,e.isRef)(y)?y.value=t:null),type:"checkbox",class:"accent-accent"},null,512),[[e.vModelCheckbox,(0,e.unref)(y)]]),r[37]||(r[37]=(0,e.createTextVNode)(" 启用快捷功能 ",-1))]),(0,e.createCommentVNode)(" 说清这个开关**管不到**什么:否则用户关了它却仍看到划词弹菜单,会当成 bug "),r[40]||(r[40]=(0,e.createElementVNode)("p",{class:"mb-2 -mt-1 px-2 -mx-2 text-[11px] text-secondary leading-snug"}," 只控制「悬停 / 双击」展开。插件主动弹出的菜单(如选中文字后的快捷翻译)不受此开关限制, 想彻底关闭 → 解绑下方「快捷菜单槽位绑定」里的插件 ↓ 或禁用该插件 ",-1)),(0,e.createElementVNode)("label",Ot,[(0,e.withDirectives)((0,e.createElementVNode)("input",{"onUpdate:modelValue":r[21]||(r[21]=t=>(0,e.isRef)(b)?b.value=t:null),type:"number",min:"2",max:"8",step:"1",class:"w-12 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary transition-shadow sc-field"},null,512),[[e.vModelText,(0,e.unref)(b)]]),r[38]||(r[38]=(0,e.createTextVNode)(" 设置快捷菜单数量 ",-1))])]),(0,e.createElementVNode)("fieldset",Ft,[r[42]||(r[42]=(0,e.createElementVNode)("legend",{class:"text-[11px] px-2 py-0.5 rounded-full bg-chip text-accent font-medium"}," 快捷菜单槽位绑定(保存后生效) ",-1)),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(Z.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t,class:"flex items-center gap-1.5 mb-1 text-xs"},[(0,e.createElementVNode)("span",Ht,"槽位 "+(0,e.toDisplayString)(t),1),(0,e.withDirectives)((0,e.createElementVNode)("select",{"onUpdate:modelValue":e=>F.value[t-1]=e,class:"flex-1 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary select-text transition-shadow sc-field"},[r[41]||(r[41]=(0,e.createElementVNode)("option",{value:""},"(空)",-1)),(0,e.createCommentVNode)(" 分两组:内置功能(脚本自带,如「刷新网页」)+ 插件(shortcut 类) "),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(fe(t-1),t=>((0,e.openBlock)(),(0,e.createElementBlock)("optgroup",{key:t.label,label:t.label},[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(t.options,t=>((0,e.openBlock)(),(0,e.createElementBlock)("option",{key:t.id,value:t.id},(0,e.toDisplayString)(t.label),9,Wt))),128))],8,Jt))),128))],8,Yt),[[e.vModelSelect,F.value[t-1]]])]))),128))])]),plugin:(0,e.withCtx)(()=>[(0,e.createElementVNode)("div",Xt,[(0,e.createElementVNode)("button",{type:"button",class:"mt-1.5 text-xs px-2.5 py-[3px] border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:ee}," 从文件导入 "),(0,e.createElementVNode)("input",{ref_key:"pluginFileInputRef",ref:W,type:"file",accept:".js,.txt",style:{display:"none"},onChange:te},null,544),(0,e.createElementVNode)("button",{type:"button",class:"mt-1.5 text-xs px-2.5 py-[3px] border-surface rounded-lg bg-subtle-btn text-primary cursor-pointer transition-colors hover:bg-white/15 active:scale-[0.97]",onClick:de}," 立即安装 ")]),(0,e.withDirectives)((0,e.createElementVNode)("textarea",{"onUpdate:modelValue":r[22]||(r[22]=e=>J.value=e),rows:"4",placeholder:"粘贴插件代码(含 ==Plugin== 头),或点击上方导入文件后点「立即安装」...",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field"},null,512),[[e.vModelText,J.value]]),H.value?((0,e.openBlock)(),(0,e.createElementBlock)("span",{key:0,class:"block mt-1 text-[11px]",style:(0,e.normalizeStyle)({color:Y.value?"var(--color-save-border)":"var(--color-danger)"})},(0,e.toDisplayString)(H.value),5)):(0,e.createCommentVNode)("v-if",!0),O.value.length?((0,e.openBlock)(),(0,e.createElementBlock)("div",Kt,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(O.value,t=>{return(0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t.manifest.id,class:"mb-0.5 text-xs"},[(0,e.createElementVNode)("div",{class:"flex items-center gap-1.5 cursor-pointer py-1 rounded-lg px-1 -mx-1 transition-colors hover:bg-white/10",onClick:e=>{return n=t.manifest.id,void(X.value=X.value===n?null:n);var n}},[(0,e.createElementVNode)("span",Qt,(0,e.toDisplayString)(X.value===t.manifest.id?"▾":"▸"),1),t.manifest.icon?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:t.manifest.icon,class:"w-4 h-4 object-contain"},null,8,en)):((0,e.openBlock)(),(0,e.createElementBlock)("span",tn,(0,e.toDisplayString)((t.manifest.name||"?").charAt(0)),1)),(0,e.createElementVNode)("span",{class:"flex-1",style:(0,e.normalizeStyle)({textDecoration:pe(t.manifest.id)?"line-through":"none",opacity:pe(t.manifest.id)?.5:1})},[(0,e.createTextVNode)((0,e.toDisplayString)(t.manifest.name)+" ",1),(0,e.createElementVNode)("span",nn,"v"+(0,e.toDisplayString)(t.manifest.version),1),t.manifest.builtin?((0,e.openBlock)(),(0,e.createElementBlock)("span",rn,"内置")):(0,e.createCommentVNode)("v-if",!0)],4)],8,Zt),X.value===t.manifest.id?((0,e.openBlock)(),(0,e.createElementBlock)("div",on,[(0,e.createElementVNode)("div",null,[r[43]||(r[43]=(0,e.createTextVNode)(" 类型:",-1)),(0,e.createElementVNode)("b",null,(0,e.toDisplayString)((n=t.manifest.type,"feature"===n?"后台运行":"shortcut"===n?"快捷功能":n)),1),t.manifest.permissions&&t.manifest.permissions.length?((0,e.openBlock)(),(0,e.createElementBlock)("span",an," · 权限:"+(0,e.toDisplayString)((t.manifest.permissions||[]).join(", ")),1)):(0,e.createCommentVNode)("v-if",!0)]),t.manifest.description?((0,e.openBlock)(),(0,e.createElementBlock)("div",sn,(0,e.toDisplayString)(t.manifest.description),1)):(0,e.createCommentVNode)("v-if",!0),pe(t.manifest.id)?((0,e.openBlock)(),(0,e.createElementBlock)("div",ln," ⚠ 卸载将清空该插件的所有数据(设置等) ")):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("div",cn,[(0,e.createElementVNode)("label",un,[(0,e.createElementVNode)("input",{type:"checkbox",checked:ue(t.manifest.id),onChange:e=>{return n=t.manifest.id,void G.setEnabled(n,!G.isEnabled(n));var n}},null,40,dn),r[44]||(r[44]=(0,e.createTextVNode)(" 启用 ",-1))]),t.manifest.builtin?((0,e.openBlock)(),(0,e.createElementBlock)("span",fn,"内置")):((0,e.openBlock)(),(0,e.createElementBlock)("button",{key:0,type:"button",class:"mt-1.5 text-xs px-2.5 py-[3px] border-surface rounded-md bg-subtle-btn cursor-pointer",style:(0,e.normalizeStyle)({color:pe(t.manifest.id)?"var(--color-danger)":"var(--color-primary)"}),onClick:(0,e.withModifiers)(e=>function(e){const t=new Set(K.value);t.has(e)?t.delete(e):t.add(e),K.value=t}(t.manifest.id),["stop"])},(0,e.toDisplayString)(pe(t.manifest.id)?"取消卸载":"卸载"),13,pn))]),(0,e.createCommentVNode)(" 插件设置表单:与上面的「类型/描述/启用」同为整行内容,**不缩进**。 "),re(t.manifest.id).length?((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,{key:2},(0,e.renderList)(re(t.manifest.id),n=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:n.key,class:"mt-1.5"},[(0,e.createElementVNode)("div",hn,(0,e.toDisplayString)(n.label),1),"text"===n.type||"password"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("input",{key:0,type:n.type,value:ae(t.manifest.id,n),placeholder:n.placeholder||"",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field",onInput:e=>se(t.manifest.id,n.key,e.target.value),onChange:e=>le(t.manifest.id,n.key,e.target.value)},null,40,gn)):"textarea"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("textarea",{key:1,value:String(ae(t.manifest.id,n)??""),placeholder:n.placeholder||"",rows:"4",class:"w-full box-border px-2 py-1.5 text-xs leading-[1.5] border-surface rounded-lg resize-y font-[inherit] bg-input text-primary select-text transition-shadow sc-field",onInput:e=>se(t.manifest.id,n.key,e.target.value),onChange:e=>le(t.manifest.id,n.key,e.target.value)},null,40,mn)):"select"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("select",{key:2,value:ae(t.manifest.id,n),class:"flex-1 px-1.5 py-1 text-xs border-surface rounded-lg bg-input text-primary select-text transition-shadow sc-field",onChange:e=>le(t.manifest.id,n.key,e.target.value)},[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(n.options||[],t=>((0,e.openBlock)(),(0,e.createElementBlock)("option",{key:t.value,value:t.value},(0,e.toDisplayString)(t.label),9,bn))),128))],40,vn)):"checkbox"===n.type?((0,e.openBlock)(),(0,e.createElementBlock)("label",yn,[(0,e.createElementVNode)("input",{type:"checkbox",checked:!!ae(t.manifest.id,n),onChange:e=>le(t.manifest.id,n.key,e.target.checked)},null,40,wn),r[45]||(r[45]=(0,e.createTextVNode)(" 启用 ",-1))])):(0,e.createCommentVNode)("v-if",!0)]))),128)):(0,e.createCommentVNode)("v-if",!0)])):(0,e.createCommentVNode)("v-if",!0)]);var n}),128))])):((0,e.openBlock)(),(0,e.createElementBlock)("div",xn,"暂无插件,点击上方导入"))]),_:1},8,["modelValue"])]),(0,e.createCommentVNode)(" 底部固定操作栏 "),(0,e.createElementVNode)("div",kn,[(0,e.createElementVNode)("button",{type:"button",class:"text-xs px-3 py-1.5 border-surface rounded-lg text-secondary cursor-pointer transition-colors hover:bg-white/10 hover:text-primary",onClick:r[24]||(r[24]=e=>t.$emit("close"))}," 取消 "),(0,e.createElementVNode)("button",{type:"button",class:"text-xs px-4 py-1.5 border border-save-border rounded-lg bg-save-btn text-white font-medium cursor-pointer shadow-sm transition hover:opacity-90 active:scale-[0.97]",onClick:he}," 保存 ")])]),_:1},8,["style"]))}}),En=["onClick"],Cn=["src"],Bn=(0,e.defineComponent)({__name:"QuickMenu",props:{show:{type:Boolean},bindings:{},slotCount:{},btnSize:{},anchorY:{},enterDelay:{}},emits:["close","slot","empty","hoverIn","hoverOut"],setup(t,{emit:n}){const r=t,o=n,i=(0,e.computed)(()=>function(e,t){const n=[];for(let r=0;ri.value.length42*(i.value.length+(a.value?1:0))-6+16),l=(0,e.computed)(()=>r.anchorY({top:l.value?"auto":r.btnSize+20+"px",bottom:l.value?r.btnSize+20+"px":"auto",transform:"translateX(-50%)",borderColor:"var(--sc-surface-border)",zIndex:Qe}));function u(e,t){return`translateX(-50%) translateY(${e}px) scale(${t})`}function d(e,t,n,r,o,i=0){const a=e;a.getAnimations().forEach(e=>e.cancel());const s=a.animate(t,{duration:n,easing:r,delay:i,fill:"backwards"});s.onfinish=()=>o(),s.oncancel=()=>o()}let p=0;function f(e,t){const n=l.value?12:-12,o=r.enterDelay??0;p=o>0?performance.now()+o:0,d(e,[{opacity:0,transform:u(n,.86),filter:"blur(6px)"},{opacity:1,transform:u(0,1),filter:"blur(0px)"}],220,"cubic-bezier(0.2, 0.9, 0.25, 1)",t,o)}function h(e,t){if(p>0&&performance.now()e.cancel()),void t();p=0;const n=l.value?8:-8;d(e,[{opacity:1,transform:u(0,1),filter:"blur(0px)"},{opacity:0,transform:u(n,.9),filter:"blur(5px)"}],150,"ease-in",t)}function g(){o("close"),o("empty",0)}return(n,r)=>((0,e.openBlock)(),(0,e.createElementBlock)(e.Fragment,null,[(0,e.createCommentVNode)(" 竖条快捷菜单:容器内 absolute 定位,内部 flex 纵向排列(浏览器自动对齐) "),(0,e.createVNode)(e.Transition,{css:!1,onEnter:f,onLeave:h},{default:(0,e.withCtx)(()=>[t.show?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,style:(0,e.normalizeStyle)(c.value),class:"absolute left-1/2 flex flex-col items-center gap-1.5 p-1.5 rounded-full bg-panel border backdrop-blur-[10px] backdrop-saturate-150 shadow-panel",onMouseenter:r[2]||(r[2]=e=>o("hoverIn")),onMouseleave:r[3]||(r[3]=e=>o("hoverOut"))},[(0,e.createCommentVNode)("\n ⚠️ 每个槽位都 `@mousedown.prevent`:mousedown 的默认行为会 collapse 页面选区,\n 于是「划词 → 点图标」这条链路会在按下的一瞬间丢掉刚选中的文字(更糟的是选区一空,\n 宿主就把插件自动打开的菜单收起,click 可能根本落不到槽位上)。\n 阻止默认行为后选区原样保留,点击与「实时选区」都稳。\n "),((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(i.value,t=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:t.slot,class:"w-9 h-9 flex items-center justify-center rounded-[10px] cursor-pointer select-none text-primary",onClick:e=>{return n=t.slot,o("close"),void o("slot",n);var n},onMousedown:r[0]||(r[0]=(0,e.withModifiers)(()=>{},["prevent"]))},[(0,e.createElementVNode)("img",{src:t.icon,class:"w-5 h-5 object-contain pointer-events-none"},null,8,Cn)],40,En))),128)),(0,e.createCommentVNode)(" 「+」单独一块(不是槽位):只在还有空位时出现,点了去设置面板绑定 "),a.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,class:"w-9 h-9 flex items-center justify-center rounded-[10px] cursor-pointer select-none text-menu-plus",title:"点击绑定快捷功能",onClick:g,onMousedown:r[1]||(r[1]=(0,e.withModifiers)(()=>{},["prevent"]))},[...r[4]||(r[4]=[(0,e.createElementVNode)("span",{class:"text-xl font-bold leading-none pointer-events-none"},"+",-1)])],32)):(0,e.createCommentVNode)("v-if",!0)],36)):(0,e.createCommentVNode)("v-if",!0)]),_:1})],2112))}}),Nn={class:"flex items-center gap-2 mb-2.5 shrink-0 sc-gutter-align"},Mn=["src"],Vn={class:"text-[13px]"},Ln={class:"min-h-0 flex-1 overflow-y-auto px-2 sc-gutter"},Tn=(0,e.defineComponent)({__name:"PluginPanelHost",props:{req:{},anchor:{},btnSize:{}},emits:["close","plugin-event"],setup(t,{emit:r}){const o=t,i=r,a=(0,e.computed)(()=>{const e=o.req.spec;return e&&"panel"===e.type&&e.title||"插件"}),s=Xe(),l=(0,e.computed)(()=>s.getPluginIcon(o.req.pluginId)),c=(0,e.computed)(()=>{const e=o.req.spec;return e&&"panel"===e.type&&e.body||[]}),u=(0,e.ref)(null),d=(0,e.ref)(0);let p=null;(0,e.onMounted)(()=>{const e=u.value?.$el;e&&(d.value=e.offsetHeight,p=new ResizeObserver(()=>{d.value=e.offsetHeight}),p.observe(e))}),(0,e.onBeforeUnmount)(()=>p?.disconnect());const f=(0,e.computed)(()=>{const e=o.btnSize??46,t=o.anchor?.x??20,n=o.anchor?.y??20,r=Math.max(0,window.innerHeight-d.value-12);return{position:"fixed",right:t+e+20+"px",bottom:Math.min(n,r)+"px",width:"300px",maxWidth:"80vw",maxHeight:"min(560px, calc(100vh - 24px))",overflowY:"hidden",display:"flex",flexDirection:"column",zIndex:Qe,boxSizing:"border-box"}}),h=(e,t)=>{e&&i("plugin-event",o.req.pluginId,e,t)};function g(e,t){return z(e,h)}return(r,o)=>t.req&&t.req.spec?((0,e.openBlock)(),(0,e.createBlock)((0,e.unref)(n),{key:0,ref_key:"panelRef",ref:u,variant:"glass",style:(0,e.normalizeStyle)(f.value),padding:"14px 0"},{default:(0,e.withCtx)(()=>[(0,e.createCommentVNode)(" 左右留白交给下面两个类(`sc-gutter-align` / `px-2` + `sc-gutter`):两者最终都是\n 「8px + 预留滚动条宽」,于是头部与内容左右对齐,且有无滚动条时都对称(v0.8.117)。 "),(0,e.createElementVNode)("div",Nn,[(0,e.createCommentVNode)(" 插件图标:与快捷菜单槽位同源(manifest.icon,无图标则首字占位)。\n 面板是插件的门面,只有名字没有图标会让「这是谁弹的」少一条线索。 "),l.value?((0,e.openBlock)(),(0,e.createElementBlock)("img",{key:0,src:l.value,class:"w-4 h-4 object-contain shrink-0",alt:""},null,8,Mn)):(0,e.createCommentVNode)("v-if",!0),(0,e.createElementVNode)("strong",Vn,(0,e.toDisplayString)(a.value),1),(0,e.createElementVNode)("button",{type:"button",class:"ml-auto border-none bg-transparent text-base cursor-pointer text-secondary leading-none",onClick:o[0]||(o[0]=e=>r.$emit("close"))}," × ")]),(0,e.createCommentVNode)(" 可滚动内容区:**唯一的滚动层**(v0.8.106)。此前 overflowY:auto 挂在 Panel 根上,\n 标题和关闭按钮会跟着一起滚、滚动条也贴在面板最外缘(看起来像在面板外)——\n 与 Settings.vue 的「固定头部 + 内容区滚动」同一套结构:根 flex column,头部\n shrink-0,内容区 flex-1 + min-h-0(flex 子项默认 min-height:auto,少了它\n 内容会把区域撑开而不滚)+ overflow-y-auto。 "),(0,e.createCommentVNode)(" ⚠️ `sc-gutter`(`scrollbar-gutter: stable both-edges`):永久预留两侧滚动条宽度 ——\n 滚动条出现/消失不再改变内容宽度(不抖),且左右留白严格对等(详见 theme.css 注释)。 "),(0,e.createElementVNode)("div",Ln,[((0,e.openBlock)(!0),(0,e.createElementBlock)(e.Fragment,null,(0,e.renderList)(c.value,(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:n,class:"mb-1.5"},[((0,e.openBlock)(),(0,e.createBlock)((0,e.resolveDynamicComponent)(g(t))))]))),128))])]),_:1},8,["style"])):(0,e.createCommentVNode)("v-if",!0)}}),An=["src"],zn="rocket-btn-pos",Dn="sc-scrolling",In=(0,e.defineComponent)({__name:"BackToTop",emits:["config-saved"],setup(n,{emit:r}){const o=(0,e.ref)(!1),i=(0,e.ref)(!1),a=(0,e.ref)(!1),s=(0,e.ref)(!1),l=(0,e.ref)(GM_info.script.name),c=at("general.alwaysShow",!1,st(!1)),u=at("general.noBtnBg",!1,st(!1)),d=at("general.customIcon","",pt()),p=(0,e.ref)(d.value);(0,e.watch)(d,e=>{p.value=e});const f=at("general.iconScale",1,ct()),h=(0,e.ref)(f.value),g=(0,e.ref)(null),v=(0,e.ref)(null);function b(e){h.value=Math.min(4,Math.max(.6,e||1))}function y(e){Fe.value=e}function w(e){g.value=e}function x(e){L.value=e}function k(e){v.value=e}(0,e.watch)(f,e=>{h.value=e});const S=at("general.menuSlots",4,dt()),E=at("general.githubAccel",!0,st(!0)),C=at("general.btnAnim","none",lt("none")),B=at("general.btnOpacity",1,ut()),N=at("general.btnRotate",0,e=>{const t=parseFloat(String(e??0));return isNaN(t)?0:Math.min(360,Math.max(0,Math.round(t)))}),M=(0,e.ref)(N.value),V=at("general.btnMirror",!1,st(!1)),L=(0,e.ref)(null),T=(0,e.computed)(()=>L.value??V.value),A=(0,e.computed)(()=>`rotate(${M.value}deg) scaleX(${T.value?-1:1})`);function z(e){M.value=e}(0,e.watch)(N,e=>{M.value=e});const D=(0,e.ref)(0);function I(e){return it(he.getBindings()[e]||"")?.icon??he.getBindingIcon(e)}const _=(0,e.computed)(()=>{D.value;const e=[];for(let t=0;t26*h.value),P=(0,e.computed)(()=>g.value??C.value),U=(0,e.computed)(()=>"none"===P.value||"ripple"===P.value?"":`sc-anim-${P.value}`),q=(0,e.computed)(()=>"ripple"===P.value&&!(v.value??u.value)),j=(0,e.computed)(()=>({width:R.value+"px",height:R.value+"px",objectFit:"cover",pointerEvents:"none"})),G=r;function O(e){p.value=Ze(e)}function F(e){c.value=st(!1)(GM_getValue("general.alwaysShow",!1)),u.value=st(!1)(GM_getValue("general.noBtnBg",!1)),f.value=ct()(GM_getValue("general.iconScale",1)),h.value=f.value,Le.value=st(!1)(GM_getValue("general.quickMenu",!1)),S.value=dt()(GM_getValue("general.menuSlots",4)),B.value=ut()(GM_getValue("general.btnOpacity",1)),Fe.value=null,g.value=null,v.value=null,L.value=null,L.value=null,d.value=pt()(GM_getValue("general.customIcon","")),p.value=Ze(e),N.value=(()=>{const e=parseFloat(String(GM_getValue("general.btnRotate",0)));return isNaN(e)?0:Math.min(360,Math.max(0,Math.round(e)))})(),M.value=N.value,Mt(),ge(),D.value++,G("config-saved")}function H(e){be(e.text,{title:"💡 还差一步",type:"info",timeout:8e3,note:e.note})}let Y=null,J=document.documentElement,W=0;const X=[],K=function(){try{const e=GM_getValue(zn,"");return e?JSON.parse(String(e)):null}catch{return null}}(),Z=(0,e.reactive)({x:K?.x??20,y:K?.y??20,fromRight:!K,fromBottom:!K});let Q=0,ee=0,te=!1;function ne(){try{GM_setValue(zn,JSON.stringify({x:Z.x,y:Z.y}))}catch{}}function re(e){0===e.button&&(te=!1,Q=e.clientX,ee=e.clientY,a.value=!1,Y=e.timeStamp,document.addEventListener("mousemove",ie),document.addEventListener("mouseup",le))}function oe(e){if(1!==e.touches.length)return;const t=e.touches[0];te=!1,Q=t.clientX,ee=t.clientY,a.value=!1,Y=e.timeStamp,document.addEventListener("touchmove",ae,{passive:!1}),document.addEventListener("touchend",ce)}function ie(e){se(e.clientX,e.clientY)}function ae(e){1===e.touches.length&&(e.preventDefault(),se(e.touches[0].clientX,e.touches[0].clientY))}function se(e,t){const n=e-Q,r=t-ee;if((Math.abs(n)>3||Math.abs(r)>3)&&(te||(te=!0,i.value&&(i.value=!1))),!te)return;s.value=!0;const o=window.innerHeight,a=o-t-23;Z.y=Math.max(0,Math.min(o-46,a)),Z.fromBottom=!0}function le(e){if(document.removeEventListener("mousemove",ie),document.removeEventListener("mouseup",le),s.value=!1,te)return ne(),void(Y=null);de(e)}function ce(){document.removeEventListener("touchmove",ae),document.removeEventListener("touchend",ce),s.value=!1,te&&ne()}function ue(e){Te.value=!1,me.value=null,e&&(ze.value=e),i.value=!0}function de(e){if(null===Y||te)return void(Y=null);const t=e.timeStamp-Y;Y=null,t<600||(a.value=!0,ue())}function pe(e){de(e),ce()}function fe(){Y=null}const he=Xe();function ge(){he.setEnabled("com.flowsaro.github-accel",E.value)}ge(),(0,e.watch)(E,ge),he.preheatFeatures();const me=(0,e.ref)(null);he.onPanelRender(e=>{"close"===e.kind?me.value=null:"panel"===e.kind&&(i.value=!1,me.value={kind:e.kind,spec:e.spec,pluginId:e.pluginId})}),he.onMenuRequest(e=>je(!0,"auto",e)),he.on("menuCloseRequest",()=>{"auto"===Ae.value&&(Te.value=!1)}),he.onChanged(()=>D.value++);const{toasts:ve,push:be,update:ye,close:we,clearPlugin:xe}=function(t={}){const n=t.max??30,r=t.minTimeout??1e3,o=(0,e.ref)([]);let i=0;const a=new Map;function s(e){return 0===e?0:Math.max(r,e)}function l(e){const t=a.get(e);void 0!==t&&(clearTimeout(t),a.delete(e))}function c(e){e.timeout<=0||a.set(e.id,setTimeout(()=>u(e.id),e.timeout))}function u(e,t){l(e);const n=o.value.find(t=>t.id===e);if(o.value=o.value.filter(t=>t.id!==e),t?.user&&n?.onClose)try{n.onClose()}catch(e){console.warn("[toast] onClose 回调抛错:",e)}}return{toasts:o,push:function(e,t){const r={id:++i,text:e,title:t?.title,type:t?.type||"info",timeout:s(t?.timeout??2500),copyable:!!t?.copyable,icon:t?.icon,broadcastId:t?.broadcastId,pluginId:t?.pluginId,severity:"high"===t?.severity?"high":"low",busy:!!t?.busy,note:t?.note,onClose:t?.onClose};for(t?.reverse?o.value.push(r):o.value.unshift(r);o.value.length>n;){const e=[...o.value].sort((e,t)=>e.id-t.id);u((e.find(e=>"high"!==e.severity)??e[0]).id)}return c(r),r.id},update:function(e,t){const n=o.value.find(t=>t.id===e);if(!n)return!1;if(void 0!==t.text&&(n.text=t.text),void 0!==t.title&&(n.title=t.title),void 0!==t.type&&(n.type=t.type),void 0!==t.icon&&(n.icon=t.icon),void 0!==t.note&&(n.note=t.note),void 0!==t.severity&&(n.severity="high"===t.severity?"high":"low"),void 0!==t.busy&&(n.busy=t.busy),void 0!==t.copyable&&(n.copyable=t.copyable),void 0!==t.timeout){const r=s(t.timeout);r!==n.timeout&&(n.timeout=r,l(e),c(n))}return!0},close:u,clearPlugin:function(e){const t=t=>t.pluginId===e&&"high"!==t.severity;o.value.filter(t).forEach(e=>l(e.id)),o.value=o.value.filter(e=>!t(e))}}}();he.onToast((e,t)=>be(e,t)),he.onToastUpdate((e,t)=>ye(e,t)),he.onToastDismissed(e=>{ve.value.filter(t=>t.broadcastId===e).forEach(e=>we(e.id))}),he.syncBroadcasts();let ke=null;function Se(){"visible"===document.visibilityState&&he.syncBroadcasts()}function Ee(e){try{navigator.clipboard.writeText(e.text)}catch{}}function Ce(e){const t=ve.value.find(t=>t.id===e);void 0!==t?.broadcastId&&he.dismissBroadcast(t.broadcastId),we(e,{user:!0})}function Be(e){xe(e),he.clearBroadcasts(e)}function Ne(e){"auto"===Ae.value&&(Te.value=!1),function(e){const t=it(he.getBindings()[e]||"");if(t){const e=t.run();return void(e&&be(e.text,{title:t.name,type:e.type??"info",timeout:e.timeout,note:e.note}))}he.activateSlot(e)}(e)}function Me(e){ue("menu")}function Ve(e,t,n){he.getRuntime(e)?.emitEvent(t,n)}document.addEventListener("visibilitychange",Se),window.addEventListener("focus",Se),window.addEventListener("pageshow",Se),function e(){const t=ve.value.some(e=>void 0!==e.broadcastId);ke=setTimeout(()=>{Se(),e()},t?2e3:8e3)}(),he.onDismissToast(e=>we(e)),he.onPluginUninstalled(e=>{me.value?.pluginId===e&&(me.value=null)});const Le=at("general.quickMenu",!1,st(!1)),Te=(0,e.ref)(!1),Ae=(0,e.ref)(null);(0,e.watch)(Te,e=>{e||(Ae.value=null)});const ze=(0,e.ref)("general");let De=null;const Ie=(0,e.ref)(0);let _e=0;const $e=(0,e.computed)(()=>({position:"fixed",right:Z.x+"px",bottom:Z.y+"px",width:"46px",height:"46px",zIndex:Qe})),Re=(0,e.computed)(()=>window.innerHeight-Z.y<200),Pe=(0,e.computed)(()=>{const e=window.innerHeight,t=e-Z.y;return{position:"fixed",right:Z.x+$+20+"px",...Re.value?{top:t+20+"px"}:{bottom:e-t+"px"},zIndex:2147483647}});function Ue(){for(let e=0;e0?performance.now()+a:0,Te.value=!0,o&&"manual"!==t||(Ae.value=t);const s={ok:!0};return n&&(s.inMenu=qe(n)),s}const Ge=window.matchMedia("(hover: hover)").matches,Oe=(0,e.ref)(!1),Fe=(0,e.ref)(null),He=(0,e.computed)(()=>{if(!Ge)return 1;const e=Fe.value??B.value;if(i.value)return e;return Oe.value||s.value||Te.value||ve.value.length>0?1:e});let Ye=null;function Je(){Oe.value=!0,Ge&&!s.value&&Le.value&&(clearTimeout(Ye),i.value||je(!0,"manual",void 0,{enterDelay:200}))}function We(){if(Oe.value=!1,Ge){if(clearTimeout(Ye),_e>0&&performance.now()<_e)return _e=0,void(Te.value=!1);Ye=setTimeout(()=>{"manual"===Ae.value&&(Te.value=!1)},500)}}function Ke(){clearTimeout(Ye)}function tt(){We()}function nt(){if(!te)return a.value?(a.value=!1,void(De&&(clearTimeout(De),De=null))):void(De?(clearTimeout(De),De=null,je()):De=setTimeout(()=>{De=null,function(){const e=document.scrollingElement;J===document.documentElement||J===e||J===document.body?window.scrollTo({top:0,behavior:"smooth"}):(J.scrollTo({top:0,behavior:"smooth"}),window.scrollY>0&&window.scrollTo({top:0,behavior:"smooth"}))}()},250))}function rt(e){try{return e.scrollHeight>e.clientHeight}catch{return!1}}function ot(){if(document.scrollingElement&&rt(document.scrollingElement))return document.scrollingElement;let e=null,t=0,n=0;const r=(o,i)=>{if(!(i>3||n>=60)){n++;try{const n=getComputedStyle(o);("auto"===n.overflowY||"scroll"===n.overflowY)&&rt(o)&&o.scrollHeight>t&&(e=o,t=o.scrollHeight)}catch{}for(const e of Array.from(o.children))r(e,i+1)}};if(r(document.body,0),e)return e;const o=[document.body,...Array.from(document.body.children)];for(const e of o)if(e&&e.scrollTop>0)return e;return document.documentElement}function ft(){const e=document.scrollingElement,t=window.scrollY||(e?e.scrollTop:0)||document.body.scrollTop||0;if(J===document.documentElement||J===e||J===document.body)return t;const n=J.scrollTop||0;return Math.max(t,n)}let vt=-1/0,bt=!1;function yt(){const e=performance.now();return e-vt>=500&&(bt=function(){const e=document.scrollingElement;return!!e&&e.scrollHeight>e.clientHeight}(),vt=e),bt}let wt=!1,xt=!1;function kt(){wt||(wt=!0,requestAnimationFrame(()=>{wt=!1,xt||St()}))}function St(){const e=ft();e>W?o.value=!1:e200),W=e}const Et=new WeakMap;function Ct(e){const t=e.target;if(!(t instanceof HTMLElement))return;t.classList.contains(Dn)||t.classList.add(Dn);const n=Et.get(t);void 0!==n&&clearTimeout(n),Et.set(t,window.setTimeout(()=>{t.classList.remove(Dn),Et.delete(t)},900))}function Bt(e){const t=e.target;if(t===document||t===document.documentElement||t===document.body)return vt=-1/0,void kt();t!==J?yt()||(rt(t)||t.scrollTop>0)&&(t!==J&&(J.removeEventListener("scroll",Bt),J=t,J.addEventListener("scroll",Bt,{passive:!0}),W=ft()),kt()):kt()}const Nt=(0,e.reactive)({position:"absolute",left:"0",top:"0",width:"100%",height:"100%",zIndex:1,opacity:"0",visibility:"hidden",transform:"translateY(8px)",transition:"opacity .25s ease, visibility .25s ease, transform .25s ease",background:u.value?"transparent":"var(--color-btn)",backdropFilter:u.value?"none":"blur(10px) saturate(150%)",WebkitBackdropFilter:u.value?"none":"blur(10px) saturate(150%)"});function Mt(){const e=v.value??u.value;Nt.background=e?"transparent":"var(--color-btn)",Nt.backdropFilter=e?"none":"blur(10px) saturate(150%)",Nt.WebkitBackdropFilter=e?"none":"blur(10px) saturate(150%)"}function Vt(){ft()<=200&&(o.value=!1),p.value=d.value,M.value=N.value,h.value=f.value,Fe.value=null,g.value=null,v.value=null,i.value=!1}(0,e.watch)([u,v],Mt),(0,e.onMounted)(()=>{var e;!GM_getValue(ht,!1)&&(GM_setValue(ht,!0),1)&&be("火箭按钮安装好了尽情玩耍吧~\n单击回顶部 · 长按打开设置 · 悬停或双击展开快捷菜单 · 支持挂载插件",{title:"🎉 安装成功",type:"success",timeout:0}),e="app.menuSeeded",!GM_getValue(e,!1)&&(GM_setValue(e,!0),1)&&he.getBindings().every(e=>!e)&&he.setBinding(0,et),J=ot(),J.addEventListener("scroll",Bt,{passive:!0}),document.addEventListener("scroll",Bt,{passive:!0,capture:!0}),Tt.value?.getRootNode()?.addEventListener("scroll",Ct,!0),window.addEventListener("resize",St,{passive:!0}),document.addEventListener("selectionchange",At),St(),setTimeout(()=>{const e=ot();e!==J&&(J.removeEventListener("scroll",Bt),J=e,J.addEventListener("scroll",Bt,{passive:!0}),W=ft(),St())},2e3)});let Lt="";const Tt=(0,e.ref)(null);function At(){if(function(){const e=window.getSelection()?.anchorNode;if(!e)return!1;const t=Tt.value?.getRootNode();return!!t&&t.contains(e)}())return;if(i.value)return;const e=window.getSelection()?.toString()||"";if(e===Lt)return;if(Lt=e,e||"auto"!==Ae.value||(Te.value=!1),he.handleSelectionChange(e),!e)return;const t=zt();if(!t.length)return;const n=t.filter(e=>qe(e.id));n.length?je(!0,"auto",n[0].id):function(){if(!mt(gt,432e5))return;const e=zt().map(e=>`「${e.name}」`);if(!e.length)return;be(`${e.join("")}还没放进快捷菜单,选中文字时它亮不出来`,{title:"💡 还差一步",type:"info",timeout:8e3,note:"长按按钮 → 设置 → 快捷菜单 → 槽位绑定选中它(之后选中文字就会自动亮出菜单)"})}()}function zt(){return he.getSelectionMenuPlugins().map(e=>({id:e,name:he.getPluginName(e)}))}return(0,e.onUnmounted)(()=>{J.removeEventListener("scroll",Bt),document.removeEventListener("scroll",Bt,{capture:!0}),Tt.value?.getRootNode()?.removeEventListener("scroll",Ct,!0),window.removeEventListener("resize",St),document.removeEventListener("selectionchange",At),document.removeEventListener("visibilitychange",Se),window.removeEventListener("focus",Se),window.removeEventListener("pageshow",Se),null!==ke&&(clearTimeout(ke),ke=null),xt=!0,function(){for(const[e,t,n]of X)e.removeEventListener(t,n);X.length=0}(),he.disposeAll()}),(0,e.watch)([o,i,s,c,Te,()=>ve.value.length>0,He],function(){c.value||o.value||i.value||s.value||Te.value||ve.value.length>0?(Nt.opacity=String(He.value),Nt.visibility="visible",Nt.transform="none"):(Nt.opacity="0",Nt.visibility="hidden",Nt.transform="translateY(8px)")},{immediate:!0}),(n,r)=>((0,e.openBlock)(),(0,e.createElementBlock)(e.Fragment,null,[(0,e.createCommentVNode)(" user-select: none 防止选中脚本自身 UI 触发 selectionchange(套娃);编辑输入框单独恢复 "),(0,e.createElementVNode)("div",{ref_key:"uiRootEl",ref:Tt,style:{userSelect:"none",WebkitUserSelect:"none"}},[(0,e.createCommentVNode)(" 快捷菜单全屏遮罩:点击外部关闭。\n ⚠️ 插件自动打开的菜单(menuOpenSource === 'auto')**不挂遮罩**:遮罩的 @mousedown\n 关闭会连带吞掉那一次 mousedown,于是「划词弹出菜单后想接着拖选下一段」的第一下没反应。 "),Te.value&&"auto"!==Ae.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,style:(0,e.normalizeStyle)({position:"fixed",inset:"0",zIndex:(0,e.unref)(2147483645)}),onMousedown:r[0]||(r[0]=e=>Te.value=!1),onTouchstart:r[1]||(r[1]=e=>Te.value=!1)},null,36)):(0,e.createCommentVNode)("v-if",!0),(0,e.createCommentVNode)(" 锚点容器:按钮 + 快捷菜单同容器(hover 容器,鼠标在按钮或菜单上都不消失) "),(0,e.createElementVNode)("div",{style:(0,e.normalizeStyle)($e.value),onMouseenter:Je,onMouseleave:r[3]||(r[3]=e=>We())},[(0,e.createVNode)((0,e.unref)(t),{dragging:s.value,transparent:(0,e.unref)(u),size:(0,e.unref)($),round:"",style:(0,e.normalizeStyle)(Nt),title:l.value+"(长按设置)",onMouseleave:fe,onClick:nt,onMousedown:re,onTouchstart:oe,onTouchend:pe,onTouchcancel:ce},{default:(0,e.withCtx)(()=>[(0,e.createCommentVNode)(" 旋转应用到外层 wrapper(不动画冲突);动画类作用在 img 上 "),(0,e.createElementVNode)("div",{class:"flex items-center justify-center w-full h-full overflow-hidden rounded-full",style:(0,e.normalizeStyle)({transform:A.value})},[(0,e.createElementVNode)("img",{src:p.value,class:(0,e.normalizeClass)(U.value),style:(0,e.normalizeStyle)(j.value)},null,14,An)],4)]),_:1},8,["dragging","transparent","size","style","title"]),(0,e.createCommentVNode)("\n 涟漪特效:独立一层贴在按钮上、靠两个圆环错开扩散(见 theme.css 的 .sc-anim-ripple)。\n ⚠️ 必须在 Button **外面**:图标那层带 `overflow: hidden`,挂在里面的圆环扩不出去;\n z-index 也比按钮低(按钮是 1),波纹才是「从按钮边缘推出来」而不是盖在图标上。\n "),q.value?((0,e.openBlock)(),(0,e.createElementBlock)("div",{key:0,class:"sc-anim-ripple",style:(0,e.normalizeStyle)({opacity:String(He.value)}),"aria-hidden":"true"},null,4)):(0,e.createCommentVNode)("v-if",!0),(0,e.createCommentVNode)(" 菜单显隐交给组件自己:进出场动画在 QuickMenu 内部,元素要撑到动画结束才移除 "),(0,e.createVNode)(Bn,{show:Te.value,bindings:_.value,"slot-count":(0,e.unref)(S),"btn-size":(0,e.unref)($),"anchor-y":Z.y,"enter-delay":Ie.value,onClose:r[2]||(r[2]=e=>Te.value=!1),onSlot:Ne,onEmpty:Me,onHoverIn:Ke,onHoverOut:tt},null,8,["show","bindings","slot-count","btn-size","anchor-y","enter-delay"])],36),(0,e.createCommentVNode)(" Toast 独立定位(按钮上方,空间不足放下方) "),(0,e.createVNode)((0,e.unref)(m),{toasts:(0,e.unref)(ve),style:(0,e.normalizeStyle)(Pe.value),align:Re.value?"top":"bottom",onClose:Ce,onCopy:Ee,onClearPlugin:Be},null,8,["toasts","style","align"]),i.value?((0,e.openBlock)(),(0,e.createBlock)(Sn,{key:1,anchor:{x:Z.x,y:Z.y},"btn-size":(0,e.unref)($),"initial-tab":ze.value,onClose:Vt,onIconChange:O,onRotateChange:z,onScaleChange:b,onOpacityChange:y,onAnimChange:w,onBgChange:k,onMirrorChange:x,onSaved:F,onHint:H},null,8,["anchor","btn-size","initial-tab"])):(0,e.createCommentVNode)("v-if",!0),me.value?((0,e.openBlock)(),(0,e.createBlock)(Tn,{key:2,req:me.value,anchor:{x:Z.x,y:Z.y},"btn-size":(0,e.unref)($),onClose:r[4]||(r[4]=e=>me.value=null),onPluginEvent:Ve},null,8,["req","anchor","btn-size"])):(0,e.createCommentVNode)("v-if",!0)],512)],2112))}}),_n=(0,e.defineComponent)({__name:"App",setup(t){let n=!1;function r(){if(n)return;const t=function(){const t=(0,e.getCurrentInstance)()?.vnode?.el;if(!t)return null;const n=t.getRootNode();return n instanceof ShadowRoot&&n.host instanceof HTMLElement?n.host:null}(),r=t?.shadowRoot;if(!r)return;const o=document.createElement("style");o.dataset.scTheme="1",o.textContent='/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, \'Helvetica Neue\', \'Noto Sans\', Arial, sans-serif, \'Apple Color Emoji\', \'Segoe UI Emoji\', \'Segoe UI Symbol\', \'Noto Color Emoji\');\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \'Liberation Mono\', \'Courier New\', monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring:where(:not(iframe)) {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\'button\'], [type=\'reset\'], [type=\'submit\']), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\'until-found\'])) {\n display: none !important;\n }\n}\n@layer theme {\n :root, :host {\n --font-sans: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial,\n sans-serif;\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \'Liberation Mono\', \'Courier New\',\n monospace;\n --color-black: #000;\n --color-white: #fff;\n --spacing: 4px;\n --text-xs: 12px;\n --text-xs--line-height: calc(1 / 0.75);\n --text-sm: 14px;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 16px;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 18px;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 20px;\n --text-xl--line-height: calc(1.75 / 1.25);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --leading-tight: 1.25;\n --leading-snug: 1.375;\n --radius-sm: 4px;\n --radius-md: 6px;\n --radius-lg: 8px;\n --radius-xl: 12px;\n --ease-in: cubic-bezier(0.4, 0, 1, 1);\n --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n --spacing-0\\.5: 2px;\n --spacing-1\\.5: 6px;\n --spacing-2\\.5: 10px;\n --spacing-3\\.5: 14px;\n --color-panel: rgba(255, 255, 255, 0.86);\n --color-border: rgba(0, 0, 0, 0.2);\n --sc-surface-border: transparent;\n --sc-focus-ring: rgba(47, 129, 247, 0.28);\n --sc-focus-border: rgba(47, 129, 247, 0.55);\n --sc-seam: rgba(0, 0, 0, 0.08);\n --sc-chip-bg: #e0ecfe;\n --sc-scrollbar: rgba(0, 0, 0, 0.28);\n --sc-scrollbar-size: 6px;\n --sc-img-filter: none;\n --color-primary: #24292f;\n --color-secondary: #57606a;\n --color-input: rgba(0, 0, 0, 0.08);\n --color-subtle-btn: rgba(0, 0, 0, 0.05);\n --color-save-btn: rgba(31, 136, 61, 0.9);\n --color-save-border: #1f883d;\n --color-btn: rgba(255, 255, 255, 0.8);\n --color-btn-hover: rgba(255, 255, 255, 0.88);\n --color-menu-plus: #111418;\n --color-accent: #2f81f7;\n --color-success: #3fb950;\n --color-warning: #d29922;\n --color-danger: #f85149;\n --sc-shadow-panel: 0 1px 2px rgba(0, 0, 0, 0.08), 0 2px 10px rgba(0, 0, 0, 0.14),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn: 0 1px 2px rgba(0, 0, 0, 0.08), 0 4px 24px rgba(0, 0, 0, 0.2),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn-hover: 0 1px 2px rgba(0, 0, 0, 0.1), 0 6px 28px rgba(0, 0, 0, 0.24),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.8);\n --sc-shadow-toast: 0 1px 2px rgba(0, 0, 0, 0.08), 0 2px 10px rgba(0, 0, 0, 0.14),\n inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n }\n}\n@layer utilities {\n .pointer-events-none {\n pointer-events: none;\n }\n .collapse {\n visibility: collapse;\n }\n .visible {\n visibility: visible;\n }\n .absolute {\n position: absolute;\n }\n .fixed {\n position: fixed;\n }\n .relative {\n position: relative;\n }\n .static {\n position: static;\n }\n .-top-1 {\n top: calc(var(--spacing) * -1);\n }\n .-right-1 {\n right: calc(var(--spacing) * -1);\n }\n .left-1\\/2 {\n left: calc(1 / 2 * 100%);\n }\n .z-\\[\\.\\.\\.\\] {\n z-index: ...;\n }\n .-mx-1 {\n margin-inline: calc(var(--spacing) * -1);\n }\n .-mx-2 {\n margin-inline: calc(var(--spacing) * -2);\n }\n .my-2 {\n margin-block: calc(var(--spacing) * 2);\n }\n .\\!mt-0 {\n margin-top: 0px !important;\n }\n .-mt-1 {\n margin-top: calc(var(--spacing) * -1);\n }\n .mt-0\\.5 {\n margin-top: var(--spacing-0\\.5);\n }\n .mt-1 {\n margin-top: var(--spacing);\n }\n .mt-1\\.5 {\n margin-top: var(--spacing-1\\.5);\n }\n .mt-2\\.5 {\n margin-top: var(--spacing-2\\.5);\n }\n .mt-3\\.5 {\n margin-top: var(--spacing-3\\.5);\n }\n .-mr-1\\.5 {\n margin-right: calc(var(--spacing-1\\.5) * -1);\n }\n .mb-0\\.5 {\n margin-bottom: var(--spacing-0\\.5);\n }\n .mb-1 {\n margin-bottom: var(--spacing);\n }\n .mb-1\\.5 {\n margin-bottom: var(--spacing-1\\.5);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .mb-2\\.5 {\n margin-bottom: var(--spacing-2\\.5);\n }\n .mb-3 {\n margin-bottom: calc(var(--spacing) * 3);\n }\n .mb-4 {\n margin-bottom: calc(var(--spacing) * 4);\n }\n .ml-1 {\n margin-left: var(--spacing);\n }\n .ml-auto {\n margin-left: auto;\n }\n .box-border {\n box-sizing: border-box;\n }\n .block {\n display: block;\n }\n .flex {\n display: flex;\n }\n .hidden {\n display: none;\n }\n .inline-block {\n display: inline-block;\n }\n .table {\n display: table;\n }\n .h-4 {\n height: calc(var(--spacing) * 4);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-6 {\n height: calc(var(--spacing) * 6);\n }\n .h-7 {\n height: calc(var(--spacing) * 7);\n }\n .h-8 {\n height: calc(var(--spacing) * 8);\n }\n .h-9 {\n height: calc(var(--spacing) * 9);\n }\n .h-16 {\n height: calc(var(--spacing) * 16);\n }\n .h-\\[13px\\] {\n height: 13px;\n }\n .h-\\[520px\\] {\n height: 520px;\n }\n .h-full {\n height: 100%;\n }\n .max-h-24 {\n max-height: calc(var(--spacing) * 24);\n }\n .max-h-\\[160px\\] {\n max-height: 160px;\n }\n .min-h-0 {\n min-height: 0px;\n }\n .min-h-\\[46px\\] {\n min-height: 46px;\n }\n .min-h-\\[96px\\] {\n min-height: 96px;\n }\n .w-4 {\n width: calc(var(--spacing) * 4);\n }\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n .w-6 {\n width: calc(var(--spacing) * 6);\n }\n .w-7 {\n width: calc(var(--spacing) * 7);\n }\n .w-8 {\n width: calc(var(--spacing) * 8);\n }\n .w-9 {\n width: calc(var(--spacing) * 9);\n }\n .w-12 {\n width: calc(var(--spacing) * 12);\n }\n .w-16 {\n width: calc(var(--spacing) * 16);\n }\n .w-\\[13px\\] {\n width: 13px;\n }\n .w-\\[52px\\] {\n width: 52px;\n }\n .w-\\[300px\\] {\n width: 300px;\n }\n .w-full {\n width: 100%;\n }\n .max-w-\\[80vw\\] {\n max-width: 80vw;\n }\n .max-w-full {\n max-width: 100%;\n }\n .min-w-0 {\n min-width: 0px;\n }\n .flex-1 {\n flex: 1;\n }\n .flex-\\[0_0_14px\\] {\n flex: 0 0 14px;\n }\n .flex-\\[0_0_44px\\] {\n flex: 0 0 44px;\n }\n .flex-\\[0_0_52px\\] {\n flex: 0 0 52px;\n }\n .shrink-0 {\n flex-shrink: 0;\n }\n .border-collapse {\n border-collapse: collapse;\n }\n .transform {\n transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);\n }\n .cursor-grab {\n cursor: grab;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .touch-none {\n touch-action: none;\n }\n .resize {\n resize: both;\n }\n .resize-y {\n resize: vertical;\n }\n .flex-col {\n flex-direction: column;\n }\n .flex-wrap {\n flex-wrap: wrap;\n }\n .items-baseline {\n align-items: baseline;\n }\n .items-center {\n align-items: center;\n }\n .items-start {\n align-items: flex-start;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .justify-end {\n justify-content: flex-end;\n }\n .gap-1 {\n gap: var(--spacing);\n }\n .gap-1\\.5 {\n gap: var(--spacing-1\\.5);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-x-5 {\n column-gap: calc(var(--spacing) * 5);\n }\n .gap-y-1 {\n row-gap: var(--spacing);\n }\n .truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .overflow-hidden {\n overflow: hidden;\n }\n .overflow-x-hidden {\n overflow-x: hidden;\n }\n .overflow-y-auto {\n overflow-y: auto;\n }\n .rounded-\\[10px\\] {\n border-radius: 10px;\n }\n .rounded-full {\n border-radius: calc(infinity * 1px);\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .rounded-sm {\n border-radius: var(--radius-sm);\n }\n .rounded-xl {\n border-radius: var(--radius-xl);\n }\n .border-surface {\n border-style: solid;\n border-width: 1px;\n border-color: var(--sc-surface-border);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-0 {\n border-style: var(--tw-border-style);\n border-width: 0px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-b {\n border-bottom-style: var(--tw-border-style);\n border-bottom-width: 1px;\n }\n .border-none {\n --tw-border-style: none;\n border-style: none;\n }\n .border-border {\n border-color: var(--color-border);\n }\n .border-danger\\/40 {\n border-color: color-mix(in srgb, #f85149 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-danger) 40%, transparent);\n }\n }\n .border-save-border {\n border-color: var(--color-save-border);\n }\n .border-seam {\n border-color: var(--sc-seam);\n }\n .border-transparent {\n border-color: transparent;\n }\n .border-warning\\/40 {\n border-color: color-mix(in srgb, #d29922 40%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n border-color: color-mix(in oklab, var(--color-warning) 40%, transparent);\n }\n }\n .bg-accent\\/15 {\n background-color: color-mix(in srgb, #2f81f7 15%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-accent) 15%, transparent);\n }\n }\n .bg-accent\\/20 {\n background-color: color-mix(in srgb, #2f81f7 20%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-accent) 20%, transparent);\n }\n }\n .bg-black\\/60 {\n background-color: color-mix(in srgb, #000 60%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-black) 60%, transparent);\n }\n }\n .bg-btn {\n background-color: var(--color-btn);\n }\n .bg-chip {\n background-color: var(--sc-chip-bg);\n }\n .bg-input {\n background-color: var(--color-input);\n }\n .bg-panel {\n background-color: var(--color-panel);\n }\n .bg-save-btn {\n background-color: var(--color-save-btn);\n }\n .bg-subtle-btn {\n background-color: var(--color-subtle-btn);\n }\n .bg-transparent {\n background-color: transparent;\n }\n .bg-warning\\/15 {\n background-color: color-mix(in srgb, #d29922 15%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-warning) 15%, transparent);\n }\n }\n .object-contain {\n object-fit: contain;\n }\n .p-0 {\n padding: 0px;\n }\n .p-1 {\n padding: var(--spacing);\n }\n .p-1\\.5 {\n padding: var(--spacing-1\\.5);\n }\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n .p-3 {\n padding: calc(var(--spacing) * 3);\n }\n .p-\\[2px_10px_8px_4px\\] {\n padding: 2px 10px 8px 4px;\n }\n .p-\\[5px_6px\\] {\n padding: 5px 6px;\n }\n .px-1 {\n padding-inline: var(--spacing);\n }\n .px-1\\.5 {\n padding-inline: var(--spacing-1\\.5);\n }\n .px-2 {\n padding-inline: calc(var(--spacing) * 2);\n }\n .px-2\\.5 {\n padding-inline: var(--spacing-2\\.5);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-4 {\n padding-inline: calc(var(--spacing) * 4);\n }\n .py-0\\.5 {\n padding-block: var(--spacing-0\\.5);\n }\n .py-1 {\n padding-block: var(--spacing);\n }\n .py-1\\.5 {\n padding-block: var(--spacing-1\\.5);\n }\n .py-\\[1px\\] {\n padding-block: 1px;\n }\n .py-\\[3px\\] {\n padding-block: 3px;\n }\n .\\!pt-0 {\n padding-top: 0px !important;\n }\n .pt-2\\.5 {\n padding-top: var(--spacing-2\\.5);\n }\n .pb-3 {\n padding-bottom: calc(var(--spacing) * 3);\n }\n .pb-\\[3px\\] {\n padding-bottom: 3px;\n }\n .pb-\\[5px\\] {\n padding-bottom: 5px;\n }\n .pl-\\[30px\\] {\n padding-left: 30px;\n }\n .font-\\[inherit\\] {\n font-family: inherit;\n }\n .text-base {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .text-xs {\n font-size: var(--text-xs);\n line-height: var(--tw-leading, var(--text-xs--line-height));\n }\n .text-\\[10px\\] {\n font-size: 10px;\n }\n .text-\\[11px\\] {\n font-size: 11px;\n }\n .text-\\[13px\\] {\n font-size: 13px;\n }\n .leading-\\[1\\.5\\] {\n --tw-leading: 1.5;\n line-height: 1.5;\n }\n .leading-none {\n --tw-leading: 1;\n line-height: 1;\n }\n .leading-snug {\n --tw-leading: var(--leading-snug);\n line-height: var(--leading-snug);\n }\n .leading-tight {\n --tw-leading: var(--leading-tight);\n line-height: var(--leading-tight);\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .break-words {\n overflow-wrap: break-word;\n }\n .whitespace-nowrap {\n white-space: nowrap;\n }\n .whitespace-pre-wrap {\n white-space: pre-wrap;\n }\n .text-accent {\n color: var(--color-accent);\n }\n .text-danger {\n color: var(--color-danger);\n }\n .text-inherit {\n color: inherit;\n }\n .text-menu-plus {\n color: var(--color-menu-plus);\n }\n .text-primary {\n color: var(--color-primary);\n }\n .text-secondary {\n color: var(--color-secondary);\n }\n .text-secondary\\/80 {\n color: color-mix(in srgb, #57606a 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, var(--color-secondary) 80%, transparent);\n }\n }\n .text-warning {\n color: var(--color-warning);\n }\n .text-white {\n color: var(--color-white);\n }\n .line-through {\n text-decoration-line: line-through;\n }\n .no-underline {\n text-decoration-line: none;\n }\n .accent-accent {\n accent-color: var(--color-accent);\n }\n .opacity-60 {\n opacity: 60%;\n }\n .shadow {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-none {\n --tw-shadow: 0 0 #0000;\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-sm {\n --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .ring {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-btn {\n box-shadow: var(--sc-shadow-btn);\n }\n .shadow-btn-hover {\n box-shadow: var(--sc-shadow-btn-hover);\n }\n .shadow-panel {\n box-shadow: var(--sc-shadow-panel);\n }\n .shadow-btn {\n --tw-shadow-color: rgba(255, 255, 255, 0.8);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-shadow-color: color-mix(in oklab, var(--color-btn) var(--tw-shadow-alpha), transparent);\n }\n }\n .shadow-btn-hover {\n --tw-shadow-color: rgba(255, 255, 255, 0.88);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-shadow-color: color-mix(in oklab, var(--color-btn-hover) var(--tw-shadow-alpha), transparent);\n }\n }\n .shadow-panel {\n --tw-shadow-color: rgba(255, 255, 255, 0.86);\n @supports (color: color-mix(in lab, red, red)) {\n --tw-shadow-color: color-mix(in oklab, var(--color-panel) var(--tw-shadow-alpha), transparent);\n }\n }\n .outline {\n outline-style: var(--tw-outline-style);\n outline-width: 1px;\n }\n .filter {\n filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);\n }\n .backdrop-blur-\\[10px\\] {\n --tw-backdrop-blur: blur(10px);\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-saturate-150 {\n --tw-backdrop-saturate: saturate(150%);\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-filter {\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-\\[margin-top\\,bottom\\,box-shadow\\] {\n transition-property: margin-top,bottom,box-shadow;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-shadow {\n transition-property: box-shadow;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-transform {\n transition-property: transform, translate, scale, rotate;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-200 {\n --tw-duration: 200ms;\n transition-duration: 200ms;\n }\n .ease-in {\n --tw-ease: var(--ease-in);\n transition-timing-function: var(--ease-in);\n }\n .ease-in-out {\n --tw-ease: var(--ease-in-out);\n transition-timing-function: var(--ease-in-out);\n }\n .outline-none {\n --tw-outline-style: none;\n outline-style: none;\n }\n .select-none {\n -webkit-user-select: none;\n user-select: none;\n }\n .select-text {\n -webkit-user-select: text;\n user-select: text;\n }\n @media (hover: hover) {\n .hover\\:scale-110:hover {\n --tw-scale-x: 110%;\n --tw-scale-y: 110%;\n --tw-scale-z: 110%;\n scale: var(--tw-scale-x) var(--tw-scale-y);\n }\n .hover\\:bg-btn-hover:hover {\n background-color: var(--color-btn-hover);\n }\n .hover\\:bg-danger\\/15:hover {\n background-color: color-mix(in srgb, #f85149 15%, transparent);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-danger\\/15:hover {\n background-color: color-mix(in oklab, var(--color-danger) 15%, transparent);\n }\n }\n .hover\\:bg-white\\/10:hover {\n background-color: color-mix(in srgb, #fff 10%, transparent);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-white\\/10:hover {\n background-color: color-mix(in oklab, var(--color-white) 10%, transparent);\n }\n }\n .hover\\:bg-white\\/15:hover {\n background-color: color-mix(in srgb, #fff 15%, transparent);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:bg-white\\/15:hover {\n background-color: color-mix(in oklab, var(--color-white) 15%, transparent);\n }\n }\n .hover\\:text-danger:hover {\n color: var(--color-danger);\n }\n .hover\\:text-primary:hover {\n color: var(--color-primary);\n }\n .hover\\:opacity-90:hover {\n opacity: 90%;\n }\n .hover\\:shadow-btn-hover:hover {\n box-shadow: var(--sc-shadow-btn-hover);\n --tw-shadow-color: rgba(255, 255, 255, 0.88);\n }\n @supports (color: color-mix(in lab, red, red)) {\n .hover\\:shadow-btn-hover:hover {\n --tw-shadow-color: color-mix(in oklab, var(--color-btn-hover) var(--tw-shadow-alpha), transparent);\n }\n }\n }\n .focus\\:border:focus {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .active\\:scale-\\[0\\.97\\]:active {\n scale: 0.97;\n }\n}\n.border,\n.border-t,\n.border-b,\n.border-l,\n.border-r {\n border-style: solid;\n}\n.border-none {\n border-style: none;\n}\nimg {\n filter: var(--sc-img-filter);\n}\n.sc-field:focus,\ninput:not([type="checkbox"]):not([type="radio"]):focus,\nselect:focus,\ntextarea:focus,\nbutton:focus-visible,\na:focus-visible,\n[tabindex]:focus-visible,\ninput[type="checkbox"]:focus-visible,\ninput[type="radio"]:focus-visible {\n outline: none;\n border-color: var(--sc-focus-border);\n box-shadow: 0 0 0 3px var(--sc-focus-ring);\n}\n@supports selector(::-webkit-scrollbar) {\n *::-webkit-scrollbar {\n width: var(--sc-scrollbar-size);\n height: var(--sc-scrollbar-size);\n }\n *::-webkit-scrollbar-track,\n *::-webkit-scrollbar-corner {\n background: transparent;\n }\n *::-webkit-scrollbar-thumb {\n border: 1px solid transparent;\n border-radius: 9999px;\n background-color: transparent;\n background-clip: padding-box;\n transition: background-color 0.25s;\n }\n .sc-scrolling::-webkit-scrollbar-thumb {\n background-color: var(--sc-scrollbar);\n }\n}\n@supports not selector(::-webkit-scrollbar) {\n * {\n scrollbar-width: thin;\n scrollbar-color: transparent transparent;\n }\n .sc-scrolling {\n scrollbar-color: var(--sc-scrollbar) transparent;\n }\n}\n.sc-gutter {\n scrollbar-gutter: stable both-edges;\n}\n.sc-gutter-align {\n padding-inline: calc(8px + var(--sc-scrollbar-size));\n}\n:host {\n font-family: var(--font-sans);\n font-size: 16px;\n}\n@layer base {\n button,\n input,\n select,\n textarea {\n font: inherit;\n color: inherit;\n margin: 0;\n }\n button {\n appearance: none;\n -webkit-appearance: none;\n background: none;\n padding: 0;\n }\n button:not(:disabled) {\n cursor: pointer;\n }\n}\n@media (prefers-color-scheme: dark) {\n :host {\n --color-panel: rgba(30, 30, 30, 0.8);\n --color-border: rgba(255, 255, 255, 0.15);\n --sc-surface-border: transparent;\n --sc-focus-ring: rgba(88, 166, 255, 0.3);\n --sc-focus-border: rgba(88, 166, 255, 0.6);\n --sc-seam: rgba(255, 255, 255, 0.1);\n --sc-chip-bg: #2b3749;\n --sc-scrollbar: rgba(255, 255, 255, 0.24);\n --sc-img-filter: brightness(0.85);\n --color-primary: #f0f6fc;\n --color-secondary: #8b949e;\n --color-input: rgba(13, 17, 23, 0.6);\n --color-subtle-btn: rgba(255, 255, 255, 0.12);\n --color-save-btn: rgba(35, 134, 54, 0.9);\n --color-save-border: #238636;\n --color-btn: rgba(30, 30, 30, 0.8);\n --color-btn-hover: rgba(45, 45, 45, 0.88);\n --color-menu-plus: #ffffff;\n --sc-shadow-panel: 0 2px 10px rgba(0, 0, 0, 0.35), inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn: 0 4px 24px rgba(0, 0, 0, 0.4), inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n --sc-shadow-btn-hover: 0 6px 28px rgba(0, 0, 0, 0.5), inset 0 0.5px 0 rgba(255, 255, 255, 0.8);\n --sc-shadow-toast: 0 2px 10px rgba(0, 0, 0, 0.35), inset 0 0.5px 0 rgba(255, 255, 255, 0.6);\n }\n}\n@keyframes sc-breathe {\n 0%,\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.65;\n transform: scale(0.9);\n }\n}\n@keyframes sc-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@keyframes sc-pulse {\n 0%,\n 100% {\n transform: scale(1);\n }\n 50% {\n transform: scale(1.15);\n }\n}\n.sc-anim-breathe {\n animation: sc-breathe 2.6s ease-in-out infinite;\n}\n.sc-anim-spin {\n animation: sc-spin 5s linear infinite;\n}\n.sc-anim-pulse {\n animation: sc-pulse 1.8s ease-in-out infinite;\n}\n@keyframes sc-ripple {\n 0% {\n transform: scale(1);\n opacity: 0.55;\n }\n 100% {\n transform: scale(1.9);\n opacity: 0;\n }\n}\n.sc-anim-ripple {\n position: absolute;\n inset: 0;\n border-radius: 9999px;\n pointer-events: none;\n z-index: 0;\n}\n.sc-anim-ripple::before,\n.sc-anim-ripple::after {\n content: "";\n position: absolute;\n inset: 0;\n border-radius: 9999px;\n border: 2px solid var(--color-accent);\n animation: sc-ripple 2.4s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;\n}\n.sc-anim-ripple::after {\n animation-delay: 1.2s;\n}\n@media (prefers-reduced-motion: reduce) {\n .sc-anim-breathe,\n .sc-anim-spin,\n .sc-anim-pulse {\n animation: none;\n }\n .sc-anim-ripple::before,\n .sc-anim-ripple::after {\n animation: none;\n opacity: 0;\n }\n}\n@property --tw-rotate-x {\n syntax: "*";\n inherits: false;\n}\n@property --tw-rotate-y {\n syntax: "*";\n inherits: false;\n}\n@property --tw-rotate-z {\n syntax: "*";\n inherits: false;\n}\n@property --tw-skew-x {\n syntax: "*";\n inherits: false;\n}\n@property --tw-skew-y {\n syntax: "*";\n inherits: false;\n}\n@property --tw-border-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-leading {\n syntax: "*";\n inherits: false;\n}\n@property --tw-font-weight {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: "";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: "*";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: "*";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-outline-style {\n syntax: "*";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-sepia {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-color {\n syntax: "*";\n inherits: false;\n}\n@property --tw-drop-shadow-alpha {\n syntax: "";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-drop-shadow-size {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-blur {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: "*";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: "*";\n inherits: false;\n}\n@property --tw-duration {\n syntax: "*";\n inherits: false;\n}\n@property --tw-ease {\n syntax: "*";\n inherits: false;\n}\n@property --tw-scale-x {\n syntax: "*";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-y {\n syntax: "*";\n inherits: false;\n initial-value: 1;\n}\n@property --tw-scale-z {\n syntax: "*";\n inherits: false;\n initial-value: 1;\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-border-style: solid;\n --tw-leading: initial;\n --tw-font-weight: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-outline-style: solid;\n --tw-blur: initial;\n --tw-brightness: initial;\n --tw-contrast: initial;\n --tw-grayscale: initial;\n --tw-hue-rotate: initial;\n --tw-invert: initial;\n --tw-opacity: initial;\n --tw-saturate: initial;\n --tw-sepia: initial;\n --tw-drop-shadow: initial;\n --tw-drop-shadow-color: initial;\n --tw-drop-shadow-alpha: 100%;\n --tw-drop-shadow-size: initial;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n --tw-duration: initial;\n --tw-ease: initial;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-scale-z: 1;\n }\n }\n}\n',r.appendChild(o),n=!0}(0,e.onMounted)(()=>{r()});const o=at("general.backTop",!0,st(!0)),i=at("general.disabledSites","",ft()),a=(0,e.computed)(()=>i.value.split("\n").map(e=>e.trim()).filter(Boolean)),s=location.hostname.toLowerCase(),l=(0,e.computed)(()=>a.value.some(e=>{const t=e.toLowerCase().replace(/^https?:\/\//,"");return t&&(s===t||s.endsWith("."+t))}));return(t,n)=>((0,e.openBlock)(),(0,e.createElementBlock)(e.Fragment,null,[(0,e.createCommentVNode)(" GitHub 加速已插件化(内置 com.flowsaro.github-accel,由 BackToTop 管理开关) "),(0,e.unref)(o)&&!l.value?((0,e.openBlock)(),(0,e.createBlock)(In,{key:0})):(0,e.createCommentVNode)("v-if",!0)],2112))}}),$n=_n,Rn="app-QGNvbS5mbG93c2Fyby9yb2NrZXRfYnRu",Pn="[火箭按钮]";console.debug(Pn+" 启动中");const Un=["transform","filter","perspective","backdropFilter","webkitBackdropFilter"],qn=()=>(e=>{if(!e)return!1;try{const t=getComputedStyle(e);for(const e of Un){const n=t[e]||t.getPropertyValue(e);if(n&&"none"!==n)return!0}if(/transform|filter|perspective/.test(String(t.willChange||"")))return!0}catch{}return!1})(document.body)?document.documentElement:document.body||document.documentElement;let jn=qn(),Gn=document.getElementById(Rn);if(!Gn){Gn=document.createElement("div"),Gn.id=Rn;const e=[["all","initial"],["position","fixed"],["z-index","2147483647"],["pointer-events","none"],["font-family","var(--font-sans, ui-sans-serif, system-ui, sans-serif)"],["font-size","16px"],["line-height","1.5"],["color-scheme","light dark"]];for(const t of e)try{Gn.style.setProperty(t[0],t[1],"important")}catch{}try{jn?jn.appendChild(Gn):document.addEventListener("DOMContentLoaded",()=>qn().appendChild(Gn))}catch(e){console.error(Pn+" 宿主挂载失败:",e)}}if(!Gn.__shadowMount){const e=Gn.attachShadow({mode:"open"}),t=document.createElement("div");t.style.cssText="pointer-events: auto;",e.appendChild(t),Gn.__shadowMount=t}let On=null;const Fn=()=>{Gn.isConnected||(jn=qn(),jn.appendChild(Gn),On&&On.disconnect(),jn&&(On=new MutationObserver(Fn),On.observe(jn,{childList:!0})))};jn&&(On=new MutationObserver(Fn),On.observe(jn,{childList:!0}));if(new MutationObserver(Fn).observe(document.documentElement,{childList:!0}),"undefined"==typeof Vue)console.error(Pn+" Vue 依赖未就绪(@require 未加载完成),本次注入放弃");else try{(0,e.createApp)($n).mount(Gn.__shadowMount),console.debug(Pn+" v0.8.161 已挂载")}catch(e){console.error(Pn+" 挂载失败:",e)}})();