@spencerboucher/switchyard 0.4.0 → 0.5.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 (39) hide show
  1. package/README.md +5 -4
  2. package/dist/bridge/switchyard-terminal.js +527 -0
  3. package/dist/switchyard.mjs +3471 -1846
  4. package/dist/terminal/holder.js +305 -0
  5. package/package.json +6 -3
  6. package/web-dist/assets/{AutomationView-BhEfjAtI.js → AutomationView-CFohp0SQ.js} +2 -2
  7. package/web-dist/assets/{AutomationView-BhEfjAtI.js.map → AutomationView-CFohp0SQ.js.map} +1 -1
  8. package/web-dist/assets/{InteractionCard-DxEZUNrD.js → InteractionCard-B-xmpTNG.js} +2 -2
  9. package/web-dist/assets/{InteractionCard-DxEZUNrD.js.map → InteractionCard-B-xmpTNG.js.map} +1 -1
  10. package/web-dist/assets/{Overlay-C-GqmwUn.js → Overlay--v0ur2lj.js} +2 -2
  11. package/web-dist/assets/{Overlay-C-GqmwUn.js.map → Overlay--v0ur2lj.js.map} +1 -1
  12. package/web-dist/assets/{attention-Dzqdk9Gz.js → attention-q6_xlnT4.js} +2 -2
  13. package/web-dist/assets/{attention-Dzqdk9Gz.js.map → attention-q6_xlnT4.js.map} +1 -1
  14. package/web-dist/assets/{automations-DzTTwxBl.js → automations-CyA83OAD.js} +2 -2
  15. package/web-dist/assets/{automations-DzTTwxBl.js.map → automations-CyA83OAD.js.map} +1 -1
  16. package/web-dist/assets/{board-C5mG_8rg.js → board-BFvNcFhk.js} +2 -2
  17. package/web-dist/assets/{board-C5mG_8rg.js.map → board-BFvNcFhk.js.map} +1 -1
  18. package/web-dist/assets/{code-9shyh1Gw.js → code-DavnmlQN.js} +2 -2
  19. package/web-dist/assets/{code-9shyh1Gw.js.map → code-DavnmlQN.js.map} +1 -1
  20. package/web-dist/assets/{describe-BbCZVvJP.js → describe-BirsjlUl.js} +2 -2
  21. package/web-dist/assets/{describe-BbCZVvJP.js.map → describe-BirsjlUl.js.map} +1 -1
  22. package/web-dist/assets/dist-C-h8FC-n.js +56 -0
  23. package/web-dist/assets/dist-C-h8FC-n.js.map +1 -0
  24. package/web-dist/assets/{enroll-DWJANJtw.js → enroll-C7UBC20s.js} +2 -2
  25. package/web-dist/assets/{enroll-DWJANJtw.js.map → enroll-C7UBC20s.js.map} +1 -1
  26. package/web-dist/assets/{index-afOJ8NRR.js → index-IdzOP9GE.js} +3 -3
  27. package/web-dist/assets/{index-afOJ8NRR.js.map → index-IdzOP9GE.js.map} +1 -1
  28. package/web-dist/assets/{more-B6qxC6M-.js → more-syTnSpW3.js} +2 -2
  29. package/web-dist/assets/{more-B6qxC6M-.js.map → more-syTnSpW3.js.map} +1 -1
  30. package/web-dist/assets/{now-BOWxgbt3.js → now-BqsLS-tK.js} +2 -2
  31. package/web-dist/assets/{now-BOWxgbt3.js.map → now-BqsLS-tK.js.map} +1 -1
  32. package/web-dist/assets/{settings-BpkmIv_4.js → settings-DRj7UPtP.js} +2 -2
  33. package/web-dist/assets/{settings-BpkmIv_4.js.map → settings-DRj7UPtP.js.map} +1 -1
  34. package/web-dist/assets/{useNow-D9Zxr5Jb.js → useNow-BQpDYijR.js} +2 -2
  35. package/web-dist/assets/{useNow-D9Zxr5Jb.js.map → useNow-BQpDYijR.js.map} +1 -1
  36. package/web-dist/index.html +1 -1
  37. package/web-dist/sw.js +1 -1
  38. package/web-dist/assets/dist-PaQekTP8.js +0 -56
  39. package/web-dist/assets/dist-PaQekTP8.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import{_ as e,m as t,n,t as r}from"./jsx-runtime-D13aM9HY.js";import{H as i,P as a,T as o,U as s,W as c,g as l,h as u,m as d,q as f,u as ee}from"./states-DrTQuYXw.js";import{I as te,O as ne,c as p}from"./index-afOJ8NRR.js";import{n as m}from"./dist-PaQekTP8.js";var h={name:`octagon-alert`,size:24,node:[[`path`,{d:`M12 16h.01`,key:`1drbdi`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z`,key:`1fd625`}]],aliases:[`alert-octagon`]};h.node;var re=n(h),g={name:`signal-high`,size:24,node:[[`path`,{d:`M2 20h.01`,key:`4haj6o`}],[`path`,{d:`M7 20v-4`,key:`j294jx`}],[`path`,{d:`M12 20v-8`,key:`i3yub9`}],[`path`,{d:`M17 20V8`,key:`1tkaf5`}]]};g.node;var ie=n(g),_={name:`signal-low`,size:24,node:[[`path`,{d:`M2 20h.01`,key:`4haj6o`}],[`path`,{d:`M7 20v-4`,key:`j294jx`}]]};_.node;var ae=n(_),v={name:`signal-medium`,size:24,node:[[`path`,{d:`M2 20h.01`,key:`4haj6o`}],[`path`,{d:`M7 20v-4`,key:`j294jx`}],[`path`,{d:`M12 20v-8`,key:`i3yub9`}]]};v.node;var y=n(v),b=e(t(),1),x=r();function oe({label:e,hint:t,error:n,children:r,className:i,optional:a}){let o=(0,b.useId)(),s=`${o}-hint`,c=`${o}-err`,l=[t?s:null,n?c:null].filter(Boolean).join(` `);return(0,x.jsxs)(`div`,{className:u(`flex min-w-0 flex-col gap-1`,i),children:[(0,x.jsxs)(`label`,{htmlFor:o,className:`text-sm font-medium`,children:[e,a&&(0,x.jsx)(`span`,{className:`font-normal text-muted`,children:` (optional)`})]}),r({id:o,"aria-invalid":n?!0:void 0,"aria-describedby":l||void 0}),t&&(0,x.jsx)(`p`,{id:s,className:`text-xs text-muted`,children:t}),n&&(0,x.jsx)(S,{id:c,children:n})]})}function S({id:e,children:t}){return(0,x.jsxs)(`p`,{id:e,className:`flex items-start gap-1 text-xs text-danger`,"data-field-error":!0,children:[(0,x.jsx)(l,{"aria-hidden":!0,className:`mt-0.5 size-3.5 shrink-0`}),(0,x.jsx)(`span`,{children:t})]})}function se({className:e,children:t,...n}){return(0,x.jsx)(`select`,{className:u(`tap block h-9 w-full min-w-0 rounded-md border border-border bg-surface px-2.5 text-base text-text md:text-sm`,`focus:border-accent focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-0`,`aria-[invalid=true]:border-danger`,e),...n,children:t})}function ce({checked:e,onChange:t,label:n,onText:r=`On`,offText:i=`Off`,busy:a,disabled:o,id:s,className:c}){return(0,x.jsxs)(`button`,{id:s,type:`button`,role:`switch`,"aria-checked":e,"aria-label":n,"aria-busy":a||void 0,disabled:o||a,onClick:()=>t(!e),className:u(`tap inline-flex min-h-9 shrink-0 items-center gap-2 rounded-md px-1.5 text-sm`,`hover:bg-surface-2 disabled:opacity-60`,c),children:[(0,x.jsx)(`span`,{"aria-hidden":!0,className:u(`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border transition-colors`,e?`border-accent bg-accent`:`border-border-strong bg-surface-2`),children:(0,x.jsx)(`span`,{className:u(`absolute size-3.5 rounded-full shadow-sm transition-transform`,e?`translate-x-[18px] bg-accent-fg`:`translate-x-[2px] bg-muted`)})}),a?(0,x.jsx)(ee,{className:`size-3.5`}):null,(0,x.jsx)(`span`,{className:e?`text-text`:`text-muted`,children:e?r:i})]})}function le({title:e,description:t,children:n,actions:r,className:i,testId:a}){let o=(0,b.useId)();return(0,x.jsxs)(`section`,{"aria-labelledby":o,"data-testid":a,className:u(`min-w-0 rounded-lg border border-border bg-surface p-4`,i),children:[(0,x.jsxs)(`div`,{className:`mb-3 flex flex-wrap items-start justify-between gap-2`,children:[(0,x.jsxs)(`div`,{className:`min-w-0`,children:[(0,x.jsx)(`h2`,{id:o,className:`text-base font-semibold`,children:e}),t&&(0,x.jsx)(`p`,{className:`text-sm text-muted`,children:t})]}),r&&(0,x.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:r})]}),(0,x.jsx)(`div`,{className:`flex flex-col gap-4`,children:n})]})}var ue=[re,ie,y,ae];function de({priority:e,className:t}){let n=ue[e]??y;return(0,x.jsx)(n,{"aria-hidden":!0,className:u(`size-4 shrink-0`,e===0?`text-danger`:`text-muted`,t)})}function fe({count:e}){return e>0?(0,x.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-sm text-warning`,children:[(0,x.jsx)(l,{"aria-hidden":!0,className:`size-4 shrink-0`}),e===1?`1 failure`:`${e} failures`]}):(0,x.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-sm text-muted`,children:[(0,x.jsx)(te,{"aria-hidden":!0,className:`size-4 shrink-0`}),`No failures`]})}function pe({className:e}){let t=o();return t.state===`live`||t.state===`connecting`&&!t.lastSyncedAt?null:(0,x.jsxs)(`p`,{role:`status`,className:u(`flex items-start gap-1.5 rounded-md border border-border bg-warning-soft px-3 py-1.5 text-sm`,e),children:[(0,x.jsx)(ne,{"aria-hidden":!0,className:`mt-0.5 size-4 shrink-0 text-warning`}),(0,x.jsxs)(`span`,{children:[`Showing last known automations`,t.lastSyncedAt?` from ${d(t.lastSyncedAt)}`:``,`. Changes are sent once the coordinator is reachable again.`]})]})}var C=(e,t=``)=>`/api/automations/${encodeURIComponent(e)}${t}`,w=f()(e=>({byId:{},deleted:{},put:t=>e(e=>({byId:{...e.byId,[t.id]:t}})),putMany:t=>e(e=>{let n={...e.byId};for(let e of t)n[e.id]=e;return{byId:n}}),remove:t=>e(e=>{let n={...e.byId};return delete n[t],{byId:n,deleted:{...e.deleted,[t]:!0}}})}));function T(e,t){return e?t&&t.updatedAt>e.updatedAt?t:e:t}function me(){let e=a(e=>e.automations),t=w(e=>e.byId),n=w(e=>e.deleted);return(0,b.useMemo)(()=>{let r={};for(let i of new Set([...Object.keys(e),...Object.keys(t)])){if(n[i])continue;let a=T(e[i],t[i]);a&&(r[i]=a)}return r},[e,t,n])}function he(e){let t=a(t=>e?t.automations[e]:void 0),n=w(t=>e?t.byId[e]:void 0);return w(t=>e?t.deleted[e]:void 0)?void 0:T(t,n)}function ge(){let[e,t]=(0,b.useState)({});return{busy:e,toggle:(0,b.useCallback)(async(e,n)=>{t(t=>({...t,[e.id]:!0}));try{let t=await i(C(e.id),{enabled:n});t&&typeof t==`object`&&`id`in t&&w.getState().put(t),p.success(`${e.name} ${n?`enabled`:`disabled`}`)}catch(t){p.error(`Could not ${n?`enable`:`disable`} ${e.name}: ${c(t)}`)}finally{t(t=>({...t,[e.id]:!1}))}},[])}}function _e(e){let[t,n]=(0,b.useState)({});return{busy:t,run:(0,b.useCallback)(async t=>{n(e=>({...e,[t.id]:!0}));try{let n=await s(C(t.id,`/run`)),r=n&&typeof n==`object`?n.state:void 0;p.success(r&&r!==`fired`?`${t.name}: occurrence recorded (${r.replace(/_/g,` `)})`:`${t.name} started`),e?.()}catch(e){p.error(`Could not run ${t.name}: ${c(e)}`)}finally{n(e=>({...e,[t.id]:!1}))}},[e])}}var ve={manual:`Manual`,once:`Once`,cron:`Schedule`,webhook:`Webhook`,dependency:`Dependency`},E=[{value:`fresh`,label:`Fresh`,explanation:`Fresh: a new task per occurrence`},{value:`continue`,label:`Continue`,explanation:`Continue: reuse the task with the same grouping key`},{value:`watch`,label:`Watch`,explanation:`Watch: only raises attention when something relevant changed`}],ye=[{value:`skip`,label:`Skip`,explanation:`Skip: drop the occurrence while earlier work is still open`},{value:`queue_one`,label:`Queue one`,explanation:`Queue one: keep a single pending occurrence and fire it when the open work ends`},{value:`append`,label:`Append`,explanation:`Append: add the new objective to the open task (as a follow-up if it is running)`}],D=[{value:`skip`,label:`Skip`,explanation:`Skip: occurrences missed while the coordinator was down are recorded and skipped`},{value:`run_once`,label:`Run once`,explanation:`Run once: on return, fire the newest missed occurrence once`}];function O(e){return E.find(t=>t.value===e)?.label??e}var k=[`{{date}}`,`{{time}}`,`{{occurrence}}`,`{{payload.<path>}}`];function A(e){return e.length<=1?e[0]??``:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`}function j(e){return String(e).padStart(2,`0`)}function M(e){let t=e%100;if(t>=11&&t<=13)return`${e}th`;switch(e%10){case 1:return`${e}st`;case 2:return`${e}nd`;case 3:return`${e}rd`;default:return`${e}th`}}function N(e){return e&&e[0].toUpperCase()+e.slice(1)}function P(e){return e.split(`
1
+ import{_ as e,m as t,n,t as r}from"./jsx-runtime-D13aM9HY.js";import{H as i,P as a,T as o,U as s,W as c,g as l,h as u,m as d,q as f,u as ee}from"./states-DrTQuYXw.js";import{I as te,O as ne,c as p}from"./index-IdzOP9GE.js";import{n as m}from"./dist-C-h8FC-n.js";var h={name:`octagon-alert`,size:24,node:[[`path`,{d:`M12 16h.01`,key:`1drbdi`}],[`path`,{d:`M12 8v4`,key:`1got3b`}],[`path`,{d:`M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z`,key:`1fd625`}]],aliases:[`alert-octagon`]};h.node;var re=n(h),g={name:`signal-high`,size:24,node:[[`path`,{d:`M2 20h.01`,key:`4haj6o`}],[`path`,{d:`M7 20v-4`,key:`j294jx`}],[`path`,{d:`M12 20v-8`,key:`i3yub9`}],[`path`,{d:`M17 20V8`,key:`1tkaf5`}]]};g.node;var ie=n(g),_={name:`signal-low`,size:24,node:[[`path`,{d:`M2 20h.01`,key:`4haj6o`}],[`path`,{d:`M7 20v-4`,key:`j294jx`}]]};_.node;var ae=n(_),v={name:`signal-medium`,size:24,node:[[`path`,{d:`M2 20h.01`,key:`4haj6o`}],[`path`,{d:`M7 20v-4`,key:`j294jx`}],[`path`,{d:`M12 20v-8`,key:`i3yub9`}]]};v.node;var y=n(v),b=e(t(),1),x=r();function oe({label:e,hint:t,error:n,children:r,className:i,optional:a}){let o=(0,b.useId)(),s=`${o}-hint`,c=`${o}-err`,l=[t?s:null,n?c:null].filter(Boolean).join(` `);return(0,x.jsxs)(`div`,{className:u(`flex min-w-0 flex-col gap-1`,i),children:[(0,x.jsxs)(`label`,{htmlFor:o,className:`text-sm font-medium`,children:[e,a&&(0,x.jsx)(`span`,{className:`font-normal text-muted`,children:` (optional)`})]}),r({id:o,"aria-invalid":n?!0:void 0,"aria-describedby":l||void 0}),t&&(0,x.jsx)(`p`,{id:s,className:`text-xs text-muted`,children:t}),n&&(0,x.jsx)(S,{id:c,children:n})]})}function S({id:e,children:t}){return(0,x.jsxs)(`p`,{id:e,className:`flex items-start gap-1 text-xs text-danger`,"data-field-error":!0,children:[(0,x.jsx)(l,{"aria-hidden":!0,className:`mt-0.5 size-3.5 shrink-0`}),(0,x.jsx)(`span`,{children:t})]})}function se({className:e,children:t,...n}){return(0,x.jsx)(`select`,{className:u(`tap block h-9 w-full min-w-0 rounded-md border border-border bg-surface px-2.5 text-base text-text md:text-sm`,`focus:border-accent focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-0`,`aria-[invalid=true]:border-danger`,e),...n,children:t})}function ce({checked:e,onChange:t,label:n,onText:r=`On`,offText:i=`Off`,busy:a,disabled:o,id:s,className:c}){return(0,x.jsxs)(`button`,{id:s,type:`button`,role:`switch`,"aria-checked":e,"aria-label":n,"aria-busy":a||void 0,disabled:o||a,onClick:()=>t(!e),className:u(`tap inline-flex min-h-9 shrink-0 items-center gap-2 rounded-md px-1.5 text-sm`,`hover:bg-surface-2 disabled:opacity-60`,c),children:[(0,x.jsx)(`span`,{"aria-hidden":!0,className:u(`relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border transition-colors`,e?`border-accent bg-accent`:`border-border-strong bg-surface-2`),children:(0,x.jsx)(`span`,{className:u(`absolute size-3.5 rounded-full shadow-sm transition-transform`,e?`translate-x-[18px] bg-accent-fg`:`translate-x-[2px] bg-muted`)})}),a?(0,x.jsx)(ee,{className:`size-3.5`}):null,(0,x.jsx)(`span`,{className:e?`text-text`:`text-muted`,children:e?r:i})]})}function le({title:e,description:t,children:n,actions:r,className:i,testId:a}){let o=(0,b.useId)();return(0,x.jsxs)(`section`,{"aria-labelledby":o,"data-testid":a,className:u(`min-w-0 rounded-lg border border-border bg-surface p-4`,i),children:[(0,x.jsxs)(`div`,{className:`mb-3 flex flex-wrap items-start justify-between gap-2`,children:[(0,x.jsxs)(`div`,{className:`min-w-0`,children:[(0,x.jsx)(`h2`,{id:o,className:`text-base font-semibold`,children:e}),t&&(0,x.jsx)(`p`,{className:`text-sm text-muted`,children:t})]}),r&&(0,x.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:r})]}),(0,x.jsx)(`div`,{className:`flex flex-col gap-4`,children:n})]})}var ue=[re,ie,y,ae];function de({priority:e,className:t}){let n=ue[e]??y;return(0,x.jsx)(n,{"aria-hidden":!0,className:u(`size-4 shrink-0`,e===0?`text-danger`:`text-muted`,t)})}function fe({count:e}){return e>0?(0,x.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-sm text-warning`,children:[(0,x.jsx)(l,{"aria-hidden":!0,className:`size-4 shrink-0`}),e===1?`1 failure`:`${e} failures`]}):(0,x.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-sm text-muted`,children:[(0,x.jsx)(te,{"aria-hidden":!0,className:`size-4 shrink-0`}),`No failures`]})}function pe({className:e}){let t=o();return t.state===`live`||t.state===`connecting`&&!t.lastSyncedAt?null:(0,x.jsxs)(`p`,{role:`status`,className:u(`flex items-start gap-1.5 rounded-md border border-border bg-warning-soft px-3 py-1.5 text-sm`,e),children:[(0,x.jsx)(ne,{"aria-hidden":!0,className:`mt-0.5 size-4 shrink-0 text-warning`}),(0,x.jsxs)(`span`,{children:[`Showing last known automations`,t.lastSyncedAt?` from ${d(t.lastSyncedAt)}`:``,`. Changes are sent once the coordinator is reachable again.`]})]})}var C=(e,t=``)=>`/api/automations/${encodeURIComponent(e)}${t}`,w=f()(e=>({byId:{},deleted:{},put:t=>e(e=>({byId:{...e.byId,[t.id]:t}})),putMany:t=>e(e=>{let n={...e.byId};for(let e of t)n[e.id]=e;return{byId:n}}),remove:t=>e(e=>{let n={...e.byId};return delete n[t],{byId:n,deleted:{...e.deleted,[t]:!0}}})}));function T(e,t){return e?t&&t.updatedAt>e.updatedAt?t:e:t}function me(){let e=a(e=>e.automations),t=w(e=>e.byId),n=w(e=>e.deleted);return(0,b.useMemo)(()=>{let r={};for(let i of new Set([...Object.keys(e),...Object.keys(t)])){if(n[i])continue;let a=T(e[i],t[i]);a&&(r[i]=a)}return r},[e,t,n])}function he(e){let t=a(t=>e?t.automations[e]:void 0),n=w(t=>e?t.byId[e]:void 0);return w(t=>e?t.deleted[e]:void 0)?void 0:T(t,n)}function ge(){let[e,t]=(0,b.useState)({});return{busy:e,toggle:(0,b.useCallback)(async(e,n)=>{t(t=>({...t,[e.id]:!0}));try{let t=await i(C(e.id),{enabled:n});t&&typeof t==`object`&&`id`in t&&w.getState().put(t),p.success(`${e.name} ${n?`enabled`:`disabled`}`)}catch(t){p.error(`Could not ${n?`enable`:`disable`} ${e.name}: ${c(t)}`)}finally{t(t=>({...t,[e.id]:!1}))}},[])}}function _e(e){let[t,n]=(0,b.useState)({});return{busy:t,run:(0,b.useCallback)(async t=>{n(e=>({...e,[t.id]:!0}));try{let n=await s(C(t.id,`/run`)),r=n&&typeof n==`object`?n.state:void 0;p.success(r&&r!==`fired`?`${t.name}: occurrence recorded (${r.replace(/_/g,` `)})`:`${t.name} started`),e?.()}catch(e){p.error(`Could not run ${t.name}: ${c(e)}`)}finally{n(e=>({...e,[t.id]:!1}))}},[e])}}var ve={manual:`Manual`,once:`Once`,cron:`Schedule`,webhook:`Webhook`,dependency:`Dependency`},E=[{value:`fresh`,label:`Fresh`,explanation:`Fresh: a new task per occurrence`},{value:`continue`,label:`Continue`,explanation:`Continue: reuse the task with the same grouping key`},{value:`watch`,label:`Watch`,explanation:`Watch: only raises attention when something relevant changed`}],ye=[{value:`skip`,label:`Skip`,explanation:`Skip: drop the occurrence while earlier work is still open`},{value:`queue_one`,label:`Queue one`,explanation:`Queue one: keep a single pending occurrence and fire it when the open work ends`},{value:`append`,label:`Append`,explanation:`Append: add the new objective to the open task (as a follow-up if it is running)`}],D=[{value:`skip`,label:`Skip`,explanation:`Skip: occurrences missed while the coordinator was down are recorded and skipped`},{value:`run_once`,label:`Run once`,explanation:`Run once: on return, fire the newest missed occurrence once`}];function O(e){return E.find(t=>t.value===e)?.label??e}var k=[`{{date}}`,`{{time}}`,`{{occurrence}}`,`{{payload.<path>}}`];function A(e){return e.length<=1?e[0]??``:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`}function j(e){return String(e).padStart(2,`0`)}function M(e){let t=e%100;if(t>=11&&t<=13)return`${e}th`;switch(e%10){case 1:return`${e}st`;case 2:return`${e}nd`;case 3:return`${e}rd`;default:return`${e}th`}}function N(e){return e&&e[0].toUpperCase()+e.slice(1)}function P(e){return e.split(`
2
2
  `).map(e=>e.trim()).filter(e=>e.length>0)}var F=[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`],I=[`January`,`February`,`March`,`April`,`May`,`June`,`July`,`August`,`September`,`October`,`November`,`December`],be=[{name:`Minute`,min:0,max:59},{name:`Hour`,min:0,max:23},{name:`Day of month`,min:1,max:31},{name:`Month`,min:1,max:12,names:I.map(e=>e.slice(0,3).toLowerCase())},{name:`Day of week`,min:0,max:7,names:F.map(e=>e.slice(0,3).toLowerCase())}];function L(e,t){let n=e.toLowerCase();if(t.names){let e=t.names.indexOf(n);if(e>=0)return t.min+e}if(!/^\d+$/.test(e))return`"${e}" is not a number`;let r=Number(e);return r<t.min||r>t.max?`${r} is out of range ${t.min}–${t.max}`:r}function xe(e,t){if(e===`*`||e===`?`)return{any:!0,values:[],step:null,extended:!1};if(/[LW#]/i.test(e)&&!t.names?.some(t=>e.toLowerCase().includes(t)))return/^[0-9A-Za-z*?,\-/#]+$/.test(e)?{any:!1,values:[],step:null,extended:!0}:`"${e}" is not valid`;let n=e.split(`,`),r=new Set,i=null;for(let e of n){if(!e)return`empty list item`;let[a,o,s]=e.split(`/`);if(s!==void 0)return`"${e}" has more than one step`;let c=1;if(o!==void 0){if(!/^\d+$/.test(o)||Number(o)<1)return`"${o}" is not a valid step`;c=Number(o)}let l,u;if(a===`*`||a===`?`)l=t.min,u=t.max;else if(a?.includes(`-`)){let[e,n]=a.split(`-`),r=L(e??``,t),i=L(n??``,t);if(typeof r==`string`)return r;if(typeof i==`string`)return i;if(r>i)return`range ${a} runs backwards`;l=r,u=i}else{let e=L(a??``,t);if(typeof e==`string`)return e;l=e,u=o===void 0?e:t.max}for(let e=l;e<=u;e+=c)r.add(e);n.length===1&&o!==void 0&&!a?.includes(`-`)&&(i={every:c,start:l})}let a=[...r].sort((e,t)=>e-t);t.max===7&&(a=[...new Set(a.map(e=>e%7))].sort((e,t)=>e-t));let o=t.max===7?7:t.max-t.min+1;return a.length===o&&!i?{any:!0,values:[],step:null,extended:!1}:{any:!1,values:a,step:i,extended:!1}}function R(e){let t=e.trim();if(!t)return`Enter a cron expression`;let n=t.split(/\s+/);if(n.length!==5)return`Expected 5 fields (minute hour day-of-month month day-of-week), got ${n.length}`;let r=[];for(let e=0;e<5;e++){let t=be[e],i=xe(n[e],t);if(typeof i==`string`)return`${t.name}: ${i}`;r.push(i)}return r}function z(e){let t=R(e);return typeof t==`string`?t:null}function B(e){if(!e.trim())return`Enter a timezone`;try{return new Intl.DateTimeFormat(void 0,{timeZone:e.trim()}),null}catch{return`Unknown timezone "${e}"`}}function V(e){for(let t=1;t<e.length;t++)if(e[t]!==e[t-1]+1)return!1;return e.length>0}function Se(e,t){if(e.any&&t.any)return{kind:`freq`,text:`Every minute`};if(e.step&&e.step.start===0&&t.any)return{kind:`freq`,text:e.step.every===1?`Every minute`:`Every ${e.step.every} minutes`};if(e.any)return t.step||t.values.length===0?null:V(t.values)?{kind:`freq`,text:`Every minute from ${j(t.values[0])}:00 to ${j(t.values[t.values.length-1])}:59`}:null;if(t.any)return e.step?null:e.values.length===1&&e.values[0]===0?{kind:`freq`,text:`Every hour`}:{kind:`freq`,text:`Every hour at ${A(e.values.map(e=>`:${j(e)}`))}`};if(t.step&&t.step.start===0&&e.values.length===1&&!e.step){let n=e.values[0]===0?``:` at :${j(e.values[0])}`;return{kind:`freq`,text:t.step.every===1?`Every hour${n}`:`Every ${t.step.every} hours${n}`}}if(e.values.length*t.values.length<=6){let n=[];for(let r of t.values)for(let t of e.values)n.push(`${j(r)}:${j(t)}`);return{kind:`at`,text:A(n)}}if(!V(t.values))return null;let n=t.values[0],r=t.values[t.values.length-1];if(e.step&&e.step.start===0)return{kind:`freq`,text:`Every ${e.step.every} minutes from ${j(n)}:00 to ${j(r)}:59`};if(e.values.length===1){let t=j(e.values[0]);return{kind:`freq`,text:`Every hour from ${j(n)}:${t} to ${j(r)}:${t}`}}return null}function Ce(e,t){return(e+6)%7-(t+6)%7}function we(e,t,n){if(!e.any&&!n.any)return null;let r=t.any?null:A(t.values.map(e=>I[e-1])),i=r?` in ${r}`:``;if(!n.any){let e=[...n.values].sort(Ce),t=e.join(`,`);if(t===`1,2,3,4,5`)return{lead:`Every weekday${i}`,qual:` on weekdays${i}`};if(t===`6,0`)return{lead:`Every Saturday and Sunday${i}`,qual:` on weekends${i}`};let r=e.map(e=>F[e]);return{lead:`Every ${A(r)}${i}`,qual:` on ${A(r.map(e=>`${e}s`))}${i}`}}if(!e.any){if(e.values.length>5)return null;let t=A(e.values.map(M)),n=r||`every month`;return{lead:`On the ${t} of ${n}`,qual:` on the ${t} of ${n}`}}return{lead:`Every day${i}`,qual:i}}function H(e,t){let n=R(e);if(typeof n==`string`||n.some(e=>e.extended))return null;let[r,i,a,o,s]=n,c=Se(r,i),l=we(a,o,s);if(!c||!l)return null;let u=c.kind===`at`?`${l.lead} at ${c.text}`:`${c.text}${l.qual}`;return t?`${u} (${t})`:u}function Te(e,t){return H(e,t)??`Cron ${e.trim()} (${t})`}function U(e){let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleString(void 0,{dateStyle:`medium`,timeStyle:`short`})}function W(e,t={}){let n=t.formatDate??U;switch(e.kind){case`manual`:return`Manual`;case`once`:return e.at&&!Number.isNaN(Date.parse(e.at))?`Once at ${n(e.at)}`:`Once (no time chosen)`;case`cron`:return Te(e.expr,e.timezone);case`webhook`:return`Webhook`;case`dependency`:{let n=e.taskId?t.taskTitle?.(e.taskId):void 0;return n?`When "${n}" is done`:e.taskId?`When task ${e.taskId} is done`:`When a task is done`}}}function Ee(e,t){let n=e.trigger;switch(n.kind){case`manual`:return`When run manually`;case`webhook`:{let t=e.filters.filter(e=>e.path.trim());return t.length===0?`When a webhook is received`:`When a webhook is received where ${A(t.map(e=>`${e.path.trim()} = "${e.equals}"`))}`}default:return W(n,t)}}function De(e,t={}){let n=e.template.title.trim()||`Untitled task`,r=t.projectName?` in ${t.projectName}`:``,i=t.hostName?` on ${t.hostName}`:` on the project's default host`,a=t.profileName?` with profile ${t.profileName}`:``,o;switch(e.mode){case`continue`:{let t=e.groupingKey?.trim();o=t?`continue the task grouped by "${t}" (or create "${n}")`:`continue the matching task (or create "${n}")`;break}case`watch`:o=`create a watch task "${n}" that only raises attention when something relevant changed`;break;default:o=`create a fresh task "${n}"`}let s=[`${Ee(e,t)}, ${o}${r}${i}${a}`];if(s.push(e.overlap===`skip`?`skip if previous work is still open`:e.overlap===`queue_one`?`queue one occurrence if previous work is still open`:`append to the open task if previous work is still open`),(e.trigger.kind===`cron`||e.trigger.kind===`once`)&&s.push(e.missed===`skip`?`skip missed runs`:`run missed runs once on return`),e.continuation.enabled){let t=e.continuation;s.push(`continue automatically up to ${t.maxContinuations} times within ${t.maxElapsedMinutes} minutes`)}let c=e.completion.checks;return c&&c.length>0&&s.push(`run ${c.length===1?`1 check`:`${c.length} checks`}`),s.push(e.completion.requireHumanReview?`requires human review`:`no human review required`),N(s.join(`; `))}function G(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||`UTC`}catch{return`UTC`}}function K(e={}){return{name:``,enabled:!0,projectId:e.projectId??``,triggerKind:`manual`,onceAt:``,cronExpr:`0 9 * * 1-5`,cronTimezone:e.timezone??G(),dependencyTaskId:``,filters:[],title:``,objective:``,criteria:``,priority:2,hostId:``,profileId:``,mode:`fresh`,groupingKey:``,overlap:`skip`,missed:`skip`,continuationEnabled:!1,continuationObjective:``,maxContinuations:`5`,maxElapsedMinutes:`60`,maxTokens:``,maxCostUsd:``,checks:``,requireHumanReview:!0}}function Oe(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:`${t.getFullYear()}-${j(t.getMonth()+1)}-${j(t.getDate())}T${j(t.getHours())}:${j(t.getMinutes())}`}function q(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toISOString()}function ke(e,t={}){let n=K({projectId:e.projectId,timezone:t.timezone}),r=e.trigger,i=e.continuation;return{...n,name:e.name,enabled:e.enabled,triggerKind:r.kind,onceAt:r.kind===`once`?Oe(r.at):``,cronExpr:r.kind===`cron`?r.expr:n.cronExpr,cronTimezone:r.kind===`cron`?r.timezone:n.cronTimezone,dependencyTaskId:r.kind===`dependency`?r.taskId:``,filters:e.filters.map(e=>({...e})),title:e.template.title,objective:e.template.objective,criteria:e.template.acceptanceCriteria.join(`
3
3
  `),priority:e.template.priority,hostId:e.hostId??``,profileId:e.profileId??``,mode:e.mode,groupingKey:e.groupingKey??``,overlap:e.overlap,missed:e.missed,continuationEnabled:i.enabled,continuationObjective:i.enabled?i.objective:``,maxContinuations:i.enabled?String(i.maxContinuations):n.maxContinuations,maxElapsedMinutes:i.enabled?String(i.maxElapsedMinutes):n.maxElapsedMinutes,maxTokens:i.enabled&&i.maxTokens!==null?String(i.maxTokens):``,maxCostUsd:i.enabled&&i.maxCostUsd!==null?String(i.maxCostUsd):``,checks:e.completion.checks?e.completion.checks.join(`
4
4
  `):``,requireHumanReview:e.completion.requireHumanReview}}function J(e){return e.trim()===``?NaN:Number(e.trim())}function Y(e){return e.trim()===``?null:Number(e.trim())}function Ae(e){switch(e.triggerKind){case`manual`:return{kind:`manual`};case`once`:return{kind:`once`,at:q(e.onceAt)};case`cron`:return{kind:`cron`,expr:e.cronExpr.trim(),timezone:e.cronTimezone.trim()};case`webhook`:return{kind:`webhook`};case`dependency`:return{kind:`dependency`,taskId:e.dependencyTaskId}}}function X(e){let t=P(e.checks);return{name:e.name.trim(),enabled:e.enabled,projectId:e.projectId,trigger:Ae(e),filters:e.filters.filter(e=>e.path.trim()||e.equals.trim()).map(e=>({path:e.path.trim(),equals:e.equals})),template:{title:e.title.trim(),objective:e.objective,acceptanceCriteria:P(e.criteria),priority:e.priority},hostId:e.hostId||null,profileId:e.profileId||null,mode:e.mode,groupingKey:e.groupingKey.trim()||null,overlap:e.overlap,missed:e.missed,continuation:e.continuationEnabled?{enabled:!0,objective:e.continuationObjective.trim(),maxContinuations:J(e.maxContinuations),maxElapsedMinutes:J(e.maxElapsedMinutes),maxTokens:Y(e.maxTokens),maxCostUsd:Y(e.maxCostUsd)}:{enabled:!1},completion:{checks:t.length>0?t:null,requireHumanReview:e.requireHumanReview}}}var je={name:`name`,enabled:`enabled`,projectId:`projectId`,trigger:`triggerKind`,"trigger.kind":`triggerKind`,"trigger.at":`onceAt`,"trigger.expr":`cronExpr`,"trigger.timezone":`cronTimezone`,"trigger.taskId":`dependencyTaskId`,"template.title":`title`,"template.objective":`objective`,"template.acceptanceCriteria":`criteria`,"template.priority":`priority`,hostId:`hostId`,profileId:`profileId`,mode:`mode`,groupingKey:`groupingKey`,overlap:`overlap`,missed:`missed`,"continuation.objective":`continuationObjective`,"continuation.maxContinuations":`maxContinuations`,"continuation.maxElapsedMinutes":`maxElapsedMinutes`,"continuation.maxTokens":`maxTokens`,"continuation.maxCostUsd":`maxCostUsd`,"completion.checks":`checks`,"completion.requireHumanReview":`requireHumanReview`};function Z(e){let t=e.map(String);if(t[0]===`filters`&&t.length>=3)return`filters.${Number(t[1])}.${t[2]===`equals`?`equals`:`path`}`;if(t[0]===`template`&&t[1]===`acceptanceCriteria`)return`criteria`;if(t[0]===`completion`&&t[1]===`checks`)return`checks`;for(let e=t.length;e>0;e--){let n=je[t.slice(0,e).join(`.`)];if(n)return n}return`form`}function Q(e,t,n,r){let i=J(e);return!Number.isInteger(i)||i<t||i>n?`${r} must be a whole number from ${t} to ${n}`:null}function Me(e){let t={},n=(e,n)=>{n&&!t[e]&&(t[e]=n)};switch(e.name.trim()||n(`name`,`Name is required`),e.projectId||n(`projectId`,`Choose a project`),e.title.trim()||n(`title`,`Task title is required`),e.triggerKind){case`once`:q(e.onceAt)||n(`onceAt`,`Choose a date and time`);break;case`cron`:n(`cronExpr`,z(e.cronExpr)),n(`cronTimezone`,B(e.cronTimezone));break;case`dependency`:e.dependencyTaskId||n(`dependencyTaskId`,`Choose the task to wait for`)}if(e.filters.forEach((e,t)=>{!e.path.trim()&&e.equals.trim()&&n(`filters.${t}.path`,`Enter a payload path`)}),e.mode===`continue`&&!e.groupingKey.trim()&&n(`groupingKey`,`A grouping key is required to continue an existing task`),e.continuationEnabled){if(e.continuationObjective.trim()||n(`continuationObjective`,`An objective is required when continuation is on`),n(`maxContinuations`,Q(e.maxContinuations,1,50,`Max continuations`)),n(`maxElapsedMinutes`,Q(e.maxElapsedMinutes,1,1440,`Max elapsed minutes`)),e.maxTokens.trim()){let t=J(e.maxTokens);(!Number.isInteger(t)||t<=0)&&n(`maxTokens`,`Max tokens must be a positive whole number`)}if(e.maxCostUsd.trim()){let t=J(e.maxCostUsd);(!Number.isFinite(t)||t<=0)&&n(`maxCostUsd`,`Max cost must be a positive amount`)}}let r=X(e),i=m.safeParse(r);if(!i.success)for(let e of i.error.issues)n(Z(e.path),e.message);return{input:i.success&&Object.keys(t).length===0?i.data:null,errors:t}}function $(e){return e.scheduledFor??e.createdAt}function Ne(...e){let t=new Map;for(let n of e)for(let e of n??[])t.set(e.id,e);return[...t.values()].sort((e,t)=>t.createdAt.localeCompare(e.createdAt)||$(t).localeCompare($(e)))}function Pe(e){if(Array.isArray(e))return e;if(e&&typeof e==`object`){let t=e;if(Array.isArray(t.items))return t.items;if(Array.isArray(t.occurrences))return t.occurrences}return[]}function Fe(e,t){return`curl -X POST -H 'Authorization: Bearer ${e}' -H 'Content-Type: application/json' -d '{}' ${t}`}export{ce as A,pe as C,de as D,S as E,_e as F,ge as I,w as M,he as N,le as O,me as P,Me as S,oe as T,O as _,ve as a,De as b,W as c,K as d,Z as f,Ne as g,G as h,k as i,C as j,se as k,ke as l,q as m,E as n,Fe as o,U as p,ye as r,H as s,D as t,X as u,Pe as v,fe as w,z as x,$ as y};
5
- //# sourceMappingURL=describe-BbCZVvJP.js.map
5
+ //# sourceMappingURL=describe-BirsjlUl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"describe-BbCZVvJP.js","names":["__iconData","__iconData","__iconData","useId","useMemo","useState","useCallback","__toESM","require_react","require_jsx_runtime","apiPatch","useSyncStore","useConnection","apiPost","errorMessage","TriangleAlert","cn","formatTime","create","Spinner","CircleCheck","CloudOff","toast","AutomationInput","__iconData$3","OctagonAlert","createLucideIcon","__iconData$2","SignalHigh","__iconData$1","SignalLow","__iconData","SignalMedium","import_react","import_jsx_runtime","Field","id","hintId","errId","describedBy","hint","error","className","label","optional","children","FieldError","Select","rest","Switch","checked","busy","disabled","onChange","onText","offText","Section","testId","title","description","actions","PRIORITY_ICONS","PriorityIcon","Icon","priority","FailureCount","count","ConnectionNote","connection","automationPath","suffix","useLocalAutomations","set","s","a","byId","list","newer","b","useMergedAutomations","store","local","deleted","out","useMergedAutomation","fromStore","fromLocal","useToggleEnabled","setBusy","res","enabled","e","useRunNow","state","onDone","TRIGGER_KIND_LABELS","MODE_OPTIONS","OVERLAP_OPTIONS","MISSED_OPTIONS","modeLabel","m","mode","TEMPLATE_VARIABLES","listText","items","pad","n","ordinal","mod100","capitalize","lines","text","l","DAY_NAMES","MONTH_NAMES","CRON_FIELDS","d","parseValue","lower","token","def","idx","parseCronField","src","parts","values","step","part","base","stepStr","extra","every","start","end","av","bv","v","i","sorted","full","parseCron","trimmed","expr","fields","parsed","validateCron","validateTimezone","tz","isContiguous","describeTime","h","at","times","hv","mv","first","last","mm","mondayFirst","describeDays","dom","dow","months","mon","inMonths","days","key","names","ords","of","describeCron","f","time","timezone","describeCronOrRaw","formatAbsolute","iso","describeTrigger","fmt","ctx","trigger","triggerClause","t","input","filters","summarizeAutomation","project","host","profile","action","c","checks","localTimezone","emptyDraft","opts","isoToLocalInput","localInputToIso","value","draftFromAutomation","toNumber","toOptionalNumber","draftTrigger","draftToInput","PATH_TO_FIELD","fieldForPath","path","intError","min","max","validateDraft","errors","msg","raw","issue","occurrenceTime","o","mergeOccurrences","lists","normalizeHistory","r","curlExample","url"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/octagon-alert.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/signal-high.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/signal-low.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/signal-medium.mjs","../../src/features/automations/controls.tsx","../../src/features/automations/describe.ts"],"sourcesContent":["/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"octagon-alert\",\n size: 24,\n node: [\n [\"path\", { d: \"M12 16h.01\", key: \"1drbdi\" }],\n [\"path\", { d: \"M12 8v4\", key: \"1got3b\" }],\n [\n \"path\",\n {\n d: \"M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z\",\n key: \"1fd625\"\n }\n ]\n ],\n aliases: [\"alert-octagon\"]\n};\n__iconData.node;\nconst OctagonAlert = createLucideIcon(__iconData);\n\nexport { __iconData, OctagonAlert as default };\n//# sourceMappingURL=octagon-alert.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"signal-high\",\n size: 24,\n node: [\n [\"path\", { d: \"M2 20h.01\", key: \"4haj6o\" }],\n [\"path\", { d: \"M7 20v-4\", key: \"j294jx\" }],\n [\"path\", { d: \"M12 20v-8\", key: \"i3yub9\" }],\n [\"path\", { d: \"M17 20V8\", key: \"1tkaf5\" }]\n ]\n};\n__iconData.node;\nconst SignalHigh = createLucideIcon(__iconData);\n\nexport { __iconData, SignalHigh as default };\n//# sourceMappingURL=signal-high.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"signal-low\",\n size: 24,\n node: [\n [\"path\", { d: \"M2 20h.01\", key: \"4haj6o\" }],\n [\"path\", { d: \"M7 20v-4\", key: \"j294jx\" }]\n ]\n};\n__iconData.node;\nconst SignalLow = createLucideIcon(__iconData);\n\nexport { __iconData, SignalLow as default };\n//# sourceMappingURL=signal-low.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"signal-medium\",\n size: 24,\n node: [\n [\"path\", { d: \"M2 20h.01\", key: \"4haj6o\" }],\n [\"path\", { d: \"M7 20v-4\", key: \"j294jx\" }],\n [\"path\", { d: \"M12 20v-8\", key: \"i3yub9\" }]\n ]\n};\n__iconData.node;\nconst SignalMedium = createLucideIcon(__iconData);\n\nexport { __iconData, SignalMedium as default };\n//# sourceMappingURL=signal-medium.mjs.map\n","import type { Automation, Priority } from \"@switchyard/protocol\";\nimport {\n CircleCheck,\n CloudOff,\n OctagonAlert,\n SignalHigh,\n SignalLow,\n SignalMedium,\n TriangleAlert,\n} from \"lucide-react\";\nimport {\n type ReactElement,\n type ReactNode,\n type SelectHTMLAttributes,\n useCallback,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport { create } from \"zustand\";\nimport { Spinner } from \"../../components/ui/Button\";\nimport { toast } from \"../../components/ui/Toast\";\nimport { cn } from \"../../lib/cn\";\nimport { formatTime } from \"../../lib/time\";\nimport { apiPatch, apiPost, errorMessage } from \"../../sync/api\";\nimport { useConnection, useSyncStore } from \"../../sync/store\";\n\n/* Small building blocks shared by the Automations list and editor. */\n\nexport interface FieldControlProps {\n id: string;\n \"aria-invalid\"?: boolean;\n \"aria-describedby\"?: string;\n}\n\n/** Labelled form field with an optional hint and inline error. */\nexport function Field({\n label,\n hint,\n error,\n children,\n className,\n optional,\n}: {\n label: ReactNode;\n hint?: ReactNode;\n error?: string;\n children: (props: FieldControlProps) => ReactElement;\n className?: string;\n optional?: boolean;\n}) {\n const id = useId();\n const hintId = `${id}-hint`;\n const errId = `${id}-err`;\n const describedBy = [hint ? hintId : null, error ? errId : null].filter(Boolean).join(\" \");\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-1\", className)}>\n <label htmlFor={id} className=\"text-sm font-medium\">\n {label}\n {optional && <span className=\"font-normal text-muted\"> (optional)</span>}\n </label>\n {children({\n id,\n \"aria-invalid\": error ? true : undefined,\n \"aria-describedby\": describedBy || undefined,\n })}\n {hint && (\n <p id={hintId} className=\"text-xs text-muted\">\n {hint}\n </p>\n )}\n {error && <FieldError id={errId}>{error}</FieldError>}\n </div>\n );\n}\n\nexport function FieldError({ id, children }: { id?: string; children: ReactNode }) {\n return (\n <p id={id} className=\"flex items-start gap-1 text-xs text-danger\" data-field-error>\n <TriangleAlert aria-hidden className=\"mt-0.5 size-3.5 shrink-0\" />\n <span>{children}</span>\n </p>\n );\n}\n\n/** Native select styled like TextInput. */\nexport function Select({ className, children, ...rest }: SelectHTMLAttributes<HTMLSelectElement>) {\n return (\n <select\n className={cn(\n \"tap block h-9 w-full min-w-0 rounded-md border border-border bg-surface px-2.5 text-base text-text md:text-sm\",\n \"focus:border-accent focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-0\",\n \"aria-[invalid=true]:border-danger\",\n className,\n )}\n {...rest}\n >\n {children}\n </select>\n );\n}\n\n/** Accessible on/off switch with a text label that states the current value. */\nexport function Switch({\n checked,\n onChange,\n label,\n onText = \"On\",\n offText = \"Off\",\n busy,\n disabled,\n id,\n className,\n}: {\n checked: boolean;\n onChange: (next: boolean) => void;\n /** Accessible name. */\n label: string;\n onText?: string;\n offText?: string;\n busy?: boolean;\n disabled?: boolean;\n id?: string;\n className?: string;\n}) {\n return (\n <button\n id={id}\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={label}\n aria-busy={busy || undefined}\n disabled={disabled || busy}\n onClick={() => onChange(!checked)}\n className={cn(\n \"tap inline-flex min-h-9 shrink-0 items-center gap-2 rounded-md px-1.5 text-sm\",\n \"hover:bg-surface-2 disabled:opacity-60\",\n className,\n )}\n >\n <span\n aria-hidden\n className={cn(\n \"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border transition-colors\",\n checked ? \"border-accent bg-accent\" : \"border-border-strong bg-surface-2\",\n )}\n >\n <span\n className={cn(\n \"absolute size-3.5 rounded-full shadow-sm transition-transform\",\n checked ? \"translate-x-[18px] bg-accent-fg\" : \"translate-x-[2px] bg-muted\",\n )}\n />\n </span>\n {busy ? <Spinner className=\"size-3.5\" /> : null}\n <span className={checked ? \"text-text\" : \"text-muted\"}>{checked ? onText : offText}</span>\n </button>\n );\n}\n\n/** Titled card section. */\nexport function Section({\n title,\n description,\n children,\n actions,\n className,\n testId,\n}: {\n title: ReactNode;\n description?: ReactNode;\n children: ReactNode;\n actions?: ReactNode;\n className?: string;\n testId?: string;\n}) {\n const id = useId();\n return (\n <section\n aria-labelledby={id}\n data-testid={testId}\n className={cn(\"min-w-0 rounded-lg border border-border bg-surface p-4\", className)}\n >\n <div className=\"mb-3 flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <h2 id={id} className=\"text-base font-semibold\">\n {title}\n </h2>\n {description && <p className=\"text-sm text-muted\">{description}</p>}\n </div>\n {actions && <div className=\"flex flex-wrap gap-2\">{actions}</div>}\n </div>\n <div className=\"flex flex-col gap-4\">{children}</div>\n </section>\n );\n}\n\nconst PRIORITY_ICONS = [OctagonAlert, SignalHigh, SignalMedium, SignalLow];\n\nexport function PriorityIcon({ priority, className }: { priority: Priority; className?: string }) {\n const Icon = PRIORITY_ICONS[priority] ?? SignalMedium;\n return (\n <Icon\n aria-hidden\n className={cn(\"size-4 shrink-0\", priority === 0 ? \"text-danger\" : \"text-muted\", className)}\n />\n );\n}\n\n/** Failure count as icon + text; warning tone when > 0. */\nexport function FailureCount({ count }: { count: number }) {\n if (count > 0) {\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-warning\">\n <TriangleAlert aria-hidden className=\"size-4 shrink-0\" />\n {count === 1 ? \"1 failure\" : `${count} failures`}\n </span>\n );\n }\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-muted\">\n <CircleCheck aria-hidden className=\"size-4 shrink-0\" />\n No failures\n </span>\n );\n}\n\n/** Inline last-known-data note when the coordinator link is not live. */\nexport function ConnectionNote({ className }: { className?: string }) {\n const connection = useConnection();\n if (connection.state === \"live\") return null;\n if (connection.state === \"connecting\" && !connection.lastSyncedAt) return null;\n return (\n <p\n role=\"status\"\n className={cn(\n \"flex items-start gap-1.5 rounded-md border border-border bg-warning-soft px-3 py-1.5 text-sm\",\n className,\n )}\n >\n <CloudOff aria-hidden className=\"mt-0.5 size-4 shrink-0 text-warning\" />\n <span>\n Showing last known automations\n {connection.lastSyncedAt ? ` from ${formatTime(connection.lastSyncedAt)}` : \"\"}. Changes are\n sent once the coordinator is reachable again.\n </span>\n </p>\n );\n}\n\nexport const automationPath = (id: string, suffix = \"\") =>\n `/api/automations/${encodeURIComponent(id)}${suffix}`;\n\n/* ------------------------------------------------------------------ */\n/* Automations acknowledged over REST (create/patch responses, list */\n/* fallback) so views do not wait for the automation.updated event. */\n/* ------------------------------------------------------------------ */\n\ninterface LocalAutomations {\n byId: Record<string, Automation>;\n deleted: Record<string, true>;\n put(a: Automation): void;\n putMany(list: Automation[]): void;\n remove(id: string): void;\n}\n\nexport const useLocalAutomations = create<LocalAutomations>()((set) => ({\n byId: {},\n deleted: {},\n put: (a) => set((s) => ({ byId: { ...s.byId, [a.id]: a } })),\n putMany: (list) =>\n set((s) => {\n const byId = { ...s.byId };\n for (const a of list) byId[a.id] = a;\n return { byId };\n }),\n remove: (id) =>\n set((s) => {\n const byId = { ...s.byId };\n delete byId[id];\n return { byId, deleted: { ...s.deleted, [id]: true } };\n }),\n}));\n\nfunction newer(a: Automation | undefined, b: Automation | undefined): Automation | undefined {\n if (!a) return b;\n if (!b) return a;\n return b.updatedAt > a.updatedAt ? b : a;\n}\n\n/** Store automations merged with REST acknowledgements (newest updatedAt wins). */\nexport function useMergedAutomations(): Record<string, Automation> {\n const store = useSyncStore((s) => s.automations);\n const local = useLocalAutomations((s) => s.byId);\n const deleted = useLocalAutomations((s) => s.deleted);\n return useMemo(() => {\n const out: Record<string, Automation> = {};\n for (const id of new Set([...Object.keys(store), ...Object.keys(local)])) {\n if (deleted[id]) continue;\n const a = newer(store[id], local[id]);\n if (a) out[id] = a;\n }\n return out;\n }, [store, local, deleted]);\n}\n\nexport function useMergedAutomation(id: string | undefined): Automation | undefined {\n const fromStore = useSyncStore((s) => (id ? s.automations[id] : undefined));\n const fromLocal = useLocalAutomations((s) => (id ? s.byId[id] : undefined));\n const deleted = useLocalAutomations((s) => (id ? s.deleted[id] : undefined));\n return deleted ? undefined : newer(fromStore, fromLocal);\n}\n\n/** Enable/disable with no optimistic success: busy until the coordinator acknowledges. */\nexport function useToggleEnabled() {\n const [busy, setBusy] = useState<Record<string, boolean>>({});\n const toggle = useCallback(async (a: Pick<Automation, \"id\" | \"name\">, enabled: boolean) => {\n setBusy((b) => ({ ...b, [a.id]: true }));\n try {\n const res = await apiPatch<Automation | undefined>(automationPath(a.id), { enabled });\n if (res && typeof res === \"object\" && \"id\" in res) useLocalAutomations.getState().put(res);\n toast.success(`${a.name} ${enabled ? \"enabled\" : \"disabled\"}`);\n } catch (e) {\n toast.error(`Could not ${enabled ? \"enable\" : \"disable\"} ${a.name}: ${errorMessage(e)}`);\n } finally {\n setBusy((b) => ({ ...b, [a.id]: false }));\n }\n }, []);\n return { busy, toggle };\n}\n\n/** Manual \"Run now\": busy until acknowledged; never reports success early. */\nexport function useRunNow(onDone?: () => void) {\n const [busy, setBusy] = useState<Record<string, boolean>>({});\n const run = useCallback(\n async (a: Pick<Automation, \"id\" | \"name\">) => {\n setBusy((b) => ({ ...b, [a.id]: true }));\n try {\n const res = await apiPost<{ state?: string } | undefined>(automationPath(a.id, \"/run\"));\n const state = res && typeof res === \"object\" ? res.state : undefined;\n toast.success(\n state && state !== \"fired\"\n ? `${a.name}: occurrence recorded (${state.replace(/_/g, \" \")})`\n : `${a.name} started`,\n );\n onDone?.();\n } catch (e) {\n toast.error(`Could not run ${a.name}: ${errorMessage(e)}`);\n } finally {\n setBusy((b) => ({ ...b, [a.id]: false }));\n }\n },\n [onDone],\n );\n return { busy, run };\n}\n","import {\n type Automation,\n AutomationInput,\n type Occurrence,\n PRIORITY_LABELS,\n type Priority,\n type Trigger,\n} from \"@switchyard/protocol\";\n\n/*\n * Pure helpers for the Automations feature: a small cron describer, trigger\n * and whole-automation summaries, the editor draft <-> AutomationInput\n * conversion with field-level validation, and history merging.\n */\n\n/* ------------------------------------------------------------------ */\n/* Labels and explanations */\n/* ------------------------------------------------------------------ */\n\nexport type AutomationMode = AutomationInput[\"mode\"];\nexport type OverlapPolicy = AutomationInput[\"overlap\"];\nexport type MissedPolicy = AutomationInput[\"missed\"];\nexport type TriggerKind = Trigger[\"kind\"];\n\nexport const TRIGGER_KIND_LABELS: Record<TriggerKind, string> = {\n manual: \"Manual\",\n once: \"Once\",\n cron: \"Schedule\",\n webhook: \"Webhook\",\n dependency: \"Dependency\",\n};\n\nexport const MODE_OPTIONS: { value: AutomationMode; label: string; explanation: string }[] = [\n { value: \"fresh\", label: \"Fresh\", explanation: \"Fresh: a new task per occurrence\" },\n {\n value: \"continue\",\n label: \"Continue\",\n explanation: \"Continue: reuse the task with the same grouping key\",\n },\n {\n value: \"watch\",\n label: \"Watch\",\n explanation: \"Watch: only raises attention when something relevant changed\",\n },\n];\n\nexport const OVERLAP_OPTIONS: { value: OverlapPolicy; label: string; explanation: string }[] = [\n {\n value: \"skip\",\n label: \"Skip\",\n explanation: \"Skip: drop the occurrence while earlier work is still open\",\n },\n {\n value: \"queue_one\",\n label: \"Queue one\",\n explanation: \"Queue one: keep a single pending occurrence and fire it when the open work ends\",\n },\n {\n value: \"append\",\n label: \"Append\",\n explanation: \"Append: add the new objective to the open task (as a follow-up if it is running)\",\n },\n];\n\nexport const MISSED_OPTIONS: { value: MissedPolicy; label: string; explanation: string }[] = [\n {\n value: \"skip\",\n label: \"Skip\",\n explanation: \"Skip: occurrences missed while the coordinator was down are recorded and skipped\",\n },\n {\n value: \"run_once\",\n label: \"Run once\",\n explanation: \"Run once: on return, fire the newest missed occurrence once\",\n },\n];\n\nexport function modeLabel(mode: AutomationMode): string {\n return MODE_OPTIONS.find((m) => m.value === mode)?.label ?? mode;\n}\n\nexport function priorityLabel(p: Priority): string {\n return PRIORITY_LABELS[p] ?? String(p);\n}\n\nexport const TEMPLATE_VARIABLES = [\"{{date}}\", \"{{time}}\", \"{{occurrence}}\", \"{{payload.<path>}}\"];\n\n/* ------------------------------------------------------------------ */\n/* Text utilities */\n/* ------------------------------------------------------------------ */\n\n/** \"a\", \"a and b\", \"a, b and c\". */\nexport function listText(items: string[]): string {\n if (items.length <= 1) return items[0] ?? \"\";\n return `${items.slice(0, -1).join(\", \")} and ${items[items.length - 1]}`;\n}\n\nfunction pad(n: number): string {\n return String(n).padStart(2, \"0\");\n}\n\nexport function ordinal(n: number): string {\n const mod100 = n % 100;\n if (mod100 >= 11 && mod100 <= 13) return `${n}th`;\n switch (n % 10) {\n case 1:\n return `${n}st`;\n case 2:\n return `${n}nd`;\n case 3:\n return `${n}rd`;\n default:\n return `${n}th`;\n }\n}\n\nfunction capitalize(s: string): string {\n return s ? s[0]!.toUpperCase() + s.slice(1) : s;\n}\n\n/** Non-empty trimmed lines. */\nexport function lines(text: string): string[] {\n return text\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0);\n}\n\n/* ------------------------------------------------------------------ */\n/* Cron */\n/* ------------------------------------------------------------------ */\n\nconst DAY_NAMES = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nconst MONTH_NAMES = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n];\n\ninterface FieldDef {\n name: string;\n min: number;\n max: number;\n /** Three-letter aliases mapped to `min + index`. */\n names?: string[];\n}\n\nconst CRON_FIELDS: FieldDef[] = [\n { name: \"Minute\", min: 0, max: 59 },\n { name: \"Hour\", min: 0, max: 23 },\n { name: \"Day of month\", min: 1, max: 31 },\n {\n name: \"Month\",\n min: 1,\n max: 12,\n names: MONTH_NAMES.map((m) => m.slice(0, 3).toLowerCase()),\n },\n {\n name: \"Day of week\",\n min: 0,\n max: 7,\n names: DAY_NAMES.map((d) => d.slice(0, 3).toLowerCase()),\n },\n];\n\nexport interface CronField {\n /** `*` (or `?`): every value. */\n any: boolean;\n /** Expanded, sorted, unique values (empty when `any`). */\n values: number[];\n /** Set when the field is a single `*\\/n` or `a/n` step. */\n step: { every: number; start: number } | null;\n /** Uses croner extensions (L, W, #) the describer does not explain. */\n extended: boolean;\n}\n\nfunction parseValue(token: string, def: FieldDef): number | string {\n const lower = token.toLowerCase();\n if (def.names) {\n const idx = def.names.indexOf(lower);\n if (idx >= 0) return def.min + idx;\n }\n if (!/^\\d+$/.test(token)) return `\"${token}\" is not a number`;\n const n = Number(token);\n if (n < def.min || n > def.max) return `${n} is out of range ${def.min}–${def.max}`;\n return n;\n}\n\n/** Parse one cron field; returns an error message for invalid input. */\nexport function parseCronField(src: string, def: FieldDef): CronField | string {\n if (src === \"*\" || src === \"?\") return { any: true, values: [], step: null, extended: false };\n if (/[LW#]/i.test(src) && !def.names?.some((n) => src.toLowerCase().includes(n))) {\n if (!/^[0-9A-Za-z*?,\\-/#]+$/.test(src)) return `\"${src}\" is not valid`;\n return { any: false, values: [], step: null, extended: true };\n }\n const parts = src.split(\",\");\n const values = new Set<number>();\n let step: CronField[\"step\"] = null;\n for (const part of parts) {\n if (!part) return \"empty list item\";\n const [base, stepStr, extra] = part.split(\"/\");\n if (extra !== undefined) return `\"${part}\" has more than one step`;\n let every = 1;\n if (stepStr !== undefined) {\n if (!/^\\d+$/.test(stepStr) || Number(stepStr) < 1) return `\"${stepStr}\" is not a valid step`;\n every = Number(stepStr);\n }\n let start: number;\n let end: number;\n if (base === \"*\" || base === \"?\") {\n start = def.min;\n end = def.max;\n } else if (base?.includes(\"-\")) {\n const [a, b] = base.split(\"-\");\n const av = parseValue(a ?? \"\", def);\n const bv = parseValue(b ?? \"\", def);\n if (typeof av === \"string\") return av;\n if (typeof bv === \"string\") return bv;\n if (av > bv) return `range ${base} runs backwards`;\n start = av;\n end = bv;\n } else {\n const v = parseValue(base ?? \"\", def);\n if (typeof v === \"string\") return v;\n start = v;\n end = stepStr !== undefined ? def.max : v;\n }\n for (let i = start; i <= end; i += every) values.add(i);\n if (parts.length === 1 && stepStr !== undefined && !base?.includes(\"-\")) {\n step = { every, start };\n }\n }\n let sorted = [...values].sort((a, b) => a - b);\n // Day of week: 7 is Sunday.\n if (def.max === 7) sorted = [...new Set(sorted.map((v) => v % 7))].sort((a, b) => a - b);\n const full = def.max === 7 ? 7 : def.max - def.min + 1;\n if (sorted.length === full && !step)\n return { any: true, values: [], step: null, extended: false };\n return { any: false, values: sorted, step, extended: false };\n}\n\nexport function parseCron(expr: string): CronField[] | string {\n const trimmed = expr.trim();\n if (!trimmed) return \"Enter a cron expression\";\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 5) {\n return `Expected 5 fields (minute hour day-of-month month day-of-week), got ${fields.length}`;\n }\n const out: CronField[] = [];\n for (let i = 0; i < 5; i++) {\n const def = CRON_FIELDS[i]!;\n const parsed = parseCronField(fields[i]!, def);\n if (typeof parsed === \"string\") return `${def.name}: ${parsed}`;\n out.push(parsed);\n }\n return out;\n}\n\n/** Null when valid, otherwise a message. */\nexport function validateCron(expr: string): string | null {\n const parsed = parseCron(expr);\n return typeof parsed === \"string\" ? parsed : null;\n}\n\n/** Null when the IANA timezone is known to this browser. */\nexport function validateTimezone(tz: string): string | null {\n if (!tz.trim()) return \"Enter a timezone\";\n try {\n new Intl.DateTimeFormat(undefined, { timeZone: tz.trim() });\n return null;\n } catch {\n return `Unknown timezone \"${tz}\"`;\n }\n}\n\nfunction isContiguous(values: number[]): boolean {\n for (let i = 1; i < values.length; i++) if (values[i] !== values[i - 1]! + 1) return false;\n return values.length > 0;\n}\n\ntype TimePhrase = { kind: \"at\"; text: string } | { kind: \"freq\"; text: string };\n\nfunction describeTime(m: CronField, h: CronField): TimePhrase | null {\n if (m.any && h.any) return { kind: \"freq\", text: \"Every minute\" };\n if (m.step && m.step.start === 0 && h.any) {\n return {\n kind: \"freq\",\n text: m.step.every === 1 ? \"Every minute\" : `Every ${m.step.every} minutes`,\n };\n }\n if (m.any) {\n if (h.step || h.values.length === 0) return null;\n if (isContiguous(h.values)) {\n return {\n kind: \"freq\",\n text: `Every minute from ${pad(h.values[0]!)}:00 to ${pad(h.values[h.values.length - 1]!)}:59`,\n };\n }\n return null;\n }\n if (h.any) {\n if (m.step) return null;\n if (m.values.length === 1 && m.values[0] === 0) return { kind: \"freq\", text: \"Every hour\" };\n return {\n kind: \"freq\",\n text: `Every hour at ${listText(m.values.map((v) => `:${pad(v)}`))}`,\n };\n }\n if (h.step && h.step.start === 0 && m.values.length === 1 && !m.step) {\n const at = m.values[0] === 0 ? \"\" : ` at :${pad(m.values[0]!)}`;\n return {\n kind: \"freq\",\n text: h.step.every === 1 ? `Every hour${at}` : `Every ${h.step.every} hours${at}`,\n };\n }\n if (m.values.length * h.values.length <= 6) {\n const times: string[] = [];\n for (const hv of h.values) for (const mv of m.values) times.push(`${pad(hv)}:${pad(mv)}`);\n return { kind: \"at\", text: listText(times) };\n }\n if (!isContiguous(h.values)) return null;\n const first = h.values[0]!;\n const last = h.values[h.values.length - 1]!;\n if (m.step && m.step.start === 0) {\n return {\n kind: \"freq\",\n text: `Every ${m.step.every} minutes from ${pad(first)}:00 to ${pad(last)}:59`,\n };\n }\n if (m.values.length === 1) {\n const mm = pad(m.values[0]!);\n return { kind: \"freq\", text: `Every hour from ${pad(first)}:${mm} to ${pad(last)}:${mm}` };\n }\n return null;\n}\n\n/** Monday-first ordering for day-of-week lists. */\nfunction mondayFirst(a: number, b: number): number {\n return ((a + 6) % 7) - ((b + 6) % 7);\n}\n\nfunction describeDays(\n dom: CronField,\n mon: CronField,\n dow: CronField,\n): { lead: string; qual: string } | null {\n if (!dom.any && !dow.any) return null;\n const months = mon.any ? null : listText(mon.values.map((v) => MONTH_NAMES[v - 1]!));\n const inMonths = months ? ` in ${months}` : \"\";\n if (!dow.any) {\n const days = [...dow.values].sort(mondayFirst);\n const key = days.join(\",\");\n if (key === \"1,2,3,4,5\") {\n return { lead: `Every weekday${inMonths}`, qual: ` on weekdays${inMonths}` };\n }\n if (key === \"6,0\") {\n return { lead: `Every Saturday and Sunday${inMonths}`, qual: ` on weekends${inMonths}` };\n }\n const names = days.map((d) => DAY_NAMES[d]!);\n return {\n lead: `Every ${listText(names)}${inMonths}`,\n qual: ` on ${listText(names.map((n) => `${n}s`))}${inMonths}`,\n };\n }\n if (!dom.any) {\n if (dom.values.length > 5) return null;\n const ords = listText(dom.values.map(ordinal));\n const of = months ? months : \"every month\";\n return { lead: `On the ${ords} of ${of}`, qual: ` on the ${ords} of ${of}` };\n }\n return { lead: `Every day${inMonths}`, qual: inMonths };\n}\n\n/**\n * Human description of a 5-field cron expression (\"Every weekday at 09:00\n * (America/Denver)\"), or null when the expression is outside what this small\n * describer covers.\n */\nexport function describeCron(expr: string, timezone?: string): string | null {\n const parsed = parseCron(expr);\n if (typeof parsed === \"string\") return null;\n if (parsed.some((f) => f.extended)) return null;\n const [m, h, dom, mon, dow] = parsed as [CronField, CronField, CronField, CronField, CronField];\n const time = describeTime(m, h);\n const days = describeDays(dom, mon, dow);\n if (!time || !days) return null;\n const text = time.kind === \"at\" ? `${days.lead} at ${time.text}` : `${time.text}${days.qual}`;\n return timezone ? `${text} (${timezone})` : text;\n}\n\n/** describeCron with the raw-expression fallback. */\nexport function describeCronOrRaw(expr: string, timezone: string): string {\n return describeCron(expr, timezone) ?? `Cron ${expr.trim()} (${timezone})`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Summaries */\n/* ------------------------------------------------------------------ */\n\nexport function formatAbsolute(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return d.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" });\n}\n\nexport interface SummaryContext {\n projectName?: string | null;\n /** Name of the explicitly selected host; null/undefined means the project default. */\n hostName?: string | null;\n profileName?: string | null;\n taskTitle?: (taskId: string) => string | undefined;\n formatDate?: (iso: string) => string;\n}\n\n/** Short trigger summary for list rows. */\nexport function describeTrigger(trigger: Trigger, ctx: SummaryContext = {}): string {\n const fmt = ctx.formatDate ?? formatAbsolute;\n switch (trigger.kind) {\n case \"manual\":\n return \"Manual\";\n case \"once\":\n return trigger.at && !Number.isNaN(Date.parse(trigger.at))\n ? `Once at ${fmt(trigger.at)}`\n : \"Once (no time chosen)\";\n case \"cron\":\n return describeCronOrRaw(trigger.expr, trigger.timezone);\n case \"webhook\":\n return \"Webhook\";\n case \"dependency\": {\n const title = trigger.taskId ? ctx.taskTitle?.(trigger.taskId) : undefined;\n if (title) return `When \"${title}\" is done`;\n return trigger.taskId ? `When task ${trigger.taskId} is done` : \"When a task is done\";\n }\n }\n}\n\ntype SummaryInput = Pick<\n AutomationInput,\n | \"trigger\"\n | \"filters\"\n | \"template\"\n | \"mode\"\n | \"groupingKey\"\n | \"overlap\"\n | \"missed\"\n | \"continuation\"\n | \"completion\"\n>;\n\nfunction triggerClause(input: SummaryInput, ctx: SummaryContext): string {\n const t = input.trigger;\n switch (t.kind) {\n case \"manual\":\n return \"When run manually\";\n case \"webhook\": {\n const filters = input.filters.filter((f) => f.path.trim());\n if (filters.length === 0) return \"When a webhook is received\";\n return `When a webhook is received where ${listText(\n filters.map((f) => `${f.path.trim()} = \"${f.equals}\"`),\n )}`;\n }\n default:\n return describeTrigger(t, ctx);\n }\n}\n\n/**\n * One-paragraph description of what the automation does, e.g. 'Every weekday\n * at 09:00 (America/Denver), create a fresh task \"Triage\" in Web on my-server; skip\n * if previous work is still open; skip missed runs; requires human review'.\n */\nexport function summarizeAutomation(input: SummaryInput, ctx: SummaryContext = {}): string {\n const title = input.template.title.trim() || \"Untitled task\";\n const project = ctx.projectName ? ` in ${ctx.projectName}` : \"\";\n const host = ctx.hostName ? ` on ${ctx.hostName}` : \" on the project's default host\";\n const profile = ctx.profileName ? ` with profile ${ctx.profileName}` : \"\";\n let action: string;\n switch (input.mode) {\n case \"continue\": {\n const key = input.groupingKey?.trim();\n action = key\n ? `continue the task grouped by \"${key}\" (or create \"${title}\")`\n : `continue the matching task (or create \"${title}\")`;\n break;\n }\n case \"watch\":\n action = `create a watch task \"${title}\" that only raises attention when something relevant changed`;\n break;\n default:\n action = `create a fresh task \"${title}\"`;\n }\n const parts = [`${triggerClause(input, ctx)}, ${action}${project}${host}${profile}`];\n parts.push(\n input.overlap === \"skip\"\n ? \"skip if previous work is still open\"\n : input.overlap === \"queue_one\"\n ? \"queue one occurrence if previous work is still open\"\n : \"append to the open task if previous work is still open\",\n );\n if (input.trigger.kind === \"cron\" || input.trigger.kind === \"once\") {\n parts.push(input.missed === \"skip\" ? \"skip missed runs\" : \"run missed runs once on return\");\n }\n if (input.continuation.enabled) {\n const c = input.continuation;\n parts.push(\n `continue automatically up to ${c.maxContinuations} times within ${c.maxElapsedMinutes} minutes`,\n );\n }\n const checks = input.completion.checks;\n if (checks && checks.length > 0) {\n parts.push(`run ${checks.length === 1 ? \"1 check\" : `${checks.length} checks`}`);\n }\n parts.push(\n input.completion.requireHumanReview ? \"requires human review\" : \"no human review required\",\n );\n return capitalize(parts.join(\"; \"));\n}\n\n/* ------------------------------------------------------------------ */\n/* Editor draft */\n/* ------------------------------------------------------------------ */\n\n/** Form state: strings for inputs so partial edits survive validation. */\nexport interface AutomationDraft {\n name: string;\n enabled: boolean;\n projectId: string;\n triggerKind: TriggerKind;\n /** datetime-local value (local time, no zone). */\n onceAt: string;\n cronExpr: string;\n cronTimezone: string;\n dependencyTaskId: string;\n filters: { path: string; equals: string }[];\n title: string;\n objective: string;\n /** One criterion per line. */\n criteria: string;\n priority: Priority;\n /** \"\" = project default. */\n hostId: string;\n /** \"\" = project default. */\n profileId: string;\n mode: AutomationMode;\n groupingKey: string;\n overlap: OverlapPolicy;\n missed: MissedPolicy;\n continuationEnabled: boolean;\n continuationObjective: string;\n maxContinuations: string;\n maxElapsedMinutes: string;\n maxTokens: string;\n maxCostUsd: string;\n /** One check per line; empty = project default (null). */\n checks: string;\n requireHumanReview: boolean;\n}\n\nexport function localTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\";\n } catch {\n return \"UTC\";\n }\n}\n\nexport function emptyDraft(opts: { projectId?: string; timezone?: string } = {}): AutomationDraft {\n return {\n name: \"\",\n enabled: true,\n projectId: opts.projectId ?? \"\",\n triggerKind: \"manual\",\n onceAt: \"\",\n cronExpr: \"0 9 * * 1-5\",\n cronTimezone: opts.timezone ?? localTimezone(),\n dependencyTaskId: \"\",\n filters: [],\n title: \"\",\n objective: \"\",\n criteria: \"\",\n priority: 2,\n hostId: \"\",\n profileId: \"\",\n mode: \"fresh\",\n groupingKey: \"\",\n overlap: \"skip\",\n missed: \"skip\",\n continuationEnabled: false,\n continuationObjective: \"\",\n maxContinuations: \"5\",\n maxElapsedMinutes: \"60\",\n maxTokens: \"\",\n maxCostUsd: \"\",\n checks: \"\",\n requireHumanReview: true,\n };\n}\n\n/** ISO -> datetime-local value in this browser's timezone. */\nexport function isoToLocalInput(iso: string | null | undefined): string {\n if (!iso) return \"\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n\n/** datetime-local value -> ISO (interpreted as local time), or \"\" when empty/invalid. */\nexport function localInputToIso(value: string): string {\n if (!value) return \"\";\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? \"\" : d.toISOString();\n}\n\nexport function draftFromAutomation(\n a: Automation | AutomationInput,\n opts: { timezone?: string } = {},\n): AutomationDraft {\n const base = emptyDraft({ projectId: a.projectId, timezone: opts.timezone });\n const t = a.trigger;\n const c = a.continuation;\n return {\n ...base,\n name: a.name,\n enabled: a.enabled,\n triggerKind: t.kind,\n onceAt: t.kind === \"once\" ? isoToLocalInput(t.at) : \"\",\n cronExpr: t.kind === \"cron\" ? t.expr : base.cronExpr,\n cronTimezone: t.kind === \"cron\" ? t.timezone : base.cronTimezone,\n dependencyTaskId: t.kind === \"dependency\" ? t.taskId : \"\",\n filters: a.filters.map((f) => ({ ...f })),\n title: a.template.title,\n objective: a.template.objective,\n criteria: a.template.acceptanceCriteria.join(\"\\n\"),\n priority: a.template.priority,\n hostId: a.hostId ?? \"\",\n profileId: a.profileId ?? \"\",\n mode: a.mode,\n groupingKey: a.groupingKey ?? \"\",\n overlap: a.overlap,\n missed: a.missed,\n continuationEnabled: c.enabled,\n continuationObjective: c.enabled ? c.objective : \"\",\n maxContinuations: c.enabled ? String(c.maxContinuations) : base.maxContinuations,\n maxElapsedMinutes: c.enabled ? String(c.maxElapsedMinutes) : base.maxElapsedMinutes,\n maxTokens: c.enabled && c.maxTokens !== null ? String(c.maxTokens) : \"\",\n maxCostUsd: c.enabled && c.maxCostUsd !== null ? String(c.maxCostUsd) : \"\",\n checks: a.completion.checks ? a.completion.checks.join(\"\\n\") : \"\",\n requireHumanReview: a.completion.requireHumanReview,\n };\n}\n\nfunction toNumber(s: string): number {\n return s.trim() === \"\" ? Number.NaN : Number(s.trim());\n}\n\nfunction toOptionalNumber(s: string): number | null {\n return s.trim() === \"\" ? null : Number(s.trim());\n}\n\nfunction draftTrigger(d: AutomationDraft): Trigger {\n switch (d.triggerKind) {\n case \"manual\":\n return { kind: \"manual\" };\n case \"once\":\n return { kind: \"once\", at: localInputToIso(d.onceAt) };\n case \"cron\":\n return { kind: \"cron\", expr: d.cronExpr.trim(), timezone: d.cronTimezone.trim() };\n case \"webhook\":\n return { kind: \"webhook\" };\n case \"dependency\":\n return { kind: \"dependency\", taskId: d.dependencyTaskId };\n }\n}\n\n/**\n * Build the request body from a draft. The result is shaped like an\n * AutomationInput but is not validated (numbers may be NaN, strings empty);\n * run validateDraft before sending it.\n */\nexport function draftToInput(d: AutomationDraft): AutomationInput {\n const checks = lines(d.checks);\n return {\n name: d.name.trim(),\n enabled: d.enabled,\n projectId: d.projectId,\n trigger: draftTrigger(d),\n filters: d.filters\n .filter((f) => f.path.trim() || f.equals.trim())\n .map((f) => ({ path: f.path.trim(), equals: f.equals })),\n template: {\n title: d.title.trim(),\n objective: d.objective,\n acceptanceCriteria: lines(d.criteria),\n priority: d.priority,\n },\n hostId: d.hostId || null,\n profileId: d.profileId || null,\n mode: d.mode,\n groupingKey: d.groupingKey.trim() || null,\n overlap: d.overlap,\n missed: d.missed,\n continuation: d.continuationEnabled\n ? {\n enabled: true,\n objective: d.continuationObjective.trim(),\n maxContinuations: toNumber(d.maxContinuations),\n maxElapsedMinutes: toNumber(d.maxElapsedMinutes),\n maxTokens: toOptionalNumber(d.maxTokens),\n maxCostUsd: toOptionalNumber(d.maxCostUsd),\n }\n : { enabled: false },\n completion: {\n checks: checks.length > 0 ? checks : null,\n requireHumanReview: d.requireHumanReview,\n },\n };\n}\n\n/** Draft field keys that can carry an inline error. */\nexport type DraftField =\n | keyof AutomationDraft\n | `filters.${number}.path`\n | `filters.${number}.equals`\n | \"form\";\n\nexport type DraftErrors = Partial<Record<DraftField, string>>;\n\nconst PATH_TO_FIELD: Record<string, DraftField> = {\n name: \"name\",\n enabled: \"enabled\",\n projectId: \"projectId\",\n trigger: \"triggerKind\",\n \"trigger.kind\": \"triggerKind\",\n \"trigger.at\": \"onceAt\",\n \"trigger.expr\": \"cronExpr\",\n \"trigger.timezone\": \"cronTimezone\",\n \"trigger.taskId\": \"dependencyTaskId\",\n \"template.title\": \"title\",\n \"template.objective\": \"objective\",\n \"template.acceptanceCriteria\": \"criteria\",\n \"template.priority\": \"priority\",\n hostId: \"hostId\",\n profileId: \"profileId\",\n mode: \"mode\",\n groupingKey: \"groupingKey\",\n overlap: \"overlap\",\n missed: \"missed\",\n \"continuation.objective\": \"continuationObjective\",\n \"continuation.maxContinuations\": \"maxContinuations\",\n \"continuation.maxElapsedMinutes\": \"maxElapsedMinutes\",\n \"continuation.maxTokens\": \"maxTokens\",\n \"continuation.maxCostUsd\": \"maxCostUsd\",\n \"completion.checks\": \"checks\",\n \"completion.requireHumanReview\": \"requireHumanReview\",\n};\n\n/** Map a zod issue path to a draft field. */\nexport function fieldForPath(path: readonly PropertyKey[]): DraftField {\n const parts = path.map(String);\n if (parts[0] === \"filters\" && parts.length >= 3) {\n return `filters.${Number(parts[1])}.${parts[2] === \"equals\" ? \"equals\" : \"path\"}`;\n }\n if (parts[0] === \"template\" && parts[1] === \"acceptanceCriteria\") return \"criteria\";\n if (parts[0] === \"completion\" && parts[1] === \"checks\") return \"checks\";\n for (let n = parts.length; n > 0; n--) {\n const f = PATH_TO_FIELD[parts.slice(0, n).join(\".\")];\n if (f) return f;\n }\n return \"form\";\n}\n\nfunction intError(s: string, min: number, max: number, label: string): string | null {\n const n = toNumber(s);\n if (!Number.isInteger(n) || n < min || n > max) {\n return `${label} must be a whole number from ${min} to ${max}`;\n }\n return null;\n}\n\n/**\n * Validate a draft: friendly checks first (required fields, cron, timezone,\n * number ranges), then AutomationInput.safeParse for anything else.\n */\nexport function validateDraft(d: AutomationDraft): {\n input: AutomationInput | null;\n errors: DraftErrors;\n} {\n const errors: DraftErrors = {};\n const set = (f: DraftField, msg: string | null) => {\n if (msg && !errors[f]) errors[f] = msg;\n };\n if (!d.name.trim()) set(\"name\", \"Name is required\");\n if (!d.projectId) set(\"projectId\", \"Choose a project\");\n if (!d.title.trim()) set(\"title\", \"Task title is required\");\n switch (d.triggerKind) {\n case \"once\":\n if (!localInputToIso(d.onceAt)) set(\"onceAt\", \"Choose a date and time\");\n break;\n case \"cron\":\n set(\"cronExpr\", validateCron(d.cronExpr));\n set(\"cronTimezone\", validateTimezone(d.cronTimezone));\n break;\n case \"dependency\":\n if (!d.dependencyTaskId) set(\"dependencyTaskId\", \"Choose the task to wait for\");\n break;\n }\n d.filters.forEach((f, i) => {\n if (!f.path.trim() && f.equals.trim()) set(`filters.${i}.path`, \"Enter a payload path\");\n });\n if (d.mode === \"continue\" && !d.groupingKey.trim()) {\n set(\"groupingKey\", \"A grouping key is required to continue an existing task\");\n }\n if (d.continuationEnabled) {\n if (!d.continuationObjective.trim()) {\n set(\"continuationObjective\", \"An objective is required when continuation is on\");\n }\n set(\"maxContinuations\", intError(d.maxContinuations, 1, 50, \"Max continuations\"));\n set(\"maxElapsedMinutes\", intError(d.maxElapsedMinutes, 1, 1440, \"Max elapsed minutes\"));\n if (d.maxTokens.trim()) {\n const n = toNumber(d.maxTokens);\n if (!Number.isInteger(n) || n <= 0)\n set(\"maxTokens\", \"Max tokens must be a positive whole number\");\n }\n if (d.maxCostUsd.trim()) {\n const n = toNumber(d.maxCostUsd);\n if (!Number.isFinite(n) || n <= 0) set(\"maxCostUsd\", \"Max cost must be a positive amount\");\n }\n }\n const raw = draftToInput(d);\n const parsed = AutomationInput.safeParse(raw);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) set(fieldForPath(issue.path), issue.message);\n }\n const ok = parsed.success && Object.keys(errors).length === 0;\n return { input: ok ? parsed.data : null, errors };\n}\n\n/* ------------------------------------------------------------------ */\n/* History */\n/* ------------------------------------------------------------------ */\n\nexport function occurrenceTime(o: Occurrence): string {\n return o.scheduledFor ?? o.createdAt;\n}\n\n/** Union by id (later lists win), newest first. */\nexport function mergeOccurrences(...lists: (Occurrence[] | undefined | null)[]): Occurrence[] {\n const byId = new Map<string, Occurrence>();\n for (const list of lists) for (const o of list ?? []) byId.set(o.id, o);\n return [...byId.values()].sort(\n (a, b) =>\n b.createdAt.localeCompare(a.createdAt) || occurrenceTime(b).localeCompare(occurrenceTime(a)),\n );\n}\n\n/** Accept `Occurrence[]` or `{items|occurrences: Occurrence[]}`. */\nexport function normalizeHistory(res: unknown): Occurrence[] {\n if (Array.isArray(res)) return res as Occurrence[];\n if (res && typeof res === \"object\") {\n const r = res as { items?: unknown; occurrences?: unknown };\n if (Array.isArray(r.items)) return r.items as Occurrence[];\n if (Array.isArray(r.occurrences)) return r.occurrences as Occurrence[];\n }\n return [];\n}\n\nexport function curlExample(token: string, url: string): string {\n return `curl -X POST -H 'Authorization: Bearer ${token}' -H 'Content-Type: application/json' -d '{}' ${url}`;\n}\n"],"ignoreList":[0,1,2,3],"mappings":"A,sQASA,IAAMA,EAAa,CACjB,KAAM,gBACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,QAAS,CAAC,EAC3C,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,QAAS,CAAC,EACxC,CACE,OACA,CACE,EAAG,gPACH,IAAK,QACP,CACF,CACF,EACA,QAAS,CAAC,eAAe,CAC3B,EACAA,EAAW,KACX,IAAMyB,GAAeC,EAAiB1B,CAAU,ECjB1CC,EAAa,CACjB,KAAM,cACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,CAC3C,CACF,EACAA,EAAW,KACX,IAAM2B,GAAaF,EAAiBzB,CAAU,ECXxCC,EAAa,CACjB,KAAM,aACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,CAC3C,CACF,EACAA,EAAW,KACX,IAAM4B,GAAYJ,EAAiBxB,CAAU,ECTvC6B,EAAa,CACjB,KAAM,gBACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,EAC1C,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,CAC5C,CACF,EACAA,EAAW,KACX,IAAMC,EAAeN,EAAiBK,CAAU,E,iBCiBhD,SAAgBI,GAAM,CACpB,QACA,OACA,QACA,WACA,YACA,YAQC,CACD,IAAMC,GAAA,EAAKjC,EAAAA,MAAAA,CAAM,EACXkC,EAAS,GAAGD,EAAG,OACfE,EAAQ,GAAGF,EAAG,MACdG,EAAc,CAACC,EAAOH,EAAS,KAAMI,EAAQH,EAAQ,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,EACzF,OACE,EAAAJ,EAAA,KAAA,CAAC,MAAD,CAAK,UAAWlB,EAAG,8BAA+B0B,CAAS,EAA3D,SAAA,EACE,EAAAR,EAAA,KAAA,CAAC,QAAD,CAAO,QAASE,EAAI,UAAU,sBAA9B,SAAA,CACGO,EACAC,IAAY,EAAAV,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,yBAAyB,SAAA,aAAiB,CAAA,CAClE,C,GACNW,EAAS,CACR,KACA,eAAgBJ,EAAQ,GAAO,IAAA,GAC/B,mBAAoBF,GAAe,IAAA,EACrC,CAAC,EACAC,IACC,EAAAN,EAAA,IAAA,CAAC,IAAD,CAAG,GAAIG,EAAQ,UAAU,qBACtB,SAAAG,CACA,CAAA,EAEJC,IAAS,EAAAP,EAAA,IAAA,CAACY,EAAD,CAAY,GAAIR,EAAQ,SAAAG,CAAkB,CAAA,CACjD,C,EAET,CAEA,SAAgBK,EAAW,CAAE,KAAI,YAAkD,CACjF,OACE,EAAAZ,EAAA,KAAA,CAAC,IAAD,CAAO,KAAI,UAAU,6CAA6C,mBAAA,GAAlE,SAAA,EACE,EAAAA,EAAA,IAAA,CAACnB,EAAD,CAAe,cAAA,GAAY,UAAU,0BAA4B,CAAA,GACjE,EAAAmB,EAAA,IAAA,CAAC,OAAD,CAAO,UAAe,CAAA,CACrB,C,EAEP,CAGA,SAAgBa,GAAO,CAAE,YAAW,WAAU,GAAGC,GAAiD,CAChG,OACE,EAAAd,EAAA,IAAA,CAAC,SAAD,CACE,UAAWlB,EACT,gHACA,gGACA,oCACA0B,CACF,EACA,GAAIM,EAEH,UACK,CAAA,CAEZ,CAGA,SAAgBC,GAAO,CACrB,UACA,WACA,QACA,SAAS,KACT,UAAU,MACV,OACA,WACA,KACA,aAYC,CACD,OACE,EAAAf,EAAA,KAAA,CAAC,SAAD,CACM,KACJ,KAAK,SACL,KAAK,SACL,eAAcgB,EACd,aAAYP,EACZ,YAAWQ,GAAQ,IAAA,GACnB,SAAUC,GAAYD,EACtB,YAAeE,EAAS,CAACH,CAAO,EAChC,UAAWlC,EACT,gFACA,yCACA0B,CACF,EAbF,SAAA,EAeE,EAAAR,EAAA,IAAA,CAAC,OAAD,CACE,cAAA,GACA,UAAWlB,EACT,2FACAkC,EAAU,0BAA4B,mCACxC,EAEA,UAAA,EAAAhB,EAAA,IAAA,CAAC,OAAD,CACE,UAAWlB,EACT,gEACAkC,EAAU,kCAAoC,4BAChD,CACD,CAAA,CACG,CAAA,EACLC,GAAO,EAAAjB,EAAA,IAAA,CAACf,GAAD,CAAS,UAAU,UAAY,CAAA,EAAI,MAC3C,EAAAe,EAAA,IAAA,CAAC,OAAD,CAAM,UAAWgB,EAAU,YAAc,aAAe,SAAAA,EAAUI,EAASC,CAAc,CAAA,CACnF,C,EAEZ,CAGA,SAAgBC,GAAQ,CACtB,QACA,cACA,WACA,UACA,YACA,UAQC,CACD,IAAMpB,GAAA,EAAKjC,EAAAA,MAAAA,CAAM,EACjB,OACE,EAAA+B,EAAA,KAAA,CAAC,UAAD,CACE,kBAAiBE,EACjB,cAAaqB,EACb,UAAWzC,EAAG,yDAA0D0B,CAAS,EAHnF,SAAA,EAKE,EAAAR,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,wDAAf,SAAA,EACE,EAAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,UAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAAC,KAAD,CAAQ,KAAI,UAAU,0BACnB,SAAAwB,CACC,CAAA,EACHC,IAAe,EAAAzB,EAAA,IAAA,CAAC,IAAD,CAAG,UAAU,qBAAsB,SAAAyB,CAAe,CAAA,CAC/D,CACJ,CAAA,EAAAC,IAAW,EAAA1B,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,uBAAwB,SAAA0B,CAAa,CAAA,CAC7D,CACL,CAAA,GAAA,EAAA1B,EAAA,IAAA,CAAC,MAAD,CAAK,UAAU,sBAAuB,UAAc,CAAA,CAC7C,C,EAEb,CAEA,IAAM2B,GAAiB,CAACpC,GAAcG,GAAYI,EAAcF,EAAS,EAEzE,SAAgBgC,GAAa,CAAE,WAAU,aAAyD,CAChG,IAAMC,EAAOF,GAAeG,IAAahC,EACzC,OACE,EAAAE,EAAA,IAAA,CAAC6B,EAAD,CACE,cAAA,GACA,UAAW/C,EAAG,kBAAmBgD,IAAa,EAAI,cAAgB,aAActB,CAAS,CAC1F,CAAA,CAEL,CAGA,SAAgBuB,GAAa,CAAE,SAA4B,CASzD,OARIC,EAAQ,GAER,EAAAhC,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,sDAAhB,SAAA,EACE,EAAAA,EAAA,IAAA,CAACnB,EAAD,CAAe,cAAA,GAAY,UAAU,iBAAmB,CAAA,EACvDmD,IAAU,EAAI,YAAc,GAAGA,EAAM,UAClC,C,IAIR,EAAAhC,EAAA,KAAA,CAAC,OAAD,CAAM,UAAU,oDAAhB,SAAA,EACE,EAAAA,EAAA,IAAA,CAACd,GAAD,CAAa,cAAA,GAAY,UAAU,iBAAmB,CAAA,EAAC,aAEnD,C,EAEV,CAGA,SAAgB+C,GAAe,CAAE,aAAqC,CACpE,IAAMC,EAAaxD,EAAc,EAGjC,OAFIwD,EAAW,QAAU,QACrBA,EAAW,QAAU,cAAgB,CAACA,EAAW,aAAqB,MAExE,EAAAlC,EAAA,KAAA,CAAC,IAAD,CACE,KAAK,SACL,UAAWlB,EACT,+FACA0B,CACF,EALF,SAAA,EAOE,EAAAR,EAAA,IAAA,CAACb,GAAD,CAAU,cAAA,GAAY,UAAU,qCAAuC,CAAA,GACvE,EAAAa,EAAA,KAAA,CAAC,OAAD,CAAA,SAAA,CAAM,iCAEHkC,EAAW,aAAe,SAASnD,EAAWmD,EAAW,YAAY,IAAM,GAAG,6DAE3E,CAAA,CAAA,CACL,C,EAEP,CAEA,IAAaC,GAAkB,EAAY,EAAS,KAClD,oBAAoB,mBAAmBjC,CAAE,IAAIkC,IAelCC,EAAsBrD,EAAyB,CAAC,CAAE,IAAS,CACtE,KAAM,CAAC,EACP,QAAS,CAAC,EACV,IAAM,GAAMsD,EAAK,IAAO,CAAE,KAAM,CAAE,GAAGC,EAAE,MAAOC,EAAE,IAAKA,CAAE,CAAE,EAAE,EAC3D,QAAU,GACRF,EAAK,GAAM,CACT,IAAMG,EAAO,CAAE,GAAGF,EAAE,IAAK,EACzB,IAAK,IAAMC,KAAKE,EAAM,EAAKF,EAAE,IAAMA,EACnC,MAAO,CAAE,MAAK,CAChB,CAAC,EACH,OAAS,GACPF,EAAK,GAAM,CACT,IAAMG,EAAO,CAAE,GAAGF,EAAE,IAAK,EAEzB,OADA,OAAOE,EAAKvC,GACL,CAAE,OAAM,QAAS,CAAE,GAAGqC,EAAE,SAAUrC,GAAK,EAAK,CAAE,CACvD,CAAC,CACL,EAAE,EAEF,SAASyC,EAAM,EAA2B,EAAmD,CAG3F,OAFKH,EACAI,GACEA,EAAE,UAAYJ,EAAE,UAAYI,EADpBJ,EADAI,CAGjB,CAGA,SAAgBC,IAAmD,CACjE,IAAMC,EAAQrE,EAAc,GAAM8D,EAAE,WAAW,EACzCQ,EAAQV,EAAqB,GAAME,EAAE,IAAI,EACzCS,EAAUX,EAAqB,GAAME,EAAE,OAAO,EACpD,OAAA,EAAOrE,EAAAA,QAAAA,KAAc,CACnB,IAAM+E,EAAkC,CAAC,EACzC,IAAK,IAAM/C,KAAM,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK4C,CAAK,EAAG,GAAG,OAAO,KAAKC,CAAK,CAAC,CAAC,EAAG,CACxE,GAAIC,EAAQ9C,GAAK,SACjB,IAAM,EAAIyC,EAAMG,EAAM5C,GAAK6C,EAAM7C,EAAG,EAChC,IAAG,EAAIA,GAAM,EACnB,CACA,OAAO+C,CACT,EAAG,CAACH,EAAOC,EAAOC,CAAO,CAAC,CAC5B,CAEA,SAAgBE,GAAoB,EAAgD,CAClF,IAAMC,EAAY1E,EAAc,GAAOyB,EAAKqC,EAAE,YAAYrC,GAAM,IAAA,EAAU,EACpEkD,EAAYf,EAAqB,GAAOnC,EAAKqC,EAAE,KAAKrC,GAAM,IAAA,EAAU,EAE1E,OADgBmC,EAAqB,GAAOnC,EAAKqC,EAAE,QAAQrC,GAAM,IAAA,EAC1D,EAAU,IAAA,GAAYyC,EAAMQ,EAAWC,CAAS,CACzD,CAGA,SAAgBC,IAAmB,CACjC,GAAM,CAACpC,EAAMqC,IAAA,EAAWnF,EAAAA,SAAAA,CAAkC,CAAC,CAAC,EAa5D,MAAO,CAAE,OAAM,QAAA,EAZAC,EAAAA,YAAAA,CAAY,MAAO,EAAoC,IAAqB,CACzFkF,EAAS,IAAO,CAAE,GAAGV,GAAIJ,EAAE,IAAK,EAAK,EAAE,EACvC,GAAI,CACF,IAAMe,EAAM,MAAM/E,EAAiC2D,EAAeK,EAAE,EAAE,EAAG,CAAE,SAAQ,CAAC,EAChFe,GAAO,OAAOA,GAAQ,UAAY,OAAQA,GAAKlB,EAAoB,SAAS,CAAC,CAAC,IAAIkB,CAAG,EACzFnE,EAAM,QAAQ,GAAGoD,EAAE,KAAK,GAAGgB,EAAU,UAAY,YAAY,CAC/D,OAASC,EAAG,CACVrE,EAAM,MAAM,aAAaoE,EAAU,SAAW,UAAU,GAAGhB,EAAE,KAAK,IAAI5D,EAAa6E,CAAC,GAAG,CACzF,QAAU,CACRH,EAAS,IAAO,CAAE,GAAGV,GAAIJ,EAAE,IAAK,EAAM,EAAE,CAC1C,CACF,EAAG,CAAC,CACW,CAAO,CACxB,CAGA,SAAgBkB,GAAU,EAAqB,CAC7C,GAAM,CAACzC,EAAMqC,IAAA,EAAWnF,EAAAA,SAAAA,CAAkC,CAAC,CAAC,EAqB5D,MAAO,CAAE,OAAM,KAAA,EApBHC,EAAAA,YAAAA,CACV,KAAO,IAAuC,CAC5CkF,EAAS,IAAO,CAAE,GAAGV,GAAIJ,EAAE,IAAK,EAAK,EAAE,EACvC,GAAI,CACF,IAAMe,EAAM,MAAM5E,EAAwCwD,EAAeK,EAAE,GAAI,MAAM,CAAC,EAChFmB,EAAQJ,GAAO,OAAOA,GAAQ,SAAWA,EAAI,MAAQ,IAAA,GAC3DnE,EAAM,QACJuE,GAASA,IAAU,QACf,GAAGnB,EAAE,KAAK,yBAAyBmB,EAAM,QAAQ,KAAM,GAAG,EAAE,GAC5D,GAAGnB,EAAE,KAAK,SAChB,EACAoB,IAAS,CACX,OAAS,EAAG,CACVxE,EAAM,MAAM,iBAAiBoD,EAAE,KAAK,IAAI5D,EAAa,CAAC,GAAG,CAC3D,QAAU,CACR0E,EAAS,IAAO,CAAE,GAAGV,GAAIJ,EAAE,IAAK,EAAM,EAAE,CAC1C,CACF,EACA,CAACoB,CAAM,CAEM,CAAI,CACrB,CC5UA,IAAaC,GAAmD,CAC9D,OAAQ,SACR,KAAM,OACN,KAAM,WACN,QAAS,UACT,WAAY,YACd,EAEaC,EAAgF,CAC3F,CAAE,MAAO,QAAS,MAAO,QAAS,YAAa,kCAAmC,EAClF,CACE,MAAO,WACP,MAAO,WACP,YAAa,qDACf,EACA,CACE,MAAO,QACP,MAAO,QACP,YAAa,8DACf,CACF,EAEaC,GAAkF,CAC7F,CACE,MAAO,OACP,MAAO,OACP,YAAa,4DACf,EACA,CACE,MAAO,YACP,MAAO,YACP,YAAa,iFACf,EACA,CACE,MAAO,SACP,MAAO,SACP,YAAa,kFACf,CACF,EAEaC,EAAgF,CAC3F,CACE,MAAO,OACP,MAAO,OACP,YAAa,kFACf,EACA,CACE,MAAO,WACP,MAAO,WACP,YAAa,6DACf,CACF,EAEA,SAAgBC,EAAU,EAA8B,CACtD,OAAOH,EAAa,KAAM,GAAMI,EAAE,QAAUC,CAAI,CAAC,EAAE,OAASA,CAC9D,CAMA,IAAaC,EAAqB,CAAC,WAAY,WAAY,iBAAkB,oBAAoB,EAOjG,SAAgBC,EAAS,EAAyB,CAEhD,OADIC,EAAM,QAAU,EAAUA,EAAM,IAAM,GACnC,GAAGA,EAAM,MAAM,EAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,OAAOA,EAAMA,EAAM,OAAS,IACtE,CAEA,SAASC,EAAI,EAAmB,CAC9B,OAAO,OAAOC,CAAC,CAAC,CAAC,SAAS,EAAG,GAAG,CAClC,CAEA,SAAgBC,EAAQ,EAAmB,CACzC,IAAMC,EAASF,EAAI,IACnB,GAAIE,GAAU,IAAMA,GAAU,GAAI,MAAO,GAAGF,EAAE,IAC9C,OAAQA,EAAI,GAAZ,CACE,IAAK,GACH,MAAO,GAAGA,EAAE,IACd,IAAK,GACH,MAAO,GAAGA,EAAE,IACd,IAAK,GACH,MAAO,GAAGA,EAAE,IACd,QACE,MAAO,GAAGA,EAAE,GAChB,CACF,CAEA,SAASG,EAAW,EAAmB,CACrC,OAAOpC,GAAIA,EAAE,EAAE,CAAE,YAAY,EAAIA,EAAE,MAAM,CAAC,CAC5C,CAGA,SAAgBqC,EAAM,EAAwB,CAC5C,OAAOC,EACJ,MAAM;CAAI,CAAC,CACX,IAAK,GAAMC,EAAE,KAAK,CAAC,CAAC,CACpB,OAAQ,GAAMA,EAAE,OAAS,CAAC,CAC/B,CAMA,IAAMC,EAAY,CAAC,SAAU,SAAU,UAAW,YAAa,WAAY,SAAU,UAAU,EACzFC,EAAc,CAClB,UACA,WACA,QACA,QACA,MACA,OACA,OACA,SACA,YACA,UACA,WACA,UACF,EAUMC,GAA0B,CAC9B,CAAE,KAAM,SAAU,IAAK,EAAG,IAAK,EAAG,EAClC,CAAE,KAAM,OAAQ,IAAK,EAAG,IAAK,EAAG,EAChC,CAAE,KAAM,eAAgB,IAAK,EAAG,IAAK,EAAG,EACxC,CACE,KAAM,QACN,IAAK,EACL,IAAK,GACL,MAAOD,EAAY,IAAK,GAAMd,EAAE,MAAM,EAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAC3D,EACA,CACE,KAAM,cACN,IAAK,EACL,IAAK,EACL,MAAOa,EAAU,IAAK,GAAMG,EAAE,MAAM,EAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CACzD,CACF,EAaA,SAASC,EAAW,EAAe,EAAgC,CACjE,IAAMC,EAAQC,EAAM,YAAY,EAChC,GAAIC,EAAI,MAAO,CACb,IAAMC,EAAMD,EAAI,MAAM,QAAQF,CAAK,EACnC,GAAIG,GAAO,EAAG,OAAOD,EAAI,IAAMC,CACjC,CACA,GAAI,CAAC,QAAQ,KAAKF,CAAK,EAAG,MAAO,IAAIA,EAAM,mBAC3C,IAAMb,EAAI,OAAOa,CAAK,EAEtB,OADIb,EAAIc,EAAI,KAAOd,EAAIc,EAAI,IAAY,GAAGd,EAAE,mBAAmBc,EAAI,IAAI,GAAGA,EAAI,MACvEd,CACT,CAGA,SAAgBgB,GAAe,EAAa,EAAmC,CAC7E,GAAIC,IAAQ,KAAOA,IAAQ,IAAK,MAAO,CAAE,IAAK,GAAM,OAAQ,CAAC,EAAG,KAAM,KAAM,SAAU,EAAM,EAC5F,GAAI,SAAS,KAAKA,CAAG,GAAK,CAACH,EAAI,OAAO,KAAM,GAAMG,EAAI,YAAY,CAAC,CAAC,SAASjB,CAAC,CAAC,EAE7E,MADK,wBAAwB,KAAKiB,CAAG,EAC9B,CAAE,IAAK,GAAO,OAAQ,CAAC,EAAG,KAAM,KAAM,SAAU,EAAK,EADb,IAAIA,EAAI,gBAGzD,IAAMC,EAAQD,EAAI,MAAM,GAAG,EACrBE,EAAS,IAAI,IACfC,EAA0B,KAC9B,IAAK,IAAMC,KAAQH,EAAO,CACxB,GAAI,CAACG,EAAM,MAAO,kBAClB,GAAM,CAACC,EAAMC,EAASC,GAASH,EAAK,MAAM,GAAG,EAC7C,GAAIG,IAAU,IAAA,GAAW,MAAO,IAAIH,EAAK,0BACzC,IAAII,EAAQ,EACZ,GAAIF,IAAY,IAAA,GAAW,CACzB,GAAI,CAAC,QAAQ,KAAKA,CAAO,GAAK,OAAOA,CAAO,EAAI,EAAG,MAAO,IAAIA,EAAQ,uBACtE,EAAQ,OAAOA,CAAO,CACxB,CACA,IAAIG,EACAC,EACJ,GAAIL,IAAS,KAAOA,IAAS,IAC3B,EAAQR,EAAI,IACZ,EAAMA,EAAI,SACL,GAAIQ,GAAM,SAAS,GAAG,EAAG,CAC9B,GAAM,CAACtD,EAAGI,GAAKkD,EAAK,MAAM,GAAG,EACvBM,EAAKjB,EAAW3C,GAAK,GAAI8C,CAAG,EAC5Be,EAAKlB,EAAWvC,GAAK,GAAI0C,CAAG,EAClC,GAAI,OAAOc,GAAO,SAAU,OAAOA,EACnC,GAAI,OAAOC,GAAO,SAAU,OAAOA,EACnC,GAAID,EAAKC,EAAI,MAAO,SAASP,EAAK,iBAClC,EAAQM,EACR,EAAMC,CACR,KAAO,CACL,IAAMC,EAAInB,EAAWW,GAAQ,GAAIR,CAAG,EACpC,GAAI,OAAOgB,GAAM,SAAU,OAAOA,EAClC,EAAQA,EACR,EAAMP,IAAY,IAAA,GAAsBO,EAAVhB,EAAI,GACpC,CACA,IAAK,IAAIiB,EAAIL,EAAOK,GAAKJ,EAAK,GAAKF,EAAON,EAAO,IAAIY,CAAC,EAClDb,EAAM,SAAW,GAAKK,IAAY,IAAA,IAAa,CAACD,GAAM,SAAS,GAAG,IACpE,EAAO,CAAE,QAAO,OAAM,EAE1B,CACA,IAAIU,EAAS,CAAC,GAAGb,CAAM,CAAC,CAAC,MAAM,EAAG,IAAMnD,EAAII,CAAC,EAEzC0C,EAAI,MAAQ,IAAG,EAAS,CAAC,GAAG,IAAI,IAAIkB,EAAO,IAAK,GAAMF,EAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAG,IAAM9D,EAAII,CAAC,GACvF,IAAM6D,EAAOnB,EAAI,MAAQ,EAAI,EAAIA,EAAI,IAAMA,EAAI,IAAM,EAGrD,OAFIkB,EAAO,SAAWC,GAAQ,CAACb,EACtB,CAAE,IAAK,GAAM,OAAQ,CAAC,EAAG,KAAM,KAAM,SAAU,EAAM,EACvD,CAAE,IAAK,GAAO,OAAQY,EAAQ,OAAM,SAAU,EAAM,CAC7D,CAEA,SAAgBE,EAAU,EAAoC,CAC5D,IAAMC,EAAUC,EAAK,KAAK,EAC1B,GAAI,CAACD,EAAS,MAAO,0BACrB,IAAME,EAASF,EAAQ,MAAM,KAAK,EAClC,GAAIE,EAAO,SAAW,EACpB,MAAO,uEAAuEA,EAAO,SAEvF,IAAM5D,EAAmB,CAAC,EAC1B,IAAK,IAAIsD,EAAI,EAAGA,EAAI,EAAG,IAAK,CAC1B,IAAMjB,EAAML,GAAYsB,GAClBO,EAAStB,GAAeqB,EAAON,GAAKjB,CAAG,EAC7C,GAAI,OAAOwB,GAAW,SAAU,MAAO,GAAGxB,EAAI,KAAK,IAAIwB,IACvD7D,EAAI,KAAK6D,CAAM,CACjB,CACA,OAAO7D,CACT,CAGA,SAAgB8D,EAAa,EAA6B,CACxD,IAAMD,EAASJ,EAAUE,CAAI,EAC7B,OAAO,OAAOE,GAAW,SAAWA,EAAS,IAC/C,CAGA,SAAgBE,EAAiB,EAA2B,CAC1D,GAAI,CAACC,EAAG,KAAK,EAAG,MAAO,mBACvB,GAAI,CAEF,OADA,IAAI,KAAK,eAAe,IAAA,GAAW,CAAE,SAAUA,EAAG,KAAK,CAAE,CAAC,EACnD,IACT,MAAQ,CACN,MAAO,qBAAqBA,EAAG,EACjC,CACF,CAEA,SAASC,EAAa,EAA2B,CAC/C,IAAK,IAAIX,EAAI,EAAGA,EAAIZ,EAAO,OAAQ,IAAK,GAAIA,EAAOY,KAAOZ,EAAOY,EAAI,GAAM,EAAG,MAAO,GACrF,OAAOZ,EAAO,OAAS,CACzB,CAIA,SAASwB,GAAa,EAAc,EAAiC,CACnE,GAAIjD,EAAE,KAAOkD,EAAE,IAAK,MAAO,CAAE,KAAM,OAAQ,KAAM,cAAe,EAChE,GAAIlD,EAAE,MAAQA,EAAE,KAAK,QAAU,GAAKkD,EAAE,IACpC,MAAO,CACL,KAAM,OACN,KAAMlD,EAAE,KAAK,QAAU,EAAI,eAAiB,SAASA,EAAE,KAAK,MAAM,SACpE,EAEF,GAAIA,EAAE,IAQJ,OAPIkD,EAAE,MAAQA,EAAE,OAAO,SAAW,EAAU,KACxCF,EAAaE,EAAE,MAAM,EAChB,CACL,KAAM,OACN,KAAM,qBAAqB7C,EAAI6C,EAAE,OAAO,EAAG,EAAE,SAAS7C,EAAI6C,EAAE,OAAOA,EAAE,OAAO,OAAS,EAAG,EAAE,IAC5F,EAEK,KAET,GAAIA,EAAE,IAGJ,OAFIlD,EAAE,KAAa,KACfA,EAAE,OAAO,SAAW,GAAKA,EAAE,OAAO,KAAO,EAAU,CAAE,KAAM,OAAQ,KAAM,YAAa,EACnF,CACL,KAAM,OACN,KAAM,iBAAiBG,EAASH,EAAE,OAAO,IAAK,GAAM,IAAIK,EAAI+B,CAAC,GAAG,CAAC,GACnE,EAEF,GAAIc,EAAE,MAAQA,EAAE,KAAK,QAAU,GAAKlD,EAAE,OAAO,SAAW,GAAK,CAACA,EAAE,KAAM,CACpE,IAAMmD,EAAKnD,EAAE,OAAO,KAAO,EAAI,GAAK,QAAQK,EAAIL,EAAE,OAAO,EAAG,IAC5D,MAAO,CACL,KAAM,OACN,KAAMkD,EAAE,KAAK,QAAU,EAAI,aAAaC,IAAO,SAASD,EAAE,KAAK,MAAM,QAAQC,GAC/E,CACF,CACA,GAAInD,EAAE,OAAO,OAASkD,EAAE,OAAO,QAAU,EAAG,CAC1C,IAAME,EAAkB,CAAC,EACzB,IAAK,IAAMC,KAAMH,EAAE,OAAQ,IAAK,IAAMI,KAAMtD,EAAE,OAAQoD,EAAM,KAAK,GAAG/C,EAAIgD,CAAE,EAAE,GAAGhD,EAAIiD,CAAE,GAAG,EACxF,MAAO,CAAE,KAAM,KAAM,KAAMnD,EAASiD,CAAK,CAAE,CAC7C,CACA,GAAI,CAACJ,EAAaE,EAAE,MAAM,EAAG,OAAO,KACpC,IAAMK,EAAQL,EAAE,OAAO,GACjBM,EAAON,EAAE,OAAOA,EAAE,OAAO,OAAS,GACxC,GAAIlD,EAAE,MAAQA,EAAE,KAAK,QAAU,EAC7B,MAAO,CACL,KAAM,OACN,KAAM,SAASA,EAAE,KAAK,MAAM,gBAAgBK,EAAIkD,CAAK,EAAE,SAASlD,EAAImD,CAAI,EAAE,IAC5E,EAEF,GAAIxD,EAAE,OAAO,SAAW,EAAG,CACzB,IAAMyD,EAAKpD,EAAIL,EAAE,OAAO,EAAG,EAC3B,MAAO,CAAE,KAAM,OAAQ,KAAM,mBAAmBK,EAAIkD,CAAK,EAAE,GAAGE,EAAG,MAAMpD,EAAImD,CAAI,EAAE,GAAGC,GAAK,CAC3F,CACA,OAAO,IACT,CAGA,SAASC,GAAY,EAAW,EAAmB,CACjD,OAASpF,EAAI,GAAK,GAAOI,EAAI,GAAK,CACpC,CAEA,SAASiF,GACP,EACA,EACA,EACuC,CACvC,GAAI,CAACC,EAAI,KAAO,CAACC,EAAI,IAAK,OAAO,KACjC,IAAMC,EAASC,EAAI,IAAM,KAAO5D,EAAS4D,EAAI,OAAO,IAAK,GAAMjD,EAAYsB,EAAI,EAAG,CAAC,EAC7E4B,EAAWF,EAAS,OAAOA,IAAW,GAC5C,GAAI,CAACD,EAAI,IAAK,CACZ,IAAMI,EAAO,CAAC,GAAGJ,EAAI,MAAM,CAAC,CAAC,KAAKH,EAAW,EACvCQ,EAAMD,EAAK,KAAK,GAAG,EACzB,GAAIC,IAAQ,YACV,MAAO,CAAE,KAAM,gBAAgBF,IAAY,KAAM,eAAeA,GAAW,EAE7E,GAAIE,IAAQ,MACV,MAAO,CAAE,KAAM,4BAA4BF,IAAY,KAAM,eAAeA,GAAW,EAEzF,IAAMG,EAAQF,EAAK,IAAK,GAAMpD,EAAUG,EAAG,EAC3C,MAAO,CACL,KAAM,SAASb,EAASgE,CAAK,IAAIH,IACjC,KAAM,OAAO7D,EAASgE,EAAM,IAAK,GAAM,GAAG7D,EAAE,EAAE,CAAC,IAAI0D,GACrD,CACF,CACA,GAAI,CAACJ,EAAI,IAAK,CACZ,GAAIA,EAAI,OAAO,OAAS,EAAG,OAAO,KAClC,IAAMQ,EAAOjE,EAASyD,EAAI,OAAO,IAAIrD,CAAO,CAAC,EACvC8D,EAAKP,GAAkB,cAC7B,MAAO,CAAE,KAAM,UAAUM,EAAK,MAAMC,IAAM,KAAM,WAAWD,EAAK,MAAMC,GAAK,CAC7E,CACA,MAAO,CAAE,KAAM,YAAYL,IAAY,KAAMA,CAAS,CACxD,CAOA,SAAgBM,EAAa,EAAc,EAAkC,CAC3E,IAAM1B,EAASJ,EAAUE,CAAI,EAE7B,GADI,OAAOE,GAAW,UAClBA,EAAO,KAAM,GAAM2B,EAAE,QAAQ,EAAG,OAAO,KAC3C,GAAM,CAACvE,EAAGkD,EAAGU,EAAKG,EAAKF,GAAOjB,EACxB4B,EAAOvB,GAAajD,EAAGkD,CAAC,EACxBe,EAAON,GAAaC,EAAKG,EAAKF,CAAG,EACvC,GAAI,CAACW,GAAQ,CAACP,EAAM,OAAO,KAC3B,IAAMtD,EAAO6D,EAAK,OAAS,KAAO,GAAGP,EAAK,KAAK,MAAMO,EAAK,OAAS,GAAGA,EAAK,OAAOP,EAAK,OACvF,OAAOQ,EAAW,GAAG9D,EAAK,IAAI8D,EAAS,GAAK9D,CAC9C,CAGA,SAAgB+D,GAAkB,EAAc,EAA0B,CACxE,OAAOJ,EAAa5B,EAAM+B,CAAQ,GAAK,QAAQ/B,EAAK,KAAK,EAAE,IAAI+B,EAAS,EAC1E,CAMA,SAAgBE,EAAe,EAAqB,CAClD,IAAM3D,EAAI,IAAI,KAAK4D,CAAG,EAEtB,OADI,OAAO,MAAM5D,EAAE,QAAQ,CAAC,EAAU4D,EAC/B5D,EAAE,eAAe,IAAA,GAAW,CAAE,UAAW,SAAU,UAAW,OAAQ,CAAC,CAChF,CAYA,SAAgB6D,EAAgB,EAAkB,EAAsB,CAAC,EAAW,CAClF,IAAMC,EAAMC,EAAI,YAAcJ,EAC9B,OAAQK,EAAQ,KAAhB,CACE,IAAK,SACH,MAAO,SACT,IAAK,OACH,OAAOA,EAAQ,IAAM,CAAC,OAAO,MAAM,KAAK,MAAMA,EAAQ,EAAE,CAAC,EACrD,WAAWF,EAAIE,EAAQ,EAAE,IACzB,wBACN,IAAK,OACH,OAAON,GAAkBM,EAAQ,KAAMA,EAAQ,QAAQ,EACzD,IAAK,UACH,MAAO,UACT,IAAK,aAAc,CACjB,IAAM1H,EAAQ0H,EAAQ,OAASD,EAAI,YAAYC,EAAQ,MAAM,EAAI,IAAA,GAEjE,OADI1H,EAAc,SAASA,EAAM,WAC1B0H,EAAQ,OAAS,aAAaA,EAAQ,OAAO,UAAY,qBAClE,CACF,CACF,CAeA,SAASC,GAAc,EAAqB,EAA6B,CACvE,IAAMC,EAAIC,EAAM,QAChB,OAAQD,EAAE,KAAV,CACE,IAAK,SACH,MAAO,oBACT,IAAK,UAAW,CACd,IAAME,EAAUD,EAAM,QAAQ,OAAQ,GAAMZ,EAAE,KAAK,KAAK,CAAC,EAEzD,OADIa,EAAQ,SAAW,EAAU,6BAC1B,oCAAoCjF,EACzCiF,EAAQ,IAAK,GAAM,GAAGb,EAAE,KAAK,KAAK,EAAE,MAAMA,EAAE,OAAO,EAAE,CACvD,GACF,CACA,QACE,OAAOM,EAAgBK,EAAGH,CAAG,CACjC,CACF,CAOA,SAAgBM,GAAoB,EAAqB,EAAsB,CAAC,EAAW,CACzF,IAAM/H,EAAQ6H,EAAM,SAAS,MAAM,KAAK,GAAK,gBACvCG,EAAUP,EAAI,YAAc,OAAOA,EAAI,cAAgB,GACvDQ,EAAOR,EAAI,SAAW,OAAOA,EAAI,WAAa,iCAC9CS,EAAUT,EAAI,YAAc,iBAAiBA,EAAI,cAAgB,GACnEU,EACJ,OAAQN,EAAM,KAAd,CACE,IAAK,WAAY,CACf,IAAMjB,EAAMiB,EAAM,aAAa,KAAK,EACpC,EAASjB,EACL,iCAAiCA,EAAI,gBAAgB5G,EAAM,IAC3D,0CAA0CA,EAAM,IACpD,KACF,CACA,IAAK,QACH,EAAS,wBAAwBA,EAAM,8DACvC,MACF,QACE,EAAS,wBAAwBA,EAAM,EAC3C,CACA,IAAMkE,EAAQ,CAAC,GAAGyD,GAAcE,EAAOJ,CAAG,EAAE,IAAIU,IAASH,IAAUC,IAAOC,GAAS,EAWnF,GAVAhE,EAAM,KACJ2D,EAAM,UAAY,OACd,sCACAA,EAAM,UAAY,YAChB,sDACA,wDACR,GACIA,EAAM,QAAQ,OAAS,QAAUA,EAAM,QAAQ,OAAS,SAC1D3D,EAAM,KAAK2D,EAAM,SAAW,OAAS,mBAAqB,gCAAgC,EAExFA,EAAM,aAAa,QAAS,CAC9B,IAAMO,EAAIP,EAAM,aAChB3D,EAAM,KACJ,gCAAgCkE,EAAE,iBAAiB,gBAAgBA,EAAE,kBAAkB,SACzF,CACF,CACA,IAAMC,EAASR,EAAM,WAAW,OAOhC,OANIQ,GAAUA,EAAO,OAAS,GAC5BnE,EAAM,KAAK,OAAOmE,EAAO,SAAW,EAAI,UAAY,GAAGA,EAAO,OAAO,UAAU,EAEjFnE,EAAM,KACJ2D,EAAM,WAAW,mBAAqB,wBAA0B,0BAClE,EACO1E,EAAWe,EAAM,KAAK,IAAI,CAAC,CACpC,CA0CA,SAAgBoE,GAAwB,CACtC,GAAI,CACF,OAAO,KAAK,eAAe,CAAC,CAAC,gBAAgB,CAAC,CAAC,UAAY,KAC7D,MAAQ,CACN,MAAO,KACT,CACF,CAEA,SAAgBC,EAAW,EAAkD,CAAC,EAAoB,CAChG,MAAO,CACL,KAAM,GACN,QAAS,GACT,UAAWC,EAAK,WAAa,GAC7B,YAAa,SACb,OAAQ,GACR,SAAU,cACV,aAAcA,EAAK,UAAYF,EAAc,EAC7C,iBAAkB,GAClB,QAAS,CAAC,EACV,MAAO,GACP,UAAW,GACX,SAAU,GACV,SAAU,EACV,OAAQ,GACR,UAAW,GACX,KAAM,QACN,YAAa,GACb,QAAS,OACT,OAAQ,OACR,oBAAqB,GACrB,sBAAuB,GACvB,iBAAkB,IAClB,kBAAmB,KACnB,UAAW,GACX,WAAY,GACZ,OAAQ,GACR,mBAAoB,EACtB,CACF,CAGA,SAAgBG,GAAgB,EAAwC,CACtE,GAAI,CAACnB,EAAK,MAAO,GACjB,IAAM5D,EAAI,IAAI,KAAK4D,CAAG,EAEtB,OADI,OAAO,MAAM5D,EAAE,QAAQ,CAAC,EAAU,GAC/B,GAAGA,EAAE,YAAY,EAAE,GAAGX,EAAIW,EAAE,SAAS,EAAI,CAAC,EAAE,GAAGX,EAAIW,EAAE,QAAQ,CAAC,EAAE,GAAGX,EAAIW,EAAE,SAAS,CAAC,EAAE,GAAGX,EAAIW,EAAE,WAAW,CAAC,GACnH,CAGA,SAAgBgF,EAAgB,EAAuB,CACrD,GAAI,CAACC,EAAO,MAAO,GACnB,IAAMjF,EAAI,IAAI,KAAKiF,CAAK,EACxB,OAAO,OAAO,MAAMjF,EAAE,QAAQ,CAAC,EAAI,GAAKA,EAAE,YAAY,CACxD,CAEA,SAAgBkF,GACd,EACA,EAA8B,CAAC,EACd,CACjB,IAAMtE,EAAOiE,EAAW,CAAE,UAAWvH,EAAE,UAAW,SAAUwH,EAAK,QAAS,CAAC,EACrEZ,EAAI5G,EAAE,QACNoH,EAAIpH,EAAE,aACZ,MAAO,CACL,GAAGsD,EACH,KAAMtD,EAAE,KACR,QAASA,EAAE,QACX,YAAa4G,EAAE,KACf,OAAQA,EAAE,OAAS,OAASa,GAAgBb,EAAE,EAAE,EAAI,GACpD,SAAUA,EAAE,OAAS,OAASA,EAAE,KAAOtD,EAAK,SAC5C,aAAcsD,EAAE,OAAS,OAASA,EAAE,SAAWtD,EAAK,aACpD,iBAAkBsD,EAAE,OAAS,aAAeA,EAAE,OAAS,GACvD,QAAS5G,EAAE,QAAQ,IAAK,IAAO,CAAE,GAAGiG,CAAE,EAAE,EACxC,MAAOjG,EAAE,SAAS,MAClB,UAAWA,EAAE,SAAS,UACtB,SAAUA,EAAE,SAAS,mBAAmB,KAAK;CAAI,EACjD,SAAUA,EAAE,SAAS,SACrB,OAAQA,EAAE,QAAU,GACpB,UAAWA,EAAE,WAAa,GAC1B,KAAMA,EAAE,KACR,YAAaA,EAAE,aAAe,GAC9B,QAASA,EAAE,QACX,OAAQA,EAAE,OACV,oBAAqBoH,EAAE,QACvB,sBAAuBA,EAAE,QAAUA,EAAE,UAAY,GACjD,iBAAkBA,EAAE,QAAU,OAAOA,EAAE,gBAAgB,EAAI9D,EAAK,iBAChE,kBAAmB8D,EAAE,QAAU,OAAOA,EAAE,iBAAiB,EAAI9D,EAAK,kBAClE,UAAW8D,EAAE,SAAWA,EAAE,YAAc,KAAO,OAAOA,EAAE,SAAS,EAAI,GACrE,WAAYA,EAAE,SAAWA,EAAE,aAAe,KAAO,OAAOA,EAAE,UAAU,EAAI,GACxE,OAAQpH,EAAE,WAAW,OAASA,EAAE,WAAW,OAAO,KAAK;CAAI,EAAI,GAC/D,mBAAoBA,EAAE,WAAW,kBACnC,CACF,CAEA,SAAS6H,EAAS,EAAmB,CACnC,OAAO9H,EAAE,KAAK,IAAM,GAAK,IAAa,OAAOA,EAAE,KAAK,CAAC,CACvD,CAEA,SAAS+H,EAAiB,EAA0B,CAClD,OAAO/H,EAAE,KAAK,IAAM,GAAK,KAAO,OAAOA,EAAE,KAAK,CAAC,CACjD,CAEA,SAASgI,GAAa,EAA6B,CACjD,OAAQrF,EAAE,YAAV,CACE,IAAK,SACH,MAAO,CAAE,KAAM,QAAS,EAC1B,IAAK,OACH,MAAO,CAAE,KAAM,OAAQ,GAAIgF,EAAgBhF,EAAE,MAAM,CAAE,EACvD,IAAK,OACH,MAAO,CAAE,KAAM,OAAQ,KAAMA,EAAE,SAAS,KAAK,EAAG,SAAUA,EAAE,aAAa,KAAK,CAAE,EAClF,IAAK,UACH,MAAO,CAAE,KAAM,SAAU,EAC3B,IAAK,aACH,MAAO,CAAE,KAAM,aAAc,OAAQA,EAAE,gBAAiB,CAC5D,CACF,CAOA,SAAgBsF,EAAa,EAAqC,CAChE,IAAMX,EAASjF,EAAMM,EAAE,MAAM,EAC7B,MAAO,CACL,KAAMA,EAAE,KAAK,KAAK,EAClB,QAASA,EAAE,QACX,UAAWA,EAAE,UACb,QAASqF,GAAarF,CAAC,EACvB,QAASA,EAAE,QACR,OAAQ,GAAMuD,EAAE,KAAK,KAAK,GAAKA,EAAE,OAAO,KAAK,CAAC,CAAC,CAC/C,IAAK,IAAO,CAAE,KAAMA,EAAE,KAAK,KAAK,EAAG,OAAQA,EAAE,MAAO,EAAE,EACzD,SAAU,CACR,MAAOvD,EAAE,MAAM,KAAK,EACpB,UAAWA,EAAE,UACb,mBAAoBN,EAAMM,EAAE,QAAQ,EACpC,SAAUA,EAAE,QACd,EACA,OAAQA,EAAE,QAAU,KACpB,UAAWA,EAAE,WAAa,KAC1B,KAAMA,EAAE,KACR,YAAaA,EAAE,YAAY,KAAK,GAAK,KACrC,QAASA,EAAE,QACX,OAAQA,EAAE,OACV,aAAcA,EAAE,oBACZ,CACE,QAAS,GACT,UAAWA,EAAE,sBAAsB,KAAK,EACxC,iBAAkBmF,EAASnF,EAAE,gBAAgB,EAC7C,kBAAmBmF,EAASnF,EAAE,iBAAiB,EAC/C,UAAWoF,EAAiBpF,EAAE,SAAS,EACvC,WAAYoF,EAAiBpF,EAAE,UAAU,CAC3C,EACA,CAAE,QAAS,EAAM,EACrB,WAAY,CACV,OAAQ2E,EAAO,OAAS,EAAIA,EAAS,KACrC,mBAAoB3E,EAAE,kBACxB,CACF,CACF,CAWA,IAAMuF,GAA4C,CAChD,KAAM,OACN,QAAS,UACT,UAAW,YACX,QAAS,cACT,eAAgB,cAChB,aAAc,SACd,eAAgB,WAChB,mBAAoB,eACpB,iBAAkB,mBAClB,iBAAkB,QAClB,qBAAsB,YACtB,8BAA+B,WAC/B,oBAAqB,WACrB,OAAQ,SACR,UAAW,YACX,KAAM,OACN,YAAa,cACb,QAAS,UACT,OAAQ,SACR,yBAA0B,wBAC1B,gCAAiC,mBACjC,iCAAkC,oBAClC,yBAA0B,YAC1B,0BAA2B,aAC3B,oBAAqB,SACrB,gCAAiC,oBACnC,EAGA,SAAgBC,EAAa,EAA0C,CACrE,IAAMhF,EAAQiF,EAAK,IAAI,MAAM,EAC7B,GAAIjF,EAAM,KAAO,WAAaA,EAAM,QAAU,EAC5C,MAAO,WAAW,OAAOA,EAAM,EAAE,EAAE,GAAGA,EAAM,KAAO,SAAW,SAAW,SAE3E,GAAIA,EAAM,KAAO,YAAcA,EAAM,KAAO,qBAAsB,MAAO,WACzE,GAAIA,EAAM,KAAO,cAAgBA,EAAM,KAAO,SAAU,MAAO,SAC/D,IAAK,IAAIlB,EAAIkB,EAAM,OAAQlB,EAAI,EAAG,IAAK,CACrC,IAAMiE,EAAIgC,GAAc/E,EAAM,MAAM,EAAGlB,CAAC,CAAC,CAAC,KAAK,GAAG,GAClD,GAAIiE,EAAG,OAAOA,CAChB,CACA,MAAO,MACT,CAEA,SAASmC,EAAS,EAAW,EAAa,EAAa,EAA8B,CACnF,IAAMpG,EAAI6F,EAAS9H,CAAC,EAIpB,MAHI,CAAC,OAAO,UAAUiC,CAAC,GAAKA,EAAIqG,GAAOrG,EAAIsG,EAClC,GAAGrK,EAAM,+BAA+BoK,EAAI,MAAMC,IAEpD,IACT,CAMA,SAAgBC,GAAc,EAG5B,CACA,IAAMC,EAAsB,CAAC,EACvB1I,GAAO,EAAe,IAAuB,CAC7C2I,GAAO,CAACD,EAAOvC,KAAI,EAAOA,GAAKwC,EACrC,EAIA,OAHK/F,EAAE,KAAK,KAAK,GAAG5C,EAAI,OAAQ,kBAAkB,EAC7C4C,EAAE,WAAW5C,EAAI,YAAa,kBAAkB,EAChD4C,EAAE,MAAM,KAAK,GAAG5C,EAAI,QAAS,wBAAwB,EAClD4C,EAAE,YAAV,CACE,IAAK,OACEgF,EAAgBhF,EAAE,MAAM,GAAG5C,EAAI,SAAU,wBAAwB,EACtE,MACF,IAAK,OACHA,EAAI,WAAYyE,EAAa7B,EAAE,QAAQ,CAAC,EACxC5C,EAAI,eAAgB0E,EAAiB9B,EAAE,YAAY,CAAC,EACpD,MACF,IAAK,aACEA,EAAE,kBAAkB5C,EAAI,mBAAoB,6BAA6B,CAElF,CAOA,GANA4C,EAAE,QAAQ,SAAS,EAAG,IAAM,CACtB,CAACuD,EAAE,KAAK,KAAK,GAAKA,EAAE,OAAO,KAAK,GAAGnG,EAAI,WAAWiE,EAAE,OAAQ,sBAAsB,CACxF,CAAC,EACGrB,EAAE,OAAS,YAAc,CAACA,EAAE,YAAY,KAAK,GAC/C5C,EAAI,cAAe,yDAAyD,EAE1E4C,EAAE,oBAAqB,CAMzB,GALKA,EAAE,sBAAsB,KAAK,GAChC5C,EAAI,wBAAyB,kDAAkD,EAEjFA,EAAI,mBAAoBsI,EAAS1F,EAAE,iBAAkB,EAAG,GAAI,mBAAmB,CAAC,EAChF5C,EAAI,oBAAqBsI,EAAS1F,EAAE,kBAAmB,EAAG,KAAM,qBAAqB,CAAC,EAClFA,EAAE,UAAU,KAAK,EAAG,CACtB,IAAMV,EAAI6F,EAASnF,EAAE,SAAS,GAC1B,CAAC,OAAO,UAAUV,CAAC,GAAKA,GAAK,IAC/BlC,EAAI,YAAa,4CAA4C,CACjE,CACA,GAAI4C,EAAE,WAAW,KAAK,EAAG,CACvB,IAAMV,EAAI6F,EAASnF,EAAE,UAAU,GAC3B,CAAC,OAAO,SAASV,CAAC,GAAKA,GAAK,IAAGlC,EAAI,aAAc,oCAAoC,CAC3F,CACF,CACA,IAAM4I,EAAMV,EAAatF,CAAC,EACpB4B,EAASzH,EAAgB,UAAU6L,CAAG,EAC5C,GAAI,CAACpE,EAAO,QACV,IAAK,IAAMqE,KAASrE,EAAO,MAAM,OAAQxE,EAAIoI,EAAaS,EAAM,IAAI,EAAGA,EAAM,OAAO,EAGtF,MAAO,CAAE,MADErE,EAAO,SAAW,OAAO,KAAKkE,CAAM,CAAC,CAAC,SAAW,EACvClE,EAAO,KAAO,KAAM,QAAO,CAClD,CAMA,SAAgBsE,EAAe,EAAuB,CACpD,OAAOC,EAAE,cAAgBA,EAAE,SAC7B,CAGA,SAAgBC,GAAiB,GAAGC,EAA0D,CAC5F,IAAM9I,EAAO,IAAI,IACjB,IAAK,IAAMC,KAAQ6I,EAAO,IAAK,IAAMF,KAAK3I,GAAQ,CAAC,EAAGD,EAAK,IAAI4I,EAAE,GAAIA,CAAC,EACtE,MAAO,CAAC,GAAG5I,EAAK,OAAO,CAAC,CAAC,CAAC,MACvB,EAAG,IACFG,EAAE,UAAU,cAAcJ,EAAE,SAAS,GAAK4I,EAAexI,CAAC,CAAC,CAAC,cAAcwI,EAAe5I,CAAC,CAAC,CAC/F,CACF,CAGA,SAAgBgJ,GAAiB,EAA4B,CAC3D,GAAI,MAAM,QAAQjI,CAAG,EAAG,OAAOA,EAC/B,GAAIA,GAAO,OAAOA,GAAQ,SAAU,CAClC,IAAMkI,EAAIlI,EACV,GAAI,MAAM,QAAQkI,EAAE,KAAK,EAAG,OAAOA,EAAE,MACrC,GAAI,MAAM,QAAQA,EAAE,WAAW,EAAG,OAAOA,EAAE,WAC7C,CACA,MAAO,CAAC,CACV,CAEA,SAAgBC,GAAY,EAAe,EAAqB,CAC9D,MAAO,0CAA0CrG,EAAM,gDAAgDsG,GACzG,C"}
1
+ {"version":3,"file":"describe-BirsjlUl.js","names":["__iconData","__iconData","__iconData","useId","useMemo","useState","useCallback","__toESM","require_react","require_jsx_runtime","apiPatch","useSyncStore","useConnection","apiPost","errorMessage","TriangleAlert","cn","formatTime","create","Spinner","CircleCheck","CloudOff","toast","AutomationInput","__iconData$3","OctagonAlert","createLucideIcon","__iconData$2","SignalHigh","__iconData$1","SignalLow","__iconData","SignalMedium","import_react","import_jsx_runtime","Field","id","hintId","errId","describedBy","hint","error","className","label","optional","children","FieldError","Select","rest","Switch","checked","busy","disabled","onChange","onText","offText","Section","testId","title","description","actions","PRIORITY_ICONS","PriorityIcon","Icon","priority","FailureCount","count","ConnectionNote","connection","automationPath","suffix","useLocalAutomations","set","s","a","byId","list","newer","b","useMergedAutomations","store","local","deleted","out","useMergedAutomation","fromStore","fromLocal","useToggleEnabled","setBusy","res","enabled","e","useRunNow","state","onDone","TRIGGER_KIND_LABELS","MODE_OPTIONS","OVERLAP_OPTIONS","MISSED_OPTIONS","modeLabel","m","mode","TEMPLATE_VARIABLES","listText","items","pad","n","ordinal","mod100","capitalize","lines","text","l","DAY_NAMES","MONTH_NAMES","CRON_FIELDS","d","parseValue","lower","token","def","idx","parseCronField","src","parts","values","step","part","base","stepStr","extra","every","start","end","av","bv","v","i","sorted","full","parseCron","trimmed","expr","fields","parsed","validateCron","validateTimezone","tz","isContiguous","describeTime","h","at","times","hv","mv","first","last","mm","mondayFirst","describeDays","dom","dow","months","mon","inMonths","days","key","names","ords","of","describeCron","f","time","timezone","describeCronOrRaw","formatAbsolute","iso","describeTrigger","fmt","ctx","trigger","triggerClause","t","input","filters","summarizeAutomation","project","host","profile","action","c","checks","localTimezone","emptyDraft","opts","isoToLocalInput","localInputToIso","value","draftFromAutomation","toNumber","toOptionalNumber","draftTrigger","draftToInput","PATH_TO_FIELD","fieldForPath","path","intError","min","max","validateDraft","errors","msg","raw","issue","occurrenceTime","o","mergeOccurrences","lists","normalizeHistory","r","curlExample","url"],"sources":["../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/octagon-alert.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/signal-high.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/signal-low.mjs","../../../../node_modules/.pnpm/lucide-react@1.61.0_@types+react@19.3.0_react@19.3.1/node_modules/lucide-react/dist/esm/icons/signal-medium.mjs","../../src/features/automations/controls.tsx","../../src/features/automations/describe.ts"],"sourcesContent":["/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"octagon-alert\",\n size: 24,\n node: [\n [\"path\", { d: \"M12 16h.01\", key: \"1drbdi\" }],\n [\"path\", { d: \"M12 8v4\", key: \"1got3b\" }],\n [\n \"path\",\n {\n d: \"M15.312 2a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586l-4.688-4.688A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2z\",\n key: \"1fd625\"\n }\n ]\n ],\n aliases: [\"alert-octagon\"]\n};\n__iconData.node;\nconst OctagonAlert = createLucideIcon(__iconData);\n\nexport { __iconData, OctagonAlert as default };\n//# sourceMappingURL=octagon-alert.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"signal-high\",\n size: 24,\n node: [\n [\"path\", { d: \"M2 20h.01\", key: \"4haj6o\" }],\n [\"path\", { d: \"M7 20v-4\", key: \"j294jx\" }],\n [\"path\", { d: \"M12 20v-8\", key: \"i3yub9\" }],\n [\"path\", { d: \"M17 20V8\", key: \"1tkaf5\" }]\n ]\n};\n__iconData.node;\nconst SignalHigh = createLucideIcon(__iconData);\n\nexport { __iconData, SignalHigh as default };\n//# sourceMappingURL=signal-high.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"signal-low\",\n size: 24,\n node: [\n [\"path\", { d: \"M2 20h.01\", key: \"4haj6o\" }],\n [\"path\", { d: \"M7 20v-4\", key: \"j294jx\" }]\n ]\n};\n__iconData.node;\nconst SignalLow = createLucideIcon(__iconData);\n\nexport { __iconData, SignalLow as default };\n//# sourceMappingURL=signal-low.mjs.map\n","/**\n * @license lucide-react v1.61.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconData = {\n name: \"signal-medium\",\n size: 24,\n node: [\n [\"path\", { d: \"M2 20h.01\", key: \"4haj6o\" }],\n [\"path\", { d: \"M7 20v-4\", key: \"j294jx\" }],\n [\"path\", { d: \"M12 20v-8\", key: \"i3yub9\" }]\n ]\n};\n__iconData.node;\nconst SignalMedium = createLucideIcon(__iconData);\n\nexport { __iconData, SignalMedium as default };\n//# sourceMappingURL=signal-medium.mjs.map\n","import type { Automation, Priority } from \"@switchyard/protocol\";\nimport {\n CircleCheck,\n CloudOff,\n OctagonAlert,\n SignalHigh,\n SignalLow,\n SignalMedium,\n TriangleAlert,\n} from \"lucide-react\";\nimport {\n type ReactElement,\n type ReactNode,\n type SelectHTMLAttributes,\n useCallback,\n useId,\n useMemo,\n useState,\n} from \"react\";\nimport { create } from \"zustand\";\nimport { Spinner } from \"../../components/ui/Button\";\nimport { toast } from \"../../components/ui/Toast\";\nimport { cn } from \"../../lib/cn\";\nimport { formatTime } from \"../../lib/time\";\nimport { apiPatch, apiPost, errorMessage } from \"../../sync/api\";\nimport { useConnection, useSyncStore } from \"../../sync/store\";\n\n/* Small building blocks shared by the Automations list and editor. */\n\nexport interface FieldControlProps {\n id: string;\n \"aria-invalid\"?: boolean;\n \"aria-describedby\"?: string;\n}\n\n/** Labelled form field with an optional hint and inline error. */\nexport function Field({\n label,\n hint,\n error,\n children,\n className,\n optional,\n}: {\n label: ReactNode;\n hint?: ReactNode;\n error?: string;\n children: (props: FieldControlProps) => ReactElement;\n className?: string;\n optional?: boolean;\n}) {\n const id = useId();\n const hintId = `${id}-hint`;\n const errId = `${id}-err`;\n const describedBy = [hint ? hintId : null, error ? errId : null].filter(Boolean).join(\" \");\n return (\n <div className={cn(\"flex min-w-0 flex-col gap-1\", className)}>\n <label htmlFor={id} className=\"text-sm font-medium\">\n {label}\n {optional && <span className=\"font-normal text-muted\"> (optional)</span>}\n </label>\n {children({\n id,\n \"aria-invalid\": error ? true : undefined,\n \"aria-describedby\": describedBy || undefined,\n })}\n {hint && (\n <p id={hintId} className=\"text-xs text-muted\">\n {hint}\n </p>\n )}\n {error && <FieldError id={errId}>{error}</FieldError>}\n </div>\n );\n}\n\nexport function FieldError({ id, children }: { id?: string; children: ReactNode }) {\n return (\n <p id={id} className=\"flex items-start gap-1 text-xs text-danger\" data-field-error>\n <TriangleAlert aria-hidden className=\"mt-0.5 size-3.5 shrink-0\" />\n <span>{children}</span>\n </p>\n );\n}\n\n/** Native select styled like TextInput. */\nexport function Select({ className, children, ...rest }: SelectHTMLAttributes<HTMLSelectElement>) {\n return (\n <select\n className={cn(\n \"tap block h-9 w-full min-w-0 rounded-md border border-border bg-surface px-2.5 text-base text-text md:text-sm\",\n \"focus:border-accent focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-0\",\n \"aria-[invalid=true]:border-danger\",\n className,\n )}\n {...rest}\n >\n {children}\n </select>\n );\n}\n\n/** Accessible on/off switch with a text label that states the current value. */\nexport function Switch({\n checked,\n onChange,\n label,\n onText = \"On\",\n offText = \"Off\",\n busy,\n disabled,\n id,\n className,\n}: {\n checked: boolean;\n onChange: (next: boolean) => void;\n /** Accessible name. */\n label: string;\n onText?: string;\n offText?: string;\n busy?: boolean;\n disabled?: boolean;\n id?: string;\n className?: string;\n}) {\n return (\n <button\n id={id}\n type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={label}\n aria-busy={busy || undefined}\n disabled={disabled || busy}\n onClick={() => onChange(!checked)}\n className={cn(\n \"tap inline-flex min-h-9 shrink-0 items-center gap-2 rounded-md px-1.5 text-sm\",\n \"hover:bg-surface-2 disabled:opacity-60\",\n className,\n )}\n >\n <span\n aria-hidden\n className={cn(\n \"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full border transition-colors\",\n checked ? \"border-accent bg-accent\" : \"border-border-strong bg-surface-2\",\n )}\n >\n <span\n className={cn(\n \"absolute size-3.5 rounded-full shadow-sm transition-transform\",\n checked ? \"translate-x-[18px] bg-accent-fg\" : \"translate-x-[2px] bg-muted\",\n )}\n />\n </span>\n {busy ? <Spinner className=\"size-3.5\" /> : null}\n <span className={checked ? \"text-text\" : \"text-muted\"}>{checked ? onText : offText}</span>\n </button>\n );\n}\n\n/** Titled card section. */\nexport function Section({\n title,\n description,\n children,\n actions,\n className,\n testId,\n}: {\n title: ReactNode;\n description?: ReactNode;\n children: ReactNode;\n actions?: ReactNode;\n className?: string;\n testId?: string;\n}) {\n const id = useId();\n return (\n <section\n aria-labelledby={id}\n data-testid={testId}\n className={cn(\"min-w-0 rounded-lg border border-border bg-surface p-4\", className)}\n >\n <div className=\"mb-3 flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <h2 id={id} className=\"text-base font-semibold\">\n {title}\n </h2>\n {description && <p className=\"text-sm text-muted\">{description}</p>}\n </div>\n {actions && <div className=\"flex flex-wrap gap-2\">{actions}</div>}\n </div>\n <div className=\"flex flex-col gap-4\">{children}</div>\n </section>\n );\n}\n\nconst PRIORITY_ICONS = [OctagonAlert, SignalHigh, SignalMedium, SignalLow];\n\nexport function PriorityIcon({ priority, className }: { priority: Priority; className?: string }) {\n const Icon = PRIORITY_ICONS[priority] ?? SignalMedium;\n return (\n <Icon\n aria-hidden\n className={cn(\"size-4 shrink-0\", priority === 0 ? \"text-danger\" : \"text-muted\", className)}\n />\n );\n}\n\n/** Failure count as icon + text; warning tone when > 0. */\nexport function FailureCount({ count }: { count: number }) {\n if (count > 0) {\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-warning\">\n <TriangleAlert aria-hidden className=\"size-4 shrink-0\" />\n {count === 1 ? \"1 failure\" : `${count} failures`}\n </span>\n );\n }\n return (\n <span className=\"inline-flex items-center gap-1 text-sm text-muted\">\n <CircleCheck aria-hidden className=\"size-4 shrink-0\" />\n No failures\n </span>\n );\n}\n\n/** Inline last-known-data note when the coordinator link is not live. */\nexport function ConnectionNote({ className }: { className?: string }) {\n const connection = useConnection();\n if (connection.state === \"live\") return null;\n if (connection.state === \"connecting\" && !connection.lastSyncedAt) return null;\n return (\n <p\n role=\"status\"\n className={cn(\n \"flex items-start gap-1.5 rounded-md border border-border bg-warning-soft px-3 py-1.5 text-sm\",\n className,\n )}\n >\n <CloudOff aria-hidden className=\"mt-0.5 size-4 shrink-0 text-warning\" />\n <span>\n Showing last known automations\n {connection.lastSyncedAt ? ` from ${formatTime(connection.lastSyncedAt)}` : \"\"}. Changes are\n sent once the coordinator is reachable again.\n </span>\n </p>\n );\n}\n\nexport const automationPath = (id: string, suffix = \"\") =>\n `/api/automations/${encodeURIComponent(id)}${suffix}`;\n\n/* ------------------------------------------------------------------ */\n/* Automations acknowledged over REST (create/patch responses, list */\n/* fallback) so views do not wait for the automation.updated event. */\n/* ------------------------------------------------------------------ */\n\ninterface LocalAutomations {\n byId: Record<string, Automation>;\n deleted: Record<string, true>;\n put(a: Automation): void;\n putMany(list: Automation[]): void;\n remove(id: string): void;\n}\n\nexport const useLocalAutomations = create<LocalAutomations>()((set) => ({\n byId: {},\n deleted: {},\n put: (a) => set((s) => ({ byId: { ...s.byId, [a.id]: a } })),\n putMany: (list) =>\n set((s) => {\n const byId = { ...s.byId };\n for (const a of list) byId[a.id] = a;\n return { byId };\n }),\n remove: (id) =>\n set((s) => {\n const byId = { ...s.byId };\n delete byId[id];\n return { byId, deleted: { ...s.deleted, [id]: true } };\n }),\n}));\n\nfunction newer(a: Automation | undefined, b: Automation | undefined): Automation | undefined {\n if (!a) return b;\n if (!b) return a;\n return b.updatedAt > a.updatedAt ? b : a;\n}\n\n/** Store automations merged with REST acknowledgements (newest updatedAt wins). */\nexport function useMergedAutomations(): Record<string, Automation> {\n const store = useSyncStore((s) => s.automations);\n const local = useLocalAutomations((s) => s.byId);\n const deleted = useLocalAutomations((s) => s.deleted);\n return useMemo(() => {\n const out: Record<string, Automation> = {};\n for (const id of new Set([...Object.keys(store), ...Object.keys(local)])) {\n if (deleted[id]) continue;\n const a = newer(store[id], local[id]);\n if (a) out[id] = a;\n }\n return out;\n }, [store, local, deleted]);\n}\n\nexport function useMergedAutomation(id: string | undefined): Automation | undefined {\n const fromStore = useSyncStore((s) => (id ? s.automations[id] : undefined));\n const fromLocal = useLocalAutomations((s) => (id ? s.byId[id] : undefined));\n const deleted = useLocalAutomations((s) => (id ? s.deleted[id] : undefined));\n return deleted ? undefined : newer(fromStore, fromLocal);\n}\n\n/** Enable/disable with no optimistic success: busy until the coordinator acknowledges. */\nexport function useToggleEnabled() {\n const [busy, setBusy] = useState<Record<string, boolean>>({});\n const toggle = useCallback(async (a: Pick<Automation, \"id\" | \"name\">, enabled: boolean) => {\n setBusy((b) => ({ ...b, [a.id]: true }));\n try {\n const res = await apiPatch<Automation | undefined>(automationPath(a.id), { enabled });\n if (res && typeof res === \"object\" && \"id\" in res) useLocalAutomations.getState().put(res);\n toast.success(`${a.name} ${enabled ? \"enabled\" : \"disabled\"}`);\n } catch (e) {\n toast.error(`Could not ${enabled ? \"enable\" : \"disable\"} ${a.name}: ${errorMessage(e)}`);\n } finally {\n setBusy((b) => ({ ...b, [a.id]: false }));\n }\n }, []);\n return { busy, toggle };\n}\n\n/** Manual \"Run now\": busy until acknowledged; never reports success early. */\nexport function useRunNow(onDone?: () => void) {\n const [busy, setBusy] = useState<Record<string, boolean>>({});\n const run = useCallback(\n async (a: Pick<Automation, \"id\" | \"name\">) => {\n setBusy((b) => ({ ...b, [a.id]: true }));\n try {\n const res = await apiPost<{ state?: string } | undefined>(automationPath(a.id, \"/run\"));\n const state = res && typeof res === \"object\" ? res.state : undefined;\n toast.success(\n state && state !== \"fired\"\n ? `${a.name}: occurrence recorded (${state.replace(/_/g, \" \")})`\n : `${a.name} started`,\n );\n onDone?.();\n } catch (e) {\n toast.error(`Could not run ${a.name}: ${errorMessage(e)}`);\n } finally {\n setBusy((b) => ({ ...b, [a.id]: false }));\n }\n },\n [onDone],\n );\n return { busy, run };\n}\n","import {\n type Automation,\n AutomationInput,\n type Occurrence,\n PRIORITY_LABELS,\n type Priority,\n type Trigger,\n} from \"@switchyard/protocol\";\n\n/*\n * Pure helpers for the Automations feature: a small cron describer, trigger\n * and whole-automation summaries, the editor draft <-> AutomationInput\n * conversion with field-level validation, and history merging.\n */\n\n/* ------------------------------------------------------------------ */\n/* Labels and explanations */\n/* ------------------------------------------------------------------ */\n\nexport type AutomationMode = AutomationInput[\"mode\"];\nexport type OverlapPolicy = AutomationInput[\"overlap\"];\nexport type MissedPolicy = AutomationInput[\"missed\"];\nexport type TriggerKind = Trigger[\"kind\"];\n\nexport const TRIGGER_KIND_LABELS: Record<TriggerKind, string> = {\n manual: \"Manual\",\n once: \"Once\",\n cron: \"Schedule\",\n webhook: \"Webhook\",\n dependency: \"Dependency\",\n};\n\nexport const MODE_OPTIONS: { value: AutomationMode; label: string; explanation: string }[] = [\n { value: \"fresh\", label: \"Fresh\", explanation: \"Fresh: a new task per occurrence\" },\n {\n value: \"continue\",\n label: \"Continue\",\n explanation: \"Continue: reuse the task with the same grouping key\",\n },\n {\n value: \"watch\",\n label: \"Watch\",\n explanation: \"Watch: only raises attention when something relevant changed\",\n },\n];\n\nexport const OVERLAP_OPTIONS: { value: OverlapPolicy; label: string; explanation: string }[] = [\n {\n value: \"skip\",\n label: \"Skip\",\n explanation: \"Skip: drop the occurrence while earlier work is still open\",\n },\n {\n value: \"queue_one\",\n label: \"Queue one\",\n explanation: \"Queue one: keep a single pending occurrence and fire it when the open work ends\",\n },\n {\n value: \"append\",\n label: \"Append\",\n explanation: \"Append: add the new objective to the open task (as a follow-up if it is running)\",\n },\n];\n\nexport const MISSED_OPTIONS: { value: MissedPolicy; label: string; explanation: string }[] = [\n {\n value: \"skip\",\n label: \"Skip\",\n explanation: \"Skip: occurrences missed while the coordinator was down are recorded and skipped\",\n },\n {\n value: \"run_once\",\n label: \"Run once\",\n explanation: \"Run once: on return, fire the newest missed occurrence once\",\n },\n];\n\nexport function modeLabel(mode: AutomationMode): string {\n return MODE_OPTIONS.find((m) => m.value === mode)?.label ?? mode;\n}\n\nexport function priorityLabel(p: Priority): string {\n return PRIORITY_LABELS[p] ?? String(p);\n}\n\nexport const TEMPLATE_VARIABLES = [\"{{date}}\", \"{{time}}\", \"{{occurrence}}\", \"{{payload.<path>}}\"];\n\n/* ------------------------------------------------------------------ */\n/* Text utilities */\n/* ------------------------------------------------------------------ */\n\n/** \"a\", \"a and b\", \"a, b and c\". */\nexport function listText(items: string[]): string {\n if (items.length <= 1) return items[0] ?? \"\";\n return `${items.slice(0, -1).join(\", \")} and ${items[items.length - 1]}`;\n}\n\nfunction pad(n: number): string {\n return String(n).padStart(2, \"0\");\n}\n\nexport function ordinal(n: number): string {\n const mod100 = n % 100;\n if (mod100 >= 11 && mod100 <= 13) return `${n}th`;\n switch (n % 10) {\n case 1:\n return `${n}st`;\n case 2:\n return `${n}nd`;\n case 3:\n return `${n}rd`;\n default:\n return `${n}th`;\n }\n}\n\nfunction capitalize(s: string): string {\n return s ? s[0]!.toUpperCase() + s.slice(1) : s;\n}\n\n/** Non-empty trimmed lines. */\nexport function lines(text: string): string[] {\n return text\n .split(\"\\n\")\n .map((l) => l.trim())\n .filter((l) => l.length > 0);\n}\n\n/* ------------------------------------------------------------------ */\n/* Cron */\n/* ------------------------------------------------------------------ */\n\nconst DAY_NAMES = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\nconst MONTH_NAMES = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n];\n\ninterface FieldDef {\n name: string;\n min: number;\n max: number;\n /** Three-letter aliases mapped to `min + index`. */\n names?: string[];\n}\n\nconst CRON_FIELDS: FieldDef[] = [\n { name: \"Minute\", min: 0, max: 59 },\n { name: \"Hour\", min: 0, max: 23 },\n { name: \"Day of month\", min: 1, max: 31 },\n {\n name: \"Month\",\n min: 1,\n max: 12,\n names: MONTH_NAMES.map((m) => m.slice(0, 3).toLowerCase()),\n },\n {\n name: \"Day of week\",\n min: 0,\n max: 7,\n names: DAY_NAMES.map((d) => d.slice(0, 3).toLowerCase()),\n },\n];\n\nexport interface CronField {\n /** `*` (or `?`): every value. */\n any: boolean;\n /** Expanded, sorted, unique values (empty when `any`). */\n values: number[];\n /** Set when the field is a single `*\\/n` or `a/n` step. */\n step: { every: number; start: number } | null;\n /** Uses croner extensions (L, W, #) the describer does not explain. */\n extended: boolean;\n}\n\nfunction parseValue(token: string, def: FieldDef): number | string {\n const lower = token.toLowerCase();\n if (def.names) {\n const idx = def.names.indexOf(lower);\n if (idx >= 0) return def.min + idx;\n }\n if (!/^\\d+$/.test(token)) return `\"${token}\" is not a number`;\n const n = Number(token);\n if (n < def.min || n > def.max) return `${n} is out of range ${def.min}–${def.max}`;\n return n;\n}\n\n/** Parse one cron field; returns an error message for invalid input. */\nexport function parseCronField(src: string, def: FieldDef): CronField | string {\n if (src === \"*\" || src === \"?\") return { any: true, values: [], step: null, extended: false };\n if (/[LW#]/i.test(src) && !def.names?.some((n) => src.toLowerCase().includes(n))) {\n if (!/^[0-9A-Za-z*?,\\-/#]+$/.test(src)) return `\"${src}\" is not valid`;\n return { any: false, values: [], step: null, extended: true };\n }\n const parts = src.split(\",\");\n const values = new Set<number>();\n let step: CronField[\"step\"] = null;\n for (const part of parts) {\n if (!part) return \"empty list item\";\n const [base, stepStr, extra] = part.split(\"/\");\n if (extra !== undefined) return `\"${part}\" has more than one step`;\n let every = 1;\n if (stepStr !== undefined) {\n if (!/^\\d+$/.test(stepStr) || Number(stepStr) < 1) return `\"${stepStr}\" is not a valid step`;\n every = Number(stepStr);\n }\n let start: number;\n let end: number;\n if (base === \"*\" || base === \"?\") {\n start = def.min;\n end = def.max;\n } else if (base?.includes(\"-\")) {\n const [a, b] = base.split(\"-\");\n const av = parseValue(a ?? \"\", def);\n const bv = parseValue(b ?? \"\", def);\n if (typeof av === \"string\") return av;\n if (typeof bv === \"string\") return bv;\n if (av > bv) return `range ${base} runs backwards`;\n start = av;\n end = bv;\n } else {\n const v = parseValue(base ?? \"\", def);\n if (typeof v === \"string\") return v;\n start = v;\n end = stepStr !== undefined ? def.max : v;\n }\n for (let i = start; i <= end; i += every) values.add(i);\n if (parts.length === 1 && stepStr !== undefined && !base?.includes(\"-\")) {\n step = { every, start };\n }\n }\n let sorted = [...values].sort((a, b) => a - b);\n // Day of week: 7 is Sunday.\n if (def.max === 7) sorted = [...new Set(sorted.map((v) => v % 7))].sort((a, b) => a - b);\n const full = def.max === 7 ? 7 : def.max - def.min + 1;\n if (sorted.length === full && !step)\n return { any: true, values: [], step: null, extended: false };\n return { any: false, values: sorted, step, extended: false };\n}\n\nexport function parseCron(expr: string): CronField[] | string {\n const trimmed = expr.trim();\n if (!trimmed) return \"Enter a cron expression\";\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 5) {\n return `Expected 5 fields (minute hour day-of-month month day-of-week), got ${fields.length}`;\n }\n const out: CronField[] = [];\n for (let i = 0; i < 5; i++) {\n const def = CRON_FIELDS[i]!;\n const parsed = parseCronField(fields[i]!, def);\n if (typeof parsed === \"string\") return `${def.name}: ${parsed}`;\n out.push(parsed);\n }\n return out;\n}\n\n/** Null when valid, otherwise a message. */\nexport function validateCron(expr: string): string | null {\n const parsed = parseCron(expr);\n return typeof parsed === \"string\" ? parsed : null;\n}\n\n/** Null when the IANA timezone is known to this browser. */\nexport function validateTimezone(tz: string): string | null {\n if (!tz.trim()) return \"Enter a timezone\";\n try {\n new Intl.DateTimeFormat(undefined, { timeZone: tz.trim() });\n return null;\n } catch {\n return `Unknown timezone \"${tz}\"`;\n }\n}\n\nfunction isContiguous(values: number[]): boolean {\n for (let i = 1; i < values.length; i++) if (values[i] !== values[i - 1]! + 1) return false;\n return values.length > 0;\n}\n\ntype TimePhrase = { kind: \"at\"; text: string } | { kind: \"freq\"; text: string };\n\nfunction describeTime(m: CronField, h: CronField): TimePhrase | null {\n if (m.any && h.any) return { kind: \"freq\", text: \"Every minute\" };\n if (m.step && m.step.start === 0 && h.any) {\n return {\n kind: \"freq\",\n text: m.step.every === 1 ? \"Every minute\" : `Every ${m.step.every} minutes`,\n };\n }\n if (m.any) {\n if (h.step || h.values.length === 0) return null;\n if (isContiguous(h.values)) {\n return {\n kind: \"freq\",\n text: `Every minute from ${pad(h.values[0]!)}:00 to ${pad(h.values[h.values.length - 1]!)}:59`,\n };\n }\n return null;\n }\n if (h.any) {\n if (m.step) return null;\n if (m.values.length === 1 && m.values[0] === 0) return { kind: \"freq\", text: \"Every hour\" };\n return {\n kind: \"freq\",\n text: `Every hour at ${listText(m.values.map((v) => `:${pad(v)}`))}`,\n };\n }\n if (h.step && h.step.start === 0 && m.values.length === 1 && !m.step) {\n const at = m.values[0] === 0 ? \"\" : ` at :${pad(m.values[0]!)}`;\n return {\n kind: \"freq\",\n text: h.step.every === 1 ? `Every hour${at}` : `Every ${h.step.every} hours${at}`,\n };\n }\n if (m.values.length * h.values.length <= 6) {\n const times: string[] = [];\n for (const hv of h.values) for (const mv of m.values) times.push(`${pad(hv)}:${pad(mv)}`);\n return { kind: \"at\", text: listText(times) };\n }\n if (!isContiguous(h.values)) return null;\n const first = h.values[0]!;\n const last = h.values[h.values.length - 1]!;\n if (m.step && m.step.start === 0) {\n return {\n kind: \"freq\",\n text: `Every ${m.step.every} minutes from ${pad(first)}:00 to ${pad(last)}:59`,\n };\n }\n if (m.values.length === 1) {\n const mm = pad(m.values[0]!);\n return { kind: \"freq\", text: `Every hour from ${pad(first)}:${mm} to ${pad(last)}:${mm}` };\n }\n return null;\n}\n\n/** Monday-first ordering for day-of-week lists. */\nfunction mondayFirst(a: number, b: number): number {\n return ((a + 6) % 7) - ((b + 6) % 7);\n}\n\nfunction describeDays(\n dom: CronField,\n mon: CronField,\n dow: CronField,\n): { lead: string; qual: string } | null {\n if (!dom.any && !dow.any) return null;\n const months = mon.any ? null : listText(mon.values.map((v) => MONTH_NAMES[v - 1]!));\n const inMonths = months ? ` in ${months}` : \"\";\n if (!dow.any) {\n const days = [...dow.values].sort(mondayFirst);\n const key = days.join(\",\");\n if (key === \"1,2,3,4,5\") {\n return { lead: `Every weekday${inMonths}`, qual: ` on weekdays${inMonths}` };\n }\n if (key === \"6,0\") {\n return { lead: `Every Saturday and Sunday${inMonths}`, qual: ` on weekends${inMonths}` };\n }\n const names = days.map((d) => DAY_NAMES[d]!);\n return {\n lead: `Every ${listText(names)}${inMonths}`,\n qual: ` on ${listText(names.map((n) => `${n}s`))}${inMonths}`,\n };\n }\n if (!dom.any) {\n if (dom.values.length > 5) return null;\n const ords = listText(dom.values.map(ordinal));\n const of = months ? months : \"every month\";\n return { lead: `On the ${ords} of ${of}`, qual: ` on the ${ords} of ${of}` };\n }\n return { lead: `Every day${inMonths}`, qual: inMonths };\n}\n\n/**\n * Human description of a 5-field cron expression (\"Every weekday at 09:00\n * (America/Denver)\"), or null when the expression is outside what this small\n * describer covers.\n */\nexport function describeCron(expr: string, timezone?: string): string | null {\n const parsed = parseCron(expr);\n if (typeof parsed === \"string\") return null;\n if (parsed.some((f) => f.extended)) return null;\n const [m, h, dom, mon, dow] = parsed as [CronField, CronField, CronField, CronField, CronField];\n const time = describeTime(m, h);\n const days = describeDays(dom, mon, dow);\n if (!time || !days) return null;\n const text = time.kind === \"at\" ? `${days.lead} at ${time.text}` : `${time.text}${days.qual}`;\n return timezone ? `${text} (${timezone})` : text;\n}\n\n/** describeCron with the raw-expression fallback. */\nexport function describeCronOrRaw(expr: string, timezone: string): string {\n return describeCron(expr, timezone) ?? `Cron ${expr.trim()} (${timezone})`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Summaries */\n/* ------------------------------------------------------------------ */\n\nexport function formatAbsolute(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n return d.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" });\n}\n\nexport interface SummaryContext {\n projectName?: string | null;\n /** Name of the explicitly selected host; null/undefined means the project default. */\n hostName?: string | null;\n profileName?: string | null;\n taskTitle?: (taskId: string) => string | undefined;\n formatDate?: (iso: string) => string;\n}\n\n/** Short trigger summary for list rows. */\nexport function describeTrigger(trigger: Trigger, ctx: SummaryContext = {}): string {\n const fmt = ctx.formatDate ?? formatAbsolute;\n switch (trigger.kind) {\n case \"manual\":\n return \"Manual\";\n case \"once\":\n return trigger.at && !Number.isNaN(Date.parse(trigger.at))\n ? `Once at ${fmt(trigger.at)}`\n : \"Once (no time chosen)\";\n case \"cron\":\n return describeCronOrRaw(trigger.expr, trigger.timezone);\n case \"webhook\":\n return \"Webhook\";\n case \"dependency\": {\n const title = trigger.taskId ? ctx.taskTitle?.(trigger.taskId) : undefined;\n if (title) return `When \"${title}\" is done`;\n return trigger.taskId ? `When task ${trigger.taskId} is done` : \"When a task is done\";\n }\n }\n}\n\ntype SummaryInput = Pick<\n AutomationInput,\n | \"trigger\"\n | \"filters\"\n | \"template\"\n | \"mode\"\n | \"groupingKey\"\n | \"overlap\"\n | \"missed\"\n | \"continuation\"\n | \"completion\"\n>;\n\nfunction triggerClause(input: SummaryInput, ctx: SummaryContext): string {\n const t = input.trigger;\n switch (t.kind) {\n case \"manual\":\n return \"When run manually\";\n case \"webhook\": {\n const filters = input.filters.filter((f) => f.path.trim());\n if (filters.length === 0) return \"When a webhook is received\";\n return `When a webhook is received where ${listText(\n filters.map((f) => `${f.path.trim()} = \"${f.equals}\"`),\n )}`;\n }\n default:\n return describeTrigger(t, ctx);\n }\n}\n\n/**\n * One-paragraph description of what the automation does, e.g. 'Every weekday\n * at 09:00 (America/Denver), create a fresh task \"Triage\" in Web on my-server; skip\n * if previous work is still open; skip missed runs; requires human review'.\n */\nexport function summarizeAutomation(input: SummaryInput, ctx: SummaryContext = {}): string {\n const title = input.template.title.trim() || \"Untitled task\";\n const project = ctx.projectName ? ` in ${ctx.projectName}` : \"\";\n const host = ctx.hostName ? ` on ${ctx.hostName}` : \" on the project's default host\";\n const profile = ctx.profileName ? ` with profile ${ctx.profileName}` : \"\";\n let action: string;\n switch (input.mode) {\n case \"continue\": {\n const key = input.groupingKey?.trim();\n action = key\n ? `continue the task grouped by \"${key}\" (or create \"${title}\")`\n : `continue the matching task (or create \"${title}\")`;\n break;\n }\n case \"watch\":\n action = `create a watch task \"${title}\" that only raises attention when something relevant changed`;\n break;\n default:\n action = `create a fresh task \"${title}\"`;\n }\n const parts = [`${triggerClause(input, ctx)}, ${action}${project}${host}${profile}`];\n parts.push(\n input.overlap === \"skip\"\n ? \"skip if previous work is still open\"\n : input.overlap === \"queue_one\"\n ? \"queue one occurrence if previous work is still open\"\n : \"append to the open task if previous work is still open\",\n );\n if (input.trigger.kind === \"cron\" || input.trigger.kind === \"once\") {\n parts.push(input.missed === \"skip\" ? \"skip missed runs\" : \"run missed runs once on return\");\n }\n if (input.continuation.enabled) {\n const c = input.continuation;\n parts.push(\n `continue automatically up to ${c.maxContinuations} times within ${c.maxElapsedMinutes} minutes`,\n );\n }\n const checks = input.completion.checks;\n if (checks && checks.length > 0) {\n parts.push(`run ${checks.length === 1 ? \"1 check\" : `${checks.length} checks`}`);\n }\n parts.push(\n input.completion.requireHumanReview ? \"requires human review\" : \"no human review required\",\n );\n return capitalize(parts.join(\"; \"));\n}\n\n/* ------------------------------------------------------------------ */\n/* Editor draft */\n/* ------------------------------------------------------------------ */\n\n/** Form state: strings for inputs so partial edits survive validation. */\nexport interface AutomationDraft {\n name: string;\n enabled: boolean;\n projectId: string;\n triggerKind: TriggerKind;\n /** datetime-local value (local time, no zone). */\n onceAt: string;\n cronExpr: string;\n cronTimezone: string;\n dependencyTaskId: string;\n filters: { path: string; equals: string }[];\n title: string;\n objective: string;\n /** One criterion per line. */\n criteria: string;\n priority: Priority;\n /** \"\" = project default. */\n hostId: string;\n /** \"\" = project default. */\n profileId: string;\n mode: AutomationMode;\n groupingKey: string;\n overlap: OverlapPolicy;\n missed: MissedPolicy;\n continuationEnabled: boolean;\n continuationObjective: string;\n maxContinuations: string;\n maxElapsedMinutes: string;\n maxTokens: string;\n maxCostUsd: string;\n /** One check per line; empty = project default (null). */\n checks: string;\n requireHumanReview: boolean;\n}\n\nexport function localTimezone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || \"UTC\";\n } catch {\n return \"UTC\";\n }\n}\n\nexport function emptyDraft(opts: { projectId?: string; timezone?: string } = {}): AutomationDraft {\n return {\n name: \"\",\n enabled: true,\n projectId: opts.projectId ?? \"\",\n triggerKind: \"manual\",\n onceAt: \"\",\n cronExpr: \"0 9 * * 1-5\",\n cronTimezone: opts.timezone ?? localTimezone(),\n dependencyTaskId: \"\",\n filters: [],\n title: \"\",\n objective: \"\",\n criteria: \"\",\n priority: 2,\n hostId: \"\",\n profileId: \"\",\n mode: \"fresh\",\n groupingKey: \"\",\n overlap: \"skip\",\n missed: \"skip\",\n continuationEnabled: false,\n continuationObjective: \"\",\n maxContinuations: \"5\",\n maxElapsedMinutes: \"60\",\n maxTokens: \"\",\n maxCostUsd: \"\",\n checks: \"\",\n requireHumanReview: true,\n };\n}\n\n/** ISO -> datetime-local value in this browser's timezone. */\nexport function isoToLocalInput(iso: string | null | undefined): string {\n if (!iso) return \"\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n\n/** datetime-local value -> ISO (interpreted as local time), or \"\" when empty/invalid. */\nexport function localInputToIso(value: string): string {\n if (!value) return \"\";\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? \"\" : d.toISOString();\n}\n\nexport function draftFromAutomation(\n a: Automation | AutomationInput,\n opts: { timezone?: string } = {},\n): AutomationDraft {\n const base = emptyDraft({ projectId: a.projectId, timezone: opts.timezone });\n const t = a.trigger;\n const c = a.continuation;\n return {\n ...base,\n name: a.name,\n enabled: a.enabled,\n triggerKind: t.kind,\n onceAt: t.kind === \"once\" ? isoToLocalInput(t.at) : \"\",\n cronExpr: t.kind === \"cron\" ? t.expr : base.cronExpr,\n cronTimezone: t.kind === \"cron\" ? t.timezone : base.cronTimezone,\n dependencyTaskId: t.kind === \"dependency\" ? t.taskId : \"\",\n filters: a.filters.map((f) => ({ ...f })),\n title: a.template.title,\n objective: a.template.objective,\n criteria: a.template.acceptanceCriteria.join(\"\\n\"),\n priority: a.template.priority,\n hostId: a.hostId ?? \"\",\n profileId: a.profileId ?? \"\",\n mode: a.mode,\n groupingKey: a.groupingKey ?? \"\",\n overlap: a.overlap,\n missed: a.missed,\n continuationEnabled: c.enabled,\n continuationObjective: c.enabled ? c.objective : \"\",\n maxContinuations: c.enabled ? String(c.maxContinuations) : base.maxContinuations,\n maxElapsedMinutes: c.enabled ? String(c.maxElapsedMinutes) : base.maxElapsedMinutes,\n maxTokens: c.enabled && c.maxTokens !== null ? String(c.maxTokens) : \"\",\n maxCostUsd: c.enabled && c.maxCostUsd !== null ? String(c.maxCostUsd) : \"\",\n checks: a.completion.checks ? a.completion.checks.join(\"\\n\") : \"\",\n requireHumanReview: a.completion.requireHumanReview,\n };\n}\n\nfunction toNumber(s: string): number {\n return s.trim() === \"\" ? Number.NaN : Number(s.trim());\n}\n\nfunction toOptionalNumber(s: string): number | null {\n return s.trim() === \"\" ? null : Number(s.trim());\n}\n\nfunction draftTrigger(d: AutomationDraft): Trigger {\n switch (d.triggerKind) {\n case \"manual\":\n return { kind: \"manual\" };\n case \"once\":\n return { kind: \"once\", at: localInputToIso(d.onceAt) };\n case \"cron\":\n return { kind: \"cron\", expr: d.cronExpr.trim(), timezone: d.cronTimezone.trim() };\n case \"webhook\":\n return { kind: \"webhook\" };\n case \"dependency\":\n return { kind: \"dependency\", taskId: d.dependencyTaskId };\n }\n}\n\n/**\n * Build the request body from a draft. The result is shaped like an\n * AutomationInput but is not validated (numbers may be NaN, strings empty);\n * run validateDraft before sending it.\n */\nexport function draftToInput(d: AutomationDraft): AutomationInput {\n const checks = lines(d.checks);\n return {\n name: d.name.trim(),\n enabled: d.enabled,\n projectId: d.projectId,\n trigger: draftTrigger(d),\n filters: d.filters\n .filter((f) => f.path.trim() || f.equals.trim())\n .map((f) => ({ path: f.path.trim(), equals: f.equals })),\n template: {\n title: d.title.trim(),\n objective: d.objective,\n acceptanceCriteria: lines(d.criteria),\n priority: d.priority,\n },\n hostId: d.hostId || null,\n profileId: d.profileId || null,\n mode: d.mode,\n groupingKey: d.groupingKey.trim() || null,\n overlap: d.overlap,\n missed: d.missed,\n continuation: d.continuationEnabled\n ? {\n enabled: true,\n objective: d.continuationObjective.trim(),\n maxContinuations: toNumber(d.maxContinuations),\n maxElapsedMinutes: toNumber(d.maxElapsedMinutes),\n maxTokens: toOptionalNumber(d.maxTokens),\n maxCostUsd: toOptionalNumber(d.maxCostUsd),\n }\n : { enabled: false },\n completion: {\n checks: checks.length > 0 ? checks : null,\n requireHumanReview: d.requireHumanReview,\n },\n };\n}\n\n/** Draft field keys that can carry an inline error. */\nexport type DraftField =\n | keyof AutomationDraft\n | `filters.${number}.path`\n | `filters.${number}.equals`\n | \"form\";\n\nexport type DraftErrors = Partial<Record<DraftField, string>>;\n\nconst PATH_TO_FIELD: Record<string, DraftField> = {\n name: \"name\",\n enabled: \"enabled\",\n projectId: \"projectId\",\n trigger: \"triggerKind\",\n \"trigger.kind\": \"triggerKind\",\n \"trigger.at\": \"onceAt\",\n \"trigger.expr\": \"cronExpr\",\n \"trigger.timezone\": \"cronTimezone\",\n \"trigger.taskId\": \"dependencyTaskId\",\n \"template.title\": \"title\",\n \"template.objective\": \"objective\",\n \"template.acceptanceCriteria\": \"criteria\",\n \"template.priority\": \"priority\",\n hostId: \"hostId\",\n profileId: \"profileId\",\n mode: \"mode\",\n groupingKey: \"groupingKey\",\n overlap: \"overlap\",\n missed: \"missed\",\n \"continuation.objective\": \"continuationObjective\",\n \"continuation.maxContinuations\": \"maxContinuations\",\n \"continuation.maxElapsedMinutes\": \"maxElapsedMinutes\",\n \"continuation.maxTokens\": \"maxTokens\",\n \"continuation.maxCostUsd\": \"maxCostUsd\",\n \"completion.checks\": \"checks\",\n \"completion.requireHumanReview\": \"requireHumanReview\",\n};\n\n/** Map a zod issue path to a draft field. */\nexport function fieldForPath(path: readonly PropertyKey[]): DraftField {\n const parts = path.map(String);\n if (parts[0] === \"filters\" && parts.length >= 3) {\n return `filters.${Number(parts[1])}.${parts[2] === \"equals\" ? \"equals\" : \"path\"}`;\n }\n if (parts[0] === \"template\" && parts[1] === \"acceptanceCriteria\") return \"criteria\";\n if (parts[0] === \"completion\" && parts[1] === \"checks\") return \"checks\";\n for (let n = parts.length; n > 0; n--) {\n const f = PATH_TO_FIELD[parts.slice(0, n).join(\".\")];\n if (f) return f;\n }\n return \"form\";\n}\n\nfunction intError(s: string, min: number, max: number, label: string): string | null {\n const n = toNumber(s);\n if (!Number.isInteger(n) || n < min || n > max) {\n return `${label} must be a whole number from ${min} to ${max}`;\n }\n return null;\n}\n\n/**\n * Validate a draft: friendly checks first (required fields, cron, timezone,\n * number ranges), then AutomationInput.safeParse for anything else.\n */\nexport function validateDraft(d: AutomationDraft): {\n input: AutomationInput | null;\n errors: DraftErrors;\n} {\n const errors: DraftErrors = {};\n const set = (f: DraftField, msg: string | null) => {\n if (msg && !errors[f]) errors[f] = msg;\n };\n if (!d.name.trim()) set(\"name\", \"Name is required\");\n if (!d.projectId) set(\"projectId\", \"Choose a project\");\n if (!d.title.trim()) set(\"title\", \"Task title is required\");\n switch (d.triggerKind) {\n case \"once\":\n if (!localInputToIso(d.onceAt)) set(\"onceAt\", \"Choose a date and time\");\n break;\n case \"cron\":\n set(\"cronExpr\", validateCron(d.cronExpr));\n set(\"cronTimezone\", validateTimezone(d.cronTimezone));\n break;\n case \"dependency\":\n if (!d.dependencyTaskId) set(\"dependencyTaskId\", \"Choose the task to wait for\");\n break;\n }\n d.filters.forEach((f, i) => {\n if (!f.path.trim() && f.equals.trim()) set(`filters.${i}.path`, \"Enter a payload path\");\n });\n if (d.mode === \"continue\" && !d.groupingKey.trim()) {\n set(\"groupingKey\", \"A grouping key is required to continue an existing task\");\n }\n if (d.continuationEnabled) {\n if (!d.continuationObjective.trim()) {\n set(\"continuationObjective\", \"An objective is required when continuation is on\");\n }\n set(\"maxContinuations\", intError(d.maxContinuations, 1, 50, \"Max continuations\"));\n set(\"maxElapsedMinutes\", intError(d.maxElapsedMinutes, 1, 1440, \"Max elapsed minutes\"));\n if (d.maxTokens.trim()) {\n const n = toNumber(d.maxTokens);\n if (!Number.isInteger(n) || n <= 0)\n set(\"maxTokens\", \"Max tokens must be a positive whole number\");\n }\n if (d.maxCostUsd.trim()) {\n const n = toNumber(d.maxCostUsd);\n if (!Number.isFinite(n) || n <= 0) set(\"maxCostUsd\", \"Max cost must be a positive amount\");\n }\n }\n const raw = draftToInput(d);\n const parsed = AutomationInput.safeParse(raw);\n if (!parsed.success) {\n for (const issue of parsed.error.issues) set(fieldForPath(issue.path), issue.message);\n }\n const ok = parsed.success && Object.keys(errors).length === 0;\n return { input: ok ? parsed.data : null, errors };\n}\n\n/* ------------------------------------------------------------------ */\n/* History */\n/* ------------------------------------------------------------------ */\n\nexport function occurrenceTime(o: Occurrence): string {\n return o.scheduledFor ?? o.createdAt;\n}\n\n/** Union by id (later lists win), newest first. */\nexport function mergeOccurrences(...lists: (Occurrence[] | undefined | null)[]): Occurrence[] {\n const byId = new Map<string, Occurrence>();\n for (const list of lists) for (const o of list ?? []) byId.set(o.id, o);\n return [...byId.values()].sort(\n (a, b) =>\n b.createdAt.localeCompare(a.createdAt) || occurrenceTime(b).localeCompare(occurrenceTime(a)),\n );\n}\n\n/** Accept `Occurrence[]` or `{items|occurrences: Occurrence[]}`. */\nexport function normalizeHistory(res: unknown): Occurrence[] {\n if (Array.isArray(res)) return res as Occurrence[];\n if (res && typeof res === \"object\") {\n const r = res as { items?: unknown; occurrences?: unknown };\n if (Array.isArray(r.items)) return r.items as Occurrence[];\n if (Array.isArray(r.occurrences)) return r.occurrences as Occurrence[];\n }\n return [];\n}\n\nexport function curlExample(token: string, url: string): string {\n return `curl -X POST -H 'Authorization: Bearer ${token}' -H 'Content-Type: application/json' -d '{}' ${url}`;\n}\n"],"ignoreList":[0,1,2,3],"mappings":"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"}