@akairos/typeset-studio 0.3.0 → 0.3.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/README.md CHANGED
@@ -39,7 +39,7 @@
39
39
 
40
40
  ```ts
41
41
  import {
42
- createArticleCoverConfig, validateArticleCoverControls,
42
+ createArticleCoverConfig, normalizeArticleCoverTitle, validateArticleCoverControls,
43
43
  ARTICLE_COVER_FONT, ARTICLE_COVER_IMAGE_KEY,
44
44
  } from "@akairos/typeset-studio/cover";
45
45
  import { CoverControls } from "@akairos/typeset-studio/editor";
@@ -49,7 +49,7 @@ import { CoverControls } from "@akairos/typeset-studio/editor";
49
49
 
50
50
  仅服务端调用的 `@akairos/typeset-studio/server-font` 提供同步 `registerArticleCoverFont({ path })`。它要求可信绝对路径,校验固定字体字节后注册 `Publishing Cover` 别名并清测量缓存;缺失、hash 错误或注册失败都抛错。字体身份为 `publishing-noto-cjk-regular-v1`,来自 Debian `fonts-noto-cjk=1:20240730+repack1-1` 的 `NotoSansCJK-Regular.ttc`,SHA256 `b76b0433203017ca80401b2ee0dd69350349871c4b19d504c34dbdd80541690a`。npm 不携带字体;宿主部署需固定包版本、保留字体许可证并保存受控恢复副本。客户端快照只记录字体 id/hash,不能提交路径。
51
51
 
52
- 可信 PNG 调用顺序:注册字体 → 工厂配置 → 解析素材占位 → `runTypeset({ markdown, config, images, maxPages: 1 })` → `renderPageToPng(...)`。原 root API 仅供服务端使用,`/cover` 和 `/editor` 没有原生 Canvas 或 Node 依赖。Pipeline 插件在实际渲染子进程中通过受信环境 `TYPESET_ARTICLE_COVER_FONT_PATH` 注册工厂配置的字体,不能只在 Worker 父进程注册;旧模板和 standalone 原路径不受影响。
52
+ 可信 PNG 调用顺序:注册字体 → 工厂配置 → 解析素材占位 → `runTypeset({ markdown, config, images, maxPages: 1 })` → `renderPageToPng(...)`。从 0.3.1 起,宿主先用 `normalizeArticleCoverTitle(title)` 清理首尾空白和前导 `#` 组,拒绝清理后为空的标题,再构造标题 Markdown;重复调用结果不变,中间及尾部的 `#` 保留。Pipeline 仅在可信 `ZZHUB_PIPELINE_COVER_SNAPSHOT=1` 分支使用同一规则,旧调用保留原标题行为。原 root API 仅供服务端使用,`/cover` 和 `/editor` 没有原生 Canvas 或 Node 依赖。Pipeline 插件在实际渲染子进程中通过受信环境 `TYPESET_ARTICLE_COVER_FONT_PATH` 注册工厂配置的字体,不能只在 Worker 父进程注册;旧模板和 standalone 原路径不受影响。
53
53
 
54
54
  本次定向检查入口为 `src/core/article-cover.test.ts` 和 `src/server-font.test.ts`;后者的真实 PNG 测试需显式设置 `TYPESET_ARTICLE_COVER_FONT_PATH` 为受控字体文件,否则该项跳过。开发只构建/静态检查,真实字体、PNG、HTTP/插件和消费方浏览器检查由主控执行并区分留证。
55
55
 
@@ -289,7 +289,7 @@ Error generating stack: `+n.message+`
289
289
  */const Th={name:"zoom-out",size:24,node:[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]]};Th.node;const Bp=we(Th),zp=({isOpen:u,onClose:r,currentKey:s,onSaveKey:c,isVerified:d})=>{const[x,g]=fe.useState(s),[v,N]=fe.useState(null);if(!u)return null;const m=()=>{c(x.trim()),N("密钥已更新并保存至本地存储"),setTimeout(()=>{r()},800)};return f.jsx("div",{className:"fixed inset-0 z-50 bg-black/50 dark:bg-black/70 backdrop-blur-sm flex items-center justify-center p-4",children:f.jsxs("div",{className:"bg-white dark:bg-[#0f0f0f] border border-[#eaeaea] dark:border-[#262626] rounded-xl w-full max-w-md flex flex-col shadow-2xl overflow-hidden animate-in fade-in zoom-in-95 duration-150 transition-colors",children:[f.jsxs("div",{className:"flex items-center justify-between px-5 py-3.5 border-b border-[#eaeaea] dark:border-[#222222]",children:[f.jsxs("div",{className:"flex items-center gap-2 font-semibold text-sm text-[#171717] dark:text-white",children:[f.jsx(eh,{className:"w-4 h-4 text-amber-500 dark:text-amber-400"}),f.jsx("span",{children:"超管密钥授权"})]}),f.jsx("button",{onClick:r,className:"text-[#888888] hover:text-black dark:hover:text-white p-1 rounded-md hover:bg-[#f5f5f5] dark:hover:bg-[#1a1a1a]",children:f.jsx(jo,{className:"w-4 h-4"})})]}),f.jsxs("div",{className:"p-5 flex flex-col gap-4",children:[f.jsxs("div",{className:"text-xs text-[#666666] dark:text-[#888888] leading-relaxed",children:["服务端默认通过 ",f.jsx("code",{className:"text-black dark:text-[#ededed] font-mono font-semibold",children:"TYPESET_ADMIN_KEY"})," 保护模板持久化、图片上传和无头出图 API。请填入服务启动时控制台打印的管理员密钥。"]}),f.jsxs("div",{className:"flex flex-col gap-1.5",children:[f.jsx("label",{className:"text-[11px] font-mono text-[#888888] dark:text-[#666666]",children:"X-Admin-Key"}),f.jsx("input",{type:"password",value:x,onChange:y=>g(y.target.value),placeholder:"tsk_...",className:"bg-[#fafafa] dark:bg-[#0a0a0a] border border-[#d4d4d4] dark:border-[#2a2a2a] rounded-lg px-3 py-2 text-xs font-mono text-black dark:text-white focus:outline-none focus:border-black dark:focus:border-[#444444]"})]}),v?f.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-500/10 border border-emerald-200 dark:border-emerald-500/20 px-3 py-2 rounded-lg flex items-center gap-2 font-medium",children:[f.jsx(Qx,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:v})]}):d?f.jsxs("div",{className:"text-xs text-emerald-700 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-500/10 border border-emerald-200 dark:border-emerald-500/20 px-3 py-2 rounded-lg flex items-center gap-2 font-medium",children:[f.jsx(Cp,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:"密钥已通过验证,拥有超管权限"})]}):f.jsx("div",{className:"text-xs text-amber-700 dark:text-amber-400 bg-amber-50 dark:bg-amber-500/10 border border-amber-200 dark:border-amber-500/20 px-3 py-2 rounded-lg",children:"当前密钥未验证或已失效,请检查后端 .env 配置"}),f.jsxs("div",{className:"flex justify-end gap-2 pt-2",children:[f.jsx("button",{onClick:r,className:"px-3 py-1.5 rounded-lg border border-[#eaeaea] dark:border-[#262626] text-xs text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white hover:bg-[#f5f5f5] dark:hover:bg-[#161616]",children:"取消"}),f.jsx("button",{onClick:m,className:"px-4 py-1.5 bg-black text-white hover:bg-[#262626] dark:bg-white dark:text-black dark:hover:bg-[#eaeaea] text-xs font-semibold rounded-lg transition-all btn-vercel",children:"保存并授权"})]})]})]})})},vx={"wechat-cover-2.35":{id:"wechat-cover-2.35",name:"微信文章封面",ratio:3.35,width:3350,height:1e3,description:"微信文章封面原图 (3.35:1):左侧 2.35:1 大图,右侧 1:1 小图",defaultSafeArea:{top:120,right:140,bottom:120,left:140}},"longform-3-4":{id:"longform-3-4",name:"通用长图文",ratio:3/4,width:1080,height:1440,description:"3:4 手机端阅读长文/图文卡片,支持多页分页、矩形图片绕排、目标填充率优化",defaultSafeArea:{top:96,right:88,bottom:96,left:88}},"wide-16-9":{id:"wide-16-9",name:"通用宽屏",ratio:16/9,width:1920,height:1080,description:"16:9 横版宽屏,适合推特/X 动态配图、技术博客 Banner、视频封面与分栏排版",defaultSafeArea:{top:100,right:120,bottom:100,left:120}},"square-1-1":{id:"square-1-1",name:"通用正方形",ratio:1,width:1200,height:1200,description:"1:1 正方形卡片,适合金句名言卡、公众号次条、小红书方图与社交媒体方版海报",defaultSafeArea:{top:100,right:100,bottom:100,left:100}}};function Tl(u){return vx[u]??vx["longform-3-4"]}function zn(u,r,s=20){const c=Math.max(100,u.width-r.left-r.right),d=Math.max(100,u.height-r.top-r.bottom-s);return{stageWidth:c,stageHeight:d,stageX:r.left,stageY:r.top}}const _p={pattern:"none",color:"#527561",opacity:.12,size:56},Rp={style:"none",color:"#527561",endColor:"#d7ad72",width:3,inset:32,radius:24,opacity:.8},Fh={none:"无花纹",lines:"横线",grid:"网格",dots:"圆点",diagonal:"斜线",waves:"波浪",rings:"同心圆",burst:"放射线",checker:"棋盘格",grain:"纸张颗粒"},jh={none:"无边框",solid:"实线",dashed:"虚线",double:"双线",corners:"四角装饰",gradient:"渐变描边"};function Dh(u){if(u===void 0)return;if(!u||typeof u!="object"||Array.isArray(u))throw new RangeError("无效的背景与边框配置");const r=c=>{if(typeof c!="string"||!/^#[0-9a-f]{6}$/i.test(c))throw new RangeError("背景装饰颜色必须是六位十六进制颜色")},s=(c,d,x)=>{if(!Number.isFinite(c)||c<d||c>x)throw new RangeError(`背景装饰参数必须在 ${d} 到 ${x} 之间`)};if(u.fill){const c=u.fill;if(c.type==="solid")r(c.color);else{if(c.type==="linear")s(c.angle,0,360);else if(c.type==="radial")s(c.position?.x,0,100),s(c.position?.y,0,100);else throw new RangeError("未知背景类型");if(!Array.isArray(c.stops)||c.stops.length<2||c.stops.length>8)throw new RangeError("渐变需要 2 到 8 个颜色节点");for(const d of c.stops){if(!d)throw new RangeError("无效的渐变节点");r(d.color),s(d.offset,0,100)}}}if(u.pattern){const c=u.pattern;if(!Object.hasOwn(Fh,c.pattern))throw new RangeError("未知背景花纹");r(c.color),s(c.opacity,0,1),s(c.size,16,240)}if(u.border){const c=u.border;if(!Object.hasOwn(jh,c.style))throw new RangeError("未知边框样式");r(c.color),r(c.endColor),s(c.width,1,24),s(c.inset,0,200),s(c.radius,0,200),s(c.opacity,0,1)}}function Lp(u,r,s){if(u.save(),s.type==="solid")u.fillStyle=s.color;else{let c;if(s.type==="linear"){const d=s.angle*Math.PI/180,x=Math.abs(Math.cos(d))*r.width/2+Math.abs(Math.sin(d))*r.height/2,g=Math.cos(d)*x,v=Math.sin(d)*x;c=u.createLinearGradient(r.width/2-g,r.height/2-v,r.width/2+g,r.height/2+v)}else{const d=r.width*s.position.x/100,x=r.height*s.position.y/100,g=Math.hypot(Math.max(d,r.width-d),Math.max(x,r.height-x));c=u.createRadialGradient(d,x,0,d,x,g)}for(const d of s.stops)c.addColorStop(d.offset/100,d.color);u.fillStyle=c}u.fillRect(0,0,r.width,r.height),u.restore()}function Hp(u,r,s){if(s.pattern==="none"||s.opacity===0)return;const{width:c,height:d}=r,x=Math.max(16,s.size);switch(u.save(),u.strokeStyle=u.fillStyle=s.color,u.globalAlpha=s.opacity,u.lineWidth=1.5,u.beginPath(),s.pattern){case"grid":case"lines":if(s.pattern==="grid")for(let g=x/2;g<c;g+=x)u.moveTo(g,0),u.lineTo(g,d);for(let g=x/2;g<d;g+=x)u.moveTo(0,g),u.lineTo(c,g);break;case"dots":for(let g=x/2;g<c;g+=x)for(let v=x/2;v<d;v+=x)u.moveTo(g+2,v),u.arc(g,v,2,0,Math.PI*2);break;case"diagonal":for(let g=-d;g<c;g+=x)u.moveTo(g,0),u.lineTo(g+d,d);break;case"waves":for(let g=-x;g<d+x;g+=x){u.moveTo(0,g);for(let v=0;v<c;v+=x*2)u.bezierCurveTo(v+x*.5,g-x*.45,v+x*1.5,g+x*.45,v+x*2,g)}break;case"rings":for(let g=x;g<Math.hypot(c,d);g+=x)u.moveTo(c*.82+g,d*.18),u.arc(c*.82,d*.18,g,0,Math.PI*2);break;case"burst":for(let g=0;g<Math.PI*2;g+=Math.PI/Math.max(8,Math.round(x/3)))u.moveTo(c*.8,d*.2),u.lineTo(c*.8+Math.cos(g)*c*2,d*.2+Math.sin(g)*d*2);break;case"checker":for(let g=0;g<c;g+=x)for(let v=0;v<d;v+=x)(Math.round(g/x)+Math.round(v/x))%2===0&&u.rect(g,v,x,x);break;case"grain":{let g=42;const v=()=>(g=Math.imul(g,1664525)+1013904223>>>0,g/4294967296);for(let N=0;N<c*d/(x*3);N++){const m=v()*c,y=v()*d;u.rect(m,y,.6+v()*1.2,.6+v()*1.2)}break}}["dots","checker","grain"].includes(s.pattern)?u.fill():u.stroke(),u.restore()}function Up(u,r,s){if(!s||s.style==="none"||s.opacity===0)return;const c=Math.min(s.inset+s.width/2,Math.min(r.width,r.height)/2-1),d=r.width-c*2,x=r.height-c*2;if(u.save(),u.globalAlpha=s.opacity,u.lineWidth=s.width,u.strokeStyle=s.color,s.style==="gradient"){const v=u.createLinearGradient(0,0,r.width,r.height);v.addColorStop(0,s.color),v.addColorStop(1,s.endColor),u.strokeStyle=v}s.style==="dashed"&&u.setLineDash([s.width*4,s.width*3]);const g=v=>{u.beginPath(),u.roundRect(c+v,c+v,d-v*2,x-v*2,Math.max(0,s.radius-v)),u.stroke()};if(s.style==="corners"){const v=Math.min(d,x)*.12;for(const N of[c,r.width-c])for(const m of[c,r.height-c]){const y=N===c?1:-1,p=m===c?1:-1;u.beginPath(),u.moveTo(N+y*v,m),u.lineTo(N,m),u.lineTo(N,m+p*v),u.stroke()}}else g(0),s.style==="double"&&g(s.width*3+4);u.restore()}function Gp(u,r=!1){const c=((u||"").split(",")[0]||"").replace(/["'\\]/g,"").trim();return c.includes("Noto Sans")?r?'"Hiragino Sans GB", sans-serif':'"Noto Sans SC", "PingFang SC", sans-serif':c.includes("PingFang")?r?'"Hiragino Sans GB", sans-serif':'"PingFang SC", "Noto Sans SC", sans-serif':c.includes("Noto Serif")?r?'"Songti SC", serif':'"Noto Serif SC", "Songti SC", serif':c.includes("Songti")||c==="STSong"?r?'"Songti SC", serif':'"Songti SC", "Noto Serif SC", serif':c.includes("Kai")||c.includes("WenKai")?r?'"STKaiti", "Kaiti SC", "Songti SC", serif':'"LXGW WenKai GB Screen", "LXGW WenKai Screen", "Kaiti SC", "STKaiti", serif':c.includes("Yuan")?r?'"STYuanti", "Yuanti SC", "Hiragino Sans GB", sans-serif':'"Yuanti SC", "STYuanti", "PingFang SC", sans-serif':c.includes("Inter")?r?'Inter, "Hiragino Sans GB", sans-serif':'Inter, "PingFang SC", sans-serif':c.includes("Georgia")?'Georgia, "Songti SC", serif':c.toLowerCase().includes("serif")||c.includes("Song")?`"${c}", "Songti SC", serif`:r?`"${c}", "Hiragino Sans GB", "PingFang SC", sans-serif`:`"${c}", "PingFang SC", sans-serif`}function ja(u,r=!1){if(!u)return'16px "PingFang SC", sans-serif';const s=u.match(/^(.*?)([\d.]+(?:px|pt|em|rem))\s+(.+)$/);if(!s)return u;const c=s[1],d=s[2],x=s[3];return`${c}${d} ${Gp(x,r)}`}async function qp(u,r){const{page:s,spec:c,config:d,totalPageCount:x=1,getImage:g,isServer:v=!1}=r,{algorithm:N,theme:m,chrome:y}=d;Dh(d.canvasStyle),u.save(),u.fillStyle=m.bgColor,u.fillRect(0,0,c.width,c.height),u.restore(),d.canvasStyle?.fill&&Lp(u,c,d.canvasStyle.fill);const p=d.coverTheme,b=async Y=>{if(!Y)return;const S=await g(Y.src);if(!S)throw new Error("Failed to load cover theme image");const U=Y.fit==="contain"?Math.min(c.width/S.width,c.height/S.height):Math.max(c.width/S.width,c.height/S.height),_=Y.fit==="fill"?c.width:S.width*U,te=Y.fit==="fill"?c.height:S.height*U;u.save(),u.globalAlpha=Y.opacity,u.drawImage(S,(c.width-_)*Y.position.x/100,(c.height-te)*Y.position.y/100,_,te),u.restore()};if(p){if(!d.canvasStyle?.fill){const S=p.background.fill;if(u.save(),S.type==="solid")u.fillStyle=S.color;else{let U;if(S.type==="linear"){const _=S.angle*Math.PI/180,te=Math.cos(_)*c.width/2,ne=Math.sin(_)*c.height/2;U=u.createLinearGradient(c.width/2-te,c.height/2-ne,c.width/2+te,c.height/2+ne)}else{const _=c.width*S.position.x/100,te=c.height*S.position.y/100;U=u.createRadialGradient(_,te,0,_,te,Math.hypot(c.width,c.height))}for(const _ of S.stops)U.addColorStop(_.offset/100,_.color);u.fillStyle=U}u.fillRect(0,0,c.width,c.height),u.restore()}await b(p.background.image),p.background.overlay&&(u.save(),u.fillStyle=p.background.overlay.color,u.globalAlpha=p.background.overlay.opacity,u.fillRect(0,0,c.width,c.height),u.restore());const Y=p.decoration;if(!d.canvasStyle?.pattern){u.save(),u.strokeStyle=u.fillStyle=Y.color,u.globalAlpha=Y.opacity;const S=Math.max(8,Y.size);if(u.beginPath(),["lines","grid","dots"].includes(Y.pattern)){for(let U=0;U<c.width;U+=S)if(Y.pattern==="grid"&&(u.moveTo(U,0),u.lineTo(U,c.height)),Y.pattern==="dots")for(let _=0;_<c.height;_+=S)u.moveTo(U+2,_),u.arc(U,_,2,0,Math.PI*2);if(Y.pattern!=="dots")for(let U=0;U<c.height;U+=S)u.moveTo(0,U),u.lineTo(c.width,U)}else if(Y.pattern==="rings")for(let U=S;U<Math.hypot(c.width,c.height);U+=S)u.moveTo(c.width/2+U,c.height/2),u.arc(c.width/2,c.height/2,U,0,Math.PI*2);else if(Y.pattern==="burst")for(let U=0;U<Math.PI*2;U+=Math.PI/Math.max(8,Math.round(S/3)))u.moveTo(c.width/2,c.height/2),u.lineTo(c.width/2+Math.cos(U)*c.width,c.height/2+Math.sin(U)*c.height);Y.pattern==="dots"?u.fill():u.stroke(),u.restore()}await b(Y.image)}d.canvasStyle?.pattern&&Hp(u,c,d.canvasStyle.pattern);const{stageX:w,stageY:M}=zn(c,N.safeArea,N.contentBottomGap),Q=d.aspectRatio==="wechat-cover-2.35",B=y?.showHeader??!Q,L=(y?.showWatermark??!Q)&&!!d.watermarkText?.trim(),P=(y?.showPageNumber??(!Q&&x>1))&&x>1;if(B&&(L||P)){const Y=Math.max(24,Math.floor(N.safeArea.top*.45));if(L&&(u.save(),u.font=ja("600 14px PingFang SC",v),u.fillStyle=m.watermarkColor,u.globalAlpha=.45,u.textBaseline="middle",u.textAlign="left",u.fillText(d.watermarkText.toUpperCase(),N.safeArea.left,Y),u.restore()),P){u.save();const S=`P.${String(s.pageNumber).padStart(2,"0")}`;u.font='500 12px "SF Mono", Monaco, Menlo, Consolas, monospace',u.textBaseline="middle",u.textAlign="left";const _=u.measureText(S).width+16,te=24,ne=c.width-N.safeArea.right-_,he=Y-te/2;u.strokeStyle=m.textColor,u.globalAlpha=.4,u.lineWidth=1,u.beginPath(),u.roundRect(ne,he,_,te,12),u.stroke(),u.fillStyle=m.textColor,u.fillText(S,ne+8,Y),u.restore()}}const ee=[...s.images||[]].sort((Y,S)=>{const U=Y.zIndex??(Y.isAbsolute?20:5),_=S.zIndex??(S.isAbsolute?20:5);return U-_}),ce=async Y=>{for(const S of Y){let U;try{U=await g(S.src)}catch(F){throw S.templateAssetKey?new Error(`模板素材 ${S.templateAssetKey} 加载失败:${F instanceof Error?F.message:String(F)}`):F}if(!U&&S.templateAssetKey)throw new Error(`模板素材 ${S.templateAssetKey} 加载失败:图片不存在或无法读取`);const _=w+S.x,te=M+S.y,ne=_+S.width/2,he=te+S.height/2;u.save(),u.translate(ne,he),S.rotate&&u.rotate(S.rotate*Math.PI/180),u.globalAlpha=S.opacity??1;const G=S.width,O=S.height,k=Math.min(S.borderRadius??12,G/2,O/2);if(u.beginPath(),u.roundRect(-G/2,-O/2,G,O,k),u.clip(),U)if(S.fit==="cover"){const F=U.naturalWidth||U.width,Z=U.naturalHeight||U.height;if(!(F>0&&Z>0))throw new Error("Invalid cover image dimensions");const W=Math.max(G/F,O/Z),ie=G/W,le=O/W;u.drawImage(U,(F-ie)/2,(Z-le)/2,ie,le,-G/2,-O/2,G,O)}else u.drawImage(U,-G/2,-O/2,G,O);else u.fillStyle=m.cardBg||"#222222",u.fillRect(-G/2,-O/2,G,O);if(u.restore(),S.caption?.trim()){u.save();const F=Math.max(14,Math.round(N.baseFontSize*.45));u.font=ja(`400 ${F}px PingFang SC`,v),u.fillStyle=m.captionColor,u.textBaseline="top",u.textAlign="center",u.fillText(S.caption,ne,te+O+12),u.restore()}}};await ce(ee.filter(Y=>(Y.zIndex??(Y.isAbsolute?20:5))<10));for(const Y of s.lines){const S=w+Y.x,U=M+Y.y;if(Y.className==="body-quote"){u.save(),u.fillStyle=m.accentColor,u.globalAlpha=.85,u.beginPath();const te=Math.max(1,Y.lineHeight-8);typeof u.roundRect=="function"?u.roundRect(w,U+4,3.5,te,2):u.rect(w,U+4,3.5,te),u.fill(),u.restore()}if(Y.bullet&&Y.bulletX!==void 0){if(u.save(),u.fillStyle=m.accentColor,Y.bullet==="•"){const te=Math.max(3,Math.round(N.baseFontSize*.08)),ne=w+Y.bulletX+8,he=U+Math.round(Y.lineHeight*.42);u.beginPath(),u.arc(ne,he,te,0,Math.PI*2),u.fill()}else u.font=ja(Y.font,v),u.textBaseline="top",u.textAlign="left",u.fillText(Y.bullet,w+Y.bulletX,U);u.restore()}let _=S;for(const te of Y.fragments){const ne=te.font||Y.font,he=ja(ne,v);u.font=he,u.textBaseline="top",u.textAlign="left",te.highlight?u.fillStyle=m.accentColor:Y.className.includes("heading")?u.fillStyle=m.headingColor||m.textColor:Y.className.includes("quote")?u.fillStyle=m.quoteColor||m.textColor:u.fillStyle=m.textColor,u.letterSpacing=`${te.letterSpacing||0}px`,u.fillText(te.text,_,U);const G=te.letterSpacing?te.occupiedWidth:u.measureText(te.text).width;_+=G+(te.gapBefore||0)}}await ce(ee.filter(Y=>(Y.zIndex??(Y.isAbsolute?20:5))>=10)),u.letterSpacing="0px";const re=y?.showFooter??!Q,H=y?.showFooterDivider??(!Q&&!!d.footerText?.trim()),V=(y?.showFooterText??!Q)&&!!d.footerText?.trim();if(re){const Y=c.height-Math.max(24,Math.floor(N.safeArea.bottom*.45));if(H&&(u.save(),u.strokeStyle=m.borderSubtle||"#e5e5e5",u.lineWidth=1,u.beginPath(),u.moveTo(N.safeArea.left,Y-14),u.lineTo(c.width-N.safeArea.right,Y-14),u.stroke(),u.restore()),y?.showFillRatio&&(u.save(),u.font=ja("500 13px PingFang SC",v),u.fillStyle=m.captionColor,u.textBaseline="middle",u.textAlign="right",u.fillText(`填充率 ${Math.round(s.fillRatio*100)}%`,c.width-N.safeArea.right,Y),u.restore()),V){u.save();const S=p?.typography.footer;u.font=ja(S?`${S.fontWeight} ${S.fontSize}px "${S.fontFamily}"`:"500 13px PingFang SC",v),u.letterSpacing=`${S?.letterSpacing||0}px`,u.fillStyle=m.watermarkColor||m.captionColor,u.globalAlpha=.6,u.textBaseline="middle",u.textAlign="left",u.fillText(d.footerText,N.safeArea.left,Y),u.restore()}}Up(u,c,d.canvasStyle?.border)}const Yp=({page:u,spec:r,config:s,totalPageCount:c,zoom:d})=>{const x=fe.useRef(null),[g,v]=fe.useState(null);return fe.useEffect(()=>{const N=x.current;if(!N)return;const m=N.getContext("2d");if(!m)return;N.dataset.renderState="loading",v(null);let y=!1;const p=new AbortController,b=M=>M?new Promise(Q=>{const B=new Image;let L;const P=ce=>{p.signal.removeEventListener("abort",ee),B.onload=B.onerror=null,L&&(L.onload=L.onerror=null),Q(ce)},ee=()=>P(null);if(p.signal.aborted){P(null);return}p.signal.addEventListener("abort",ee,{once:!0}),B.crossOrigin="anonymous",B.onload=()=>P(B),B.onerror=()=>{L=new Image,L.onload=()=>P(L),L.onerror=()=>P(null),L.src=M},B.src=M}):Promise.resolve(null);return(async()=>{const M=document.createElement("canvas");M.width=r.width,M.height=r.height;const Q=M.getContext("2d");Q&&(await qp(Q,{page:u,spec:r,config:s,totalPageCount:c,getImage:b,isServer:!1}),y||(m.clearRect(0,0,r.width,r.height),m.drawImage(M,0,0),N.dataset.renderState="ready"))})().catch(M=>{y||(N.dataset.renderState="error",m.clearRect(0,0,r.width,r.height),v(M instanceof Error?M.message:"画布绘制失败"))}),()=>{y=!0,p.abort()}},[u,r,s,c]),f.jsxs(f.Fragment,{children:[f.jsx("canvas",{id:`typeset-page-${u.pageNumber}`,ref:x,width:r.width,height:r.height,className:"typeset-page absolute top-0 left-0 border border-[#e0e0e0] dark:border-[#222222] shadow-sm select-none",style:{width:r.width*d,height:r.height*d,backgroundColor:s.theme.bgColor}}),g&&f.jsx("div",{role:"alert",className:"absolute inset-0 flex items-center justify-center bg-white/90 p-4 text-sm text-red-600",children:g})]})},Xp=({result:u,zoom:r,viewportRef:s,onAutoFit:c,isAutoFit:d,viewMode:x="grid",onToggleViewMode:g,onFocusPage:v})=>{const{pages:N,canvasSpec:m,config:y}=u;return f.jsxs("main",{ref:s,className:"flex-1 min-w-0 overflow-auto bg-[#f5f5f5] dark:bg-[#050505] bg-grid flex flex-col p-6 select-none relative transition-colors",children:[f.jsxs("div",{className:"sticky top-0 z-20 self-center mb-6 px-3.5 py-1.5 rounded-full bg-white/90 dark:bg-[#111111]/90 backdrop-blur border border-[#eaeaea] dark:border-[#222222] text-[11px] font-mono text-[#666666] dark:text-[#888888] flex items-center gap-2.5 shadow-sm",children:[f.jsx("span",{className:"text-[#171717] dark:text-white font-semibold",children:m.name}),f.jsx("span",{children:"•"}),f.jsxs("span",{children:[m.width," × ",m.height,"px"]}),f.jsx("span",{children:"•"}),f.jsxs("span",{className:"text-black dark:text-white font-medium",children:[N.length," 张图片"]}),N.length>1&&g&&f.jsxs(f.Fragment,{children:[f.jsx("span",{children:"•"}),f.jsxs("div",{className:"flex items-center bg-[#eaeaea] dark:bg-[#1a1a1a] rounded-md p-0.5 border border-[#dfdfdf] dark:border-[#262626]",children:[f.jsxs("button",{onClick:()=>g("grid"),className:`flex items-center gap-1 px-2 py-0.5 rounded text-[10px] font-medium transition-all ${x==="grid"?"bg-white dark:bg-[#2b2b2b] text-black dark:text-white shadow-xs font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,title:"多图瀑布流平铺全览",children:[f.jsx(bp,{className:"w-3 h-3"}),f.jsx("span",{children:"多图平铺"})]}),f.jsxs("button",{onClick:()=>g("stack"),className:`flex items-center gap-1 px-2 py-0.5 rounded text-[10px] font-medium transition-all ${x==="stack"?"bg-white dark:bg-[#2b2b2b] text-black dark:text-white shadow-xs font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,title:"单列纵向逐页滚动",children:[f.jsx(Ap,{className:"w-3 h-3"}),f.jsx("span",{children:"纵向单列"})]})]})]}),c&&f.jsxs(f.Fragment,{children:[f.jsx("span",{children:"•"}),f.jsx("button",{onClick:c,className:`hover:text-black dark:hover:text-white transition-colors underline underline-offset-2 ${d?"text-emerald-600 dark:text-emerald-400 font-semibold":""}`,title:N.length>1?"缩放至视口内完整排列多张图片":"自适应画布比例",children:d?N.length>1?"已平铺适配":"已自适应":N.length>1?"平铺适配":"自适应"})]})]}),f.jsx("div",{className:"min-w-fit w-full flex-1 flex flex-col items-center justify-start pb-32",children:f.jsx("div",{className:`flex items-start justify-center gap-7 transition-all duration-300 ${x==="grid"?"flex-wrap max-w-full":"flex-col items-center"}`,children:N.map(p=>f.jsxs("div",{className:"flex flex-col items-center",children:[N.length>1&&f.jsxs("div",{className:"mb-2 px-2.5 py-1 rounded-md bg-white/90 dark:bg-[#181818]/90 border border-[#eaeaea] dark:border-[#262626] text-[11px] font-mono text-[#666666] dark:text-[#888888] shadow-xs flex items-center justify-between transition-colors",style:{width:m.width*r},children:[f.jsxs("div",{className:"flex items-center gap-1.5 truncate",children:[f.jsxs("span",{className:"font-semibold text-[#171717] dark:text-white",children:["第 ",p.pageNumber," / ",N.length," 页"]}),f.jsx("span",{children:"•"}),f.jsx("span",{className:"truncate",children:m.name})]}),v&&f.jsxs("button",{onClick:b=>{b.stopPropagation(),v(p.pageNumber)},className:"shrink-0 text-[10px] px-1.5 py-0.5 rounded bg-[#f5f5f5] dark:bg-[#242424] hover:bg-[#eaeaea] dark:hover:bg-[#333333] text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 font-medium transition-colors flex items-center gap-1 cursor-pointer",title:"放大聚焦此页",children:[f.jsx(kh,{className:"w-2.5 h-2.5"}),f.jsx("span",{children:"聚焦单图"})]})]}),f.jsx("div",{onDoubleClick:()=>v?.(p.pageNumber),className:"relative shrink-0 shadow-xl dark:shadow-2xl rounded-sm transition-shadow hover:shadow-2xl cursor-pointer",title:N.length>1?"双击放大聚焦此页":void 0,style:{width:m.width*r,height:m.height*r},children:f.jsx(Yp,{page:p,spec:m,config:y,totalPageCount:N.length,zoom:r})})]},p.pageNumber))})})]})},Qp=({markdown:u,onMarkdownChange:r,images:s,onAddImage:c,onToggleBackground:d,onResetImageLayout:x,backgroundImageIds:g,onUpdateImage:v,onRemoveImage:N,onMoveImage:m,pageCount:y=1,highlightWords:p,onHighlightWordsChange:b,adminKey:w})=>{const[M,Q]=fe.useState("text"),[B,L]=fe.useState(""),P=fe.useRef(null),[ee,ce]=fe.useState(!1),re=S=>{r(u?`${u}
290
290
 
291
291
  ${S}`:S)},H=async S=>{const U=S.target.files?.[0];if(!U)return;const _=ne=>c({src:ne,alt:U.name,caption:"",x:40,y:400,width:440,height:300,captionHeight:36,layoutPreset:"auto"}),te=()=>{const ne=new FileReader;ne.onload=()=>{typeof ne.result=="string"&&_(ne.result)},ne.readAsDataURL(U)};ce(!0);try{const ne=new FormData;ne.append("file",U);const G=await(await fetch("/api/upload",{method:"POST",headers:w?{"x-admin-key":w}:{},body:ne})).json();G.ok&&G.url?_(G.url):te()}catch{te()}finally{ce(!1),P.current&&(P.current.value="")}},V=()=>{B.trim()&&(p.includes(B.trim())||b([...p,B.trim()]),L(""))},Y=S=>{b(p.filter(U=>U!==S))};return f.jsxs("aside",{className:"w-80 border-r border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] flex flex-col shrink-0 select-none transition-colors",children:[f.jsxs("div",{className:"flex border-b border-[#eaeaea] dark:border-[#222222] bg-[#f9f9f9] dark:bg-[#050505] p-1 gap-1",children:[f.jsxs("button",{onClick:()=>Q("text"),className:`flex-1 flex items-center justify-center gap-1.5 py-1.5 text-xs rounded font-medium transition-all ${M==="text"?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-[#cccccc]"}`,children:[f.jsx(fp,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:"正文"})]}),f.jsxs("button",{onClick:()=>Q("images"),className:`flex-1 flex items-center justify-center gap-1.5 py-1.5 text-xs rounded font-medium transition-all ${M==="images"?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-[#cccccc]"}`,children:[f.jsx(gp,{className:"w-3.5 h-3.5"}),f.jsxs("span",{children:["配图 (",s.length,")"]})]}),f.jsxs("button",{onClick:()=>Q("highlights"),className:`flex-1 flex items-center justify-center gap-1.5 py-1.5 text-xs rounded font-medium transition-all ${M==="highlights"?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-[#cccccc]"}`,children:[f.jsx(mp,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:"重点词"})]})]}),M==="text"&&f.jsxs("div",{className:"flex-1 flex flex-col p-3 gap-2 overflow-hidden",children:[f.jsxs("div",{className:"flex items-center gap-1 pb-1 flex-wrap border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("button",{onClick:()=>re("# 标题"),className:"px-2 py-1 bg-[#f5f5f5] dark:bg-[#141414] hover:bg-[#eaeaea] dark:hover:bg-[#202020] text-[#555555] dark:text-[#aaaaaa] hover:text-black dark:hover:text-white rounded text-[11px] font-mono flex items-center gap-1 transition-colors",title:"插入主标题",children:[f.jsx(hp,{className:"w-3 h-3"}),f.jsx("span",{children:"H1"})]}),f.jsxs("button",{onClick:()=>re("## 二级标题"),className:"px-2 py-1 bg-[#f5f5f5] dark:bg-[#141414] hover:bg-[#eaeaea] dark:hover:bg-[#202020] text-[#555555] dark:text-[#aaaaaa] hover:text-black dark:hover:text-white rounded text-[11px] font-mono flex items-center gap-1 transition-colors",title:"插入副标题",children:[f.jsx(xp,{className:"w-3 h-3"}),f.jsx("span",{children:"H2"})]}),f.jsx("button",{onClick:()=>re("> 引用格言名句..."),className:"px-2 py-1 bg-[#f5f5f5] dark:bg-[#141414] hover:bg-[#eaeaea] dark:hover:bg-[#202020] text-[#555555] dark:text-[#aaaaaa] hover:text-black dark:hover:text-white rounded text-[11px] font-mono transition-colors",title:"插入引用块",children:"Quote"}),f.jsxs("button",{onClick:()=>re("【第二页】"),className:"px-2 py-1 bg-blue-500/10 hover:bg-blue-500/20 text-blue-600 dark:text-blue-400 rounded text-[11px] font-mono flex items-center gap-1 transition-colors",title:"显式分页标记",children:[f.jsx(pp,{className:"w-3 h-3"}),f.jsx("span",{children:"分页面"})]})]}),f.jsx("textarea",{value:u,onChange:S=>r(S.target.value),placeholder:"在此输入 Markdown 内容,纯算法即时排版...",className:"flex-1 w-full bg-[#fafafa] dark:bg-[#0d0d0d] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-3 text-xs font-mono text-[#171717] dark:text-[#ededed] placeholder-[#999999] dark:placeholder-[#444444] resize-none focus:outline-none focus:border-black dark:focus:border-[#444444] transition-all leading-relaxed"}),f.jsxs("div",{className:"flex items-center justify-between text-[11px] text-[#888888] dark:text-[#555555] font-mono px-1",children:[f.jsxs("span",{children:["字符数: ",u.length]}),f.jsxs("span",{children:["行数: ",u.split(`
292
- `).length]})]})]}),M==="images"&&f.jsxs("div",{className:"flex-1 flex flex-col p-3 gap-3 overflow-y-auto",children:[f.jsxs("div",{className:"flex gap-2",children:[f.jsx("input",{type:"file",ref:P,onChange:H,accept:"image/*",className:"hidden"}),f.jsxs("button",{onClick:()=>P.current?.click(),disabled:ee,className:"flex-1 flex items-center justify-center gap-2 py-2.5 rounded-lg border border-dashed border-[#d4d4d4] dark:border-[#333333] hover:border-black dark:hover:border-[#555555] bg-[#fafafa] dark:bg-[#0f0f0f] hover:bg-[#f5f5f5] dark:hover:bg-[#141414] text-xs text-[#555555] dark:text-[#cccccc] hover:text-black dark:hover:text-white transition-all",children:[f.jsx(Op,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:ee?"正在上传...":"上传配图素材"})]}),f.jsx("button",{onClick:()=>c({src:"https://images.unsplash.com/photo-1579783900882-c0d3dad7b119?w=800&auto=format&fit=crop&q=80",alt:"艺术插画",caption:"示例艺术配图",x:36,y:400,width:440,height:300,captionHeight:36,layoutPreset:"auto"}),className:"px-3 py-2.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-[#fafafa] dark:bg-[#0f0f0f] hover:bg-[#f5f5f5] dark:hover:bg-[#141414] text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white transition-all",title:"插入在线示例图",children:f.jsx(Sp,{className:"w-3.5 h-3.5"})})]}),f.jsx("div",{className:"flex flex-col gap-2.5",children:s.length===0?f.jsx("div",{className:"text-center py-8 text-xs text-[#888888] dark:text-[#555555]",children:"暂无配图素材,点击上方按钮上传或插入"}):s.map((S,U)=>f.jsxs("div",{className:"bg-[#fafafa] dark:bg-[#0f0f0f] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-2.5 flex flex-col gap-2",children:[f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsx("img",{src:S.src,alt:S.alt,className:"w-12 h-12 object-cover rounded bg-[#eeeeee] dark:bg-[#1a1a1a] border border-[#e5e5e5] dark:border-[#262626] shrink-0"}),f.jsxs("div",{className:"flex-1 min-w-0",children:[f.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[f.jsxs("span",{className:"text-[10px] px-1 rounded bg-[#eaeaea] dark:bg-[#262626] font-mono text-[#555555] dark:text-[#aaaaaa] font-semibold shrink-0",children:["#",U+1]}),f.jsx("span",{className:"text-xs font-medium text-[#171717] dark:text-white truncate max-w-[120px]",children:S.caption||S.alt||`配图 #${U+1}`}),f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 font-medium shrink-0",children:["第 ",S.pageIndex||1," 页"]})]}),f.jsxs("div",{className:"text-[10px] text-[#888888] dark:text-[#666666] font-mono mt-0.5",children:[S.width," × ",S.height,"px · X: ",S.x??0,", Y: ",S.y??0]})]}),f.jsxs("div",{className:"flex items-center gap-0.5",children:[f.jsx("button",{onClick:()=>m?.(S.id,"up"),disabled:U===0,className:"p-1 text-[#888888] hover:text-black dark:hover:text-white disabled:opacity-20 rounded hover:bg-[#eeeeee] dark:hover:bg-[#1f1f1f]",title:"上移顺序 (调整在同一页中的先后次序)",children:f.jsx(cp,{className:"w-3.5 h-3.5"})}),f.jsx("button",{onClick:()=>m?.(S.id,"down"),disabled:U===s.length-1,className:"p-1 text-[#888888] hover:text-black dark:hover:text-white disabled:opacity-20 rounded hover:bg-[#eeeeee] dark:hover:bg-[#1f1f1f]",title:"下移顺序 (调整在同一页中的先后次序)",children:f.jsx(up,{className:"w-3.5 h-3.5"})}),f.jsx("button",{onClick:()=>N(S.id),className:"p-1 text-[#888888] hover:text-red-500 rounded hover:bg-[#eeeeee] dark:hover:bg-[#1f1f1f]",title:"删除该图",children:f.jsx(Eh,{className:"w-3.5 h-3.5"})})]})]}),f.jsxs("div",{className:"flex bg-[#eeeeee] dark:bg-[#1a1a1a] p-0.5 rounded text-[11px] font-medium pt-1 border-t border-[#eeeeee] dark:border-[#1a1a1a]",children:[f.jsx("button",{onClick:()=>v(S.id,{isAbsolute:!1}),className:`flex-1 py-1 rounded transition-all text-center ${S.isAbsolute?"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white":"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold"}`,children:"绕排避让 (Flow)"}),f.jsx("button",{onClick:()=>v(S.id,{isAbsolute:!0,layoutPreset:"custom",zIndex:S.zIndex??15,rotate:S.rotate??0,opacity:S.opacity??1}),className:`flex-1 py-1 rounded transition-all text-center ${S.isAbsolute?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:"自由图层 (Absolute)"})]}),f.jsxs("div",{className:"flex flex-col gap-2 text-[11px]",children:[f.jsxs("label",{className:"flex items-center gap-2",children:[f.jsx("input",{type:"checkbox",checked:S.templateAssetKey!==void 0,onChange:_=>v(S.id,{templateAssetKey:_.target.checked?`asset_${S.id.replace(/[^a-zA-Z0-9_-]/g,"_")}`:void 0,repeatEveryPage:!1})}),"固定模板素材"]}),S.templateAssetKey!==void 0&&f.jsxs(f.Fragment,{children:[f.jsxs("label",{className:"flex flex-col gap-1",children:["素材标识",f.jsx("input",{"aria-label":"素材标识",value:S.templateAssetKey,onChange:_=>v(S.id,{templateAssetKey:_.target.value}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1"})]}),s.some(_=>_.id!==S.id&&_.templateAssetKey===S.templateAssetKey)&&f.jsx("span",{role:"alert",className:"text-red-600",children:"素材标识不能重复"}),f.jsxs("label",{className:"flex items-center gap-2",children:[f.jsx("input",{type:"checkbox",disabled:!S.isAbsolute,checked:!!(S.isAbsolute&&S.repeatEveryPage),onChange:_=>v(S.id,{repeatEveryPage:_.target.checked})}),"每页重复"]}),!S.isAbsolute&&f.jsx("span",{className:"text-[#888888]",children:"每页重复仅支持自由图层,避免阻塞文字排版。"}),f.jsx("span",{className:"text-[#888888]",children:"默认保留此图,仅按素材标识明确替换。"})]}),S.isAbsolute&&f.jsxs("label",{className:"flex items-center gap-2",children:[f.jsx("input",{type:"checkbox",checked:g.includes(S.id),onChange:_=>d(S.id,_.target.checked)}),"设为整页背景"]}),f.jsx("button",{type:"button",onClick:()=>x(S.id),title:"恢复上传或应用模板时的尺寸、位置和图层设置",className:"rounded border border-[#d4d4d4] dark:border-[#333333] px-2 py-1.5 hover:bg-[#eeeeee] dark:hover:bg-[#222222]",children:"重置布局"})]}),S.isAbsolute?f.jsxs(f.Fragment,{children:[f.jsxs("div",{className:"text-[10px] text-blue-600 dark:text-blue-400 bg-blue-500/10 p-1.5 rounded flex items-center gap-1 font-medium",children:[f.jsx(So,{className:"w-3 h-3 shrink-0"}),f.jsx("span",{children:"自由定位图层:脱离文本流,不触发障碍物绕排"})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"所属页面"}),f.jsx("select",{value:S.pageIndex||1,onChange:_=>v(S.id,{pageIndex:parseInt(_.target.value,10)||1}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] focus:outline-none",children:Array.from({length:Math.max(y,2)},(_,te)=>te+1).map(_=>f.jsxs("option",{value:_,children:["第 ",_," 页 ",_===1?"(首页/封面)":""]},_))})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] mb-1",children:[f.jsx("span",{children:"层级 (Z-Index)"}),f.jsx("span",{className:"font-mono text-black dark:text-white font-semibold",children:S.zIndex??15})]}),f.jsx("div",{className:"flex gap-1",children:[{label:"底",val:0,title:"底层背景"},{label:"文字",val:10,title:"正文同层"},{label:"顶",val:20,title:"置顶贴纸"}].map(_=>f.jsx("button",{onClick:()=>v(S.id,{zIndex:_.val}),title:_.title,className:`flex-1 py-0.5 text-[10px] rounded border ${(S.zIndex??15)===_.val?"bg-black dark:bg-white text-white dark:text-black border-transparent font-bold":"border-[#d4d4d4] dark:border-[#262626] text-[#666666] dark:text-[#888888]"}`,children:_.label},_.val))})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] mb-1",children:[f.jsxs("span",{className:"flex items-center gap-0.5",children:[f.jsx(Ep,{className:"w-2.5 h-2.5"})," 旋转角度"]}),f.jsxs("span",{className:"font-mono text-black dark:text-white font-semibold",children:[S.rotate??0,"°"]})]}),f.jsx("input",{type:"range",min:"-45",max:"45",step:"1",value:S.rotate??0,onChange:_=>v(S.id,{rotate:parseInt(_.target.value,10)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded cursor-pointer mt-1"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] mb-1",children:[f.jsx("span",{children:"不透明度"}),f.jsxs("span",{className:"font-mono text-black dark:text-white font-semibold",children:[Math.round((S.opacity??1)*100),"%"]})]}),f.jsx("input",{type:"range",min:"0.1",max:"1",step:"0.05",value:S.opacity??1,onChange:_=>v(S.id,{opacity:parseFloat(_.target.value)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded cursor-pointer mt-1"})]})]}),f.jsxs("div",{className:"text-[11px]",children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"圆角半径 (px)"}),f.jsx("input",{type:"number",min:"0",step:"4",value:S.borderRadius??12,onChange:_=>v(S.id,{borderRadius:parseInt(_.target.value,10)||0}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"横向 X"}),f.jsx("input",{type:"number",step:"10",value:S.x??0,onChange:_=>v(S.id,{x:parseInt(_.target.value,10)||0}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"纵向 Y"}),f.jsx("input",{type:"number",step:"10",value:S.y??0,onChange:_=>v(S.id,{y:parseInt(_.target.value,10)||0}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"宽度 (W)"}),f.jsx("input",{type:"number",step:"10",value:S.width??420,onChange:_=>v(S.id,{width:Math.max(20,parseInt(_.target.value,10)||20)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"高度 (H)"}),f.jsx("input",{type:"number",step:"10",value:S.height??280,onChange:_=>v(S.id,{height:Math.max(20,parseInt(_.target.value,10)||20)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]})]}):f.jsxs(f.Fragment,{children:[f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"排版预设"}),f.jsxs("select",{value:S.layoutPreset||"auto",onChange:_=>v(S.id,{layoutPreset:_.target.value}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] focus:outline-none",children:[f.jsx("option",{value:"auto",children:"自适应 (Auto)"}),f.jsx("option",{value:"mid-left",children:"居左浮动 (Left)"}),f.jsx("option",{value:"mid-right",children:"居右浮动 (Right)"}),f.jsx("option",{value:"center",children:"居中横幅 (Center)"}),f.jsx("option",{value:"staggered",children:"交错排版 (Staggered)"}),f.jsx("option",{value:"corner-soft",children:"角落软着陆 (Corner)"}),f.jsx("option",{value:"fill",children:"底部填满 (Fill)"}),f.jsx("option",{value:"custom",children:"自定义坐标 (Custom)"})]})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"所属页面"}),f.jsx("select",{value:S.pageIndex||1,onChange:_=>v(S.id,{pageIndex:parseInt(_.target.value,10)||1}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] focus:outline-none",children:Array.from({length:Math.max(y,2)},(_,te)=>te+1).map(_=>f.jsxs("option",{value:_,children:["第 ",_," 页 ",_===1?"(首页/封面)":""]},_))})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"宽度 (W)"}),f.jsx("input",{type:"number",min:"50",step:"10",value:S.width??420,onChange:_=>v(S.id,{width:Math.max(50,parseInt(_.target.value,10)||50)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"高度 (H)"}),f.jsx("input",{type:"number",min:"50",step:"10",value:S.height??280,onChange:_=>v(S.id,{height:Math.max(50,parseInt(_.target.value,10)||50)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"纵向位置 Y"}),f.jsx("input",{type:"number",step:"20",value:S.y??300,onChange:_=>v(S.id,{y:parseInt(_.target.value,10)||0,layoutPreset:"custom"}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"横向坐标 X"}),f.jsx("input",{type:"number",step:"10",value:S.x??16,onChange:_=>v(S.id,{x:parseInt(_.target.value,10)||0,layoutPreset:"custom"}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] text-[11px] block mb-1",children:"图片说明 (Caption)"}),f.jsx("input",{type:"text",placeholder:"下方说明文字...",value:S.caption||"",onChange:_=>v(S.id,{caption:_.target.value}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white text-[11px] focus:outline-none"})]})]})]},S.id))})]}),M==="highlights"&&f.jsxs("div",{className:"flex-1 flex flex-col p-3 gap-3 overflow-y-auto",children:[f.jsx("div",{className:"text-xs text-[#666666] dark:text-[#888888] leading-relaxed",children:"在正文中出现的高亮词,将被算法自动匹配并渲染为品牌强调色。"}),f.jsxs("div",{className:"flex gap-2",children:[f.jsx("input",{type:"text",placeholder:"新增高亮关键词...",value:B,onChange:S=>L(S.target.value),onKeyDown:S=>S.key==="Enter"&&V(),className:"flex-1 bg-white dark:bg-[#0d0d0d] border border-[#d4d4d4] dark:border-[#222222] rounded-lg px-2.5 py-1.5 text-xs text-black dark:text-white placeholder-[#888888] dark:placeholder-[#555555] focus:outline-none focus:border-black dark:focus:border-[#444444]"}),f.jsx("button",{onClick:V,className:"px-3 py-1.5 bg-black dark:bg-[#1f1f1f] hover:bg-[#262626] text-white rounded-lg text-xs font-medium",children:"添加"})]}),f.jsx("div",{className:"flex flex-wrap gap-1.5 mt-1",children:p.map(S=>f.jsxs("span",{className:"flex items-center gap-1 px-2.5 py-1 rounded-md bg-[#f0fdf4] dark:bg-[#161616] border border-[#bbf7d0] dark:border-[#262626] text-xs text-emerald-700 dark:text-emerald-400 font-medium",children:[f.jsx(So,{className:"w-3 h-3"}),f.jsx("span",{children:S}),f.jsx("button",{onClick:()=>Y(S),className:"hover:text-red-500 ml-1",children:"×"})]},S))})]})]})},Vp=[{id:"wechat-cover-2.35",label:"微信封面",ratioTag:"3.35:1"},{id:"longform-3-4",label:"通用长图文",ratioTag:"3:4"},{id:"wide-16-9",label:"通用宽屏",ratioTag:"16:9"},{id:"square-1-1",label:"通用正方形",ratioTag:"1:1"}],Zp=({currentRatio:u,onSelectRatio:r,zoom:s,onZoomChange:c,onAutoFit:d,isAutoFit:x,onOpenTemplates:g,isTemplateDrawerOpen:v,templateName:N,onSaveTemplate:m,onOpenAuth:y,onExport:p,isExporting:b,isAuthed:w,pageCount:M,themeMode:Q,onToggleThemeMode:B})=>f.jsxs("header",{className:"h-14 border-b border-[#eaeaea] dark:border-[#222222] bg-white/80 dark:bg-[#000000]/80 backdrop-blur-md px-4 flex items-center justify-between select-none z-30 shrink-0 transition-colors",children:[f.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[f.jsxs("div",{className:"flex items-center gap-2 font-semibold text-[#171717] dark:text-white tracking-tight text-sm",children:[f.jsx("span",{className:"flex items-center justify-center w-6 h-6 rounded bg-black dark:bg-white text-white dark:text-black font-black text-xs shadow-sm",children:"▲"}),f.jsx("span",{className:"hidden 2xl:inline",children:"Typeset Studio"})]}),f.jsx("span",{className:"text-xs text-[#888888] dark:text-[#555555] font-mono hidden 2xl:inline",children:"v0.3.0"}),f.jsxs("div",{title:N||"未命名模板",className:"flex min-w-0 items-center gap-1.5 px-2 py-0.5 rounded-full bg-[#f5f5f5] dark:bg-[#111111] border border-[#e5e5e5] dark:border-[#222222] text-[11px] text-emerald-600 dark:text-[#00e676]",children:[f.jsx("span",{className:"w-1.5 h-1.5 shrink-0 rounded-full bg-emerald-500 dark:bg-[#00e676]"}),f.jsx("span",{"aria-live":"polite",className:"max-w-40 truncate",children:N||"未命名模板"})]})]}),f.jsx("div",{className:"flex items-center bg-[#f5f5f5] dark:bg-[#0a0a0a] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-0.5 shadow-inner",children:Vp.map(L=>{const P=u===L.id;return f.jsxs("button",{onClick:()=>r(L.id),className:`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-all ${P?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-[#171717] dark:hover:text-[#cccccc] hover:bg-[#eaeaea] dark:hover:bg-[#141414]"}`,children:[f.jsx("span",{className:"hidden xl:inline",children:L.label}),f.jsx("span",{className:`text-[10px] font-mono px-1 py-0.2 rounded ${P?"bg-[#eaeaea] dark:bg-[#333333] text-black dark:text-white font-semibold":"bg-[#e5e5e5] dark:bg-[#181818] text-[#777777] dark:text-[#666666]"}`,children:L.ratioTag})]},L.id)})}),f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsxs("div",{className:"flex items-center bg-[#f5f5f5] dark:bg-[#0a0a0a] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-0.5 text-xs text-[#666666] dark:text-[#888888]",children:[f.jsx("button",{onClick:()=>c(Math.max(.2,Number((s-.05).toFixed(2)))),className:"p-1 hover:text-black dark:hover:text-white rounded hover:bg-[#e8e8e8] dark:hover:bg-[#1f1f1f]",title:"缩小",children:f.jsx(Bp,{className:"w-3.5 h-3.5"})}),f.jsxs("span",{onDoubleClick:d,className:"w-11 text-center font-mono text-[11px] text-[#333333] dark:text-[#cccccc] cursor-pointer hover:underline select-none",title:"双击恢复自适应",children:[Math.round(s*100),"%"]}),f.jsx("button",{onClick:()=>c(Math.min(1.5,Number((s+.05).toFixed(2)))),className:"p-1 hover:text-black dark:hover:text-white rounded hover:bg-[#e8e8e8] dark:hover:bg-[#1f1f1f]",title:"放大",children:f.jsx(kh,{className:"w-3.5 h-3.5"})}),d&&f.jsxs(f.Fragment,{children:[f.jsx("div",{className:"w-[1px] h-3 bg-[#e0e0e0] dark:bg-[#262626] mx-0.5"}),f.jsxs("button",{onClick:d,className:`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-all ${x?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-xs font-semibold":"hover:text-black dark:hover:text-white hover:bg-[#e8e8e8] dark:hover:bg-[#1f1f1f]"}`,title:M>1?"缩放至视口内完整排列多张图片(瀑布流平铺)":"自适应画布大小",children:[f.jsx(vp,{className:"w-3 h-3"}),f.jsx("span",{children:M>1?"多图平铺":"自适应"})]})]})]}),f.jsx("button",{onClick:B,className:"p-2 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] hover:bg-[#f5f5f5] dark:hover:bg-[#161616] text-[#444444] dark:text-[#cccccc] transition-all btn-vercel",title:Q==="light"?"切换至深色模式":"切换至浅色模式",children:Q==="light"?f.jsx(yp,{className:"w-3.5 h-3.5 text-[#555555]"}):f.jsx(kp,{className:"w-3.5 h-3.5 text-amber-400"})}),f.jsxs("button",{onClick:g,"aria-expanded":v,className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] hover:bg-[#f5f5f5] dark:hover:bg-[#161616] text-xs text-[#333333] dark:text-[#cccccc] hover:text-black dark:hover:text-white transition-all btn-vercel",children:[f.jsx(dp,{className:"w-3.5 h-3.5 text-[#777777] dark:text-[#888888]"}),f.jsx("span",{children:"模板库"})]}),f.jsxs("button",{onClick:m,className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] hover:bg-[#f5f5f5] dark:hover:bg-[#161616] text-xs text-[#333333] dark:text-[#cccccc] transition-all btn-vercel",children:[f.jsx(dh,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:"保存模板"})]}),f.jsxs("button",{onClick:p,disabled:b,className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-black text-white hover:bg-[#262626] dark:bg-white dark:text-black dark:hover:bg-[#eaeaea] text-xs font-semibold transition-all btn-vercel shadow-sm disabled:opacity-50",children:[b?f.jsx(ch,{className:"w-3.5 h-3.5 animate-spin"}):f.jsx(op,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:b?"导出中...":"导出图片"}),M>1&&f.jsxs("span",{className:"text-[10px] bg-white/20 dark:bg-black text-white px-1.5 py-0.2 rounded font-mono",children:[M,"P"]})]}),f.jsx("button",{onClick:y,className:`p-1.5 rounded-lg border transition-all btn-vercel ${w?"border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] text-[#777777] dark:text-[#888888] hover:text-black dark:hover:text-white hover:bg-[#f5f5f5] dark:hover:bg-[#161616]":"border-amber-500/50 bg-amber-500/10 text-amber-600 dark:text-amber-400"}`,title:w?"超管密钥已就绪":"配置超管密钥",children:f.jsx(eh,{className:"w-3.5 h-3.5"})})]})]});function Kp(){const[u,r]=fe.useState([]),[s,c]=fe.useState(!1),d=fe.useCallback(async(x=!1)=>{try{c(!0);const g=await fetch(`/api/fonts${x?"?refresh=1":""}`);if(!g.ok)return;const v=await g.json();if(!v.ok||!Array.isArray(v.fonts))return;r(v.fonts);let N=!1;if(typeof window<"u"&&"FontFace"in window&&document.fonts)for(const m of v.fonts)try{let y=!1;const p=[];if(document.fonts.forEach(b=>{(b.family===m.family||b.family===`"${m.family}"`)&&(y=!0,p.push(b))}),x&&(p.forEach(b=>document.fonts.delete(b)),y=!1),!y){const w=await new FontFace(m.family,`url(${m.url}${x?`?v=${Date.now()}`:""})`).load();document.fonts.add(w),N=!0}}catch(y){console.warn(`[useLocalFonts] Failed to load web font ${m.family}:`,y)}N&&window.dispatchEvent(new Event("typeset-fonts-loaded"))}catch(g){console.warn("[useLocalFonts] Failed to fetch local fonts:",g)}finally{c(!1)}},[]);return fe.useEffect(()=>{d()},[d]),{fonts:u,loading:s,refreshFonts:()=>d(!0)}}const mo="w-full rounded border border-[#dfdfdf] dark:border-[#333333] bg-white dark:bg-[#141414] px-2 py-1 text-[11px]";function Jp({config:u,onChange:r}){const s=u.canvasStyle||{},c=s.fill||u.coverTheme?.background.fill||{type:"solid",color:u.theme.bgColor},d=s.pattern||u.coverTheme?.decoration||_p,x=s.border||Rp,g=b=>r({...s,fill:b}),v=b=>r({...s,pattern:{...d,...b}}),N=b=>r({...s,border:{...x,...b}}),m=(b,w,M)=>f.jsxs("label",{className:"flex items-center justify-between gap-2",children:[f.jsx("span",{children:b}),f.jsxs("span",{className:"flex items-center gap-1.5 font-mono",children:[f.jsx("span",{children:w}),f.jsx("input",{"aria-label":b,type:"color",value:w,onChange:Q=>M(Q.target.value),className:"h-6 w-7 cursor-pointer bg-transparent"})]})]}),y=(b,w,M,Q,B,L=1)=>f.jsxs("label",{className:"flex flex-col gap-1",children:[f.jsxs("span",{className:"flex justify-between",children:[f.jsx("span",{children:b}),f.jsx("span",{className:"font-mono",children:L<1?`${Math.round(w*100)}%`:w})]}),f.jsx("input",{"aria-label":b,type:"range",min:M,max:Q,step:L,value:w,onChange:P=>B(Number(P.target.value)),className:"w-full accent-emerald-600"})]}),p=b=>{const w=c.type==="solid"?c.color:c.stops[0].color,M=c.type==="solid"?[{color:w,offset:0},{color:u.theme.accentColor,offset:100}]:c.stops;g(b==="solid"?{type:b,color:w}:b==="linear"?{type:b,angle:90,stops:M}:{type:b,position:{x:50,y:30},stops:M})};return f.jsxs("section",{className:"border-b border-[#f0f0f0] dark:border-[#1c1c1c] p-3.5 text-xs",children:[f.jsx("div",{className:"mb-3 font-semibold text-[#171717] dark:text-white",children:"背景、花纹与边框"}),f.jsxs("div",{className:"flex flex-col gap-3 text-[11px] text-[#666666] dark:text-[#aaaaaa]",children:[f.jsxs("label",{className:"flex flex-col gap-1",children:["背景类型",f.jsxs("select",{className:mo,value:c.type,onChange:b=>p(b.target.value),children:[f.jsx("option",{value:"solid",children:"纯色"}),f.jsx("option",{value:"linear",children:"线性渐变"}),f.jsx("option",{value:"radial",children:"径向渐变"})]})]}),c.type==="solid"?m("背景颜色",c.color,b=>g({type:"solid",color:b})):f.jsxs(f.Fragment,{children:[f.jsxs("div",{className:"flex flex-col gap-2 rounded border border-[#eaeaea] dark:border-[#333333] p-2",children:[c.stops.map((b,w)=>f.jsxs("div",{className:"flex flex-col gap-1.5",children:[f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsxs("label",{className:"flex flex-1 items-center gap-1.5",children:[f.jsx("input",{"aria-label":`渐变颜色 ${w+1}`,type:"color",value:b.color,onChange:M=>g({...c,stops:c.stops.map((Q,B)=>B===w?{...Q,color:M.target.value}:Q)}),className:"h-6 w-7 bg-transparent"}),f.jsx("span",{className:"font-mono",children:b.color})]}),f.jsx("button",{type:"button",disabled:c.stops.length<=2,onClick:()=>g({...c,stops:c.stops.filter((M,Q)=>Q!==w)}),className:"disabled:opacity-30","aria-label":`删除渐变颜色 ${w+1}`,children:"移除"})]}),y(`节点 ${w+1} 位置`,b.offset,0,100,M=>g({...c,stops:c.stops.map((Q,B)=>B===w?{...Q,offset:M}:Q)}))]},w)),f.jsx("button",{type:"button",disabled:c.stops.length>=8,onClick:()=>g({...c,stops:[...c.stops,{color:u.theme.accentColor,offset:50}]}),className:"rounded border border-[#dfdfdf] dark:border-[#333333] py-1 disabled:opacity-30",children:"添加颜色节点"})]}),c.type==="linear"?y("渐变角度",c.angle,0,360,b=>g({...c,angle:b})):f.jsxs(f.Fragment,{children:[y("渐变中心 X",c.position.x,0,100,b=>g({...c,position:{...c.position,x:b}})),y("渐变中心 Y",c.position.y,0,100,b=>g({...c,position:{...c.position,y:b}}))]})]}),f.jsxs("label",{className:"flex flex-col gap-1",children:["几何花纹",f.jsx("select",{className:mo,value:d.pattern,onChange:b=>v({pattern:b.target.value}),children:Object.entries(Fh).map(([b,w])=>f.jsx("option",{value:b,children:w},b))})]}),d.pattern!=="none"&&f.jsxs(f.Fragment,{children:[m("花纹颜色",d.color,b=>v({color:b})),y("花纹透明度",d.opacity,0,1,b=>v({opacity:b}),.01),y("花纹间距",d.size,16,240,b=>v({size:b}))]}),f.jsxs("label",{className:"flex flex-col gap-1",children:["边框样式",f.jsx("select",{className:mo,value:x.style,onChange:b=>N({style:b.target.value}),children:Object.entries(jh).map(([b,w])=>f.jsx("option",{value:b,children:w},b))})]}),x.style!=="none"&&f.jsxs(f.Fragment,{children:[m("边框颜色",x.color,b=>N({color:b})),x.style==="gradient"&&m("边框渐变终色",x.endColor,b=>N({endColor:b})),y("边框粗细",x.width,1,24,b=>N({width:b})),y("边框内缩",x.inset,0,200,b=>N({inset:b})),x.style!=="corners"&&y("边框圆角",x.radius,0,200,b=>N({radius:b})),y("边框透明度",x.opacity,0,1,b=>N({opacity:b}),.01)]}),f.jsx("p",{className:"leading-relaxed text-[#888888]",children:"配置随模板保存,作用于每页。背景图会覆盖底色与花纹;边框绘制在最上层。"})]})]})}const yx=[{label:"苹方 / 极简黑体 (默认清爽)",value:"PingFang SC"},{label:"思源黑体 (现代极简·粗黑)",value:"Noto Sans SC"},{label:"典雅宋体 (经典报刊·书卷)",value:"Songti SC"},{label:"思源宋体 (高阶报刊·典雅)",value:"Noto Serif SC"},{label:"人文楷体 (温润随笔·手写)",value:"Kaiti SC"},{label:"柔和圆体 (亲和灵动·现代)",value:"Yuanti SC"},{label:"Inter / 国际西文无衬线",value:"Inter"},{label:"Georgia / 文艺西文衬线",value:"Georgia"}],Ip=({config:u,onUpdateAlgorithm:r,onUpdateTheme:s,onUpdateTypography:c,onUpdateSafeArea:d,onUpdateBranding:x,onUpdateChrome:g,onUpdateCanvasStyle:v})=>{const{algorithm:N,theme:m,typography:y}=u,{fonts:p,loading:b,refreshFonts:w}=Kp();return f.jsxs("aside",{className:"w-80 border-l border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] flex flex-col shrink-0 select-none overflow-y-auto transition-colors",children:[f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(rp,{className:"w-3.5 h-3.5 text-blue-500 dark:text-blue-400"}),f.jsx("span",{children:"文字对齐与空间居中"})]}),f.jsxs("div",{className:"flex flex-col gap-3 text-xs",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1.5 font-medium",children:"垂直排版对齐 (封面必备)"}),f.jsx("div",{className:"grid grid-cols-3 gap-1 bg-[#f5f5f5] dark:bg-[#141414] p-1 rounded-lg border border-[#e5e5e5] dark:border-[#262626]",children:[{id:"top",label:"顶端对齐"},{id:"center",label:"垂直居中"},{id:"bottom",label:"底端对齐"}].map(M=>f.jsx("button",{onClick:()=>r({verticalAlign:M.id}),className:`py-1 text-[11px] rounded transition-all font-medium ${(N.verticalAlign||"top")===M.id?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:M.label},M.id))})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1.5 font-medium",children:"水平排版对齐"}),f.jsxs("div",{className:"grid grid-cols-3 gap-1 bg-[#f5f5f5] dark:bg-[#141414] p-1 rounded-lg border border-[#e5e5e5] dark:border-[#262626]",children:[f.jsxs("button",{onClick:()=>r({textAlign:"left"}),className:`py-1 flex items-center justify-center gap-1 text-[11px] rounded transition-all font-medium ${(N.textAlign||"left")==="left"?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:[f.jsx(jp,{className:"w-3 h-3"}),f.jsx("span",{children:"居左"})]}),f.jsxs("button",{onClick:()=>r({textAlign:"center"}),className:`py-1 flex items-center justify-center gap-1 text-[11px] rounded transition-all font-medium ${N.textAlign==="center"?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:[f.jsx(Fp,{className:"w-3 h-3"}),f.jsx("span",{children:"居中"})]}),f.jsxs("button",{onClick:()=>r({textAlign:"right"}),className:`py-1 flex items-center justify-center gap-1 text-[11px] rounded transition-all font-medium ${N.textAlign==="right"?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:[f.jsx(Tp,{className:"w-3 h-3"}),f.jsx("span",{children:"居右"})]})]})]})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center justify-between text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsx(Dp,{className:"w-3.5 h-3.5 text-indigo-500 dark:text-indigo-400"}),f.jsx("span",{children:"字体与排版字阶"})]}),f.jsx("button",{onClick:()=>w(),disabled:b,title:"重新扫描 public/fonts 目录",className:"p-1 text-[#888888] hover:text-black dark:hover:text-white rounded hover:bg-[#eaeaea] dark:hover:bg-[#222222] transition-colors",children:f.jsx(ch,{className:`w-3 h-3 ${b?"animate-spin text-blue-500":""}`})})]}),f.jsxs("div",{className:"flex flex-col gap-3 text-xs",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1",children:"标题字体 (Heading Font)"}),f.jsxs("select",{value:y.headingFont,onChange:M=>c({headingFont:M.target.value}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded-md px-2 py-1.5 text-black dark:text-white text-xs focus:outline-none",children:[p.length>0&&f.jsx("optgroup",{label:"✨ 项目本地字体 (public/fonts)",children:p.map(M=>f.jsx("option",{value:M.family,children:M.label},`head-local-${M.family}`))}),f.jsx("optgroup",{label:"🌐 系统 / 云端预设",children:yx.map(M=>f.jsx("option",{value:M.value,children:M.label},`head-preset-${M.value}`))})]})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1",children:"正文字体 (Body Font)"}),f.jsxs("select",{value:y.bodyFont,onChange:M=>c({bodyFont:M.target.value}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded-md px-2 py-1.5 text-black dark:text-white text-xs focus:outline-none",children:[p.length>0&&f.jsx("optgroup",{label:"✨ 项目本地字体 (public/fonts)",children:p.map(M=>f.jsx("option",{value:M.family,children:M.label},`body-local-${M.family}`))}),f.jsx("optgroup",{label:"🌐 系统 / 云端预设",children:yx.map(M=>f.jsx("option",{value:M.value,children:M.label},`body-preset-${M.value}`))})]})]}),p.length===0?f.jsx("div",{className:"text-[10px] text-[#888888] dark:text-[#666666] flex items-center justify-between pt-1 border-t border-[#f5f5f5] dark:border-[#1a1a1a]",children:f.jsxs("span",{children:["💡 将 .ttf / .otf 放入 ",f.jsx("code",{children:"public/fonts/"})," 即可识别"]})}):f.jsx("div",{className:"text-[10px] text-emerald-600 dark:text-emerald-400 flex items-center justify-between pt-1 border-t border-[#f5f5f5] dark:border-[#1a1a1a]",children:f.jsxs("span",{children:["✨ 已加载 ",p.length," 个项目本地字体"]})})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(wp,{className:"w-3.5 h-3.5 text-blue-500 dark:text-blue-400"}),f.jsx("span",{children:"字号与比例参数"})]}),f.jsxs("div",{className:"flex flex-col gap-3.5 text-xs",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"基准字号 (Base Size)"}),f.jsxs("span",{className:"text-[#171717] dark:text-white font-semibold",children:[N.baseFontSize,"px"]})]}),f.jsx("input",{type:"range",min:"24",max:"96",step:"1",value:N.baseFontSize,onChange:M=>r({baseFontSize:parseInt(M.target.value,10)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"比例字阶系数 (大标题倍率)"}),f.jsxs("span",{className:"text-[#171717] dark:text-white font-semibold",children:[N.scaleRatio.toFixed(2),"x"]})]}),f.jsx("input",{type:"range",min:"1.15",max:"1.6",step:"0.01",value:N.scaleRatio,onChange:M=>r({scaleRatio:parseFloat(M.target.value)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"行高舒展倍率"}),f.jsx("span",{className:"text-[#171717] dark:text-white font-semibold",children:N.lineHeightMultiplier.toFixed(2)})]}),f.jsx("input",{type:"range",min:"1.2",max:"1.8",step:"0.02",value:N.lineHeightMultiplier,onChange:M=>r({lineHeightMultiplier:parseFloat(M.target.value)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"配图避让间隙 (Gap)"}),f.jsxs("span",{className:"text-[#171717] dark:text-white font-semibold",children:[N.obstacleGap,"px"]})]}),f.jsx("input",{type:"range",min:"12",max:"48",step:"2",value:N.obstacleGap,onChange:M=>r({obstacleGap:parseInt(M.target.value,10)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(Mp,{className:"w-3.5 h-3.5 text-emerald-600 dark:text-emerald-400"}),f.jsx("span",{children:"版心安全边距"})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px] font-mono",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"上边距 (Top)"}),f.jsx("input",{type:"number",value:N.safeArea.top,onChange:M=>d({top:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"下边距 (Bottom)"}),f.jsx("input",{type:"number",value:N.safeArea.bottom,onChange:M=>d({bottom:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"左边距 (Left)"}),f.jsx("input",{type:"number",value:N.safeArea.left,onChange:M=>d({left:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"右边距 (Right)"}),f.jsx("input",{type:"number",value:N.safeArea.right,onChange:M=>d({right:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(Np,{className:"w-3.5 h-3.5 text-purple-600 dark:text-purple-400"}),f.jsx("span",{children:"视觉色彩主题"})]}),f.jsxs("div",{className:"flex flex-col gap-2.5 text-xs",children:[f.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[f.jsx("button",{onClick:()=>s({bgColor:"#ffffff",textColor:"#171717",headingColor:"#171717",accentColor:"#059669",quoteColor:"#525252",cardBg:"#f5f5f5"}),className:"w-6 h-6 rounded-full bg-[#ffffff] border-2 border-emerald-500 shadow-sm hover:scale-105 transition-all",title:"素白雅致 (推荐)"}),f.jsx("button",{onClick:()=>s({bgColor:"#f9fcfa",textColor:"#22201d",headingColor:"#0f2e22",accentColor:"#1d4f39",quoteColor:"#474038",cardBg:"#ffffff"}),className:"w-6 h-6 rounded-full bg-[#f9fcfa] border border-[#ccc] shadow-sm hover:scale-105 transition-all",title:"纸白浅草"}),f.jsx("button",{onClick:()=>s({bgColor:"#0a0a0a",textColor:"#ededed",headingColor:"#ffffff",accentColor:"#00e676",quoteColor:"#a0a0a0",cardBg:"#121212"}),className:"w-6 h-6 rounded-full bg-[#0a0a0a] border border-[#444] shadow-sm hover:scale-105 transition-all",title:"深邃暗夜"}),f.jsx("button",{onClick:()=>s({bgColor:"#09090b",textColor:"#fafafa",headingColor:"#ffffff",accentColor:"#3b82f6",quoteColor:"#a1a1aa",cardBg:"#18181b"}),className:"w-6 h-6 rounded-full bg-[#09090b] border border-blue-500 shadow-sm hover:scale-105 transition-all",title:"数码蓝暗黑"})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] font-medium",children:"标题颜色 (Heading)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:m.headingColor||m.textColor,onChange:M=>s({headingColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.headingColor||m.textColor})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888]",children:"正文字色 (Text)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:m.textColor,onChange:M=>s({textColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.textColor})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888]",children:"重点强调色 (Accent)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:m.accentColor,onChange:M=>s({accentColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.accentColor})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888]",children:"背景底色 (Canvas)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:u.canvasStyle?.fill?.type==="solid"?u.canvasStyle.fill.color:m.bgColor,onChange:M=>s({bgColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.bgColor})]})]})]})]}),f.jsx(Jp,{config:u,onChange:v}),f.jsxs("div",{className:"p-3.5",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(sp,{className:"w-3.5 h-3.5 text-amber-500 dark:text-amber-400"}),f.jsx("span",{children:"页眉页脚与版式装饰 (Chrome)"})]}),f.jsxs("div",{className:"flex flex-col gap-3 text-xs",children:[f.jsxs("div",{className:"bg-[#f9f9f9] dark:bg-[#141414] p-2.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] flex flex-col gap-2",children:[f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"font-semibold text-[#333333] dark:text-[#cccccc] text-[11px]",children:"顶部栏 (Header)"}),f.jsxs("label",{className:"flex items-center gap-1.5 cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showHeader??!!u.watermarkText?.trim(),onChange:M=>g({showHeader:M.target.checked}),className:"rounded text-emerald-500 accent-emerald-500 cursor-pointer"}),f.jsx("span",{className:"text-[10px] text-[#666666] dark:text-[#888888]",children:"启用"})]})]}),(u.chrome?.showHeader??!!u.watermarkText?.trim())&&f.jsxs("div",{className:"flex flex-col gap-2 pl-2 border-l-2 border-[#e0e0e0] dark:border-[#2a2a2a] mt-1",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex items-center justify-between mb-1",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"水印 / 品牌标识"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showWatermark??!0,onChange:M=>g({showWatermark:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]}),f.jsx("input",{type:"text",value:u.watermarkText,onChange:M=>x(u.footerText,M.target.value),placeholder:"作者水印/标识文本...",className:"w-full bg-white dark:bg-[#0a0a0a] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white text-[11px]"})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"页码角标 (P.01)"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showPageNumber??u.aspectRatio==="longform-3-4",onChange:M=>g({showPageNumber:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]})]})]}),f.jsxs("div",{className:"bg-[#f9f9f9] dark:bg-[#141414] p-2.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] flex flex-col gap-2",children:[f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"font-semibold text-[#333333] dark:text-[#cccccc] text-[11px]",children:"底部栏 (Footer)"}),f.jsxs("label",{className:"flex items-center gap-1.5 cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFooter??!!u.footerText?.trim(),onChange:M=>g({showFooter:M.target.checked}),className:"rounded text-emerald-500 accent-emerald-500 cursor-pointer"}),f.jsx("span",{className:"text-[10px] text-[#666666] dark:text-[#888888]",children:"启用"})]})]}),(u.chrome?.showFooter??!!u.footerText?.trim())&&f.jsxs("div",{className:"flex flex-col gap-2 pl-2 border-l-2 border-[#e0e0e0] dark:border-[#2a2a2a] mt-1",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex items-center justify-between mb-1",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"页脚署名 / 版权"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFooterText??!0,onChange:M=>g({showFooterText:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]}),f.jsx("input",{type:"text",value:u.footerText,onChange:M=>x(M.target.value,u.watermarkText),placeholder:"页脚版权/署名...",className:"w-full bg-white dark:bg-[#0a0a0a] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white text-[11px]"})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"顶部分割细线"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFooterDivider??!!u.footerText?.trim(),onChange:M=>g({showFooterDivider:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"算法填充率提示"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFillRatio??!1,onChange:M=>g({showFillRatio:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]})]})]})]})]})]})},Wp=({isOpen:u,onClose:r,refreshKey:s,onApplyTemplate:c,adminKey:d})=>{const[x,g]=fe.useState([]),[v,N]=fe.useState({}),[m,y]=fe.useState("default"),[p,b]=fe.useState("all"),[w,M]=fe.useState(!1),[Q,B]=fe.useState(null),L=async(H=m)=>{try{const V=await fetch(`/api/templates/slots?account=${encodeURIComponent(H)}`,{headers:{"x-admin-key":d}}),Y=await V.json();if(!V.ok||!Y.ok)throw new Error(Y.message||Y.error||"获取槽位失败");Y.ok&&Y.slots&&N(Y.slots)}catch(V){B(V instanceof Error?V.message:"模板请求失败")}},P=async(H,V)=>{try{const Y=await fetch("/api/templates/slots",{method:"POST",headers:{"Content-Type":"application/json",...d?{"x-admin-key":d}:{}},body:JSON.stringify({slot:H,templateId:V,account:m})}),S=await Y.json();if(!Y.ok||!S.ok)throw new Error(S.message||S.error||"设置默认模板失败");S.ok&&await L(m)}catch(Y){B(Y instanceof Error?Y.message:"模板请求失败")}},ee=async()=>{M(!0),B(null);try{const H=await fetch("/api/templates",{headers:d?{"x-admin-key":d}:{}}),V=await H.json();H.ok&&V.ok&&Array.isArray(V.templates)?g(V.templates):B(V.message||"获取模板失败,请检查密钥")}catch{B("连接后端服务失败")}finally{M(!1)}};fe.useEffect(()=>{u&&(ee(),L(m))},[u,m,d,s]),fe.useEffect(()=>{if(!u)return;const H=V=>{V.key==="Escape"&&!document.querySelector("dialog[open]")&&r()};return window.addEventListener("keydown",H),()=>window.removeEventListener("keydown",H)},[u,r]);const ce=async H=>{try{const V=await fetch(`/api/templates/${encodeURIComponent(H)}`,{method:"DELETE",headers:d?{"x-admin-key":d}:{}}),Y=await V.json();if(!V.ok||!Y.ok)throw new Error(Y.message||Y.error||"删除模板失败");g(S=>S.filter(U=>U.id!==H)),await L(m)}catch(V){B(V instanceof Error?V.message:"模板请求失败")}};if(!u)return null;const re=x.filter(H=>p==="all"?!0:H.slot===p);return f.jsxs("aside",{"aria-label":"模板库",className:"absolute inset-y-0 right-0 z-40 w-80 max-w-full bg-white dark:bg-[#0f0f0f] border-l border-[#eaeaea] dark:border-[#262626] flex flex-col shadow-xl overflow-hidden",children:[f.jsxs("div",{className:"flex items-center justify-between px-5 py-3.5 border-b border-[#eaeaea] dark:border-[#222222]",children:[f.jsxs("div",{className:"flex items-center gap-2 font-semibold text-sm text-[#171717] dark:text-white",children:[f.jsx(So,{className:"w-4 h-4 text-emerald-500 dark:text-emerald-400"}),f.jsx("span",{children:"模板库"})]}),f.jsx("button",{onClick:r,"aria-label":"关闭模板库",className:"text-[#888888] hover:text-black dark:hover:text-white p-1 rounded-md hover:bg-[#f5f5f5] dark:hover:bg-[#1a1a1a]",children:f.jsx(jo,{className:"w-4 h-4"})})]}),f.jsxs("div",{className:"p-3 flex-1 min-h-0 flex flex-col gap-4 overflow-y-auto",children:[Q&&f.jsx("div",{role:"alert",className:"text-xs text-red-500 bg-red-500/10 p-2 rounded border border-red-500/20",children:Q}),f.jsxs("div",{className:"flex flex-col gap-2",children:[f.jsx("div",{className:"flex items-center justify-between text-xs",children:f.jsxs("div",{className:"flex items-center gap-1.5 font-medium text-[#666666] dark:text-[#888888]",children:[f.jsx("span",{children:"槽位账号:"}),f.jsxs("select",{value:m,onChange:H=>y(H.target.value),className:"bg-white dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#2a2a2a] rounded px-2 py-0.5 text-xs text-black dark:text-white focus:outline-none font-mono",children:[f.jsx("option",{value:"default",children:"default (主账号)"}),f.jsx("option",{value:"ancientone",children:"ancientone"})]})]})}),f.jsxs("div",{className:"flex flex-wrap items-center gap-1 text-xs",children:[f.jsx("button",{onClick:()=>b("all"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="all"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"全部"}),f.jsx("button",{onClick:()=>b("article_cover"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="article_cover"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"文章封面"}),f.jsx("button",{onClick:()=>b("newspic_cover"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="newspic_cover"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"贴图封面"}),f.jsx("button",{onClick:()=>b("newspic_content"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="newspic_content"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"贴图内容"})]})]}),f.jsx("div",{className:"flex flex-col gap-2",children:w?f.jsx("div",{className:"text-center py-8 text-xs text-[#888888] dark:text-[#555555]",children:"正在加载模板..."}):re.length===0?f.jsx("div",{className:"text-center py-8 text-xs text-[#888888] dark:text-[#555555]",children:"暂无匹配模板"}):re.map(H=>{const V=v.article_cover?.id===H.id,Y=v.newspic_cover?.id===H.id,S=v.newspic_content?.id===H.id;return f.jsxs("div",{className:"flex flex-col justify-between p-3 rounded-lg bg-[#fafafa] dark:bg-[#141414] border border-[#eaeaea] dark:border-[#222222] hover:border-[#cccccc] dark:hover:border-[#333333] transition-all gap-2 group",children:[f.jsxs("div",{className:"flex items-center gap-3",children:[f.jsx("div",{className:"w-5 h-5 rounded border border-[#d4d4d4] dark:border-[#333333] shrink-0",style:{backgroundColor:H.theme.bgColor}}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[f.jsx("span",{className:"text-xs font-semibold text-[#171717] dark:text-white",children:H.name}),H.slot&&f.jsx("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/20 font-medium",children:H.slot==="article_cover"?"文章封面":H.slot==="newspic_cover"?"贴图封面":"贴图内容"}),V&&f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/20 font-medium flex items-center gap-0.5",children:[f.jsx(ho,{className:"w-2.5 h-2.5 fill-amber-500"})," 文章封面默认"]}),Y&&f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/20 font-medium flex items-center gap-0.5",children:[f.jsx(ho,{className:"w-2.5 h-2.5 fill-amber-500"})," 贴图封面默认"]}),S&&f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 font-medium flex items-center gap-0.5",children:[f.jsx(ho,{className:"w-2.5 h-2.5 fill-emerald-500"})," 贴图内容默认"]})]}),f.jsxs("div",{className:"text-[10px] text-[#888888] dark:text-[#666666] font-mono mt-0.5",children:[H.aspectRatio," • 字号: ",H.algorithm.baseFontSize,"px",H.images&&H.images.length>0&&` • 配图: ${H.images.length}个`]})]})]}),f.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[H.id&&f.jsxs("select",{value:"",onChange:U=>{U.target.value&&P(U.target.value,H.id)},className:"text-[11px] bg-white dark:bg-[#1a1a1a] border border-[#d4d4d4] dark:border-[#333333] text-[#666666] dark:text-[#aaaaaa] rounded px-2 py-1 focus:outline-none",title:"为此账号设为某个槽位的默认模板",children:[f.jsx("option",{value:"",children:"设为槽位默认..."}),f.jsx("option",{value:"article_cover",children:"设为「文章封面默认」"}),f.jsx("option",{value:"newspic_cover",children:"设为「贴图封面默认」"}),f.jsx("option",{value:"newspic_content",children:"设为「贴图内容默认」"})]}),f.jsxs("button",{onClick:()=>{c(H)},className:"flex items-center gap-1 px-2.5 py-1 bg-white dark:bg-[#1f1f1f] hover:bg-emerald-50 dark:hover:bg-emerald-500/20 text-[#333333] dark:text-[#cccccc] hover:text-emerald-700 dark:hover:text-emerald-400 border border-[#d4d4d4] dark:border-[#2a2a2a] hover:border-emerald-500/40 rounded text-xs transition-all font-medium",children:[f.jsx(Qx,{className:"w-3 h-3"}),f.jsx("span",{children:"套用"})]}),H.id&&!H.id.startsWith("tpl_wechat_")&&!H.id.startsWith("tpl_longform_")&&!H.id.startsWith("tpl_square_")&&!H.id.startsWith("tpl_wide_")&&f.jsx("button",{onClick:()=>ce(H.id),className:"p-1 text-[#888888] dark:text-[#555555] hover:text-red-500 rounded hover:bg-[#f0f0f0] dark:hover:bg-[#1f1f1f]",title:"删除自定义模板",children:f.jsx(Eh,{className:"w-3.5 h-3.5"})})]})]},H.id)})})]})]})};function Cr(u=[]){if(!Array.isArray(u))throw new RangeError("模板图片必须是数组");const r=new Set;for(const s of u){if(!s||typeof s!="object")throw new RangeError("无效的模板图片");if(s.templateAssetKey===void 0)continue;const c=s.templateAssetKey;if(s.repeatEveryPage!==void 0&&typeof s.repeatEveryPage!="boolean")throw new RangeError(`素材 ${c} 的每页重复开关必须是布尔值`);if(typeof c!="string"||!/^[a-zA-Z0-9_-]+$/.test(c))throw new RangeError("素材标识只能包含字母、数字、下划线和短横线");if(s.repeatEveryPage&&!s.isAbsolute)throw new RangeError(`素材 ${c} 的每页重复仅支持自由定位模式`);if(r.has(c))throw new RangeError(`重复的模板素材标识:${c}`);r.add(c)}}function $p(u,r=[],s={}){if(Cr(r),!s||typeof s!="object"||Array.isArray(s))throw new RangeError("素材替换必须是标识到图片地址的映射");const c=r.filter(v=>v.templateAssetKey);for(const[v,N]of Object.entries(s)){if(!c.some(m=>m.templateAssetKey===v))throw new RangeError(`未知模板素材:${v}`);if(typeof N!="string"||!N.trim())throw new RangeError(`素材 ${v} 的替换图片不能为空`)}const d=u.filter(v=>!v.templateAssetKey),x=r.filter(v=>!v.templateAssetKey);return[...d.length===0?x.map(v=>({...v,id:`img_${crypto.randomUUID()}`})):d.map((v,N)=>{const m=x[N];return m?{...v,layoutPreset:m.layoutPreset??v.layoutPreset,isAbsolute:m.isAbsolute??v.isAbsolute,x:m.x??v.x,y:m.y??v.y,width:m.width??v.width,height:m.height??v.height,rotate:m.rotate??v.rotate,opacity:m.opacity??v.opacity,zIndex:m.zIndex??v.zIndex,borderRadius:m.borderRadius??v.borderRadius,captionHeight:m.captionHeight??v.captionHeight,pageIndex:m.pageIndex??v.pageIndex}:v}),...c.map(v=>({...v,src:Object.hasOwn(s,v.templateAssetKey)?s[v.templateAssetKey]:v.src}))]}const Pp=({isOpen:u,onClose:r,currentConfig:s,onSaved:c,adminKey:d})=>{const x=fe.useRef(null),[g,v]=fe.useState(""),[N,m]=fe.useState("none"),[y,p]=fe.useState(!1),[b,w]=fe.useState(null);fe.useEffect(()=>{u?(v(s.name||"我的自定义模板"),m(s.slot||(s.aspectRatio==="wechat-cover-2.35"?"article_cover":"newspic_content")),w(null),x.current?.showModal()):x.current?.close()},[u]);const M=async Q=>{if(Q.preventDefault(),!(!g.trim()||y)){p(!0),w(null);try{Cr(s.images);const B=await fetch("/api/templates",{method:"POST",headers:{"Content-Type":"application/json",...d?{"x-admin-key":d}:{}},body:JSON.stringify({...s,id:void 0,name:g.trim(),slot:N==="none"?void 0:N})}),L=await B.json();if(!B.ok||!L.ok)throw new Error(L.message||L.error||"保存模板失败");c(L.template),r()}catch(B){w(B instanceof Error?B.message:"保存模板请求异常")}finally{p(!1)}}};return f.jsx("dialog",{ref:x,"aria-labelledby":"save-template-title",onCancel:Q=>{Q.preventDefault(),y||r()},className:"m-auto w-[calc(100%-2rem)] max-w-sm p-0 rounded-xl border border-[#eaeaea] dark:border-[#262626] bg-white dark:bg-[#0f0f0f] text-[#171717] dark:text-white shadow-2xl backdrop:bg-black/40",children:f.jsxs("form",{onSubmit:M,children:[f.jsxs("div",{className:"flex items-center justify-between px-5 py-3.5 border-b border-[#eaeaea] dark:border-[#222222]",children:[f.jsx("h2",{id:"save-template-title",className:"text-sm font-semibold",children:"保存模板"}),f.jsx("button",{type:"button",onClick:r,disabled:y,"aria-label":"关闭保存模板",className:"p-1 rounded hover:bg-black/5 dark:hover:bg-white/10 disabled:opacity-50",children:f.jsx(jo,{className:"w-4 h-4"})})]}),f.jsxs("div",{className:"p-5 flex flex-col gap-4",children:[f.jsxs("label",{className:"flex flex-col gap-2 text-xs",children:["模板名称",f.jsx("input",{autoFocus:!0,required:!0,value:g,onChange:Q=>v(Q.target.value),placeholder:"输入模板名称",className:"bg-transparent border border-[#d4d4d4] dark:border-[#333333] rounded px-3 py-2 focus:outline-none focus:border-emerald-500"})]}),f.jsxs("label",{className:"flex flex-col gap-2 text-xs",children:["保存到槽位",f.jsxs("select",{value:N,onChange:Q=>m(Q.target.value),className:"bg-white dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#333333] rounded px-3 py-2",children:[f.jsx("option",{value:"article_cover",children:"文章封面 (3.35:1)"}),f.jsx("option",{value:"newspic_cover",children:"贴图封面 (3:4)"}),f.jsx("option",{value:"newspic_content",children:"贴图内容 (3:4)"}),f.jsx("option",{value:"none",children:"通用模板"})]})]}),b&&f.jsx("p",{role:"alert",className:"text-xs text-red-500",children:b}),f.jsxs("button",{type:"submit",disabled:y||!g.trim(),className:"flex items-center justify-center gap-2 px-3 py-2 rounded bg-black text-white dark:bg-white dark:text-black text-xs font-semibold disabled:opacity-50",children:[f.jsx(dh,{className:"w-3.5 h-3.5"}),y?"保存中...":"保存模板"]})]})]})})},go="typeset_studio_admin_key";function eb(){const[u,r]=fe.useState(()=>localStorage.getItem(go)||""),[s,c]=fe.useState(null),[d,x]=fe.useState(!1),g=async N=>{if(!N)return c(!1),!1;x(!0);try{const p=!!(await(await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:N})})).json()).ok;return c(p),p}catch{return c(!1),!1}finally{x(!1)}},v=N=>{localStorage.setItem(go,N),r(N),g(N)};return fe.useEffect(()=>{(async()=>{let m=u;if(!m)try{const p=await(await fetch("/api/auth/current-key")).json();p.ok&&p.key&&(m=p.key,r(p.key),localStorage.setItem(go,p.key))}catch{}m?g(m):c(!1)})()},[]),{adminKey:u,setAdminKey:v,isVerified:s,isVerifying:d,verifyKey:g}}const tb=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],Nx=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function lb(u){if(u<=255)return tb[u];let r=0,s=Nx.length-1;for(;r<=s;){const c=r+s>>1,d=Nx[c];if(u<d[0]){s=c-1;continue}if(u>d[1]){r=c+1;continue}return d[2]}return"L"}function nb(u){const r=u.length;if(r===0)return null;const s=new Array(r);let c=!1;for(let m=0;m<r;){const y=u.charCodeAt(m);let p=y,b=1;if(y>=55296&&y<=56319&&m+1<r){const M=u.charCodeAt(m+1);M>=56320&&M<=57343&&(p=(y-55296<<10)+(M-56320)+65536,b=2)}const w=lb(p);(w==="R"||w==="AL"||w==="AN")&&(c=!0);for(let M=0;M<b;M++)s[m+M]=w;m+=b}if(!c)return null;let d=0;for(let m=0;m<r;m++){const y=s[m];if(y==="L"){d=0;break}if(y==="R"||y==="AL"){d=1;break}}const x=new Int8Array(r);for(let m=0;m<r;m++)x[m]=d;const g=d&1?"R":"L",v=g;let N=v;for(let m=0;m<r;m++)s[m]==="NSM"?s[m]=N:N=s[m];N=v;for(let m=0;m<r;m++){const y=s[m];y==="EN"?s[m]=N==="AL"?"AN":"EN":(y==="R"||y==="L"||y==="AL")&&(N=y)}for(let m=0;m<r;m++)s[m]==="AL"&&(s[m]="R");for(let m=1;m<r-1;m++)s[m]==="ES"&&s[m-1]==="EN"&&s[m+1]==="EN"&&(s[m]="EN"),s[m]==="CS"&&(s[m-1]==="EN"||s[m-1]==="AN")&&s[m+1]===s[m-1]&&(s[m]=s[m-1]);for(let m=0;m<r;m++){if(s[m]!=="EN")continue;let y;for(y=m-1;y>=0&&s[y]==="ET";y--)s[y]="EN";for(y=m+1;y<r&&s[y]==="ET";y++)s[y]="EN"}for(let m=0;m<r;m++){const y=s[m];(y==="WS"||y==="ES"||y==="ET"||y==="CS")&&(s[m]="ON")}N=v;for(let m=0;m<r;m++){const y=s[m];y==="EN"?s[m]=N==="L"?"L":"EN":(y==="R"||y==="L")&&(N=y)}for(let m=0;m<r;m++){if(s[m]!=="ON")continue;let y=m+1;for(;y<r&&s[y]==="ON";)y++;const p=m>0?s[m-1]:v,b=y<r?s[y]:v,w=p!=="L"?"R":"L";if(w===(b!=="L"?"R":"L"))for(let Q=m;Q<y;Q++)s[Q]=w;m=y-1}for(let m=0;m<r;m++)s[m]==="ON"&&(s[m]=g);for(let m=0;m<r;m++){const y=s[m];(x[m]&1)===0?y==="R"?x[m]++:(y==="AN"||y==="EN")&&(x[m]+=2):(y==="L"||y==="AN"||y==="EN")&&x[m]++}return x}function ab(u,r){const s=nb(u);if(s===null)return null;const c=new Int8Array(r.length);for(let d=0;d<r.length;d++)c[d]=s[r[d]];return c}const ib=/[ \t\n\r\f]+/g,ub=/[\t\n\r\f]| {2,}|^ | $/;function rb(u){const r=u??"normal";return r==="pre-wrap"?{mode:r,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:r,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}}function cb(u){if(!ub.test(u))return u;let r=u.replace(ib," ");return r.charCodeAt(0)===32&&(r=r.slice(1)),r.length>0&&r.charCodeAt(r.length-1)===32&&(r=r.slice(0,-1)),r}function sb(u){return/[\r\f]/.test(u)?u.replace(/\r\n/g,`
292
+ `).length]})]})]}),M==="images"&&f.jsxs("div",{className:"flex-1 flex flex-col p-3 gap-3 overflow-y-auto",children:[f.jsxs("div",{className:"flex gap-2",children:[f.jsx("input",{type:"file",ref:P,onChange:H,accept:"image/*",className:"hidden"}),f.jsxs("button",{onClick:()=>P.current?.click(),disabled:ee,className:"flex-1 flex items-center justify-center gap-2 py-2.5 rounded-lg border border-dashed border-[#d4d4d4] dark:border-[#333333] hover:border-black dark:hover:border-[#555555] bg-[#fafafa] dark:bg-[#0f0f0f] hover:bg-[#f5f5f5] dark:hover:bg-[#141414] text-xs text-[#555555] dark:text-[#cccccc] hover:text-black dark:hover:text-white transition-all",children:[f.jsx(Op,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:ee?"正在上传...":"上传配图素材"})]}),f.jsx("button",{onClick:()=>c({src:"https://images.unsplash.com/photo-1579783900882-c0d3dad7b119?w=800&auto=format&fit=crop&q=80",alt:"艺术插画",caption:"示例艺术配图",x:36,y:400,width:440,height:300,captionHeight:36,layoutPreset:"auto"}),className:"px-3 py-2.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-[#fafafa] dark:bg-[#0f0f0f] hover:bg-[#f5f5f5] dark:hover:bg-[#141414] text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white transition-all",title:"插入在线示例图",children:f.jsx(Sp,{className:"w-3.5 h-3.5"})})]}),f.jsx("div",{className:"flex flex-col gap-2.5",children:s.length===0?f.jsx("div",{className:"text-center py-8 text-xs text-[#888888] dark:text-[#555555]",children:"暂无配图素材,点击上方按钮上传或插入"}):s.map((S,U)=>f.jsxs("div",{className:"bg-[#fafafa] dark:bg-[#0f0f0f] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-2.5 flex flex-col gap-2",children:[f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsx("img",{src:S.src,alt:S.alt,className:"w-12 h-12 object-cover rounded bg-[#eeeeee] dark:bg-[#1a1a1a] border border-[#e5e5e5] dark:border-[#262626] shrink-0"}),f.jsxs("div",{className:"flex-1 min-w-0",children:[f.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[f.jsxs("span",{className:"text-[10px] px-1 rounded bg-[#eaeaea] dark:bg-[#262626] font-mono text-[#555555] dark:text-[#aaaaaa] font-semibold shrink-0",children:["#",U+1]}),f.jsx("span",{className:"text-xs font-medium text-[#171717] dark:text-white truncate max-w-[120px]",children:S.caption||S.alt||`配图 #${U+1}`}),f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 font-medium shrink-0",children:["第 ",S.pageIndex||1," 页"]})]}),f.jsxs("div",{className:"text-[10px] text-[#888888] dark:text-[#666666] font-mono mt-0.5",children:[S.width," × ",S.height,"px · X: ",S.x??0,", Y: ",S.y??0]})]}),f.jsxs("div",{className:"flex items-center gap-0.5",children:[f.jsx("button",{onClick:()=>m?.(S.id,"up"),disabled:U===0,className:"p-1 text-[#888888] hover:text-black dark:hover:text-white disabled:opacity-20 rounded hover:bg-[#eeeeee] dark:hover:bg-[#1f1f1f]",title:"上移顺序 (调整在同一页中的先后次序)",children:f.jsx(cp,{className:"w-3.5 h-3.5"})}),f.jsx("button",{onClick:()=>m?.(S.id,"down"),disabled:U===s.length-1,className:"p-1 text-[#888888] hover:text-black dark:hover:text-white disabled:opacity-20 rounded hover:bg-[#eeeeee] dark:hover:bg-[#1f1f1f]",title:"下移顺序 (调整在同一页中的先后次序)",children:f.jsx(up,{className:"w-3.5 h-3.5"})}),f.jsx("button",{onClick:()=>N(S.id),className:"p-1 text-[#888888] hover:text-red-500 rounded hover:bg-[#eeeeee] dark:hover:bg-[#1f1f1f]",title:"删除该图",children:f.jsx(Eh,{className:"w-3.5 h-3.5"})})]})]}),f.jsxs("div",{className:"flex bg-[#eeeeee] dark:bg-[#1a1a1a] p-0.5 rounded text-[11px] font-medium pt-1 border-t border-[#eeeeee] dark:border-[#1a1a1a]",children:[f.jsx("button",{onClick:()=>v(S.id,{isAbsolute:!1}),className:`flex-1 py-1 rounded transition-all text-center ${S.isAbsolute?"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white":"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold"}`,children:"绕排避让 (Flow)"}),f.jsx("button",{onClick:()=>v(S.id,{isAbsolute:!0,layoutPreset:"custom",zIndex:S.zIndex??15,rotate:S.rotate??0,opacity:S.opacity??1}),className:`flex-1 py-1 rounded transition-all text-center ${S.isAbsolute?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:"自由图层 (Absolute)"})]}),f.jsxs("div",{className:"flex flex-col gap-2 text-[11px]",children:[f.jsxs("label",{className:"flex items-center gap-2",children:[f.jsx("input",{type:"checkbox",checked:S.templateAssetKey!==void 0,onChange:_=>v(S.id,{templateAssetKey:_.target.checked?`asset_${S.id.replace(/[^a-zA-Z0-9_-]/g,"_")}`:void 0,repeatEveryPage:!1})}),"固定模板素材"]}),S.templateAssetKey!==void 0&&f.jsxs(f.Fragment,{children:[f.jsxs("label",{className:"flex flex-col gap-1",children:["素材标识",f.jsx("input",{"aria-label":"素材标识",value:S.templateAssetKey,onChange:_=>v(S.id,{templateAssetKey:_.target.value}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1"})]}),s.some(_=>_.id!==S.id&&_.templateAssetKey===S.templateAssetKey)&&f.jsx("span",{role:"alert",className:"text-red-600",children:"素材标识不能重复"}),f.jsxs("label",{className:"flex items-center gap-2",children:[f.jsx("input",{type:"checkbox",disabled:!S.isAbsolute,checked:!!(S.isAbsolute&&S.repeatEveryPage),onChange:_=>v(S.id,{repeatEveryPage:_.target.checked})}),"每页重复"]}),!S.isAbsolute&&f.jsx("span",{className:"text-[#888888]",children:"每页重复仅支持自由图层,避免阻塞文字排版。"}),f.jsx("span",{className:"text-[#888888]",children:"默认保留此图,仅按素材标识明确替换。"})]}),S.isAbsolute&&f.jsxs("label",{className:"flex items-center gap-2",children:[f.jsx("input",{type:"checkbox",checked:g.includes(S.id),onChange:_=>d(S.id,_.target.checked)}),"设为整页背景"]}),f.jsx("button",{type:"button",onClick:()=>x(S.id),title:"恢复上传或应用模板时的尺寸、位置和图层设置",className:"rounded border border-[#d4d4d4] dark:border-[#333333] px-2 py-1.5 hover:bg-[#eeeeee] dark:hover:bg-[#222222]",children:"重置布局"})]}),S.isAbsolute?f.jsxs(f.Fragment,{children:[f.jsxs("div",{className:"text-[10px] text-blue-600 dark:text-blue-400 bg-blue-500/10 p-1.5 rounded flex items-center gap-1 font-medium",children:[f.jsx(So,{className:"w-3 h-3 shrink-0"}),f.jsx("span",{children:"自由定位图层:脱离文本流,不触发障碍物绕排"})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"所属页面"}),f.jsx("select",{value:S.pageIndex||1,onChange:_=>v(S.id,{pageIndex:parseInt(_.target.value,10)||1}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] focus:outline-none",children:Array.from({length:Math.max(y,2)},(_,te)=>te+1).map(_=>f.jsxs("option",{value:_,children:["第 ",_," 页 ",_===1?"(首页/封面)":""]},_))})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] mb-1",children:[f.jsx("span",{children:"层级 (Z-Index)"}),f.jsx("span",{className:"font-mono text-black dark:text-white font-semibold",children:S.zIndex??15})]}),f.jsx("div",{className:"flex gap-1",children:[{label:"底",val:0,title:"底层背景"},{label:"文字",val:10,title:"正文同层"},{label:"顶",val:20,title:"置顶贴纸"}].map(_=>f.jsx("button",{onClick:()=>v(S.id,{zIndex:_.val}),title:_.title,className:`flex-1 py-0.5 text-[10px] rounded border ${(S.zIndex??15)===_.val?"bg-black dark:bg-white text-white dark:text-black border-transparent font-bold":"border-[#d4d4d4] dark:border-[#262626] text-[#666666] dark:text-[#888888]"}`,children:_.label},_.val))})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] mb-1",children:[f.jsxs("span",{className:"flex items-center gap-0.5",children:[f.jsx(Ep,{className:"w-2.5 h-2.5"})," 旋转角度"]}),f.jsxs("span",{className:"font-mono text-black dark:text-white font-semibold",children:[S.rotate??0,"°"]})]}),f.jsx("input",{type:"range",min:"-45",max:"45",step:"1",value:S.rotate??0,onChange:_=>v(S.id,{rotate:parseInt(_.target.value,10)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded cursor-pointer mt-1"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] mb-1",children:[f.jsx("span",{children:"不透明度"}),f.jsxs("span",{className:"font-mono text-black dark:text-white font-semibold",children:[Math.round((S.opacity??1)*100),"%"]})]}),f.jsx("input",{type:"range",min:"0.1",max:"1",step:"0.05",value:S.opacity??1,onChange:_=>v(S.id,{opacity:parseFloat(_.target.value)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded cursor-pointer mt-1"})]})]}),f.jsxs("div",{className:"text-[11px]",children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"圆角半径 (px)"}),f.jsx("input",{type:"number",min:"0",step:"4",value:S.borderRadius??12,onChange:_=>v(S.id,{borderRadius:parseInt(_.target.value,10)||0}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"横向 X"}),f.jsx("input",{type:"number",step:"10",value:S.x??0,onChange:_=>v(S.id,{x:parseInt(_.target.value,10)||0}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"纵向 Y"}),f.jsx("input",{type:"number",step:"10",value:S.y??0,onChange:_=>v(S.id,{y:parseInt(_.target.value,10)||0}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"宽度 (W)"}),f.jsx("input",{type:"number",step:"10",value:S.width??420,onChange:_=>v(S.id,{width:Math.max(20,parseInt(_.target.value,10)||20)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"高度 (H)"}),f.jsx("input",{type:"number",step:"10",value:S.height??280,onChange:_=>v(S.id,{height:Math.max(20,parseInt(_.target.value,10)||20)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]})]}):f.jsxs(f.Fragment,{children:[f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"排版预设"}),f.jsxs("select",{value:S.layoutPreset||"auto",onChange:_=>v(S.id,{layoutPreset:_.target.value}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] focus:outline-none",children:[f.jsx("option",{value:"auto",children:"自适应 (Auto)"}),f.jsx("option",{value:"mid-left",children:"居左浮动 (Left)"}),f.jsx("option",{value:"mid-right",children:"居右浮动 (Right)"}),f.jsx("option",{value:"center",children:"居中横幅 (Center)"}),f.jsx("option",{value:"staggered",children:"交错排版 (Staggered)"}),f.jsx("option",{value:"corner-soft",children:"角落软着陆 (Corner)"}),f.jsx("option",{value:"fill",children:"底部填满 (Fill)"}),f.jsx("option",{value:"custom",children:"自定义坐标 (Custom)"})]})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"所属页面"}),f.jsx("select",{value:S.pageIndex||1,onChange:_=>v(S.id,{pageIndex:parseInt(_.target.value,10)||1}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] focus:outline-none",children:Array.from({length:Math.max(y,2)},(_,te)=>te+1).map(_=>f.jsxs("option",{value:_,children:["第 ",_," 页 ",_===1?"(首页/封面)":""]},_))})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"宽度 (W)"}),f.jsx("input",{type:"number",min:"50",step:"10",value:S.width??420,onChange:_=>v(S.id,{width:Math.max(50,parseInt(_.target.value,10)||50)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"高度 (H)"}),f.jsx("input",{type:"number",min:"50",step:"10",value:S.height??280,onChange:_=>v(S.id,{height:Math.max(50,parseInt(_.target.value,10)||50)}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px]",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"纵向位置 Y"}),f.jsx("input",{type:"number",step:"20",value:S.y??300,onChange:_=>v(S.id,{y:parseInt(_.target.value,10)||0,layoutPreset:"custom"}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] block mb-1",children:"横向坐标 X"}),f.jsx("input",{type:"number",step:"10",value:S.x??16,onChange:_=>v(S.id,{x:parseInt(_.target.value,10)||0,layoutPreset:"custom"}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-1.5 py-1 text-black dark:text-white text-[11px] font-mono focus:outline-none"})]})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] text-[11px] block mb-1",children:"图片说明 (Caption)"}),f.jsx("input",{type:"text",placeholder:"下方说明文字...",value:S.caption||"",onChange:_=>v(S.id,{caption:_.target.value}),className:"w-full bg-white dark:bg-[#181818] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white text-[11px] focus:outline-none"})]})]})]},S.id))})]}),M==="highlights"&&f.jsxs("div",{className:"flex-1 flex flex-col p-3 gap-3 overflow-y-auto",children:[f.jsx("div",{className:"text-xs text-[#666666] dark:text-[#888888] leading-relaxed",children:"在正文中出现的高亮词,将被算法自动匹配并渲染为品牌强调色。"}),f.jsxs("div",{className:"flex gap-2",children:[f.jsx("input",{type:"text",placeholder:"新增高亮关键词...",value:B,onChange:S=>L(S.target.value),onKeyDown:S=>S.key==="Enter"&&V(),className:"flex-1 bg-white dark:bg-[#0d0d0d] border border-[#d4d4d4] dark:border-[#222222] rounded-lg px-2.5 py-1.5 text-xs text-black dark:text-white placeholder-[#888888] dark:placeholder-[#555555] focus:outline-none focus:border-black dark:focus:border-[#444444]"}),f.jsx("button",{onClick:V,className:"px-3 py-1.5 bg-black dark:bg-[#1f1f1f] hover:bg-[#262626] text-white rounded-lg text-xs font-medium",children:"添加"})]}),f.jsx("div",{className:"flex flex-wrap gap-1.5 mt-1",children:p.map(S=>f.jsxs("span",{className:"flex items-center gap-1 px-2.5 py-1 rounded-md bg-[#f0fdf4] dark:bg-[#161616] border border-[#bbf7d0] dark:border-[#262626] text-xs text-emerald-700 dark:text-emerald-400 font-medium",children:[f.jsx(So,{className:"w-3 h-3"}),f.jsx("span",{children:S}),f.jsx("button",{onClick:()=>Y(S),className:"hover:text-red-500 ml-1",children:"×"})]},S))})]})]})},Vp=[{id:"wechat-cover-2.35",label:"微信封面",ratioTag:"3.35:1"},{id:"longform-3-4",label:"通用长图文",ratioTag:"3:4"},{id:"wide-16-9",label:"通用宽屏",ratioTag:"16:9"},{id:"square-1-1",label:"通用正方形",ratioTag:"1:1"}],Zp=({currentRatio:u,onSelectRatio:r,zoom:s,onZoomChange:c,onAutoFit:d,isAutoFit:x,onOpenTemplates:g,isTemplateDrawerOpen:v,templateName:N,onSaveTemplate:m,onOpenAuth:y,onExport:p,isExporting:b,isAuthed:w,pageCount:M,themeMode:Q,onToggleThemeMode:B})=>f.jsxs("header",{className:"h-14 border-b border-[#eaeaea] dark:border-[#222222] bg-white/80 dark:bg-[#000000]/80 backdrop-blur-md px-4 flex items-center justify-between select-none z-30 shrink-0 transition-colors",children:[f.jsxs("div",{className:"flex min-w-0 items-center gap-3",children:[f.jsxs("div",{className:"flex items-center gap-2 font-semibold text-[#171717] dark:text-white tracking-tight text-sm",children:[f.jsx("span",{className:"flex items-center justify-center w-6 h-6 rounded bg-black dark:bg-white text-white dark:text-black font-black text-xs shadow-sm",children:"▲"}),f.jsx("span",{className:"hidden 2xl:inline",children:"Typeset Studio"})]}),f.jsx("span",{className:"text-xs text-[#888888] dark:text-[#555555] font-mono hidden 2xl:inline",children:"v0.3.1"}),f.jsxs("div",{title:N||"未命名模板",className:"flex min-w-0 items-center gap-1.5 px-2 py-0.5 rounded-full bg-[#f5f5f5] dark:bg-[#111111] border border-[#e5e5e5] dark:border-[#222222] text-[11px] text-emerald-600 dark:text-[#00e676]",children:[f.jsx("span",{className:"w-1.5 h-1.5 shrink-0 rounded-full bg-emerald-500 dark:bg-[#00e676]"}),f.jsx("span",{"aria-live":"polite",className:"max-w-40 truncate",children:N||"未命名模板"})]})]}),f.jsx("div",{className:"flex items-center bg-[#f5f5f5] dark:bg-[#0a0a0a] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-0.5 shadow-inner",children:Vp.map(L=>{const P=u===L.id;return f.jsxs("button",{onClick:()=>r(L.id),className:`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-all ${P?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-[#171717] dark:hover:text-[#cccccc] hover:bg-[#eaeaea] dark:hover:bg-[#141414]"}`,children:[f.jsx("span",{className:"hidden xl:inline",children:L.label}),f.jsx("span",{className:`text-[10px] font-mono px-1 py-0.2 rounded ${P?"bg-[#eaeaea] dark:bg-[#333333] text-black dark:text-white font-semibold":"bg-[#e5e5e5] dark:bg-[#181818] text-[#777777] dark:text-[#666666]"}`,children:L.ratioTag})]},L.id)})}),f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsxs("div",{className:"flex items-center bg-[#f5f5f5] dark:bg-[#0a0a0a] border border-[#eaeaea] dark:border-[#222222] rounded-lg p-0.5 text-xs text-[#666666] dark:text-[#888888]",children:[f.jsx("button",{onClick:()=>c(Math.max(.2,Number((s-.05).toFixed(2)))),className:"p-1 hover:text-black dark:hover:text-white rounded hover:bg-[#e8e8e8] dark:hover:bg-[#1f1f1f]",title:"缩小",children:f.jsx(Bp,{className:"w-3.5 h-3.5"})}),f.jsxs("span",{onDoubleClick:d,className:"w-11 text-center font-mono text-[11px] text-[#333333] dark:text-[#cccccc] cursor-pointer hover:underline select-none",title:"双击恢复自适应",children:[Math.round(s*100),"%"]}),f.jsx("button",{onClick:()=>c(Math.min(1.5,Number((s+.05).toFixed(2)))),className:"p-1 hover:text-black dark:hover:text-white rounded hover:bg-[#e8e8e8] dark:hover:bg-[#1f1f1f]",title:"放大",children:f.jsx(kh,{className:"w-3.5 h-3.5"})}),d&&f.jsxs(f.Fragment,{children:[f.jsx("div",{className:"w-[1px] h-3 bg-[#e0e0e0] dark:bg-[#262626] mx-0.5"}),f.jsxs("button",{onClick:d,className:`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-all ${x?"bg-white dark:bg-[#1f1f1f] text-black dark:text-white shadow-xs font-semibold":"hover:text-black dark:hover:text-white hover:bg-[#e8e8e8] dark:hover:bg-[#1f1f1f]"}`,title:M>1?"缩放至视口内完整排列多张图片(瀑布流平铺)":"自适应画布大小",children:[f.jsx(vp,{className:"w-3 h-3"}),f.jsx("span",{children:M>1?"多图平铺":"自适应"})]})]})]}),f.jsx("button",{onClick:B,className:"p-2 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] hover:bg-[#f5f5f5] dark:hover:bg-[#161616] text-[#444444] dark:text-[#cccccc] transition-all btn-vercel",title:Q==="light"?"切换至深色模式":"切换至浅色模式",children:Q==="light"?f.jsx(yp,{className:"w-3.5 h-3.5 text-[#555555]"}):f.jsx(kp,{className:"w-3.5 h-3.5 text-amber-400"})}),f.jsxs("button",{onClick:g,"aria-expanded":v,className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] hover:bg-[#f5f5f5] dark:hover:bg-[#161616] text-xs text-[#333333] dark:text-[#cccccc] hover:text-black dark:hover:text-white transition-all btn-vercel",children:[f.jsx(dp,{className:"w-3.5 h-3.5 text-[#777777] dark:text-[#888888]"}),f.jsx("span",{children:"模板库"})]}),f.jsxs("button",{onClick:m,className:"flex items-center gap-1.5 px-2.5 py-1.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] hover:bg-[#f5f5f5] dark:hover:bg-[#161616] text-xs text-[#333333] dark:text-[#cccccc] transition-all btn-vercel",children:[f.jsx(dh,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:"保存模板"})]}),f.jsxs("button",{onClick:p,disabled:b,className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-black text-white hover:bg-[#262626] dark:bg-white dark:text-black dark:hover:bg-[#eaeaea] text-xs font-semibold transition-all btn-vercel shadow-sm disabled:opacity-50",children:[b?f.jsx(ch,{className:"w-3.5 h-3.5 animate-spin"}):f.jsx(op,{className:"w-3.5 h-3.5"}),f.jsx("span",{children:b?"导出中...":"导出图片"}),M>1&&f.jsxs("span",{className:"text-[10px] bg-white/20 dark:bg-black text-white px-1.5 py-0.2 rounded font-mono",children:[M,"P"]})]}),f.jsx("button",{onClick:y,className:`p-1.5 rounded-lg border transition-all btn-vercel ${w?"border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] text-[#777777] dark:text-[#888888] hover:text-black dark:hover:text-white hover:bg-[#f5f5f5] dark:hover:bg-[#161616]":"border-amber-500/50 bg-amber-500/10 text-amber-600 dark:text-amber-400"}`,title:w?"超管密钥已就绪":"配置超管密钥",children:f.jsx(eh,{className:"w-3.5 h-3.5"})})]})]});function Kp(){const[u,r]=fe.useState([]),[s,c]=fe.useState(!1),d=fe.useCallback(async(x=!1)=>{try{c(!0);const g=await fetch(`/api/fonts${x?"?refresh=1":""}`);if(!g.ok)return;const v=await g.json();if(!v.ok||!Array.isArray(v.fonts))return;r(v.fonts);let N=!1;if(typeof window<"u"&&"FontFace"in window&&document.fonts)for(const m of v.fonts)try{let y=!1;const p=[];if(document.fonts.forEach(b=>{(b.family===m.family||b.family===`"${m.family}"`)&&(y=!0,p.push(b))}),x&&(p.forEach(b=>document.fonts.delete(b)),y=!1),!y){const w=await new FontFace(m.family,`url(${m.url}${x?`?v=${Date.now()}`:""})`).load();document.fonts.add(w),N=!0}}catch(y){console.warn(`[useLocalFonts] Failed to load web font ${m.family}:`,y)}N&&window.dispatchEvent(new Event("typeset-fonts-loaded"))}catch(g){console.warn("[useLocalFonts] Failed to fetch local fonts:",g)}finally{c(!1)}},[]);return fe.useEffect(()=>{d()},[d]),{fonts:u,loading:s,refreshFonts:()=>d(!0)}}const mo="w-full rounded border border-[#dfdfdf] dark:border-[#333333] bg-white dark:bg-[#141414] px-2 py-1 text-[11px]";function Jp({config:u,onChange:r}){const s=u.canvasStyle||{},c=s.fill||u.coverTheme?.background.fill||{type:"solid",color:u.theme.bgColor},d=s.pattern||u.coverTheme?.decoration||_p,x=s.border||Rp,g=b=>r({...s,fill:b}),v=b=>r({...s,pattern:{...d,...b}}),N=b=>r({...s,border:{...x,...b}}),m=(b,w,M)=>f.jsxs("label",{className:"flex items-center justify-between gap-2",children:[f.jsx("span",{children:b}),f.jsxs("span",{className:"flex items-center gap-1.5 font-mono",children:[f.jsx("span",{children:w}),f.jsx("input",{"aria-label":b,type:"color",value:w,onChange:Q=>M(Q.target.value),className:"h-6 w-7 cursor-pointer bg-transparent"})]})]}),y=(b,w,M,Q,B,L=1)=>f.jsxs("label",{className:"flex flex-col gap-1",children:[f.jsxs("span",{className:"flex justify-between",children:[f.jsx("span",{children:b}),f.jsx("span",{className:"font-mono",children:L<1?`${Math.round(w*100)}%`:w})]}),f.jsx("input",{"aria-label":b,type:"range",min:M,max:Q,step:L,value:w,onChange:P=>B(Number(P.target.value)),className:"w-full accent-emerald-600"})]}),p=b=>{const w=c.type==="solid"?c.color:c.stops[0].color,M=c.type==="solid"?[{color:w,offset:0},{color:u.theme.accentColor,offset:100}]:c.stops;g(b==="solid"?{type:b,color:w}:b==="linear"?{type:b,angle:90,stops:M}:{type:b,position:{x:50,y:30},stops:M})};return f.jsxs("section",{className:"border-b border-[#f0f0f0] dark:border-[#1c1c1c] p-3.5 text-xs",children:[f.jsx("div",{className:"mb-3 font-semibold text-[#171717] dark:text-white",children:"背景、花纹与边框"}),f.jsxs("div",{className:"flex flex-col gap-3 text-[11px] text-[#666666] dark:text-[#aaaaaa]",children:[f.jsxs("label",{className:"flex flex-col gap-1",children:["背景类型",f.jsxs("select",{className:mo,value:c.type,onChange:b=>p(b.target.value),children:[f.jsx("option",{value:"solid",children:"纯色"}),f.jsx("option",{value:"linear",children:"线性渐变"}),f.jsx("option",{value:"radial",children:"径向渐变"})]})]}),c.type==="solid"?m("背景颜色",c.color,b=>g({type:"solid",color:b})):f.jsxs(f.Fragment,{children:[f.jsxs("div",{className:"flex flex-col gap-2 rounded border border-[#eaeaea] dark:border-[#333333] p-2",children:[c.stops.map((b,w)=>f.jsxs("div",{className:"flex flex-col gap-1.5",children:[f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsxs("label",{className:"flex flex-1 items-center gap-1.5",children:[f.jsx("input",{"aria-label":`渐变颜色 ${w+1}`,type:"color",value:b.color,onChange:M=>g({...c,stops:c.stops.map((Q,B)=>B===w?{...Q,color:M.target.value}:Q)}),className:"h-6 w-7 bg-transparent"}),f.jsx("span",{className:"font-mono",children:b.color})]}),f.jsx("button",{type:"button",disabled:c.stops.length<=2,onClick:()=>g({...c,stops:c.stops.filter((M,Q)=>Q!==w)}),className:"disabled:opacity-30","aria-label":`删除渐变颜色 ${w+1}`,children:"移除"})]}),y(`节点 ${w+1} 位置`,b.offset,0,100,M=>g({...c,stops:c.stops.map((Q,B)=>B===w?{...Q,offset:M}:Q)}))]},w)),f.jsx("button",{type:"button",disabled:c.stops.length>=8,onClick:()=>g({...c,stops:[...c.stops,{color:u.theme.accentColor,offset:50}]}),className:"rounded border border-[#dfdfdf] dark:border-[#333333] py-1 disabled:opacity-30",children:"添加颜色节点"})]}),c.type==="linear"?y("渐变角度",c.angle,0,360,b=>g({...c,angle:b})):f.jsxs(f.Fragment,{children:[y("渐变中心 X",c.position.x,0,100,b=>g({...c,position:{...c.position,x:b}})),y("渐变中心 Y",c.position.y,0,100,b=>g({...c,position:{...c.position,y:b}}))]})]}),f.jsxs("label",{className:"flex flex-col gap-1",children:["几何花纹",f.jsx("select",{className:mo,value:d.pattern,onChange:b=>v({pattern:b.target.value}),children:Object.entries(Fh).map(([b,w])=>f.jsx("option",{value:b,children:w},b))})]}),d.pattern!=="none"&&f.jsxs(f.Fragment,{children:[m("花纹颜色",d.color,b=>v({color:b})),y("花纹透明度",d.opacity,0,1,b=>v({opacity:b}),.01),y("花纹间距",d.size,16,240,b=>v({size:b}))]}),f.jsxs("label",{className:"flex flex-col gap-1",children:["边框样式",f.jsx("select",{className:mo,value:x.style,onChange:b=>N({style:b.target.value}),children:Object.entries(jh).map(([b,w])=>f.jsx("option",{value:b,children:w},b))})]}),x.style!=="none"&&f.jsxs(f.Fragment,{children:[m("边框颜色",x.color,b=>N({color:b})),x.style==="gradient"&&m("边框渐变终色",x.endColor,b=>N({endColor:b})),y("边框粗细",x.width,1,24,b=>N({width:b})),y("边框内缩",x.inset,0,200,b=>N({inset:b})),x.style!=="corners"&&y("边框圆角",x.radius,0,200,b=>N({radius:b})),y("边框透明度",x.opacity,0,1,b=>N({opacity:b}),.01)]}),f.jsx("p",{className:"leading-relaxed text-[#888888]",children:"配置随模板保存,作用于每页。背景图会覆盖底色与花纹;边框绘制在最上层。"})]})]})}const yx=[{label:"苹方 / 极简黑体 (默认清爽)",value:"PingFang SC"},{label:"思源黑体 (现代极简·粗黑)",value:"Noto Sans SC"},{label:"典雅宋体 (经典报刊·书卷)",value:"Songti SC"},{label:"思源宋体 (高阶报刊·典雅)",value:"Noto Serif SC"},{label:"人文楷体 (温润随笔·手写)",value:"Kaiti SC"},{label:"柔和圆体 (亲和灵动·现代)",value:"Yuanti SC"},{label:"Inter / 国际西文无衬线",value:"Inter"},{label:"Georgia / 文艺西文衬线",value:"Georgia"}],Ip=({config:u,onUpdateAlgorithm:r,onUpdateTheme:s,onUpdateTypography:c,onUpdateSafeArea:d,onUpdateBranding:x,onUpdateChrome:g,onUpdateCanvasStyle:v})=>{const{algorithm:N,theme:m,typography:y}=u,{fonts:p,loading:b,refreshFonts:w}=Kp();return f.jsxs("aside",{className:"w-80 border-l border-[#eaeaea] dark:border-[#222222] bg-white dark:bg-[#0a0a0a] flex flex-col shrink-0 select-none overflow-y-auto transition-colors",children:[f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(rp,{className:"w-3.5 h-3.5 text-blue-500 dark:text-blue-400"}),f.jsx("span",{children:"文字对齐与空间居中"})]}),f.jsxs("div",{className:"flex flex-col gap-3 text-xs",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1.5 font-medium",children:"垂直排版对齐 (封面必备)"}),f.jsx("div",{className:"grid grid-cols-3 gap-1 bg-[#f5f5f5] dark:bg-[#141414] p-1 rounded-lg border border-[#e5e5e5] dark:border-[#262626]",children:[{id:"top",label:"顶端对齐"},{id:"center",label:"垂直居中"},{id:"bottom",label:"底端对齐"}].map(M=>f.jsx("button",{onClick:()=>r({verticalAlign:M.id}),className:`py-1 text-[11px] rounded transition-all font-medium ${(N.verticalAlign||"top")===M.id?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:M.label},M.id))})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1.5 font-medium",children:"水平排版对齐"}),f.jsxs("div",{className:"grid grid-cols-3 gap-1 bg-[#f5f5f5] dark:bg-[#141414] p-1 rounded-lg border border-[#e5e5e5] dark:border-[#262626]",children:[f.jsxs("button",{onClick:()=>r({textAlign:"left"}),className:`py-1 flex items-center justify-center gap-1 text-[11px] rounded transition-all font-medium ${(N.textAlign||"left")==="left"?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:[f.jsx(jp,{className:"w-3 h-3"}),f.jsx("span",{children:"居左"})]}),f.jsxs("button",{onClick:()=>r({textAlign:"center"}),className:`py-1 flex items-center justify-center gap-1 text-[11px] rounded transition-all font-medium ${N.textAlign==="center"?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:[f.jsx(Fp,{className:"w-3 h-3"}),f.jsx("span",{children:"居中"})]}),f.jsxs("button",{onClick:()=>r({textAlign:"right"}),className:`py-1 flex items-center justify-center gap-1 text-[11px] rounded transition-all font-medium ${N.textAlign==="right"?"bg-white dark:bg-[#262626] text-black dark:text-white shadow-sm font-semibold":"text-[#666666] dark:text-[#888888] hover:text-black dark:hover:text-white"}`,children:[f.jsx(Tp,{className:"w-3 h-3"}),f.jsx("span",{children:"居右"})]})]})]})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center justify-between text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsxs("div",{className:"flex items-center gap-2",children:[f.jsx(Dp,{className:"w-3.5 h-3.5 text-indigo-500 dark:text-indigo-400"}),f.jsx("span",{children:"字体与排版字阶"})]}),f.jsx("button",{onClick:()=>w(),disabled:b,title:"重新扫描 public/fonts 目录",className:"p-1 text-[#888888] hover:text-black dark:hover:text-white rounded hover:bg-[#eaeaea] dark:hover:bg-[#222222] transition-colors",children:f.jsx(ch,{className:`w-3 h-3 ${b?"animate-spin text-blue-500":""}`})})]}),f.jsxs("div",{className:"flex flex-col gap-3 text-xs",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1",children:"标题字体 (Heading Font)"}),f.jsxs("select",{value:y.headingFont,onChange:M=>c({headingFont:M.target.value}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded-md px-2 py-1.5 text-black dark:text-white text-xs focus:outline-none",children:[p.length>0&&f.jsx("optgroup",{label:"✨ 项目本地字体 (public/fonts)",children:p.map(M=>f.jsx("option",{value:M.family,children:M.label},`head-local-${M.family}`))}),f.jsx("optgroup",{label:"🌐 系统 / 云端预设",children:yx.map(M=>f.jsx("option",{value:M.value,children:M.label},`head-preset-${M.value}`))})]})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] text-[11px] block mb-1",children:"正文字体 (Body Font)"}),f.jsxs("select",{value:y.bodyFont,onChange:M=>c({bodyFont:M.target.value}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded-md px-2 py-1.5 text-black dark:text-white text-xs focus:outline-none",children:[p.length>0&&f.jsx("optgroup",{label:"✨ 项目本地字体 (public/fonts)",children:p.map(M=>f.jsx("option",{value:M.family,children:M.label},`body-local-${M.family}`))}),f.jsx("optgroup",{label:"🌐 系统 / 云端预设",children:yx.map(M=>f.jsx("option",{value:M.value,children:M.label},`body-preset-${M.value}`))})]})]}),p.length===0?f.jsx("div",{className:"text-[10px] text-[#888888] dark:text-[#666666] flex items-center justify-between pt-1 border-t border-[#f5f5f5] dark:border-[#1a1a1a]",children:f.jsxs("span",{children:["💡 将 .ttf / .otf 放入 ",f.jsx("code",{children:"public/fonts/"})," 即可识别"]})}):f.jsx("div",{className:"text-[10px] text-emerald-600 dark:text-emerald-400 flex items-center justify-between pt-1 border-t border-[#f5f5f5] dark:border-[#1a1a1a]",children:f.jsxs("span",{children:["✨ 已加载 ",p.length," 个项目本地字体"]})})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(wp,{className:"w-3.5 h-3.5 text-blue-500 dark:text-blue-400"}),f.jsx("span",{children:"字号与比例参数"})]}),f.jsxs("div",{className:"flex flex-col gap-3.5 text-xs",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"基准字号 (Base Size)"}),f.jsxs("span",{className:"text-[#171717] dark:text-white font-semibold",children:[N.baseFontSize,"px"]})]}),f.jsx("input",{type:"range",min:"24",max:"96",step:"1",value:N.baseFontSize,onChange:M=>r({baseFontSize:parseInt(M.target.value,10)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"比例字阶系数 (大标题倍率)"}),f.jsxs("span",{className:"text-[#171717] dark:text-white font-semibold",children:[N.scaleRatio.toFixed(2),"x"]})]}),f.jsx("input",{type:"range",min:"1.15",max:"1.6",step:"0.01",value:N.scaleRatio,onChange:M=>r({scaleRatio:parseFloat(M.target.value)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"行高舒展倍率"}),f.jsx("span",{className:"text-[#171717] dark:text-white font-semibold",children:N.lineHeightMultiplier.toFixed(2)})]}),f.jsx("input",{type:"range",min:"1.2",max:"1.8",step:"0.02",value:N.lineHeightMultiplier,onChange:M=>r({lineHeightMultiplier:parseFloat(M.target.value)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex justify-between text-[#666666] dark:text-[#888888] mb-1 font-mono text-[11px]",children:[f.jsx("span",{children:"配图避让间隙 (Gap)"}),f.jsxs("span",{className:"text-[#171717] dark:text-white font-semibold",children:[N.obstacleGap,"px"]})]}),f.jsx("input",{type:"range",min:"12",max:"48",step:"2",value:N.obstacleGap,onChange:M=>r({obstacleGap:parseInt(M.target.value,10)}),className:"w-full h-1.5 bg-[#e5e5e5] dark:bg-[#222222] rounded-lg cursor-pointer"})]})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(Mp,{className:"w-3.5 h-3.5 text-emerald-600 dark:text-emerald-400"}),f.jsx("span",{children:"版心安全边距"})]}),f.jsxs("div",{className:"grid grid-cols-2 gap-2 text-[11px] font-mono",children:[f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"上边距 (Top)"}),f.jsx("input",{type:"number",value:N.safeArea.top,onChange:M=>d({top:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"下边距 (Bottom)"}),f.jsx("input",{type:"number",value:N.safeArea.bottom,onChange:M=>d({bottom:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"左边距 (Left)"}),f.jsx("input",{type:"number",value:N.safeArea.left,onChange:M=>d({left:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]}),f.jsxs("div",{children:[f.jsx("span",{className:"text-[#777777] dark:text-[#666666] block mb-1",children:"右边距 (Right)"}),f.jsx("input",{type:"number",value:N.safeArea.right,onChange:M=>d({right:parseInt(M.target.value,10)||0}),className:"w-full bg-[#fafafa] dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white"})]})]})]}),f.jsxs("div",{className:"p-3.5 border-b border-[#f0f0f0] dark:border-[#1c1c1c]",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(Np,{className:"w-3.5 h-3.5 text-purple-600 dark:text-purple-400"}),f.jsx("span",{children:"视觉色彩主题"})]}),f.jsxs("div",{className:"flex flex-col gap-2.5 text-xs",children:[f.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[f.jsx("button",{onClick:()=>s({bgColor:"#ffffff",textColor:"#171717",headingColor:"#171717",accentColor:"#059669",quoteColor:"#525252",cardBg:"#f5f5f5"}),className:"w-6 h-6 rounded-full bg-[#ffffff] border-2 border-emerald-500 shadow-sm hover:scale-105 transition-all",title:"素白雅致 (推荐)"}),f.jsx("button",{onClick:()=>s({bgColor:"#f9fcfa",textColor:"#22201d",headingColor:"#0f2e22",accentColor:"#1d4f39",quoteColor:"#474038",cardBg:"#ffffff"}),className:"w-6 h-6 rounded-full bg-[#f9fcfa] border border-[#ccc] shadow-sm hover:scale-105 transition-all",title:"纸白浅草"}),f.jsx("button",{onClick:()=>s({bgColor:"#0a0a0a",textColor:"#ededed",headingColor:"#ffffff",accentColor:"#00e676",quoteColor:"#a0a0a0",cardBg:"#121212"}),className:"w-6 h-6 rounded-full bg-[#0a0a0a] border border-[#444] shadow-sm hover:scale-105 transition-all",title:"深邃暗夜"}),f.jsx("button",{onClick:()=>s({bgColor:"#09090b",textColor:"#fafafa",headingColor:"#ffffff",accentColor:"#3b82f6",quoteColor:"#a1a1aa",cardBg:"#18181b"}),className:"w-6 h-6 rounded-full bg-[#09090b] border border-blue-500 shadow-sm hover:scale-105 transition-all",title:"数码蓝暗黑"})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888] font-medium",children:"标题颜色 (Heading)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:m.headingColor||m.textColor,onChange:M=>s({headingColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.headingColor||m.textColor})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888]",children:"正文字色 (Text)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:m.textColor,onChange:M=>s({textColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.textColor})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888]",children:"重点强调色 (Accent)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:m.accentColor,onChange:M=>s({accentColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.accentColor})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#666666] dark:text-[#888888]",children:"背景底色 (Canvas)"}),f.jsxs("div",{className:"flex items-center gap-1.5",children:[f.jsx("input",{type:"color",value:u.canvasStyle?.fill?.type==="solid"?u.canvasStyle.fill.color:m.bgColor,onChange:M=>s({bgColor:M.target.value}),className:"w-6 h-6 rounded cursor-pointer bg-transparent border-0"}),f.jsx("span",{className:"font-mono text-[11px] text-[#444444] dark:text-[#cccccc]",children:m.bgColor})]})]})]})]}),f.jsx(Jp,{config:u,onChange:v}),f.jsxs("div",{className:"p-3.5",children:[f.jsxs("div",{className:"flex items-center gap-2 text-xs font-semibold text-[#171717] dark:text-white mb-3",children:[f.jsx(sp,{className:"w-3.5 h-3.5 text-amber-500 dark:text-amber-400"}),f.jsx("span",{children:"页眉页脚与版式装饰 (Chrome)"})]}),f.jsxs("div",{className:"flex flex-col gap-3 text-xs",children:[f.jsxs("div",{className:"bg-[#f9f9f9] dark:bg-[#141414] p-2.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] flex flex-col gap-2",children:[f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"font-semibold text-[#333333] dark:text-[#cccccc] text-[11px]",children:"顶部栏 (Header)"}),f.jsxs("label",{className:"flex items-center gap-1.5 cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showHeader??!!u.watermarkText?.trim(),onChange:M=>g({showHeader:M.target.checked}),className:"rounded text-emerald-500 accent-emerald-500 cursor-pointer"}),f.jsx("span",{className:"text-[10px] text-[#666666] dark:text-[#888888]",children:"启用"})]})]}),(u.chrome?.showHeader??!!u.watermarkText?.trim())&&f.jsxs("div",{className:"flex flex-col gap-2 pl-2 border-l-2 border-[#e0e0e0] dark:border-[#2a2a2a] mt-1",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex items-center justify-between mb-1",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"水印 / 品牌标识"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showWatermark??!0,onChange:M=>g({showWatermark:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]}),f.jsx("input",{type:"text",value:u.watermarkText,onChange:M=>x(u.footerText,M.target.value),placeholder:"作者水印/标识文本...",className:"w-full bg-white dark:bg-[#0a0a0a] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white text-[11px]"})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"页码角标 (P.01)"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showPageNumber??u.aspectRatio==="longform-3-4",onChange:M=>g({showPageNumber:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]})]})]}),f.jsxs("div",{className:"bg-[#f9f9f9] dark:bg-[#141414] p-2.5 rounded-lg border border-[#eaeaea] dark:border-[#222222] flex flex-col gap-2",children:[f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"font-semibold text-[#333333] dark:text-[#cccccc] text-[11px]",children:"底部栏 (Footer)"}),f.jsxs("label",{className:"flex items-center gap-1.5 cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFooter??!!u.footerText?.trim(),onChange:M=>g({showFooter:M.target.checked}),className:"rounded text-emerald-500 accent-emerald-500 cursor-pointer"}),f.jsx("span",{className:"text-[10px] text-[#666666] dark:text-[#888888]",children:"启用"})]})]}),(u.chrome?.showFooter??!!u.footerText?.trim())&&f.jsxs("div",{className:"flex flex-col gap-2 pl-2 border-l-2 border-[#e0e0e0] dark:border-[#2a2a2a] mt-1",children:[f.jsxs("div",{children:[f.jsxs("div",{className:"flex items-center justify-between mb-1",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"页脚署名 / 版权"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFooterText??!0,onChange:M=>g({showFooterText:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]}),f.jsx("input",{type:"text",value:u.footerText,onChange:M=>x(M.target.value,u.watermarkText),placeholder:"页脚版权/署名...",className:"w-full bg-white dark:bg-[#0a0a0a] border border-[#d4d4d4] dark:border-[#262626] rounded px-2 py-1 text-black dark:text-white text-[11px]"})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"顶部分割细线"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFooterDivider??!!u.footerText?.trim(),onChange:M=>g({showFooterDivider:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]}),f.jsxs("div",{className:"flex items-center justify-between",children:[f.jsx("span",{className:"text-[#777777] dark:text-[#888888] text-[10px]",children:"算法填充率提示"}),f.jsxs("label",{className:"flex items-center gap-1 text-[10px] text-[#666666] dark:text-[#888888] cursor-pointer",children:[f.jsx("input",{type:"checkbox",checked:u.chrome?.showFillRatio??!1,onChange:M=>g({showFillRatio:M.target.checked}),className:"rounded accent-emerald-500 cursor-pointer"}),f.jsx("span",{children:"显示"})]})]})]})]})]})]})]})},Wp=({isOpen:u,onClose:r,refreshKey:s,onApplyTemplate:c,adminKey:d})=>{const[x,g]=fe.useState([]),[v,N]=fe.useState({}),[m,y]=fe.useState("default"),[p,b]=fe.useState("all"),[w,M]=fe.useState(!1),[Q,B]=fe.useState(null),L=async(H=m)=>{try{const V=await fetch(`/api/templates/slots?account=${encodeURIComponent(H)}`,{headers:{"x-admin-key":d}}),Y=await V.json();if(!V.ok||!Y.ok)throw new Error(Y.message||Y.error||"获取槽位失败");Y.ok&&Y.slots&&N(Y.slots)}catch(V){B(V instanceof Error?V.message:"模板请求失败")}},P=async(H,V)=>{try{const Y=await fetch("/api/templates/slots",{method:"POST",headers:{"Content-Type":"application/json",...d?{"x-admin-key":d}:{}},body:JSON.stringify({slot:H,templateId:V,account:m})}),S=await Y.json();if(!Y.ok||!S.ok)throw new Error(S.message||S.error||"设置默认模板失败");S.ok&&await L(m)}catch(Y){B(Y instanceof Error?Y.message:"模板请求失败")}},ee=async()=>{M(!0),B(null);try{const H=await fetch("/api/templates",{headers:d?{"x-admin-key":d}:{}}),V=await H.json();H.ok&&V.ok&&Array.isArray(V.templates)?g(V.templates):B(V.message||"获取模板失败,请检查密钥")}catch{B("连接后端服务失败")}finally{M(!1)}};fe.useEffect(()=>{u&&(ee(),L(m))},[u,m,d,s]),fe.useEffect(()=>{if(!u)return;const H=V=>{V.key==="Escape"&&!document.querySelector("dialog[open]")&&r()};return window.addEventListener("keydown",H),()=>window.removeEventListener("keydown",H)},[u,r]);const ce=async H=>{try{const V=await fetch(`/api/templates/${encodeURIComponent(H)}`,{method:"DELETE",headers:d?{"x-admin-key":d}:{}}),Y=await V.json();if(!V.ok||!Y.ok)throw new Error(Y.message||Y.error||"删除模板失败");g(S=>S.filter(U=>U.id!==H)),await L(m)}catch(V){B(V instanceof Error?V.message:"模板请求失败")}};if(!u)return null;const re=x.filter(H=>p==="all"?!0:H.slot===p);return f.jsxs("aside",{"aria-label":"模板库",className:"absolute inset-y-0 right-0 z-40 w-80 max-w-full bg-white dark:bg-[#0f0f0f] border-l border-[#eaeaea] dark:border-[#262626] flex flex-col shadow-xl overflow-hidden",children:[f.jsxs("div",{className:"flex items-center justify-between px-5 py-3.5 border-b border-[#eaeaea] dark:border-[#222222]",children:[f.jsxs("div",{className:"flex items-center gap-2 font-semibold text-sm text-[#171717] dark:text-white",children:[f.jsx(So,{className:"w-4 h-4 text-emerald-500 dark:text-emerald-400"}),f.jsx("span",{children:"模板库"})]}),f.jsx("button",{onClick:r,"aria-label":"关闭模板库",className:"text-[#888888] hover:text-black dark:hover:text-white p-1 rounded-md hover:bg-[#f5f5f5] dark:hover:bg-[#1a1a1a]",children:f.jsx(jo,{className:"w-4 h-4"})})]}),f.jsxs("div",{className:"p-3 flex-1 min-h-0 flex flex-col gap-4 overflow-y-auto",children:[Q&&f.jsx("div",{role:"alert",className:"text-xs text-red-500 bg-red-500/10 p-2 rounded border border-red-500/20",children:Q}),f.jsxs("div",{className:"flex flex-col gap-2",children:[f.jsx("div",{className:"flex items-center justify-between text-xs",children:f.jsxs("div",{className:"flex items-center gap-1.5 font-medium text-[#666666] dark:text-[#888888]",children:[f.jsx("span",{children:"槽位账号:"}),f.jsxs("select",{value:m,onChange:H=>y(H.target.value),className:"bg-white dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#2a2a2a] rounded px-2 py-0.5 text-xs text-black dark:text-white focus:outline-none font-mono",children:[f.jsx("option",{value:"default",children:"default (主账号)"}),f.jsx("option",{value:"ancientone",children:"ancientone"})]})]})}),f.jsxs("div",{className:"flex flex-wrap items-center gap-1 text-xs",children:[f.jsx("button",{onClick:()=>b("all"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="all"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"全部"}),f.jsx("button",{onClick:()=>b("article_cover"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="article_cover"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"文章封面"}),f.jsx("button",{onClick:()=>b("newspic_cover"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="newspic_cover"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"贴图封面"}),f.jsx("button",{onClick:()=>b("newspic_content"),className:`px-2.5 py-1 rounded text-xs transition-colors font-medium ${p==="newspic_content"?"bg-black text-white dark:bg-white dark:text-black":"text-[#666666] dark:text-[#888888] hover:bg-[#f5f5f5] dark:hover:bg-[#1c1c1c]"}`,children:"贴图内容"})]})]}),f.jsx("div",{className:"flex flex-col gap-2",children:w?f.jsx("div",{className:"text-center py-8 text-xs text-[#888888] dark:text-[#555555]",children:"正在加载模板..."}):re.length===0?f.jsx("div",{className:"text-center py-8 text-xs text-[#888888] dark:text-[#555555]",children:"暂无匹配模板"}):re.map(H=>{const V=v.article_cover?.id===H.id,Y=v.newspic_cover?.id===H.id,S=v.newspic_content?.id===H.id;return f.jsxs("div",{className:"flex flex-col justify-between p-3 rounded-lg bg-[#fafafa] dark:bg-[#141414] border border-[#eaeaea] dark:border-[#222222] hover:border-[#cccccc] dark:hover:border-[#333333] transition-all gap-2 group",children:[f.jsxs("div",{className:"flex items-center gap-3",children:[f.jsx("div",{className:"w-5 h-5 rounded border border-[#d4d4d4] dark:border-[#333333] shrink-0",style:{backgroundColor:H.theme.bgColor}}),f.jsxs("div",{children:[f.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[f.jsx("span",{className:"text-xs font-semibold text-[#171717] dark:text-white",children:H.name}),H.slot&&f.jsx("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/20 font-medium",children:H.slot==="article_cover"?"文章封面":H.slot==="newspic_cover"?"贴图封面":"贴图内容"}),V&&f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/20 font-medium flex items-center gap-0.5",children:[f.jsx(ho,{className:"w-2.5 h-2.5 fill-amber-500"})," 文章封面默认"]}),Y&&f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/20 font-medium flex items-center gap-0.5",children:[f.jsx(ho,{className:"w-2.5 h-2.5 fill-amber-500"})," 贴图封面默认"]}),S&&f.jsxs("span",{className:"text-[10px] px-1.5 py-0.2 rounded bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border border-emerald-500/20 font-medium flex items-center gap-0.5",children:[f.jsx(ho,{className:"w-2.5 h-2.5 fill-emerald-500"})," 贴图内容默认"]})]}),f.jsxs("div",{className:"text-[10px] text-[#888888] dark:text-[#666666] font-mono mt-0.5",children:[H.aspectRatio," • 字号: ",H.algorithm.baseFontSize,"px",H.images&&H.images.length>0&&` • 配图: ${H.images.length}个`]})]})]}),f.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[H.id&&f.jsxs("select",{value:"",onChange:U=>{U.target.value&&P(U.target.value,H.id)},className:"text-[11px] bg-white dark:bg-[#1a1a1a] border border-[#d4d4d4] dark:border-[#333333] text-[#666666] dark:text-[#aaaaaa] rounded px-2 py-1 focus:outline-none",title:"为此账号设为某个槽位的默认模板",children:[f.jsx("option",{value:"",children:"设为槽位默认..."}),f.jsx("option",{value:"article_cover",children:"设为「文章封面默认」"}),f.jsx("option",{value:"newspic_cover",children:"设为「贴图封面默认」"}),f.jsx("option",{value:"newspic_content",children:"设为「贴图内容默认」"})]}),f.jsxs("button",{onClick:()=>{c(H)},className:"flex items-center gap-1 px-2.5 py-1 bg-white dark:bg-[#1f1f1f] hover:bg-emerald-50 dark:hover:bg-emerald-500/20 text-[#333333] dark:text-[#cccccc] hover:text-emerald-700 dark:hover:text-emerald-400 border border-[#d4d4d4] dark:border-[#2a2a2a] hover:border-emerald-500/40 rounded text-xs transition-all font-medium",children:[f.jsx(Qx,{className:"w-3 h-3"}),f.jsx("span",{children:"套用"})]}),H.id&&!H.id.startsWith("tpl_wechat_")&&!H.id.startsWith("tpl_longform_")&&!H.id.startsWith("tpl_square_")&&!H.id.startsWith("tpl_wide_")&&f.jsx("button",{onClick:()=>ce(H.id),className:"p-1 text-[#888888] dark:text-[#555555] hover:text-red-500 rounded hover:bg-[#f0f0f0] dark:hover:bg-[#1f1f1f]",title:"删除自定义模板",children:f.jsx(Eh,{className:"w-3.5 h-3.5"})})]})]},H.id)})})]})]})};function Cr(u=[]){if(!Array.isArray(u))throw new RangeError("模板图片必须是数组");const r=new Set;for(const s of u){if(!s||typeof s!="object")throw new RangeError("无效的模板图片");if(s.templateAssetKey===void 0)continue;const c=s.templateAssetKey;if(s.repeatEveryPage!==void 0&&typeof s.repeatEveryPage!="boolean")throw new RangeError(`素材 ${c} 的每页重复开关必须是布尔值`);if(typeof c!="string"||!/^[a-zA-Z0-9_-]+$/.test(c))throw new RangeError("素材标识只能包含字母、数字、下划线和短横线");if(s.repeatEveryPage&&!s.isAbsolute)throw new RangeError(`素材 ${c} 的每页重复仅支持自由定位模式`);if(r.has(c))throw new RangeError(`重复的模板素材标识:${c}`);r.add(c)}}function $p(u,r=[],s={}){if(Cr(r),!s||typeof s!="object"||Array.isArray(s))throw new RangeError("素材替换必须是标识到图片地址的映射");const c=r.filter(v=>v.templateAssetKey);for(const[v,N]of Object.entries(s)){if(!c.some(m=>m.templateAssetKey===v))throw new RangeError(`未知模板素材:${v}`);if(typeof N!="string"||!N.trim())throw new RangeError(`素材 ${v} 的替换图片不能为空`)}const d=u.filter(v=>!v.templateAssetKey),x=r.filter(v=>!v.templateAssetKey);return[...d.length===0?x.map(v=>({...v,id:`img_${crypto.randomUUID()}`})):d.map((v,N)=>{const m=x[N];return m?{...v,layoutPreset:m.layoutPreset??v.layoutPreset,isAbsolute:m.isAbsolute??v.isAbsolute,x:m.x??v.x,y:m.y??v.y,width:m.width??v.width,height:m.height??v.height,rotate:m.rotate??v.rotate,opacity:m.opacity??v.opacity,zIndex:m.zIndex??v.zIndex,borderRadius:m.borderRadius??v.borderRadius,captionHeight:m.captionHeight??v.captionHeight,pageIndex:m.pageIndex??v.pageIndex}:v}),...c.map(v=>({...v,src:Object.hasOwn(s,v.templateAssetKey)?s[v.templateAssetKey]:v.src}))]}const Pp=({isOpen:u,onClose:r,currentConfig:s,onSaved:c,adminKey:d})=>{const x=fe.useRef(null),[g,v]=fe.useState(""),[N,m]=fe.useState("none"),[y,p]=fe.useState(!1),[b,w]=fe.useState(null);fe.useEffect(()=>{u?(v(s.name||"我的自定义模板"),m(s.slot||(s.aspectRatio==="wechat-cover-2.35"?"article_cover":"newspic_content")),w(null),x.current?.showModal()):x.current?.close()},[u]);const M=async Q=>{if(Q.preventDefault(),!(!g.trim()||y)){p(!0),w(null);try{Cr(s.images);const B=await fetch("/api/templates",{method:"POST",headers:{"Content-Type":"application/json",...d?{"x-admin-key":d}:{}},body:JSON.stringify({...s,id:void 0,name:g.trim(),slot:N==="none"?void 0:N})}),L=await B.json();if(!B.ok||!L.ok)throw new Error(L.message||L.error||"保存模板失败");c(L.template),r()}catch(B){w(B instanceof Error?B.message:"保存模板请求异常")}finally{p(!1)}}};return f.jsx("dialog",{ref:x,"aria-labelledby":"save-template-title",onCancel:Q=>{Q.preventDefault(),y||r()},className:"m-auto w-[calc(100%-2rem)] max-w-sm p-0 rounded-xl border border-[#eaeaea] dark:border-[#262626] bg-white dark:bg-[#0f0f0f] text-[#171717] dark:text-white shadow-2xl backdrop:bg-black/40",children:f.jsxs("form",{onSubmit:M,children:[f.jsxs("div",{className:"flex items-center justify-between px-5 py-3.5 border-b border-[#eaeaea] dark:border-[#222222]",children:[f.jsx("h2",{id:"save-template-title",className:"text-sm font-semibold",children:"保存模板"}),f.jsx("button",{type:"button",onClick:r,disabled:y,"aria-label":"关闭保存模板",className:"p-1 rounded hover:bg-black/5 dark:hover:bg-white/10 disabled:opacity-50",children:f.jsx(jo,{className:"w-4 h-4"})})]}),f.jsxs("div",{className:"p-5 flex flex-col gap-4",children:[f.jsxs("label",{className:"flex flex-col gap-2 text-xs",children:["模板名称",f.jsx("input",{autoFocus:!0,required:!0,value:g,onChange:Q=>v(Q.target.value),placeholder:"输入模板名称",className:"bg-transparent border border-[#d4d4d4] dark:border-[#333333] rounded px-3 py-2 focus:outline-none focus:border-emerald-500"})]}),f.jsxs("label",{className:"flex flex-col gap-2 text-xs",children:["保存到槽位",f.jsxs("select",{value:N,onChange:Q=>m(Q.target.value),className:"bg-white dark:bg-[#141414] border border-[#d4d4d4] dark:border-[#333333] rounded px-3 py-2",children:[f.jsx("option",{value:"article_cover",children:"文章封面 (3.35:1)"}),f.jsx("option",{value:"newspic_cover",children:"贴图封面 (3:4)"}),f.jsx("option",{value:"newspic_content",children:"贴图内容 (3:4)"}),f.jsx("option",{value:"none",children:"通用模板"})]})]}),b&&f.jsx("p",{role:"alert",className:"text-xs text-red-500",children:b}),f.jsxs("button",{type:"submit",disabled:y||!g.trim(),className:"flex items-center justify-center gap-2 px-3 py-2 rounded bg-black text-white dark:bg-white dark:text-black text-xs font-semibold disabled:opacity-50",children:[f.jsx(dh,{className:"w-3.5 h-3.5"}),y?"保存中...":"保存模板"]})]})]})})},go="typeset_studio_admin_key";function eb(){const[u,r]=fe.useState(()=>localStorage.getItem(go)||""),[s,c]=fe.useState(null),[d,x]=fe.useState(!1),g=async N=>{if(!N)return c(!1),!1;x(!0);try{const p=!!(await(await fetch("/api/auth/verify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({key:N})})).json()).ok;return c(p),p}catch{return c(!1),!1}finally{x(!1)}},v=N=>{localStorage.setItem(go,N),r(N),g(N)};return fe.useEffect(()=>{(async()=>{let m=u;if(!m)try{const p=await(await fetch("/api/auth/current-key")).json();p.ok&&p.key&&(m=p.key,r(p.key),localStorage.setItem(go,p.key))}catch{}m?g(m):c(!1)})()},[]),{adminKey:u,setAdminKey:v,isVerified:s,isVerifying:d,verifyKey:g}}const tb=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],Nx=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function lb(u){if(u<=255)return tb[u];let r=0,s=Nx.length-1;for(;r<=s;){const c=r+s>>1,d=Nx[c];if(u<d[0]){s=c-1;continue}if(u>d[1]){r=c+1;continue}return d[2]}return"L"}function nb(u){const r=u.length;if(r===0)return null;const s=new Array(r);let c=!1;for(let m=0;m<r;){const y=u.charCodeAt(m);let p=y,b=1;if(y>=55296&&y<=56319&&m+1<r){const M=u.charCodeAt(m+1);M>=56320&&M<=57343&&(p=(y-55296<<10)+(M-56320)+65536,b=2)}const w=lb(p);(w==="R"||w==="AL"||w==="AN")&&(c=!0);for(let M=0;M<b;M++)s[m+M]=w;m+=b}if(!c)return null;let d=0;for(let m=0;m<r;m++){const y=s[m];if(y==="L"){d=0;break}if(y==="R"||y==="AL"){d=1;break}}const x=new Int8Array(r);for(let m=0;m<r;m++)x[m]=d;const g=d&1?"R":"L",v=g;let N=v;for(let m=0;m<r;m++)s[m]==="NSM"?s[m]=N:N=s[m];N=v;for(let m=0;m<r;m++){const y=s[m];y==="EN"?s[m]=N==="AL"?"AN":"EN":(y==="R"||y==="L"||y==="AL")&&(N=y)}for(let m=0;m<r;m++)s[m]==="AL"&&(s[m]="R");for(let m=1;m<r-1;m++)s[m]==="ES"&&s[m-1]==="EN"&&s[m+1]==="EN"&&(s[m]="EN"),s[m]==="CS"&&(s[m-1]==="EN"||s[m-1]==="AN")&&s[m+1]===s[m-1]&&(s[m]=s[m-1]);for(let m=0;m<r;m++){if(s[m]!=="EN")continue;let y;for(y=m-1;y>=0&&s[y]==="ET";y--)s[y]="EN";for(y=m+1;y<r&&s[y]==="ET";y++)s[y]="EN"}for(let m=0;m<r;m++){const y=s[m];(y==="WS"||y==="ES"||y==="ET"||y==="CS")&&(s[m]="ON")}N=v;for(let m=0;m<r;m++){const y=s[m];y==="EN"?s[m]=N==="L"?"L":"EN":(y==="R"||y==="L")&&(N=y)}for(let m=0;m<r;m++){if(s[m]!=="ON")continue;let y=m+1;for(;y<r&&s[y]==="ON";)y++;const p=m>0?s[m-1]:v,b=y<r?s[y]:v,w=p!=="L"?"R":"L";if(w===(b!=="L"?"R":"L"))for(let Q=m;Q<y;Q++)s[Q]=w;m=y-1}for(let m=0;m<r;m++)s[m]==="ON"&&(s[m]=g);for(let m=0;m<r;m++){const y=s[m];(x[m]&1)===0?y==="R"?x[m]++:(y==="AN"||y==="EN")&&(x[m]+=2):(y==="L"||y==="AN"||y==="EN")&&x[m]++}return x}function ab(u,r){const s=nb(u);if(s===null)return null;const c=new Int8Array(r.length);for(let d=0;d<r.length;d++)c[d]=s[r[d]];return c}const ib=/[ \t\n\r\f]+/g,ub=/[\t\n\r\f]| {2,}|^ | $/;function rb(u){const r=u??"normal";return r==="pre-wrap"?{mode:r,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:r,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}}function cb(u){if(!ub.test(u))return u;let r=u.replace(ib," ");return r.charCodeAt(0)===32&&(r=r.slice(1)),r.length>0&&r.charCodeAt(r.length-1)===32&&(r=r.slice(0,-1)),r}function sb(u){return/[\r\f]/.test(u)?u.replace(/\r\n/g,`
293
293
  `).replace(/[\r\f]/g,`
294
294
  `):u}let br=null,ob;function fb(){return br===null&&(br=new Intl.Segmenter(ob,{granularity:"word"})),br}function db(){br=null}const xb=/\p{Script=Arabic}/u,cn=/\p{M}/u,Do=/\p{Nd}/u;function Sx(u){return xb.test(u)}function Ex(u){return u>=19968&&u<=40959||u>=13312&&u<=19903||u>=131072&&u<=173791||u>=173824&&u<=177983||u>=177984&&u<=178207||u>=178208&&u<=183983||u>=183984&&u<=191471||u>=191472&&u<=192093||u>=194560&&u<=195103||u>=196608&&u<=201551||u>=201552&&u<=205743||u>=205744&&u<=210041||u>=63744&&u<=64255||u>=12288&&u<=12351||u>=12352&&u<=12447||u>=12448&&u<=12543||u>=12592&&u<=12687||u>=44032&&u<=55215||u>=65280&&u<=65519}function dl(u){for(let r=0;r<u.length;r++){const s=u.charCodeAt(r);if(!(s<12288)){if(s>=55296&&s<=56319&&r+1<u.length){const c=u.charCodeAt(r+1);if(c>=56320&&c<=57343){const d=(s-55296<<10)+(c-56320)+65536;if(Ex(d))return!0;r++;continue}}if(Ex(s))return!0}}return!1}function hb(u){const r=Ri(u);return r!==null&&(Oo.has(r)||Rn.has(r))}const mb=new Set([" "," ","⁠","\uFEFF"]),gb=new Set(["-","‐","–","—"]);function pb(u){const r=Ri(u);return r!==null&&mb.has(r)}function bb(u){const r=Ri(u);return r!==null&&gb.has(r)}function Oh(u,r){return pb(u)?!1:r?!(hb(u)||bb(u)):!0}const Oo=new Set([",",".","!",":",";","?","、","。","・",")","〕","〉","》","」","』","】","〗","〙","〛","ー","々","〻","ゝ","ゞ","ヽ","ヾ"]),Mr=new Set(['"',"(","[","{","¡","¿","“","‘","‚","„","«","‹","⸘","(","〔","〈","《","「","『","【","〖","〘","〚"]),Bo=new Set(["'","’"]),Rn=new Set([".",",","!","?",":",";","،","؛","؟","।","॥","၊","။","၌","၍","၏",")","]","}","%",'"',"”","’","»","›","…"]),vb=new Set([":",".","،","؛"]),yb=new Set(["၏"]),Nb=new Set(["”","’","»","›","」","』","】","》","〉","〕",")"]);function Sb(u){if(zo(u))return!0;let r=!1;for(const s of u){if(Rn.has(s)||kr(s)){r=!0;continue}if(!(r&&cn.test(s)))return!1}return r}function Eb(u){for(const r of u)if(!Oo.has(r)&&!Rn.has(r))return!1;return u.length>0}function Ab(u){if(zo(u))return!0;for(const r of u)if(!Mr.has(r)&&!Bo.has(r)&&!cn.test(r)&&!kr(r))return!1;return u.length>0}function zo(u){let r=!1;for(const s of u)if(!(s==="\\"||cn.test(s))){if(Mr.has(s)||Rn.has(s)||Bo.has(s)){r=!0;continue}return!1}return r}function wr(u,r){const s=r-1;if(s<=0)return Math.max(s,0);const c=u.charCodeAt(s);if(c<56320||c>57343)return s;const d=s-1;if(d<0)return s;const x=u.charCodeAt(d);return x>=55296&&x<=56319?d:s}function Ri(u){if(u.length===0)return null;const r=wr(u,u.length);return u.slice(r)}function Cb(u){for(const r of u)if(!cn.test(r))return r;return null}function Mb(u){for(let r=u.length;r>0;){const s=wr(u,r),c=u.slice(s,r);if(!cn.test(c))return c;r=s}return null}const wb=[36,37,43,43,92,92,162,165,176,177,1423,1423,1545,1547,1642,1642,2046,2047,2546,2547,2553,2555,2801,2801,3065,3065,3449,3449,3647,3647,6107,6107,8240,8247,8279,8279,8352,8399,8451,8451,8457,8457,8470,8470,8722,8723,43064,43064,65020,65020,65129,65130,65284,65285,65504,65505,65509,65510,73693,73696,123647,123647,126124,126124,126128,126128];function kb(u,r){for(let s=0;s<r.length;s+=2)if(u>=r[s]&&u<=r[s+1])return!0;return!1}function kr(u){const r=u.codePointAt(0);return r!==void 0&&kb(r,wb)}function Tb(u){const r=Mb(u);return r!==null&&kr(r)}function Fb(u){const r=Cb(u);return r!==null&&Do.test(r)}function jb(u){const r=Array.from(u);let s=r.length;for(;s>0;){const c=r[s-1];if(cn.test(c)){s--;continue}if(Mr.has(c)||Bo.has(c)){s--;continue}break}return s<=0||s===r.length?null:{head:r.slice(0,s).join(""),tail:r.slice(s).join("")}}function Db(u,r,s){return s==="text"&&!r&&u.length===1&&u!=="-"&&u!=="—"?u:null}function Ax(u,r,s,c){const d=r[c],x=u[c];if(d==null)return x;const g=s[c];if(x.length===g)return x;const v=d.repeat(g);return u[c]=v,v}function Cx(u,r){return u&&r!==null&&vb.has(r)}function Ob(u){const r=Ri(u);return r!==null&&yb.has(r)}function Bb(u){if(u.length<2||u[0]!==" ")return null;const r=u.slice(1);return/^\p{M}+$/u.test(r)?{space:" ",marks:r}:null}function Eo(u){let r=u.length;for(;r>0;){const s=wr(u,r),c=u.slice(s,r);if(Nb.has(c))return!0;if(!Rn.has(c))return!1;r=s}return!1}function zb(u,r){if(r.preserveOrdinarySpaces||r.preserveHardBreaks){if(u===" ")return"preserved-space";if(u===" ")return"tab";if(r.preserveHardBreaks&&u===`
295
295
  `)return"hard-break"}return u===" "?"space":u===" "||u===" "||u==="⁠"||u==="\uFEFF"?"glue":u==="​"?"zero-width-break":u==="­"?"soft-hyphen":"text"}const _b=/[\x20\t\n\xA0\xAD\u200B\u202F\u2060\uFEFF]/;function $t(u){return u.length===1?u[0]:u.join("")}function Rb(u,r){const s=[];for(let c=u.length-1;c>=0;c--)s.push(u[c]);return s.push(r),$t(s)}function Lb(u,r,s,c){if(!_b.test(u))return[{text:u,isWordLike:r,kind:"text",start:s}];const d=[];let x=null,g=[],v=s,N=!1,m=0;for(const y of u){const p=zb(y,c),b=p==="text"&&r;if(x!==null&&p===x&&b===N){g.push(y),m+=y.length;continue}x!==null&&d.push({text:$t(g),isWordLike:N,kind:x,start:v}),x=p,g=[y],v=s+m,N=b,m+=y.length}return x!==null&&d.push({text:$t(g),isWordLike:N,kind:x,start:v}),d}function Ao(u){return u==="space"||u==="preserved-space"||u==="zero-width-break"||u==="hard-break"}const Hb=/^[A-Za-z][A-Za-z0-9+.-]*:$/;function Ub(u,r){const s=u.texts[r];return s.startsWith("www.")?!0:Hb.test(s)&&r+1<u.len&&u.kinds[r+1]==="text"&&u.texts[r+1]==="//"}function Gb(u){return u.includes("?")&&(u.includes("://")||u.startsWith("www."))}function qb(u){const r=u.texts.slice(),s=u.isWordLike.slice(),c=u.kinds.slice(),d=u.starts.slice();for(let g=0;g<u.len;g++){if(c[g]!=="text"||!Ub(u,g))continue;const v=[r[g]];let N=g+1;for(;N<u.len&&!Ao(c[N]);){v.push(r[N]),s[g]=!0;const m=r[N].includes("?");if(c[N]="text",r[N]="",N++,m)break}r[g]=$t(v)}let x=0;for(let g=0;g<r.length;g++){const v=r[g];v.length!==0&&(x!==g&&(r[x]=v,s[x]=s[g],c[x]=c[g],d[x]=d[g]),x++)}return r.length=x,s.length=x,c.length=x,d.length=x,{len:x,texts:r,isWordLike:s,kinds:c,starts:d}}function Yb(u){const r=[],s=[],c=[],d=[];for(let x=0;x<u.len;x++){const g=u.texts[x];if(r.push(g),s.push(u.isWordLike[x]),c.push(u.kinds[x]),d.push(u.starts[x]),!Gb(g))continue;const v=x+1;if(v>=u.len||Ao(u.kinds[v]))continue;const N=[],m=u.starts[v];let y=v;for(;y<u.len&&!Ao(u.kinds[y]);)N.push(u.texts[y]),y++;N.length>0&&(r.push($t(N)),s.push(!0),c.push("text"),d.push(m),x=y-1)}return{len:r.length,texts:r,isWordLike:s,kinds:c,starts:d}}const Xb=new Set([":","-","/","×",",",".","+","–","—"]),Qb=/[\p{P}\p{S}\p{Co}]/u,Vb=/\p{Emoji_Presentation}/u,Zb=new Set(["?","֊","-","‐","‒","–","—","…","‼","‽","⁉"]);function Kb(u){return u>=33&&u<=47&&u!==45||u>=58&&u<=64&&u!==63||u>=91&&u<=96||u>=123&&u<=126}function Bh(u){const r=u.charCodeAt(0);return r<128?Kb(r):!Zb.has(u)&&!Vb.test(u)&&Qb.test(u)}function Mx(u){let r=!1;for(const s of u)if(!cn.test(s)){if(!Bh(s))return!1;r=!0}return r}function Jb(u){for(let r=u.length;r>0;){const s=wr(u,r),c=u.slice(s,r);if(cn.test(c)){r=s;continue}return Bh(c)||kr(c)}return!1}function Ib(u,r,s,c){const d=!r&&Mx(u),x=!c&&Mx(s),g=Tb(u),v=(r||g)&&Jb(u);return!d&&!x&&!v||dl(u)||dl(s)?!1:(r||d||g)&&(c||x)}function zh(u){for(const r of u)if(Do.test(r))return!0;return!1}function Sr(u){if(u.length===0)return!1;for(const r of u)if(!(Do.test(r)||Xb.has(r)))return!1;return!0}function Wb(u){const r=[],s=[],c=[],d=[];for(let x=0;x<u.len;x++){const g=u.texts[x],v=u.kinds[x];if(v==="text"&&Sr(g)&&zh(g)){const N=[g];let m=x+1;for(;m<u.len&&u.kinds[m]==="text"&&Sr(u.texts[m]);)N.push(u.texts[m]),m++;r.push($t(N)),s.push(!0),c.push("text"),d.push(u.starts[x]),x=m-1;continue}r.push(g),s.push(u.isWordLike[x]),c.push(v),d.push(u.starts[x])}return{len:r.length,texts:r,isWordLike:s,kinds:c,starts:d}}function $b(u){const r=[],s=[],c=[],d=[];let x=0;for(;x<u.len;){const g=u.texts[x],v=u.kinds[x],N=u.isWordLike[x];if(v==="text"){const m=[g];let y=x+1,p=N;for(;y<u.len&&u.kinds[y]==="text"&&Ib(u.texts[y-1],u.isWordLike[y-1],u.texts[y],u.isWordLike[y]);){const b=u.texts[y];m.push(b),p=p||u.isWordLike[y],y++}if(y>x+1){r.push($t(m)),s.push(p),c.push("text"),d.push(u.starts[x]),x=y;continue}}r.push(g),s.push(N),c.push(v),d.push(u.starts[x]),x++}return{len:r.length,texts:r,isWordLike:s,kinds:c,starts:d}}function Pb(u){const r=[],s=[],c=[],d=[];for(let x=0;x<u.len;x++){const g=u.texts[x];if(u.kinds[x]==="text"&&g.includes("-")){const v=g.split("-");let N=v.length>1;for(let m=0;m<v.length;m++){const y=v[m];if(!N)break;(y.length===0||!zh(y)||!Sr(y))&&(N=!1)}if(N){let m=0;for(let y=0;y<v.length;y++){const p=v[y],b=y<v.length-1?`${p}-`:p;r.push(b),s.push(!0),c.push("text"),d.push(u.starts[x]+m),m+=b.length}continue}}r.push(g),s.push(u.isWordLike[x]),c.push(u.kinds[x]),d.push(u.starts[x])}return{len:r.length,texts:r,isWordLike:s,kinds:c,starts:d}}function ev(u){const r=[],s=[],c=[],d=[];let x=0;for(;x<u.len;){const g=[u.texts[x]];let v=u.isWordLike[x],N=u.kinds[x],m=u.starts[x];if(N==="glue"){const y=[g[0]],p=m;for(x++;x<u.len&&u.kinds[x]==="glue";)y.push(u.texts[x]),x++;const b=$t(y);if(x<u.len&&u.kinds[x]==="text")g[0]=b,g.push(u.texts[x]),v=u.isWordLike[x],N="text",m=p,x++;else{r.push(b),s.push(!1),c.push("glue"),d.push(p);continue}}else x++;if(N==="text")for(;x<u.len&&u.kinds[x]==="glue";){const y=[];for(;x<u.len&&u.kinds[x]==="glue";)y.push(u.texts[x]),x++;const p=$t(y);if(x<u.len&&u.kinds[x]==="text"){g.push(p,u.texts[x]),v=v||u.isWordLike[x],x++;continue}g.push(p)}r.push($t(g)),s.push(v),c.push(N),d.push(m)}return{len:r.length,texts:r,isWordLike:s,kinds:c,starts:d}}function tv(u){const r=u.texts.slice(),s=u.isWordLike.slice(),c=u.kinds.slice(),d=u.starts.slice();for(let x=0;x<r.length-1;x++){if(c[x]!=="text"||c[x+1]!=="text"||!dl(r[x])||!dl(r[x+1]))continue;const g=jb(r[x]);g!==null&&(r[x]=g.head,r[x+1]=g.tail+r[x+1],d[x+1]=d[x]+g.head.length)}return{len:r.length,texts:r,isWordLike:s,kinds:c,starts:d}}function lv(u,r,s){const c=fb();let d=0;const x=[],g=[],v=[],N=[],m=[],y=[],p=[],b=[],w=[],M=[],Q=[],B=[];for(const H of c.segment(u))for(const V of Lb(H.segment,H.isWordLike??!1,H.index,s)){let O=function(){y[G]!==null&&(g[G]=[Ax(x,y,p,G)],y[G]=null),g[G].push(V.text),v[G]=v[G]||V.isWordLike,b[G]=b[G]||U,w[G]=w[G]||_,M[G]=ne,Q[G]=he,B[G]=Cx(w[G],te)};const Y=V.kind==="text",S=Db(V.text,V.isWordLike,V.kind),U=dl(V.text),_=Sx(V.text),te=Ri(V.text),ne=Eo(V.text),he=Ob(V.text),G=d-1;r.carryCJKAfterClosingQuote&&Y&&d>0&&N[G]==="text"&&U&&b[G]&&M[G]||Y&&d>0&&N[G]==="text"&&Eb(V.text)&&b[G]||Y&&d>0&&N[G]==="text"&&Q[G]?O():Y&&d>0&&N[G]==="text"&&V.isWordLike&&_&&B[G]?(O(),v[G]=!0):S!==null&&d>0&&N[G]==="text"&&y[G]===S?p[G]=(p[G]??1)+1:Y&&!V.isWordLike&&d>0&&N[G]==="text"&&!b[G]&&(Sb(V.text)||V.text==="-"&&v[G])?O():(x[d]=V.text,g[d]=[V.text],v[d]=V.isWordLike,N[d]=V.kind,m[d]=V.start,y[d]=S,p[d]=S===null?0:1,b[d]=U,w[d]=_,M[d]=ne,Q[d]=he,B[d]=Cx(_,te),d++)}for(let H=0;H<d;H++){if(y[H]!==null){x[H]=Ax(x,y,p,H);continue}x[H]=$t(g[H])}for(let H=1;H<d;H++)N[H]==="text"&&!v[H]&&zo(x[H])&&N[H-1]==="text"&&!b[H-1]&&(x[H-1]+=x[H],v[H-1]=v[H-1]||v[H],x[H]="");const L=Array.from({length:d},()=>null);let P=-1;for(let H=d-1;H>=0;H--){const V=x[H];if(V.length!==0){if(N[H]==="text"&&!v[H]&&P>=0&&N[P]==="text"&&(Ab(V)||V==="-"&&Fb(x[P]))){const Y=L[P]??[];Y.push(V),L[P]=Y,m[P]=m[H],x[H]="";continue}P=H}}for(let H=0;H<d;H++){const V=L[H];V!=null&&(x[H]=Rb(V,x[H]))}let ee=0;for(let H=0;H<d;H++){const V=x[H];V.length!==0&&(ee!==H&&(x[ee]=V,v[ee]=v[H],N[ee]=N[H],m[ee]=m[H]),ee++)}x.length=ee,v.length=ee,N.length=ee,m.length=ee;const ce=ev({len:ee,texts:x,isWordLike:v,kinds:N,starts:m}),re=tv($b(Pb(Wb(Yb(qb(ce))))));for(let H=0;H<re.len-1;H++){const V=Bb(re.texts[H]);V!==null&&(re.kinds[H]!=="space"&&re.kinds[H]!=="preserved-space"||re.kinds[H+1]!=="text"||!Sx(re.texts[H+1])||(re.texts[H]=V.space,re.isWordLike[H]=!1,re.kinds[H]=re.kinds[H]==="preserved-space"?"preserved-space":"space",re.texts[H+1]=V.marks+re.texts[H+1],re.starts[H+1]=re.starts[H]+V.space.length))}return re}function nv(u,r){if(u.len===0)return[];if(!r.preserveHardBreaks)return[{startSegmentIndex:0,endSegmentIndex:u.len,consumedEndSegmentIndex:u.len}];const s=[];let c=0;for(let d=0;d<u.len;d++)u.kinds[d]==="hard-break"&&(s.push({startSegmentIndex:c,endSegmentIndex:d,consumedEndSegmentIndex:d+1}),c=d+1);return c<u.len&&s.push({startSegmentIndex:c,endSegmentIndex:u.len,consumedEndSegmentIndex:u.len}),s}function av(u,r,s){if(r.len<=1)return r;const c=[],d=[],x=[],g=[];let v=-1,N=!1;function m(b){c.push(r.texts[b]),d.push(r.isWordLike[b]),x.push("text"),g.push(r.starts[b])}function y(b,w){let M=!1;for(let L=b;L<w;L++)M=M||r.isWordLike[L];const Q=r.starts[b],B=w<r.len?r.starts[w]:u.length;c.push(u.slice(Q,B)),d.push(M),x.push("text"),g.push(Q)}function p(b){if(!(v<0)){if(N)v+1===b?m(v):y(v,b);else for(let w=v;w<b;w++)m(w);v=-1,N=!1}}for(let b=0;b<r.len;b++){const w=r.texts[b],M=r.kinds[b];if(M==="text"){v>=0&&!Oh(r.texts[b-1],s)&&p(b),v<0&&(v=b),N=N||dl(w);continue}p(b),c.push(w),d.push(r.isWordLike[b]),x.push(M),g.push(r.starts[b])}return p(r.len),{len:c.length,texts:c,isWordLike:d,kinds:x,starts:g}}function iv(u,r,s="normal",c="normal"){const d=rb(s),x=d.mode==="pre-wrap"?sb(u):cb(u);if(x.length===0)return{normalized:x,chunks:[],len:0,texts:[],isWordLike:[],kinds:[],starts:[]};const g=lv(x,r,d),v=c==="keep-all"?av(x,g,r.breakKeepAllAfterPunctuation):g;return{normalized:x,chunks:nv(v,d),...v}}let Da=null;const Co=new Map;let Oa=null;const uv=96,rv=/\p{Emoji_Presentation}/u,cv=/[\p{Emoji_Presentation}\p{Extended_Pictographic}\p{Regional_Indicator}\uFE0F\u20E3]/u;let vr=null;const Mo=new Map;function _o(){if(Da!==null)return Da;if(typeof OffscreenCanvas<"u")return Da=new OffscreenCanvas(1,1).getContext("2d"),Da;if(typeof document<"u")return Da=document.createElement("canvas").getContext("2d"),Da;throw new Error("Text measurement requires OffscreenCanvas or a DOM canvas context.")}function sv(u){let r=Co.get(u);return r||(r=new Map,Co.set(u,r)),r}function rn(u,r){let s=r.get(u);return s===void 0&&(s={width:_o().measureText(u).width,containsCJK:dl(u)},r.set(u,s)),s}function La(){if(Oa!==null)return Oa;if(typeof navigator>"u")return Oa={lineFitEpsilon:.005,carryCJKAfterClosingQuote:!1,breakKeepAllAfterPunctuation:!0,preferPrefixWidthsForBreakableRuns:!1,preferEarlySoftHyphenBreak:!1},Oa;const u=navigator.userAgent,s=navigator.vendor==="Apple Computer, Inc."&&u.includes("Safari/")&&!u.includes("Chrome/")&&!u.includes("Chromium/")&&!u.includes("CriOS/")&&!u.includes("FxiOS/")&&!u.includes("EdgiOS/"),c=u.includes("Chrome/")||u.includes("Chromium/")||u.includes("CriOS/")||u.includes("Edg/");return Oa={lineFitEpsilon:s?1/64:.005,carryCJKAfterClosingQuote:c,breakKeepAllAfterPunctuation:!s,preferPrefixWidthsForBreakableRuns:s,preferEarlySoftHyphenBreak:s},Oa}function ov(u){const r=u.match(/(\d+(?:\.\d+)?)\s*px/);return r?parseFloat(r[1]):16}function _h(){return vr===null&&(vr=new Intl.Segmenter(void 0,{granularity:"grapheme"})),vr}function fv(u){return rv.test(u)||u.includes("️")}function dv(u){return cv.test(u)}function xv(u,r){let s=Mo.get(u);if(s!==void 0)return s;const c=_o();c.font=u;const d=c.measureText("😀").width;if(s=0,d>r+.5&&typeof document<"u"&&document.body!==null){const x=document.createElement("span");x.style.font=u,x.style.display="inline-block",x.style.visibility="hidden",x.style.position="absolute",x.textContent="😀",document.body.appendChild(x);const g=x.getBoundingClientRect().width;document.body.removeChild(x),d-g>.5&&(s=d-g)}return Mo.set(u,s),s}function hv(u){let r=0;const s=_h();for(const c of s.segment(u))fv(c.segment)&&r++;return r}function mv(u,r){return r.emojiCount===void 0&&(r.emojiCount=hv(u)),r.emojiCount}function _n(u,r,s){return s===0?r.width:r.width-mv(u,r)*s}function gv(u,r,s,c,d){if(r.breakableFitAdvances!==void 0&&r.breakableFitMode===d)return r.breakableFitAdvances;r.breakableFitMode=d;const x=_h(),g=[];for(const y of x.segment(u))g.push(y.segment);if(g.length<=1)return r.breakableFitAdvances=null,r.breakableFitAdvances;if(d==="sum-graphemes"){const y=[];for(const p of g){const b=rn(p,s);y.push(_n(p,b,c))}return r.breakableFitAdvances=y,r.breakableFitAdvances}if(d==="pair-context"||g.length>uv){const y=[];let p=null,b=0;for(const w of g){const M=rn(w,s),Q=_n(w,M,c);if(p===null)y.push(Q);else{const B=p+w,L=rn(B,s);y.push(_n(B,L,c)-b)}p=w,b=Q}return r.breakableFitAdvances=y,r.breakableFitAdvances}const v=[];let N="",m=0;for(const y of g){N+=y;const p=rn(N,s),b=_n(N,p,c);v.push(b-m),m=b}return r.breakableFitAdvances=v,r.breakableFitAdvances}function pv(u,r){const s=_o();s.font=u;const c=sv(u),d=ov(u),x=r?xv(u,d):0;return{cache:c,fontSize:d,emojiCorrection:x}}function bv(){Co.clear(),Mo.clear(),vr=null}function vv(u){return u==="space"||u==="zero-width-break"||u==="soft-hyphen"}function Tr(u){return u==="space"||u==="preserved-space"||u==="tab"||u==="zero-width-break"||u==="soft-hyphen"}function Ro(u,r,s=u.widths.length){for(;r<s;){const c=u.kinds[r];if(!vv(c))break;r++}return r}function Rh(u,r){if(r<=0)return 0;const s=u%r;return Math.abs(s)<=1e-6?r:r-s}function Lh(u,r,s){return u.letterSpacing!==0&&r&&u.spacingGraphemeCounts[s]>0?u.letterSpacing:0}function Lo(u,r){return r===0?0:u+r}function yv(u,r){return u.letterSpacing!==0&&u.spacingGraphemeCounts[r]>0?u.letterSpacing:0}function Hh(u,r,s,c,d){const x=r==="tab"?d+yv(u,s):u.lineEndFitAdvances[s];return Lo(c,x)}function Er(u,r,s,c){const d=r==="tab"?0:u.lineEndFitAdvances[s];return Lo(c,d)}function Ar(u,r,s,c,d){const x=r==="tab"?d:u.lineEndPaintAdvances[s];return Lo(c,x)}function Uh(u,r,s){return u.letterSpacing!==0&&r?s+u.letterSpacing:s}function Gh(u,r){return u.letterSpacing===0?r:r+u.letterSpacing}function Ra(u,r,s){let c=r;for(;c<u.length&&u[c]<s;)c++;return c}function Nv(u,r,s,c,d){if(u.letterSpacing===0)return 0;if(d>0)return u.spacingGraphemeCounts[c]>0?u.letterSpacing:0;for(let x=c-1;x>=r;x--){const g=u.kinds[x];if(!(g==="space"||g==="zero-width-break"||g==="hard-break")){if(g==="soft-hyphen"){if(x===c-1)return 0;continue}return x===r&&s>0||u.spacingGraphemeCounts[x]>0?u.letterSpacing:0}}return 0}function qh(u,r,s,c,d,x){return r+Nv(u,s,c,d,x)}function Sv(u,r){let s=0,c=u.chunks.length;for(;s<c;){const d=Math.floor((s+c)/2);r<u.chunks[d].consumedEndSegmentIndex?c=d:s=d+1}return s<u.chunks.length?s:-1}function Ev(u,r,s){let c=s.segmentIndex;if(s.graphemeIndex>0)return r;const d=u.chunks[r];return d.startSegmentIndex===d.endSegmentIndex&&c===d.startSegmentIndex||(c<d.startSegmentIndex&&(c=d.startSegmentIndex),c=Ro(u,c,d.endSegmentIndex),c<d.endSegmentIndex)?(s.segmentIndex=c,s.graphemeIndex=0,r):d.consumedEndSegmentIndex>=u.widths.length?-1:(s.segmentIndex=d.consumedEndSegmentIndex,s.graphemeIndex=0,r+1)}function Av(u,r){if(r.segmentIndex>=u.widths.length)return-1;const s=Sv(u,r.segmentIndex);return s<0?-1:Ev(u,s,r)}function Cv(u,r,s){const{widths:c,kinds:d,breakableFitAdvances:x,breakablePreferredBreaks:g}=u;if(c.length===0)return 0;const N=La().lineFitEpsilon,m=r+N;let y=0,p=0,b=!1,w=0,M=0,Q=0,B=0,L=-1,P=0;function ee(){L=-1,P=0}function ce(U=Q,_=B,te=p){y++,s?.(te,w,M,U,_),p=0,b=!1,ee()}function re(U,_){b=!0,w=U,M=0,Q=U+1,B=0,p=_}function H(U,_,te){b=!0,w=U,M=_,Q=U,B=_+1,p=te}function V(U,_){if(!b){re(U,_);return}p+=_,Q=U+1,B=0}function Y(U,_){const te=x[U],ne=g[U]??null;let he=ne===null?-1:Ra(ne,0,_+1),G=-1,O=0,k=_;for(;k<te.length;){const F=te[k];if(!b)H(U,k,F);else if(p+F>m){if(ne!==null&&G>_){ce(U,G,O),k=G,he=Ra(ne,he,k+1),G=-1,O=0;continue}ce(),H(U,k,F)}else p+=F,Q=U,B=k+1;const Z=k+1;ne!==null&&ne[he]===Z&&(G=Z,O=p,he++),k++}b&&Q===U&&B===te.length&&(Q=U+1,B=0)}let S=0;for(;S<c.length&&!(!b&&(S=Ro(u,S),S>=c.length));){const U=c[S],_=d[S],te=Tr(_);if(!b){U>m&&x[S]!==null?Y(S,0):re(S,U),te&&(L=S+1,P=p-U),S++;continue}if(p+U>m){if(te){V(S,U),ce(S+1,0,p-U),S++;continue}if(L>=0){if(Q>L||Q===L&&B>0){ce();continue}ce(L,0,P);continue}if(U>m&&x[S]!==null){ce(),Y(S,0),S++;continue}ce();continue}V(S,U),te&&(L=S+1,P=p-U),S++}return b&&ce(),y}function Mv(u,r,s){if(u.simpleLineWalkFastPath)return Cv(u,r,s);const{widths:c,kinds:d,breakableFitAdvances:x,breakablePreferredBreaks:g,discretionaryHyphenWidth:v,chunks:N}=u;if(c.length===0||N.length===0)return 0;const m=La(),y=m.lineFitEpsilon,p=r+y;let b=0,w=0,M=!1,Q=0,B=0,L=0,P=0,ee=-1,ce=0,re=0,H=null;function V(){ee=-1,ce=0,re=0,H=null}function Y(){return H==="soft-hyphen"&&ee===L&&P===0?re:w}function S(O=L,k=P,F){b++,s!==void 0&&s(qh(u,F??Y(),Q,B,O,k),Q,B,O,k),w=0,M=!1,V()}function U(O,k){M=!0,Q=O,B=0,L=O+1,P=0,w=k}function _(O,k,F){M=!0,Q=O,B=k,L=O,P=k+1,w=F}function te(O,k){if(!M){U(O,k);return}w+=k,L=O+1,P=0}function ne(O,k,F,Z,W,ie){if(!k)return;const le=Er(u,O,F,W),ae=Ar(u,O,F,W,Z);ee=F+1,ce=w-ie+le,re=w-ie+ae,H=O}function he(O,k){const F=x[O],Z=g[O]??null;let W=Z===null?-1:Ra(Z,0,k+1),ie=-1,le=0,ae=k;for(;ae<F.length;){const A=F[ae];if(!M)_(O,ae,A);else{const K=Uh(u,!0,A),$=w+K;if(Gh(u,$)>p){if(Z!==null&&ie>k){S(O,ie,le),ae=ie,W=Ra(Z,W,ae+1),ie=-1,le=0;continue}S(),_(O,ae,A)}else w=$,L=O,P=ae+1}const X=ae+1;Z!==null&&Z[W]===X&&(ie=X,le=w,W++),ae++}M&&L===O&&P===F.length&&(L=O+1,P=0)}function G(O){b++,s?.(0,O.startSegmentIndex,0,O.consumedEndSegmentIndex,0),V()}for(let O=0;O<N.length;O++){const k=N[O];if(k.startSegmentIndex===k.endSegmentIndex){G(k);continue}M=!1,w=0,Q=k.startSegmentIndex,B=0,L=k.startSegmentIndex,P=0,V();let F=k.startSegmentIndex;for(;F<k.endSegmentIndex&&!(!M&&(F=Ro(u,F,k.endSegmentIndex),F>=k.endSegmentIndex));){const Z=d[F],W=Tr(Z),ie=Lh(u,M,F),le=Z==="tab"?Rh(w+ie,u.tabStopAdvance):c[F],ae=ie+le,A=Hh(u,Z,F,ie,le);if(Z==="soft-hyphen"){M&&(L=F+1,P=0,ee=F+1,ce=w+v,re=w+v,H=Z),F++;continue}if(!M){A>p&&x[F]!==null?he(F,0):U(F,le),ne(Z,W,F,le,ie,ae),F++;continue}if(w+A>p){const K=w+Er(u,Z,F,ie),$=w+Ar(u,Z,F,ie,le);if(H==="soft-hyphen"&&m.preferEarlySoftHyphenBreak&&ce<=p){S(ee,0,re);continue}if(W&&K<=p){te(F,ae),S(F+1,0,$),F++;continue}if(ee>=0&&ce<=p){if(L>ee||L===ee&&P>0){S();continue}const me=ee;S(me,0,re),F=me;continue}if(A>p&&x[F]!==null){S(),he(F,0),F++;continue}S();continue}te(F,ae),ne(Z,W,F,le,ie,ae),F++}if(M){const Z=ee===k.consumedEndSegmentIndex?re:w;S(k.consumedEndSegmentIndex,0,Z)}}return b}function wv(u,r,s,c){const d=u.chunks[s];if(d.startSegmentIndex===d.endSegmentIndex)return r.segmentIndex=d.consumedEndSegmentIndex,r.graphemeIndex=0,0;const{widths:x,kinds:g,breakableFitAdvances:v,breakablePreferredBreaks:N,discretionaryHyphenWidth:m}=u,y=La(),p=y.lineFitEpsilon,b=c+p,w=r.segmentIndex,M=r.graphemeIndex;let Q=0,B=!1,L=r.segmentIndex,P=r.graphemeIndex,ee=-1,ce=0,re=0,H=null;function V(){return H==="soft-hyphen"&&ee===L&&P===0?re:Q}function Y(G=L,O=P,k=V()){return B?(r.segmentIndex=G,r.graphemeIndex=O,qh(u,k,w,M,G,O)):null}function S(G,O){B=!0,L=G+1,P=0,Q=O}function U(G,O,k){B=!0,L=G,P=O+1,Q=k}function _(G,O){if(!B){S(G,O);return}Q+=O,L=G+1,P=0}function te(G,O,k,F,Z,W){if(!O)return;const ie=Er(u,G,k,Z),le=Ar(u,G,k,Z,F);ee=k+1,ce=Q-W+ie,re=Q-W+le,H=G}function ne(G,O){const k=v[G],F=N[G]??null;let Z=F===null?-1:Ra(F,0,O+1),W=-1,ie=0;for(let le=O;le<k.length;le++){const ae=k[le];if(!B)U(G,le,ae);else{const X=Uh(u,!0,ae),K=Q+X;if(Gh(u,K)>b)return F!==null&&W>O?Y(G,W,ie):Y();Q=K,L=G,P=le+1}const A=le+1;F!==null&&F[Z]===A&&(W=A,ie=Q,Z++)}return B&&L===G&&P===k.length&&(L=G+1,P=0),null}function he(){return H!=="soft-hyphen"||ee<0?null:ce<=b?Y(ee,0,re):null}for(let G=r.segmentIndex;G<d.endSegmentIndex;G++){const O=g[G],k=Tr(O),F=G===r.segmentIndex?r.graphemeIndex:0,Z=Lh(u,B,G),W=O==="tab"?Rh(Q+Z,u.tabStopAdvance):x[G],ie=Z+W,le=Hh(u,O,G,Z,W);if(O==="soft-hyphen"&&F===0){B&&(L=G+1,P=0,ee=G+1,ce=Q+m,re=Q+m,H=O);continue}if(!B){if(F>0){const A=ne(G,F);if(A!==null)return A}else if(le>b&&v[G]!==null){const A=ne(G,0);if(A!==null)return A}else S(G,W);te(O,k,G,W,Z,ie);continue}if(Q+le>b){const A=Q+Er(u,O,G,Z),X=Q+Ar(u,O,G,Z,W);if(H==="soft-hyphen"&&y.preferEarlySoftHyphenBreak&&ce<=b)return Y(ee,0,re);const K=he();if(K!==null)return K;if(k&&A<=b)return _(G,ie),Y(G+1,0,X);if(ee>=0&&ce<=b)return L>ee||L===ee&&P>0?Y():Y(ee,0,re);if(le>b&&v[G]!==null){const $=Y();if($!==null)return $;const me=ne(G,0);if(me!==null)return me}return Y()}_(G,ie),te(O,k,G,W,Z,ie)}return ee===d.consumedEndSegmentIndex&&P===0?Y(d.consumedEndSegmentIndex,0,re):Y(d.consumedEndSegmentIndex,0,Q)}function kv(u,r,s){const{widths:c,kinds:d,breakableFitAdvances:x,breakablePreferredBreaks:g}=u,N=La().lineFitEpsilon,m=s+N;let y=0,p=!1,b=r.segmentIndex,w=r.graphemeIndex,M=-1,Q=0;for(let B=r.segmentIndex;B<c.length;B++){const L=d[B],P=Tr(L),ee=B===r.segmentIndex?r.graphemeIndex:0,ce=x[B],re=c[B];if(!p){if(ee>0||re>m&&ce!==null){const H=ce,V=g[B]??null;let Y=V===null?-1:Ra(V,0,ee+1),S=-1,U=0;const _=H[ee];p=!0,y=_,b=B,w=ee+1,V!==null&&V[Y]===w&&(S=w,U=y,Y++);for(let te=ee+1;te<H.length;te++){const ne=H[te];if(y+ne>m)return V!==null&&S>ee?(r.segmentIndex=B,r.graphemeIndex=S,U):(r.segmentIndex=b,r.graphemeIndex=w,y);y+=ne,b=B,w=te+1,V!==null&&V[Y]===w&&(S=w,U=y,Y++)}b===B&&w===H.length&&(b=B+1,w=0)}else p=!0,y=re,b=B+1,w=0;P&&(M=B+1,Q=y-re);continue}if(y+re>m)return P?(r.segmentIndex=B+1,r.graphemeIndex=0,y):M>=0?b>M||b===M&&w>0?(r.segmentIndex=b,r.graphemeIndex=w,y):(r.segmentIndex=M,r.graphemeIndex=0,Q):(r.segmentIndex=b,r.graphemeIndex=w,y);y+=re,b=B+1,w=0,P&&(M=B+1,Q=y-re)}return p?(r.segmentIndex=b,r.graphemeIndex=w,y):null}function Tv(u,r,s,c){return u.simpleLineWalkFastPath?kv(u,r,c):wv(u,r,s,c)}function wo(u,r,s){const c=Av(u,r);return c<0?null:Tv(u,r,c,s)}let yr=null,ko=new WeakMap;function Fv(){return yr===null&&(yr=new Intl.Segmenter(void 0,{granularity:"grapheme"})),yr}function wx(u,r,s){let c=s.get(u);if(c!==void 0)return c;c=[];const d=Fv();for(const x of d.segment(r[u]))c.push(x.segment);return s.set(u,c),c}function jv(u,r,s){return s>r&&u[s-1]==="soft-hyphen"}function kx(u,r,s,c){for(let d=s;d<c;d++)u+=r[d];return u}function Dv(u){let r=ko.get(u);return r!==void 0||(r=new Map,ko.set(u,r)),r}function Ov(u,r,s,c,d,x){let g="";const v=jv(u.kinds,s,d);for(let N=s;N<d;N++)if(!(u.kinds[N]==="soft-hyphen"||u.kinds[N]==="hard-break"))if(N===s&&c>0){const m=wx(N,u.segments,r);g=kx(g,m,c,m.length)}else g+=u.segments[N];if(x>0){v&&(g+="-");const N=wx(d,u.segments,r);g=kx(g,N,s===d?c:0,x)}else v&&(g+="-");return g}function Bv(){yr=null,ko=new WeakMap}let Nr=null;function Ho(){return Nr===null&&(Nr=new Intl.Segmenter(void 0,{granularity:"grapheme"})),Nr}function zv(u){return{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],breakablePreferredBreaks:[],letterSpacing:0,spacingGraphemeCounts:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[],segments:[]}}function _v(u,r){const s=[];let c=[],d=0,x=!1,g=!1,v=!1;function N(){c.length!==0&&(s.push({text:c.length===1?c[0]:c.join(""),start:d}),c=[],x=!1,g=!1,v=!1)}function m(p,b,w){c=[p],d=b,x=w,g=Eo(p),v=Mr.has(p)}function y(p,b){c.push(p),x=x||b;const w=Eo(p);p.length===1&&Rn.has(p)?g=g||w:g=w,v=!1}for(const p of Ho().segment(u)){const b=p.segment,w=dl(b);if(c.length===0){m(b,p.index,w);continue}if(v||Oo.has(b)||Rn.has(b)||r.carryCJKAfterClosingQuote&&w&&g){y(b,w);continue}if(!x&&!w){y(b,w);continue}N(),m(b,p.index,w)}return N(),s}function Rv(u,r,s){if(r.length<=1)return r;const c=[];let d=-1,x=!1;function g(N,m){const y=r[N].start,p=m<r.length?r[m].start:u.length;c.push({text:u.slice(y,p),start:y})}function v(N){if(!(d<0)){if(x)d+1===N?c.push(r[d]):g(d,N);else for(let m=d;m<N;m++)c.push(r[m]);d=-1,x=!1}}for(let N=0;N<r.length;N++){const m=r[N];d>=0&&!Oh(r[N-1].text,s)&&v(N),d<0&&(d=N),x=x||dl(m.text)}return v(r.length),c}function Tx(u,r){if(r==="zero-width-break"||r==="soft-hyphen"||r==="hard-break")return 0;if(r==="tab")return 1;let s=0;const c=Ho();for(const d of c.segment(u))s++;return s}function Lv(u){return u==="-"||u==="֊"||u==="‐"||u==="‒"||u==="–"||u==="—"}function Hv(u){if(!/[-\u058A\u2010\u2012\u2013\u2014]/u.test(u))return null;const r=[];let s=0;for(const c of Ho().segment(u))s++,Lv(c.segment)&&r.push(s);return r.length===0?null:r}function Uv(u,r,s){return r>1?u+(r-1)*s:u}function Gv(u,r,s,c,d){const x=La(),{cache:g,emojiCorrection:v}=pv(r,dv(u.normalized)),N=_n("-",rn("-",g),v)+(d===0?0:d*2),y=_n(" ",rn(" ",g),v)*8,p=d!==0;if(u.len===0)return zv();const b=[],w=[],M=[],Q=[];let B=u.chunks.length<=1&&!p;const L=s?[]:null,P=[],ee=[],ce=[],re=s?[]:null,H=Array.from({length:u.len});function V(_,te,ne,he,G,O,k,F,Z){G!=="text"&&G!=="space"&&G!=="zero-width-break"&&(B=!1),b.push(te),w.push(ne),M.push(he),Q.push(G),L?.push(O),P.push(k),ee.push(F),p&&ce.push(Z),re!==null&&re.push(_)}function Y(_,te,ne,he,G){const O=rn(_,g),k=p?Tx(_,te):0,F=Uv(_n(_,O,v),k,d),Z=te==="space"||te==="preserved-space"||te==="zero-width-break"?0:F,W=Z===0?0:Z+(k>0?d:0),ie=te==="space"||te==="zero-width-break"?0:F;if(G&&he&&_.length>1){let le="sum-graphemes";d!==0?le="segment-prefixes":Sr(_)?le="pair-context":x.preferPrefixWidthsForBreakableRuns&&(le="segment-prefixes");const ae=gv(_,O,g,v,le),A=ae===null||c==="keep-all"?null:Hv(_);V(_,F,W,ie,te,ne,ae,A,k);return}V(_,F,W,ie,te,ne,null,null,k)}for(let _=0;_<u.len;_++){H[_]=b.length;const te=u.texts[_],ne=u.isWordLike[_],he=u.kinds[_],G=u.starts[_];if(he==="soft-hyphen"){V(te,0,N,N,he,G,null,null,0);continue}if(he==="hard-break"){V(te,0,0,0,he,G,null,null,0);continue}if(he==="tab"){V(te,0,0,0,he,G,null,null,p?Tx(te,he):0);continue}const O=rn(te,g);if(he==="text"&&O.containsCJK){const k=_v(te,x),F=c==="keep-all"?Rv(te,k,x.breakKeepAllAfterPunctuation):k;for(let Z=0;Z<F.length;Z++){const W=F[Z];Y(W.text,"text",G+W.start,ne,c==="keep-all"||!dl(W.text))}continue}Y(te,he,G,ne,!0)}const S=qv(u.chunks,H,b.length),U=L===null?null:ab(u.normalized,L);return re!==null?{widths:b,lineEndFitAdvances:w,lineEndPaintAdvances:M,kinds:Q,simpleLineWalkFastPath:B,segLevels:U,breakableFitAdvances:P,breakablePreferredBreaks:ee,letterSpacing:d,spacingGraphemeCounts:ce,discretionaryHyphenWidth:N,tabStopAdvance:y,chunks:S,segments:re}:{widths:b,lineEndFitAdvances:w,lineEndPaintAdvances:M,kinds:Q,simpleLineWalkFastPath:B,segLevels:U,breakableFitAdvances:P,breakablePreferredBreaks:ee,letterSpacing:d,spacingGraphemeCounts:ce,discretionaryHyphenWidth:N,tabStopAdvance:y,chunks:S}}function qv(u,r,s){const c=[];for(let d=0;d<u.length;d++){const x=u[d],g=x.startSegmentIndex<r.length?r[x.startSegmentIndex]:s,v=x.endSegmentIndex<r.length?r[x.endSegmentIndex]:s,N=x.consumedEndSegmentIndex<r.length?r[x.consumedEndSegmentIndex]:s;c.push({startSegmentIndex:g,endSegmentIndex:v,consumedEndSegmentIndex:N})}return c}function Yv(u,r,s,c){const d=c?.wordBreak??"normal",x=c?.letterSpacing??0,g=iv(u,La(),c?.whiteSpace,d);return Gv(g,r,s,d,x)}function To(u,r,s){return Yv(u,r,!0,s)}function Fx(u){let r=0;return Mv(u,Number.POSITIVE_INFINITY,s=>{s>r&&(r=s)}),r}function Xv(){db(),Nr=null,Bv(),bv()}function dr(u){return u.replace(/[ \t]+/g," ")}function Qv(u,r=[]){const s=[],c=r.filter(m=>m.length>0).map(m=>m.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")),d=c.length?new RegExp(`(${c.join("|")})`,"g"):null,x=/(\*\*[^*]+\*\*|\*[^*]+\*|==[^=]+==)/g;let g=0,v;function N(m,y={}){if(!m)return;if(!d){s.push({text:m,...y});return}d.lastIndex=0;let p=0,b;for(;(b=d.exec(m))!==null;)b.index>p&&s.push({text:m.slice(p,b.index),...y}),s.push({text:b[0],...y,highlight:!0}),p=b.index+b[0].length;p<m.length&&s.push({text:m.slice(p),...y})}for(;(v=x.exec(u))!==null;){v.index>g&&N(u.slice(g,v.index));const m=v[0];m.startsWith("**")&&m.endsWith("**")?N(m.slice(2,-2),{bold:!0}):m.startsWith("*")&&m.endsWith("*")?N(m.slice(1,-1),{italic:!0}):m.startsWith("==")&&m.endsWith("==")&&s.push({text:m.slice(2,-2),highlight:!0,bold:!0}),g=v.index+m.length}return g<u.length&&N(u.slice(g)),s.length>0?s:[{text:u}]}function Vv(u){const r=u.replaceAll(`\r
@@ -12,6 +12,9 @@ var DEFAULT_ARTICLE_COVER_CONTROLS = Object.freeze({
12
12
  textAlign: "left",
13
13
  safePadding: 120
14
14
  });
15
+ function normalizeArticleCoverTitle(raw) {
16
+ return raw.trim().replace(/^(?:#+\s*)+/, "").trim();
17
+ }
15
18
  function object(value) {
16
19
  if (!value || typeof value !== "object" || Array.isArray(value))
17
20
  throw new RangeError("Invalid article cover object");
@@ -113,6 +116,7 @@ function createArticleCoverConfig(value) {
113
116
  }
114
117
  export {
115
118
  validateArticleCoverControls,
119
+ normalizeArticleCoverTitle,
116
120
  createArticleCoverConfig,
117
121
  DEFAULT_ARTICLE_COVER_CONTROLS,
118
122
  ARTICLE_COVER_IMAGE_KEY,
package/dist/index.html CHANGED
@@ -11,7 +11,7 @@
11
11
  rel="stylesheet"
12
12
  />
13
13
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lxgw-wenkai-screen-web/style.css" />
14
- <script type="module" crossorigin src="/assets/index-DMxjiZmE.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-CrJAVx3W.js"></script>
15
15
  <link rel="stylesheet" crossorigin href="/assets/index-JCv_QmUn.css">
16
16
  </head>
17
17
  <body class="bg-[#fafafa] dark:bg-[#000000] text-[#171717] dark:text-[#ededed] antialiased selection:bg-[#eaeaea] selection:text-[#000000] dark:selection:bg-[#333333] dark:selection:text-[#ffffff] overflow-hidden">
@@ -2,7 +2,8 @@ import {
2
2
  adapter_default,
3
3
  plugin,
4
4
  typesetStudioAdapter
5
- } from "./index-q952vprv.js";
5
+ } from "./index-51d5rpf7.js";
6
+ import"./index-nwch18wp.js";
6
7
  import"./index-37x76zdn.js";
7
8
  export {
8
9
  typesetStudioAdapter,
@@ -1,7 +1,9 @@
1
1
  import {
2
- ARTICLE_COVER_FONT,
3
2
  registerArticleCoverFont
4
- } from "./index-r4swepwa.js";
3
+ } from "./index-94yttj49.js";
4
+ import {
5
+ ARTICLE_COVER_FONT
6
+ } from "./index-nwch18wp.js";
5
7
  import {
6
8
  DEFAULT_BORDER,
7
9
  DEFAULT_PATTERN,
@@ -1,3 +1,6 @@
1
+ import {
2
+ normalizeArticleCoverTitle
3
+ } from "./index-nwch18wp.js";
1
4
  import {
2
5
  __require
3
6
  } from "./index-37x76zdn.js";
@@ -103,7 +106,7 @@ async function renderRemoteBatch(studioUrl, body, outputDir, route, kind) {
103
106
  }
104
107
  async function renderLocalBatch(body, outputDir, route, kind) {
105
108
  const [{ resolveTypesetResult }, { renderTypesetResultToPngs }] = await Promise.all([
106
- import("./render-fvtcq3hb.js"),
109
+ import("./render-epbcmzxe.js"),
107
110
  import("./canvas-renderer-hpe2bqkt.js")
108
111
  ]);
109
112
  const { result } = resolveTypesetResult(body);
@@ -131,7 +134,7 @@ async function renderLocalBatch(body, outputDir, route, kind) {
131
134
  }
132
135
  var typesetStudioAdapter = {
133
136
  name: "typeset-studio",
134
- version: "0.3.0",
137
+ version: "0.3.1",
135
138
  async doctor() {
136
139
  const checks = [];
137
140
  const REMOTE_STUDIO_URL = remoteStudioUrl();
@@ -213,7 +216,10 @@ var typesetStudioAdapter = {
213
216
  const fallbackIcon = visual.fallbackIcon ?? stateVisual?.fallback_icon;
214
217
  const template = ["wechat-cover-split", "poster-3-4", "longform-3-4"].includes(input.template || "") ? undefined : input.template;
215
218
  input.onProgress?.({ stage: "typeset", message: "开始排版", route, account });
216
- const title = cleanTitle(input.title || state.metadata?.title || "");
219
+ const rawTitle = input.title || state.metadata?.title || "";
220
+ const title = process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT === "1" ? normalizeArticleCoverTitle(rawTitle) : cleanTitle(rawTitle);
221
+ if (process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT === "1" && !title)
222
+ throw new RangeError("Article cover title is empty after normalization");
217
223
  const common = {
218
224
  account,
219
225
  title,
@@ -1,3 +1,6 @@
1
+ import {
2
+ ARTICLE_COVER_FONT
3
+ } from "./index-nwch18wp.js";
1
4
  import {
2
5
  clearCache
3
6
  } from "./index-xg6pyfw6.js";
@@ -7,22 +10,6 @@ import { createHash } from "node:crypto";
7
10
  import { readFileSync } from "node:fs";
8
11
  import { isAbsolute } from "node:path";
9
12
  import { GlobalFonts } from "@napi-rs/canvas";
10
-
11
- // src/core/article-cover.ts
12
- var ARTICLE_COVER_FONT = Object.freeze({
13
- id: "publishing-noto-cjk-regular-v1",
14
- sha256: "b76b0433203017ca80401b2ee0dd69350349871c4b19d504c34dbdd80541690a",
15
- family: "Publishing Cover"
16
- });
17
- var DEFAULT_ARTICLE_COVER_CONTROLS = Object.freeze({
18
- backgroundColor: "#ffffff",
19
- titleColor: "#171717",
20
- fontSize: 120,
21
- textAlign: "left",
22
- safePadding: 120
23
- });
24
-
25
- // src/server-font.ts
26
13
  var registered = false;
27
14
  function registerArticleCoverFont({ path }) {
28
15
  if (typeof path !== "string" || !isAbsolute(path))
@@ -44,4 +31,4 @@ function registerArticleCoverFont({ path }) {
44
31
  return ARTICLE_COVER_FONT;
45
32
  }
46
33
 
47
- export { ARTICLE_COVER_FONT, registerArticleCoverFont };
34
+ export { registerArticleCoverFont };
@@ -0,0 +1,18 @@
1
+ // src/core/article-cover.ts
2
+ var ARTICLE_COVER_FONT = Object.freeze({
3
+ id: "publishing-noto-cjk-regular-v1",
4
+ sha256: "b76b0433203017ca80401b2ee0dd69350349871c4b19d504c34dbdd80541690a",
5
+ family: "Publishing Cover"
6
+ });
7
+ var DEFAULT_ARTICLE_COVER_CONTROLS = Object.freeze({
8
+ backgroundColor: "#ffffff",
9
+ titleColor: "#171717",
10
+ fontSize: 120,
11
+ textAlign: "left",
12
+ safePadding: 120
13
+ });
14
+ function normalizeArticleCoverTitle(raw) {
15
+ return raw.trim().replace(/^(?:#+\s*)+/, "").trim();
16
+ }
17
+
18
+ export { ARTICLE_COVER_FONT, normalizeArticleCoverTitle };
package/dist/lib/index.js CHANGED
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  plugin,
3
3
  typesetStudioAdapter
4
- } from "./index-q952vprv.js";
4
+ } from "./index-51d5rpf7.js";
5
5
  import {
6
6
  applyTemplateImages,
7
7
  getDefaultConfig,
8
8
  resolveTypesetResult,
9
9
  runTypeset,
10
10
  validateTemplateAssets
11
- } from "./index-1yt7sbqe.js";
12
- import"./index-r4swepwa.js";
11
+ } from "./index-3ptjkctd.js";
12
+ import"./index-94yttj49.js";
13
+ import"./index-nwch18wp.js";
13
14
  import {
14
15
  drawPageToContext,
15
16
  renderPageToCanvas,
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  renderRouter,
3
3
  resolveTypesetResult
4
- } from "./index-1yt7sbqe.js";
5
- import"./index-r4swepwa.js";
4
+ } from "./index-3ptjkctd.js";
5
+ import"./index-94yttj49.js";
6
+ import"./index-nwch18wp.js";
6
7
  import"./index-dz9pmgbk.js";
7
8
  import"./index-2vgqm8ms.js";
8
9
  import"./index-xg6pyfw6.js";
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  registerArticleCoverFont
3
- } from "./index-r4swepwa.js";
3
+ } from "./index-94yttj49.js";
4
+ import"./index-nwch18wp.js";
4
5
  import"./index-xg6pyfw6.js";
5
6
  import"./index-37x76zdn.js";
6
7
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akairos/typeset-studio",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Algorithmic typesetting studio & zzhub-pipeline image renderer plugin",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -2,6 +2,47 @@ import { afterAll, describe, expect, it } from "bun:test";
2
2
  import { existsSync, readFileSync, rmSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { typesetStudioAdapter, type ImageRenderInput } from "./adapter";
5
+ import { normalizeArticleCoverTitle } from "./cover";
6
+
7
+ it("uses preview title normalization only for trusted cover snapshots and rejects empty normalized titles", async () => {
8
+ const { mkdtemp, rm } = await import("node:fs/promises");
9
+ const { tmpdir } = await import("node:os");
10
+ const directory = await mkdtemp(join(tmpdir(), "typeset-cover-title-"));
11
+ const previousUrl = process.env.TYPESET_STUDIO_URL;
12
+ const previousSnapshot = process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT;
13
+ const requests: any[] = [];
14
+ // 只替换远程传输边界,读取实际 adapter 构造的标题,不能冒充正式渲染结果。
15
+ const server = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch: async request => {
16
+ requests.push(await request.json());
17
+ return Response.json({ ok: true, pages: [{ pageNumber: 1, dataUrl: "data:image/png;base64,", bodyImageCount: 0, bodyImageSources: [], bodyImageIds: [] }] });
18
+ } });
19
+ const render = (title: string) => typesetStudioAdapter.render({
20
+ title, route: "wechat-article", bodyText: "", outputDir: directory, state: { route: {} },
21
+ });
22
+ try {
23
+ process.env.TYPESET_STUDIO_URL = server.url.toString();
24
+ process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT = "1";
25
+ for (const raw of ["AI", "#AI", " #AI", "## 标题", "# #AI", "正文 #尾"]) {
26
+ await render(raw);
27
+ const title = normalizeArticleCoverTitle(raw);
28
+ expect(requests.at(-1).title).toBe(title);
29
+ expect(requests.at(-1).markdown).toBe(`# ${title}`);
30
+ }
31
+ const accepted = requests.length;
32
+ for (const raw of ["", " \t ", " ### "]) await expect(render(raw)).rejects.toThrow("title is empty after normalization");
33
+ expect(requests.length).toBe(accepted);
34
+ delete process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT;
35
+ await render(" #AI");
36
+ expect(requests.at(-1).markdown).toBe("# #AI");
37
+ await render("");
38
+ expect(requests.at(-1).markdown).toBe("# 未命名文章");
39
+ } finally {
40
+ if (previousUrl === undefined) delete process.env.TYPESET_STUDIO_URL; else process.env.TYPESET_STUDIO_URL = previousUrl;
41
+ if (previousSnapshot === undefined) delete process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT; else process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT = previousSnapshot;
42
+ server.stop(true);
43
+ await rm(directory, { recursive: true, force: true });
44
+ }
45
+ });
5
46
 
6
47
  describe("Typeset Studio — zzhub-pipeline ImageRenderPlugin Adapter", () => {
7
48
  const tempTestDir = join(process.cwd(), "tmp", `test-adapter-${Date.now()}`);
package/src/adapter.ts CHANGED
@@ -2,6 +2,7 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { extname, join } from "node:path";
3
3
  import type { FlowImage, PipelineCoverTheme } from "./core/types";
4
4
  import type { RenderRequestBody } from "./server/routes/render";
5
+ import { normalizeArticleCoverTitle } from "./core/article-cover";
5
6
 
6
7
  // ── Typeset Studio & zzhub-pipeline compatible types ──────────────
7
8
 
@@ -266,7 +267,7 @@ async function renderLocalBatch(
266
267
 
267
268
  export const typesetStudioAdapter: ImageRenderPlugin = {
268
269
  name: "typeset-studio",
269
- version: "0.3.0",
270
+ version: "0.3.1",
270
271
 
271
272
  async doctor(): Promise<PipelinePluginDoctorCheck[]> {
272
273
  const checks: PipelinePluginDoctorCheck[] = [];
@@ -353,7 +354,9 @@ export const typesetStudioAdapter: ImageRenderPlugin = {
353
354
  // pipeline 的模式标记只选择分页方式,具体模板名才参与模板解析。
354
355
  const template = ["wechat-cover-split", "poster-3-4", "longform-3-4"].includes(input.template || "") ? undefined : input.template;
355
356
  input.onProgress?.({ stage: "typeset", message: "开始排版", route, account });
356
- const title = cleanTitle(input.title || state.metadata?.title || "");
357
+ const rawTitle = input.title || state.metadata?.title || "";
358
+ const title = process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT === "1" ? normalizeArticleCoverTitle(rawTitle) : cleanTitle(rawTitle);
359
+ if (process.env.ZZHUB_PIPELINE_COVER_SNAPSHOT === "1" && !title) throw new RangeError("Article cover title is empty after normalization");
357
360
  const common: RenderRequestBody = {
358
361
  account,
359
362
  title,
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "bun:test";
2
- import { ARTICLE_COVER_FONT, ARTICLE_COVER_IMAGE_KEY, createArticleCoverConfig, validateArticleCoverControls } from "./article-cover";
2
+ import { ARTICLE_COVER_FONT, ARTICLE_COVER_IMAGE_KEY, createArticleCoverConfig, normalizeArticleCoverTitle, validateArticleCoverControls } from "./article-cover";
3
3
  import { applyTemplateImages } from "./template";
4
4
  import { drawPageToContext } from "./canvas-draw";
5
5
  import { getCanvasSpec } from "./geometry";
@@ -9,6 +9,14 @@ const assetId = "87654321-4321-4321-8321-cba987654321";
9
9
  const controls = { backgroundColor: "#F1F8FF", titleColor: "#123ABC", fontSize: 120, textAlign: "center", safePadding: 120 };
10
10
 
11
11
  describe("finite article-cover contract", () => {
12
+ it.each([
13
+ ["AI", "AI"], ["#AI", "AI"], [" #AI", "AI"], ["## 标题", "标题"],
14
+ ["# #AI", "AI"], ["正文 #尾", "正文 #尾"], [" \t ", ""], [" ### ", ""],
15
+ ])("normalizes cover title %j once and remains idempotent", (raw, expected) => {
16
+ expect(normalizeArticleCoverTitle(raw)).toBe(expected);
17
+ expect(normalizeArticleCoverTitle(normalizeArticleCoverTitle(raw))).toBe(expected);
18
+ });
19
+
12
20
  it("normalizes finite controls and rejects paths, extra schema and invalid ranges", () => {
13
21
  expect(validateArticleCoverControls(controls)).toMatchObject({ backgroundColor: "#f1f8ff", titleColor: "#123abc" });
14
22
  for (const input of [{ ...controls, fontSize: 79 }, { ...controls, fontSize: 201 }, { ...controls, safePadding: 59 }, { ...controls, safePadding: 201 }, { ...controls, fontSize: 80.5 }, { ...controls, fontPath: "/private/font" }, { ...controls, backgroundColor: "url(https://invalid)" }, { ...controls, schemaVersion: 99 }]) {
@@ -19,6 +19,11 @@ export const DEFAULT_ARTICLE_COVER_CONTROLS: Readonly<ArticleCoverControls> = Ob
19
19
  textAlign: "left", safePadding: 120,
20
20
  });
21
21
 
22
+ /** 预览与快照渲染共用标题清理,重复调用不会继续改变标题。 */
23
+ export function normalizeArticleCoverTitle(raw: string): string {
24
+ return raw.trim().replace(/^(?:#+\s*)+/, "").trim();
25
+ }
26
+
22
27
  function object(value: unknown): Record<string, unknown> {
23
28
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new RangeError("Invalid article cover object");
24
29
  return value as Record<string, unknown>;
package/src/cover.ts CHANGED
@@ -2,6 +2,7 @@ export {
2
2
  ARTICLE_COVER_FONT,
3
3
  ARTICLE_COVER_IMAGE_KEY,
4
4
  DEFAULT_ARTICLE_COVER_CONTROLS,
5
+ normalizeArticleCoverTitle,
5
6
  validateArticleCoverControls,
6
7
  createArticleCoverConfig,
7
8
  type ArticleCoverControls,
@@ -17,7 +17,7 @@ app.get("/api/health", (c) => {
17
17
  return c.json({
18
18
  status: "ok",
19
19
  name: "Typeset Studio Server",
20
- version: "0.3.0",
20
+ version: "0.3.1",
21
21
  time: new Date().toISOString(),
22
22
  });
23
23
  });
@@ -58,7 +58,7 @@ export const Header: React.FC<HeaderProps> = ({
58
58
  </span>
59
59
  <span className="hidden 2xl:inline">Typeset Studio</span>
60
60
  </div>
61
- <span className="text-xs text-[#888888] dark:text-[#555555] font-mono hidden 2xl:inline">v0.3.0</span>
61
+ <span className="text-xs text-[#888888] dark:text-[#555555] font-mono hidden 2xl:inline">v0.3.1</span>
62
62
  <div title={templateName || "未命名模板"} className="flex min-w-0 items-center gap-1.5 px-2 py-0.5 rounded-full bg-[#f5f5f5] dark:bg-[#111111] border border-[#e5e5e5] dark:border-[#222222] text-[11px] text-emerald-600 dark:text-[#00e676]">
63
63
  <span className="w-1.5 h-1.5 shrink-0 rounded-full bg-emerald-500 dark:bg-[#00e676]" />
64
64
  <span aria-live="polite" className="max-w-40 truncate">{templateName || "未命名模板"}</span>