sagadeck 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 (233) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +305 -0
  3. package/SKILL.md +148 -0
  4. package/bin/sagadeck.js +511 -0
  5. package/docs/ANDAMENTO.md +1255 -0
  6. package/docs/EXPERIENCIAS.md +39 -0
  7. package/docs/PLANO-EXPERIENCIAS.md +39 -0
  8. package/docs/PLANO-TESTE-AULAS-TECNICAS.md +44 -0
  9. package/docs/PLANO-TESTE-DESINFORMACAO.md +38 -0
  10. package/docs/REFERENCIA.md +1131 -0
  11. package/package.json +59 -0
  12. package/src/adaptive-layouts.js +18 -0
  13. package/src/ai/art-direction.js +8 -0
  14. package/src/ai/commands.js +130 -0
  15. package/src/ai/context.js +245 -0
  16. package/src/ai/deck-ai.js +1135 -0
  17. package/src/ai/directions.js +74 -0
  18. package/src/ai/document-materials.js +49 -0
  19. package/src/ai/document-visuals.js +215 -0
  20. package/src/ai/evaluation.js +31 -0
  21. package/src/ai/ground.js +55 -0
  22. package/src/ai/llm.js +292 -0
  23. package/src/ai/quality.js +51 -0
  24. package/src/ai/relay.js +45 -0
  25. package/src/ai/staged-generation.js +24 -0
  26. package/src/ai/transform.js +858 -0
  27. package/src/ai/usage.js +17 -0
  28. package/src/ai/variety.js +80 -0
  29. package/src/ai/video-frames.js +24 -0
  30. package/src/ai/video-generation.js +126 -0
  31. package/src/ai/web-operation.js +31 -0
  32. package/src/algo-catalog.js +153 -0
  33. package/src/algo-trace.js +139 -0
  34. package/src/api-client.js +514 -0
  35. package/src/api-collections.js +14 -0
  36. package/src/api-demo.js +222 -0
  37. package/src/aspect.js +40 -0
  38. package/src/build.js +323 -0
  39. package/src/carousel.js +56 -0
  40. package/src/chrome.js +65 -0
  41. package/src/code-highlight.js +68 -0
  42. package/src/code-lab-browser.js +22 -0
  43. package/src/code-lab.js +3 -0
  44. package/src/code-language.js +52 -0
  45. package/src/csv.js +74 -0
  46. package/src/decision-lab.js +20 -0
  47. package/src/deck-file.js +119 -0
  48. package/src/diagram/napkin-examples.js +13 -0
  49. package/src/diagram/napkin.js +539 -0
  50. package/src/docx.js +128 -0
  51. package/src/dynamics/git-sim.js +200 -0
  52. package/src/dynamics/layouts.js +112 -0
  53. package/src/elements.js +554 -0
  54. package/src/experiences.js +124 -0
  55. package/src/exploration.js +31 -0
  56. package/src/export/browser.js +53 -0
  57. package/src/export/estudo.js +67 -0
  58. package/src/export/pptx.js +475 -0
  59. package/src/export/roteiro.js +40 -0
  60. package/src/export/shots.js +182 -0
  61. package/src/figures/charts.js +383 -0
  62. package/src/figures/diagrams.js +117 -0
  63. package/src/figures/icons.js +166 -0
  64. package/src/figures/material-pictos.js +20 -0
  65. package/src/figures/pictos.js +255 -0
  66. package/src/figures/points.js +106 -0
  67. package/src/figures/qr.js +29 -0
  68. package/src/figures/ufmap.js +48 -0
  69. package/src/fiscal/autofix.js +377 -0
  70. package/src/fiscal/normalize.js +115 -0
  71. package/src/graph-lab.js +24 -0
  72. package/src/hologram.js +30 -0
  73. package/src/identity.js +86 -0
  74. package/src/import/crop.js +59 -0
  75. package/src/import/index.js +132 -0
  76. package/src/import/legacy-word.js +42 -0
  77. package/src/import/merge.js +45 -0
  78. package/src/import/office.js +123 -0
  79. package/src/import/omml.js +69 -0
  80. package/src/import/pdf-render.js +56 -0
  81. package/src/import/pptx.js +701 -0
  82. package/src/import/xml.js +42 -0
  83. package/src/infographic.js +401 -0
  84. package/src/layouts.js +723 -0
  85. package/src/lessons.js +171 -0
  86. package/src/library.js +399 -0
  87. package/src/markup.js +116 -0
  88. package/src/master.js +214 -0
  89. package/src/mcp/server.js +371 -0
  90. package/src/meeting.js +42 -0
  91. package/src/motion.js +56 -0
  92. package/src/package.js +116 -0
  93. package/src/playground.js +19 -0
  94. package/src/portal-scene.js +20 -0
  95. package/src/preferences.js +61 -0
  96. package/src/protect.js +51 -0
  97. package/src/purpose.js +24 -0
  98. package/src/pytrace.js +1092 -0
  99. package/src/research/duckduckgo.js +73 -0
  100. package/src/research/research.js +202 -0
  101. package/src/research/svg-image.js +17 -0
  102. package/src/research/visuals.js +52 -0
  103. package/src/runtime/api-collection-ui.js +5 -0
  104. package/src/runtime/api-collections.js +28 -0
  105. package/src/runtime/api-core.js +530 -0
  106. package/src/runtime/api-ui.js +966 -0
  107. package/src/runtime/base.css +1774 -0
  108. package/src/runtime/calc.js +139 -0
  109. package/src/runtime/code-lab.js +371 -0
  110. package/src/runtime/decision-lab.js +49 -0
  111. package/src/runtime/diagram.js +341 -0
  112. package/src/runtime/fit.js +268 -0
  113. package/src/runtime/fonts/caveat.css +2 -0
  114. package/src/runtime/fonts/comic-neue.css +3 -0
  115. package/src/runtime/fonts/fredoka.css +2 -0
  116. package/src/runtime/fonts/index.json +10 -0
  117. package/src/runtime/fonts/inter.css +2 -0
  118. package/src/runtime/fonts/patrick-hand.css +2 -0
  119. package/src/runtime/fonts/plus-jakarta-sans.css +2 -0
  120. package/src/runtime/fonts/press-start-2p.css +2 -0
  121. package/src/runtime/fonts/vt323.css +2 -0
  122. package/src/runtime/formula.js +148 -0
  123. package/src/runtime/graph-lab.js +72 -0
  124. package/src/runtime/meeting.css +7 -0
  125. package/src/runtime/meeting.js +10 -0
  126. package/src/runtime/motion.js +15 -0
  127. package/src/runtime/playground.js +11 -0
  128. package/src/runtime/points.js +19 -0
  129. package/src/runtime/portal-scene.css +6 -0
  130. package/src/runtime/portal-scene.js +22 -0
  131. package/src/runtime/runtime.js +827 -0
  132. package/src/runtime/science.js +89 -0
  133. package/src/runtime/skins/aluminio.css +31 -0
  134. package/src/runtime/skins/arcade.css +25 -0
  135. package/src/runtime/skins/aurora.css +17 -0
  136. package/src/runtime/skins/bauhaus.css +19 -0
  137. package/src/runtime/skins/editorial.css +19 -0
  138. package/src/runtime/skins/jornal.css +17 -0
  139. package/src/runtime/skins/manual-noite.css +14 -0
  140. package/src/runtime/skins/manual.css +14 -0
  141. package/src/runtime/skins/noite.css +21 -0
  142. package/src/runtime/skins/oceano.css +17 -0
  143. package/src/runtime/skins/pop.css +23 -0
  144. package/src/runtime/skins/prata.css +18 -0
  145. package/src/runtime/skins/prisma.css +28 -0
  146. package/src/runtime/skins/rabisco.css +18 -0
  147. package/src/runtime/skins/relevo.css +33 -0
  148. package/src/runtime/skins/sinal.css +16 -0
  149. package/src/runtime/skins/terminal.css +23 -0
  150. package/src/runtime/vendor/KATEX-LICENSE.txt +21 -0
  151. package/src/runtime/vendor/MERMAID-LICENSE.txt +21 -0
  152. package/src/runtime/vendor/PLOTLY-LICENSE.txt +21 -0
  153. package/src/runtime/vendor/katex.css +1 -0
  154. package/src/runtime/vendor/mermaid.min.js +3636 -0
  155. package/src/runtime/vendor/plotly.min.js +3620 -0
  156. package/src/runtime/video-player.js +35 -0
  157. package/src/science.js +162 -0
  158. package/src/studio/ai-response.js +36 -0
  159. package/src/studio/api-routes.js +152 -0
  160. package/src/studio/assets/contexto/leia-me.md +12 -0
  161. package/src/studio/assets/contexto/vendas.csv +7 -0
  162. package/src/studio/assets/imagens/colecao-arquitetura.png +0 -0
  163. package/src/studio/assets/imagens/colecao-cor.png +0 -0
  164. package/src/studio/assets/imagens/colecao-equipe.png +0 -0
  165. package/src/studio/assets/imagens/lavanda-cover.jpg +0 -0
  166. package/src/studio/code-routes.js +32 -0
  167. package/src/studio/command-approval.js +48 -0
  168. package/src/studio/demo-decks.js +98 -0
  169. package/src/studio/direction-routes.js +29 -0
  170. package/src/studio/errors.js +65 -0
  171. package/src/studio/exploration-demo.js +17 -0
  172. package/src/studio/exporting.js +105 -0
  173. package/src/studio/generation-report.js +10 -0
  174. package/src/studio/instance.js +48 -0
  175. package/src/studio/layout-samples.js +152 -0
  176. package/src/studio/project.js +371 -0
  177. package/src/studio/public/api-collections.js +28 -0
  178. package/src/studio/public/app.js +5265 -0
  179. package/src/studio/public/art-preview.js +10 -0
  180. package/src/studio/public/calc-fields.js +11 -0
  181. package/src/studio/public/chat-progress.js +47 -0
  182. package/src/studio/public/developer-fields.js +22 -0
  183. package/src/studio/public/explorer.js +443 -0
  184. package/src/studio/public/history.js +58 -0
  185. package/src/studio/public/index.html +867 -0
  186. package/src/studio/public/inspector.js +270 -0
  187. package/src/studio/public/lab-fields.js +5 -0
  188. package/src/studio/public/library.css +275 -0
  189. package/src/studio/public/library.html +55 -0
  190. package/src/studio/public/library.js +471 -0
  191. package/src/studio/public/merge-decks.js +155 -0
  192. package/src/studio/public/review-ui.js +100 -0
  193. package/src/studio/public/screenshot-editor.js +140 -0
  194. package/src/studio/public/share-ui.js +72 -0
  195. package/src/studio/public/slide-clipboard.js +23 -0
  196. package/src/studio/public/slide-form.js +1263 -0
  197. package/src/studio/public/studio-awareness.js +154 -0
  198. package/src/studio/public/studio-next.css +303 -0
  199. package/src/studio/public/style.css +1262 -0
  200. package/src/studio/public/ui-icons.js +2 -0
  201. package/src/studio/public/viewers.js +372 -0
  202. package/src/studio/public/visual-editor.js +326 -0
  203. package/src/studio/public/workspace.js +18 -0
  204. package/src/studio/public-files.js +1 -0
  205. package/src/studio/request-helpers.js +41 -0
  206. package/src/studio/server.js +1583 -0
  207. package/src/studio/share-routes.js +146 -0
  208. package/src/studio/slide-copy-routes.js +26 -0
  209. package/src/studio/slide-copy.js +30 -0
  210. package/src/studio/snapshot.js +160 -0
  211. package/src/studio/style-routes.js +103 -0
  212. package/src/studio/template-collections.js +97 -0
  213. package/src/studio/versions.js +95 -0
  214. package/src/studio/video-download.js +29 -0
  215. package/src/studio/visual-keys.js +52 -0
  216. package/src/studio/workspaces.js +39 -0
  217. package/src/table.js +93 -0
  218. package/src/templates/scaffold.js +372 -0
  219. package/src/themes.js +604 -0
  220. package/src/trace-view.js +450 -0
  221. package/src/uid.js +19 -0
  222. package/src/video-player.js +40 -0
  223. package/src/visual-edits.js +99 -0
  224. package/src/ws.js +134 -0
  225. package/templates/cenario/Texto no cen/303/241rio.yaml" +171 -0
  226. package/templates/cenario/imagens/cidade.svg +30 -0
  227. package/templates/cenario/imagens/pessoa.svg +15 -0
  228. package/templates/cenario-e-ciencia.yaml +47 -0
  229. package/templates/ensaio-api.yaml +160 -0
  230. package/templates/exemplo-alegre.yaml +75 -0
  231. package/templates/exemplo-keynote.yaml +90 -0
  232. package/templates/exemplo-napkin.yaml +139 -0
  233. package/templates/exemplo.yaml +228 -0
@@ -0,0 +1,139 @@
1
+ // Calculadora ao vivo (layout calc): a mesma conta no motor (Node: prévia, PDF) e na apresentação (controles).
2
+ // Precisa de src/runtime/formula.js carregado antes (SagaFormula).
3
+ (function (root) {
4
+ const SUP = { "-": "⁻", 0: "⁰", 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹" };
5
+ function format(v, o = {}) {
6
+ if (v == null || !Number.isFinite(v)) return "—";
7
+ if (o.sci || Math.abs(v) >= 1e7 || (Math.abs(v) < 1e-3 && v !== 0)) {
8
+ const [m, e] = v.toExponential(2).split("e");
9
+ return `${m.replace(".", ",")} × 10${String(Number(e)).split("").map((c) => SUP[c] ?? c).join("")}`;
10
+ }
11
+ if (o.decimals != null) return v.toLocaleString("pt-BR", { minimumFractionDigits: o.decimals, maximumFractionDigits: o.decimals });
12
+ return v.toLocaleString("pt-BR", { maximumSignificantDigits: Math.abs(v) >= 1000 ? 7 : 4 });
13
+ }
14
+ // todas as saídas na ordem (uma saída usa as anteriores); `cases` escolhe texto/cor/fórmula pela faixa de `of`
15
+ function evaluate(model, values = {}) {
16
+ const F = root.SagaFormula;
17
+ const env = Object.fromEntries(model.inputs.map((i) => [i.name, values[i.name] ?? i.value]));
18
+ const vars = [...model.inputs.map((i) => i.name), ...model.outputs.map((o) => o.name)];
19
+ const out = {};
20
+ for (const o of model.outputs) {
21
+ const ofVal = o.of ? env[o.of] : null;
22
+ const kase = o.cases.length ? o.cases.find((c) => c.below == null || (ofVal ?? NaN) < c.below) || o.cases[o.cases.length - 1] : null;
23
+ const src = (kase && kase.fn) || o.fn;
24
+ let value = null, error = "";
25
+ if (src) { try { value = F.compile(src, vars).eval(env); } catch (e) { error = e.message; } }
26
+ if (src && !Number.isFinite(value)) error ||= 'A fórmula não produziu um número finito para estas entradas.';
27
+ if (value != null) env[o.name] = value;
28
+ out[o.name] = { value, error, text: (kase && kase.text) || "", color: (kase && kase.color) || "" };
29
+ }
30
+ return out;
31
+ }
32
+ function scalePos(v, sc) {
33
+ if (v == null) return 0;
34
+ const lg = (x) => Math.log10(Math.max(x, 1e-12));
35
+ const t = sc.log ? (lg(v) - lg(sc.min)) / (lg(sc.max) - lg(sc.min)) : (v - sc.min) / (sc.max - sc.min);
36
+ return Math.max(0, Math.min(1, t)) * 100;
37
+ }
38
+ function curveData(model, values, output) {
39
+ const input = model.inputs.find(i => i.name === model.sweep);
40
+ if (!input) return { path: '', min: null, max: null };
41
+ const points = Array.from({ length: 41 }, (_, k) => {
42
+ const x = input.min + (input.max - input.min) * k / 40;
43
+ return { x, y: evaluate(model, { ...values, [input.name]: x })[output]?.value };
44
+ });
45
+ const valid = points.filter(p => Number.isFinite(p.y));
46
+ if (!valid.length) return { path: '', min: null, max: null };
47
+ const lo = Math.min(...valid.map(p => p.y)), hi = Math.max(...valid.map(p => p.y));
48
+ let lift = true;
49
+ const path = points.map((p, k) => {
50
+ if (!Number.isFinite(p.y)) { lift = true; return ''; }
51
+ const command = lift ? 'M' : 'L'; lift = false;
52
+ return `${command}${(k * 8).toFixed(1)},${(75 - (p.y - lo) / (hi - lo || 1) * 70).toFixed(1)}`;
53
+ }).join(' ');
54
+ return { path, min: lo, max: hi };
55
+ }
56
+ const curve = (model, values, output) => curveData(model, values, output).path;
57
+ // na apresentação: mexeu no controle, recalcula e atualiza números, selos e ponteiros
58
+ function mount(doc) {
59
+ doc.querySelectorAll("[data-calc]:not([data-calc-ready])").forEach((rootEl) => {
60
+ rootEl.dataset.calcReady = "1";
61
+ const model = JSON.parse(rootEl.querySelector(".calc-model").textContent);
62
+ let frozen = null;
63
+ let previous = null;
64
+ const resultsEl = rootEl.querySelector('.calc-outputs');
65
+ const explain = rootEl.querySelector('[data-calc-explanation]');
66
+ const setValues = (v) => rootEl.querySelectorAll('[data-calc-in]').forEach(el => { el.value = v[el.dataset.calcIn] ?? model.inputs.find(i => i.name === el.dataset.calcIn).value; });
67
+ if (model.prediction) rootEl.classList.add('calc-unrevealed');
68
+ const values = () => Object.fromEntries([...rootEl.querySelectorAll("[data-calc-in]")].map((i) => [i.dataset.calcIn, Number(i.value)]));
69
+ const revealButton = rootEl.querySelector('[data-calc-reveal]');
70
+ const reveal = () => { rootEl.classList.remove('calc-unrevealed'); if (revealButton) { revealButton.textContent = 'Resultado revelado'; revealButton.disabled = true; } };
71
+ const redraw = () => {
72
+ const v = values(), res = evaluate(model, v);
73
+ for (const i of model.inputs) { const el = rootEl.querySelector(`[data-calc-show="${i.name}"]`); if (el) el.textContent = format(v[i.name], i); }
74
+ for (const o of model.outputs) {
75
+ const r = res[o.name];
76
+ const out = rootEl.querySelector(`[data-calc-out="${o.name}"]`); if (out) out.textContent = format(r.value, o);
77
+ if (out) out.classList.toggle('calc-changed', !!previous && previous[o.name]?.value !== r.value);
78
+ const comparison = rootEl.querySelector(`[data-calc-compare="${o.name}"]`);
79
+ if (comparison) {
80
+ comparison.hidden = !frozen;
81
+ comparison.textContent = frozen ? `Antes: ${format(frozen.results[o.name].value, o)} ${o.unit || ''} · Variação: ${format(r.value == null || frozen.results[o.name].value == null ? null : r.value - frozen.results[o.name].value, o)}` : '';
82
+ }
83
+ const b = rootEl.querySelector(`[data-calc-badge="${o.name}"]`); if (b) { b.textContent = r.text; b.style.background = r.color ? `var(--${r.color})` : ""; }
84
+ const ptr = rootEl.querySelector(`[data-calc-pointer="${o.name}"]`);
85
+ if (ptr && o.scale) ptr.style.left = `${scalePos(o.of ? res[o.of] ? res[o.of].value : v[o.of] : r.value, o.scale)}%`;
86
+ const path = rootEl.querySelector(`[data-calc-curve="${o.name}"]`);
87
+ if (path) {
88
+ const data = curveData(model, v, o.name);
89
+ path.setAttribute('d', data.path);
90
+ const axis = rootEl.querySelector(`[data-calc-axis="${o.name}"]`);
91
+ if (axis) axis.textContent = `${o.label}: ${format(data.min, o)} a ${format(data.max, o)} ${o.unit || ''} (escala automática)`;
92
+ }
93
+ }
94
+ previous = res;
95
+ rootEl.dispatchEvent(new CustomEvent('sagadeck:values', { bubbles: true, detail: { inputs: { ...v }, outputs: res } }));
96
+ // Comparação e explicação podem aumentar o painel depois da primeira montagem.
97
+ const slide = rootEl.closest('.slide');
98
+ if (slide && root.SagadeckFit) root.requestAnimationFrame(() => root.SagadeckFit.shrink(slide));
99
+ };
100
+ rootEl.querySelectorAll('button').forEach(button => {
101
+ ['keydown', 'pointerdown', 'click'].forEach(ev => button.addEventListener(ev, e => e.stopPropagation()));
102
+ });
103
+ rootEl.querySelectorAll('[data-calc-scenario]').forEach(button => button.addEventListener('click', () => {
104
+ const scenario = model.scenarios[Number(button.dataset.calcScenario)];
105
+ setValues(scenario.values || {});
106
+ if (explain) explain.textContent = scenario.explanation || model.explanation;
107
+ rootEl.querySelectorAll('[data-calc-scenario]').forEach(b => b.setAttribute('aria-pressed', String(b === button)));
108
+ redraw();
109
+ }));
110
+ const freezeButton = rootEl.querySelector('[data-calc-freeze]');
111
+ freezeButton?.addEventListener('click', () => { frozen = { values: values(), results: evaluate(model, values()) }; freezeButton.textContent = 'Comparação fixada'; freezeButton.setAttribute('aria-pressed', 'true'); redraw(); });
112
+ rootEl.querySelector('[data-calc-reset]')?.addEventListener('click', () => {
113
+ frozen = null; previous = null; setValues({});
114
+ if (revealButton) { revealButton.textContent = 'Ver resultado'; revealButton.disabled = false; }
115
+ if (freezeButton) { freezeButton.textContent = 'Comparar com este'; freezeButton.setAttribute('aria-pressed', 'false'); }
116
+ rootEl.querySelectorAll('[data-calc-scenario]').forEach(b => b.setAttribute('aria-pressed', 'false'));
117
+ if (explain) explain.textContent = model.explanation;
118
+ rootEl.classList.toggle('calc-unrevealed', !!model.prediction); redraw();
119
+ });
120
+ revealButton?.addEventListener('click', reveal);
121
+ rootEl.querySelector('[data-calc-free]')?.addEventListener('click', () => { reveal(); if (explain) explain.textContent = `Modo livre: ajuste as entradas. ${model.explanation || ''}`; rootEl.querySelector('[data-calc-in]')?.focus(); });
122
+ rootEl.querySelectorAll("[data-calc-in]").forEach((inp) => {
123
+ const stop = (e) => e.stopPropagation(); // setas e cliques no controle não trocam de slide
124
+ ["keydown", "pointerdown", "click"].forEach((ev) => inp.addEventListener(ev, stop));
125
+ inp.addEventListener("input", () => {
126
+ rootEl.querySelectorAll('[data-calc-scenario]').forEach(b => b.setAttribute('aria-pressed', 'false'));
127
+ if (explain) explain.textContent = model.explanation;
128
+ redraw();
129
+ });
130
+ });
131
+ redraw();
132
+ });
133
+ }
134
+ root.SagaCalc = { evaluate, format, scalePos, curve, curveData, mount };
135
+ if (typeof document !== "undefined") {
136
+ const go = () => mount(document);
137
+ document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", go) : go();
138
+ }
139
+ })(typeof globalThis !== "undefined" ? globalThis : window);