koishi-plugin-kkk 3.2.0 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# 更新日志
|
|
2
2
|
|
|
3
|
-
## 3.2.
|
|
3
|
+
## 3.2.1
|
|
4
4
|
|
|
5
5
|
### 出错时自动上报,进群报个编号就行
|
|
6
6
|
|
|
7
7
|
- **新增错误上报(默认开启)**:插件出错时,自动把**错误信息、错误堆栈、运行环境(Koishi 版本、已安装插件清单、适配器)、最近的日志**上传到收集站,站长在网页上就能看到全部细节 —— 不用再让你截图、也不用让你翻日志文件。上传到 `https://err.tangbot.xyz`(面板「通用 → 错误上报」里能改地址、令牌、日志行数,也能一键关掉)。上传失败不影响报错本身,错误卡片照常发。
|
|
8
8
|
- **错误消息里带上编号和群**:卡片下面会跟一条「错误信息已上传,ID:xxxxxxxx」+「可以前往 QQ 群内寻找帮助,在群内发送错误 ID 或该错误图片」。QQ 官方机器人那边群号是**可点的加群链接**(markdown),个人号(NapCat 等)给纯文本链接,客户端同样点得动。编号也印在错误卡片上。
|
|
9
|
-
-
|
|
9
|
+
- 面板「通用」多了「错误上报」一栏,里面**只有一个开关**(上传错误信息,默认开)。地址、令牌、反馈群、日志行数全部写死,没有可以填错的地方 —— 关掉开关就完全不上传。
|
|
10
10
|
|
|
11
11
|
### 错误卡片不再卡十几分钟
|
|
12
12
|
|
|
@@ -44,4 +44,4 @@ Please change the parent <Route path="${e}"> to <Route path="${e===`/`?`*`:`${e}
|
|
|
44
44
|
style="stroke: #88f; stroke-width: 2px; fill: none; stroke-opacity: 0.5; marker-end: url(#markerArrow);"
|
|
45
45
|
></path>
|
|
46
46
|
</svg>
|
|
47
|
-
</div>`),e.hasArrows=!0}format_textdiff(e,t){e.out(`<div class="jsondiffpatch-value">`),this.formatTextDiffString(e,t[0]),e.out(`</div>`)}};function sL(e){if(typeof e==`number`)return e;let t=String(e);for(let e of[[/&/g,`&`],[/</g,`<`],[/>/g,`>`],[/'/g,`'`],[/"/g,`"`]])t=t.replace(e[0],e[1]);return t}var cL=function(e){let t=e||document,n=({textContent:e,innerText:t})=>e||t,r=(e,t,n)=>{let r=e.querySelectorAll(t);for(let e=0,t=r.length;e<t;e++)n(r[e])},i=({children:e},t)=>{for(let n=0,r=e.length;n<r;n++){let r=e[n];r&&t(r,n)}};r(t,`.jsondiffpatch-arrow`,({parentNode:e,children:t,style:r})=>{let a=e,o=t[0],s=o.children[1];o.style.display=`none`;let c=a.querySelector(`.jsondiffpatch-moved-destination`);if(!(c instanceof HTMLElement))return;let l=n(c),u=a.parentNode;if(!u)return;let d;if(i(u,e=>{e.getAttribute(`data-key`)===l&&(d=e)}),d)try{let e=d.offsetTop-a.offsetTop;o.setAttribute(`height`,`${Math.abs(e)+6}`),r.top=`${-8+(e>0?0:e)}px`;let t=e>0?`M30,0 Q-10,${Math.round(e/2)} 26,${e-4}`:`M30,${-e} Q-10,${Math.round(-e/2)} 26,4`;s.setAttribute(`d`,t),o.style.display=``}catch(e){console.debug(`[jsondiffpatch] error adjusting arrows: ${e}`)}})},lL=(e,t,n)=>{let r=t||document.body,i=`jsondiffpatch-unchanged-`,a={showing:`${i}showing`,hiding:`${i}hiding`,visible:`${i}visible`,hidden:`${i}hidden`},o=r.classList;if(!o)return;if(!n){o.remove(a.showing),o.remove(a.hiding),o.remove(a.visible),o.remove(a.hidden),e===!1&&o.add(a.hidden);return}e===!1?(o.remove(a.showing),o.add(a.visible),setTimeout(()=>{o.add(a.hiding)},10)):(o.remove(a.hiding),o.add(a.showing),o.remove(a.hidden));let s=setInterval(()=>{cL(r)},100);setTimeout(()=>{o.remove(a.showing),o.remove(a.hiding),e===!1?(o.add(a.hidden),o.remove(a.visible)):(o.add(a.visible),o.remove(a.hidden)),setTimeout(()=>{o.remove(a.visible),clearInterval(s)},n+400)},n)},uL=(e,t)=>lL(!1,e,t),dL;function fL(e,t){return dL||=new oL,dL.format(e,t)}var pL=e=>e.join(`.`),mL=e=>!!(e&&typeof e==`object`),Q=(e,t,n)=>e?t.reduce((e,t)=>{if(mL(e))return e[t]},e)??n:n,hL=(e,t,n)=>{let r=structuredClone(e),i=r;for(let e=0;e<t.length-1;e++){let n=t[e],r=i[n];mL(r)||(i[n]={}),i=i[n]}return i[t[t.length-1]]=n,r},gL=(e,t)=>{let n=Number(e);return Number.isFinite(n)?n:t},_L=(e,t)=>Array.isArray(e)&&e.includes(t),vL=e=>!!(e&&typeof e==`object`&&`description`in e),yL=e=>{if(!e||typeof e!=`object`)return e;let t=structuredClone(e);for(let{path:e,options:n}of[{path:[`bilibili`,`sendContent`],options:[`info`,`comment`,`video`,`image`]},{path:[`bilibili`,`displayContent`],options:[`cover`,`title`,`author`,`stats`,`desc`]},{path:[`bilibili`,`push`,`parseDynamicTypes`],options:[`DYNAMIC_TYPE_AV`,`DYNAMIC_TYPE_DRAW`,`DYNAMIC_TYPE_ARTICLE`]},{path:[`douyin`,`sendContent`],options:[`info`,`comment`,`video`,`image`]},{path:[`xiaohongshu`,`sendContent`],options:[`info`,`comment`,`video`,`image`]},{path:[`kuaishou`,`sendContent`],options:[`info`,`comment`,`video`,`image`]}]){let r=Q(t,e,null);if(!Array.isArray(r))continue;let i=n.filter(e=>r.includes(e)),a=t;for(let t=0;t<e.length-1;t++){let n=e[t];mL(a[n])||(a[n]={}),a=a[n]}a[e[e.length-1]]=i}return t},bL=e=>typeof e==`object`&&!!e,xL=e=>{let t={added:0,modified:0,deleted:0},n=e=>{if(bL(e)){if(Array.isArray(e)){e.length===1?t.added+=1:e.length===2?t.modified+=1:e.length===3&&e[2]===0&&(t.deleted+=1);return}for(let[t,r]of Object.entries(e))t!==`_t`&&n(r)}};return n(e),t},SL=({original:e,current:t,showUnchanged:n=!1})=>{let r=(0,v.useRef)(null),i=(0,v.useMemo)(()=>{if(!(!e||!t))return iL(yL(e),yL(t))},[e,t]),a=(0,v.useMemo)(()=>e?yL(e):void 0,[e]),o=(0,v.useMemo)(()=>{if(i)return fL(i,a)},[i,a]),s=(0,v.useMemo)(()=>xL(i),[i]);return(0,v.useEffect)(()=>{r.current&&(o?(r.current.innerHTML=o,n?lL(!0,r.current):uL(r.current)):r.current.innerHTML=``)},[o,n]),o?(0,U.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,U.jsx)(v_,{size:`sm`,color:`success`,variant:`soft`,children:(0,U.jsxs)(v_.Label,{children:[`+ `,s.added,` 新增`]})}),(0,U.jsx)(v_,{size:`sm`,color:`warning`,variant:`soft`,children:(0,U.jsxs)(v_.Label,{children:[`~ `,s.modified,` 修改`]})}),(0,U.jsx)(v_,{size:`sm`,color:`danger`,variant:`soft`,children:(0,U.jsxs)(v_.Label,{children:[`- `,s.deleted,` 删除`]})})]}),(0,U.jsx)(`div`,{className:`max-h-[60vh] overflow-auto rounded-xl border border-default-200 bg-surface p-4`,children:(0,U.jsx)(`div`,{ref:r,className:`min-w-fit`})})]}):(0,U.jsx)(`div`,{className:`flex flex-col items-center justify-center gap-2 py-10 text-center`,children:(0,U.jsx)(px,{className:`text-sm text-muted`,children:`当前没有检测到配置变更`})})},CL=`变更预览`,wL=`绿色 = 新增/改后的内容,红色 = 删除/改前的内容,灰色 = 没变化的内容。`,TL=({device:e,original:t,current:n,isOpen:r,onOpenChange:i})=>{let[a,o]=(0,v.useState)(!1),s=(0,U.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,U.jsx)(px,{className:`text-xs text-muted`,children:wL}),(0,U.jsx)(ob,{size:`sm`,isSelected:a,onChange:o,"aria-label":`显示未变更字段`,children:(0,U.jsxs)(ob.Content,{children:[(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})}),`显示未变更`]})})]}),(0,U.jsx)(SL,{original:t,current:n,showUnchanged:a})]}),c=(0,U.jsx)(Vg,{slot:`close`,size:`sm`,variant:`secondary`,children:`关闭`});return e===`mobile`?(0,U.jsx)(pv,{children:(0,U.jsx)(pv.Backdrop,{isOpen:r,onOpenChange:i,children:(0,U.jsx)(pv.Content,{placement:`bottom`,children:(0,U.jsxs)(pv.Dialog,{className:`h-[85vh]`,children:[(0,U.jsx)(pv.Handle,{}),(0,U.jsx)(pv.CloseTrigger,{}),(0,U.jsx)(pv.Header,{children:(0,U.jsx)(pv.Heading,{children:CL})}),(0,U.jsx)(pv.Body,{children:s}),(0,U.jsx)(pv.Footer,{children:c})]})})})}):(0,U.jsx)(Dx,{children:(0,U.jsx)(Dx.Backdrop,{isOpen:r,onOpenChange:i,children:(0,U.jsx)(Dx.Container,{scroll:`inside`,size:`lg`,children:(0,U.jsxs)(Dx.Dialog,{className:`w-full max-w-4xl`,children:[(0,U.jsx)(Dx.CloseTrigger,{}),(0,U.jsxs)(Dx.Header,{children:[(0,U.jsx)(Dx.Icon,{className:`bg-accent-soft text-accent-soft-foreground`,children:(0,U.jsx)(Lj,{className:`size-5`})}),(0,U.jsx)(Dx.Heading,{children:CL})]}),(0,U.jsx)(Dx.Body,{children:s}),(0,U.jsx)(Dx.Footer,{children:c})]})})})})},EL=e=>!!(e&&typeof e==`object`),$=(e,t,n)=>e?t.reduce((e,t)=>{if(EL(e))return e[t]},e)??n:n,DL=(e,t)=>Array.isArray(e)&&e.includes(t),OL=[{path:[`app`,`priority`],rules:[{condition:e=>$(e,[`app`,`videoTool`],!0),message:`修改此配置项需要先将「默认解析优先级」关闭`}]},{path:[`app`,`multiPageHeight`],rules:[{condition:e=>!$(e,[`app`,`multiPageRender`],!0),message:`修改此配置项需要先将「分页渲染」打开`}]},{path:[`app`,`livePhotoSystem`],rules:[{condition:e=>$(e,[`app`,`livePhotoMode`],`video_and_livephoto`)===`video_only`,message:`修改此配置项需要先将「Live Photo 处理和发送方式」改为非「仅视频」模式`}]},{path:[`amagi`,`APIServerMount`],rules:[{condition:e=>!$(e,[`amagi`,`APIServer`],!1),message:`修改此配置项需要先将「API 服务」打开`}]},{path:[`amagi`,`APIServerPort`],rules:[{condition:e=>$(e,[`amagi`,`APIServerMount`],!0),message:`修改此配置项需要先将「挂载到 Koishi」关闭`}]},{path:[`app`,`qrLoginExternalAddr`],rules:[{condition:e=>$(e,[`app`,`qrLoginAddrType`],`lan`)!==`external`,message:`修改此配置项需要先将「扫码登录地址」改为「外部地址」`}]},{path:[`app`,`videoSendMode`],rules:[{condition:e=>$(e,[`app`,`usegroupfile`],!1),message:`修改此配置项需要先将「群文件上传」关闭`}]},{path:[`app`,`usegroupfile`],rules:[{condition:e=>$(e,[`app`,`videoSendMode`],`file`)===`base64`,message:`修改此配置项需要先将「本地视频发送方式」改为「File 协议」`}]},{path:[`app`,`groupfilevalue`],rules:[{condition:e=>!$(e,[`app`,`usegroupfile`],!1),message:`修改此配置项需要先将「群文件上传」打开`},{condition:e=>$(e,[`app`,`videoSendMode`],`file`)===`base64`,message:`修改此配置项需要先将「本地视频发送方式」改为「File 协议」`}]},{path:[`app`,`filelimit`],rules:[{condition:e=>!$(e,[`app`,`usefilelimit`],!1),message:`修改此配置项需要先将「视频上传拦截」打开`}]},{path:[`app`,`compresstrigger`],rules:[{condition:e=>!$(e,[`app`,`compress`],!1),message:`修改此配置项需要先将「压缩视频」打开`}]},{path:[`app`,`compressvalue`],rules:[{condition:e=>!$(e,[`app`,`compress`],!1),message:`修改此配置项需要先将「压缩视频」打开`}]},{path:[`app`,`downloadMaxSpeed`],rules:[{condition:e=>!$(e,[`app`,`downloadThrottle`],!1),message:`修改此配置项需要先将「下载限速」打开`}]},{path:[`app`,`downloadAutoReduce`],rules:[{condition:e=>!$(e,[`app`,`downloadThrottle`],!1),message:`修改此配置项需要先将「下载限速」打开`}]},{path:[`app`,`downloadMinSpeed`],rules:[{condition:e=>!$(e,[`app`,`downloadThrottle`],!1),message:`修改此配置项需要先将「下载限速」打开`},{condition:e=>!$(e,[`app`,`downloadAutoReduce`],!1),message:`修改此配置项需要先将「断流自动降速」打开`}]},{path:[`amagi`,`proxy`,`protocol`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`host`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`port`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`auth`,`username`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`auth`,`password`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`douyin`,`sendContent`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`numcomment`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`douyin`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`douyin`,`subCommentLimit`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`douyin`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`douyin`,`commentImageCollection`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`douyin`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`douyin`,`liveImageMergeMode`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`app`,`livePhotoMode`],`video_and_livephoto`)===`livephoto_only`,message:`修改此配置项需要先将「Live Photo 处理和发送方式」改为非「仅实况图」模式`}]},{path:[`douyin`,`videoQuality`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`maxAutoVideoSize`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`douyin`,`videoQuality`],`adapt`)!==`adapt`,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]},{path:[`douyin`,`videoInfoMode`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`displayContent`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`douyin`,`videoInfoMode`],`text`)===`image`,message:`修改此配置项需要先将「视频信息返回形式」改为「文本模式」`}]},{path:[`douyin`,`burnDanmaku`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`danmakuArea`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`danmakuFontSize`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`danmakuOpacity`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`verticalMode`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`videoCodec`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`push`,`permission`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`cron`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`parsedynamic`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`shareType`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`pushVideoQuality`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`pushMaxAutoVideoSize`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>$(e,[`douyin`,`push`,`pushVideoQuality`],`adapt`)!==`adapt`,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]},{path:[`bilibili`,`sendContent`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`numcomment`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`bilibili`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`bilibili`,`realCommentCount`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`bilibili`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`bilibili`,`commentImageCollection`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`bilibili`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`bilibili`,`videoQuality`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`maxAutoVideoSize`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>Number($(e,[`bilibili`,`videoQuality`],0))!==0,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]},{path:[`bilibili`,`videoInfoMode`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`displayContent`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`bilibili`,`videoInfoMode`],`text`)===`image`,message:`修改此配置项需要先将「视频信息返回形式」改为「文本模式」`}]},{path:[`bilibili`,`showDanmakuInVideoInfo`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`bilibili`,`videoInfoMode`],`text`)===`text`,message:`修改此配置项需要先将「视频信息返回形式」改为「图片模式」`}]},{path:[`bilibili`,`burnDanmaku`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`danmakuArea`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`danmakuFontSize`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`danmakuOpacity`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`verticalMode`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`videoCodec`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`push`,`permission`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`bilibili`,`push`,`cron`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`bilibili`,`push`,`parsedynamic`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`bilibili`,`push`,`parseDynamicTypes`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>!$(e,[`bilibili`,`push`,`parsedynamic`],!1),message:`修改此配置项需要先将「作品解析」打开`}]},{path:[`bilibili`,`push`,`pushVideoQuality`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>!$(e,[`bilibili`,`push`,`parsedynamic`],!1),message:`修改此配置项需要先将「作品解析」打开`}]},{path:[`bilibili`,`push`,`pushMaxAutoVideoSize`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>!$(e,[`bilibili`,`push`,`parsedynamic`],!1),message:`修改此配置项需要先将「作品解析」打开`},{condition:e=>Number($(e,[`bilibili`,`push`,`pushVideoQuality`],0))!==0,message:`修改此配置项需要先将「解析视频动态时的画质偏好」改为「自动选择」`}]},{path:[`kuaishou`,`comment`],rules:[{condition:e=>!$(e,[`kuaishou`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`kuaishou`,`numcomment`],rules:[{condition:e=>!$(e,[`kuaishou`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`kuaishou`,`comment`],!1),message:`修改此配置项需要先将「评论解析」打开`}]},{path:[`xiaohongshu`,`sendContent`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`xiaohongshu`,`numcomment`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`xiaohongshu`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`xiaohongshu`,`videoQuality`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`xiaohongshu`,`maxAutoVideoSize`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`xiaohongshu`,`videoQuality`],`adapt`)!==`adapt`,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]}],kL=e=>e.join(`.`),AL=(e,t)=>{let n=kL(t),r=OL.find(e=>kL(e.path)===n);if(!r)return``;for(let t of r.rules)if(t.condition(e))return t.message;return``},jL=[{label:`信息`,value:`info`},{label:`评论图`,value:`comment`},{label:`视频`,value:`video`},{label:`图片`,value:`image`}],ML=[{label:`封面`,value:`cover`},{label:`标题`,value:`title`},{label:`作者`,value:`author`},{label:`统计`,value:`stats`},{label:`简介`,value:`desc`}],NL=[{label:`自动选择`,value:`adapt`,description:`根据「视频体积上限(MB)」自动选择分辨率进行下载`},{label:`标清 540p`,value:`540p`},{label:`高清 720p`,value:`720p`},{label:`高清 1080p`,value:`1080p`},{label:`超清 2k`,value:`2k`},{label:`超清 4k`,value:`4k`}],PL=[{label:`自动选择`,value:`0`},{label:`240P 极速`,value:`6`},{label:`360P 流畅`,value:`16`},{label:`480P 清晰`,value:`32`,description:`需登录(配置ck)`},{label:`720P 高清`,value:`64`,description:`需登录(配置ck)`},{label:`720P60 高帧率`,value:`74`,description:`需登录(配置ck)`},{label:`1080P 高清`,value:`80`,description:`需登录(配置ck)`},{label:`1080P+ 高码率`,value:`112`,description:`需大会员&视频支持`},{label:`1080P60 高帧率`,value:`116`,description:`需大会员&视频支持`},{label:`4K 超清`,value:`120`,description:`需大会员&视频支持`},{label:`8K 超高清`,value:`127`,description:`需大会员&视频支持`}],FL=[{label:`视频动态`,value:`DYNAMIC_TYPE_AV`},{label:`图文动态`,value:`DYNAMIC_TYPE_DRAW`},{label:`文章动态`,value:`DYNAMIC_TYPE_ARTICLE`}],IL=[{label:`所有人`,value:`all`},{label:`管理员`,value:`admin`},{label:`主人`,value:`master`},{label:`群主`,value:`group.owner`},{label:`群管理员`,value:`group.admin`}],LL=[{label:`H.264`,value:`h264`,description:`兼容性最好,支持几乎所有设备`},{label:`H.265`,value:`h265`,description:`压缩率更高,近几年设备支持良好(推荐)`},{label:`AV1`,value:`av1`,description:`最新编码格式,压缩率最高,但编码较慢`}],RL=[{label:`关闭`,value:`off`,description:`保持原始比例,不做转换`},{label:`智能`,value:`standard`,description:`仅对宽屏比例视频生效`},{label:`强制 9:16`,value:`force`,description:`所有视频统一转为 9:16 竖屏`}],zL=[{label:`1/4 屏`,value:`0.25`,description:`仅顶部区域`},{label:`半屏`,value:`0.5`,description:`上半部分(推荐)`},{label:`3/4 屏`,value:`0.75`,description:`大部分区域`},{label:`全屏`,value:`1`,description:`铺满整个画面`}],BL=[{label:`小号`,value:`small`},{label:`中号`,value:`medium`},{label:`大号`,value:`large`}],VL={enabled:`已开启`,disabled:`已关闭`},HL=[{key:`amagi`,label:`接口库`,description:`请求与 Cookies`},{key:`app`,label:`通用`,description:`运行与交互`},{key:`douyin`,label:`抖音`,description:`解析与推送`},{key:`bilibili`,label:`哔哩哔哩`,description:`解析与推送`},{key:`kuaishou`,label:`快手`,description:`快手解析`},{key:`xiaohongshu`,label:`小红书`,description:`小红书解析`},{key:`qq`,label:`QQ 适配器`,description:`QQ 平台专属`},{key:`pushlist`,label:`推送列表`,description:`订阅 JSON`}],UL=(0,v.lazy)(()=>YS(()=>import(`./CronEditor-CYgFpX-g.js`),__vite__mapDeps([0,1]))),WL=({className:e,disabled:t,...n})=>{let[r,i]=(0,v.useState)(!1),a=r?`隐藏密码`:`显示密码`;return(0,U.jsxs)(`div`,{className:`relative w-full`,children:[(0,U.jsx)(cx,{...n,variant:`secondary`,className:`w-full pr-10 ${e??``}`,type:r?`text`:`password`}),(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":a,className:`absolute right-1 top-1/2 -translate-y-1/2`,isDisabled:t,size:`sm`,type:`button`,variant:`tertiary`,onPress:()=>i(e=>!e),children:r?(0,U.jsx)(Fj,{className:`size-4`,"aria-hidden":`true`}):(0,U.jsx)(Ij,{className:`size-4`,"aria-hidden":`true`})})]})},GL=({config:e,device:t,classes:n,validationErrors:r,updateConfigValue:i})=>{let a=e=>{let n=vL(e)?e:{description:e},r=t===`mobile`?n.mobileContent??n.desktopContent:n.desktopContent;return(0,U.jsxs)(px,{className:`flex items-center gap-2`,children:[(0,U.jsx)(`span`,{children:n.description}),r?(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{"aria-label":`查看详细说明`,children:(0,U.jsx)(Vg,{isIconOnly:!0,size:`sm`,variant:`tertiary`,children:(0,U.jsx)(Rj,{className:`size-4`,"aria-hidden":`true`})})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:t===`mobile`?`bottom`:`top`,children:[(0,U.jsx)(tx.Arrow,{}),(0,U.jsx)(`div`,{className:`max-w-72`,children:r})]})]}):null,n.extra]})},o=(n,r,i)=>{if(!i)return n;let a=AL(e,r);return a?t===`mobile`?(0,U.jsxs)(gv,{children:[(0,U.jsx)(gv.Trigger,{className:`w-full cursor-not-allowed`,children:n}),(0,U.jsx)(gv.Content,{placement:`bottom`,children:(0,U.jsxs)(gv.Dialog,{children:[(0,U.jsx)(gv.Arrow,{}),(0,U.jsx)(`div`,{className:`max-w-72 text-sm`,children:a})]})})]}):(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{className:`w-full cursor-not-allowed`,children:n}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),(0,U.jsx)(`div`,{className:`max-w-72`,children:a})]})]}):n},s=(t,n,r,a)=>{let o=Q(e,t,[]),s=r?Array.from(new Set([...o,n])):o.filter(e=>e!==n);if(a&&r){let e=a.find(e=>e.includes(n));if(e){let t=e.filter(e=>e!==n);s=s.filter(e=>!t.includes(e))}}i(t,s)};return{renderSwitch:(t,n,r,s=!1)=>{let c=Q(e,t,!1),l=(0,U.jsxs)(ob,{isDisabled:s,isSelected:c,onChange:e=>i(t,e),children:[(0,U.jsxs)(ob.Content,{children:[(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})}),(0,U.jsx)(`span`,{className:`font-semibold`,children:n})]}),a(r||(c?VL.enabled:VL.disabled))]});return o(l,t,s)},renderTextField:(t,n,s,c)=>{let l=c?.type||`text`,u=String(Q(e,t,l===`number`?c?.fallback??0:``)),d=r[pL(t)],f=c?.disabled??!1,p=(0,U.jsxs)(lx,{fullWidth:!0,isInvalid:!!d,isDisabled:f,name:t.join(`.`),type:l,value:u,onChange:e=>{i(t,l===`number`?gL(e,c?.fallback??0):e)},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:n}),l===`password`?(0,U.jsx)(WL,{disabled:f,max:c?.max,min:c?.min,pattern:c?.pattern,placeholder:c?.placeholder||n,step:c?.step}):(0,U.jsx)(cx,{variant:`secondary`,max:c?.max,min:c?.min,pattern:c?.pattern,placeholder:c?.placeholder||n,step:c?.step}),d?(0,U.jsx)(hx,{children:d}):a(s)]});return o(p,t,f)},renderSelectField:(t,n,r,s,c=e=>e,l=!1)=>{let u=String(Q(e,t,s[0]?.value||``)),d=(0,U.jsxs)(Ax,{disabledKeys:s.filter(e=>e.disabled).map(e=>e.value),fullWidth:!0,isDisabled:l,name:t.join(`.`),placeholder:n,value:u,variant:`secondary`,onChange:e=>{e===null||Array.isArray(e)||i(t,c(String(e)))},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:n}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{}),(0,U.jsx)(Ax.Indicator,{})]}),a(r),(0,U.jsx)(Ax.Popover,{children:(0,U.jsx)(wx,{children:s.map(e=>(0,U.jsxs)(wx.Item,{id:e.value,textValue:e.label,children:[(0,U.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1`,children:[(0,U.jsx)(dx,{children:e.label}),e.description?(0,U.jsx)(px,{children:e.description}):null]}),(0,U.jsx)(wx.ItemIndicator,{})]},e.value))})})]});return o(d,t,l)},renderCheckboxGroup:(t,r,i,c,l=!1,u)=>{let d=Q(e,t,[]),f=(0,U.jsxs)(`div`,{className:n.field,children:[(0,U.jsx)(dx,{className:`font-semibold`,children:r}),a(i),(0,U.jsx)(`div`,{className:n.choiceGrid,children:c.map(e=>(0,U.jsxs)(m_,{variant:`secondary`,isDisabled:l,isSelected:_L(d,e.value),onChange:n=>s(t,e.value,n,u),children:[(0,U.jsxs)(m_.Content,{children:[(0,U.jsx)(m_.Control,{children:(0,U.jsx)(m_.Indicator,{})}),e.label]}),e.description?(0,U.jsx)(px,{children:e.description}):null]},e.value))})]});return o(f,t,l)},renderSlider:(t,r,s,c)=>{let l=Q(e,t,c?.fallback??0),u=c?.disabled??!1,d=(0,U.jsxs)(`div`,{className:n.field,children:[(0,U.jsxs)(Nx,{className:`w-full`,isDisabled:u,value:l,formatOptions:c?.formatOptions??{style:`percent`,maximumFractionDigits:0},maxValue:c?.max??1,minValue:c?.min??0,step:c?.step??.01,onChange:e=>{Array.isArray(e)||i(t,e)},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:r}),(0,U.jsx)(Nx.Output,{}),(0,U.jsxs)(Nx.Track,{children:[(0,U.jsx)(Nx.Fill,{}),(0,U.jsx)(Nx.Thumb,{})]})]}),a(s)]});return o(d,t,u)},renderCronField:(r,a,s,c=!1)=>{let l=Q(e,r,`*/10 * * * *`),u=(0,U.jsx)(`div`,{className:n.field,children:(0,U.jsx)(v.Suspense,{fallback:(0,U.jsx)(`div`,{className:`h-64 animate-pulse rounded-lg bg-muted/30`}),children:(0,U.jsx)(UL,{device:t,disabled:c,value:l,onChange:e=>i(r,e)})})});return o(u,r,c)},/*KKK-PERM-START*/renderPermField:(t,r,s,c)=>{c=c||{};const p=t,list=!!c.list,modes=c.modes||[],raw=Q(e,p,list?[]:`all`),arr0=list?(Array.isArray(raw)?raw.map(String):(raw?[String(raw)]:[])):[],ids=list?arr0.filter(x=>/^\d+$/.test(x)):[],numText=list?ids.join(`, `):([`all`,`admin`].includes(String(raw))?``:String(raw||``)),kw=list?(arr0.find(x=>!/^\d+$/.test(x))||``):([`all`,`admin`].includes(String(raw))?String(raw):``),guess=(kw===`trigger`)?`trigger`:(kw||(String(numText).trim()?`id`:(list?`trigger`:`all`))),pair=(0,v.useState)(null),mode=pair[0]||guess,setMode=pair[1],apply=n=>{setMode(n);if(n===`id`){i(p,list?ids:String(numText))}else{i(p,list?[n]:n)}},setIds=n=>{i(p,list?String(n).split(/[,,\s]+/).map(x=>x.trim()).filter(Boolean):n)},sel=(0,U.jsxs)(Ax,{fullWidth:!0,name:p.join(`.`),placeholder:r,value:mode,variant:`secondary`,onChange:e=>{e===null||Array.isArray(e)||apply(String(e))},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:r}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{}),(0,U.jsx)(Ax.Indicator,{})]}),a(s),(0,U.jsx)(Ax.Popover,{children:(0,U.jsx)(wx,{children:modes.map(m=>(0,U.jsx)(wx.Item,{id:m.value,textValue:m.label,children:m.label},m.value))})})]}),inp=mode===`id`?(0,U.jsxs)(lx,{fullWidth:!0,name:p.join(`.`),value:numText,onChange:e=>setIds(e),children:[(0,U.jsx)(dx,{className:`font-semibold`,children:list?`接收账号`:`允许的账号`}),(0,U.jsx)(cx,{variant:`secondary`,placeholder:`填写用户 ID,多个用逗号分隔`})]}):null,box=(0,U.jsxs)(`div`,{className:n.field,children:[sel,inp]});return o(box,t,!1)},/*KKK-PERM-END*/renderPageHeader:(e,n)=>(0,U.jsxs)(`div`,{className:`mb-6 ${t===`mobile`?`pr-36`:``}`,"data-config-section":!0,children:[(0,U.jsx)(`h2`,{className:`text-2xl font-bold`,children:e}),(0,U.jsx)(`div`,{className:`mt-3`,children:(0,U.jsx)(px,{children:n})})]}),renderSubSection:(e,t)=>(0,U.jsxs)(Wg,{"data-config-section":!0,className:`mb-4`,children:[(0,U.jsx)(Wg.Header,{className:n.sectionHeader,children:(0,U.jsx)(Wg.Title,{className:`text-lg font-semibold`,children:e})}),(0,U.jsx)(Wg.Content,{className:n.sectionContent,children:(0,U.jsx)(`div`,{className:n.fields,children:t})})]})}},KL={root:`relative flex min-w-0 max-w-full flex-col gap-8`,loading:`flex min-h-80 items-center justify-center gap-3`,header:`grid grid-cols-[minmax(0,1fr)_auto] items-start gap-8 pr-44`,headerCopy:`flex min-w-0 flex-col gap-2`,form:`flex min-w-0 max-w-full flex-col gap-6`,floatingActions:`fixed right-6 top-20 z-10`,actionControls:`flex items-center justify-end gap-3`,sectionHeader:`p-2`,sectionContent:`p-6`,fields:`grid grid-cols-2 gap-x-6 gap-y-5`,field:`flex min-w-0 flex-col gap-2`,choiceGrid:`grid grid-cols-2 gap-3`,divider:`col-span-full flex min-w-0 flex-col gap-2 pt-3`,tabsListContainer:`w-full min-w-0 max-w-full overflow-x-auto overflow-y-hidden overscroll-x-contain overscroll-y-none [scrollbar-width:none] [&::-webkit-scrollbar]:hidden`,tabsList:`w-fit min-w-max *:w-fit *:min-w-fit *:flex-none *:shrink-0 *:whitespace-nowrap`,topLevelFields:`mb-4 space-y-4 px-2`},qL={root:`relative flex min-w-0 max-w-full flex-col gap-5`,loading:`flex min-h-80 items-center justify-center gap-3`,header:`flex flex-col gap-3 pt-12`,headerCopy:`flex min-w-0 flex-col gap-2`,form:`flex min-w-0 max-w-full flex-col gap-3`,floatingActions:`sticky top-0 z-20 flex h-0 w-full justify-end overflow-visible`,actionControls:`flex w-fit h-11 p-1 items-center gap-2 rounded-full border border-default-200 bg-background/90 shadow-sm backdrop-blur-md`,sectionHeader:`p-1`,sectionContent:`p-0`,fields:`grid grid-cols-1 gap-5`,field:`flex min-w-0 flex-col gap-2`,choiceGrid:`grid grid-cols-1 gap-3`,divider:`col-span-full flex min-w-0 flex-col gap-2 pt-3`,tabsListContainer:`w-full min-w-0 max-w-full overflow-x-auto overflow-y-hidden overscroll-x-contain overscroll-y-none [scrollbar-width:none] [&::-webkit-scrollbar]:hidden`,tabsList:`w-fit min-w-max *:w-fit *:min-w-fit *:flex-none *:shrink-0 *:whitespace-nowrap`,topLevelFields:`mb-4 space-y-4 px-4`},JL=e=>e===`mobile`?qL:KL,YL=({config:e,renderers:t})=>{let{renderPageHeader:n,renderSelectField:r,renderSubSection:i,renderSwitch:a,renderTextField:o}=t,s=Q(e,[`amagi`,`proxy`,`switch`],!1),c=Q(e,[`amagi`,`APIServer`],!1);return(0,U.jsxs)(U.Fragment,{children:[n(`接口库配置`,`接口库的 Cookies、请求、代理和 API 服务配置。保存后后端会重载接口库客户端。`),i(`平台 Cookies`,(0,U.jsxs)(U.Fragment,{children:[o([`amagi`,`cookies`,`douyin`],`抖音 Cookies`,`请输入你的抖音Cookies,不输入则无法使用抖音相关功能噢。`,{type:`password`}),o([`amagi`,`cookies`,`bilibili`],`B站 Cookies`,`请输入你的B站Cookies,不输入部分功能将受限噢。`,{type:`password`}),o([`amagi`,`cookies`,`kuaishou`],`快手 Cookies`,`请输入你的快手Cookies,不输入则无法使用快手相关功能噢。`,{type:`password`}),o([`amagi`,`cookies`,`xiaohongshu`],`小红书 Cookies`,`请输入你的小红书Cookies,不输入则无法使用小红书相关功能噢。`,{type:`password`})]})),i(`请求配置`,(0,U.jsxs)(U.Fragment,{children:[o([`amagi`,`timeout`],`请求超时时间`,`网络请求的超时时间,单位:毫秒。`,{type:`number`,fallback:15e3,min:1e3,max:3e5}),o([`amagi`,`User-Agent`],`User-Agent`,`请求头中的User-Agent字段,用于标识客户端类型。`)]})),i(`代理配置(可选)`,(0,U.jsxs)(U.Fragment,{children:[a([`amagi`,`proxy`,`switch`],`代理开关`,`开启后需要配置「代理主机」「代理端口」。`),r([`amagi`,`proxy`,`protocol`],`代理协议`,`代理服务使用的协议。`,[{label:`HTTP`,value:`http`},{label:`HTTPS`,value:`https`}],e=>e,!s),o([`amagi`,`proxy`,`host`],`代理主机`,`代理服务器的主机地址,如:127.0.0.1。`,{disabled:!s}),o([`amagi`,`proxy`,`port`],`代理端口`,`代理服务器的端口号。`,{type:`number`,fallback:7890,min:1,max:65535,disabled:!s}),o([`amagi`,`proxy`,`auth`,`username`],`代理用户名`,`代理服务器的认证用户名(如果需要)。`,{disabled:!s}),o([`amagi`,`proxy`,`auth`,`password`],`代理密码`,`代理服务器的认证密码(如果需要)。`,{type:`password`,disabled:!s})]})),i(`API 服务配置`,(0,U.jsxs)(U.Fragment,{children:[a([`amagi`,`APIServer`],`API 服务`,`本地部署一个视频解析API服务,接口范围为本插件用到的所有。`),a([`amagi`,`APIServerMount`],`挂载到 Koishi`,`API 服务是否挂载到 Koishi 上,开启后监听端口为 Koishi 的 http 端口,修改后需重启。需开启「API服务」。`,!c),o([`amagi`,`APIServerPort`],`API 服务端口`,`仅未挂载到 Koishi 时生效。`,{type:`number`,disabled:Q(e,[`amagi`,`APIServerMount`],!0),fallback:4567,min:1024,max:65535})]}))]})},XL=({config:e,renderers:t})=>{let{renderCheckboxGroup:n,renderPageHeader:r,renderSelectField:i,renderSlider:a,renderSubSection:o,renderSwitch:s,renderTextField:c}=t,l=Q(e,[`app`,`livePhotoMode`],`video_and_livephoto`);return(0,U.jsxs)(U.Fragment,{children:[r(`通用`,`插件运行、渲染和交互相关配置。`),o(`缓存设置`,(0,U.jsx)(U.Fragment,{children:s([`app`,`removeCache`],`自动删除视频缓存`,`任务完成后删除下载缓存。`)})),o(`交互设置`,(0,U.jsxs)(U.Fragment,{children:[s([`app`,`EmojiReply`],`表情回应`,`在解析任务开始时添加表情回应,若适配器不支持需要关闭。`),s([`app`,`parseTip`],`解析提示`,`发送提示信息:"检测到xxx链接,开始解析"。`),s([`app`,`fakeForward`],`解析结果合并转发`,`**全局合并转发(优先级最高)**:打开时所有平台的解析结果都合并成一条转发消息发出,转发用触发者身份展示;过程提示(开始解析 / 下载中 / 发送中…)不会进转发。**关掉就不合并**,内容像以前一样一条一条发。只有支持合并转发的适配器有效果(QQ 官方适配器没有这个能力,会自动退化成逐条发送)。`),/*KKK-FORWARD-START*/t.renderCheckboxGroup([`app`,`forwardContent`],`合并转发内容(全局)`,`全局合并转发里包含哪些内容(通用页这个开关打开时生效,所有平台共用):没勾选的内容单独直发。视频类内容建议先不勾——转发节点太大的话适配器会整条拒绝。语音和 markdown 不在候选里:QQ 的聊天记录不支持语音气泡,markdown 只有官方 bot 认、而官方适配器没有合并转发能力。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])/*KKK-FORWARD-END*/,,,,,,t.renderPermField([`app`,`errorLogSendTo`],`错误日志`,`谁来接收错误日志,选「指定账号」后填用户 ID,多个用逗号分隔。`,{list:true,modes:[{value:`trigger`,label:`触发者所在的群`},{value:`admin`,label:`管理员(权限等级 4 及以上)`},{value:`id`,label:`指定账号`}]}),/*KKK-APP-START*/s([`qq`,`recallPanel`],`自动撤回面板`,`用户在面板上点完按钮后,自动把上一条提示 / 选择消息撤回,群里不会堆着一排旧提示和选择。`),s([`qq`,`forceNoDanmaku`],`强制不烧录弹幕`,`优先级最高的总开关:打开时无论指令、面板按钮还是平台配置,都不会烧录弹幕,一律按纯视频解析。要用弹幕功能时先把它关掉。`),s([`qq`,`parseDedupe`],`短时间不重复解析`,`默认开启。同一条链接在下面设定的一段时间内只解析一次:QQ 的指令按钮是「发一条消息 + 再发一个交互事件」,用户连点、客户端重发也会把同一条链接投递两遍,跑两遍就是两次「开始解析」、两次下载、两次发送(第二次还常因为缓存已被清理而失败)。去重键包含会话、作品 ID、画质与弹幕开关,换画质、换作品、换群都不会被误伤。**关掉后每条消息都会解析**,需要反复调试同一条链接时可以临时关掉。`),c([`qq`,`parseDedupeMinutes`],`重复解析间隔(分钟)`,`上面那个开关打开时才生效:同一条链接在这段时间内只解析一次,默认 1 分钟(可填 1 ~ 60)。填得越大越省事(重复投递/连点不会再跑第二遍),但也意味着这段时间里你手动再发一次同一条链接会被忽略;想立刻重解析就把上面的开关关掉。(这一项要先把上面的「短时间不重复解析」打开才能改)`,{type:`number`,fallback:1,min:1,max:60,disabled:Q(e,[`qq`,`parseDedupe`],!0)===!1})/*KKK-APP-END*/,,]})),/*KKK-SECTION-START*/o(`在线播放器设置`,(0,U.jsx)(U.Fragment,{children:[s([`qq`,`playerEnabled`],`在线播放器总开关`,`**这一组的总开关**,默认开启。打开时,解析面板里那一列按钮上的「弹幕」会把视频放到在线播放页(带弹幕)并回一条链接,不再把弹幕烧进视频、也不再把视频传到群里;链接有有效期,过期自动清理文件。开着时面板上还会多一列「在线看」(点它直接在线看,不管弹幕功能有没有开都带弹幕),这一列由下面的「面板显示「在线看」按钮」单独控制。**关掉它,这一组里其它设置都会变灰不可改**,解析也回到原来的 ffmpeg 烧录流程(面板列头变回「烧录弹幕」、不再有「在线看」列)。(这一项要先关掉上面的「强制不烧录弹幕」(也就是打开弹幕功能)才能改)`,Q(e,[`qq`,`forceNoDanmaku`],!0)===!0),s([`qq`,`playerWatchButton`],`面板显示「在线看」按钮`,`默认开启。打开后,QQ 解析面板的「弹幕」列右边会多一列「在线看」:点它**直接在线播放**(带弹幕,视频不发到群里、也不占群文件),不看弹幕功能开没开 —— 在线看永远带弹幕。关掉就不显示这一列。注意:只有上面的「在线播放器总开关」开着时这一列才会出现(总开关关掉时这一项会变灰);播放器关掉时它没有任何作用。**超过「在线播放最大文件」的画质档不给「在线看」按钮**,那一格会标「超上限」。(这一项要先把上面的「在线播放器总开关」打开才能改)`,Q(e,[`qq`,`playerEnabled`],!0)===!1),c([`qq`,`playerBaseUrl`],`播放器公网地址`,`**这是你自己的公网地址,插件猜不出来,必须由你填。**例如 https://play.example.com(结尾斜杠会自动去掉),用户收到的链接就是它加上 /kkk/player/<令牌>。留空时链接会退化成「http://本机 IP:端口」,**只有本机 / 内网能打开**;这时日志里会警告一次,机器人回复和播放页上也会带一句「未配置公网地址,仅本机可访问」——公网用户点开打不开是正常的,不是插件坏了。用 Nginx / Caddy 之类的反向代理指向下面的「播放器端口」即可,代理到 https 域名时这里就填那个域名。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`text`,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),c([`qq`,`playerPort`],`播放器端口`,`0 = 复用 Koishi 自己的端口(推荐,不用额外开端口);填其它值会用 node:http 另起一个服务。端口被占用时只记一条日志并退回 Koishi 端口,不会影响解析。注意别填浏览器禁止访问的端口(例如 6665-6669 这些 IRC 段),否则用户点开链接会直接 ERR_UNSAFE_PORT,看起来就像网页坏了。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`number`,fallback:0,min:0,max:65535,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),c([`qq`,`playerExpireMinutes`],`链接有效期(分钟)`,`播放链接与视频文件的有效期,默认 60 分钟(最小 1、最大 1440)。到点后视频和弹幕会被自动删除,链接打开是「链接已过期」。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`number`,fallback:60,min:1,max:1440,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),c([`qq`,`playerMaxFileMB`],`在线播放最大文件(MB)`,`体积超过这个值的视频**不走在线播放**,改回原来的发送流程(免得把机器磁盘塞满)。留空或填 0 = 跟随全局:用上游的「文件大小限制」(usefilelimit / filelimit,当前默认 200MB);全局没开限制就是不限制。**这条上限对「超限转在线播放」一样有效**:开了转播、但视频比这条上限还大时,仍然按原来的方式处理(拒绝并说明),不会为了转播把机器磁盘塞满。判定发生在把文件搬进播放器目录之前,超限的视频一点都不会占播放器目录。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`number`,fallback:0,min:0,max:102400,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),s([`qq`,`playerOnOversize`],`超限转在线播放`,`打开后,体积超过全局「文件大小限制」的视频不再被拒绝(原来会回一句「视频太大了,还是去B站看吧」),而是照常下载、改为在线播放:用户收到一条播放链接,视频不发到群里、也不占群文件。注意:**只有体积不超过上面「在线播放最大文件」的视频才会被转播**——比那个上限还大的照旧拒绝(免得把机器磁盘塞满),拒绝时会说明「超过在线播放的体积上限,按原来的方式处理」。关着时维持原来的行为。(这一项要先把上面的「在线播放器总开关」打开才能改)`,Q(e,[`qq`,`playerEnabled`],!0)===!1),c([`qq`,`forceOnlinePlayer`],`强制在线播放的适配器`,`填**适配器平台名**(多个用逗号分隔,例如 bilibili 或 bilibili,onebot),**默认就是 bilibili**;留空表示不强制任何适配器。填了之后,**从这些适配器进来的消息**解析完一律只给在线播放链接:视频不发出去、也不占群文件,跟用户在面板上点的是「解析」还是「在线看」、体积有没有超限都无关。典型用法:B站私聊机器人(adapter-bilibili-dm)的平台名就是 bilibili,它发不了视频文件,把它填进去即可。注意这里填的是**适配器**的名字,不是解析来源平台(抖音 / B站 这些由「发送内容」那些开关管)。要求「在线播放器总开关」开着。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`text`,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1})]})),o(`错误上报`,(0,U.jsx)(U.Fragment,{children:[s([`qq`,`errorReportUpload`],`上传错误信息`,`插件出错时,自动把**错误信息、运行环境(Koishi 版本、装了哪些插件、适配器)、最近的日志**上传到收集站,站长在网页上就能查到,不用你截图、也不用翻日志文件。**默认开启**。上传失败不影响报错本身(错误卡片照常发)。不想要就在这里关掉。`),c([`qq`,`errorReportUrl`],`上报服务器地址`,`错误收集站的地址,**默认 https://err.tangbot.xyz**。自建的话填自己的域名(不要带结尾斜杠)。上报内容会 POST 到「地址 + /api/v1/reports」。`,{type:`text`}),c([`qq`,`errorReportToken`],`上报令牌`,`收集站要求的令牌,要和服务器端的 KKK_ERR_TOKEN 一致;填错会返回 401,日志里会写「上传失败 HTTP 401」。服务器启动时会打印这个令牌(没设就随机生成一个)。`,{type:`text`}),c([`qq`,`errorReportLogLines`],`上报日志行数`,`上报时带多少行日志:本次请求捕获的日志 + 宿主日志文件的尾部(宿主那份最多 300 行)。0 = 完全不上传日志。单行超长的(比如 OneBot 把 4.6MB 的 base64 塞进报错)会自动折叠,不会把上报撑爆。`,{type:`number`,fallback:200,min:0,max:1000}),c([`qq`,`errorReportGroup`],`问题反馈群号`,`错误消息里带上这个群号,用户拿着上报编号进群提问。QQ 官方机器人会把它渲染成**可点的加群链接**(https://qm.qq.com/q/群号),个人号(NapCat 等)直接给纯文本链接,QQ 客户端同样会变成可点。`,{type:`text`})]}))/*KKK-SECTION-END*/,o(`渲染设置`,(0,U.jsxs)(U.Fragment,{children:[c([`app`,`renderScale`],`渲染精度`,`可选值50~200,建议100。设置高精度会提高图片的精细度,过高可能会影响渲染与发送速度。`,{type:`number`,fallback:100,min:50,max:200}),(0,U.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,U.jsx)(`div`,{className:`min-w-0 flex-1`,children:i([`app`,`Theme`],`渲染图片的主题色`,`渲染评论图和推送图的主题色。`,[{label:`自动`,value:`0`,description:`06:00-18:00为浅色,18:00-06:00为深色`},{label:`浅色`,value:`1`},{label:`深色`,value:`2`},{label:`智能场景(实验性)`,value:`3`,description:`自动模式的超集;部分模板会根据封面色调 智能调整主题色,可能会出现不适配的情况。`}],e=>Number(e))}),(0,U.jsxs)(gv,{children:[(0,U.jsx)(gv.Trigger,{"aria-label":`封面氛围背景参数`,className:`mt-7 shrink-0`,children:(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":`封面氛围背景参数`,variant:`secondary`,children:(0,U.jsx)(Gj,{className:`size-4`,"aria-hidden":`true`})})}),(0,U.jsx)(gv.Content,{className:`w-90 max-w-[calc(100vw-2rem)]`,placement:`bottom`,children:(0,U.jsxs)(gv.Dialog,{children:[(0,U.jsx)(gv.Arrow,{}),(0,U.jsx)(gv.Heading,{children:`封面氛围背景`}),(0,U.jsx)(`p`,{className:`mt-1 mb-5 text-sm text-muted`,children:`仅对使用封面氛围背景的模板生效(抖音视频/图文作品、B站视频信息、B站直播推荐动态)。`}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[a([`app`,`ambientCover`,`coverOpacity`],`封面氛围强度`,`封面图对背景氛围的贡献度,即模糊封面层的不透明度,越大封面色越浓。`,{fallback:.7}),a([`app`,`ambientCover`,`overlayEdgeOpacity`],`氛围压色(顶部/底部)`,`背景两端主题色压色罩的不透明度,越大两端越接近纯色主题背景。`,{fallback:.9}),a([`app`,`ambientCover`,`overlayMiddleOpacity`],`氛围压色(中间带)`,`背景中间带主题色压色罩的不透明度,越小封面色越透。`,{fallback:.2})]})]})})]})]}),c([`app`,`RenderWaitTime`],`渲染图片的等待时间`,`单位:秒,Linux系统下不能为0;其他系统传递 0 可禁用。`,{type:`number`,fallback:60,min:0}),s([`app`,`multiPageRender`],`分页渲染`,`将模板渲染成多页的图片,以降低渲染器压力,默认开启,非必要不修改!`),c([`app`,`multiPageHeight`],`分页渲染时,每页的高度`,`经测试最佳每页高度为12000px,默认12000px。`,{type:`number`,disabled:!Q(e,[`app`,`multiPageRender`],!0),fallback:12e3,min:1e3,max:2e4})]})),/*KKK-RENDERER-START*/o(`通用设置`,(0,U.jsxs)(U.Fragment,{children:[i([`app`,`renderer`],`优先渲染器`,`卡片优先用哪个渲染器渲染。两个渲染服务都在时会按这里选的走,缺一个就自动用另一个;`,[{label:`shotkit 内核(默认)`,value:`shotkit`,description:`不依赖浏览器,单张几十毫秒、内存低。注意:当前预编译内核在 Windows 上加载不了 https 资源,卡片里的远程封面、头像会缺图。`},{label:`浏览器(Chrome / Edge)`,value:`puppeteer`,description:`完整渲染、远程资源正常,单张通常 1 秒以上,需要浏览器渲染服务(koishi-plugin-puppeteer 或同类)。`}],e=>e)]}))/*KKK-RENDERER-END*/,o(`上传与下载设置`,(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(Ev,{className:`flex flex-col gap-5 p-4 mb-4 rounded-3xl`,variant:`secondary`,children:[i([`app`,`videoSendMode`],`本地视频发送方式`,`选择本地视频交付给协议端的方式。`,[{label:`File 协议(本地文件)`,value:`file`,description:`使用 file 协议发送本地视频,需 Koishi 与协议端在同一网络环境下`},{label:`Base64(编码传输)`,value:`base64`,description:`将本地视频转换为 base64 发送,传输数据量增大约 30%,不在同一网络环境可能导致额外带宽成本,适合 karin 和协议端不在同一网络环境`}],e=>e,Q(e,[`app`,`usegroupfile`],!1)),s([`app`,`usegroupfile`],`群文件上传`,`使用群文件上传,开启后会将视频文件上传到群文件中,需配置「群文件上传阈值」。与「本地视频发送方式 = Base64」互斥。`,Q(e,[`app`,`videoSendMode`],`file`)===`base64`),c([`app`,`groupfilevalue`],`群文件上传阈值`,`当文件大小超过该值时将使用群文件上传,单位:MB,「使用群文件上传」开启后才会生效。`,{type:`number`,fallback:100,min:1,disabled:!Q(e,[`app`,`usegroupfile`],!1)||Q(e,[`app`,`videoSendMode`],`file`)===`base64`})]}),(0,U.jsx)(Ev,{className:`flex flex-col gap-5 p-4 mb-4 rounded-3xl`,variant:`secondary`,children:i([`app`,`imageSendMode`],`网络图片发送方式`,`图片资源发送给协议端的方式。`,[{label:`URL 链接(直接传递)`,value:`url`,description:`直接传递 HTTP 链接给上游下载,可能因上游网络问题导致下载超时`},{label:`File 协议(本地文件)`,value:`file`,description:`下载到本地后使用 file 协议发送,需 Koishi 与协议端在同一网络环境下`},{label:`Base64(编码传输)`,value:`base64`,description:`下载后转换为 base64 发送,传输数据量增大约 30%,不在同一网络环境可能导致额外带宽成本`}])}),(0,U.jsxs)(Ev,{className:`flex flex-col gap-5 p-4 mb-4 rounded-3xl`,variant:`secondary`,children:[s([`app`,`usefilelimit`],`视频上传拦截`,`开启后会根据视频文件大小判断是否需要上传,需配置「视频拦截阈值」。`),c([`app`,`filelimit`],`视频拦截阈值`,`视频文件大于该数值则直接结束任务,不会上传,单位: MB,「视频上传拦截」开启后才会生效。`,{type:`number`,fallback:20,min:1,disabled:!Q(e,[`app`,`usefilelimit`],!1)}),s([`app`,`compress`],`压缩视频`,`开启后会将视频文件压缩后再上传,适合上传大文件,任务过程中会吃满CPU,对低配服务器不友好。需配置「压缩触发阈值」与「压缩后的值」。`),c([`app`,`compresstrigger`],`压缩触发阈值`,`触发视频压缩的阈值,单位:MB。当文件大小超过该值时,才会压缩视频,「压缩视频」开启后才会生效。`,{type:`number`,fallback:80,min:1,disabled:!Q(e,[`app`,`compress`],!1)}),c([`app`,`compressvalue`],`压缩后的值`,`单位:MB,若视频文件大小大于「压缩触发阈值」的值,则会进行压缩至该值(±5%),「压缩视频」开启后才会生效。`,{type:`number`,fallback:30,min:1,disabled:!Q(e,[`app`,`compress`],!1)})]}),(0,U.jsxs)(Ev,{className:`flex flex-col gap-5 p-4 rounded-3xl`,variant:`secondary`,children:[s([`app`,`downloadThrottle`],`下载限速`,`开启后会限制下载速度,避免触发服务器风控导致连接被重置(ECONNRESET)。如果下载时经常报错"连接被重置",建议开启。`),c([`app`,`downloadMaxSpeed`],`最大下载速度`,`限速开关打开后生效。单位:MB/s,建议值:10,根据实际情况调整。`,{type:`number`,fallback:10,min:1,max:100,disabled:!Q(e,[`app`,`downloadThrottle`],!1)}),s([`app`,`downloadAutoReduce`],`断流自动降速`,`限速开关打开后生效。当检测到下载中断时,自动降低下载速度,避免再次触发风控。`,!Q(e,[`app`,`downloadThrottle`],!1)),c([`app`,`downloadMinSpeed`],`最低下载速度`,`断流降速开关打开后生效。单位:MB/s,自动降速的下限值。`,{type:`number`,fallback:1,min:.5,max:50,disabled:!Q(e,[`app`,`downloadThrottle`],!1)||!Q(e,[`app`,`downloadAutoReduce`],!1)})]})]})),o(`Live Photo 兼容设置`,(0,U.jsxs)(U.Fragment,{children:[i([`app`,`livePhotoMode`],`Live Photo 处理和发送方式`,`解析遇到实况图时的处理和发送方式。注意:生成视频性能开销大,2C2G 服务器单张约需 20 秒。`,[{label:`视频 + 实况图`,value:`video_and_livephoto`,description:`生成并发送仿 iPhone Live Photo 播放效果的视频(播放三次)+ 对应系统的实况图`},{label:`仅视频`,value:`video_only`,description:`仅生成并发送仿 iPhone Live Photo 播放效果的视频(播放三次)`},{label:`仅实况图`,value:`livephoto_only`,description:`仅生成并发送对应系统的实况图,性能开销小`}]),i([`app`,`livePhotoSystem`],`Live Photo 静态图兼容系统`,`当解析到作品/动态包含 Live Photo 时,合并转发里发送的 Live Photo 静态图按所选系统生成。推荐 OPPO,兼容性最广。`,[{label:`Google`,value:`google`,description:`Google Motion Photo 格式`},{label:`小米(HyperOS)`,value:`xiaomi`,description:`兼容小米(任何版本)和 Google,但无法被 OPPO 识别`},{label:`OPPO(ColorOS)`,value:`oppo`,description:`推荐,兼容 OPPO、小米(较新版本)和 Google`},{label:`华为/荣耀(HarmonyOS/MagicOS)`,value:`huawei_honor`,description:`理论可行但未实测(作者无对应设备)`},{label:`vivo(Origin OS)`,value:`vivo`,description:`需要独立的图片和同名视频文件,暂不支持`,disabled:!0},{label:`iPhone(iOS)`,value:`iphone`,description:`需要独立的图片和同名视频文件,暂不支持`,disabled:!0}],e=>e,l===`video_only`)]})),o(`我的小玩具`,(0,U.jsxs)(U.Fragment,{children:[s([`app`,`videoTool`],`默认解析优先级`,`关闭后使用自定义优先级,修改后需重启。`),c([`app`,`priority`],`自定义优先级`,`默认解析优先级关闭后生效。`,{type:`number`,disabled:Q(e,[`app`,`videoTool`],!0),fallback:800}),i([`app`,`qrLoginAddrType`],`扫码登录地址`,`生成登录二维码时使用的服务器地址。`,[{label:`局域网`,value:`lan`,description:`适用于手机和服务器在同一局域网`},{label:`外部地址`,value:`external`,description:`适用于远程访问,需手动配置`}]),c([`app`,`qrLoginExternalAddr`],`外部访问地址`,`公网 IP 或域名,如:123.45.67.89 或 example.com。`,{disabled:Q(e,[`app`,`qrLoginAddrType`],`lan`)!==`external`})]}))]})},ZL=({config:e,renderers:t,classes:n})=>{let{renderCheckboxGroup:r,renderCronField:i,renderPageHeader:a,renderSelectField:o,renderSubSection:s,renderSwitch:c,renderTextField:l}=t,u=Q(e,[`bilibili`,`switch`],!1),d=Q(e,[`bilibili`,`sendContent`],[]),f=Q(e,[`bilibili`,`burnDanmaku`],!1),p=Q(e,[`bilibili`,`videoQuality`],0),m=Q(e,[`bilibili`,`videoInfoMode`],`text`),h=Q(e,[`bilibili`,`push`,`switch`],!1),g=Q(e,[`bilibili`,`push`,`parsedynamic`],!1),_=Q(e,[`bilibili`,`push`,`pushVideoQuality`],0),v=!u||!_L(d,`comment`),y=!u||!f;return(0,U.jsxs)(U.Fragment,{children:[a(`哔哩哔哩`,`B站解析、动态图片布局、弹幕和推送基础设置。`),(0,U.jsxs)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:[c([`bilibili`,`switch`],`解析开关`,`B站解析开关,此开关为单独开关。`),r([`bilibili`,`sendContent`],`解析时发送的内容`,`若什么都不选,可能不会返回任何解析结果。`,jL.filter(e=>e.value!==`image`),!u)]}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`bilibili`,`forward`],`合并转发(哔哩哔哩)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`bilibili`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,s(`评论详情设置`,(0,U.jsxs)(U.Fragment,{children:[l([`bilibili`,`numcomment`],`评论解析数量`,`主评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:v}),c([`bilibili`,`realCommentCount`],`显示真实评论数量`,`关闭则显示解析到的评论数量。`,v),c([`bilibili`,`commentImageCollection`],`是否收集评论区的图片`,`开启后将收集评论区的图片,以合并转发的形式返回。`,v)]})),s(`渲染与画质设置`,(0,U.jsxs)(U.Fragment,{children:[o([`bilibili`,`videoQuality`],`画质偏好`,`解析视频的分辨率偏好。`,PL,Number,!u),l([`bilibili`,`maxAutoVideoSize`],`视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!u||Number(p)!==0}),o([`bilibili`,`imageLayout`],`解析图文动态时,遇到多张图片时的页面布局方式(动态推送图片也生效)`,`自动布局:少于4张时逐张上下排列;4~8张时瀑布流;9张及以上九宫格。`,[{label:`自动布局`,value:`auto`},{label:`逐张上下排列`,value:`vertical`},{label:`瀑布流排列`,value:`waterfall`},{label:`九宫格排列`,value:`grid`}]),o([`bilibili`,`videoInfoMode`],`视频信息返回形式`,`视频信息返回文本或图片。`,[{label:`图片模式`,value:`image`},{label:`文本模式`,value:`text`}],e=>e,!u),r([`bilibili`,`displayContent`],`视频信息前返回的内容`,`若什么都不选,则不会返回任何视频相关信息。`,ML,!u||m===`image`),c([`bilibili`,`showDanmakuInVideoInfo`],`视频信息图片中显示弹幕`,`开启后在视频信息图片的封面区域显示热门弹幕。关闭后不会请求弹幕数据,可提升解析速度。仅「视频信息返回形式」为图片模式时生效。`,!u||m===`text`)]})),s(`权限设置`,(0,U.jsx)(U.Fragment,{children:t.renderPermField([`bilibili`,`loginPerm`],`谁可以触发扫码登录`,`选「指定账号」后填用户 ID,多个用逗号分隔。`,{modes:[{value:`all`,label:`所有人`},{value:`admin`,label:`管理员(权限等级 4 及以上)`},{value:`id`,label:`指定账号`}]})})),s(`弹幕烧录相关`,(0,U.jsxs)(U.Fragment,{children:[c([`bilibili`,`burnDanmaku`],`弹幕烧录`,`将弹幕硬编码到视频画面中。开启后视频需要重新编码,耗时较长,高分辨率视频会占用较多资源。`,!u),o([`bilibili`,`danmakuArea`],`弹幕区域`,`限制弹幕的显示范围,避免遮挡视频主体内容。`,zL,Number,y),o([`bilibili`,`danmakuFontSize`],`弹幕字号`,`弹幕文字大小。`,BL,e=>e,y),l([`bilibili`,`danmakuOpacity`],`弹幕透明度`,`0为完全透明,100为完全不透明,推荐70。`,{type:`number`,fallback:70,min:0,max:100,disabled:y}),o([`bilibili`,`verticalMode`],`竖屏适配`,`模拟手机端竖屏观看体验,视频居中显示,上下黑边区域用于展示弹幕。`,RL,e=>e,y),o([`bilibili`,`videoCodec`],`视频编码格式`,`弹幕烧录时使用的视频编码格式,会自动检测硬件加速。`,LL,e=>e,y)]})),s(`B站推送相关`,(0,U.jsxs)(U.Fragment,{children:[c([`bilibili`,`push`,`switch`],`推送开关`,`推送开关,修改后需重启;使用「#设置B站推送 + UID」配置推送列表。`),o([`bilibili`,`push`,`permission`],`谁可以设置推送`,`修改后需重启。`,IL,e=>e,!h),i([`bilibili`,`push`,`cron`],`定时任务表达式`,`定时推送的时间,支持可视化编辑或手动输入 cron 表达式。`,!h),c([`bilibili`,`push`,`parsedynamic`],`作品解析`,`触发推送时是否一同解析该作品。`,!h),r([`bilibili`,`push`,`parseDynamicTypes`],`需要解析的动态类型`,`选择推送时需要进一步解析的动态类型;未选择的类型只发送动态卡片。`,FL,!h||!g),o([`bilibili`,`push`,`pushVideoQuality`],`解析视频动态时的画质偏好`,`「作品解析」开启时生效,仅对视频动态有效。`,PL.filter(e=>e.value!==`127`),Number,!h||!g),l([`bilibili`,`push`,`pushMaxAutoVideoSize`],`视频动态的视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「解析视频动态时的画质偏好」 为 "自动选择" 且「作品解析」开启时生效,仅对视频动态有效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!h||!g||Number(_)!==0})]}))]})},QL=({config:e,renderers:t,classes:n})=>{let{renderCheckboxGroup:r,renderCronField:i,renderPageHeader:a,renderSelectField:o,renderSubSection:s,renderSwitch:c,renderTextField:l}=t,u=Q(e,[`app`,`livePhotoMode`],`video_and_livephoto`),d=Q(e,[`douyin`,`switch`],!1),f=Q(e,[`douyin`,`sendContent`],[]),p=Q(e,[`douyin`,`burnDanmaku`],!1),m=Q(e,[`douyin`,`videoQuality`],`adapt`),h=Q(e,[`douyin`,`videoInfoMode`],`text`),g=Q(e,[`douyin`,`push`,`switch`],!1),_=Q(e,[`douyin`,`push`,`pushVideoQuality`],`adapt`),v=!d||!_L(f,`comment`),y=!d||!p;return(0,U.jsxs)(U.Fragment,{children:[a(`抖音`,`抖音解析、画质、弹幕和推送基础设置。`),(0,U.jsxs)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:[c([`douyin`,`switch`],`解析开关`,`抖音解析开关,此开关为单独开关。`),r([`douyin`,`sendContent`],`解析时发送的内容`,`若什么都不选,可能不会返回任何解析结果。`,jL.filter(e=>e.value!==`image`),!d)]}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`douyin`,`forward`],`合并转发(抖音)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`douyin`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,s(`评论详情设置`,(0,U.jsxs)(U.Fragment,{children:[l([`douyin`,`numcomment`],`评论解析数量`,`主评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:v}),l([`douyin`,`subCommentLimit`],`子评论请求数量`,`单条主评论下请求的子评论总条数(含多层嵌套)。注意:UI中最多显示 6 层回复嵌套,超出部分会被隐藏;因实际嵌套深度不可预知,配置数量不代表最终可见数量。`,{type:`number`,fallback:5,min:1,max:20,disabled:v}),c([`douyin`,`commentImageCollection`],`是否收集评论区的图片`,`开启后将收集评论区的图片,以合并转发的形式返回。`,v)]})),s(`渲染与画质设置`,(0,U.jsxs)(U.Fragment,{children:[o([`douyin`,`liveImageMergeMode`],`合辑 Live 图 BGM 合并方式`,`合辑 Live 图 BGM 合并方式,仅 Live Photo 模式不是「仅实况图」时生效。`,[{label:`连续`,value:`continuous`,description:`BGM 接续播放,结束后自动循环`},{label:`独立`,value:`independent`,description:`每张图 BGM 从头开始`}],e=>e,!d||u===`livephoto_only`),o([`douyin`,`videoQuality`],`画质偏好`,`解析视频的分辨率偏好。`,NL,e=>e,!d),l([`douyin`,`maxAutoVideoSize`],`视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!d||m!==`adapt`}),o([`douyin`,`videoInfoMode`],`视频信息返回形式`,`视频信息返回文本或图片。`,[{label:`图片模式`,value:`image`},{label:`文本模式`,value:`text`}],e=>e,!d),r([`douyin`,`displayContent`],`视频信息的内容`,`若什么都不选,则不会返回任何视频相关信息。`,ML.filter(e=>e.value!==`desc`),!d||h===`image`)]})),s(`权限设置`,(0,U.jsx)(U.Fragment,{children:t.renderPermField([`douyin`,`loginPerm`],`谁可以触发扫码登录`,`选「指定账号」后填用户 ID,多个用逗号分隔。`,{modes:[{value:`all`,label:`所有人`},{value:`admin`,label:`管理员(权限等级 4 及以上)`},{value:`id`,label:`指定账号`}]})})),s(`弹幕烧录相关`,(0,U.jsxs)(U.Fragment,{children:[c([`douyin`,`burnDanmaku`],`弹幕烧录`,`将弹幕硬编码到视频画面中。开启后视频需要重新编码,耗时较长。`,!d),o([`douyin`,`danmakuArea`],`弹幕显示区域`,`限制弹幕范围,避免遮挡视频主体。`,zL,Number,y),o([`douyin`,`danmakuFontSize`],`弹幕字号`,`弹幕文字大小。`,BL,e=>e,y),l([`douyin`,`danmakuOpacity`],`弹幕透明度`,`0为完全透明,100为完全不透明,推荐70。`,{type:`number`,fallback:70,min:0,max:100,disabled:y}),o([`douyin`,`verticalMode`],`竖屏适配`,`针对横屏视频,模拟手机端竖屏观看体验,视频居中显示,上下黑边区域用于展示弹幕。`,RL,e=>e,y),o([`douyin`,`videoCodec`],`视频编码格式`,`烧录弹幕后的视频编码格式。`,LL,e=>e,y)]})),s(`抖音推送相关`,(0,U.jsxs)(U.Fragment,{children:[c([`douyin`,`push`,`switch`],`推送开关`,`推送开关,修改后需重启;使用「#设置抖音推送 + 抖音号」配置推送列表。`),o([`douyin`,`push`,`permission`],`谁可以设置推送`,`修改后需重启。`,IL,e=>e,!g),i([`douyin`,`push`,`cron`],`定时任务表达式`,`定时推送的时间,支持可视化编辑或手动输入 cron 表达式。`,!g),c([`douyin`,`push`,`parsedynamic`],`作品解析`,`触发推送时是否一同解析该作品。`,!g),o([`douyin`,`push`,`shareType`],`推送图二维码的类型`,`推送图二维码识别后的跳转类型。`,[{label:`网页链接`,value:`web`,description:`识别后访问抖音官网对应的作品地址`},{label:`下载链接`,value:`download`,description:`识别后访问无水印作品下载地址`}],e=>e,!g),o([`douyin`,`push`,`pushVideoQuality`],`画质偏好`,`推送解析时解析视频的分辨率偏好。`,NL,e=>e,!g),l([`douyin`,`push`,`pushMaxAutoVideoSize`],`视频体积上限(MB)`,`推送解析时根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!g||_!==`adapt`})]}))]})},$L=({config:e,renderers:t,classes:n})=>{let{renderPageHeader:r,renderSubSection:i,renderSwitch:a,renderTextField:o}=t,s=Q(e,[`kuaishou`,`switch`],!1),c=Q(e,[`kuaishou`,`comment`],!1);return(0,U.jsxs)(U.Fragment,{children:[r(`快手`,`快手解析基础设置。`),(0,U.jsx)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:a([`kuaishou`,`switch`],`解析开关`,`快手解析开关,此开关为单独开关。`)}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`kuaishou`,`forward`],`合并转发(快手)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`kuaishou`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,i(`评论详情设置`,(0,U.jsxs)(U.Fragment,{children:[a([`kuaishou`,`comment`],`评论解析`,`快手评论解析,开启后可发送快手作品评论图。`,!s),o([`kuaishou`,`numcomment`],`评论解析数量`,`快手评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:!s||!c})]}))]})},eR=({children:e,disabled:t,message:n,device:r})=>t?r===`mobile`?(0,U.jsxs)(gv,{children:[(0,U.jsx)(gv.Trigger,{className:`w-full cursor-not-allowed`,children:e}),(0,U.jsxs)(gv.Content,{placement:`bottom`,children:[(0,U.jsx)(gv.Arrow,{}),(0,U.jsx)(`div`,{className:`px-3 py-2`,children:(0,U.jsx)(`p`,{className:`text-sm text-foreground`,children:n})})]})]}):(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{className:`w-full cursor-not-allowed`,children:e}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),n]})]}):e,tR=e=>e===`desktop`?`grid grid-cols-2 gap-4`:`flex flex-col gap-4`,nR=[{label:`作品列表`,value:`post`,description:`推送用户发布的作品`},{label:`喜欢列表`,value:`favorite`,description:`推送用户喜欢的作品`},{label:`推荐列表`,value:`recommend`,description:`推送推荐的作品`},{label:`直播`,value:`live`,description:`推送直播状态`}],rR=[{label:`投稿视频`,value:`video`,description:`推送UP主投稿的视频`},{label:`图文动态`,value:`draw`,description:`推送图文动态`},{label:`纯文动态`,value:`word`,description:`推送纯文字动态`},{label:`直播动态`,value:`live`,description:`推送直播状态`},{label:`转发动态`,value:`forward`,description:`推送转发的动态`},{label:`投稿专栏`,value:`article`,description:`推送专栏文章`}],iR=[{label:`黑名单`,value:`blacklist`,description:`命中关键词/标签则不推送`},{label:`白名单`,value:`whitelist`,description:`只推送命中关键词/标签的内容`}],aR=({label:e,description:t,items:n,onAdd:r,onRemove:i,disabled:a=!1})=>{let[o,s]=(0,v.useState)(``),[c,l]=(0,v.useState)(``),u=()=>{let e=o.trim();if(!e){l(`请输入内容`);return}if(n.includes(e)){l(`该项已存在,请勿重复添加`);return}r(e),s(``),l(``)};return(0,U.jsxs)(`div`,{className:`space-y-2`,children:[(0,U.jsxs)(`div`,{className:`flex gap-2`,children:[(0,U.jsxs)(lx,{className:`flex-1`,isDisabled:a,isInvalid:!!c,value:o,onChange:e=>{s(e),c&&l(``)},children:[(0,U.jsx)(dx,{children:e}),(0,U.jsx)(cx,{variant:`secondary`,placeholder:`输入${e}`,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),u())}}),c?(0,U.jsx)(hx,{children:c}):null]}),(0,U.jsx)(Vg,{isDisabled:a,variant:`secondary`,onPress:u,children:(0,U.jsx)(Hj,{className:`size-4`})})]}),n.length>0?(0,U.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:n.map(e=>(0,U.jsxs)(v_,{color:`accent`,variant:`soft`,children:[(0,U.jsx)(`span`,{children:e}),a?null:(0,U.jsx)(`button`,{type:`button`,className:`ml-1 rounded-full p-0.5 hover:bg-black/10`,onClick:()=>i(e),children:(0,U.jsx)(Kj,{className:`size-3`})})]},e))}):(0,U.jsxs)(px,{children:[`暂无`,e]}),(0,U.jsx)(px,{children:t})]})},oR=(e,t)=>{if((e.success||e.code===200)&&e.data!==void 0)return e.data;throw Error(e.message||t)},sR=async()=>{let r=(await eI.get(`/kkk/v1/bots`)).data?.data;return Array.isArray(r)?r:[]},cR=async e=>{let r=(await eI.get(`/kkk/v1/bots/${encodeURIComponent(e)}/groups`)).data?.data;return Array.isArray(r)?r:[]},lR=async e=>{if(!e.length)return [];let r=(await eI.post(`/kkk/v1/groups/batch`,{groups:e})).data?.data;return Array.isArray(r)?r:[]},uR=({mapping:e,compact:t=!1,stacked:n=!1})=>n?(0,U.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2`,children:[(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.groupName||e.groupId,src:e.groupAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.groupName||e.groupId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.groupName||e.groupId}),(0,U.jsx)(px,{className:`block truncate`,children:e.groupId})]})]}),(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 pl-8`,children:[(0,U.jsx)(Nj,{className:`size-4 shrink-0 text-muted`}),(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.botName||e.botId,src:e.botAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.botName||e.botId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.botName||e.botId}),(0,U.jsx)(px,{className:`block truncate`,children:t?e.botId:`Bot ${e.botId}`})]})]})]}):(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.groupName||e.groupId,src:e.groupAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.groupName||e.groupId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.groupName||e.groupId}),(0,U.jsx)(px,{className:`block truncate`,children:e.groupId})]}),(0,U.jsx)(Nj,{className:`size-4 shrink-0 text-muted`}),(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.botName||e.botId,src:e.botAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.botName||e.botId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.botName||e.botId}),(0,U.jsx)(px,{className:`block truncate`,children:t?e.botId:`Bot ${e.botId}`})]})]}),dR=e=>`${e.groupId}:${e.botId}`,fR=e=>{let[t,n,r]=e.split(`:`);return!t||!n||r!==void 0?null:{groupId:t,botId:n}},pR=e=>{let t=new Set,n=[];return e.forEach(e=>{let r=fR(e);if(!r)return;let i=dR(r);t.has(i)||(t.add(i),n.push(i))}),n},mR=({device:e,mappings:t,onEdit:n,onRemove:r})=>(0,U.jsxs)(`div`,{className:e===`mobile`?`flex min-h-0 min-w-0 flex-1 flex-col gap-4`:`flex min-w-0 flex-col gap-3`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(dx,{children:`已配置目标`}),(0,U.jsxs)(px,{children:[t.length,` 个推送目标`]})]}),t.length>0?(0,U.jsx)(`div`,{className:e===`mobile`?`flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto pb-2`:`flex max-h-72 flex-col gap-2 overflow-y-auto`,children:t.map(t=>{let i=dR(t);return(0,U.jsxs)(`div`,{className:`flex min-w-0 items-start gap-2 rounded-lg border border-default-200 bg-default-50/50 p-2.5`,children:[(0,U.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,U.jsx)(uR,{compact:!0,mapping:t,stacked:e===`mobile`})}),(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":`编辑推送目标`,size:`sm`,variant:`tertiary`,onPress:()=>n(i),children:(0,U.jsx)(Vj,{className:`size-4`})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),`编辑`]})]}),(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":`删除推送目标`,size:`sm`,variant:`danger`,onPress:()=>r(i),children:(0,U.jsx)(Kj,{className:`size-4`})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),`删除`]})]})]},i)})}):(0,U.jsx)(`div`,{className:`rounded-lg border border-dashed border-default-300 px-4 py-5 text-sm text-muted`,children:`还没有推送目标,点击上方按钮添加。`})]}),hR=({label:e,description:t,placeholder:n,disabled:r=!1,items:i,selectedId:a,onSelect:o})=>(0,U.jsxs)(Ax,{fullWidth:!0,allowsEmptyCollection:!0,isDisabled:r,placeholder:n,value:a||null,variant:`secondary`,onChange:e=>o(String(e||``)),children:[(0,U.jsx)(dx,{children:e}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{children:({defaultChildren:e,isPlaceholder:t,state:n})=>{if(t||n.selectedItems.length===0)return e;let r=i.find(e=>e.id===n.selectedItems[0]?.key);return r?(0,U.jsxs)(`span`,{className:`flex min-w-0 items-center gap-3`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:r.name,src:r.avatar}),(0,U.jsx)(Ig.Fallback,{children:r.name.slice(0,1)})]}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`span`,{className:`block truncate`,children:r.name}),(0,U.jsx)(`span`,{className:`block truncate text-xs text-muted`,children:r.description})]})]}):e}}),(0,U.jsx)(Ax.Indicator,{})]}),(0,U.jsx)(px,{children:t}),!r&&i.length===0?(0,U.jsx)(px,{className:`text-warning`,children:`当前没有可选项`}):null,(0,U.jsx)(Ax.Popover,{className:`max-h-72`,children:(0,U.jsx)(wx,{items:i,children:e=>(0,U.jsxs)(wx.Item,{id:e.id,textValue:`${e.name} ${e.description}`,children:[(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.name,src:e.avatar}),(0,U.jsx)(Ig.Fallback,{children:e.name.slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(dx,{className:`truncate`,children:e.name}),(0,U.jsx)(px,{className:`truncate`,children:e.description})]})]}),(0,U.jsx)(wx.ItemIndicator,{})]})})})]}),gR=({isOpen:e,device:t,initialMapping:n,onOpenChange:r,onConfirm:i})=>{let[a,o]=(0,v.useState)([]),[s,c]=(0,v.useState)([]),[l,u]=(0,v.useState)(n?.botId||``),[d,f]=(0,v.useState)(n?.groupId||``),[p,m]=(0,v.useState)(!0),[h,g]=(0,v.useState)(!!n?.botId),[_,y]=(0,v.useState)(``);(0,v.useEffect)(()=>{e&&(u(n?.botId||``),f(n?.groupId||``),c([]),o([]),m(!0),g(!!n?.botId),y(``))},[e,n?.botId,n?.groupId]);let b=(0,v.useMemo)(()=>a.find(e=>e.id===l),[a,l]),x=(0,v.useMemo)(()=>s.find(e=>e.id===d),[s,d]),S=(0,v.useMemo)(()=>a.map(e=>({id:e.id,name:e.name,avatar:e.avatar,description:e.id})),[a]),C=(0,v.useMemo)(()=>s.map(e=>({id:e.id,name:e.name,avatar:e.avatar,description:e.id})),[s]),w=!!(l&&d);(0,v.useEffect)(()=>{e&&sR().then(o).catch(e=>{y(e instanceof Error?e.message:`获取 Bot 列表失败`)}).finally(()=>m(!1))},[e]),(0,v.useEffect)(()=>{!e||!l||cR(l).then(e=>{c(e),f(t=>e.some(e=>e.id===t)?t:``)}).catch(e=>{y(e instanceof Error?e.message:`获取群列表失败`)}).finally(()=>g(!1))},[e,l]);let T=()=>{if(!w||!b)return;let e={groupId:(x&&x.id)||String(d||``).trim(),botId:b.id};x&&x.name&&(e.groupName=x.name),x&&x.avatar&&(e.groupAvatar=x.avatar),b.name&&(e.botName=b.name),b.avatar&&(e.botAvatar=b.avatar),b.isOnline!==void 0&&(e.isOnline=b.isOnline),i(e)},E=t===`desktop`?`right`:`bottom`,D=n?`编辑推送目标`:`添加推送目标`;return(0,U.jsx)(pv.Backdrop,{isOpen:e,onOpenChange:r,children:(0,U.jsx)(pv.Content,{placement:E,children:(0,U.jsxs)(pv.Dialog,{className:t===`desktop`?`h-full w-105 max-w-[90vw]`:`max-h-[78dvh]`,children:[(0,U.jsx)(pv.Handle,{}),(0,U.jsx)(pv.CloseTrigger,{}),(0,U.jsxs)(pv.Header,{children:[(0,U.jsx)(pv.Heading,{children:D}),(0,U.jsx)(px,{children:`先选择机器人账号,再填写要推送的群号。`})]}),(0,U.jsxs)(pv.Body,{className:`flex flex-col gap-4`,children:[(0,U.jsx)(hR,{description:`Koishi 当前已注册且在线的 Bot。`,disabled:p,items:S,label:`机器人账号`,placeholder:`选择机器人账号`,selectedId:l,onSelect:e=>{y(``),c([]),g(!!e),u(e),f(``)}}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(dx,{className:`font-semibold`,children:`推送群`}),(0,U.jsx)(`input`,{className:`w-full rounded-large border border-default-200 bg-default-100 px-3 py-2 text-sm outline-none`,placeholder:`填写群号,例如 1050229473`,value:d||``,onChange:e=>f(e.target.value)}),(0,U.jsx)(px,{className:`text-xs`,children:`直接填群号(频道 id)即可;要指定平台时写成 平台:群号。`})]}),p||h?(0,U.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在读取列表`}),(0,U.jsx)(`span`,{children:`正在读取列表`})]}):null,b&&x?(0,U.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-lg border border-default-200 bg-default-50/60 p-3`,children:[(0,U.jsx)(dx,{children:`将写入`}),(0,U.jsxs)(px,{className:`mt-1`,children:[x.name,`(`,x.id,`) -> `,b.name,`(`,b.id,`)`]})]}):null,_?(0,U.jsx)(px,{className:`text-danger`,children:_}):null]}),(0,U.jsxs)(pv.Footer,{children:[(0,U.jsx)(Vg,{size:t===`mobile`?`sm`:`md`,slot:`close`,variant:`secondary`,children:`取消`}),(0,U.jsx)(Vg,{size:t===`mobile`?`sm`:`md`,slot:`close`,isDisabled:!w,onPress:T,children:n?`保存`:`添加`})]})]})})})},_R=(e,t,n)=>{let r=pR(e);return{values:r,mappings:r.map(e=>{let r=fR(e),i=n[e]||t.find(t=>dR(t)===e);if(!r)return null;let a={groupId:r.groupId,botId:r.botId};return i?.groupName&&(a.groupName=i.groupName),i?.groupAvatar&&(a.groupAvatar=i.groupAvatar),i?.botName&&(a.botName=i.botName),i?.botAvatar&&(a.botAvatar=i.botAvatar),i?.isOnline!==void 0&&(a.isOnline=i.isOnline),a}).filter(e=>!!e)}},vR=({isOpen:e,values:t,mappings:n,device:r,onOpenChange:i,onApply:a})=>{let[o,s]=(0,v.useState)(()=>pR(t)),[c,l]=(0,v.useState)({}),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(!1),m=(0,v.useMemo)(()=>_R(o,n,c),[o,c,n]),h=r===`desktop`?`right`:`bottom`,g=u?fR(u):null,_=e=>{d(e),p(!0)};return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(pv.Backdrop,{isOpen:e,onOpenChange:e=>{e||a(m.values),i(e)},variant:`blur`,children:(0,U.jsx)(pv.Content,{placement:h,children:(0,U.jsxs)(pv.Dialog,{className:r===`desktop`?`h-full w-130 max-w-[90vw]`:`max-h-[84dvh]`,children:[(0,U.jsx)(pv.Handle,{}),(0,U.jsx)(pv.CloseTrigger,{}),(0,U.jsxs)(pv.Header,{children:[(0,U.jsx)(pv.Heading,{children:`推送目标`}),(0,U.jsx)(px,{children:`管理所有接收推送的群和 Bot 映射。`})]}),(0,U.jsxs)(pv.Body,{className:`flex min-h-0 flex-col gap-3`,children:[(0,U.jsxs)(Vg,{className:`self-start`,size:r===`mobile`?`sm`:`md`,onPress:()=>_(null),children:[(0,U.jsx)(Hj,{className:`size-4`}),`添加推送目标`]}),(0,U.jsx)(mR,{device:r,mappings:m.mappings,onEdit:e=>_(e),onRemove:e=>{s(t=>t.filter(t=>t!==e)),l(t=>{let n={...t};return delete n[e],n})}})]}),(0,U.jsxs)(pv.Footer,{children:[(0,U.jsx)(Vg,{size:r===`mobile`?`sm`:`md`,slot:`close`,variant:`secondary`,children:`取消`}),(0,U.jsx)(Vg,{size:r===`mobile`?`sm`:`md`,slot:`close`,onPress:()=>{a(m.values)},children:`完成`})]})]})})}),(0,U.jsx)(gR,{device:r,initialMapping:g,isOpen:f,onConfirm:e=>{let t=dR(e),n=[...o],r=u?n.indexOf(u):-1;r>=0?n[r]=t:n.unshift(t),s(pR(n)),l(n=>{let r={...n,[t]:e};return u&&u!==t&&delete r[u],r}),p(!1),d(null)},onOpenChange:p},u||`new`)]})},yR=(e,t)=>{let n=fR(e);if(!n)return null;let r={groupId:n.groupId,botId:n.botId};return t?.groupName&&(r.groupName=t.groupName),t?.groupAvatar&&(r.groupAvatar=t.groupAvatar),t?.botName&&(r.botName=t.botName),t?.botAvatar&&(r.botAvatar=t.botAvatar),t?.isOnline!==void 0&&(r.isOnline=t.isOnline),r},bR=({value:e,disabled:t,itemLabel:n,device:r,onChange:i})=>{let a=(0,v.useMemo)(()=>pR(e),[e]),o=(0,v.useMemo)(()=>e.filter(e=>!fR(e)),[e]),[s,c]=(0,v.useState)([]),[l,u]=(0,v.useState)(!1),[d,f]=(0,v.useState)(!1),p=(0,v.useMemo)(()=>a.map(e=>{let t=fR(e);return yR(e,t?s.find(e=>e.groupId===t.groupId&&e.botId===t.botId):void 0)}).filter(e=>!!e),[s,a]);(0,v.useEffect)(()=>{lR(a.map(fR).filter(e=>!!e)).then(c).catch(()=>c([])).finally(()=>u(!1))},[a]);let m=e=>i(pR(e)),h=`开启【${n}】的推送开关后才能编辑此字段`,g=a.length>0?`已配置 ${a.length} 个推送目标`:`还没有配置推送目标`;return(0,U.jsx)(eR,{disabled:t,device:r,message:h,children:(0,U.jsxs)(`div`,{className:`space-y-3`,children:[(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-4 rounded-lg border border-default-200 bg-default-50/50 px-4 py-3`,children:[(0,U.jsxs)(`div`,{className:`flex flex-col min-w-0`,children:[(0,U.jsx)(dx,{children:`推送目标`}),(0,U.jsx)(px,{className:`mt-1`,children:g})]}),(0,U.jsxs)(Vg,{isDisabled:t,size:r===`mobile`?`sm`:`md`,variant:r===`mobile`?`primary`:`secondary`,onPress:()=>f(!0),children:[(0,U.jsx)(Vj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`管理`})]})]}),l?(0,U.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在读取推送目标`}),(0,U.jsx)(`span`,{children:`正在读取推送目标`})]}):null,o.length>0?(0,U.jsxs)(`div`,{className:`rounded-lg border border-warning/30 bg-warning/10 p-3 text-sm`,children:[(0,U.jsxs)(`div`,{className:`flex items-center gap-2 font-medium text-warning`,children:[(0,U.jsx)(qj,{className:`size-4`}),(0,U.jsxs)(`span`,{children:[`发现 `,o.length,` 条旧格式或错误格式`]})]}),(0,U.jsx)(px,{className:`mt-1`,children:`建议删除后用可视化选择重新添加,避免后端解析异常。`})]}):null,(0,U.jsx)(vR,{device:r,isOpen:d,mappings:p,values:a,onApply:m,onOpenChange:f})]})})},xR=({disabled:e,itemLabel:t,device:n,value:r,onChange:i})=>(0,U.jsx)(bR,{disabled:e,device:n,itemLabel:t,value:r,onChange:i}),SR=({disabled:e,itemLabel:t,device:n,options:r,value:i,onChange:a})=>(0,U.jsx)(eR,{disabled:e,device:n,message:`开启【${t}】的推送开关后才能编辑此字段`,children:(0,U.jsxs)(c_,{"aria-label":`推送类型`,isDisabled:e,value:i,onChange:e=>a(e),children:[(0,U.jsx)(dx,{children:`推送类型`}),(0,U.jsx)(px,{children:`选择要推送的内容类型`}),(0,U.jsx)(`div`,{className:`mt-2 ${tR(n)}`,children:r.map(e=>(0,U.jsxs)(m_,{value:e.value,variant:`secondary`,children:[(0,U.jsxs)(m_.Content,{children:[(0,U.jsx)(m_.Control,{children:(0,U.jsx)(m_.Indicator,{})}),e.label]}),(0,U.jsx)(px,{children:e.description})]},e.value))})]})}),CR=({disabled:e,itemLabel:t,device:n,value:r,onChange:i})=>(0,U.jsx)(eR,{disabled:e,device:n,message:`开启【${t}】的推送开关后才能编辑此字段`,children:(0,U.jsxs)(Ax,{fullWidth:!0,isDisabled:e,value:r,onChange:e=>{e&&!Array.isArray(e)&&i(e)},children:[(0,U.jsx)(dx,{children:`过滤模式`}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{}),(0,U.jsx)(Ax.Indicator,{})]}),(0,U.jsx)(px,{children:`设置关键词/标签的过滤方式`}),(0,U.jsx)(Ax.Popover,{children:(0,U.jsx)(wx,{children:iR.map(e=>(0,U.jsxs)(wx.Item,{id:e.value,textValue:e.label,children:[(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(dx,{children:e.label}),(0,U.jsx)(px,{children:e.description})]}),(0,U.jsx)(wx.ItemIndicator,{})]},e.value))})})]})}),wR=({disabled:e,itemLabel:t,device:n,keywords:r,tags:i,onKeywordsChange:a,onTagsChange:o})=>{let s=`开启【${t}】的推送开关后才能编辑此字段`;return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(eR,{disabled:e,device:n,message:s,children:(0,U.jsx)(`div`,{children:(0,U.jsx)(aR,{label:`关键词`,description:`多个关键词用于内容过滤`,disabled:e,items:r,onAdd:e=>a([...r,e]),onRemove:e=>a(r.filter(t=>t!==e))})})}),(0,U.jsx)(eR,{disabled:e,device:n,message:s,children:(0,U.jsx)(`div`,{children:(0,U.jsx)(aR,{label:`标签`,description:`多个标签用于内容过滤`,disabled:e,items:i,onAdd:e=>o([...i,e]),onRemove:e=>o(i.filter(t=>t!==e))})})})]})},TR=({onDelete:e})=>(0,U.jsxs)(Vg,{className:`w-full`,variant:`danger`,onPress:e,children:[(0,U.jsx)(Kj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`删除此推送项`})]}),ER=({item:e,index:t,list:n,onChange:r,device:i})=>{let a=i=>{let a=[...n];a[t]={...e,...i},r(a)},o=!e.switch,s=e.remark||`UID: ${e.host_mid}`||`未命名`,c=`开启【${s}】的推送开关后才能编辑此字段`;return(0,U.jsxs)(Fc.Item,{id:`bilibili-${t}`,children:[(0,U.jsx)(Fc.Heading,{children:(0,U.jsxs)(Fc.Trigger,{children:[(0,U.jsxs)(`div`,{className:`flex flex-1 items-center gap-3`,children:[(0,U.jsx)(`div`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:(0,U.jsx)(ob,{"aria-label":`推送开关`,isSelected:e.switch,onChange:e=>a({switch:e}),children:(0,U.jsx)(ob.Content,{children:(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})})})})}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(`span`,{className:`font-medium`,children:e.remark||`UID: ${e.host_mid}`||`推送项 ${t+1}`}),(0,U.jsxs)(px,{className:`text-xs`,children:[`B站 UID: `,e.host_mid]})]})]}),(0,U.jsx)(Fc.Indicator,{children:(0,U.jsx)(Pj,{className:`size-5`})})]})}),(0,U.jsx)(Fc.Panel,{children:(0,U.jsx)(Fc.Body,{children:(0,U.jsxs)(`div`,{className:`space-y-4`,children:[(0,U.jsxs)(`div`,{className:tR(i),children:[(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,isRequired:!0,type:`number`,value:String(e.host_mid),onChange:e=>a({host_mid:Number(e)||0}),children:[(0,U.jsx)(dx,{children:`B站 UID`}),(0,U.jsx)(cx,{placeholder:`UP主的 UID`}),(0,U.jsx)(px,{children:`B站用户的唯一标识,必填`})]})}),(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,value:e.remark,onChange:e=>a({remark:e}),children:[(0,U.jsx)(dx,{children:`备注名称`}),(0,U.jsx)(cx,{placeholder:`可选,用于识别该推送项`}),(0,U.jsx)(px,{children:`方便识别的名称,如:UP主昵称`})]})})]}),(0,U.jsx)(xR,{disabled:o,device:i,itemLabel:s,value:e.group_id,onChange:e=>a({group_id:e})}),(0,U.jsx)(SR,{disabled:o,device:i,itemLabel:s,options:rR,value:e.pushTypes||[],onChange:e=>a({pushTypes:e})}),(0,U.jsx)(CR,{disabled:o,device:i,itemLabel:s,value:e.filterMode||`blacklist`,onChange:e=>a({filterMode:e})}),(0,U.jsx)(wR,{disabled:o,device:i,itemLabel:s,keywords:e.Keywords||[],tags:e.Tags||[],onKeywordsChange:e=>a({Keywords:e}),onTagsChange:e=>a({Tags:e})}),(0,U.jsx)(TR,{onDelete:()=>r(n.filter((e,n)=>n!==t))})]})})})]},t)},DR=({item:e,index:t,list:n,onChange:r,device:i})=>{let a=i=>{let a=[...n];a[t]={...e,...i},r(a)},o=!e.switch,s=e.remark||e.short_id||e.sec_uid||`未命名`,c=`开启【${s}】的推送开关后才能编辑此字段`;return(0,U.jsxs)(Fc.Item,{id:`douyin-${t}`,children:[(0,U.jsx)(Fc.Heading,{children:(0,U.jsxs)(Fc.Trigger,{children:[(0,U.jsxs)(`div`,{className:`flex flex-1 items-center gap-3`,children:[(0,U.jsx)(`div`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:(0,U.jsx)(ob,{"aria-label":`推送开关`,isSelected:e.switch,onChange:e=>a({switch:e}),children:(0,U.jsx)(ob.Content,{children:(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})})})})}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(`span`,{className:`font-medium`,children:e.remark||e.short_id||e.sec_uid||`推送项 ${t+1}`}),(0,U.jsxs)(px,{className:`text-xs`,children:[e.short_id&&`抖音号: ${e.short_id}`,e.sec_uid&&!e.short_id&&`sec_uid: ${e.sec_uid.slice(0,20)}...`]})]})]}),(0,U.jsx)(Fc.Indicator,{children:(0,U.jsx)(Pj,{className:`size-5`})})]})}),(0,U.jsx)(Fc.Panel,{children:(0,U.jsx)(Fc.Body,{children:(0,U.jsxs)(`div`,{className:`space-y-4`,children:[(0,U.jsxs)(`div`,{className:tR(i),children:[(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,isRequired:!0,value:e.short_id,onChange:e=>a({short_id:e}),children:[(0,U.jsx)(dx,{children:`抖音号`}),(0,U.jsx)(cx,{placeholder:`用户的抖音号`,variant:`secondary`}),(0,U.jsx)(px,{children:`用户的抖音号(short_id),必填`})]})}),(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,value:e.sec_uid,onChange:e=>a({sec_uid:e}),children:[(0,U.jsx)(dx,{children:`sec_uid`}),(0,U.jsx)(cx,{placeholder:`选填,会根据抖音号自动获取`,variant:`secondary`}),(0,U.jsx)(px,{children:`用户的 sec_uid,可从分享链接获取。选填,推送时会自动获取`})]})})]}),(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,value:e.remark,onChange:e=>a({remark:e}),children:[(0,U.jsx)(dx,{children:`备注名称`}),(0,U.jsx)(cx,{placeholder:`可选,用于识别该推送项`,variant:`secondary`}),(0,U.jsx)(px,{children:`方便识别的名称,如:博主昵称`})]})}),(0,U.jsx)(xR,{disabled:o,device:i,itemLabel:s,value:e.group_id,onChange:e=>a({group_id:e})}),(0,U.jsx)(SR,{disabled:o,device:i,itemLabel:s,options:nR,value:e.pushTypes||[],onChange:e=>a({pushTypes:e})}),(0,U.jsx)(CR,{disabled:o,device:i,itemLabel:s,value:e.filterMode||`blacklist`,onChange:e=>a({filterMode:e})}),(0,U.jsx)(wR,{disabled:o,device:i,itemLabel:s,keywords:e.Keywords||[],tags:e.Tags||[],onKeywordsChange:e=>a({Keywords:e}),onTagsChange:e=>a({Tags:e})}),(0,U.jsx)(TR,{onDelete:()=>r(n.filter((e,n)=>n!==t))})]})})})]},t)},OR=()=>({switch:!0,sec_uid:``,short_id:``,group_id:[],remark:``,pushTypes:[`post`],filterMode:`blacklist`,Keywords:[],Tags:[]}),kR=()=>({switch:!0,host_mid:0,group_id:[],remark:``,pushTypes:[`video`],filterMode:`blacklist`,Keywords:[],Tags:[]}),AR=({platform:e})=>(0,U.jsx)(`div`,{className:`rounded-lg border-2 border-dashed border-gray-300 p-8 text-center`,children:(0,U.jsxs)(`p`,{className:`text-muted`,children:[`暂无`,e===`douyin`?`抖音`:`B站`,`推送项,点击上方按钮添加`]})});function jR({douyinList:e,bilibiliList:t,onDouyinChange:n,onBilibiliChange:r,device:i}){let[a,o]=(0,v.useState)(`douyin`);return(0,U.jsx)(`div`,{className:`space-y-4`,children:(0,U.jsxs)(kb,{selectedKey:a,onSelectionChange:e=>o(e),children:[(0,U.jsx)(kb.ListContainer,{children:(0,U.jsxs)(kb.List,{children:[(0,U.jsxs)(kb.Tab,{id:`douyin`,children:[(0,U.jsx)(`span`,{children:`抖音推送`}),(0,U.jsx)(kb.Indicator,{})]}),(0,U.jsxs)(kb.Tab,{id:`bilibili`,children:[(0,U.jsx)(`span`,{children:`B站推送`}),(0,U.jsx)(kb.Indicator,{})]})]})}),(0,U.jsx)(kb.Panel,{id:`douyin`,children:(0,U.jsxs)(`div`,{className:`space-y-4 pt-4`,children:[(0,U.jsxs)(Vg,{className:`w-full`,variant:`primary`,size:`sm`,onPress:()=>n([...e,OR()]),children:[(0,U.jsx)(Hj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`添加抖音推送项`})]}),e.length>0?(0,U.jsx)(Fc,{variant:`surface`,"aria-label":`抖音推送列表`,children:e.map((t,r)=>(0,U.jsx)(DR,{device:i,index:r,item:t,list:e,onChange:n},r))}):(0,U.jsx)(AR,{platform:`douyin`})]})}),(0,U.jsx)(kb.Panel,{id:`bilibili`,children:(0,U.jsxs)(`div`,{className:`space-y-4 pt-4`,children:[(0,U.jsxs)(Vg,{className:`w-full`,variant:`primary`,onPress:()=>r([...t,kR()]),children:[(0,U.jsx)(Hj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`添加B站推送项`})]}),t.length>0?(0,U.jsx)(Fc,{variant:`surface`,"aria-label":`B站推送列表`,children:t.map((e,n)=>(0,U.jsx)(ER,{device:i,index:n,item:e,list:t,onChange:r},n))}):(0,U.jsx)(AR,{platform:`bilibili`})]})})]})})}var MR=({config:e,device:t,renderers:n,updateConfigValue:r})=>{let{renderPageHeader:i}=n;return(0,U.jsxs)(U.Fragment,{children:[i(`推送列表`,`管理「抖音」与「哔哩哔哩」的推送订阅。`),(0,U.jsx)(jR,{douyinList:e.pushlist?.douyin||[],bilibiliList:e.pushlist?.bilibili||[],onDouyinChange:e=>{r([`pushlist`,`douyin`],e)},onBilibiliChange:e=>{r([`pushlist`,`bilibili`],e)},device:t})]})},NR=({config:e,renderers:t,classes:n})=>{let{renderCheckboxGroup:r,renderPageHeader:i,renderSelectField:a,renderSubSection:o,renderSwitch:s,renderTextField:c}=t,l=Q(e,[`xiaohongshu`,`switch`],!1),u=Q(e,[`xiaohongshu`,`sendContent`],[]),d=Q(e,[`xiaohongshu`,`videoQuality`],`adapt`);return(0,U.jsxs)(U.Fragment,{children:[i(`小红书`,`小红书解析基础设置。`),(0,U.jsxs)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:[s([`xiaohongshu`,`switch`],`解析开关`,`小红书解析开关,此开关为单独开关。`),r([`xiaohongshu`,`sendContent`],`解析时发送的内容`,`若什么都不选,可能不会返回任何解析结果。`,jL,!l),c([`xiaohongshu`,`numcomment`],`评论解析数量`,`小红书评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:!l||!_L(u,`comment`)})]}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`xiaohongshu`,`forward`],`合并转发(小红书)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`xiaohongshu`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,o(`渲染与画质设置`,(0,U.jsxs)(U.Fragment,{children:[a([`xiaohongshu`,`videoQuality`],`画质偏好`,`解析视频的分辨率偏好。`,NL,e=>e,!l),c([`xiaohongshu`,`maxAutoVideoSize`],`视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!l||d!==`adapt`})]}))]})},/*KKK-QQ-START*/KKKQQConfig=({config:e,renderers:t})=>{let{renderPageHeader:n,renderSubSection:r,renderSwitch:i,renderTextField:a}=t;return(0,U.jsxs)(U.Fragment,{children:[n(`QQ 适配器`,`这些设置只对 QQ 平台生效,其它平台不受影响。改完点右下角保存即可,不用重启。`),r(`解析面板`,(0,U.jsx)(U.Fragment,{children:[i([`qq`,`qqPanel`],`链接解析面板`,`QQ 里收到链接时先回一条带按钮的面板,让用户自己挑解析内容和画质,点一下才开始下载。关掉就直接按默认配置解析。`),a([`qq`,`qqFileLimitMB`],`画质档体积上限(MB)`,`面板里「清晰度」(= 发到 QQ)这一列的体积上限:超过它的画质档不给发送按钮,那一格标「超上限」。QQ 单个视频上限 200MB,选了也发不出去,所以默认 200。**在线播放模式下画质档位不再按这个值过滤**:视频根本不发到 QQ,所有档位都会列出来,超过这个值的档位只是不能发到 QQ,右边的「在线看」照常可用(它受「在线播放最大文件」约束)。`,{type:`number`,fallback:200,min:1,max:2000}),i([`qq`,`qqPanelDanmaku`],`面板显示「烧录弹幕」列`,`只对**烧录模式**生效(通用里把「弹幕重定向在线播放器」关掉之后):打开后,QQ 里的解析面板会多一列「烧录弹幕」,用户点它就按那一档画质把弹幕烧进视频再发。在线播放模式下那一列由「弹幕重定向在线播放器」自己控制(开着就有),不需要在这里开。`),i([`qq`,`qqPanelSourceLink`],`面板带「打开原站」链接`,`打开后,解析面板(以及番剧选集面板)的下方会多一个「打开原站」按钮,点一下直接跳到抖音 / B站的原作品页;关掉就不显示。`)]})),r(`番剧选集面板`,(0,U.jsx)(U.Fragment,{children:[a([`qq`,`bangumiPanelCols`],`表格列数`,`番剧分集面板每行放几个集数,默认 5。`,{type:`number`,fallback:5,min:1,max:10}),a([`qq`,`bangumiPanelRows`],`表格行数`,`番剧分集面板每页几行(含表头那一行),默认 4 行。列数 × 行数就是每页的集数。`,{type:`number`,fallback:4,min:1,max:10})]})),r(`图片发送`,(0,U.jsx)(U.Fragment,{children:[i([`qq`,`sliceImageOnDemand`],`超大图片自动切片`,`长图(评论区那种)默认按普通图片发;只有超过 20MB 或者发送失败(拿不到消息 ID)时才自动切成几片,再用一条 markdown 拼回一整张。关掉就一律按普通图片发。`),a([`qq`,`sliceImageHeight`],`切片高度(像素)`,`切片时每片的高度,默认 2000。越大片数越少、字越小;越小越清晰、片数越多。`,{type:`number`,fallback:2000,min:500,max:4000})]})),r(`卡片识别`,(0,U.jsx)(U.Fragment,{children:[a([`qq`,`ocrApiKey`],`卡片文字识别密钥`,`群里转发过来的分享卡片没有链接,只能靠截图识别出标题和作者再去搜索。填自己的免费密钥更稳定:https://ocr.space/ocrapi 。留空会用公共测试密钥,容易被限流。`,{type:`password`,placeholder:`留空则使用公共测试密钥`})]})),r(`视频发送`,(0,U.jsx)(U.Fragment,{children:[a([`qq`,`qqGroupFileLimitMB`],`群文件发送阈值(MB)`,`视频体积超过这个值时,改用「群文件」发送。QQ 对富媒体视频会压缩、改名甚至丢掉后缀,走群文件才能原样发出去;填 0 表示不启用。`,{type:`number`,fallback:30,min:0,max:2000})]}))]})}/*KKK-QQ-END*/,PR=e=>{switch(e.activeFile){case`amagi`:return(0,U.jsx)(YL,{...e});case`app`:return(0,U.jsx)(XL,{...e});case`douyin`:return(0,U.jsx)(QL,{...e});case`bilibili`:return(0,U.jsx)(ZL,{...e});case`kuaishou`:return(0,U.jsx)($L,{...e});case`xiaohongshu`:return(0,U.jsx)(NR,{...e});case`pushlist`:return(0,U.jsx)(MR,{...e});case`qq`:return(0,U.jsx)(KKKQQConfig,{...e})}},FR=(e,t)=>{let n=Number(e);return Number.isFinite(n)?t.min!==void 0&&n<t.min?t.error||`${t.label} 不能小于 ${t.min}`:t.max!==void 0&&n>t.max?t.error||`${t.label} 不能大于 ${t.max}`:``:`${t.label} 必须是数字`},IR=(e,t,n)=>{if(n.disabled)return;let r=FR(Q(t,n.path,0),n);r&&(e[pL(n.path)]=r)},LR=e=>typeof e==`string`&&/.+:.+/.test(e),RR=(e,t,n)=>{if(!Array.isArray(n)){e[`pushlist.${t}`]=`${t} 推送列表必须是数组`;return}let r=n.findIndex(e=>{if(!mL(e))return!0;let n=e.group_id,r=t===`douyin`?e.short_id:e.host_mid;return r==null||String(r).trim()===``||!Array.isArray(n)||n.length===0||n.some(e=>!LR(e))});r>=0&&(e[`pushlist.${t}`]=`${t} 推送列表第 ${r+1} 项缺少必填 UID/抖音号,或 group_id 未使用「群号:机器人账号」格式`)},zR=e=>{if(!e)return{};let t={},n=Q(e,[`app`,`livePhotoMode`],`video_and_livephoto`),r=Q(e,[`amagi`,`APIServerMount`],!1),i=Q(e,[`app`,`videoSendMode`],`file`),a=Q(e,[`app`,`usegroupfile`],!1),o=Q(e,[`app`,`usefilelimit`],!1),s=Q(e,[`app`,`compress`],!1),c=Q(e,[`app`,`downloadThrottle`],!1),l=Q(e,[`app`,`downloadAutoReduce`],!1),u=Q(e,[`amagi`,`proxy`,`switch`],!1),d=Q(e,[`douyin`,`switch`],!1),f=Q(e,[`douyin`,`sendContent`],[]),p=Q(e,[`douyin`,`burnDanmaku`],!1),m=Q(e,[`douyin`,`videoQuality`],`adapt`),h=Q(e,[`douyin`,`push`,`switch`],!1),g=Q(e,[`douyin`,`push`,`pushVideoQuality`],`adapt`),_=Q(e,[`bilibili`,`switch`],!1),v=Q(e,[`bilibili`,`sendContent`],[]),y=Q(e,[`bilibili`,`burnDanmaku`],!1),b=Q(e,[`bilibili`,`videoQuality`],0),x=Q(e,[`bilibili`,`push`,`switch`],!1),S=Q(e,[`bilibili`,`push`,`parsedynamic`],!1),C=Q(e,[`bilibili`,`push`,`pushVideoQuality`],0),w=Q(e,[`kuaishou`,`switch`],!1),T=Q(e,[`kuaishou`,`comment`],!1),E=Q(e,[`xiaohongshu`,`switch`],!1),D=Q(e,[`xiaohongshu`,`sendContent`],[]),O=Q(e,[`xiaohongshu`,`videoQuality`],`adapt`);return[{path:[`app`,`renderScale`],label:`渲染精度`,min:50,max:200},{path:[`app`,`ambientCover`,`coverOpacity`],label:`封面氛围强度`,min:0,max:1},{path:[`app`,`ambientCover`,`overlayEdgeOpacity`],label:`氛围压色(顶部/底部)`,min:0,max:1},{path:[`app`,`ambientCover`,`overlayMiddleOpacity`],label:`氛围压色(中间带)`,min:0,max:1},{path:[`app`,`RenderWaitTime`],label:`渲染图片的等待时间`,min:0},{path:[`app`,`multiPageHeight`],label:`分页渲染时,每页的高度`,min:1e3,max:2e4,disabled:!Q(e,[`app`,`multiPageRender`],!0),error:`请输入一个范围在 1000 到 20000 之间的数字`},{path:[`amagi`,`APIServerPort`],label:`API服务端口`,min:1024,max:65535,disabled:r,error:`请输入一个范围在 1024 到 65535 之间的数字`},{path:[`app`,`groupfilevalue`],label:`群文件上传阈值`,min:1,disabled:!a||i===`base64`},{path:[`app`,`filelimit`],label:`视频拦截阈值`,min:1,disabled:!o},{path:[`app`,`compresstrigger`],label:`压缩触发阈值`,min:1,disabled:!s},{path:[`app`,`compressvalue`],label:`压缩后的值`,min:1,disabled:!s},{path:[`app`,`downloadMaxSpeed`],label:`最大下载速度`,min:1,max:1e3,disabled:!c,error:`请输入一个范围在 1 到 1000 之间的数字`},{path:[`app`,`downloadMinSpeed`],label:`最低下载速度`,min:.1,max:100,disabled:!c||!l,error:`请输入一个范围在 0.1 到 100 之间的数字`},{path:[`amagi`,`timeout`],label:`请求超时时间`,min:1e3,max:3e5,error:`请输入一个范围在 1000 到 300000 之间的数字`},{path:[`amagi`,`proxy`,`port`],label:`代理端口`,min:1,max:65535,disabled:!u,error:`请输入一个范围在 1 到 65535 之间的数字`},{path:[`douyin`,`numcomment`],label:`评论解析数量`,min:1,disabled:!d||!_L(f,`comment`)},{path:[`douyin`,`subCommentLimit`],label:`次级评论解析数量`,min:1,max:20,disabled:!d||!_L(f,`comment`)},{path:[`douyin`,`maxAutoVideoSize`],label:`视频体积上限(MB)`,min:1,max:2e4,disabled:!d||m!==`adapt`},{path:[`douyin`,`danmakuOpacity`],label:`弹幕透明度`,min:0,max:100,disabled:!d||!p},{path:[`douyin`,`push`,`pushMaxAutoVideoSize`],label:`推送视频体积上限(MB)`,min:1,max:2e4,disabled:!h||g!==`adapt`},{path:[`bilibili`,`numcomment`],label:`评论解析数量`,min:1,disabled:!_||!_L(v,`comment`)},{path:[`bilibili`,`maxAutoVideoSize`],label:`视频体积上限(MB)`,min:1,max:2e4,disabled:!_||Number(b)!==0},{path:[`bilibili`,`danmakuOpacity`],label:`弹幕透明度`,min:0,max:100,disabled:!_||!y},{path:[`bilibili`,`push`,`pushMaxAutoVideoSize`],label:`视频动态的视频体积上限(MB)`,min:1,max:2e4,disabled:!x||!S||Number(C)!==0},{path:[`kuaishou`,`numcomment`],label:`评论解析数量`,min:1,disabled:!w||!T},{path:[`xiaohongshu`,`numcomment`],label:`评论解析数量`,min:1,disabled:!E||!_L(D,`comment`)},{path:[`xiaohongshu`,`maxAutoVideoSize`],label:`视频体积上限(MB)`,min:1,max:2e4,disabled:!E||O!==`adapt`}].forEach(n=>IR(t,e,n)),n===`video_only`&&delete t[`app.livePhotoSystem`],RR(t,`douyin`,e.pushlist?.douyin||[]),RR(t,`bilibili`,e.pushlist?.bilibili||[]),t},BR=({device:e=`desktop`})=>{let t=(0,v.useRef)(null),[n,r]=JT(),i=Px(),a=n.get(`file`),[o,s]=GS({config:null,savedConfig:null,activeFile:a&&HL.some(e=>e.key===a)?a:`amagi`}),{activeFile:c,config:l,savedConfig:u}=o,d=(0,v.useMemo)(()=>JL(e),[e]),f=e===`mobile`?`sm`:`md`,{loading:p,run:m}=HS(iI,{onSuccess:e=>{s({config:structuredClone(e),savedConfig:structuredClone(e)})},onError:e=>{Ny.danger(`加载配置失败`,{description:e.message})}}),{loading:h,runAsync:g}=HS(aI,{manual:!0}),_=(0,v.useMemo)(()=>!l||!u?!1:!(0,mE.default)(yL(l),yL(u)),[l,u]),y=(0,v.useMemo)(()=>zR(l),[l]),b=(0,v.useMemo)(()=>Object.values(y).some(Boolean),[y]),x=(0,v.useMemo)(()=>_&&!b&&!p,[_,b,p]),S=Ux((e,t)=>{s(n=>n.config?{config:hL(n.config,e,t)}:null)}),C=Ux(()=>{if(!l||b)return;let e=l,t=g(e).then(()=>{s({savedConfig:e})});Ny.promise(t,{loading:`正在保存配置...`,success:`配置已保存`,error:e=>e instanceof Error?e.message:`保存配置失败`})}),w=Ux(()=>{m()}),T=Ux(e=>{r({file:e})}),E=Ux(e=>{e.preventDefault(),C()});(0,v.useEffect)(()=>{let e=n.get(`file`);e&&HL.some(t=>t.key===e)&&e!==c&&s({activeFile:e})},[n,c,s]),(0,v.useEffect)(()=>{let e=t.current?.querySelector(`[data-config-tabs-scroll="true"]`);if(!e)return;let n=t=>{let n=Math.abs(t.deltaX)>Math.abs(t.deltaY)?t.deltaX:t.deltaY;n&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),!(e.scrollWidth<=e.clientWidth)&&(e.scrollLeft+=n))};return e.addEventListener(`wheel`,n,{passive:!1}),()=>{e.removeEventListener(`wheel`,n)}},[l]);let D=Ux(()=>{t.current&&Sj.fromTo(t.current.querySelectorAll(`[data-config-section]`),uI,{...dI,duration:sI(.35),stagger:cI(.03)})});(0,v.useEffect)(()=>{!l||t.current?.dataset.animated===`true`||(t.current&&(t.current.dataset.animated=`true`),D())},[l,D]),Wx(()=>{D()},[c]);let O=(0,v.useMemo)(()=>l?GL({config:l,device:e,classes:d,validationErrors:y,updateConfigValue:S}):{},[l,e,d,y,S]);if(p||!l)return(0,U.jsxs)(`div`,{className:`${d.root} ${d.loading}`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在读取配置`}),(0,U.jsx)(`span`,{children:`正在读取配置`})]});let k=(0,U.jsx)(`div`,{className:d.floatingActions,children:(0,U.jsxs)(`div`,{className:d.actionControls,children:[(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{"aria-label":`重新读取配置`,children:(0,U.jsx)(Vg,{isIconOnly:!0,size:f,variant:`secondary`,isDisabled:p||h,onPress:w,children:(0,U.jsx)(Uj,{size:16,"aria-hidden":`true`})})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`bottom`,children:[(0,U.jsx)(tx.Arrow,{}),`重新读取`]})]}),(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{"aria-label":`查看配置变更`,children:(0,U.jsx)(Vg,{isIconOnly:!0,size:f,variant:`secondary`,isDisabled:!_,onPress:i.open,children:(0,U.jsx)(Lj,{size:16,"aria-hidden":`true`})})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`bottom`,children:[(0,U.jsx)(tx.Arrow,{}),`查看变更`]})]}),(0,U.jsxs)(Vg,{size:f,isDisabled:!x,isPending:h,onPress:C,variant:`primary`,children:[(0,U.jsx)(Wj,{size:16,"aria-hidden":`true`}),(0,U.jsx)(`span`,{children:`保存`})]})]})});return(0,U.jsxs)(`div`,{ref:t,className:d.root,children:[(0,U.jsx)(TL,{device:e,original:u,current:l,isOpen:i.isOpen,onOpenChange:i.setOpen}),(0,U.jsxs)(_x,{className:d.form,onSubmit:E,children:[(0,U.jsx)(kb,{className:`w-full min-w-0 max-w-full`,selectedKey:c,onSelectionChange:T,children:(0,U.jsx)(kb.ListContainer,{className:d.tabsListContainer,"data-config-tabs-scroll":`true`,"data-scrollbar":`none`,children:(0,U.jsx)(kb.List,{"aria-label":`配置文件选择`,className:d.tabsList,children:HL.map((e,t)=>(0,U.jsxs)(kb.Tab,{id:e.key,children:[t>0?(0,U.jsx)(kb.Separator,{}):null,(0,U.jsx)(`span`,{className:`whitespace-nowrap`,children:e.label}),(0,U.jsx)(kb.Indicator,{})]},e.key))})})}),(0,U.jsxs)(`div`,{className:`relative min-w-0 max-w-full`,children:[k,(0,U.jsx)(PR,{activeFile:c,classes:d,config:l,device:e,renderers:O,updateConfigValue:S},c)]})]})]})},VR=({onLogin:e})=>{let[t,n]=GS({authKey:``,loading:!1,error:``}),[r,{toggle:i}]=WS(!1),a=r?`隐藏密钥`:`显示密钥`,o=Ux(async r=>{r.preventDefault();let i=t.authKey.trim();if(!i){n({error:`请输入 Koishi HTTP 鉴权密钥`});return}try{n({loading:!0,error:``}),await tI(i),e()}catch(e){n({error:e instanceof Error?e.message:`登录失败`})}finally{n({loading:!1})}});return(0,U.jsx)(Ev,{className:`flex min-h-screen items-center justify-center px-4 py-8`,children:(0,U.jsxs)(Wg,{className:`w-full max-w-105`,children:[(0,U.jsxs)(Wg.Header,{className:`gap-4 p-6`,children:[(0,U.jsx)(zj,{className:`size-8 shrink-0`,"aria-hidden":`true`}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(Wg.Title,{children:`Koishi 鉴权`}),(0,U.jsx)(Wg.Description,{children:`使用 Koishi HTTP 鉴权密钥登录后管理 KKK 配置。`})]})]}),(0,U.jsx)(Wg.Content,{className:`p-6`,children:(0,U.jsxs)(_x,{className:`flex flex-col gap-6`,onSubmit:o,children:[(0,U.jsxs)(lx,{fullWidth:!0,isInvalid:!!t.error,value:t.authKey,onChange:e=>{n({authKey:e,error:t.error?``:t.error})},children:[(0,U.jsx)(dx,{children:`HTTP 鉴权密钥`}),(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(cx,{autoComplete:`current-password`,className:`min-w-0 flex-1`,placeholder:`请输入 Koishi 的 HTTP_AUTH_KEY`,type:r?`text`:`password`}),(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":a,type:`button`,variant:`tertiary`,onPress:i,children:r?(0,U.jsx)(Fj,{className:`size-4`,"aria-hidden":`true`}):(0,U.jsx)(Ij,{className:`size-4`,"aria-hidden":`true`})})]}),(0,U.jsx)(px,{children:t.error||`生产环境会复用 Koishi 主 Web 已保存的登录凭据。`})]}),(0,U.jsx)(Vg,{fullWidth:!0,isPending:t.loading,type:`submit`,children:({isPending:e})=>(0,U.jsxs)(U.Fragment,{children:[e?(0,U.jsx)(Tv,{color:`current`,size:`sm`,"aria-label":`登录中`}):(0,U.jsx)(Bj,{className:`size-4`,"aria-hidden":`true`}),(0,U.jsx)(`span`,{children:`登录`})]})})]})})]})})},HR=`theme`,UR=`kkk-theme-changed`,WR=`karin-theme-change`,GR={light:`light`,dark:`dark`,system:`system`,inverse:`inverse`},KR=e=>e===GR.system||e===GR.inverse,qR=e=>e===GR.light||e===GR.dark,JR=e=>!e||typeof e!=`object`?!1:e.type===WR,YR=()=>{let e=localStorage.getItem(HR);if(KR(e))return e;try{let t=JSON.parse(e??``);if(KR(t))return t}catch{}return localStorage.setItem(HR,GR.system),GR.system},XR=()=>window.matchMedia(`(prefers-color-scheme: dark)`).matches?GR.dark:GR.light,ZR=()=>window.matchMedia(`(prefers-color-scheme: dark)`).matches?GR.light:GR.dark,QR=e=>e===GR.system?XR():ZR(),$R=e=>ez(QR(e)),ez=e=>(document.documentElement.classList.remove(GR.light,GR.dark),document.documentElement.classList.add(e),document.documentElement.dataset.theme=e,e),tz=()=>{let[e,t]=(0,v.useState)(()=>YR()),[n,r]=(0,v.useState)(()=>QR(e)),i=(0,v.useRef)(!1),a=(0,v.useCallback)(e=>{localStorage.setItem(HR,e),t(e),r($R(e)),window.dispatchEvent(new CustomEvent(UR,{detail:e}))},[]),o=(0,v.useCallback)(()=>{a(GR.system)},[a]),s=(0,v.useCallback)(()=>{a(GR.inverse)},[a]),c=(0,v.useCallback)(()=>{a(e===GR.system?GR.inverse:GR.system)},[a,e]);return(0,v.useEffect)(()=>{i.current?i.current=!1:r($R(e));let n=window.matchMedia(`(prefers-color-scheme: dark)`),a=()=>{r($R(e))},o=e=>{if(e.key!==HR||window.self!==window.top)return;let n=YR();t(n),r($R(n))},s=e=>{let n=e.detail;KR(n)&&(t(n),r($R(n)))},c=e=>{if(!JR(e.data))return;let n=e.data.theme,a=KR(n??null)?n:YR(),o=qR(e.data.appliedTheme)?e.data.appliedTheme:QR(a);i.current=!0,localStorage.setItem(HR,a),t(a),r(ez(o))};return n.addEventListener(`change`,a),window.addEventListener(`storage`,o),window.addEventListener(UR,s),window.addEventListener(`message`,c),()=>{n.removeEventListener(`change`,a),window.removeEventListener(`storage`,o),window.removeEventListener(UR,s),window.removeEventListener(`message`,c)}},[e]),{theme:e,appliedTheme:n,isDark:(0,v.useMemo)(()=>n===GR.dark,[n]),isLight:(0,v.useMemo)(()=>n===GR.light,[n]),isSystem:e===GR.system,isInverse:e===GR.inverse,setSystemTheme:o,setInverseTheme:s,toggleTheme:c}},nz=()=>document.documentElement.clientWidth||window.innerWidth,rz=(e=nz())=>e<=768?`mobile`:`desktop`,iz=()=>{let e=navigator.userAgent.toLowerCase();return[`android`,`webos`,`iphone`,`ipad`,`ipod`,`blackberry`,`windows phone`,`mobile`].some(t=>e.includes(t))},az=()=>{let e=rz();return iz()||e===`mobile`?`mobile`:`desktop`},oz=()=>YS(()=>import(`./DesktopLayout-iI43ij11.js`),__vite__mapDeps([2,1,3])),sz=()=>YS(()=>import(`./MobileLayout-CziU8MCR.js`),__vite__mapDeps([4,3])),cz={config:`/kkk/assets/config`,about:`/kkk/assets/about`},lz={"/kkk/assets/config":`config`,"/kkk/assets/about":`about`},uz=({device:e})=>(0,U.jsxs)(Ev,{className:`h-screen overflow-hidden bg-background`,children:[(0,U.jsx)(qy.Provider,{placement:`top`}),(0,U.jsx)(bv,{hideScrollBar:!0,className:`h-full px-3 py-3 sm:px-5 sm:py-4 ${e===`mobile`?`data-[top-scroll=true]:mask-none data-[top-scroll=true]:[-webkit-mask-image:none] data-[top-bottom-scroll=true]:mask-[linear-gradient(180deg,black_calc(100%-var(--scroll-shadow-size)),transparent)] data-[top-bottom-scroll=true]:[-webkit-mask-image:linear-gradient(180deg,black_calc(100%-var(--scroll-shadow-size)),transparent)]`:``}`,size:56,children:(0,U.jsx)(BR,{device:e})})]}),dz=({LayoutComponent:e})=>{let t=vw(),n=xw(),r=lz[t.pathname]||`config`,i=Ux(e=>{n(cz[e])});return e?(0,U.jsxs)(`div`,{children:[(0,U.jsx)(qy.Provider,{placement:`top`}),(0,U.jsx)(e,{activeMenu:r,onMenuChange:i})]}):(0,U.jsxs)(Ev,{className:`flex min-h-screen items-center justify-center gap-4`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在加载布局`}),(0,U.jsx)(px,{children:`正在加载`})]})},fz=()=>{tz();let[e,t]=GS({authenticated:uE(),device:az(),LayoutComponent:null}),{authenticated:n,device:r,LayoutComponent:i}=e;(0,v.useEffect)(()=>{let e=()=>{t({authenticated:uE()})};return window.addEventListener(oE,e),window.addEventListener(`storage`,e),()=>{window.removeEventListener(oE,e),window.removeEventListener(`storage`,e)}},[t]);let a=Ux(()=>{let e=az();t(t=>t.device===e?null:{device:e,LayoutComponent:null})});(0,v.useEffect)(()=>{let e=0,t=()=>{window.cancelAnimationFrame(e),e=window.requestAnimationFrame(a)};return window.addEventListener(`resize`,t),window.addEventListener(`orientationchange`,t),()=>{window.cancelAnimationFrame(e),window.removeEventListener(`resize`,t),window.removeEventListener(`orientationchange`,t)}},[a]),(0,v.useEffect)(()=>{if(!n){t({LayoutComponent:null});return}let e=!1;return(async()=>{if(r===`mobile`){let n=await sz();e||t({LayoutComponent:n.default})}else{let n=await oz();e||t({LayoutComponent:n.default})}})(),()=>{e=!0}},[n,r,t]);let o=Ux(()=>{t({authenticated:!0})});return n?(0,U.jsxs)(Yw,{children:[(0,U.jsx)(qw,{path:`/kkk/assets/karin-config`,element:(0,U.jsx)(uz,{device:r})}),(0,U.jsx)(qw,{path:`/kkk/assets/config`,element:(0,U.jsx)(dz,{LayoutComponent:i})}),(0,U.jsx)(qw,{path:`/kkk/assets/about`,element:(0,U.jsx)(dz,{LayoutComponent:i})}),(0,U.jsx)(qw,{path:`/kkk/assets`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})}),(0,U.jsx)(qw,{path:`/kkk`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})}),(0,U.jsx)(qw,{path:`/kkk/login`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})}),(0,U.jsx)(qw,{path:`*`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})})]}):(0,U.jsxs)(Yw,{children:[(0,U.jsx)(qw,{path:`/kkk/login`,element:(0,U.jsx)(VR,{onLogin:o})}),(0,U.jsx)(qw,{path:`*`,element:(0,U.jsx)(Kw,{to:`/kkk/login`,replace:!0})})]})};(0,y.createRoot)(document.getElementById(`root`)).render((0,U.jsx)(v.StrictMode,{children:(0,U.jsx)(()=>(0,U.jsx)(RT,{children:(0,U.jsx)(fz,{})}),{})}));export{Rs as $,hm as A,Le as At,rd as B,l as Bt,Wg as C,wt as Ct,jh as D,H as Dt,Ph as E,rt as Et,_f as F,E as Ft,Y as G,Vl as H,gf as I,M as It,tc as J,J as K,pf as L,O as Lt,om as M,ke as Mt,am as N,we as Nt,Sm as O,V as Ot,vf as P,R as Pt,qs as Q,df as R,h as Rt,Jg as S,kt as St,Ig as T,at as Tt,kc as U,ed as V,Ac as W,ec as X,nc as Y,Js as Z,gv as _,ga as _t,pE as a,Do as at,b_ as b,Yt as bt,Ax as c,q as ct,dx as d,Ja as dt,Es as et,lx as f,Qa as ft,Ev as g,ma as gt,kb as h,Xa as ht,Sj as i,Mo as it,sm as j,B as jt,mm as k,He as kt,wx as l,qa as lt,tx as m,$a as mt,BR as n,cs as nt,WS as o,wo as ot,cx as p,K as pt,sc as q,Mj as r,jo as rt,Ux as s,yo as st,tz as t,Ss as tt,px as u,Za as ut,pv as v,nn as vt,Vg as w,st as wt,S_ as x,Zt as xt,C_ as y,$t as yt,lf as z,d as zt};
|
|
47
|
+
</div>`),e.hasArrows=!0}format_textdiff(e,t){e.out(`<div class="jsondiffpatch-value">`),this.formatTextDiffString(e,t[0]),e.out(`</div>`)}};function sL(e){if(typeof e==`number`)return e;let t=String(e);for(let e of[[/&/g,`&`],[/</g,`<`],[/>/g,`>`],[/'/g,`'`],[/"/g,`"`]])t=t.replace(e[0],e[1]);return t}var cL=function(e){let t=e||document,n=({textContent:e,innerText:t})=>e||t,r=(e,t,n)=>{let r=e.querySelectorAll(t);for(let e=0,t=r.length;e<t;e++)n(r[e])},i=({children:e},t)=>{for(let n=0,r=e.length;n<r;n++){let r=e[n];r&&t(r,n)}};r(t,`.jsondiffpatch-arrow`,({parentNode:e,children:t,style:r})=>{let a=e,o=t[0],s=o.children[1];o.style.display=`none`;let c=a.querySelector(`.jsondiffpatch-moved-destination`);if(!(c instanceof HTMLElement))return;let l=n(c),u=a.parentNode;if(!u)return;let d;if(i(u,e=>{e.getAttribute(`data-key`)===l&&(d=e)}),d)try{let e=d.offsetTop-a.offsetTop;o.setAttribute(`height`,`${Math.abs(e)+6}`),r.top=`${-8+(e>0?0:e)}px`;let t=e>0?`M30,0 Q-10,${Math.round(e/2)} 26,${e-4}`:`M30,${-e} Q-10,${Math.round(-e/2)} 26,4`;s.setAttribute(`d`,t),o.style.display=``}catch(e){console.debug(`[jsondiffpatch] error adjusting arrows: ${e}`)}})},lL=(e,t,n)=>{let r=t||document.body,i=`jsondiffpatch-unchanged-`,a={showing:`${i}showing`,hiding:`${i}hiding`,visible:`${i}visible`,hidden:`${i}hidden`},o=r.classList;if(!o)return;if(!n){o.remove(a.showing),o.remove(a.hiding),o.remove(a.visible),o.remove(a.hidden),e===!1&&o.add(a.hidden);return}e===!1?(o.remove(a.showing),o.add(a.visible),setTimeout(()=>{o.add(a.hiding)},10)):(o.remove(a.hiding),o.add(a.showing),o.remove(a.hidden));let s=setInterval(()=>{cL(r)},100);setTimeout(()=>{o.remove(a.showing),o.remove(a.hiding),e===!1?(o.add(a.hidden),o.remove(a.visible)):(o.add(a.visible),o.remove(a.hidden)),setTimeout(()=>{o.remove(a.visible),clearInterval(s)},n+400)},n)},uL=(e,t)=>lL(!1,e,t),dL;function fL(e,t){return dL||=new oL,dL.format(e,t)}var pL=e=>e.join(`.`),mL=e=>!!(e&&typeof e==`object`),Q=(e,t,n)=>e?t.reduce((e,t)=>{if(mL(e))return e[t]},e)??n:n,hL=(e,t,n)=>{let r=structuredClone(e),i=r;for(let e=0;e<t.length-1;e++){let n=t[e],r=i[n];mL(r)||(i[n]={}),i=i[n]}return i[t[t.length-1]]=n,r},gL=(e,t)=>{let n=Number(e);return Number.isFinite(n)?n:t},_L=(e,t)=>Array.isArray(e)&&e.includes(t),vL=e=>!!(e&&typeof e==`object`&&`description`in e),yL=e=>{if(!e||typeof e!=`object`)return e;let t=structuredClone(e);for(let{path:e,options:n}of[{path:[`bilibili`,`sendContent`],options:[`info`,`comment`,`video`,`image`]},{path:[`bilibili`,`displayContent`],options:[`cover`,`title`,`author`,`stats`,`desc`]},{path:[`bilibili`,`push`,`parseDynamicTypes`],options:[`DYNAMIC_TYPE_AV`,`DYNAMIC_TYPE_DRAW`,`DYNAMIC_TYPE_ARTICLE`]},{path:[`douyin`,`sendContent`],options:[`info`,`comment`,`video`,`image`]},{path:[`xiaohongshu`,`sendContent`],options:[`info`,`comment`,`video`,`image`]},{path:[`kuaishou`,`sendContent`],options:[`info`,`comment`,`video`,`image`]}]){let r=Q(t,e,null);if(!Array.isArray(r))continue;let i=n.filter(e=>r.includes(e)),a=t;for(let t=0;t<e.length-1;t++){let n=e[t];mL(a[n])||(a[n]={}),a=a[n]}a[e[e.length-1]]=i}return t},bL=e=>typeof e==`object`&&!!e,xL=e=>{let t={added:0,modified:0,deleted:0},n=e=>{if(bL(e)){if(Array.isArray(e)){e.length===1?t.added+=1:e.length===2?t.modified+=1:e.length===3&&e[2]===0&&(t.deleted+=1);return}for(let[t,r]of Object.entries(e))t!==`_t`&&n(r)}};return n(e),t},SL=({original:e,current:t,showUnchanged:n=!1})=>{let r=(0,v.useRef)(null),i=(0,v.useMemo)(()=>{if(!(!e||!t))return iL(yL(e),yL(t))},[e,t]),a=(0,v.useMemo)(()=>e?yL(e):void 0,[e]),o=(0,v.useMemo)(()=>{if(i)return fL(i,a)},[i,a]),s=(0,v.useMemo)(()=>xL(i),[i]);return(0,v.useEffect)(()=>{r.current&&(o?(r.current.innerHTML=o,n?lL(!0,r.current):uL(r.current)):r.current.innerHTML=``)},[o,n]),o?(0,U.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,U.jsx)(v_,{size:`sm`,color:`success`,variant:`soft`,children:(0,U.jsxs)(v_.Label,{children:[`+ `,s.added,` 新增`]})}),(0,U.jsx)(v_,{size:`sm`,color:`warning`,variant:`soft`,children:(0,U.jsxs)(v_.Label,{children:[`~ `,s.modified,` 修改`]})}),(0,U.jsx)(v_,{size:`sm`,color:`danger`,variant:`soft`,children:(0,U.jsxs)(v_.Label,{children:[`- `,s.deleted,` 删除`]})})]}),(0,U.jsx)(`div`,{className:`max-h-[60vh] overflow-auto rounded-xl border border-default-200 bg-surface p-4`,children:(0,U.jsx)(`div`,{ref:r,className:`min-w-fit`})})]}):(0,U.jsx)(`div`,{className:`flex flex-col items-center justify-center gap-2 py-10 text-center`,children:(0,U.jsx)(px,{className:`text-sm text-muted`,children:`当前没有检测到配置变更`})})},CL=`变更预览`,wL=`绿色 = 新增/改后的内容,红色 = 删除/改前的内容,灰色 = 没变化的内容。`,TL=({device:e,original:t,current:n,isOpen:r,onOpenChange:i})=>{let[a,o]=(0,v.useState)(!1),s=(0,U.jsxs)(`div`,{className:`flex flex-col gap-4`,children:[(0,U.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,U.jsx)(px,{className:`text-xs text-muted`,children:wL}),(0,U.jsx)(ob,{size:`sm`,isSelected:a,onChange:o,"aria-label":`显示未变更字段`,children:(0,U.jsxs)(ob.Content,{children:[(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})}),`显示未变更`]})})]}),(0,U.jsx)(SL,{original:t,current:n,showUnchanged:a})]}),c=(0,U.jsx)(Vg,{slot:`close`,size:`sm`,variant:`secondary`,children:`关闭`});return e===`mobile`?(0,U.jsx)(pv,{children:(0,U.jsx)(pv.Backdrop,{isOpen:r,onOpenChange:i,children:(0,U.jsx)(pv.Content,{placement:`bottom`,children:(0,U.jsxs)(pv.Dialog,{className:`h-[85vh]`,children:[(0,U.jsx)(pv.Handle,{}),(0,U.jsx)(pv.CloseTrigger,{}),(0,U.jsx)(pv.Header,{children:(0,U.jsx)(pv.Heading,{children:CL})}),(0,U.jsx)(pv.Body,{children:s}),(0,U.jsx)(pv.Footer,{children:c})]})})})}):(0,U.jsx)(Dx,{children:(0,U.jsx)(Dx.Backdrop,{isOpen:r,onOpenChange:i,children:(0,U.jsx)(Dx.Container,{scroll:`inside`,size:`lg`,children:(0,U.jsxs)(Dx.Dialog,{className:`w-full max-w-4xl`,children:[(0,U.jsx)(Dx.CloseTrigger,{}),(0,U.jsxs)(Dx.Header,{children:[(0,U.jsx)(Dx.Icon,{className:`bg-accent-soft text-accent-soft-foreground`,children:(0,U.jsx)(Lj,{className:`size-5`})}),(0,U.jsx)(Dx.Heading,{children:CL})]}),(0,U.jsx)(Dx.Body,{children:s}),(0,U.jsx)(Dx.Footer,{children:c})]})})})})},EL=e=>!!(e&&typeof e==`object`),$=(e,t,n)=>e?t.reduce((e,t)=>{if(EL(e))return e[t]},e)??n:n,DL=(e,t)=>Array.isArray(e)&&e.includes(t),OL=[{path:[`app`,`priority`],rules:[{condition:e=>$(e,[`app`,`videoTool`],!0),message:`修改此配置项需要先将「默认解析优先级」关闭`}]},{path:[`app`,`multiPageHeight`],rules:[{condition:e=>!$(e,[`app`,`multiPageRender`],!0),message:`修改此配置项需要先将「分页渲染」打开`}]},{path:[`app`,`livePhotoSystem`],rules:[{condition:e=>$(e,[`app`,`livePhotoMode`],`video_and_livephoto`)===`video_only`,message:`修改此配置项需要先将「Live Photo 处理和发送方式」改为非「仅视频」模式`}]},{path:[`amagi`,`APIServerMount`],rules:[{condition:e=>!$(e,[`amagi`,`APIServer`],!1),message:`修改此配置项需要先将「API 服务」打开`}]},{path:[`amagi`,`APIServerPort`],rules:[{condition:e=>$(e,[`amagi`,`APIServerMount`],!0),message:`修改此配置项需要先将「挂载到 Koishi」关闭`}]},{path:[`app`,`qrLoginExternalAddr`],rules:[{condition:e=>$(e,[`app`,`qrLoginAddrType`],`lan`)!==`external`,message:`修改此配置项需要先将「扫码登录地址」改为「外部地址」`}]},{path:[`app`,`videoSendMode`],rules:[{condition:e=>$(e,[`app`,`usegroupfile`],!1),message:`修改此配置项需要先将「群文件上传」关闭`}]},{path:[`app`,`usegroupfile`],rules:[{condition:e=>$(e,[`app`,`videoSendMode`],`file`)===`base64`,message:`修改此配置项需要先将「本地视频发送方式」改为「File 协议」`}]},{path:[`app`,`groupfilevalue`],rules:[{condition:e=>!$(e,[`app`,`usegroupfile`],!1),message:`修改此配置项需要先将「群文件上传」打开`},{condition:e=>$(e,[`app`,`videoSendMode`],`file`)===`base64`,message:`修改此配置项需要先将「本地视频发送方式」改为「File 协议」`}]},{path:[`app`,`filelimit`],rules:[{condition:e=>!$(e,[`app`,`usefilelimit`],!1),message:`修改此配置项需要先将「视频上传拦截」打开`}]},{path:[`app`,`compresstrigger`],rules:[{condition:e=>!$(e,[`app`,`compress`],!1),message:`修改此配置项需要先将「压缩视频」打开`}]},{path:[`app`,`compressvalue`],rules:[{condition:e=>!$(e,[`app`,`compress`],!1),message:`修改此配置项需要先将「压缩视频」打开`}]},{path:[`app`,`downloadMaxSpeed`],rules:[{condition:e=>!$(e,[`app`,`downloadThrottle`],!1),message:`修改此配置项需要先将「下载限速」打开`}]},{path:[`app`,`downloadAutoReduce`],rules:[{condition:e=>!$(e,[`app`,`downloadThrottle`],!1),message:`修改此配置项需要先将「下载限速」打开`}]},{path:[`app`,`downloadMinSpeed`],rules:[{condition:e=>!$(e,[`app`,`downloadThrottle`],!1),message:`修改此配置项需要先将「下载限速」打开`},{condition:e=>!$(e,[`app`,`downloadAutoReduce`],!1),message:`修改此配置项需要先将「断流自动降速」打开`}]},{path:[`amagi`,`proxy`,`protocol`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`host`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`port`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`auth`,`username`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`amagi`,`proxy`,`auth`,`password`],rules:[{condition:e=>!$(e,[`amagi`,`proxy`,`switch`],!1),message:`修改此配置项需要先将「代理开关」打开`}]},{path:[`douyin`,`sendContent`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`numcomment`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`douyin`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`douyin`,`subCommentLimit`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`douyin`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`douyin`,`commentImageCollection`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`douyin`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`douyin`,`liveImageMergeMode`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`app`,`livePhotoMode`],`video_and_livephoto`)===`livephoto_only`,message:`修改此配置项需要先将「Live Photo 处理和发送方式」改为非「仅实况图」模式`}]},{path:[`douyin`,`videoQuality`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`maxAutoVideoSize`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`douyin`,`videoQuality`],`adapt`)!==`adapt`,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]},{path:[`douyin`,`videoInfoMode`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`displayContent`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`douyin`,`videoInfoMode`],`text`)===`image`,message:`修改此配置项需要先将「视频信息返回形式」改为「文本模式」`}]},{path:[`douyin`,`burnDanmaku`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`douyin`,`danmakuArea`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`danmakuFontSize`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`danmakuOpacity`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`verticalMode`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`videoCodec`],rules:[{condition:e=>!$(e,[`douyin`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`douyin`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`douyin`,`push`,`permission`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`cron`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`parsedynamic`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`shareType`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`pushVideoQuality`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`douyin`,`push`,`pushMaxAutoVideoSize`],rules:[{condition:e=>!$(e,[`douyin`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>$(e,[`douyin`,`push`,`pushVideoQuality`],`adapt`)!==`adapt`,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]},{path:[`bilibili`,`sendContent`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`numcomment`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`bilibili`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`bilibili`,`realCommentCount`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`bilibili`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`bilibili`,`commentImageCollection`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`bilibili`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`bilibili`,`videoQuality`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`maxAutoVideoSize`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>Number($(e,[`bilibili`,`videoQuality`],0))!==0,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]},{path:[`bilibili`,`videoInfoMode`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`displayContent`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`bilibili`,`videoInfoMode`],`text`)===`image`,message:`修改此配置项需要先将「视频信息返回形式」改为「文本模式」`}]},{path:[`bilibili`,`showDanmakuInVideoInfo`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`bilibili`,`videoInfoMode`],`text`)===`text`,message:`修改此配置项需要先将「视频信息返回形式」改为「图片模式」`}]},{path:[`bilibili`,`burnDanmaku`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`bilibili`,`danmakuArea`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`danmakuFontSize`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`danmakuOpacity`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`verticalMode`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`videoCodec`],rules:[{condition:e=>!$(e,[`bilibili`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`bilibili`,`burnDanmaku`],!1),message:`修改此配置项需要先将「弹幕烧录」打开`}]},{path:[`bilibili`,`push`,`permission`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`bilibili`,`push`,`cron`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`bilibili`,`push`,`parsedynamic`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`}]},{path:[`bilibili`,`push`,`parseDynamicTypes`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>!$(e,[`bilibili`,`push`,`parsedynamic`],!1),message:`修改此配置项需要先将「作品解析」打开`}]},{path:[`bilibili`,`push`,`pushVideoQuality`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>!$(e,[`bilibili`,`push`,`parsedynamic`],!1),message:`修改此配置项需要先将「作品解析」打开`}]},{path:[`bilibili`,`push`,`pushMaxAutoVideoSize`],rules:[{condition:e=>!$(e,[`bilibili`,`push`,`switch`],!1),message:`修改此配置项需要先将「推送开关」打开`},{condition:e=>!$(e,[`bilibili`,`push`,`parsedynamic`],!1),message:`修改此配置项需要先将「作品解析」打开`},{condition:e=>Number($(e,[`bilibili`,`push`,`pushVideoQuality`],0))!==0,message:`修改此配置项需要先将「解析视频动态时的画质偏好」改为「自动选择」`}]},{path:[`kuaishou`,`comment`],rules:[{condition:e=>!$(e,[`kuaishou`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`kuaishou`,`numcomment`],rules:[{condition:e=>!$(e,[`kuaishou`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!$(e,[`kuaishou`,`comment`],!1),message:`修改此配置项需要先将「评论解析」打开`}]},{path:[`xiaohongshu`,`sendContent`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`xiaohongshu`,`numcomment`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>!DL($(e,[`xiaohongshu`,`sendContent`],[]),`comment`),message:`修改此配置项需要在「解析时发送的内容」中勾选「评论图」`}]},{path:[`xiaohongshu`,`videoQuality`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`}]},{path:[`xiaohongshu`,`maxAutoVideoSize`],rules:[{condition:e=>!$(e,[`xiaohongshu`,`switch`],!1),message:`修改此配置项需要先将「解析开关」打开`},{condition:e=>$(e,[`xiaohongshu`,`videoQuality`],`adapt`)!==`adapt`,message:`修改此配置项需要先将「画质偏好」改为「自动选择」`}]}],kL=e=>e.join(`.`),AL=(e,t)=>{let n=kL(t),r=OL.find(e=>kL(e.path)===n);if(!r)return``;for(let t of r.rules)if(t.condition(e))return t.message;return``},jL=[{label:`信息`,value:`info`},{label:`评论图`,value:`comment`},{label:`视频`,value:`video`},{label:`图片`,value:`image`}],ML=[{label:`封面`,value:`cover`},{label:`标题`,value:`title`},{label:`作者`,value:`author`},{label:`统计`,value:`stats`},{label:`简介`,value:`desc`}],NL=[{label:`自动选择`,value:`adapt`,description:`根据「视频体积上限(MB)」自动选择分辨率进行下载`},{label:`标清 540p`,value:`540p`},{label:`高清 720p`,value:`720p`},{label:`高清 1080p`,value:`1080p`},{label:`超清 2k`,value:`2k`},{label:`超清 4k`,value:`4k`}],PL=[{label:`自动选择`,value:`0`},{label:`240P 极速`,value:`6`},{label:`360P 流畅`,value:`16`},{label:`480P 清晰`,value:`32`,description:`需登录(配置ck)`},{label:`720P 高清`,value:`64`,description:`需登录(配置ck)`},{label:`720P60 高帧率`,value:`74`,description:`需登录(配置ck)`},{label:`1080P 高清`,value:`80`,description:`需登录(配置ck)`},{label:`1080P+ 高码率`,value:`112`,description:`需大会员&视频支持`},{label:`1080P60 高帧率`,value:`116`,description:`需大会员&视频支持`},{label:`4K 超清`,value:`120`,description:`需大会员&视频支持`},{label:`8K 超高清`,value:`127`,description:`需大会员&视频支持`}],FL=[{label:`视频动态`,value:`DYNAMIC_TYPE_AV`},{label:`图文动态`,value:`DYNAMIC_TYPE_DRAW`},{label:`文章动态`,value:`DYNAMIC_TYPE_ARTICLE`}],IL=[{label:`所有人`,value:`all`},{label:`管理员`,value:`admin`},{label:`主人`,value:`master`},{label:`群主`,value:`group.owner`},{label:`群管理员`,value:`group.admin`}],LL=[{label:`H.264`,value:`h264`,description:`兼容性最好,支持几乎所有设备`},{label:`H.265`,value:`h265`,description:`压缩率更高,近几年设备支持良好(推荐)`},{label:`AV1`,value:`av1`,description:`最新编码格式,压缩率最高,但编码较慢`}],RL=[{label:`关闭`,value:`off`,description:`保持原始比例,不做转换`},{label:`智能`,value:`standard`,description:`仅对宽屏比例视频生效`},{label:`强制 9:16`,value:`force`,description:`所有视频统一转为 9:16 竖屏`}],zL=[{label:`1/4 屏`,value:`0.25`,description:`仅顶部区域`},{label:`半屏`,value:`0.5`,description:`上半部分(推荐)`},{label:`3/4 屏`,value:`0.75`,description:`大部分区域`},{label:`全屏`,value:`1`,description:`铺满整个画面`}],BL=[{label:`小号`,value:`small`},{label:`中号`,value:`medium`},{label:`大号`,value:`large`}],VL={enabled:`已开启`,disabled:`已关闭`},HL=[{key:`amagi`,label:`接口库`,description:`请求与 Cookies`},{key:`app`,label:`通用`,description:`运行与交互`},{key:`douyin`,label:`抖音`,description:`解析与推送`},{key:`bilibili`,label:`哔哩哔哩`,description:`解析与推送`},{key:`kuaishou`,label:`快手`,description:`快手解析`},{key:`xiaohongshu`,label:`小红书`,description:`小红书解析`},{key:`qq`,label:`QQ 适配器`,description:`QQ 平台专属`},{key:`pushlist`,label:`推送列表`,description:`订阅 JSON`}],UL=(0,v.lazy)(()=>YS(()=>import(`./CronEditor-CYgFpX-g.js`),__vite__mapDeps([0,1]))),WL=({className:e,disabled:t,...n})=>{let[r,i]=(0,v.useState)(!1),a=r?`隐藏密码`:`显示密码`;return(0,U.jsxs)(`div`,{className:`relative w-full`,children:[(0,U.jsx)(cx,{...n,variant:`secondary`,className:`w-full pr-10 ${e??``}`,type:r?`text`:`password`}),(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":a,className:`absolute right-1 top-1/2 -translate-y-1/2`,isDisabled:t,size:`sm`,type:`button`,variant:`tertiary`,onPress:()=>i(e=>!e),children:r?(0,U.jsx)(Fj,{className:`size-4`,"aria-hidden":`true`}):(0,U.jsx)(Ij,{className:`size-4`,"aria-hidden":`true`})})]})},GL=({config:e,device:t,classes:n,validationErrors:r,updateConfigValue:i})=>{let a=e=>{let n=vL(e)?e:{description:e},r=t===`mobile`?n.mobileContent??n.desktopContent:n.desktopContent;return(0,U.jsxs)(px,{className:`flex items-center gap-2`,children:[(0,U.jsx)(`span`,{children:n.description}),r?(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{"aria-label":`查看详细说明`,children:(0,U.jsx)(Vg,{isIconOnly:!0,size:`sm`,variant:`tertiary`,children:(0,U.jsx)(Rj,{className:`size-4`,"aria-hidden":`true`})})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:t===`mobile`?`bottom`:`top`,children:[(0,U.jsx)(tx.Arrow,{}),(0,U.jsx)(`div`,{className:`max-w-72`,children:r})]})]}):null,n.extra]})},o=(n,r,i)=>{if(!i)return n;let a=AL(e,r);return a?t===`mobile`?(0,U.jsxs)(gv,{children:[(0,U.jsx)(gv.Trigger,{className:`w-full cursor-not-allowed`,children:n}),(0,U.jsx)(gv.Content,{placement:`bottom`,children:(0,U.jsxs)(gv.Dialog,{children:[(0,U.jsx)(gv.Arrow,{}),(0,U.jsx)(`div`,{className:`max-w-72 text-sm`,children:a})]})})]}):(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{className:`w-full cursor-not-allowed`,children:n}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),(0,U.jsx)(`div`,{className:`max-w-72`,children:a})]})]}):n},s=(t,n,r,a)=>{let o=Q(e,t,[]),s=r?Array.from(new Set([...o,n])):o.filter(e=>e!==n);if(a&&r){let e=a.find(e=>e.includes(n));if(e){let t=e.filter(e=>e!==n);s=s.filter(e=>!t.includes(e))}}i(t,s)};return{renderSwitch:(t,n,r,s=!1)=>{let c=Q(e,t,!1),l=(0,U.jsxs)(ob,{isDisabled:s,isSelected:c,onChange:e=>i(t,e),children:[(0,U.jsxs)(ob.Content,{children:[(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})}),(0,U.jsx)(`span`,{className:`font-semibold`,children:n})]}),a(r||(c?VL.enabled:VL.disabled))]});return o(l,t,s)},renderTextField:(t,n,s,c)=>{let l=c?.type||`text`,u=String(Q(e,t,l===`number`?c?.fallback??0:``)),d=r[pL(t)],f=c?.disabled??!1,p=(0,U.jsxs)(lx,{fullWidth:!0,isInvalid:!!d,isDisabled:f,name:t.join(`.`),type:l,value:u,onChange:e=>{i(t,l===`number`?gL(e,c?.fallback??0):e)},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:n}),l===`password`?(0,U.jsx)(WL,{disabled:f,max:c?.max,min:c?.min,pattern:c?.pattern,placeholder:c?.placeholder||n,step:c?.step}):(0,U.jsx)(cx,{variant:`secondary`,max:c?.max,min:c?.min,pattern:c?.pattern,placeholder:c?.placeholder||n,step:c?.step}),d?(0,U.jsx)(hx,{children:d}):a(s)]});return o(p,t,f)},renderSelectField:(t,n,r,s,c=e=>e,l=!1)=>{let u=String(Q(e,t,s[0]?.value||``)),d=(0,U.jsxs)(Ax,{disabledKeys:s.filter(e=>e.disabled).map(e=>e.value),fullWidth:!0,isDisabled:l,name:t.join(`.`),placeholder:n,value:u,variant:`secondary`,onChange:e=>{e===null||Array.isArray(e)||i(t,c(String(e)))},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:n}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{}),(0,U.jsx)(Ax.Indicator,{})]}),a(r),(0,U.jsx)(Ax.Popover,{children:(0,U.jsx)(wx,{children:s.map(e=>(0,U.jsxs)(wx.Item,{id:e.value,textValue:e.label,children:[(0,U.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-1`,children:[(0,U.jsx)(dx,{children:e.label}),e.description?(0,U.jsx)(px,{children:e.description}):null]}),(0,U.jsx)(wx.ItemIndicator,{})]},e.value))})})]});return o(d,t,l)},renderCheckboxGroup:(t,r,i,c,l=!1,u)=>{let d=Q(e,t,[]),f=(0,U.jsxs)(`div`,{className:n.field,children:[(0,U.jsx)(dx,{className:`font-semibold`,children:r}),a(i),(0,U.jsx)(`div`,{className:n.choiceGrid,children:c.map(e=>(0,U.jsxs)(m_,{variant:`secondary`,isDisabled:l,isSelected:_L(d,e.value),onChange:n=>s(t,e.value,n,u),children:[(0,U.jsxs)(m_.Content,{children:[(0,U.jsx)(m_.Control,{children:(0,U.jsx)(m_.Indicator,{})}),e.label]}),e.description?(0,U.jsx)(px,{children:e.description}):null]},e.value))})]});return o(f,t,l)},renderSlider:(t,r,s,c)=>{let l=Q(e,t,c?.fallback??0),u=c?.disabled??!1,d=(0,U.jsxs)(`div`,{className:n.field,children:[(0,U.jsxs)(Nx,{className:`w-full`,isDisabled:u,value:l,formatOptions:c?.formatOptions??{style:`percent`,maximumFractionDigits:0},maxValue:c?.max??1,minValue:c?.min??0,step:c?.step??.01,onChange:e=>{Array.isArray(e)||i(t,e)},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:r}),(0,U.jsx)(Nx.Output,{}),(0,U.jsxs)(Nx.Track,{children:[(0,U.jsx)(Nx.Fill,{}),(0,U.jsx)(Nx.Thumb,{})]})]}),a(s)]});return o(d,t,u)},renderCronField:(r,a,s,c=!1)=>{let l=Q(e,r,`*/10 * * * *`),u=(0,U.jsx)(`div`,{className:n.field,children:(0,U.jsx)(v.Suspense,{fallback:(0,U.jsx)(`div`,{className:`h-64 animate-pulse rounded-lg bg-muted/30`}),children:(0,U.jsx)(UL,{device:t,disabled:c,value:l,onChange:e=>i(r,e)})})});return o(u,r,c)},/*KKK-PERM-START*/renderPermField:(t,r,s,c)=>{c=c||{};const p=t,list=!!c.list,modes=c.modes||[],raw=Q(e,p,list?[]:`all`),arr0=list?(Array.isArray(raw)?raw.map(String):(raw?[String(raw)]:[])):[],ids=list?arr0.filter(x=>/^\d+$/.test(x)):[],numText=list?ids.join(`, `):([`all`,`admin`].includes(String(raw))?``:String(raw||``)),kw=list?(arr0.find(x=>!/^\d+$/.test(x))||``):([`all`,`admin`].includes(String(raw))?String(raw):``),guess=(kw===`trigger`)?`trigger`:(kw||(String(numText).trim()?`id`:(list?`trigger`:`all`))),pair=(0,v.useState)(null),mode=pair[0]||guess,setMode=pair[1],apply=n=>{setMode(n);if(n===`id`){i(p,list?ids:String(numText))}else{i(p,list?[n]:n)}},setIds=n=>{i(p,list?String(n).split(/[,,\s]+/).map(x=>x.trim()).filter(Boolean):n)},sel=(0,U.jsxs)(Ax,{fullWidth:!0,name:p.join(`.`),placeholder:r,value:mode,variant:`secondary`,onChange:e=>{e===null||Array.isArray(e)||apply(String(e))},children:[(0,U.jsx)(dx,{className:`font-semibold`,children:r}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{}),(0,U.jsx)(Ax.Indicator,{})]}),a(s),(0,U.jsx)(Ax.Popover,{children:(0,U.jsx)(wx,{children:modes.map(m=>(0,U.jsx)(wx.Item,{id:m.value,textValue:m.label,children:m.label},m.value))})})]}),inp=mode===`id`?(0,U.jsxs)(lx,{fullWidth:!0,name:p.join(`.`),value:numText,onChange:e=>setIds(e),children:[(0,U.jsx)(dx,{className:`font-semibold`,children:list?`接收账号`:`允许的账号`}),(0,U.jsx)(cx,{variant:`secondary`,placeholder:`填写用户 ID,多个用逗号分隔`})]}):null,box=(0,U.jsxs)(`div`,{className:n.field,children:[sel,inp]});return o(box,t,!1)},/*KKK-PERM-END*/renderPageHeader:(e,n)=>(0,U.jsxs)(`div`,{className:`mb-6 ${t===`mobile`?`pr-36`:``}`,"data-config-section":!0,children:[(0,U.jsx)(`h2`,{className:`text-2xl font-bold`,children:e}),(0,U.jsx)(`div`,{className:`mt-3`,children:(0,U.jsx)(px,{children:n})})]}),renderSubSection:(e,t)=>(0,U.jsxs)(Wg,{"data-config-section":!0,className:`mb-4`,children:[(0,U.jsx)(Wg.Header,{className:n.sectionHeader,children:(0,U.jsx)(Wg.Title,{className:`text-lg font-semibold`,children:e})}),(0,U.jsx)(Wg.Content,{className:n.sectionContent,children:(0,U.jsx)(`div`,{className:n.fields,children:t})})]})}},KL={root:`relative flex min-w-0 max-w-full flex-col gap-8`,loading:`flex min-h-80 items-center justify-center gap-3`,header:`grid grid-cols-[minmax(0,1fr)_auto] items-start gap-8 pr-44`,headerCopy:`flex min-w-0 flex-col gap-2`,form:`flex min-w-0 max-w-full flex-col gap-6`,floatingActions:`fixed right-6 top-20 z-10`,actionControls:`flex items-center justify-end gap-3`,sectionHeader:`p-2`,sectionContent:`p-6`,fields:`grid grid-cols-2 gap-x-6 gap-y-5`,field:`flex min-w-0 flex-col gap-2`,choiceGrid:`grid grid-cols-2 gap-3`,divider:`col-span-full flex min-w-0 flex-col gap-2 pt-3`,tabsListContainer:`w-full min-w-0 max-w-full overflow-x-auto overflow-y-hidden overscroll-x-contain overscroll-y-none [scrollbar-width:none] [&::-webkit-scrollbar]:hidden`,tabsList:`w-fit min-w-max *:w-fit *:min-w-fit *:flex-none *:shrink-0 *:whitespace-nowrap`,topLevelFields:`mb-4 space-y-4 px-2`},qL={root:`relative flex min-w-0 max-w-full flex-col gap-5`,loading:`flex min-h-80 items-center justify-center gap-3`,header:`flex flex-col gap-3 pt-12`,headerCopy:`flex min-w-0 flex-col gap-2`,form:`flex min-w-0 max-w-full flex-col gap-3`,floatingActions:`sticky top-0 z-20 flex h-0 w-full justify-end overflow-visible`,actionControls:`flex w-fit h-11 p-1 items-center gap-2 rounded-full border border-default-200 bg-background/90 shadow-sm backdrop-blur-md`,sectionHeader:`p-1`,sectionContent:`p-0`,fields:`grid grid-cols-1 gap-5`,field:`flex min-w-0 flex-col gap-2`,choiceGrid:`grid grid-cols-1 gap-3`,divider:`col-span-full flex min-w-0 flex-col gap-2 pt-3`,tabsListContainer:`w-full min-w-0 max-w-full overflow-x-auto overflow-y-hidden overscroll-x-contain overscroll-y-none [scrollbar-width:none] [&::-webkit-scrollbar]:hidden`,tabsList:`w-fit min-w-max *:w-fit *:min-w-fit *:flex-none *:shrink-0 *:whitespace-nowrap`,topLevelFields:`mb-4 space-y-4 px-4`},JL=e=>e===`mobile`?qL:KL,YL=({config:e,renderers:t})=>{let{renderPageHeader:n,renderSelectField:r,renderSubSection:i,renderSwitch:a,renderTextField:o}=t,s=Q(e,[`amagi`,`proxy`,`switch`],!1),c=Q(e,[`amagi`,`APIServer`],!1);return(0,U.jsxs)(U.Fragment,{children:[n(`接口库配置`,`接口库的 Cookies、请求、代理和 API 服务配置。保存后后端会重载接口库客户端。`),i(`平台 Cookies`,(0,U.jsxs)(U.Fragment,{children:[o([`amagi`,`cookies`,`douyin`],`抖音 Cookies`,`请输入你的抖音Cookies,不输入则无法使用抖音相关功能噢。`,{type:`password`}),o([`amagi`,`cookies`,`bilibili`],`B站 Cookies`,`请输入你的B站Cookies,不输入部分功能将受限噢。`,{type:`password`}),o([`amagi`,`cookies`,`kuaishou`],`快手 Cookies`,`请输入你的快手Cookies,不输入则无法使用快手相关功能噢。`,{type:`password`}),o([`amagi`,`cookies`,`xiaohongshu`],`小红书 Cookies`,`请输入你的小红书Cookies,不输入则无法使用小红书相关功能噢。`,{type:`password`})]})),i(`请求配置`,(0,U.jsxs)(U.Fragment,{children:[o([`amagi`,`timeout`],`请求超时时间`,`网络请求的超时时间,单位:毫秒。`,{type:`number`,fallback:15e3,min:1e3,max:3e5}),o([`amagi`,`User-Agent`],`User-Agent`,`请求头中的User-Agent字段,用于标识客户端类型。`)]})),i(`代理配置(可选)`,(0,U.jsxs)(U.Fragment,{children:[a([`amagi`,`proxy`,`switch`],`代理开关`,`开启后需要配置「代理主机」「代理端口」。`),r([`amagi`,`proxy`,`protocol`],`代理协议`,`代理服务使用的协议。`,[{label:`HTTP`,value:`http`},{label:`HTTPS`,value:`https`}],e=>e,!s),o([`amagi`,`proxy`,`host`],`代理主机`,`代理服务器的主机地址,如:127.0.0.1。`,{disabled:!s}),o([`amagi`,`proxy`,`port`],`代理端口`,`代理服务器的端口号。`,{type:`number`,fallback:7890,min:1,max:65535,disabled:!s}),o([`amagi`,`proxy`,`auth`,`username`],`代理用户名`,`代理服务器的认证用户名(如果需要)。`,{disabled:!s}),o([`amagi`,`proxy`,`auth`,`password`],`代理密码`,`代理服务器的认证密码(如果需要)。`,{type:`password`,disabled:!s})]})),i(`API 服务配置`,(0,U.jsxs)(U.Fragment,{children:[a([`amagi`,`APIServer`],`API 服务`,`本地部署一个视频解析API服务,接口范围为本插件用到的所有。`),a([`amagi`,`APIServerMount`],`挂载到 Koishi`,`API 服务是否挂载到 Koishi 上,开启后监听端口为 Koishi 的 http 端口,修改后需重启。需开启「API服务」。`,!c),o([`amagi`,`APIServerPort`],`API 服务端口`,`仅未挂载到 Koishi 时生效。`,{type:`number`,disabled:Q(e,[`amagi`,`APIServerMount`],!0),fallback:4567,min:1024,max:65535})]}))]})},XL=({config:e,renderers:t})=>{let{renderCheckboxGroup:n,renderPageHeader:r,renderSelectField:i,renderSlider:a,renderSubSection:o,renderSwitch:s,renderTextField:c}=t,l=Q(e,[`app`,`livePhotoMode`],`video_and_livephoto`);return(0,U.jsxs)(U.Fragment,{children:[r(`通用`,`插件运行、渲染和交互相关配置。`),o(`缓存设置`,(0,U.jsx)(U.Fragment,{children:s([`app`,`removeCache`],`自动删除视频缓存`,`任务完成后删除下载缓存。`)})),o(`交互设置`,(0,U.jsxs)(U.Fragment,{children:[s([`app`,`EmojiReply`],`表情回应`,`在解析任务开始时添加表情回应,若适配器不支持需要关闭。`),s([`app`,`parseTip`],`解析提示`,`发送提示信息:"检测到xxx链接,开始解析"。`),s([`app`,`fakeForward`],`解析结果合并转发`,`**全局合并转发(优先级最高)**:打开时所有平台的解析结果都合并成一条转发消息发出,转发用触发者身份展示;过程提示(开始解析 / 下载中 / 发送中…)不会进转发。**关掉就不合并**,内容像以前一样一条一条发。只有支持合并转发的适配器有效果(QQ 官方适配器没有这个能力,会自动退化成逐条发送)。`),/*KKK-FORWARD-START*/t.renderCheckboxGroup([`app`,`forwardContent`],`合并转发内容(全局)`,`全局合并转发里包含哪些内容(通用页这个开关打开时生效,所有平台共用):没勾选的内容单独直发。视频类内容建议先不勾——转发节点太大的话适配器会整条拒绝。语音和 markdown 不在候选里:QQ 的聊天记录不支持语音气泡,markdown 只有官方 bot 认、而官方适配器没有合并转发能力。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])/*KKK-FORWARD-END*/,,,,,,,t.renderPermField([`app`,`errorLogSendTo`],`错误日志`,`谁来接收错误日志,选「指定账号」后填用户 ID,多个用逗号分隔。`,{list:true,modes:[{value:`trigger`,label:`触发者所在的群`},{value:`admin`,label:`管理员(权限等级 4 及以上)`},{value:`id`,label:`指定账号`}]}),/*KKK-APP-START*/s([`qq`,`recallPanel`],`自动撤回面板`,`用户在面板上点完按钮后,自动把上一条提示 / 选择消息撤回,群里不会堆着一排旧提示和选择。`),s([`qq`,`forceNoDanmaku`],`强制不烧录弹幕`,`优先级最高的总开关:打开时无论指令、面板按钮还是平台配置,都不会烧录弹幕,一律按纯视频解析。要用弹幕功能时先把它关掉。`),s([`qq`,`parseDedupe`],`短时间不重复解析`,`默认开启。同一条链接在下面设定的一段时间内只解析一次:QQ 的指令按钮是「发一条消息 + 再发一个交互事件」,用户连点、客户端重发也会把同一条链接投递两遍,跑两遍就是两次「开始解析」、两次下载、两次发送(第二次还常因为缓存已被清理而失败)。去重键包含会话、作品 ID、画质与弹幕开关,换画质、换作品、换群都不会被误伤。**关掉后每条消息都会解析**,需要反复调试同一条链接时可以临时关掉。`),c([`qq`,`parseDedupeMinutes`],`重复解析间隔(分钟)`,`上面那个开关打开时才生效:同一条链接在这段时间内只解析一次,默认 1 分钟(可填 1 ~ 60)。填得越大越省事(重复投递/连点不会再跑第二遍),但也意味着这段时间里你手动再发一次同一条链接会被忽略;想立刻重解析就把上面的开关关掉。(这一项要先把上面的「短时间不重复解析」打开才能改)`,{type:`number`,fallback:1,min:1,max:60,disabled:Q(e,[`qq`,`parseDedupe`],!0)===!1})/*KKK-APP-END*/,,]})),/*KKK-SECTION-START*/o(`在线播放器设置`,(0,U.jsx)(U.Fragment,{children:[s([`qq`,`playerEnabled`],`在线播放器总开关`,`**这一组的总开关**,默认开启。打开时,解析面板里那一列按钮上的「弹幕」会把视频放到在线播放页(带弹幕)并回一条链接,不再把弹幕烧进视频、也不再把视频传到群里;链接有有效期,过期自动清理文件。开着时面板上还会多一列「在线看」(点它直接在线看,不管弹幕功能有没有开都带弹幕),这一列由下面的「面板显示「在线看」按钮」单独控制。**关掉它,这一组里其它设置都会变灰不可改**,解析也回到原来的 ffmpeg 烧录流程(面板列头变回「烧录弹幕」、不再有「在线看」列)。(这一项要先关掉上面的「强制不烧录弹幕」(也就是打开弹幕功能)才能改)`,Q(e,[`qq`,`forceNoDanmaku`],!0)===!0),s([`qq`,`playerWatchButton`],`面板显示「在线看」按钮`,`默认开启。打开后,QQ 解析面板的「弹幕」列右边会多一列「在线看」:点它**直接在线播放**(带弹幕,视频不发到群里、也不占群文件),不看弹幕功能开没开 —— 在线看永远带弹幕。关掉就不显示这一列。注意:只有上面的「在线播放器总开关」开着时这一列才会出现(总开关关掉时这一项会变灰);播放器关掉时它没有任何作用。**超过「在线播放最大文件」的画质档不给「在线看」按钮**,那一格会标「超上限」。(这一项要先把上面的「在线播放器总开关」打开才能改)`,Q(e,[`qq`,`playerEnabled`],!0)===!1),c([`qq`,`playerBaseUrl`],`播放器公网地址`,`**这是你自己的公网地址,插件猜不出来,必须由你填。**例如 https://play.example.com(结尾斜杠会自动去掉),用户收到的链接就是它加上 /kkk/player/<令牌>。留空时链接会退化成「http://本机 IP:端口」,**只有本机 / 内网能打开**;这时日志里会警告一次,机器人回复和播放页上也会带一句「未配置公网地址,仅本机可访问」——公网用户点开打不开是正常的,不是插件坏了。用 Nginx / Caddy 之类的反向代理指向下面的「播放器端口」即可,代理到 https 域名时这里就填那个域名。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`text`,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),c([`qq`,`playerPort`],`播放器端口`,`0 = 复用 Koishi 自己的端口(推荐,不用额外开端口);填其它值会用 node:http 另起一个服务。端口被占用时只记一条日志并退回 Koishi 端口,不会影响解析。注意别填浏览器禁止访问的端口(例如 6665-6669 这些 IRC 段),否则用户点开链接会直接 ERR_UNSAFE_PORT,看起来就像网页坏了。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`number`,fallback:0,min:0,max:65535,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),c([`qq`,`playerExpireMinutes`],`链接有效期(分钟)`,`播放链接与视频文件的有效期,默认 60 分钟(最小 1、最大 1440)。到点后视频和弹幕会被自动删除,链接打开是「链接已过期」。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`number`,fallback:60,min:1,max:1440,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),c([`qq`,`playerMaxFileMB`],`在线播放最大文件(MB)`,`体积超过这个值的视频**不走在线播放**,改回原来的发送流程(免得把机器磁盘塞满)。留空或填 0 = 跟随全局:用上游的「文件大小限制」(usefilelimit / filelimit,当前默认 200MB);全局没开限制就是不限制。**这条上限对「超限转在线播放」一样有效**:开了转播、但视频比这条上限还大时,仍然按原来的方式处理(拒绝并说明),不会为了转播把机器磁盘塞满。判定发生在把文件搬进播放器目录之前,超限的视频一点都不会占播放器目录。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`number`,fallback:0,min:0,max:102400,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1}),s([`qq`,`playerOnOversize`],`超限转在线播放`,`打开后,体积超过全局「文件大小限制」的视频不再被拒绝(原来会回一句「视频太大了,还是去B站看吧」),而是照常下载、改为在线播放:用户收到一条播放链接,视频不发到群里、也不占群文件。注意:**只有体积不超过上面「在线播放最大文件」的视频才会被转播**——比那个上限还大的照旧拒绝(免得把机器磁盘塞满),拒绝时会说明「超过在线播放的体积上限,按原来的方式处理」。关着时维持原来的行为。(这一项要先把上面的「在线播放器总开关」打开才能改)`,Q(e,[`qq`,`playerEnabled`],!0)===!1),c([`qq`,`forceOnlinePlayer`],`强制在线播放的适配器`,`填**适配器平台名**(多个用逗号分隔,例如 bilibili 或 bilibili,onebot),**默认就是 bilibili**;留空表示不强制任何适配器。填了之后,**从这些适配器进来的消息**解析完一律只给在线播放链接:视频不发出去、也不占群文件,跟用户在面板上点的是「解析」还是「在线看」、体积有没有超限都无关。典型用法:B站私聊机器人(adapter-bilibili-dm)的平台名就是 bilibili,它发不了视频文件,把它填进去即可。注意这里填的是**适配器**的名字,不是解析来源平台(抖音 / B站 这些由「发送内容」那些开关管)。要求「在线播放器总开关」开着。(这一项要先把上面的「在线播放器总开关」打开才能改)`,{type:`text`,disabled:Q(e,[`qq`,`playerEnabled`],!0)===!1})]})),o(`错误上报`,(0,U.jsx)(U.Fragment,{children:[s([`qq`,`errorReportUpload`],`上传错误信息`,`插件出错时,自动把**错误信息、运行环境(Koishi 版本、装了哪些插件、适配器)、最近的日志**上传到收集站,站长在网页上就能查到,不用你截图、也不用翻日志文件。**默认开启**。上传失败不影响报错本身(错误卡片照常发)。不想要就在这里关掉。`)]}))/*KKK-SECTION-END*/,o(`渲染设置`,(0,U.jsxs)(U.Fragment,{children:[c([`app`,`renderScale`],`渲染精度`,`可选值50~200,建议100。设置高精度会提高图片的精细度,过高可能会影响渲染与发送速度。`,{type:`number`,fallback:100,min:50,max:200}),(0,U.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,U.jsx)(`div`,{className:`min-w-0 flex-1`,children:i([`app`,`Theme`],`渲染图片的主题色`,`渲染评论图和推送图的主题色。`,[{label:`自动`,value:`0`,description:`06:00-18:00为浅色,18:00-06:00为深色`},{label:`浅色`,value:`1`},{label:`深色`,value:`2`},{label:`智能场景(实验性)`,value:`3`,description:`自动模式的超集;部分模板会根据封面色调 智能调整主题色,可能会出现不适配的情况。`}],e=>Number(e))}),(0,U.jsxs)(gv,{children:[(0,U.jsx)(gv.Trigger,{"aria-label":`封面氛围背景参数`,className:`mt-7 shrink-0`,children:(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":`封面氛围背景参数`,variant:`secondary`,children:(0,U.jsx)(Gj,{className:`size-4`,"aria-hidden":`true`})})}),(0,U.jsx)(gv.Content,{className:`w-90 max-w-[calc(100vw-2rem)]`,placement:`bottom`,children:(0,U.jsxs)(gv.Dialog,{children:[(0,U.jsx)(gv.Arrow,{}),(0,U.jsx)(gv.Heading,{children:`封面氛围背景`}),(0,U.jsx)(`p`,{className:`mt-1 mb-5 text-sm text-muted`,children:`仅对使用封面氛围背景的模板生效(抖音视频/图文作品、B站视频信息、B站直播推荐动态)。`}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-5`,children:[a([`app`,`ambientCover`,`coverOpacity`],`封面氛围强度`,`封面图对背景氛围的贡献度,即模糊封面层的不透明度,越大封面色越浓。`,{fallback:.7}),a([`app`,`ambientCover`,`overlayEdgeOpacity`],`氛围压色(顶部/底部)`,`背景两端主题色压色罩的不透明度,越大两端越接近纯色主题背景。`,{fallback:.9}),a([`app`,`ambientCover`,`overlayMiddleOpacity`],`氛围压色(中间带)`,`背景中间带主题色压色罩的不透明度,越小封面色越透。`,{fallback:.2})]})]})})]})]}),c([`app`,`RenderWaitTime`],`渲染图片的等待时间`,`单位:秒,Linux系统下不能为0;其他系统传递 0 可禁用。`,{type:`number`,fallback:60,min:0}),s([`app`,`multiPageRender`],`分页渲染`,`将模板渲染成多页的图片,以降低渲染器压力,默认开启,非必要不修改!`),c([`app`,`multiPageHeight`],`分页渲染时,每页的高度`,`经测试最佳每页高度为12000px,默认12000px。`,{type:`number`,disabled:!Q(e,[`app`,`multiPageRender`],!0),fallback:12e3,min:1e3,max:2e4})]})),/*KKK-RENDERER-START*/o(`通用设置`,(0,U.jsxs)(U.Fragment,{children:[i([`app`,`renderer`],`优先渲染器`,`卡片优先用哪个渲染器渲染。两个渲染服务都在时会按这里选的走,缺一个就自动用另一个;`,[{label:`shotkit 内核(默认)`,value:`shotkit`,description:`不依赖浏览器,单张几十毫秒、内存低。注意:当前预编译内核在 Windows 上加载不了 https 资源,卡片里的远程封面、头像会缺图。`},{label:`浏览器(Chrome / Edge)`,value:`puppeteer`,description:`完整渲染、远程资源正常,单张通常 1 秒以上,需要浏览器渲染服务(koishi-plugin-puppeteer 或同类)。`}],e=>e)]}))/*KKK-RENDERER-END*/,o(`上传与下载设置`,(0,U.jsxs)(U.Fragment,{children:[(0,U.jsxs)(Ev,{className:`flex flex-col gap-5 p-4 mb-4 rounded-3xl`,variant:`secondary`,children:[i([`app`,`videoSendMode`],`本地视频发送方式`,`选择本地视频交付给协议端的方式。`,[{label:`File 协议(本地文件)`,value:`file`,description:`使用 file 协议发送本地视频,需 Koishi 与协议端在同一网络环境下`},{label:`Base64(编码传输)`,value:`base64`,description:`将本地视频转换为 base64 发送,传输数据量增大约 30%,不在同一网络环境可能导致额外带宽成本,适合 karin 和协议端不在同一网络环境`}],e=>e,Q(e,[`app`,`usegroupfile`],!1)),s([`app`,`usegroupfile`],`群文件上传`,`使用群文件上传,开启后会将视频文件上传到群文件中,需配置「群文件上传阈值」。与「本地视频发送方式 = Base64」互斥。`,Q(e,[`app`,`videoSendMode`],`file`)===`base64`),c([`app`,`groupfilevalue`],`群文件上传阈值`,`当文件大小超过该值时将使用群文件上传,单位:MB,「使用群文件上传」开启后才会生效。`,{type:`number`,fallback:100,min:1,disabled:!Q(e,[`app`,`usegroupfile`],!1)||Q(e,[`app`,`videoSendMode`],`file`)===`base64`})]}),(0,U.jsx)(Ev,{className:`flex flex-col gap-5 p-4 mb-4 rounded-3xl`,variant:`secondary`,children:i([`app`,`imageSendMode`],`网络图片发送方式`,`图片资源发送给协议端的方式。`,[{label:`URL 链接(直接传递)`,value:`url`,description:`直接传递 HTTP 链接给上游下载,可能因上游网络问题导致下载超时`},{label:`File 协议(本地文件)`,value:`file`,description:`下载到本地后使用 file 协议发送,需 Koishi 与协议端在同一网络环境下`},{label:`Base64(编码传输)`,value:`base64`,description:`下载后转换为 base64 发送,传输数据量增大约 30%,不在同一网络环境可能导致额外带宽成本`}])}),(0,U.jsxs)(Ev,{className:`flex flex-col gap-5 p-4 mb-4 rounded-3xl`,variant:`secondary`,children:[s([`app`,`usefilelimit`],`视频上传拦截`,`开启后会根据视频文件大小判断是否需要上传,需配置「视频拦截阈值」。`),c([`app`,`filelimit`],`视频拦截阈值`,`视频文件大于该数值则直接结束任务,不会上传,单位: MB,「视频上传拦截」开启后才会生效。`,{type:`number`,fallback:20,min:1,disabled:!Q(e,[`app`,`usefilelimit`],!1)}),s([`app`,`compress`],`压缩视频`,`开启后会将视频文件压缩后再上传,适合上传大文件,任务过程中会吃满CPU,对低配服务器不友好。需配置「压缩触发阈值」与「压缩后的值」。`),c([`app`,`compresstrigger`],`压缩触发阈值`,`触发视频压缩的阈值,单位:MB。当文件大小超过该值时,才会压缩视频,「压缩视频」开启后才会生效。`,{type:`number`,fallback:80,min:1,disabled:!Q(e,[`app`,`compress`],!1)}),c([`app`,`compressvalue`],`压缩后的值`,`单位:MB,若视频文件大小大于「压缩触发阈值」的值,则会进行压缩至该值(±5%),「压缩视频」开启后才会生效。`,{type:`number`,fallback:30,min:1,disabled:!Q(e,[`app`,`compress`],!1)})]}),(0,U.jsxs)(Ev,{className:`flex flex-col gap-5 p-4 rounded-3xl`,variant:`secondary`,children:[s([`app`,`downloadThrottle`],`下载限速`,`开启后会限制下载速度,避免触发服务器风控导致连接被重置(ECONNRESET)。如果下载时经常报错"连接被重置",建议开启。`),c([`app`,`downloadMaxSpeed`],`最大下载速度`,`限速开关打开后生效。单位:MB/s,建议值:10,根据实际情况调整。`,{type:`number`,fallback:10,min:1,max:100,disabled:!Q(e,[`app`,`downloadThrottle`],!1)}),s([`app`,`downloadAutoReduce`],`断流自动降速`,`限速开关打开后生效。当检测到下载中断时,自动降低下载速度,避免再次触发风控。`,!Q(e,[`app`,`downloadThrottle`],!1)),c([`app`,`downloadMinSpeed`],`最低下载速度`,`断流降速开关打开后生效。单位:MB/s,自动降速的下限值。`,{type:`number`,fallback:1,min:.5,max:50,disabled:!Q(e,[`app`,`downloadThrottle`],!1)||!Q(e,[`app`,`downloadAutoReduce`],!1)})]})]})),o(`Live Photo 兼容设置`,(0,U.jsxs)(U.Fragment,{children:[i([`app`,`livePhotoMode`],`Live Photo 处理和发送方式`,`解析遇到实况图时的处理和发送方式。注意:生成视频性能开销大,2C2G 服务器单张约需 20 秒。`,[{label:`视频 + 实况图`,value:`video_and_livephoto`,description:`生成并发送仿 iPhone Live Photo 播放效果的视频(播放三次)+ 对应系统的实况图`},{label:`仅视频`,value:`video_only`,description:`仅生成并发送仿 iPhone Live Photo 播放效果的视频(播放三次)`},{label:`仅实况图`,value:`livephoto_only`,description:`仅生成并发送对应系统的实况图,性能开销小`}]),i([`app`,`livePhotoSystem`],`Live Photo 静态图兼容系统`,`当解析到作品/动态包含 Live Photo 时,合并转发里发送的 Live Photo 静态图按所选系统生成。推荐 OPPO,兼容性最广。`,[{label:`Google`,value:`google`,description:`Google Motion Photo 格式`},{label:`小米(HyperOS)`,value:`xiaomi`,description:`兼容小米(任何版本)和 Google,但无法被 OPPO 识别`},{label:`OPPO(ColorOS)`,value:`oppo`,description:`推荐,兼容 OPPO、小米(较新版本)和 Google`},{label:`华为/荣耀(HarmonyOS/MagicOS)`,value:`huawei_honor`,description:`理论可行但未实测(作者无对应设备)`},{label:`vivo(Origin OS)`,value:`vivo`,description:`需要独立的图片和同名视频文件,暂不支持`,disabled:!0},{label:`iPhone(iOS)`,value:`iphone`,description:`需要独立的图片和同名视频文件,暂不支持`,disabled:!0}],e=>e,l===`video_only`)]})),o(`我的小玩具`,(0,U.jsxs)(U.Fragment,{children:[s([`app`,`videoTool`],`默认解析优先级`,`关闭后使用自定义优先级,修改后需重启。`),c([`app`,`priority`],`自定义优先级`,`默认解析优先级关闭后生效。`,{type:`number`,disabled:Q(e,[`app`,`videoTool`],!0),fallback:800}),i([`app`,`qrLoginAddrType`],`扫码登录地址`,`生成登录二维码时使用的服务器地址。`,[{label:`局域网`,value:`lan`,description:`适用于手机和服务器在同一局域网`},{label:`外部地址`,value:`external`,description:`适用于远程访问,需手动配置`}]),c([`app`,`qrLoginExternalAddr`],`外部访问地址`,`公网 IP 或域名,如:123.45.67.89 或 example.com。`,{disabled:Q(e,[`app`,`qrLoginAddrType`],`lan`)!==`external`})]}))]})},ZL=({config:e,renderers:t,classes:n})=>{let{renderCheckboxGroup:r,renderCronField:i,renderPageHeader:a,renderSelectField:o,renderSubSection:s,renderSwitch:c,renderTextField:l}=t,u=Q(e,[`bilibili`,`switch`],!1),d=Q(e,[`bilibili`,`sendContent`],[]),f=Q(e,[`bilibili`,`burnDanmaku`],!1),p=Q(e,[`bilibili`,`videoQuality`],0),m=Q(e,[`bilibili`,`videoInfoMode`],`text`),h=Q(e,[`bilibili`,`push`,`switch`],!1),g=Q(e,[`bilibili`,`push`,`parsedynamic`],!1),_=Q(e,[`bilibili`,`push`,`pushVideoQuality`],0),v=!u||!_L(d,`comment`),y=!u||!f;return(0,U.jsxs)(U.Fragment,{children:[a(`哔哩哔哩`,`B站解析、动态图片布局、弹幕和推送基础设置。`),(0,U.jsxs)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:[c([`bilibili`,`switch`],`解析开关`,`B站解析开关,此开关为单独开关。`),r([`bilibili`,`sendContent`],`解析时发送的内容`,`若什么都不选,可能不会返回任何解析结果。`,jL.filter(e=>e.value!==`image`),!u)]}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`bilibili`,`forward`],`合并转发(哔哩哔哩)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`bilibili`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,,s(`评论详情设置`,(0,U.jsxs)(U.Fragment,{children:[l([`bilibili`,`numcomment`],`评论解析数量`,`主评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:v}),c([`bilibili`,`realCommentCount`],`显示真实评论数量`,`关闭则显示解析到的评论数量。`,v),c([`bilibili`,`commentImageCollection`],`是否收集评论区的图片`,`开启后将收集评论区的图片,以合并转发的形式返回。`,v)]})),s(`渲染与画质设置`,(0,U.jsxs)(U.Fragment,{children:[o([`bilibili`,`videoQuality`],`画质偏好`,`解析视频的分辨率偏好。`,PL,Number,!u),l([`bilibili`,`maxAutoVideoSize`],`视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!u||Number(p)!==0}),o([`bilibili`,`imageLayout`],`解析图文动态时,遇到多张图片时的页面布局方式(动态推送图片也生效)`,`自动布局:少于4张时逐张上下排列;4~8张时瀑布流;9张及以上九宫格。`,[{label:`自动布局`,value:`auto`},{label:`逐张上下排列`,value:`vertical`},{label:`瀑布流排列`,value:`waterfall`},{label:`九宫格排列`,value:`grid`}]),o([`bilibili`,`videoInfoMode`],`视频信息返回形式`,`视频信息返回文本或图片。`,[{label:`图片模式`,value:`image`},{label:`文本模式`,value:`text`}],e=>e,!u),r([`bilibili`,`displayContent`],`视频信息前返回的内容`,`若什么都不选,则不会返回任何视频相关信息。`,ML,!u||m===`image`),c([`bilibili`,`showDanmakuInVideoInfo`],`视频信息图片中显示弹幕`,`开启后在视频信息图片的封面区域显示热门弹幕。关闭后不会请求弹幕数据,可提升解析速度。仅「视频信息返回形式」为图片模式时生效。`,!u||m===`text`)]})),s(`权限设置`,(0,U.jsx)(U.Fragment,{children:t.renderPermField([`bilibili`,`loginPerm`],`谁可以触发扫码登录`,`选「指定账号」后填用户 ID,多个用逗号分隔。`,{modes:[{value:`all`,label:`所有人`},{value:`admin`,label:`管理员(权限等级 4 及以上)`},{value:`id`,label:`指定账号`}]})})),s(`弹幕烧录相关`,(0,U.jsxs)(U.Fragment,{children:[c([`bilibili`,`burnDanmaku`],`弹幕烧录`,`将弹幕硬编码到视频画面中。开启后视频需要重新编码,耗时较长,高分辨率视频会占用较多资源。`,!u),o([`bilibili`,`danmakuArea`],`弹幕区域`,`限制弹幕的显示范围,避免遮挡视频主体内容。`,zL,Number,y),o([`bilibili`,`danmakuFontSize`],`弹幕字号`,`弹幕文字大小。`,BL,e=>e,y),l([`bilibili`,`danmakuOpacity`],`弹幕透明度`,`0为完全透明,100为完全不透明,推荐70。`,{type:`number`,fallback:70,min:0,max:100,disabled:y}),o([`bilibili`,`verticalMode`],`竖屏适配`,`模拟手机端竖屏观看体验,视频居中显示,上下黑边区域用于展示弹幕。`,RL,e=>e,y),o([`bilibili`,`videoCodec`],`视频编码格式`,`弹幕烧录时使用的视频编码格式,会自动检测硬件加速。`,LL,e=>e,y)]})),s(`B站推送相关`,(0,U.jsxs)(U.Fragment,{children:[c([`bilibili`,`push`,`switch`],`推送开关`,`推送开关,修改后需重启;使用「#设置B站推送 + UID」配置推送列表。`),o([`bilibili`,`push`,`permission`],`谁可以设置推送`,`修改后需重启。`,IL,e=>e,!h),i([`bilibili`,`push`,`cron`],`定时任务表达式`,`定时推送的时间,支持可视化编辑或手动输入 cron 表达式。`,!h),c([`bilibili`,`push`,`parsedynamic`],`作品解析`,`触发推送时是否一同解析该作品。`,!h),r([`bilibili`,`push`,`parseDynamicTypes`],`需要解析的动态类型`,`选择推送时需要进一步解析的动态类型;未选择的类型只发送动态卡片。`,FL,!h||!g),o([`bilibili`,`push`,`pushVideoQuality`],`解析视频动态时的画质偏好`,`「作品解析」开启时生效,仅对视频动态有效。`,PL.filter(e=>e.value!==`127`),Number,!h||!g),l([`bilibili`,`push`,`pushMaxAutoVideoSize`],`视频动态的视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「解析视频动态时的画质偏好」 为 "自动选择" 且「作品解析」开启时生效,仅对视频动态有效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!h||!g||Number(_)!==0})]}))]})},QL=({config:e,renderers:t,classes:n})=>{let{renderCheckboxGroup:r,renderCronField:i,renderPageHeader:a,renderSelectField:o,renderSubSection:s,renderSwitch:c,renderTextField:l}=t,u=Q(e,[`app`,`livePhotoMode`],`video_and_livephoto`),d=Q(e,[`douyin`,`switch`],!1),f=Q(e,[`douyin`,`sendContent`],[]),p=Q(e,[`douyin`,`burnDanmaku`],!1),m=Q(e,[`douyin`,`videoQuality`],`adapt`),h=Q(e,[`douyin`,`videoInfoMode`],`text`),g=Q(e,[`douyin`,`push`,`switch`],!1),_=Q(e,[`douyin`,`push`,`pushVideoQuality`],`adapt`),v=!d||!_L(f,`comment`),y=!d||!p;return(0,U.jsxs)(U.Fragment,{children:[a(`抖音`,`抖音解析、画质、弹幕和推送基础设置。`),(0,U.jsxs)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:[c([`douyin`,`switch`],`解析开关`,`抖音解析开关,此开关为单独开关。`),r([`douyin`,`sendContent`],`解析时发送的内容`,`若什么都不选,可能不会返回任何解析结果。`,jL.filter(e=>e.value!==`image`),!d)]}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`douyin`,`forward`],`合并转发(抖音)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`douyin`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,,s(`评论详情设置`,(0,U.jsxs)(U.Fragment,{children:[l([`douyin`,`numcomment`],`评论解析数量`,`主评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:v}),l([`douyin`,`subCommentLimit`],`子评论请求数量`,`单条主评论下请求的子评论总条数(含多层嵌套)。注意:UI中最多显示 6 层回复嵌套,超出部分会被隐藏;因实际嵌套深度不可预知,配置数量不代表最终可见数量。`,{type:`number`,fallback:5,min:1,max:20,disabled:v}),c([`douyin`,`commentImageCollection`],`是否收集评论区的图片`,`开启后将收集评论区的图片,以合并转发的形式返回。`,v)]})),s(`渲染与画质设置`,(0,U.jsxs)(U.Fragment,{children:[o([`douyin`,`liveImageMergeMode`],`合辑 Live 图 BGM 合并方式`,`合辑 Live 图 BGM 合并方式,仅 Live Photo 模式不是「仅实况图」时生效。`,[{label:`连续`,value:`continuous`,description:`BGM 接续播放,结束后自动循环`},{label:`独立`,value:`independent`,description:`每张图 BGM 从头开始`}],e=>e,!d||u===`livephoto_only`),o([`douyin`,`videoQuality`],`画质偏好`,`解析视频的分辨率偏好。`,NL,e=>e,!d),l([`douyin`,`maxAutoVideoSize`],`视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!d||m!==`adapt`}),o([`douyin`,`videoInfoMode`],`视频信息返回形式`,`视频信息返回文本或图片。`,[{label:`图片模式`,value:`image`},{label:`文本模式`,value:`text`}],e=>e,!d),r([`douyin`,`displayContent`],`视频信息的内容`,`若什么都不选,则不会返回任何视频相关信息。`,ML.filter(e=>e.value!==`desc`),!d||h===`image`)]})),s(`权限设置`,(0,U.jsx)(U.Fragment,{children:t.renderPermField([`douyin`,`loginPerm`],`谁可以触发扫码登录`,`选「指定账号」后填用户 ID,多个用逗号分隔。`,{modes:[{value:`all`,label:`所有人`},{value:`admin`,label:`管理员(权限等级 4 及以上)`},{value:`id`,label:`指定账号`}]})})),s(`弹幕烧录相关`,(0,U.jsxs)(U.Fragment,{children:[c([`douyin`,`burnDanmaku`],`弹幕烧录`,`将弹幕硬编码到视频画面中。开启后视频需要重新编码,耗时较长。`,!d),o([`douyin`,`danmakuArea`],`弹幕显示区域`,`限制弹幕范围,避免遮挡视频主体。`,zL,Number,y),o([`douyin`,`danmakuFontSize`],`弹幕字号`,`弹幕文字大小。`,BL,e=>e,y),l([`douyin`,`danmakuOpacity`],`弹幕透明度`,`0为完全透明,100为完全不透明,推荐70。`,{type:`number`,fallback:70,min:0,max:100,disabled:y}),o([`douyin`,`verticalMode`],`竖屏适配`,`针对横屏视频,模拟手机端竖屏观看体验,视频居中显示,上下黑边区域用于展示弹幕。`,RL,e=>e,y),o([`douyin`,`videoCodec`],`视频编码格式`,`烧录弹幕后的视频编码格式。`,LL,e=>e,y)]})),s(`抖音推送相关`,(0,U.jsxs)(U.Fragment,{children:[c([`douyin`,`push`,`switch`],`推送开关`,`推送开关,修改后需重启;使用「#设置抖音推送 + 抖音号」配置推送列表。`),o([`douyin`,`push`,`permission`],`谁可以设置推送`,`修改后需重启。`,IL,e=>e,!g),i([`douyin`,`push`,`cron`],`定时任务表达式`,`定时推送的时间,支持可视化编辑或手动输入 cron 表达式。`,!g),c([`douyin`,`push`,`parsedynamic`],`作品解析`,`触发推送时是否一同解析该作品。`,!g),o([`douyin`,`push`,`shareType`],`推送图二维码的类型`,`推送图二维码识别后的跳转类型。`,[{label:`网页链接`,value:`web`,description:`识别后访问抖音官网对应的作品地址`},{label:`下载链接`,value:`download`,description:`识别后访问无水印作品下载地址`}],e=>e,!g),o([`douyin`,`push`,`pushVideoQuality`],`画质偏好`,`推送解析时解析视频的分辨率偏好。`,NL,e=>e,!g),l([`douyin`,`push`,`pushMaxAutoVideoSize`],`视频体积上限(MB)`,`推送解析时根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!g||_!==`adapt`})]}))]})},$L=({config:e,renderers:t,classes:n})=>{let{renderPageHeader:r,renderSubSection:i,renderSwitch:a,renderTextField:o}=t,s=Q(e,[`kuaishou`,`switch`],!1),c=Q(e,[`kuaishou`,`comment`],!1);return(0,U.jsxs)(U.Fragment,{children:[r(`快手`,`快手解析基础设置。`),(0,U.jsx)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:a([`kuaishou`,`switch`],`解析开关`,`快手解析开关,此开关为单独开关。`)}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`kuaishou`,`forward`],`合并转发(快手)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`kuaishou`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,,i(`评论详情设置`,(0,U.jsxs)(U.Fragment,{children:[a([`kuaishou`,`comment`],`评论解析`,`快手评论解析,开启后可发送快手作品评论图。`,!s),o([`kuaishou`,`numcomment`],`评论解析数量`,`快手评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:!s||!c})]}))]})},eR=({children:e,disabled:t,message:n,device:r})=>t?r===`mobile`?(0,U.jsxs)(gv,{children:[(0,U.jsx)(gv.Trigger,{className:`w-full cursor-not-allowed`,children:e}),(0,U.jsxs)(gv.Content,{placement:`bottom`,children:[(0,U.jsx)(gv.Arrow,{}),(0,U.jsx)(`div`,{className:`px-3 py-2`,children:(0,U.jsx)(`p`,{className:`text-sm text-foreground`,children:n})})]})]}):(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{className:`w-full cursor-not-allowed`,children:e}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),n]})]}):e,tR=e=>e===`desktop`?`grid grid-cols-2 gap-4`:`flex flex-col gap-4`,nR=[{label:`作品列表`,value:`post`,description:`推送用户发布的作品`},{label:`喜欢列表`,value:`favorite`,description:`推送用户喜欢的作品`},{label:`推荐列表`,value:`recommend`,description:`推送推荐的作品`},{label:`直播`,value:`live`,description:`推送直播状态`}],rR=[{label:`投稿视频`,value:`video`,description:`推送UP主投稿的视频`},{label:`图文动态`,value:`draw`,description:`推送图文动态`},{label:`纯文动态`,value:`word`,description:`推送纯文字动态`},{label:`直播动态`,value:`live`,description:`推送直播状态`},{label:`转发动态`,value:`forward`,description:`推送转发的动态`},{label:`投稿专栏`,value:`article`,description:`推送专栏文章`}],iR=[{label:`黑名单`,value:`blacklist`,description:`命中关键词/标签则不推送`},{label:`白名单`,value:`whitelist`,description:`只推送命中关键词/标签的内容`}],aR=({label:e,description:t,items:n,onAdd:r,onRemove:i,disabled:a=!1})=>{let[o,s]=(0,v.useState)(``),[c,l]=(0,v.useState)(``),u=()=>{let e=o.trim();if(!e){l(`请输入内容`);return}if(n.includes(e)){l(`该项已存在,请勿重复添加`);return}r(e),s(``),l(``)};return(0,U.jsxs)(`div`,{className:`space-y-2`,children:[(0,U.jsxs)(`div`,{className:`flex gap-2`,children:[(0,U.jsxs)(lx,{className:`flex-1`,isDisabled:a,isInvalid:!!c,value:o,onChange:e=>{s(e),c&&l(``)},children:[(0,U.jsx)(dx,{children:e}),(0,U.jsx)(cx,{variant:`secondary`,placeholder:`输入${e}`,onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),u())}}),c?(0,U.jsx)(hx,{children:c}):null]}),(0,U.jsx)(Vg,{isDisabled:a,variant:`secondary`,onPress:u,children:(0,U.jsx)(Hj,{className:`size-4`})})]}),n.length>0?(0,U.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:n.map(e=>(0,U.jsxs)(v_,{color:`accent`,variant:`soft`,children:[(0,U.jsx)(`span`,{children:e}),a?null:(0,U.jsx)(`button`,{type:`button`,className:`ml-1 rounded-full p-0.5 hover:bg-black/10`,onClick:()=>i(e),children:(0,U.jsx)(Kj,{className:`size-3`})})]},e))}):(0,U.jsxs)(px,{children:[`暂无`,e]}),(0,U.jsx)(px,{children:t})]})},oR=(e,t)=>{if((e.success||e.code===200)&&e.data!==void 0)return e.data;throw Error(e.message||t)},sR=async()=>{let r=(await eI.get(`/kkk/v1/bots`)).data?.data;return Array.isArray(r)?r:[]},cR=async e=>{let r=(await eI.get(`/kkk/v1/bots/${encodeURIComponent(e)}/groups`)).data?.data;return Array.isArray(r)?r:[]},lR=async e=>{if(!e.length)return [];let r=(await eI.post(`/kkk/v1/groups/batch`,{groups:e})).data?.data;return Array.isArray(r)?r:[]},uR=({mapping:e,compact:t=!1,stacked:n=!1})=>n?(0,U.jsxs)(`div`,{className:`flex min-w-0 flex-col gap-2`,children:[(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.groupName||e.groupId,src:e.groupAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.groupName||e.groupId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.groupName||e.groupId}),(0,U.jsx)(px,{className:`block truncate`,children:e.groupId})]})]}),(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 pl-8`,children:[(0,U.jsx)(Nj,{className:`size-4 shrink-0 text-muted`}),(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.botName||e.botId,src:e.botAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.botName||e.botId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.botName||e.botId}),(0,U.jsx)(px,{className:`block truncate`,children:t?e.botId:`Bot ${e.botId}`})]})]})]}):(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.groupName||e.groupId,src:e.groupAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.groupName||e.groupId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.groupName||e.groupId}),(0,U.jsx)(px,{className:`block truncate`,children:e.groupId})]}),(0,U.jsx)(Nj,{className:`size-4 shrink-0 text-muted`}),(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.botName||e.botId,src:e.botAvatar}),(0,U.jsx)(Ig.Fallback,{children:(e.botName||e.botId).slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,U.jsx)(dx,{className:`block truncate`,children:e.botName||e.botId}),(0,U.jsx)(px,{className:`block truncate`,children:t?e.botId:`Bot ${e.botId}`})]})]}),dR=e=>`${e.groupId}:${e.botId}`,fR=e=>{let[t,n,r]=e.split(`:`);return!t||!n||r!==void 0?null:{groupId:t,botId:n}},pR=e=>{let t=new Set,n=[];return e.forEach(e=>{let r=fR(e);if(!r)return;let i=dR(r);t.has(i)||(t.add(i),n.push(i))}),n},mR=({device:e,mappings:t,onEdit:n,onRemove:r})=>(0,U.jsxs)(`div`,{className:e===`mobile`?`flex min-h-0 min-w-0 flex-1 flex-col gap-4`:`flex min-w-0 flex-col gap-3`,children:[(0,U.jsxs)(`div`,{children:[(0,U.jsx)(dx,{children:`已配置目标`}),(0,U.jsxs)(px,{children:[t.length,` 个推送目标`]})]}),t.length>0?(0,U.jsx)(`div`,{className:e===`mobile`?`flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto pb-2`:`flex max-h-72 flex-col gap-2 overflow-y-auto`,children:t.map(t=>{let i=dR(t);return(0,U.jsxs)(`div`,{className:`flex min-w-0 items-start gap-2 rounded-lg border border-default-200 bg-default-50/50 p-2.5`,children:[(0,U.jsx)(`div`,{className:`min-w-0 flex-1`,children:(0,U.jsx)(uR,{compact:!0,mapping:t,stacked:e===`mobile`})}),(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":`编辑推送目标`,size:`sm`,variant:`tertiary`,onPress:()=>n(i),children:(0,U.jsx)(Vj,{className:`size-4`})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),`编辑`]})]}),(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":`删除推送目标`,size:`sm`,variant:`danger`,onPress:()=>r(i),children:(0,U.jsx)(Kj,{className:`size-4`})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`top`,children:[(0,U.jsx)(tx.Arrow,{}),`删除`]})]})]},i)})}):(0,U.jsx)(`div`,{className:`rounded-lg border border-dashed border-default-300 px-4 py-5 text-sm text-muted`,children:`还没有推送目标,点击上方按钮添加。`})]}),hR=({label:e,description:t,placeholder:n,disabled:r=!1,items:i,selectedId:a,onSelect:o})=>(0,U.jsxs)(Ax,{fullWidth:!0,allowsEmptyCollection:!0,isDisabled:r,placeholder:n,value:a||null,variant:`secondary`,onChange:e=>o(String(e||``)),children:[(0,U.jsx)(dx,{children:e}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{children:({defaultChildren:e,isPlaceholder:t,state:n})=>{if(t||n.selectedItems.length===0)return e;let r=i.find(e=>e.id===n.selectedItems[0]?.key);return r?(0,U.jsxs)(`span`,{className:`flex min-w-0 items-center gap-3`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:r.name,src:r.avatar}),(0,U.jsx)(Ig.Fallback,{children:r.name.slice(0,1)})]}),(0,U.jsxs)(`span`,{className:`min-w-0`,children:[(0,U.jsx)(`span`,{className:`block truncate`,children:r.name}),(0,U.jsx)(`span`,{className:`block truncate text-xs text-muted`,children:r.description})]})]}):e}}),(0,U.jsx)(Ax.Indicator,{})]}),(0,U.jsx)(px,{children:t}),!r&&i.length===0?(0,U.jsx)(px,{className:`text-warning`,children:`当前没有可选项`}):null,(0,U.jsx)(Ax.Popover,{className:`max-h-72`,children:(0,U.jsx)(wx,{items:i,children:e=>(0,U.jsxs)(wx.Item,{id:e.id,textValue:`${e.name} ${e.description}`,children:[(0,U.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,U.jsxs)(Ig,{size:`sm`,children:[(0,U.jsx)(Ig.Image,{alt:e.name,src:e.avatar}),(0,U.jsx)(Ig.Fallback,{children:e.name.slice(0,1)})]}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(dx,{className:`truncate`,children:e.name}),(0,U.jsx)(px,{className:`truncate`,children:e.description})]})]}),(0,U.jsx)(wx.ItemIndicator,{})]})})})]}),gR=({isOpen:e,device:t,initialMapping:n,onOpenChange:r,onConfirm:i})=>{let[a,o]=(0,v.useState)([]),[s,c]=(0,v.useState)([]),[l,u]=(0,v.useState)(n?.botId||``),[d,f]=(0,v.useState)(n?.groupId||``),[p,m]=(0,v.useState)(!0),[h,g]=(0,v.useState)(!!n?.botId),[_,y]=(0,v.useState)(``);(0,v.useEffect)(()=>{e&&(u(n?.botId||``),f(n?.groupId||``),c([]),o([]),m(!0),g(!!n?.botId),y(``))},[e,n?.botId,n?.groupId]);let b=(0,v.useMemo)(()=>a.find(e=>e.id===l),[a,l]),x=(0,v.useMemo)(()=>s.find(e=>e.id===d),[s,d]),S=(0,v.useMemo)(()=>a.map(e=>({id:e.id,name:e.name,avatar:e.avatar,description:e.id})),[a]),C=(0,v.useMemo)(()=>s.map(e=>({id:e.id,name:e.name,avatar:e.avatar,description:e.id})),[s]),w=!!(l&&d);(0,v.useEffect)(()=>{e&&sR().then(o).catch(e=>{y(e instanceof Error?e.message:`获取 Bot 列表失败`)}).finally(()=>m(!1))},[e]),(0,v.useEffect)(()=>{!e||!l||cR(l).then(e=>{c(e),f(t=>e.some(e=>e.id===t)?t:``)}).catch(e=>{y(e instanceof Error?e.message:`获取群列表失败`)}).finally(()=>g(!1))},[e,l]);let T=()=>{if(!w||!b)return;let e={groupId:(x&&x.id)||String(d||``).trim(),botId:b.id};x&&x.name&&(e.groupName=x.name),x&&x.avatar&&(e.groupAvatar=x.avatar),b.name&&(e.botName=b.name),b.avatar&&(e.botAvatar=b.avatar),b.isOnline!==void 0&&(e.isOnline=b.isOnline),i(e)},E=t===`desktop`?`right`:`bottom`,D=n?`编辑推送目标`:`添加推送目标`;return(0,U.jsx)(pv.Backdrop,{isOpen:e,onOpenChange:r,children:(0,U.jsx)(pv.Content,{placement:E,children:(0,U.jsxs)(pv.Dialog,{className:t===`desktop`?`h-full w-105 max-w-[90vw]`:`max-h-[78dvh]`,children:[(0,U.jsx)(pv.Handle,{}),(0,U.jsx)(pv.CloseTrigger,{}),(0,U.jsxs)(pv.Header,{children:[(0,U.jsx)(pv.Heading,{children:D}),(0,U.jsx)(px,{children:`先选择机器人账号,再填写要推送的群号。`})]}),(0,U.jsxs)(pv.Body,{className:`flex flex-col gap-4`,children:[(0,U.jsx)(hR,{description:`Koishi 当前已注册且在线的 Bot。`,disabled:p,items:S,label:`机器人账号`,placeholder:`选择机器人账号`,selectedId:l,onSelect:e=>{y(``),c([]),g(!!e),u(e),f(``)}}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(dx,{className:`font-semibold`,children:`推送群`}),(0,U.jsx)(`input`,{className:`w-full rounded-large border border-default-200 bg-default-100 px-3 py-2 text-sm outline-none`,placeholder:`填写群号,例如 1050229473`,value:d||``,onChange:e=>f(e.target.value)}),(0,U.jsx)(px,{className:`text-xs`,children:`直接填群号(频道 id)即可;要指定平台时写成 平台:群号。`})]}),p||h?(0,U.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在读取列表`}),(0,U.jsx)(`span`,{children:`正在读取列表`})]}):null,b&&x?(0,U.jsxs)(`div`,{className:`flex flex-col gap-2 rounded-lg border border-default-200 bg-default-50/60 p-3`,children:[(0,U.jsx)(dx,{children:`将写入`}),(0,U.jsxs)(px,{className:`mt-1`,children:[x.name,`(`,x.id,`) -> `,b.name,`(`,b.id,`)`]})]}):null,_?(0,U.jsx)(px,{className:`text-danger`,children:_}):null]}),(0,U.jsxs)(pv.Footer,{children:[(0,U.jsx)(Vg,{size:t===`mobile`?`sm`:`md`,slot:`close`,variant:`secondary`,children:`取消`}),(0,U.jsx)(Vg,{size:t===`mobile`?`sm`:`md`,slot:`close`,isDisabled:!w,onPress:T,children:n?`保存`:`添加`})]})]})})})},_R=(e,t,n)=>{let r=pR(e);return{values:r,mappings:r.map(e=>{let r=fR(e),i=n[e]||t.find(t=>dR(t)===e);if(!r)return null;let a={groupId:r.groupId,botId:r.botId};return i?.groupName&&(a.groupName=i.groupName),i?.groupAvatar&&(a.groupAvatar=i.groupAvatar),i?.botName&&(a.botName=i.botName),i?.botAvatar&&(a.botAvatar=i.botAvatar),i?.isOnline!==void 0&&(a.isOnline=i.isOnline),a}).filter(e=>!!e)}},vR=({isOpen:e,values:t,mappings:n,device:r,onOpenChange:i,onApply:a})=>{let[o,s]=(0,v.useState)(()=>pR(t)),[c,l]=(0,v.useState)({}),[u,d]=(0,v.useState)(null),[f,p]=(0,v.useState)(!1),m=(0,v.useMemo)(()=>_R(o,n,c),[o,c,n]),h=r===`desktop`?`right`:`bottom`,g=u?fR(u):null,_=e=>{d(e),p(!0)};return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(pv.Backdrop,{isOpen:e,onOpenChange:e=>{e||a(m.values),i(e)},variant:`blur`,children:(0,U.jsx)(pv.Content,{placement:h,children:(0,U.jsxs)(pv.Dialog,{className:r===`desktop`?`h-full w-130 max-w-[90vw]`:`max-h-[84dvh]`,children:[(0,U.jsx)(pv.Handle,{}),(0,U.jsx)(pv.CloseTrigger,{}),(0,U.jsxs)(pv.Header,{children:[(0,U.jsx)(pv.Heading,{children:`推送目标`}),(0,U.jsx)(px,{children:`管理所有接收推送的群和 Bot 映射。`})]}),(0,U.jsxs)(pv.Body,{className:`flex min-h-0 flex-col gap-3`,children:[(0,U.jsxs)(Vg,{className:`self-start`,size:r===`mobile`?`sm`:`md`,onPress:()=>_(null),children:[(0,U.jsx)(Hj,{className:`size-4`}),`添加推送目标`]}),(0,U.jsx)(mR,{device:r,mappings:m.mappings,onEdit:e=>_(e),onRemove:e=>{s(t=>t.filter(t=>t!==e)),l(t=>{let n={...t};return delete n[e],n})}})]}),(0,U.jsxs)(pv.Footer,{children:[(0,U.jsx)(Vg,{size:r===`mobile`?`sm`:`md`,slot:`close`,variant:`secondary`,children:`取消`}),(0,U.jsx)(Vg,{size:r===`mobile`?`sm`:`md`,slot:`close`,onPress:()=>{a(m.values)},children:`完成`})]})]})})}),(0,U.jsx)(gR,{device:r,initialMapping:g,isOpen:f,onConfirm:e=>{let t=dR(e),n=[...o],r=u?n.indexOf(u):-1;r>=0?n[r]=t:n.unshift(t),s(pR(n)),l(n=>{let r={...n,[t]:e};return u&&u!==t&&delete r[u],r}),p(!1),d(null)},onOpenChange:p},u||`new`)]})},yR=(e,t)=>{let n=fR(e);if(!n)return null;let r={groupId:n.groupId,botId:n.botId};return t?.groupName&&(r.groupName=t.groupName),t?.groupAvatar&&(r.groupAvatar=t.groupAvatar),t?.botName&&(r.botName=t.botName),t?.botAvatar&&(r.botAvatar=t.botAvatar),t?.isOnline!==void 0&&(r.isOnline=t.isOnline),r},bR=({value:e,disabled:t,itemLabel:n,device:r,onChange:i})=>{let a=(0,v.useMemo)(()=>pR(e),[e]),o=(0,v.useMemo)(()=>e.filter(e=>!fR(e)),[e]),[s,c]=(0,v.useState)([]),[l,u]=(0,v.useState)(!1),[d,f]=(0,v.useState)(!1),p=(0,v.useMemo)(()=>a.map(e=>{let t=fR(e);return yR(e,t?s.find(e=>e.groupId===t.groupId&&e.botId===t.botId):void 0)}).filter(e=>!!e),[s,a]);(0,v.useEffect)(()=>{lR(a.map(fR).filter(e=>!!e)).then(c).catch(()=>c([])).finally(()=>u(!1))},[a]);let m=e=>i(pR(e)),h=`开启【${n}】的推送开关后才能编辑此字段`,g=a.length>0?`已配置 ${a.length} 个推送目标`:`还没有配置推送目标`;return(0,U.jsx)(eR,{disabled:t,device:r,message:h,children:(0,U.jsxs)(`div`,{className:`space-y-3`,children:[(0,U.jsxs)(`div`,{className:`flex items-center justify-between gap-4 rounded-lg border border-default-200 bg-default-50/50 px-4 py-3`,children:[(0,U.jsxs)(`div`,{className:`flex flex-col min-w-0`,children:[(0,U.jsx)(dx,{children:`推送目标`}),(0,U.jsx)(px,{className:`mt-1`,children:g})]}),(0,U.jsxs)(Vg,{isDisabled:t,size:r===`mobile`?`sm`:`md`,variant:r===`mobile`?`primary`:`secondary`,onPress:()=>f(!0),children:[(0,U.jsx)(Vj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`管理`})]})]}),l?(0,U.jsxs)(`div`,{className:`flex items-center gap-2 text-sm text-muted`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在读取推送目标`}),(0,U.jsx)(`span`,{children:`正在读取推送目标`})]}):null,o.length>0?(0,U.jsxs)(`div`,{className:`rounded-lg border border-warning/30 bg-warning/10 p-3 text-sm`,children:[(0,U.jsxs)(`div`,{className:`flex items-center gap-2 font-medium text-warning`,children:[(0,U.jsx)(qj,{className:`size-4`}),(0,U.jsxs)(`span`,{children:[`发现 `,o.length,` 条旧格式或错误格式`]})]}),(0,U.jsx)(px,{className:`mt-1`,children:`建议删除后用可视化选择重新添加,避免后端解析异常。`})]}):null,(0,U.jsx)(vR,{device:r,isOpen:d,mappings:p,values:a,onApply:m,onOpenChange:f})]})})},xR=({disabled:e,itemLabel:t,device:n,value:r,onChange:i})=>(0,U.jsx)(bR,{disabled:e,device:n,itemLabel:t,value:r,onChange:i}),SR=({disabled:e,itemLabel:t,device:n,options:r,value:i,onChange:a})=>(0,U.jsx)(eR,{disabled:e,device:n,message:`开启【${t}】的推送开关后才能编辑此字段`,children:(0,U.jsxs)(c_,{"aria-label":`推送类型`,isDisabled:e,value:i,onChange:e=>a(e),children:[(0,U.jsx)(dx,{children:`推送类型`}),(0,U.jsx)(px,{children:`选择要推送的内容类型`}),(0,U.jsx)(`div`,{className:`mt-2 ${tR(n)}`,children:r.map(e=>(0,U.jsxs)(m_,{value:e.value,variant:`secondary`,children:[(0,U.jsxs)(m_.Content,{children:[(0,U.jsx)(m_.Control,{children:(0,U.jsx)(m_.Indicator,{})}),e.label]}),(0,U.jsx)(px,{children:e.description})]},e.value))})]})}),CR=({disabled:e,itemLabel:t,device:n,value:r,onChange:i})=>(0,U.jsx)(eR,{disabled:e,device:n,message:`开启【${t}】的推送开关后才能编辑此字段`,children:(0,U.jsxs)(Ax,{fullWidth:!0,isDisabled:e,value:r,onChange:e=>{e&&!Array.isArray(e)&&i(e)},children:[(0,U.jsx)(dx,{children:`过滤模式`}),(0,U.jsxs)(Ax.Trigger,{children:[(0,U.jsx)(Ax.Value,{}),(0,U.jsx)(Ax.Indicator,{})]}),(0,U.jsx)(px,{children:`设置关键词/标签的过滤方式`}),(0,U.jsx)(Ax.Popover,{children:(0,U.jsx)(wx,{children:iR.map(e=>(0,U.jsxs)(wx.Item,{id:e.value,textValue:e.label,children:[(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(dx,{children:e.label}),(0,U.jsx)(px,{children:e.description})]}),(0,U.jsx)(wx.ItemIndicator,{})]},e.value))})})]})}),wR=({disabled:e,itemLabel:t,device:n,keywords:r,tags:i,onKeywordsChange:a,onTagsChange:o})=>{let s=`开启【${t}】的推送开关后才能编辑此字段`;return(0,U.jsxs)(U.Fragment,{children:[(0,U.jsx)(eR,{disabled:e,device:n,message:s,children:(0,U.jsx)(`div`,{children:(0,U.jsx)(aR,{label:`关键词`,description:`多个关键词用于内容过滤`,disabled:e,items:r,onAdd:e=>a([...r,e]),onRemove:e=>a(r.filter(t=>t!==e))})})}),(0,U.jsx)(eR,{disabled:e,device:n,message:s,children:(0,U.jsx)(`div`,{children:(0,U.jsx)(aR,{label:`标签`,description:`多个标签用于内容过滤`,disabled:e,items:i,onAdd:e=>o([...i,e]),onRemove:e=>o(i.filter(t=>t!==e))})})})]})},TR=({onDelete:e})=>(0,U.jsxs)(Vg,{className:`w-full`,variant:`danger`,onPress:e,children:[(0,U.jsx)(Kj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`删除此推送项`})]}),ER=({item:e,index:t,list:n,onChange:r,device:i})=>{let a=i=>{let a=[...n];a[t]={...e,...i},r(a)},o=!e.switch,s=e.remark||`UID: ${e.host_mid}`||`未命名`,c=`开启【${s}】的推送开关后才能编辑此字段`;return(0,U.jsxs)(Fc.Item,{id:`bilibili-${t}`,children:[(0,U.jsx)(Fc.Heading,{children:(0,U.jsxs)(Fc.Trigger,{children:[(0,U.jsxs)(`div`,{className:`flex flex-1 items-center gap-3`,children:[(0,U.jsx)(`div`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:(0,U.jsx)(ob,{"aria-label":`推送开关`,isSelected:e.switch,onChange:e=>a({switch:e}),children:(0,U.jsx)(ob.Content,{children:(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})})})})}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(`span`,{className:`font-medium`,children:e.remark||`UID: ${e.host_mid}`||`推送项 ${t+1}`}),(0,U.jsxs)(px,{className:`text-xs`,children:[`B站 UID: `,e.host_mid]})]})]}),(0,U.jsx)(Fc.Indicator,{children:(0,U.jsx)(Pj,{className:`size-5`})})]})}),(0,U.jsx)(Fc.Panel,{children:(0,U.jsx)(Fc.Body,{children:(0,U.jsxs)(`div`,{className:`space-y-4`,children:[(0,U.jsxs)(`div`,{className:tR(i),children:[(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,isRequired:!0,type:`number`,value:String(e.host_mid),onChange:e=>a({host_mid:Number(e)||0}),children:[(0,U.jsx)(dx,{children:`B站 UID`}),(0,U.jsx)(cx,{placeholder:`UP主的 UID`}),(0,U.jsx)(px,{children:`B站用户的唯一标识,必填`})]})}),(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,value:e.remark,onChange:e=>a({remark:e}),children:[(0,U.jsx)(dx,{children:`备注名称`}),(0,U.jsx)(cx,{placeholder:`可选,用于识别该推送项`}),(0,U.jsx)(px,{children:`方便识别的名称,如:UP主昵称`})]})})]}),(0,U.jsx)(xR,{disabled:o,device:i,itemLabel:s,value:e.group_id,onChange:e=>a({group_id:e})}),(0,U.jsx)(SR,{disabled:o,device:i,itemLabel:s,options:rR,value:e.pushTypes||[],onChange:e=>a({pushTypes:e})}),(0,U.jsx)(CR,{disabled:o,device:i,itemLabel:s,value:e.filterMode||`blacklist`,onChange:e=>a({filterMode:e})}),(0,U.jsx)(wR,{disabled:o,device:i,itemLabel:s,keywords:e.Keywords||[],tags:e.Tags||[],onKeywordsChange:e=>a({Keywords:e}),onTagsChange:e=>a({Tags:e})}),(0,U.jsx)(TR,{onDelete:()=>r(n.filter((e,n)=>n!==t))})]})})})]},t)},DR=({item:e,index:t,list:n,onChange:r,device:i})=>{let a=i=>{let a=[...n];a[t]={...e,...i},r(a)},o=!e.switch,s=e.remark||e.short_id||e.sec_uid||`未命名`,c=`开启【${s}】的推送开关后才能编辑此字段`;return(0,U.jsxs)(Fc.Item,{id:`douyin-${t}`,children:[(0,U.jsx)(Fc.Heading,{children:(0,U.jsxs)(Fc.Trigger,{children:[(0,U.jsxs)(`div`,{className:`flex flex-1 items-center gap-3`,children:[(0,U.jsx)(`div`,{onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:(0,U.jsx)(ob,{"aria-label":`推送开关`,isSelected:e.switch,onChange:e=>a({switch:e}),children:(0,U.jsx)(ob.Content,{children:(0,U.jsx)(ob.Control,{children:(0,U.jsx)(ob.Thumb,{})})})})}),(0,U.jsxs)(`div`,{className:`flex flex-col gap-1`,children:[(0,U.jsx)(`span`,{className:`font-medium`,children:e.remark||e.short_id||e.sec_uid||`推送项 ${t+1}`}),(0,U.jsxs)(px,{className:`text-xs`,children:[e.short_id&&`抖音号: ${e.short_id}`,e.sec_uid&&!e.short_id&&`sec_uid: ${e.sec_uid.slice(0,20)}...`]})]})]}),(0,U.jsx)(Fc.Indicator,{children:(0,U.jsx)(Pj,{className:`size-5`})})]})}),(0,U.jsx)(Fc.Panel,{children:(0,U.jsx)(Fc.Body,{children:(0,U.jsxs)(`div`,{className:`space-y-4`,children:[(0,U.jsxs)(`div`,{className:tR(i),children:[(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,isRequired:!0,value:e.short_id,onChange:e=>a({short_id:e}),children:[(0,U.jsx)(dx,{children:`抖音号`}),(0,U.jsx)(cx,{placeholder:`用户的抖音号`,variant:`secondary`}),(0,U.jsx)(px,{children:`用户的抖音号(short_id),必填`})]})}),(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,value:e.sec_uid,onChange:e=>a({sec_uid:e}),children:[(0,U.jsx)(dx,{children:`sec_uid`}),(0,U.jsx)(cx,{placeholder:`选填,会根据抖音号自动获取`,variant:`secondary`}),(0,U.jsx)(px,{children:`用户的 sec_uid,可从分享链接获取。选填,推送时会自动获取`})]})})]}),(0,U.jsx)(eR,{disabled:o,device:i,message:c,children:(0,U.jsxs)(lx,{fullWidth:!0,isDisabled:o,value:e.remark,onChange:e=>a({remark:e}),children:[(0,U.jsx)(dx,{children:`备注名称`}),(0,U.jsx)(cx,{placeholder:`可选,用于识别该推送项`,variant:`secondary`}),(0,U.jsx)(px,{children:`方便识别的名称,如:博主昵称`})]})}),(0,U.jsx)(xR,{disabled:o,device:i,itemLabel:s,value:e.group_id,onChange:e=>a({group_id:e})}),(0,U.jsx)(SR,{disabled:o,device:i,itemLabel:s,options:nR,value:e.pushTypes||[],onChange:e=>a({pushTypes:e})}),(0,U.jsx)(CR,{disabled:o,device:i,itemLabel:s,value:e.filterMode||`blacklist`,onChange:e=>a({filterMode:e})}),(0,U.jsx)(wR,{disabled:o,device:i,itemLabel:s,keywords:e.Keywords||[],tags:e.Tags||[],onKeywordsChange:e=>a({Keywords:e}),onTagsChange:e=>a({Tags:e})}),(0,U.jsx)(TR,{onDelete:()=>r(n.filter((e,n)=>n!==t))})]})})})]},t)},OR=()=>({switch:!0,sec_uid:``,short_id:``,group_id:[],remark:``,pushTypes:[`post`],filterMode:`blacklist`,Keywords:[],Tags:[]}),kR=()=>({switch:!0,host_mid:0,group_id:[],remark:``,pushTypes:[`video`],filterMode:`blacklist`,Keywords:[],Tags:[]}),AR=({platform:e})=>(0,U.jsx)(`div`,{className:`rounded-lg border-2 border-dashed border-gray-300 p-8 text-center`,children:(0,U.jsxs)(`p`,{className:`text-muted`,children:[`暂无`,e===`douyin`?`抖音`:`B站`,`推送项,点击上方按钮添加`]})});function jR({douyinList:e,bilibiliList:t,onDouyinChange:n,onBilibiliChange:r,device:i}){let[a,o]=(0,v.useState)(`douyin`);return(0,U.jsx)(`div`,{className:`space-y-4`,children:(0,U.jsxs)(kb,{selectedKey:a,onSelectionChange:e=>o(e),children:[(0,U.jsx)(kb.ListContainer,{children:(0,U.jsxs)(kb.List,{children:[(0,U.jsxs)(kb.Tab,{id:`douyin`,children:[(0,U.jsx)(`span`,{children:`抖音推送`}),(0,U.jsx)(kb.Indicator,{})]}),(0,U.jsxs)(kb.Tab,{id:`bilibili`,children:[(0,U.jsx)(`span`,{children:`B站推送`}),(0,U.jsx)(kb.Indicator,{})]})]})}),(0,U.jsx)(kb.Panel,{id:`douyin`,children:(0,U.jsxs)(`div`,{className:`space-y-4 pt-4`,children:[(0,U.jsxs)(Vg,{className:`w-full`,variant:`primary`,size:`sm`,onPress:()=>n([...e,OR()]),children:[(0,U.jsx)(Hj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`添加抖音推送项`})]}),e.length>0?(0,U.jsx)(Fc,{variant:`surface`,"aria-label":`抖音推送列表`,children:e.map((t,r)=>(0,U.jsx)(DR,{device:i,index:r,item:t,list:e,onChange:n},r))}):(0,U.jsx)(AR,{platform:`douyin`})]})}),(0,U.jsx)(kb.Panel,{id:`bilibili`,children:(0,U.jsxs)(`div`,{className:`space-y-4 pt-4`,children:[(0,U.jsxs)(Vg,{className:`w-full`,variant:`primary`,onPress:()=>r([...t,kR()]),children:[(0,U.jsx)(Hj,{className:`size-4`}),(0,U.jsx)(`span`,{children:`添加B站推送项`})]}),t.length>0?(0,U.jsx)(Fc,{variant:`surface`,"aria-label":`B站推送列表`,children:t.map((e,n)=>(0,U.jsx)(ER,{device:i,index:n,item:e,list:t,onChange:r},n))}):(0,U.jsx)(AR,{platform:`bilibili`})]})})]})})}var MR=({config:e,device:t,renderers:n,updateConfigValue:r})=>{let{renderPageHeader:i}=n;return(0,U.jsxs)(U.Fragment,{children:[i(`推送列表`,`管理「抖音」与「哔哩哔哩」的推送订阅。`),(0,U.jsx)(jR,{douyinList:e.pushlist?.douyin||[],bilibiliList:e.pushlist?.bilibili||[],onDouyinChange:e=>{r([`pushlist`,`douyin`],e)},onBilibiliChange:e=>{r([`pushlist`,`bilibili`],e)},device:t})]})},NR=({config:e,renderers:t,classes:n})=>{let{renderCheckboxGroup:r,renderPageHeader:i,renderSelectField:a,renderSubSection:o,renderSwitch:s,renderTextField:c}=t,l=Q(e,[`xiaohongshu`,`switch`],!1),u=Q(e,[`xiaohongshu`,`sendContent`],[]),d=Q(e,[`xiaohongshu`,`videoQuality`],`adapt`);return(0,U.jsxs)(U.Fragment,{children:[i(`小红书`,`小红书解析基础设置。`),(0,U.jsxs)(`div`,{className:n.topLevelFields,"data-config-section":!0,children:[s([`xiaohongshu`,`switch`],`解析开关`,`小红书解析开关,此开关为单独开关。`),r([`xiaohongshu`,`sendContent`],`解析时发送的内容`,`若什么都不选,可能不会返回任何解析结果。`,jL,!l),c([`xiaohongshu`,`numcomment`],`评论解析数量`,`小红书评论解析数量。`,{type:`number`,fallback:5,min:1,disabled:!l||!_L(u,`comment`)})]}),/*KKK-FORWARD-START*/t.renderSubSection(`合并转发`,(0,U.jsxs)(U.Fragment,{children:[t.renderSwitch([`xiaohongshu`,`forward`],`合并转发(小红书)`,`本平台单独打开合并转发。**全局优先**:通用里的「解析结果合并转发」打开时,所有平台都会合并(这里开不开都一样);只有全局关着时这个开关才起作用。默认关闭。`),t.renderCheckboxGroup([`xiaohongshu`,`forwardContent`],`合并转发内容`,`合并转发里包含哪些内容:没勾选的内容会**单独直发**,不进转发节点。留空 = 用通用里那份全局设置。提示:视频体积大时有些适配器(如 NapCat)会拒绝整个转发节点,这时会自动改成单独发送,不会丢内容。`,[{value:`text`,label:`文字`},{value:`image`,label:`图片`},{value:`video`,label:`视频`},{value:`file`,label:`文件`}])]}))/*KKK-FORWARD-END*/,,,,,,,o(`渲染与画质设置`,(0,U.jsxs)(U.Fragment,{children:[a([`xiaohongshu`,`videoQuality`],`画质偏好`,`解析视频的分辨率偏好。`,NL,e=>e,!l),c([`xiaohongshu`,`maxAutoVideoSize`],`视频体积上限(MB)`,`根据该值自动选择分辨率进行下载。仅在「画质偏好」 为 "自动选择" 时生效。`,{type:`number`,fallback:50,min:1,max:2e4,disabled:!l||d!==`adapt`})]}))]})},/*KKK-QQ-START*/KKKQQConfig=({config:e,renderers:t})=>{let{renderPageHeader:n,renderSubSection:r,renderSwitch:i,renderTextField:a}=t;return(0,U.jsxs)(U.Fragment,{children:[n(`QQ 适配器`,`这些设置只对 QQ 平台生效,其它平台不受影响。改完点右下角保存即可,不用重启。`),r(`解析面板`,(0,U.jsx)(U.Fragment,{children:[i([`qq`,`qqPanel`],`链接解析面板`,`QQ 里收到链接时先回一条带按钮的面板,让用户自己挑解析内容和画质,点一下才开始下载。关掉就直接按默认配置解析。`),a([`qq`,`qqFileLimitMB`],`画质档体积上限(MB)`,`面板里「清晰度」(= 发到 QQ)这一列的体积上限:超过它的画质档不给发送按钮,那一格标「超上限」。QQ 单个视频上限 200MB,选了也发不出去,所以默认 200。**在线播放模式下画质档位不再按这个值过滤**:视频根本不发到 QQ,所有档位都会列出来,超过这个值的档位只是不能发到 QQ,右边的「在线看」照常可用(它受「在线播放最大文件」约束)。`,{type:`number`,fallback:200,min:1,max:2000}),i([`qq`,`qqPanelDanmaku`],`面板显示「烧录弹幕」列`,`只对**烧录模式**生效(通用里把「弹幕重定向在线播放器」关掉之后):打开后,QQ 里的解析面板会多一列「烧录弹幕」,用户点它就按那一档画质把弹幕烧进视频再发。在线播放模式下那一列由「弹幕重定向在线播放器」自己控制(开着就有),不需要在这里开。`),i([`qq`,`qqPanelSourceLink`],`面板带「打开原站」链接`,`打开后,解析面板(以及番剧选集面板)的下方会多一个「打开原站」按钮,点一下直接跳到抖音 / B站的原作品页;关掉就不显示。`)]})),r(`番剧选集面板`,(0,U.jsx)(U.Fragment,{children:[a([`qq`,`bangumiPanelCols`],`表格列数`,`番剧分集面板每行放几个集数,默认 5。`,{type:`number`,fallback:5,min:1,max:10}),a([`qq`,`bangumiPanelRows`],`表格行数`,`番剧分集面板每页几行(含表头那一行),默认 4 行。列数 × 行数就是每页的集数。`,{type:`number`,fallback:4,min:1,max:10})]})),r(`图片发送`,(0,U.jsx)(U.Fragment,{children:[i([`qq`,`sliceImageOnDemand`],`超大图片自动切片`,`长图(评论区那种)默认按普通图片发;只有超过 20MB 或者发送失败(拿不到消息 ID)时才自动切成几片,再用一条 markdown 拼回一整张。关掉就一律按普通图片发。`),a([`qq`,`sliceImageHeight`],`切片高度(像素)`,`切片时每片的高度,默认 2000。越大片数越少、字越小;越小越清晰、片数越多。`,{type:`number`,fallback:2000,min:500,max:4000})]})),r(`卡片识别`,(0,U.jsx)(U.Fragment,{children:[a([`qq`,`ocrApiKey`],`卡片文字识别密钥`,`群里转发过来的分享卡片没有链接,只能靠截图识别出标题和作者再去搜索。填自己的免费密钥更稳定:https://ocr.space/ocrapi 。留空会用公共测试密钥,容易被限流。`,{type:`password`,placeholder:`留空则使用公共测试密钥`})]})),r(`视频发送`,(0,U.jsx)(U.Fragment,{children:[a([`qq`,`qqGroupFileLimitMB`],`群文件发送阈值(MB)`,`视频体积超过这个值时,改用「群文件」发送。QQ 对富媒体视频会压缩、改名甚至丢掉后缀,走群文件才能原样发出去;填 0 表示不启用。`,{type:`number`,fallback:30,min:0,max:2000})]}))]})}/*KKK-QQ-END*/,PR=e=>{switch(e.activeFile){case`amagi`:return(0,U.jsx)(YL,{...e});case`app`:return(0,U.jsx)(XL,{...e});case`douyin`:return(0,U.jsx)(QL,{...e});case`bilibili`:return(0,U.jsx)(ZL,{...e});case`kuaishou`:return(0,U.jsx)($L,{...e});case`xiaohongshu`:return(0,U.jsx)(NR,{...e});case`pushlist`:return(0,U.jsx)(MR,{...e});case`qq`:return(0,U.jsx)(KKKQQConfig,{...e})}},FR=(e,t)=>{let n=Number(e);return Number.isFinite(n)?t.min!==void 0&&n<t.min?t.error||`${t.label} 不能小于 ${t.min}`:t.max!==void 0&&n>t.max?t.error||`${t.label} 不能大于 ${t.max}`:``:`${t.label} 必须是数字`},IR=(e,t,n)=>{if(n.disabled)return;let r=FR(Q(t,n.path,0),n);r&&(e[pL(n.path)]=r)},LR=e=>typeof e==`string`&&/.+:.+/.test(e),RR=(e,t,n)=>{if(!Array.isArray(n)){e[`pushlist.${t}`]=`${t} 推送列表必须是数组`;return}let r=n.findIndex(e=>{if(!mL(e))return!0;let n=e.group_id,r=t===`douyin`?e.short_id:e.host_mid;return r==null||String(r).trim()===``||!Array.isArray(n)||n.length===0||n.some(e=>!LR(e))});r>=0&&(e[`pushlist.${t}`]=`${t} 推送列表第 ${r+1} 项缺少必填 UID/抖音号,或 group_id 未使用「群号:机器人账号」格式`)},zR=e=>{if(!e)return{};let t={},n=Q(e,[`app`,`livePhotoMode`],`video_and_livephoto`),r=Q(e,[`amagi`,`APIServerMount`],!1),i=Q(e,[`app`,`videoSendMode`],`file`),a=Q(e,[`app`,`usegroupfile`],!1),o=Q(e,[`app`,`usefilelimit`],!1),s=Q(e,[`app`,`compress`],!1),c=Q(e,[`app`,`downloadThrottle`],!1),l=Q(e,[`app`,`downloadAutoReduce`],!1),u=Q(e,[`amagi`,`proxy`,`switch`],!1),d=Q(e,[`douyin`,`switch`],!1),f=Q(e,[`douyin`,`sendContent`],[]),p=Q(e,[`douyin`,`burnDanmaku`],!1),m=Q(e,[`douyin`,`videoQuality`],`adapt`),h=Q(e,[`douyin`,`push`,`switch`],!1),g=Q(e,[`douyin`,`push`,`pushVideoQuality`],`adapt`),_=Q(e,[`bilibili`,`switch`],!1),v=Q(e,[`bilibili`,`sendContent`],[]),y=Q(e,[`bilibili`,`burnDanmaku`],!1),b=Q(e,[`bilibili`,`videoQuality`],0),x=Q(e,[`bilibili`,`push`,`switch`],!1),S=Q(e,[`bilibili`,`push`,`parsedynamic`],!1),C=Q(e,[`bilibili`,`push`,`pushVideoQuality`],0),w=Q(e,[`kuaishou`,`switch`],!1),T=Q(e,[`kuaishou`,`comment`],!1),E=Q(e,[`xiaohongshu`,`switch`],!1),D=Q(e,[`xiaohongshu`,`sendContent`],[]),O=Q(e,[`xiaohongshu`,`videoQuality`],`adapt`);return[{path:[`app`,`renderScale`],label:`渲染精度`,min:50,max:200},{path:[`app`,`ambientCover`,`coverOpacity`],label:`封面氛围强度`,min:0,max:1},{path:[`app`,`ambientCover`,`overlayEdgeOpacity`],label:`氛围压色(顶部/底部)`,min:0,max:1},{path:[`app`,`ambientCover`,`overlayMiddleOpacity`],label:`氛围压色(中间带)`,min:0,max:1},{path:[`app`,`RenderWaitTime`],label:`渲染图片的等待时间`,min:0},{path:[`app`,`multiPageHeight`],label:`分页渲染时,每页的高度`,min:1e3,max:2e4,disabled:!Q(e,[`app`,`multiPageRender`],!0),error:`请输入一个范围在 1000 到 20000 之间的数字`},{path:[`amagi`,`APIServerPort`],label:`API服务端口`,min:1024,max:65535,disabled:r,error:`请输入一个范围在 1024 到 65535 之间的数字`},{path:[`app`,`groupfilevalue`],label:`群文件上传阈值`,min:1,disabled:!a||i===`base64`},{path:[`app`,`filelimit`],label:`视频拦截阈值`,min:1,disabled:!o},{path:[`app`,`compresstrigger`],label:`压缩触发阈值`,min:1,disabled:!s},{path:[`app`,`compressvalue`],label:`压缩后的值`,min:1,disabled:!s},{path:[`app`,`downloadMaxSpeed`],label:`最大下载速度`,min:1,max:1e3,disabled:!c,error:`请输入一个范围在 1 到 1000 之间的数字`},{path:[`app`,`downloadMinSpeed`],label:`最低下载速度`,min:.1,max:100,disabled:!c||!l,error:`请输入一个范围在 0.1 到 100 之间的数字`},{path:[`amagi`,`timeout`],label:`请求超时时间`,min:1e3,max:3e5,error:`请输入一个范围在 1000 到 300000 之间的数字`},{path:[`amagi`,`proxy`,`port`],label:`代理端口`,min:1,max:65535,disabled:!u,error:`请输入一个范围在 1 到 65535 之间的数字`},{path:[`douyin`,`numcomment`],label:`评论解析数量`,min:1,disabled:!d||!_L(f,`comment`)},{path:[`douyin`,`subCommentLimit`],label:`次级评论解析数量`,min:1,max:20,disabled:!d||!_L(f,`comment`)},{path:[`douyin`,`maxAutoVideoSize`],label:`视频体积上限(MB)`,min:1,max:2e4,disabled:!d||m!==`adapt`},{path:[`douyin`,`danmakuOpacity`],label:`弹幕透明度`,min:0,max:100,disabled:!d||!p},{path:[`douyin`,`push`,`pushMaxAutoVideoSize`],label:`推送视频体积上限(MB)`,min:1,max:2e4,disabled:!h||g!==`adapt`},{path:[`bilibili`,`numcomment`],label:`评论解析数量`,min:1,disabled:!_||!_L(v,`comment`)},{path:[`bilibili`,`maxAutoVideoSize`],label:`视频体积上限(MB)`,min:1,max:2e4,disabled:!_||Number(b)!==0},{path:[`bilibili`,`danmakuOpacity`],label:`弹幕透明度`,min:0,max:100,disabled:!_||!y},{path:[`bilibili`,`push`,`pushMaxAutoVideoSize`],label:`视频动态的视频体积上限(MB)`,min:1,max:2e4,disabled:!x||!S||Number(C)!==0},{path:[`kuaishou`,`numcomment`],label:`评论解析数量`,min:1,disabled:!w||!T},{path:[`xiaohongshu`,`numcomment`],label:`评论解析数量`,min:1,disabled:!E||!_L(D,`comment`)},{path:[`xiaohongshu`,`maxAutoVideoSize`],label:`视频体积上限(MB)`,min:1,max:2e4,disabled:!E||O!==`adapt`}].forEach(n=>IR(t,e,n)),n===`video_only`&&delete t[`app.livePhotoSystem`],RR(t,`douyin`,e.pushlist?.douyin||[]),RR(t,`bilibili`,e.pushlist?.bilibili||[]),t},BR=({device:e=`desktop`})=>{let t=(0,v.useRef)(null),[n,r]=JT(),i=Px(),a=n.get(`file`),[o,s]=GS({config:null,savedConfig:null,activeFile:a&&HL.some(e=>e.key===a)?a:`amagi`}),{activeFile:c,config:l,savedConfig:u}=o,d=(0,v.useMemo)(()=>JL(e),[e]),f=e===`mobile`?`sm`:`md`,{loading:p,run:m}=HS(iI,{onSuccess:e=>{s({config:structuredClone(e),savedConfig:structuredClone(e)})},onError:e=>{Ny.danger(`加载配置失败`,{description:e.message})}}),{loading:h,runAsync:g}=HS(aI,{manual:!0}),_=(0,v.useMemo)(()=>!l||!u?!1:!(0,mE.default)(yL(l),yL(u)),[l,u]),y=(0,v.useMemo)(()=>zR(l),[l]),b=(0,v.useMemo)(()=>Object.values(y).some(Boolean),[y]),x=(0,v.useMemo)(()=>_&&!b&&!p,[_,b,p]),S=Ux((e,t)=>{s(n=>n.config?{config:hL(n.config,e,t)}:null)}),C=Ux(()=>{if(!l||b)return;let e=l,t=g(e).then(()=>{s({savedConfig:e})});Ny.promise(t,{loading:`正在保存配置...`,success:`配置已保存`,error:e=>e instanceof Error?e.message:`保存配置失败`})}),w=Ux(()=>{m()}),T=Ux(e=>{r({file:e})}),E=Ux(e=>{e.preventDefault(),C()});(0,v.useEffect)(()=>{let e=n.get(`file`);e&&HL.some(t=>t.key===e)&&e!==c&&s({activeFile:e})},[n,c,s]),(0,v.useEffect)(()=>{let e=t.current?.querySelector(`[data-config-tabs-scroll="true"]`);if(!e)return;let n=t=>{let n=Math.abs(t.deltaX)>Math.abs(t.deltaY)?t.deltaX:t.deltaY;n&&(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),!(e.scrollWidth<=e.clientWidth)&&(e.scrollLeft+=n))};return e.addEventListener(`wheel`,n,{passive:!1}),()=>{e.removeEventListener(`wheel`,n)}},[l]);let D=Ux(()=>{t.current&&Sj.fromTo(t.current.querySelectorAll(`[data-config-section]`),uI,{...dI,duration:sI(.35),stagger:cI(.03)})});(0,v.useEffect)(()=>{!l||t.current?.dataset.animated===`true`||(t.current&&(t.current.dataset.animated=`true`),D())},[l,D]),Wx(()=>{D()},[c]);let O=(0,v.useMemo)(()=>l?GL({config:l,device:e,classes:d,validationErrors:y,updateConfigValue:S}):{},[l,e,d,y,S]);if(p||!l)return(0,U.jsxs)(`div`,{className:`${d.root} ${d.loading}`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在读取配置`}),(0,U.jsx)(`span`,{children:`正在读取配置`})]});let k=(0,U.jsx)(`div`,{className:d.floatingActions,children:(0,U.jsxs)(`div`,{className:d.actionControls,children:[(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{"aria-label":`重新读取配置`,children:(0,U.jsx)(Vg,{isIconOnly:!0,size:f,variant:`secondary`,isDisabled:p||h,onPress:w,children:(0,U.jsx)(Uj,{size:16,"aria-hidden":`true`})})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`bottom`,children:[(0,U.jsx)(tx.Arrow,{}),`重新读取`]})]}),(0,U.jsxs)(tx,{delay:0,children:[(0,U.jsx)(tx.Trigger,{"aria-label":`查看配置变更`,children:(0,U.jsx)(Vg,{isIconOnly:!0,size:f,variant:`secondary`,isDisabled:!_,onPress:i.open,children:(0,U.jsx)(Lj,{size:16,"aria-hidden":`true`})})}),(0,U.jsxs)(tx.Content,{showArrow:!0,placement:`bottom`,children:[(0,U.jsx)(tx.Arrow,{}),`查看变更`]})]}),(0,U.jsxs)(Vg,{size:f,isDisabled:!x,isPending:h,onPress:C,variant:`primary`,children:[(0,U.jsx)(Wj,{size:16,"aria-hidden":`true`}),(0,U.jsx)(`span`,{children:`保存`})]})]})});return(0,U.jsxs)(`div`,{ref:t,className:d.root,children:[(0,U.jsx)(TL,{device:e,original:u,current:l,isOpen:i.isOpen,onOpenChange:i.setOpen}),(0,U.jsxs)(_x,{className:d.form,onSubmit:E,children:[(0,U.jsx)(kb,{className:`w-full min-w-0 max-w-full`,selectedKey:c,onSelectionChange:T,children:(0,U.jsx)(kb.ListContainer,{className:d.tabsListContainer,"data-config-tabs-scroll":`true`,"data-scrollbar":`none`,children:(0,U.jsx)(kb.List,{"aria-label":`配置文件选择`,className:d.tabsList,children:HL.map((e,t)=>(0,U.jsxs)(kb.Tab,{id:e.key,children:[t>0?(0,U.jsx)(kb.Separator,{}):null,(0,U.jsx)(`span`,{className:`whitespace-nowrap`,children:e.label}),(0,U.jsx)(kb.Indicator,{})]},e.key))})})}),(0,U.jsxs)(`div`,{className:`relative min-w-0 max-w-full`,children:[k,(0,U.jsx)(PR,{activeFile:c,classes:d,config:l,device:e,renderers:O,updateConfigValue:S},c)]})]})]})},VR=({onLogin:e})=>{let[t,n]=GS({authKey:``,loading:!1,error:``}),[r,{toggle:i}]=WS(!1),a=r?`隐藏密钥`:`显示密钥`,o=Ux(async r=>{r.preventDefault();let i=t.authKey.trim();if(!i){n({error:`请输入 Koishi HTTP 鉴权密钥`});return}try{n({loading:!0,error:``}),await tI(i),e()}catch(e){n({error:e instanceof Error?e.message:`登录失败`})}finally{n({loading:!1})}});return(0,U.jsx)(Ev,{className:`flex min-h-screen items-center justify-center px-4 py-8`,children:(0,U.jsxs)(Wg,{className:`w-full max-w-105`,children:[(0,U.jsxs)(Wg.Header,{className:`gap-4 p-6`,children:[(0,U.jsx)(zj,{className:`size-8 shrink-0`,"aria-hidden":`true`}),(0,U.jsxs)(`div`,{className:`min-w-0`,children:[(0,U.jsx)(Wg.Title,{children:`Koishi 鉴权`}),(0,U.jsx)(Wg.Description,{children:`使用 Koishi HTTP 鉴权密钥登录后管理 KKK 配置。`})]})]}),(0,U.jsx)(Wg.Content,{className:`p-6`,children:(0,U.jsxs)(_x,{className:`flex flex-col gap-6`,onSubmit:o,children:[(0,U.jsxs)(lx,{fullWidth:!0,isInvalid:!!t.error,value:t.authKey,onChange:e=>{n({authKey:e,error:t.error?``:t.error})},children:[(0,U.jsx)(dx,{children:`HTTP 鉴权密钥`}),(0,U.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,U.jsx)(cx,{autoComplete:`current-password`,className:`min-w-0 flex-1`,placeholder:`请输入 Koishi 的 HTTP_AUTH_KEY`,type:r?`text`:`password`}),(0,U.jsx)(Vg,{isIconOnly:!0,"aria-label":a,type:`button`,variant:`tertiary`,onPress:i,children:r?(0,U.jsx)(Fj,{className:`size-4`,"aria-hidden":`true`}):(0,U.jsx)(Ij,{className:`size-4`,"aria-hidden":`true`})})]}),(0,U.jsx)(px,{children:t.error||`生产环境会复用 Koishi 主 Web 已保存的登录凭据。`})]}),(0,U.jsx)(Vg,{fullWidth:!0,isPending:t.loading,type:`submit`,children:({isPending:e})=>(0,U.jsxs)(U.Fragment,{children:[e?(0,U.jsx)(Tv,{color:`current`,size:`sm`,"aria-label":`登录中`}):(0,U.jsx)(Bj,{className:`size-4`,"aria-hidden":`true`}),(0,U.jsx)(`span`,{children:`登录`})]})})]})})]})})},HR=`theme`,UR=`kkk-theme-changed`,WR=`karin-theme-change`,GR={light:`light`,dark:`dark`,system:`system`,inverse:`inverse`},KR=e=>e===GR.system||e===GR.inverse,qR=e=>e===GR.light||e===GR.dark,JR=e=>!e||typeof e!=`object`?!1:e.type===WR,YR=()=>{let e=localStorage.getItem(HR);if(KR(e))return e;try{let t=JSON.parse(e??``);if(KR(t))return t}catch{}return localStorage.setItem(HR,GR.system),GR.system},XR=()=>window.matchMedia(`(prefers-color-scheme: dark)`).matches?GR.dark:GR.light,ZR=()=>window.matchMedia(`(prefers-color-scheme: dark)`).matches?GR.light:GR.dark,QR=e=>e===GR.system?XR():ZR(),$R=e=>ez(QR(e)),ez=e=>(document.documentElement.classList.remove(GR.light,GR.dark),document.documentElement.classList.add(e),document.documentElement.dataset.theme=e,e),tz=()=>{let[e,t]=(0,v.useState)(()=>YR()),[n,r]=(0,v.useState)(()=>QR(e)),i=(0,v.useRef)(!1),a=(0,v.useCallback)(e=>{localStorage.setItem(HR,e),t(e),r($R(e)),window.dispatchEvent(new CustomEvent(UR,{detail:e}))},[]),o=(0,v.useCallback)(()=>{a(GR.system)},[a]),s=(0,v.useCallback)(()=>{a(GR.inverse)},[a]),c=(0,v.useCallback)(()=>{a(e===GR.system?GR.inverse:GR.system)},[a,e]);return(0,v.useEffect)(()=>{i.current?i.current=!1:r($R(e));let n=window.matchMedia(`(prefers-color-scheme: dark)`),a=()=>{r($R(e))},o=e=>{if(e.key!==HR||window.self!==window.top)return;let n=YR();t(n),r($R(n))},s=e=>{let n=e.detail;KR(n)&&(t(n),r($R(n)))},c=e=>{if(!JR(e.data))return;let n=e.data.theme,a=KR(n??null)?n:YR(),o=qR(e.data.appliedTheme)?e.data.appliedTheme:QR(a);i.current=!0,localStorage.setItem(HR,a),t(a),r(ez(o))};return n.addEventListener(`change`,a),window.addEventListener(`storage`,o),window.addEventListener(UR,s),window.addEventListener(`message`,c),()=>{n.removeEventListener(`change`,a),window.removeEventListener(`storage`,o),window.removeEventListener(UR,s),window.removeEventListener(`message`,c)}},[e]),{theme:e,appliedTheme:n,isDark:(0,v.useMemo)(()=>n===GR.dark,[n]),isLight:(0,v.useMemo)(()=>n===GR.light,[n]),isSystem:e===GR.system,isInverse:e===GR.inverse,setSystemTheme:o,setInverseTheme:s,toggleTheme:c}},nz=()=>document.documentElement.clientWidth||window.innerWidth,rz=(e=nz())=>e<=768?`mobile`:`desktop`,iz=()=>{let e=navigator.userAgent.toLowerCase();return[`android`,`webos`,`iphone`,`ipad`,`ipod`,`blackberry`,`windows phone`,`mobile`].some(t=>e.includes(t))},az=()=>{let e=rz();return iz()||e===`mobile`?`mobile`:`desktop`},oz=()=>YS(()=>import(`./DesktopLayout-iI43ij11.js`),__vite__mapDeps([2,1,3])),sz=()=>YS(()=>import(`./MobileLayout-CziU8MCR.js`),__vite__mapDeps([4,3])),cz={config:`/kkk/assets/config`,about:`/kkk/assets/about`},lz={"/kkk/assets/config":`config`,"/kkk/assets/about":`about`},uz=({device:e})=>(0,U.jsxs)(Ev,{className:`h-screen overflow-hidden bg-background`,children:[(0,U.jsx)(qy.Provider,{placement:`top`}),(0,U.jsx)(bv,{hideScrollBar:!0,className:`h-full px-3 py-3 sm:px-5 sm:py-4 ${e===`mobile`?`data-[top-scroll=true]:mask-none data-[top-scroll=true]:[-webkit-mask-image:none] data-[top-bottom-scroll=true]:mask-[linear-gradient(180deg,black_calc(100%-var(--scroll-shadow-size)),transparent)] data-[top-bottom-scroll=true]:[-webkit-mask-image:linear-gradient(180deg,black_calc(100%-var(--scroll-shadow-size)),transparent)]`:``}`,size:56,children:(0,U.jsx)(BR,{device:e})})]}),dz=({LayoutComponent:e})=>{let t=vw(),n=xw(),r=lz[t.pathname]||`config`,i=Ux(e=>{n(cz[e])});return e?(0,U.jsxs)(`div`,{children:[(0,U.jsx)(qy.Provider,{placement:`top`}),(0,U.jsx)(e,{activeMenu:r,onMenuChange:i})]}):(0,U.jsxs)(Ev,{className:`flex min-h-screen items-center justify-center gap-4`,children:[(0,U.jsx)(Tv,{size:`sm`,"aria-label":`正在加载布局`}),(0,U.jsx)(px,{children:`正在加载`})]})},fz=()=>{tz();let[e,t]=GS({authenticated:uE(),device:az(),LayoutComponent:null}),{authenticated:n,device:r,LayoutComponent:i}=e;(0,v.useEffect)(()=>{let e=()=>{t({authenticated:uE()})};return window.addEventListener(oE,e),window.addEventListener(`storage`,e),()=>{window.removeEventListener(oE,e),window.removeEventListener(`storage`,e)}},[t]);let a=Ux(()=>{let e=az();t(t=>t.device===e?null:{device:e,LayoutComponent:null})});(0,v.useEffect)(()=>{let e=0,t=()=>{window.cancelAnimationFrame(e),e=window.requestAnimationFrame(a)};return window.addEventListener(`resize`,t),window.addEventListener(`orientationchange`,t),()=>{window.cancelAnimationFrame(e),window.removeEventListener(`resize`,t),window.removeEventListener(`orientationchange`,t)}},[a]),(0,v.useEffect)(()=>{if(!n){t({LayoutComponent:null});return}let e=!1;return(async()=>{if(r===`mobile`){let n=await sz();e||t({LayoutComponent:n.default})}else{let n=await oz();e||t({LayoutComponent:n.default})}})(),()=>{e=!0}},[n,r,t]);let o=Ux(()=>{t({authenticated:!0})});return n?(0,U.jsxs)(Yw,{children:[(0,U.jsx)(qw,{path:`/kkk/assets/karin-config`,element:(0,U.jsx)(uz,{device:r})}),(0,U.jsx)(qw,{path:`/kkk/assets/config`,element:(0,U.jsx)(dz,{LayoutComponent:i})}),(0,U.jsx)(qw,{path:`/kkk/assets/about`,element:(0,U.jsx)(dz,{LayoutComponent:i})}),(0,U.jsx)(qw,{path:`/kkk/assets`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})}),(0,U.jsx)(qw,{path:`/kkk`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})}),(0,U.jsx)(qw,{path:`/kkk/login`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})}),(0,U.jsx)(qw,{path:`*`,element:(0,U.jsx)(Kw,{to:`/kkk/assets/config`,replace:!0})})]}):(0,U.jsxs)(Yw,{children:[(0,U.jsx)(qw,{path:`/kkk/login`,element:(0,U.jsx)(VR,{onLogin:o})}),(0,U.jsx)(qw,{path:`*`,element:(0,U.jsx)(Kw,{to:`/kkk/login`,replace:!0})})]})};(0,y.createRoot)(document.getElementById(`root`)).render((0,U.jsx)(v.StrictMode,{children:(0,U.jsx)(()=>(0,U.jsx)(RT,{children:(0,U.jsx)(fz,{})}),{})}));export{Rs as $,hm as A,Le as At,rd as B,l as Bt,Wg as C,wt as Ct,jh as D,H as Dt,Ph as E,rt as Et,_f as F,E as Ft,Y as G,Vl as H,gf as I,M as It,tc as J,J as K,pf as L,O as Lt,om as M,ke as Mt,am as N,we as Nt,Sm as O,V as Ot,vf as P,R as Pt,qs as Q,df as R,h as Rt,Jg as S,kt as St,Ig as T,at as Tt,kc as U,ed as V,Ac as W,ec as X,nc as Y,Js as Z,gv as _,ga as _t,pE as a,Do as at,b_ as b,Yt as bt,Ax as c,q as ct,dx as d,Ja as dt,Es as et,lx as f,Qa as ft,Ev as g,ma as gt,kb as h,Xa as ht,Sj as i,Mo as it,sm as j,B as jt,mm as k,He as kt,wx as l,qa as lt,tx as m,$a as mt,BR as n,cs as nt,WS as o,wo as ot,cx as p,K as pt,sc as q,Mj as r,jo as rt,Ux as s,yo as st,tz as t,Ss as tt,px as u,Za as ut,pv as v,nn as vt,Vg as w,st as wt,S_ as x,Zt as xt,C_ as y,$t as yt,lf as z,d as zt};
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.errorHelpSegments = exports.uploadErrorReport = exports.groupLinkOf = exports.
|
|
6
|
+
exports.errorHelpSegments = exports.uploadErrorReport = exports.groupLinkOf = exports.REPORT_LOG_LINES = exports.REPORT_GROUP = exports.REPORT_TOKEN = exports.REPORT_URL = void 0;
|
|
7
7
|
exports.reportConfig = reportConfig;
|
|
8
8
|
/**
|
|
9
9
|
* 错误上报。
|
|
@@ -25,37 +25,50 @@ const runtime_1 = require("../../../compat/runtime");
|
|
|
25
25
|
const qqOptions_1 = require("../../../qqOptions");
|
|
26
26
|
const root_1 = require("../../root");
|
|
27
27
|
const build_metadata_1 = require("./build-metadata");
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
/**
|
|
29
|
+
* 收集站地址:**写死,不开放配置**。
|
|
30
|
+
* 自建的人改这一行重新构建即可 —— 面板里只留「是否上传」一个开关,少一个能填错的地方。
|
|
31
|
+
*/
|
|
32
|
+
exports.REPORT_URL = 'https://err.tangbot.xyz';
|
|
33
|
+
/**
|
|
34
|
+
* 上报令牌:**写死**。
|
|
35
|
+
* 服务端 \`KKK_ERR_TOKEN\` 的默认值就是它,所以两边开箱即用、什么都不用配。
|
|
36
|
+
* 它写在开源插件里,等于公开 —— 服务端那边另有 IP 限流兜着,挡的是随机刷接口的流量。
|
|
37
|
+
*/
|
|
38
|
+
exports.REPORT_TOKEN = 'kkk-err-9f3c1d7a5b2e4c80';
|
|
39
|
+
/** 反馈群:写死(QQ 客户端点群链接就能进) */
|
|
40
|
+
exports.REPORT_GROUP = '1050229473';
|
|
41
|
+
/** 上报多少行日志:写死(本次请求的日志 + 宿主日志文件尾部各取这么多行) */
|
|
42
|
+
exports.REPORT_LOG_LINES = 200;
|
|
43
|
+
/**
|
|
44
|
+
* 上传超时(毫秒):超了就放弃,不拖住错误卡片。
|
|
45
|
+
*
|
|
46
|
+
* 上报是**在渲染错误卡片之前**做的(编号要印在卡片上),所以站点挂掉时这 5 秒会加到
|
|
47
|
+
* 报错送达上 —— 正常情况一次上传 50 毫秒左右,只有连不上站点才会等到超时。
|
|
48
|
+
*/
|
|
49
|
+
const UPLOAD_TIMEOUT_MS = 5000;
|
|
34
50
|
/** 上报日志单行最长字符数 */
|
|
35
51
|
const LOG_LINE_LIMIT = 2000;
|
|
36
52
|
/** 整份上报最多多大(压缩前),超了继续砍日志 */
|
|
37
53
|
const PAYLOAD_LIMIT_BYTES = 2 * 1024 * 1024;
|
|
38
54
|
/** 读取宿主日志文件时最多读多少字节 */
|
|
39
55
|
const LOG_FILE_TAIL_BYTES = 512 * 1024;
|
|
40
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* 上报配置。
|
|
58
|
+
*
|
|
59
|
+
* 面板里**只有「上传错误信息」一个开关**(通用 → 错误上报):地址、令牌、群号、日志行数全部写死,
|
|
60
|
+
* 用户没有可以填错的地方。关掉开关就完全不上传。
|
|
61
|
+
*/
|
|
41
62
|
function reportConfig() {
|
|
42
|
-
let
|
|
63
|
+
let enabled = true;
|
|
43
64
|
try {
|
|
44
|
-
options = (0, qqOptions_1.readQqOptions)(((0, runtime_1.tryGetRuntime)()?.config ?? {}));
|
|
65
|
+
const options = (0, qqOptions_1.readQqOptions)(((0, runtime_1.tryGetRuntime)()?.config ?? {}));
|
|
66
|
+
enabled = options.errorReportUpload !== false;
|
|
45
67
|
}
|
|
46
68
|
catch {
|
|
47
|
-
|
|
69
|
+
enabled = (0, runtime_1.tryGetRuntime)()?.config?.errorReportUpload !== false;
|
|
48
70
|
}
|
|
49
|
-
|
|
50
|
-
const logLines = Number(options.errorReportLogLines);
|
|
51
|
-
return {
|
|
52
|
-
enabled: options.errorReportUpload !== false,
|
|
53
|
-
// 末尾斜杠统一去掉,拼 /api/v1/reports 时不会出现双斜杠
|
|
54
|
-
url: url.replace(/\/+$/, ''),
|
|
55
|
-
token: String(options.errorReportToken ?? '').trim(),
|
|
56
|
-
logLines: Number.isFinite(logLines) ? Math.min(1000, Math.max(0, Math.trunc(logLines))) : 200,
|
|
57
|
-
group: String(options.errorReportGroup ?? '').trim() || exports.DEFAULT_REPORT_GROUP
|
|
58
|
-
};
|
|
71
|
+
return { enabled, url: exports.REPORT_URL, token: exports.REPORT_TOKEN, logLines: exports.REPORT_LOG_LINES, group: exports.REPORT_GROUP };
|
|
59
72
|
}
|
|
60
73
|
/** 反馈群链接:QQ 官方的加群链接格式,面板里只填群号 */
|
|
61
74
|
const groupLinkOf = (group) => 'https://qm.qq.com/q/' + group;
|
package/lib/qqFields.json
CHANGED
|
@@ -224,48 +224,5 @@
|
|
|
224
224
|
"default": true,
|
|
225
225
|
"label": "上传错误信息",
|
|
226
226
|
"description": "插件出错时,自动把**错误信息、运行环境(Koishi 版本、装了哪些插件、适配器)、最近的日志**上传到收集站,站长在网页上就能查到,不用你截图、也不用翻日志文件。**默认开启**。上传失败不影响报错本身(错误卡片照常发)。不想要就在这里关掉。"
|
|
227
|
-
},
|
|
228
|
-
{
|
|
229
|
-
"key": "errorReportUrl",
|
|
230
|
-
"group": "通用",
|
|
231
|
-
"renderIn": "app",
|
|
232
|
-
"section": "错误上报",
|
|
233
|
-
"type": "string",
|
|
234
|
-
"default": "https://err.tangbot.xyz",
|
|
235
|
-
"label": "上报服务器地址",
|
|
236
|
-
"description": "错误收集站的地址,**默认 https://err.tangbot.xyz**。自建的话填自己的域名(不要带结尾斜杠)。上报内容会 POST 到「地址 + /api/v1/reports」。"
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
"key": "errorReportToken",
|
|
240
|
-
"group": "通用",
|
|
241
|
-
"renderIn": "app",
|
|
242
|
-
"section": "错误上报",
|
|
243
|
-
"type": "string",
|
|
244
|
-
"default": "",
|
|
245
|
-
"secret": true,
|
|
246
|
-
"label": "上报令牌",
|
|
247
|
-
"description": "收集站要求的令牌,要和服务器端的 KKK_ERR_TOKEN 一致;填错会返回 401,日志里会写「上传失败 HTTP 401」。服务器启动时会打印这个令牌(没设就随机生成一个)。"
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
"key": "errorReportLogLines",
|
|
251
|
-
"group": "通用",
|
|
252
|
-
"renderIn": "app",
|
|
253
|
-
"section": "错误上报",
|
|
254
|
-
"type": "number",
|
|
255
|
-
"default": 200,
|
|
256
|
-
"min": 0,
|
|
257
|
-
"max": 1000,
|
|
258
|
-
"label": "上报日志行数",
|
|
259
|
-
"description": "上报时带多少行日志:本次请求捕获的日志 + 宿主日志文件的尾部(宿主那份最多 300 行)。0 = 完全不上传日志。单行超长的(比如 OneBot 把 4.6MB 的 base64 塞进报错)会自动折叠,不会把上报撑爆。"
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
"key": "errorReportGroup",
|
|
263
|
-
"group": "通用",
|
|
264
|
-
"renderIn": "app",
|
|
265
|
-
"section": "错误上报",
|
|
266
|
-
"type": "string",
|
|
267
|
-
"default": "1050229473",
|
|
268
|
-
"label": "问题反馈群号",
|
|
269
|
-
"description": "错误消息里带上这个群号,用户拿着上报编号进群提问。QQ 官方机器人会把它渲染成**可点的加群链接**(https://qm.qq.com/q/群号),个人号(NapCat 等)直接给纯文本链接,QQ 客户端同样会变成可点。"
|
|
270
227
|
}
|
|
271
228
|
]
|
package/package.json
CHANGED
|
@@ -21,13 +21,29 @@ import { readQqOptions } from '../../../qqOptions'
|
|
|
21
21
|
import { Root } from '../../root'
|
|
22
22
|
import { getBuildMetadata } from './build-metadata'
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
/**
|
|
25
|
+
* 收集站地址:**写死,不开放配置**。
|
|
26
|
+
* 自建的人改这一行重新构建即可 —— 面板里只留「是否上传」一个开关,少一个能填错的地方。
|
|
27
|
+
*/
|
|
28
|
+
export const REPORT_URL = 'https://err.tangbot.xyz'
|
|
29
|
+
/**
|
|
30
|
+
* 上报令牌:**写死**。
|
|
31
|
+
* 服务端 \`KKK_ERR_TOKEN\` 的默认值就是它,所以两边开箱即用、什么都不用配。
|
|
32
|
+
* 它写在开源插件里,等于公开 —— 服务端那边另有 IP 限流兜着,挡的是随机刷接口的流量。
|
|
33
|
+
*/
|
|
34
|
+
export const REPORT_TOKEN = 'kkk-err-9f3c1d7a5b2e4c80'
|
|
35
|
+
/** 反馈群:写死(QQ 客户端点群链接就能进) */
|
|
36
|
+
export const REPORT_GROUP = '1050229473'
|
|
37
|
+
/** 上报多少行日志:写死(本次请求的日志 + 宿主日志文件尾部各取这么多行) */
|
|
38
|
+
export const REPORT_LOG_LINES = 200
|
|
28
39
|
|
|
29
|
-
/**
|
|
30
|
-
|
|
40
|
+
/**
|
|
41
|
+
* 上传超时(毫秒):超了就放弃,不拖住错误卡片。
|
|
42
|
+
*
|
|
43
|
+
* 上报是**在渲染错误卡片之前**做的(编号要印在卡片上),所以站点挂掉时这 5 秒会加到
|
|
44
|
+
* 报错送达上 —— 正常情况一次上传 50 毫秒左右,只有连不上站点才会等到超时。
|
|
45
|
+
*/
|
|
46
|
+
const UPLOAD_TIMEOUT_MS = 5000
|
|
31
47
|
/** 上报日志单行最长字符数 */
|
|
32
48
|
const LOG_LINE_LIMIT = 2000
|
|
33
49
|
/** 整份上报最多多大(压缩前),超了继续砍日志 */
|
|
@@ -50,24 +66,21 @@ interface ReportConfig {
|
|
|
50
66
|
group: string
|
|
51
67
|
}
|
|
52
68
|
|
|
53
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* 上报配置。
|
|
71
|
+
*
|
|
72
|
+
* 面板里**只有「上传错误信息」一个开关**(通用 → 错误上报):地址、令牌、群号、日志行数全部写死,
|
|
73
|
+
* 用户没有可以填错的地方。关掉开关就完全不上传。
|
|
74
|
+
*/
|
|
54
75
|
export function reportConfig (): ReportConfig {
|
|
55
|
-
let
|
|
76
|
+
let enabled = true
|
|
56
77
|
try {
|
|
57
|
-
options = readQqOptions((tryGetRuntime()?.config ?? {}) as any)
|
|
78
|
+
const options = readQqOptions((tryGetRuntime()?.config ?? {}) as any)
|
|
79
|
+
enabled = options.errorReportUpload !== false
|
|
58
80
|
} catch {
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
const url = String(options.errorReportUrl ?? '').trim() || DEFAULT_REPORT_URL
|
|
62
|
-
const logLines = Number(options.errorReportLogLines)
|
|
63
|
-
return {
|
|
64
|
-
enabled: options.errorReportUpload !== false,
|
|
65
|
-
// 末尾斜杠统一去掉,拼 /api/v1/reports 时不会出现双斜杠
|
|
66
|
-
url: url.replace(/\/+$/, ''),
|
|
67
|
-
token: String(options.errorReportToken ?? '').trim(),
|
|
68
|
-
logLines: Number.isFinite(logLines) ? Math.min(1000, Math.max(0, Math.trunc(logLines))) : 200,
|
|
69
|
-
group: String(options.errorReportGroup ?? '').trim() || DEFAULT_REPORT_GROUP
|
|
81
|
+
enabled = (tryGetRuntime()?.config as any)?.errorReportUpload !== false
|
|
70
82
|
}
|
|
83
|
+
return { enabled, url: REPORT_URL, token: REPORT_TOKEN, logLines: REPORT_LOG_LINES, group: REPORT_GROUP }
|
|
71
84
|
}
|
|
72
85
|
|
|
73
86
|
/** 反馈群链接:QQ 官方的加群链接格式,面板里只填群号 */
|
package/src/qqFields.json
CHANGED
|
@@ -224,47 +224,5 @@
|
|
|
224
224
|
"default": true,
|
|
225
225
|
"label": "上传错误信息",
|
|
226
226
|
"description": "插件出错时,自动把**错误信息、运行环境(Koishi 版本、装了哪些插件、适配器)、最近的日志**上传到收集站,站长在网页上就能查到,不用你截图、也不用翻日志文件。**默认开启**。上传失败不影响报错本身(错误卡片照常发)。不想要就在这里关掉。"
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
"key": "errorReportUrl",
|
|
230
|
-
"group": "通用",
|
|
231
|
-
"renderIn": "app",
|
|
232
|
-
"section": "错误上报",
|
|
233
|
-
"type": "string",
|
|
234
|
-
"default": "https://err.tangbot.xyz",
|
|
235
|
-
"label": "上报服务器地址",
|
|
236
|
-
"description": "错误收集站的地址,**默认 https://err.tangbot.xyz**。自建的话填自己的域名(不要带结尾斜杠)。上报内容会 POST 到「地址 + /api/v1/reports」。"
|
|
237
|
-
},
|
|
238
|
-
{
|
|
239
|
-
"key": "errorReportToken",
|
|
240
|
-
"group": "通用",
|
|
241
|
-
"renderIn": "app",
|
|
242
|
-
"section": "错误上报",
|
|
243
|
-
"type": "string",
|
|
244
|
-
"default": "",
|
|
245
|
-
"secret": true,
|
|
246
|
-
"label": "上报令牌",
|
|
247
|
-
"description": "收集站要求的令牌,要和服务器端的 KKK_ERR_TOKEN 一致;填错会返回 401,日志里会写「上传失败 HTTP 401」。服务器启动时会打印这个令牌(没设就随机生成一个)。"
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
"key": "errorReportLogLines",
|
|
251
|
-
"group": "通用",
|
|
252
|
-
"renderIn": "app",
|
|
253
|
-
"section": "错误上报",
|
|
254
|
-
"type": "number",
|
|
255
|
-
"default": 200,
|
|
256
|
-
"min": 0,
|
|
257
|
-
"max": 1000,
|
|
258
|
-
"label": "上报日志行数",
|
|
259
|
-
"description": "上报时带多少行日志:本次请求捕获的日志 + 宿主日志文件的尾部(宿主那份最多 300 行)。0 = 完全不上传日志。单行超长的(比如 OneBot 把 4.6MB 的 base64 塞进报错)会自动折叠,不会把上报撑爆。"
|
|
260
|
-
},
|
|
261
|
-
{
|
|
262
|
-
"key": "errorReportGroup",
|
|
263
|
-
"group": "通用",
|
|
264
|
-
"renderIn": "app",
|
|
265
|
-
"section": "错误上报",
|
|
266
|
-
"type": "string",
|
|
267
|
-
"default": "1050229473",
|
|
268
|
-
"label": "问题反馈群号",
|
|
269
|
-
"description": "错误消息里带上这个群号,用户拿着上报编号进群提问。QQ 官方机器人会把它渲染成**可点的加群链接**(https://qm.qq.com/q/群号),个人号(NapCat 等)直接给纯文本链接,QQ 客户端同样会变成可点。"
|
|
270
|
-
}]
|
|
227
|
+
}
|
|
228
|
+
]
|