Initial commit SteelBase - Oficiais e Funcionando
This commit is contained in:
7268
ORIGINAL/app.js
Normal file
7268
ORIGINAL/app.js
Normal file
File diff suppressed because it is too large
Load Diff
908
ORIGINAL/calculations.js
Normal file
908
ORIGINAL/calculations.js
Normal file
@@ -0,0 +1,908 @@
|
||||
// ========================================
|
||||
// CONTINUATION OF CALCULATION FUNCTIONS
|
||||
// ========================================
|
||||
|
||||
// Bolts Calculation
|
||||
function calcularParafusos() {
|
||||
const fy = parseFloat(document.getElementById('bolt-type').value) || 400;
|
||||
const d = parseFloat(document.getElementById('bolt-d').value) || 20;
|
||||
const qty = parseInt(document.getElementById('bolt-qty').value) || 1;
|
||||
const planes = parseInt(document.getElementById('bolt-planes').value) || 1;
|
||||
const force = parseFloat(document.getElementById('bolt-force').value) || 0;
|
||||
|
||||
const area = Math.PI * Math.pow(d / 2, 2);
|
||||
const Fv = 0.6 * fy * area * planes / 1000;
|
||||
const capacity = Fv * qty;
|
||||
const utilization = (force / capacity) * 100;
|
||||
|
||||
let alertClass = 'alert-success';
|
||||
let status = '✅ OK - Capacidade adequada';
|
||||
if (utilization > 100) {
|
||||
alertClass = 'alert-error';
|
||||
status = '❌ FALHA - Capacidade insuficiente';
|
||||
} else if (utilization > 80) {
|
||||
alertClass = 'alert-warning';
|
||||
status = '⚠️ ATENÇÃO - Utilização elevada';
|
||||
}
|
||||
|
||||
document.getElementById('bolt-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Verificação ao Cisalhamento</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Área Parafuso</div>
|
||||
<div class="result-value">${area.toFixed(0)} mm²</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Fv por Parafuso</div>
|
||||
<div class="result-value">${Fv.toFixed(1)} kN</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Capacidade Total</div>
|
||||
<div class="result-value">${capacity.toFixed(1)} kN</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Utilização</div>
|
||||
<div class="result-value">${utilization.toFixed(1)}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||||
<strong>${status}</strong>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Ligações Parafusadas', `${qty} parafusos Ø${d}mm, Utilização = ${utilization.toFixed(1)}%`);
|
||||
}
|
||||
|
||||
// Layout Verification
|
||||
function verificarLayout() {
|
||||
const d = parseFloat(document.getElementById('layout-d').value) || 20;
|
||||
const edge = parseFloat(document.getElementById('layout-edge').value) || 0;
|
||||
const spacing = parseFloat(document.getElementById('layout-spacing').value) || 0;
|
||||
|
||||
const minEdge = 1.5 * d;
|
||||
const maxEdge = 12 * 10;
|
||||
const minSpacing = 2.67 * d;
|
||||
const maxSpacing = 300;
|
||||
|
||||
let edgeStatus = '✅ Conforme';
|
||||
let edgeClass = 'alert-success';
|
||||
if (edge < minEdge) {
|
||||
edgeStatus = `❌ Abaixo do mínimo (${minEdge.toFixed(1)}mm)`;
|
||||
edgeClass = 'alert-error';
|
||||
} else if (edge > maxEdge) {
|
||||
edgeStatus = `⚠️ Acima do máximo (${maxEdge}mm)`;
|
||||
edgeClass = 'alert-warning';
|
||||
}
|
||||
|
||||
let spacingStatus = '✅ Conforme';
|
||||
let spacingClass = 'alert-success';
|
||||
if (spacing < minSpacing) {
|
||||
spacingStatus = `❌ Abaixo do mínimo (${minSpacing.toFixed(1)}mm)`;
|
||||
spacingClass = 'alert-error';
|
||||
} else if (spacing > maxSpacing) {
|
||||
spacingStatus = `⚠️ Acima do máximo (${maxSpacing}mm)`;
|
||||
spacingClass = 'alert-warning';
|
||||
}
|
||||
|
||||
document.getElementById('layout-result').innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-title">Verificação NBR 8800</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Dist. Borda Mín</div>
|
||||
<div class="result-value" style="font-size: 18px;">${minEdge.toFixed(1)} mm</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Dist. Borda Máx</div>
|
||||
<div class="result-value" style="font-size: 18px;">${maxEdge} mm</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Espaç. Mínimo</div>
|
||||
<div class="result-value" style="font-size: 18px;">${minSpacing.toFixed(1)} mm</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Espaç. Máximo</div>
|
||||
<div class="result-value" style="font-size: 18px;">${maxSpacing} mm</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert ${edgeClass}" style="margin-top: 16px;">
|
||||
<strong>Distância de Borda: ${edgeStatus}</strong>
|
||||
</div>
|
||||
<div class="alert ${spacingClass}">
|
||||
<strong>Espaçamento: ${spacingStatus}</strong>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Layout de Furação', `Ø${d}mm, Borda: ${edge}mm, Espaç: ${spacing}mm`);
|
||||
}
|
||||
|
||||
// Bolt vs Weld Comparison
|
||||
function compararParafusoSolda() {
|
||||
const force = parseFloat(document.getElementById('comp-force').value) || 0;
|
||||
const length = parseFloat(document.getElementById('comp-length').value) || 0;
|
||||
const fy = parseFloat(document.getElementById('comp-fy').value) || 345;
|
||||
|
||||
// Parafusos A325 Ø20mm
|
||||
const boltCapacity = 60;
|
||||
const boltQty = Math.ceil(force / boltCapacity);
|
||||
const boltCost = boltQty * 15;
|
||||
|
||||
// Solda
|
||||
const weldLeg = (force * 1000) / (0.707 * length * 0.65 * fy);
|
||||
const weldLegRounded = Math.ceil(weldLeg);
|
||||
const weldCost = (weldLegRounded * length / 1000) * 25;
|
||||
|
||||
document.getElementById('comparison-result').innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-title">Comparação de Soluções</div>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||||
<div style="background: var(--color-bg-1); padding: 20px; border-radius: 12px;">
|
||||
<h3 style="color: var(--color-primary); margin-bottom: 16px;">🔩 Solução Parafusada</h3>
|
||||
<p><strong>Tipo:</strong> A325 Ø20mm</p>
|
||||
<p><strong>Quantidade:</strong> ${boltQty} parafusos</p>
|
||||
<p><strong>Capacidade:</strong> ${(boltQty * boltCapacity).toFixed(1)} kN</p>
|
||||
<p><strong>Custo estimado:</strong> R$ ${boltCost.toFixed(2)}</p>
|
||||
<p><strong>Vantagens:</strong> Desmontável, inspeção visual</p>
|
||||
<p><strong>Desvantagens:</strong> Maior tempo de instalação</p>
|
||||
</div>
|
||||
<div style="background: var(--color-bg-2); padding: 20px; border-radius: 12px;">
|
||||
<h3 style="color: var(--color-warning); margin-bottom: 16px;">🔥 Solução Soldada</h3>
|
||||
<p><strong>Tipo:</strong> Solda de filete</p>
|
||||
<p><strong>Perna:</strong> ${weldLegRounded} mm</p>
|
||||
<p><strong>Comprimento:</strong> ${length} mm</p>
|
||||
<p><strong>Custo estimado:</strong> R$ ${weldCost.toFixed(2)}</p>
|
||||
<p><strong>Vantagens:</strong> Melhor rigidez, econômica</p>
|
||||
<p><strong>Desvantagens:</strong> Permanente, requer qualificação</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-success" style="margin-top: 20px;">
|
||||
<strong>Recomendação:</strong> ${weldCost < boltCost ? 'Solda de filete é mais econômica' : 'Parafusos mais econômicos'}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Parafuso vs Solda', `${boltQty} parafusos vs solda ${weldLegRounded}mm`);
|
||||
}
|
||||
|
||||
// Preheat Calculation
|
||||
function calcularPreaquecimento() {
|
||||
const cev = parseFloat(document.getElementById('preheat-cev').value) || 0;
|
||||
const thickness = parseFloat(document.getElementById('preheat-thickness').value) || 0;
|
||||
const ambient = parseFloat(document.getElementById('preheat-ambient').value) || 20;
|
||||
|
||||
const preheatTemp = 50 + (cev * 100) + (thickness / 10 * 20) + ((20 - ambient) / 2);
|
||||
const maxInterpass = preheatTemp + 100;
|
||||
|
||||
let pwhtRecommendation = '';
|
||||
if (thickness > 50 || cev > 0.60) {
|
||||
pwhtRecommendation = '⚠️ PWHT (Tratamento Térmico Pós-Soldagem) recomendado';
|
||||
} else {
|
||||
pwhtRecommendation = '✅ PWHT não obrigatório';
|
||||
}
|
||||
|
||||
document.getElementById('preheat-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Temperatura de Pré-Aquecimento (AWS D1.1)</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Temp. Mínima</div>
|
||||
<div class="result-value">${Math.round(preheatTemp)}°C</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Temp. Interpasse Máx</div>
|
||||
<div class="result-value">${Math.round(maxInterpass)}°C</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-warning" style="margin-top: 16px;">
|
||||
<strong>${pwhtRecommendation}</strong>
|
||||
</div>
|
||||
<div class="expert-only" style="margin-top: 16px; padding: 16px; background: var(--color-bg-3); border-radius: 8px;">
|
||||
<strong>Procedimento:</strong><br>
|
||||
1. Aquecer uniformemente até ${Math.round(preheatTemp)}°C<br>
|
||||
2. Medir temperatura a 75mm da junta<br>
|
||||
3. Manter durante toda a soldagem<br>
|
||||
4. Temperatura interpasse máxima: ${Math.round(maxInterpass)}°C
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Pré-Aquecimento', `CEV=${cev}, esp=${thickness}mm → ${Math.round(preheatTemp)}°C`);
|
||||
}
|
||||
|
||||
// Weld Fillet Calculation
|
||||
function calcularSoldaFilete() {
|
||||
const force = parseFloat(document.getElementById('weld-force').value) || 0;
|
||||
const length = parseFloat(document.getElementById('weld-length').value) || 0;
|
||||
const fy = parseFloat(document.getElementById('weld-fy').value) || 345;
|
||||
|
||||
const fyWeld = fy * 0.6;
|
||||
const leg = (force * 1000) / (0.707 * length * 0.65 * fyWeld);
|
||||
const throat = leg * 0.707;
|
||||
const legCommercial = Math.ceil(leg);
|
||||
|
||||
const passes = legCommercial <= 5 ? 1 : legCommercial <= 8 ? 2 : 3;
|
||||
|
||||
document.getElementById('weld-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Dimensionamento da Solda de Filete</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Perna Calculada</div>
|
||||
<div class="result-value">${leg.toFixed(2)} mm</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Perna Adotada</div>
|
||||
<div class="result-value">${legCommercial} mm</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Garganta Efetiva</div>
|
||||
<div class="result-value">${throat.toFixed(2)} mm</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Número de Passes</div>
|
||||
<div class="result-value">${passes}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-success" style="margin-top: 16px;">
|
||||
<strong>Eletrodo recomendado:</strong> E${Math.round(fy * 1.15)} (resistência compatível com o aço base)
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Solda de Filete', `Perna ${legCommercial}mm, ${passes} passe(s)`);
|
||||
}
|
||||
|
||||
// Heat Input Calculation
|
||||
function calcularEnergiaSoldagem() {
|
||||
const voltage = parseFloat(document.getElementById('hi-voltage').value) || 0;
|
||||
const current = parseFloat(document.getElementById('hi-current').value) || 0;
|
||||
const speed = parseFloat(document.getElementById('hi-speed').value) || 0;
|
||||
|
||||
const heatInput = (voltage * current * 60) / (speed * 1000);
|
||||
|
||||
let interpretation = '';
|
||||
let alertClass = '';
|
||||
if (heatInput < 1.0) {
|
||||
interpretation = 'Energia baixa - Risco de falta de fusão ou trincas a frio';
|
||||
alertClass = 'alert-warning';
|
||||
} else if (heatInput <= 2.0) {
|
||||
interpretation = 'Energia adequada - Dentro da faixa recomendada';
|
||||
alertClass = 'alert-success';
|
||||
} else {
|
||||
interpretation = 'Energia alta - Risco de fragilização da ZTA e distorção';
|
||||
alertClass = 'alert-error';
|
||||
}
|
||||
|
||||
document.getElementById('hi-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Energia de Soldagem (Heat Input)</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Energia</div>
|
||||
<div class="result-value">${heatInput.toFixed(2)} kJ/mm</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||||
<strong>${interpretation}</strong>
|
||||
</div>
|
||||
<div class="expert-only" style="margin-top: 16px; padding: 16px; background: var(--color-bg-4); border-radius: 8px;">
|
||||
<strong>Fórmula:</strong> HI = (V × I × 60) / (v × 1000)<br>
|
||||
<strong>Recomendações:</strong><br>
|
||||
• Aços carbono: 0.8 - 2.0 kJ/mm<br>
|
||||
• Alta resistência: 0.8 - 1.5 kJ/mm<br>
|
||||
• Baixa liga: 1.0 - 2.5 kJ/mm
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Energia de Soldagem', `HI = ${heatInput.toFixed(2)} kJ/mm`);
|
||||
}
|
||||
|
||||
// Electrode Consumption
|
||||
function calcularConsumoEletrodos() {
|
||||
const leg = parseFloat(document.getElementById('elec-leg').value) || 0;
|
||||
const length = parseFloat(document.getElementById('elec-length').value) || 0;
|
||||
const factor = parseFloat(document.getElementById('elec-type').value) || 1.10;
|
||||
const loss = parseFloat(document.getElementById('elec-loss').value) || 15;
|
||||
|
||||
const throat = leg * 0.707;
|
||||
const volume = throat * leg * length * 1000;
|
||||
const mass = (volume / 1000000) * 7850 / 1000;
|
||||
const consumption = mass * factor * (1 + loss / 100);
|
||||
|
||||
document.getElementById('elec-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Consumo de Eletrodos</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Volume de Solda</div>
|
||||
<div class="result-value">${(volume / 1000).toFixed(1)} cm³</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Massa de Solda</div>
|
||||
<div class="result-value">${mass.toFixed(2)} kg</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Consumo Total</div>
|
||||
<div class="result-value">${consumption.toFixed(2)} kg</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-5); border-radius: 8px;">
|
||||
<strong>Estimativa de embalagens:</strong><br>
|
||||
Eletrodos Ø3,25mm (1 kg cada): ${Math.ceil(consumption)} embalagens
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Consumo de Eletrodos', `${consumption.toFixed(2)} kg para ${length}m de solda`);
|
||||
}
|
||||
|
||||
// Hardness Converter
|
||||
function converterDureza(source) {
|
||||
let HB = 0;
|
||||
|
||||
if (source === 'hb') {
|
||||
HB = parseFloat(document.getElementById('hard-hb').value) || 0;
|
||||
} else if (source === 'hrc') {
|
||||
const HRC = parseFloat(document.getElementById('hard-hrc').value) || 0;
|
||||
HB = (HRC + 9.8) / 0.0338;
|
||||
document.getElementById('hard-hb').value = Math.round(HB);
|
||||
} else if (source === 'hv') {
|
||||
const HV = parseFloat(document.getElementById('hard-hv').value) || 0;
|
||||
HB = HV / 0.95;
|
||||
document.getElementById('hard-hb').value = Math.round(HB);
|
||||
}
|
||||
|
||||
if (HB === 0) return;
|
||||
|
||||
const HRC = HB * 0.0338 - 9.8;
|
||||
const HV = HB * 0.95;
|
||||
const fu = HB * 10;
|
||||
const fy = fu * 0.7;
|
||||
|
||||
if (source !== 'hrc') document.getElementById('hard-hrc').value = HRC.toFixed(1);
|
||||
if (source !== 'hv') document.getElementById('hard-hv').value = Math.round(HV);
|
||||
|
||||
document.getElementById('hardness-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Conversão de Dureza</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">HB (Brinell)</div>
|
||||
<div class="result-value">${Math.round(HB)}</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">HRC (Rockwell C)</div>
|
||||
<div class="result-value">${HRC.toFixed(1)}</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">HV (Vickers)</div>
|
||||
<div class="result-value">${Math.round(HV)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
|
||||
<strong>Estimativa de Resistência:</strong><br>
|
||||
fu ≈ ${fu.toFixed(0)} MPa<br>
|
||||
fy ≈ ${fy.toFixed(0)} MPa (aproximado)
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Charpy Analysis
|
||||
function analisarCharpy() {
|
||||
const temps = [
|
||||
parseFloat(document.getElementById('charpy-t1').value),
|
||||
parseFloat(document.getElementById('charpy-t2').value),
|
||||
parseFloat(document.getElementById('charpy-t3').value),
|
||||
parseFloat(document.getElementById('charpy-t4').value)
|
||||
];
|
||||
|
||||
const energies = [
|
||||
parseFloat(document.getElementById('charpy-e1').value),
|
||||
parseFloat(document.getElementById('charpy-e2').value),
|
||||
parseFloat(document.getElementById('charpy-e3').value),
|
||||
parseFloat(document.getElementById('charpy-e4').value)
|
||||
];
|
||||
|
||||
const validPoints = temps.map((t, i) => ({ temp: t, energy: energies[i] }))
|
||||
.filter(p => !isNaN(p.temp) && !isNaN(p.energy))
|
||||
.sort((a, b) => a.temp - b.temp);
|
||||
|
||||
if (validPoints.length < 2) {
|
||||
alert('Insira pelo menos 2 pontos válidos');
|
||||
return;
|
||||
}
|
||||
|
||||
let ttdf = null;
|
||||
for (let i = 0; i < validPoints.length - 1; i++) {
|
||||
if ((validPoints[i].energy >= 27 && validPoints[i+1].energy < 27) ||
|
||||
(validPoints[i].energy < 27 && validPoints[i+1].energy >= 27)) {
|
||||
const t1 = validPoints[i].temp;
|
||||
const e1 = validPoints[i].energy;
|
||||
const t2 = validPoints[i+1].temp;
|
||||
const e2 = validPoints[i+1].energy;
|
||||
ttdf = t1 + (27 - e1) * (t2 - t1) / (e2 - e1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('charpy-result').innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-title">Curva de Transição Dúctil-Frágil</div>
|
||||
<div class="chart-container">
|
||||
<canvas id="charpy-chart"></canvas>
|
||||
</div>
|
||||
${ttdf !== null ? `
|
||||
<div class="alert alert-success" style="margin-top: 16px;">
|
||||
<strong>TTDF (Temperatura de Transição):</strong> ${ttdf.toFixed(1)}°C<br>
|
||||
Temperatura onde a energia de impacto = 27J
|
||||
</div>
|
||||
` : `
|
||||
<div class="alert alert-warning" style="margin-top: 16px;">
|
||||
<strong>Não foi possível calcular TTDF</strong><br>
|
||||
A curva não intercepta 27J no intervalo medido
|
||||
</div>
|
||||
`}
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (currentChart) {
|
||||
currentChart.destroy();
|
||||
}
|
||||
|
||||
const ctx = document.getElementById('charpy-chart').getContext('2d');
|
||||
currentChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: validPoints.map(p => p.temp + '°C'),
|
||||
datasets: [{
|
||||
label: 'Energia (J)',
|
||||
data: validPoints.map(p => p.energy),
|
||||
borderColor: '#1FB8CD',
|
||||
backgroundColor: '#1FB8CD40',
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Curva de Transição Charpy'
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Energia (J)'
|
||||
}
|
||||
},
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Temperatura (°C)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
addToHistory('Análise Charpy', `${validPoints.length} pontos, TTDF = ${ttdf ? ttdf.toFixed(1) : 'N/A'}°C`);
|
||||
}
|
||||
|
||||
// Certificate Checklist
|
||||
function gerarChecklistCertificado() {
|
||||
const norm = document.getElementById('cert-norm').value;
|
||||
const requirements = certRequirements[norm] || [];
|
||||
|
||||
document.getElementById('cert-result').innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-title">Checklist de Requisitos - ${norm.toUpperCase().replace('_', ' ')}</div>
|
||||
${requirements.map((req, index) => `
|
||||
<div style="padding: 12px; background: var(--color-background); border-radius: 8px; margin-bottom: 8px; display: flex; align-items: center; gap: 12px;">
|
||||
<input type="checkbox" id="req-${index}" style="width: 20px; height: 20px; cursor: pointer;">
|
||||
<label for="req-${index}" style="cursor: pointer; flex: 1;">${req}</label>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Paint Area Calculation
|
||||
function updatePaintFields() {
|
||||
const type = document.getElementById('paint-type').value;
|
||||
const field3 = document.getElementById('paint-field3');
|
||||
|
||||
if (type === 'chapa') {
|
||||
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
|
||||
document.getElementById('paint-label2').textContent = 'Largura (mm)';
|
||||
field3.style.display = 'none';
|
||||
} else if (type === 'perfilW') {
|
||||
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
|
||||
document.getElementById('paint-label2').textContent = 'Altura (mm)';
|
||||
field3.style.display = 'none';
|
||||
} else if (type === 'tubo') {
|
||||
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
|
||||
document.getElementById('paint-label2').textContent = 'Diâmetro (mm)';
|
||||
field3.style.display = 'none';
|
||||
} else if (type === 'rhs') {
|
||||
document.getElementById('paint-label1').textContent = 'Comprimento (mm)';
|
||||
document.getElementById('paint-label2').textContent = 'Largura (mm)';
|
||||
document.getElementById('paint-label3').textContent = 'Altura (mm)';
|
||||
field3.style.display = 'block';
|
||||
}
|
||||
}
|
||||
|
||||
function calcularAreaPintura() {
|
||||
const type = document.getElementById('paint-type').value;
|
||||
const dim1 = parseFloat(document.getElementById('paint-dim1').value) || 0;
|
||||
const dim2 = parseFloat(document.getElementById('paint-dim2').value) || 0;
|
||||
const dim3 = parseFloat(document.getElementById('paint-dim3').value) || 0;
|
||||
const qty = parseInt(document.getElementById('paint-qty').value) || 1;
|
||||
|
||||
let area = 0;
|
||||
|
||||
if (type === 'chapa') {
|
||||
area = (dim1 * dim2 * 2) / 1000000;
|
||||
} else if (type === 'perfilW') {
|
||||
const perimeter = dim2 * 3.5;
|
||||
area = (perimeter * dim1) / 1000000;
|
||||
} else if (type === 'tubo') {
|
||||
area = (Math.PI * dim2 * dim1) / 1000000;
|
||||
} else if (type === 'rhs') {
|
||||
const perimeter = 2 * (dim2 + dim3);
|
||||
area = (perimeter * dim1) / 1000000;
|
||||
}
|
||||
|
||||
const totalArea = area * qty;
|
||||
|
||||
document.getElementById('paint-area-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Área de Pintura</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Área Unitária</div>
|
||||
<div class="result-value">${area.toFixed(2)} m²</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Área Total</div>
|
||||
<div class="result-value">${totalArea.toFixed(2)} m²</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('tinta-area').value = totalArea.toFixed(2);
|
||||
|
||||
addToHistory('Área de Pintura', `${totalArea.toFixed(2)}m² (${qty} unidades)`);
|
||||
}
|
||||
|
||||
// Paint Consumption
|
||||
function calcularConsumoTinta() {
|
||||
const area = parseFloat(document.getElementById('tinta-area').value) || 0;
|
||||
const dft = parseFloat(document.getElementById('tinta-dft').value) || 0;
|
||||
const solids = parseFloat(document.getElementById('tinta-solids').value) || 0;
|
||||
const loss = parseFloat(document.getElementById('tinta-loss').value) || 0;
|
||||
const coats = parseInt(document.getElementById('tinta-coats').value) || 1;
|
||||
const cost = parseFloat(document.getElementById('tinta-cost').value) || 0;
|
||||
|
||||
const volumeTheoretical = (dft * area) / (1000 * (solids / 100));
|
||||
const volumeWithLoss = volumeTheoretical / (1 - loss / 100);
|
||||
const volumePerCoat = volumeWithLoss;
|
||||
const volumeTotal = volumePerCoat * coats;
|
||||
const totalCost = volumeTotal * cost;
|
||||
|
||||
document.getElementById('tinta-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Consumo de Tinta</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Volume Teórico</div>
|
||||
<div class="result-value">${volumeTheoretical.toFixed(2)} L</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Volume por Demão</div>
|
||||
<div class="result-value">${volumePerCoat.toFixed(2)} L</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Volume Total</div>
|
||||
<div class="result-value">${volumeTotal.toFixed(2)} L</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Custo Total</div>
|
||||
<div class="result-value">R$ ${totalCost.toFixed(2)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-7); border-radius: 8px;">
|
||||
<strong>Recomendação de embalagens:</strong><br>
|
||||
${volumeTotal > 20 ? `Galões 20L: ${Math.ceil(volumeTotal / 20)} unidades` :
|
||||
volumeTotal > 5 ? `Galões 5L: ${Math.ceil(volumeTotal / 5)} unidades` :
|
||||
`Latas 1L: ${Math.ceil(volumeTotal)} unidades`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Consumo de Tinta', `${volumeTotal.toFixed(2)}L para ${area}m²`);
|
||||
}
|
||||
|
||||
// Galvanization
|
||||
function calcularGalvanizacao() {
|
||||
const env = document.getElementById('galv-env').value;
|
||||
const area = parseFloat(document.getElementById('galv-area').value) || 0;
|
||||
const thickness = parseFloat(document.getElementById('galv-thickness').value) || 85;
|
||||
|
||||
const corrosionRate = {
|
||||
'interno': 0.5,
|
||||
'urbano': 1.5,
|
||||
'marinho': 3.0,
|
||||
'industrial': 2.5
|
||||
};
|
||||
|
||||
const rate = corrosionRate[env] || 1.5;
|
||||
const lifeYears = thickness / rate;
|
||||
|
||||
const zincDensity = 7140;
|
||||
const zincMass = (area * thickness / 1000) * (zincDensity / 1000000);
|
||||
const zincCost = zincMass * 12;
|
||||
|
||||
document.getElementById('galv-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Galvanização a Quente</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Taxa de Corrosão</div>
|
||||
<div class="result-value">${rate.toFixed(1)} μm/ano</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Vida Útil Estimada</div>
|
||||
<div class="result-value">${lifeYears.toFixed(0)} anos</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Consumo de Zinco</div>
|
||||
<div class="result-value">${zincMass.toFixed(2)} kg</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Custo Estimado</div>
|
||||
<div class="result-value">R$ ${(zincCost + area * 180).toFixed(2)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-success" style="margin-top: 16px;">
|
||||
<strong>Normas aplicáveis:</strong> ASTM A123, ISO 1461, NBR 6323
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Galvanização', `${area}m², ${thickness}μm → ${lifeYears.toFixed(0)} anos`);
|
||||
}
|
||||
|
||||
// Budget
|
||||
function adicionarItemOrcamento() {
|
||||
const type = document.getElementById('budget-type').value;
|
||||
const spec = document.getElementById('budget-spec').value;
|
||||
const qty = parseFloat(document.getElementById('budget-qty').value) || 0;
|
||||
const unit = document.getElementById('budget-unit').value;
|
||||
const price = parseFloat(document.getElementById('budget-price').value) || 0;
|
||||
|
||||
if (!spec || qty <= 0 || price <= 0) {
|
||||
alert('Preencha todos os campos corretamente');
|
||||
return;
|
||||
}
|
||||
|
||||
const item = {
|
||||
id: Date.now(),
|
||||
type: type,
|
||||
spec: spec,
|
||||
qty: qty,
|
||||
unit: unit,
|
||||
price: price,
|
||||
total: qty * price
|
||||
};
|
||||
|
||||
appState.budgetItems.push(item);
|
||||
atualizarTabelaOrcamento();
|
||||
|
||||
document.getElementById('budget-spec').value = '';
|
||||
document.getElementById('budget-qty').value = '1';
|
||||
document.getElementById('budget-price').value = '0';
|
||||
}
|
||||
|
||||
function removerItemOrcamento(id) {
|
||||
appState.budgetItems = appState.budgetItems.filter(item => item.id !== id);
|
||||
atualizarTabelaOrcamento();
|
||||
}
|
||||
|
||||
function atualizarTabelaOrcamento() {
|
||||
const tbody = document.getElementById('budget-tbody');
|
||||
|
||||
if (appState.budgetItems.length === 0) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" style="text-align: center; color: var(--color-text-secondary);">Nenhum item adicionado</td></tr>';
|
||||
} else {
|
||||
tbody.innerHTML = appState.budgetItems.map(item => `
|
||||
<tr>
|
||||
<td>${item.type}</td>
|
||||
<td>${item.spec}</td>
|
||||
<td>${item.qty.toFixed(2)}</td>
|
||||
<td>${item.unit}</td>
|
||||
<td>R$ ${item.price.toFixed(2)}</td>
|
||||
<td><strong>R$ ${item.total.toFixed(2)}</strong></td>
|
||||
<td><button class="btn btn-secondary" style="padding: 6px 12px; font-size: 12px;" onclick="removerItemOrcamento(${item.id})">Remover</button></td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
atualizarTotalOrcamento();
|
||||
}
|
||||
|
||||
function atualizarTotalOrcamento() {
|
||||
const subtotal = appState.budgetItems.reduce((sum, item) => sum + item.total, 0);
|
||||
const bdi = parseFloat(document.getElementById('budget-bdi').value) || 0;
|
||||
const total = subtotal * (1 + bdi / 100);
|
||||
|
||||
const resultDiv = document.getElementById('budget-total');
|
||||
resultDiv.innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Subtotal</div>
|
||||
<div class="result-value">R$ ${subtotal.toFixed(2)}</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">BDI (${bdi}%)</div>
|
||||
<div class="result-value">R$ ${(total - subtotal).toFixed(2)}</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">TOTAL GERAL</div>
|
||||
<div class="result-value" style="color: var(--color-success);">R$ ${total.toFixed(2)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Weight & Rigging
|
||||
function updateWeightFields() {
|
||||
const type = document.getElementById('weight-type').value;
|
||||
const field3 = document.getElementById('weight-field3');
|
||||
const field4 = document.getElementById('weight-field4');
|
||||
|
||||
if (type === 'perfilW') {
|
||||
document.getElementById('weight-label1').textContent = 'Altura (mm)';
|
||||
document.getElementById('weight-label2').textContent = 'Comprimento (m)';
|
||||
field3.style.display = 'none';
|
||||
field4.style.display = 'none';
|
||||
} else if (type === 'chapa') {
|
||||
document.getElementById('weight-label1').textContent = 'Largura (mm)';
|
||||
document.getElementById('weight-label2').textContent = 'Altura (mm)';
|
||||
document.getElementById('weight-label3').textContent = 'Espessura (mm)';
|
||||
field3.style.display = 'block';
|
||||
field4.style.display = 'none';
|
||||
} else if (type === 'tubo') {
|
||||
document.getElementById('weight-label1').textContent = 'Diâmetro Externo (mm)';
|
||||
document.getElementById('weight-label2').textContent = 'Comprimento (m)';
|
||||
document.getElementById('weight-label3').textContent = 'Espessura Parede (mm)';
|
||||
field3.style.display = 'block';
|
||||
field4.style.display = 'none';
|
||||
} else if (type === 'barra') {
|
||||
document.getElementById('weight-label1').textContent = 'Diâmetro (mm)';
|
||||
document.getElementById('weight-label2').textContent = 'Comprimento (m)';
|
||||
field3.style.display = 'none';
|
||||
field4.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
function calcularPeso() {
|
||||
const type = document.getElementById('weight-type').value;
|
||||
const dim1 = parseFloat(document.getElementById('weight-dim1').value) || 0;
|
||||
const dim2 = parseFloat(document.getElementById('weight-dim2').value) || 0;
|
||||
const dim3 = parseFloat(document.getElementById('weight-dim3').value) || 0;
|
||||
|
||||
let weight = 0;
|
||||
|
||||
if (type === 'perfilW') {
|
||||
weight = (dim1 / 100) * 31.8 * dim2;
|
||||
} else if (type === 'chapa') {
|
||||
weight = (dim1 / 1000) * (dim2 / 1000) * (dim3 / 1000) * 7850;
|
||||
} else if (type === 'tubo') {
|
||||
const dExt = dim1;
|
||||
const dInt = dExt - 2 * dim3;
|
||||
const area = Math.PI * (Math.pow(dExt/2, 2) - Math.pow(dInt/2, 2));
|
||||
weight = area / 1000000 * dim2 * 7850;
|
||||
} else if (type === 'barra') {
|
||||
const area = Math.PI * Math.pow(dim1/2, 2);
|
||||
weight = area / 1000000 * dim2 * 7850;
|
||||
}
|
||||
|
||||
document.getElementById('weight-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Cálculo de Peso</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Peso Total</div>
|
||||
<div class="result-value">${weight.toFixed(2)} kg</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.getElementById('rigging-weight').value = weight.toFixed(0);
|
||||
|
||||
addToHistory('Cálculo de Peso', `${weight.toFixed(2)}kg`);
|
||||
}
|
||||
|
||||
function calcularRigging() {
|
||||
const weight = parseFloat(document.getElementById('rigging-weight').value) || 0;
|
||||
const points = parseInt(document.getElementById('rigging-points').value) || 2;
|
||||
const angle = parseInt(document.getElementById('rigging-angle').value) || 60;
|
||||
const fs = parseFloat(document.getElementById('rigging-fs').value) || 4;
|
||||
|
||||
const angleRad = angle * Math.PI / 180;
|
||||
const forcePerCable = (weight * 9.81 / 1000) / (points * Math.cos(angleRad)) * fs;
|
||||
|
||||
const cableSteelCapacity = 21;
|
||||
const chainCapacity = 15;
|
||||
const syntheticCapacity = 12;
|
||||
|
||||
let recommendation = '';
|
||||
let alertClass = 'alert-success';
|
||||
if (forcePerCable <= syntheticCapacity) {
|
||||
recommendation = '✅ Cabo sintético (12 kN)';
|
||||
} else if (forcePerCable <= chainCapacity) {
|
||||
recommendation = '✅ Corrente grau 80 (15 kN)';
|
||||
} else if (forcePerCable <= cableSteelCapacity) {
|
||||
recommendation = '⚠️ Cabo de aço (21 kN)';
|
||||
alertClass = 'alert-warning';
|
||||
} else {
|
||||
recommendation = '❌ Requer cabo especial ou mais pontos de içamento';
|
||||
alertClass = 'alert-error';
|
||||
}
|
||||
|
||||
document.getElementById('rigging-result').innerHTML = `
|
||||
<div class="result-box">
|
||||
<div class="result-title">Plano de Rigging</div>
|
||||
<div class="result-grid">
|
||||
<div class="result-item">
|
||||
<div class="result-label">Força por Cabo</div>
|
||||
<div class="result-value">${forcePerCable.toFixed(1)} kN</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Ângulo</div>
|
||||
<div class="result-value">${angle}°</div>
|
||||
</div>
|
||||
<div class="result-item">
|
||||
<div class="result-label">Fator Segurança</div>
|
||||
<div class="result-value">${fs}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||||
<strong>Recomendação: ${recommendation}</strong>
|
||||
</div>
|
||||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-8); border-radius: 8px;">
|
||||
<strong>Capacidades de Referência:</strong><br>
|
||||
• Cabo sintético: 12 kN<br>
|
||||
• Corrente grau 80: 15 kN<br>
|
||||
• Cabo de aço: 21 kN
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
addToHistory('Rigging', `${weight}kg, ${points} pontos, ${angle}° → ${forcePerCable.toFixed(1)}kN/cabo`);
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// INITIALIZATION
|
||||
// ========================================
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
showSection('cev');
|
||||
mostrarEquivalencias();
|
||||
gerarChecklistCertificado();
|
||||
updatePaintFields();
|
||||
updateWeightFields();
|
||||
});
|
||||
305
ORIGINAL/index.html
Normal file
305
ORIGINAL/index.html
Normal file
@@ -0,0 +1,305 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="pt-BR">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🏗️ AÇO CALC PRO v5.0 - Plataforma Técnica de Engenharia Estrutural</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="header-content">
|
||||
<div class="logo-section">
|
||||
<div class="logo" id="appLogo">🏗️ AÇO CALC PRO</div>
|
||||
<div class="subtitle" id="appSubtitle">Plataforma Técnica de Engenharia Estrutural v6.5 - Base de Materiais Integrada</div>
|
||||
<span class="badge">PROFESSIONAL EDITION</span>
|
||||
</div>
|
||||
<div class="header-actions">
|
||||
<button class="btn-icon" onclick="openManualUsuario()" title="Manual do Usuário">📖 Manual</button>
|
||||
<button class="btn-icon" onclick="openHistoryModal()" title="Histórico">📋 Histórico</button>
|
||||
<button class="btn-icon" onclick="openFavoritesModal()" title="Favoritos">⭐ Favoritos</button>
|
||||
<button class="btn-icon" onclick="openAdminModal()" title="Admin" id="admin-toggle">⚙️ Admin</button>
|
||||
<button class="btn-icon" onclick="toggleExpertMode()" title="Modo Expert" id="expert-toggle">🎯 Expert</button>
|
||||
<button class="btn-icon" onclick="toggleTheme()" title="Alternar Tema" id="theme-toggle">🌙 Escuro</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-tabs">
|
||||
<button class="sidebar-tab active" onclick="switchSidebarTab(0)">📦 MATERIAIS</button>
|
||||
<button class="sidebar-tab" onclick="switchSidebarTab(1)">🔗 CONEXÕES</button>
|
||||
<button class="sidebar-tab" onclick="switchSidebarTab(2)">🔥 SOLDAGEM</button>
|
||||
<button class="sidebar-tab" onclick="switchSidebarTab(3)">✅ ENSAIOS</button>
|
||||
<button class="sidebar-tab" onclick="switchSidebarTab(4)">🎨 PINTURA</button>
|
||||
<button class="sidebar-tab" onclick="switchSidebarTab(5)">💰 ORÇAMENTO</button>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-content active" id="sidebar-0">
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-item" onclick="showSection('cev')" data-section="cev">
|
||||
🔬 CEV Avançado (IIW + Pcm)
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'cev')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('seletor')" data-section="seletor">
|
||||
🎯 Seletor de Aço Inteligente
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'seletor')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('equivalencias')" data-section="equivalencias">
|
||||
📊 Equivalências Internacionais
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'equivalencias')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('comparativo')" data-section="comparativo">
|
||||
📈 Comparativo de Aços
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'comparativo')">☆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-content" id="sidebar-1">
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-item" onclick="showSection('parafusos')" data-section="parafusos">
|
||||
🔩 Ligações Parafusadas
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'parafusos')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('layout')" data-section="layout">
|
||||
🎯 Layout de Furação
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'layout')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('parafuso-vs-solda')" data-section="parafuso-vs-solda">
|
||||
⚙️ Parafuso vs Solda
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'parafuso-vs-solda')">☆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-content" id="sidebar-2">
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-item" onclick="showSection('preaquecimento')" data-section="preaquecimento">
|
||||
🔥 Ferramentas de Soldagem
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'preaquecimento')">☆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="sidebar-content" id="sidebar-3">
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-item" onclick="showSection('dureza')" data-section="dureza">
|
||||
🔨 Conversor de Dureza
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'dureza')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('charpy')" data-section="charpy">
|
||||
📉 Análise de Charpy
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'charpy')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('certificado')" data-section="certificado">
|
||||
📋 Checklist Certificado
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'certificado')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('ultrassom')" data-section="ultrassom">
|
||||
🏥 Interpretação Ultrassom
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'ultrassom')">☆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-content" id="sidebar-4">
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-item" onclick="showSection('area-pintura')" data-section="area-pintura">
|
||||
📐 Cálculo de Área
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'area-pintura')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('consumo-tinta')" data-section="consumo-tinta">
|
||||
🎯 Consumo de Tinta
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'consumo-tinta')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('galvanizacao')" data-section="galvanizacao">
|
||||
🛡️ Galvanização
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'galvanizacao')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('custo-pintura')" data-section="custo-pintura">
|
||||
💰 Custo Total
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'custo-pintura')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('secagem')" data-section="secagem">
|
||||
⏱️ Tempo de Secagem
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'secagem')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('inspecao-pintura')" data-section="inspecao-pintura">
|
||||
✔️ Inspeção de Qualidade
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'inspecao-pintura')">☆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-content" id="sidebar-5">
|
||||
<div class="sidebar-section">
|
||||
<div class="sidebar-item" onclick="showSection('orcamento')" data-section="orcamento">
|
||||
💵 Orçamento Detalhado
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'orcamento')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('peso-rigging')" data-section="peso-rigging">
|
||||
⚖️ Peso e Rigging
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'peso-rigging')">☆</button>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="showSection('referencia')" data-section="referencia">
|
||||
📖 Referência Técnica
|
||||
<button class="star-btn" onclick="toggleFavorite(event, 'referencia')">☆</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="main-content" id="main-content">
|
||||
<!-- Content will be dynamically loaded here -->
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- History Modal -->
|
||||
<div class="modal" id="history-modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">📋 Histórico de Cálculos</div>
|
||||
<button class="close-btn" onclick="closeHistoryModal()">×</button>
|
||||
</div>
|
||||
<div id="history-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Favorites Modal -->
|
||||
<div class="modal" id="favorites-modal">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title">⭐ Favoritos</div>
|
||||
<button class="close-btn" onclick="closeFavoritesModal()">×</button>
|
||||
</div>
|
||||
<div id="favorites-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Admin Modal -->
|
||||
<div class="modal-admin" id="adminModal">
|
||||
<div class="modal-admin-content">
|
||||
<div class="modal-admin-header">
|
||||
<h2>⚙️ Painel Administrativo</h2>
|
||||
<button class="close-btn" onclick="closeAdminModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-admin-body">
|
||||
<div class="admin-section">
|
||||
<h3>🎨 Customização de Branding</h3>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Nome do Aplicativo</label>
|
||||
<input type="text" class="form-control" id="adminAppName" value="AÇO CALC PRO" maxlength="30">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Subtítulo</label>
|
||||
<input type="text" class="form-control" id="adminAppSubtitle" value="Plataforma Técnica com Base de Dados de Materiais Brasileiros" maxlength="100">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Texto do Rodapé</label>
|
||||
<textarea class="form-control" id="adminFooterText" rows="2" maxlength="200">© 2025 AÇO CALC PRO v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros</textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-section">
|
||||
<h3>🔧 Ferramentas Visíveis (Modo Simples)</h3>
|
||||
<p class="admin-note">No Modo Expert, TODAS as ferramentas aparecem sempre.</p>
|
||||
<div class="admin-tools-grid">
|
||||
<label class="checkbox-item"><input type="checkbox" value="cev" checked> CEV Avançado</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="seletor" checked> Seletor de Aço</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="equivalencias"> Equivalências</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="comparativo"> Comparativo</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="parafusos" checked> Parafusados</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="layout" checked> Layout Furação</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="parafuso-vs-solda"> Parafuso vs Solda</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="preaquecimento" checked> Pré-Aquecimento</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="dureza" checked> Conversor Dureza</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="charpy" checked> Análise Charpy</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="certificado"> Checklist Certificado</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="ultrassom"> Ultrassom</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="area-pintura" checked> Área Pintura</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="consumo-tinta" checked> Consumo Tinta</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="galvanizacao"> Galvanização</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="custo-pintura" checked> Custo Pintura</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="orcamento" checked> Orçamento</label>
|
||||
<label class="checkbox-item"><input type="checkbox" value="peso-rigging"> Peso & Rigging</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-section">
|
||||
<h3>⚙️ Preferências</h3>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Tema Padrão</label>
|
||||
<select class="form-control" id="adminThemeDefault">
|
||||
<option value="escuro">Escuro</option>
|
||||
<option value="claro">Claro</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Modo Padrão</label>
|
||||
<select class="form-control" id="adminModeDefault">
|
||||
<option value="simples">Simples</option>
|
||||
<option value="expert">Expert</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-admin-footer">
|
||||
<button class="btn btn-secondary" onclick="resetAdminDefaults()">🔄 Restaurar Padrões</button>
|
||||
<button class="btn btn-primary" onclick="saveAdminConfig()">💾 Salvar Alterações</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Help Modal -->
|
||||
<div class="modal-help" id="modalAjuda">
|
||||
<div class="modal-help-content">
|
||||
<div class="modal-help-header">
|
||||
<h2 id="ajudaTitulo">📚 Ajuda</h2>
|
||||
<button class="close-btn" onclick="closeAjudaModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-help-tabs">
|
||||
<button class="help-tab-btn active" onclick="switchHelpTab(0)">📖 Explicação</button>
|
||||
<button class="help-tab-btn" onclick="switchHelpTab(1)">🔧 Campos</button>
|
||||
<button class="help-tab-btn" onclick="switchHelpTab(2)">📊 Resultados</button>
|
||||
<button class="help-tab-btn" onclick="switchHelpTab(3)">📚 Referências</button>
|
||||
</div>
|
||||
<div class="modal-help-body">
|
||||
<div class="help-tab-content active" id="help-tab-0"></div>
|
||||
<div class="help-tab-content" id="help-tab-1"></div>
|
||||
<div class="help-tab-content" id="help-tab-2"></div>
|
||||
<div class="help-tab-content" id="help-tab-3"></div>
|
||||
</div>
|
||||
<div class="modal-help-footer">
|
||||
<button class="btn btn-primary" onclick="abrirManualRelacionado()">📖 Ver no Manual do Usuário</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Manual Usuario Modal -->
|
||||
<div class="modal-manual" id="modalManual">
|
||||
<div class="modal-manual-container">
|
||||
<div class="manual-sidebar">
|
||||
<div class="manual-search">
|
||||
<input type="text" id="manualSearch" placeholder="🔍 Buscar..." oninput="buscarNoManual()">
|
||||
</div>
|
||||
<nav class="manual-nav" id="manualNav"></nav>
|
||||
</div>
|
||||
<div class="manual-content">
|
||||
<button class="close-btn" onclick="closeManualModal()" style="position: absolute; top: 20px; right: 20px;">×</button>
|
||||
<div id="manualConteudo"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer" id="appFooter">
|
||||
<p>© 2025 AÇO CALC PRO v6.5 PROFESSIONAL EDITION - Plataforma Técnica com Base de Dados de Materiais Brasileiros</p>
|
||||
</div>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
2090
ORIGINAL/style.css
Normal file
2090
ORIGINAL/style.css
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user