@igoruehara/canvas-flow 0.1.8 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,11 @@
1
1
  # Canvas Flow
2
2
 
3
- Canvas Flow e uma aplicacao web local para criar, testar e executar fluxos de IA multiagente em formato visual. O pacote npm sobe frontend e backend juntos em um unico comando.
3
+ Canvas Flow é uma aplicação web local para criar, testar e executar agentes de IA multiagente em formato visual, com canais prontos para WhatsApp e Web Widget. O pacote npm sobe frontend e backend juntos em um único comando.
4
4
 
5
5
  Use quando quiser:
6
6
 
7
- - criar automacoes com agentes de IA;
7
+ - criar agentes de IA para atendimento e automação;
8
+ - publicar agentes nos canais WhatsApp e Web Widget;
8
9
  - conectar prompts, ferramentas, webhooks e documentos;
9
10
  - testar fluxos localmente antes de publicar;
10
11
  - usar RAG com documentos;
@@ -42,7 +43,7 @@ http://localhost:3333
42
43
  - execucao local de frontend e API no mesmo processo Node;
43
44
  - configuracao de provedores de IA pela UI ou pelo `config.json`;
44
45
  - RAG com Milvus/Zilliz ou Azure AI Search;
45
- - entrada por API, webhook, web widget e canais configurados no app;
46
+ - canais de entrada para WhatsApp, Web Widget, API e webhook;
46
47
  - chaves de API para consumir fluxos publicados;
47
48
  - validacao do ambiente com `doctor`.
48
49
 
package/package.json CHANGED
@@ -1,7 +1,15 @@
1
1
  {
2
2
  "name": "@igoruehara/canvas-flow",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Standalone npm launcher for Canvas Flow multi-agent GenAI workflows.",
5
+ "homepage": "https://github.com/igoruehara/canvas-flow#readme",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/igoruehara/canvas-flow.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/igoruehara/canvas-flow/issues"
12
+ },
5
13
  "keywords": [
6
14
  "IA",
7
15
  "LLM",
@@ -427,7 +427,7 @@ ${Kf(m).split(`
427
427
  `).map(f=>` ${f}`).join(`
428
428
  `)}`:"";return`${r+1}. ${l?`${l}: `:""}${p||Mk(n)}${h}`}return`${r+1}. ${String(n)}`}).join(`
429
429
  `)}function Qx(t){return t==="buttons"||t==="quickReplies"?qt.buttons:t==="list"||t==="appointmentFlow"?qt.listRows:t==="carousel"?qt.carouselCards:1}const Jr={field:"",type:"text",value:""};function Nj(t){return Array.isArray(t)?"array":typeof t=="boolean"?"boolean":typeof t=="number"?"number":"text"}function Cj(t){return Array.isArray(t)?t.map(n=>String(n)).join(", "):t==null?"":typeof t=="object"?JSON.stringify(t):String(t)}function Rd(t,n){const r=n.trim();if(t==="number"){if(!r)return null;const s=Number(r.replace(",","."));return Number.isFinite(s)?s:null}return t==="boolean"?r==="true":t==="array"?r.split(",").map(s=>s.trim()).filter(Boolean).map(s=>{if(s==="true")return!0;if(s==="false")return!1;const l=Number(s.replace(",","."));return Number.isFinite(l)&&/^-?\d+([.,]\d+)?$/.test(s)?l:s}):n}function Pk(t,n){return Array.isArray(n)&&n.length?n.map(r=>({field:String(r.field||"").trim(),value:r.value,condition:String(r.condition||"")})).filter(r=>r.field):Object.entries(t||{}).map(([r,s])=>({field:r,value:s,condition:""}))}function _k(t){return t.reduce((n,r)=>{const s=String(r.field||"").trim(),l=String(r.condition||"").trim();return s&&!l&&(n[s]=r.value),n},{})}function wh({type:t,value:n,onChange:r}){return t==="boolean"?e.jsxs("select",{value:n==="true"?"true":"false",onChange:s=>r(s.target.value),children:[e.jsx("option",{value:"true",children:"true"}),e.jsx("option",{value:"false",children:"false"})]}):e.jsx("input",{value:n,placeholder:t==="array"?"valor1, valor2":"Valor",onChange:s=>r(s.target.value)})}function Ki({filter:t,draft:n,emptyText:r,onChange:s,onDraftChange:l}){const p=Object.entries(t||{}),m=()=>{const h=n.field.trim();h&&(s({...t,[h]:Rd(n.type,n.value)}),l(Jr))};return e.jsxs("div",{className:"filter-editor",children:[p.length===0&&e.jsx("div",{className:"filter-empty",children:r}),p.map(([h,f],x)=>{const j=Nj(f),w=Cj(f);return e.jsxs("div",{className:"filter-row",children:[e.jsx("input",{"aria-label":"Campo extraFields",value:h,placeholder:"Campo",onChange:N=>{const C=N.target.value.trim(),E={...t};delete E[h],C&&(E[C]=f),s(E)}}),e.jsxs("select",{"aria-label":"Tipo do filtro",value:j,onChange:N=>{s({...t,[h]:Rd(N.target.value,w)})},children:[e.jsx("option",{value:"text",children:"Texto"}),e.jsx("option",{value:"number",children:"Número"}),e.jsx("option",{value:"boolean",children:"Booleano"}),e.jsx("option",{value:"array",children:"Lista"})]}),e.jsx(wh,{type:j,value:w,onChange:N=>s({...t,[h]:Rd(j,N)})}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover filtro",title:"Remover filtro",onClick:()=>{const N={...t};delete N[h],s(N)},children:e.jsx(Nt,{size:14})})]},x)}),e.jsxs("div",{className:"filter-row filter-row-new",children:[e.jsx("input",{value:n.field,placeholder:"Campo",onChange:h=>l({...n,field:h.target.value})}),e.jsxs("select",{value:n.type,onChange:h=>l({...n,type:h.target.value}),children:[e.jsx("option",{value:"text",children:"Texto"}),e.jsx("option",{value:"number",children:"Número"}),e.jsx("option",{value:"boolean",children:"Booleano"}),e.jsx("option",{value:"array",children:"Lista"})]}),e.jsx(wh,{type:n.type,value:n.value,onChange:h=>l({...n,value:h})}),e.jsxs("button",{type:"button",className:"filter-add-button",onClick:m,disabled:!n.field.trim(),children:[e.jsx(un,{size:14}),"Add"]})]})]})}function Qf(t){if(t.bodyType==="none"||t.bodyType==="jsonFields"||t.bodyType==="jsonText"||t.bodyType==="text")return t.bodyType;const n=t.body!==void 0?t.body:t.data;return typeof n=="string"?"text":n&&typeof n=="object"&&!Array.isArray(n)?"jsonFields":"none"}function uo(t){return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}function Xx(){return{method:"GET",url:"https://example.com",headers:{},params:{},bodyType:"none"}}function Ok(){return{enabled:!0,url:"",method:"GET",headers:{},params:{},intervalSeconds:5,maxAttempts:10,stopCondition:'result.data.status === "done"'}}function Fl(t){if(t==null||t==="")return`{
430
-
430
+
431
431
  }`;if(typeof t=="string")return t;try{return JSON.stringify(t,null,2)}catch{return"{}"}}function Xm({requests:t,onChange:n}){const[r,s]=b.useState({}),[l,p]=b.useState({}),m=Array.isArray(t)?t:[],h=(j,w)=>s(N=>({...N,[j]:w})),f=(j,w)=>{const N=[...m];N[j]={...N[j]||Xx(),...w},n(N)},x=j=>n(m.filter((w,N)=>N!==j));return e.jsxs("div",{className:"http-batch-editor",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsxs("strong",{children:["Requests httpBatch (",m.length,")"]}),e.jsxs("button",{type:"button",onClick:()=>n([...m,Xx()]),children:[e.jsx(un,{size:14}),"Request"]})]}),m.length===0&&e.jsx("div",{className:"filter-empty",children:"Nenhuma chamada configurada."}),m.map((j,w)=>{const N=Qf(j),C=j.body!==void 0?j.body:j.data,E=uo(j.polling),T=E.enabled===!0,R=Qf(E),D=E.body!==void 0?E.body:E.data,q=I=>f(w,{polling:{...Ok(),...E,...I}});return e.jsxs("div",{className:"http-request-card",children:[e.jsxs("div",{className:"http-request-header",children:[e.jsxs("strong",{children:["Request ",w+1]}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover request",title:"Remover request",onClick:()=>x(w),children:e.jsx(Nt,{size:14})})]}),e.jsxs("div",{className:"http-request-grid",children:[e.jsxs("label",{children:["Método",e.jsx("select",{value:String(j.method||"GET").toUpperCase(),onChange:I=>f(w,{method:I.target.value}),children:Gf.map(I=>e.jsx("option",{value:I,children:I},I))})]}),e.jsxs("label",{children:["URL",e.jsx("input",{value:String(j.url||""),placeholder:"https://api.exemplo.com/recurso",onChange:I=>f(w,{url:I.target.value})})]})]}),e.jsxs("div",{className:"filter-section",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Headers"})}),e.jsx(Ki,{filter:uo(j.headers),draft:r[`headers-${w}`]||Jr,emptyText:"Sem headers.",onDraftChange:I=>h(`headers-${w}`,I),onChange:I=>f(w,{headers:I})})]}),e.jsxs("div",{className:"filter-section",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Query params"})}),e.jsx(Ki,{filter:uo(j.params),draft:r[`params-${w}`]||Jr,emptyText:"Sem query params.",onDraftChange:I=>h(`params-${w}`,I),onChange:I=>f(w,{params:I})})]}),e.jsxs("label",{children:["Body",e.jsx("select",{value:N,onChange:I=>{const F=I.target.value;if(F==="none"&&f(w,{bodyType:F,body:void 0,data:void 0}),F==="jsonFields"&&f(w,{bodyType:F,body:uo(C),data:void 0}),F==="jsonText"){const Y=Fl(C);p(ne=>({...ne,[w]:Y})),f(w,{bodyType:F,body:Ns(Y,uo(C)),data:void 0})}F==="text"&&f(w,{bodyType:F,body:typeof C=="string"?C:"",data:void 0})},children:Jf.map(I=>e.jsx("option",{value:I.value,children:I.label},I.value))})]}),N==="jsonFields"&&e.jsxs("div",{className:"filter-section",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Campos do body"})}),e.jsx(Ki,{filter:uo(C),draft:r[`body-${w}`]||Jr,emptyText:"Sem campos no body.",onDraftChange:I=>h(`body-${w}`,I),onChange:I=>f(w,{body:I,data:void 0,bodyType:N})})]}),N==="jsonText"&&e.jsxs("label",{children:["JSON do body",e.jsx("textarea",{rows:6,value:l[w]??Fl(C),placeholder:'{"campo": "valor"}',onChange:I=>p(F=>({...F,[w]:I.target.value})),onBlur:()=>{const I=l[w]??Fl(C);f(w,{body:Ns(I,uo(C)),data:void 0,bodyType:N})}})]}),N==="text"&&e.jsxs("label",{children:["Texto do body",e.jsx("textarea",{rows:4,value:String(C||""),placeholder:"Conteúdo bruto enviado no body",onChange:I=>f(w,{body:I.target.value,data:void 0,bodyType:N})})]}),e.jsxs("div",{className:"filter-section",children:[e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:T,onChange:I=>q({enabled:I.target.checked})}),e.jsx("span",{children:"Ativar polling"})]}),T&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"filter-empty",children:["Use polling quando a chamada inicial dispara um processamento/webhook e outra URL precisa ser consultada até o dado aparecer. Em URL, headers ou params, você pode usar ",e.jsx("code",{children:"{{result.data.id}}"})," ou ",e.jsx("code",{children:"{{initialResult.data.id}}"}),"."]}),e.jsxs("div",{className:"http-request-grid",children:[e.jsxs("label",{children:["Método do polling",e.jsx("select",{value:String(E.method||"GET").toUpperCase(),onChange:I=>q({method:I.target.value}),children:Gf.map(I=>e.jsx("option",{value:I,children:I},I))})]}),e.jsxs("label",{children:["URL de polling",e.jsx("input",{value:String(E.url||""),placeholder:"https://api.exemplo.com/status/{{result.data.id}}",onChange:I=>q({url:I.target.value})})]})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Intervalo (segundos)",e.jsx("input",{type:"number",min:1,max:600,value:Number(E.intervalSeconds||5),onChange:I=>q({intervalSeconds:Math.max(1,Number(I.target.value)||1)})})]}),e.jsxs("label",{children:["Máx. tentativas",e.jsx("input",{type:"number",min:1,max:100,value:Number(E.maxAttempts||10),onChange:I=>q({maxAttempts:Math.max(1,Number(I.target.value)||1)})})]})]}),e.jsxs("div",{className:"filter-empty",children:["Use a condição JS para decidir quando parar. Você recebe ",e.jsx("code",{children:"result"})," com a resposta atual do polling,",e.jsx("code",{children:"initialResult"})," com a resposta da primeira chamada e ",e.jsx("code",{children:"attempt"})," com o número da tentativa."]}),e.jsxs("label",{children:["Condição JS para parar",e.jsx("textarea",{rows:3,value:String(E.stopCondition||""),placeholder:'result.data.status === "done" && Boolean(result.data.result?.xpto)',onChange:I=>q({stopCondition:I.target.value})})]}),e.jsxs("label",{children:["Body do polling",e.jsx("select",{value:R,onChange:I=>{const F=I.target.value;if(F==="none"&&q({bodyType:F,body:void 0,data:void 0}),F==="jsonFields"&&q({bodyType:F,body:uo(D),data:void 0}),F==="jsonText"){const Y=Fl(D);p(ne=>({...ne,[`polling-${w}`]:Y})),q({bodyType:F,body:Ns(Y,uo(D)),data:void 0})}F==="text"&&q({bodyType:F,body:typeof D=="string"?D:"",data:void 0})},children:Jf.map(I=>e.jsx("option",{value:I.value,children:I.label},I.value))})]}),R==="jsonFields"&&e.jsxs("div",{className:"filter-section",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Campos do body do polling"})}),e.jsx(Ki,{filter:uo(D),draft:r[`polling-body-${w}`]||Jr,emptyText:"Sem campos no body.",onDraftChange:I=>h(`polling-body-${w}`,I),onChange:I=>q({body:I,data:void 0,bodyType:R})})]}),R==="jsonText"&&e.jsxs("label",{children:["JSON do body do polling",e.jsx("textarea",{rows:6,value:l[`polling-${w}`]??Fl(D),placeholder:'{"id": "{{initialResult.data.id}}"}',onChange:I=>p(F=>({...F,[`polling-${w}`]:I.target.value})),onBlur:()=>{const I=l[`polling-${w}`]??Fl(D);q({body:Ns(I,uo(D)),data:void 0,bodyType:R})}})]}),R==="text"&&e.jsxs("label",{children:["Texto do body do polling",e.jsx("textarea",{rows:4,value:String(D||""),placeholder:"Conteúdo bruto enviado no polling",onChange:I=>q({body:I.target.value,data:void 0,bodyType:R})})]}),e.jsxs("div",{className:"filter-section",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Headers do polling"})}),e.jsx(Ki,{filter:uo(E.headers),draft:r[`polling-headers-${w}`]||Jr,emptyText:"Sem headers.",onDraftChange:I=>h(`polling-headers-${w}`,I),onChange:I=>q({headers:I})})]}),e.jsxs("div",{className:"filter-section",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Query params do polling"})}),e.jsx(Ki,{filter:uo(E.params),draft:r[`polling-params-${w}`]||Jr,emptyText:"Sem query params.",onDraftChange:I=>h(`polling-params-${w}`,I),onChange:I=>q({params:I})})]})]})]})]},w)})]})}function Ph(t){return`${t}-${Math.random().toString(36).slice(2,8)}`}function Rk({tags:t,onChange:n}){const r=(s,l)=>{const p=[...t];p[s]={...p[s],...l},n(p)};return e.jsxs("div",{className:"rich-editor-block",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsx("strong",{children:"Tags do nó"}),e.jsxs("button",{type:"button",onClick:()=>n([...t,{id:Ph("tag"),tag:"novo_evento",label:"Novo evento",mode:"always",valueTemplate:"",metadataJson:"{}"}]),children:[e.jsx(un,{size:14}),"Tag"]})]}),e.jsxs("div",{className:"filter-empty",children:["Salva métricas em uma coleção separada quando a conversa passar por este nó. Use ",e.jsx("strong",{children:"uma vez"})," para funil/conversão e ",e.jsx("strong",{children:"sempre"})," para contagem de passagem."]}),t.length===0&&e.jsx("div",{className:"filter-empty",children:"Nenhuma tag configurada neste nó."}),t.map((s,l)=>{const p=s.metadataJson?Gr(s.metadataJson):"";return e.jsxs("div",{className:"rich-card-editor",children:[e.jsxs("div",{className:"rich-card-header",children:[e.jsxs("strong",{children:["Tag ",l+1]}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover tag",title:"Remover tag",onClick:()=>n(t.filter((m,h)=>h!==l)),children:e.jsx(Nt,{size:14})})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Tag",e.jsx("input",{value:s.tag||"",placeholder:"lead_qualificado",onChange:m=>r(l,{tag:m.target.value})})]}),e.jsxs("label",{children:["Nome para exibição",e.jsx("input",{value:s.label||"",placeholder:"Lead qualificado",onChange:m=>r(l,{label:m.target.value})})]})]}),e.jsxs("label",{children:["Frequência de gravação",e.jsxs("select",{value:s.mode||"always",onChange:m=>r(l,{mode:m.target.value}),children:[e.jsx("option",{value:"once",children:"Salvar uma vez por conversa neste nó"}),e.jsx("option",{value:"always",children:"Salvar toda vez que passar por aqui"})]})]}),e.jsxs("label",{children:["Valor opcional",e.jsx("input",{value:s.valueTemplate||"",placeholder:"{{context.slots.valor}}",onChange:m=>r(l,{valueTemplate:m.target.value})})]}),e.jsxs("label",{children:["Metadados JSON",e.jsx("textarea",{rows:3,value:s.metadataJson||"{}",placeholder:'{"canal":"{{context.channel}}"}',onChange:m=>r(l,{metadataJson:m.target.value})})]}),p&&e.jsxs("div",{className:"field-error",children:["JSON inválido: ",p]})]},s.id||l)})]})}function Xf({title:t,actions:n,onChange:r,maxActions:s=qt.buttons}){return e.jsxs("div",{className:"rich-editor-block",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsxs("strong",{children:[t," (",n.length,"/",s,")"]}),e.jsxs("button",{type:"button",disabled:n.length>=s,onClick:()=>r([...n,{id:Ph("action"),label:"Opcao",value:"opcao"}]),children:[e.jsx(un,{size:14}),"Add"]})]}),n.length===0&&e.jsx("div",{className:"filter-empty",children:"Nenhuma opcao cadastrada."}),n.map((l,p)=>e.jsxs("div",{className:"rich-action-row",children:[e.jsx("input",{value:l.label||"",placeholder:"Texto do botão",maxLength:qt.buttonLabel,onChange:m=>{const h=[...n];h[p]={...l,label:m.target.value},r(h)}}),e.jsx("input",{value:l.value||"",placeholder:"Valor salvo/enviado",maxLength:qt.buttonId,onChange:m=>{const h=[...n];h[p]={...l,value:m.target.value},r(h)}}),e.jsx("input",{value:l.id||"",placeholder:"ID",maxLength:qt.buttonId,onChange:m=>{const h=[...n];h[p]={...l,id:m.target.value},r(h)}}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover opcao",title:"Remover opcao",onClick:()=>r(n.filter((m,h)=>h!==p)),children:e.jsx(Nt,{size:14})})]},l.id||p))]})}function Fk({sections:t,onChange:n}){const r=t.reduce((l,p)=>l+(p.items||[]).length,0),s=(l,p)=>{const m=[...t];m[l]={...m[l],...p},n(m)};return e.jsxs("div",{className:"rich-editor-block",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsxs("strong",{children:["Secoes da lista (",r,"/",qt.listRows," itens)"]}),e.jsxs("button",{type:"button",disabled:t.length>=qt.listSections,onClick:()=>n([...t,{title:"Seção",items:[]}]),children:[e.jsx(un,{size:14}),"Seção"]})]}),t.length===0&&e.jsx("div",{className:"filter-empty",children:"Adicione uma secao com itens de lista."}),t.map((l,p)=>e.jsxs("div",{className:"rich-card-editor",children:[e.jsxs("div",{className:"rich-card-header",children:[e.jsx("input",{value:l.title||"",placeholder:"Título da secao",maxLength:qt.sectionTitle,onChange:m=>s(p,{title:m.target.value})}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover secao",title:"Remover secao",onClick:()=>n(t.filter((m,h)=>h!==p)),children:e.jsx(Nt,{size:14})})]}),(l.items||[]).map((m,h)=>e.jsxs("div",{className:"rich-list-item-row",children:[e.jsx("input",{value:m.title||"",placeholder:"Item",maxLength:qt.rowTitle,onChange:f=>{const x=[...l.items||[]];x[h]={...m,title:f.target.value},s(p,{items:x})}}),e.jsx("input",{value:m.description||"",placeholder:"Descricao",maxLength:qt.rowDescription,onChange:f=>{const x=[...l.items||[]];x[h]={...m,description:f.target.value},s(p,{items:x})}}),e.jsx("input",{value:m.value||"",placeholder:"Valor",maxLength:qt.rowId,onChange:f=>{const x=[...l.items||[]];x[h]={...m,value:f.target.value},s(p,{items:x})}}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover item",title:"Remover item",onClick:()=>s(p,{items:l.items.filter((f,x)=>x!==h)}),children:e.jsx(Nt,{size:14})})]},m.id||h)),e.jsxs("button",{type:"button",className:"filter-add-button",disabled:r>=qt.listRows,onClick:()=>s(p,{items:[...l.items||[],{id:Ph("item"),title:"Item",value:"item"}]}),children:[e.jsx(un,{size:14}),"Item"]})]},p))]})}function zk({cards:t,onChange:n}){const r=(s,l)=>{const p=[...t];p[s]={...p[s],...l},n(p)};return e.jsxs("div",{className:"rich-editor-block",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsxs("strong",{children:["Cards do carrossel (",t.length,"/",qt.carouselCards,")"]}),e.jsxs("button",{type:"button",disabled:t.length>=qt.carouselCards,onClick:()=>n([...t,{id:Ph("card"),title:"Card",subtitle:"",imageUrl:"",buttons:[]}]),children:[e.jsx(un,{size:14}),"Card"]})]}),t.length===0&&e.jsx("div",{className:"filter-empty",children:"Adicione cards para o web widget."}),t.map((s,l)=>e.jsxs("div",{className:"rich-card-editor",children:[e.jsxs("div",{className:"rich-card-header",children:[e.jsxs("strong",{children:["Card ",l+1]}),e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover card",title:"Remover card",onClick:()=>n(t.filter((p,m)=>m!==l)),children:e.jsx(Nt,{size:14})})]}),e.jsx("input",{value:s.title||"",maxLength:qt.carouselCardTitle,placeholder:"Título",onChange:p=>r(l,{title:p.target.value})}),e.jsx("input",{value:s.subtitle||"",maxLength:qt.carouselCardSubtitle,placeholder:"Subtítulo",onChange:p=>r(l,{subtitle:p.target.value})}),e.jsx("input",{value:s.imageUrl||"",maxLength:qt.imageUrl,placeholder:"URL da imagem",onChange:p=>r(l,{imageUrl:p.target.value})}),e.jsx(Xf,{title:"Botões do card",actions:s.buttons||[],onChange:p=>r(l,{buttons:p}),maxActions:qt.buttons})]},s.id||l))]})}function Lk({appointmentFlow:t,flowConfig:n,currentFlowId:r,stepId:s,agentId:l,onChange:p}){var mt,Et,Ye,Pe,Ze,Ct;const[m,h]=b.useState(""),[f,x]=b.useState(!1),[j,w]=b.useState(""),[N,C]=b.useState(""),[E,T]=b.useState(!1),[R,D]=b.useState(""),[q,I]=b.useState([]),[F,Y]=b.useState(!1),[ne,ae]=b.useState(""),[oe,Q]=b.useState(!1),[fe,xe]=b.useState(""),[ye,le]=b.useState(""),M={...bh,...t||{}},ee=re=>p({...M,...re}),H=(Array.isArray(M.attachmentSteps)?M.attachmentSteps:[]).slice(0,3).map((re,we)=>({id:Ep(re.id||`anexo_${we+1}`,we),label:ih(re.label||`Anexo ${we+1}`),type:re.type==="document"?"document":"image",required:re.required!==!1,description:ih(re.description||"")})),se={...bh.stepLabels,...M.stepLabels||{}};for(const re of Object.keys(se))se[re]=ih(se[re]);const G=ff(M.stepOrder,H),V=Du.filter(re=>!G.includes(re.key)),K=!!((mt=n.whatsapp)!=null&&mt.businessAccountId&&((Et=n.whatsapp)!=null&&Et.accessToken))||oe;b.useEffect(()=>{let re=!1;const we=async()=>{var Me;try{const et=await Oe.getProviderConfig({agentId:(l==null?void 0:l.trim())||"default-agent"});if(re)return;const it=et.settings.whatsapp;Q(!!((it==null?void 0:it.provider)==="meta"&&it.businessAccountId&&((Me=et.secretStatus)!=null&&Me["whatsapp.accessToken"]||it.accessToken)))}catch{re||Q(!1)}};return we(),window.addEventListener("canvas-flow-provider-config-updated",we),()=>{re=!0,window.removeEventListener("canvas-flow-provider-config-updated",we)}},[l]);const P=async()=>{if(!K){I([]);return}Y(!0),ae("");try{const re=await Oe.listWhatsappFlows({whatsapp:n.whatsapp,agentId:l});I(Array.isArray(re.flows)?re.flows:[])}catch(re){ae(re instanceof Error?re.message:"Não foi possível listar os WhatsApp Flows.")}finally{Y(!1)}},O=async re=>{const we=String(re||"").trim();if(we&&window.confirm("Excluir ou desativar este WhatsApp Flow na Meta?")){xe(we),ae("");try{const Me=await Oe.deleteWhatsappFlow(we,{whatsapp:n.whatsapp,agentId:l});M.flowId===we&&ee({flowId:""}),C(Me.deprecated?`Flow desativado: ${we}`:`Flow excluído: ${we}`),await P()}catch(Me){ae(Me instanceof Error?Me.message:"Não foi possível excluir o Flow.")}finally{xe("")}}},ve=re=>{var we;return e.jsx("button",{type:"button",className:"field-help-button",title:`Ver exemplo de ${((we=Gx[re])==null?void 0:we.title)||"campo"}`,onClick:Me=>{Me.preventDefault(),Me.stopPropagation(),D(et=>et===re?"":re)},children:"?"})},ge=re=>{const we=Gx[re];return R!==re||!we?null:e.jsxs("div",{className:"appointment-field-example inline",children:[e.jsxs("div",{children:[e.jsx("strong",{children:we.title}),e.jsx("button",{type:"button",title:"Fechar exemplo",onClick:Me=>{Me.preventDefault(),Me.stopPropagation(),D("")},children:e.jsx(Vt,{size:14})})]}),e.jsx("span",{children:we.description}),e.jsx("pre",{children:JSON.stringify(we.value,null,2)})]})},be=re=>ee({stepOrder:ff(re,H)}),Ce=(re,we)=>{ee({stepLabels:{...se,[re]:we}})},$=re=>{if(!(G.length<=1)){if(re.startsWith("attachment:")){const we=re.replace(/^attachment:/,"");he(H.filter(Me=>Me.id!==we),G.filter(Me=>Me!==re));return}be(G.filter(we=>we!==re))}},z=re=>{!re||G.includes(re)||(be([...G,re]),le(""))},Z=(re,we)=>{const Me=[...G],et=re+we;et<0||et>=Me.length||([Me[re],Me[et]]=[Me[et],Me[re]],be(Me))},he=(re,we=G)=>{const Me=re.slice(0,3).map((et,it)=>({...et,id:Ep(et.id,it),label:et.label||`Anexo ${it+1}`}));ee({attachmentSteps:Me,stepOrder:ff(we,Me)})},Be=()=>{if(H.length>=3)return;const re=H.length,we=Ep(`anexo_${re+1}`,re),Me={id:we,label:re===0?"Carteirinha de saúde":re===1?"Pedido médico":"RG",type:"image",required:!0,description:"Anexe uma imagem legível."};he([...H,Me],[...G,Md(we)])},at=async re=>{if(p(re),!r||!s)return!1;const we={...n,steps:n.steps.map(Me=>Me.id!==s?Me:{...Me,richMessage:{...Me.richMessage||{type:"appointmentFlow",text:""},appointmentFlow:re}})};return await Oe.updateFlow(r,{agentId:l,config:we}),!0},gt=re=>{const we=Ek(re);return we?e.jsxs("div",{className:"appointment-step-data-field",children:[e.jsxs("label",{children:["Label da etapa",e.jsx("input",{value:se[re]||we.title,maxLength:30,placeholder:we.title,onChange:Me=>Ce(re,Me.target.value)})]}),e.jsxs("label",{children:[e.jsxs("span",{className:"field-label-with-help",children:[e.jsx("span",{children:"Dados dinâmicos ou fixos"}),ve(we.helpKey)]}),e.jsx("textarea",{rows:we.rows,value:String(M[we.valueKey]||""),placeholder:we.placeholder,onChange:Me=>ee({[we.valueKey]:Me.target.value})})]}),ge(we.helpKey),re==="items"&&e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Filtro dos itens",e.jsx("input",{value:M.itemsFilterTemplate||"",placeholder:"{{context.slots.itemFilter}}",onChange:Me=>ee({itemsFilterTemplate:Me.target.value})}),e.jsx("span",{className:"field-hint",children:"Filtra por ID, título ou descrição antes de montar o Flow."})]}),e.jsxs("label",{children:["Máx. selecionados",e.jsx("input",{type:"number",min:1,max:20,value:M.itemsMaxSelected??20,onChange:Me=>ee({itemsMaxSelected:Number(Me.target.value)})}),e.jsx("span",{className:"field-hint",children:"Quantidade máxima que o usuário pode marcar neste passo."})]})]})]}):null};b.useEffect(()=>{P()},[(Ye=n.whatsapp)==null?void 0:Ye.businessAccountId,(Pe=n.whatsapp)==null?void 0:Pe.accessToken,(Ze=n.whatsapp)==null?void 0:Ze.graphApiVersion,l,oe]);const ht=async re=>{x(!0),w(""),C("");try{const we=n.whatsapp;if(!K)throw new Error("Configure WhatsApp Business Account ID e Access token em Provedores > WhatsApp.");const Me=m.trim()||`${n.title||"Canvas Flow"} Agendamento`;if(M.flowId&&re){const Re=await Oe.uploadWhatsappFlowJson(M.flowId,{whatsapp:we,agentId:l,title:M.headerText||"Agendamento",appointmentFlow:{...M,attachmentSteps:H,stepOrder:G,stepLabels:se},introText:n.title?`Agendamento - ${n.title}`:"Escolha as opções para montar seu agendamento."}),ot=Array.isArray(Re.validationErrors)?Re.validationErrors:[];if(ot.length){const rt=Kf(ot);w(`Flow atualizado, mas o JSON voltou com ${ot.length} erro(s) de validação.${rt?`
432
432
  ${rt}`:""}`),await P();return}const kt=await Oe.publishWhatsappFlow(M.flowId,{whatsapp:we,agentId:l}),Fe={...M,attachmentSteps:H,stepOrder:G,stepLabels:se,mode:"auto"},Te=await at(Fe);C(`Flow publicado: ${String(kt.flowId||M.flowId)}${Te?" e salvo no Canvas.":". Clique em Salvar para persistir no Canvas."}`),await P();return}const et=await Oe.createWhatsappFlow({name:Me,categories:["APPOINTMENT_BOOKING"],publish:re,whatsapp:we,agentId:l,title:M.headerText||"Agendamento",appointmentFlow:{...M,attachmentSteps:H,stepOrder:G,stepLabels:se},introText:n.title?`Agendamento - ${n.title}`:"Escolha as opções para montar seu agendamento."}),it=String(et.flowId||"");it&&await at({...M,flowId:it,mode:"auto",attachmentSteps:H,stepOrder:G,stepLabels:se});const qe=Array.isArray(et.validationErrors)?et.validationErrors:[];if(qe.length){const Re=Kf(qe);w(`Flow criado, mas o JSON voltou com ${qe.length} erro(s) de validação.${Re?`
433
433
  ${Re}`:""}`)}else C(re?`Flow criado, publicado e salvo no Canvas: ${it}`:`Rascunho criado e salvo no Canvas: ${it}`);await P()}catch(we){w(we instanceof Error?we.message:"Nao foi possivel criar/publicar o Flow.")}finally{x(!1)}};return e.jsxs("div",{className:"rich-editor-block",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsx("strong",{children:"WhatsApp Flow de agendamento"}),e.jsxs("button",{type:"button",title:"Ver exemplos dos dados dinâmicos",onClick:()=>T(re=>!re),children:[e.jsx(cj,{size:14}),"Exemplos"]})]}),e.jsx("div",{className:"filter-empty",children:"API oficial envia Flow nativo quando houver Flow ID publicado. Blip e Sinch recebem uma lista interativa equivalente usando os mesmos dados dinâmicos."}),E&&e.jsxs("div",{className:"filter-empty",children:[e.jsx("strong",{children:"Formato esperado dos dados dinâmicos"}),e.jsx("pre",{children:JSON.stringify({providers:[{id:"prestador_ana",title:"Dra. Ana",description:"Cardiologia"},{id:"prestador_bruno",title:"Dr. Bruno",description:"Clínico geral"}],services:[{id:"consulta",title:"Consulta",description:"30 min"},{id:"retorno",title:"Retorno",description:"15 min"}],items:[{id:"hemograma",title:"Hemograma",description:"Exame de sangue"},{id:"tsh",title:"TSH",description:"Tireoide"},{id:"glicemia",title:"Glicemia",description:"Jejum"}],dates:[{id:"2026-05-20",title:"20/05/2026",description:"Quarta-feira"},{id:"2026-05-21",title:"21/05/2026",description:"Quinta-feira"}],times:[{id:"09:00",title:"09:00",description:"Manhã"},{id:"14:30",title:"14:30",description:"Tarde"}],appointments:[{id:"ag_123",title:"20/05 às 09:00",description:"Dra. Ana - Consulta"}]},null,2)}),e.jsxs("span",{children:["Você pode preencher esses campos com uma variável, por exemplo ","{{context.slots.providers}}",", ou com um JSON direto. O componente também aceita itens com ",e.jsx("code",{children:"label"}),", ",e.jsx("code",{children:"name"})," ou ",e.jsx("code",{children:"nome"})," no lugar de ",e.jsx("code",{children:"title"}),"."]})]}),e.jsxs("div",{className:"rich-editor-block nested",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsx("strong",{children:"Criar e publicar na Meta"}),e.jsxs("button",{type:"button",onClick:()=>void P(),disabled:!K||F,children:[F?e.jsx(Ut,{size:14,className:"spin"}):e.jsx(kp,{size:14}),"Atualizar"]})]}),e.jsxs("label",{children:["Nome do Flow",e.jsx("input",{value:m,placeholder:`${n.title||"Canvas Flow"} Agendamento`,onChange:re=>h(re.target.value)})]}),e.jsx("div",{className:"filter-empty",children:"Usa o WhatsApp Business Account ID e o Access token configurados em Provedores > WhatsApp. Depois de criar, o Flow ID e gravado abaixo automaticamente."}),e.jsxs("div",{className:"meta-flow-manager",children:[e.jsxs("label",{children:["Flow criado na Meta",e.jsxs("select",{value:M.flowId||"",onChange:re=>ee({flowId:re.target.value,mode:re.target.value?"auto":M.mode}),disabled:!K||F,children:[e.jsx("option",{value:"",children:F?"Carregando flows...":"Selecionar flow criado"}),q.map(re=>{const we=String(re.id||""),Me=String(re.name||we),et=String(re.status||"");return e.jsxs("option",{value:we,children:[Me,et?` - ${et}`:""]},we)})]})]}),e.jsxs("button",{type:"button",className:"danger-link",onClick:()=>void O(M.flowId||""),disabled:!M.flowId||fe===M.flowId,title:"Excluir ou desativar o Flow selecionado na Meta",children:[e.jsx(Nt,{size:14}),fe===M.flowId?"Excluindo...":"Excluir"]})]}),!K&&e.jsx("div",{className:"filter-empty",children:"Configure Business Account ID e Access token em Provedores > WhatsApp para listar os flows criados."}),ne&&e.jsx("div",{className:"field-error",children:ne}),e.jsxs("div",{className:"rich-action-row compact",children:[e.jsx("button",{type:"button",onClick:()=>void ht(!1),disabled:f,children:f?"Processando...":"Criar rascunho"}),e.jsx("button",{type:"button",className:"primary-button",onClick:()=>void ht(!0),disabled:f,children:M.flowId?"Publicar Flow ID":"Criar e publicar"})]}),N&&e.jsx("div",{className:"filter-empty success",children:N}),j&&e.jsx("div",{className:"field-error",children:j})]}),e.jsxs("div",{className:"rich-editor-block nested",children:[e.jsx("div",{className:"filter-section-header",children:e.jsx("strong",{children:"Formatar dados com LLM"})}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:M.llmEnabled===!0,onChange:re=>ee({llmEnabled:re.target.checked})}),e.jsx("span",{children:"Usar LLM para converter dados brutos no formato do Flow"})]}),M.llmEnabled===!0&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{children:["Dados de entrada para a LLM",e.jsx("textarea",{rows:3,value:M.llmSourceTemplate||"",placeholder:"{{context.slots.schedules}}",onChange:re=>ee({llmSourceTemplate:re.target.value})})]}),e.jsxs("label",{children:["Instrução da formatação",e.jsx("textarea",{rows:4,value:M.llmInstruction||"",placeholder:"Transforme a agenda bruta em providers, services, items, dates, times e appointments.",onChange:re=>ee({llmInstruction:re.target.value})})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Modelo",e.jsxs("select",{value:M.llmModel||"",onChange:re=>ee({llmModel:re.target.value}),children:[e.jsxs("option",{value:"",children:["Usar modelo do fluxo (",n.model,")"]}),Sd(pk,M.llmModel).map(re=>e.jsx("option",{value:re.value,children:re.label},re.value))]})]}),e.jsxs("label",{children:["Temperatura",e.jsx("input",{type:"number",min:0,max:1,step:.1,value:M.llmTemperature??.1,onChange:re=>ee({llmTemperature:Number(re.target.value)})})]})]}),e.jsxs("div",{className:"filter-empty",children:["Exemplo: a LLM recebe ","{{context.slots.schedules}}"," e retorna JSON com ",e.jsx("code",{children:"providers"}),", ",e.jsx("code",{children:"services"}),", ",e.jsx("code",{children:"items"}),", ",e.jsx("code",{children:"dates"}),", ",e.jsx("code",{children:"times"})," e ",e.jsx("code",{children:"appointments"}),". O runtime normaliza títulos, descrições e IDs para os limites do WhatsApp."]})]})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Como enviar",e.jsxs("select",{value:M.mode||"auto",onChange:re=>ee({mode:re.target.value}),children:[e.jsx("option",{value:"auto",children:"Automático: Flow se tiver ID, senão lista"}),e.jsx("option",{value:"metaFlow",children:"Usar WhatsApp Flow da Meta"}),e.jsx("option",{value:"interactive",children:"Usar lista/botões interativos"})]})]}),e.jsxs("label",{children:["Lista exibida agora",e.jsx("select",{value:M.stage||"actions",onChange:re=>ee({stage:re.target.value}),children:Ak.map(re=>e.jsx("option",{value:re.value,children:re.label},re.value))})]})]}),e.jsxs("div",{className:"filter-empty",children:[e.jsx("strong",{children:"Como enviar:"})," controla se este nó usa o Flow publicado da Meta ou uma lista compatível com Blip/Sinch. ",e.jsx("strong",{children:"Lista exibida agora:"})," define qual conjunto de opções aparece neste passo quando o envio for por lista."]}),e.jsxs("label",{children:["Lista exibida por contexto",e.jsx("input",{value:M.stageTemplate||"",placeholder:"{{context.slots.appointmentStage}}",onChange:re=>ee({stageTemplate:re.target.value})})]}),e.jsxs("div",{className:"filter-empty",children:["Se esse campo retornar ",e.jsx("code",{children:"providers"}),", ",e.jsx("code",{children:"services"}),", ",e.jsx("code",{children:"items"}),", ",e.jsx("code",{children:"dates"}),", ",e.jsx("code",{children:"times"})," ou ",e.jsx("code",{children:"appointments"}),", ele sobrescreve a lista escolhida acima."]}),e.jsxs("div",{className:"rich-editor-block nested",children:[e.jsxs("div",{className:"filter-section-header",children:[e.jsx("strong",{children:"Etapas do Flow"}),e.jsxs("button",{type:"button",onClick:Be,disabled:H.length>=3,children:[e.jsx(un,{size:14}),"Anexo"]})]}),e.jsxs("div",{className:"filter-empty",children:["Ordene as telas que o WhatsApp Flow vai renderizar. Para começar direto em uma etapa, escolha a tela em ",e.jsx("strong",{children:"Tela inicial"}),"; o Flow segue as próximas etapas desta ordem."]}),V.length>0&&e.jsxs("div",{className:"appointment-add-step-row",children:[e.jsx("select",{value:ye||((Ct=V[0])==null?void 0:Ct.key)||"",onChange:re=>le(re.target.value),children:V.map(re=>e.jsx("option",{value:re.key,children:se[re.key]||re.label},re.key))}),e.jsxs("button",{type:"button",onClick:()=>{var re;return z(ye||((re=V[0])==null?void 0:re.key)||"")},children:[e.jsx(un,{size:14}),"Etapa"]})]}),e.jsx("div",{className:"appointment-step-order-list",children:G.map((re,we)=>{const Me=H.find(qe=>Md(qe.id)===re),et=Me?H.findIndex(qe=>qe.id===Me.id):-1,it=Du.some(qe=>qe.key===re);return e.jsx("div",{className:"appointment-step-order-row",children:e.jsxs("div",{className:"appointment-step-order-main",children:[e.jsxs("div",{className:"appointment-step-order-title",children:[e.jsxs("div",{children:[e.jsxs("strong",{children:[we+1,". ",Jx(re,H,se)]}),e.jsx("small",{children:Kx(re,we)})]}),e.jsxs("div",{className:"appointment-step-order-actions",children:[e.jsx("button",{type:"button","aria-label":"Subir etapa",onClick:()=>Z(we,-1),disabled:we===0,children:e.jsx(bS,{size:14})}),e.jsx("button",{type:"button","aria-label":"Descer etapa",onClick:()=>Z(we,1),disabled:we===G.length-1,children:e.jsx(vS,{size:14})}),(Me||it)&&e.jsx("button",{type:"button",className:"filter-icon-button","aria-label":"Remover etapa",onClick:()=>$(re),disabled:G.length<=1,children:e.jsx(Nt,{size:14})})]})]}),Me&&et>=0?e.jsxs("div",{className:"appointment-step-inline-editor",children:[e.jsxs("div",{className:"rich-card-header",children:[e.jsxs("strong",{children:["Anexo ",et+1]}),e.jsxs("label",{className:"checkbox-row",children:[e.jsx("input",{type:"checkbox",checked:Me.required!==!1,onChange:qe=>{const Re=[...H];Re[et]={...Me,required:qe.target.checked},he(Re)}}),e.jsx("span",{children:"Obrigatório"})]})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Tipo",e.jsxs("select",{value:Me.type||"image",onChange:qe=>{const Re=[...H];Re[et]={...Me,type:qe.target.value==="document"?"document":"image"},he(Re)},children:[e.jsx("option",{value:"image",children:"Imagem"}),e.jsx("option",{value:"document",children:"Documento"})]})]}),e.jsxs("label",{children:["ID",e.jsx("input",{value:Me.id,placeholder:`anexo_${et+1}`,onChange:qe=>{const Re=Md(Me.id),ot=Ep(qe.target.value,et),kt=[...H];kt[et]={...Me,id:ot},he(kt,G.map(Fe=>Fe===Re?Md(ot):Fe))}})]})]}),e.jsxs("label",{children:["Label",e.jsx("input",{value:Me.label,maxLength:30,placeholder:"Carteirinha de saúde",onChange:qe=>{const Re=[...H];Re[et]={...Me,label:qe.target.value},he(Re)}})]}),e.jsxs("label",{children:["Descrição",e.jsx("input",{value:Me.description||"",maxLength:300,placeholder:"Envie uma imagem legível do documento.",onChange:qe=>{const Re=[...H];Re[et]={...Me,description:qe.target.value},he(Re)}})]})]}):gt(re)]})},re)})})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Flow ID Meta",e.jsx("input",{value:M.flowId||"",placeholder:"ID do Flow publicado",onChange:re=>ee({flowId:re.target.value})})]}),e.jsxs("label",{children:["CTA do Flow",e.jsx("input",{value:M.flowCta||"",maxLength:qt.buttonLabel,placeholder:"Agendar",onChange:re=>ee({flowCta:re.target.value})})]})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Token do Flow",e.jsx("input",{value:M.flowToken||"",placeholder:"{{context.conversationId}}",onChange:re=>ee({flowToken:re.target.value})})]}),e.jsxs("label",{children:["Tela inicial",e.jsxs("select",{value:M.flowScreen||"",onChange:re=>ee({flowScreen:re.target.value}),children:[e.jsx("option",{value:"",children:"Primeira etapa da ordem"}),G.map((re,we)=>{const Me=Kx(re,we);return e.jsxs("option",{value:Me,children:[Jx(re,H,se)," (",Me,")"]},`${re}-${Me}`)})]})]})]}),e.jsxs("div",{className:"inspector-grid-two",children:[e.jsxs("label",{children:["Header",e.jsx("input",{value:M.headerText||"",placeholder:"Agendamento",onChange:re=>ee({headerText:re.target.value})})]}),e.jsxs("label",{children:["Botao da lista",e.jsx("input",{value:M.buttonText||"",maxLength:qt.listButton,placeholder:"Ver opções",onChange:re=>ee({buttonText:re.target.value})})]})]}),e.jsxs("div",{className:"filter-empty",children:["Os campos de dados aceitam array JSON, string JSON ou variável ","{{context.slots...}}",". Cada item pode usar id, title/label/name e description."]})]})}function Vp({language:t,value:n,placeholder:r,rows:s,error:l,fill:p=!1,readOnly:m=!1,onChange:h}){const[f,x]=b.useState({top:0,left:0}),j=b.useRef(null),w=b.useMemo(()=>{const C=Math.max(String(n||"").split(`