primocode 8.42.1 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -37
- package/bin/primocode.js +599 -327
- package/lib/acervo.js +8 -1
- package/lib/act.js +205 -114
- package/lib/api.js +35 -4
- package/lib/boas-vindas.js +31 -192
- package/lib/catalogo.js +60 -60
- package/lib/config.js +1 -1
- package/lib/conta.js +3 -24
- package/lib/diff.js +161 -0
- package/lib/diretor.js +37 -47
- package/lib/entrada.js +545 -0
- package/lib/especialistas.js +2 -2
- package/lib/estudio/assets.js +343 -0
- package/lib/estudio/identidade.js +560 -0
- package/lib/estudio/index.js +565 -0
- package/lib/estudio/plano.js +327 -0
- package/lib/estudio/projeto.js +246 -0
- package/lib/estudio/remotion.js +606 -0
- package/lib/estudio/slides.js +190 -0
- package/lib/estudio/video.js +296 -0
- package/lib/fala.js +13 -1
- package/lib/marca.js +4 -1
- package/lib/marketplace.js +189 -0
- package/lib/permissao.js +137 -0
- package/lib/registro.js +229 -0
- package/lib/skills.js +329 -0
- package/lib/tools.js +51 -181
- package/lib/ui.js +7 -3
- package/lib/voz.js +239 -0
- package/package.json +12 -3
- package/skills/acessibilidade/SKILL.md +28 -0
- package/skills/api-que-nao-quebra/SKILL.md +27 -0
- package/skills/depurar-de-verdade/SKILL.md +29 -0
- package/skills/editar-meu-video/SKILL.md +59 -0
- package/skills/escrever-em-portugues/SKILL.md +28 -0
- package/skills/git-limpo/SKILL.md +28 -0
- package/skills/motion-de-primeira/SKILL.md +62 -0
- package/skills/pagina-que-converte/SKILL.md +28 -0
- package/skills/performance-web/SKILL.md +28 -0
- package/skills/revisao-antes-de-entregar/SKILL.md +27 -0
- package/skills/slides-que-prendem/SKILL.md +40 -0
- package/studio/edge.py +16 -66
- package/studio/narrar.py +274 -0
- package/studio/pessoa.py +167 -0
- package/voz/primo_voz/__init__.py +0 -0
- package/voz/primo_voz/__main__.py +325 -0
- package/voz/primo_voz/escuta.py +235 -0
- package/voz/primo_voz/orbe.py +216 -0
- package/lib/audio-livre.js +0 -177
- package/lib/chaves.js +0 -149
- package/lib/claude-engine.js +0 -631
- package/lib/codex-engine.js +0 -208
- package/lib/remotion.js +0 -663
- package/lib/studio.js +0 -960
- package/studio/PRIMOCODE.md +0 -58
- package/studio/README.md +0 -154
- package/studio/__pycache__/edge.cpython-311.pyc +0 -0
- package/studio/__pycache__/elevenlabs.cpython-311.pyc +0 -0
- package/studio/__pycache__/voz.cpython-311.pyc +0 -0
- package/studio/arquivos/corte-teste-de-camera-fb823.json +0 -57
- package/studio/ferramentas/00-protocolo.md +0 -125
- package/studio/ferramentas/01-modelos.md +0 -270
- package/studio/ferramentas/README.md +0 -32
- package/studio/ferramentas/corte.md +0 -919
- package/studio/ferramentas/grade.md +0 -92
- package/studio/ferramentas/prisma.md +0 -107
- package/studio/ferramentas/prosa.md +0 -86
- package/studio/ferramentas/tela.md +0 -93
- package/studio/ferramentas/traco.md +0 -79
- package/studio/server.py +0 -2254
- package/studio/studio.log +0 -57
- package/studio/voz.py +0 -388
- package/studio/web/analise.html +0 -52
- package/studio/web/core.css +0 -1167
- package/studio/web/fontes/bebas.woff2 +0 -0
- package/studio/web/fontes/grotesk-700.woff2 +0 -0
- package/studio/web/fontes/inter-400.woff2 +0 -0
- package/studio/web/fontes/inter-700.woff2 +0 -0
- package/studio/web/fontes/jetbrains-400.woff2 +0 -0
- package/studio/web/fontes/playfair-700.woff2 +0 -0
- package/studio/web/fontes.css +0 -23
- package/studio/web/home.html +0 -217
- package/studio/web/js/analise.js +0 -510
- package/studio/web/js/audio.js +0 -607
- package/studio/web/js/editor.js +0 -1802
- package/studio/web/js/exportar.js +0 -222
- package/studio/web/js/ferramentas.js +0 -108
- package/studio/web/js/icones.js +0 -120
- package/studio/web/js/midia.js +0 -157
- package/studio/web/js/narracao.js +0 -325
- package/studio/web/js/player.js +0 -903
- package/studio/web/js/render-grade.js +0 -243
- package/studio/web/js/render-prosa.js +0 -104
- package/studio/web/js/render.js +0 -1852
- package/studio/web/js/sfx.js +0 -233
- package/studio/web/js/video.js +0 -464
- package/studio/web/js/voz-neural.js +0 -152
- package/studio/web/render.css +0 -1352
- package/studio/web/tf.html +0 -15
- package/studio/web/tool.html +0 -78
- package/studio/web/view.html +0 -27
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/* ==========================================================================
|
|
2
|
-
exportar.js — transforma uma cena renderizada em PNG ou JPG.
|
|
3
|
-
|
|
4
|
-
Exportar.imagem(cenaEl, {largura, altura, escala, formato, nome})
|
|
5
|
-
|
|
6
|
-
Caminho: clona a cena → embute as imagens como data URI → empacota num
|
|
7
|
-
<foreignObject> de SVG com o CSS junto → desenha em canvas → baixa.
|
|
8
|
-
Sem biblioteca externa.
|
|
9
|
-
========================================================================== */
|
|
10
|
-
|
|
11
|
-
var Exportar = (function () {
|
|
12
|
-
"use strict";
|
|
13
|
-
|
|
14
|
-
var cssCache = null;
|
|
15
|
-
|
|
16
|
-
function css() {
|
|
17
|
-
if (cssCache) return Promise.resolve(cssCache);
|
|
18
|
-
return Promise.all([
|
|
19
|
-
fetch("/core.css").then(function (r) { return r.text(); }),
|
|
20
|
-
fetch("/render.css").then(function (r) { return r.text(); }),
|
|
21
|
-
]).then(function (partes) {
|
|
22
|
-
cssCache = partes.join("\n");
|
|
23
|
-
return cssCache;
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function paraDataURI(url) {
|
|
28
|
-
if (!url || /^data:/.test(url)) return Promise.resolve(url);
|
|
29
|
-
return fetch(url)
|
|
30
|
-
.then(function (r) { return r.blob(); })
|
|
31
|
-
.then(function (b) {
|
|
32
|
-
return new Promise(function (ok, falha) {
|
|
33
|
-
var l = new FileReader();
|
|
34
|
-
l.onload = function () { ok(l.result); };
|
|
35
|
-
l.onerror = falha;
|
|
36
|
-
l.readAsDataURL(b);
|
|
37
|
-
});
|
|
38
|
-
})
|
|
39
|
-
.catch(function () { return url; });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/* Toda imagem precisa virar data URI: dentro de um SVG carregado como
|
|
43
|
-
imagem, referência externa não é buscada. */
|
|
44
|
-
function embutirImagens(raiz) {
|
|
45
|
-
var tarefas = [];
|
|
46
|
-
|
|
47
|
-
Array.prototype.forEach.call(raiz.querySelectorAll("img"), function (img) {
|
|
48
|
-
tarefas.push(paraDataURI(img.getAttribute("src")).then(function (d) {
|
|
49
|
-
img.setAttribute("src", d);
|
|
50
|
-
}));
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
Array.prototype.forEach.call(raiz.querySelectorAll("*"), function (no) {
|
|
54
|
-
var bg = no.style && no.style.backgroundImage;
|
|
55
|
-
if (!bg || bg.indexOf("url(") < 0) return;
|
|
56
|
-
var m = bg.match(/url\(["']?([^"')]+)["']?\)/);
|
|
57
|
-
if (!m || /^data:/.test(m[1])) return;
|
|
58
|
-
tarefas.push(paraDataURI(m[1]).then(function (d) {
|
|
59
|
-
no.style.backgroundImage = 'url("' + d + '")';
|
|
60
|
-
}));
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
return Promise.all(tarefas);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/* Copia para o clone o estado ATUAL de cada animação.
|
|
67
|
-
*
|
|
68
|
-
* Sem isto o vídeo exportado perde todo o movimento, e o erro é silencioso.
|
|
69
|
-
* O XMLSerializer copia a MARCAÇÃO, não o instante: o SVG resultante mostra
|
|
70
|
-
* o elemento no estado final da animação, sempre. Foi medido — aos 0,3 s de
|
|
71
|
-
* um vídeo, o título já aparecia no lugar final, com a entrada inteira
|
|
72
|
-
* perdida. O arquivo ficava tecnicamente perfeito e visualmente morto.
|
|
73
|
-
*
|
|
74
|
-
* A leitura vem do getComputedStyle do elemento VIVO, que reflete onde a
|
|
75
|
-
* animação está agora, e entra como estilo inline no clone. Depois as
|
|
76
|
-
* animações são desligadas no clone: o estado já está escrito, e deixá-las
|
|
77
|
-
* ligadas faria o SVG recomeçar do zero por cima.
|
|
78
|
-
*
|
|
79
|
-
* Só três propriedades são copiadas — são as que as animações do estúdio
|
|
80
|
-
* mexem (entrada, transição, chaves, Ken Burns, cubo 3D). Copiar o estilo
|
|
81
|
-
* computado inteiro seria dezenas de vezes mais caro por quadro, e o resto
|
|
82
|
-
* já vem das folhas embutidas no próprio SVG. */
|
|
83
|
-
function assarAnimacoes(original, clone) {
|
|
84
|
-
var deLa = original.querySelectorAll("*");
|
|
85
|
-
var daCa = clone.querySelectorAll("*");
|
|
86
|
-
var n = Math.min(deLa.length, daCa.length);
|
|
87
|
-
for (var i = 0; i < n; i++) {
|
|
88
|
-
var cs = window.getComputedStyle(deLa[i]);
|
|
89
|
-
var alvo = daCa[i].style;
|
|
90
|
-
if (cs.transform && cs.transform !== "none") alvo.transform = cs.transform;
|
|
91
|
-
if (cs.opacity !== "" && cs.opacity !== "1") alvo.opacity = cs.opacity;
|
|
92
|
-
if (cs.filter && cs.filter !== "none") alvo.filter = cs.filter;
|
|
93
|
-
alvo.animation = "none";
|
|
94
|
-
}
|
|
95
|
-
// A raiz também: a TRANSIÇÃO de cena (zoom, deslizar, persiana) anima o
|
|
96
|
-
// transform dela. Quem chama zera esse transform para desfazer a escala de
|
|
97
|
-
// pré-visualização — e sem copiar de volta o valor animado, toda transição
|
|
98
|
-
// sumia do arquivo exportado.
|
|
99
|
-
var raiz = window.getComputedStyle(original);
|
|
100
|
-
if (raiz.transform && raiz.transform !== "none") clone.style.transform = raiz.transform;
|
|
101
|
-
if (raiz.opacity !== "" && raiz.opacity !== "1") clone.style.opacity = raiz.opacity;
|
|
102
|
-
if (raiz.filter && raiz.filter !== "none") clone.style.filter = raiz.filter;
|
|
103
|
-
clone.style.animation = "none";
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/* Uma cena do DOM → uma <img> pronta para desenhar no canvas.
|
|
107
|
-
*
|
|
108
|
-
* Separado de `imagem()` porque o vídeo precisa disto CENTENAS de vezes, e
|
|
109
|
-
* com a folha de CSS já buscada: refazer o fetch do core.css e do render.css
|
|
110
|
-
* a cada quadro seria o gasto dominante.
|
|
111
|
-
*
|
|
112
|
-
* `congelar` põe as animações no estado final — é o que a exportação de PNG
|
|
113
|
-
* quer. O vídeo passa false, porque o que ele quer é o retrato do instante. */
|
|
114
|
-
/* `mascara` recebe o clone antes de virar SVG e pode esconder camadas. É como
|
|
115
|
-
a exportação de vídeo tira o fundo da cena que tem gravação do usuário: o
|
|
116
|
-
quadro do <video> é pintado à parte, no canvas, e o fundo do tema por cima
|
|
117
|
-
dele apagaria justamente a imagem que se quer mostrar. */
|
|
118
|
-
function retrato(cenaEl, L, A, folha, congelar, mascara) {
|
|
119
|
-
var clone = cenaEl.cloneNode(true);
|
|
120
|
-
clone.style.transform = "none";
|
|
121
|
-
clone.style.position = "static";
|
|
122
|
-
clone.style.display = "block";
|
|
123
|
-
clone.style.width = L + "px";
|
|
124
|
-
clone.style.height = A + "px";
|
|
125
|
-
if (congelar) {
|
|
126
|
-
clone.classList.remove("animar");
|
|
127
|
-
Array.prototype.forEach.call(clone.querySelectorAll("*"), function (n) {
|
|
128
|
-
n.style.animation = "none";
|
|
129
|
-
n.style.opacity = n.style.opacity === "0" ? "1" : n.style.opacity;
|
|
130
|
-
});
|
|
131
|
-
} else {
|
|
132
|
-
assarAnimacoes(cenaEl, clone);
|
|
133
|
-
}
|
|
134
|
-
if (typeof mascara === "function") mascara(clone);
|
|
135
|
-
var caixa = document.createElement("div");
|
|
136
|
-
caixa.appendChild(clone);
|
|
137
|
-
return embutirImagens(caixa).then(function () {
|
|
138
|
-
var html = new XMLSerializer().serializeToString(clone);
|
|
139
|
-
var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + L + '" height="' + A + '">' +
|
|
140
|
-
"<foreignObject width='100%' height='100%'>" +
|
|
141
|
-
'<div xmlns="http://www.w3.org/1999/xhtml">' +
|
|
142
|
-
"<style>" + folha.replace(/<\/style>/gi, "") + "</style>" +
|
|
143
|
-
html + "</div></foreignObject></svg>";
|
|
144
|
-
return new Promise(function (ok, falha) {
|
|
145
|
-
var img = new Image();
|
|
146
|
-
img.onload = function () { ok(img); };
|
|
147
|
-
img.onerror = function () { falha(new Error("não consegui montar a imagem")); };
|
|
148
|
-
img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
function imagem(cenaEl, op) {
|
|
154
|
-
op = op || {};
|
|
155
|
-
var L = op.largura || cenaEl.offsetWidth || 1920;
|
|
156
|
-
var A = op.altura || cenaEl.offsetHeight || 1080;
|
|
157
|
-
var escala = op.escala || 2;
|
|
158
|
-
var formato = op.formato === "jpg" ? "image/jpeg" : "image/png";
|
|
159
|
-
|
|
160
|
-
var clone = cenaEl.cloneNode(true);
|
|
161
|
-
clone.classList.remove("animar");
|
|
162
|
-
clone.style.transform = "none";
|
|
163
|
-
clone.style.position = "static";
|
|
164
|
-
clone.style.width = L + "px";
|
|
165
|
-
clone.style.height = A + "px";
|
|
166
|
-
// animação parada no estado final, senão sai tudo transparente
|
|
167
|
-
Array.prototype.forEach.call(clone.querySelectorAll("*"), function (n) {
|
|
168
|
-
n.style.animation = "none";
|
|
169
|
-
n.style.opacity = n.style.opacity === "0" ? "1" : n.style.opacity;
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
var caixa = document.createElement("div");
|
|
173
|
-
caixa.appendChild(clone);
|
|
174
|
-
|
|
175
|
-
return embutirImagens(caixa)
|
|
176
|
-
.then(css)
|
|
177
|
-
.then(function (folha) {
|
|
178
|
-
var html = new XMLSerializer().serializeToString(clone);
|
|
179
|
-
var svg =
|
|
180
|
-
'<svg xmlns="http://www.w3.org/2000/svg" width="' + L + '" height="' + A + '">' +
|
|
181
|
-
"<foreignObject width='100%' height='100%'>" +
|
|
182
|
-
'<div xmlns="http://www.w3.org/1999/xhtml">' +
|
|
183
|
-
"<style>" + folha.replace(/<\/style>/gi, "") + "</style>" +
|
|
184
|
-
html +
|
|
185
|
-
"</div></foreignObject></svg>";
|
|
186
|
-
|
|
187
|
-
return new Promise(function (ok, falha) {
|
|
188
|
-
var img = new Image();
|
|
189
|
-
img.onload = function () { ok(img); };
|
|
190
|
-
img.onerror = function () { falha(new Error("não consegui montar a imagem")); };
|
|
191
|
-
img.src = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
|
|
192
|
-
});
|
|
193
|
-
})
|
|
194
|
-
.then(function (img) {
|
|
195
|
-
var tela = document.createElement("canvas");
|
|
196
|
-
tela.width = L * escala;
|
|
197
|
-
tela.height = A * escala;
|
|
198
|
-
var c = tela.getContext("2d");
|
|
199
|
-
if (formato === "image/jpeg") {
|
|
200
|
-
c.fillStyle = "#ffffff";
|
|
201
|
-
c.fillRect(0, 0, tela.width, tela.height);
|
|
202
|
-
}
|
|
203
|
-
c.drawImage(img, 0, 0, tela.width, tela.height);
|
|
204
|
-
return new Promise(function (ok) {
|
|
205
|
-
tela.toBlob(function (b) { ok(b); }, formato, 0.94);
|
|
206
|
-
});
|
|
207
|
-
})
|
|
208
|
-
.then(function (blob) {
|
|
209
|
-
if (!blob) throw new Error("o navegador não gerou o arquivo");
|
|
210
|
-
var url = URL.createObjectURL(blob);
|
|
211
|
-
var a = document.createElement("a");
|
|
212
|
-
a.href = url;
|
|
213
|
-
a.download = (op.nome || "arte").replace(/[^\w\-]+/g, "-").toLowerCase() +
|
|
214
|
-
(formato === "image/jpeg" ? ".jpg" : ".png");
|
|
215
|
-
a.click();
|
|
216
|
-
setTimeout(function () { URL.revokeObjectURL(url); }, 4000);
|
|
217
|
-
return true;
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return { imagem: imagem, retrato: retrato, css: css, assarAnimacoes: assarAnimacoes };
|
|
222
|
-
})();
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/* ==========================================================================
|
|
2
|
-
ferramentas.js — o que cada ferramenta oferece na interface.
|
|
3
|
-
========================================================================== */
|
|
4
|
-
|
|
5
|
-
// Os doze que o render.css define. A lista tinha seis: quatro temas existiam
|
|
6
|
-
// no CSS, a IA podia usá-los, e o editor não os oferecia a ninguém.
|
|
7
|
-
var TEMAS = ["meia-noite", "claro", "papel", "neon", "brasa", "floresta",
|
|
8
|
-
"retro", "oceano", "doce", "mono", "ambar", "grafite"];
|
|
9
|
-
|
|
10
|
-
var PALETA = ["#ff5a36", "#ffb03a", "#f4e04d", "#2fbf7f", "#1f8fe0", "#8b5cf6",
|
|
11
|
-
"#f472b6", "#ffffff", "#9aa4b2", "#111318"];
|
|
12
|
-
|
|
13
|
-
var FERR = {
|
|
14
|
-
prisma: {
|
|
15
|
-
nome: "Prisma", papel: "Apresentações", cor: "#FF5A36", icone: "tela", modelo: "cena",
|
|
16
|
-
layouts: ["capa", "titulo", "secao", "duas-colunas", "tres-colunas", "citacao",
|
|
17
|
-
"numeros", "imagem-direita", "imagem-esquerda", "centro", "livre"],
|
|
18
|
-
layoutPadrao: "titulo",
|
|
19
|
-
trilho: [
|
|
20
|
-
{ k: "titulo", i: "titulo", r: "Título", novo: { tipo: "texto", papel: "titulo", texto: "Novo título" } },
|
|
21
|
-
{ k: "texto", i: "texto", r: "Texto", novo: { tipo: "texto", papel: "corpo", texto: "Um parágrafo de apoio." } },
|
|
22
|
-
{ k: "lista", i: "lista", r: "Lista", novo: { tipo: "lista", itens: ["Primeiro ponto", "Segundo ponto"] } },
|
|
23
|
-
{ k: "cartoes", i: "cartao", r: "Cartões", novo: { tipo: "cartoes", itens: ["Título | descrição", "Título | descrição"] } },
|
|
24
|
-
{ k: "numeros", i: "numero", r: "Números", novo: { tipo: "numeros", itens: ["3x | crescimento", "42% | margem"] } },
|
|
25
|
-
{ k: "tabela", i: "tabela", r: "Tabela", novo: { tipo: "tabela", linhas: [["Coluna", "Coluna"], ["dado", "dado"]] } },
|
|
26
|
-
{ k: "citacao", i: "citacao", r: "Citação", novo: { tipo: "citacao", texto: "Uma frase que fica.", autor: "Autor" } },
|
|
27
|
-
{ k: "grafico", i: "grafico", r: "Gráfico", novo: { tipo: "grafico", grafico: "barras", dados: [["A", 30], ["B", 55], ["C", 40]] } },
|
|
28
|
-
{ k: "imagem", i: "imagem", r: "Imagem", novo: { tipo: "imagem", src: "", ajuste: "cobrir" } },
|
|
29
|
-
{ k: "icone", i: "icone", r: "Ícone", novo: { tipo: "icone", nome: "raio", tamanho: 120 } },
|
|
30
|
-
{ k: "codigo", i: "codigo", r: "Código", novo: { tipo: "codigo", texto: "npm install" } },
|
|
31
|
-
{ k: "forma", i: "quadrado", r: "Forma", novo: { tipo: "forma", forma: "retangulo", x: 200, y: 200, l: 400, a: 220, raio: 20 } },
|
|
32
|
-
],
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
tela: {
|
|
36
|
-
nome: "Tela", papel: "Design gráfico", cor: "#8B5CF6", icone: "lapis", modelo: "cena",
|
|
37
|
-
layouts: ["livre", "centro", "capa"], layoutPadrao: "livre",
|
|
38
|
-
tamanhos: [["Post 1080", 1080, 1080], ["Story 1080x1920", 1080, 1920],
|
|
39
|
-
["Capa 1920x1080", 1920, 1080], ["Banner 1600x600", 1600, 600]],
|
|
40
|
-
trilho: [
|
|
41
|
-
{ k: "texto", i: "texto", r: "Texto", novo: { tipo: "texto", texto: "Texto", x: 120, y: 120, l: 700, a: 140, tamanho: 88, peso: 700 } },
|
|
42
|
-
{ k: "quadrado", i: "quadrado", r: "Retângulo", novo: { tipo: "forma", forma: "retangulo", x: 160, y: 160, l: 420, a: 300, raio: 24 } },
|
|
43
|
-
{ k: "circulo", i: "circulo", r: "Círculo", novo: { tipo: "forma", forma: "circulo", x: 200, y: 200, l: 320, a: 320 } },
|
|
44
|
-
{ k: "triangulo", i: "triangulo", r: "Triângulo", novo: { tipo: "forma", forma: "triangulo", x: 200, y: 200, l: 320, a: 300 } },
|
|
45
|
-
{ k: "linha", i: "linha", r: "Linha", novo: { tipo: "forma", forma: "linha", x: 160, y: 400, l: 620, a: 6, espessura: 6 } },
|
|
46
|
-
{ k: "seta", i: "seta", r: "Seta", novo: { tipo: "forma", forma: "seta", x: 200, y: 400, l: 460, a: 60 } },
|
|
47
|
-
{ k: "imagem", i: "imagem", r: "Imagem", novo: { tipo: "imagem", src: "", x: 120, y: 120, l: 620, a: 460 } },
|
|
48
|
-
{ k: "icone", i: "icone", r: "Ícone", novo: { tipo: "icone", nome: "estrela", x: 300, y: 300, tamanho: 160 } },
|
|
49
|
-
{ k: "grafico", i: "grafico", r: "Gráfico", novo: { tipo: "grafico", grafico: "rosca", x: 160, y: 200, l: 620, a: 460, dados: [["A", 40], ["B", 30], ["C", 30]] } },
|
|
50
|
-
],
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
corte: {
|
|
54
|
-
nome: "Corte", papel: "Vídeo", cor: "#E0397A", icone: "video", modelo: "cena",
|
|
55
|
-
layouts: ["capa", "centro", "titulo", "citacao", "numeros", "imagem-direita", "livre"],
|
|
56
|
-
layoutPadrao: "capa", tempo: true,
|
|
57
|
-
trilho: [
|
|
58
|
-
{ k: "titulo", i: "titulo", r: "Título", novo: { tipo: "texto", papel: "titulo", texto: "Título da cena" } },
|
|
59
|
-
{ k: "texto", i: "texto", r: "Texto", novo: { tipo: "texto", papel: "apoio", texto: "Legenda da cena" } },
|
|
60
|
-
{ k: "lista", i: "lista", r: "Lista", novo: { tipo: "lista", itens: ["Um", "Dois"], revelar: true } },
|
|
61
|
-
{ k: "numeros", i: "numero", r: "Números", novo: { tipo: "numeros", itens: ["100% | atenção"] } },
|
|
62
|
-
{ k: "imagem", i: "imagem", r: "Imagem", novo: { tipo: "imagem", src: "", ajuste: "cobrir" } },
|
|
63
|
-
{ k: "icone", i: "icone", r: "Ícone", novo: { tipo: "icone", nome: "foguete", tamanho: 200 } },
|
|
64
|
-
{ k: "forma", i: "quadrado", r: "Forma", novo: { tipo: "forma", forma: "retangulo", x: 200, y: 200, l: 400, a: 220, raio: 20 } },
|
|
65
|
-
],
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
traco: {
|
|
69
|
-
nome: "Traço", papel: "Diagramas", cor: "#D9A21B", icone: "conector", modelo: "cena",
|
|
70
|
-
layouts: ["livre"], layoutPadrao: "livre",
|
|
71
|
-
trilho: [
|
|
72
|
-
{ k: "no", i: "no", r: "Nó", novo: { tipo: "no", texto: "Etapa", x: 300, y: 300, l: 340, a: 150 } },
|
|
73
|
-
{ k: "no-destaque", i: "circulo", r: "Nó destacado", novo: { tipo: "no", texto: "Chave", destaque: true, x: 300, y: 500, l: 340, a: 150 } },
|
|
74
|
-
{ k: "conector", i: "conector", r: "Conector", novo: { tipo: "conector", de: "", para: "" } },
|
|
75
|
-
{ k: "texto", i: "texto", r: "Texto", novo: { tipo: "texto", texto: "Anotação", x: 200, y: 120, l: 500, a: 90, tamanho: 32 } },
|
|
76
|
-
{ k: "forma", i: "quadrado", r: "Área", novo: { tipo: "forma", forma: "retangulo", x: 160, y: 160, l: 700, a: 500, raio: 26, preenchimento: "rgba(255,255,255,.04)", borda: { cor: "var(--c-linha)", largura: 2 } } },
|
|
77
|
-
{ k: "icone", i: "icone", r: "Ícone", novo: { tipo: "icone", nome: "engrenagem", x: 300, y: 300, tamanho: 120 } },
|
|
78
|
-
],
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
prosa: {
|
|
82
|
-
nome: "Prosa", papel: "Documentos", cor: "#2E9E6B", icone: "livro", modelo: "documento",
|
|
83
|
-
trilho: [
|
|
84
|
-
{ k: "titulo", i: "titulo", r: "Título", novo: { tipo: "titulo", texto: "Título" } },
|
|
85
|
-
{ k: "secao", i: "texto", r: "Seção", novo: { tipo: "secao", texto: "Nova seção" } },
|
|
86
|
-
{ k: "subsecao", i: "texto", r: "Subseção", novo: { tipo: "subsecao", texto: "Subseção" } },
|
|
87
|
-
{ k: "paragrafo", i: "texto", r: "Parágrafo", novo: { tipo: "paragrafo", texto: "Escreva aqui." } },
|
|
88
|
-
{ k: "lista", i: "lista", r: "Lista", novo: { tipo: "lista", itens: ["Item um", "Item dois"] } },
|
|
89
|
-
{ k: "numerada", i: "numero", r: "Numerada", novo: { tipo: "numerada", itens: ["Primeiro", "Segundo"] } },
|
|
90
|
-
{ k: "citacao", i: "citacao", r: "Citação", novo: { tipo: "citacao", texto: "Trecho citado.", autor: "Fonte" } },
|
|
91
|
-
{ k: "tabela", i: "tabela", r: "Tabela", novo: { tipo: "tabela", linhas: [["Coluna", "Coluna"], ["dado", "dado"]] } },
|
|
92
|
-
{ k: "codigo", i: "codigo", r: "Código", novo: { tipo: "codigo", texto: "console.log('oi')" } },
|
|
93
|
-
{ k: "destaque", i: "cartao", r: "Destaque", novo: { tipo: "destaque", titulo: "Atenção", texto: "Ponto importante." } },
|
|
94
|
-
{ k: "imagem", i: "imagem", r: "Imagem", novo: { tipo: "imagem", src: "", legenda: "" } },
|
|
95
|
-
{ k: "divisor", i: "linha", r: "Divisor", novo: { tipo: "divisor" } },
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
grade: {
|
|
100
|
-
nome: "Grade", papel: "Planilhas", cor: "#1F8FE0", icone: "tabela", modelo: "planilha",
|
|
101
|
-
trilho: [
|
|
102
|
-
{ k: "linha", i: "mais", r: "Nova linha" },
|
|
103
|
-
{ k: "coluna", i: "tabela", r: "Nova coluna" },
|
|
104
|
-
{ k: "total", i: "numero", r: "Linha de total" },
|
|
105
|
-
{ k: "grafico", i: "grafico", r: "Gráfico" },
|
|
106
|
-
],
|
|
107
|
-
},
|
|
108
|
-
};
|
package/studio/web/js/icones.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
/* ==========================================================================
|
|
2
|
-
icones.js — biblioteca de ícones em SVG, sem dependência externa.
|
|
3
|
-
Traço de 24x24, herda a cor do texto. Usada na interface e nos documentos.
|
|
4
|
-
========================================================================== */
|
|
5
|
-
|
|
6
|
-
var ICONES = {
|
|
7
|
-
/* interface */
|
|
8
|
-
cursor: "M4 3l7 17 2.5-6.5L20 11z",
|
|
9
|
-
texto: "M5 6V4h14v2M12 4v16M9 20h6",
|
|
10
|
-
titulo: "M5 5v14M13 5v14M5 12h8M17 9h3v10M17 9l3-2",
|
|
11
|
-
lista: "M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01",
|
|
12
|
-
quadrado: "M4 4h16v16H4z",
|
|
13
|
-
circulo: "M12 3a9 9 0 100 18 9 9 0 000-18z",
|
|
14
|
-
triangulo: "M12 4l9 16H3z",
|
|
15
|
-
linha: "M4 20L20 4",
|
|
16
|
-
seta: "M4 12h15M14 6l6 6-6 6",
|
|
17
|
-
imagem: "M3 5h18v14H3zM3 15l5-5 4 4 3-3 6 6",
|
|
18
|
-
icone: "M12 3l2.6 5.6 6.1.8-4.5 4.2 1.2 6.1L12 16.8 6.6 19.7l1.2-6.1L3.3 9.4l6.1-.8z",
|
|
19
|
-
grafico: "M4 20V10M10 20V4M16 20v-7M22 20H2",
|
|
20
|
-
cartao: "M3 5h8v6H3zM13 5h8v6h-8zM3 13h8v6H3zM13 13h8v6h-8z",
|
|
21
|
-
numero: "M6 20V8l-2 1M12 20V4M18 20v-6l-2 1",
|
|
22
|
-
tabela: "M3 5h18v14H3zM3 10h18M9 10v9M15 10v9",
|
|
23
|
-
codigo: "M9 7l-5 5 5 5M15 7l5 5-5 5",
|
|
24
|
-
citacao: "M8 6c-2.5 0-4 2-4 4.5S5.5 15 8 15c0 3-2 4-2 4 5 0 8-3.5 8-9 0-2.5-2-4-3-4zM19 6c-2 0-3 1.5-3 4 0 5.5 3 9 8 9 0 0-2-1-2-4 2.5 0 4-2 4-4.5S21.5 6 19 6z",
|
|
25
|
-
no: "M5 8h14v8H5zM12 3v5M12 16v5",
|
|
26
|
-
conector: "M6 6a3 3 0 100 6 3 3 0 000-6zM18 12a3 3 0 100 6 3 3 0 000-6zM8.5 10.5L15.5 14",
|
|
27
|
-
video: "M3 6h13v12H3zM16 10l5-3v10l-5-3",
|
|
28
|
-
lapis: "M4 20l4-1 11-11-3-3L5 16z",
|
|
29
|
-
cor: "M12 3a9 9 0 000 18c1 0 2-.8 2-1.8 0-1.5-1.4-1.7-1.4-3 0-1 .8-1.7 1.8-1.7H16a5 5 0 005-5c0-3.6-4-6.5-9-6.5z",
|
|
30
|
-
camada: "M12 3l9 5-9 5-9-5zM3 13l9 5 9-5",
|
|
31
|
-
mais: "M12 5v14M5 12h14",
|
|
32
|
-
menos: "M5 12h14",
|
|
33
|
-
lixeira: "M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13",
|
|
34
|
-
duplicar: "M8 8h12v12H8zM4 16V4h12",
|
|
35
|
-
subir: "M12 19V5M6 11l6-6 6 6",
|
|
36
|
-
descer: "M12 5v14M6 13l6 6 6-6",
|
|
37
|
-
play: "M7 4l13 8-13 8z",
|
|
38
|
-
pausa: "M8 5h3v14H8zM13 5h3v14h-3z",
|
|
39
|
-
olho: "M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7zM12 9a3 3 0 100 6 3 3 0 000-6z",
|
|
40
|
-
baixar: "M12 4v11M7 11l5 5 5-5M4 20h16",
|
|
41
|
-
tela: "M3 4h18v13H3zM8 21h8M12 17v4",
|
|
42
|
-
voltar: "M4 9h11a4 4 0 010 8h-6M4 9l4-4M4 9l4 4",
|
|
43
|
-
refazer: "M20 9H9a4 4 0 000 8h6M20 9l-4-4M20 9l-4 4",
|
|
44
|
-
fechar: "M6 6l12 12M18 6L6 18",
|
|
45
|
-
check: "M4 12l5 5L20 6",
|
|
46
|
-
livro: "M4 5h7a2 2 0 012 2v12a2 2 0 00-2-2H4zM20 5h-7a2 2 0 00-2 2v12a2 2 0 012-2h7z",
|
|
47
|
-
raio2: "M13 2L4 14h6l-1 8 9-12h-6z",
|
|
48
|
-
|
|
49
|
-
/* conteúdo — para o elemento "icone" */
|
|
50
|
-
raio: "M13 2L4 14h6l-1 8 9-12h-6z",
|
|
51
|
-
alvo: "M12 3a9 9 0 100 18 9 9 0 000-18zM12 8a4 4 0 100 8 4 4 0 000-8zM12 11.5a.5.5 0 100 1 .5.5 0 000-1z",
|
|
52
|
-
foguete: "M12 3c4 2 6 6 6 10l-3 3H9l-3-3c0-4 2-8 6-10zM9 16l-3 5 4-2M15 16l3 5-4-2M12 9a1.5 1.5 0 100 3 1.5 1.5 0 000-3z",
|
|
53
|
-
escudo: "M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z",
|
|
54
|
-
relogio: "M12 3a9 9 0 100 18 9 9 0 000-18zM12 7v5l3 2",
|
|
55
|
-
usuario: "M12 4a4 4 0 100 8 4 4 0 000-8zM4 21c0-4 3.5-6 8-6s8 2 8 6",
|
|
56
|
-
coracao: "M12 20S3 14 3 8.5A4.5 4.5 0 0112 6a4.5 4.5 0 019 2.5C21 14 12 20 12 20z",
|
|
57
|
-
estrela: "M12 3l2.6 5.6 6.1.8-4.5 4.2 1.2 6.1L12 16.8 6.6 19.7l1.2-6.1L3.3 9.4l6.1-.8z",
|
|
58
|
-
nuvem: "M7 18a4 4 0 010-8 5.5 5.5 0 0110.5 1.5A3.5 3.5 0 0117 18z",
|
|
59
|
-
engrenagem: "M12 9a3 3 0 100 6 3 3 0 000-6zM19 12l2-1.5-2-3.5-2.4.8a7 7 0 00-2-1.2L14 4h-4l-.6 2.6a7 7 0 00-2 1.2L5 7l-2 3.5L5 12l-2 1.5L5 17l2.4-.8a7 7 0 002 1.2L10 20h4l.6-2.6a7 7 0 002-1.2L19 17l2-3.5z",
|
|
60
|
-
lampada: "M9 18h6M10 21h4M12 3a6 6 0 00-4 10.5c.7.8 1 1.5 1 2.5h6c0-1 .3-1.7 1-2.5A6 6 0 0012 3z",
|
|
61
|
-
cadeado: "M5 11h14v10H5zM8 11V8a4 4 0 018 0v3",
|
|
62
|
-
casa: "M4 11l8-7 8 7v9h-5v-6h-6v6H4z",
|
|
63
|
-
email: "M3 6h18v12H3zM3 7l9 6 9-6",
|
|
64
|
-
telefone: "M6 3h4l2 5-2.5 1.5a12 12 0 005 5L16 12l5 2v4a2 2 0 01-2 2C11 20 4 13 4 5a2 2 0 012-2z",
|
|
65
|
-
camera: "M4 8h4l1.5-2h5L16 8h4v11H4zM12 10.5a3.5 3.5 0 100 7 3.5 3.5 0 000-7z",
|
|
66
|
-
fogo: "M12 3s5 4 5 9a5 5 0 01-10 0c0-2 1-3 1-3s.5 2 2 2c0-3 2-5 2-8z",
|
|
67
|
-
globo: "M12 3a9 9 0 100 18 9 9 0 000-18zM3 12h18M12 3c2.5 3 2.5 15 0 18M12 3c-2.5 3-2.5 15 0 18",
|
|
68
|
-
chave: "M14 4a5 5 0 015 5 5 5 0 01-6.5 4.8L11 16H9v2H7v2H3v-4l7.2-7.2A5 5 0 0114 4zM16 8a1 1 0 100 2 1 1 0 000-2z",
|
|
69
|
-
presente: "M3 11h18v9H3zM3 7h18v4H3zM12 7v13M12 7C10 3 6 4 7 7M12 7c2-4 6-3 5 0",
|
|
70
|
-
sino: "M12 3a6 6 0 00-6 6c0 5-2 6-2 6h16s-2-1-2-6a6 6 0 00-6-6zM10 19a2 2 0 004 0",
|
|
71
|
-
mapa: "M9 4L3 6v14l6-2 6 2 6-2V4l-6 2zM9 4v14M15 6v14",
|
|
72
|
-
dinheiro: "M12 4v16M15.5 8c0-1.4-1.6-2.2-3.5-2.2S8.5 6.7 8.5 8.3 10.4 10.5 12 11s3.5 1 3.5 2.7-1.6 2.5-3.5 2.5-3.5-.9-3.5-2.4",
|
|
73
|
-
crescimento: "M4 18l5-5 3 3 8-8M15 8h5v5",
|
|
74
|
-
pessoas: "M9 5a3.5 3.5 0 100 7 3.5 3.5 0 000-7zM2 20c0-3.5 3-5 7-5s7 1.5 7 5M17 6a3 3 0 110 6M18 20c0-2.5-.8-4-2-4.6",
|
|
75
|
-
balao: "M4 5h16v11H9l-5 4z",
|
|
76
|
-
pasta: "M3 6h6l2 3h10v10H3z",
|
|
77
|
-
play2: "M12 3a9 9 0 100 18 9 9 0 000-18zM10 8.5l6 3.5-6 3.5z",
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
function svgIcone(nome, cls) {
|
|
81
|
-
var d = ICONES[nome] || ICONES.circulo;
|
|
82
|
-
return '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" ' +
|
|
83
|
-
'stroke-linecap="round" stroke-linejoin="round"' + (cls ? ' class="' + cls + '"' : "") +
|
|
84
|
-
"><path d=\"" + d + '"/></svg>';
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function nomesIcones() {
|
|
88
|
-
return Object.keys(ICONES);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/* O ícone que a IA DESENHA, quando o que ela precisa não está na lista.
|
|
92
|
-
*
|
|
93
|
-
* "A IA irá desenvolver ícones."
|
|
94
|
-
*
|
|
95
|
-
* `caminho` é o path SVG numa caixa de 24×24 — uma string, ou uma lista de
|
|
96
|
-
* strings (um traço por peça). Sai no MESMO traço dos ícones da casa (1.7,
|
|
97
|
-
* cantos redondos, cor do texto), para o desenhado não destoar do pronto.
|
|
98
|
-
*
|
|
99
|
-
* Só entram os caracteres de path: letra de comando, número, espaço,
|
|
100
|
-
* vírgula. Nada mais — isto vira innerHTML numa página nossa, e o documento
|
|
101
|
-
* foi escrito por um modelo. Path inválido cai no círculo, que é o mesmo
|
|
102
|
-
* destino de um nome que não existe: o erro fica visível e inofensivo. */
|
|
103
|
-
// Começa em M/m: todo path de verdade abre com um moveto, e "42" sozinho
|
|
104
|
-
// não é desenho nenhum.
|
|
105
|
-
var CAMINHO_OK = /^[Mm][MmZzLlHhVvCcSsQqTtAa0-9\s,.\-+eE]*$/;
|
|
106
|
-
|
|
107
|
-
function svgCaminho(caminho, op) {
|
|
108
|
-
op = op || {};
|
|
109
|
-
var lista = Array.isArray(caminho) ? caminho : [caminho];
|
|
110
|
-
var ds = lista.map(function (d) { return String(d == null ? "" : d).trim(); })
|
|
111
|
-
.filter(function (d) { return d && d.length <= 4000 && CAMINHO_OK.test(d); });
|
|
112
|
-
if (!ds.length) return svgIcone("circulo", op.cls);
|
|
113
|
-
var fill = op.preenchido ? "currentColor" : "none";
|
|
114
|
-
return '<svg viewBox="0 0 24 24" fill="' + fill + '" stroke="currentColor" stroke-width="' +
|
|
115
|
-
(Number(op.traco) > 0 ? Number(op.traco) : 1.7) + '" stroke-linecap="round" stroke-linejoin="round"' +
|
|
116
|
-
(op.cls ? ' class="' + op.cls + '"' : "") + ">" +
|
|
117
|
-
ds.map(function (d) { return '<path d="' + d + '"/>'; }).join("") + "</svg>";
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (typeof module !== "undefined" && module.exports) module.exports = { ICONES: ICONES, svgIcone: svgIcone, svgCaminho: svgCaminho, CAMINHO_OK: CAMINHO_OK };
|
package/studio/web/js/midia.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/* ==========================================================================
|
|
2
|
-
midia.js — biblioteca de arquivos do computador (imagem, áudio, vídeo).
|
|
3
|
-
|
|
4
|
-
Midia.escolher({ tipo: "imagem" | "audio" }) → Promise<{url, nome, tipo}>
|
|
5
|
-
Aceita upload por botão ou arrastando o arquivo para dentro da janela.
|
|
6
|
-
========================================================================== */
|
|
7
|
-
|
|
8
|
-
var Midia = (function () {
|
|
9
|
-
"use strict";
|
|
10
|
-
|
|
11
|
-
var LIMITE_MB = 60;
|
|
12
|
-
|
|
13
|
-
function el(tag, cls, html) {
|
|
14
|
-
var n = document.createElement(tag);
|
|
15
|
-
if (cls) n.className = cls;
|
|
16
|
-
if (html != null) n.innerHTML = html;
|
|
17
|
-
return n;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function kb(bytes) {
|
|
21
|
-
return bytes > 1048576 ? (bytes / 1048576).toFixed(1) + " MB"
|
|
22
|
-
: Math.max(1, Math.round(bytes / 1024)) + " KB";
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function listar() {
|
|
26
|
-
return fetch("/api/midia").then(function (r) { return r.json(); });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* Envia um File do computador para o servidor. */
|
|
30
|
-
function enviar(arquivo) {
|
|
31
|
-
if (arquivo.size > LIMITE_MB * 1048576) {
|
|
32
|
-
return Promise.reject(new Error("arquivo acima de " + LIMITE_MB + " MB"));
|
|
33
|
-
}
|
|
34
|
-
return new Promise(function (ok, falha) {
|
|
35
|
-
var leitor = new FileReader();
|
|
36
|
-
leitor.onerror = function () { falha(new Error("não consegui ler o arquivo")); };
|
|
37
|
-
leitor.onload = function () {
|
|
38
|
-
fetch("/api/midia", {
|
|
39
|
-
method: "POST",
|
|
40
|
-
headers: { "Content-Type": "application/json" },
|
|
41
|
-
body: JSON.stringify({ nome: arquivo.name, dados: leitor.result }),
|
|
42
|
-
}).then(function (r) { return r.json(); })
|
|
43
|
-
.then(function (m) { m.erro ? falha(new Error(m.erro)) : ok(m); })
|
|
44
|
-
.catch(falha);
|
|
45
|
-
};
|
|
46
|
-
leitor.readAsDataURL(arquivo);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function apagar(nome) {
|
|
51
|
-
return fetch("/api/midia/" + encodeURIComponent(nome), { method: "DELETE" });
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/* ------------------------------------------------------------- modal -- */
|
|
55
|
-
|
|
56
|
-
function escolher(op) {
|
|
57
|
-
op = op || {};
|
|
58
|
-
var tipo = op.tipo || "imagem";
|
|
59
|
-
|
|
60
|
-
return new Promise(function (resolver) {
|
|
61
|
-
var folha = el("div", "folha midia on");
|
|
62
|
-
folha.innerHTML =
|
|
63
|
-
'<div class="caixa">' +
|
|
64
|
-
'<div class="midia-topo">' +
|
|
65
|
-
"<h3>" + (tipo === "audio" ? "Áudio do computador" : "Imagens") + "</h3>" +
|
|
66
|
-
'<div style="flex:1"></div>' +
|
|
67
|
-
'<button class="btn" data-x="fechar">Fechar</button>' +
|
|
68
|
-
'<button class="btn primo" data-x="subir">Escolher arquivo</button>' +
|
|
69
|
-
"</div>" +
|
|
70
|
-
'<div class="solta" data-x="solta">Arraste um arquivo aqui — ou clique em ' +
|
|
71
|
-
"<b>Escolher arquivo</b>. Até " + LIMITE_MB + " MB.</div>" +
|
|
72
|
-
'<div class="midia-grade" data-x="grade"></div>' +
|
|
73
|
-
"</div>";
|
|
74
|
-
document.body.appendChild(folha);
|
|
75
|
-
|
|
76
|
-
var entrada = el("input");
|
|
77
|
-
entrada.type = "file";
|
|
78
|
-
entrada.accept = tipo === "audio" ? "audio/*" : "image/*";
|
|
79
|
-
entrada.style.display = "none";
|
|
80
|
-
folha.appendChild(entrada);
|
|
81
|
-
|
|
82
|
-
var grade = folha.querySelector('[data-x="grade"]');
|
|
83
|
-
var solta = folha.querySelector('[data-x="solta"]');
|
|
84
|
-
|
|
85
|
-
function fechar(resultado) {
|
|
86
|
-
folha.remove();
|
|
87
|
-
document.removeEventListener("dragover", pegaArrasto);
|
|
88
|
-
document.removeEventListener("drop", pegaSolta);
|
|
89
|
-
resolver(resultado || null);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function desenhar() {
|
|
93
|
-
grade.innerHTML = '<div class="vazio-midia">carregando…</div>';
|
|
94
|
-
listar().then(function (lista) {
|
|
95
|
-
var itens = lista.filter(function (m) { return m.tipo === tipo; });
|
|
96
|
-
if (!itens.length) {
|
|
97
|
-
grade.innerHTML = '<div class="vazio-midia">Nada aqui ainda. ' +
|
|
98
|
-
(tipo === "audio" ? "Suba uma música que você já tem no computador."
|
|
99
|
-
: "Suba uma imagem para começar.") + "</div>";
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
grade.innerHTML = "";
|
|
103
|
-
itens.forEach(function (m) {
|
|
104
|
-
var c = el("div", "midia-item");
|
|
105
|
-
c.innerHTML = (tipo === "audio"
|
|
106
|
-
? '<div class="mini-audio">' + svgIcone("play2") + "</div>"
|
|
107
|
-
: '<div class="mini-img" style="background-image:url(\'' + m.url + '\')"></div>') +
|
|
108
|
-
'<div class="mini-nome" title="' + m.nome + '">' + m.nome + "</div>" +
|
|
109
|
-
'<div class="mini-meta">' + kb(m.bytes) + "</div>" +
|
|
110
|
-
'<button class="mini-x" title="Apagar">×</button>';
|
|
111
|
-
c.onclick = function (ev) {
|
|
112
|
-
if (ev.target.classList.contains("mini-x")) {
|
|
113
|
-
ev.stopPropagation();
|
|
114
|
-
apagar(m.nome).then(desenhar);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
fechar(m);
|
|
118
|
-
};
|
|
119
|
-
grade.appendChild(c);
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
function subir(arquivo) {
|
|
125
|
-
if (!arquivo) return;
|
|
126
|
-
solta.textContent = "enviando " + arquivo.name + "…";
|
|
127
|
-
enviar(arquivo).then(function (m) {
|
|
128
|
-
solta.textContent = "pronto: " + m.nome;
|
|
129
|
-
if (op.direto) return fechar(m);
|
|
130
|
-
desenhar();
|
|
131
|
-
}).catch(function (e) {
|
|
132
|
-
solta.textContent = "erro: " + e.message;
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
folha.addEventListener("click", function (ev) {
|
|
137
|
-
var acao = (ev.target.dataset || {}).x;
|
|
138
|
-
if (acao === "fechar" || ev.target === folha) fechar(null);
|
|
139
|
-
if (acao === "subir" || acao === "solta") entrada.click();
|
|
140
|
-
});
|
|
141
|
-
entrada.onchange = function () { subir(entrada.files[0]); };
|
|
142
|
-
|
|
143
|
-
function pegaArrasto(ev) { ev.preventDefault(); solta.classList.add("ativo"); }
|
|
144
|
-
function pegaSolta(ev) {
|
|
145
|
-
ev.preventDefault();
|
|
146
|
-
solta.classList.remove("ativo");
|
|
147
|
-
subir(ev.dataTransfer.files[0]);
|
|
148
|
-
}
|
|
149
|
-
document.addEventListener("dragover", pegaArrasto);
|
|
150
|
-
document.addEventListener("drop", pegaSolta);
|
|
151
|
-
|
|
152
|
-
desenhar();
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return { escolher: escolher, enviar: enviar, listar: listar, apagar: apagar };
|
|
157
|
-
})();
|