/* Site DTF — Accepting files: the drop zone, the accept rules, first measurement. Extracted verbatim from the single inline script in web/index.html. Loaded as classic scripts in the order listed there: they share one global scope and run top to bottom, exactly as the original did. */ // ── upload // Untrusted filenames and recovered cart text must never become HTML. function escapeHTML(value){ return String(value).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); } function recusa(lista){ const el=$('recusa'); if(!el) return; if(!lista.length){ el.style.display='none'; el.innerHTML=''; return; } const exts=escapeHTML([...new Set(lista.map(f=>extDe(f.name)))].join(', ')); el.style.display='block'; el.innerHTML = ehFolha() ? ''+exts+' não dá para enviar aqui. A folha pronta aceita PNG, JPG, TIFF, '+ 'PDF, PSD, AI e CDR.' : ''+exts+' não dá para enviar aqui. Artes avulsas precisam de PNG ou JPG com '+ 'fundo transparente — é o que a montagem enxerga para encaixar. '+ 'Se o seu arquivo é CDR, AI ou PSD, exporte em PNG ou use Arquivo por metro.'; } const Z=$('zona'), I=$('inp'); Z.addEventListener('click',()=>I.click()); Z.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){I.click();e.preventDefault();}}); ['dragover','dragenter'].forEach(ev=>Z.addEventListener(ev,e=>{e.preventDefault();Z.classList.add('sobre')})); ['dragleave','drop'].forEach(ev=>Z.addEventListener(ev,e=>{ e.preventDefault(); Z.classList.remove('sobre'); if(ev==='drop') sel([...e.dataTransfer.files]); })); I.addEventListener('change',()=>sel([...I.files])); function sel(fs){ if(!fs.length) return; // Pixels cannot tell a loose artwork from a finished sheet, so the customer // declares it by choosing the product in the selector above. The declaration is // verified in medirFolha; the file never changes product or price on its own. const regra = ehFolha() ? ACEITA.folha : ACEITA.avulsa; const fora = fs.filter(f=>!regra.test(f.name)); fs = fs.filter(f=>regra.test(f.name)); recusa(fora); const max=window.dtfUploadMaxBytes||5*1073741824; const grandes=fs.filter(f=>f.size>max); if(grandes.length){ const el=$('recusa'); el.style.display='block'; el.innerHTML='Arquivo acima do limite de '+(max/1073741824).toFixed(0)+ ' GB. Divida a folha em partes menores antes de enviar.'; fs=fs.filter(f=>f.size<=max); } if(!fs.length) return; if(ehFolha()){ const novas=fs.map(f=>({f, med:null, rep:1, m:0, semAnalise:null})); folhas=folhas.concat(novas); // soma, não substitui pintaFolha(); novas.forEach(x=>{ x.pct=5; pintaFolha(); medirFolha(x.f).then(md=>{ if(md && md.rejected){ x.measurementError=md.reason; x.pct=null; pintaFolha(); return; } if(md && md.dpiFolha!=null && md.dpiFolha{ const pct=60+Math.floor(p*38); x.leitura.p=p; if(pct-mostrado>=1){ mostrado=pct; x.pct=pct; pintaProgressoFolha(x); } }).then(cv=>{ if(cv && folhas.includes(x)){ x.previewSrc=cv.toDataURL('image/webp',0.85); x.miniSrc=miniatura(cv); try{ const an=analisarFolha(cv, md.larg); x.an={...an, dpi:md.dpiFolha, fonteDpi:'arquivo', grande:false}; }catch(e){} } }).catch(()=>{}).finally(()=>{ x.pct=null; pintaFolha(); }); }else if(md && RENDERIZA.test(x.f.name)){ carregarImagem(x.f).then(img=>{ if(img){ x.previewSrc=img.src; x.miniSrc=miniatura(img); try{ x.an=analisarFolha(img, md.larg); if(x.an) x.an.fonteDpi='arquivo'; } catch(e){} } x.pct=null; pintaFolha(); }); }else if(md && /\.pdf$/i.test(x.f.name) && x.f.size>GRANDE_BYTES){ x.semAnalise='PDF grande: a resolução das imagens de dentro é conferida pela equipe'; x.pct=null; pintaFolha(); }else if(md && /\.pdf$/i.test(x.f.name)){ x.pct=70; pintaFolha(); rasterizarPdf(x.f, md.larg, md.alt).then(r=>{ if(r && r.erro){ x.semAnalise = r.erro + (r.semWorker ? ' · este navegador não deixa o leitor rodar em segundo plano' : ''); } if(r && r.tela){ x.miniSrc=miniatura(r.tela); try{ x.an=analisarFolha(r.tela, md.larg); // vetor puro não tem resolução · nota máxima, e está certo x.an.dpi = r.dpi==null ? DPI_AVISA : r.dpi; x.an.vetor = r.dpi==null; x.an.fonteDpi = r.dpi==null ? 'vetor' : 'imagens'; x.an.res = r.res || null; }catch(e){} } x.pct=null; pintaFolha(); }); }else{ x.pct=null; pintaFolha(); } }); }); return; } const novos=fs.map(f=>({f,px:0,py:0,cm:0,q:1,prop:1,giro:0,esp:false})); artes=novos.concat(artes); // a mais recente fica no topo da fila recemChegada=novos[0]; pintaArtes(); $('lista').scrollIntoView({behavior:'smooth',block:'nearest'}); Promise.all(novos.map(medir)).then(pintaArtes); } function medir(a){ // A large artwork is measured from its header and packed from a small copy // read as a stream (previaPngGrande); the file itself is never decoded. if(a.f.size>GRANDE_BYTES){ return dimensoesImagem(a.f).then(async d=>{ if(!d || !(d.w>0) || !(d.h>0)){ a.decodeError=true; return a; } a.px=d.w; a.py=d.h; a.prop=d.h/d.w; a.grande=true; // JPG and WebP cannot be read in parts: the art is placed by its // measurements, as a full box, and the team checks it before printing. if(!/\.png$/i.test(a.f.name)){ a.semPrevia=true; return a; } a.lendo=0; a.leitura={inicio:Date.now(), p:0}; pintaArtes(); let mostrado=0; const cv=await previaPngGrande(a.f, 1200, p=>{ const pct=Math.floor(p*100); a.leitura.p=p; if(pct-mostrado>=1){ mostrado=pct; a.lendo=pct; pintaProgressoArte(a); } }).catch(()=>null); a.lendo=null; if(cv && artes.includes(a)){ a.src=cv.toDataURL('image/webp',0.9); a.miniSrc=miniatura(cv); } else if(!cv) a.decodeError=true; return a; }).catch(()=>{ a.decodeError=true; return a; }); } return carregarImagem(a.f).then(img=>{ if(img){ a.prop=img.height/img.width; a.px=img.width; a.py=img.height; a.src=img.src; a.miniSrc=miniatura(img); } else a.decodeError=true; return a; }); } // A metragem sai do arquivo, nunca do peso em bytes. // imagem → proporção da imagem aplicada à largura do filme // PDF → página única lida pelo PDF.js, com boxes, rotação e UserUnit // TIFF, PSD, AI, CDR → o navegador não abre; o cliente informa o comprimento