house-lights 1.0.1 → 1.2.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 (118) hide show
  1. package/README.md +7 -3
  2. package/cli.mjs +3 -2
  3. package/package.json +4 -3
  4. package/skills/back-of-napkin/assets/player.html +1 -1
  5. package/skills/back-of-napkin/scripts/contract.mjs +1 -1
  6. package/skills/back-of-napkin/scripts/pptx.mjs +1 -1
  7. package/skills/cast-list/assets/VERSION +2 -0
  8. package/skills/cast-list/assets/lesson.html +182 -0
  9. package/skills/cast-list/assets/map.html +244 -0
  10. package/skills/cast-list/examples/LICENSE-microsoft-skills-for-copilot-studio +21 -0
  11. package/skills/cast-list/examples/NOTICE.md +27 -0
  12. package/skills/cast-list/examples/agents/bodega-cupons/actions/ConsultarCuponsAtivos.mcs.yml +34 -0
  13. package/skills/cast-list/examples/agents/bodega-cupons/actions/EnviarCupomEmail.mcs.yml +34 -0
  14. package/skills/cast-list/examples/agents/bodega-cupons/actions/PromocoesMCP.mcs.yml +20 -0
  15. package/skills/cast-list/examples/agents/bodega-cupons/agent.mcs.yml +27 -0
  16. package/skills/cast-list/examples/agents/bodega-cupons/connectionreferences.mcs.yml +17 -0
  17. package/skills/cast-list/examples/agents/bodega-cupons/knowledge/RegulamentoCupons.knowledge.mcs.yml +7 -0
  18. package/skills/cast-list/examples/agents/bodega-cupons/settings.mcs.yml +13 -0
  19. package/skills/cast-list/examples/agents/bodega-cupons/topics/ConsultarRegulamentoCupons.topic.mcs.yml +56 -0
  20. package/skills/cast-list/examples/agents/bodega-cupons/topics/Escalate.topic.mcs.yml +20 -0
  21. package/skills/cast-list/examples/agents/bodega-cupons/topics/Fallback.topic.mcs.yml +32 -0
  22. package/skills/cast-list/examples/agents/bodega-cupons/topics/Greeting.topic.mcs.yml +14 -0
  23. package/skills/cast-list/examples/agents/bodega-cupons/topics/OnError.topic.mcs.yml +48 -0
  24. package/skills/cast-list/examples/agents/bodega-cupons/topics/RecebimentoOrquestrador.topic.mcs.yml +16 -0
  25. package/skills/cast-list/examples/agents/bodega-cupons/variables/CategoriaSolicitacao.mcs.yml +10 -0
  26. package/skills/cast-list/examples/agents/bodega-devolucoes/actions/AbrirSolicitacaoDevolucao.mcs.yml +32 -0
  27. package/skills/cast-list/examples/agents/bodega-devolucoes/agent.mcs.yml +26 -0
  28. package/skills/cast-list/examples/agents/bodega-devolucoes/connectionreferences.mcs.yml +6 -0
  29. package/skills/cast-list/examples/agents/bodega-devolucoes/knowledge/PoliticaTrocasDevolucoes.knowledge.mcs.yml +7 -0
  30. package/skills/cast-list/examples/agents/bodega-devolucoes/settings.mcs.yml +13 -0
  31. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/ConsultarPoliticaDevolucoes.topic.mcs.yml +56 -0
  32. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/Escalate.topic.mcs.yml +20 -0
  33. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/Fallback.topic.mcs.yml +32 -0
  34. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/Greeting.topic.mcs.yml +14 -0
  35. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/OnError.topic.mcs.yml +48 -0
  36. package/skills/cast-list/examples/agents/bodega-devolucoes/topics/RecebimentoOrquestrador.topic.mcs.yml +16 -0
  37. package/skills/cast-list/examples/agents/bodega-devolucoes/variables/CategoriaSolicitacao.mcs.yml +10 -0
  38. package/skills/cast-list/examples/agents/bodega-frete/actions/EnviarOpcoesFrete.mcs.yml +34 -0
  39. package/skills/cast-list/examples/agents/bodega-frete/agent.mcs.yml +26 -0
  40. package/skills/cast-list/examples/agents/bodega-frete/connectionreferences.mcs.yml +6 -0
  41. package/skills/cast-list/examples/agents/bodega-frete/knowledge/TabelaFreteEntregas.knowledge.mcs.yml +7 -0
  42. package/skills/cast-list/examples/agents/bodega-frete/settings.mcs.yml +13 -0
  43. package/skills/cast-list/examples/agents/bodega-frete/topics/ConsultarTabelaFrete.topic.mcs.yml +56 -0
  44. package/skills/cast-list/examples/agents/bodega-frete/topics/Fallback.topic.mcs.yml +31 -0
  45. package/skills/cast-list/examples/agents/bodega-frete/topics/Greeting.topic.mcs.yml +14 -0
  46. package/skills/cast-list/examples/agents/bodega-frete/topics/OnError.topic.mcs.yml +48 -0
  47. package/skills/cast-list/examples/agents/bodega-frete/topics/RecebimentoOrquestrador.topic.mcs.yml +16 -0
  48. package/skills/cast-list/examples/agents/bodega-frete/variables/CategoriaSolicitacao.mcs.yml +10 -0
  49. package/skills/cast-list/examples/agents/bodega-loja-fisica/actions/EnviarInstrucoesRetirada.mcs.yml +34 -0
  50. package/skills/cast-list/examples/agents/bodega-loja-fisica/agent.mcs.yml +27 -0
  51. package/skills/cast-list/examples/agents/bodega-loja-fisica/connectionreferences.mcs.yml +6 -0
  52. package/skills/cast-list/examples/agents/bodega-loja-fisica/knowledge/GuiaLojaFisica.knowledge.mcs.yml +8 -0
  53. package/skills/cast-list/examples/agents/bodega-loja-fisica/settings.mcs.yml +13 -0
  54. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/ConsultarGuiaLojaFisica.topic.mcs.yml +56 -0
  55. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/Escalate.topic.mcs.yml +20 -0
  56. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/Fallback.topic.mcs.yml +32 -0
  57. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/Greeting.topic.mcs.yml +14 -0
  58. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/OnError.topic.mcs.yml +43 -0
  59. package/skills/cast-list/examples/agents/bodega-loja-fisica/topics/RecebimentoOrquestrador.topic.mcs.yml +16 -0
  60. package/skills/cast-list/examples/agents/bodega-loja-fisica/variables/CategoriaSolicitacao.mcs.yml +10 -0
  61. package/skills/cast-list/examples/agents/bodega-orquestrador/actions/AgenteCupons.mcs.yml +24 -0
  62. package/skills/cast-list/examples/agents/bodega-orquestrador/actions/AgenteDevolucoes.mcs.yml +24 -0
  63. package/skills/cast-list/examples/agents/bodega-orquestrador/actions/AgenteFrete.mcs.yml +24 -0
  64. package/skills/cast-list/examples/agents/bodega-orquestrador/actions/AgenteLojaFisica.mcs.yml +24 -0
  65. package/skills/cast-list/examples/agents/bodega-orquestrador/actions/AgentePedidos.mcs.yml +24 -0
  66. package/skills/cast-list/examples/agents/bodega-orquestrador/agent.mcs.yml +35 -0
  67. package/skills/cast-list/examples/agents/bodega-orquestrador/agents/SobreBodegaAzul/agent.mcs.yml +32 -0
  68. package/skills/cast-list/examples/agents/bodega-orquestrador/settings.mcs.yml +12 -0
  69. package/skills/cast-list/examples/agents/bodega-orquestrador/topics/ClassificarSolicitacao.topic.mcs.yml +35 -0
  70. package/skills/cast-list/examples/agents/bodega-orquestrador/topics/Escalate.topic.mcs.yml +20 -0
  71. package/skills/cast-list/examples/agents/bodega-orquestrador/topics/Fallback.topic.mcs.yml +32 -0
  72. package/skills/cast-list/examples/agents/bodega-orquestrador/topics/Greeting.topic.mcs.yml +14 -0
  73. package/skills/cast-list/examples/agents/bodega-orquestrador/topics/OnError.topic.mcs.yml +48 -0
  74. package/skills/cast-list/examples/agents/bodega-orquestrador/variables/CategoriaSolicitacao.mcs.yml +9 -0
  75. package/skills/cast-list/examples/agents/bodega-pedidos/actions/EnviarResumoPedido.mcs.yml +34 -0
  76. package/skills/cast-list/examples/agents/bodega-pedidos/agent.mcs.yml +26 -0
  77. package/skills/cast-list/examples/agents/bodega-pedidos/connectionreferences.mcs.yml +6 -0
  78. package/skills/cast-list/examples/agents/bodega-pedidos/knowledge/PoliticasPedidos.knowledge.mcs.yml +7 -0
  79. package/skills/cast-list/examples/agents/bodega-pedidos/settings.mcs.yml +13 -0
  80. package/skills/cast-list/examples/agents/bodega-pedidos/topics/ConsultarPoliticasPedidos.topic.mcs.yml +56 -0
  81. package/skills/cast-list/examples/agents/bodega-pedidos/topics/Escalate.topic.mcs.yml +20 -0
  82. package/skills/cast-list/examples/agents/bodega-pedidos/topics/Fallback.topic.mcs.yml +32 -0
  83. package/skills/cast-list/examples/agents/bodega-pedidos/topics/Greeting.topic.mcs.yml +14 -0
  84. package/skills/cast-list/examples/agents/bodega-pedidos/topics/OnError.topic.mcs.yml +48 -0
  85. package/skills/cast-list/examples/agents/bodega-pedidos/topics/RecebimentoOrquestrador.topic.mcs.yml +16 -0
  86. package/skills/cast-list/examples/agents/bodega-pedidos/variables/CategoriaSolicitacao.mcs.yml +10 -0
  87. package/skills/cast-list/examples/demo.cast.yaml +10 -0
  88. package/skills/cast-list/examples/profile.cast.yaml +15 -0
  89. package/skills/cast-list/references/format.md +50 -0
  90. package/skills/cast-list/references/keys.md +107 -0
  91. package/skills/cast-list/references/profile.md +32 -0
  92. package/skills/cast-list/scripts/browser.mjs +198 -0
  93. package/skills/cast-list/scripts/build.mjs +179 -0
  94. package/skills/cast-list/scripts/engine.mjs +155 -0
  95. package/skills/cast-list/scripts/page.mjs +15 -0
  96. package/skills/cast-list/scripts/read-xlsx.mjs +67 -0
  97. package/skills/cast-list/vendor/microsoft/LICENSE +21 -0
  98. package/skills/cast-list/vendor/microsoft/NOTICE +9 -0
  99. package/skills/cast-list/vendor/microsoft/package.json +1 -0
  100. package/skills/cast-list/vendor/microsoft/reference/bot.schema.yaml-authoring.json +27605 -0
  101. package/skills/cast-list/vendor/microsoft/scripts/schema-lookup.bundle.js +3495 -0
  102. package/skills/chalk-talk/assets/VERSION +1 -1
  103. package/skills/chalk-talk/assets/player.html +1 -1
  104. package/skills/chalk-talk/scripts/contract.mjs +1 -1
  105. package/skills/chalk-talk/scripts/mermaid.mjs +1 -1
  106. package/skills/chalk-talk/scripts/pptx.mjs +1 -1
  107. package/skills/dress-rehearsal/assets/drill.html +1 -1
  108. package/skills/gates-and-handoffs/assets/VERSION +1 -1
  109. package/skills/gates-and-handoffs/assets/lesson.html +1 -1
  110. package/skills/gates-and-handoffs/assets/map.html +36 -24
  111. package/skills/gates-and-handoffs/examples/feature-delivery.way.yaml +8 -1
  112. package/skills/gates-and-handoffs/references/format.schema.json +25 -1
  113. package/skills/gates-and-handoffs/references/questions.md +2 -1
  114. package/skills/gates-and-handoffs/scripts/engine.mjs +83 -83
  115. package/skills/service-blueprint/assets/VERSION +1 -1
  116. package/skills/service-blueprint/assets/lesson.html +1 -1
  117. package/skills/service-blueprint/assets/map.html +1 -1
  118. package/skills/service-blueprint/scripts/engine.mjs +1 -1
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="generator" content="gates-and-handoffs (engine v0.258.0)">
6
+ <meta name="generator" content="gates-and-handoffs (engine v0.259.0)">
7
7
  <title>gates-and-handoffs</title>
8
8
  <style>/* The map of a way of working: tokens on .sd (not :root) so the PNG, drawn apart, carries them too. */
9
9
  .sd {
@@ -59,6 +59,12 @@ body { margin: 0; }
59
59
  .sd-gate i { flex: none; width: 12px; height: 12px; transform: rotate(45deg); border: 2px solid var(--gate); background: var(--gate-bg); }
60
60
  .sd-gate.flag i { border-style: dashed; }
61
61
  .sd-gate em { font-style: normal; color: var(--muted); }
62
+ .sd-gate .sd-also { display: block; color: var(--muted); font-size: 11px; }
63
+ .sd-gate .sd-where, .sd-approval .sd-where { color: var(--look); }
64
+ .sd-approval { display: flex; gap: 6px; align-items: baseline; padding: 3px 0; border-top: 1px solid var(--line); }
65
+ .sd-approval:first-child { border-top: 0; }
66
+ .sd-approval .sd-where, .sd-approval .sd-muted { margin-left: auto; font-size: 12px; }
67
+ .sd-muted { color: var(--muted); }
62
68
  .sd-picked { outline: 2.5px solid var(--focus); outline-offset: 2px; }
63
69
  .sd-linked { box-shadow: 0 0 0 3px var(--link-bg); }
64
70
  .sd-chip { display: inline-block; margin: 1px 4px 1px 0; padding: 1px 8px; border-radius: 999px; background: var(--link-bg); color: var(--link); font-size: 12px; line-height: 1.6; }
@@ -100,38 +106,38 @@ body { margin: 0; }
100
106
  <body>
101
107
  <div class="sd" id="app"></div>
102
108
  <script type="application/json" id="way">{{WAY}}</script>
103
- <script>"use strict";(()=>{var te=/\b(medir|medi[çc][ãa]o|medida|resultado|meta|measur\w*|outcome|kpi)\b/i;function D(e){let t=e.gates??[],a=new Map;e.stages.forEach((r,f)=>a.set(r.id,2*f));for(let r of t)a.set(r.id,(a.get(r.after)??0)+1);let s=[...e.stages.flatMap(r=>(r.outputs??[]).map(f=>({at:a.get(r.id),by:r.id,kind:"stage",output:f}))),...t.flatMap(r=>(r.outputs??[]).map(f=>({at:a.get(r.id),by:r.id,kind:"gate",output:f})))].sort((r,f)=>r.at-f.at),i={},d={},m=(r,f)=>{(d[r]??(d[r]=[])).includes(f)||d[r].push(f)};for(let r of e.stages){let f=a.get(r.id);i[r.id]=(r.inputs??[]).map(o=>{if((r.outside??[]).includes(o))return{name:o,kind:"outside"};let l=s.filter($=>$.output.name.trim().toLowerCase()===o.trim().toLowerCase()),g=l.filter($=>$.at<f).at(-1),c=g??l[0];return c?(m(c.output.id,r.id),{name:o,kind:c.kind,from:c.by,output:c.output.id,...g?{}:{late:!0}}):{name:o,kind:"nowhere"}})}for(let r of t)for(let f of r.criteria??[])if(f.kind==="outputs")for(let o of f.outputs)m(o,r.id);for(let r of Object.keys(d))d[r].sort((f,o)=>(a.get(f)??0)-(a.get(o)??0));return{uses:e.stages.some(r=>(r.inputs??[]).length),inputs:i,receivers:d}}var se=/^(dev|desenvolvimento|qa|hml|homolog(a[çc][ãa]o)?|staging|stage|uat|prd|prod|produ[çc][ãa]o|production|sandbox)$/i,$e=/(^|\s)(daily|dailies|planning|planejamento|refinement|refinamento|grooming|retro|retrospectiva|retrospective|sprint review|review da sprint|stand-?up)(\s|$)/i,we=/(^|\s)(owner|lead|leader|manager|master|analyst|engineer|developer|designer|tester|architect|director|head|coordinator|specialist|team|squad|gerente|l[ií]der|analista|engenheir[oa]|desenvolvedor[a]?|arquitet[oa]|diretor[a]?|coordenador[a]?|especialista|time|equipe|comit[êe]|qualidade|produto|neg[óo]cio|dono|respons[áa]vel)(\s|$)/i,be=/^[A-ZÀ-Ý][a-zà-ÿ]+(\s+(da|de|do|dos|das|e)?\s*[A-ZÀ-Ý][a-zà-ÿ]+){1,2}$/;function W(e){let t=[],a=e.stages,s=e.gates??[],i=e.roles??[],d=o=>a.find(l=>l.id===o)?.name??o;for(let o of a.slice(0,-1))(o.outputs??[]).length||o.optional||t.push({key:"outputs",at:{stage:o.id},en:`\xAB${o.name}\xBB delivers nothing: what comes out of it?`,pt:`\xAB${o.name}\xBB n\xE3o entrega nada: o que sai dela?`});a.length>1&&!s.length&&t.push({key:"noGate",en:"No gate: where does someone decide the work goes on?",pt:"Nenhum gate: onde algu\xE9m decide que o trabalho segue?"});let m=new Set(i.map(o=>o.acronym.toLowerCase()).concat(i.map(o=>o.id.toLowerCase()))),r=(o,l)=>!!l&&(l===o.id||l.toLowerCase()===o.acronym.toLowerCase());for(let o of s)o.approver?i.length&&!m.has(o.approver.toLowerCase())&&t.push({key:"unknownApprover",at:{gate:o.id},en:`The gate \xAB${o.name}\xBB is approved by \xAB${o.approver}\xBB, which is not one of the roles`,pt:`O gate \xAB${o.name}\xBB \xE9 aprovado por \xAB${o.approver}\xBB, que n\xE3o \xE9 um dos pap\xE9is`}):t.push({key:"approver",at:{gate:o.id},en:`Nobody approves the gate \xAB${o.name}\xBB`,pt:`Ningu\xE9m aprova o gate \xAB${o.name}\xBB`}),(o.criteria??[]).length||t.push({key:"criteria",at:{gate:o.id},en:`The gate \xAB${o.name}\xBB (after \xAB${d(o.after)}\xBB) says nothing about what must be ready`,pt:`O gate \xAB${o.name}\xBB (depois de \xAB${d(o.after)}\xBB) n\xE3o diz o que precisa estar pronto`});for(let o of e.phases){if(se.test(o.name.trim())||se.test(o.id)){t.push({key:"environment",at:{phase:o.id},en:`The phase \xAB${o.name}\xBB is an environment: it is where stages happen (their \xABwhere\xBB), not a milestone`,pt:`A fase \xAB${o.name}\xBB \xE9 um ambiente: \xE9 onde as etapas acontecem (\xABonde\xBB), n\xE3o um marco`});continue}let l=a.filter(g=>g.phase===o.id);e.phases.length>1&&l.length&&!l.some(g=>(g.outputs??[]).length||s.some(c=>c.after===g.id))&&t.push({key:"phase",at:{phase:o.id},en:`The phase \xAB${o.name}\xBB has no deliverable and no gate closes it`,pt:`A fase \xAB${o.name}\xBB n\xE3o tem entrega e nenhum gate a fecha`})}a.length>=3&&!a.some(o=>te.test(o.name)||(o.outputs??[]).some(l=>l.kpi))&&t.push({key:"measure",en:"No stage measures the result: what number shows it worked, and where is it measured?",pt:"Nenhuma etapa mede o resultado: que n\xFAmero mostra que deu certo, e onde se mede?"});for(let o of a)$e.test(o.name)&&t.push({key:"ritual",at:{stage:o.id},en:`\xAB${o.name}\xBB is a ritual (it has a cadence): it stays out of the flow`,pt:`\xAB${o.name}\xBB \xE9 um ritual (tem cad\xEAncia): fica fora do fluxo`});for(let o of e.lanes)a.length&&!a.some(l=>l.lane===o.id)&&t.push({key:"lane",at:{lane:o.id},en:`No stage is led by \xAB${o.name}\xBB`,pt:`Nenhuma etapa \xE9 liderada por \xAB${o.name}\xBB`});for(let o of i){let l=(o.name??"").trim();l&&be.test(l)&&!we.test(l)&&t.push({key:"person",at:{role:o.id},en:`\xAB${l}\xBB reads as a person: a role is a function (who does it is a lane's \xABsub\xBB)`,pt:`\xAB${l}\xBB parece uma pessoa: papel \xE9 uma fun\xE7\xE3o (quem faz fica no \xABsub\xBB da raia)`});let g=a.some(c=>(c.roles??[]).some($=>r(o,$)))||s.some(c=>r(o,c.approver));a.length&&!g&&t.push({key:"idleRole",at:{role:o.id},en:`The role \xAB${o.acronym}\xBB takes part in no stage and approves no gate`,pt:`O papel \xAB${o.acronym}\xBB n\xE3o participa de nenhuma etapa nem aprova gate`})}let f=D(e);if(f.uses){let o=l=>a.find(g=>g.id===l)?.name??s.find(g=>g.id===l)?.name??l??"";for(let l of a)for(let g of f.inputs[l.id]??[])g.kind==="nowhere"?t.push({key:"inputNowhere",at:{stage:l.id},en:`\xAB${l.name}\xBB receives \xAB${g.name}\xBB and nothing before it delivers that: does it come from outside?`,pt:`\xAB${l.name}\xBB recebe \xAB${g.name}\xBB e nada antes dela entrega isso: vem de fora?`}):g.late&&t.push({key:"lateInput",at:{stage:l.id},en:`\xAB${l.name}\xBB receives \xAB${g.name}\xBB, which only \xAB${o(g.from)}\xBB delivers, at or after it`,pt:`\xAB${l.name}\xBB recebe \xAB${g.name}\xBB, que s\xF3 \xAB${o(g.from)}\xBB entrega, nela ou depois dela`});for(let l of a.slice(0,-1))for(let g of l.outputs??[])!g.kpi&&!(f.receivers[g.id]??[]).length&&t.push({key:"unusedOutput",at:{stage:l.id,output:g.id},en:`\xAB${g.name}\xBB comes out of \xAB${l.name}\xBB and no stage or gate receives it: who is it for?`,pt:`\xAB${g.name}\xBB sai de \xAB${l.name}\xBB e nenhuma etapa nem gate o recebe: \xE9 para quem?`});for(let l of s)(l.outputs??[]).length||t.push({key:"gateNoOutputs",at:{gate:l.id},en:`The gate \xAB${l.name}\xBB says nothing about what comes out of it (the decision, what was approved)`,pt:`O gate \xAB${l.name}\xBB n\xE3o diz o que sai dele (a decis\xE3o, o que foi aprovado)`})}return t}var ye={prod:"DCE6FF",tech:"DDF3E6",qa:"FFE9D1",forge:"ECE0FF",slate:"E8EAED",coral:"FFE0DA"},ae=["prod","tech","qa","forge","slate","coral"],ke={en:{summary:"Summary",stages:"Stages",gates:"Gates",roles:"Roles (RACI)",outputs:"Outputs",kpis:"KPIs",checklist:"Gate checklist",way:"Way of working",phases:"Phases",nStages:"Stages",nGates:"Gates",nRoles:"Roles",look:"To look at",none:"Nothing to look at",raci:"R leads (the stage\u2019s lane) \xB7 C takes part \xB7 A approves the gate after it",id:"id",order:"#",phase:"Phase",stage:"Stage",lane:"Led by",roles2:"Take part",question:"Key question",inputs:"Comes in",delivers:"Delivers",activities:"Activities",where:"Where",wip:"Limit",gate:"Gate",after:"After",approver:"Approves",criteria:"Criteria",onFail:"If it fails",results:"Results",role:"Role",name:"Name",output:"Output",description:"Description",by:"By",kpi:"KPI",unit:"Unit",source:"Source",since:"Since",check:"What must be ready",ok:"OK?",note:"Note",who:"Who confirms",yes:"yes",outputsOf:e=>`Outputs: ${e}`,activitiesOf:e=>`Activities of \xAB${e}\xBB done`,subitems:(e,t)=>`At least ${e} sub-items \xAB${t}\xBB`,kpisOf:e=>`KPIs: ${e}`,metrics:"Metrics",gateOut:"What comes out",thread:"Thread",fromCol:"From",toCol:"To",outsideWord:"from outside",nobody:"nobody"},pt:{summary:"Resumo",stages:"Etapas",gates:"Gates",roles:"Pap\xE9is (RACI)",outputs:"Entregas",kpis:"KPIs",checklist:"Checklist de gate",way:"Jeito de trabalhar",phases:"Fases",nStages:"Etapas",nGates:"Gates",nRoles:"Pap\xE9is",look:"Para olhar",none:"Nada para olhar",raci:"R lidera (a raia da etapa) \xB7 C participa \xB7 A aprova o gate depois dela",id:"id",order:"#",phase:"Fase",stage:"Etapa",lane:"Lidera",roles2:"Participam",question:"Pergunta-chave",inputs:"Entra",delivers:"Entrega",activities:"Atividades",where:"Onde",wip:"Limite",gate:"Gate",after:"Depois de",approver:"Quem aprova",criteria:"Crit\xE9rios",onFail:"Se n\xE3o passar",results:"Resultados",role:"Papel",name:"Nome",output:"Entrega",description:"Descri\xE7\xE3o",by:"Por",kpi:"KPI",unit:"Unidade",source:"Fonte",since:"Desde",check:"O que precisa estar pronto",ok:"OK?",note:"Nota",who:"Quem confirma",yes:"sim",outputsOf:e=>`Entregas: ${e}`,activitiesOf:e=>`Atividades de \xAB${e}\xBB feitas`,subitems:(e,t)=>`Pelo menos ${e} subitens \xAB${t}\xBB`,kpisOf:e=>`KPIs: ${e}`,metrics:"M\xE9tricas",gateOut:"O que sai",thread:"Fio",fromCol:"De",toCol:"Para",outsideWord:"de fora",nobody:"ningu\xE9m"}};var ve={bold:!0,fill:"E8EEF7"},T=e=>e.map(t=>({v:t,...ve})),A=e=>(e??[]).filter(Boolean).join("; ");function ne(e,t,a="pt"){let s=ke[a],i=n=>{let p=t.lanes.findIndex(O=>O.id===n),y=t.lanes[p];return y?ye[y.color??ae[p%ae.length]]:void 0},d=n=>t.lanes.find(p=>p.id===n)?.name??n,m=n=>t.phases.find(p=>p.id===n)?.name??n,r=n=>n?t.stages.find(p=>p.id===n)?.name??n:"",f=n=>t.stages.flatMap(p=>p.outputs??[]).find(p=>p.id===n)?.name??n,o=n=>(t.kpis??[]).find(p=>p.id===n)?.name??n,l=n=>n?(t.roles??[]).find(p=>p.id===n)?.acronym??n:"",g=n=>n.kind==="outputs"?s.outputsOf(n.outputs.map(f).join(", ")):n.kind==="activities"?s.activitiesOf(r(n.stage)):n.kind==="subitems"?s.subitems(n.min,n.result):s.kpisOf(n.kpis.map(o).join(", ")),c=t.gates??[],$=t.roles??[],w=W(t),S=D(t),x=n=>t.stages.find(p=>p.id===n)?.name??c.find(p=>p.id===n)?.name??"",U=n=>(S.inputs[n]??[]).map(p=>p.kind==="outside"?`${p.name} (${s.outsideWord})`:p.from?`${p.name} (${x(p.from)})`:p.name),ge={key:"summary",name:s.summary,header:!1,columns:[{title:"",width:26},{title:"",width:90}],rows:[[{v:s.way,bold:!0},{v:e,bold:!0}],[s.phases,t.phases.map(n=>n.name).join(" \u2192 ")],[s.nStages,t.stages.length],[s.nGates,c.length],[s.nRoles,$.map(n=>n.acronym).join(", ")],[],[{v:s.look,bold:!0},w.length?"":s.none],...w.map(n=>["",{v:n[a],wrap:!0}])]},G={key:"stages",name:s.stages,header:!0,columns:[{title:s.order,width:5},{title:s.id,width:14},{title:s.phase,width:14},{title:s.stage,width:22},{title:s.lane,width:16},{title:s.roles2,width:16},{title:s.question,width:32},{title:s.inputs,width:30},{title:s.delivers,width:34},{title:s.metrics,width:30},{title:s.activities,width:30},{title:s.where,width:10},{title:s.wip,width:8},{title:s.description,width:40}],rows:[]};G.rows=[T(G.columns.map(n=>n.title)),...t.stages.map((n,p)=>[p+1,n.id,m(n.phase),{v:n.name,bold:!0},{v:d(n.lane),fill:i(n.lane)},(n.roles??[]).map(l).join(", "),{v:n.question??"",wrap:!0},{v:A(U(n.id)),wrap:!0},{v:A((n.outputs??[]).map(y=>y.name)),wrap:!0},{v:A(n.metrics),wrap:!0},{v:A((n.activities??[]).map(y=>y.name)),wrap:!0},n.where??"",n.wip??"",{v:n.description??"",wrap:!0}])];let z={key:"gates",name:s.gates,header:!0,columns:[{title:s.id,width:16},{title:s.gate,width:26},{title:s.after,width:20},{title:s.approver,width:12},{title:s.criteria,width:46},{title:s.onFail,width:20},{title:s.gateOut,width:34},{title:s.metrics,width:30},{title:s.results,width:20}],rows:[]};z.rows=[T(z.columns.map(n=>n.title)),...c.map(n=>[n.id,{v:n.name,bold:!0},r(n.after),l(n.approver),{v:(n.criteria??[]).map(g).join(`
104
- `),wrap:!0},r(n.on_fail),{v:A((n.outputs??[]).map(p=>p.name)),wrap:!0},{v:A(n.metrics),wrap:!0},n.results.map(p=>p.label).join(" / ")])];let fe=(n,p)=>{let y=[];return(p.roles??[]).includes(n.id)&&y.push(n.lane===p.lane?"R":"C"),c.some(O=>O.after===p.id&&O.approver===n.id)&&y.push("A"),y.join("/")},K={key:"roles",name:s.roles,header:!0,columns:[{title:s.role,width:10},{title:s.name,width:22},{title:s.lane,width:16},...t.stages.map(n=>({title:n.name,width:Math.max(9,Math.min(18,n.name.length+2))}))],rows:[]};K.rows=[T(K.columns.map(n=>n.title)),...$.map(n=>[{v:n.acronym,bold:!0},n.name??"",{v:d(n.lane),fill:i(n.lane)},...t.stages.map(p=>({v:fe(n,p),center:!0,bold:!0}))]),[],[{v:s.raci,color:"6B6B6B"}]];let X={key:"outputs",name:s.outputs,header:!0,columns:[{title:s.stage,width:20},{title:s.id,width:14},{title:s.output,width:32},{title:s.description,width:40},{title:s.by,width:10},{title:s.kpi,width:8}],rows:[]};X.rows=[T(X.columns.map(n=>n.title)),...t.stages.flatMap(n=>(n.outputs??[]).map(p=>[r(n.id),p.id,{v:p.name,bold:!0},{v:p.description??"",wrap:!0},l(p.by),p.kpi?s.yes:""]))];let H={key:"kpis",name:s.kpis,header:!0,columns:[{title:s.id,width:14},{title:s.name,width:30},{title:s.unit,width:12},{title:s.stage,width:20},{title:s.source,width:14},{title:s.since,width:20}],rows:[]};H.rows=[T(H.columns.map(n=>n.title)),...(t.kpis??[]).map(n=>[n.id,{v:n.name,bold:!0},n.unit,r(n.stage),n.source,r(n.since)])];let M={key:"checklist",name:s.checklist,header:!0,columns:[{title:s.gate,width:26},{title:s.check,width:48},{title:s.who,width:14},{title:s.ok,width:8},{title:s.note,width:36}],rows:[]};M.rows=[T(M.columns.map(n=>n.title))];for(let n of c){let p=(n.criteria??[]).flatMap(y=>y.kind==="outputs"?y.outputs.map(O=>f(O)):[g(y)]);M.rows.push(...(p.length?p:["\u2014"]).map((y,O)=>[O===0?{v:n.name,bold:!0}:"",`\u2610 ${y}`,l(n.approver),"",""]))}let J={key:"thread",name:s.thread,header:!0,columns:[{title:s.fromCol,width:26},{title:s.output,width:34},{title:s.toCol,width:40}],rows:[]},he=[...t.stages.flatMap(n=>[...(n.outputs??[]).map(p=>[n.id,p]),...c.filter(p=>p.after===n.id).flatMap(p=>(p.outputs??[]).map(y=>[p.id,y]))])];return J.rows=[T(J.columns.map(n=>n.title)),...he.map(([n,p])=>[x(n),{v:p.name,bold:!0},{v:A((S.receivers[p.id]??[]).map(x))||`(${s.nobody})`,wrap:!0}]),...t.stages.flatMap(n=>(S.inputs[n.id]??[]).filter(p=>p.kind==="outside"||p.kind==="nowhere").map(p=>[`(${p.kind==="outside"?s.outsideWord:s.nobody})`,{v:p.name,bold:!0},n.name]))],[ge,G,z,K,X,H,M,J]}var oe=new TextEncoder,Q=e=>e.replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t]).replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g,""),j=e=>e<26?String.fromCharCode(65+e):j(Math.floor(e/26)-1)+String.fromCharCode(65+e%26),xe=e=>e.replace(/[:\\/?*[\]]/g," ").slice(0,31)||"Sheet";function Se(e){let t=[{}],a=c=>JSON.stringify([c.bold??!1,c.fill??"",c.color??"",c.center??!1,c.wrap??!1]),s=new Map([[a({}),0]]);for(let c of e)for(let $ of c.rows)for(let w of $){if(typeof w!="object")continue;let{v:S,...x}=w,U=a(x);s.has(U)||(s.set(U,t.length),t.push(x))}let i=new Map([["|",0]]),d=new Map([["",0]]),m=c=>{let $=`${c.bold?"b":""}|${c.color??""}`;return i.has($)||i.set($,i.size),i.get($)},r=c=>c.fill?(d.has(c.fill)||d.set(c.fill,d.size+1),d.get(c.fill)):0,f=t.map(c=>{let $=c.center||c.wrap?`<alignment${c.center?' horizontal="center"':""}${c.wrap?' wrapText="1"':""} vertical="top"/>`:'<alignment vertical="top"/>';return`<xf numFmtId="0" fontId="${m(c)}" fillId="${r(c)}" borderId="${c.fill||c.bold?1:0}" xfId="0" applyFont="1" applyFill="1" applyBorder="1" applyAlignment="1">${$}</xf>`}),o=[...i.keys()].map(c=>{let[$,w]=c.split("|");return`<font>${$?"<b/>":""}<sz val="11"/>${w?`<color rgb="FF${w}"/>`:""}<name val="Calibri"/><family val="2"/></font>`}),l=['<fill><patternFill patternType="none"/></fill>','<fill><patternFill patternType="gray125"/></fill>',...[...d.keys()].filter(Boolean).map(c=>`<fill><patternFill patternType="solid"><fgColor rgb="FF${c}"/><bgColor indexed="64"/></patternFill></fill>`)];return{xml:`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
109
+ <script>"use strict";(()=>{var v=e=>e.approvals?.length?e.approvals:e.approver?[{by:e.approver}]:[],ie=(e,t)=>{let n=v(e).find(s=>s.by===t);return n?n.when??null:void 0};var oe=/\b(medir|medi[çc][ãa]o|medida|resultado|meta|measur\w*|outcome|kpi)\b/i;function T(e){let t=e.gates??[],n=new Map;e.stages.forEach((l,f)=>n.set(l.id,2*f));for(let l of t)n.set(l.id,(n.get(l.after)??0)+1);let s=[...e.stages.flatMap(l=>(l.outputs??[]).map(f=>({at:n.get(l.id),by:l.id,kind:"stage",output:f}))),...t.flatMap(l=>(l.outputs??[]).map(f=>({at:n.get(l.id),by:l.id,kind:"gate",output:f})))].sort((l,f)=>l.at-f.at),o={},c={},m=(l,f)=>{(c[l]??(c[l]=[])).includes(f)||c[l].push(f)};for(let l of e.stages){let f=n.get(l.id);o[l.id]=(l.inputs??[]).map(i=>{if((l.outside??[]).includes(i))return{name:i,kind:"outside"};let r=s.filter(b=>b.output.name.trim().toLowerCase()===i.trim().toLowerCase()),u=r.filter(b=>b.at<f).at(-1),p=u??r[0];return p?(m(p.output.id,l.id),{name:i,kind:p.kind,from:p.by,output:p.output.id,...u?{}:{late:!0}}):{name:i,kind:"nowhere"}})}for(let l of t)for(let f of l.criteria??[])if(f.kind==="outputs")for(let i of f.outputs)m(i,l.id);for(let l of Object.keys(c))c[l].sort((f,i)=>(n.get(f)??0)-(n.get(i)??0));return{uses:e.stages.some(l=>(l.inputs??[]).length),inputs:o,receivers:c}}var re=/^(dev|desenvolvimento|qa|hml|homolog(a[çc][ãa]o)?|staging|stage|uat|prd|prod|produ[çc][ãa]o|production|sandbox)$/i,we=/(^|\s)(daily|dailies|planning|planejamento|refinement|refinamento|grooming|retro|retrospectiva|retrospective|sprint review|review da sprint|stand-?up)(\s|$)/i,ve=/(^|\s)(owner|lead|leader|manager|master|analyst|engineer|developer|designer|tester|architect|director|head|coordinator|specialist|team|squad|gerente|l[ií]der|analista|engenheir[oa]|desenvolvedor[a]?|arquitet[oa]|diretor[a]?|coordenador[a]?|especialista|time|equipe|comit[êe]|qualidade|produto|neg[óo]cio|dono|respons[áa]vel)(\s|$)/i,xe=/^[A-ZÀ-Ý][a-zà-ÿ]+(\s+(da|de|do|dos|das|e)?\s*[A-ZÀ-Ý][a-zà-ÿ]+){1,2}$/;function U(e){let t=[],n=e.stages,s=e.gates??[],o=e.roles??[],c=i=>n.find(r=>r.id===i)?.name??i;for(let i of n.slice(0,-1))(i.outputs??[]).length||i.optional||t.push({key:"outputs",at:{stage:i.id},en:`\xAB${i.name}\xBB delivers nothing: what comes out of it?`,pt:`\xAB${i.name}\xBB n\xE3o entrega nada: o que sai dela?`});n.length>1&&!s.length&&t.push({key:"noGate",en:"No gate: where does someone decide the work goes on?",pt:"Nenhum gate: onde algu\xE9m decide que o trabalho segue?"});let m=new Set(o.map(i=>i.acronym.toLowerCase()).concat(o.map(i=>i.id.toLowerCase()))),l=(i,r)=>!!r&&(r===i.id||r.toLowerCase()===i.acronym.toLowerCase());for(let i of s){let r=v(i).map(u=>u.by);if(!r.length)t.push({key:"approver",at:{gate:i.id},en:`Nobody approves the gate \xAB${i.name}\xBB`,pt:`Ningu\xE9m aprova o gate \xAB${i.name}\xBB`});else for(let u of r.filter(p=>o.length&&!m.has(p.toLowerCase())))t.push({key:"unknownApprover",at:{gate:i.id},en:`The gate \xAB${i.name}\xBB is approved by \xAB${u}\xBB, which is not one of the roles`,pt:`O gate \xAB${i.name}\xBB \xE9 aprovado por \xAB${u}\xBB, que n\xE3o \xE9 um dos pap\xE9is`});(i.criteria??[]).length||t.push({key:"criteria",at:{gate:i.id},en:`The gate \xAB${i.name}\xBB (after \xAB${c(i.after)}\xBB) says nothing about what must be ready`,pt:`O gate \xAB${i.name}\xBB (depois de \xAB${c(i.after)}\xBB) n\xE3o diz o que precisa estar pronto`})}for(let i of e.phases){if(re.test(i.name.trim())||re.test(i.id)){t.push({key:"environment",at:{phase:i.id},en:`The phase \xAB${i.name}\xBB is an environment: it is where stages happen (their \xABwhere\xBB), not a milestone`,pt:`A fase \xAB${i.name}\xBB \xE9 um ambiente: \xE9 onde as etapas acontecem (\xABonde\xBB), n\xE3o um marco`});continue}let r=n.filter(u=>u.phase===i.id);e.phases.length>1&&r.length&&!r.some(u=>(u.outputs??[]).length||s.some(p=>p.after===u.id))&&t.push({key:"phase",at:{phase:i.id},en:`The phase \xAB${i.name}\xBB has no deliverable and no gate closes it`,pt:`A fase \xAB${i.name}\xBB n\xE3o tem entrega e nenhum gate a fecha`})}n.length>=3&&!n.some(i=>oe.test(i.name)||(i.outputs??[]).some(r=>r.kpi))&&t.push({key:"measure",en:"No stage measures the result: what number shows it worked, and where is it measured?",pt:"Nenhuma etapa mede o resultado: que n\xFAmero mostra que deu certo, e onde se mede?"});for(let i of n)we.test(i.name)&&t.push({key:"ritual",at:{stage:i.id},en:`\xAB${i.name}\xBB is a ritual (it has a cadence): it stays out of the flow`,pt:`\xAB${i.name}\xBB \xE9 um ritual (tem cad\xEAncia): fica fora do fluxo`});for(let i of e.lanes)n.length&&!n.some(r=>r.lane===i.id)&&t.push({key:"lane",at:{lane:i.id},en:`No stage is led by \xAB${i.name}\xBB`,pt:`Nenhuma etapa \xE9 liderada por \xAB${i.name}\xBB`});for(let i of o){let r=(i.name??"").trim();r&&xe.test(r)&&!ve.test(r)&&t.push({key:"person",at:{role:i.id},en:`\xAB${r}\xBB reads as a person: a role is a function (who does it is a lane's \xABsub\xBB)`,pt:`\xAB${r}\xBB parece uma pessoa: papel \xE9 uma fun\xE7\xE3o (quem faz fica no \xABsub\xBB da raia)`});let u=n.some(p=>(p.roles??[]).some(b=>l(i,b)))||s.some(p=>v(p).some(b=>l(i,b.by)));n.length&&!u&&t.push({key:"idleRole",at:{role:i.id},en:`The role \xAB${i.acronym}\xBB takes part in no stage and approves no gate`,pt:`O papel \xAB${i.acronym}\xBB n\xE3o participa de nenhuma etapa nem aprova gate`})}let f=T(e);if(f.uses){let i=r=>n.find(u=>u.id===r)?.name??s.find(u=>u.id===r)?.name??r??"";for(let r of n)for(let u of f.inputs[r.id]??[])u.kind==="nowhere"?t.push({key:"inputNowhere",at:{stage:r.id},en:`\xAB${r.name}\xBB receives \xAB${u.name}\xBB and nothing before it delivers that: does it come from outside?`,pt:`\xAB${r.name}\xBB recebe \xAB${u.name}\xBB e nada antes dela entrega isso: vem de fora?`}):u.late&&t.push({key:"lateInput",at:{stage:r.id},en:`\xAB${r.name}\xBB receives \xAB${u.name}\xBB, which only \xAB${i(u.from)}\xBB delivers, at or after it`,pt:`\xAB${r.name}\xBB recebe \xAB${u.name}\xBB, que s\xF3 \xAB${i(u.from)}\xBB entrega, nela ou depois dela`});for(let r of n.slice(0,-1))for(let u of r.outputs??[])!u.kpi&&!(f.receivers[u.id]??[]).length&&t.push({key:"unusedOutput",at:{stage:r.id,output:u.id},en:`\xAB${u.name}\xBB comes out of \xAB${r.name}\xBB and no stage or gate receives it: who is it for?`,pt:`\xAB${u.name}\xBB sai de \xAB${r.name}\xBB e nenhuma etapa nem gate o recebe: \xE9 para quem?`});for(let r of s)(r.outputs??[]).length||t.push({key:"gateNoOutputs",at:{gate:r.id},en:`The gate \xAB${r.name}\xBB says nothing about what comes out of it (the decision, what was approved)`,pt:`O gate \xAB${r.name}\xBB n\xE3o diz o que sai dele (a decis\xE3o, o que foi aprovado)`})}return t}var We={prod:"DCE6FF",tech:"DDF3E6",qa:"FFE9D1",forge:"ECE0FF",slate:"E8EAED",coral:"FFE0DA"},le=["prod","tech","qa","forge","slate","coral"],Oe={en:{summary:"Summary",stages:"Stages",gates:"Gates",roles:"Roles (RACI)",outputs:"Outputs",kpis:"KPIs",checklist:"Gate checklist",way:"Way of working",phases:"Phases",nStages:"Stages",nGates:"Gates",nRoles:"Roles",look:"To look at",none:"Nothing to look at",raci:"R leads (the stage\u2019s lane) \xB7 C takes part \xB7 A approves the gate after it",id:"id",order:"#",phase:"Phase",stage:"Stage",lane:"Led by",roles2:"Take part",question:"Key question",inputs:"Comes in",delivers:"Delivers",activities:"Activities",where:"Where",wip:"Limit",gate:"Gate",after:"After",approver:"Approves",when:"When",ifWord:"if",okOf:(e,t)=>`Ok from ${e}, if ${t} (n/a when not)`,criteria:"Criteria",onFail:"If it fails",results:"Results",role:"Role",name:"Name",output:"Output",description:"Description",by:"By",kpi:"KPI",unit:"Unit",source:"Source",since:"Since",check:"What must be ready",ok:"OK?",note:"Note",who:"Who confirms",yes:"yes",outputsOf:e=>`Outputs: ${e}`,activitiesOf:e=>`Activities of \xAB${e}\xBB done`,subitems:(e,t)=>`At least ${e} sub-items \xAB${t}\xBB`,kpisOf:e=>`KPIs: ${e}`,metrics:"Metrics",gateOut:"What comes out",thread:"Thread",fromCol:"From",toCol:"To",outsideWord:"from outside",nobody:"nobody"},pt:{summary:"Resumo",stages:"Etapas",gates:"Gates",roles:"Pap\xE9is (RACI)",outputs:"Entregas",kpis:"KPIs",checklist:"Checklist de gate",way:"Jeito de trabalhar",phases:"Fases",nStages:"Etapas",nGates:"Gates",nRoles:"Pap\xE9is",look:"Para olhar",none:"Nada para olhar",raci:"R lidera (a raia da etapa) \xB7 C participa \xB7 A aprova o gate depois dela",id:"id",order:"#",phase:"Fase",stage:"Etapa",lane:"Lidera",roles2:"Participam",question:"Pergunta-chave",inputs:"Entra",delivers:"Entrega",activities:"Atividades",where:"Onde",wip:"Limite",gate:"Gate",after:"Depois de",approver:"Quem aprova",when:"Quando",ifWord:"se",okOf:(e,t)=>`Ok de ${e}, se ${t} (n.a. quando n\xE3o for)`,criteria:"Crit\xE9rios",onFail:"Se n\xE3o passar",results:"Resultados",role:"Papel",name:"Nome",output:"Entrega",description:"Descri\xE7\xE3o",by:"Por",kpi:"KPI",unit:"Unidade",source:"Fonte",since:"Desde",check:"O que precisa estar pronto",ok:"OK?",note:"Nota",who:"Quem confirma",yes:"sim",outputsOf:e=>`Entregas: ${e}`,activitiesOf:e=>`Atividades de \xAB${e}\xBB feitas`,subitems:(e,t)=>`Pelo menos ${e} subitens \xAB${t}\xBB`,kpisOf:e=>`KPIs: ${e}`,metrics:"M\xE9tricas",gateOut:"O que sai",thread:"Fio",fromCol:"De",toCol:"Para",outsideWord:"de fora",nobody:"ningu\xE9m"}};var Se={bold:!0,fill:"E8EEF7"},R=e=>e.map(t=>({v:t,...Se})),M=e=>(e??[]).filter(Boolean).join("; ");function de(e,t,n="pt"){let s=Oe[n],o=a=>{let d=t.lanes.findIndex(k=>k.id===a),W=t.lanes[d];return W?We[W.color??le[d%le.length]]:void 0},c=a=>t.lanes.find(d=>d.id===a)?.name??a,m=a=>t.phases.find(d=>d.id===a)?.name??a,l=a=>a?t.stages.find(d=>d.id===a)?.name??a:"",f=a=>t.stages.flatMap(d=>d.outputs??[]).find(d=>d.id===a)?.name??a,i=a=>(t.kpis??[]).find(d=>d.id===a)?.name??a,r=a=>a?(t.roles??[]).find(d=>d.id===a)?.acronym??a:"",u=a=>a.kind==="outputs"?s.outputsOf(a.outputs.map(f).join(", ")):a.kind==="activities"?s.activitiesOf(l(a.stage)):a.kind==="subitems"?s.subitems(a.min,a.result):s.kpisOf(a.kpis.map(i).join(", ")),p=t.gates??[],b=t.roles??[],y=U(t),F=T(t),S=a=>t.stages.find(d=>d.id===a)?.name??p.find(d=>d.id===a)?.name??"",q=a=>(F.inputs[a]??[]).map(d=>d.kind==="outside"?`${d.name} (${s.outsideWord})`:d.from?`${d.name} (${S(d.from)})`:d.name),ye={key:"summary",name:s.summary,header:!1,columns:[{title:"",width:26},{title:"",width:90}],rows:[[{v:s.way,bold:!0},{v:e,bold:!0}],[s.phases,t.phases.map(a=>a.name).join(" \u2192 ")],[s.nStages,t.stages.length],[s.nGates,p.length],[s.nRoles,b.map(a=>a.acronym).join(", ")],[],[{v:s.look,bold:!0},y.length?"":s.none],...y.map(a=>["",{v:a[n],wrap:!0}])]},K={key:"stages",name:s.stages,header:!0,columns:[{title:s.order,width:5},{title:s.id,width:14},{title:s.phase,width:14},{title:s.stage,width:22},{title:s.lane,width:16},{title:s.roles2,width:16},{title:s.question,width:32},{title:s.inputs,width:30},{title:s.delivers,width:34},{title:s.metrics,width:30},{title:s.activities,width:30},{title:s.where,width:10},{title:s.wip,width:8},{title:s.description,width:40}],rows:[]};K.rows=[R(K.columns.map(a=>a.title)),...t.stages.map((a,d)=>[d+1,a.id,m(a.phase),{v:a.name,bold:!0},{v:c(a.lane),fill:o(a.lane)},(a.roles??[]).map(r).join(", "),{v:a.question??"",wrap:!0},{v:M(q(a.id)),wrap:!0},{v:M((a.outputs??[]).map(W=>W.name)),wrap:!0},{v:M(a.metrics),wrap:!0},{v:M((a.activities??[]).map(W=>W.name)),wrap:!0},a.where??"",a.wip??"",{v:a.description??"",wrap:!0}])];let ae=p.some(a=>v(a).some(d=>d.when)),X={key:"gates",name:s.gates,header:!0,columns:[{title:s.id,width:16},{title:s.gate,width:26},{title:s.after,width:20},{title:s.approver,width:12},...ae?[{title:s.when,width:28}]:[],{title:s.criteria,width:46},{title:s.onFail,width:20},{title:s.gateOut,width:34},{title:s.metrics,width:30},{title:s.results,width:20}],rows:[]};X.rows=[R(X.columns.map(a=>a.title)),...p.flatMap(a=>{let[d,...W]=v(a).length?v(a):[void 0],k=w=>ae?[w?.when??""]:[];return[[a.id,{v:a.name,bold:!0},l(a.after),r(d?.by),...k(d),{v:(a.criteria??[]).map(u).join(`
110
+ `),wrap:!0},l(a.on_fail),{v:M((a.outputs??[]).map(w=>w.name)),wrap:!0},{v:M(a.metrics),wrap:!0},a.results.map(w=>w.label).join(" / ")],...W.map(w=>[a.id,"","",r(w.by),...k(w),"","","","",""])]})];let $e=(a,d)=>{let W=[];(d.roles??[]).includes(a.id)&&W.push(a.lane===d.lane?"R":"C");for(let k of p.filter(w=>w.after===d.id)){let w=ie(k,a.id);w!==void 0&&W.push(w?`A (${s.ifWord} ${w})`:"A")}return W.join("/")},H={key:"roles",name:s.roles,header:!0,columns:[{title:s.role,width:10},{title:s.name,width:22},{title:s.lane,width:16},...t.stages.map(a=>({title:a.name,width:Math.max(9,Math.min(18,a.name.length+2))}))],rows:[]};H.rows=[R(H.columns.map(a=>a.title)),...b.map(a=>[{v:a.acronym,bold:!0},a.name??"",{v:c(a.lane),fill:o(a.lane)},...t.stages.map(d=>({v:$e(a,d),center:!0,bold:!0}))]),[],[{v:s.raci,color:"6B6B6B"}]];let Q={key:"outputs",name:s.outputs,header:!0,columns:[{title:s.stage,width:20},{title:s.id,width:14},{title:s.output,width:32},{title:s.description,width:40},{title:s.by,width:10},{title:s.kpi,width:8}],rows:[]};Q.rows=[R(Q.columns.map(a=>a.title)),...t.stages.flatMap(a=>(a.outputs??[]).map(d=>[l(a.id),d.id,{v:d.name,bold:!0},{v:d.description??"",wrap:!0},r(d.by),d.kpi?s.yes:""]))];let J={key:"kpis",name:s.kpis,header:!0,columns:[{title:s.id,width:14},{title:s.name,width:30},{title:s.unit,width:12},{title:s.stage,width:20},{title:s.source,width:14},{title:s.since,width:20}],rows:[]};J.rows=[R(J.columns.map(a=>a.title)),...(t.kpis??[]).map(a=>[a.id,{v:a.name,bold:!0},a.unit,l(a.stage),a.source,l(a.since)])];let L={key:"checklist",name:s.checklist,header:!0,columns:[{title:s.gate,width:26},{title:s.check,width:48},{title:s.who,width:14},{title:s.ok,width:8},{title:s.note,width:36}],rows:[]};L.rows=[R(L.columns.map(a=>a.title))];for(let a of p){let d=(a.criteria??[]).flatMap(k=>k.kind==="outputs"?k.outputs.map(w=>f(w)):[u(k)]),W=v(a).filter(k=>!k.when).map(k=>r(k.by)).join(", ");L.rows.push(...(d.length?d:["\u2014"]).map((k,w)=>[w===0?{v:a.name,bold:!0}:"",`\u2610 ${k}`,W,"",""]));for(let k of v(a).filter(w=>w.when))L.rows.push(["",`\u2610 ${s.okOf(r(k.by),k.when)}`,r(k.by),"",""])}let Y={key:"thread",name:s.thread,header:!0,columns:[{title:s.fromCol,width:26},{title:s.output,width:34},{title:s.toCol,width:40}],rows:[]},ke=[...t.stages.flatMap(a=>[...(a.outputs??[]).map(d=>[a.id,d]),...p.filter(d=>d.after===a.id).flatMap(d=>(d.outputs??[]).map(W=>[d.id,W]))])];return Y.rows=[R(Y.columns.map(a=>a.title)),...ke.map(([a,d])=>[S(a),{v:d.name,bold:!0},{v:M((F.receivers[d.id]??[]).map(S))||`(${s.nobody})`,wrap:!0}]),...t.stages.flatMap(a=>(F.inputs[a.id]??[]).filter(d=>d.kind==="outside"||d.kind==="nowhere").map(d=>[`(${d.kind==="outside"?s.outsideWord:s.nobody})`,{v:d.name,bold:!0},a.name]))],[ye,K,X,H,Q,J,L,Y]}var pe=new TextEncoder,Z=e=>e.replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t]).replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g,""),E=e=>e<26?String.fromCharCode(65+e):E(Math.floor(e/26)-1)+String.fromCharCode(65+e%26),De=e=>e.replace(/[:\\/?*[\]]/g," ").slice(0,31)||"Sheet";function Fe(e){let t=[{}],n=p=>JSON.stringify([p.bold??!1,p.fill??"",p.color??"",p.center??!1,p.wrap??!1]),s=new Map([[n({}),0]]);for(let p of e)for(let b of p.rows)for(let y of b){if(typeof y!="object")continue;let{v:F,...S}=y,q=n(S);s.has(q)||(s.set(q,t.length),t.push(S))}let o=new Map([["|",0]]),c=new Map([["",0]]),m=p=>{let b=`${p.bold?"b":""}|${p.color??""}`;return o.has(b)||o.set(b,o.size),o.get(b)},l=p=>p.fill?(c.has(p.fill)||c.set(p.fill,c.size+1),c.get(p.fill)):0,f=t.map(p=>{let b=p.center||p.wrap?`<alignment${p.center?' horizontal="center"':""}${p.wrap?' wrapText="1"':""} vertical="top"/>`:'<alignment vertical="top"/>';return`<xf numFmtId="0" fontId="${m(p)}" fillId="${l(p)}" borderId="${p.fill||p.bold?1:0}" xfId="0" applyFont="1" applyFill="1" applyBorder="1" applyAlignment="1">${b}</xf>`}),i=[...o.keys()].map(p=>{let[b,y]=p.split("|");return`<font>${b?"<b/>":""}<sz val="11"/>${y?`<color rgb="FF${y}"/>`:""}<name val="Calibri"/><family val="2"/></font>`}),r=['<fill><patternFill patternType="none"/></fill>','<fill><patternFill patternType="gray125"/></fill>',...[...c.keys()].filter(Boolean).map(p=>`<fill><patternFill patternType="solid"><fgColor rgb="FF${p}"/><bgColor indexed="64"/></patternFill></fill>`)];return{xml:`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
105
111
  <styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
106
- <fonts count="${o.length}">${o.join("")}</fonts>
107
- <fills count="${l.length}">${l.join("")}</fills>
112
+ <fonts count="${i.length}">${i.join("")}</fonts>
113
+ <fills count="${r.length}">${r.join("")}</fills>
108
114
  <borders count="2"><border><left/><right/><top/><bottom/><diagonal/></border><border><left style="thin"><color rgb="FFD0D7E2"/></left><right style="thin"><color rgb="FFD0D7E2"/></right><top style="thin"><color rgb="FFD0D7E2"/></top><bottom style="thin"><color rgb="FFD0D7E2"/></bottom><diagonal/></border></borders>
109
115
  <cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>
110
116
  <cellXfs count="${f.length}">${f.join("")}</cellXfs>
111
117
  <cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>
112
- </styleSheet>`,styleOf:c=>typeof c=="object"?s.get(a((({v:$,...w})=>w)(c)))??0:0}}function Oe(e,t){let a=Math.max(e.columns.length,...e.rows.map(f=>f.length),1),s=e.rows.map((f,o)=>{let l=f.map((g,c)=>{let $=`${j(c)}${o+1}`,w=typeof g=="object"?g.v:g,S=t(g),x=S?` s="${S}"`:"";return w===""||w===void 0||w===null?S?`<c r="${$}"${x}/>`:"":typeof w=="number"?`<c r="${$}"${x}><v>${w}</v></c>`:`<c r="${$}"${x} t="inlineStr"><is><t xml:space="preserve">${Q(String(w))}</t></is></c>`}).join("");return`<row r="${o+1}">${l}</row>`}),i=`${j(a-1)}${Math.max(1,e.rows.length)}`,d=e.header?'<pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/><selection pane="bottomLeft" activeCell="A2" sqref="A2"/>':"",m=e.columns.length?`<cols>${e.columns.map((f,o)=>`<col min="${o+1}" max="${o+1}" width="${f.width}" customWidth="1"/>`).join("")}</cols>`:"",r=e.header&&e.rows.length>1?`<autoFilter ref="A1:${j(Math.max(0,e.columns.length-1))}${e.rows.length}"/>`:"";return`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
118
+ </styleSheet>`,styleOf:p=>typeof p=="object"?s.get(n((({v:b,...y})=>y)(p)))??0:0}}function Ce(e,t){let n=Math.max(e.columns.length,...e.rows.map(f=>f.length),1),s=e.rows.map((f,i)=>{let r=f.map((u,p)=>{let b=`${E(p)}${i+1}`,y=typeof u=="object"?u.v:u,F=t(u),S=F?` s="${F}"`:"";return y===""||y===void 0||y===null?F?`<c r="${b}"${S}/>`:"":typeof y=="number"?`<c r="${b}"${S}><v>${y}</v></c>`:`<c r="${b}"${S} t="inlineStr"><is><t xml:space="preserve">${Z(String(y))}</t></is></c>`}).join("");return`<row r="${i+1}">${r}</row>`}),o=`${E(n-1)}${Math.max(1,e.rows.length)}`,c=e.header?'<pane ySplit="1" topLeftCell="A2" activePane="bottomLeft" state="frozen"/><selection pane="bottomLeft" activeCell="A2" sqref="A2"/>':"",m=e.columns.length?`<cols>${e.columns.map((f,i)=>`<col min="${i+1}" max="${i+1}" width="${f.width}" customWidth="1"/>`).join("")}</cols>`:"",l=e.header&&e.rows.length>1?`<autoFilter ref="A1:${E(Math.max(0,e.columns.length-1))}${e.rows.length}"/>`:"";return`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
113
119
  <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
114
- <dimension ref="A1:${i}"/><sheetViews><sheetView workbookViewId="0">${d}</sheetView></sheetViews><sheetFormatPr defaultRowHeight="15"/>${m}<sheetData>${s.join("")}</sheetData>${r}
115
- </worksheet>`}function ie(e){let{xml:t,styleOf:a}=Se(e),s=e.map(m=>xe(m.name)),i=e.map((m,r)=>m.header&&m.rows.length>1?`<definedName name="_xlnm._FilterDatabase" localSheetId="${r}" hidden="1">'${Q(s[r]).replace(/'/g,"''")}'!$A$1:$${j(Math.max(0,m.columns.length-1))}$${m.rows.length}</definedName>`:"").join(""),d=[["[Content_Types].xml",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
116
- <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>${e.map((m,r)=>`<Override PartName="/xl/worksheets/sheet${r+1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`).join("")}</Types>`],["_rels/.rels",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
120
+ <dimension ref="A1:${o}"/><sheetViews><sheetView workbookViewId="0">${c}</sheetView></sheetViews><sheetFormatPr defaultRowHeight="15"/>${m}<sheetData>${s.join("")}</sheetData>${l}
121
+ </worksheet>`}function ce(e){let{xml:t,styleOf:n}=Fe(e),s=e.map(m=>De(m.name)),o=e.map((m,l)=>m.header&&m.rows.length>1?`<definedName name="_xlnm._FilterDatabase" localSheetId="${l}" hidden="1">'${Z(s[l]).replace(/'/g,"''")}'!$A$1:$${E(Math.max(0,m.columns.length-1))}$${m.rows.length}</definedName>`:"").join(""),c=[["[Content_Types].xml",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
122
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>${e.map((m,l)=>`<Override PartName="/xl/worksheets/sheet${l+1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`).join("")}</Types>`],["_rels/.rels",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
117
123
  <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>`],["xl/workbook.xml",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
118
- <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><bookViews><workbookView/></bookViews><sheets>${s.map((m,r)=>`<sheet name="${Q(m)}" sheetId="${r+1}" r:id="rId${r+1}"/>`).join("")}</sheets>${i?`<definedNames>${i}</definedNames>`:""}</workbook>`],["xl/_rels/workbook.xml.rels",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
119
- <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${e.map((m,r)=>`<Relationship Id="rId${r+1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet${r+1}.xml"/>`).join("")}<Relationship Id="rId${e.length+1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>`],["xl/styles.xml",t],...e.map((m,r)=>[`xl/worksheets/sheet${r+1}.xml`,Oe(m,a)])];return Te(d.map(([m,r])=>[m,oe.encode(r)]))}var Ce=(()=>{let e=new Uint32Array(256);for(let t=0;t<256;t++){let a=t;for(let s=0;s<8;s++)a=a&1?3988292384^a>>>1:a>>>1;e[t]=a>>>0}return e})();function Ee(e){let t=4294967295;for(let a=0;a<e.length;a++)t=Ce[(t^e[a])&255]^t>>>8;return(t^4294967295)>>>0}function Te(e){let t=[],a=[],s=0;for(let[o,l]of e){let g=oe.encode(o),c=Ee(l),$=new DataView(new ArrayBuffer(30));$.setUint32(0,67324752,!0),$.setUint16(4,20,!0),$.setUint16(6,2048,!0),$.setUint16(8,0,!0),$.setUint32(14,c,!0),$.setUint32(18,l.length,!0),$.setUint32(22,l.length,!0),$.setUint16(26,g.length,!0),t.push(new Uint8Array($.buffer),g,l);let w=new DataView(new ArrayBuffer(46));w.setUint32(0,33639248,!0),w.setUint16(4,20,!0),w.setUint16(6,20,!0),w.setUint16(8,2048,!0),w.setUint32(16,c,!0),w.setUint32(20,l.length,!0),w.setUint32(24,l.length,!0),w.setUint16(28,g.length,!0),w.setUint32(42,s,!0),a.push(new Uint8Array(w.buffer),g),s+=30+g.length+l.length}let i=a.reduce((o,l)=>o+l.length,0),d=new DataView(new ArrayBuffer(22));d.setUint32(0,101010256,!0),d.setUint16(8,e.length,!0),d.setUint16(10,e.length,!0),d.setUint32(12,i,!0),d.setUint32(16,s,!0);let m=[...t,...a,new Uint8Array(d.buffer)],r=new Uint8Array(m.reduce((o,l)=>o+l.length,0)),f=0;for(let o of m)r.set(o,f),f+=o.length;return r}var Ae={en:{map:"Map",excel:"Excel",yaml:"YAML",png:"PNG",look:"To look at",stage:"Stage",gate:"Gate",optional:"optional",leads:"Led by",takePart:"Take part",comesIn:"Comes in",delivers:"Delivers",activities:"Activities",where:"Where",limit:"Limit",then:"Then",approves:"Approves",nobody:"nobody yet",criteria:"Must be ready",onFail:"If not",back:"back to",after:"After",results:"Results",pick:"Pick a stage or a gate on the map to see it whole.",summary:(e,t,a)=>`${e} ${e===1?"stage":"stages"} \xB7 ${t} ${t===1?"gate":"gates"} \xB7 ${a} ${a===1?"role":"roles"}`,stages:"Stages",stage2:"Stage",description:"Description",roles:"Roles",metrics:"Metrics",outside:"from outside",comesOut:"What comes out",nobodyTakes:"nobody receives it"},pt:{map:"Mapa",excel:"Excel",yaml:"YAML",png:"PNG",look:"Para olhar",stage:"Etapa",gate:"Gate",optional:"opcional",leads:"Lidera",takePart:"Participam",comesIn:"Entra",delivers:"Entrega",activities:"Atividades",where:"Onde",limit:"Limite",then:"Depois",approves:"Aprova",nobody:"ningu\xE9m ainda",criteria:"Precisa estar pronto",onFail:"Se n\xE3o",back:"volta para",after:"Depois de",results:"Resultados",pick:"Escolha uma etapa ou um gate no mapa para ver inteiro.",summary:(e,t,a)=>`${e} ${e===1?"etapa":"etapas"} \xB7 ${t} ${t===1?"gate":"gates"} \xB7 ${a} ${a===1?"papel":"pap\xE9is"}`,stages:"Etapas",stage2:"Etapa",description:"Descri\xE7\xE3o",roles:"Pap\xE9is",metrics:"M\xE9tricas",outside:"de fora",comesOut:"O que sai",nobodyTakes:"ningu\xE9m recebe"}},Fe={prod:"#2F5BEA",tech:"#2E8F62",qa:"#C77700",forge:"#7B4FC9",slate:"#5E5A52",coral:"#C8442C"},re=["prod","tech","qa","forge","slate","coral"],R=JSON.parse(document.getElementById("way").textContent),{way:b,lang:_,name:Y}=R,h=Ae[_],F=b.gates??[],de=b.roles??[],q=W(b),Z=ne(Y,b,_),I=D(b);document.documentElement.lang=_==="pt"?"pt-BR":"en";document.title=Y;var u=e=>String(e??"").replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t]),De=e=>{let t=b.lanes.findIndex(a=>a.id===e);return b.lanes[t]?.color??re[Math.max(0,t)%re.length]},E=e=>e?de.find(t=>t.id===e)?.acronym??e:"",le=e=>e?b.stages.find(t=>t.id===e)?.name??e:"",Le=e=>b.lanes.find(t=>t.id===e)?.name??e,ee=e=>F.find(t=>t.after===e),ce=e=>b.stages.find(t=>t.id===e)?.name??F.find(t=>t.id===e)?.name??"",Re=e=>e.kind==="outside"?`<span class="sd-chip out">${h.outside} \xB7 ${u(e.name)}</span>`:e.from?`<span class="sd-chip${e.late?" miss":""}">\u2190 ${u(ce(e.from))} \xB7 ${u(e.name)}</span>`:`<span class="sd-chip miss">? ${u(e.name)}</span>`,me=e=>(I.inputs[e]??[]).map(Re).join(""),je=(e,t)=>{let a=I.receivers[e.id]??[],s=a.length?` <span class="sd-to">\u2192 ${u(a.map(ce).join(", "))}</span>`:I.uses&&!t&&!e.kpi?` <span class="sd-to miss">\u2192 ${h.nobodyTakes}</span>`:"";return`<li>${u(e.name)}${s}</li>`},V=(e,t=!1)=>e.length?`<ul class="sd-outs">${e.map(a=>je(a,t)).join("")}</ul>`:"",Ne=()=>{let e=v.stage??v.gate;if(!e)return new Set;let t=[...b.stages.find(i=>i.id===e)?.outputs??[],...F.find(i=>i.id===e)?.outputs??[]],a=(F.find(i=>i.id===e)?.criteria??[]).flatMap(i=>i.kind==="outputs"?i.outputs:[]),s=b.stages.filter(i=>(i.outputs??[]).some(d=>a.includes(d.id))).map(i=>i.id);return new Set([...(I.inputs[e]??[]).map(i=>i.from).filter(i=>!!i),...s,...t.flatMap(i=>I.receivers[i.id]??[])])},pe=e=>q.some(t=>t.at&&Object.entries(e??{}).every(([a,s])=>t.at[a]===s)),Ie=e=>{let s=Z.find(i=>i.key==="gates").rows.find(i=>i[0]===e.id)?.[4];return String(typeof s=="object"?s.v:s??"").split(`
120
- `).filter(Boolean)},C="map",v={},L=document.getElementById("app");function ue(){let e=[["map",h.map],["stages",h.stages],["roles",P("roles").name],["gates",P("gates").name],["outputs",P("outputs").name]];L.innerHTML=`<div class="sd-wrap">
121
- <header><h1 class="sd-title">${u(Y)}</h1><p class="sd-sub">${u(b.phases.map(t=>t.name).join(" \u2192 "))} \xB7 ${h.summary(b.stages.length,F.length,de.length)}</p></header>
122
- <div class="sd-bar" role="tablist">${e.map(([t,a])=>`<button class="sd-tab" role="tab" aria-selected="${t===C}" data-tab="${t}">${u(a)}</button>`).join("")}
124
+ <workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><bookViews><workbookView/></bookViews><sheets>${s.map((m,l)=>`<sheet name="${Z(m)}" sheetId="${l+1}" r:id="rId${l+1}"/>`).join("")}</sheets>${o?`<definedNames>${o}</definedNames>`:""}</workbook>`],["xl/_rels/workbook.xml.rels",`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
125
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">${e.map((m,l)=>`<Relationship Id="rId${l+1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet${l+1}.xml"/>`).join("")}<Relationship Id="rId${e.length+1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>`],["xl/styles.xml",t],...e.map((m,l)=>[`xl/worksheets/sheet${l+1}.xml`,Ce(m,n)])];return Ae(c.map(([m,l])=>[m,pe.encode(l)]))}var Re=(()=>{let e=new Uint32Array(256);for(let t=0;t<256;t++){let n=t;for(let s=0;s<8;s++)n=n&1?3988292384^n>>>1:n>>>1;e[t]=n>>>0}return e})();function Me(e){let t=4294967295;for(let n=0;n<e.length;n++)t=Re[(t^e[n])&255]^t>>>8;return(t^4294967295)>>>0}function Ae(e){let t=[],n=[],s=0;for(let[i,r]of e){let u=pe.encode(i),p=Me(r),b=new DataView(new ArrayBuffer(30));b.setUint32(0,67324752,!0),b.setUint16(4,20,!0),b.setUint16(6,2048,!0),b.setUint16(8,0,!0),b.setUint32(14,p,!0),b.setUint32(18,r.length,!0),b.setUint32(22,r.length,!0),b.setUint16(26,u.length,!0),t.push(new Uint8Array(b.buffer),u,r);let y=new DataView(new ArrayBuffer(46));y.setUint32(0,33639248,!0),y.setUint16(4,20,!0),y.setUint16(6,20,!0),y.setUint16(8,2048,!0),y.setUint32(16,p,!0),y.setUint32(20,r.length,!0),y.setUint32(24,r.length,!0),y.setUint16(28,u.length,!0),y.setUint32(42,s,!0),n.push(new Uint8Array(y.buffer),u),s+=30+u.length+r.length}let o=n.reduce((i,r)=>i+r.length,0),c=new DataView(new ArrayBuffer(22));c.setUint32(0,101010256,!0),c.setUint16(8,e.length,!0),c.setUint16(10,e.length,!0),c.setUint32(12,o,!0),c.setUint32(16,s,!0);let m=[...t,...n,new Uint8Array(c.buffer)],l=new Uint8Array(m.reduce((i,r)=>i+r.length,0)),f=0;for(let i of m)l.set(i,f),f+=i.length;return l}var Te={en:{map:"Map",excel:"Excel",yaml:"YAML",png:"PNG",look:"To look at",stage:"Stage",gate:"Gate",optional:"optional",leads:"Led by",takePart:"Take part",comesIn:"Comes in",delivers:"Delivers",activities:"Activities",where:"Where",limit:"Limit",then:"Then",approves:"Approves",approvesAll:"Who approves (all)",always:"always",ifWord:"if",nobody:"nobody yet",criteria:"Must be ready",onFail:"If not",back:"back to",after:"After",results:"Results",pick:"Pick a stage or a gate on the map to see it whole.",summary:(e,t,n)=>`${e} ${e===1?"stage":"stages"} \xB7 ${t} ${t===1?"gate":"gates"} \xB7 ${n} ${n===1?"role":"roles"}`,stages:"Stages",stage2:"Stage",description:"Description",roles:"Roles",metrics:"Metrics",outside:"from outside",comesOut:"What comes out",nobodyTakes:"nobody receives it"},pt:{map:"Mapa",excel:"Excel",yaml:"YAML",png:"PNG",look:"Para olhar",stage:"Etapa",gate:"Gate",optional:"opcional",leads:"Lidera",takePart:"Participam",comesIn:"Entra",delivers:"Entrega",activities:"Atividades",where:"Onde",limit:"Limite",then:"Depois",approves:"Aprova",approvesAll:"Quem aprova (todos)",always:"sempre",ifWord:"se",nobody:"ningu\xE9m ainda",criteria:"Precisa estar pronto",onFail:"Se n\xE3o",back:"volta para",after:"Depois de",results:"Resultados",pick:"Escolha uma etapa ou um gate no mapa para ver inteiro.",summary:(e,t,n)=>`${e} ${e===1?"etapa":"etapas"} \xB7 ${t} ${t===1?"gate":"gates"} \xB7 ${n} ${n===1?"papel":"pap\xE9is"}`,stages:"Etapas",stage2:"Etapa",description:"Descri\xE7\xE3o",roles:"Pap\xE9is",metrics:"M\xE9tricas",outside:"de fora",comesOut:"O que sai",nobodyTakes:"ningu\xE9m recebe"}},Pe={prod:"#2F5BEA",tech:"#2E8F62",qa:"#C77700",forge:"#7B4FC9",slate:"#5E5A52",coral:"#C8442C"},ue=["prod","tech","qa","forge","slate","coral"],j=JSON.parse(document.getElementById("way").textContent),{way:$,lang:z,name:ee}=j,h=Te[z],A=$.gates??[],te=$.roles??[],_=U($),se=de(ee,$,z),I=T($);document.documentElement.lang=z==="pt"?"pt-BR":"en";document.title=ee;var g=e=>String(e??"").replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t]),je=e=>{let t=$.lanes.findIndex(n=>n.id===e);return $.lanes[t]?.color??ue[Math.max(0,t)%ue.length]},D=e=>e?te.find(t=>t.id===e)?.acronym??e:"",Le=e=>te.find(t=>t.id===e)?.name??"",ge=e=>e?$.stages.find(t=>t.id===e)?.name??e:"",Ee=e=>$.lanes.find(t=>t.id===e)?.name??e,ne=e=>A.find(t=>t.after===e),fe=e=>$.stages.find(t=>t.id===e)?.name??A.find(t=>t.id===e)?.name??"",Ne=e=>e.kind==="outside"?`<span class="sd-chip out">${h.outside} \xB7 ${g(e.name)}</span>`:e.from?`<span class="sd-chip${e.late?" miss":""}">\u2190 ${g(fe(e.from))} \xB7 ${g(e.name)}</span>`:`<span class="sd-chip miss">? ${g(e.name)}</span>`,he=e=>(I.inputs[e]??[]).map(Ne).join(""),Ie=(e,t)=>{let n=I.receivers[e.id]??[],s=n.length?` <span class="sd-to">\u2192 ${g(n.map(fe).join(", "))}</span>`:I.uses&&!t&&!e.kpi?` <span class="sd-to miss">\u2192 ${h.nobodyTakes}</span>`:"";return`<li>${g(e.name)}${s}</li>`},V=(e,t=!1)=>e.length?`<ul class="sd-outs">${e.map(n=>Ie(n,t)).join("")}</ul>`:"",qe=()=>{let e=O.stage??O.gate;if(!e)return new Set;let t=[...$.stages.find(o=>o.id===e)?.outputs??[],...A.find(o=>o.id===e)?.outputs??[]],n=(A.find(o=>o.id===e)?.criteria??[]).flatMap(o=>o.kind==="outputs"?o.outputs:[]),s=$.stages.filter(o=>(o.outputs??[]).some(c=>n.includes(c.id))).map(o=>o.id);return new Set([...(I.inputs[e]??[]).map(o=>o.from).filter(o=>!!o),...s,...t.flatMap(o=>I.receivers[o.id]??[])])},me=e=>_.some(t=>t.at&&Object.entries(e??{}).every(([n,s])=>t.at[n]===s)),Ue=e=>{let s=se.find(o=>o.key==="gates").rows.find(o=>o[0]===e.id)?.[4];return String(typeof s=="object"?s.v:s??"").split(`
126
+ `).filter(Boolean)},C="map",O={},P=document.getElementById("app");function be(){let e=[["map",h.map],["stages",h.stages],["roles",G("roles").name],["gates",G("gates").name],["outputs",G("outputs").name]];P.innerHTML=`<div class="sd-wrap">
127
+ <header><h1 class="sd-title">${g(ee)}</h1><p class="sd-sub">${g($.phases.map(t=>t.name).join(" \u2192 "))} \xB7 ${h.summary($.stages.length,A.length,te.length)}</p></header>
128
+ <div class="sd-bar" role="tablist">${e.map(([t,n])=>`<button class="sd-tab" role="tab" aria-selected="${t===C}" data-tab="${t}">${g(n)}</button>`).join("")}
123
129
  <span class="sd-space"></span>
124
130
  <button class="sd-get" data-get="xlsx">\u2B07 ${h.excel}</button><button class="sd-get" data-get="yaml">\u2B07 ${h.yaml}</button>${C==="map"?`<button class="sd-get" data-get="png">\u2B07 ${h.png}</button>`:""}
125
131
  </div>
126
- ${q.length?`<section class="sd-look"><h2>${h.look}</h2><ul>${q.map((t,a)=>`<li><button data-look="${a}">${u(t[_])}</button></li>`).join("")}</ul></section>`:""}
127
- ${C==="map"?`<div class="sd-body"><section class="sd-board">${Ue()}</section><aside class="sd-detail" aria-live="polite">${We()}</aside></div>`:C==="stages"?Pe():qe(P(C))}
128
- </div>`}var P=e=>Z.find(t=>t.key===e);function Ue(){let e=b.stages.length,t=[];for(let i of b.stages)t.at(-1)?.phase===i.phase?t.at(-1).span++:t.push({phase:i.phase,span:1});let a=Ne(),s=`<div class="sd-grid" style="grid-template-columns: 104px repeat(${e}, minmax(128px, 1fr)); min-width: ${104+e*136}px">`;s+="<div></div>"+t.map(i=>`<div class="sd-phase" style="grid-column: span ${i.span}">${u(b.phases.find(d=>d.id===i.phase)?.name??i.phase)}</div>`).join("");for(let i of b.lanes){let d=Fe[De(i.id)];s+=`<div class="sd-lane" style="color:${d}">${u(i.name)}${i.sub?`<small>${u(i.sub)}</small>`:""}</div>`;for(let m of b.stages)s+=`<div class="sd-cell">${m.lane===i.id?Me(m,d,a):""}</div>`}return s+"</div>"}function Me(e,t,a){let s=ee(e.id),d=`<button class="${["sd-stage",e.optional?"optional":"",pe({stage:e.id})?"flag":"",v.stage===e.id?"sd-picked":a.has(e.id)?"sd-linked":""].filter(Boolean).join(" ")}" style="--lane:${t}" data-stage="${u(e.id)}"><b>${u(e.name)}</b>${(e.roles??[]).length?`<span>${u((e.roles??[]).map(E).join(", "))}</span>`:""}${e.where?`<span class="sd-where">${h.where.toLowerCase()}: ${u(e.where)}</span>`:""}</button>`;if(!s)return d;let m=["sd-gate",pe({gate:s.id})?"flag":"",v.gate===s.id?"sd-picked":a.has(s.id)?"sd-linked":""].filter(Boolean).join(" ");return`${d}<button class="${m}" data-gate="${u(s.id)}"><i></i><span>${u(s.name)}${s.approver?` <em>\xB7 ${u(E(s.approver))}</em>`:""}</span></button>`}var N=e=>u(e.join(" \xB7 ")),k=(e,t)=>t?`<dt>${e}</dt><dd>${t}</dd>`:"";function We(){let e=v.stage?b.stages.find(a=>a.id===v.stage):void 0,t=v.gate?F.find(a=>a.id===v.gate):void 0;if(e){let a=ee(e.id),s=(e.roles??[]).map(E);return`<span class="sd-kicker">${h.stage}${e.optional?` \xB7 ${h.optional}`:""}</span><h3>${u(e.question??e.name)}</h3>${e.question?`<p>${u(e.name)}</p>`:""}
129
- ${e.description?`<p>${u(e.description)}</p>`:""}
130
- <dl>${k(h.leads,u(Le(e.lane)))}${k(h.takePart,N(s))}${k(h.comesIn,me(e.id))}${k(h.delivers,V(e.outputs??[],e===b.stages.at(-1)))}${k(h.metrics,N(e.metrics??[]))}
131
- ${k(h.activities,N((e.activities??[]).map(i=>i.name)))}${k(h.where,u(e.where??""))}${k(h.limit,e.wip?String(e.wip):"")}
132
- ${k(h.then,a?`<span class="sd-gate-name">\u25C6 ${u(a.name)}</span>${a.approver?` (${u(E(a.approver))})`:""}`:"")}</dl>`}return t?`<span class="sd-kicker">${h.gate}</span><h3 class="sd-gate-name">\u25C6 ${u(t.name)}</h3>${t.description?`<p>${u(t.description)}</p>`:""}
133
- <dl>${k(h.after,u(le(t.after)))}${k(h.approves,t.approver?u(E(t.approver)):`<em>${h.nobody}</em>`)}
134
- ${k(h.criteria,Ie(t).map(u).join("<br>"))}${k(h.comesOut,V(t.outputs??[],!0))}${k(h.onFail,t.on_fail?`${h.back} ${u(le(t.on_fail))}`:"")}${k(h.metrics,N(t.metrics??[]))}${k(h.results,N(t.results.map(a=>a.label)))}</dl>`:`<p>${h.pick}</p>`}function Pe(){let e=[h.stage2,h.description,h.comesIn,h.delivers,h.roles,h.metrics].map(s=>`<th>${s}</th>`).join(""),t=s=>s.length?`<ul class="sd-list">${s.map(i=>`<li>${u(i)}</li>`).join("")}</ul>`:"",a=b.stages.flatMap((s,i)=>{let d=ee(s.id),m=`<tr><td><button class="sd-link" data-stage="${u(s.id)}">${i+1} \xB7 ${u(s.name)}</button></td><td>${u(s.description??s.question??"")}</td><td>${me(s.id)}</td><td>${V(s.outputs??[],i===b.stages.length-1)}</td><td>${u((s.roles??[]).map(E).join(", "))}</td><td>${t(s.metrics??[])}</td></tr>`;if(!d)return[m];let r=(d.criteria??[]).flatMap(o=>o.kind==="outputs"?o.outputs:[]).map(o=>{let l=[...b.stages,...F].find(c=>(c.outputs??[]).some($=>$.id===o)),g=(l?.outputs??[]).find(c=>c.id===o)?.name??o;return`<span class="sd-chip">\u2190 ${u(l?.name??"")} \xB7 ${u(g)}</span>`}).join(""),f=[d.approver?`${E(d.approver)} (${h.approves.toLowerCase()})`:"",...(d.roles??[]).map(E)].filter(Boolean).join(", ");return[m,`<tr class="gate"><td><button class="sd-link" data-gate="${u(d.id)}">\u25C6 ${u(d.name)}</button></td><td>${u(d.description??"")}</td><td>${r}</td><td>${V(d.outputs??[],!0)}</td><td>${u(f)}</td><td>${t(d.metrics??[])}</td></tr>`]});return`<div class="sd-table sd-stages" role="tabpanel"><table><thead><tr>${e}</tr></thead><tbody>${a.join("")}</tbody></table></div>`}function qe(e){let t=(i,d)=>{let m=typeof i=="object"?i:{v:i},r=[m.center?"c":"",m.bold&&!d?"b":"",m.fill?"lane":""].filter(Boolean).join(" "),f=d?"th":"td";return`<${f}${r?` class="${r}"`:""}${m.fill&&!d?` style="background:#${m.fill}"`:""}>${u(m.v)}</${f}>`},[a,...s]=e.rows;return`<div class="sd-table" role="tabpanel"><table><thead><tr>${a.map(i=>t(i,!0)).join("")}</tr></thead><tbody>${s.map(i=>`<tr>${i.map(d=>t(d,!1)).join("")}</tr>`).join("")}</tbody></table></div>`}function B(e,t){let a=document.createElement("a");a.href=URL.createObjectURL(e),a.download=t,a.click(),setTimeout(()=>URL.revokeObjectURL(a.href),1e3)}async function Ve(){let e=L.querySelector(".sd-grid"),[t,a]=[e.scrollWidth+32,e.scrollHeight+32],s=new XMLSerializer().serializeToString(e).replace(/ sd-picked/g,""),i=`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${a}"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" class="sd light" style="min-height:0;padding:16px;background:#fff;width:${t}px"><style>/* The map of a way of working: tokens on .sd (not :root) so the PNG, drawn apart, carries them too. */
132
+ ${_.length?`<section class="sd-look"><h2>${h.look}</h2><ul>${_.map((t,n)=>`<li><button data-look="${n}">${g(t[z])}</button></li>`).join("")}</ul></section>`:""}
133
+ ${C==="map"?`<div class="sd-body"><section class="sd-board">${Ge()}</section><aside class="sd-detail" aria-live="polite">${Ve()}</aside></div>`:C==="stages"?Be():ze(G(C))}
134
+ </div>`}var G=e=>se.find(t=>t.key===e);function Ge(){let e=$.stages.length,t=[];for(let o of $.stages)t.at(-1)?.phase===o.phase?t.at(-1).span++:t.push({phase:o.phase,span:1});let n=qe(),s=`<div class="sd-grid" style="grid-template-columns: 104px repeat(${e}, minmax(128px, 1fr)); min-width: ${104+e*136}px">`;s+="<div></div>"+t.map(o=>`<div class="sd-phase" style="grid-column: span ${o.span}">${g($.phases.find(c=>c.id===o.phase)?.name??o.phase)}</div>`).join("");for(let o of $.lanes){let c=Pe[je(o.id)];s+=`<div class="sd-lane" style="color:${c}">${g(o.name)}${o.sub?`<small>${g(o.sub)}</small>`:""}</div>`;for(let m of $.stages)s+=`<div class="sd-cell">${m.lane===o.id?_e(m,c,n):""}</div>`}return s+"</div>"}function _e(e,t,n){let s=ne(e.id),c=`<button class="${["sd-stage",e.optional?"optional":"",me({stage:e.id})?"flag":"",O.stage===e.id?"sd-picked":n.has(e.id)?"sd-linked":""].filter(Boolean).join(" ")}" style="--lane:${t}" data-stage="${g(e.id)}"><b>${g(e.name)}</b>${(e.roles??[]).length?`<span>${g((e.roles??[]).map(D).join(", "))}</span>`:""}${e.where?`<span class="sd-where">${h.where.toLowerCase()}: ${g(e.where)}</span>`:""}</button>`;if(!s)return c;let m=["sd-gate",me({gate:s.id})?"flag":"",O.gate===s.id?"sd-picked":n.has(s.id)?"sd-linked":""].filter(Boolean).join(" "),l=v(s),f=l.filter(r=>!r.when).map(r=>D(r.by)),i=l.filter(r=>r.when).map(r=>`<small class="sd-also">+ ${g(D(r.by))} <span class="sd-where">${h.ifWord} ${g(r.when)}</span></small>`).join("");return`${c}<button class="${m}" data-gate="${g(s.id)}"><i></i><span>${g(s.name)}${f.length?` <em>\xB7 ${g(f.join(", "))}</em>`:""}${i}</span></button>`}var N=e=>g(e.join(" \xB7 ")),x=(e,t)=>t?`<dt>${e}</dt><dd>${t}</dd>`:"";function Ve(){let e=O.stage?$.stages.find(n=>n.id===O.stage):void 0,t=O.gate?A.find(n=>n.id===O.gate):void 0;if(e){let n=ne(e.id),s=(e.roles??[]).map(D);return`<span class="sd-kicker">${h.stage}${e.optional?` \xB7 ${h.optional}`:""}</span><h3>${g(e.question??e.name)}</h3>${e.question?`<p>${g(e.name)}</p>`:""}
135
+ ${e.description?`<p>${g(e.description)}</p>`:""}
136
+ <dl>${x(h.leads,g(Ee(e.lane)))}${x(h.takePart,N(s))}${x(h.comesIn,he(e.id))}${x(h.delivers,V(e.outputs??[],e===$.stages.at(-1)))}${x(h.metrics,N(e.metrics??[]))}
137
+ ${x(h.activities,N((e.activities??[]).map(o=>o.name)))}${x(h.where,g(e.where??""))}${x(h.limit,e.wip?String(e.wip):"")}
138
+ ${x(h.then,n?`<span class="sd-gate-name">\u25C6 ${g(n.name)}</span>${v(n).length?` (${g(v(n).map(o=>D(o.by)).join(", "))})`:""}`:"")}</dl>`}return t?`<span class="sd-kicker">${h.gate}</span><h3 class="sd-gate-name">\u25C6 ${g(t.name)}</h3>${t.description?`<p>${g(t.description)}</p>`:""}
139
+ <dl>${x(h.after,g(ge(t.after)))}${v(t).length?x(h.approvesAll,v(t).map(n=>`<span class="sd-approval"><b>${g(D(n.by))}</b> ${g(Le(n.by))} <span class="${n.when?"sd-where":"sd-muted"}">${n.when?`${h.ifWord} ${g(n.when)}`:h.always}</span></span>`).join("")):x(h.approves,`<em>${h.nobody}</em>`)}
140
+ ${x(h.criteria,Ue(t).map(g).join("<br>"))}${x(h.comesOut,V(t.outputs??[],!0))}${x(h.onFail,t.on_fail?`${h.back} ${g(ge(t.on_fail))}`:"")}${x(h.metrics,N(t.metrics??[]))}${x(h.results,N(t.results.map(n=>n.label)))}</dl>`:`<p>${h.pick}</p>`}function Be(){let e=[h.stage2,h.description,h.comesIn,h.delivers,h.roles,h.metrics].map(s=>`<th>${s}</th>`).join(""),t=s=>s.length?`<ul class="sd-list">${s.map(o=>`<li>${g(o)}</li>`).join("")}</ul>`:"",n=$.stages.flatMap((s,o)=>{let c=ne(s.id),m=`<tr><td><button class="sd-link" data-stage="${g(s.id)}">${o+1} \xB7 ${g(s.name)}</button></td><td>${g(s.description??s.question??"")}</td><td>${he(s.id)}</td><td>${V(s.outputs??[],o===$.stages.length-1)}</td><td>${g((s.roles??[]).map(D).join(", "))}</td><td>${t(s.metrics??[])}</td></tr>`;if(!c)return[m];let l=(c.criteria??[]).flatMap(i=>i.kind==="outputs"?i.outputs:[]).map(i=>{let r=[...$.stages,...A].find(p=>(p.outputs??[]).some(b=>b.id===i)),u=(r?.outputs??[]).find(p=>p.id===i)?.name??i;return`<span class="sd-chip">\u2190 ${g(r?.name??"")} \xB7 ${g(u)}</span>`}).join(""),f=[...v(c).map(i=>`${D(i.by)} (${h.approves.toLowerCase()}${i.when?`, ${h.ifWord} ${i.when}`:""})`),...(c.roles??[]).map(D)].join(", ");return[m,`<tr class="gate"><td><button class="sd-link" data-gate="${g(c.id)}">\u25C6 ${g(c.name)}</button></td><td>${g(c.description??"")}</td><td>${l}</td><td>${V(c.outputs??[],!0)}</td><td>${g(f)}</td><td>${t(c.metrics??[])}</td></tr>`]});return`<div class="sd-table sd-stages" role="tabpanel"><table><thead><tr>${e}</tr></thead><tbody>${n.join("")}</tbody></table></div>`}function ze(e){let t=(o,c)=>{let m=typeof o=="object"?o:{v:o},l=[m.center?"c":"",m.bold&&!c?"b":"",m.fill?"lane":""].filter(Boolean).join(" "),f=c?"th":"td";return`<${f}${l?` class="${l}"`:""}${m.fill&&!c?` style="background:#${m.fill}"`:""}>${g(m.v)}</${f}>`},[n,...s]=e.rows;return`<div class="sd-table" role="tabpanel"><table><thead><tr>${n.map(o=>t(o,!0)).join("")}</tr></thead><tbody>${s.map(o=>`<tr>${o.map(c=>t(c,!1)).join("")}</tr>`).join("")}</tbody></table></div>`}function B(e,t){let n=document.createElement("a");n.href=URL.createObjectURL(e),n.download=t,n.click(),setTimeout(()=>URL.revokeObjectURL(n.href),1e3)}async function Ke(){let e=P.querySelector(".sd-grid"),[t,n]=[e.scrollWidth+32,e.scrollHeight+32],s=new XMLSerializer().serializeToString(e).replace(/ sd-picked/g,""),o=`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${n}"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml" class="sd light" style="min-height:0;padding:16px;background:#fff;width:${t}px"><style>/* The map of a way of working: tokens on .sd (not :root) so the PNG, drawn apart, carries them too. */
135
141
  .sd {
136
142
  --bg: #f5f6f8; --card: #ffffff; --ink: #1d2330; --muted: #5f6878; --line: #dfe3ea; --soft: #eef1f5;
137
143
  --gate: #c8442c; --gate-bg: #fff0ec; --look: #8a5a00; --look-bg: #fff6e0; --active: #1d2330; --on-active: #ffffff;
@@ -185,6 +191,12 @@ body { margin: 0; }
185
191
  .sd-gate i { flex: none; width: 12px; height: 12px; transform: rotate(45deg); border: 2px solid var(--gate); background: var(--gate-bg); }
186
192
  .sd-gate.flag i { border-style: dashed; }
187
193
  .sd-gate em { font-style: normal; color: var(--muted); }
194
+ .sd-gate .sd-also { display: block; color: var(--muted); font-size: 11px; }
195
+ .sd-gate .sd-where, .sd-approval .sd-where { color: var(--look); }
196
+ .sd-approval { display: flex; gap: 6px; align-items: baseline; padding: 3px 0; border-top: 1px solid var(--line); }
197
+ .sd-approval:first-child { border-top: 0; }
198
+ .sd-approval .sd-where, .sd-approval .sd-muted { margin-left: auto; font-size: 12px; }
199
+ .sd-muted { color: var(--muted); }
188
200
  .sd-picked { outline: 2.5px solid var(--focus); outline-offset: 2px; }
189
201
  .sd-linked { box-shadow: 0 0 0 3px var(--link-bg); }
190
202
  .sd-chip { display: inline-block; margin: 1px 4px 1px 0; padding: 1px 8px; border-radius: 999px; background: var(--link-bg); color: var(--link); font-size: 12px; line-height: 1.6; }
@@ -221,7 +233,7 @@ body { margin: 0; }
221
233
  @media (max-width: 720px) {
222
234
  .sd { padding: 14px 16px 32px; }
223
235
  }
224
- </style>${s}</div></foreignObject></svg>`,d=new Blob([i],{type:"image/svg+xml"});try{let m=new Image;m.src=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(i)}`,await m.decode();let r=document.createElement("canvas");r.width=t*2,r.height=a*2;let f=r.getContext("2d");f.scale(2,2),f.drawImage(m,0,0);let o=await new Promise(l=>r.toBlob(l,"image/png"));if(!o)throw new Error("no PNG");B(o,`${R.id}.png`)}catch{B(d,`${R.id}.svg`)}}L.addEventListener("click",e=>{let t=e.target.closest("button");if(!t)return;let a=t.dataset;if(a.tab)C=a.tab;else if(a.stage||a.gate)v=a.stage?{stage:a.stage}:{gate:a.gate},C="map";else if(a.look){let i=q[Number(a.look)].at??{};C="map",v=i.stage?{stage:i.stage}:i.gate?{gate:i.gate}:v}else{if(a.get==="xlsx")return B(new Blob([ie(Z)],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}),`${R.id}.xlsx`);if(a.get==="yaml")return B(new Blob([R.yaml],{type:"text/yaml"}),`${R.id}.way.yaml`);if(a.get==="png")return void Ve()}let s=a.tab?`[data-tab="${a.tab}"]`:a.stage?`[data-stage="${a.stage}"]`:a.gate?`[data-gate="${a.gate}"]`:void 0;ue(),s&&L.querySelector(s)?.focus(),a.look&&L.querySelector(".sd-picked")?.scrollIntoView({block:"nearest",inline:"center"}),(a.stage||a.gate)&&L.querySelector(".sd-detail")?.scrollIntoView({block:"nearest"})});ue();})();
236
+ </style>${s}</div></foreignObject></svg>`,c=new Blob([o],{type:"image/svg+xml"});try{let m=new Image;m.src=`data:image/svg+xml;charset=utf-8,${encodeURIComponent(o)}`,await m.decode();let l=document.createElement("canvas");l.width=t*2,l.height=n*2;let f=l.getContext("2d");f.scale(2,2),f.drawImage(m,0,0);let i=await new Promise(r=>l.toBlob(r,"image/png"));if(!i)throw new Error("no PNG");B(i,`${j.id}.png`)}catch{B(c,`${j.id}.svg`)}}P.addEventListener("click",e=>{let t=e.target.closest("button");if(!t)return;let n=t.dataset;if(n.tab)C=n.tab;else if(n.stage||n.gate)O=n.stage?{stage:n.stage}:{gate:n.gate},C="map";else if(n.look){let o=_[Number(n.look)].at??{};C="map",O=o.stage?{stage:o.stage}:o.gate?{gate:o.gate}:O}else{if(n.get==="xlsx")return B(new Blob([ce(se)],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}),`${j.id}.xlsx`);if(n.get==="yaml")return B(new Blob([j.yaml],{type:"text/yaml"}),`${j.id}.way.yaml`);if(n.get==="png")return void Ke()}let s=n.tab?`[data-tab="${n.tab}"]`:n.stage?`[data-stage="${n.stage}"]`:n.gate?`[data-gate="${n.gate}"]`:void 0;be(),s&&P.querySelector(s)?.focus(),n.look&&P.querySelector(".sd-picked")?.scrollIntoView({block:"nearest",inline:"center"}),(n.stage||n.gate)&&P.querySelector(".sd-detail")?.scrollIntoView({block:"nearest"})});be();})();
225
237
  </script>
226
238
  </body>
227
239
  </html>
@@ -31,6 +31,10 @@ roles:
31
31
  acronym: QA
32
32
  name: Qualidade
33
33
  lane: qualidade
34
+ - id: seg
35
+ acronym: SEG
36
+ name: Segurança
37
+ lane: engenharia
34
38
  phases:
35
39
  - id: descoberta
36
40
  name: Descoberta
@@ -191,7 +195,10 @@ gates:
191
195
  - id: producao-gate
192
196
  after: testar
193
197
  name: Pronto para produção?
194
- approver: tl
198
+ approvals:
199
+ - by: tl
200
+ - by: seg
201
+ when: mudança em pagamento
195
202
  results:
196
203
  - id: sim
197
204
  label: Sim
@@ -297,7 +297,31 @@
297
297
  },
298
298
  "approver": {
299
299
  "$ref": "#/$defs/id",
300
- "description": "The role that approves it"
300
+ "description": "The role that approves it: the shorthand of approvals with one, no condition"
301
+ },
302
+ "approvals": {
303
+ "description": "Every approval the gate needs, all of them (with it, no approver): a role, and when it applies",
304
+ "type": "array",
305
+ "minItems": 1,
306
+ "maxItems": 6,
307
+ "items": {
308
+ "type": "object",
309
+ "required": [
310
+ "by"
311
+ ],
312
+ "additionalProperties": false,
313
+ "properties": {
314
+ "by": {
315
+ "$ref": "#/$defs/id",
316
+ "description": "The role that approves"
317
+ },
318
+ "when": {
319
+ "type": "string",
320
+ "maxLength": 80,
321
+ "description": "When it applies, as people say it (\"change to payments\"); none: always"
322
+ }
323
+ }
324
+ }
301
325
  },
302
326
  "results": {
303
327
  "type": "array",
@@ -9,7 +9,8 @@ what you already know:
9
9
  1. **Who leads** — the lanes (a role, a team, an area).
10
10
  2. **How it starts** — where an item comes from, the first stage.
11
11
  3. **The stages in order**, and who leads each.
12
- 4. **Where someone decides** — the gates, who approves each, what must be ready.
12
+ 4. **Where someone decides** — the gates, who approves each (and whether someone else also approves, in some
13
+ case: "also", "if it is", "when it involves"), what must be ready.
13
14
  5. **What each stage delivers.**
14
15
  6. **Where a failed gate goes back.**
15
16
  7. **The number** that says it worked (only when the flow delivers something measurable).