dsh-motion-ui 0.6.0 → 0.7.0

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +37 -1
  3. package/VERIFICATION.md +36 -0
  4. package/client.js +1856 -984
  5. package/examples/mechanism-assembly.json +50 -0
  6. package/examples/mechanism-crank.json +103 -0
  7. package/examples/mechanism-gears.json +103 -0
  8. package/index.js +115 -104
  9. package/lib/assets/standalone-runtime.js +3 -1
  10. package/lib/assets/visual.js +3 -1
  11. package/lib/author-expression.js +3 -2
  12. package/lib/authoring-guide.js +2 -1
  13. package/lib/build-info.js +1 -1
  14. package/lib/catalog.js +4 -4
  15. package/lib/components.js +2 -2
  16. package/lib/export-runtime-bundle.js +1 -1
  17. package/lib/expressive-examples.js +6 -0
  18. package/lib/fence-feedback.js +1 -1
  19. package/lib/freeform.js +4 -3
  20. package/lib/mechanism-catalog.js +24 -0
  21. package/lib/mechanism-css.js +13 -0
  22. package/lib/mechanism-entry.js +20 -0
  23. package/lib/mechanism-geometry.js +62 -0
  24. package/lib/mechanism-render.js +24 -0
  25. package/lib/mechanism-runtime-bundle.js +2 -0
  26. package/lib/mechanism-scenes.js +20 -0
  27. package/lib/motion-library.js +18 -0
  28. package/lib/normalize-authoring.js +6 -2
  29. package/lib/protocol.js +23 -8
  30. package/lib/sandbox.js +2 -0
  31. package/lib/style-system.js +28 -0
  32. package/lib/third-party/anatomy-LICENSE.txt +21 -0
  33. package/lib/third-party/anatomy-NOTICE.md +13 -0
  34. package/lib/third-party/anatomy-iso.mjs +674 -0
  35. package/lib/third-party/lucian-uxui-LICENSE.txt +21 -0
  36. package/lib/third-party/lucian-uxui-NOTICE.md +1 -0
  37. package/lib/tool-schema.js +5 -5
  38. package/lib/ui-intent.js +1 -1
  39. package/lib/ui-skill.js +3 -2
  40. package/lib/visual-styles.js +134 -22
  41. package/package.json +92 -92
  42. package/skills/intelligent-ui/SKILL.md +113 -100
@@ -273,8 +273,10 @@ l0,-`+(r+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,
273
273
  .motion-copy-title{flex:1;min-width:0;overflow-wrap:anywhere}.motion-copy-button{display:inline-flex!important;align-items:center;justify-content:center;flex:none;width:32px;height:32px;padding:6px!important;border:0!important;border-radius:10px!important;background:transparent!important;color:inherit;font:inherit;cursor:pointer;margin-left:auto}
274
274
  .motion-copy-button:hover{background:var(--du-line,#8882)!important;color:var(--du-ink,inherit)}.motion-copy-button:focus-visible{outline:2px solid var(--du-accent,#508bff);outline-offset:2px}.motion-copy-button:disabled{opacity:.45;cursor:default}.motion-copy-button[data-status=done]{color:var(--du-green,#17995a)}.motion-copy-button[data-status=error]{color:var(--du-red,#d54b5b)}
275
275
  .motion-copy-body{white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.8}.motion-copy-code{margin:0!important;padding:0!important;border:0!important;background:transparent!important;overflow:auto;white-space:pre!important;tab-size:2;font:14px/1.75 ui-monospace,SFMono-Regular,Consolas,monospace}.motion-copy-code[data-wrap]{white-space:pre-wrap!important;overflow-wrap:anywhere}.motion-copy-code code{font:inherit!important;background:none!important;padding:0!important;color:inherit!important}.motion-copy-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
276
+ .motion-copy-button[data-status=done] .dgui-icon{animation:motion-copy-confirm 420ms cubic-bezier(.34,1.45,.64,1)}.motion-copy-button[data-status=done] path{stroke-dasharray:28;animation:motion-check-draw 450ms ease-out}@keyframes motion-check-draw{from{stroke-dashoffset:28}to{stroke-dashoffset:0}}@keyframes motion-copy-confirm{from{opacity:.5;transform:scale(.8)}to{opacity:1;transform:none}}
277
+ @media(prefers-reduced-motion:reduce){.motion-copy-button .dgui-icon,.motion-copy-button path{animation:none!important;transition:none!important}}
276
278
  @media(max-width:600px){.motion-copy-block{padding:14px 16px;border-radius:20px}}
277
- `;function Bl({text:e,children:t,title:r,lang:n,code:a=!1,wrap:i=!1,disabled:s=!1,style:o,nodeId:l,copyLabel:u,copiedLabel:d}){let[p,m]=(0,Jn.useState)("idle"),g=(0,Jn.useRef)();(0,Jn.useEffect)(()=>()=>clearTimeout(g.current),[]);let A=p==="done"?d??"\u5DF2\u590D\u5236":p==="error"?"\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5185\u5BB9":u??(a?"\u590D\u5236\u4EE3\u7801":"\u590D\u5236\u6587\u672C");async function N(){clearTimeout(g.current),m("copying");let R=await db(e);m(R?"done":"error"),g.current=setTimeout(()=>m("idle"),2e3)}return zr("section",{className:"motion-copy-block","data-code":a||void 0,"data-ui-node":l,style:o},zr("style",null,pb),zr("div",{className:"motion-copy-bar"},a&&zr("span",{"aria-hidden":!0},"\u3008/\u3009"),zr("span",{className:"motion-copy-title"},r??(a?n||"\u4EE3\u7801":"\u6587\u672C")),zr("button",{className:"motion-copy-button",type:"button",title:A,"aria-label":A,"data-status":p,disabled:s||p==="copying",onClick:N},zr(Kg,{name:p==="done"?"check":p==="error"?"warning":"copy"})),zr("span",{className:"motion-copy-sr",role:"status","aria-live":"polite"},p==="done"?"\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F":p==="error"?A:"")),a?zr("pre",{className:"motion-copy-code","data-wrap":i||void 0},zr("code",{"data-language":n},e)):zr("div",{className:"motion-copy-body"},t??e))}var hr=ie(Le()),Jg={overflow:"auto",padding:12,borderRadius:8,background:"var(--dsw-alias-bg-layer-2)",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12,lineHeight:1.5,whiteSpace:"pre-wrap"};function Zg({code:e,lang:t,title:r,wrap:n,copyLabel:a,copiedLabel:i}){return(0,hr.jsx)(Bl,{text:e,lang:t,title:r,wrap:n,code:!0,copyLabel:a,copiedLabel:i})}function e4({diffs:e}){return(0,hr.jsx)("div",{children:e.map((t,r)=>(0,hr.jsxs)("section",{children:[(0,hr.jsx)("strong",{children:t.path}),(0,hr.jsx)("pre",{style:Jg,children:(t.oldText??"").split(`
279
+ `;function Bl({text:e,children:t,title:r,lang:n,code:a=!1,wrap:i=!1,disabled:s=!1,style:o,nodeId:l,copyLabel:u,copiedLabel:d}){let[p,m]=(0,Jn.useState)("idle"),g=(0,Jn.useRef)();(0,Jn.useEffect)(()=>()=>clearTimeout(g.current),[]);let A=p==="done"?d??"\u5DF2\u590D\u5236":p==="error"?"\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5185\u5BB9":u??(a?"\u590D\u5236\u4EE3\u7801":"\u590D\u5236\u6587\u672C");async function N(){clearTimeout(g.current),m("copying");let R=await db(e);m(R?"done":"error"),g.current=setTimeout(()=>m("idle"),2e3)}return zr("section",{className:"motion-copy-block","data-copy-status":p,"data-code":a||void 0,"data-ui-node":l,style:o},zr("style",null,pb),zr("div",{className:"motion-copy-bar"},a&&zr("span",{"aria-hidden":!0},"\u3008/\u3009"),zr("span",{className:"motion-copy-title"},r??(a?n||"\u4EE3\u7801":"\u6587\u672C")),zr("button",{className:"motion-copy-button",type:"button",title:A,"aria-label":A,"data-status":p,disabled:s||p==="copying",onClick:N},zr(Kg,{name:p==="done"?"check":p==="error"?"warning":"copy"})),zr("span",{className:"motion-copy-sr",role:"status","aria-live":"polite"},p==="done"?"\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F":p==="error"?A:"")),a?zr("pre",{className:"motion-copy-code","data-wrap":i||void 0},zr("code",{"data-language":n},e)):zr("div",{className:"motion-copy-body"},t??e))}var hr=ie(Le()),Jg={overflow:"auto",padding:12,borderRadius:8,background:"var(--dsw-alias-bg-layer-2)",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12,lineHeight:1.5,whiteSpace:"pre-wrap"};function Zg({code:e,lang:t,title:r,wrap:n,copyLabel:a,copiedLabel:i}){return(0,hr.jsx)(Bl,{text:e,lang:t,title:r,wrap:n,code:!0,copyLabel:a,copiedLabel:i})}function e4({diffs:e}){return(0,hr.jsx)("div",{children:e.map((t,r)=>(0,hr.jsxs)("section",{children:[(0,hr.jsx)("strong",{children:t.path}),(0,hr.jsx)("pre",{style:Jg,children:(t.oldText??"").split(`
278
280
  `).map(n=>`- ${n}`).concat((t.newText??"").split(`
279
281
  `).map(n=>`+ ${n}`)).join(`
280
282
  `)})]},`${t.path}:${r}`))})}function t4({data:e,label:t,copyable:r,labels:n}){let[a,i]=(0,As.useState)(!0),[s,o]=(0,As.useState)(!1),l=JSON.stringify(e,null,2),u=async()=>{await Ns(l)&&(o(!0),window.setTimeout(()=>o(!1),1200))};return(0,hr.jsxs)("section",{children:[(0,hr.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(0,hr.jsxs)("button",{type:"button","aria-expanded":a,onClick:()=>i(d=>!d),children:[a?re("label.collapse"):re("label.expandNode")," ",t??"JSON"]}),r&&(0,hr.jsx)("button",{type:"button",onClick:()=>void u(),children:s?n?.copied??re("label.copied"):n?.copyJson??re("label.copy")})]}),a&&(0,hr.jsx)("pre",{style:Jg,children:l})]})}async function Ns(e){if(typeof navigator.clipboard?.writeText=="function")try{return await navigator.clipboard.writeText(e),!0}catch{return!1}let t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.left="-9999px",document.body.appendChild(t);try{return t.select(),document.execCommand("copy")}catch{return!1}finally{t.remove()}}function r4(e){}var n4=(0,As.createContext)(void 0);var bb=(0,Hl.createContext)(void 0),Id=n4??bb;function i4(){return(0,Hl.useContext)(Id)}var s4="dsh.genui.interaction";function Gd(){return{order:[],blocks:{}}}function o4(){try{let e=localStorage.getItem(s4);if(e===null)return Gd();let t=JSON.parse(e);return!Array.isArray(t.order)||typeof t.blocks!="object"||t.blocks===null?Gd():{order:t.order.filter(r=>typeof r=="string"),blocks:t.blocks}}catch{return Gd()}}function xb(e){try{localStorage.setItem(s4,JSON.stringify(e))}catch{}}function l4(e){return e===""?null:o4().blocks[e]??null}function u4(e,t){if(e==="")return;let r=o4(),n=r.order.filter(i=>i!==e);n.unshift(e);let a={...r.blocks,[e]:t};for(;n.length>200;){let i=n.pop();i!==void 0&&delete a[i]}xb({order:n,blocks:a})}function jl(){return{fences:0,panels:0,interactions:0,templates:0,charts:0,advanced:0}}var _l=e=>t=>t.fences>=e;function wb(e){return re(`ach.${e}.name`)}function kb(e){return re(`ach.${e}.desc`)}function gr(e,t,r,n=!1){return{id:e,rarity:t,check:r,...n?{hidden:!0}:{},get name(){return wb(e)},get description(){return kb(e)}}}var c4=[gr("first-fence","common",_l(1)),gr("fence-5","common",_l(5)),gr("fence-25","rare",_l(25)),gr("fence-50","legendary",_l(50),!0),gr("first-interaction","common",e=>e.interactions>=1),gr("interaction-10","rare",e=>e.interactions>=10),gr("first-panel","common",e=>e.panels>=1),gr("panel-5","rare",e=>e.panels>=5),gr("first-chart","common",e=>e.charts>=1),gr("chart-10","rare",e=>e.charts>=10),gr("first-advanced","rare",e=>e.advanced>=1),gr("template-1","common",e=>e.templates>=1)];function d4(e){let t=0,r=0,n=a=>{if(Array.isArray(a))for(let i of a){if(typeof i!="object"||i===null)continue;let s=i,o=s.type;if((o==="chart"||o==="plot"||o==="echart")&&(t+=1),(o==="scene3d"||o==="mermaid"||o==="diagram")&&(r+=1),Array.isArray(s.items)&&n(s.items),Array.isArray(s.tabs))for(let l of s.tabs)n(l.items)}};return n(e.items),{charts:t,advanced:r}}function p4(e,t){return c4.filter(r=>t[r.id]===void 0&&r.check(e))}var f4="dsh.genui.achievements",m4="dsh.genui.achievements.seen",Sb=200,Qr=Tb(),Ab=new Set,Nb=[];function Tb(){try{let e=localStorage.getItem(f4);if(e===null)return{state:jl(),unlocked:{}};let t=JSON.parse(e);return{state:{...jl(),...t.state??{}},unlocked:typeof t.unlocked=="object"&&t.unlocked!==null?t.unlocked:{}}}catch{return{state:jl(),unlocked:{}}}}function Cb(){try{localStorage.setItem(f4,JSON.stringify(Qr))}catch{}}function Mb(){try{let e=localStorage.getItem(m4);if(e===null)return[];let t=JSON.parse(e);return Array.isArray(t)?t.filter(r=>typeof r=="string"):[]}catch{return[]}}function zb(e){try{localStorage.setItem(m4,JSON.stringify(e.slice(0,Sb)))}catch{}}function Eb(){for(let e of Ab)e()}function h4(e){Qr.state={...Qr.state,...e};let t=p4(Qr.state,Qr.unlocked);for(let r of t)Qr.unlocked[r.id]=Date.now();t.length>0&&Nb.push(...t),Cb(),Eb()}function Rb(e){let t=JSON.stringify(e),r=3735928559,n=1103547991;for(let a=0;a<t.length;a++){let i=t.charCodeAt(a);r=Math.imul(r^i,2654435761),n=Math.imul(n^i,1597334677)}return`${(r>>>0).toString(36)}-${(n>>>0).toString(36)}`}function g4(e){let t=Rb(e),r=Mb();if(r.includes(t))return;zb([t,...r]);let n=d4(e);h4({fences:Qr.state.fences+1,charts:Qr.state.charts+(n.charts>0?1:0),advanced:Qr.state.advanced+(n.advanced>0?1:0)})}function v4(){h4({interactions:Qr.state.interactions+1})}var Q2=ie(_e(),1);var Er=ie(_e(),1),Pd=(0,Er.createContext)({path:"root"});function y4({id:e,answers:t,children:r}){let n=(0,Er.useContext)(Pd);return(0,Er.createElement)(Pd.Provider,{value:{path:n.path+"/"+e,answers:t??n.answers}},r)}function Bt(e,t,r=()=>!0,n=!0){let a=(0,Er.useContext)(Pd),i="__motion_widget_"+a.path+":"+e,[s,o]=(0,Er.useState)(()=>{let d=n?a.answers?.fields[i]:void 0;if(d!==void 0)try{let p=JSON.parse(d);if(r(p))return p}catch{}return typeof t=="function"?t():t}),l=(0,Er.useRef)(s);l.current=s;let u=(d,p)=>{let m=typeof d=="function"?d(l.current):d;if(!r(m))return;l.current=m,o(m);let g=JSON.stringify(m);n&&p&&g!==void 0&&g.length<=4096&&g!==a.answers?.fields[i]&&a.answers?.setField(i,g)};return[s,d=>u(d,!0),d=>u(d,!1)]}var r0=ie(_e(),1);var z={maxDepth:8,maxNodes:200,maxString:2e3,maxCode:12e3,maxMermaid:8e3,maxGridCols:12,maxTabs:12,maxAccordionItems:24,maxListItems:50,maxOptions:50,maxTableRows:50,maxTableCols:12,maxChartPoints:60,maxPlotSeries:8,maxPlotParams:6,maxMeshes:5,maxQuizOptions:8,maxSteps:24,maxTimelineItems:24,maxBreadcrumbItems:12,maxKeyValuePairs:24,maxTreeDepth:6,maxDiagramNodes:9,maxDiagramEdges:12,maxDiagramZones:3,maxDiagramFocal:2,maxDiagramLabel:14,maxEChartOptionDepth:10,maxEChartArrayLen:500,maxEChartOptionNodes:2e3};var Rr=ie(_e(),1);var Mt=ie(Le(),1),b4=["var(--dsw-static-deepseek-400)","var(--dsw-static-deepseek-450)","var(--dsw-static-blue-450)","var(--dsw-static-green-400)","var(--dsw-static-amber-400)","var(--dsw-static-red-400)","var(--dsw-static-deepseek-300)","var(--dsw-static-neutral-bluish-400)"];function x4(e){let t=0;for(let r=0;r<e.length;r++)t=t*31+e.charCodeAt(r)>>>0;return b4[t%b4.length]}function w4({className:e,disabled:t,onClick:r,children:n}){let a=tt(),[i,s]=(0,Rr.useState)(!1),o=(0,Rr.useRef)(null);return(0,Rr.useEffect)(()=>()=>{o.current!==null&&clearTimeout(o.current)},[]),(0,Mt.jsxs)(Mt.Fragment,{children:[(0,Mt.jsxs)("button",{type:"button",className:e,disabled:t,onClick:r===void 0?void 0:()=>{r(),o.current!==null&&clearTimeout(o.current),s(!0),o.current=setTimeout(()=>s(!1),1400)},children:[n,i&&(0,Mt.jsx)("span",{className:y.btnSent,"aria-hidden":!0,children:a("block.triggered")})]}),(0,Mt.jsx)("span",{className:y.visuallyHidden,role:"status",children:i?a("block.triggeredPlain"):""})]})}var k4=(0,Rr.memo)(function({node:t}){let r=tt(),[n,a]=(0,Rr.useState)(!1);return(0,Mt.jsxs)("figure",{className:y.media,children:[t.alt!==void 0&&(0,Mt.jsx)("figcaption",{className:y.mediaLabel,children:q(t.alt)}),n?(0,Mt.jsx)("div",{className:y.mediaError,role:"alert",children:r("block.audioError")}):(0,Mt.jsx)("audio",{className:y.mediaPlayer,src:t.src,"aria-label":t.alt??r("block.audio"),controls:!0,preload:"metadata",loop:t.loop===!0,onError:()=>a(!0)})]})}),S4=(0,Rr.memo)(function({node:t}){let r=tt(),[n,a]=(0,Rr.useState)(!1);return(0,Mt.jsxs)("figure",{className:y.media,children:[t.alt!==void 0&&(0,Mt.jsx)("figcaption",{className:y.mediaLabel,children:q(t.alt)}),n?(0,Mt.jsx)("div",{className:y.mediaError,role:"alert",children:r("block.videoError")}):(0,Mt.jsx)("video",{className:`${y.mediaPlayer} ${y.videoPlayer}`,src:t.src,poster:t.poster,"aria-label":t.alt??r("block.video"),controls:!0,preload:"metadata",playsInline:!0,loop:t.loop===!0,muted:t.muted===!0,style:t.aspectRatio===void 0?void 0:{aspectRatio:t.aspectRatio.replace(":"," / ")},onError:()=>a(!0)})]})});var qe=ie(_e(),1);function Fd(e){let t=e.columns,r=Array.isArray(t)&&t.length>0,n=r&&Array.isArray(t)&&typeof t[0]=="object"&&t[0]!==null?t.map(Gb):t,a=Db(n),i=e.rows!==void 0?e.rows:e.data;if(Array.isArray(i)&&i.length>0&&typeof i[0]=="object"&&i[0]!==null&&!Array.isArray(i[0])){let l=Array.isArray(e.columns)&&e.columns.length>0&&typeof e.columns[0]=="object"&&e.columns[0]!==null?e.columns.map(Lb).filter(u=>u!==void 0):Object.keys(i[0]);i=i.map(u=>l.map(d=>Ib(u[d])))}let s=null;if(!r&&Array.isArray(i)&&i.length>0&&Array.isArray(i[0])){let l=Od(i),u=l.length===0?null:$b(l);u!==null&&Od(u.rows).length===u.rows.length&&(s=u,a=u.columns.map(d=>d.slice(0,128)))}if(a.length===0&&!Array.isArray(e.columns))return null;let o=Od(s===null?i:s.rows);return Array.isArray(i)?{columns:a.slice(0,z.maxTableCols),rows:o}:null}function yn(e){return Fd(e)?.rows??[]}function Bd(e,t){return!Array.isArray(e)||!Array.isArray(t)||t[0]!=="group"?!1:String(e[0]??"").trim()!==""&&e.slice(1).every(r=>String(r??"").trim()==="")}function Dr(e,t){let r=yn(e);return t>=0&&t<r.length&&!Bd(r[t],e.types)}function Db(e){if(!Array.isArray(e))return[];let t=[];for(let r of e){if(t.length>=z.maxTableCols)break;if(typeof r=="string")t.push(r.slice(0,128));else if(r!==null&&typeof r=="object"){let n=r,a=typeof n.label=="string"?n.label:typeof n.value=="string"?n.value:typeof n.title=="string"?n.title:JSON.stringify(r);t.push(a.slice(0,128))}}return t}function Od(e){if(!Array.isArray(e))return[];let t=[];for(let r of e){if(t.length>=z.maxTableRows)break;if(!Array.isArray(r))continue;let n=[];for(let a of r){if(n.length>=z.maxTableCols)break;typeof a=="string"?n.push(a.slice(0,256)):typeof a=="number"&&Number.isFinite(a)&&n.push(a)}n.length>0&&t.push(n)}return t}function $b(e){let t=e[0];if(t===void 0||t.length===0)return null;let r=e.slice(1);if(r.length===0){let n=t.map(a=>String(a).trim());return n.every(a=>a!=="")?{columns:n,rows:[]}:null}return r.every(n=>n.length===t.length)?{columns:t.map(n=>String(n).trim()),rows:r}:{columns:Array.from({length:t.length},(n,a)=>`\u5217${a+1}`),rows:e}}function Lb(e){if(e===null||typeof e!="object"||Array.isArray(e))return;let t=e;for(let r of["key","dataIndex","title","label"])if(typeof t[r]=="string"&&t[r]!=="")return t[r]}function Ib(e){return typeof e=="string"||typeof e=="number"&&Number.isFinite(e)?e:e==null?"":JSON.stringify(e)}function Gb(e){if(e===null||typeof e!="object"||Array.isArray(e))return String(e);let t=e;for(let r of["title","label","key","dataIndex"])if(typeof t[r]=="string"&&t[r]!=="")return t[r];return JSON.stringify(e)}var E=ie(Le(),1),Ul=["var(--dsw-static-deepseek-400)","var(--dsw-static-green-400)","var(--dsw-static-amber-400)","var(--dsw-static-red-400)","var(--dsw-static-blue-450)","var(--dsw-static-deepseek-450)","var(--dsw-static-neutral-bluish-400)","var(--dsw-static-deepseek-300)"],Vl=(e,t,r,n)=>r??(n!==void 0&&n.length>0?n[e%n.length]:t>1?Ul[e%Ul.length]:void 0);function di(e){if(typeof e=="number")return Number.isFinite(e)?e:NaN;if(typeof e!="string")return NaN;let t=e.trim();if(t==="")return NaN;t=t.replace(/^[¥$€£]/,""),t.endsWith("%")&&(t=t.slice(0,-1));let n=1;if(t.endsWith("\u4E07"))n=1e4,t=t.slice(0,-1);else if(t.endsWith("\u4EBF"))n=1e8,t=t.slice(0,-1);else if(/[kmb]$/i.test(t)){let i=t.slice(-1).toLowerCase();n=i==="k"?1e3:i==="m"?1e6:1e9,t=t.slice(0,-1)}t=t.replace(/[,,\s]/g,"");let a=Number(t);return Number.isFinite(a)?a*n:NaN}function Pb(e,t){return Array.from({length:t},(r,n)=>{let a=!1;for(let i of e){let s=i[n];if(!(s==null||s==="")){if(!Number.isFinite(di(s)))return!1;a=!0}}return a})}function Ob(e){return typeof e=="string"&&/[\n\r]/.test(e)}function Fb(e){return typeof e!="string"?!1:/(^|\n)[ \t]/.test(e)||e.includes("```")}function qd(e){if(Ob(e))return Fb(e)?y.tdCode:y.tdMultiline}function Bb(e){if(typeof e!="string")return null;let t=e.trim();return!/^[+][\s]*[\d.]/.test(t)&&!/^[-−][\s]*[\d.]/.test(t)?null:t.startsWith("+")?"up":"down"}function qb({cell:e}){let t=String(e).split(/[\s,;]+/).map(Number).filter(Number.isFinite);if(t.length<2)return(0,E.jsx)(E.Fragment,{children:q(String(e),!1)});let r=88,n=22,a=2,i=Math.min(...t),o=Math.max(...t)-i||1,l=(r-a*2)/(t.length-1),u=t.map((g,A)=>[a+A*l,n-a-(g-i)/o*(n-a*2)]),d=u.map(([g,A])=>`${g.toFixed(1)},${A.toFixed(1)}`).join(" "),p=u[u.length-1],m=`M ${a},${n-a} L ${d.split(" ").join(" L ")} L ${p[0].toFixed(1)},${n-a} Z`;return(0,E.jsxs)("svg",{className:y.cellSpark,viewBox:`0 0 ${r} ${n}`,preserveAspectRatio:"none","aria-hidden":"true",children:[(0,E.jsx)("path",{d:m,fill:"var(--dsl-g-accent)",opacity:"0.14"}),(0,E.jsx)("polyline",{points:d,fill:"none",stroke:"var(--dsl-g-accent)",strokeWidth:"1.5",strokeLinejoin:"round",strokeLinecap:"round",vectorEffect:"non-scaling-stroke"}),(0,E.jsx)("path",{d:`M ${p[0].toFixed(1)} ${p[1].toFixed(1)} L ${p[0].toFixed(1)} ${p[1].toFixed(1)}`,stroke:"var(--dsl-g-accent)",strokeWidth:4,strokeLinecap:"round",vectorEffect:"non-scaling-stroke",fill:"none"})]})}function Hb({cell:e}){let t=di(e),r=Number.isFinite(t)?Math.max(0,Math.min(100,t)):0,n=11,a=2*Math.PI*n;return(0,E.jsxs)("span",{className:y.cellRing,children:[(0,E.jsxs)("svg",{width:28,height:28,viewBox:"0 0 28 28","aria-hidden":"true",children:[(0,E.jsx)("circle",{cx:14,cy:14,r:n,fill:"none",strokeWidth:4,className:y.ringTrack}),(0,E.jsx)("circle",{cx:14,cy:14,r:n,fill:"none",strokeWidth:4,strokeLinecap:"round",className:y.ringFill,strokeDasharray:`${r/100*a} ${a}`,transform:"rotate(-90 14 14)"})]}),(0,E.jsx)("span",{className:y.cellRingText,children:q(String(e),!1)})]})}function _b(e,t){let r=s=>String(s??"").replace(/\|/g,"\\|").replace(/\n/g," "),n=`| ${e.map(r).join(" | ")} |`,a=`| ${e.map(()=>"---").join(" | ")} |`,i=t.map(s=>`| ${e.map((o,l)=>r(s[l])).join(" | ")} |`);return[n,a,...i].join(`
@@ -265,8 +265,10 @@ l0,-`+(r+144)+`c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,
265
265
  .motion-copy-title{flex:1;min-width:0;overflow-wrap:anywhere}.motion-copy-button{display:inline-flex!important;align-items:center;justify-content:center;flex:none;width:32px;height:32px;padding:6px!important;border:0!important;border-radius:10px!important;background:transparent!important;color:inherit;font:inherit;cursor:pointer;margin-left:auto}
266
266
  .motion-copy-button:hover{background:var(--du-line,#8882)!important;color:var(--du-ink,inherit)}.motion-copy-button:focus-visible{outline:2px solid var(--du-accent,#508bff);outline-offset:2px}.motion-copy-button:disabled{opacity:.45;cursor:default}.motion-copy-button[data-status=done]{color:var(--du-green,#17995a)}.motion-copy-button[data-status=error]{color:var(--du-red,#d54b5b)}
267
267
  .motion-copy-body{white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.8}.motion-copy-code{margin:0!important;padding:0!important;border:0!important;background:transparent!important;overflow:auto;white-space:pre!important;tab-size:2;font:14px/1.75 ui-monospace,SFMono-Regular,Consolas,monospace}.motion-copy-code[data-wrap]{white-space:pre-wrap!important;overflow-wrap:anywhere}.motion-copy-code code{font:inherit!important;background:none!important;padding:0!important;color:inherit!important}.motion-copy-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
268
+ .motion-copy-button[data-status=done] .dgui-icon{animation:motion-copy-confirm 420ms cubic-bezier(.34,1.45,.64,1)}.motion-copy-button[data-status=done] path{stroke-dasharray:28;animation:motion-check-draw 450ms ease-out}@keyframes motion-check-draw{from{stroke-dashoffset:28}to{stroke-dashoffset:0}}@keyframes motion-copy-confirm{from{opacity:.5;transform:scale(.8)}to{opacity:1;transform:none}}
269
+ @media(prefers-reduced-motion:reduce){.motion-copy-button .dgui-icon,.motion-copy-button path{animation:none!important;transition:none!important}}
268
270
  @media(max-width:600px){.motion-copy-block{padding:14px 16px;border-radius:20px}}
269
- `;function Qn({text:t,children:e,title:r,lang:n,code:a=!1,wrap:i=!1,disabled:s=!1,style:o,nodeId:l,copyLabel:m,copiedLabel:u}){let[p,b]=(0,lr.useState)("idle"),y=(0,lr.useRef)();(0,lr.useEffect)(()=>()=>clearTimeout(y.current),[]);let k=p==="done"?u??"\u5DF2\u590D\u5236":p==="error"?"\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5185\u5BB9":m??(a?"\u590D\u5236\u4EE3\u7801":"\u590D\u5236\u6587\u672C");async function T(){clearTimeout(y.current),b("copying");let C=await cm(t);b(C?"done":"error"),y.current=setTimeout(()=>b("idle"),2e3)}return St("section",{className:"motion-copy-block","data-code":a||void 0,"data-ui-node":l,style:o},St("style",null,dm),St("div",{className:"motion-copy-bar"},a&&St("span",{"aria-hidden":!0},"\u3008/\u3009"),St("span",{className:"motion-copy-title"},r??(a?n||"\u4EE3\u7801":"\u6587\u672C")),St("button",{className:"motion-copy-button",type:"button",title:k,"aria-label":k,"data-status":p,disabled:s||p==="copying",onClick:T},St(u0,{name:p==="done"?"check":p==="error"?"warning":"copy"})),St("span",{className:"motion-copy-sr",role:"status","aria-live":"polite"},p==="done"?"\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F":p==="error"?k:"")),a?St("pre",{className:"motion-copy-code","data-wrap":i||void 0},St("code",{"data-language":n},t)):St("div",{className:"motion-copy-body"},e??t))}var bt=require("react/jsx-runtime"),m0={overflow:"auto",padding:12,borderRadius:8,background:"var(--dsw-alias-bg-layer-2)",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12,lineHeight:1.5,whiteSpace:"pre-wrap"};function p0({code:t,lang:e,title:r,wrap:n,copyLabel:a,copiedLabel:i}){return(0,bt.jsx)(Qn,{text:t,lang:e,title:r,wrap:n,code:!0,copyLabel:a,copiedLabel:i})}function f0({diffs:t}){return(0,bt.jsx)("div",{children:t.map((e,r)=>(0,bt.jsxs)("section",{children:[(0,bt.jsx)("strong",{children:e.path}),(0,bt.jsx)("pre",{style:m0,children:(e.oldText??"").split(`
271
+ `;function Qn({text:t,children:e,title:r,lang:n,code:a=!1,wrap:i=!1,disabled:s=!1,style:o,nodeId:l,copyLabel:m,copiedLabel:u}){let[p,b]=(0,lr.useState)("idle"),y=(0,lr.useRef)();(0,lr.useEffect)(()=>()=>clearTimeout(y.current),[]);let k=p==="done"?u??"\u5DF2\u590D\u5236":p==="error"?"\u590D\u5236\u5931\u8D25\uFF0C\u8BF7\u624B\u52A8\u9009\u62E9\u5185\u5BB9":m??(a?"\u590D\u5236\u4EE3\u7801":"\u590D\u5236\u6587\u672C");async function T(){clearTimeout(y.current),b("copying");let C=await cm(t);b(C?"done":"error"),y.current=setTimeout(()=>b("idle"),2e3)}return St("section",{className:"motion-copy-block","data-copy-status":p,"data-code":a||void 0,"data-ui-node":l,style:o},St("style",null,dm),St("div",{className:"motion-copy-bar"},a&&St("span",{"aria-hidden":!0},"\u3008/\u3009"),St("span",{className:"motion-copy-title"},r??(a?n||"\u4EE3\u7801":"\u6587\u672C")),St("button",{className:"motion-copy-button",type:"button",title:k,"aria-label":k,"data-status":p,disabled:s||p==="copying",onClick:T},St(u0,{name:p==="done"?"check":p==="error"?"warning":"copy"})),St("span",{className:"motion-copy-sr",role:"status","aria-live":"polite"},p==="done"?"\u5DF2\u590D\u5236\u5230\u526A\u8D34\u677F":p==="error"?k:"")),a?St("pre",{className:"motion-copy-code","data-wrap":i||void 0},St("code",{"data-language":n},t)):St("div",{className:"motion-copy-body"},e??t))}var bt=require("react/jsx-runtime"),m0={overflow:"auto",padding:12,borderRadius:8,background:"var(--dsw-alias-bg-layer-2)",fontFamily:"ui-monospace, SFMono-Regular, Menlo, monospace",fontSize:12,lineHeight:1.5,whiteSpace:"pre-wrap"};function p0({code:t,lang:e,title:r,wrap:n,copyLabel:a,copiedLabel:i}){return(0,bt.jsx)(Qn,{text:t,lang:e,title:r,wrap:n,code:!0,copyLabel:a,copiedLabel:i})}function f0({diffs:t}){return(0,bt.jsx)("div",{children:t.map((e,r)=>(0,bt.jsxs)("section",{children:[(0,bt.jsx)("strong",{children:e.path}),(0,bt.jsx)("pre",{style:m0,children:(e.oldText??"").split(`
270
272
  `).map(n=>`- ${n}`).concat((e.newText??"").split(`
271
273
  `).map(n=>`+ ${n}`)).join(`
272
274
  `)})]},`${e.path}:${r}`))})}function h0({data:t,label:e,copyable:r,labels:n}){let[a,i]=(0,tn.useState)(!0),[s,o]=(0,tn.useState)(!1),l=JSON.stringify(t,null,2),m=async()=>{await rn(l)&&(o(!0),window.setTimeout(()=>o(!1),1200))};return(0,bt.jsxs)("section",{children:[(0,bt.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:8},children:[(0,bt.jsxs)("button",{type:"button","aria-expanded":a,onClick:()=>i(u=>!u),children:[a?_("label.collapse"):_("label.expandNode")," ",e??"JSON"]}),r&&(0,bt.jsx)("button",{type:"button",onClick:()=>void m(),children:s?n?.copied??_("label.copied"):n?.copyJson??_("label.copy")})]}),a&&(0,bt.jsx)("pre",{style:m0,children:l})]})}async function rn(t){if(typeof navigator.clipboard?.writeText=="function")try{return await navigator.clipboard.writeText(t),!0}catch{return!1}let e=document.createElement("textarea");e.value=t,e.setAttribute("readonly",""),e.style.position="fixed",e.style.left="-9999px",document.body.appendChild(e);try{return e.select(),document.execCommand("copy")}catch{return!1}finally{e.remove()}}function g0(t){}var b0=(0,tn.createContext)(void 0);var um=(0,ea.createContext)(void 0),Ni=b0??um;function v0(){return(0,ea.useContext)(Ni)}var x0="dsh.genui.interaction";function Mi(){return{order:[],blocks:{}}}function w0(){try{let t=localStorage.getItem(x0);if(t===null)return Mi();let e=JSON.parse(t);return!Array.isArray(e.order)||typeof e.blocks!="object"||e.blocks===null?Mi():{order:e.order.filter(r=>typeof r=="string"),blocks:e.blocks}}catch{return Mi()}}function mm(t){try{localStorage.setItem(x0,JSON.stringify(t))}catch{}}function k0(t){return t===""?null:w0().blocks[t]??null}function S0(t,e){if(t==="")return;let r=w0(),n=r.order.filter(i=>i!==t);n.unshift(t);let a={...r.blocks,[t]:e};for(;n.length>200;){let i=n.pop();i!==void 0&&delete a[i]}mm({order:n,blocks:a})}function ra(){return{fences:0,panels:0,interactions:0,templates:0,charts:0,advanced:0}}var ta=t=>e=>e.fences>=t;function pm(t){return _(`ach.${t}.name`)}function fm(t){return _(`ach.${t}.desc`)}function yt(t,e,r,n=!1){return{id:t,rarity:e,check:r,...n?{hidden:!0}:{},get name(){return pm(t)},get description(){return fm(t)}}}var A0=[yt("first-fence","common",ta(1)),yt("fence-5","common",ta(5)),yt("fence-25","rare",ta(25)),yt("fence-50","legendary",ta(50),!0),yt("first-interaction","common",t=>t.interactions>=1),yt("interaction-10","rare",t=>t.interactions>=10),yt("first-panel","common",t=>t.panels>=1),yt("panel-5","rare",t=>t.panels>=5),yt("first-chart","common",t=>t.charts>=1),yt("chart-10","rare",t=>t.charts>=10),yt("first-advanced","rare",t=>t.advanced>=1),yt("template-1","common",t=>t.templates>=1)];function T0(t){let e=0,r=0,n=a=>{if(Array.isArray(a))for(let i of a){if(typeof i!="object"||i===null)continue;let s=i,o=s.type;if((o==="chart"||o==="plot"||o==="echart")&&(e+=1),(o==="scene3d"||o==="mermaid"||o==="diagram")&&(r+=1),Array.isArray(s.items)&&n(s.items),Array.isArray(s.tabs))for(let l of s.tabs)n(l.items)}};return n(t.items),{charts:e,advanced:r}}function N0(t,e){return A0.filter(r=>e[r.id]===void 0&&r.check(t))}var M0="dsh.genui.achievements",C0="dsh.genui.achievements.seen",hm=200,qt=ym(),gm=new Set,bm=[];function ym(){try{let t=localStorage.getItem(M0);if(t===null)return{state:ra(),unlocked:{}};let e=JSON.parse(t);return{state:{...ra(),...e.state??{}},unlocked:typeof e.unlocked=="object"&&e.unlocked!==null?e.unlocked:{}}}catch{return{state:ra(),unlocked:{}}}}function vm(){try{localStorage.setItem(M0,JSON.stringify(qt))}catch{}}function xm(){try{let t=localStorage.getItem(C0);if(t===null)return[];let e=JSON.parse(t);return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}catch{return[]}}function wm(t){try{localStorage.setItem(C0,JSON.stringify(t.slice(0,hm)))}catch{}}function km(){for(let t of gm)t()}function z0(t){qt.state={...qt.state,...t};let e=N0(qt.state,qt.unlocked);for(let r of e)qt.unlocked[r.id]=Date.now();e.length>0&&bm.push(...e),vm(),km()}function Sm(t){let e=JSON.stringify(t),r=3735928559,n=1103547991;for(let a=0;a<e.length;a++){let i=e.charCodeAt(a);r=Math.imul(r^i,2654435761),n=Math.imul(n^i,1597334677)}return`${(r>>>0).toString(36)}-${(n>>>0).toString(36)}`}function R0(t){let e=Sm(t),r=xm();if(r.includes(e))return;wm([e,...r]);let n=T0(t);z0({fences:qt.state.fences+1,charts:qt.state.charts+(n.charts>0?1:0),advanced:qt.state.advanced+(n.advanced>0?1:0)})}function G0(){z0({interactions:qt.state.interactions+1})}var cc=require("react");var At=require("react"),Ci=(0,At.createContext)({path:"root"});function $0({id:t,answers:e,children:r}){let n=(0,At.useContext)(Ci);return(0,At.createElement)(Ci.Provider,{value:{path:n.path+"/"+t,answers:e??n.answers}},r)}function st(t,e,r=()=>!0,n=!0){let a=(0,At.useContext)(Ci),i="__motion_widget_"+a.path+":"+t,[s,o]=(0,At.useState)(()=>{let u=n?a.answers?.fields[i]:void 0;if(u!==void 0)try{let p=JSON.parse(u);if(r(p))return p}catch{}return typeof e=="function"?e():e}),l=(0,At.useRef)(s);l.current=s;let m=(u,p)=>{let b=typeof u=="function"?u(l.current):u;if(!r(b))return;l.current=b,o(b);let y=JSON.stringify(b);n&&p&&y!==void 0&&y.length<=4096&&y!==a.answers?.fields[i]&&a.answers?.setField(i,y)};return[s,u=>m(u,!0),u=>m(u,!1)]}var fa=require("react");var A={maxDepth:8,maxNodes:200,maxString:2e3,maxCode:12e3,maxMermaid:8e3,maxGridCols:12,maxTabs:12,maxAccordionItems:24,maxListItems:50,maxOptions:50,maxTableRows:50,maxTableCols:12,maxChartPoints:60,maxPlotSeries:8,maxPlotParams:6,maxMeshes:5,maxQuizOptions:8,maxSteps:24,maxTimelineItems:24,maxBreadcrumbItems:12,maxKeyValuePairs:24,maxTreeDepth:6,maxDiagramNodes:9,maxDiagramEdges:12,maxDiagramZones:3,maxDiagramFocal:2,maxDiagramLabel:14,maxEChartOptionDepth:10,maxEChartArrayLen:500,maxEChartOptionNodes:2e3};var Tt=require("react");var Ze=require("react/jsx-runtime"),E0=["var(--dsw-static-deepseek-400)","var(--dsw-static-deepseek-450)","var(--dsw-static-blue-450)","var(--dsw-static-green-400)","var(--dsw-static-amber-400)","var(--dsw-static-red-400)","var(--dsw-static-deepseek-300)","var(--dsw-static-neutral-bluish-400)"];function D0(t){let e=0;for(let r=0;r<t.length;r++)e=e*31+t.charCodeAt(r)>>>0;return E0[e%E0.length]}function I0({className:t,disabled:e,onClick:r,children:n}){let a=Oe(),[i,s]=(0,Tt.useState)(!1),o=(0,Tt.useRef)(null);return(0,Tt.useEffect)(()=>()=>{o.current!==null&&clearTimeout(o.current)},[]),(0,Ze.jsxs)(Ze.Fragment,{children:[(0,Ze.jsxs)("button",{type:"button",className:t,disabled:e,onClick:r===void 0?void 0:()=>{r(),o.current!==null&&clearTimeout(o.current),s(!0),o.current=setTimeout(()=>s(!1),1400)},children:[n,i&&(0,Ze.jsx)("span",{className:g.btnSent,"aria-hidden":!0,children:a("block.triggered")})]}),(0,Ze.jsx)("span",{className:g.visuallyHidden,role:"status",children:i?a("block.triggeredPlain"):""})]})}var L0=(0,Tt.memo)(function({node:e}){let r=Oe(),[n,a]=(0,Tt.useState)(!1);return(0,Ze.jsxs)("figure",{className:g.media,children:[e.alt!==void 0&&(0,Ze.jsx)("figcaption",{className:g.mediaLabel,children:B(e.alt)}),n?(0,Ze.jsx)("div",{className:g.mediaError,role:"alert",children:r("block.audioError")}):(0,Ze.jsx)("audio",{className:g.mediaPlayer,src:e.src,"aria-label":e.alt??r("block.audio"),controls:!0,preload:"metadata",loop:e.loop===!0,onError:()=>a(!0)})]})}),B0=(0,Tt.memo)(function({node:e}){let r=Oe(),[n,a]=(0,Tt.useState)(!1);return(0,Ze.jsxs)("figure",{className:g.media,children:[e.alt!==void 0&&(0,Ze.jsx)("figcaption",{className:g.mediaLabel,children:B(e.alt)}),n?(0,Ze.jsx)("div",{className:g.mediaError,role:"alert",children:r("block.videoError")}):(0,Ze.jsx)("video",{className:`${g.mediaPlayer} ${g.videoPlayer}`,src:e.src,poster:e.poster,"aria-label":e.alt??r("block.video"),controls:!0,preload:"metadata",playsInline:!0,loop:e.loop===!0,muted:e.muted===!0,style:e.aspectRatio===void 0?void 0:{aspectRatio:e.aspectRatio.replace(":"," / ")},onError:()=>a(!0)})]})});var $e=require("react");function Ri(t){let e=t.columns,r=Array.isArray(e)&&e.length>0,n=r&&Array.isArray(e)&&typeof e[0]=="object"&&e[0]!==null?e.map(Cm):e,a=Am(n),i=t.rows!==void 0?t.rows:t.data;if(Array.isArray(i)&&i.length>0&&typeof i[0]=="object"&&i[0]!==null&&!Array.isArray(i[0])){let l=Array.isArray(t.columns)&&t.columns.length>0&&typeof t.columns[0]=="object"&&t.columns[0]!==null?t.columns.map(Nm).filter(m=>m!==void 0):Object.keys(i[0]);i=i.map(m=>l.map(u=>Mm(m[u])))}let s=null;if(!r&&Array.isArray(i)&&i.length>0&&Array.isArray(i[0])){let l=zi(i),m=l.length===0?null:Tm(l);m!==null&&zi(m.rows).length===m.rows.length&&(s=m,a=m.columns.map(u=>u.slice(0,128)))}if(a.length===0&&!Array.isArray(t.columns))return null;let o=zi(s===null?i:s.rows);return Array.isArray(i)?{columns:a.slice(0,A.maxTableCols),rows:o}:null}function Yt(t){return Ri(t)?.rows??[]}function Gi(t,e){return!Array.isArray(t)||!Array.isArray(e)||e[0]!=="group"?!1:String(t[0]??"").trim()!==""&&t.slice(1).every(r=>String(r??"").trim()==="")}function Nt(t,e){let r=Yt(t);return e>=0&&e<r.length&&!Gi(r[e],t.types)}function Am(t){if(!Array.isArray(t))return[];let e=[];for(let r of t){if(e.length>=A.maxTableCols)break;if(typeof r=="string")e.push(r.slice(0,128));else if(r!==null&&typeof r=="object"){let n=r,a=typeof n.label=="string"?n.label:typeof n.value=="string"?n.value:typeof n.title=="string"?n.title:JSON.stringify(r);e.push(a.slice(0,128))}}return e}function zi(t){if(!Array.isArray(t))return[];let e=[];for(let r of t){if(e.length>=A.maxTableRows)break;if(!Array.isArray(r))continue;let n=[];for(let a of r){if(n.length>=A.maxTableCols)break;typeof a=="string"?n.push(a.slice(0,256)):typeof a=="number"&&Number.isFinite(a)&&n.push(a)}n.length>0&&e.push(n)}return e}function Tm(t){let e=t[0];if(e===void 0||e.length===0)return null;let r=t.slice(1);if(r.length===0){let n=e.map(a=>String(a).trim());return n.every(a=>a!=="")?{columns:n,rows:[]}:null}return r.every(n=>n.length===e.length)?{columns:e.map(n=>String(n).trim()),rows:r}:{columns:Array.from({length:e.length},(n,a)=>`\u5217${a+1}`),rows:t}}function Nm(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e=t;for(let r of["key","dataIndex","title","label"])if(typeof e[r]=="string"&&e[r]!=="")return e[r]}function Mm(t){return typeof t=="string"||typeof t=="number"&&Number.isFinite(t)?t:t==null?"":JSON.stringify(t)}function Cm(t){if(t===null||typeof t!="object"||Array.isArray(t))return String(t);let e=t;for(let r of["title","label","key","dataIndex"])if(typeof e[r]=="string"&&e[r]!=="")return e[r];return JSON.stringify(t)}var N=require("react/jsx-runtime"),na=["var(--dsw-static-deepseek-400)","var(--dsw-static-green-400)","var(--dsw-static-amber-400)","var(--dsw-static-red-400)","var(--dsw-static-blue-450)","var(--dsw-static-deepseek-450)","var(--dsw-static-neutral-bluish-400)","var(--dsw-static-deepseek-300)"],aa=(t,e,r,n)=>r??(n!==void 0&&n.length>0?n[t%n.length]:e>1?na[t%na.length]:void 0);function Gr(t){if(typeof t=="number")return Number.isFinite(t)?t:NaN;if(typeof t!="string")return NaN;let e=t.trim();if(e==="")return NaN;e=e.replace(/^[¥$€£]/,""),e.endsWith("%")&&(e=e.slice(0,-1));let n=1;if(e.endsWith("\u4E07"))n=1e4,e=e.slice(0,-1);else if(e.endsWith("\u4EBF"))n=1e8,e=e.slice(0,-1);else if(/[kmb]$/i.test(e)){let i=e.slice(-1).toLowerCase();n=i==="k"?1e3:i==="m"?1e6:1e9,e=e.slice(0,-1)}e=e.replace(/[,,\s]/g,"");let a=Number(e);return Number.isFinite(a)?a*n:NaN}function zm(t,e){return Array.from({length:e},(r,n)=>{let a=!1;for(let i of t){let s=i[n];if(!(s==null||s==="")){if(!Number.isFinite(Gr(s)))return!1;a=!0}}return a})}function Rm(t){return typeof t=="string"&&/[\n\r]/.test(t)}function Gm(t){return typeof t!="string"?!1:/(^|\n)[ \t]/.test(t)||t.includes("```")}function $i(t){if(Rm(t))return Gm(t)?g.tdCode:g.tdMultiline}function $m(t){if(typeof t!="string")return null;let e=t.trim();return!/^[+][\s]*[\d.]/.test(e)&&!/^[-−][\s]*[\d.]/.test(e)?null:e.startsWith("+")?"up":"down"}function Em({cell:t}){let e=String(t).split(/[\s,;]+/).map(Number).filter(Number.isFinite);if(e.length<2)return(0,N.jsx)(N.Fragment,{children:B(String(t),!1)});let r=88,n=22,a=2,i=Math.min(...e),o=Math.max(...e)-i||1,l=(r-a*2)/(e.length-1),m=e.map((y,k)=>[a+k*l,n-a-(y-i)/o*(n-a*2)]),u=m.map(([y,k])=>`${y.toFixed(1)},${k.toFixed(1)}`).join(" "),p=m[m.length-1],b=`M ${a},${n-a} L ${u.split(" ").join(" L ")} L ${p[0].toFixed(1)},${n-a} Z`;return(0,N.jsxs)("svg",{className:g.cellSpark,viewBox:`0 0 ${r} ${n}`,preserveAspectRatio:"none","aria-hidden":"true",children:[(0,N.jsx)("path",{d:b,fill:"var(--dsl-g-accent)",opacity:"0.14"}),(0,N.jsx)("polyline",{points:u,fill:"none",stroke:"var(--dsl-g-accent)",strokeWidth:"1.5",strokeLinejoin:"round",strokeLinecap:"round",vectorEffect:"non-scaling-stroke"}),(0,N.jsx)("path",{d:`M ${p[0].toFixed(1)} ${p[1].toFixed(1)} L ${p[0].toFixed(1)} ${p[1].toFixed(1)}`,stroke:"var(--dsl-g-accent)",strokeWidth:4,strokeLinecap:"round",vectorEffect:"non-scaling-stroke",fill:"none"})]})}function Dm({cell:t}){let e=Gr(t),r=Number.isFinite(e)?Math.max(0,Math.min(100,e)):0,n=11,a=2*Math.PI*n;return(0,N.jsxs)("span",{className:g.cellRing,children:[(0,N.jsxs)("svg",{width:28,height:28,viewBox:"0 0 28 28","aria-hidden":"true",children:[(0,N.jsx)("circle",{cx:14,cy:14,r:n,fill:"none",strokeWidth:4,className:g.ringTrack}),(0,N.jsx)("circle",{cx:14,cy:14,r:n,fill:"none",strokeWidth:4,strokeLinecap:"round",className:g.ringFill,strokeDasharray:`${r/100*a} ${a}`,transform:"rotate(-90 14 14)"})]}),(0,N.jsx)("span",{className:g.cellRingText,children:B(String(t),!1)})]})}function Im(t,e){let r=s=>String(s??"").replace(/\|/g,"\\|").replace(/\n/g," "),n=`| ${t.map(r).join(" | ")} |`,a=`| ${t.map(()=>"---").join(" | ")} |`,i=e.map(s=>`| ${t.map((o,l)=>r(s[l])).join(" | ")} |`);return[n,a,...i].join(`
@@ -1,7 +1,7 @@
1
1
  // A small authoring language compiled to the existing interpreter; never eval.
2
2
  import { IDENTIFIER_SOURCE, validIdentifier } from './identifiers.js';
3
3
  export function compileExpression(source) {
4
- const fail = () => { throw new Error('DSH UI: invalid formula; use state.x, data.x, derived.x, item.x, numbers, strings, + - * /, comparisons, ?: and min/max/round/abs'); };
4
+ const fail = () => { throw new Error('DSH UI: invalid formula; use state.x, data.x, derived.x, item.x, numbers, strings, + - * /, comparisons, ?: and min/max/round/ceil/floor/abs'); };
5
5
  if (typeof source !== 'string' || !source.trim() || source.length > 2048) fail();
6
6
  const tokens = []; let offset = 0;
7
7
  const token = new RegExp(String.raw`\s*(?:(\d+(?:\.\d*)?|\.\d+)([eE][+-]?\d+)?|("(?:[^"\\]|\\.)*")|(${IDENTIFIER_SOURCE}(?:\.${IDENTIFIER_SOURCE})?)|(===|!==|<=|>=|==|!=|[+*/()?,:<>-]))`, 'uy');
@@ -23,7 +23,7 @@ export function compileExpression(source) {
23
23
  else if (t === '(') { out = parse(0, depth + 1); take(')'); }
24
24
  else if (t === '-' || t === '+') { const arg = parse(5, depth + 1); out = t === '-' ? { op: 'sub', args: [{ const: 0 }, arg] } : arg; }
25
25
  else if (typeof t === 'string' && t.split('.').length === 2 && ['state','data','derived','item'].includes(t.split('.')[0]) && validIdentifier(t.split('.')[1])) out = { ref: t };
26
- else if (['min', 'max', 'round', 'abs'].includes(t)) {
26
+ else if (['min', 'max', 'round', 'ceil', 'floor', 'abs'].includes(t)) {
27
27
  take('('); const args = [parse(0, depth + 1)];
28
28
  while (tokens[pos] === ',') { pos++; args.push(parse(0, depth + 1)); if (args.length > 8) fail(); }
29
29
  take(')'); out = { op: t, args };
@@ -55,6 +55,7 @@ export function expandExpressions(doc) {
55
55
  const walk = nodes => { if (!Array.isArray(nodes)) return; for (const node of nodes) {
56
56
  if (!node || typeof node !== 'object') continue;
57
57
  for (const field of ['text', 'value', 'max', 'rows']) if (Object.hasOwn(node, field)) node[field] = expression(node[field]);
58
+ if (['table','chart'].includes(node.type)&&Array.isArray(node.rows)) for(const row of node.rows) if(row&&typeof row==='object'&&!Array.isArray(row)) for(const k of Object.keys(row)) row[k]=expression(row[k]);
58
59
  walk(node.children);
59
60
  } };
60
61
  walk(doc.nodes); return doc;
@@ -4,10 +4,11 @@ export const AUTHORING_GUIDE = `Authoring fast path:
4
4
  - JSON object field order never matters. Every node, including each sandbox, must include a unique id. sandbox title/fallback default to the document's only when omitted; do not send null or empty values.
5
5
  - Declaring state does NOT create controls. For each parameter the user should edit, add a native slider/input/select/toggle bound to state.key, or actual canvas HTML controls wired to DSHUI.setState with that key in stateKeys. A canvas subscribe callback only updates display; it does not create an input. Read-only state and static UI are valid; do not invent controls where the task does not need them. Check intended controls exist before calling the tool.
6
6
  - Use render_ui/render_canvas directly for UI construction. This contract and ui_catalog are the protocol reference; installation source inspection is not a prerequisite. For unclear component/formula details consult ui_catalog, rather than grep/glob/shell searches of DSH checkouts or app.asar. File/search tools needed for the user's actual task or data remain appropriate.
7
- - Formula round(x) takes ONE argument and uses JavaScript Math.round: nearest integer, ties toward positive infinity (round(2.5)=3, round(-2.5)=-2). It is not ceil/floor, which are not registered native formula functions. For ceiling/floor use Math.ceil/Math.floor in a canvas subscribed to declared shared state. Display decimals formats numbers without changing calculation precision.
7
+ - Formula round(x) takes ONE argument and uses JavaScript Math.round: nearest integer, ties toward positive infinity (round(2.5)=3, round(-2.5)=-2). Native ceil(x) rounds up and floor(x) rounds down, each with ONE argument. Use {expr:"ceil(state.people / 2)"} for room counts directly, without a canvas or lookup chain. Display decimals formats numbers without changing calculation precision.
8
8
  - Pass tool JSON fields as objects, not hand-escaped JSON strings. For custom HTML/SVG use render_canvas({title,fallback,html,css,script}) to avoid nesting source in document JSON.
9
9
  - Start with the smallest useful static UI. State/derived/actions are optional. A table can put its object rows directly in rows; reuse data/derived references only when useful. Example: {id:"t",type:"table",label:"方案比较",columns:[{key:"方案",label:"方案"}],rows:[{"方案":"A"}]}.
10
10
  - For a short ordered process, use steps with a DIRECT items array: {id:"flow",type:"steps",items:[{title:"整理文件",description:"保留源码和说明,排除密钥。"},{title:"提交代码",description:"检查变更后提交。"}]}. Do not wrap items in {item:[...]}. status is optional: omit it for explanatory guides; use pending/active/done/error only for known task states. Keep one sentence per requested step; avoid extra command disclosures unless asked.
11
+ - A short dynamic chart/table can use inline formula cells: rows:[{label:"餐饮",value:{ref:"derived.food"}},{label:"住宿",value:{expr:"ceil(state.people / 2) * state.room"}}]. Chart labelKey:"label",valueKey:"value". No map/if chain is required for a few categories. Submit complete nodes/state/derived together on every render_ui retry; it creates a document, not a partial patch.
11
12
  - Numeric controls need complete typed state: state:{people:{type:"number",default:2,min:1,max:12,step:1},days:{type:"number",default:5,min:2,max:15,step:1}}. Use numbers without quotes or units. Prefer derived:{food:{expr:"state.people * state.days * 100"}} to a deep op/args tree. children, options, columns and expression args are direct arrays. The host normalizes plain numeric strings only in explicitly numeric fields and exact {item:[...]} wrappers only at declared array positions; ordinary text/data retain their types.
12
13
  - Host defaults use readable editorial typography, quiet backgrounds, light borders and restrained accents. For guided canvas designs prefer 12..18px radii and flat surfaces; gradients are optional and must not replace information hierarchy. Let content determine height: no empty spacer sections, min-height:100vh or large fixed min-heights. A canvas auto-fits its rendered content after commit, including shrinking after filtering; height is only the initial placeholder. Use SVG viewBox bounds close to actual graphics plus reasonable padding.
13
14
  - metric.value accepts a finite number or display string/boolean. Numbers use decimals and unit; strings display verbatim ("约 12 GiB", "待确认"). Calculations and chart series still require real numbers, never formatted strings.
package/lib/build-info.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by npm run build.
2
- export const BUILD_INFO = Object.freeze({"version":"0.6.0","id":"0.6.0+185e0952117f","sourceHash":"185e0952117fa36c7fd9bd5c1d6b04868628a4042bd2534cadd9f3f3ffce8f99"});
2
+ export const BUILD_INFO = Object.freeze({"version":"0.7.0","id":"0.7.0+6adc22f63978","sourceHash":"6adc22f639783dee4cfb7400828727748c020f09b8e912e4500dde67fc871562"});
package/lib/catalog.js CHANGED
@@ -5,17 +5,17 @@ import {VISUAL_GUIDE} from './visual.js';
5
5
  export { sceneExamples } from './scenes.js';
6
6
  export { bicycleExample, oscillatorExample } from './canvas-example.js';
7
7
  export const PROTOCOL_GUIDE = VISUAL_GUIDE+'\n\n'+AUTHORING_GUIDE+`\n\nDSH UI v1. Call render_ui({document: ...}) directly when visualization helps. Do not call it inside run_code/PTC in this version.
8
- Formula shorthand: {expr:"state.V * state.V / state.R"} compiles to the same validated interpreter. Supports explicit state.x/data.x/derived.x/item.x references, + - * /, == != < <= > >=, parentheses, condition ? yes : no, min/max/round/abs, double-quoted strings and booleans. Use it in derived, node text/value/max/rows or map.fields. No arbitrary functions, property chains, statements or side effects; complex animation belongs in render_canvas. Example derived:{power:{expr:"state.V * state.V / state.R"}}, metric.value:{ref:"derived.power"}.
8
+ Formula shorthand: {expr:"state.V * state.V / state.R"} compiles to the same validated interpreter. Supports explicit state.x/data.x/derived.x/item.x references, + - * /, == != < <= > >=, parentheses, condition ? yes : no, min/max/round/ceil/floor/abs, double-quoted strings and booleans. Use it in derived, node text/value/max/rows or map.fields. No arbitrary functions, property chains, statements or side effects; complex animation belongs in render_canvas. Example derived:{power:{expr:"state.V * state.V / state.R"}}, metric.value:{ref:"derived.power"}.
9
9
  Document: {version:1,title:string,fallback:string,presentation?:{layout,accent,density,preset},state?:{},data?:{},derived?:{},nodes:[],actions?:{}}.
10
10
  Scene layouts: dashboard (metrics/trends), workbench (parameter controls/results), comparison (parallel choice cards), guide (ordered instructions), status (observed task snapshot), report (reading and evidence). Accent: blue/teal/violet/amber/rose; density: comfortable/compact. Omit to keep the standard design. Choose based on the task, not at random. Card surface: outline/soft/featured. Featured indicates discussion focus, not an automatic recommendation.
11
11
  Additional nodes: badge {id,type,text,icon?,tone?}; progress {id,type,label,value,max,unit?,icon?,tone?} where values may be bindings and 0 <= value <= positive max; steps {id,type,items:[{title,description?,status?:"pending"|"active"|"done"|"error"}]} (direct array of 1..12 items, not {item:[...]}; omit status for static guides); details {id,type,title,children,open?:boolean,icon?,tone?}. Progress and steps are declared snapshots, not a live host task subscription. Only claim real progress/completion from actual tool evidence; mark demo data visibly. Details keeps the content available in text fallback.
12
12
  Display lifecycle: submit native render_text/render_ui/render_canvas directly. Several independent UI documents may be created in one answer. Complete validated native blocks appear progressively as read-only previews. Keep previews visible through later reasoning and text; durable turn/end activates controls and scripts. Incomplete/failed tools never become interactive. Use small meaningful documents; no separate ui.begin/append calls.
13
13
  All IDs and dictionary keys: Unicode letters (including Chinese) or underscore, followed by letters/marks/digits/underscore, max64; unique node IDs. Standard components reject HTML, JS, arbitrary styles and callbacks. link/button href explicitly supports http/https URLs; path uses the host file opener on user click. The sandbox component below is the explicit exception; unlisted fields are always rejected.
14
- Freeform canvas: {id,type:"sandbox",title,html,css?:string,script?:string,height?:160..1000,fallback,stateKeys?:string[],dataKeys?:string[],derivedKeys?:string[]}. Use it for custom SVG diagrams, animation, simulations and bespoke interfaces that fixed components cannot express. HTML is a body fragment. Put CSS in css and ALL JavaScript in script (not inline handlers, script tags or remote imports). Inline SVG is supported. Each source field allows up to 49152 characters; the total document remains 128KiB. The iframe has no same-origin privilege, remote resources/network APIs are blocked by CSP, and no host tools are exposed. Never put credentials or private unrelated data in a canvas. It is browser origin isolation, not a CPU/memory hard sandbox.
14
+ Freeform canvas: {id,type:"sandbox",title,html,css?:string,script?:string,height?:160..1000,fallback,stateKeys?:string[],dataKeys?:string[],derivedKeys?:string[],libraries?:["mechanism"]}. For internal assemblies and mechanical relations, ui_catalog topic=mechanism provides an opt-in local drawing/kinematics helper and three complete examples (assembly/gears/crank). Use it for custom SVG diagrams, animation, simulations and bespoke interfaces that fixed components cannot express. HTML is a body fragment. Put CSS in css and ALL JavaScript in script (not inline handlers, script tags or remote imports). Inline SVG is supported. Each source field allows up to 49152 characters; the total document remains 128KiB. The iframe has no same-origin privilege, remote resources/network APIs are blocked by CSP, and no host tools are exposed. Never put credentials or private unrelated data in a canvas. It is browser origin isolation, not a CPU/memory hard sandbox.
15
15
  Canvas API: window.DSHUI.snapshot -> {state,data,derived,disabled,theme,visible}; DSHUI.animate(fn) returns cleanup and calls fn({time,delta,reducedMotion,visible}), time/delta in seconds, delta capped at 0.05. It pauses offscreen/background and supplies a static delta=0 callback for reduced motion; integrate delta for pause/resume without jumps. DSHUI.subscribe(snapshot=>{...}) immediately supplies current selected values and returns unsubscribe; DSHUI.setState({key:value,...}) requests an atomic Host-validated update of declared stateKeys. Use bare dictionary keys in stateKeys/dataKeys/derivedKeys. Only declared keys are exposed; state types/ranges/options remain enforced. Subscribe to drive DOM/SVG from host state; do not send the same state back from subscribe (feedback loop). Native controls and canvas share the saved state. Local animation may use requestAnimationFrame without saving every frame. No Agent/tool action API in this release. theme exposes bg,soft,ink,muted,line,accent,scheme; CSS variables --canvas-bg/soft/ink/muted/line/accent update automatically. Honor reduced motion, provide accessible labels and responsive layout. Canvas scripts activate only after successful tool commit and state restoration; previews show inert completed HTML/CSS. Use a complete useful fallback per canvas. Code or reset changes restart the frame, state changes do not. All transient internal animation state is reset on reload; declare important parameters in document.state.
16
16
  state: key -> {type:"number",default,min,max,step} or {type:"string",default,options?:scalar[]} or {type:"boolean",default} or {type:"json",default:array/object} (canvas structured state, max16KiB per value). select requires scalar options. Numeric defaults follow step from min.
17
- derived: key -> expression: {const:scalar}, {ref:"state.key"|"data.key"|"derived.key"}, or {op,args:expression[]}. Allowed ops add,mul,min,max (1..8 args); sub,div,eq,neq,lt,lte,gt,gte (2); round,abs (1); if (3, boolean condition). No cycles. Arithmetic requires finite numbers: add does NOT concatenate strings. For formatted labels use a metric's label/unit/decimals, or format text inside a sandbox; omit unused derived fields. if can return strings: {op:"if",args:[{op:"gt",args:[{ref:"derived.weightGiB"},{const:20}]},{const:"超过理论预算"},{const:"在理论预算内"}]} -> bind a text node to this derived result. No separate conditional-rendering field is needed.
18
- Text/metric values are literal scalars or {ref:...}. Table/chart rows accept inline arrays of objects, {ref:"data.rows"}, {ref:"derived.rows"}, or the shorthand string "data.rows"/"derived.rows". Table label is an optional caption. Static table example: data:{rows:[{name:"A",note:"示例"}]}, node:{id:"t",type:"table",rows:{ref:"data.rows"},columns:[{key:"name",label:"方案"},{key:"note",label:"说明"}]}. Dynamic rows: a derived root may be {map:{source:"data.samples",fields:{contextK:{op:"mul",args:[{ref:"state.contextK"},{ref:"item.fraction"}]},value:{ref:"derived.total"}}}}. source must be the string "data.samples", not an inline array; declare those object rows in document.data.samples. Internal field keys support Chinese identifiers such as 功率 and ASCII identifiers such as powerW; spaces/dots/hyphens belong in display labels. item.key is available only inside map fields. Each field is a normal scalar expression. No nested maps/callbacks; 1..16 fields, max500 generated rows across all maps; normal expression and calculation budgets apply. Derived output max128KiB. DSHUI.formatNumber(value, decimals=2) formats finite numbers with 0..6 decimal places and comma grouping, exactly matching native metrics and fallback; use it for shared readouts instead of mixing toFixed rounding. Use this for live charts/tables, never model calls on slider changes.
17
+ derived: key -> expression: {const:scalar}, {ref:"state.key"|"data.key"|"derived.key"}, or {op,args:expression[]}. Allowed ops add,mul,min,max (1..8 args); sub,div,eq,neq,lt,lte,gt,gte (2); round,ceil,floor,abs (1); if (3, boolean condition). No cycles. Arithmetic requires finite numbers: add does NOT concatenate strings. For formatted labels use a metric's label/unit/decimals, or format text inside a sandbox; omit unused derived fields. if can return strings: {op:"if",args:[{op:"gt",args:[{ref:"derived.weightGiB"},{const:20}]},{const:"超过理论预算"},{const:"在理论预算内"}]} -> bind a text node to this derived result. No separate conditional-rendering field is needed.
18
+ Text/metric values are literal scalars or {ref:...}. Table/chart rows accept inline arrays of objects, {ref:"data.rows"}, {ref:"derived.rows"}, or the shorthand string "data.rows"/"derived.rows". Table label is an optional caption. Static table example: data:{rows:[{name:"A",note:"示例"}]}, node:{id:"t",type:"table",rows:{ref:"data.rows"},columns:[{key:"name",label:"方案"},{key:"note",label:"说明"}]}. For a short live breakdown prefer inline formula cells: rows:[{label:"餐饮",value:{ref:"derived.mealTotal"}},{label:"住宿",value:{expr:"ceil(state.people / 2) * state.room"}}], labelKey:"label",valueKey:"value". These cells recalculate locally; data remains literal and never executes formulas. Dynamic rows for many samples: a derived root may be {map:{source:"data.samples",fields:{contextK:{op:"mul",args:[{ref:"state.contextK"},{ref:"item.fraction"}]},value:{ref:"derived.total"}}}}. source must be the string "data.samples", not an inline array; declare those object rows in document.data.samples. Internal field keys support Chinese identifiers such as 功率 and ASCII identifiers such as powerW; spaces/dots/hyphens belong in display labels. item.key is available only inside map fields. Each field is a normal scalar expression. No nested maps/callbacks; 1..16 fields, max500 generated rows across all maps; normal expression and calculation budgets apply. Derived output max128KiB. DSHUI.formatNumber(value, decimals=2) formats finite numbers with 0..6 decimal places and comma grouping, exactly matching native metrics and fallback; use it for shared readouts instead of mixing toFixed rounding. Use this for live charts/tables, never model calls on slider changes.
19
19
  Registered component fields (some optional; required values and types follow the rules above/below): ${componentGuide()}. Controls bind "state.key"; slider numeric, toggle boolean, select requires state options. Metric decimals 0..6. Table columns: [{key,label,unit?}]. Chart kind bar/line, finite numeric values, rows as a data/derived binding; line xScale linear positions numeric labelKey samples by their actual coordinate, category uses equal spacing. Use ascending samples for a curve.
20
20
  actions: key -> {type:"agent.followup",intent:string,stateKeys:string[]}. Button submits current selected parameters as a new conversation request; it does not perform a host action itself. All host actions still use ordinary DSH permissions.
21
21
  Presentation: heading/text/card/metric accept optional tone (${UI_TONES.join(', ')}); heading/text/card/metric/button accept optional icon (${UI_ICONS.join(', ')}). Fixed tokens only, no SVG/HTML/CSS/color strings. Defaults already include icons and themed spacing. Use accent for primary information, warning for assumptions/caveats, success/danger only for explicitly established facts. Tones are static, not conditional; use derived string text to report changing verdicts. Use row for 2-3 related metrics, card for a meaningful section, avoid repeated headings and deep decorative nesting. Do not use color as the only explanation.
package/lib/components.js CHANGED
@@ -13,13 +13,13 @@ export const COMPONENTS = Object.freeze({
13
13
  steps: define(['title','items'], 'Ordered declared steps with an optional heading'),
14
14
  metric: define(['label', 'value', 'unit', 'decimals'], 'Number with units, or a literal/bound status string', 'tone'),
15
15
  input: define(['label', 'bind'], 'String or numeric state input'), slider: define(['label', 'bind'], 'Numeric state control'),
16
- select: define(['label', 'bind'], 'Selection from declared state options'), toggle: define(['label', 'bind'], 'Boolean state control'),
16
+ select: define(['label', 'bind','variant'], 'Selection from declared state options; variant:segmented for 2..8 short options, dropdown otherwise'), toggle: define(['label', 'bind'], 'Boolean state control'),
17
17
  button: define(['text', 'action','href','path','variant'], 'Agent follow-up, web link or host file opener', 'icon'),
18
18
  link: define(['text','href','path','variant'], 'User-clicked webpage or local file button', 'icon'),
19
19
  divider: define(['label'], 'Quiet section divider'),
20
20
  table: define(['label', 'rows', 'columns'], 'Supplied or derived values; inline rows or data/derived reference'),
21
21
  chart: define(['kind', 'rows', 'labelKey', 'valueKey', 'label', 'unit', 'xScale'], 'Bar/line comparison with accessible data'),
22
- sandbox: define(['title', 'html', 'css', 'script', 'fallback', 'height', 'stateKeys', 'dataKeys', 'derivedKeys'], 'Freeform isolated HTML/SVG/CSS/JavaScript visualization')
22
+ sandbox: define(['title', 'html', 'css', 'script', 'fallback', 'height', 'libraries', 'stateKeys', 'dataKeys', 'derivedKeys'], 'Freeform isolated HTML/SVG/CSS/JavaScript visualization')
23
23
  });
24
24
  export function componentFields(type) {
25
25
  const c = Object.hasOwn(COMPONENTS, type) ? COMPONENTS[type] : undefined;