awaitly-visualizer 1.0.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 (43) hide show
  1. package/dist/index.browser.cjs +1677 -0
  2. package/dist/index.browser.cjs.map +1 -0
  3. package/dist/index.browser.d.cts +166 -0
  4. package/dist/index.browser.d.ts +166 -0
  5. package/dist/index.browser.js +1677 -0
  6. package/dist/index.browser.js.map +1 -0
  7. package/dist/index.cjs +1680 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.d.cts +242 -0
  10. package/dist/index.d.ts +242 -0
  11. package/dist/index.js +1680 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/kroki/fetch.cjs +3 -0
  14. package/dist/kroki/fetch.cjs.map +1 -0
  15. package/dist/kroki/fetch.d.cts +86 -0
  16. package/dist/kroki/fetch.d.ts +86 -0
  17. package/dist/kroki/fetch.js +3 -0
  18. package/dist/kroki/fetch.js.map +1 -0
  19. package/dist/notifiers/discord.cjs +3 -0
  20. package/dist/notifiers/discord.cjs.map +1 -0
  21. package/dist/notifiers/discord.d.cts +70 -0
  22. package/dist/notifiers/discord.d.ts +70 -0
  23. package/dist/notifiers/discord.js +3 -0
  24. package/dist/notifiers/discord.js.map +1 -0
  25. package/dist/notifiers/slack.cjs +38 -0
  26. package/dist/notifiers/slack.cjs.map +1 -0
  27. package/dist/notifiers/slack.d.cts +95 -0
  28. package/dist/notifiers/slack.d.ts +95 -0
  29. package/dist/notifiers/slack.js +38 -0
  30. package/dist/notifiers/slack.js.map +1 -0
  31. package/dist/notifiers/webhook.cjs +3 -0
  32. package/dist/notifiers/webhook.cjs.map +1 -0
  33. package/dist/notifiers/webhook.d.cts +115 -0
  34. package/dist/notifiers/webhook.d.ts +115 -0
  35. package/dist/notifiers/webhook.js +3 -0
  36. package/dist/notifiers/webhook.js.map +1 -0
  37. package/dist/performance-analyzer-B5VF5b1F.d.ts +663 -0
  38. package/dist/performance-analyzer-BNwE4AiO.d.cts +663 -0
  39. package/dist/types-BIZSmXif.d.ts +350 -0
  40. package/dist/types-BnWc9Wlr.d.cts +350 -0
  41. package/dist/url-PkfQz4V5.d.cts +750 -0
  42. package/dist/url-PkfQz4V5.d.ts +750 -0
  43. package/package.json +105 -0
@@ -0,0 +1,1677 @@
1
+ "use strict";var jt=Object.create;var xe=Object.defineProperty;var Vt=Object.getOwnPropertyDescriptor;var Gt=Object.getOwnPropertyNames;var Yt=Object.getPrototypeOf,Jt=Object.prototype.hasOwnProperty;var Xt=(e,t)=>{for(var r in t)xe(e,r,{get:t[r],enumerable:!0})},Qe=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Gt(t))!Jt.call(e,i)&&i!==r&&xe(e,i,{get:()=>t[i],enumerable:!(o=Vt(t,i))||o.enumerable});return e};var qt=(e,t,r)=>(r=e!=null?jt(Yt(e)):{},Qe(t||!e||!e.__esModule?xe(r,"default",{value:e,enumerable:!0}):r,e)),Zt=e=>Qe(xe({},"__esModule",{value:!0}),e);var mn={};Xt(mn,{asciiRenderer:()=>ce,buildMermaidInkUrl:()=>Ze,combineEventHandlers:()=>un,createEventCollector:()=>fn,createIRBuilder:()=>ue,createLiveVisualizer:()=>ln,createMermaidInkGenerator:()=>Pt,createParallelDetector:()=>et,createPerformanceAnalyzer:()=>st,createTimeTravelController:()=>Et,createUrlGenerator:()=>Dt,createVisualizer:()=>Ae,defaultColorScheme:()=>V,detectParallelGroups:()=>we,encodeForMermaidInk:()=>qe,flowchartRenderer:()=>le,getHeatLevel:()=>fe,hasChildren:()=>tr,htmlRenderer:()=>St,isDecisionNode:()=>Y,isParallelNode:()=>j,isRaceNode:()=>H,isSequenceNode:()=>Pe,isStepNode:()=>z,isStreamNode:()=>Q,loggerRenderer:()=>ke,mermaidRenderer:()=>te,renderToHTML:()=>Rt,toKrokiPngUrl:()=>Ot,toKrokiSvgUrl:()=>Tt,toKrokiUrl:()=>se,toMermaidInkJpegUrl:()=>Wt,toMermaidInkPdfUrl:()=>At,toMermaidInkPngUrl:()=>_t,toMermaidInkSvgUrl:()=>Lt,toMermaidInkUrl:()=>G,toMermaidInkWebpUrl:()=>Bt,trackDecision:()=>We,trackIf:()=>It,trackSwitch:()=>$t,visualizeEvents:()=>pn});module.exports=Zt(mn);function B(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(e/1e3).toFixed(1).replace(/\.0$/,"")}s`;let t=Math.floor(e/6e4),r=Math.round(e%6e4/1e3);return r>=60&&(t+=1,r=0),r===0?`${t}m`:`${t}m ${r}s`}function Se(){return`node_${Date.now()}_${Math.random().toString(36).slice(2,8)}`}function Qt(e){for(let t of e)if((t.type==="parallel"||t.type==="race"||t.type==="sequence")&&!t.id.startsWith("detected_")||t.type==="decision")return!0;return!1}function we(e,t={}){if(Qt(e))return e;let{minOverlapMs:r=0,maxGapMs:o=5}=t,i=[],n=[];for(let c=0;c<e.length;c++){let l=e[c];l.type==="step"&&l.startTs!==void 0?i.push({node:l,startTs:l.startTs,endTs:l.endTs??l.startTs+(l.durationMs??0),originalIndex:c}):n.push({node:l,originalIndex:c})}if(i.length<=1)return e;i.sort((c,l)=>c.startTs-l.startTs);let a=[],s=[i[0]];for(let c=1;c<i.length;c++){let l=i[c],p=Math.min(...s.map($=>$.startTs)),g=Math.max(...s.map($=>$.endTs)),f=l.startTs<=p+o,y=l.startTs<g;if(!f&&!y){a.push(s),s=[l];continue}let k=y?Math.min(l.endTs,g)-l.startTs:0;f||k>=r?s.push(l):(a.push(s),s=[l])}a.push(s);let u=[];for(let c of a){let l=Math.min(...c.map(p=>p.originalIndex));if(c.length===1)u.push({node:c[0].node,position:l});else{let p=c.map(k=>k.node),g=Math.min(...c.map(k=>k.startTs)),f=Math.max(...c.map(k=>k.endTs)),y={type:"parallel",id:`detected_parallel_${g}`,name:`${p.length} parallel steps`,state:er(p),mode:"all",children:p,startTs:g,endTs:f,durationMs:f-g};u.push({node:y,position:l})}}for(let{node:c,originalIndex:l}of n)u.push({node:c,position:l});return u.sort((c,l)=>c.position-l.position),u.map(c=>c.node)}function er(e){return e.some(n=>n.state==="error")?"error":e.some(n=>n.state==="running")?"running":e.some(n=>n.state==="pending")?"pending":(e.every(n=>n.state==="success"||n.state==="cached"),"success")}function et(e={}){return{detect:t=>we(t,e)}}function ue(e={}){let{detectParallel:t=!0,parallelDetection:r,enableSnapshots:o=!1,maxSnapshots:i=1e3}=e,n=o,a=Se(),s,u,c,l="pending",p,g,f=new Map,y=[],k=[],$=new Map,M=[],N=Date.now(),I=N,v={onAfterStep:new Map},x,m=[],w=0;function R(d){return d.stepId??d.stepKey??d.name??Se()}function D(d){if(y.length>0){y[y.length-1].children.push(d),I=Date.now();return}if(k.length>0){let b=k[k.length-1];for(let h of b.branches.values())if(h.taken){h.children.push(d),I=Date.now();return}b.pendingChildren.push(d),I=Date.now();return}M.push(d),I=Date.now()}function E(d){if(!n)return;let b=oe(),h=new Map;for(let[C,J]of f)h.set(C,{id:J.id,name:J.name,key:J.key,startTs:J.startTs,retryCount:J.retryCount,timedOut:J.timedOut,timeoutMs:J.timeoutMs});let A={id:`snapshot_${w}`,eventIndex:w,event:structuredClone(d),ir:structuredClone(b),timestamp:Date.now(),activeSteps:h};m.push(A),m.length>i&&m.shift(),w++}function T(d){switch(d.type){case"workflow_start":{M=[],c=void 0,g=void 0,p=void 0,f.clear(),y.length=0,k.length=0,$.clear(),s=d.workflowId,u=d.ts,l="running",N=Date.now(),I=N,x!==void 0&&x!==d.workflowId&&(v.shouldRun=void 0,v.onBeforeStart=void 0),x=d.workflowId,v.onAfterStep=new Map;break}case"workflow_success":l="success",c=d.ts,g=d.durationMs,I=Date.now();break;case"workflow_error":l="error",c=d.ts,p=d.error,g=d.durationMs,I=Date.now();break;case"workflow_cancelled":l="aborted",c=d.ts,g=d.durationMs,I=Date.now();break;case"step_start":{let b=R(d);f.set(b,{id:b,name:d.name,key:d.stepKey,startTs:d.ts,retryCount:0,timedOut:!1}),I=Date.now();break}case"step_success":{let b=R(d),h=f.get(b);if(h){let A={type:"step",id:h.id,name:h.name,key:h.key,state:"success",startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,...h.retryCount>0&&{retryCount:h.retryCount},...h.timedOut&&{timedOut:!0,timeoutMs:h.timeoutMs}};D(A),f.delete(b)}break}case"step_error":{let b=R(d),h=f.get(b);if(h){let A={type:"step",id:h.id,name:h.name,key:h.key,state:"error",startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,error:d.error,...h.retryCount>0&&{retryCount:h.retryCount},...h.timedOut&&{timedOut:!0,timeoutMs:h.timeoutMs}};D(A),f.delete(b)}break}case"step_aborted":{let b=R(d),h=f.get(b);if(h){let A={type:"step",id:h.id,name:h.name,key:h.key,state:"aborted",startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,...h.retryCount>0&&{retryCount:h.retryCount},...h.timedOut&&{timedOut:!0,timeoutMs:h.timeoutMs}};D(A),f.delete(b)}break}case"step_cache_hit":{let h={type:"step",id:R(d),name:d.name,key:d.stepKey,state:"cached",startTs:d.ts,endTs:d.ts,durationMs:0};D(h);break}case"step_cache_miss":break;case"step_complete":break;case"step_timeout":{let b=R(d),h=f.get(b);h&&(h.timedOut=!0,h.timeoutMs=d.timeoutMs),I=Date.now();break}case"step_retry":{let b=R(d),h=f.get(b);h&&(h.retryCount=(d.attempt??1)-1),I=Date.now();break}case"step_retries_exhausted":I=Date.now();break;case"step_skipped":{let h={type:"step",id:R(d),name:d.name,key:d.stepKey,state:"skipped",startTs:d.ts,endTs:d.ts,durationMs:0};D(h);break}case"hook_should_run":{let b={type:"shouldRun",state:"success",ts:d.ts,durationMs:d.durationMs,context:{result:d.result,skipped:d.skipped}};v.shouldRun=b,x=d.workflowId,I=Date.now();break}case"hook_should_run_error":{let b={type:"shouldRun",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error};v.shouldRun=b,x=d.workflowId,I=Date.now();break}case"hook_before_start":{let b={type:"onBeforeStart",state:"success",ts:d.ts,durationMs:d.durationMs,context:{result:d.result,skipped:d.skipped}};v.onBeforeStart=b,x=d.workflowId,I=Date.now();break}case"hook_before_start_error":{let b={type:"onBeforeStart",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error};v.onBeforeStart=b,x=d.workflowId,I=Date.now();break}case"hook_after_step":{let b={type:"onAfterStep",state:"success",ts:d.ts,durationMs:d.durationMs,context:{stepKey:d.stepKey}};v.onAfterStep.set(d.stepKey,b),I=Date.now();break}case"hook_after_step_error":{let b={type:"onAfterStep",state:"error",ts:d.ts,durationMs:d.durationMs,error:d.error,context:{stepKey:d.stepKey}};v.onAfterStep.set(d.stepKey,b),I=Date.now();break}case"stream_created":{let b=`${d.workflowId}:${d.namespace}`;$.set(b,{id:Se(),namespace:d.namespace,startTs:d.ts,writeCount:0,readCount:0,streamState:"active",backpressureOccurred:!1,finalPosition:0}),I=Date.now();break}case"stream_write":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);h&&(h.writeCount++,h.finalPosition=Math.max(h.finalPosition,d.position)),I=Date.now();break}case"stream_read":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);h&&h.readCount++,I=Date.now();break}case"stream_close":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);if(h){h.streamState="closed",h.finalPosition=d.finalPosition;let A={type:"stream",id:h.id,namespace:h.namespace,state:"success",startTs:h.startTs,endTs:d.ts,durationMs:d.ts-h.startTs,writeCount:h.writeCount,readCount:h.readCount,finalPosition:d.finalPosition,streamState:"closed",backpressureOccurred:h.backpressureOccurred};D(A),$.delete(b)}I=Date.now();break}case"stream_error":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);if(h){h.streamState="error";let A={type:"stream",id:h.id,namespace:h.namespace,state:"error",error:d.error,startTs:h.startTs,endTs:d.ts,durationMs:d.ts-h.startTs,writeCount:h.writeCount,readCount:h.readCount,finalPosition:d.position,streamState:"error",backpressureOccurred:h.backpressureOccurred};D(A),$.delete(b)}I=Date.now();break}case"stream_backpressure":{let b=`${d.workflowId}:${d.namespace}`,h=$.get(b);h&&(h.backpressureOccurred=!0),I=Date.now();break}}E(d)}function P(d){if(d.type==="scope_start")y.push({id:d.scopeId,name:d.name,type:d.scopeType,startTs:d.ts,children:[]}),I=Date.now();else if(d.type==="scope_end"){let b=y.findIndex(C=>C.id===d.scopeId);if(b===-1)return;for(;y.length>b+1;){let C=y.pop(),J=C.type==="race"?{type:"race",id:C.id,name:C.name,state:_(C.children),startTs:C.startTs,endTs:d.ts,children:C.children}:{type:"parallel",id:C.id,name:C.name,state:_(C.children),startTs:C.startTs,endTs:d.ts,children:C.children,mode:C.type==="allSettled"?"allSettled":"all"};y[y.length-1].children.push(J)}let[h]=y.splice(b,1),A=h.type==="race"?{type:"race",id:h.id,name:h.name,state:_(h.children),startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,children:h.children,winnerId:d.winnerId}:{type:"parallel",id:h.id,name:h.name,state:_(h.children),startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,children:h.children,mode:h.type==="allSettled"?"allSettled":"all"};D(A)}}function K(d){if(d.type==="decision_start")k.push({id:d.decisionId,name:d.name,condition:d.condition,decisionValue:d.decisionValue,startTs:d.ts,branches:new Map,pendingChildren:[]}),I=Date.now();else if(d.type==="decision_branch"){let b=k.find(h=>h.id===d.decisionId);if(b){let h=d.branchLabel,A=b.branches.get(h);if(A)A.taken=d.taken,d.taken&&b.pendingChildren.length>0&&(A.children.unshift(...b.pendingChildren),b.pendingChildren=[]);else{let C=d.taken?[...b.pendingChildren]:[];d.taken&&(b.pendingChildren=[]),b.branches.set(h,{label:d.branchLabel,condition:d.condition,taken:d.taken,children:C})}I=Date.now()}}else if(d.type==="decision_end"){let b=k.findIndex(h=>h.id===d.decisionId);if(b!==-1){let[h]=k.splice(b,1),A=k.splice(b),C=Array.from(h.branches.values());C.length===0&&h.pendingChildren.length>0&&(C=[{label:"default",taken:!0,children:[...h.pendingChildren]}]);let J=C.find(ve=>ve.taken)?.label,Kt={type:"decision",id:h.id,name:h.name,state:_(C.flatMap(ve=>ve.taken?ve.children:[])),startTs:h.startTs,endTs:d.ts,durationMs:d.durationMs,condition:h.condition,decisionValue:h.decisionValue,branchTaken:d.branchTaken??J,branches:C};D(Kt),k.push(...A),I=Date.now()}}}function _(d){return d.length===0?"success":d.some(C=>C.state==="error")?"error":d.every(C=>C.state==="success"||C.state==="cached")?"success":d.some(C=>C.state==="running")?"running":"pending"}function ne(){let d=[...M];for(let[,b]of f)d.push({type:"step",id:b.id,name:b.name,key:b.key,state:"running",startTs:b.startTs,...b.retryCount>0&&{retryCount:b.retryCount},...b.timedOut&&{timedOut:!0,timeoutMs:b.timeoutMs}});for(let[,b]of $)d.push({type:"stream",id:b.id,namespace:b.namespace,state:"running",startTs:b.startTs,writeCount:b.writeCount,readCount:b.readCount,finalPosition:b.finalPosition,streamState:b.streamState,backpressureOccurred:b.backpressureOccurred});return d}function oe(){let d=ne();t&&(d=we(d,r));let b={type:"workflow",id:s??a,workflowId:s??a,state:l,startTs:u,endTs:c,durationMs:g,children:d,error:p},h=v.shouldRun!==void 0||v.onBeforeStart!==void 0||v.onAfterStep.size>0;return{root:b,metadata:{createdAt:N,lastUpdatedAt:I},...h&&{hooks:v}}}function ie(){s=void 0,u=void 0,c=void 0,l="pending",p=void 0,g=void 0,f.clear(),y.length=0,k.length=0,$.clear(),M=[],N=Date.now(),I=N,v={onAfterStep:new Map},x=void 0,m.length=0,w=0}function Ht(){return[...m]}function Ft(d){return m[d]}function zt(d){return m[d]?.ir}function Ut(){m.length=0,w=0}return{handleEvent:T,handleScopeEvent:P,handleDecisionEvent:K,getIR:oe,reset:ie,getSnapshots:Ht,getSnapshotAt:Ft,getIRAt:zt,clearSnapshots:Ut,get hasActiveSteps(){return f.size>0},get state(){return l},get snapshotCount(){return m.length},get snapshotsEnabled(){return n},setSnapshotsEnabled(d){n=d}}}var Ie=require("awaitly");function z(e){return e.type==="step"}function Pe(e){return e.type==="sequence"}function j(e){return e.type==="parallel"}function H(e){return e.type==="race"}function Y(e){return e.type==="decision"}function Q(e){return e.type==="stream"}function tr(e){return"children"in e||e.type==="decision"&&"branches"in e}var He="\x1B[0m",rr="\x1B[1m",rt="\x1B[2m",nr="\x1B[31m",or="\x1B[32m",ir="\x1B[33m",ar="\x1B[34m",tt="\x1B[90m",sr="\x1B[37m";function X(e,t){return t?`${t}${e}${He}`:e}function be(e){return`${rr}${e}${He}`}function O(e){return`${rt}${e}${He}`}var V={pending:sr,running:ir,success:or,error:nr,aborted:tt,cached:ar,skipped:rt+tt};function cr(e){switch(e){case"pending":return"\u25CB";case"running":return"\u27F3";case"success":return"\u2713";case"error":return"\u2717";case"aborted":return"\u2298";case"cached":return"\u21BA";case"skipped":return"\u2298"}}function ye(e,t){let r=cr(e);return X(r,t[e])}function Re(e,t,r){return X(e,r[t])}function ee(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}var S={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",teeRight:"\u251C",teeLeft:"\u2524",teeDown:"\u252C",teeUp:"\u2534",cross:"\u253C"},pe={cold:"\x1B[34m",cool:"\x1B[36m",neutral:"",warm:"\x1B[33m",hot:"\x1B[31m",critical:"\x1B[41m"},dr="\x1B[0m";function lr(e){return e<.2?pe.cold:e<.4?pe.cool:e<.6?pe.neutral:e<.8?pe.warm:e<.95?pe.hot:pe.critical}function nt(e,t){let r=lr(t);return r?`${r}${e}${dr}`:e}function ur(e){try{return(0,Ie.ok)(JSON.stringify(e,(r,o)=>{if(typeof o!="bigint")return o;let i=Number(o);return Number.isSafeInteger(i)?i:o.toString()}))}catch{return(0,Ie.err)("STRINGIFY_ERROR")}}function ot(e){let t=ur(e);return t.ok?t.value:"[unserializable]"}var it="\u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2588";function ze(e,t=10){if(e.length===0)return"";let r=e.slice(-t),o=Math.min(...r),n=Math.max(...r)-o||1;return r.map(a=>{let s=(a-o)/n,u=Math.floor(s*(it.length-1));return it[u]}).join("")}function Fe(e,t){let r=ee(e).length,o=Math.max(0,t-r);return e+" ".repeat(o)}function pr(e,t){if(!t)return S.horizontal.repeat(e);let r=` ${t} `,o=ee(r).length,i=e-o;if(i<4)return S.horizontal.repeat(e);let n=2,a=i-n;return S.horizontal.repeat(n)+r+S.horizontal.repeat(a)}function at(e,t,r){let o=e.state==="success"?X("\u2699",r.success):X("\u26A0",r.error),i=e.durationMs!==void 0?O(` [${B(e.durationMs)}]`):"",n="";e.type==="shouldRun"&&e.context?.skipped?n=O(" \u2192 workflow skipped"):e.type==="shouldRun"&&e.context?.result===!0?n=O(" \u2192 proceed"):e.type==="onBeforeStart"&&e.context?.skipped?n=O(" \u2192 workflow skipped"):e.type==="onAfterStep"&&e.context?.stepKey&&(n=O(` (${e.context.stepKey})`));let a=e.state==="error"&&e.error?O(` error: ${String(e.error)}`):"";return`${o} ${O(t)}${n}${i}${a}`}function fr(e,t){let r=[];return e.shouldRun&&r.push(at(e.shouldRun,"shouldRun",t)),e.onBeforeStart&&r.push(at(e.onBeforeStart,"onBeforeStart",t)),r.length>0&&r.push(O("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")),r}function ce(){return{name:"ascii",supportsLive:!0,render(e,t){let r={...V,...t.colors},o=Math.max(t.terminalWidth??60,5),i=o-4,n=[],a=e.root.name??"workflow",s=be(a);if(n.push(`${S.topLeft}${pr(o-2,s)}${S.topRight}`),n.push(`${S.vertical}${" ".repeat(o-2)}${S.vertical}`),e.hooks){let c=fr(e.hooks,r);for(let l of c)n.push(`${S.vertical} ${Fe(l,i)}${S.vertical}`)}let u=$e(e.root.children,t,r,0,e.hooks);for(let c of u)n.push(`${S.vertical} ${Fe(c,i)}${S.vertical}`);if(n.push(`${S.vertical}${" ".repeat(o-2)}${S.vertical}`),e.root.durationMs!==void 0&&t.showTimings){let c=e.root.state==="success"?"Completed":e.root.state==="aborted"?"Cancelled":"Failed",p=`${Re(c,e.root.state,r)} in ${B(e.root.durationMs)}`;n.push(`${S.vertical} ${Fe(p,i)}${S.vertical}`),n.push(`${S.vertical}${" ".repeat(o-2)}${S.vertical}`)}return n.push(`${S.bottomLeft}${S.horizontal.repeat(o-2)}${S.bottomRight}`),n.join(`
2
+ `)}}}function $e(e,t,r,o,i){let n=[];for(let a of e)z(a)?n.push(Ue(a,t,r,i)):j(a)?n.push(...hr(a,t,r,o,i)):H(a)?n.push(...gr(a,t,r,o,i)):Y(a)?n.push(...wr(a,t,r,o,i)):Q(a)&&n.push(mr(a,t,r));return n}function Ue(e,t,r,o){let i=ye(e.state,r),n=e.name??e.key??"step",a=t,s=a.showHeatmap&&a.heatmapData?a.heatmapData.heat.get(e.key??"")??a.heatmapData.heat.get(e.name??"")??a.heatmapData.heat.get(e.id):void 0,u;s!==void 0?u=nt(n,s):u=Re(n,e.state,r);let c=`${i} ${u}`;if(t.showKeys&&e.key&&e.name&&(c+=O(` [key: ${e.key}]`)),e.input!==void 0){let p=typeof e.input=="string"?e.input:ot(e.input).slice(0,30);c+=O(` [in: ${p}${p.length>=30?"...":""}]`)}if(e.output!==void 0&&e.state==="success"){let p=typeof e.output=="string"?e.output:ot(e.output).slice(0,30);c+=O(` [out: ${p}${p.length>=30?"...":""}]`)}if(t.showTimings&&e.durationMs!==void 0){let p=B(e.durationMs),g=s!==void 0?nt(`[${p}]`,s):O(`[${p}]`);c+=` ${g}`}if(a.showSparklines&&a.timingHistory){let p=a.timingHistory.get(e.key??"")??a.timingHistory.get(e.name??"")??a.timingHistory.get(e.id);p&&p.length>1&&(c+=` ${O(ze(p))}`)}if(e.retryCount!==void 0&&e.retryCount>0&&(c+=O(` [${e.retryCount} ${e.retryCount===1?"retry":"retries"}]`)),e.timedOut){let p=e.timeoutMs!==void 0?` ${e.timeoutMs}ms`:"";c+=O(` [timeout${p}]`)}let l=e.key??e.id;if(o&&l&&o.onAfterStep.has(l)){let p=o.onAfterStep.get(l),g=p.state==="success"?X("\u2699",r.success):X("\u26A0",r.error),f=p.durationMs!==void 0?O(` ${B(p.durationMs)}`):"";c+=` ${g}${f}`}return c}function mr(e,t,r){let o=e.streamState==="active"?X("\u27F3",r.running):e.streamState==="closed"?X("\u2713",r.success):X("\u2717",r.error),i=`stream:${e.namespace}`,n=Re(i,e.state,r),a=O(`[W:${e.writeCount} R:${e.readCount}]`),s=`${o} ${n} ${a}`;return t.showTimings&&e.durationMs!==void 0&&(s+=` ${O(`[${B(e.durationMs)}]`)}`),e.backpressureOccurred&&(s+=O(" [backpressure]")),e.streamState==="closed"&&(s+=O(` pos:${e.finalPosition}`)),s}function hr(e,t,r,o,i){let n=[],a=" ".repeat(o),s=ye(e.state,r),u=e.name??"parallel",c=e.mode==="allSettled"?" (allSettled)":"";if(n.push(`${a}${S.teeRight}${S.teeDown}${S.horizontal} ${s} ${be(u)}${c}`),e.children.length===0)n.push(`${a}${S.vertical} ${O("(operations not individually tracked)")}`),n.push(`${a}${S.vertical} ${O("(wrap each operation with step() to see individual steps)")}`);else for(let l=0;l<e.children.length;l++){let p=e.children[l],f=l===e.children.length-1?`${a}${S.vertical} ${S.bottomLeft}`:`${a}${S.vertical} ${S.teeRight}`;if(z(p))n.push(`${f} ${Ue(p,t,r,i)}`);else{let y=$e([p],t,r,o+1,i);for(let k of y)n.push(`${a}${S.vertical} ${k}`)}}return t.showTimings&&e.durationMs!==void 0&&n.push(`${a}${S.bottomLeft}${S.horizontal}${S.horizontal} ${O(`[${B(e.durationMs)}]`)}`),n}function gr(e,t,r,o,i){let n=[],a=" ".repeat(o),s=ye(e.state,r),u=e.name??"race";if(n.push(`${a}${S.teeRight}\u26A1 ${s} ${be(u)}`),e.children.length===0)n.push(`${a}${S.vertical} ${O("(operations not individually tracked)")}`),n.push(`${a}${S.vertical} ${O("(wrap each operation with step() to see individual steps)")}`);else for(let c=0;c<e.children.length;c++){let l=e.children[c],g=c===e.children.length-1?`${a}${S.vertical} ${S.bottomLeft}`:`${a}${S.vertical} ${S.teeRight}`,y=e.winnerId&&l.id===e.winnerId?O(" (winner)"):"";if(z(l))n.push(`${g} ${Ue(l,t,r,i)}${y}`);else{let k=$e([l],t,r,o+1,i);for(let $ of k)n.push(`${a}${S.vertical} ${$}`)}}return t.showTimings&&e.durationMs!==void 0&&n.push(`${a}${S.bottomLeft}${S.horizontal}${S.horizontal} ${O(`[${B(e.durationMs)}]`)}`),n}function wr(e,t,r,o,i){let n=[],a=" ".repeat(o),s=ye(e.state,r),u=e.name??"decision",c=e.condition?O(` (${e.condition})`):"",l=e.decisionValue!==void 0?O(` = ${String(e.decisionValue)}`):"",p=e.branchTaken!==void 0?O(` \u2192 ${String(e.branchTaken)}`):"";n.push(`${a}${S.teeRight}${S.teeDown}${S.horizontal} ${s} ${be(u)}${c}${l}${p}`);for(let g=0;g<e.branches.length;g++){let f=e.branches[g],k=g===e.branches.length-1?`${a}${S.vertical} ${S.bottomLeft}`:`${a}${S.vertical} ${S.teeRight}`,$=f.taken?"\u2713":"\u2298",M=f.taken?r.success:r.skipped,N=X(`${$} ${f.label}`,M),I=f.condition?O(` (${f.condition})`):"";if(n.push(`${k} ${N}${I}`),f.children.length>0){let v=$e(f.children,t,r,o+1,i);for(let x of v)n.push(`${a}${S.vertical} ${x}`)}else f.taken||n.push(`${a}${S.vertical} ${O("(skipped)")}`)}return t.showTimings&&e.durationMs!==void 0&&n.push(`${a}${S.bottomLeft}${S.horizontal}${S.horizontal} ${O(`[${B(e.durationMs)}]`)}`),n}var Te=require("awaitly");function Ke(e){let t=[];for(let r of e)if(t.push(r),"children"in r&&Array.isArray(r.children)&&t.push(...Ke(r.children)),"branches"in r)for(let o of r.branches)t.push(...Ke(o.children));return t}function Ee(e,t){if(e.length===0)return 0;let r=Math.floor(e.length*t);return e[Math.min(r,e.length-1)]}function fe(e){return e<.2?"cold":e<.4?"cool":e<.6?"neutral":e<.8?"warm":e<.95?"hot":"critical"}function st(){let e=new Map,t=new Map,r=new Map,o=new Map,i=[];function n(v){return v.stepKey??v.stepId??v.name??"unknown"}function a(v){let x=new Map;for(let m of v)switch(m.type){case"step_start":{let w=n(m);x.set(w,{retried:!1,timedOut:!1});break}case"step_retry":{let w=n(m),R=x.get(w);R&&(R.retried=!0);break}case"step_timeout":{let w=n(m),R=x.get(w);R&&(R.timedOut=!0);break}case"step_success":{let w=n(m),R=x.get(w),D=e.get(w)??[];D.push(m.durationMs),e.set(w,D);let E=t.get(w)??{retried:0,total:0};E.total++,R?.retried&&E.retried++,t.set(w,E);let T=o.get(w)??{timedOut:0,total:0};T.total++,R?.timedOut&&T.timedOut++,o.set(w,T);let P=r.get(w)??{errors:0,total:0};P.total++,r.set(w,P),x.delete(w);break}case"step_error":{let w=n(m),R=x.get(w),D=e.get(w)??[];D.push(m.durationMs),e.set(w,D);let E=t.get(w)??{retried:0,total:0};E.total++,R?.retried&&E.retried++,t.set(w,E);let T=o.get(w)??{timedOut:0,total:0};T.total++,R?.timedOut&&T.timedOut++,o.set(w,T);let P=r.get(w)??{errors:0,total:0};P.total++,P.errors++,r.set(w,P),x.delete(w);break}}}function s(v){a(v.events)}function u(v){i.push(v)}function c(v){i.length>0&&(a(i),i=[])}function l(v){let x=e.get(v);if(!x||x.length===0)return;let m=[...x].sort((K,_)=>K-_),R=m.reduce((K,_)=>K+_,0)/m.length,D=m.reduce((K,_)=>K+(_-R)**2,0)/m.length,E=t.get(v)??{retried:0,total:1},T=r.get(v)??{errors:0,total:1},P=o.get(v)??{timedOut:0,total:1};return{nodeId:v,avgDurationMs:R,minDurationMs:m[0],maxDurationMs:m[m.length-1],stdDevMs:Math.sqrt(D),samples:m.length,retryRate:E.total>0?E.retried/E.total:0,timeoutRate:P.total>0?P.timedOut/P.total:0,errorRate:T.total>0?T.errors/T.total:0,percentiles:{p50:Ee(m,.5),p90:Ee(m,.9),p95:Ee(m,.95),p99:Ee(m,.99)}}}function p(v){return l(v)}function g(v,x="duration"){let m=new Map,w=Ke(v.root.children),R=[];for(let _ of w){let ne=("key"in _?_.key:void 0)??_.id??_.name,oe=l(ne);if(oe){let ie;switch(x){case"duration":ie=oe.avgDurationMs;break;case"retryRate":ie=oe.retryRate;break;case"errorRate":ie=oe.errorRate;break}R.push({id:_.id,value:ie})}}if(R.length===0)return{heat:m,metric:x,stats:{min:0,max:0,mean:0,threshold:0}};let D=R.map(_=>_.value),E=Math.min(...D),T=Math.max(...D),P=D.reduce((_,ne)=>_+ne,0)/D.length,K=T-E||1;for(let{id:_,value:ne}of R)m.set(_,(ne-E)/K);return{heat:m,metric:x,stats:{min:E,max:T,mean:P,threshold:P+(T-P)*.5}}}function f(){let v=new Map;for(let x of e.keys()){let m=l(x);m&&v.set(x,m)}return v}function y(v=10){return[...f().values()].sort((m,w)=>w.avgDurationMs-m.avgDurationMs).slice(0,v)}function k(v=10){return[...f().values()].filter(m=>m.errorRate>0).sort((m,w)=>w.errorRate-m.errorRate).slice(0,v)}function $(v=10){return[...f().values()].filter(m=>m.retryRate>0).sort((m,w)=>w.retryRate-m.retryRate).slice(0,v)}function M(){return JSON.stringify({timingData:Object.fromEntries(e),retryData:Object.fromEntries(t),errorData:Object.fromEntries(r),timeoutData:Object.fromEntries(o)})}function N(v){let x=JSON.parse(v);e.clear(),t.clear(),r.clear(),o.clear();for(let[m,w]of Object.entries(x.timingData??{}))e.set(m,w);for(let[m,w]of Object.entries(x.retryData??{}))t.set(m,w);for(let[m,w]of Object.entries(x.errorData??{}))r.set(m,w);for(let[m,w]of Object.entries(x.timeoutData??{}))o.set(m,w)}function I(){e.clear(),t.clear(),r.clear(),o.clear(),i=[]}return{addRun:s,addEvent:u,finalizeRun:c,getNodePerformance:p,getHeatmap:g,getSlowestNodes:y,getErrorProneNodes:k,getRetryProneNodes:$,getAllPerformance:f,exportData:M,importData:N,clear:I}}function br(){return[" classDef pending fill:#f3f4f6,stroke:#9ca3af,stroke-width:2px,color:#374151"," classDef running fill:#fef3c7,stroke:#f59e0b,stroke-width:3px,color:#92400e"," classDef success fill:#d1fae5,stroke:#10b981,stroke-width:3px,color:#065f46"," classDef error fill:#fee2e2,stroke:#ef4444,stroke-width:3px,color:#991b1b"," classDef aborted fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#4b5563,stroke-dasharray: 5 5"," classDef cached fill:#dbeafe,stroke:#3b82f6,stroke-width:3px,color:#1e40af"," classDef skipped fill:#f9fafb,stroke:#d1d5db,stroke-width:2px,color:#6b7280,stroke-dasharray: 5 5"," classDef stream fill:#ede9fe,stroke:#8b5cf6,stroke-width:3px,color:#5b21b6"," classDef streamActive fill:#ddd6fe,stroke:#7c3aed,stroke-width:3px,color:#4c1d95"," classDef streamError fill:#fce7f3,stroke:#db2777,stroke-width:3px,color:#9d174d"]}function yr(){return[" classDef heat_cold fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e40af"," classDef heat_cool fill:#ccfbf1,stroke:#14b8a6,stroke-width:2px,color:#0f766e"," classDef heat_neutral fill:#f3f4f6,stroke:#6b7280,stroke-width:2px,color:#374151"," classDef heat_warm fill:#fef3c7,stroke:#f59e0b,stroke-width:2px,color:#92400e"," classDef heat_hot fill:#fed7aa,stroke:#f97316,stroke-width:3px,color:#c2410c"," classDef heat_critical fill:#fecaca,stroke:#ef4444,stroke-width:3px,color:#b91c1c"]}function kr(e){return`heat_${e}`}function vr(){return[" classDef hook_success fill:#e0f2fe,stroke:#0284c7,stroke-width:2px,color:#0c4a6e"," classDef hook_error fill:#fef2f2,stroke:#dc2626,stroke-width:2px,color:#7f1d1d"]}function xr(e){try{return(0,Te.ok)(JSON.stringify(e,(r,o)=>{if(typeof o!="bigint")return o;let i=Number(o);return Number.isSafeInteger(i)?i:o.toString()}))}catch{return(0,Te.err)("STRINGIFY_ERROR")}}function ct(e){let t=xr(e);return t.ok?t.value:"[unserializable]"}function Sr(e,t,r){let o;if(e.shouldRun){let i="hook_shouldRun",n=e.shouldRun.state==="success"?"hook_success":"hook_error",a=e.shouldRun.state==="success"?"\u2699":"\u26A0",s=r.showTimings&&e.shouldRun.durationMs!==void 0?` ${B(e.shouldRun.durationMs)}`:"",u=e.shouldRun.context?.skipped?"\\nskipped workflow":e.shouldRun.context?.result===!0?"\\nproceed":"";t.push(` ${i}[["${a} shouldRun${u}${s}"]]:::${n}`),o=i}if(e.onBeforeStart){let i="hook_beforeStart",n=e.onBeforeStart.state==="success"?"hook_success":"hook_error",a=e.onBeforeStart.state==="success"?"\u2699":"\u26A0",s=r.showTimings&&e.onBeforeStart.durationMs!==void 0?` ${B(e.onBeforeStart.durationMs)}`:"",u=e.onBeforeStart.context?.skipped?"\\nskipped workflow":"";t.push(` ${i}[["${a} onBeforeStart${u}${s}"]]:::${n}`),o&&t.push(` ${o} --> ${i}`),o=i}return{lastHookId:o}}var dt=0,Ne=new Set,Me=new Set;function me(e="node"){return`${e}_${++dt}`}function Rr(){dt=0,Ne.clear(),Me.clear()}function U(e){return e.replace(/"/g,"#quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;").trim()}function lt(e){return U(e).replace(/[{}[\]()]/g,"")}function te(){return{name:"mermaid",supportsLive:!1,render(e,t){Rr();let r=[],o=t;r.push("flowchart TD");let i;e.hooks&&(i=Sr(e.hooks,r,t).lastHookId);let n="start";r.push(` ${n}(("\u25B6 Start"))`),i&&r.push(` ${i} --> ${n}`);let a=n;for(let u of e.root.children){let c=Oe(u,t,r,o,e.hooks);r.push(` ${a} --> ${c.entryId}`),a=c.exitId}if(["success","error","aborted"].includes(e.root.state)){let u="finish",c=e.root.state==="success"?"\u2713":e.root.state==="error"?"\u2717":"\u2298",l=e.root.state==="success"?"Done":e.root.state==="error"?"Failed":"Cancelled",p=`(("${c} ${l}"))`,g=e.root.state==="success"?":::success":e.root.state==="error"?":::error":":::aborted";r.push(` ${u}${p}${g}`),r.push(` ${a} --> ${u}`)}return r.push(""),r.push(...br()),o.showHeatmap&&r.push(...yr()),e.hooks&&r.push(...vr()),r.join(`
3
+ `)}}}function Oe(e,t,r,o,i){if(z(e))return Ir(e,t,r,o,i);if(j(e))return $r(e,t,r,o,i);if(H(e))return Er(e,t,r,o,i);if(Y(e))return Nr(e,t,r,o,i);if(Q(e))return Mr(e,t,r);let n=me("unknown");return r.push(` ${n}["Unknown Node"]`),{entryId:n,exitId:n}}function Ir(e,t,r,o,i){let n=t,a=n.showRetryEdges??!0,s=n.showErrorEdges??!0,u=n.showTimeoutEdges??!0,c=e.key?`step_${e.key.replace(/[^a-zA-Z0-9]/g,"_")}`:me("step");if(Me.has(c)){let m=2;for(;Me.has(`${c}_${m}`);)m++;c=`${c}_${m}`}Me.add(c);let l=e.name??e.key??"Step",p=t.showKeys&&e.key&&e.name?`${l} [${e.key}]`:l,g=U(p),f=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"",y="";switch(e.state){case"success":y="\u2713 ";break;case"error":y="\u2717 ";break;case"cached":y="\u{1F4BE} ";break;case"running":y="\u23F3 ";break;case"skipped":y="\u2298 ";break}let k="";if(e.input!==void 0){let m=typeof e.input=="string"?U(e.input):U(ct(e.input).slice(0,20));k+=`\\nin: ${m}`}if(e.output!==void 0&&e.state==="success"){let m=typeof e.output=="string"?U(e.output):U(ct(e.output).slice(0,20));k+=`\\nout: ${m}`}let $="",M=e.key??e.id;if(i&&M&&i.onAfterStep.has(M)){let m=i.onAfterStep.get(M),w=m.state==="success"?"\u2699":"\u26A0",R=t.showTimings&&m.durationMs!==void 0?` ${B(m.durationMs)}`:"";$=`\\n${w} hook${R}`}let N=(y+g+k+$+f).trim(),I,v=o?.showHeatmap&&o.heatmapData?o.heatmapData.heat.get(e.key??"")??o.heatmapData.heat.get(e.name??"")??o.heatmapData.heat.get(e.id):void 0;if(v!==void 0){let m=fe(v);I=kr(m)}else I=e.state;let x;switch(e.state){case"error":x=`{{"${N}"}}`;break;case"cached":x=`[("${N}")]`;break;case"skipped":x=`["${N}"]`;break;default:x=`["${N}"]`}if(r.push(` ${c}${x}:::${I}`),a&&e.retryCount!==void 0&&e.retryCount>0){let m=`\u21BB ${e.retryCount} retr${e.retryCount===1?"y":"ies"}`;r.push(` ${c} -.->|"${m}"| ${c}`)}if(s&&e.state==="error"&&e.error!==void 0){let m=`ERR_${c}`,w=U(String(e.error)).slice(0,30);r.push(` ${m}{{"${w}"}}`),r.push(` ${c} -->|error| ${m}`),r.push(` style ${m} fill:#fee2e2,stroke:#dc2626`)}if(u&&e.timedOut){let m=`TO_${c}`,w=e.timeoutMs!==void 0?`${e.timeoutMs}ms`:"";r.push(` ${m}{{"\u23F1 Timeout ${w}"}}`),r.push(` ${c} -.->|timeout| ${m}`),r.push(` style ${m} fill:#fef3c7,stroke:#f59e0b`)}return{entryId:c,exitId:c}}function $r(e,t,r,o,i){let n=me("parallel"),a=`${n}_fork`,s=`${n}_join`,u=lt(e.name??"Parallel"),c=e.mode==="allSettled"?" (allSettled)":"";if(e.children.length===0){let g=n,f=U(`${u}${c}`),y="operations not individually tracked",k=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"";return r.push(` ${g}["${f}${k}\\n${y}"]:::${e.state}`),{entryId:g,exitId:g}}r.push(` subgraph ${n}["${u}${c}"]`),r.push(" direction TB"),r.push(` ${a}{"\u26A1 Fork"}`);let l=[];for(let g of e.children){let f=Oe(g,t,r,o,i);r.push(` ${a} --> ${f.entryId}`),l.push(f.exitId)}r.push(` ${s}{"\u2713 Join"}`);for(let g of l)r.push(` ${g} --> ${s}`);r.push(" end");let p=e.state;return r.push(` class ${n} ${p}`),{entryId:a,exitId:s}}function Er(e,t,r,o,i){let n=me("race"),a=`${n}_start`,s=`${n}_end`,u=lt(e.name??"Race");if(e.children.length===0){let g=n,f=U(u),y="operations not individually tracked",k=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"";return r.push(` ${g}["\u26A1 ${f}${k}\\n${y}"]:::${e.state}`),{entryId:g,exitId:g}}r.push(` subgraph ${n}["\u26A1 ${u}"]`),r.push(" direction TB"),r.push(` ${a}(("\u{1F3C1} Start"))`);let c=[],l;for(let g of e.children){let f=Oe(g,t,r,o,i),y=e.winnerId===g.id;r.push(` ${a} --> ${f.entryId}`),y&&(l=f.exitId),c.push({exitId:f.exitId,isWinner:y})}r.push(` ${s}(("\u2713 First"))`);for(let{exitId:g,isWinner:f}of c)f&&l?r.push(` ${g} ==>|\u{1F3C6} Winner| ${s}`):e.winnerId?r.push(` ${g} -. cancelled .-> ${s}`):r.push(` ${g} --> ${s}`);r.push(" end");let p=e.state;return r.push(` class ${n} ${p}`),{entryId:a,exitId:s}}function Nr(e,t,r,o,i){let n=e.key?`decision_${e.key.replace(/[^a-zA-Z0-9]/g,"_")}`:me("decision");if(Ne.has(n)){let g=2;for(;Ne.has(`${n}_${g}`);)g++;n=`${n}_${g}`}Ne.add(n);let a=U(e.condition??"condition"),s=e.decisionValue!==void 0?` = ${U(String(e.decisionValue)).slice(0,30)}`:"",u=`${a}${s}`.trim();r.push(` ${n}{"${u}"}`);let c=[],l,p=new Set;for(let g of e.branches){let f=`${n}_${g.label.replace(/[^a-zA-Z0-9]/g,"_")}`;if(p.has(f)){let N=2;for(;p.has(`${f}_${N}`);)N++;f=`${f}_${N}`}p.add(f);let y=U(g.label),k=g.taken?`${y} \u2713`:`${y} skipped`,$=g.taken?":::success":":::skipped";r.push(` ${f}["${k}"]${$}`);let M=g.condition?`|${U(g.condition).replace(/\|/g,"")}|`:"";if(r.push(` ${n} -->${M} ${f}`),g.children.length>0){let N=f;for(let I of g.children){let v=Oe(I,t,r,o,i);r.push(` ${N} --> ${v.entryId}`),N=v.exitId}c.push(N),g.taken&&(l=N)}else c.push(f),g.taken&&(l=f)}return l?{entryId:n,exitId:l}:{entryId:n,exitId:n}}function Mr(e,t,r){let o=`stream_${e.namespace.replace(/[^a-zA-Z0-9]/g,"_")}_${me("")}`,i=`W:${e.writeCount} R:${e.readCount}`,n="";switch(e.streamState){case"active":n="\u27F3 ";break;case"closed":n="\u2713 ";break;case"error":n="\u2717 ";break}let a=t.showTimings&&e.durationMs!==void 0?` ${B(e.durationMs)}`:"",s=e.backpressureOccurred?"\\nbackpressure":"",u=`${n}stream:${U(e.namespace)}\\n${i}${s}${a}`,c;return e.streamState==="error"?c="streamError":e.streamState==="active"?c="streamActive":c="stream",r.push(` ${o}{{"${u}"}}:::${c}`),{entryId:o,exitId:o}}var L={topLeft:"\u250C",topRight:"\u2510",bottomLeft:"\u2514",bottomRight:"\u2518",horizontal:"\u2500",vertical:"\u2502",teeDown:"\u252C",teeUp:"\u2534",teeRight:"\u251C",teeLeft:"\u2524",cross:"\u253C",arrowDown:"\u25BC",arrowUp:"\u25B2"},Tr={cold:"\x1B[34m",cool:"\x1B[36m",neutral:"",warm:"\x1B[33m",hot:"\x1B[31m",critical:"\x1B[41m"},Or="\x1B[0m";function Dr(e,t){let r=[],o=[];for(let i=0;i<t;i++)r.push(Array(e).fill(" ")),o.push(Array(e).fill(void 0));return{cells:r,colors:o,width:e,height:t}}function W(e,t,r,o,i){t>=0&&t<e.width&&r>=0&&r<e.height&&(e.cells[r][t]=o,i&&(e.colors[r][t]=i))}function ft(e,t,r){return t>=0&&t<e.width&&r>=0&&r<e.height?e.cells[r][t]:" "}function Cr(e,t,r,o,i){W(e,t,r,L.topLeft);for(let n=1;n<o-1;n++)W(e,t+n,r,L.horizontal);W(e,t+o-1,r,L.topRight);for(let n=1;n<i-1;n++)W(e,t,r+n,L.vertical),W(e,t+o-1,r+n,L.vertical);W(e,t,r+i-1,L.bottomLeft);for(let n=1;n<o-1;n++)W(e,t+n,r+i-1,L.horizontal);W(e,t+o-1,r+i-1,L.bottomRight)}function ut(e,t,r,o,i){let n=ee(o).split("");for(let a=0;a<n.length;a++)W(e,t+a,r,n[a],i)}function re(e,t,r,o){let i=Math.min(r,o),n=Math.max(r,o);for(let a=i;a<=n;a++){let s=ft(e,t,a);s===L.horizontal?W(e,t,a,L.cross):(s===" "||s===L.vertical)&&W(e,t,a,L.vertical)}}function pt(e,t,r,o){let i=Math.min(r,o),n=Math.max(r,o);for(let a=i;a<=n;a++){let s=ft(e,a,t);s===L.vertical?W(e,a,t,L.cross):(s===" "||s===L.horizontal)&&W(e,a,t,L.horizontal)}}function de(e,t,r){W(e,t,r,L.arrowDown)}function Lr(e){let t=[];for(let r=0;r<e.height;r++){let o="";for(let i=0;i<e.width;i++){let n=e.colors[r][i],a=e.cells[r][i];n?o+=n+a+Or:o+=a}t.push(o.trimEnd())}for(;t.length>0&&t[t.length-1]==="";)t.pop();return t.join(`
4
+ `)}var q=11,Z=2,he=2,De=3;function Ve(e,t){if(e.length<=t)return[e];let r=e.split(" "),o=[],i="";for(let n of r)i?i.length+1+n.length<=t?i+=" "+n:(o.push(i),i=n):i=n;if(i&&o.push(i),o.length===0)for(let n=0;n<e.length;n+=t)o.push(e.slice(n,n+t));return o}function mt(e){switch(e){case"success":return"\u2713";case"error":return"\u2717";case"running":return"\u27F3";case"pending":return"\u25CB";case"aborted":case"skipped":return"\u2298";case"cached":return"\u21BA";default:return"\u25CB"}}function _r(e,t,r){let o=t.showStartEnd??!0,i=t,n=Math.floor(r/2),a=[],s=0;if(o){let c=Ce("start","start",["\u25B6 Start"],"success",n,s);a.push(c),s=c.bottomY+he}for(let c of e.root.children){let l=Le(c,n,s,r-4,t,i);a.push(l.node),s=l.bottomY+he}if(o&&["success","error","aborted"].includes(e.root.state)){let c=e.root.state==="success"?"\u2713 Done":e.root.state==="error"?"\u2717 Failed":"\u2298 Cancelled",l=Ce("end","end",[c],e.root.state,n,s);a.push(l),s=l.bottomY}return{nodes:a,totalHeight:s+2}}function Ce(e,t,r,o,i,n){let a=Math.max(...r.map(l=>ee(l).length)),s=Math.max(q,a+Z*2),u=r.length+2,c=i-Math.floor(s/2);return{id:e,type:t,label:r,state:o,x:c,y:n,width:s,height:u,centerX:i,bottomY:n+u-1}}function Le(e,t,r,o,i,n){if(z(e))return Wr(e,t,r,o,i,n);if(j(e)||H(e))return Ar(e,t,r,o,i,n);if(Y(e))return Pr(e,t,r,o,i,n);if(Q(e))return Br(e,t,r,o,i,n);let a=Ce(e.id,"step",["?"],e.state,t,r);return{node:a,bottomY:a.bottomY}}function Wr(e,t,r,o,i,n){let a=e.name??e.key??"step",s=mt(e.state),u=[],c=`${s} ${a}`;i.showKeys&&e.key&&e.name&&(c+=` [${e.key}]`);let l=Math.min(o-Z*2,40);if(u.push(...Ve(c,l)),i.showTimings&&e.durationMs!==void 0&&u.push(`[${B(e.durationMs)}]`),e.retryCount&&e.retryCount>0&&u.push(`${e.retryCount}x retry`),e.timedOut&&u.push("timeout"),n?.showSparklines&&n.timingHistory){let M=n.timingHistory.get(e.key??"")??n.timingHistory.get(e.name??"")??n.timingHistory.get(e.id);M&&M.length>1&&u.push(ze(M,8))}let p=Math.max(...u.map(M=>ee(M).length)),g=Math.max(q,p+Z*2),f=u.length+2,y=t-Math.floor(g/2),k;if(n?.showHeatmap&&n.heatmapData){let M=e.key??e.name??e.id;k=n.heatmapData.heat.get(e.id)??n.heatmapData.heat.get(M)}let $={id:e.id,type:"step",label:u,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:r+f-1,metadata:k!==void 0?{heat:k}:void 0};return{node:$,bottomY:$.bottomY}}function Br(e,t,r,o,i,n){let a=`stream:${e.namespace}`,s=e.streamState==="active"?"\u27F3":e.streamState==="closed"?"\u2713":"\u2717",u=[],c=`${s} ${a}`,l=Math.min(o-Z*2,40);u.push(...Ve(c,l)),u.push(`W:${e.writeCount} R:${e.readCount}`),i.showTimings&&e.durationMs!==void 0&&u.push(`[${B(e.durationMs)}]`),e.backpressureOccurred&&u.push("backpressure");let p=Math.max(...u.map($=>ee($).length)),g=Math.max(q,p+Z*2),f=u.length+2,y=t-Math.floor(g/2),k={id:e.id,type:"stream",label:u,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:r+f-1,metadata:{streamState:e.streamState,backpressureOccurred:e.backpressureOccurred}};return{node:k,bottomY:k.bottomY}}function Ar(e,t,r,o,i,n){let a=H(e),s=e.name??(a?"race":"parallel"),c=`${a?"\u26A1":"\u2AD8"} ${s}`;if(e.children.length===0){let w=[c,"(not tracked)"],R=Ce(e.id,a?"race":"parallel",w,e.state,t,r);return{node:R,bottomY:R.bottomY}}let l=Math.floor((o-De*(e.children.length-1))/e.children.length),p=[];for(let w of e.children){let R=je(w,Math.max(l,q),i,n);p.push(R.width)}let g=p.reduce((w,R)=>w+R,0)+De*(e.children.length-1),f=g>o&&e.children.length>1,y=Math.max(q,c.length+Z*2),k=3,$=t-Math.floor(y/2),M=r;M+=k,M+=1,M+=1;let N=[];if(f)for(let w=0;w<e.children.length;w++){let R=e.children[w],D=Le(R,t,M,o,i,n);a&&H(e)&&e.winnerId===R.id&&(D.node.metadata={...D.node.metadata,isWinner:!0}),N.push(D.node),M=D.bottomY+he}else{let w=t-Math.floor(g/2);for(let R=0;R<e.children.length;R++){let D=e.children[R],E=w+Math.floor(p[R]/2),T=Le(D,E,M,p[R],i,n);a&&H(e)&&e.winnerId===D.id&&(T.node.metadata={...T.node.metadata,isWinner:!0}),N.push(T.node),w+=p[R]+De}}let I=Math.max(...N.map(w=>w.bottomY)),x=!f&&N.length>1?I+2:I;return{node:{id:e.id,type:a?"race":"parallel",label:[c],state:e.state,x:$,y:r,width:y,height:k,centerX:t,bottomY:x,children:N,metadata:{verticalLayout:f}},bottomY:x}}function Pr(e,t,r,o,i,n){let a=e.name??"decision",s=e.condition?` (${e.condition.slice(0,20)})`:"",u=`\u25C7 ${a}${s}`,c=Math.min(o-Z*2,40),l=Ve(u,c),p=Math.max(...l.map(x=>ee(x).length)),g=Math.max(q,p+Z*2),f=l.length+2,y=t-Math.floor(g/2),k=e.branches.find(x=>x.taken),$=k&&k.children.length>0?k:e.branches.find(x=>x.children.length>0);if(!$||$.children.length===0){let x={id:e.id,type:"decision",label:l,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:r+f-1};return{node:x,bottomY:x.bottomY}}let M=r+f+he,N=[];for(let x of $.children){let m=Le(x,t,M,o,i,n);N.push(m.node),M=m.bottomY+he}let I=N.length>0?N[N.length-1].bottomY:r+f-1;return{node:{id:e.id,type:"decision",label:l,state:e.state,x:y,y:r,width:g,height:f,centerX:t,bottomY:I,children:N},bottomY:I}}function je(e,t,r,o){if(z(e)){let i=e.name??e.key??"step",n=mt(e.state),a=1;r.showTimings&&e.durationMs!==void 0&&a++,e.retryCount&&e.retryCount>0&&a++,e.timedOut&&a++,o?.showSparklines&&(o.timingHistory?.has(e.key??"")||o.timingHistory?.has(e.name??"")||o.timingHistory?.has(e.id))&&a++;let s=`${n} ${i}`;r.showKeys&&e.key&&e.name&&(s+=` [${e.key}]`);let u=Math.min(t,Math.max(q,s.length+Z*2)),c=a+2;return{width:u,height:c}}if(j(e)||H(e)){if(e.children.length===0)return{width:q+4,height:4};let i=Math.floor(t/e.children.length),n=0,a=0;for(let s of e.children){let u=je(s,i,r,o);n+=u.width,a=Math.max(a,u.height)}return n+=De*(e.children.length-1),{width:Math.max(n,q),height:5+a+2}}if(Y(e)){let i=e.branches.find(a=>a.taken),n=0;if(i)for(let a of i.children){let s=je(a,t,r,o);n+=s.height+he}return{width:Math.min(t,30),height:3+n}}if(Q(e)){let i=`stream:${e.namespace}`,n=2;r.showTimings&&e.durationMs!==void 0&&n++,e.backpressureOccurred&&n++;let a=Math.min(t,Math.max(q,i.length+Z*2+4)),s=n+2;return{width:a,height:s}}return{width:q,height:3}}function Hr(e,t,r){let o={...V,...r.colors};for(let i=0;i<t.length;i++){let n=t[i],a=i===t.length-1;if(_e(e,n,o),!a){let s=t[i+1],u=n.centerX,c=n.bottomY+1,l=s.centerX,p=s.y-1;re(e,u,c,p-1),de(e,l,p)}}}function _e(e,t,r){let o=t.type!=="start",i=t.type!=="end"&&(!t.children||t.children.length===0);Cr(e,t.x,t.y,t.width,t.height),o&&W(e,t.centerX,t.y,L.teeUp),(i||t.children&&t.children.length>0)&&W(e,t.centerX,t.y+t.height-1,L.teeDown);let n=t.width-Z*2,a=Kr(t,r);for(let s=0;s<t.label.length;s++){let u=t.label[s],c=t.x+1+Math.floor((n-ee(u).length)/2),l=t.y+1+s;ut(e,c,l,u,a)}t.metadata?.isWinner&&ut(e,t.x+t.width-2,t.y,"\u{1F3C6}"),t.children&&t.children.length>0&&(t.type==="parallel"||t.type==="race"?Fr(e,t,r):zr(e,t,r))}function Fr(e,t,r){let o=t.children;if(o.length===0)return;let i=t.y+t.height,n=t.centerX;if(t.metadata?.verticalLayout===!0){let s=o[0];re(e,n,i,s.y-2),de(e,s.centerX,s.y-1);for(let u=0;u<o.length;u++){let c=o[u];if(_e(e,c,r),u<o.length-1){let l=o[u+1];re(e,c.centerX,c.bottomY+1,l.y-2),de(e,l.centerX,l.y-1)}}return}if(o.length===1)re(e,n,i,o[0].y-2),de(e,o[0].centerX,o[0].y-1);else{let s=o.map(l=>l.centerX),u=Math.min(...s),c=Math.max(...s);re(e,n,i,i+1),pt(e,i+1,u,c),W(e,n,i+1,L.teeUp);for(let l of o){let p=l.centerX;p===u?W(e,p,i+1,L.topLeft):p===c?W(e,p,i+1,L.topRight):p!==n&&W(e,p,i+1,L.teeDown),re(e,p,i+2,l.y-2),de(e,p,l.y-1)}}for(let s of o)_e(e,s,r);if(o.length>1){let s=o.map(f=>f.bottomY),u=Math.max(...s),c=u+1,l=o.map(f=>f.centerX),p=Math.min(...l),g=Math.max(...l);for(let f of o)f.bottomY<u&&re(e,f.centerX,f.bottomY+1,c-1);pt(e,c,p,g);for(let f of o){let y=f.centerX;y===p?W(e,y,c,L.bottomLeft):y===g?W(e,y,c,L.bottomRight):W(e,y,c,L.teeUp)}W(e,t.centerX,c,L.teeDown),W(e,t.centerX,c+1,L.vertical)}}function zr(e,t,r){let o=t.children;if(o.length===0)return;let i=t.y+t.height,n=o[0];re(e,t.centerX,i,n.y-2),de(e,n.centerX,n.y-1);for(let a=0;a<o.length;a++){let s=o[a];if(_e(e,s,r),a<o.length-1){let u=o[a+1];re(e,s.centerX,s.bottomY+1,u.y-2),de(e,u.centerX,u.y-1)}}}var Ur={active:"\x1B[36m",closed:"\x1B[32m",error:"\x1B[31m"};function Kr(e,t){if(e.metadata?.heat!==void 0){let r=fe(e.metadata.heat);return Tr[r]||void 0}return e.type==="stream"&&e.metadata?.streamState?Ur[e.metadata.streamState]||void 0:t[e.state]||void 0}function le(){return{name:"flowchart",supportsLive:!1,render(e,t){let r=t.terminalWidth??80,{nodes:o,totalHeight:i}=_r(e,t,r),n=Dr(r,i);return Hr(n,o,t),Lr(n)}}}function jr(e){return e.replace(/\x1b\[[0-9;]*m/g,"")}function Vr(e){let t=[];function r(o){for(let i of o)if(z(i))t.push(i);else if(Pe(i))r(i.children);else if(j(i)||H(i))r(i.children);else if(Y(i))for(let n of i.branches)n.taken&&r(n.children)}return r(e),t}function Gr(e){let t={id:e.id,name:e.name??e.key??e.id,state:e.state};return e.key&&(t.key=e.key),e.durationMs!==void 0&&(t.durationMs=e.durationMs),e.startTs!==void 0&&(t.startTs=e.startTs),e.endTs!==void 0&&(t.endTs=e.endTs),e.retryCount!==void 0&&e.retryCount>0&&(t.retryCount=e.retryCount),e.timedOut&&(t.timedOut=!0,e.timeoutMs!==void 0&&(t.timeoutMs=e.timeoutMs)),e.error!==void 0&&(t.error=typeof e.error=="string"?e.error:String(e.error)),t}function Yr(e){let t=0,r=0,o=0,i=0,n=0,a;for(let s of e)s.state==="success"&&t++,s.state==="error"&&r++,s.state==="cached"&&o++,s.state==="skipped"&&i++,s.retryCount!==void 0&&(n+=s.retryCount),s.durationMs!==void 0&&(!a||s.durationMs>a.durationMs)&&(a={name:s.name??s.key??s.id,durationMs:s.durationMs});return{totalSteps:e.length,successCount:t,errorCount:r,cacheHits:o,skippedCount:i,totalRetries:n,slowestStep:a}}function Jr(e){let t={};if(e.shouldRun&&(t.shouldRun={result:e.shouldRun.context?.result,durationMs:e.shouldRun.durationMs},e.shouldRun.error!==void 0&&e.shouldRun.error!==null&&(t.shouldRun.error=String(e.shouldRun.error))),e.onBeforeStart&&(t.onBeforeStart={durationMs:e.onBeforeStart.durationMs},e.onBeforeStart.error!==void 0&&e.onBeforeStart.error!==null&&(t.onBeforeStart.error=String(e.onBeforeStart.error))),e.onAfterStep.size>0){t.onAfterStep=[];for(let[r,o]of e.onAfterStep){let i={stepKey:r};o.durationMs!==void 0&&(i.durationMs=o.durationMs),o.error!==void 0&&o.error!==null&&(i.error=String(o.error)),t.onAfterStep.push(i)}}return t}function Xr(e,t){let r=e.root,o=Vr(r.children),i=t.includeDiagram??!0,n=t.stripAnsiColors??!0,a={workflow:{id:r.workflowId,name:r.name,state:r.state,durationMs:r.durationMs,startedAt:r.startTs,completedAt:r.endTs},steps:o.map(Gr),summary:Yr(o)};if(e.hooks){let s=Jr(e.hooks);Object.keys(s).length>0&&(a.hooks=s)}if(i){let c=((t.diagramFormat??"ascii")==="flowchart"?le():ce()).render(e,t);n&&(c=jr(c)),a.diagram=c}return a}function ke(){return{name:"logger",supportsLive:!1,render(e,t){let o=Xr(e,t);return JSON.stringify(o)}}}function ht(e){let t={bg:"#ffffff",bgSecondary:"#f8f9fa",text:"#212529",textMuted:"#6c757d",border:"#dee2e6",primary:"#0d6efd",success:"#198754",error:"#dc3545",warning:"#ffc107",info:"#0dcaf0",muted:"#6c757d",nodePending:"#e9ecef",nodeRunning:"#fff3cd",nodeSuccess:"#d1e7dd",nodeError:"#f8d7da",nodeAborted:"#e9ecef",nodeCached:"#cfe2ff",nodeSkipped:"#f8f9fa",heatCold:"#0d6efd",heatCool:"#0dcaf0",heatNeutral:"#6c757d",heatWarm:"#ffc107",heatHot:"#fd7e14",heatCritical:"#dc3545"},r={bg:"#212529",bgSecondary:"#343a40",text:"#f8f9fa",textMuted:"#adb5bd",border:"#495057",primary:"#0d6efd",success:"#198754",error:"#dc3545",warning:"#ffc107",info:"#0dcaf0",muted:"#6c757d",nodePending:"#495057",nodeRunning:"#664d03",nodeSuccess:"#0f5132",nodeError:"#842029",nodeAborted:"#495057",nodeCached:"#084298",nodeSkipped:"#343a40",heatCold:"#0d6efd",heatCool:"#0dcaf0",heatNeutral:"#6c757d",heatWarm:"#ffc107",heatHot:"#fd7e14",heatCritical:"#dc3545"},o=n=>`
5
+ --bg: ${n.bg};
6
+ --bg-secondary: ${n.bgSecondary};
7
+ --text: ${n.text};
8
+ --text-muted: ${n.textMuted};
9
+ --border: ${n.border};
10
+ --primary: ${n.primary};
11
+ --success: ${n.success};
12
+ --error: ${n.error};
13
+ --warning: ${n.warning};
14
+ --info: ${n.info};
15
+ --muted: ${n.muted};
16
+ --node-pending: ${n.nodePending};
17
+ --node-running: ${n.nodeRunning};
18
+ --node-success: ${n.nodeSuccess};
19
+ --node-error: ${n.nodeError};
20
+ --node-aborted: ${n.nodeAborted};
21
+ --node-cached: ${n.nodeCached};
22
+ --node-skipped: ${n.nodeSkipped};
23
+ --heat-cold: ${n.heatCold};
24
+ --heat-cool: ${n.heatCool};
25
+ --heat-neutral: ${n.heatNeutral};
26
+ --heat-warm: ${n.heatWarm};
27
+ --heat-hot: ${n.heatHot};
28
+ --heat-critical: ${n.heatCritical};
29
+ `,i;return e==="auto"?i=`
30
+ :root {
31
+ ${o(t)}
32
+ }
33
+ @media (prefers-color-scheme: dark) {
34
+ :root {
35
+ ${o(r)}
36
+ }
37
+ }
38
+ `:e==="dark"?i=`
39
+ :root {
40
+ ${o(r)}
41
+ }
42
+ `:i=`
43
+ :root {
44
+ ${o(t)}
45
+ }
46
+ `,`
47
+ ${i}
48
+
49
+ * {
50
+ box-sizing: border-box;
51
+ margin: 0;
52
+ padding: 0;
53
+ }
54
+
55
+ body {
56
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
57
+ background-color: var(--bg);
58
+ color: var(--text);
59
+ line-height: 1.5;
60
+ }
61
+
62
+ .workflow-visualizer {
63
+ display: flex;
64
+ flex-direction: column;
65
+ height: 100vh;
66
+ overflow: hidden;
67
+ }
68
+
69
+ /* Header */
70
+ .wv-header {
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: space-between;
74
+ padding: 12px 20px;
75
+ background-color: var(--bg-secondary);
76
+ border-bottom: 1px solid var(--border);
77
+ }
78
+
79
+ .wv-header h1 {
80
+ font-size: 1.25rem;
81
+ font-weight: 600;
82
+ }
83
+
84
+ .wv-controls {
85
+ display: flex;
86
+ gap: 8px;
87
+ align-items: center;
88
+ }
89
+
90
+ .wv-btn {
91
+ display: inline-flex;
92
+ align-items: center;
93
+ justify-content: center;
94
+ padding: 6px 12px;
95
+ font-size: 0.875rem;
96
+ font-weight: 500;
97
+ border: 1px solid var(--border);
98
+ border-radius: 6px;
99
+ background-color: var(--bg);
100
+ color: var(--text);
101
+ cursor: pointer;
102
+ transition: all 0.15s ease;
103
+ }
104
+
105
+ .wv-btn:hover {
106
+ background-color: var(--bg-secondary);
107
+ }
108
+
109
+ .wv-btn:disabled {
110
+ opacity: 0.5;
111
+ cursor: not-allowed;
112
+ background-color: var(--bg-secondary);
113
+ color: var(--text-muted);
114
+ }
115
+
116
+ .wv-btn--primary {
117
+ background-color: var(--primary);
118
+ border-color: var(--primary);
119
+ color: white;
120
+ }
121
+
122
+ .wv-btn--primary:hover {
123
+ opacity: 0.9;
124
+ }
125
+
126
+ .wv-btn--icon {
127
+ padding: 6px;
128
+ min-width: 32px;
129
+ }
130
+
131
+ /* Main content area */
132
+ .wv-main {
133
+ display: flex;
134
+ flex: 1;
135
+ overflow: hidden;
136
+ }
137
+
138
+ /* Diagram container */
139
+ .wv-diagram {
140
+ flex: 1;
141
+ position: relative;
142
+ overflow: hidden;
143
+ background-color: var(--bg);
144
+ background-image:
145
+ radial-gradient(circle, var(--border) 1px, transparent 1px);
146
+ background-size: 20px 20px;
147
+ }
148
+
149
+ .wv-diagram svg {
150
+ width: 100%;
151
+ height: 100%;
152
+ }
153
+
154
+ /* SVG Node styles */
155
+ .wv-node {
156
+ cursor: pointer;
157
+ transition: filter 0.15s ease;
158
+ }
159
+
160
+ .wv-node:hover {
161
+ filter: brightness(1.1) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2));
162
+ }
163
+
164
+ .wv-node rect,
165
+ .wv-node circle {
166
+ stroke: var(--border);
167
+ stroke-width: 2;
168
+ transition: all 0.2s ease;
169
+ }
170
+
171
+ .wv-node:hover rect,
172
+ .wv-node:hover circle {
173
+ stroke-width: 3;
174
+ }
175
+
176
+ .wv-node--pending rect { fill: var(--node-pending); }
177
+ .wv-node--running rect { fill: var(--node-running); stroke: var(--warning); }
178
+ .wv-node--success rect { fill: var(--node-success); stroke: var(--success); }
179
+ .wv-node--error rect { fill: var(--node-error); stroke: var(--error); }
180
+ .wv-node--aborted rect { fill: var(--node-aborted); }
181
+ .wv-node--cached rect { fill: var(--node-cached); stroke: var(--info); }
182
+ .wv-node--skipped rect { fill: var(--node-skipped); opacity: 0.6; }
183
+
184
+ .wv-node--selected rect {
185
+ stroke: var(--primary);
186
+ stroke-width: 3;
187
+ }
188
+
189
+ .wv-node text {
190
+ fill: var(--text);
191
+ font-size: 12px;
192
+ font-weight: 500;
193
+ dominant-baseline: middle;
194
+ text-anchor: middle;
195
+ }
196
+
197
+ .wv-node .wv-node-timing {
198
+ fill: var(--text-muted);
199
+ font-size: 10px;
200
+ }
201
+
202
+ /* Edge styles */
203
+ .wv-edge {
204
+ fill: none;
205
+ stroke: var(--border);
206
+ stroke-width: 2;
207
+ }
208
+
209
+ .wv-edge--active {
210
+ stroke: var(--success);
211
+ stroke-width: 2.5;
212
+ }
213
+
214
+ .wv-edge-arrow {
215
+ fill: var(--border);
216
+ }
217
+
218
+ /* Parallel/Race container */
219
+ .wv-container {
220
+ fill: transparent;
221
+ stroke: var(--border);
222
+ stroke-dasharray: 5 3;
223
+ }
224
+
225
+ .wv-container--parallel { stroke: var(--info); }
226
+ .wv-container--race { stroke: var(--warning); }
227
+
228
+ .wv-container-label {
229
+ fill: var(--text-muted);
230
+ font-size: 10px;
231
+ font-weight: 600;
232
+ text-transform: uppercase;
233
+ letter-spacing: 0.5px;
234
+ }
235
+
236
+ /* Heatmap overlay */
237
+ .wv-node--heat-cold rect { fill: var(--heat-cold) !important; opacity: 0.7; }
238
+ .wv-node--heat-cool rect { fill: var(--heat-cool) !important; opacity: 0.7; }
239
+ .wv-node--heat-neutral rect { fill: var(--heat-neutral) !important; opacity: 0.7; }
240
+ .wv-node--heat-warm rect { fill: var(--heat-warm) !important; opacity: 0.7; }
241
+ .wv-node--heat-hot rect { fill: var(--heat-hot) !important; opacity: 0.7; }
242
+ .wv-node--heat-critical rect { fill: var(--heat-critical) !important; opacity: 0.85; }
243
+
244
+ /* Timeline scrubber */
245
+ .wv-timeline {
246
+ height: 80px;
247
+ padding: 12px 20px;
248
+ background-color: var(--bg-secondary);
249
+ border-top: 1px solid var(--border);
250
+ }
251
+
252
+ .wv-timeline-track {
253
+ position: relative;
254
+ height: 24px;
255
+ background-color: var(--bg);
256
+ border-radius: 4px;
257
+ overflow: hidden;
258
+ }
259
+
260
+ .wv-timeline-progress {
261
+ position: absolute;
262
+ top: 0;
263
+ left: 0;
264
+ height: 100%;
265
+ background-color: var(--primary);
266
+ opacity: 0.3;
267
+ transition: width 0.1s ease;
268
+ }
269
+
270
+ .wv-timeline-marker {
271
+ position: absolute;
272
+ top: 0;
273
+ width: 3px;
274
+ height: 100%;
275
+ background-color: var(--primary);
276
+ cursor: ew-resize;
277
+ }
278
+
279
+ .wv-timeline-events {
280
+ display: flex;
281
+ gap: 2px;
282
+ height: 100%;
283
+ align-items: center;
284
+ padding: 4px;
285
+ }
286
+
287
+ .wv-timeline-event {
288
+ width: 4px;
289
+ height: 16px;
290
+ border-radius: 2px;
291
+ background-color: var(--muted);
292
+ }
293
+
294
+ .wv-timeline-event--success { background-color: var(--success); }
295
+ .wv-timeline-event--error { background-color: var(--error); }
296
+ .wv-timeline-event--running { background-color: var(--warning); }
297
+
298
+ .wv-timeline-controls {
299
+ display: flex;
300
+ gap: 8px;
301
+ margin-top: 8px;
302
+ align-items: center;
303
+ }
304
+
305
+ .wv-timeline-time {
306
+ font-size: 0.75rem;
307
+ color: var(--text-muted);
308
+ font-family: monospace;
309
+ }
310
+
311
+ /* Inspector panel */
312
+ .wv-inspector {
313
+ width: 320px;
314
+ background-color: var(--bg-secondary);
315
+ border-left: 1px solid var(--border);
316
+ overflow-y: auto;
317
+ transition: width 0.2s ease;
318
+ }
319
+
320
+ .wv-inspector--collapsed {
321
+ width: 0;
322
+ }
323
+
324
+ .wv-inspector-header {
325
+ display: flex;
326
+ align-items: center;
327
+ justify-content: space-between;
328
+ padding: 12px 16px;
329
+ border-bottom: 1px solid var(--border);
330
+ }
331
+
332
+ .wv-inspector-header h2 {
333
+ font-size: 0.875rem;
334
+ font-weight: 600;
335
+ }
336
+
337
+ .wv-inspector-content {
338
+ padding: 16px;
339
+ }
340
+
341
+ .wv-inspector-section {
342
+ margin-bottom: 20px;
343
+ }
344
+
345
+ .wv-inspector-section h3 {
346
+ font-size: 0.75rem;
347
+ font-weight: 600;
348
+ text-transform: uppercase;
349
+ letter-spacing: 0.5px;
350
+ color: var(--text-muted);
351
+ margin-bottom: 8px;
352
+ }
353
+
354
+ .wv-inspector-row {
355
+ display: flex;
356
+ justify-content: space-between;
357
+ padding: 4px 0;
358
+ font-size: 0.875rem;
359
+ }
360
+
361
+ .wv-inspector-label {
362
+ color: var(--text-muted);
363
+ }
364
+
365
+ .wv-inspector-value {
366
+ font-weight: 500;
367
+ font-family: monospace;
368
+ }
369
+
370
+ .wv-inspector-value--success { color: var(--success); }
371
+ .wv-inspector-value--error { color: var(--error); }
372
+ .wv-inspector-value--running { color: var(--warning); }
373
+
374
+ /* Status badge */
375
+ .wv-badge {
376
+ display: inline-flex;
377
+ align-items: center;
378
+ padding: 2px 8px;
379
+ font-size: 0.75rem;
380
+ font-weight: 500;
381
+ border-radius: 4px;
382
+ text-transform: capitalize;
383
+ }
384
+
385
+ .wv-badge--pending { background-color: var(--node-pending); }
386
+ .wv-badge--running { background-color: var(--node-running); color: #664d03; }
387
+ .wv-badge--success { background-color: var(--node-success); color: #0f5132; }
388
+ .wv-badge--error { background-color: var(--node-error); color: #842029; }
389
+ .wv-badge--cached { background-color: var(--node-cached); color: #084298; }
390
+
391
+ /* Live indicator */
392
+ .wv-live {
393
+ display: flex;
394
+ align-items: center;
395
+ gap: 6px;
396
+ padding: 4px 10px;
397
+ background-color: var(--error);
398
+ color: white;
399
+ font-size: 0.75rem;
400
+ font-weight: 600;
401
+ border-radius: 4px;
402
+ }
403
+
404
+ .wv-live-dot {
405
+ width: 8px;
406
+ height: 8px;
407
+ background-color: white;
408
+ border-radius: 50%;
409
+ animation: wv-pulse 1.5s infinite;
410
+ }
411
+
412
+ @keyframes wv-pulse {
413
+ 0%, 100% { opacity: 1; }
414
+ 50% { opacity: 0.5; }
415
+ }
416
+
417
+ /* Performance stats */
418
+ .wv-perf-bar {
419
+ height: 8px;
420
+ background-color: var(--bg);
421
+ border-radius: 4px;
422
+ overflow: hidden;
423
+ margin-top: 4px;
424
+ }
425
+
426
+ .wv-perf-bar-fill {
427
+ height: 100%;
428
+ border-radius: 4px;
429
+ transition: width 0.3s ease;
430
+ }
431
+
432
+ .wv-perf-bar-fill--cold { background-color: var(--heat-cold); }
433
+ .wv-perf-bar-fill--cool { background-color: var(--heat-cool); }
434
+ .wv-perf-bar-fill--neutral { background-color: var(--heat-neutral); }
435
+ .wv-perf-bar-fill--warm { background-color: var(--heat-warm); }
436
+ .wv-perf-bar-fill--hot { background-color: var(--heat-hot); }
437
+ .wv-perf-bar-fill--critical { background-color: var(--heat-critical); }
438
+
439
+ /* Tooltip */
440
+ .wv-tooltip {
441
+ position: fixed;
442
+ padding: 8px 12px;
443
+ background-color: var(--text);
444
+ color: var(--bg);
445
+ font-size: 0.75rem;
446
+ border-radius: 4px;
447
+ pointer-events: none;
448
+ z-index: 1000;
449
+ max-width: 300px;
450
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
451
+ }
452
+
453
+ /* Loading state */
454
+ .wv-loading {
455
+ display: flex;
456
+ align-items: center;
457
+ justify-content: center;
458
+ height: 100%;
459
+ color: var(--text-muted);
460
+ }
461
+
462
+ .wv-spinner {
463
+ width: 24px;
464
+ height: 24px;
465
+ border: 3px solid var(--border);
466
+ border-top-color: var(--primary);
467
+ border-radius: 50%;
468
+ animation: wv-spin 1s linear infinite;
469
+ margin-right: 8px;
470
+ }
471
+
472
+ @keyframes wv-spin {
473
+ to { transform: rotate(360deg); }
474
+ }
475
+
476
+ /* Empty state */
477
+ .wv-empty {
478
+ display: flex;
479
+ flex-direction: column;
480
+ align-items: center;
481
+ justify-content: center;
482
+ height: 100%;
483
+ color: var(--text-muted);
484
+ text-align: center;
485
+ padding: 40px;
486
+ }
487
+
488
+ .wv-empty svg {
489
+ width: 64px;
490
+ height: 64px;
491
+ margin-bottom: 16px;
492
+ opacity: 0.5;
493
+ }
494
+
495
+ /* Modal */
496
+ .wv-modal {
497
+ position: fixed;
498
+ top: 0;
499
+ left: 0;
500
+ right: 0;
501
+ bottom: 0;
502
+ background-color: rgba(0, 0, 0, 0.5);
503
+ display: flex;
504
+ align-items: center;
505
+ justify-content: center;
506
+ z-index: 1000;
507
+ }
508
+
509
+ .wv-modal-content {
510
+ background-color: var(--bg);
511
+ border-radius: 8px;
512
+ width: 90%;
513
+ max-width: 600px;
514
+ max-height: 90vh;
515
+ display: flex;
516
+ flex-direction: column;
517
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
518
+ }
519
+
520
+ .wv-modal-header {
521
+ display: flex;
522
+ align-items: center;
523
+ justify-content: space-between;
524
+ padding: 16px 20px;
525
+ border-bottom: 1px solid var(--border);
526
+ }
527
+
528
+ .wv-modal-header h2 {
529
+ font-size: 1.125rem;
530
+ font-weight: 600;
531
+ margin: 0;
532
+ }
533
+
534
+ .wv-modal-body {
535
+ padding: 20px;
536
+ overflow-y: auto;
537
+ flex: 1;
538
+ }
539
+
540
+ .wv-modal-body p {
541
+ margin: 0 0 12px 0;
542
+ font-size: 0.875rem;
543
+ color: var(--text-muted);
544
+ }
545
+
546
+ .wv-modal-body code {
547
+ background-color: var(--bg-secondary);
548
+ padding: 2px 6px;
549
+ border-radius: 4px;
550
+ font-size: 0.875rem;
551
+ font-family: monospace;
552
+ }
553
+
554
+ .wv-textarea {
555
+ width: 100%;
556
+ padding: 12px;
557
+ font-family: monospace;
558
+ font-size: 0.875rem;
559
+ border: 1px solid var(--border);
560
+ border-radius: 6px;
561
+ background-color: var(--bg);
562
+ color: var(--text);
563
+ resize: vertical;
564
+ box-sizing: border-box;
565
+ }
566
+
567
+ .wv-textarea:focus {
568
+ outline: none;
569
+ border-color: var(--primary);
570
+ }
571
+
572
+ .wv-error {
573
+ margin-top: 12px;
574
+ padding: 12px;
575
+ background-color: var(--node-error);
576
+ color: #842029;
577
+ border-radius: 6px;
578
+ font-size: 0.875rem;
579
+ }
580
+
581
+ .wv-modal-footer {
582
+ display: flex;
583
+ gap: 8px;
584
+ justify-content: flex-end;
585
+ padding: 16px 20px;
586
+ border-top: 1px solid var(--border);
587
+ }
588
+
589
+ /* Responsive */
590
+ @media (max-width: 768px) {
591
+ .wv-inspector {
592
+ position: fixed;
593
+ right: 0;
594
+ top: 0;
595
+ bottom: 0;
596
+ z-index: 100;
597
+ box-shadow: -4px 0 12px rgba(0, 0, 0, 0.1);
598
+ }
599
+
600
+ .wv-timeline {
601
+ height: auto;
602
+ }
603
+
604
+ .wv-modal-content {
605
+ width: 95%;
606
+ max-height: 95vh;
607
+ }
608
+ }
609
+ `}function gt(e){return`
610
+ (function() {
611
+ 'use strict';
612
+
613
+ // State
614
+ let selectedNodeId = null;
615
+ let transform = { x: 0, y: 0, scale: 1 };
616
+ let isDragging = false;
617
+ let dragStart = { x: 0, y: 0 };
618
+ let ws = null;
619
+ let snapshots = [];
620
+ let currentSnapshotIndex = -1;
621
+ let isPlaying = false;
622
+ let playbackSpeed = 1;
623
+ let heatmapEnabled = false;
624
+ let heatmapMetric = 'duration';
625
+
626
+ // DOM elements
627
+ const diagram = document.getElementById('diagram');
628
+ const svg = diagram?.querySelector('svg');
629
+ const inspector = document.getElementById('inspector');
630
+ const timeline = document.getElementById('timeline');
631
+
632
+ // Initialize
633
+ document.addEventListener('DOMContentLoaded', init);
634
+
635
+ function init() {
636
+ ${e.interactive?"setupInteractivity(); setupLoadJSON();":""}
637
+ // WebSocket must be initialized before time-travel and heatmap checks
638
+ ${e.wsUrl?`setupWebSocket('${e.wsUrl}');`:""}
639
+ ${e.timeTravel?"setupTimeTravel(); initializeTimeTravelFromData();":""}
640
+ ${e.heatmap?"setupHeatmap();":""}
641
+ setupKeyboardShortcuts();
642
+ }
643
+
644
+ // Load JSON functionality
645
+ function setupLoadJSON() {
646
+ const loadBtn = document.getElementById('load-json-btn');
647
+ const modal = document.getElementById('load-json-modal');
648
+ const closeBtn = document.getElementById('load-json-close');
649
+ const cancelBtn = document.getElementById('load-json-cancel');
650
+ const submitBtn = document.getElementById('load-json-submit');
651
+ const input = document.getElementById('load-json-input');
652
+ const errorDiv = document.getElementById('load-json-error');
653
+
654
+ if (!loadBtn || !modal) return;
655
+
656
+ loadBtn.addEventListener('click', () => {
657
+ modal.style.display = 'flex';
658
+ if (input) {
659
+ input.value = '';
660
+ input.focus();
661
+ }
662
+ if (errorDiv) errorDiv.style.display = 'none';
663
+ });
664
+
665
+ const closeModal = () => {
666
+ modal.style.display = 'none';
667
+ if (errorDiv) errorDiv.style.display = 'none';
668
+ };
669
+
670
+ closeBtn?.addEventListener('click', closeModal);
671
+ cancelBtn?.addEventListener('click', closeModal);
672
+ modal.addEventListener('click', (e) => {
673
+ if (e.target === modal) closeModal();
674
+ });
675
+
676
+ submitBtn?.addEventListener('click', () => {
677
+ if (!input) return;
678
+
679
+ try {
680
+ const jsonText = input.value.trim();
681
+ if (!jsonText) {
682
+ showError('Please paste JSON data');
683
+ return;
684
+ }
685
+
686
+ const ir = JSON.parse(jsonText);
687
+
688
+ // Validate IR structure
689
+ if (!ir || !ir.root || !ir.root.type || ir.root.type !== 'workflow') {
690
+ showError('Invalid workflow IR. Expected object with root.type === "workflow"');
691
+ return;
692
+ }
693
+
694
+ // Update global data
695
+ window.__WORKFLOW_IR__ = ir;
696
+ const newData = buildWorkflowDataFromIR(ir);
697
+ window.__WORKFLOW_DATA__ = newData;
698
+
699
+ // Save to sessionStorage for full rebuild on reload
700
+ try {
701
+ sessionStorage.setItem('workflow_ir', JSON.stringify(ir));
702
+ } catch (storageErr) {
703
+ console.warn('Failed to save IR to sessionStorage:', storageErr);
704
+ }
705
+
706
+ // Rebuild the diagram (updates node states in-place)
707
+ rebuildDiagram(ir);
708
+
709
+ // Update inspector if node is selected
710
+ if (selectedNodeId) {
711
+ updateInspector(selectedNodeId);
712
+ }
713
+
714
+ closeModal();
715
+
716
+ // Offer full rebuild via reload if structure changed significantly
717
+ console.log('IR loaded. Node states updated. Reload page for full layout rebuild with new structure.');
718
+ } catch (e) {
719
+ showError('Invalid JSON: ' + e.message);
720
+ }
721
+ });
722
+
723
+ function showError(message) {
724
+ if (errorDiv) {
725
+ errorDiv.textContent = message;
726
+ errorDiv.style.display = 'block';
727
+ }
728
+ }
729
+ }
730
+
731
+ function buildWorkflowDataFromIR(ir) {
732
+ const nodes = {};
733
+
734
+ function collectNodes(flowNodes) {
735
+ for (const node of flowNodes || []) {
736
+ nodes[node.id] = {
737
+ id: node.id,
738
+ name: node.name,
739
+ type: node.type,
740
+ state: node.state,
741
+ key: node.key,
742
+ durationMs: node.durationMs,
743
+ startTs: node.startTs,
744
+ error: node.error !== undefined && node.error !== null ? String(node.error) : undefined,
745
+ retryCount: node.retryCount,
746
+ input: node.input,
747
+ output: node.output,
748
+ ...(node.type === 'stream' && {
749
+ namespace: node.namespace,
750
+ writeCount: node.writeCount,
751
+ readCount: node.readCount,
752
+ finalPosition: node.finalPosition,
753
+ streamState: node.streamState,
754
+ backpressureOccurred: node.backpressureOccurred,
755
+ }),
756
+ ...(node.type === 'decision' && {
757
+ condition: node.condition,
758
+ decisionValue: node.decisionValue,
759
+ branchTaken: node.branchTaken,
760
+ branches: node.branches,
761
+ }),
762
+ };
763
+
764
+ if (node.children) {
765
+ collectNodes(node.children);
766
+ }
767
+ if (node.branches) {
768
+ for (const branch of node.branches) {
769
+ collectNodes(branch.children);
770
+ }
771
+ }
772
+ }
773
+ }
774
+
775
+ collectNodes(ir.root.children);
776
+ const hooks = ir.hooks
777
+ ? {
778
+ ...ir.hooks,
779
+ onAfterStep:
780
+ ir.hooks.onAfterStep instanceof Map
781
+ ? Object.fromEntries(ir.hooks.onAfterStep)
782
+ : ir.hooks.onAfterStep,
783
+ }
784
+ : undefined;
785
+ return { nodes, hooks };
786
+ }
787
+
788
+ function rebuildDiagram(ir) {
789
+ // Update workflow data and node states
790
+ const newData = buildWorkflowDataFromIR(ir);
791
+ window.__WORKFLOW_DATA__ = newData;
792
+ window.__WORKFLOW_IR__ = ir;
793
+
794
+ // Update existing node states in SVG
795
+ renderIR(ir);
796
+
797
+ // Note: Full diagram rebuild (new nodes, layout changes) requires regenerating the HTML
798
+ // For now, we update node states. Users can save the IR and regenerate HTML for full rebuild.
799
+ console.log('Workflow IR loaded. Node states updated. For full diagram rebuild, regenerate HTML with the new IR.');
800
+ }
801
+
802
+ function initializeTimeTravelFromData() {
803
+ // For static HTML (no WebSocket), time travel doesn't work since we only have one state
804
+ // Initialize with empty snapshots and disable controls
805
+ if (!ws) {
806
+ snapshots = [];
807
+ currentSnapshotIndex = -1;
808
+ updateTimelineUI();
809
+
810
+ // Disable time travel controls for static HTML
811
+ const playBtn = document.getElementById('tt-play');
812
+ const pauseBtn = document.getElementById('tt-pause');
813
+ const prevBtn = document.getElementById('tt-prev');
814
+ const nextBtn = document.getElementById('tt-next');
815
+ const slider = document.getElementById('tt-slider');
816
+
817
+ [playBtn, pauseBtn, prevBtn, nextBtn, slider].forEach(btn => {
818
+ if (btn) {
819
+ btn.disabled = true;
820
+ btn.title = 'Time travel requires a live WebSocket connection';
821
+ }
822
+ });
823
+ }
824
+ }
825
+
826
+ // Interactivity
827
+ function setupInteractivity() {
828
+ if (!diagram || !svg) return;
829
+
830
+ // Zoom with mouse wheel
831
+ diagram.addEventListener('wheel', (e) => {
832
+ e.preventDefault();
833
+ const delta = e.deltaY > 0 ? 0.9 : 1.1;
834
+ const rect = diagram.getBoundingClientRect();
835
+ const x = e.clientX - rect.left;
836
+ const y = e.clientY - rect.top;
837
+
838
+ // Zoom towards cursor position
839
+ transform.scale *= delta;
840
+ transform.scale = Math.max(0.1, Math.min(5, transform.scale));
841
+ transform.x = x - (x - transform.x) * delta;
842
+ transform.y = y - (y - transform.y) * delta;
843
+
844
+ applyTransform();
845
+ });
846
+
847
+ // Pan with drag
848
+ diagram.addEventListener('mousedown', (e) => {
849
+ if (e.target === diagram || e.target === svg) {
850
+ isDragging = true;
851
+ dragStart = { x: e.clientX - transform.x, y: e.clientY - transform.y };
852
+ diagram.style.cursor = 'grabbing';
853
+ }
854
+ });
855
+
856
+ document.addEventListener('mousemove', (e) => {
857
+ if (!isDragging) return;
858
+ transform.x = e.clientX - dragStart.x;
859
+ transform.y = e.clientY - dragStart.y;
860
+ applyTransform();
861
+ });
862
+
863
+ document.addEventListener('mouseup', () => {
864
+ isDragging = false;
865
+ if (diagram) diagram.style.cursor = 'grab';
866
+ });
867
+
868
+ // Node selection - handle clicks on nodes and their children (rect, text, etc.)
869
+ document.querySelectorAll('.wv-node').forEach((node) => {
870
+ node.addEventListener('click', (e) => {
871
+ e.stopPropagation();
872
+ const nodeId = node.dataset.nodeId;
873
+ if (nodeId) {
874
+ selectNode(nodeId);
875
+ }
876
+ });
877
+ });
878
+
879
+ // Also handle clicks directly on child elements (rect, text) that bubble up
880
+ if (svg) {
881
+ svg.addEventListener('click', (e) => {
882
+ // Find the closest .wv-node parent
883
+ let target = e.target;
884
+ while (target && target !== svg) {
885
+ if (target.classList && target.classList.contains('wv-node')) {
886
+ const nodeId = target.dataset?.nodeId;
887
+ if (nodeId) {
888
+ e.stopPropagation();
889
+ selectNode(nodeId);
890
+ return;
891
+ }
892
+ }
893
+ target = target.parentElement;
894
+ }
895
+ });
896
+ }
897
+
898
+ // Deselect on background click
899
+ diagram.addEventListener('click', (e) => {
900
+ if (e.target === diagram || e.target === svg) {
901
+ selectNode(null);
902
+ }
903
+ });
904
+
905
+ // Zoom buttons
906
+ document.getElementById('zoom-in')?.addEventListener('click', () => zoom(1.2));
907
+ document.getElementById('zoom-out')?.addEventListener('click', () => zoom(0.8));
908
+ document.getElementById('zoom-reset')?.addEventListener('click', resetZoom);
909
+
910
+ // Set initial cursor
911
+ diagram.style.cursor = 'grab';
912
+ }
913
+
914
+ function applyTransform() {
915
+ if (!svg) return;
916
+ const g = svg.querySelector('g.wv-root');
917
+ if (g) {
918
+ g.setAttribute('transform', 'translate(' + transform.x + ',' + transform.y + ') scale(' + transform.scale + ')');
919
+ }
920
+ }
921
+
922
+ function zoom(factor) {
923
+ if (!diagram) return;
924
+ const rect = diagram.getBoundingClientRect();
925
+ const centerX = rect.width / 2;
926
+ const centerY = rect.height / 2;
927
+
928
+ transform.scale *= factor;
929
+ transform.scale = Math.max(0.1, Math.min(5, transform.scale));
930
+ transform.x = centerX - (centerX - transform.x) * factor;
931
+ transform.y = centerY - (centerY - transform.y) * factor;
932
+
933
+ applyTransform();
934
+ }
935
+
936
+ function resetZoom() {
937
+ transform = { x: 0, y: 0, scale: 1 };
938
+ applyTransform();
939
+ }
940
+
941
+ function selectNode(nodeId) {
942
+ // Remove previous selection
943
+ document.querySelectorAll('.wv-node--selected').forEach((n) => {
944
+ n.classList.remove('wv-node--selected');
945
+ });
946
+
947
+ selectedNodeId = nodeId;
948
+
949
+ if (nodeId) {
950
+ const node = document.querySelector('[data-node-id="' + nodeId + '"]');
951
+ if (node) {
952
+ node.classList.add('wv-node--selected');
953
+ updateInspector(nodeId);
954
+ }
955
+ } else {
956
+ clearInspector();
957
+ }
958
+ }
959
+
960
+ function updateInspector(nodeId) {
961
+ const content = document.getElementById('inspector-content');
962
+ if (!content) return;
963
+
964
+ const nodeData = window.__WORKFLOW_DATA__?.nodes?.[nodeId];
965
+ if (!nodeData) {
966
+ // Clear and add empty message using safe DOM methods
967
+ while (content.firstChild) content.removeChild(content.firstChild);
968
+ const p = document.createElement('p');
969
+ p.className = 'wv-empty';
970
+ p.textContent = 'No data available';
971
+ content.appendChild(p);
972
+ return;
973
+ }
974
+
975
+ renderInspectorContent(content, nodeData);
976
+ }
977
+
978
+ function renderInspectorContent(container, node) {
979
+ // Clear container using safe DOM method
980
+ while (container.firstChild) container.removeChild(container.firstChild);
981
+
982
+ // Node Info section
983
+ const infoSection = createSection('Node Info');
984
+ infoSection.appendChild(createRow('Name', node.name || node.id));
985
+ infoSection.appendChild(createRow('Type', node.type));
986
+
987
+ // State badge
988
+ const stateRow = document.createElement('div');
989
+ stateRow.className = 'wv-inspector-row';
990
+ const stateLabel = document.createElement('span');
991
+ stateLabel.className = 'wv-inspector-label';
992
+ stateLabel.textContent = 'State';
993
+ const stateBadge = document.createElement('span');
994
+ stateBadge.className = 'wv-badge wv-badge--' + node.state;
995
+ stateBadge.textContent = node.state;
996
+ stateRow.appendChild(stateLabel);
997
+ stateRow.appendChild(stateBadge);
998
+ infoSection.appendChild(stateRow);
999
+
1000
+ if (node.key) {
1001
+ infoSection.appendChild(createRow('Key', node.key));
1002
+ }
1003
+ container.appendChild(infoSection);
1004
+
1005
+ // Timing section
1006
+ if (node.durationMs !== undefined) {
1007
+ const timingSection = createSection('Timing');
1008
+ timingSection.appendChild(createRow('Duration', formatDuration(node.durationMs)));
1009
+ if (node.startTs !== undefined) {
1010
+ timingSection.appendChild(createRow('Started', new Date(node.startTs).toLocaleTimeString()));
1011
+ }
1012
+ container.appendChild(timingSection);
1013
+ }
1014
+
1015
+ // Retries section
1016
+ if (node.retryCount !== undefined && node.retryCount > 0) {
1017
+ const retrySection = createSection('Retries');
1018
+ retrySection.appendChild(createRow('Retry Count', String(node.retryCount)));
1019
+ container.appendChild(retrySection);
1020
+ }
1021
+
1022
+ // Input/Output section
1023
+ if (node.input !== undefined || node.output !== undefined) {
1024
+ const ioSection = createSection('Input / Output');
1025
+ if (node.input !== undefined) {
1026
+ const inputPre = document.createElement('pre');
1027
+ inputPre.style.cssText = 'font-size:11px;overflow:auto;max-height:120px;background:var(--bg);padding:8px;border-radius:4px;';
1028
+ inputPre.textContent = typeof node.input === 'string' ? node.input : safeStringify(node.input);
1029
+ ioSection.appendChild(createRow('Input', ''));
1030
+ ioSection.appendChild(inputPre);
1031
+ }
1032
+ if (node.output !== undefined) {
1033
+ const outputPre = document.createElement('pre');
1034
+ outputPre.style.cssText = 'font-size:11px;overflow:auto;max-height:120px;background:var(--bg);padding:8px;border-radius:4px;';
1035
+ outputPre.textContent = typeof node.output === 'string' ? node.output : safeStringify(node.output);
1036
+ ioSection.appendChild(createRow('Output', ''));
1037
+ ioSection.appendChild(outputPre);
1038
+ }
1039
+ container.appendChild(ioSection);
1040
+ }
1041
+
1042
+ // Hook timing (onAfterStep)
1043
+ const hookKey = node.key || node.id;
1044
+ const hookExec = window.__WORKFLOW_DATA__?.hooks?.onAfterStep?.[hookKey];
1045
+ if (hookExec && (hookExec.durationMs !== undefined || hookExec.ts !== undefined)) {
1046
+ const hookSection = createSection('Hook (onAfterStep)');
1047
+ if (hookExec.durationMs !== undefined) {
1048
+ hookSection.appendChild(createRow('Duration', formatDuration(hookExec.durationMs)));
1049
+ }
1050
+ if (hookExec.ts !== undefined) {
1051
+ hookSection.appendChild(createRow('At', new Date(hookExec.ts).toLocaleTimeString()));
1052
+ }
1053
+ container.appendChild(hookSection);
1054
+ }
1055
+
1056
+ // Error section (preserve falsy errors: 0, "", false)
1057
+ if (node.error !== undefined && node.error !== null) {
1058
+ const errorSection = createSection('Error');
1059
+ const pre = document.createElement('pre');
1060
+ pre.style.cssText = 'font-size:11px;overflow:auto;max-height:150px;background:var(--bg);padding:8px;border-radius:4px;';
1061
+ pre.textContent = String(node.error);
1062
+ errorSection.appendChild(pre);
1063
+ container.appendChild(errorSection);
1064
+ }
1065
+ }
1066
+
1067
+ function createSection(title) {
1068
+ const section = document.createElement('div');
1069
+ section.className = 'wv-inspector-section';
1070
+ const h3 = document.createElement('h3');
1071
+ h3.textContent = title;
1072
+ section.appendChild(h3);
1073
+ return section;
1074
+ }
1075
+
1076
+ function createRow(label, value) {
1077
+ const row = document.createElement('div');
1078
+ row.className = 'wv-inspector-row';
1079
+ const labelSpan = document.createElement('span');
1080
+ labelSpan.className = 'wv-inspector-label';
1081
+ labelSpan.textContent = label;
1082
+ const valueSpan = document.createElement('span');
1083
+ valueSpan.className = 'wv-inspector-value';
1084
+ valueSpan.textContent = value;
1085
+ row.appendChild(labelSpan);
1086
+ row.appendChild(valueSpan);
1087
+ return row;
1088
+ }
1089
+
1090
+ function clearInspector() {
1091
+ const content = document.getElementById('inspector-content');
1092
+ if (content) {
1093
+ while (content.firstChild) content.removeChild(content.firstChild);
1094
+ const p = document.createElement('p');
1095
+ p.className = 'wv-empty';
1096
+ p.textContent = 'Select a node to inspect';
1097
+ content.appendChild(p);
1098
+ }
1099
+ }
1100
+
1101
+ // Time Travel
1102
+ function setupTimeTravel() {
1103
+ const playBtn = document.getElementById('tt-play');
1104
+ const pauseBtn = document.getElementById('tt-pause');
1105
+ const prevBtn = document.getElementById('tt-prev');
1106
+ const nextBtn = document.getElementById('tt-next');
1107
+ const speedSelect = document.getElementById('tt-speed');
1108
+ const slider = document.getElementById('tt-slider');
1109
+
1110
+ playBtn?.addEventListener('click', play);
1111
+ pauseBtn?.addEventListener('click', pause);
1112
+ prevBtn?.addEventListener('click', stepBackward);
1113
+ nextBtn?.addEventListener('click', stepForward);
1114
+ speedSelect?.addEventListener('change', (e) => {
1115
+ playbackSpeed = parseFloat(e.target.value);
1116
+ });
1117
+ slider?.addEventListener('input', (e) => {
1118
+ seek(parseInt(e.target.value, 10));
1119
+ });
1120
+ }
1121
+
1122
+ function play() {
1123
+ if (snapshots.length === 0) {
1124
+ console.warn('[Visualizer] No snapshots available for time travel. Time travel requires a live WebSocket connection.');
1125
+ return;
1126
+ }
1127
+ isPlaying = true;
1128
+ updatePlaybackUI();
1129
+ playNext();
1130
+ }
1131
+
1132
+ function pause() {
1133
+ isPlaying = false;
1134
+ updatePlaybackUI();
1135
+ }
1136
+
1137
+ function playNext() {
1138
+ if (!isPlaying) return;
1139
+ if (currentSnapshotIndex < snapshots.length - 1) {
1140
+ const current = snapshots[currentSnapshotIndex];
1141
+ const next = snapshots[currentSnapshotIndex + 1];
1142
+ const delay = (next.timestamp - current.timestamp) / playbackSpeed;
1143
+
1144
+ setTimeout(() => {
1145
+ stepForward();
1146
+ playNext();
1147
+ }, Math.max(16, delay));
1148
+ } else {
1149
+ pause();
1150
+ }
1151
+ }
1152
+
1153
+ function stepForward() {
1154
+ if (snapshots.length === 0) {
1155
+ console.warn('[Visualizer] No snapshots available for time travel.');
1156
+ return;
1157
+ }
1158
+ if (currentSnapshotIndex < snapshots.length - 1) {
1159
+ seek(currentSnapshotIndex + 1);
1160
+ }
1161
+ }
1162
+
1163
+ function stepBackward() {
1164
+ if (snapshots.length === 0) {
1165
+ console.warn('[Visualizer] No snapshots available for time travel.');
1166
+ return;
1167
+ }
1168
+ if (currentSnapshotIndex > 0) {
1169
+ seek(currentSnapshotIndex - 1);
1170
+ }
1171
+ }
1172
+
1173
+ function seek(index) {
1174
+ if (index < 0 || index >= snapshots.length) return;
1175
+ currentSnapshotIndex = index;
1176
+ updateTimelineUI();
1177
+
1178
+ // Request IR update from server or use cached
1179
+ if (ws && ws.readyState === WebSocket.OPEN) {
1180
+ ws.send(JSON.stringify({ type: 'time_travel_seek', payload: { index } }));
1181
+ } else if (snapshots[index]?.ir) {
1182
+ renderIR(snapshots[index].ir);
1183
+ }
1184
+ }
1185
+
1186
+ function updatePlaybackUI() {
1187
+ const playBtn = document.getElementById('tt-play');
1188
+ const pauseBtn = document.getElementById('tt-pause');
1189
+
1190
+ if (playBtn) playBtn.style.display = isPlaying ? 'none' : 'inline-flex';
1191
+ if (pauseBtn) pauseBtn.style.display = isPlaying ? 'inline-flex' : 'none';
1192
+ }
1193
+
1194
+ function updateTimelineUI() {
1195
+ const slider = document.getElementById('tt-slider');
1196
+ const timeDisplay = document.getElementById('tt-time');
1197
+
1198
+ if (slider) {
1199
+ slider.max = String(Math.max(0, snapshots.length - 1));
1200
+ slider.value = String(Math.max(0, currentSnapshotIndex));
1201
+ }
1202
+
1203
+ if (timeDisplay) {
1204
+ timeDisplay.textContent = (currentSnapshotIndex + 1) + ' / ' + snapshots.length;
1205
+ }
1206
+ }
1207
+
1208
+ // WebSocket
1209
+ function setupWebSocket(url) {
1210
+ ws = new WebSocket(url);
1211
+
1212
+ ws.onopen = () => {
1213
+ console.log('[Visualizer] Connected to server');
1214
+ showLiveIndicator(true);
1215
+ ${e.timeTravel?"if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: 'request_snapshots' }));":""}
1216
+ };
1217
+
1218
+ ws.onclose = () => {
1219
+ console.log('[Visualizer] Disconnected from server');
1220
+ showLiveIndicator(false);
1221
+ // Attempt reconnect after 2 seconds
1222
+ setTimeout(() => setupWebSocket(url), 2000);
1223
+ };
1224
+
1225
+ ws.onmessage = (event) => {
1226
+ try {
1227
+ const msg = JSON.parse(event.data);
1228
+ handleServerMessage(msg);
1229
+ } catch (e) {
1230
+ console.error('[Visualizer] Failed to parse message:', e);
1231
+ }
1232
+ };
1233
+
1234
+ ws.onerror = (error) => {
1235
+ console.error('[Visualizer] WebSocket error:', error);
1236
+ };
1237
+ }
1238
+
1239
+ function handleServerMessage(msg) {
1240
+ switch (msg.type) {
1241
+ case 'ir_update':
1242
+ renderIR(msg.payload);
1243
+ break;
1244
+ case 'snapshot':
1245
+ snapshots.push(msg.payload);
1246
+ currentSnapshotIndex = snapshots.length - 1;
1247
+ updateTimelineUI();
1248
+ break;
1249
+ case 'snapshots_list':
1250
+ snapshots = msg.payload;
1251
+ currentSnapshotIndex = snapshots.length - 1;
1252
+ updateTimelineUI();
1253
+ break;
1254
+ case 'performance_data':
1255
+ window.__PERFORMANCE_DATA__ = msg.payload;
1256
+ if (heatmapEnabled) applyHeatmap();
1257
+ break;
1258
+ case 'workflow_complete':
1259
+ showLiveIndicator(false);
1260
+ break;
1261
+ case 'time_travel_state':
1262
+ currentSnapshotIndex = msg.payload.currentIndex;
1263
+ isPlaying = msg.payload.isPlaying;
1264
+ playbackSpeed = msg.payload.playbackSpeed;
1265
+ updateTimelineUI();
1266
+ updatePlaybackUI();
1267
+ break;
1268
+ }
1269
+ }
1270
+
1271
+ function showLiveIndicator(show) {
1272
+ const indicator = document.getElementById('live-indicator');
1273
+ if (indicator) {
1274
+ indicator.style.display = show ? 'flex' : 'none';
1275
+ }
1276
+ }
1277
+
1278
+ // Heatmap
1279
+ function setupHeatmap() {
1280
+ const toggle = document.getElementById('heatmap-toggle');
1281
+ const metricSelect = document.getElementById('heatmap-metric');
1282
+
1283
+ // For static HTML (no WebSocket), disable heatmap controls
1284
+ if (!ws) {
1285
+ if (toggle) {
1286
+ toggle.disabled = true;
1287
+ toggle.title = 'Heatmap requires a live WebSocket connection with performance data';
1288
+ }
1289
+ if (metricSelect) {
1290
+ metricSelect.disabled = true;
1291
+ metricSelect.title = 'Heatmap requires a live WebSocket connection with performance data';
1292
+ }
1293
+ return;
1294
+ }
1295
+
1296
+ toggle?.addEventListener('click', () => {
1297
+ heatmapEnabled = !heatmapEnabled;
1298
+ toggle.classList.toggle('wv-btn--primary', heatmapEnabled);
1299
+ if (ws && ws.readyState === 1) {
1300
+ ws.send(JSON.stringify({ type: 'toggle_heatmap', payload: { enabled: heatmapEnabled } }));
1301
+ }
1302
+ if (heatmapEnabled) {
1303
+ applyHeatmap();
1304
+ } else {
1305
+ removeHeatmap();
1306
+ }
1307
+ });
1308
+
1309
+ metricSelect?.addEventListener('change', (e) => {
1310
+ heatmapMetric = e.target.value;
1311
+ if (ws && ws.readyState === 1) {
1312
+ ws.send(JSON.stringify({ type: 'set_heatmap_metric', payload: { metric: heatmapMetric } }));
1313
+ }
1314
+ if (heatmapEnabled) applyHeatmap();
1315
+ });
1316
+ }
1317
+
1318
+ function applyHeatmap() {
1319
+ const perfData = window.__PERFORMANCE_DATA__;
1320
+ if (!perfData) return;
1321
+
1322
+ const heat = perfData.heat;
1323
+ document.querySelectorAll('.wv-node').forEach((node) => {
1324
+ const nodeId = node.dataset.nodeId;
1325
+ const value = heat && (typeof heat.get === 'function' ? heat.get(nodeId) : heat[nodeId]);
1326
+
1327
+ // Remove existing heat classes
1328
+ node.classList.remove(
1329
+ 'wv-node--heat-cold',
1330
+ 'wv-node--heat-cool',
1331
+ 'wv-node--heat-neutral',
1332
+ 'wv-node--heat-warm',
1333
+ 'wv-node--heat-hot',
1334
+ 'wv-node--heat-critical'
1335
+ );
1336
+
1337
+ if (value !== undefined) {
1338
+ const level = getHeatLevel(value);
1339
+ node.classList.add('wv-node--heat-' + level);
1340
+ }
1341
+ });
1342
+ }
1343
+
1344
+ function removeHeatmap() {
1345
+ document.querySelectorAll('.wv-node').forEach((node) => {
1346
+ node.classList.remove(
1347
+ 'wv-node--heat-cold',
1348
+ 'wv-node--heat-cool',
1349
+ 'wv-node--heat-neutral',
1350
+ 'wv-node--heat-warm',
1351
+ 'wv-node--heat-hot',
1352
+ 'wv-node--heat-critical'
1353
+ );
1354
+ });
1355
+ }
1356
+
1357
+ function getHeatLevel(heat) {
1358
+ if (heat < 0.2) return 'cold';
1359
+ if (heat < 0.4) return 'cool';
1360
+ if (heat < 0.6) return 'neutral';
1361
+ if (heat < 0.8) return 'warm';
1362
+ if (heat < 0.95) return 'hot';
1363
+ return 'critical';
1364
+ }
1365
+
1366
+ // Keyboard shortcuts
1367
+ function setupKeyboardShortcuts() {
1368
+ document.addEventListener('keydown', (e) => {
1369
+ // Don't trigger shortcuts when typing in inputs
1370
+ if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
1371
+
1372
+ switch (e.key) {
1373
+ case ' ':
1374
+ e.preventDefault();
1375
+ isPlaying ? pause() : play();
1376
+ break;
1377
+ case 'ArrowLeft':
1378
+ e.preventDefault();
1379
+ stepBackward();
1380
+ break;
1381
+ case 'ArrowRight':
1382
+ e.preventDefault();
1383
+ stepForward();
1384
+ break;
1385
+ case '0':
1386
+ resetZoom();
1387
+ break;
1388
+ case '+':
1389
+ case '=':
1390
+ zoom(1.2);
1391
+ break;
1392
+ case '-':
1393
+ zoom(0.8);
1394
+ break;
1395
+ case 'h':
1396
+ ${e.heatmap?"document.getElementById('heatmap-toggle')?.click();":""}
1397
+ break;
1398
+ case 'Escape':
1399
+ selectNode(null);
1400
+ break;
1401
+ }
1402
+ });
1403
+ }
1404
+
1405
+ // Render functions
1406
+ function renderIR(ir) {
1407
+ window.__WORKFLOW_DATA__ = buildWorkflowDataFromIR(ir);
1408
+
1409
+ // Update SVG node states
1410
+ document.querySelectorAll('.wv-node').forEach((node) => {
1411
+ const nodeId = node.dataset.nodeId;
1412
+ const nodeData = window.__WORKFLOW_DATA__.nodes[nodeId];
1413
+ if (nodeData) {
1414
+ // Update only state class so heatmap (wv-node--heat-*) and other classes are preserved
1415
+ node.className = node.className.replace(/wv-node--(success|error|running|cached|skipped|pending|aborted)/g, '').replace(/\\s+/g, ' ').trim();
1416
+ node.classList.add('wv-node', 'wv-node--' + nodeData.state);
1417
+
1418
+ // Update timing text if present
1419
+ const timing = node.querySelector('.wv-node-timing');
1420
+ if (timing && nodeData.durationMs !== undefined) {
1421
+ timing.textContent = formatDuration(nodeData.durationMs);
1422
+ }
1423
+ }
1424
+ });
1425
+
1426
+ // Re-apply selection so wv-node--selected is not lost after class updates
1427
+ if (selectedNodeId) {
1428
+ selectNode(selectedNodeId);
1429
+ }
1430
+ }
1431
+
1432
+ function flattenNodes(nodes) {
1433
+ const result = [];
1434
+ for (const node of nodes) {
1435
+ result.push(node);
1436
+ if (node.children) {
1437
+ result.push(...flattenNodes(node.children));
1438
+ }
1439
+ if (node.branches) {
1440
+ for (const branch of node.branches) {
1441
+ result.push(...flattenNodes(branch.children));
1442
+ }
1443
+ }
1444
+ }
1445
+ return result;
1446
+ }
1447
+
1448
+ // Utilities
1449
+ function safeStringify(val) {
1450
+ const seen = new WeakSet();
1451
+ try {
1452
+ return JSON.stringify(val, function(key, value) {
1453
+ if (typeof value === 'bigint') return value.toString();
1454
+ if (typeof value === 'object' && value !== null) {
1455
+ if (seen.has(value)) return '[Circular]';
1456
+ seen.add(value);
1457
+ }
1458
+ return value;
1459
+ }, 2);
1460
+ } catch (e) {
1461
+ return String(val);
1462
+ }
1463
+ }
1464
+
1465
+ function formatDuration(ms) {
1466
+ if (ms < 1000) return Math.round(ms) + 'ms';
1467
+ if (ms < 60000) {
1468
+ const s = (ms / 1000).toFixed(1).replace(/\\.0$/, '');
1469
+ return s + 's';
1470
+ }
1471
+ let min = Math.floor(ms / 60000);
1472
+ let sec = Math.round((ms % 60000) / 1000);
1473
+ if (sec >= 60) { min += 1; sec = 0; }
1474
+ if (sec === 0) return min + 'm';
1475
+ return min + 'm ' + sec + 's';
1476
+ }
1477
+ })();
1478
+ `}var ae=160,ge=50,Ge=40,qr=30,F=20;function Zr(e,t="TB",r){let o=t==="TB"||t==="BT",i=t==="RL"||t==="BT",n=[],a=F,s=F,u=0,c=0;for(let g of e){let f=Ye(g,a,s,o,r);n.push(f.node),o?(s+=f.height+qr,u=Math.max(u,f.width),c=s):(a+=f.width+Ge,c=Math.max(c,f.height),u=a)}let l=u+F,p=c+F;if(i)for(let g of n)bt(g,l,p,o);return{nodes:n,width:l,height:p}}function bt(e,t,r,o){if(o?e.y=r-e.y-e.height:e.x=t-e.x-e.width,e.children)for(let i of e.children)bt(i,t,r,o)}function Ye(e,t,r,o,i){if(z(e)){let n=e.name??e.key??"step",a=i?.showKeys&&e.key&&e.name?`${n} [key: ${e.key}]`:n;return{node:{id:e.id,name:a,type:"step",state:e.state,x:t,y:r,width:ae,height:ge,durationMs:e.durationMs},width:ae,height:ge}}if(Q(e)){let n=e.streamState==="active"?`stream:${e.namespace} \u27F3`:e.streamState==="error"?`stream:${e.namespace} \u2717`:`stream:${e.namespace} \u2713`;return{node:{id:e.id,name:n,type:"stream",state:e.state,x:t,y:r,width:ae,height:ge,durationMs:e.durationMs},width:ae,height:ge}}if(j(e)||H(e)){let n=j(e)?"parallel":"race",a=e.name??n,s=[],u=t+F,c=r+F+20,l=0,p=0;for(let y of e.children){let k=Ye(y,u,c,!0,i);s.push(k.node),u+=k.width+Ge,p=Math.max(p,k.height)}l=u-t-F;let g=Math.max(l+F,ae+F*2),f=p+F*2+20;return{node:{id:e.id,name:a,type:n,state:e.state,x:t,y:r,width:g,height:f,durationMs:e.durationMs,children:s,containerType:n,containerLabel:n==="parallel"?"PARALLEL":"RACE"},width:g,height:f}}if(Y(e)){let n=e.name??"decision",a=[],s=t+F,u=r+F+20,c=0;for(let g of e.branches)for(let f of g.children){let y=Ye(f,s,u,!0,i);a.push(y.node),s+=y.width+Ge,c=Math.max(c,y.height)}let l=Math.max(s-t,ae+F*2),p=c+F*2+20;return{node:{id:e.id,name:n,type:"decision",state:e.state,x:t,y:r,width:l,height:p,durationMs:e.durationMs,children:a,containerType:"decision",containerLabel:"DECISION"},width:l,height:p}}return{node:{id:e.id,name:e.name??"unknown",type:e.type,state:e.state,x:t,y:r,width:ae,height:ge},width:ae,height:ge}}function yt(e,t){return e.containerType?en(e,t):Qr(e,t)}function Qr(e,t){let o=t&&e.durationMs!==void 0?B(e.durationMs):"";return`
1479
+ <g class="wv-node wv-node--${e.state}" data-node-id="${vt(e.id)}" transform="translate(${e.x}, ${e.y})">
1480
+ <rect width="${e.width}" height="${e.height}" rx="8" ry="8" />
1481
+ <text x="${e.width/2}" y="${e.height/2-(o?4:0)}">${Xe(rn(e.name,e.name.includes("[key:")?40:20))}</text>
1482
+ ${o?`<text class="wv-node-timing" x="${e.width/2}" y="${e.height/2+12}">${o}</text>`:""}
1483
+ </g>
1484
+ `}function en(e,t){let o=e.children?.map(i=>yt(i,t)).join(`
1485
+ `)??"";return`
1486
+ <g class="wv-container wv-container--${e.containerType}" data-node-id="${vt(e.id)}" transform="translate(${e.x}, ${e.y})">
1487
+ <rect width="${e.width}" height="${e.height}" rx="12" ry="12" />
1488
+ <text class="wv-container-label" x="${F}" y="16">${e.containerLabel}</text>
1489
+ <g transform="translate(${-e.x}, ${-e.y})">
1490
+ ${o}
1491
+ </g>
1492
+ </g>
1493
+ `}function Je(e,t){for(let r of e){if(r.id===t)return r;if("children"in r&&r.children){let o=Je(r.children,t);if(o)return o}if("branches"in r&&r.branches)for(let o of r.branches){let i=Je(o.children,t);if(i)return i}}}function tn(e,t){let r=[];function o(n,a){if(Math.abs(n.y-a.y)<n.height){let u=n.x+n.width,c=n.y+n.height/2,l=a.x,p=a.y+a.height/2;r.push(`
1494
+ <path class="wv-edge" d="M ${u} ${c} L ${l-8} ${p}" />
1495
+ <polygon class="wv-edge-arrow" points="${l-8},${p-4} ${l-8},${p+4} ${l},${p}" />
1496
+ `)}else{let u=n.x+n.width/2,c=n.y+n.height,l=a.x+a.width/2,p=a.y;r.push(`
1497
+ <path class="wv-edge" d="M ${u} ${c} L ${l} ${p-8}" />
1498
+ <polygon class="wv-edge-arrow" points="${l-4},${p-8} ${l+4},${p-8} ${l},${p}" />
1499
+ `)}}function i(n){for(let a=0;a<n.length-1;a++)o(n[a],n[a+1]);for(let a of n)if(a.children&&a.children.length>0)if(a.containerType==="decision"){let s=Je(t.root.children,a.id);if(s&&s.type==="decision"&&s.branches){let u=0;for(let c of s.branches){let l=c.children.length;l>0&&o(a,a.children[u]);for(let p=0;p<l-1;p++)o(a.children[u+p],a.children[u+p+1]);u+=l}}}else if(a.containerType==="parallel"||a.containerType==="race")for(let s of a.children)s.children&&s.children.length>0&&i([s]);else i(a.children)}return i(e),r.join(`
1500
+ `)}function kt(e,t){let r=Zr(e.root.children,t.layout,t),o=Math.max(r.width,400),i=Math.max(r.height,300),n=r.nodes.map(l=>yt(l,t.showTimings)).join(`
1501
+ `),a=tn(r.nodes,e),s=e.root.name??"Workflow",u=ht(t.theme),c=gt({wsUrl:t.wsUrl,interactive:t.interactive,timeTravel:t.timeTravel,heatmap:t.heatmap});return`<!DOCTYPE html>
1502
+ <html lang="en">
1503
+ <head>
1504
+ <meta charset="UTF-8">
1505
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1506
+ <title>${Xe(s)} - Workflow Visualizer</title>
1507
+ <style>${u}</style>
1508
+ </head>
1509
+ <body>
1510
+ <div class="workflow-visualizer">
1511
+ <header class="wv-header">
1512
+ <h1>${Xe(s)}</h1>
1513
+ <div class="wv-controls">
1514
+ ${t.interactive?`
1515
+ <button id="load-json-btn" class="wv-btn" title="Load workflow state from JSON">Load JSON</button>
1516
+ `:""}
1517
+ ${t.wsUrl?'<div id="live-indicator" class="wv-live" style="display:none"><span class="wv-live-dot"></span>LIVE</div>':""}
1518
+ ${t.heatmap&&t.wsUrl?`
1519
+ <button id="heatmap-toggle" class="wv-btn">Heatmap</button>
1520
+ <select id="heatmap-metric" class="wv-btn">
1521
+ <option value="duration">Duration</option>
1522
+ <option value="retryRate">Retry Rate</option>
1523
+ <option value="errorRate">Error Rate</option>
1524
+ </select>
1525
+ `:""}
1526
+ ${t.interactive?`
1527
+ <button id="zoom-out" class="wv-btn wv-btn--icon" title="Zoom out (-)">\u2212</button>
1528
+ <button id="zoom-reset" class="wv-btn wv-btn--icon" title="Reset zoom (0)">\u27F2</button>
1529
+ <button id="zoom-in" class="wv-btn wv-btn--icon" title="Zoom in (+)">+</button>
1530
+ `:""}
1531
+ </div>
1532
+ </header>
1533
+
1534
+ <div class="wv-main">
1535
+ <div id="diagram" class="wv-diagram">
1536
+ <svg viewBox="0 0 ${o} ${i}" preserveAspectRatio="xMidYMid meet">
1537
+ <g class="wv-root">
1538
+ ${a}
1539
+ ${n}
1540
+ </g>
1541
+ </svg>
1542
+ </div>
1543
+
1544
+ ${t.interactive?`
1545
+ <aside id="inspector" class="wv-inspector">
1546
+ <div class="wv-inspector-header">
1547
+ <h2>Inspector</h2>
1548
+ </div>
1549
+ <div id="inspector-content" class="wv-inspector-content">
1550
+ <p class="wv-empty">Select a node to inspect</p>
1551
+ </div>
1552
+ </aside>
1553
+ `:""}
1554
+ </div>
1555
+
1556
+ ${t.timeTravel?`
1557
+ <div id="timeline" class="wv-timeline">
1558
+ <div class="wv-timeline-track">
1559
+ <input type="range" id="tt-slider" min="0" max="0" value="0" style="width:100%">
1560
+ </div>
1561
+ <div class="wv-timeline-controls">
1562
+ <button id="tt-prev" class="wv-btn wv-btn--icon" title="Step backward (\u2190)">\u23EE</button>
1563
+ <button id="tt-play" class="wv-btn wv-btn--icon" title="Play (Space)">\u25B6</button>
1564
+ <button id="tt-pause" class="wv-btn wv-btn--icon" style="display:none" title="Pause (Space)">\u23F8</button>
1565
+ <button id="tt-next" class="wv-btn wv-btn--icon" title="Step forward (\u2192)">\u23ED</button>
1566
+ <select id="tt-speed" class="wv-btn">
1567
+ <option value="0.5">0.5x</option>
1568
+ <option value="1" selected>1x</option>
1569
+ <option value="2">2x</option>
1570
+ <option value="4">4x</option>
1571
+ <option value="10">10x</option>
1572
+ </select>
1573
+ <span id="tt-time" class="wv-timeline-time">0 / 0</span>
1574
+ </div>
1575
+ </div>
1576
+ `:""}
1577
+ </div>
1578
+
1579
+ ${t.interactive?`
1580
+ <div id="load-json-modal" class="wv-modal" style="display:none">
1581
+ <div class="wv-modal-content">
1582
+ <div class="wv-modal-header">
1583
+ <h2>Load Workflow State</h2>
1584
+ <button id="load-json-close" class="wv-btn wv-btn--icon" title="Close">\xD7</button>
1585
+ </div>
1586
+ <div class="wv-modal-body">
1587
+ <p>Paste the workflow IR JSON (from <code>viz.getIR()</code> or <code>viz.renderAs('json')</code>):</p>
1588
+ <textarea id="load-json-input" class="wv-textarea" rows="15" placeholder='{"root":{"type":"workflow","id":"...","children":[...]}}'></textarea>
1589
+ <div id="load-json-error" class="wv-error" style="display:none"></div>
1590
+ </div>
1591
+ <div class="wv-modal-footer">
1592
+ <button id="load-json-submit" class="wv-btn wv-btn--primary">Load</button>
1593
+ <button id="load-json-cancel" class="wv-btn">Cancel</button>
1594
+ </div>
1595
+ </div>
1596
+ </div>
1597
+ `:""}
1598
+
1599
+ <script>
1600
+ // Check if we have a saved IR in sessionStorage (from Load JSON)
1601
+ (function() {
1602
+ let initialIR = ${wt(nn(e))};
1603
+ try {
1604
+ const savedIR = sessionStorage.getItem('workflow_ir');
1605
+ if (savedIR) {
1606
+ initialIR = JSON.parse(savedIR);
1607
+ sessionStorage.removeItem('workflow_ir'); // Clear after use
1608
+ }
1609
+ } catch (e) {
1610
+ console.warn('Failed to load saved IR:', e);
1611
+ }
1612
+
1613
+ const irObj = typeof initialIR === 'string' ? JSON.parse(initialIR) : initialIR;
1614
+ window.__WORKFLOW_IR__ = irObj;
1615
+
1616
+ // Build workflow data from IR (nodes include input/output; hooks serialized for inspector)
1617
+ function buildWorkflowDataFromIR(ir) {
1618
+ const nodes = {};
1619
+ function collectNodes(flowNodes) {
1620
+ for (const node of flowNodes || []) {
1621
+ nodes[node.id] = {
1622
+ id: node.id,
1623
+ name: node.name,
1624
+ type: node.type,
1625
+ state: node.state,
1626
+ key: node.key,
1627
+ durationMs: node.durationMs,
1628
+ startTs: node.startTs,
1629
+ error: node.error !== undefined && node.error !== null ? String(node.error) : undefined,
1630
+ retryCount: node.retryCount,
1631
+ input: node.input,
1632
+ output: node.output,
1633
+ ...(node.type === "stream" && {
1634
+ namespace: node.namespace,
1635
+ writeCount: node.writeCount,
1636
+ readCount: node.readCount,
1637
+ finalPosition: node.finalPosition,
1638
+ streamState: node.streamState,
1639
+ backpressureOccurred: node.backpressureOccurred,
1640
+ }),
1641
+ ...(node.type === "decision" && {
1642
+ condition: node.condition,
1643
+ decisionValue: node.decisionValue,
1644
+ branchTaken: node.branchTaken,
1645
+ branches: node.branches,
1646
+ }),
1647
+ };
1648
+ if (node.children) collectNodes(node.children);
1649
+ if (node.branches) {
1650
+ for (const branch of node.branches) {
1651
+ collectNodes(branch.children);
1652
+ }
1653
+ }
1654
+ }
1655
+ }
1656
+ collectNodes(ir.root.children);
1657
+ const hooks = ir.hooks
1658
+ ? {
1659
+ ...ir.hooks,
1660
+ onAfterStep:
1661
+ ir.hooks.onAfterStep instanceof Map
1662
+ ? Object.fromEntries(ir.hooks.onAfterStep)
1663
+ : ir.hooks.onAfterStep,
1664
+ }
1665
+ : undefined;
1666
+ return { nodes, hooks };
1667
+ }
1668
+
1669
+ window.__WORKFLOW_DATA__ = buildWorkflowDataFromIR(irObj);
1670
+
1671
+ ${t.heatmapData?`window.__PERFORMANCE_DATA__ = ${wt({heat:Object.fromEntries(t.heatmapData.heat),metric:t.heatmapData.metric,stats:t.heatmapData.stats})};`:""}
1672
+ })();
1673
+ </script>
1674
+ <script>${c}</script>
1675
+ </body>
1676
+ </html>`}function Xe(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function vt(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function rn(e,t){return e.length<=t?e:e.slice(0,t-1)+"\u2026"}function nn(e){if(!e.hooks)return e;let t=e.hooks.onAfterStep instanceof Map?Object.fromEntries(e.hooks.onAfterStep):e.hooks.onAfterStep;return{...e,hooks:{...e.hooks,onAfterStep:t}}}function wt(e){let t=new WeakSet;return JSON.stringify(e,(o,i)=>{if(typeof i=="bigint")return i.toString();if(o==="error"&&i!==void 0&&i!==null)return String(i);if(typeof i=="object"&&i!==null){if(t.has(i))return"[Circular]";t.add(i)}return i}).replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}var xt={interactive:!0,timeTravel:!0,heatmap:!0,animationDuration:200,theme:"auto",layout:"TB"};function St(){return{name:"html",supportsLive:!0,render(e,t){let r={...t,...xt,...t};return kt(e,r)}}}function Rt(e,t={}){let r={showTimings:!0,showKeys:!1,colors:{pending:"#6c757d",running:"#ffc107",success:"#198754",error:"#dc3545",aborted:"#6c757d",cached:"#0dcaf0",skipped:"#adb5bd"},...xt,...t};return kt(e,r)}function We(e,t={}){let{condition:r,value:o,name:i,workflowId:n=crypto.randomUUID(),emit:a}=t,s=Date.now(),u,c=[];function l(g,f,y){c.push({label:g,condition:y,taken:f}),f&&(u=g),a?.({type:"decision_branch",workflowId:n,decisionId:e,branchLabel:g,condition:y,taken:f,ts:Date.now()})}function p(){let g=Date.now()-s;a?.({type:"decision_end",workflowId:n,decisionId:e,branchTaken:u,ts:Date.now(),durationMs:g})}return a?.({type:"decision_start",workflowId:n,decisionId:e,condition:r,decisionValue:o,name:i,ts:s}),{takeBranch:l,end:p,getBranchTaken:()=>u,getBranches:()=>[...c]}}function It(e,t,r={}){let o=We(e,{...r,condition:r.condition??String(t),value:r.value??t}),i=!1;return{...o,condition:t,then:()=>{i||(i=!0,o.takeBranch("if",!0),o.takeBranch("else",!1))},else:()=>{i||(i=!0,o.takeBranch("if",!1),o.takeBranch("else",!0))}}}function $t(e,t,r={}){let o=We(e,{...r,condition:r.condition??`switch(${String(t)})`,value:t});return{...o,value:t,case:(i,n)=>{o.takeBranch(`case '${i}'`,n,`value === '${i}'`)},default:i=>{o.takeBranch("default",i)}}}function Et(e={}){let{maxSnapshots:t=1e3,autoRecord:r=!0,builderOptions:o={}}=e,i=ue({...o,enableSnapshots:!0,maxSnapshots:t}),n={snapshots:[],currentIndex:-1,isPlaying:!1,playbackSpeed:1,isRecording:r},a=new Set,s=null;function u(){let E=v();for(let T of a)T(E)}function c(){n.snapshots=i.getSnapshots(),n.isRecording&&n.snapshots.length>0&&(n.currentIndex=n.snapshots.length-1)}function l(E){i.handleEvent(E),n.isRecording&&(c(),u())}function p(E){let T=i.getSnapshots();if(!(E<0||E>=T.length))return n.currentIndex=E,n.snapshots=T,u(),T[E].ir}function g(){return p(n.currentIndex+1)}function f(){return p(n.currentIndex-1)}function y(E=1){let T=i.getSnapshots();if(T.length===0)return;n.currentIndex===-1&&(n.currentIndex=0,n.snapshots=T),n.playbackSpeed=E,n.isPlaying=!0,u();let P=()=>{if(!n.isPlaying)return;let K=i.getSnapshots();if(n.currentIndex<K.length-1){let _=K[n.currentIndex],ie=(K[n.currentIndex+1].timestamp-_.timestamp)/n.playbackSpeed;s=setTimeout(()=>{g(),P()},Math.max(16,ie))}else k()};P()}function k(){n.isPlaying=!1,s&&(clearTimeout(s),s=null),u()}function $(){let E=i.getSnapshots();return n.currentIndex>=0&&n.currentIndex<E.length?E[n.currentIndex].ir:i.getIR()}function M(E){return i.getIRAt(E)}function N(){return i.getSnapshots()}function I(E){return i.getSnapshotAt(E)}function v(){return{snapshots:i.getSnapshots(),currentIndex:n.currentIndex,isPlaying:n.isPlaying,playbackSpeed:n.playbackSpeed,isRecording:n.isRecording}}function x(E){return a.add(E),()=>a.delete(E)}function m(){n.isRecording=!0,i.setSnapshotsEnabled(!0),c(),u()}function w(){n.isRecording=!1,i.setSnapshotsEnabled(!1),u()}function R(){k(),i.reset(),i.setSnapshotsEnabled(r),n={snapshots:[],currentIndex:-1,isPlaying:!1,playbackSpeed:1,isRecording:r},u()}function D(){return i}return{handleEvent:l,seek:p,stepForward:g,stepBackward:f,play:y,pause:k,getCurrentIR:$,getIRAt:M,getSnapshots:N,getSnapshotAt:I,getState:v,onStateChange:x,startRecording:m,stopRecording:w,reset:R,getBuilder:D}}var Nt=qt(require("pako"),1),on=typeof globalThis<"u"&&"Buffer"in globalThis&&typeof globalThis.Buffer=="function";function an(e){let t;if(on)t=globalThis.Buffer.from(e).toString("base64");else{let r="";for(let o=0;o<e.length;o++)r+=String.fromCharCode(e[o]);t=btoa(r)}return t.replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Be(e){let r=new TextEncoder().encode(e),o=Nt.default.deflate(r);return an(o)}var Mt="https://kroki.io";function sn(e,t,r,o={}){let i=o.baseUrl??Mt,n=Be(r);return`${i}/${e}/${t}/${n}`}function se(e,t="svg",r={}){let o=te(),i={showTimings:!0,showKeys:!1,terminalWidth:80,colors:V},n=o.render(e,i);return sn("mermaid",t,n,r)}function Tt(e,t={}){return se(e,"svg",t)}function Ot(e,t={}){return se(e,"png",t)}function Dt(e={}){let t=e.baseUrl??Mt;return{toUrl(r,o){return se(r,o,{baseUrl:t})},toSvgUrl(r){return se(r,"svg",{baseUrl:t})},toPngUrl(r){return se(r,"png",{baseUrl:t})},toPdfUrl(r){return se(r,"pdf",{baseUrl:t})},getBaseUrl(){return t}}}var Ct="https://mermaid.ink";function qe(e){return`pako:${Be(e)}`}function cn(e){if("provider"in e){let t=e;return{theme:t.mermaidTheme,bgColor:t.background,scale:t.scale,fit:t.fit,width:t.width,height:t.height,paper:t.paper,imageType:"png"}}return e}function dn(e,t){let r=[];return t.bgColor&&r.push(`bgColor=${encodeURIComponent(t.bgColor)}`),t.theme&&r.push(`theme=${t.theme}`),t.width!==void 0&&r.push(`width=${t.width}`),t.height!==void 0&&r.push(`height=${t.height}`),t.scale!==void 0&&(t.width!==void 0||t.height!==void 0)&&r.push(`scale=${t.scale}`),e==="img"&&t.imageType&&t.imageType!=="jpeg"&&r.push(`type=${t.imageType}`),e==="pdf"&&(t.fit&&r.push("fit"),t.paper&&!t.fit&&r.push(`paper=${t.paper}`),t.landscape&&!t.fit&&r.push("landscape")),r.length>0?`?${r.join("&")}`:""}function Ze(e,t,r={}){let o=cn(r),i=o.baseUrl??Ct,n=qe(t),a=dn(e,o);return`${i}/${e}/${n}${a}`}function G(e,t="svg",r={}){let o=te(),i={showTimings:!0,showKeys:!1,terminalWidth:80,colors:V},n=o.render(e,i);return Ze(t,n,r)}function Lt(e,t={}){return G(e,"svg",t)}function _t(e,t={}){return G(e,"img",{...t,imageType:"png"})}function Wt(e,t={}){return G(e,"img",{...t,imageType:"jpeg"})}function Bt(e,t={}){return G(e,"img",{...t,imageType:"webp"})}function At(e,t={}){return G(e,"pdf",t)}function Pt(e={}){let t=e.baseUrl??Ct;return{toUrl(r,o){return G(r,o,e)},toSvgUrl(r){return G(r,"svg",e)},toPngUrl(r){return G(r,"img",{...e,imageType:"png"})},toJpegUrl(r){return G(r,"img",{...e,imageType:"jpeg"})},toWebpUrl(r){return G(r,"img",{...e,imageType:"webp"})},toPdfUrl(r){return G(r,"pdf",e)},getBaseUrl(){return t},getOptions(){return{...e}}}}var ln=()=>{throw new Error("createLiveVisualizer is not available in browser. It requires Node.js process.stdout.")};function Ae(e={}){let{workflowName:t,detectParallel:r=!0,showTimings:o=!0,showKeys:i=!1,colors:n}=e,a=ue({detectParallel:r}),s=new Set,u=ce(),c=te(),l=ke(),p=le(),g={showTimings:o,showKeys:i,terminalWidth:80,colors:{...V,...n}};function f(){if(s.size>0){let m=a.getIR();for(let w of s)w(m)}}function y(m){if(m.type==="scope_start"||m.type==="scope_end"){k(m);return}a.handleEvent(m),m.type,f()}function k(m){a.handleScopeEvent(m),f()}function $(m){a.handleDecisionEvent(m),f()}function M(){let m=a.getIR();return t&&!m.root.name&&(m.root.name=t),m}function N(){let m=M();return u.render(m,g)}function I(m){let w=M();switch(m){case"ascii":return u.render(w,g);case"mermaid":return c.render(w,g);case"json":{let R=w.hooks?{...w,hooks:{...w.hooks,onAfterStep:w.hooks.onAfterStep instanceof Map?Object.fromEntries(w.hooks.onAfterStep):w.hooks.onAfterStep??{}}}:w;return JSON.stringify(R,(E,T)=>typeof T=="bigint"?T.toString():T,2)}case"logger":return l.render(w,g);case"flowchart":return p.render(w,g);default:throw new Error(`Unknown format: ${m}`)}}function v(){a.reset(),f()}function x(m){return s.add(m),()=>s.delete(m)}return{handleEvent:y,handleScopeEvent:k,handleDecisionEvent:$,getIR:M,render:N,renderAs:I,reset:v,onUpdate:x}}function un(...e){return(t,r)=>{for(let o of e)o(t,r)}}function pn(e,t={}){let r=Ae(t);for(let o of e)o.type.startsWith("decision_")?r.handleDecisionEvent(o):r.handleEvent(o);return r.render()}function fn(e={}){let t=[];return{handleEvent:r=>{t.push(r)},handleDecisionEvent:r=>{t.push(r)},getEvents:()=>[...t],getWorkflowEvents:()=>t.filter(r=>!r.type.startsWith("decision_")),getDecisionEvents:()=>t.filter(r=>r.type.startsWith("decision_")),clear:()=>{t.length=0},visualize:()=>{let r=Ae(e);for(let o of t)o.type.startsWith("decision_")?r.handleDecisionEvent(o):r.handleEvent(o);return r.render()},visualizeAs:r=>{let o=Ae(e);for(let i of t)i.type.startsWith("decision_")?o.handleDecisionEvent(i):o.handleEvent(i);return o.renderAs(r)}}}0&&(module.exports={asciiRenderer,buildMermaidInkUrl,combineEventHandlers,createEventCollector,createIRBuilder,createLiveVisualizer,createMermaidInkGenerator,createParallelDetector,createPerformanceAnalyzer,createTimeTravelController,createUrlGenerator,createVisualizer,defaultColorScheme,detectParallelGroups,encodeForMermaidInk,flowchartRenderer,getHeatLevel,hasChildren,htmlRenderer,isDecisionNode,isParallelNode,isRaceNode,isSequenceNode,isStepNode,isStreamNode,loggerRenderer,mermaidRenderer,renderToHTML,toKrokiPngUrl,toKrokiSvgUrl,toKrokiUrl,toMermaidInkJpegUrl,toMermaidInkPdfUrl,toMermaidInkPngUrl,toMermaidInkSvgUrl,toMermaidInkUrl,toMermaidInkWebpUrl,trackDecision,trackIf,trackSwitch,visualizeEvents});
1677
+ //# sourceMappingURL=index.browser.cjs.map