10959 lines
540 KiB
JavaScript
10959 lines
540 KiB
JavaScript
// ========================================
|
||
// SteelBase v7.5 - PROFESSIONAL EDITION
|
||
// Plataforma Técnica Completa com Base de Materiais
|
||
// ========================================
|
||
|
||
// Logger disponível globalmente (carregado antes em logger.js)
|
||
// Usar window.Logger.info('mensagem') para logs controlados
|
||
|
||
// State e config disponíveis globalmente via script state.js (carregado antes)
|
||
|
||
// ========================================
|
||
// CSV MAPPING AND LOADING FUNCTIONS v6.6
|
||
// ========================================
|
||
|
||
const csvMapping = {
|
||
'perfil_w': 'BD/perfis/perfis_w_brasil_completo.csv',
|
||
'perfil_i': 'BD/perfis/perfis_i_brasil_completo.csv',
|
||
'perfil_hp': 'BD/perfis/perfis_hp_brasil_completo.csv',
|
||
'cantoneira': 'BD/perfis/cantoneiras_brasil_completo.csv',
|
||
'tubo_circ': 'BD/perfis/tubos_circulares_brasil_completo.csv',
|
||
'tubo_rhs': 'BD/perfis/tubos_rhs_brasil_completo.csv',
|
||
'chapa': 'BD/perfis/chapas_brasil_completo.csv',
|
||
'barra': 'BD/perfis/barras_brasil_completo.csv',
|
||
'barra_chata': 'BD/perfis/barras_chatas_brasil_completo.csv',
|
||
'barra_roscada': 'BD/perfis/barras_roscadas_brasil_completo.csv'
|
||
};
|
||
|
||
// Function to load CSV
|
||
async function carregarCSV(tipoMaterial) {
|
||
const caminhoCSV = csvMapping[tipoMaterial];
|
||
|
||
if (!caminhoCSV) {
|
||
console.warn('Tipo de material não mapeado:', tipoMaterial);
|
||
return [];
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(caminhoCSV);
|
||
if (!response.ok) {
|
||
throw new Error(`Erro ao carregar ${caminhoCSV}: ${response.status}`);
|
||
}
|
||
|
||
const csvText = await response.text();
|
||
return parseCSV(csvText);
|
||
} catch (error) {
|
||
console.error('Erro ao carregar CSV:', error);
|
||
// Return fallback data from materialsDatabase
|
||
return getFallbackData(tipoMaterial);
|
||
}
|
||
}
|
||
|
||
// Function to parse CSV
|
||
function parseCSV(csvText) {
|
||
const lines = csvText.trim().split('\n');
|
||
if (lines.length === 0) return [];
|
||
|
||
const headers = lines[0].split(',').map(h => h.trim());
|
||
const dados = [];
|
||
|
||
for (let i = 1; i < lines.length; i++) {
|
||
const obj = {};
|
||
const currentLine = lines[i].split(',');
|
||
|
||
for (let j = 0; j < headers.length; j++) {
|
||
obj[headers[j]] = currentLine[j] ? currentLine[j].trim() : '';
|
||
}
|
||
|
||
dados.push(obj);
|
||
}
|
||
|
||
return dados;
|
||
}
|
||
|
||
// Fallback to in-memory data if CSV fails
|
||
function getFallbackData(tipoMaterial) {
|
||
const typeMap = {
|
||
'perfil_w': 'perfis_w',
|
||
'perfil_i': 'perfis_i',
|
||
'perfil_hp': 'perfis_hp',
|
||
'cantoneira': 'cantoneiras',
|
||
'tubo_circ': 'tubos_circulares',
|
||
'tubo_rhs': 'tubos_retangulares',
|
||
'chapa': 'chapas',
|
||
'barra': 'barras',
|
||
'eletrodo': 'consumiveis',
|
||
'parafuso': 'parafusos',
|
||
'tinta': 'consumiveis'
|
||
};
|
||
|
||
const dbKey = typeMap[tipoMaterial];
|
||
return materialsDatabase[dbKey] || [];
|
||
}
|
||
|
||
// ========================================
|
||
// COMPREHENSIVE MATERIALS DATABASE
|
||
// ========================================
|
||
|
||
const materialsDatabase = {
|
||
perfis_w: [
|
||
{id: 'w150_13', nome: 'W150×13', altura: 150, aba: 100, peso: 13, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w150_18', nome: 'W150×18', altura: 150, aba: 100, peso: 18, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w200_15', nome: 'W200×15', altura: 200, aba: 100, peso: 15, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w200_22', nome: 'W200×22', altura: 200, aba: 100, peso: 22, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w200_31', nome: 'W200×31', altura: 200, aba: 100, peso: 31, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w250_25', nome: 'W250×25', altura: 254, aba: 203, peso: 25, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w250_32', nome: 'W250×32', altura: 254, aba: 203, peso: 32, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w250_38', nome: 'W250×38', altura: 254, aba: 203, peso: 38, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w310_24', nome: 'W310×24', altura: 307, aba: 200, peso: 24, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w310_33', nome: 'W310×33', altura: 307, aba: 203, peso: 33, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w310_39', nome: 'W310×39', altura: 307, aba: 203, peso: 39, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w310_52', nome: 'W310×52', altura: 307, aba: 205, peso: 52, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w310_67', nome: 'W310×67', altura: 310, aba: 306, peso: 67, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w360_44', nome: 'W360×44', altura: 355, aba: 203, peso: 44, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w360_51', nome: 'W360×51', altura: 357, aba: 204, peso: 51, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w360_72', nome: 'W360×72', altura: 361, aba: 206, peso: 72, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w410_60', nome: 'W410×60', altura: 410, aba: 205, peso: 60, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w410_85', nome: 'W410×85', altura: 414, aba: 209, peso: 85, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w500_84', nome: 'W500×84', altura: 510, aba: 210, peso: 84, tipo: 'Perfil W', unidade: 'm'},
|
||
{id: 'w610_101', nome: 'W610×101', altura: 615, aba: 210, peso: 101, tipo: 'Perfil W', unidade: 'm'}
|
||
],
|
||
perfis_i: [
|
||
{id: 'ipe_100', nome: 'IPE 100', altura: 100, aba: 55, peso: 8.1, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_120', nome: 'IPE 120', altura: 120, aba: 64, peso: 10.4, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_140', nome: 'IPE 140', altura: 140, aba: 73, peso: 12.9, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_160', nome: 'IPE 160', altura: 160, aba: 82, peso: 15.8, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_180', nome: 'IPE 180', altura: 180, aba: 91, peso: 18.8, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_200', nome: 'IPE 200', altura: 200, aba: 100, peso: 22.4, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_240', nome: 'IPE 240', altura: 240, aba: 120, peso: 30.7, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_300', nome: 'IPE 300', altura: 300, aba: 150, peso: 42.2, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_360', nome: 'IPE 360', altura: 360, aba: 170, peso: 57.1, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_400', nome: 'IPE 400', altura: 400, aba: 180, peso: 66.3, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_500', nome: 'IPE 500', altura: 500, aba: 200, peso: 90.7, tipo: 'Perfil I', unidade: 'm'},
|
||
{id: 'ipe_600', nome: 'IPE 600', altura: 600, aba: 220, peso: 122, tipo: 'Perfil I', unidade: 'm'}
|
||
],
|
||
perfis_hp: [
|
||
{id: 'hp200_53', nome: 'HP200×53', altura: 203, aba: 203, peso: 53, tipo: 'Perfil HP', unidade: 'm'},
|
||
{id: 'hp250_63', nome: 'HP250×63', altura: 254, aba: 254, peso: 63, tipo: 'Perfil HP', unidade: 'm'},
|
||
{id: 'hp310_79', nome: 'HP310×79', altura: 310, aba: 310, peso: 79, tipo: 'Perfil HP', unidade: 'm'},
|
||
{id: 'hp360_102', nome: 'HP360×102', altura: 362, aba: 362, peso: 102, tipo: 'Perfil HP', unidade: 'm'}
|
||
],
|
||
cantoneiras: [
|
||
{id: 'l50_50_5', nome: 'L50×50×5', lado: 50, esp: 5, peso: 3.75, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l50_50_6', nome: 'L50×50×6', lado: 50, esp: 6, peso: 4.50, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l63_63_6', nome: 'L63×63×6', lado: 63, esp: 6, peso: 5.80, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l75_75_8', nome: 'L75×75×8', lado: 75, esp: 8, peso: 9.1, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l100_100_10', nome: 'L100×100×10', lado: 100, esp: 10, peso: 15.0, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l100_100_12', nome: 'L100×100×12', lado: 100, esp: 12, peso: 17.8, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l125_125_12', nome: 'L125×125×12', lado: 125, esp: 12, peso: 22.4, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l150_150_12', nome: 'L150×150×12', lado: 150, esp: 12, peso: 26.8, tipo: 'Cantoneira', unidade: 'm'},
|
||
{id: 'l150_150_15', nome: 'L150×150×15', lado: 150, esp: 15, peso: 32.8, tipo: 'Cantoneira', unidade: 'm'}
|
||
],
|
||
tubos_circulares: [
|
||
{id: 'tubo_50_2', nome: 'Ø50×2.0', diametro: 50, esp: 2.0, peso: 2.45, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_60_2', nome: 'Ø60×2.0', diametro: 60, esp: 2.0, peso: 2.95, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_76_25', nome: 'Ø76×2.5', diametro: 76, esp: 2.5, peso: 4.65, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_80_3', nome: 'Ø80×3.0', diametro: 80, esp: 3.0, peso: 5.85, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_100_3', nome: 'Ø100×3.0', diametro: 100, esp: 3.0, peso: 7.35, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_100_4', nome: 'Ø100×4.0', diametro: 100, esp: 4.0, peso: 9.65, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_120_4', nome: 'Ø120×4.0', diametro: 120, esp: 4.0, peso: 11.70, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_150_5', nome: 'Ø150×5.0', diametro: 150, esp: 5.0, peso: 18.20, tipo: 'Tubo Circular', unidade: 'm'},
|
||
{id: 'tubo_200_4', nome: 'Ø200×4.0', diametro: 200, esp: 4.0, peso: 19.60, tipo: 'Tubo Circular', unidade: 'm'}
|
||
],
|
||
tubos_retangulares: [
|
||
{id: 'rhs_100_100_4', nome: '100×100×4', largura: 100, altura: 100, esp: 4, peso: 15.0, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_100_100_5', nome: '100×100×5', largura: 100, altura: 100, esp: 5, peso: 18.5, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_120_80_5', nome: '120×80×5', largura: 120, altura: 80, esp: 5, peso: 18.7, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_150_100_5', nome: '150×100×5', largura: 150, altura: 100, esp: 5, peso: 22.0, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_150_150_5', nome: '150×150×5', largura: 150, altura: 150, esp: 5, peso: 27.8, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_150_150_6', nome: '150×150×6', largura: 150, altura: 150, esp: 6, peso: 33.1, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_200_100_6', nome: '200×100×6', largura: 200, altura: 100, esp: 6, peso: 30.6, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_200_200_6', nome: '200×200×6', largura: 200, altura: 200, esp: 6, peso: 43.8, tipo: 'Tubo RHS', unidade: 'm'},
|
||
{id: 'rhs_200_200_8', nome: '200×200×8', largura: 200, altura: 200, esp: 8, peso: 57.8, tipo: 'Tubo RHS', unidade: 'm'}
|
||
],
|
||
chapas: [
|
||
{id: 'chapa_475', nome: 'CHAPA 4.75mm', esp: 4.75, formato: '2500×1250', peso_m2: 37.3, tipo: 'Chapa', unidade: 'm²'},
|
||
{id: 'chapa_635', nome: 'CHAPA 6.35mm', esp: 6.35, formato: '2500×1250', peso_m2: 49.8, tipo: 'Chapa', unidade: 'm²'},
|
||
{id: 'chapa_95', nome: 'CHAPA 9.5mm', esp: 9.5, formato: '2500×1250', peso_m2: 74.6, tipo: 'Chapa', unidade: 'm²'},
|
||
{id: 'chapa_127', nome: 'CHAPA 12.7mm', esp: 12.7, formato: '2500×1250', peso_m2: 99.7, tipo: 'Chapa', unidade: 'm²'},
|
||
{id: 'chapa_159', nome: 'CHAPA 15.9mm', esp: 15.9, formato: '2500×1250', peso_m2: 124.8, tipo: 'Chapa', unidade: 'm²'},
|
||
{id: 'chapa_191', nome: 'CHAPA 19.1mm', esp: 19.1, formato: '2500×1250', peso_m2: 150.0, tipo: 'Chapa', unidade: 'm²'},
|
||
{id: 'chapa_254', nome: 'CHAPA 25.4mm', esp: 25.4, formato: '2000×1000', peso_m2: 199.4, tipo: 'Chapa', unidade: 'm²'}
|
||
],
|
||
barras: [
|
||
{id: 'barra_8', nome: 'Ø8mm', diametro: 8, peso: 0.395, tipo: 'Barra Redonda', unidade: 'm'},
|
||
{id: 'barra_10', nome: 'Ø10mm', diametro: 10, peso: 0.616, tipo: 'Barra Redonda', unidade: 'm'},
|
||
{id: 'barra_12', nome: 'Ø12mm', diametro: 12, peso: 0.888, tipo: 'Barra Redonda', unidade: 'm'},
|
||
{id: 'barra_16', nome: 'Ø16mm', diametro: 16, peso: 1.580, tipo: 'Barra Redonda', unidade: 'm'},
|
||
{id: 'barra_20', nome: 'Ø20mm', diametro: 20, peso: 2.466, tipo: 'Barra Redonda', unidade: 'm'},
|
||
{id: 'barra_25', nome: 'Ø25mm', diametro: 25, peso: 3.852, tipo: 'Barra Redonda', unidade: 'm'},
|
||
{id: 'barra_32', nome: 'Ø32mm', diametro: 32, peso: 6.313, tipo: 'Barra Redonda', unidade: 'm'}
|
||
],
|
||
consumiveis: [
|
||
{id: 'e7018', nome: 'E7018 (Eletrodo)', peso_kg: 1, custo_kg: 45, tipo: 'Consumível', unidade: 'kg'},
|
||
{id: 'e6013', nome: 'E6013 (Eletrodo)', peso_kg: 1, custo_kg: 28, tipo: 'Consumível', unidade: 'kg'},
|
||
{id: 'e8018', nome: 'E8018 (Eletrodo)', peso_kg: 1, custo_kg: 65, tipo: 'Consumível', unidade: 'kg'},
|
||
{id: 'er70s6', nome: 'ER70S-6 (MIG)', peso_kg: 1, custo_kg: 32, tipo: 'Consumível', unidade: 'kg'},
|
||
{id: 'tinta_c3', nome: 'TINTA C3 Epóxi', custo_l: 80, tipo: 'Consumível', unidade: 'L'},
|
||
{id: 'tinta_c4', nome: 'TINTA C4 Epóxi+PU', custo_l: 120, tipo: 'Consumível', unidade: 'L'},
|
||
{id: 'tinta_c5', nome: 'TINTA C5 Zinc-Rich', custo_l: 150, tipo: 'Consumível', unidade: 'L'},
|
||
{id: 'fundo_zinc', nome: 'FUNDO Zinc-Rich', custo_l: 60, tipo: 'Consumível', unidade: 'L'}
|
||
],
|
||
parafusos: [
|
||
{id: 'para_a325_m12', nome: 'Parafuso A325 M12', custo_un: 0.85, tipo: 'Parafuso', unidade: 'un'},
|
||
{id: 'para_a325_m16', nome: 'Parafuso A325 M16', custo_un: 1.20, tipo: 'Parafuso', unidade: 'un'},
|
||
{id: 'para_a325_m20', nome: 'Parafuso A325 M20', custo_un: 1.80, tipo: 'Parafuso', unidade: 'un'},
|
||
{id: 'para_a490_m16', nome: 'Parafuso A490 M16', custo_un: 2.50, tipo: 'Parafuso', unidade: 'un'},
|
||
{id: 'porca_m12', nome: 'Porca M12', custo_un: 0.15, tipo: 'Parafuso', unidade: 'un'},
|
||
{id: 'porca_m16', nome: 'Porca M16', custo_un: 0.25, tipo: 'Parafuso', unidade: 'un'},
|
||
{id: 'arruela', nome: 'Arruela DIN 125', custo_un: 0.08, tipo: 'Parafuso', unidade: 'un'}
|
||
]
|
||
};
|
||
|
||
const regionalPricing = {
|
||
sudeste: {
|
||
perfil_w: 7.50,
|
||
perfil_i: 7.50,
|
||
perfil_hp: 7.50,
|
||
cantoneira: 7.50,
|
||
tubo_circ: 8.00,
|
||
tubo_rhs: 8.50,
|
||
chapa: 7.80,
|
||
barra: 7.50
|
||
},
|
||
sul: {
|
||
perfil_w: 7.20,
|
||
perfil_i: 7.20,
|
||
perfil_hp: 7.20,
|
||
cantoneira: 7.20,
|
||
tubo_circ: 7.80,
|
||
tubo_rhs: 8.20,
|
||
chapa: 7.50,
|
||
barra: 7.20
|
||
},
|
||
nordeste: {
|
||
perfil_w: 8.00,
|
||
perfil_i: 8.00,
|
||
perfil_hp: 8.00,
|
||
cantoneira: 8.00,
|
||
tubo_circ: 8.50,
|
||
tubo_rhs: 9.00,
|
||
chapa: 8.20,
|
||
barra: 8.00
|
||
},
|
||
centrooeste: {
|
||
perfil_w: 7.70,
|
||
perfil_i: 7.70,
|
||
perfil_hp: 7.70,
|
||
cantoneira: 7.70,
|
||
tubo_circ: 8.30,
|
||
tubo_rhs: 8.70,
|
||
chapa: 8.00,
|
||
barra: 7.70
|
||
}
|
||
};
|
||
|
||
// Steel database
|
||
const steelDatabase = {
|
||
a36: { nome: 'ASTM A36', fy: 250, fu: 400, elong: 20, cev: 0.41, charpy: 27, temp: -20, custo: 100, soldabilidade: '⭐⭐⭐⭐⭐', equiv: ['EN S235JR', 'JIS SS400'] },
|
||
a572: { nome: 'ASTM A572 Gr.50', fy: 345, fu: 450, elong: 18, cev: 0.45, charpy: 27, temp: -20, custo: 115, soldabilidade: '⭐⭐⭐⭐', equiv: ['EN S355J2', 'JIS SM490'] },
|
||
a588: { nome: 'ASTM A588', fy: 345, fu: 485, elong: 19, cev: 0.50, charpy: 27, temp: -20, custo: 125, soldabilidade: '⭐⭐⭐', equiv: ['EN S355K2G3', 'API 2H'] },
|
||
a992: { nome: 'ASTM A992', fy: 345, fu: 450, elong: 21, cev: 0.45, charpy: 27, temp: -20, custo: 118, soldabilidade: '⭐⭐⭐⭐', equiv: ['EN S355J2'] },
|
||
s235: { nome: 'EN S235JR', fy: 235, fu: 360, elong: 26, cev: 0.38, charpy: 27, temp: -20, custo: 100, soldabilidade: '⭐⭐⭐⭐⭐', equiv: ['ASTM A36', 'JIS SS400'] },
|
||
s355: { nome: 'EN S355J2', fy: 355, fu: 490, elong: 22, cev: 0.50, charpy: 27, temp: -20, custo: 115, soldabilidade: '⭐⭐⭐⭐', equiv: ['ASTM A572', 'API 2H'] },
|
||
s460: { nome: 'EN S460', fy: 460, fu: 540, elong: 17, cev: 0.55, charpy: 27, temp: -20, custo: 140, soldabilidade: '⭐⭐⭐', equiv: ['ASTM A514'] },
|
||
ar350: { nome: 'NBR AR350', fy: 345, fu: 450, elong: 18, cev: 0.45, charpy: 27, temp: -20, custo: 115, soldabilidade: '⭐⭐⭐⭐', equiv: ['ASTM A572', 'EN S355J2'] }
|
||
};
|
||
|
||
// Regional pricing
|
||
const regionalPrices = {
|
||
sudeste: { a36: 2800, a572: 3100, solda: 65, pintura: 40, galv: 180 },
|
||
sul: { a36: 2700, a572: 3000, solda: 60, pintura: 38, galv: 175 },
|
||
nordeste: { a36: 3000, a572: 3300, solda: 70, pintura: 42, galv: 190 },
|
||
centrooeste: { a36: 2900, a572: 3200, solda: 68, pintura: 41, galv: 185 }
|
||
};
|
||
|
||
// Normative requirements
|
||
const certRequirements = {
|
||
astm_a36: ['fy ≥ 250 MPa', 'fu 400-550 MPa', 'Alongamento ≥ 20%', 'C ≤ 0.25%', 'Mn ≤ 1.20%'],
|
||
astm_a572: ['fy ≥ 345 MPa', 'fu 450-620 MPa', 'Alongamento ≥ 18%', 'CEV ≤ 0.55%'],
|
||
en_s235: ['fy ≥ 235 MPa', 'fu 360-510 MPa', 'Alongamento ≥ 26%'],
|
||
en_s355: ['fy ≥ 355 MPa', 'fu 470-630 MPa', 'Alongamento ≥ 22%', 'Charpy 27J @ -20°C'],
|
||
nbr_ar350: ['fy ≥ 345 MPa', 'fu ≥ 450 MPa', 'Alongamento ≥ 18%', 'C ≤ 0.15%']
|
||
};
|
||
|
||
let currentChart = null;
|
||
|
||
// ========================================
|
||
// NAVIGATION & UI FUNCTIONS
|
||
// ========================================
|
||
|
||
function switchSidebarTab(index) {
|
||
document.querySelectorAll('.sidebar-tab').forEach((tab, i) => {
|
||
tab.classList.toggle('active', i === index);
|
||
});
|
||
|
||
document.querySelectorAll('.sidebar-content').forEach((content, i) => {
|
||
content.classList.toggle('active', i === index);
|
||
});
|
||
|
||
appState.currentSidebarTab = index;
|
||
}
|
||
|
||
function showSection(sectionId) {
|
||
appState.currentSection = sectionId;
|
||
|
||
// Update sidebar active state
|
||
document.querySelectorAll('.sidebar-item').forEach(item => {
|
||
item.classList.toggle('active', item.dataset.section === sectionId);
|
||
});
|
||
|
||
// Load section content
|
||
loadSectionContent(sectionId);
|
||
|
||
// Carregar dados específicos para catálogo de perfis
|
||
// SOLUÇÃO DEFINITIVA: Usar a função que funciona!
|
||
if (sectionId === 'cantoneiras') {
|
||
console.log('🔧 Seção cantoneiras detectada - carregando automaticamente');
|
||
|
||
// Aguardar o DOM estar pronto e chamar a função que funciona
|
||
setTimeout(() => {
|
||
if (typeof forcarCarregamentoCantoneiras === 'function') {
|
||
console.log('✅ Chamando forcarCarregamentoCantoneiras automaticamente');
|
||
forcarCarregamentoCantoneiras();
|
||
} else {
|
||
console.error('❌ Função forcarCarregamentoCantoneiras não encontrada');
|
||
}
|
||
}, 500);
|
||
}
|
||
|
||
// Add help button after content loads
|
||
setTimeout(() => {
|
||
if (sectionId === 'preaquecimento') {
|
||
addHelpButton('preaquecimento');
|
||
} else if (sectionId === 'parafusos') {
|
||
addHelpButton('parafusos-cisalhamento');
|
||
} else {
|
||
addHelpButton(sectionId);
|
||
}
|
||
}, 200);
|
||
}
|
||
|
||
function loadSectionContent(sectionId) {
|
||
const content = document.getElementById('main-content');
|
||
|
||
const sections = {
|
||
'cev': getCEVContent(),
|
||
'seletor': getSeletorContent(),
|
||
'equivalencias': getEquivalenciasContent(),
|
||
'comparativo': getComparativoContent(),
|
||
// Assistente Inteligente
|
||
'assistente-inteligente': getAssistenteInteligenteContent(),
|
||
// Catálogo de Perfis
|
||
'cantoneiras': typeof getCantoneirasContent === 'function' ? getCantoneirasContent() : '<p>Carregando cantoneiras...</p>',
|
||
'barras-redondas': typeof getBarrasRedondasContent === 'function' ? getBarrasRedondasContent() : '<p>Em desenvolvimento</p>',
|
||
'tubos-circulares': typeof getTubosCircularesContent === 'function' ? getTubosCircularesContent() : '<p>Em desenvolvimento</p>',
|
||
'perfis-i': typeof getPerfisIContent === 'function' ? getPerfisIContent() : '<p>Em desenvolvimento</p>',
|
||
'perfis-w': typeof getPerfisWContent === 'function' ? getPerfisWContent() : '<p>Em desenvolvimento</p>',
|
||
'tubos-rhs': typeof getTubosRHSContent === 'function' ? getTubosRHSContent() : '<p>Em desenvolvimento</p>',
|
||
'chapas': typeof getChapasContent === 'function' ? getChapasContent() : '<p>Em desenvolvimento</p>',
|
||
'perfis-hp': typeof getPerfisHPContent === 'function' ? getPerfisHPContent() : '<p>Em desenvolvimento</p>',
|
||
'barras-roscadas': typeof getBarrasRoscadasContent === 'function' ? getBarrasRoscadasContent() : '<p>Em desenvolvimento</p>',
|
||
'barras-chatas': typeof getBarrasChatasContent === 'function' ? getBarrasChatasContent() : '<p>Em desenvolvimento</p>',
|
||
// Conexões
|
||
'parafusos': getParafusosContent(),
|
||
'layout': getLayoutContent(),
|
||
'parafuso-vs-solda': getParafusoVsSoldaContent(),
|
||
// Soldagem
|
||
'preaquecimento': getPreaquecimentoContent(),
|
||
'solda-filete': getSoldaFileteContent(),
|
||
'energia-soldagem': getEnergiaSoldagemContent(),
|
||
'consumo-eletrodos': getConsumoEletrodosContent(),
|
||
// Ensaios
|
||
'dureza': getDurezaContent(),
|
||
'charpy': getCharpyContent(),
|
||
'certificado': getCertificadoContent(),
|
||
'ultrassom': getUltrassomContent(),
|
||
// Pintura
|
||
'area-pintura': getAreaPinturaContent(),
|
||
'consumo-tinta': getConsumoTintaContent(),
|
||
'galvanizacao': getGalvanizacaoContent(),
|
||
'custo-pintura': getCustoPinturaContent(),
|
||
'secagem': getSecagemContent(),
|
||
'inspecao-pintura': getInspecaoPinturaContent(),
|
||
// Orçamento
|
||
'orcamento': getOrcamentoContent(),
|
||
'peso-rigging': getPesoRiggingContent(),
|
||
'referencia': getReferenciaContent()
|
||
};
|
||
|
||
content.innerHTML = sections[sectionId] || '<p>Seção não encontrada</p>';
|
||
}
|
||
|
||
function toggleTheme() {
|
||
appState.currentTheme = appState.currentTheme === 'dark' ? 'light' : 'dark';
|
||
userPreferences.theme = appState.currentTheme;
|
||
savePreferences();
|
||
applyTheme();
|
||
}
|
||
|
||
function applyTheme() {
|
||
// Apply theme
|
||
document.documentElement.setAttribute('data-theme', appState.currentTheme);
|
||
document.documentElement.setAttribute('data-color-scheme', appState.currentTheme);
|
||
|
||
const btn = document.getElementById('theme-toggle');
|
||
if (btn) {
|
||
btn.textContent = appState.currentTheme === 'dark' ? '☀️ Claro' : '🌙 Escuro';
|
||
btn.classList.toggle('light', appState.currentTheme === 'light');
|
||
}
|
||
}
|
||
|
||
// Apply all user preferences
|
||
function applyUserPreferences() {
|
||
// Apply theme
|
||
appState.currentTheme = userPreferences.theme;
|
||
applyTheme();
|
||
|
||
// Apply color scheme
|
||
document.documentElement.setAttribute('data-color-scheme-variant', userPreferences.colorScheme);
|
||
|
||
// Apply font size
|
||
document.documentElement.setAttribute('data-font-size', userPreferences.fontSize);
|
||
|
||
// Apply font family
|
||
document.documentElement.setAttribute('data-font-family', userPreferences.fontFamily);
|
||
}
|
||
|
||
function toggleExpertMode() {
|
||
appState.expertMode = !appState.expertMode;
|
||
document.documentElement.classList.toggle('expert-mode', appState.expertMode);
|
||
const btn = document.getElementById('expert-toggle');
|
||
if (btn) {
|
||
btn.textContent = appState.expertMode ? '🔬 Expert' : '🎯 Simples';
|
||
btn.classList.toggle('active', appState.expertMode);
|
||
}
|
||
filterToolsByMode();
|
||
}
|
||
|
||
function filterToolsByMode() {
|
||
console.log('🔍 Filtrando ferramentas por modo...');
|
||
|
||
const allItems = document.querySelectorAll('.sidebar-item');
|
||
|
||
allItems.forEach(item => {
|
||
const sectionId = item.dataset.section;
|
||
|
||
if (appState.expertMode) {
|
||
// Expert mode: show all tools
|
||
item.classList.remove('hidden');
|
||
} else {
|
||
// Simple mode: show only selected tools
|
||
const isVisible = adminConfig.toolsVisibility[sectionId];
|
||
if (isVisible) {
|
||
item.classList.remove('hidden');
|
||
} else {
|
||
item.classList.add('hidden');
|
||
}
|
||
}
|
||
});
|
||
|
||
// FIRST: Reset all subcategories to closed state
|
||
resetSubcategoriesToClosedState();
|
||
|
||
// THEN: Initialize sidebar expansion (respects manual state)
|
||
initializeSidebarExpansion();
|
||
}
|
||
|
||
/**
|
||
* Reset all subcategories to closed state initially
|
||
* This ensures consistent starting state
|
||
*/
|
||
function resetSubcategoriesToClosedState() {
|
||
console.log('🔄 Resetando subcategorias para estado fechado...');
|
||
|
||
const subcategories = document.querySelectorAll('.sidebar-subcategory');
|
||
const categories = document.querySelectorAll('.sidebar-category');
|
||
|
||
// Close all subcategories first
|
||
subcategories.forEach(subcategory => {
|
||
const icon = subcategory.querySelector('.category-icon');
|
||
const title = subcategory.querySelector('.subcategory-title')?.textContent || 'Subcategoria';
|
||
|
||
subcategory.classList.remove('expanded');
|
||
if (icon) {
|
||
icon.style.transform = 'rotate(0deg)';
|
||
icon.textContent = '▶';
|
||
}
|
||
|
||
console.log(`❌ Fechando: ${title} (ícone: ▶)`);
|
||
});
|
||
|
||
// Close all categories
|
||
categories.forEach(category => {
|
||
const icon = category.querySelector('.category-icon');
|
||
const title = category.querySelector('.category-title')?.textContent || 'Categoria';
|
||
|
||
category.classList.remove('expanded');
|
||
if (icon) {
|
||
icon.style.transform = 'rotate(0deg)';
|
||
icon.textContent = '▶';
|
||
}
|
||
|
||
console.log(`❌ Fechando categoria: ${title} (ícone: ▶)`);
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Debug function to test accordion functionality
|
||
*/
|
||
function debugAccordion() {
|
||
console.log('🐛 DEBUG ACCORDION - Estado atual:');
|
||
|
||
const subcategories = document.querySelectorAll('.sidebar-subcategory');
|
||
subcategories.forEach((sub, index) => {
|
||
const title = sub.querySelector('.subcategory-title')?.textContent || `Subcategoria ${index}`;
|
||
const isExpanded = sub.classList.contains('expanded');
|
||
const manuallyCollapsed = sub.getAttribute('data-manually-collapsed') === 'true';
|
||
const visibleItems = sub.querySelectorAll('.sidebar-item:not(.hidden)').length;
|
||
|
||
console.log(`📂 ${title}:`);
|
||
console.log(` - Expandido: ${isExpanded}`);
|
||
console.log(` - Manualmente fechado: ${manuallyCollapsed}`);
|
||
console.log(` - Itens visíveis: ${visibleItems}`);
|
||
});
|
||
}
|
||
|
||
// Adicionar função global para debug
|
||
window.debugAccordion = debugAccordion;
|
||
|
||
/**
|
||
* Initialize sidebar expansion - CORRIGINDO ÍCONES E ESTADO
|
||
* Expands subcategories and UPDATES ICONS correctly
|
||
*/
|
||
function initializeSidebarExpansion() {
|
||
console.log('🔧 Inicializando sidebar: estado padrão FECHADO (mobile e desktop)');
|
||
|
||
// SUBCATEGORIAS: sempre iniciar FECHADAS
|
||
const subcategories = document.querySelectorAll('.sidebar-subcategory');
|
||
subcategories.forEach(subcategory => {
|
||
subcategory.classList.remove('expanded');
|
||
const icon = subcategory.querySelector('.category-icon');
|
||
const content = subcategory.querySelector('.sidebar-subcategory-content');
|
||
if (icon) {
|
||
icon.style.transform = 'rotate(0deg)';
|
||
icon.textContent = '▶';
|
||
}
|
||
if (content) {
|
||
content.style.maxHeight = '';
|
||
content.style.opacity = '';
|
||
content.style.visibility = '';
|
||
}
|
||
});
|
||
|
||
// CATEGORIAS: sempre iniciar FECHADAS
|
||
const categories = document.querySelectorAll('.sidebar-category');
|
||
categories.forEach(category => {
|
||
category.classList.remove('expanded');
|
||
const icon = category.querySelector('.category-icon');
|
||
const content = category.querySelector('.sidebar-category-content');
|
||
if (icon) {
|
||
icon.style.transform = 'rotate(0deg)';
|
||
icon.textContent = '▶';
|
||
}
|
||
if (content) {
|
||
content.style.maxHeight = '';
|
||
content.style.opacity = '';
|
||
content.style.visibility = '';
|
||
}
|
||
});
|
||
}
|
||
|
||
function toggleFavorite(event, sectionId) {
|
||
event.stopPropagation();
|
||
const starBtn = event.target;
|
||
|
||
const favIndex = appState.favorites.indexOf(sectionId);
|
||
if (favIndex > -1) {
|
||
appState.favorites.splice(favIndex, 1);
|
||
starBtn.textContent = '☆';
|
||
starBtn.classList.remove('active');
|
||
} else {
|
||
appState.favorites.push(sectionId);
|
||
starBtn.textContent = '★';
|
||
starBtn.classList.add('active');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Toggle category expansion in sidebar - CORRIGINDO ÍCONES
|
||
* @param {HTMLElement} header - Category header element
|
||
* @param {Event} event - Click event
|
||
*/
|
||
function toggleCategory(header, event) {
|
||
if (event) {
|
||
event.stopPropagation();
|
||
event.preventDefault();
|
||
}
|
||
|
||
console.log('🔄 toggleCategory chamado');
|
||
|
||
const category = header.parentElement;
|
||
const isExpanded = category.classList.contains('expanded');
|
||
const categoryTitle = header.querySelector('.category-title, .subcategory-title')?.textContent || 'Categoria';
|
||
const icon = header.querySelector('.category-icon');
|
||
const content = header.nextElementSibling; // Works for both category and subcategory content
|
||
|
||
console.log(`📂 Categoria: ${categoryTitle}`);
|
||
console.log(`📊 Estado atual: ${isExpanded ? 'EXPANDIDO (▼)' : 'FECHADO (▶)'}`);
|
||
|
||
if (isExpanded) {
|
||
// FECHAR
|
||
category.classList.remove('expanded');
|
||
category.setAttribute('data-manually-collapsed', 'true');
|
||
|
||
if (icon) {
|
||
icon.style.transform = 'rotate(0deg)';
|
||
icon.textContent = '▶';
|
||
}
|
||
|
||
// Clear any inline styles to let CSS handle transitions
|
||
if (content) {
|
||
content.style.maxHeight = '';
|
||
content.style.opacity = '';
|
||
content.style.visibility = '';
|
||
}
|
||
|
||
console.log('❌ FECHANDO categoria (ícone: ▶)');
|
||
} else {
|
||
// ABRIR
|
||
category.classList.add('expanded');
|
||
category.removeAttribute('data-manually-collapsed');
|
||
|
||
if (icon) {
|
||
icon.style.transform = 'rotate(90deg)';
|
||
icon.textContent = '▼';
|
||
}
|
||
|
||
// Ensure inline styles are cleared so CSS expanded state applies cleanly
|
||
if (content) {
|
||
content.style.maxHeight = '';
|
||
content.style.opacity = '';
|
||
content.style.visibility = '';
|
||
}
|
||
|
||
console.log('✅ ABRINDO categoria (ícone: ▼)');
|
||
}
|
||
}
|
||
|
||
function addToHistory(title, details) {
|
||
const historyItem = {
|
||
id: Date.now(),
|
||
title: title,
|
||
details: details,
|
||
date: new Date().toLocaleString('pt-BR')
|
||
};
|
||
appState.history.unshift(historyItem);
|
||
if (appState.history.length > 100) {
|
||
appState.history = appState.history.slice(0, 100);
|
||
}
|
||
}
|
||
|
||
function openHistoryModal() {
|
||
const modal = document.getElementById('history-modal');
|
||
const list = document.getElementById('history-list');
|
||
|
||
if (appState.history.length === 0) {
|
||
list.innerHTML = '<p style="text-align: center; color: var(--color-text-secondary);">Nenhum cálculo no histórico</p>';
|
||
} else {
|
||
list.innerHTML = appState.history.map(item => `
|
||
<div class="history-item">
|
||
<div style="font-weight: 600; margin-bottom: 4px;">${item.title}</div>
|
||
<div style="font-size: 12px; color: var(--color-text-secondary);">${item.date}</div>
|
||
<p style="margin-top: 8px; font-size: 14px;">${item.details}</p>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
|
||
modal.classList.add('active');
|
||
}
|
||
|
||
function closeHistoryModal() {
|
||
document.getElementById('history-modal').classList.remove('active');
|
||
}
|
||
|
||
function openFavoritesModal() {
|
||
const modal = document.getElementById('favorites-modal');
|
||
const list = document.getElementById('favorites-list');
|
||
|
||
if (appState.favorites.length === 0) {
|
||
list.innerHTML = '<p style="text-align: center; color: var(--color-text-secondary);">Nenhuma seção favoritada</p>';
|
||
} else {
|
||
list.innerHTML = appState.favorites.map(sectionId => `
|
||
<div class="favorite-item" style="cursor: pointer;" onclick="showSection('${sectionId}'); closeFavoritesModal();">
|
||
<strong>${getSectionName(sectionId)}</strong>
|
||
</div>
|
||
`).join('');
|
||
}
|
||
|
||
modal.classList.add('active');
|
||
}
|
||
|
||
function closeFavoritesModal() {
|
||
document.getElementById('favorites-modal').classList.remove('active');
|
||
}
|
||
|
||
function updateUtFields() {
|
||
const type = document.getElementById('ut-type').value;
|
||
const diameterGroup = document.getElementById('ut-diameter-group');
|
||
const qtyGroup = document.getElementById('ut-qty-group');
|
||
const lengthGroup = document.getElementById('ut-length-group');
|
||
|
||
if (type === 'porosidade') {
|
||
diameterGroup.style.display = 'block';
|
||
qtyGroup.style.display = 'block';
|
||
lengthGroup.style.display = 'block';
|
||
} else if (type === 'trinca' || type === 'falta-fusao' || type === 'falta-penetracao') {
|
||
diameterGroup.style.display = 'none';
|
||
qtyGroup.style.display = 'none';
|
||
lengthGroup.style.display = 'block';
|
||
} else {
|
||
diameterGroup.style.display = 'block';
|
||
qtyGroup.style.display = 'block';
|
||
lengthGroup.style.display = 'block';
|
||
}
|
||
}
|
||
|
||
function analisarUltrassom() {
|
||
const norm = document.getElementById('ut-norm').value;
|
||
const type = document.getElementById('ut-type').value;
|
||
const location = document.getElementById('ut-location').value;
|
||
const diameter = parseFloat(document.getElementById('ut-diameter').value) || 0;
|
||
const qty = parseInt(document.getElementById('ut-qty').value) || 0;
|
||
const length = parseFloat(document.getElementById('ut-length').value) || 0;
|
||
const depth = parseFloat(document.getElementById('ut-depth').value) || 0;
|
||
const thickness = parseFloat(document.getElementById('ut-thickness').value) || 0;
|
||
|
||
let maxDiameter = 3;
|
||
let maxQtyIn25mm = 5;
|
||
let maxDepth = thickness / 4;
|
||
let status = '✅ ACEITA';
|
||
let alertClass = 'alert-success';
|
||
let reasoning = [];
|
||
|
||
if (norm === 'aws') {
|
||
maxDiameter = 3;
|
||
maxQtyIn25mm = 5;
|
||
} else if (norm === 'asme') {
|
||
maxDiameter = 4;
|
||
maxQtyIn25mm = 6;
|
||
} else {
|
||
maxDiameter = 3.5;
|
||
maxQtyIn25mm = 5;
|
||
}
|
||
|
||
if (type === 'porosidade') {
|
||
const totalLength = qty * diameter;
|
||
const allowedInSpan = 25 * 0.36;
|
||
|
||
if (diameter > maxDiameter) {
|
||
status = '❌ REJEITA';
|
||
alertClass = 'alert-error';
|
||
reasoning.push(`Diâmetro ${diameter}mm > máximo ${maxDiameter}mm`);
|
||
}
|
||
|
||
if (qty > maxQtyIn25mm) {
|
||
status = '❌ REJEITA';
|
||
alertClass = 'alert-error';
|
||
reasoning.push(`Quantidade ${qty} > máximo ${maxQtyIn25mm} poros em 25mm`);
|
||
}
|
||
|
||
if (totalLength > allowedInSpan) {
|
||
status = '⚠️ ANÁLISE';
|
||
if (alertClass !== 'alert-error') alertClass = 'alert-warning';
|
||
reasoning.push(`Comprimento total ${totalLength.toFixed(1)}mm > permitido ${allowedInSpan.toFixed(1)}mm`);
|
||
}
|
||
|
||
if (depth > maxDepth) {
|
||
status = '❌ REJEITA';
|
||
alertClass = 'alert-error';
|
||
reasoning.push(`Profundidade ${depth}mm > máximo ${maxDepth.toFixed(1)}mm (esp/4)`);
|
||
}
|
||
|
||
if (status === '✅ ACEITA') {
|
||
reasoning.push(`Diâmetro ${diameter}mm ≤ ${maxDiameter}mm ✓`);
|
||
reasoning.push(`Quantidade ${qty} ≤ ${maxQtyIn25mm} em 25mm ✓`);
|
||
reasoning.push(`Comprimento total ${totalLength.toFixed(1)}mm ≤ ${allowedInSpan.toFixed(1)}mm ✓`);
|
||
reasoning.push(`Profundidade ${depth}mm ≤ ${maxDepth.toFixed(1)}mm ✓`);
|
||
}
|
||
} else if (type === 'trinca') {
|
||
status = '❌ REJEITA';
|
||
alertClass = 'alert-error';
|
||
reasoning.push('Trincas não são permitidas em nenhuma norma');
|
||
reasoning.push('Ação requerida: Remover completamente a solda e refazer');
|
||
} else if (type === 'falta-fusao' || type === 'falta-penetracao') {
|
||
if (length > 25) {
|
||
status = '❌ REJEITA';
|
||
alertClass = 'alert-error';
|
||
reasoning.push(`Comprimento ${length}mm > máximo 25mm`);
|
||
} else if (length > 10) {
|
||
status = '⚠️ ANÁLISE';
|
||
alertClass = 'alert-warning';
|
||
reasoning.push(`Comprimento ${length}mm requer análise de engenharia`);
|
||
} else {
|
||
status = '✅ ACEITA';
|
||
reasoning.push(`Comprimento ${length}mm ≤ 10mm (aceitável) ✓`);
|
||
}
|
||
}
|
||
|
||
const normName = norm === 'aws' ? 'AWS D1.1' : norm === 'asme' ? 'ASME Sec VIII' : 'DNV-GL';
|
||
const typeName = {
|
||
'porosidade': 'Porosidade',
|
||
'inclusao': 'Inclusão de Escória',
|
||
'falta-fusao': 'Falta de Fusão',
|
||
'falta-penetracao': 'Falta de Penetração',
|
||
'trinca': 'Trinca',
|
||
'mordedura': 'Mordedura'
|
||
}[type];
|
||
|
||
document.getElementById('ut-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-primary);">
|
||
<div class="result-title">🏥 INTERPRETAÇÃO ULTRASSOM - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>NORMA APLICADA:</strong> ${normName}<br>
|
||
<strong>Descontinuidade:</strong> ${typeName}<br>
|
||
<strong>Localização:</strong> ${location.charAt(0).toUpperCase() + location.slice(1)}
|
||
</div>
|
||
|
||
${type === 'porosidade' ? `
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>DADOS DA DESCONTINUIDADE:</strong><br>
|
||
• Diâmetro: ${diameter} mm<br>
|
||
• Quantidade: ${qty} poros<br>
|
||
• Tamanho Total: ${(qty * diameter).toFixed(1)} mm<br>
|
||
• Profundidade: ${depth} mm<br>
|
||
• Espessura Chapa: ${thickness} mm
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-bg-2); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>CRITÉRIO ${normName}:</strong><br>
|
||
<strong>Porosidade Isolada:</strong><br>
|
||
• Diâmetro máximo: ${maxDiameter} mm<br>
|
||
• Quantidade máxima: ${maxQtyIn25mm} poros em 25mm<br>
|
||
• Comprimento total permitido: ${(25 * 0.36).toFixed(1)} mm em 25mm<br>
|
||
• Profundidade máxima: ${maxDepth.toFixed(1)} mm (espessura/4)
|
||
</div>
|
||
` : type === 'trinca' ? `
|
||
<div style="padding: 16px; background: var(--color-bg-4); border-radius: 8px; margin-bottom: 16px; border: 2px solid var(--color-error);">
|
||
<strong>⚠️ DESCONTINUIDADE CRÍTICA:</strong><br>
|
||
Trincas são defeitos graves que comprometem a integridade estrutural.<br>
|
||
Nenhuma norma permite trincas de qualquer tamanho.
|
||
</div>
|
||
` : `
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>DADOS:</strong><br>
|
||
• Comprimento: ${length} mm<br>
|
||
• Profundidade: ${depth} mm<br>
|
||
• Espessura: ${thickness} mm
|
||
</div>
|
||
`}
|
||
|
||
<div style="padding: 16px; background: var(--color-bg-3); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>📊 ANÁLISE:</strong><br>
|
||
${reasoning.map(r => `• ${r}`).join('<br>')}
|
||
</div>
|
||
|
||
<div class="alert ${alertClass}">
|
||
<strong>RESULTADO: ${status}</strong><br>
|
||
${status === '✅ ACEITA' ? 'Descontinuidade dentro dos limites permitidos. A solda está APROVADA para serviço.' :
|
||
status === '❌ REJEITA' ? 'Descontinuidade excede limites. REPROVAR a solda e realizar retrabalho.' :
|
||
'Descontinuidade requer análise de engenharia detalhada antes da aprovação.'}
|
||
</div>
|
||
|
||
${status === '❌ REJEITA' ? `
|
||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
|
||
<strong>🔧 OPÇÕES DE REPARO:</strong><br>
|
||
1. <strong>Retrabalho Total:</strong> Remover completamente a solda defeituosa e refazer<br>
|
||
2. <strong>Retoque Local:</strong> Escarear o defeito e preencher com nova solda<br>
|
||
3. <strong>Análise de Risco:</strong> Para casos não-críticos, avaliar se pode ser aceito com ressalvas
|
||
</div>
|
||
` : ''}
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Ultrassom', `${typeName}, ${status}`);
|
||
}
|
||
|
||
function calcularCustoTotal() {
|
||
const areaInput = document.getElementById('custo-area');
|
||
const regiaoInput = document.getElementById('custo-regiao');
|
||
const tipoTintaInput = document.getElementById('custo-tipo-tinta');
|
||
const custoMOInput = document.getElementById('custo-mo');
|
||
const prodInput = document.getElementById('custo-prod');
|
||
const volumeInput = document.getElementById('custo-volume');
|
||
|
||
const area = parseFloat(areaInput?.value) || 0;
|
||
const regiao = regiaoInput?.value || 'sudeste';
|
||
const tipoTinta = tipoTintaInput?.value || 'padrao';
|
||
const custoMO = parseFloat(custoMOInput?.value) || 85;
|
||
const prod = parseFloat(prodInput?.value) || 5;
|
||
const volume = parseFloat(volumeInput?.value) || 0;
|
||
const incluirEPI = document.getElementById('custo-incluir-epi')?.checked || false;
|
||
const incluirEquip = document.getElementById('custo-incluir-equip')?.checked || false;
|
||
|
||
if (area <= 0 || isNaN(area)) {
|
||
const resultEl = document.getElementById('custo-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Área inválida. Insira um valor maior que 0.</div>';
|
||
return;
|
||
}
|
||
if (prod <= 0) {
|
||
const resultEl = document.getElementById('custo-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Produtividade inválida. Insira um valor maior que 0.</div>';
|
||
return;
|
||
}
|
||
if (volume < 0) {
|
||
const resultEl = document.getElementById('custo-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Volume não pode ser negativo.</div>';
|
||
return;
|
||
}
|
||
|
||
const precosTinta = {
|
||
sudeste: { padrao: 80, premium: 120, economica: 50 },
|
||
sul: { padrao: 75, premium: 115, economica: 48 },
|
||
nordeste: { padrao: 85, premium: 125, economica: 52 },
|
||
centrooeste: { padrao: 82, premium: 122, economica: 51 }
|
||
};
|
||
|
||
const precoLitro = precosTinta[regiao][tipoTinta];
|
||
const custoMaterial = volume * precoLitro;
|
||
const horasTotais = area / prod;
|
||
const custoMaoObra = horasTotais * custoMO;
|
||
const custoEPI = incluirEPI ? 500 : 0;
|
||
const custoEquip = incluirEquip ? 800 : 0;
|
||
|
||
const subtotal = custoMaterial + custoMaoObra + custoEPI + custoEquip;
|
||
const margem = subtotal * 0.10;
|
||
const total = subtotal + margem;
|
||
const custoPorM2 = total / area;
|
||
|
||
const regiaoNome = {
|
||
sudeste: 'Sudeste',
|
||
sul: 'Sul',
|
||
nordeste: 'Nordeste',
|
||
centrooeste: 'Centro-Oeste'
|
||
}[regiao];
|
||
|
||
const tintaNome = {
|
||
padrao: 'Padrão Industrial',
|
||
premium: 'Premium',
|
||
economica: 'Econômica'
|
||
}[tipoTinta];
|
||
|
||
document.getElementById('custo-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-2); border-left: 4px solid var(--color-warning);">
|
||
<div class="result-title">💰 CUSTO TOTAL - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>PARÂMETROS:</strong><br>
|
||
Área: ${area} m²<br>
|
||
Região: ${regiaoNome}<br>
|
||
Tinta: ${tintaNome} (R$ ${precoLitro}/L)<br>
|
||
Volume: ${volume} L
|
||
</div>
|
||
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Custo Material (Tinta)</div>
|
||
<div class="result-value">R$ ${custoMaterial.toFixed(2)}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Custo Mão de Obra</div>
|
||
<div class="result-value">R$ ${custoMaoObra.toFixed(2)}</div>
|
||
</div>
|
||
${incluirEPI ? `
|
||
<div class="result-item">
|
||
<div class="result-label">EPI e Consumíveis</div>
|
||
<div class="result-value">R$ ${custoEPI.toFixed(2)}</div>
|
||
</div>
|
||
` : ''}
|
||
${incluirEquip ? `
|
||
<div class="result-item">
|
||
<div class="result-label">Aluguel Equipamentos</div>
|
||
<div class="result-value">R$ ${custoEquip.toFixed(2)}</div>
|
||
</div>
|
||
` : ''}
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 20px; background: var(--color-bg-3); border-radius: 12px; border: 2px solid var(--color-success);">
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px;">
|
||
<div>
|
||
<strong>Subtotal:</strong><br>
|
||
<span style="font-size: 20px;">R$ ${subtotal.toFixed(2)}</span>
|
||
</div>
|
||
<div>
|
||
<strong>Margem (10%):</strong><br>
|
||
<span style="font-size: 20px;">R$ ${margem.toFixed(2)}</span>
|
||
</div>
|
||
</div>
|
||
<hr style="margin: 16px 0; border: 1px solid var(--color-border);">
|
||
<div style="text-align: center;">
|
||
<strong style="font-size: 18px;">TOTAL GERAL:</strong><br>
|
||
<span style="font-size: 32px; color: var(--color-success); font-weight: bold;">R$ ${total.toFixed(2)}</span><br>
|
||
<span style="color: var(--color-text-secondary);">(Custo por m²: R$ ${custoPorM2.toFixed(2)}/m²)</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>📊 BREAKDOWN DETALHADO:</strong><br>
|
||
• Horas totais: ${horasTotais.toFixed(1)} h (${area}m² ÷ ${prod}m²/h)<br>
|
||
• Custo/hora MO: R$ ${custoMO}/h<br>
|
||
• Produtividade: ${prod} m²/h<br>
|
||
• Tempo estimado: ${Math.ceil(horasTotais / 8)} dias (8h/dia)
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Custo Pintura', `${area}m², R$ ${total.toFixed(2)}`);
|
||
}
|
||
|
||
function calcularSecagem() {
|
||
const tipoInput = document.getElementById('sec-tipo');
|
||
const tempInput = document.getElementById('sec-temp');
|
||
const umidadeInput = document.getElementById('sec-umidade');
|
||
const espessuraInput = document.getElementById('sec-espessura');
|
||
|
||
const tipo = tipoInput?.value || 'epoxi';
|
||
const temp = parseFloat(tempInput?.value) || 25;
|
||
const umidade = parseFloat(umidadeInput?.value) || 60;
|
||
const espessura = parseFloat(espessuraInput?.value) || 80;
|
||
|
||
if (temp < -20 || temp > 300) {
|
||
const resultEl = document.getElementById('sec-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Temperatura inválida. Use valores entre -20°C e 300°C.</div>';
|
||
return;
|
||
}
|
||
if (umidade < 0 || umidade > 100) {
|
||
const resultEl = document.getElementById('sec-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Umidade inválida. Use valores entre 0% e 100%.</div>';
|
||
return;
|
||
}
|
||
if (espessura <= 0 || espessura > 1000) {
|
||
const resultEl = document.getElementById('sec-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Espessura inválida. Use valores entre 1 e 1000 microns.</div>';
|
||
return;
|
||
}
|
||
|
||
const dadosTinta = {
|
||
epoxi: { tempIdeal: 25, umidadeMax: 85, tempoBase: 24, fatorEsp: 0.2 },
|
||
poliuretano: { tempIdeal: 20, umidadeMax: 80, tempoBase: 16, fatorEsp: 0.15 },
|
||
alquidica: { tempIdeal: 25, umidadeMax: 75, tempoBase: 48, fatorEsp: 0.3 },
|
||
acrilica: { tempIdeal: 23, umidadeMax: 70, tempoBase: 12, fatorEsp: 0.1 }
|
||
};
|
||
|
||
const dados = dadosTinta[tipo];
|
||
const fatorTemp = 1 + ((dados.tempIdeal - temp) * 0.05);
|
||
const fatorUmid = umidade > dados.umidadeMax ? 1.3 : 1.0;
|
||
const fatorEsp = 1 + ((espessura - 80) / 80 * dados.fatorEsp);
|
||
|
||
const tempoToque = dados.tempoBase * 0.25 * fatorTemp * fatorUmid * fatorEsp;
|
||
const tempoManipulacao = dados.tempoBase * 0.5 * fatorTemp * fatorUmid * fatorEsp;
|
||
const tempoProximaDemao = dados.tempoBase * fatorTemp * fatorUmid * fatorEsp;
|
||
const tempoCuraTotal = dados.tempoBase * 3 * fatorTemp * fatorUmid * fatorEsp;
|
||
|
||
let alertas = [];
|
||
let alertClass = 'alert-success';
|
||
|
||
if (temp < 5) {
|
||
alertas.push('⚠️ Temperatura muito baixa (< 5°C) - NÃO APLICAR');
|
||
alertClass = 'alert-error';
|
||
} else if (temp < 10) {
|
||
alertas.push('⚠️ Temperatura baixa - Tempo de secagem significativamente aumentado');
|
||
alertClass = 'alert-warning';
|
||
}
|
||
|
||
if (umidade > dados.umidadeMax) {
|
||
alertas.push(`⚠️ Umidade acima do máximo (${dados.umidadeMax}%) - Risco de defeitos`);
|
||
alertClass = 'alert-error';
|
||
} else if (umidade > dados.umidadeMax - 10) {
|
||
alertas.push(`⚠️ Umidade próxima do limite - Monitorar condições`);
|
||
if (alertClass !== 'alert-error') alertClass = 'alert-warning';
|
||
}
|
||
|
||
if (temp > 40) {
|
||
alertas.push('⚠️ Temperatura muito alta - Risco de secagem rápida e defeitos');
|
||
if (alertClass !== 'alert-error') alertClass = 'alert-warning';
|
||
}
|
||
|
||
if (alertas.length === 0) {
|
||
alertas.push('✅ Condições ideais para aplicação');
|
||
}
|
||
|
||
const tipoNome = {
|
||
epoxi: 'Epóxi (2 componentes)',
|
||
poliuretano: 'Poliuretano (PU)',
|
||
alquidica: 'Alquídica',
|
||
acrilica: 'Acrílica'
|
||
}[tipo];
|
||
|
||
document.getElementById('sec-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-5); border-left: 4px solid #a855f7;">
|
||
<div class="result-title">⏱️ TEMPO DE SECAGEM - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>TIPO DE TINTA:</strong> ${tipoNome}<br>
|
||
<strong>Temperatura:</strong> ${temp}°C<br>
|
||
<strong>Umidade Relativa:</strong> ${umidade}%<br>
|
||
<strong>Espessura:</strong> ${espessura} μm
|
||
</div>
|
||
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Secagem ao Toque</div>
|
||
<div class="result-value">${Math.round(tempoToque)} h</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Manipulação</div>
|
||
<div class="result-value">${Math.round(tempoManipulacao)} h</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Próxima Demão</div>
|
||
<div class="result-value">${Math.round(tempoProximaDemao)} h</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Cura Total</div>
|
||
<div class="result-value">${Math.round(tempoCuraTotal / 24)} dias</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
|
||
<strong>📊 FATORES DE CORREÇÃO APLICADOS:</strong><br>
|
||
• Fator Temperatura: ${fatorTemp.toFixed(2)}×<br>
|
||
• Fator Umidade: ${fatorUmid.toFixed(2)}×<br>
|
||
• Fator Espessura: ${fatorEsp.toFixed(2)}×<br>
|
||
• Tempo Base (${tipoNome}): ${dados.tempoBase}h
|
||
</div>
|
||
|
||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||
<strong>ALERTAS E RECOMENDAÇÕES:</strong><br>
|
||
${alertas.map(a => `${a}`).join('<br>')}
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>💡 DICAS PARA MELHORAR CONDIÇÕES:</strong><br>
|
||
${temp < 15 ? '• Aumentar temperatura do ambiente com aquecedores<br>' : ''}
|
||
${umidade > 75 ? '• Usar desumidificadores ou melhorar ventilação<br>' : ''}
|
||
• Aplicar em horários de menor umidade (meio-dia)<br>
|
||
• Evitar aplicação com orvalho ou chuva prevista<br>
|
||
• Proteger superfície de contaminação durante secagem
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Tempo Secagem', `${tipoNome}, ${Math.round(tempoProximaDemao)}h`);
|
||
}
|
||
|
||
function gerarRelatorioInspecao() {
|
||
const checks = [];
|
||
for (let i = 1; i <= 8; i++) {
|
||
const checkbox = document.getElementById(`insp-${i}`);
|
||
checks.push({
|
||
id: i,
|
||
checked: checkbox.checked,
|
||
label: checkbox.nextElementSibling.textContent
|
||
});
|
||
}
|
||
|
||
const totalChecked = checks.filter(c => c.checked).length;
|
||
const percentApproved = (totalChecked / checks.length) * 100;
|
||
|
||
let status = '';
|
||
let alertClass = '';
|
||
let recommendation = '';
|
||
|
||
if (percentApproved === 100) {
|
||
status = '✅ APROVADO';
|
||
alertClass = 'alert-success';
|
||
recommendation = 'Todos os critérios foram atendidos. Pintura aprovada para aceitação final.';
|
||
} else if (percentApproved >= 75) {
|
||
status = '⚠️ APROVADO COM RESSALVAS';
|
||
alertClass = 'alert-warning';
|
||
recommendation = 'Maioria dos critérios atendidos. Verificar itens pendentes antes da liberação final.';
|
||
} else {
|
||
status = '❌ REPROVADO';
|
||
alertClass = 'alert-error';
|
||
recommendation = 'Vários critérios não atendidos. Realizar correções antes de aprovar.';
|
||
}
|
||
|
||
const uncheckedItems = checks.filter(c => !c.checked);
|
||
|
||
document.getElementById('insp-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-primary);">
|
||
<div class="result-title">📋 RELATÓRIO DE INSPEÇÃO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 20px; background: var(--color-surface); border-radius: 12px; text-align: center;">
|
||
<div style="font-size: 48px; margin-bottom: 10px;">${Math.round(percentApproved)}%</div>
|
||
<div style="font-size: 18px; font-weight: bold;">${totalChecked} de ${checks.length} critérios aprovados</div>
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>ITENS VERIFICADOS:</strong><br><br>
|
||
${checks.map(c => `
|
||
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 8px;">
|
||
<span style="font-size: 20px;">${c.checked ? '✅' : '❌'}</span>
|
||
<span style="${c.checked ? '' : 'color: var(--color-error); font-weight: bold;'}">${c.label}</span>
|
||
</div>
|
||
`).join('')}
|
||
</div>
|
||
|
||
${uncheckedItems.length > 0 ? `
|
||
<div style="padding: 16px; background: var(--color-bg-4); border-radius: 8px; margin-bottom: 16px; border: 2px solid var(--color-error);">
|
||
<strong>⚠️ ITENS NÃO CONFORMES (${uncheckedItems.length}):</strong><br><br>
|
||
${uncheckedItems.map((item, idx) => `${idx + 1}. ${item.label}`).join('<br>')}
|
||
</div>
|
||
` : ''}
|
||
|
||
<div class="alert ${alertClass}">
|
||
<strong>STATUS: ${status}</strong><br>
|
||
${recommendation}
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-3); border-radius: 8px;">
|
||
<strong>📝 AÇÕES CORRETIVAS SUGERIDAS:</strong><br>
|
||
${uncheckedItems.length > 0 ? `
|
||
${uncheckedItems.map((item, idx) => {
|
||
let action = '';
|
||
if (item.id === 1) action = 'Realizar nova preparação com grau Sa 2½';
|
||
else if (item.id === 2) action = 'Limpar superfície com solvente adequado';
|
||
else if (item.id === 3) action = 'Aplicar demão adicional para atingir DFT especificado';
|
||
else if (item.id === 4) action = 'Melhorar técnica de aplicação ou preparação';
|
||
else if (item.id === 5) action = 'Aplicar retoque ou nova demão';
|
||
else if (item.id === 6) action = 'Aplicar nova demão nas áreas descobertas';
|
||
else if (item.id === 7) action = 'Remover defeitos e reaplicar';
|
||
else if (item.id === 8) action = 'Aguardar tempo de cura adequado';
|
||
return `${idx + 1}. ${action}`;
|
||
}).join('<br>')}
|
||
` : 'Nenhuma ação corretiva necessária ✓'}
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; text-align: center;">
|
||
<strong>Data da Inspeção:</strong> ${new Date().toLocaleDateString('pt-BR')}<br>
|
||
<strong>Norma de Referência:</strong> ISO 12944
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Inspeção Pintura', `${percentApproved.toFixed(0)}% aprovado, ${status}`);
|
||
}
|
||
|
||
function getSectionName(sectionId) {
|
||
const names = {
|
||
'cev': 'CEV Avançado',
|
||
'seletor': 'Seletor de Aço',
|
||
'equivalencias': 'Equivalências',
|
||
'comparativo': 'Comparativo',
|
||
'parafusos': 'Ligações Parafusadas',
|
||
'layout': 'Layout de Furação',
|
||
'parafuso-vs-solda': 'Parafuso vs Solda',
|
||
'preaquecimento': 'Pré-Aquecimento',
|
||
'solda-filete': 'Solda Filete',
|
||
'energia-soldagem': 'Energia de Soldagem',
|
||
'consumo-eletrodos': 'Consumo de Eletrodos',
|
||
'dureza': 'Dureza',
|
||
'charpy': 'Charpy',
|
||
'certificado': 'Certificado',
|
||
'ultrassom': 'Ultrassom',
|
||
'area-pintura': 'Área de Pintura',
|
||
'consumo-tinta': 'Consumo de Tinta',
|
||
'galvanizacao': 'Galvanização',
|
||
'custo-pintura': 'Custo Pintura',
|
||
'secagem': 'Secagem',
|
||
'inspecao-pintura': 'Inspeção',
|
||
'orcamento': 'Orçamento',
|
||
'peso-rigging': 'Peso & Rigging',
|
||
'referencia': 'Referência'
|
||
};
|
||
return names[sectionId] || sectionId;
|
||
}
|
||
|
||
// ========================================
|
||
// SECTION CONTENT GENERATORS
|
||
// ========================================
|
||
|
||
function getCEVContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🔬 CEV Avançado (IIW + Pcm)</div>
|
||
<div class="section-description">Cálculo do Carbono Equivalente para avaliação de soldabilidade segundo IIW e Pcm</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Composição Química (%)</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Carbono (C)</label>
|
||
<input type="number" class="form-control" id="cev-c" step="0.01" value="0.20">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Manganês (Mn)</label>
|
||
<input type="number" class="form-control" id="cev-mn" step="0.01" value="1.00">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Cromo (Cr)</label>
|
||
<input type="number" class="form-control" id="cev-cr" step="0.01" value="0.10">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Molibdênio (Mo)</label>
|
||
<input type="number" class="form-control" id="cev-mo" step="0.01" value="0.05">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Vanádio (V)</label>
|
||
<input type="number" class="form-control" id="cev-v" step="0.01" value="0.03">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Níquel (Ni)</label>
|
||
<input type="number" class="form-control" id="cev-ni" step="0.01" value="0.10">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Cobre (Cu)</label>
|
||
<input type="number" class="form-control" id="cev-cu" step="0.01" value="0.10">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Silício (Si)</label>
|
||
<input type="number" class="form-control" id="cev-si" step="0.01" value="0.25">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura (mm)</label>
|
||
<input type="number" class="form-control" id="cev-thickness" step="1" value="25">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Temperatura Ambiente (°C)</label>
|
||
<input type="number" class="form-control" id="cev-temp" step="1" value="20">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Fórmula</label>
|
||
<select class="form-control" id="cev-formula">
|
||
<option value="iw">IIW (Padrão)</option>
|
||
<option value="pcm">Pcm (Alta resistência)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="calcularCEV()">🔬 Calcular CEV</button>
|
||
</div>
|
||
|
||
<div id="cev-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getSeletorContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🎯 Seletor de Aço Inteligente</div>
|
||
<div class="section-description">Selecione o aço ideal baseado em critérios técnicos</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Critérios de Seleção</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Aplicação</label>
|
||
<select class="form-control" id="sel-app">
|
||
<option value="edificio">Edifício</option>
|
||
<option value="ponte">Ponte</option>
|
||
<option value="offshore">Offshore</option>
|
||
<option value="industrial">Industrial</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Temperatura de Serviço (°C)</label>
|
||
<input type="number" class="form-control" id="sel-temp" value="20">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Resistência Mínima (MPa)</label>
|
||
<input type="number" class="form-control" id="sel-fy" value="250">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Soldabilidade</label>
|
||
<select class="form-control" id="sel-weld">
|
||
<option value="any">Qualquer</option>
|
||
<option value="excellent">Excelente</option>
|
||
<option value="good">Boa</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="selecionarAco()">🎯 Buscar Aços</button>
|
||
</div>
|
||
|
||
<div id="seletor-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getEquivalenciasContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📊 Equivalências Internacionais</div>
|
||
<div class="section-description">Tabela de equivalências entre normas ASTM, EN, JIS, NBR</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Selecionar Aço</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Aço de Referência</label>
|
||
<select class="form-control" id="equiv-steel" onchange="mostrarEquivalencias()">
|
||
<option value="a36">ASTM A36</option>
|
||
<option value="a572">ASTM A572 Gr.50</option>
|
||
<option value="a588">ASTM A588</option>
|
||
<option value="s235">EN S235JR</option>
|
||
<option value="s355">EN S355J2</option>
|
||
<option value="ar350">NBR AR350</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="equiv-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getComparativoContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📈 Comparativo de Aços</div>
|
||
<div class="section-description">Comparação visual de propriedades mecânicas</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Selecionar Aços para Comparação</div>
|
||
<div class="checkbox-group">
|
||
<label class="checkbox-item">
|
||
<input type="checkbox" value="a36" checked> A36
|
||
</label>
|
||
<label class="checkbox-item">
|
||
<input type="checkbox" value="a572" checked> A572
|
||
</label>
|
||
<label class="checkbox-item">
|
||
<input type="checkbox" value="a588"> A588
|
||
</label>
|
||
<label class="checkbox-item">
|
||
<input type="checkbox" value="s235"> S235
|
||
</label>
|
||
<label class="checkbox-item">
|
||
<input type="checkbox" value="s355"> S355
|
||
</label>
|
||
<label class="checkbox-item">
|
||
<input type="checkbox" value="s460"> S460
|
||
</label>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Visualização</label>
|
||
<select class="form-control" id="chart-type" style="max-width: 300px;">
|
||
<option value="resistance">Resistência (fy vs fu)</option>
|
||
<option value="ductility">Ductilidade</option>
|
||
<option value="table">Tabela Comparativa</option>
|
||
</select>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="gerarGraficoComparativo()">📊 Gerar Comparação</button>
|
||
</div>
|
||
|
||
<div id="chart-result"></div>
|
||
`;
|
||
}
|
||
|
||
// Assistente Inteligente - Integrated Recommendation System
|
||
function getAssistenteInteligenteContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🤖 Assistente Inteligente de Seleção</div>
|
||
<div class="section-description">Recomendação integrada: Aço + Soldagem + Pintura baseada em relacionamentos técnicos</div>
|
||
</div>
|
||
|
||
<div class="card" style="background: var(--color-bg-1); border: 2px solid var(--color-primary);">
|
||
<div class="card-title">🎯 Seleção de Requisitos</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 16px;">
|
||
Informe os requisitos do projeto e receba recomendações técnicas completas
|
||
</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Aço Estrutural</label>
|
||
<select class="form-control" id="ai-steel" onchange="updateAIRecommendations()">
|
||
<option value="">-- Selecione o aço --</option>
|
||
<option value="ASTM A36">ASTM A36 - Construção civil leve</option>
|
||
<option value="ASTM A572 Gr.50">ASTM A572 Gr.50 - Estruturas médias/pesadas</option>
|
||
<option value="ASTM A572 Gr.60">ASTM A572 Gr.60 - Estruturas muito pesadas</option>
|
||
<option value="ASTM A588">ASTM A588 - Cor-Ten (sem pintura)</option>
|
||
<option value="ASTM A992">ASTM A992 - Perfis modernos</option>
|
||
<option value="ASTM A106">ASTM A106 - Tubulações alta pressão</option>
|
||
<option value="ASTM A709 Gr.50">ASTM A709 Gr.50 - Pontes</option>
|
||
<option value="EN S235JR">EN S235JR - Construção Europa</option>
|
||
<option value="EN S275">EN S275 - Estruturas médias Europa</option>
|
||
<option value="EN S355J2">EN S355J2 - Estruturas pesadas Europa</option>
|
||
<option value="EN S460">EN S460 - Alta resistência Europa</option>
|
||
<option value="NBR 7007 MR250">NBR 7007 MR250 - Brasil (equiv. A36)</option>
|
||
<option value="NBR 7007 AR290">NBR 7007 AR290 - Brasil média resist.</option>
|
||
<option value="NBR 7007 AR345">NBR 7007 AR345 - Brasil alta resist.</option>
|
||
<option value="ASTM A304">ASTM A304 (SS304) - Inox</option>
|
||
<option value="ASTM A316">ASTM A316 (SS316) - Inox marinho</option>
|
||
<option value="ABS Grade A">ABS Grade A - Naval mercante</option>
|
||
<option value="ABS Grade B">ABS Grade B - Naval reforçado</option>
|
||
<option value="ABS Grade AH36">ABS Grade AH36 - Naval alta resist.</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label class="form-label">Ambiente Corrosivo</label>
|
||
<select class="form-control" id="ai-environment" onchange="updateAIRecommendations()">
|
||
<option value="">-- Selecione o ambiente --</option>
|
||
<option value="C2">C2 - Urbano (baixa corrosão)</option>
|
||
<option value="C3">C3 - Industrial/Costeiro</option>
|
||
<option value="C4">C4 - Marinho/Industrial severo</option>
|
||
<option value="C5">C5 - Offshore/Extremo</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="generateAIRecommendation()" style="width: 100%;">
|
||
🤖 Gerar Recomendação Completa
|
||
</button>
|
||
</div>
|
||
|
||
<div id="ai-recommendations"></div>
|
||
`;
|
||
}
|
||
|
||
// ========================================
|
||
// NEW MATERIAL SECTIONS - PLACEHOLDERS
|
||
// ========================================
|
||
|
||
// CONSUMÍVEIS DE SOLDAGEM
|
||
function getEletrodosContent() {
|
||
return `<div class="section-header"><div class="section-title">⚡ Eletrodos Revestidos</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de eletrodos revestidos (SMAW)</p></div>`;
|
||
}
|
||
|
||
function getAramesContent() {
|
||
return `<div class="section-header"><div class="section-title">🌀 Arames Sólidos/Tubulares</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de arames para GMAW/FCAW</p></div>`;
|
||
}
|
||
|
||
function getFluxosContent() {
|
||
return `<div class="section-header"><div class="section-title">💨 Fluxos para SAW</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de fluxos para soldagem ao arco submerso</p></div>`;
|
||
}
|
||
|
||
function getGasesContent() {
|
||
return `<div class="section-header"><div class="section-title">🌫️ Gases de Proteção</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Gases e misturas para soldagem</p></div>`;
|
||
}
|
||
|
||
// FIXADORES
|
||
function getParafusosCatalogoContent() {
|
||
return `<div class="section-header"><div class="section-title">🔩 Catálogo de Parafusos</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Especificações técnicas de parafusos</p></div>`;
|
||
}
|
||
|
||
function getPorcasContent() {
|
||
return `<div class="section-header"><div class="section-title">🔸 Porcas</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de porcas</p></div>`;
|
||
}
|
||
|
||
function getArruelasContent() {
|
||
return `<div class="section-header"><div class="section-title">⭕ Arruelas</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Catálogo de arruelas</p></div>`;
|
||
}
|
||
|
||
function getChumbadoresContent() {
|
||
return `<div class="section-header"><div class="section-title">🔗 Chumbadores/Ancoragens</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Sistemas de ancoragem</p></div>`;
|
||
}
|
||
|
||
// TINTAS E REVESTIMENTOS
|
||
function getTintasCatalogoContent() {
|
||
return `<div class="section-header"><div class="section-title">🎨 Catálogo de Tintas</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Especificações técnicas de tintas</p></div>`;
|
||
}
|
||
|
||
function getSistemasPinturaContent() {
|
||
return `<div class="section-header"><div class="section-title">🖌️ Sistemas de Pintura</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Sistemas completos por ambiente</p></div>`;
|
||
}
|
||
|
||
function getAbrasivosContent() {
|
||
return `<div class="section-header"><div class="section-title">💎 Abrasivos para Jateamento</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Tipos de abrasivos e aplicações</p></div>`;
|
||
}
|
||
|
||
function getGranalhaContent() {
|
||
return `<div class="section-header"><div class="section-title">🔘 Granalha Metálica</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Granalha de aço para jateamento</p></div>`;
|
||
}
|
||
|
||
// ELEMENTOS COMPLEMENTARES
|
||
function getTelhasContent() {
|
||
return `<div class="section-header"><div class="section-title">🏠 Telhas Metálicas</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Especificações de telhas metálicas</p></div>`;
|
||
}
|
||
|
||
function getPaineisContent() {
|
||
return `<div class="section-header"><div class="section-title">🧱 Painéis Sanduíche</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Painéis termoacústicos</p></div>`;
|
||
}
|
||
|
||
function getSteelDeckContent() {
|
||
return `<div class="section-header"><div class="section-title">📐 Steel Deck</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Lajes mistas com steel deck</p></div>`;
|
||
}
|
||
|
||
function getPerfisFormadosContent() {
|
||
return `<div class="section-header"><div class="section-title">🔲 Perfis Formados a Frio</div></div>
|
||
<div class="card"><p>🚧 Seção em desenvolvimento - Light steel framing</p></div>`;
|
||
}
|
||
|
||
// ========================================
|
||
// CATÁLOGO DE PERFIS - FUNÇÕES DE CONTEÚDO
|
||
// ========================================
|
||
|
||
function getTubosRHSContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">▭ Tubos RHS (Retangulares)</div>
|
||
<div class="section-description">Catálogo completo de tubos retangulares estruturais</div>
|
||
</div>
|
||
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
|
||
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
|
||
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
|
||
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
|
||
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
|
||
</div>
|
||
|
||
<!-- Tab 1: Tabela Técnica -->
|
||
<div class="tab-content active" id="tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<div>
|
||
<h3 style="margin: 0; color: var(--color-primary);">📊 Tubos RHS Disponíveis</h3>
|
||
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
|
||
Total: <strong id="tubos_rhs-total">-</strong> perfis
|
||
</p>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="forcarCarregamentoTubosRhs()">
|
||
🔄 Recarregar Dados
|
||
</button>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Designação</th>
|
||
<th>Largura (mm)</th>
|
||
<th>Altura (mm)</th>
|
||
<th>Espessura (mm)</th>
|
||
<th>Peso (kg/m)</th>
|
||
<th>Área (cm²)</th>
|
||
<th>Categoria</th>
|
||
<th>Ações</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="tubos_rhs-tbody">
|
||
<tr>
|
||
<td colspan="8" style="text-align: center; padding: 40px;">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
|
||
<div style="font-size: 18px; font-weight: bold;">Carregando tubos RHS...</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 2: Especificações -->
|
||
<div class="tab-content" id="tab-1">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
|
||
<p><strong>Tubos estruturais retangulares/quadrados sem costura e soldados</strong></p>
|
||
<p>Perfis estruturais versáteis amplamente utilizados em construção civil, naval e industrial. Fabricados por soldagem ou sem costura, apresentam excelente relação resistência/peso e simetria estrutural.</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
|
||
<ul>
|
||
<li><strong>Dimensões:</strong> 50×50×2mm a 250×250×8mm</li>
|
||
<li><strong>Espessura:</strong> 2mm a 8mm</li>
|
||
<li><strong>Quantidade de modelos:</strong> 35 perfis diferentes</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Categoria</th>
|
||
<th>Dimensões</th>
|
||
<th>Quantidade</th>
|
||
<th>Aplicações Típicas</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><span class="badge badge-info">Pequeno</span></td>
|
||
<td>50×50 - 60×60</td>
|
||
<td>4 modelos</td>
|
||
<td>Estruturas leves, suportes</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-info">Médio</span></td>
|
||
<td>75 - 100</td>
|
||
<td>5 modelos</td>
|
||
<td>Treliças, galpões pequenos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Grande</span></td>
|
||
<td>120 - 150</td>
|
||
<td>7 modelos</td>
|
||
<td>Estruturas médias, torres</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Muito Grande</span></td>
|
||
<td>150 - 200</td>
|
||
<td>10 modelos</td>
|
||
<td>Estruturas críticas, pontes</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-danger">Massivo</span></td>
|
||
<td>200 - 250</td>
|
||
<td>9 modelos</td>
|
||
<td>Estruturas offshore, navais</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Qualidade</th>
|
||
<th>Fy (MPa)</th>
|
||
<th>Fu (MPa)</th>
|
||
<th>Aplicação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>SAE 1008-1015</td>
|
||
<td>210</td>
|
||
<td>400</td>
|
||
<td>Básica - estruturas leves</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1020-1025</td>
|
||
<td>235</td>
|
||
<td>420</td>
|
||
<td>Média - estruturas gerais</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1035-1045</td>
|
||
<td>280</td>
|
||
<td>520</td>
|
||
<td>Alta - estruturas pesadas</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 3: Fabricantes -->
|
||
<div class="tab-content" id="tab-2">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
|
||
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Fabricante</th>
|
||
<th>Localização</th>
|
||
<th>Gama de Produtos</th>
|
||
<th>Especialidade</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Gerdau</strong></td>
|
||
<td>Múltiplas plantas</td>
|
||
<td>Completa</td>
|
||
<td>Principal fornecedor nacional</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>CSN</strong></td>
|
||
<td>Volta Redonda (RJ)</td>
|
||
<td>Média a Grande</td>
|
||
<td>Séries pesadas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Usiminas</strong></td>
|
||
<td>Ipatinga (MG)</td>
|
||
<td>Pequena a Média</td>
|
||
<td>Qualidades especiais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Tupy</strong></td>
|
||
<td>Joinville (SC)</td>
|
||
<td>Média</td>
|
||
<td>Tubos especiais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Vallourec</strong></td>
|
||
<td>Múltiplas</td>
|
||
<td>Pequena</td>
|
||
<td>Tubos sem costura</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Confab</strong></td>
|
||
<td>Pindamonhangaba (SP)</td>
|
||
<td>Média a Grande</td>
|
||
<td>Tubos industriais</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
|
||
<p><strong>Padrão:</strong> 6m, 9m, 12m, 13.5m</p>
|
||
<p><strong>Especiais:</strong> Sob consulta</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
|
||
<ul>
|
||
<li><strong>Estoque:</strong> 3-5 dias</li>
|
||
<li><strong>Sob encomenda:</strong> 7-12 dias</li>
|
||
<li><strong>Especiais:</strong> 15-25 dias</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 4: Preços 2025 -->
|
||
<div class="tab-content" id="tab-3">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
|
||
|
||
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
|
||
<p><strong>Preço base:</strong> R$ 4,50 - R$ 10,00 por kg</p>
|
||
<p><strong>Variação por região:</strong> ±10-15%</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Situação</th>
|
||
<th>Variação</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Modelos pequenos (50-75mm)</td>
|
||
<td><span class="badge badge-danger">+15%</span></td>
|
||
<td>Menor demanda</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Modelos assimétricos</td>
|
||
<td><span class="badge badge-warning">+10%</span></td>
|
||
<td>Produção especial</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Paredes finas</td>
|
||
<td><span class="badge badge-warning">+5%</span></td>
|
||
<td>Processo delicado</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Quantidade >20 toneladas</td>
|
||
<td><span class="badge badge-success">-15%</span></td>
|
||
<td>Desconto por volume</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Corte customizado</td>
|
||
<td><span class="badge badge-warning">+taxa</span></td>
|
||
<td>Serviço adicional</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
|
||
<ul>
|
||
<li><strong>ABNT NBR 6591</strong> - Tubos de aço carbono para usos comuns</li>
|
||
<li><strong>ASTM A500</strong> - Tubos estruturais formados a frio</li>
|
||
<li><strong>EN 10210-1</strong> - Perfis estruturais acabados a quente</li>
|
||
<li><strong>API 5L</strong> - Tubos para transporte (aplicável)</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 5: Aplicações -->
|
||
<div class="tab-content" id="tab-4">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
|
||
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏗️ Construção Civil</h4>
|
||
<ul>
|
||
<li>Torres e antenas</li>
|
||
<li>Estruturas simétricas</li>
|
||
<li>Colunas estruturais</li>
|
||
<li>Treliças espaciais</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">⚓ Estruturas Marítimas</h4>
|
||
<ul>
|
||
<li>Plataformas offshore</li>
|
||
<li>Estruturas portuárias</li>
|
||
<li>Suportes subaquáticos</li>
|
||
<li>Estruturas navais</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
|
||
<ul>
|
||
<li>Suportes de equipamentos</li>
|
||
<li>Estruturas de máquinas</li>
|
||
<li>Plataformas industriais</li>
|
||
<li>Chassis e estruturas</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🌉 Infraestrutura</h4>
|
||
<ul>
|
||
<li>Pontes e viadutos</li>
|
||
<li>Passarelas</li>
|
||
<li>Estruturas de contenção</li>
|
||
<li>Suportes de sinalização</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
|
||
<ul>
|
||
<li>✓ Resistência à torção superior a perfis abertos</li>
|
||
<li>✓ Simetria facilita ligações e cálculos</li>
|
||
<li>✓ Teste de pressão 100% em modelos maiores</li>
|
||
<li>✓ Costura visível (sem costura sob pedido premium)</li>
|
||
<li>✓ Tolerância dimensional ±1mm</li>
|
||
<li>✓ Soldagem com E7018 ou GMAW recomendada</li>
|
||
<li>✓ Verificar flambagem em ambos os eixos</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getChapasContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📄 Chapas de Aço</div>
|
||
<div class="section-description">Catálogo completo de chapas estruturais</div>
|
||
</div>
|
||
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
|
||
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
|
||
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
|
||
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
|
||
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
|
||
</div>
|
||
|
||
<!-- Tab 1: Tabela Técnica -->
|
||
<div class="tab-content active" id="tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<div>
|
||
<h3 style="margin: 0; color: var(--color-primary);">📊 Chapas Disponíveis</h3>
|
||
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
|
||
Total: <strong id="chapas-total">-</strong> espessuras
|
||
</p>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="forcarCarregamentoChapas()">
|
||
🔄 Recarregar Dados
|
||
</button>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Designação</th>
|
||
<th>Espessura (mm)</th>
|
||
<th>Peso (kg/m²)</th>
|
||
<th>Categoria</th>
|
||
<th>Ações</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="chapas-tbody">
|
||
<tr>
|
||
<td colspan="5" style="text-align: center; padding: 40px;">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
|
||
<div style="font-size: 18px; font-weight: bold;">Carregando chapas...</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 2: Especificações -->
|
||
<div class="tab-content" id="tab-1">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
|
||
<p><strong>Chapas de aço carbono laminadas a quente</strong></p>
|
||
<p>Produtos planos de aço carbono laminados a quente, utilizados em estruturas soldadas, equipamentos industriais e componentes estruturais. Disponíveis em diversos formatos e espessuras.</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
|
||
<ul>
|
||
<li><strong>Espessura:</strong> 3.2mm a 50.8mm</li>
|
||
<li><strong>Formatos:</strong> 2500×1250mm a 2000×1000mm</li>
|
||
<li><strong>Peso:</strong> 25.12 kg/m² a 399.40 kg/m²</li>
|
||
<li><strong>Quantidade de modelos:</strong> 16 espessuras diferentes</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Categoria</th>
|
||
<th>Espessura</th>
|
||
<th>Quantidade</th>
|
||
<th>Aplicações Típicas</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><span class="badge badge-info">Fina</span></td>
|
||
<td>3.2 - 4.75mm</td>
|
||
<td>1 modelo</td>
|
||
<td>Chapas decorativas, revestimentos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-info">Média</span></td>
|
||
<td>6.35 - 9.5mm</td>
|
||
<td>3 modelos</td>
|
||
<td>Estruturas gerais, tanques</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Grossa</span></td>
|
||
<td>12.7 - 25.4mm</td>
|
||
<td>4 modelos</td>
|
||
<td>Estruturas críticas, bases</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Muito Grossa</span></td>
|
||
<td>31.75 - 44.5mm</td>
|
||
<td>4 modelos</td>
|
||
<td>Offshore, equipamentos pesados</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-danger">Ultra Grossa</span></td>
|
||
<td>38.1 - 50.8mm</td>
|
||
<td>4 modelos</td>
|
||
<td>Aplicações extremas, blindagem</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Qualidade</th>
|
||
<th>Fy (MPa)</th>
|
||
<th>Fu (MPa)</th>
|
||
<th>Aplicação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>SAE 1008-1025</td>
|
||
<td>210-235</td>
|
||
<td>400-420</td>
|
||
<td>Básica - estruturas gerais</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1035-1055</td>
|
||
<td>280-340</td>
|
||
<td>490-580</td>
|
||
<td>Média - estruturas críticas</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1080-1100</td>
|
||
<td>385-445</td>
|
||
<td>630-700</td>
|
||
<td>Alta - aplicações extremas</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 3: Fabricantes -->
|
||
<div class="tab-content" id="tab-2">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
|
||
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Fabricante</th>
|
||
<th>Localização</th>
|
||
<th>Gama de Produtos</th>
|
||
<th>Especialidade</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>CSN</strong></td>
|
||
<td>Volta Redonda (RJ)</td>
|
||
<td>Completa</td>
|
||
<td>Principal fornecedor nacional</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Gerdau</strong></td>
|
||
<td>Múltiplas plantas</td>
|
||
<td>Média a Grossa</td>
|
||
<td>Chapas estruturais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Usiminas</strong></td>
|
||
<td>Ipatinga (MG)</td>
|
||
<td>Fina a Média</td>
|
||
<td>Qualidades especiais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Vallourec</strong></td>
|
||
<td>Múltiplas</td>
|
||
<td>Grossa a Ultra</td>
|
||
<td>Chapas especiais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Arcelor Mittal</strong></td>
|
||
<td>Tubarão (ES)</td>
|
||
<td>Completa</td>
|
||
<td>Exportação e mercado interno</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Confab</strong></td>
|
||
<td>Pindamonhangaba (SP)</td>
|
||
<td>Média a Grossa</td>
|
||
<td>Caldeiraria</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">📦 Formatos Comerciais</h4>
|
||
<p><strong>Padrão:</strong> Formatos conforme espessura</p>
|
||
<p><strong>Customizado:</strong> Corte sob pedido</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
|
||
<ul>
|
||
<li><strong>Estoque:</strong> 5-10 dias</li>
|
||
<li><strong>Sob encomenda:</strong> 15-25 dias</li>
|
||
<li><strong>Especiais:</strong> 30-45 dias</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 4: Preços 2025 -->
|
||
<div class="tab-content" id="tab-3">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
|
||
|
||
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
|
||
<p><strong>Preço base:</strong> R$ 3,00 - R$ 9,00 por kg</p>
|
||
<p><strong>Variação por região:</strong> ±10-15%</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Situação</th>
|
||
<th>Variação</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Espessura >40mm</td>
|
||
<td><span class="badge badge-danger">+20%</span></td>
|
||
<td>Produção especial</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Espessura <5mm</td>
|
||
<td><span class="badge badge-danger">+25%</span></td>
|
||
<td>Processo delicado</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Corte customizado</td>
|
||
<td><span class="badge badge-warning">+10%</span></td>
|
||
<td>Serviço adicional</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Quantidade >50 toneladas</td>
|
||
<td><span class="badge badge-success">-20%</span></td>
|
||
<td>Desconto por volume</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
|
||
<ul>
|
||
<li><strong>ABNT NBR 5007</strong> - Chapas grossas de aço carbono</li>
|
||
<li><strong>ASTM A36</strong> - Aço estrutural carbono</li>
|
||
<li><strong>EN 10025-2</strong> - Produtos laminados a quente</li>
|
||
<li><strong>DIN 17102</strong> - Chapas e tiras de aço</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 5: Aplicações -->
|
||
<div class="tab-content" id="tab-4">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
|
||
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏗️ Estruturas Soldadas</h4>
|
||
<ul>
|
||
<li>Vigas e colunas compostas</li>
|
||
<li>Estruturas de edifícios</li>
|
||
<li>Pontes e viadutos</li>
|
||
<li>Galpões industriais</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏭 Equipamentos Industriais</h4>
|
||
<ul>
|
||
<li>Recipientes sob pressão</li>
|
||
<li>Tanques e reservatórios</li>
|
||
<li>Caldeiras</li>
|
||
<li>Vasos de processo</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">⚓ Estruturas Marítimas</h4>
|
||
<ul>
|
||
<li>Plataformas offshore</li>
|
||
<li>Cascos de navios</li>
|
||
<li>Estruturas portuárias</li>
|
||
<li>Componentes navais</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🛡️ Proteção e Blindagem</h4>
|
||
<ul>
|
||
<li>Blindagem balística</li>
|
||
<li>Proteção de equipamentos</li>
|
||
<li>Bases e fundações</li>
|
||
<li>Estruturas de contenção</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
|
||
<ul>
|
||
<li>✓ Soldabilidade garantida para todas as espessuras</li>
|
||
<li>✓ Identificação por tinta conforme norma</li>
|
||
<li>✓ Escalas de laminação visíveis (acabamento padrão)</li>
|
||
<li>✓ Filme de óleo de proteção contra corrosão</li>
|
||
<li>✓ Tolerância de espessura ±5%</li>
|
||
<li>✓ Soldagem com E7018 ou E8018 recomendada</li>
|
||
<li>✓ Pré-aquecimento necessário para espessuras >25mm</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getPerfisHPContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🏛️ Perfis HP (Heavy Pile - Estacas)</div>
|
||
<div class="section-description">Catálogo completo de perfis HP para fundações profundas</div>
|
||
</div>
|
||
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
|
||
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
|
||
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
|
||
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
|
||
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
|
||
</div>
|
||
|
||
<!-- Tab 1: Tabela Técnica -->
|
||
<div class="tab-content active" id="tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<div>
|
||
<h3 style="margin: 0; color: var(--color-primary);">📊 Perfis HP Disponíveis</h3>
|
||
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
|
||
Total: <strong id="perfis_hp-total">-</strong> perfis
|
||
</p>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="forcarCarregamentoPerfisHp()">
|
||
🔄 Recarregar Dados
|
||
</button>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Designação</th>
|
||
<th>Altura (mm)</th>
|
||
<th>Largura (mm)</th>
|
||
<th>Esp. Alma (mm)</th>
|
||
<th>Esp. Mesa (mm)</th>
|
||
<th>Peso (kg/m)</th>
|
||
<th>Área (cm²)</th>
|
||
<th>Categoria</th>
|
||
<th>Ações</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="perfis_hp-tbody">
|
||
<tr>
|
||
<td colspan="9" style="text-align: center; padding: 40px;">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
|
||
<div style="font-size: 18px; font-weight: bold;">Carregando perfis HP...</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 2: Especificações -->
|
||
<div class="tab-content" id="tab-1">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
|
||
<p><strong>Perfis em H laminados a quente especializados em estacas (Heavy Pile)</strong></p>
|
||
<p>Perfis estruturais robustos projetados especificamente para fundações profundas e estacas cravadas. Apresentam seção H com abas e alma de espessuras similares, garantindo excelente resistência à compressão axial e cravação.</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
|
||
<ul>
|
||
<li><strong>Dimensões:</strong> HP100 a HP350</li>
|
||
<li><strong>Peso:</strong> 20.0 kg/m a 132.0 kg/m</li>
|
||
<li><strong>Quantidade de modelos:</strong> 19 perfis diferentes</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Categoria</th>
|
||
<th>Dimensões</th>
|
||
<th>Quantidade</th>
|
||
<th>Aplicações Típicas</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><span class="badge badge-info">Pequeno</span></td>
|
||
<td>HP100</td>
|
||
<td>2 modelos</td>
|
||
<td>Estacas leves, contenções</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-info">Médio</span></td>
|
||
<td>HP125-HP150</td>
|
||
<td>3 modelos</td>
|
||
<td>Fundações medianas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Grande</span></td>
|
||
<td>HP200</td>
|
||
<td>5 modelos</td>
|
||
<td>Fundações pesadas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Muito Grande</span></td>
|
||
<td>HP250-HP300</td>
|
||
<td>5 modelos</td>
|
||
<td>Estruturas críticas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-danger">Massivo</span></td>
|
||
<td>HP350</td>
|
||
<td>4 modelos</td>
|
||
<td>Offshore, portos</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Qualidade</th>
|
||
<th>Fy (MPa)</th>
|
||
<th>Fu (MPa)</th>
|
||
<th>Aplicação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>SAE 1020-1045</td>
|
||
<td>235-280</td>
|
||
<td>420-490</td>
|
||
<td>Médio-alto - fundações gerais</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1050-1100</td>
|
||
<td>340-445</td>
|
||
<td>580-700</td>
|
||
<td>Muito alto - cravação pesada</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 3: Fabricantes -->
|
||
<div class="tab-content" id="tab-2">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
|
||
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Fabricante</th>
|
||
<th>Localização</th>
|
||
<th>Gama de Produtos</th>
|
||
<th>Especialidade</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Usiminas</strong></td>
|
||
<td>Ipatinga (MG)</td>
|
||
<td>Completa</td>
|
||
<td>Principal fornecedor nacional</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Gerdau</strong></td>
|
||
<td>Múltiplas plantas</td>
|
||
<td>Média a Grande</td>
|
||
<td>Parceria com Usiminas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Vallourec</strong></td>
|
||
<td>Múltiplas</td>
|
||
<td>Grande a Massivo</td>
|
||
<td>Perfis especiais</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
|
||
<p><strong>Padrão:</strong> 6m, 9m, 12m, 13.5m</p>
|
||
<p><strong>Especiais:</strong> Até 18m sob consulta</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
|
||
<ul>
|
||
<li><strong>Estoque:</strong> 2-5 dias</li>
|
||
<li><strong>Sob encomenda:</strong> 10-20 dias</li>
|
||
<li><strong>Especiais:</strong> 20-30 dias</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 4: Preços 2025 -->
|
||
<div class="tab-content" id="tab-3">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
|
||
|
||
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
|
||
<p><strong>Preço base:</strong> R$ 5,00 - R$ 12,00 por kg</p>
|
||
<p><strong>Variação por região:</strong> ±10-15%</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Situação</th>
|
||
<th>Variação</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>HP100</td>
|
||
<td><span class="badge badge-success">-10%</span></td>
|
||
<td>Mais comum</td>
|
||
</tr>
|
||
<tr>
|
||
<td>HP350</td>
|
||
<td><span class="badge badge-danger">+25%</span></td>
|
||
<td>Produção especial</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Com cravação</td>
|
||
<td><span class="badge badge-warning">+5%</span></td>
|
||
<td>Serviço adicional</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Quantidade >30 toneladas</td>
|
||
<td><span class="badge badge-success">-15%</span></td>
|
||
<td>Desconto por volume</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
|
||
<ul>
|
||
<li><strong>ASTM A588</strong> - Aço estrutural alta resistência</li>
|
||
<li><strong>ASTM A992</strong> - Perfis estruturais</li>
|
||
<li><strong>ISO 5148</strong> - Equivalente internacional</li>
|
||
<li><strong>EN 10025</strong> - Produtos laminados a quente</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 5: Aplicações -->
|
||
<div class="tab-content" id="tab-4">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
|
||
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏗️ Fundações Profundas</h4>
|
||
<ul>
|
||
<li>Estacas cravadas</li>
|
||
<li>Fundações de edifícios</li>
|
||
<li>Contenções de solo</li>
|
||
<li>Muros de arrimo</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">⚓ Estruturas Marítimas</h4>
|
||
<ul>
|
||
<li>Plataformas offshore</li>
|
||
<li>Estruturas portuárias</li>
|
||
<li>Píeres e atracadouros</li>
|
||
<li>Fundações subaquáticas</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🌉 Infraestrutura</h4>
|
||
<ul>
|
||
<li>Fundações de pontes</li>
|
||
<li>Viadutos</li>
|
||
<li>Estruturas geotécnicas</li>
|
||
<li>Suportes estruturais</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
|
||
<ul>
|
||
<li>Fundações de equipamentos</li>
|
||
<li>Estruturas pesadas</li>
|
||
<li>Suportes de máquinas</li>
|
||
<li>Bases de torres</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
|
||
<ul>
|
||
<li>✓ Compressão axial muito alta</li>
|
||
<li>✓ Excelente para flambagem lateral</li>
|
||
<li>✓ Emendas soldadas certificadas obrigatórias</li>
|
||
<li>✓ Teste de carga incluído em projetos críticos</li>
|
||
<li>✓ Seção robusta com simetria total</li>
|
||
<li>✓ Resistência à cravação garantida</li>
|
||
<li>✓ Soldagem com E8018 ou E9018 recomendada</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getBarrasRoscadasContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🔩 Barras Roscadas</div>
|
||
<div class="section-description">Catálogo completo de barras roscadas estruturais (Métrica e UNC)</div>
|
||
</div>
|
||
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
|
||
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
|
||
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
|
||
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
|
||
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
|
||
</div>
|
||
|
||
<!-- Tab 1: Tabela Técnica -->
|
||
<div class="tab-content active" id="tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<div>
|
||
<h3 style="margin: 0; color: var(--color-primary);">📊 Barras Roscadas Disponíveis</h3>
|
||
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
|
||
Total: <strong id="barras_roscadas-total">-</strong> diâmetros
|
||
</p>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="forcarCarregamentoBarrasRoscadas()">
|
||
🔄 Recarregar Dados
|
||
</button>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Designação</th>
|
||
<th>Diâmetro (mm)</th>
|
||
<th>Passo (mm)</th>
|
||
<th>Peso (kg/m)</th>
|
||
<th>Área (cm²)</th>
|
||
<th>Categoria</th>
|
||
<th>Ações</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="barras_roscadas-tbody">
|
||
<tr>
|
||
<td colspan="7" style="text-align: center; padding: 40px;">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
|
||
<div style="font-size: 18px; font-weight: bold;">Carregando barras roscadas...</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 2: Especificações -->
|
||
<div class="tab-content" id="tab-1">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
|
||
|
||
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>⚠️ IMPORTANTE:</strong> Barras Métricas e UNC NÃO são compatíveis! Verifique sempre o tipo de rosca.
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
|
||
<p><strong>Barras de aço carbono com rosca contínua (métrica e UNC)</strong></p>
|
||
<p>Barras roscadas utilizadas em fundações, ancoragens e sistemas de fixação. Disponíveis em padrão métrico (ISO) e UNC (americano).</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
|
||
<ul>
|
||
<li><strong>Métrica:</strong> M10 a M64 (19 modelos)</li>
|
||
<li><strong>UNC:</strong> 3/8"-16 a 2"-4.5 (19 modelos)</li>
|
||
<li><strong>Total:</strong> 38 modelos</li>
|
||
<li><strong>Peso:</strong> 0.617 kg/m a 25.130 kg/m</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Tipo</th>
|
||
<th>Categoria</th>
|
||
<th>Dimensões</th>
|
||
<th>Quantidade</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td rowspan="4"><strong>Métrica</strong></td>
|
||
<td><span class="badge badge-info">Pequeno</span></td>
|
||
<td>M10-M12</td>
|
||
<td>4 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-info">Médio</span></td>
|
||
<td>M16-M20</td>
|
||
<td>6 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Grande</span></td>
|
||
<td>M24-M48</td>
|
||
<td>5 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-danger">Muito Grande</span></td>
|
||
<td>M48-M64</td>
|
||
<td>4 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td rowspan="4"><strong>UNC</strong></td>
|
||
<td><span class="badge badge-info">Pequeno</span></td>
|
||
<td>3/8"-1/2"</td>
|
||
<td>4 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-info">Médio</span></td>
|
||
<td>5/8"-1"</td>
|
||
<td>6 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Grande</span></td>
|
||
<td>1 1/4"-1 1/2"</td>
|
||
<td>5 modelos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-danger">Muito Grande</span></td>
|
||
<td>1 5/8"-2"</td>
|
||
<td>4 modelos</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Qualidade</th>
|
||
<th>Fy (MPa)</th>
|
||
<th>Fu (MPa)</th>
|
||
<th>Aplicação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>SAE 1008-1015</td>
|
||
<td>210</td>
|
||
<td>400</td>
|
||
<td>Básica - fundações leves</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1020-1045</td>
|
||
<td>235-280</td>
|
||
<td>420-490</td>
|
||
<td>Média - fundações gerais</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1050-1100</td>
|
||
<td>340-445</td>
|
||
<td>580-700</td>
|
||
<td>Alta - aplicações críticas</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 3: Fabricantes -->
|
||
<div class="tab-content" id="tab-2">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
|
||
|
||
<h4 style="color: var(--color-primary); margin-top: 24px;">Barras Métricas</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Fabricante</th>
|
||
<th>Localização</th>
|
||
<th>Gama de Produtos</th>
|
||
<th>Especialidade</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Confab</strong></td>
|
||
<td>Pindamonhangaba (SP)</td>
|
||
<td>Completa</td>
|
||
<td>Principal fornecedor nacional</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Gerdau</strong></td>
|
||
<td>Múltiplas plantas</td>
|
||
<td>Média a Grande</td>
|
||
<td>Barras estruturais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Tecel</strong></td>
|
||
<td>São Paulo (SP)</td>
|
||
<td>Pequena a Média</td>
|
||
<td>Distribuição</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h4 style="color: var(--color-primary); margin-top: 24px;">Barras UNC</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Origem</th>
|
||
<th>Disponibilidade</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Fornecedores especializados</td>
|
||
<td>Estoque distribuído</td>
|
||
<td>Importação direta EUA</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
|
||
<p><strong>Padrão:</strong> 1m, 3m, 6m, 9m, 12m</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
|
||
<ul>
|
||
<li><strong>Métrica estoque:</strong> 1-3 dias</li>
|
||
<li><strong>Métrica encomenda:</strong> 5-10 dias</li>
|
||
<li><strong>UNC importada:</strong> 15-30 dias</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 4: Preços 2025 -->
|
||
<div class="tab-content" id="tab-3">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
|
||
|
||
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. UNC tem premium de 30-50% sobre Métrica.
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
|
||
<p><strong>Métrica:</strong> R$ 5,00 - R$ 15,00 por kg</p>
|
||
<p><strong>UNC:</strong> R$ 6,50 - R$ 22,50 por kg (premium +30-50%)</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Fatores de Preço - Métrica</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Situação</th>
|
||
<th>Variação</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Pequenas (M10-M12)</td>
|
||
<td><span class="badge badge-success">-5%</span></td>
|
||
<td>Mais comuns</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Grandes (M48+)</td>
|
||
<td><span class="badge badge-success">-5-10%</span></td>
|
||
<td>Volume maior</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Quantidade >2 toneladas</td>
|
||
<td><span class="badge badge-success">-10%</span></td>
|
||
<td>Desconto por volume</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Fatores de Preço - UNC</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Situação</th>
|
||
<th>Variação</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Premium vs Métrica</td>
|
||
<td><span class="badge badge-danger">+30-50%</span></td>
|
||
<td>Importação</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Quantidade >1 tonelada</td>
|
||
<td><span class="badge badge-success">-5%</span></td>
|
||
<td>Desconto limitado</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
|
||
<ul>
|
||
<li><strong>ABNT NBR 5629</strong> - Barras roscadas (Brasil)</li>
|
||
<li><strong>ISO 8839</strong> - Rosca métrica</li>
|
||
<li><strong>ANSI B1.1</strong> - Rosca UNC</li>
|
||
<li><strong>ASTM F568</strong> - Parafusos e barras</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 5: Aplicações -->
|
||
<div class="tab-content" id="tab-4">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
|
||
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏗️ Fundações</h4>
|
||
<ul>
|
||
<li>Fundações de edifícios</li>
|
||
<li>Ancoragem de estruturas</li>
|
||
<li>Pernos de fundação</li>
|
||
<li>Chumbadores</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🌍 Geotecnia</h4>
|
||
<ul>
|
||
<li>Estacas raiz</li>
|
||
<li>Tirantes</li>
|
||
<li>Ancoragens de solo</li>
|
||
<li>Contenções</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">⚓ Estruturas Offshore</h4>
|
||
<ul>
|
||
<li>Plataformas</li>
|
||
<li>Ancoragens marinhas</li>
|
||
<li>Estruturas subaquáticas</li>
|
||
<li>Fixações críticas</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
|
||
<ul>
|
||
<li>Equipamentos industriais</li>
|
||
<li>Sistemas de protensão</li>
|
||
<li>Fixações de máquinas</li>
|
||
<li>Estruturas pesadas</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
|
||
<ul>
|
||
<li>⚠️ <strong>CRÍTICO:</strong> Métrica e UNC NÃO são compatíveis</li>
|
||
<li>✓ Porcas métricas ISO para barras Métricas</li>
|
||
<li>✓ Porcas UNC para barras UNC</li>
|
||
<li>✓ Compatibilidade de rosca obrigatória</li>
|
||
<li>✓ Identificação por tinta na barra</li>
|
||
<li>✓ Verificar qualidade do aço antes da instalação</li>
|
||
<li>✓ Proteção anticorrosiva em ambientes agressivos</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getBarrasChatassContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">▬ Barras Chatas</div>
|
||
<div class="section-description">Catálogo completo de barras chatas estruturais</div>
|
||
</div>
|
||
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">📊 Tabela Técnica</button>
|
||
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">📋 Especificações</button>
|
||
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">🏭 Fabricantes</button>
|
||
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">💰 Preços 2025</button>
|
||
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">🔧 Aplicações</button>
|
||
</div>
|
||
|
||
<!-- Tab 1: Tabela Técnica -->
|
||
<div class="tab-content active" id="tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<div>
|
||
<h3 style="margin: 0; color: var(--color-primary);">📊 Barras Chatas Disponíveis</h3>
|
||
<p style="margin: 8px 0 0 0; color: var(--color-text-secondary);">
|
||
Total: <strong id="barras_chatas-total">-</strong> perfis
|
||
</p>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="forcarCarregamentoBarrasChatas()">
|
||
🔄 Recarregar Dados
|
||
</button>
|
||
</div>
|
||
|
||
<div style="overflow-x: auto;">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Designação</th>
|
||
<th>Largura (mm)</th>
|
||
<th>Espessura (mm)</th>
|
||
<th>Peso (kg/m)</th>
|
||
<th>Área (cm²)</th>
|
||
<th>Categoria</th>
|
||
<th>Ações</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="barras_chatas-tbody">
|
||
<tr>
|
||
<td colspan="7" style="text-align: center; padding: 40px;">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">⏳</div>
|
||
<div style="font-size: 18px; font-weight: bold;">Carregando barras chatas...</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 2: Especificações -->
|
||
<div class="tab-content" id="tab-1">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">📋 Especificações Técnicas Completas</h3>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔧 Descrição Geral</h4>
|
||
<p><strong>Barras de aço laminadas a quente com seção retangular (Largura >> Espessura)</strong></p>
|
||
<p>Perfis planos versáteis utilizados em estruturas, suportes e componentes soldados. Caracterizados pela relação largura/espessura elevada.</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📏 Faixa de Dimensões</h4>
|
||
<ul>
|
||
<li><strong>Dimensões:</strong> 12.7×3.2mm a 127×22.2mm</li>
|
||
<li><strong>Peso:</strong> 0.309 kg/m a 21.68 kg/m</li>
|
||
<li><strong>Quantidade de modelos:</strong> 31 perfis diferentes</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Distribuição dos Modelos</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Categoria</th>
|
||
<th>Largura</th>
|
||
<th>Quantidade</th>
|
||
<th>Aplicações Típicas</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><span class="badge badge-info">Pequeno</span></td>
|
||
<td>12.7-25.4mm</td>
|
||
<td>9 modelos</td>
|
||
<td>Estruturas leves, suportes</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-info">Médio</span></td>
|
||
<td>31-50.8mm</td>
|
||
<td>6 modelos</td>
|
||
<td>Estruturas medianas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Grande</span></td>
|
||
<td>50.8-76.2mm</td>
|
||
<td>4 modelos</td>
|
||
<td>Estruturas pesadas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-warning">Muito Grande</span></td>
|
||
<td>76.2-127mm</td>
|
||
<td>6 modelos</td>
|
||
<td>Estruturas críticas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><span class="badge badge-danger">Massivo</span></td>
|
||
<td>101-127mm</td>
|
||
<td>6 modelos</td>
|
||
<td>Offshore, industrial</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">🔬 Qualidades Disponíveis (SAE)</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Qualidade</th>
|
||
<th>Fy (MPa)</th>
|
||
<th>Fu (MPa)</th>
|
||
<th>Aplicação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>SAE 1008-1015</td>
|
||
<td>210</td>
|
||
<td>400</td>
|
||
<td>Básica - estruturas leves</td>
|
||
</tr>
|
||
<tr>
|
||
<td>SAE 1020-1045</td>
|
||
<td>235-280</td>
|
||
<td>420-490</td>
|
||
<td>Alta - estruturas pesadas</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 3: Fabricantes -->
|
||
<div class="tab-content" id="tab-2">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🏭 Fabricantes no Brasil</h3>
|
||
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Fabricante</th>
|
||
<th>Localização</th>
|
||
<th>Gama de Produtos</th>
|
||
<th>Especialidade</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>Gerdau</strong></td>
|
||
<td>Múltiplas plantas</td>
|
||
<td>Completa</td>
|
||
<td>Principal fornecedor nacional</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>CSN</strong></td>
|
||
<td>Volta Redonda (RJ)</td>
|
||
<td>Média a Grande</td>
|
||
<td>Barras pesadas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Confab</strong></td>
|
||
<td>Pindamonhangaba (SP)</td>
|
||
<td>Pequena a Média</td>
|
||
<td>Distribuição</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Tecel</strong></td>
|
||
<td>São Paulo (SP)</td>
|
||
<td>Pequena</td>
|
||
<td>Corte e distribuição</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>Fornecedores regionais</strong></td>
|
||
<td>Diversos</td>
|
||
<td>Variada</td>
|
||
<td>Distribuição local</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">📦 Comprimentos Comerciais</h4>
|
||
<p><strong>Padrão:</strong> 3m, 6m, 9m, 12m</p>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">⏱️ Prazos de Entrega</h4>
|
||
<ul>
|
||
<li><strong>Estoque:</strong> 2-4 dias</li>
|
||
<li><strong>Sob encomenda:</strong> 7-12 dias</li>
|
||
<li><strong>Especiais:</strong> 15-20 dias</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 4: Preços 2025 -->
|
||
<div class="tab-content" id="tab-3">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">💰 Preços 2025</h3>
|
||
|
||
<div style="background: var(--color-warning); padding: 16px; border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>⚠️ Preços de Referência:</strong> Valores médios de mercado. Consulte fornecedores para cotação atualizada.
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">💵 Faixa de Preços</h4>
|
||
<p><strong>Preço base:</strong> R$ 4,50 - R$ 8,50 por kg</p>
|
||
<p><strong>Variação por região:</strong> ±10-15%</p>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📊 Fatores de Preço</h4>
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>Situação</th>
|
||
<th>Variação</th>
|
||
<th>Observação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Pequenas (até 50mm)</td>
|
||
<td><span class="badge badge-warning">+10%</span></td>
|
||
<td>Menor demanda</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Grandes (101-127mm)</td>
|
||
<td><span class="badge badge-success">-5%</span></td>
|
||
<td>Volume maior</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Corte customizado</td>
|
||
<td><span class="badge badge-warning">+taxa</span></td>
|
||
<td>Serviço adicional</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Furação em CNC</td>
|
||
<td><span class="badge badge-warning">+taxa</span></td>
|
||
<td>Serviço adicional</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Quantidade >5 toneladas</td>
|
||
<td><span class="badge badge-success">-10%</span></td>
|
||
<td>Desconto por volume</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div style="margin-bottom: 24px;">
|
||
<h4 style="color: var(--color-primary);">📋 Normas Aplicáveis</h4>
|
||
<ul>
|
||
<li><strong>ABNT NBR 5005</strong> - Barras chatas de aço</li>
|
||
<li><strong>ASTM A36</strong> - Aço estrutural carbono</li>
|
||
<li><strong>DIN 17100</strong> - Aços para construção</li>
|
||
<li><strong>EN 10025-2</strong> - Produtos laminados a quente</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Tab 5: Aplicações -->
|
||
<div class="tab-content" id="tab-4">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 20px;">🔧 Aplicações Principais</h3>
|
||
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 20px;">
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏗️ Estruturas</h4>
|
||
<ul>
|
||
<li>Suportes de máquinas</li>
|
||
<li>Estruturas de edifícios</li>
|
||
<li>Eixos estruturais</li>
|
||
<li>Componentes soldados</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🏭 Industrial</h4>
|
||
<ul>
|
||
<li>Plataformas industriais</li>
|
||
<li>Elementos de fixação</li>
|
||
<li>Suportes de equipamentos</li>
|
||
<li>Estruturas de máquinas</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">⚓ Offshore</h4>
|
||
<ul>
|
||
<li>Estruturas offshore</li>
|
||
<li>Plataformas marítimas</li>
|
||
<li>Componentes navais</li>
|
||
<li>Fixações críticas</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="background: var(--color-bg-2); padding: 16px; border-radius: 8px;">
|
||
<h4 style="color: var(--color-primary);">🔧 Mecânica</h4>
|
||
<ul>
|
||
<li>Eixos e pernos</li>
|
||
<li>Suportes mecânicos</li>
|
||
<li>Componentes usinados</li>
|
||
<li>Estruturas de chassis</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 24px;">
|
||
<h4 style="color: var(--color-primary);">✅ Recomendações de Uso</h4>
|
||
<ul>
|
||
<li>✓ Fácil furação com brocas padrão</li>
|
||
<li>✓ Soldagem simples com E7018</li>
|
||
<li>✓ Flexibilidade em projeto</li>
|
||
<li>✓ Acabamento rugoso escamoso (padrão)</li>
|
||
<li>✓ Embalagem em feixes 200-500kg</li>
|
||
<li>✓ Verificar planicidade antes da soldagem</li>
|
||
<li>✓ Proteção anticorrosiva recomendada</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getParafusosContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🔩 Ligações Parafusadas - 5 Abas Completas</div>
|
||
<div class="section-description">Dimensionamento completo de conexões parafusadas</div>
|
||
</div>
|
||
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchTab(0)" data-tab="0">1️⃣ Cisalhamento</button>
|
||
<button class="tab-btn" onclick="switchTab(1)" data-tab="1">2️⃣ Esmagamento</button>
|
||
<button class="tab-btn" onclick="switchTab(2)" data-tab="2">3️⃣ Bloco</button>
|
||
<button class="tab-btn" onclick="switchTab(3)" data-tab="3">4️⃣ Layout</button>
|
||
<button class="tab-btn" onclick="switchTab(4)" data-tab="4">5️⃣ vs Solda</button>
|
||
</div>
|
||
|
||
<!-- Tab 1: Cisalhamento -->
|
||
<div class="tab-content active" id="tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div class="card-title">📐 Dimensionamento de Parafusos ao Cisalhamento</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula a resistência ao cisalhamento de parafusos individuais e totais</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Parafuso</label>
|
||
<select class="form-control" id="bolt-type">
|
||
<option value="a325">A325 (fy = 400 MPa)</option>
|
||
<option value="a490">A490 (fy = 565 MPa)</option>
|
||
<option value="iso88">ISO 8.8 (fy = 640 MPa)</option>
|
||
<option value="iso109">ISO 10.9 (fy = 900 MPa)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Diâmetro (mm)</label>
|
||
<select class="form-control" id="bolt-d">
|
||
<option value="12">12</option>
|
||
<option value="16">16</option>
|
||
<option value="20" selected>20</option>
|
||
<option value="24">24</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Quantidade</label>
|
||
<input type="number" class="form-control" id="bolt-qty" step="1" value="4" min="1" max="100">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Planos de Corte</label>
|
||
<select class="form-control" id="bolt-planes">
|
||
<option value="1">1</option>
|
||
<option value="2" selected>2</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Força Aplicada (kN)</label>
|
||
<input type="number" class="form-control" id="bolt-force" step="1" value="200">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularCisalhamento()">🔧 Calcular Cisalhamento</button>
|
||
</div>
|
||
<div id="bolt-shear-result"></div>
|
||
</div>
|
||
|
||
<!-- Tab 2: Esmagamento -->
|
||
<div class="tab-content" id="tab-1">
|
||
<div class="card" style="background: var(--color-bg-3);">
|
||
<div class="card-title">🔨 Verificação de Esmagamento (Bearing)</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula a resistência ao esmagamento da chapa</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Diâmetro Parafuso (mm)</label>
|
||
<select class="form-control" id="bear-d">
|
||
<option value="12">12</option>
|
||
<option value="16" selected>16</option>
|
||
<option value="20">20</option>
|
||
<option value="24">24</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura da Chapa (mm)</label>
|
||
<input type="number" class="form-control" id="bear-thickness" step="1" value="10">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Quantidade de Parafusos</label>
|
||
<input type="number" class="form-control" id="bear-qty" step="1" value="4">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Aço da Chapa</label>
|
||
<select class="form-control" id="bear-steel">
|
||
<option value="a36">A36 (fy=250, fu=400 MPa)</option>
|
||
<option value="a572" selected>A572 (fy=345, fu=450 MPa)</option>
|
||
<option value="s235">S235 (fy=235, fu=360 MPa)</option>
|
||
<option value="s355">S355 (fy=355, fu=490 MPa)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Distância de Borda (mm)</label>
|
||
<input type="number" class="form-control" id="bear-edge" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espaçamento entre Furos (mm)</label>
|
||
<input type="number" class="form-control" id="bear-spacing" step="1" value="75">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularEsmagamento()">🔧 Calcular Esmagamento</button>
|
||
</div>
|
||
<div id="bolt-bearing-result"></div>
|
||
</div>
|
||
|
||
<!-- Tab 3: Ruptura Bloco -->
|
||
<div class="tab-content" id="tab-2">
|
||
<div class="card" style="background: var(--color-bg-6);">
|
||
<div class="card-title">⚠️ Ruptura em Bloco de Cisalhamento</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Verifica ruptura por bloco segundo AISC 360-16</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Diâmetro Parafuso (mm)</label>
|
||
<select class="form-control" id="block-d">
|
||
<option value="12">12</option>
|
||
<option value="16" selected>16</option>
|
||
<option value="20">20</option>
|
||
<option value="24">24</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Quantidade Horizontal</label>
|
||
<input type="number" class="form-control" id="block-h-qty" step="1" value="2">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Quantidade Vertical</label>
|
||
<input type="number" class="form-control" id="block-v-qty" step="1" value="2">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espaçamento Horizontal (mm)</label>
|
||
<input type="number" class="form-control" id="block-h-space" step="1" value="75">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Distância Borda Esquerda (mm)</label>
|
||
<input type="number" class="form-control" id="block-edge-left" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Distância Borda Topo (mm)</label>
|
||
<input type="number" class="form-control" id="block-edge-top" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Distância Borda Direita (mm)</label>
|
||
<input type="number" class="form-control" id="block-edge-right" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura (mm)</label>
|
||
<input type="number" class="form-control" id="block-thickness" step="1" value="10">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Aço</label>
|
||
<select class="form-control" id="block-steel">
|
||
<option value="a36">A36 (fu=400 MPa)</option>
|
||
<option value="a572" selected>A572 (fu=450 MPa)</option>
|
||
<option value="s235">S235 (fu=360 MPa)</option>
|
||
<option value="s355">S355 (fu=490 MPa)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Força (kN)</label>
|
||
<input type="number" class="form-control" id="block-force" step="1" value="200">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularBlocoRuptura()">🔧 Calcular Bloco</button>
|
||
</div>
|
||
<div id="bolt-block-result"></div>
|
||
</div>
|
||
|
||
<!-- Tab 4: Layout de Furação -->
|
||
<div class="tab-content" id="tab-3">
|
||
<div class="card" style="background: var(--color-bg-5);">
|
||
<div class="card-title">📐 Verificação de Layout de Furação</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Verifica conformidade com NBR 8800 e AISC 360</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Diâmetro Parafuso (mm)</label>
|
||
<select class="form-control" id="layout2-d">
|
||
<option value="12">12</option>
|
||
<option value="16" selected>16</option>
|
||
<option value="20">20</option>
|
||
<option value="24">24</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Borda Esquerda (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-edge-left" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Borda Direita (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-edge-right" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Borda Topo (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-edge-top" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Borda Base (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-edge-bottom" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espaçamento Horizontal (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-h-space" step="1" value="75">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espaçamento Vertical (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-v-space" step="1" value="75">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura Chapa (mm)</label>
|
||
<input type="number" class="form-control" id="layout2-thickness" step="1" value="10">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="verificarLayoutCompleto()">✓ Verificar Conformidade</button>
|
||
</div>
|
||
<div id="layout-full-result"></div>
|
||
</div>
|
||
|
||
<!-- Tab 5: Parafuso vs Solda -->
|
||
<div class="tab-content" id="tab-4">
|
||
<div class="card" style="background: var(--color-bg-4);">
|
||
<div class="card-title">⚖️ Comparação: Parafuso vs Solda</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Compara alternativas de conexão com análise de custos</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Força a Transmitir (kN)</label>
|
||
<input type="number" class="form-control" id="comp2-force" step="1" value="200">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Disponível (mm)</label>
|
||
<input type="number" class="form-control" id="comp2-length" step="1" value="300">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo Aço Base</label>
|
||
<select class="form-control" id="comp2-steel">
|
||
<option value="a36">A36 (fy=250 MPa)</option>
|
||
<option value="a572" selected>A572 (fy=345 MPa)</option>
|
||
<option value="s355">S355 (fy=355 MPa)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 20px 0;">
|
||
<div style="padding: 16px; background: var(--color-bg-1); border-radius: 12px;">
|
||
<h4 style="margin-bottom: 12px; color: var(--color-primary);">🔩 Opção Parafuso</h4>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo</label>
|
||
<select class="form-control" id="comp2-bolt-type">
|
||
<option value="a325" selected>A325</option>
|
||
<option value="a490">A490</option>
|
||
<option value="iso88">ISO 8.8</option>
|
||
<option value="iso109">ISO 10.9</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Diâmetro (mm)</label>
|
||
<select class="form-control" id="comp2-bolt-d">
|
||
<option value="12">12</option>
|
||
<option value="16" selected>16</option>
|
||
<option value="20">20</option>
|
||
<option value="24">24</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div style="padding: 16px; background: var(--color-bg-6); border-radius: 12px;">
|
||
<h4 style="margin-bottom: 12px; color: var(--color-warning);">🔥 Opção Solda</h4>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo Eletrodo</label>
|
||
<select class="form-control" id="comp2-electrode">
|
||
<option value="e6010">E6010</option>
|
||
<option value="e7018" selected>E7018</option>
|
||
<option value="e8018">E8018</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="compararParafusoSoldaCompleto()">🔄 Gerar Comparação Completa</button>
|
||
</div>
|
||
<div id="comparison-full-result"></div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getLayoutContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🎯 Layout de Furação (NBR 8800)</div>
|
||
<div class="section-description">Verificação de distâncias e espaçamentos</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros de Layout</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Diâmetro Parafuso (mm)</label>
|
||
<input type="number" class="form-control" id="layout-d" step="1" value="20">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Distância de Borda (mm)</label>
|
||
<input type="number" class="form-control" id="layout-edge" step="1" value="40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espaçamento entre Furos (mm)</label>
|
||
<input type="number" class="form-control" id="layout-spacing" step="1" value="60">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Espessura Chapa (mm)</label>
|
||
<input type="number" class="form-control" id="layout-thickness" step="1" value="10">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="verificarLayout()">✓ Verificar Conformidade</button>
|
||
</div>
|
||
|
||
<div id="layout-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getParafusoVsSoldaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">⚙️ Comparação: Parafuso vs Solda</div>
|
||
<div class="section-description">Análise comparativa de soluções de ligação</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros da Ligação</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Força a Transmitir (kN)</label>
|
||
<input type="number" class="form-control" id="comp-force" step="1" value="150">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Disponível (mm)</label>
|
||
<input type="number" class="form-control" id="comp-length" step="1" value="400">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Aço Base (fy MPa)</label>
|
||
<input type="number" class="form-control" id="comp-fy" step="1" value="345">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="compararParafusoSolda()">⚙️ Comparar Soluções</button>
|
||
</div>
|
||
|
||
<div id="comparison-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getPreaquecimentoContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🔥 SOLDAGEM - Sistema Completo</div>
|
||
<div class="section-description">Dimensionamento completo de soldagem com 6 ferramentas integradas</div>
|
||
</div>
|
||
|
||
<!-- Seletor Global de Processo e Consumível -->
|
||
<div class="card" style="background: var(--color-bg-2); border: 2px solid var(--color-primary);">
|
||
<div class="card-title">⚙️ SELEÇÃO DE PROCESSO E CONSUMÍVEL</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 16px;">Selecione o processo e consumível que será usado em todas as ferramentas abaixo</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Processo de Soldagem</label>
|
||
<select class="form-control" id="weld-process" onchange="updateWeldingProcess()">
|
||
<option value="smaw" selected>SMAW (Eletrodo Revestido)</option>
|
||
<option value="gmaw">GMAW (MIG/MAG)</option>
|
||
<option value="fcaw">FCAW (Arame Tubular)</option>
|
||
<option value="gtaw">GTAW (TIG)</option>
|
||
<option value="saw">SAW (Soldagem Submersa)</option>
|
||
<option value="esw">ESW (Soldagem por Escória)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Consumível / Eletrodo</label>
|
||
<select class="form-control" id="weld-electrode" onchange="updateWeldingElectrode()">
|
||
<option value="e7018" selected>E7018 (AWS) - Básico</option>
|
||
<option value="e6013">E6013 (AWS) - Rutílico</option>
|
||
<option value="e8018">E8018 (AWS) - Básico Alta Resistência</option>
|
||
<option value="e7016">E7016 (AWS) - Básico</option>
|
||
<option value="e8016">E8016 (AWS) - Básico</option>
|
||
<option value="er70s2">ER70S-2 (MIG)</option>
|
||
<option value="er70s6">ER70S-6 (MIG)</option>
|
||
<option value="er4043">ER4043 (TIG - Al)</option>
|
||
<option value="er5356">ER5356 (TIG - Al)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-success" onclick="applyToAllTabs()" style="margin-top: 16px;">✅ Atualizar Todas as Abas</button>
|
||
<button class="btn btn-secondary" onclick="showElectrodeProperties()" style="margin-top: 16px;">📋 Mostrar Propriedades do Consumível</button>
|
||
</div>
|
||
|
||
<div id="electrode-properties"></div>
|
||
|
||
<!-- 6 Abas de Soldagem -->
|
||
<div class="tabs-container">
|
||
<div class="tabs-nav">
|
||
<button class="tab-btn active" onclick="switchWeldTab(0)">🌡️ Pré-Aquecimento</button>
|
||
<button class="tab-btn" onclick="switchWeldTab(1)">⚡ Filete</button>
|
||
<button class="tab-btn" onclick="switchWeldTab(2)">🔥 Energia</button>
|
||
<button class="tab-btn" onclick="switchWeldTab(3)">📊 Consumo</button>
|
||
<button class="tab-btn" onclick="switchWeldTab(4)">🔄 Sequência</button>
|
||
<button class="tab-btn" onclick="switchWeldTab(5)">📋 Padrões</button>
|
||
</div>
|
||
|
||
<!-- ABA 1: Pré-Aquecimento -->
|
||
<div class="tab-content active" id="weld-tab-0">
|
||
<div class="card" style="background: var(--color-bg-1);">
|
||
<div class="card-title">🌡️ Pré-Aquecimento AWS D1.1</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula temperatura mínima de pré-aquecimento</p>
|
||
|
||
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>Processo Selecionado:</strong> <span id="preheat-process-display">SMAW (E7018)</span>
|
||
</div>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Carbono Equivalente (CEV)</label>
|
||
<input type="number" class="form-control" id="preheat-cev" step="0.01" value="0.45">
|
||
<small style="color: var(--color-text-secondary);">Ou calcule na seção Materiais</small>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura da Junta (mm)</label>
|
||
<input type="number" class="form-control" id="preheat-thickness" step="1" value="25">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Temperatura Ambiente (°C)</label>
|
||
<input type="number" class="form-control" id="preheat-ambient" step="1" value="15">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Junta</label>
|
||
<select class="form-control" id="preheat-joint">
|
||
<option value="filete">Filete</option>
|
||
<option value="topo">Topo</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Restrição da Junta</label>
|
||
<select class="form-control" id="preheat-restraint">
|
||
<option value="1.0">Não Restrita</option>
|
||
<option value="1.1">Parcialmente Restrita</option>
|
||
<option value="1.2" selected>Totalmente Restrita</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin: 20px 0;">
|
||
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="preheat-interpass" style="width: 18px; height: 18px;">
|
||
<span>Calcular Temperatura Interpass (entre passes)</span>
|
||
</label>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="calcularPreaquecimentoCompleto()">🔥 Calcular Pré-Aquecimento</button>
|
||
</div>
|
||
<div id="preheat-result"></div>
|
||
</div>
|
||
|
||
<!-- ABA 2: Dimensionamento de Filete -->
|
||
<div class="tab-content" id="weld-tab-1">
|
||
<div class="card" style="background: var(--color-bg-3);">
|
||
<div class="card-title">⚡ Dimensionamento de Soldas de Filete</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula perna necessária e número de passes</p>
|
||
|
||
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>Processo:</strong> <span id="filete-process-display">SMAW (E7018)</span>
|
||
</div>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Força a Transmitir (kN)</label>
|
||
<input type="number" class="form-control" id="filete-force" step="1" value="250">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Disponível (mm)</label>
|
||
<input type="number" class="form-control" id="filete-length" step="1" value="400">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Junta</label>
|
||
<select class="form-control" id="filete-joint">
|
||
<option value="1">Filete Simples</option>
|
||
<option value="2" selected>Filete Duplo</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Aço Base</label>
|
||
<select class="form-control" id="filete-steel">
|
||
<option value="250">A36 (250 MPa)</option>
|
||
<option value="345" selected>A572 (345 MPa)</option>
|
||
<option value="235">S235 (235 MPa)</option>
|
||
<option value="355">S355 (355 MPa)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Posição Soldagem</label>
|
||
<select class="form-control" id="filete-position">
|
||
<option value="1.0" selected>Plana (1F)</option>
|
||
<option value="0.9">Horizontal (2F)</option>
|
||
<option value="0.8">Vertical (3F)</option>
|
||
<option value="0.7">Sobrecabeça (4F)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="calcularFileteCompleto()">⚡ Calcular Filete</button>
|
||
</div>
|
||
<div id="filete-result"></div>
|
||
</div>
|
||
|
||
<!-- ABA 3: Energia de Soldagem -->
|
||
<div class="tab-content" id="weld-tab-2">
|
||
<div class="card" style="background: var(--color-bg-6);">
|
||
<div class="card-title">🔥 Energia de Soldagem (Heat Input)</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Controla aporte de calor para evitar fragilização</p>
|
||
|
||
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>Processo:</strong> <span id="hi-process-display">SMAW (E7018)</span>
|
||
</div>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Voltagem (V)</label>
|
||
<input type="number" class="form-control" id="hi-voltage" step="1" value="26">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Corrente (A)</label>
|
||
<input type="number" class="form-control" id="hi-current" step="1" value="140">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Velocidade Soldagem (cm/min)</label>
|
||
<input type="number" class="form-control" id="hi-speed" step="1" value="25">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Eficiência de Arco</label>
|
||
<input type="number" class="form-control" id="hi-efficiency" step="0.01" value="0.75">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Aço (para análise)</label>
|
||
<select class="form-control" id="hi-steel">
|
||
<option value="a36">A36 (1.5-3.0 kJ/mm)</option>
|
||
<option value="a572" selected>A572 (1.0-2.5 kJ/mm)</option>
|
||
<option value="s355">S355 (0.8-2.0 kJ/mm)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="calcularEnergiaCompleta()">🔥 Calcular Energia</button>
|
||
<button class="btn btn-secondary" onclick="verificarLimitesAco()" style="margin-left: 10px;">📊 Verificar Limites por Aço</button>
|
||
</div>
|
||
<div id="hi-result"></div>
|
||
</div>
|
||
|
||
<!-- ABA 4: Consumo de Eletrodos -->
|
||
<div class="tab-content" id="weld-tab-3">
|
||
<div class="card" style="background: var(--color-bg-5);">
|
||
<div class="card-title">📊 Consumo de Eletrodos e Consumíveis</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Calcula quantidade e custo de eletrodos necessários</p>
|
||
|
||
<div style="padding: 12px; background: var(--color-surface); border-radius: 8px; margin-bottom: 20px;">
|
||
<strong>Eletrodo:</strong> <span id="consumo-electrode-display">E7018</span>
|
||
</div>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Perna da Solda (mm)</label>
|
||
<input type="number" class="form-control" id="consumo-leg" step="1" value="6">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Total (m)</label>
|
||
<input type="number" class="form-control" id="consumo-length" step="0.1" value="10">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Perdas/Respingos (%)</label>
|
||
<input type="number" class="form-control" id="consumo-loss" step="1" value="15">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Porcentagem de Sucata (%)</label>
|
||
<input type="number" class="form-control" id="consumo-scrap" step="1" value="5">
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="calcularConsumoCompleto()">📊 Calcular Consumo</button>
|
||
<button class="btn btn-secondary" onclick="gerarOrcamentoConsumiveis()" style="margin-left: 10px;">💰 Gerar Orçamento</button>
|
||
</div>
|
||
<div id="consumo-result"></div>
|
||
</div>
|
||
|
||
<!-- ABA 5: Sequência de Soldagem -->
|
||
<div class="tab-content" id="weld-tab-4">
|
||
<div class="card" style="background: var(--color-bg-7);">
|
||
<div class="card-title">🔄 Sequência de Soldagem para Minimizar Distorções</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Padrões de deposição e passes</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Junta</label>
|
||
<select class="form-control" id="seq-joint">
|
||
<option value="filete" selected>Filete Duplo</option>
|
||
<option value="topo">Topo</option>
|
||
<option value="angular">Angular</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Total (mm)</label>
|
||
<input type="number" class="form-control" id="seq-length" step="1" value="400">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Perna (mm)</label>
|
||
<input type="number" class="form-control" id="seq-leg" step="1" value="3">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Número de Passes</label>
|
||
<input type="number" class="form-control" id="seq-passes" step="1" value="2">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Padrão de Deposição</label>
|
||
<select class="form-control" id="seq-pattern">
|
||
<option value="skip" selected>Skip Welding (Recomendado)</option>
|
||
<option value="backstep">Backstep Welding</option>
|
||
<option value="pulsed">Pulsado</option>
|
||
<option value="continuous">Contínuo</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="gerarDiagramaSequencia()">📐 Gerar Diagrama de Sequência</button>
|
||
<button class="btn btn-secondary" onclick="visualizarDistorcoes()" style="margin-left: 10px;">📊 Visualizar Distorções Esperadas</button>
|
||
</div>
|
||
<div id="sequencia-result"></div>
|
||
</div>
|
||
|
||
<!-- ABA 6: Padrões de Solda -->
|
||
<div class="tab-content" id="weld-tab-5">
|
||
<div class="card" style="background: var(--color-bg-8);">
|
||
<div class="card-title">📋 Padrões de Solda Recomendados por Aplicação</div>
|
||
<p style="color: var(--color-text-secondary); margin-bottom: 20px;">Seleção de padrão otimizado para sua aplicação</p>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Aplicação / Estrutura</label>
|
||
<select class="form-control" id="padrao-app">
|
||
<option value="edificio" selected>Edifício de Múltiplos Andares</option>
|
||
<option value="ponte">Ponte Rodoviária</option>
|
||
<option value="industrial">Estrutura Industrial</option>
|
||
<option value="tubulacao">Tubulação de Pressão</option>
|
||
<option value="equipamento">Equipamento Mecânico</option>
|
||
<option value="offshore">Marinha/Offshore</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Criticidade</label>
|
||
<select class="form-control" id="padrao-criticality">
|
||
<option value="baixa">Baixa (Cargas Estáticas)</option>
|
||
<option value="media" selected>Média (Fadiga Baixa)</option>
|
||
<option value="alta">Alta (Fadiga/Impacto)</option>
|
||
<option value="critica">Crítica (Pressão/Temperatura)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Ambiente Serviço</label>
|
||
<select class="form-control" id="padrao-env">
|
||
<option value="interno">Interno Seco</option>
|
||
<option value="externo" selected>Externo Temperado</option>
|
||
<option value="agressivo">Externo Agressivo / Marinho</option>
|
||
<option value="baixatemp">Baixas Temperaturas (-20°C)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<button class="btn btn-primary" onclick="buscarPadraoIdeal()">🔍 Buscar Padrão Ideal</button>
|
||
</div>
|
||
<div id="padrao-result"></div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getSoldaFileteContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">⚡ Dimensionamento de Solda de Filete</div>
|
||
<div class="section-description">Cálculo da perna necessária segundo NBR 8800</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Dados da Solda</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Força (kN)</label>
|
||
<input type="number" class="form-control" id="weld-force" step="1" value="100">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Total (mm)</label>
|
||
<input type="number" class="form-control" id="weld-length" step="1" value="500">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Aço Base (fy MPa)</label>
|
||
<input type="number" class="form-control" id="weld-fy" step="1" value="345">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Posição de Soldagem</label>
|
||
<select class="form-control" id="weld-position">
|
||
<option value="1.0">Plana</option>
|
||
<option value="0.9">Horizontal</option>
|
||
<option value="0.85">Vertical</option>
|
||
<option value="0.8">Sobrecabeça</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularSoldaFilete()">⚡ Dimensionar Solda</button>
|
||
</div>
|
||
|
||
<div id="weld-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getEnergiaSoldagemContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🔥 Energia de Soldagem (Heat Input)</div>
|
||
<div class="section-description">Controle de energia para evitar fragilização da ZTA</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros de Soldagem</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Voltagem (V)</label>
|
||
<input type="number" class="form-control" id="hi-voltage" step="1" value="25">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Corrente (A)</label>
|
||
<input type="number" class="form-control" id="hi-current" step="1" value="150">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Velocidade (cm/min)</label>
|
||
<input type="number" class="form-control" id="hi-speed" step="1" value="20">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Eficiência (%)</label>
|
||
<input type="number" class="form-control" id="hi-efficiency" step="1" value="85">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularEnergiaS oldagem()">🔥 Calcular Energia</button>
|
||
</div>
|
||
|
||
<div id="hi-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getConsumoEletrodosContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📊 Consumo de Eletrodos</div>
|
||
<div class="section-description">Estimativa de consumo com perdas</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Dados da Solda</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Perna da Solda (mm)</label>
|
||
<input type="number" class="form-control" id="elec-leg" step="1" value="6">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Comprimento Total (m)</label>
|
||
<input type="number" class="form-control" id="elec-length" step="0.1" value="10">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Eletrodo</label>
|
||
<select class="form-control" id="elec-type">
|
||
<option value="1.15">E6010</option>
|
||
<option value="1.10" selected>E7018</option>
|
||
<option value="1.12">E8018</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Perdas (%)</label>
|
||
<input type="number" class="form-control" id="elec-loss" step="1" value="15">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularConsumoEletrodos()">📊 Calcular Consumo</button>
|
||
</div>
|
||
|
||
<div id="elec-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getDurezaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🔨 Conversor de Dureza</div>
|
||
<div class="section-description">Conversão entre escalas HB, HRC, HV</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Digite em Qualquer Campo</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Brinell (HB)</label>
|
||
<input type="number" class="form-control" id="hard-hb" step="1" value="200" oninput="converterDureza('hb')">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Rockwell C (HRC)</label>
|
||
<input type="number" class="form-control" id="hard-hrc" step="0.1" oninput="converterDureza('hrc')">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Vickers (HV)</label>
|
||
<input type="number" class="form-control" id="hard-hv" step="1" oninput="converterDureza('hv')">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="hardness-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getCharpyContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📉 Análise de Charpy</div>
|
||
<div class="section-description">Curva de transição dúctil-frágil</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Insira até 4 Pares Temperatura/Energia</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Temp 1 (°C)</label>
|
||
<input type="number" class="form-control" id="charpy-t1" step="1" value="20">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Energia 1 (J)</label>
|
||
<input type="number" class="form-control" id="charpy-e1" step="1" value="80">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Temp 2 (°C)</label>
|
||
<input type="number" class="form-control" id="charpy-t2" step="1" value="0">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Energia 2 (J)</label>
|
||
<input type="number" class="form-control" id="charpy-e2" step="1" value="50">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Temp 3 (°C)</label>
|
||
<input type="number" class="form-control" id="charpy-t3" step="1" value="-20">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Energia 3 (J)</label>
|
||
<input type="number" class="form-control" id="charpy-e3" step="1" value="30">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Temp 4 (°C)</label>
|
||
<input type="number" class="form-control" id="charpy-t4" step="1" value="-40">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Energia 4 (J)</label>
|
||
<input type="number" class="form-control" id="charpy-e4" step="1" value="15">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="analisarCharpy()">📉 Gerar Curva</button>
|
||
</div>
|
||
|
||
<div id="charpy-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getUltrassomContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🏥 Interpretação de Ultrassom</div>
|
||
<div class="section-description">Classificação de descontinuidades segundo AWS/ASME</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros da Descontinuidade</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Norma de Avaliação</label>
|
||
<select class="form-control" id="ut-norm">
|
||
<option value="aws">AWS D1.1</option>
|
||
<option value="asme">ASME Section VIII Div 1</option>
|
||
<option value="dnv">DNV-GL</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Descontinuidade</label>
|
||
<select class="form-control" id="ut-type" onchange="updateUtFields()">
|
||
<option value="porosidade">Porosidade</option>
|
||
<option value="inclusao">Inclusão de Escória</option>
|
||
<option value="falta-fusao">Falta de Fusão</option>
|
||
<option value="falta-penetracao">Falta de Penetração</option>
|
||
<option value="trinca">Trinca</option>
|
||
<option value="mordedura">Mordedura</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Localização</label>
|
||
<select class="form-control" id="ut-location">
|
||
<option value="raiz">Raiz</option>
|
||
<option value="passes">Passes Intermediários</option>
|
||
<option value="enchimento">Enchimento</option>
|
||
<option value="acabamento">Acabamento</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group" id="ut-diameter-group">
|
||
<label class="form-label">Diâmetro (mm)</label>
|
||
<input type="number" class="form-control" id="ut-diameter" step="0.1" value="2.5">
|
||
</div>
|
||
<div class="form-group" id="ut-qty-group">
|
||
<label class="form-label">Quantidade</label>
|
||
<input type="number" class="form-control" id="ut-qty" step="1" value="3">
|
||
</div>
|
||
<div class="form-group" id="ut-length-group">
|
||
<label class="form-label">Comprimento Total (mm)</label>
|
||
<input type="number" class="form-control" id="ut-length" step="0.1" value="25">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Profundidade (mm)</label>
|
||
<input type="number" class="form-control" id="ut-depth" step="0.1" value="1.2">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura da Chapa (mm)</label>
|
||
<input type="number" class="form-control" id="ut-thickness" step="1" value="10">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="analisarUltrassom()">🔍 Analisar Conforme Norma</button>
|
||
</div>
|
||
|
||
<div id="ut-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getCertificadoContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📋 Checklist de Certificado</div>
|
||
<div class="section-description">Verificação de conformidade com normas</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Selecionar Norma</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Norma de Referência</label>
|
||
<select class="form-control" id="cert-norm" onchange="gerarChecklistCertificado()">
|
||
<option value="astm_a36">ASTM A36</option>
|
||
<option value="astm_a572">ASTM A572 Gr.50</option>
|
||
<option value="en_s235">EN S235JR</option>
|
||
<option value="en_s355">EN S355J2</option>
|
||
<option value="nbr_ar350">NBR AR350</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="cert-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getAreaPinturaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📐 Cálculo de Área de Pintura</div>
|
||
<div class="section-description">Área total de superfície a pintar</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Tipo de Produto</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo</label>
|
||
<select class="form-control" id="paint-type" onchange="updatePaintFields()">
|
||
<option value="chapa">Chapa</option>
|
||
<option value="perfilW">Perfil W</option>
|
||
<option value="tubo">Tubo Circular</option>
|
||
<option value="rhs">Tubo Retangular (RHS)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group" id="paint-field1">
|
||
<label class="form-label" id="paint-label1">Comprimento (mm)</label>
|
||
<input type="number" class="form-control" id="paint-dim1" step="1" value="6000">
|
||
</div>
|
||
<div class="form-group" id="paint-field2">
|
||
<label class="form-label" id="paint-label2">Largura (mm)</label>
|
||
<input type="number" class="form-control" id="paint-dim2" step="1" value="1000">
|
||
</div>
|
||
<div class="form-group" id="paint-field3" style="display:none;">
|
||
<label class="form-label" id="paint-label3">Altura (mm)</label>
|
||
<input type="number" class="form-control" id="paint-dim3" step="1" value="300">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Quantidade</label>
|
||
<input type="number" class="form-control" id="paint-qty" step="1" value="1">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularAreaPintura()">📐 Calcular Área</button>
|
||
</div>
|
||
|
||
<div id="paint-area-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getConsumoTintaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🎯 Consumo de Tinta</div>
|
||
<div class="section-description">Cálculo de volume e custo</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros de Pintura</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Área Total (m²)</label>
|
||
<input type="number" class="form-control" id="tinta-area" step="0.1" value="50">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">DFT Desejado (μm)</label>
|
||
<input type="number" class="form-control" id="tinta-dft" step="1" value="160">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">% Sólidos</label>
|
||
<input type="number" class="form-control" id="tinta-solids" step="1" value="65">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">% Perdas</label>
|
||
<input type="number" class="form-control" id="tinta-loss" step="1" value="25">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Número de Demãos</label>
|
||
<input type="number" class="form-control" id="tinta-coats" step="1" value="2">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Custo/Litro (R$)</label>
|
||
<input type="number" class="form-control" id="tinta-cost" step="0.01" value="80.00">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularConsumoTinta()">🎯 Calcular Consumo</button>
|
||
</div>
|
||
|
||
<div id="tinta-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getCustoPinturaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">💰 Custo Total de Pintura</div>
|
||
<div class="section-description">Análise completa de custos com mão de obra e materiais</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros de Custos</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Área Total (m²)</label>
|
||
<input type="number" class="form-control" id="custo-area" step="0.1" value="50">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Região do Brasil</label>
|
||
<select class="form-control" id="custo-regiao">
|
||
<option value="sudeste">Sudeste (SP/RJ/MG)</option>
|
||
<option value="sul">Sul (RS/SC/PR)</option>
|
||
<option value="nordeste">Nordeste (CE/PE/BA)</option>
|
||
<option value="centrooeste">Centro-Oeste (DF/GO/MS)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Tinta</label>
|
||
<select class="form-control" id="custo-tipo-tinta">
|
||
<option value="padrao">Padrão Industrial</option>
|
||
<option value="premium">Premium (Maior Durabilidade)</option>
|
||
<option value="economica">Econômica (Budget)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Custo Mão de Obra (R$/hora)</label>
|
||
<input type="number" class="form-control" id="custo-mo" step="1" value="85">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Produtividade (m²/hora)</label>
|
||
<input type="number" class="form-control" id="custo-prod" step="0.1" value="5">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Volume de Tinta (L)</label>
|
||
<input type="number" class="form-control" id="custo-volume" step="0.1" value="100">
|
||
</div>
|
||
</div>
|
||
<div style="margin: 20px 0;">
|
||
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="custo-incluir-epi" checked style="width: 18px; height: 18px;">
|
||
<span>Incluir EPI e Materiais Consumíveis</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; margin-top: 8px;">
|
||
<input type="checkbox" id="custo-incluir-equip" style="width: 18px; height: 18px;">
|
||
<span>Incluir Aluguel de Equipamentos</span>
|
||
</label>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularCustoTotal()">💵 Calcular Custo Final</button>
|
||
</div>
|
||
|
||
<div id="custo-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getSecagemContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">⏱️ Tempo de Secagem</div>
|
||
<div class="section-description">Estimativa de tempo com análise de condições ambientais</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Condições de Aplicação</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Tinta</label>
|
||
<select class="form-control" id="sec-tipo">
|
||
<option value="epoxi">Epóxi</option>
|
||
<option value="poliuretano">Poliuretano (PU)</option>
|
||
<option value="alquidica">Alquídica</option>
|
||
<option value="acrilica">Acrílica</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Temperatura (°C)</label>
|
||
<input type="number" class="form-control" id="sec-temp" step="1" value="25">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Umidade Relativa (%)</label>
|
||
<input type="number" class="form-control" id="sec-umidade" step="1" value="60">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura Aplicada (μm)</label>
|
||
<input type="number" class="form-control" id="sec-espessura" step="10" value="80">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularSecagem()">⏱️ Calcular Tempo</button>
|
||
</div>
|
||
|
||
<div id="sec-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getInspecaoPinturaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">✔️ Inspeção de Qualidade de Pintura</div>
|
||
<div class="section-description">Checklist profissional conforme ISO 12944</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Checklist de Inspeção</div>
|
||
<div style="display: flex; flex-direction: column; gap: 12px; margin: 20px 0;">
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-1" style="width: 20px; height: 20px;">
|
||
<span><strong>Preparação de Superfície (ISO 8501):</strong> Grau de limpeza adequado (Sa 2½ mínimo)</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-2" style="width: 20px; height: 20px;">
|
||
<span><strong>Limpeza:</strong> Superfície livre de pó, óleo, ferrugem e contaminantes</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-3" style="width: 20px; height: 20px;">
|
||
<span><strong>Medição DFT:</strong> Espessura de película seca conforme especificação</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-4" style="width: 20px; height: 20px;">
|
||
<span><strong>Teste de Aderência (ISO 2409):</strong> Cross-cut test aprovado</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-5" style="width: 20px; height: 20px;">
|
||
<span><strong>Aspecto Visual:</strong> Cor, brilho e textura uniformes</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-6" style="width: 20px; height: 20px;">
|
||
<span><strong>Uniformidade de Cobertura:</strong> Sem áreas descobertas ou falhas</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-7" style="width: 20px; height: 20px;">
|
||
<span><strong>Ausência de Defeitos:</strong> Sem bolhas, rachaduras, escorrimentos ou crateras</span>
|
||
</label>
|
||
<label style="display: flex; align-items: center; gap: 12px; padding: 12px; background: var(--color-background); border-radius: 8px; cursor: pointer;">
|
||
<input type="checkbox" id="insp-8" style="width: 20px; height: 20px;">
|
||
<span><strong>Tempo de Cura:</strong> Intervalo entre demãos e cura final adequados</span>
|
||
</label>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="gerarRelatorioInspecao()">📋 Gerar Relatório</button>
|
||
</div>
|
||
|
||
<div id="insp-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getGalvanizacaoContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">🛡️ Galvanização a Quente</div>
|
||
<div class="section-description">Espessura mínima e vida útil</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Parâmetros de Galvanização</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Ambiente</label>
|
||
<select class="form-control" id="galv-env">
|
||
<option value="interno">Interno (C1)</option>
|
||
<option value="urbano">Urbano (C2/C3)</option>
|
||
<option value="marinho" selected>Marinho (C4/C5)</option>
|
||
<option value="industrial">Industrial (C4)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Área a Galvanizar (m²)</label>
|
||
<input type="number" class="form-control" id="galv-area" step="0.1" value="100">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Espessura Desejada (μm)</label>
|
||
<input type="number" class="form-control" id="galv-thickness" step="1" value="85">
|
||
</div>
|
||
<div class="form-group expert-only">
|
||
<label class="form-label">Vida Útil Desejada (anos)</label>
|
||
<input type="number" class="form-control" id="galv-life" step="1" value="20">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularGalvanizacao()">🛡️ Calcular</button>
|
||
</div>
|
||
|
||
<div id="galv-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getOrcamentoContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">💵 Orçamento Detalhado v6.5</div>
|
||
<div class="section-description">Gerenciador completo com base de dados integrada de materiais</div>
|
||
</div>
|
||
|
||
<div style="padding: 20px; background: var(--color-bg-8); border-radius: 12px; border: 2px solid var(--color-primary); margin-bottom: 20px;">
|
||
<h3 style="margin-bottom: 12px; color: var(--color-primary);">🎉 NOVIDADE v6.5: Base de Dados Completa de Materiais!</h3>
|
||
<p style="margin-bottom: 12px;">Agora você pode selecionar materiais de um banco de dados com <strong>100+ produtos do mercado brasileiro</strong> (Gerdau, Usiminas):</p>
|
||
<ul style="margin-left: 20px; margin-bottom: 12px;">
|
||
<li>✅ Perfis W, I (IPE), HP - Pesos automáticos</li>
|
||
<li>✅ Cantoneiras, Tubos Circulares e RHS</li>
|
||
<li>✅ Chapas, Barras, Eletrodos, Tintas, Parafusos</li>
|
||
<li>✅ Preços regionais (Sudeste, Sul, Nordeste, Centro-Oeste)</li>
|
||
<li>✅ Cálculo automático de preço unitário baseado em peso e região</li>
|
||
</ul>
|
||
<button class="btn btn-primary" onclick="carregarOrcamentoExemplo()" style="margin-right: 10px;">📦 Carregar Orçamento Exemplo</button>
|
||
<button class="btn btn-secondary" onclick="alert('📖 TUTORIAL:\n\n1. Selecione a Região (preços ajustam automaticamente)\n2. Escolha Categoria: Material, Serviço, Consumível ou Indireto\n3. Selecione Tipo de Produto (ex: Perfil W)\n4. Escolha Especificação da lista (ex: W250×38)\n5. Preço e peso preenchem automaticamente!\n6. Digite quantidade e adicione\n\nSimples assim! 🚀')">📖 Como Usar</button>
|
||
</div>
|
||
|
||
<div class="card" style="background: var(--color-bg-1); border: 2px solid var(--color-primary);">
|
||
<div class="card-title">🌍 Configuração Regional</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Região do Brasil</label>
|
||
<select class="form-control" id="budget-region" onchange="updateRegionalPricing()">
|
||
<option value="sudeste" selected>Sudeste (SP/RJ/MG)</option>
|
||
<option value="sul">Sul (RS/SC/PR)</option>
|
||
<option value="nordeste">Nordeste (CE/PE/BA)</option>
|
||
<option value="centrooeste">Centro-Oeste (DF/GO/MS)</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Data do Orçamento</label>
|
||
<input type="date" class="form-control" id="budget-date" value="2025-11-07">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Nome do Projeto</label>
|
||
<input type="text" class="form-control" id="budget-project" placeholder="Ex: Estrutura Galpão Industrial">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">✎ Adicionar Item ao Orçamento</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Categoria</label>
|
||
<select class="form-control" id="budget-category" onchange="updateBudgetTypeOptions()">
|
||
<option value="material">Material</option>
|
||
<option value="servico">Serviço</option>
|
||
<option value="consumivel">Consumível</option>
|
||
<option value="indireto">Indireto</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo de Produto</label>
|
||
<select class="form-control" id="budget-type" onchange="updateBudgetSpecOptions()">
|
||
<option value="perfil_w">Perfil W</option>
|
||
<option value="perfil_i">Perfil I (IPE)</option>
|
||
<option value="perfil_hp">Perfil HP</option>
|
||
<option value="cantoneira">Cantoneira</option>
|
||
<option value="tubo_circ">Tubo Circular</option>
|
||
<option value="tubo_rhs">Tubo Retangular (RHS)</option>
|
||
<option value="chapa">Chapa</option>
|
||
<option value="barra">Barra Redonda</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Especificação (Produto)</label>
|
||
<select class="form-control" id="budget-spec" onchange="autoFillBudgetData()">
|
||
<option value="">Selecione...</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; margin: 16px 0; display: none;" id="product-info-display">
|
||
<strong>📋 Informações do Produto:</strong><br>
|
||
<span id="product-details"></span>
|
||
</div>
|
||
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Quantidade</label>
|
||
<input type="number" class="form-control" id="budget-qty" step="0.01" value="1" oninput="updateBudgetTotal()">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Unidade</label>
|
||
<input type="text" class="form-control" id="budget-unit" value="m" readonly style="background: var(--color-secondary);">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Preço Unitário (R$)</label>
|
||
<input type="number" class="form-control" id="budget-price" step="0.01" value="0" readonly style="background: var(--color-bg-3); font-weight: bold;">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Total (R$)</label>
|
||
<input type="text" class="form-control" id="budget-item-total" value="R$ 0.00" readonly style="background: var(--color-bg-1); font-weight: bold; font-size: 16px;">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-success" onclick="adicionarItemOrcamentoV2()" style="width: 100%; padding: 16px; font-size: 16px;">➕ Adicionar ao Orçamento</button>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">📋 Itens do Orçamento</div>
|
||
<div class="table-container">
|
||
<table id="budget-table" style="font-size: 13px;">
|
||
<thead>
|
||
<tr style="background: var(--color-primary); color: var(--color-btn-primary-text);">
|
||
<th style="padding: 12px;">#</th>
|
||
<th>Categoria</th>
|
||
<th>Especificação</th>
|
||
<th>Qtd</th>
|
||
<th>Un</th>
|
||
<th>Preço Unit.</th>
|
||
<th>Valor Total</th>
|
||
<th>Ações</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="budget-tbody">
|
||
<tr>
|
||
<td colspan="8" style="text-align: center; color: var(--color-text-secondary); padding: 24px;">Nenhum item adicionado</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="form-group" style="margin-top: 20px; max-width: 300px;">
|
||
<label class="form-label">BDI / Margem (%)</label>
|
||
<input type="number" class="form-control" id="budget-bdi" step="0.1" value="25" onchange="atualizarTotalOrcamentoV2()" style="font-size: 16px; font-weight: bold;">
|
||
</div>
|
||
|
||
<div id="budget-total"></div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function getPesoRiggingContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">⚖️ Peso & Plano de Rigging</div>
|
||
<div class="section-description">Cálculo de peso e dimensionamento de içamento</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Cálculo de Peso</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Tipo</label>
|
||
<select class="form-control" id="weight-type" onchange="updateWeightFields()">
|
||
<option value="perfilW">Perfil W</option>
|
||
<option value="chapa">Chapa</option>
|
||
<option value="tubo">Tubo Circular</option>
|
||
<option value="barra">Barra Redonda</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group" id="weight-field1">
|
||
<label class="form-label" id="weight-label1">Altura (mm)</label>
|
||
<input type="number" class="form-control" id="weight-dim1" step="1" value="300">
|
||
</div>
|
||
<div class="form-group" id="weight-field2">
|
||
<label class="form-label" id="weight-label2">Comprimento (m)</label>
|
||
<input type="number" class="form-control" id="weight-dim2" step="0.1" value="6">
|
||
</div>
|
||
<div class="form-group" id="weight-field3" style="display:none;">
|
||
<label class="form-label" id="weight-label3">Largura (mm)</label>
|
||
<input type="number" class="form-control" id="weight-dim3" step="1" value="1000">
|
||
</div>
|
||
<div class="form-group" id="weight-field4" style="display:none;">
|
||
<label class="form-label" id="weight-label4">Espessura (mm)</label>
|
||
<input type="number" class="form-control" id="weight-dim4" step="0.1" value="10">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularPeso()">⚖️ Calcular Peso</button>
|
||
</div>
|
||
|
||
<div id="weight-result"></div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Dimensionamento de Rigging</div>
|
||
<div class="form-grid">
|
||
<div class="form-group">
|
||
<label class="form-label">Peso Total (kg)</label>
|
||
<input type="number" class="form-control" id="rigging-weight" step="1" value="1000">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Pontos de Içamento</label>
|
||
<select class="form-control" id="rigging-points">
|
||
<option value="2" selected>2</option>
|
||
<option value="3">3</option>
|
||
<option value="4">4</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Ângulo</label>
|
||
<select class="form-control" id="rigging-angle">
|
||
<option value="90">90°</option>
|
||
<option value="75">75°</option>
|
||
<option value="60" selected>60°</option>
|
||
<option value="45">45°</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Fator de Segurança</label>
|
||
<input type="number" class="form-control" id="rigging-fs" step="0.1" value="4">
|
||
</div>
|
||
</div>
|
||
<button class="btn btn-primary" onclick="calcularRigging()">🏗️ Calcular Rigging</button>
|
||
</div>
|
||
|
||
<div id="rigging-result"></div>
|
||
`;
|
||
}
|
||
|
||
function getReferenciaContent() {
|
||
return `
|
||
<div class="section-header">
|
||
<div class="section-title">📖 Referência Técnica</div>
|
||
<div class="section-description">Banco de dados completo de aços e sistemas</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Aços Estruturais</div>
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Designação</th>
|
||
<th>fy (MPa)</th>
|
||
<th>fu (MPa)</th>
|
||
<th>Along. (%)</th>
|
||
<th>CEV</th>
|
||
<th>Soldabilidade</th>
|
||
<th>Aplicação</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>ASTM A36</strong></td>
|
||
<td>250</td>
|
||
<td>400</td>
|
||
<td>20</td>
|
||
<td>0.41</td>
|
||
<td>⭐⭐⭐⭐⭐</td>
|
||
<td>Estruturas gerais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>ASTM A572 Gr.50</strong></td>
|
||
<td>345</td>
|
||
<td>450</td>
|
||
<td>18</td>
|
||
<td>0.45</td>
|
||
<td>⭐⭐⭐⭐</td>
|
||
<td>Edifícios, pontes</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>ASTM A588</strong></td>
|
||
<td>345</td>
|
||
<td>485</td>
|
||
<td>19</td>
|
||
<td>0.50</td>
|
||
<td>⭐⭐⭐</td>
|
||
<td>Weathering</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>EN S235JR</strong></td>
|
||
<td>235</td>
|
||
<td>360</td>
|
||
<td>26</td>
|
||
<td>0.38</td>
|
||
<td>⭐⭐⭐⭐⭐</td>
|
||
<td>Estruturas gerais</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>EN S355J2</strong></td>
|
||
<td>355</td>
|
||
<td>490</td>
|
||
<td>22</td>
|
||
<td>0.50</td>
|
||
<td>⭐⭐⭐⭐</td>
|
||
<td>Pontes, pesadas</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>NBR AR350</strong></td>
|
||
<td>345</td>
|
||
<td>450</td>
|
||
<td>18</td>
|
||
<td>0.45</td>
|
||
<td>⭐⭐⭐⭐</td>
|
||
<td>Construção civil</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Sistemas de Pintura ISO 12944</div>
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Classe</th>
|
||
<th>Ambiente</th>
|
||
<th>DFT (μm)</th>
|
||
<th>Sistema</th>
|
||
<th>Vida Útil</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><strong>C1</strong></td>
|
||
<td>Interior seco</td>
|
||
<td>80</td>
|
||
<td>Monocomponente</td>
|
||
<td>5-10 anos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>C2</strong></td>
|
||
<td>Interior úmido</td>
|
||
<td>120</td>
|
||
<td>Epóxi 2c</td>
|
||
<td>5-10 anos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>C3</strong></td>
|
||
<td>Exterior médio</td>
|
||
<td>160</td>
|
||
<td>Epóxi + PU</td>
|
||
<td>10-15 anos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>C4</strong></td>
|
||
<td>Exterior agressivo</td>
|
||
<td>200</td>
|
||
<td>Epóxi alicíclico + PU</td>
|
||
<td>15-20 anos</td>
|
||
</tr>
|
||
<tr>
|
||
<td><strong>C5</strong></td>
|
||
<td>Marinho</td>
|
||
<td>250</td>
|
||
<td>Epóxi zinc-rich + PU</td>
|
||
<td>20+ anos</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div class="card-title">Normas de Referência</div>
|
||
<ul style="list-style-type: none; padding: 0;">
|
||
<li style="padding: 12px; background: var(--color-bg-1); margin-bottom: 8px; border-radius: 8px;">
|
||
<strong>AWS D1.1/D1.1M</strong> - Soldagem de estruturas de aço
|
||
</li>
|
||
<li style="padding: 12px; background: var(--color-bg-2); margin-bottom: 8px; border-radius: 8px;">
|
||
<strong>NBR 8800:2008</strong> - Projeto de estruturas de aço de edifícios
|
||
</li>
|
||
<li style="padding: 12px; background: var(--color-bg-3); margin-bottom: 8px; border-radius: 8px;">
|
||
<strong>EN 1993-1-8</strong> - Design of connections
|
||
</li>
|
||
<li style="padding: 12px; background: var(--color-bg-4); margin-bottom: 8px; border-radius: 8px;">
|
||
<strong>ISO 12944</strong> - Proteção de estruturas de aço com tinta
|
||
</li>
|
||
<li style="padding: 12px; background: var(--color-bg-5); margin-bottom: 8px; border-radius: 8px;">
|
||
<strong>ASTM A123</strong> - Galvanização a quente
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
// ========================================
|
||
// CALCULATION FUNCTIONS
|
||
// ========================================
|
||
|
||
// CEV Calculation
|
||
function calcularCEV() {
|
||
const getVal = (id) => parseFloat(document.getElementById(id)?.value) || 0;
|
||
|
||
const C = getVal('cev-c');
|
||
const Mn = getVal('cev-mn');
|
||
const Cr = getVal('cev-cr');
|
||
const Mo = getVal('cev-mo');
|
||
const V = getVal('cev-v');
|
||
const Ni = getVal('cev-ni');
|
||
const Cu = getVal('cev-cu');
|
||
const thickness = getVal('cev-thickness');
|
||
|
||
if ([C, Mn, Cr, Mo, V, Ni, Cu].every(v => v === 0)) {
|
||
const resultEl = document.getElementById('cev-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-warning">⚠️ Preencha pelo menos um elemento de liga para calcular o CEV.</div>';
|
||
return;
|
||
}
|
||
|
||
if (C < 0 || C > 2 || Mn < 0 || Mn > 5 || Cr < 0 || Cr > 30 || Mo < 0 || Mo > 5 || V < 0 || V > 5 || Ni < 0 || Ni > 5 || Cu < 0 || Cu > 5) {
|
||
const resultEl = document.getElementById('cev-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Valores fora dos limites típicos para aços. Verifique os valores inseridos.</div>';
|
||
return;
|
||
}
|
||
|
||
// IIW Formula
|
||
const CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15;
|
||
|
||
// Interpretation
|
||
let stars = '';
|
||
let interpretation = '';
|
||
let alertClass = '';
|
||
|
||
if (CEV < 0.40) {
|
||
stars = '⭐⭐⭐⭐⭐';
|
||
interpretation = 'Excelente soldabilidade - Sem pré-aquecimento até 50mm';
|
||
alertClass = 'alert-success';
|
||
} else if (CEV < 0.50) {
|
||
stars = '⭐⭐⭐⭐';
|
||
interpretation = 'Boa soldabilidade - Pré-aquecimento recomendado acima de 25mm';
|
||
alertClass = 'alert-success';
|
||
} else if (CEV < 0.60) {
|
||
stars = '⭐⭐⭐';
|
||
interpretation = 'Soldabilidade média - Pré-aquecimento essencial acima de 15mm';
|
||
alertClass = 'alert-warning';
|
||
} else if (CEV < 0.70) {
|
||
stars = '⭐⭐';
|
||
interpretation = 'Soldabilidade difícil - Pré-aquecimento obrigatório, considerar PWHT';
|
||
alertClass = 'alert-warning';
|
||
} else {
|
||
stars = '⭐';
|
||
interpretation = 'Soldabilidade muito difícil - Procedimento especial necessário';
|
||
alertClass = 'alert-error';
|
||
}
|
||
|
||
// Preheat temperature (AWS D1.1)
|
||
const tempAmb = parseFloat(document.getElementById('cev-temp')?.value) || 20;
|
||
const preheatTemp = 50 + (CEV * 50) + (thickness / 10 * 20) + ((20 - tempAmb) / 2);
|
||
|
||
const result = document.getElementById('cev-result');
|
||
result.innerHTML = `
|
||
<div class="result-box">
|
||
<div class="result-title">Resultado do Cálculo CEV (IIW)</div>
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">CEV</div>
|
||
<div class="result-value">${CEV.toFixed(3)}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Avaliação</div>
|
||
<div class="result-value" style="font-size: 28px;">${stars}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Pré-aquecimento Mínimo</div>
|
||
<div class="result-value">${Math.round(preheatTemp)}°C</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-2); border-radius: 8px;">
|
||
<strong>Fórmula IIW:</strong> CEV = C + Mn/6 + (Cr+Mo+V)/5 + (Ni+Cu)/15<br>
|
||
<strong>Normas aplicáveis:</strong> AWS D1.1, NBR 16239, EN 1011-2
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('CEV Avançado', `CEV = ${CEV.toFixed(3)}, Pré-aquecimento = ${Math.round(preheatTemp)}°C`);
|
||
}
|
||
|
||
// Steel Selector
|
||
function selecionarAco() {
|
||
const fyMin = parseFloat(document.getElementById('sel-fy').value) || 0;
|
||
const weldReq = document.getElementById('sel-weld').value;
|
||
|
||
const steels = Object.values(steelDatabase).filter(steel => {
|
||
if (steel.fy < fyMin) return false;
|
||
if (weldReq === 'excellent' && steel.cev > 0.45) return false;
|
||
if (weldReq === 'good' && steel.cev > 0.55) return false;
|
||
return true;
|
||
});
|
||
|
||
if (steels.length === 0) {
|
||
document.getElementById('seletor-result').innerHTML = `
|
||
<div class="alert alert-warning">
|
||
Nenhum aço encontrado com os critérios especificados
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
const result = steels.map(steel => `
|
||
<div class="steel-card">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 12px;">${steel.nome}</h3>
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">fy</div>
|
||
<div class="result-value" style="font-size: 20px;">${steel.fy} MPa</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">fu</div>
|
||
<div class="result-value" style="font-size: 20px;">${steel.fu} MPa</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Alongamento</div>
|
||
<div class="result-value" style="font-size: 20px;">${steel.elong}%</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">CEV</div>
|
||
<div class="result-value" style="font-size: 20px;">${steel.cev}</div>
|
||
</div>
|
||
</div>
|
||
<p style="margin-top: 12px;"><strong>Soldabilidade:</strong> ${steel.soldabilidade}</p>
|
||
<p><strong>Equivalentes:</strong> ${steel.equiv.join(', ')}</p>
|
||
<p><strong>Custo relativo:</strong> ${steel.custo}%</p>
|
||
</div>
|
||
`).join('');
|
||
|
||
document.getElementById('seletor-result').innerHTML = `
|
||
<div class="card">
|
||
<div class="card-title">Aços Recomendados (${steels.length})</div>
|
||
${result}
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Seletor de Aço', `${steels.length} aços encontrados com fy ≥ ${fyMin} MPa`);
|
||
}
|
||
|
||
// Equivalencias
|
||
function mostrarEquivalencias() {
|
||
const steelSelect = document.getElementById('equiv-steel');
|
||
const resultDiv = document.getElementById('equiv-result');
|
||
|
||
// Verificar se os elementos existem antes de continuar
|
||
if (!steelSelect || !resultDiv) return;
|
||
|
||
const steelId = steelSelect.value;
|
||
const steel = steelDatabase[steelId];
|
||
|
||
if (!steel) return;
|
||
|
||
document.getElementById('equiv-result').innerHTML = `
|
||
<div class="card">
|
||
<div class="card-title">Equivalências para ${steel.nome}</div>
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Norma</th>
|
||
<th>Designação</th>
|
||
<th>fy (MPa)</th>
|
||
<th>fu (MPa)</th>
|
||
<th>Along. (%)</th>
|
||
<th>CEV</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr style="background: var(--color-bg-1);">
|
||
<td><strong>Base</strong></td>
|
||
<td><strong>${steel.nome}</strong></td>
|
||
<td><strong>${steel.fy}</strong></td>
|
||
<td><strong>${steel.fu}</strong></td>
|
||
<td><strong>${steel.elong}</strong></td>
|
||
<td><strong>${steel.cev}</strong></td>
|
||
</tr>
|
||
${steel.equiv.map(eq => {
|
||
const eqSteel = Object.values(steelDatabase).find(s => s.nome === eq);
|
||
if (!eqSteel) return '';
|
||
return `
|
||
<tr>
|
||
<td>${eq.includes('ASTM') ? 'ASTM' : eq.includes('EN') ? 'EN' : eq.includes('NBR') ? 'NBR' : 'JIS'}</td>
|
||
<td>${eqSteel.nome}</td>
|
||
<td>${eqSteel.fy}</td>
|
||
<td>${eqSteel.fu}</td>
|
||
<td>${eqSteel.elong}</td>
|
||
<td>${eqSteel.cev}</td>
|
||
</tr>
|
||
`;
|
||
}).join('')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
// Comparative Chart
|
||
function gerarGraficoComparativo() {
|
||
const checkboxes = document.querySelectorAll('.checkbox-group input:checked');
|
||
const selectedSteels = Array.from(checkboxes).map(cb => cb.value);
|
||
const chartType = document.getElementById('chart-type').value;
|
||
|
||
if (selectedSteels.length === 0) {
|
||
alert('Selecione pelo menos um aço');
|
||
return;
|
||
}
|
||
|
||
if (chartType === 'table') {
|
||
let tableHtml = `
|
||
<div class="card">
|
||
<div class="card-title">Tabela Comparativa</div>
|
||
<div class="table-container">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Aço</th>
|
||
<th>fy (MPa)</th>
|
||
<th>fu (MPa)</th>
|
||
<th>Along. (%)</th>
|
||
<th>CEV</th>
|
||
<th>Soldabilidade</th>
|
||
<th>Custo</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
`;
|
||
|
||
selectedSteels.forEach(steelId => {
|
||
const steel = steelDatabase[steelId];
|
||
if (steel) {
|
||
tableHtml += `
|
||
<tr>
|
||
<td><strong>${steel.nome}</strong></td>
|
||
<td>${steel.fy}</td>
|
||
<td>${steel.fu}</td>
|
||
<td>${steel.elong}</td>
|
||
<td>${steel.cev}</td>
|
||
<td>${steel.soldabilidade}</td>
|
||
<td>${steel.custo}%</td>
|
||
</tr>
|
||
`;
|
||
}
|
||
});
|
||
|
||
tableHtml += `
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('chart-result').innerHTML = tableHtml;
|
||
} else {
|
||
document.getElementById('chart-result').innerHTML = `
|
||
<div class="card">
|
||
<div class="card-title">Gráfico Comparativo</div>
|
||
<div class="chart-container">
|
||
<canvas id="comparison-chart"></canvas>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
if (currentChart) {
|
||
currentChart.destroy();
|
||
}
|
||
|
||
const ctx = document.getElementById('comparison-chart').getContext('2d');
|
||
const colors = ['#1FB8CD', '#FFC185', '#B4413C', '#ECEBD5', '#5D878F', '#DB4545'];
|
||
|
||
if (chartType === 'resistance') {
|
||
currentChart = new Chart(ctx, {
|
||
type: 'bar',
|
||
data: {
|
||
labels: selectedSteels.map(s => steelDatabase[s]?.nome || s),
|
||
datasets: [
|
||
{
|
||
label: 'fy (MPa)',
|
||
data: selectedSteels.map(s => steelDatabase[s]?.fy || 0),
|
||
backgroundColor: colors[0]
|
||
},
|
||
{
|
||
label: 'fu (MPa)',
|
||
data: selectedSteels.map(s => steelDatabase[s]?.fu || 0),
|
||
backgroundColor: colors[1]
|
||
}
|
||
]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Comparação de Resistência'
|
||
}
|
||
}
|
||
}
|
||
});
|
||
} else if (chartType === 'ductility') {
|
||
currentChart = new Chart(ctx, {
|
||
type: 'line',
|
||
data: {
|
||
labels: selectedSteels.map(s => steelDatabase[s]?.nome || s),
|
||
datasets: [{
|
||
label: 'Alongamento (%)',
|
||
data: selectedSteels.map(s => steelDatabase[s]?.elong || 0),
|
||
borderColor: colors[2],
|
||
backgroundColor: colors[2] + '40',
|
||
tension: 0.4,
|
||
fill: true
|
||
}]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Comparação de Ductilidade'
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
addToHistory('Gráficos Comparativos', `Comparação de ${selectedSteels.length} aços`);
|
||
}
|
||
|
||
// ========================================
|
||
// ASSISTENTE INTELIGENTE - AI RECOMMENDATIONS
|
||
// ========================================
|
||
|
||
/**
|
||
* Update AI recommendations based on current selections
|
||
*/
|
||
function updateAIRecommendations() {
|
||
const steel = document.getElementById('ai-steel')?.value;
|
||
const environment = document.getElementById('ai-environment')?.value;
|
||
|
||
if (!steel || !environment) {
|
||
document.getElementById('ai-recommendations').innerHTML = '';
|
||
return;
|
||
}
|
||
|
||
// Show preview
|
||
document.getElementById('ai-recommendations').innerHTML = `
|
||
<div class="card" style="background: var(--color-bg-2); border-left: 4px solid var(--color-primary);">
|
||
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 12px;">
|
||
<span style="font-size: 24px;">⚡</span>
|
||
<div>
|
||
<h4 style="margin: 0;">Pré-visualização</h4>
|
||
<p style="margin: 0; font-size: 13px; color: var(--color-text-secondary);">Clique em "Gerar Recomendação" para ver detalhes completos</p>
|
||
</div>
|
||
</div>
|
||
<div style="display: flex; gap: 20px; font-size: 14px;">
|
||
<div><strong>Aço:</strong> ${steel}</div>
|
||
<div><strong>Ambiente:</strong> ${environment}</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
/**
|
||
* Generate complete AI recommendation
|
||
*/
|
||
async function generateAIRecommendation() {
|
||
const steel = document.getElementById('ai-steel')?.value;
|
||
const environment = document.getElementById('ai-environment')?.value;
|
||
|
||
if (!steel || !environment) {
|
||
alert('⚠️ Selecione o aço e o ambiente antes de gerar a recomendação!');
|
||
return;
|
||
}
|
||
|
||
const resultsDiv = document.getElementById('ai-recommendations');
|
||
|
||
// Show loading
|
||
resultsDiv.innerHTML = `
|
||
<div class="card" style="text-align: center; padding: 40px;">
|
||
<div style="font-size: 48px; margin-bottom: 16px;">🤖</div>
|
||
<h3>Analisando requisitos...</h3>
|
||
<p style="color: var(--color-text-secondary);">Cruzando dados de aço, soldagem e pintura</p>
|
||
<div style="margin-top: 20px;">
|
||
<div style="display: inline-block; width: 200px; height: 4px; background: var(--color-bg-3); border-radius: 2px; overflow: hidden;">
|
||
<div style="width: 100%; height: 100%; background: var(--color-primary); animation: loading 1.5s ease-in-out infinite;"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
try {
|
||
// Import and use the relationships module
|
||
const {
|
||
loadRelationships,
|
||
getCompleteRecommendation,
|
||
formatWeldingRecommendation,
|
||
formatPaintingRecommendation
|
||
} = await import('./js/utils/material-relationships.js');
|
||
|
||
// Ensure relationships are loaded
|
||
await loadRelationships();
|
||
|
||
// Get recommendation
|
||
const recommendation = getCompleteRecommendation(steel, environment);
|
||
|
||
// Generate results HTML
|
||
let html = `
|
||
<div class="card" style="background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-hover) 100%); color: white; margin-bottom: 20px;">
|
||
<div style="display: flex; align-items: center; gap: 16px; margin-bottom: 16px;">
|
||
<span style="font-size: 48px;">🤖</span>
|
||
<div>
|
||
<h2 style="margin: 0; font-size: 24px;">Recomendação Inteligente</h2>
|
||
<p style="margin: 0; opacity: 0.9;">Baseada em relacionamentos técnicos da base de dados</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-top: 20px;">
|
||
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
|
||
<div style="font-size: 20px; margin-bottom: 8px;">🏗️</div>
|
||
<div style="font-weight: bold;">Aço Selecionado</div>
|
||
<div style="opacity: 0.9;">${steel}</div>
|
||
</div>
|
||
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
|
||
<div style="font-size: 20px; margin-bottom: 8px;">🌊</div>
|
||
<div style="font-weight: bold;">Ambiente</div>
|
||
<div style="opacity: 0.9;">${environment}</div>
|
||
</div>
|
||
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
|
||
<div style="font-size: 20px; margin-bottom: 8px;">${recommendation.hasWelding ? '✅' : '❌'}</div>
|
||
<div style="font-weight: bold;">Soldagem</div>
|
||
<div style="opacity: 0.9;">${recommendation.hasWelding ? 'Disponível' : 'Não encontrada'}</div>
|
||
</div>
|
||
<div style="background: rgba(255,255,255,0.1); padding: 16px; border-radius: 8px;">
|
||
<div style="font-size: 20px; margin-bottom: 8px;">${recommendation.hasPainting ? '✅' : '❌'}</div>
|
||
<div style="font-weight: bold;">Pintura</div>
|
||
<div style="opacity: 0.9;">${recommendation.hasPainting ? 'Disponível' : 'Não encontrada'}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: rgba(255,255,255,0.1); border-radius: 8px;">
|
||
<div style="font-weight: bold; margin-bottom: 8px;">📊 Status da Recomendação</div>
|
||
<div style="display: flex; align-items: center; gap: 8px;">
|
||
<div style="font-size: 24px;">${recommendation.isComplete ? '🎯' : '⚠️'}</div>
|
||
<div>
|
||
${recommendation.isComplete
|
||
? 'Recomendação completa disponível!'
|
||
: 'Recomendação parcial - alguns dados podem estar indisponíveis'}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
// Add welding recommendation
|
||
html += formatWeldingRecommendation(recommendation.welding);
|
||
|
||
// Add painting recommendation
|
||
html += formatPaintingRecommendation(recommendation.painting);
|
||
|
||
// Add action buttons
|
||
html += `
|
||
<div class="card" style="background: var(--color-bg-4); text-align: center;">
|
||
<h4 style="margin-bottom: 16px;">🚀 Próximos Passos</h4>
|
||
<div style="display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
|
||
<button class="btn btn-primary" onclick="showSection('preaquecimento')">
|
||
🔥 Calcular Pré-aquecimento
|
||
</button>
|
||
<button class="btn btn-primary" onclick="showSection('area-pintura')">
|
||
🎨 Calcular Área de Pintura
|
||
</button>
|
||
<button class="btn btn-secondary" onclick="exportAIRecommendation()">
|
||
📄 Exportar Relatório
|
||
</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
resultsDiv.innerHTML = html;
|
||
|
||
// Add to history
|
||
addToHistory('Assistente IA', `${steel} + ${environment}`);
|
||
|
||
} catch (error) {
|
||
console.error('Erro ao gerar recomendação:', error);
|
||
resultsDiv.innerHTML = `
|
||
<div class="card" style="background: var(--color-bg-4); border-left: 4px solid var(--color-error);">
|
||
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 12px;">
|
||
<span style="font-size: 32px;">❌</span>
|
||
<div>
|
||
<h4 style="margin: 0; color: var(--color-error);">Erro ao Gerar Recomendação</h4>
|
||
<p style="margin: 0; font-size: 13px; color: var(--color-text-secondary);">Não foi possível carregar os dados de relacionamento</p>
|
||
</div>
|
||
</div>
|
||
<p style="margin-bottom: 16px;">Possíveis causas:</p>
|
||
<ul style="margin-bottom: 16px;">
|
||
<li>Arquivos CSV de relacionamento não encontrados</li>
|
||
<li>Erro de rede ao carregar dados</li>
|
||
<li>Formato de dados incompatível</li>
|
||
</ul>
|
||
<p style="font-size: 13px; color: var(--color-text-secondary);">Erro: ${error.message}</p>
|
||
<button class="btn btn-primary" onclick="location.reload()">🔄 Recarregar Página</button>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Export AI recommendation as PDF report
|
||
*/
|
||
async function exportAIRecommendation() {
|
||
const steel = document.getElementById('ai-steel')?.value;
|
||
const environment = document.getElementById('ai-environment')?.value;
|
||
|
||
if (!steel || !environment) {
|
||
alert('⚠️ Gere uma recomendação primeiro!');
|
||
return;
|
||
}
|
||
|
||
// Show loading toast
|
||
const loadingToast = document.createElement('div');
|
||
loadingToast.textContent = '⏳ Gerando PDF...';
|
||
loadingToast.style.cssText = `
|
||
position: fixed;
|
||
bottom: 24px;
|
||
right: 24px;
|
||
padding: 16px 24px;
|
||
background: var(--color-primary);
|
||
color: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||
z-index: 10000;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
`;
|
||
document.body.appendChild(loadingToast);
|
||
|
||
try {
|
||
// Get recommendation data from the module
|
||
const {
|
||
loadRelationships,
|
||
getCompleteRecommendation
|
||
} = await import('./js/utils/material-relationships.js');
|
||
|
||
await loadRelationships();
|
||
const recommendation = getCompleteRecommendation(steel, environment);
|
||
|
||
console.log('📊 Dados da recomendação:', recommendation);
|
||
|
||
// Extract data with correct field names
|
||
const w = recommendation.welding || {};
|
||
const p = recommendation.painting || {};
|
||
|
||
// Generate HTML for PDF
|
||
const htmlContent = `
|
||
<!DOCTYPE html>
|
||
<html lang="pt-BR">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Relatório de Recomendação</title>
|
||
<style>
|
||
@page { size: A4; margin: 1.5cm; }
|
||
body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #ffffff; color: #333; line-height: 1.35; font-size: 10pt; }
|
||
.container { width: 100%; max-width: 100%; margin: 0; padding: 0; background-color: #ffffff; }
|
||
h1 { text-align: center; color: #0d47a1; border-bottom: 2px solid #0d47a1; padding-bottom: 5px; margin-bottom: 15px; font-size: 16pt; }
|
||
h2 { font-size: 13pt; color: #1565c0; border-bottom: 1px solid #eee; padding-bottom: 4px; margin-top: 15px; margin-bottom: 10px; page-break-after: avoid; }
|
||
h3 { font-size: 11pt; color: #333; margin-top: 10px; margin-bottom: 5px; page-break-after: avoid; }
|
||
.data-group { background-color: #fdfdfd; border: 1px solid #eaeaea; border-radius: 5px; padding: 10px; margin-bottom: 10px; page-break-inside: avoid; }
|
||
.data-item { display: flex; flex-wrap: wrap; margin-bottom: 4px; padding-bottom: 4px; border-bottom: 1px dashed #f0f0f0; }
|
||
.data-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
|
||
.data-label { font-weight: bold; color: #555; flex-basis: 180px; flex-grow: 0; }
|
||
.data-value { flex-basis: 300px; flex-grow: 1; color: #222; }
|
||
.paint-table { width: 100%; border-collapse: collapse; margin-top: 5px; table-layout: fixed; page-break-inside: avoid; }
|
||
.paint-table th, .paint-table td { border: 1px solid #ccc; padding: 5px; text-align: left; vertical-align: top; }
|
||
.paint-table th { background-color: #e3f2fd; color: #0d47a1; font-size: 9pt; text-transform: uppercase; text-align: center; }
|
||
.paint-table td strong { font-size: 10pt; color: #333; display: block; margin-bottom: 2px; }
|
||
.paint-table td span { font-size: 8pt; color: #666; display: block; }
|
||
.observations { background-color: #fffde7; border: 1px solid #fff9c4; border-left: 5px solid #fbc02d; padding: 8px 12px; margin-top: 10px; border-radius: 5px; font-style: italic; page-break-inside: avoid; }
|
||
.observations .data-label { font-weight: bold; color: #665c1e; }
|
||
.header-info { text-align: center; color: #666; font-size: 9pt; margin-bottom: 20px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>Relatório de Recomendação Inteligente</h1>
|
||
<div class="header-info">
|
||
SteelBase v7.5 | Data: ${new Date().toLocaleDateString('pt-BR')} | Hora: ${new Date().toLocaleTimeString('pt-BR')}
|
||
</div>
|
||
|
||
<!-- Seção 1: Seleção de Requisitos -->
|
||
<h2>Seleção de Requisitos</h2>
|
||
<div class="data-group">
|
||
<div class="data-item">
|
||
<span class="data-label">Aço Estrutural:</span>
|
||
<span class="data-value">${steel}</span>
|
||
</div>
|
||
<div class="data-item">
|
||
<span class="data-label">Ambiente Corrosivo:</span>
|
||
<span class="data-value">${environment}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Seção 2: Resumo da Recomendação -->
|
||
<h2>Resumo da Recomendação</h2>
|
||
<div class="data-group">
|
||
<div class="data-item">
|
||
<span class="data-label">Aço Selecionado:</span>
|
||
<span class="data-value">${steel}</span>
|
||
</div>
|
||
<div class="data-item">
|
||
<span class="data-label">Ambiente:</span>
|
||
<span class="data-value">${environment}</span>
|
||
</div>
|
||
<div class="data-item">
|
||
<span class="data-label">Soldagem:</span>
|
||
<span class="data-value">${recommendation.hasWelding ? 'Disponível' : 'Não encontrada'}</span>
|
||
</div>
|
||
<div class="data-item">
|
||
<span class="data-label">Pintura:</span>
|
||
<span class="data-value">${recommendation.hasPainting ? 'Disponível' : 'Não encontrada'}</span>
|
||
</div>
|
||
<div class="data-item">
|
||
<span class="data-label">Status:</span>
|
||
<span class="data-value" style="color: ${recommendation.isComplete ? '#2e7d32' : '#f57c00'}; font-weight: bold;">
|
||
${recommendation.isComplete ? 'Recomendação completa disponível!' : 'Recomendação parcial'}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Seção 3: Soldagem Recomendada -->
|
||
${w && Object.keys(w).length > 0 ? `
|
||
<h2>Soldagem Recomendada</h2>
|
||
<div class="data-group">
|
||
<h3>Processos</h3>
|
||
${w.Processo_Soldagem_1 ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Processo 1:</span>
|
||
<span class="data-value">${w.Processo_Soldagem_1} (Eletrodo: ${w.Eletrodo_1 || 'N/A'})</span>
|
||
</div>` : ''}
|
||
${w.Processo_Soldagem_2 ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Processo 2:</span>
|
||
<span class="data-value">${w.Processo_Soldagem_2} (Arame: ${w.Arame_2 || 'N/A'}, Gás: ${w['Gás_Proteção'] || 'N/A'})</span>
|
||
</div>` : ''}
|
||
${w.Processo_Soldagem_3 ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Processo 3:</span>
|
||
<span class="data-value">${w.Processo_Soldagem_3} (Arame/Fluxo: ${w.Arame_Fluxo_3 || 'N/A'})</span>
|
||
</div>` : ''}
|
||
|
||
<h3>Parâmetros e Normas</h3>
|
||
${w.CEV ? `
|
||
<div class="data-item">
|
||
<span class="data-label">CEV:</span>
|
||
<span class="data-value">${w.CEV}</span>
|
||
</div>` : ''}
|
||
${w['Pré_Aquecimento'] ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Pré-aquecimento:</span>
|
||
<span class="data-value">${w['Pré_Aquecimento']}</span>
|
||
</div>` : ''}
|
||
${w.Norma_Soldagem ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Norma:</span>
|
||
<span class="data-value">${w.Norma_Soldagem}</span>
|
||
</div>` : ''}
|
||
${w.Ensaios_NDT ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Ensaios:</span>
|
||
<span class="data-value">${w.Ensaios_NDT}</span>
|
||
</div>` : ''}
|
||
${w['Observações'] ? `
|
||
<div class="observations">
|
||
<div class="data-item">
|
||
<span class="data-label">Observações:</span>
|
||
<span class="data-value">${w['Observações']}</span>
|
||
</div>
|
||
</div>` : ''}
|
||
</div>
|
||
` : '<h2>Soldagem Recomendada</h2><div class="data-group"><p>Dados de soldagem não disponíveis para este aço.</p></div>'}
|
||
|
||
<!-- Seção 4: Pintura Recomendada -->
|
||
${p && Object.keys(p).length > 0 ? `
|
||
<h2>Pintura Recomendada</h2>
|
||
<div class="data-group">
|
||
<h3>Condições e Preparação</h3>
|
||
${p.Ambiente_Corrosivo ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Ambiente:</span>
|
||
<span class="data-value">${p.Ambiente_Corrosivo}</span>
|
||
</div>` : ''}
|
||
${p['Vida_Útil_Esperada'] ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Vida útil:</span>
|
||
<span class="data-value">${p['Vida_Útil_Esperada']}</span>
|
||
</div>` : ''}
|
||
${p['Preparação_Superfície'] ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Preparação:</span>
|
||
<span class="data-value">${p['Preparação_Superfície']}</span>
|
||
</div>` : ''}
|
||
${p.Rugosidade ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Rugosidade:</span>
|
||
<span class="data-value">${p.Rugosidade}</span>
|
||
</div>` : ''}
|
||
${p.DFT_Total ? `
|
||
<div class="data-item">
|
||
<span class="data-label">DFT Total:</span>
|
||
<span class="data-value">${p.DFT_Total}</span>
|
||
</div>` : ''}
|
||
${p['Custo_Estimado_$/m²'] ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Custo Estimado:</span>
|
||
<span class="data-value">${p['Custo_Estimado_$/m²']}</span>
|
||
</div>` : ''}
|
||
|
||
<h3>Sistema de Pintura (3 camadas)</h3>
|
||
<table class="paint-table">
|
||
<thead>
|
||
<tr>
|
||
<th>PRIMER</th>
|
||
<th>INTERMEDIÁRIA</th>
|
||
<th>ACABAMENTO</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<strong>${p.Primer || 'N/A'}</strong><br>
|
||
<span>${p.DFT_Primer || 'N/A'}</span><br>
|
||
<span style="font-size: 7pt;">${p.Primer_Descrição || ''}</span>
|
||
</td>
|
||
<td>
|
||
<strong>${p['Intermediária'] || 'N/A'}</strong><br>
|
||
<span>${p['DFT_Intermediária'] || 'N/A'}</span><br>
|
||
<span style="font-size: 7pt;">${p['Intermediária_Descrição'] || ''}</span>
|
||
</td>
|
||
<td>
|
||
<strong>${p.Acabamento || 'N/A'}</strong><br>
|
||
<span>${p.DFT_Acabamento || 'N/A'}</span><br>
|
||
<span style="font-size: 7pt;">${p['Acabamento_Descrição'] || ''}</span>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h3 style="margin-top: 10px;">Normas e Ensaios</h3>
|
||
${p.Norma_Pintura ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Norma:</span>
|
||
<span class="data-value">${p.Norma_Pintura}</span>
|
||
</div>` : ''}
|
||
${p.Ensaios_Qualidade ? `
|
||
<div class="data-item">
|
||
<span class="data-label">Ensaios:</span>
|
||
<span class="data-value">${p.Ensaios_Qualidade}</span>
|
||
</div>` : ''}
|
||
${p['Observações'] ? `
|
||
<div class="observations">
|
||
<div class="data-item">
|
||
<span class="data-label">Observações:</span>
|
||
<span class="data-value">${p['Observações']}</span>
|
||
</div>
|
||
</div>` : ''}
|
||
</div>
|
||
` : '<h2>Pintura Recomendada</h2><div class="data-group"><p>Dados de pintura não disponíveis para este aço/ambiente.</p></div>'}
|
||
|
||
<!-- Rodapé -->
|
||
<div style="margin-top: 30px; padding-top: 10px; border-top: 1px solid #ccc; text-align: center; font-size: 8pt; color: #666;">
|
||
<p>Relatório gerado automaticamente pelo SteelBase v7.5</p>
|
||
<p>Este relatório é baseado em dados técnicos da base de conhecimento</p>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|
||
`;
|
||
|
||
// Create a hidden iframe to print
|
||
const printFrame = document.createElement('iframe');
|
||
printFrame.style.position = 'fixed';
|
||
printFrame.style.right = '0';
|
||
printFrame.style.bottom = '0';
|
||
printFrame.style.width = '0';
|
||
printFrame.style.height = '0';
|
||
printFrame.style.border = '0';
|
||
document.body.appendChild(printFrame);
|
||
|
||
const doc = printFrame.contentWindow.document;
|
||
doc.open();
|
||
// Inserir logotipo se configurado
|
||
const cfg = window.adminConfigManager ? window.adminConfigManager.getConfig() : null;
|
||
let logoBlock = '';
|
||
if (cfg && cfg.branding && cfg.branding.logo) {
|
||
logoBlock = `<div style="text-align:center; margin-bottom: 8px;"><img src="${cfg.branding.logo}" alt="Logo" style="max-height:48px; object-fit:contain;"></div>`;
|
||
}
|
||
const htmlWithLogo = htmlContent.replace('<h1>Relatório de Recomendação Inteligente</h1>', `${logoBlock}<h1>Relatório de Recomendação Inteligente</h1>`);
|
||
doc.write(htmlWithLogo);
|
||
doc.close();
|
||
|
||
// Wait for content to load
|
||
await new Promise(resolve => setTimeout(resolve, 500));
|
||
|
||
// Trigger print dialog (user can save as PDF)
|
||
printFrame.contentWindow.print();
|
||
|
||
// Clean up
|
||
setTimeout(() => {
|
||
document.body.removeChild(printFrame);
|
||
}, 1000);
|
||
|
||
// Remove loading toast
|
||
loadingToast.remove();
|
||
|
||
// Show success message
|
||
const toast = document.createElement('div');
|
||
toast.textContent = '📄 Relatório pronto! Use "Salvar como PDF" na janela de impressão';
|
||
toast.style.cssText = `
|
||
position: fixed;
|
||
bottom: 24px;
|
||
right: 24px;
|
||
padding: 16px 24px;
|
||
background: var(--color-success);
|
||
color: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||
z-index: 10000;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
`;
|
||
|
||
document.body.appendChild(toast);
|
||
setTimeout(() => toast.remove(), 5000);
|
||
|
||
} catch (error) {
|
||
console.error('Erro ao gerar PDF:', error);
|
||
loadingToast.remove();
|
||
alert('❌ Erro ao gerar PDF. Verifique o console para mais detalhes.');
|
||
}
|
||
}
|
||
|
||
// Tab switching function
|
||
function switchTab(tabIndex) {
|
||
document.querySelectorAll('.tab-btn').forEach((btn, i) => {
|
||
btn.classList.toggle('active', i === tabIndex);
|
||
});
|
||
document.querySelectorAll('.tab-content').forEach((content, i) => {
|
||
content.classList.toggle('active', i === tabIndex);
|
||
});
|
||
|
||
// Update help button for the active tab (for parafusos section)
|
||
const tabIds = ['parafusos-cisalhamento', 'parafusos-esmagamento', 'parafusos-bloco', 'layout', 'parafuso-vs-solda'];
|
||
if (tabIds[tabIndex]) {
|
||
addHelpButton(tabIds[tabIndex]);
|
||
}
|
||
}
|
||
|
||
// Bolt database with capacities
|
||
const boltDatabase = {
|
||
a325: {fy: 400, fu: 635, capacidade: {12: 5.2, 16: 9.2, 20: 14.4, 24: 20.7}, custo: 8},
|
||
a490: {fy: 565, fu: 895, capacidade: {12: 7.3, 16: 13.0, 20: 20.3, 24: 29.2}, custo: 15},
|
||
iso88: {fy: 640, fu: 800, capacidade: {12: 6.1, 16: 10.8, 20: 16.8, 24: 24.2}, custo: 5},
|
||
iso109: {fy: 900, fu: 1000, capacidade: {12: 8.7, 16: 15.5, 20: 24.2, 24: 34.8}, custo: 20}
|
||
};
|
||
|
||
const steelBearing = {
|
||
a36: {fy: 250, fu: 400},
|
||
a572: {fy: 345, fu: 450},
|
||
s235: {fy: 235, fu: 360},
|
||
s355: {fy: 355, fu: 490}
|
||
};
|
||
|
||
// Tab 1: Cisalhamento (Shear)
|
||
function calcularCisalhamento() {
|
||
const getVal = (id, fallback = 0) => {
|
||
const el = document.getElementById(id);
|
||
return el ? (id.includes('qty') || id.includes('planes') ? parseInt(el.value) : parseFloat(el.value)) : fallback;
|
||
};
|
||
|
||
const boltType = document.getElementById('bolt-type')?.value || 'a325';
|
||
const d = getVal('bolt-d');
|
||
const qty = getVal('bolt-qty', 1);
|
||
const planes = getVal('bolt-planes', 1);
|
||
const force = getVal('bolt-force');
|
||
|
||
if (!d || d <= 0 || d > 36) {
|
||
const resultEl = document.getElementById('bolt-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Diâmetro do parafuso inválido. Use valores entre 1mm e 36mm.</div>';
|
||
return;
|
||
}
|
||
if (!boltDatabase[boltType]?.capacidade[d]) {
|
||
const resultEl = document.getElementById('bolt-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Diâmetro não disponível para o tipo de parafuso selecionado.</div>';
|
||
return;
|
||
}
|
||
if (qty < 1 || qty > 100) {
|
||
const resultEl = document.getElementById('bolt-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Quantidade de parafusos inválida. Use valores entre 1 e 100.</div>';
|
||
return;
|
||
}
|
||
if (!force || force <= 0) {
|
||
const resultEl = document.getElementById('bolt-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Força aplicada inválida. Insira um valor maior que 0.</div>';
|
||
return;
|
||
}
|
||
|
||
const bolt = boltDatabase[boltType];
|
||
const area = Math.PI * Math.pow(d / 2, 2);
|
||
const Fv = bolt.capacidade[d] * planes;
|
||
const capacity = Fv * qty;
|
||
const utilization = (force / capacity) * 100;
|
||
|
||
let alertClass = 'alert-success';
|
||
let status = '✅ ATENDE';
|
||
let recommendation = 'Capacidade adequada para a força aplicada';
|
||
|
||
if (utilization > 100) {
|
||
alertClass = 'alert-error';
|
||
status = '⚠️ NÃO ATENDE (Insuficiente)';
|
||
const qtyNeeded = Math.ceil(force / Fv);
|
||
recommendation = `Aumentar para ${qtyNeeded} parafusos ou usar tipo mais resistente`;
|
||
} else if (utilization > 85) {
|
||
alertClass = 'alert-warning';
|
||
status = '⚠️ ATENÇÃO (Utilização elevada)';
|
||
recommendation = 'Considere aumentar a quantidade de parafusos';
|
||
}
|
||
|
||
// Alternativas
|
||
let alternatives = '';
|
||
Object.keys(boltDatabase).forEach(type => {
|
||
if (type !== boltType) {
|
||
const altCap = boltDatabase[type].capacidade[d] * planes * qty;
|
||
const altUtil = (force / altCap) * 100;
|
||
if (altUtil < 100) {
|
||
alternatives += `<li>• ${qty} parafusos ${type.toUpperCase()} → ${altCap.toFixed(1)} kN ✅</li>`;
|
||
}
|
||
}
|
||
});
|
||
|
||
// Reference table
|
||
const refTable = `
|
||
<table style="width: 100%; margin-top: 20px; font-size: 12px;">
|
||
<thead>
|
||
<tr style="background: var(--color-primary); color: white;">
|
||
<th style="padding: 8px;">Tipo</th>
|
||
<th>Ø12</th>
|
||
<th>Ø16</th>
|
||
<th>Ø20</th>
|
||
<th>Ø24</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td><strong>A325</strong></td><td>5.2</td><td>9.2</td><td>14.4</td><td>20.7</td></tr>
|
||
<tr><td><strong>A490</strong></td><td>7.3</td><td>13.0</td><td>20.3</td><td>29.2</td></tr>
|
||
<tr><td><strong>ISO88</strong></td><td>6.1</td><td>10.8</td><td>16.8</td><td>24.2</td></tr>
|
||
<tr><td><strong>ISO109</strong></td><td>8.7</td><td>15.5</td><td>24.2</td><td>34.8</td></tr>
|
||
</tbody>
|
||
</table>
|
||
`;
|
||
|
||
document.getElementById('bolt-shear-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-primary);">
|
||
<div class="result-title">✅ CISALHAMENTO - RESULTADO</div>
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Capacidade por Parafuso</div>
|
||
<div class="result-value">${Fv.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Capacidade Total (${qty}×${boltType.toUpperCase()})</div>
|
||
<div class="result-value">${capacity.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Força Aplicada</div>
|
||
<div class="result-value">${force.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Utilização</div>
|
||
<div class="result-value" style="color: ${utilization > 100 ? 'var(--color-error)' : utilization > 85 ? 'var(--color-warning)' : 'var(--color-success)'}">${utilization.toFixed(0)}%</div>
|
||
</div>
|
||
</div>
|
||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||
<strong>STATUS: ${status}</strong><br>
|
||
Recomendação: ${recommendation}
|
||
</div>
|
||
${alternatives ? `
|
||
<div style="margin-top: 16px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>Alternativas Sugeridas:</strong>
|
||
<ul style="margin: 8px 0 0 20px;">${alternatives}</ul>
|
||
</div>
|
||
` : ''}
|
||
<div style="margin-top: 20px;">
|
||
<strong>Tabela de Referência (kN por parafuso, plano simples):</strong>
|
||
${refTable}
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Cisalhamento', `${qty} parafusos Ø${d}mm ${boltType.toUpperCase()}, Util: ${utilization.toFixed(0)}%`);
|
||
}
|
||
|
||
// Tab 2: Esmagamento (Bearing)
|
||
function calcularEsmagamento() {
|
||
const d = parseFloat(document.getElementById('bear-d').value);
|
||
const thickness = parseFloat(document.getElementById('bear-thickness').value);
|
||
const qty = parseInt(document.getElementById('bear-qty').value);
|
||
const steelType = document.getElementById('bear-steel').value;
|
||
const edge = parseFloat(document.getElementById('bear-edge').value);
|
||
const spacing = parseFloat(document.getElementById('bear-spacing').value);
|
||
|
||
const steel = steelBearing[steelType];
|
||
const fu = steel.fu;
|
||
|
||
// Location factor
|
||
let factor = 1.0;
|
||
if (edge < 1.5 * d) {
|
||
factor = 0.7;
|
||
}
|
||
|
||
// Bearing capacity
|
||
const Abc = d * thickness;
|
||
const Fb = 1.2 * fu * d * thickness * factor / 1000;
|
||
const FbTotal = Fb * qty;
|
||
|
||
// Compare with shear (assuming A325 Ø16)
|
||
const shearCap = 9.2 * 2 * qty;
|
||
const critical = FbTotal < shearCap ? 'ESMAGAMENTO' : 'CISALHAMENTO';
|
||
|
||
let status = '✅ OK';
|
||
let alertClass = 'alert-success';
|
||
let recommendation = 'Capacidade de esmagamento adequada';
|
||
|
||
if (factor < 1.0) {
|
||
alertClass = 'alert-warning';
|
||
status = '⚠️ ATENÇÃO';
|
||
recommendation = 'Distância de borda reduzida (fator 0.7 aplicado)';
|
||
}
|
||
|
||
document.getElementById('bolt-bearing-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-3); border-left: 4px solid #16a34a;">
|
||
<div class="result-title">✅ ESMAGAMENTO - RESULTADO</div>
|
||
<div style="margin-bottom: 20px;">
|
||
<p><strong>Espessura da Chapa:</strong> ${thickness} mm</p>
|
||
<p><strong>Diâmetro Parafuso:</strong> ${d} mm</p>
|
||
<p><strong>Aço da Chapa:</strong> ${steelType.toUpperCase()} (fu=${fu} MPa)</p>
|
||
</div>
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Área de Contato</div>
|
||
<div class="result-value">${Abc.toFixed(0)} mm²</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Fator Localização</div>
|
||
<div class="result-value">${factor.toFixed(1)} ${factor === 1.0 ? '✓' : '⚠️'}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Capacidade por Parafuso</div>
|
||
<div class="result-value">${Fb.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Capacidade Total (${qty} un)</div>
|
||
<div class="result-value">${FbTotal.toFixed(1)} kN</div>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>Verificação contra Cisalhamento:</strong><br>
|
||
Cisalhamento: ${shearCap.toFixed(1)} kN<br>
|
||
Esmagamento: ${FbTotal.toFixed(1)} kN<br>
|
||
<strong style="color: var(--color-warning);">CONTROLA O ${critical}</strong>
|
||
</div>
|
||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||
<strong>STATUS: ${status}</strong><br>
|
||
${recommendation}
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Esmagamento', `Ø${d}mm, esp=${thickness}mm, Cap=${FbTotal.toFixed(1)}kN`);
|
||
}
|
||
|
||
// Tab 3: Ruptura em Bloco
|
||
function calcularBlocoRuptura() {
|
||
const d = parseFloat(document.getElementById('block-d').value);
|
||
const hQty = parseInt(document.getElementById('block-h-qty').value);
|
||
const vQty = parseInt(document.getElementById('block-v-qty').value);
|
||
const hSpace = parseFloat(document.getElementById('block-h-space').value);
|
||
const edgeLeft = parseFloat(document.getElementById('block-edge-left').value);
|
||
const edgeTop = parseFloat(document.getElementById('block-edge-top').value);
|
||
const edgeRight = parseFloat(document.getElementById('block-edge-right').value);
|
||
const thickness = parseFloat(document.getElementById('block-thickness').value);
|
||
const steelType = document.getElementById('block-steel').value;
|
||
const force = parseFloat(document.getElementById('block-force').value);
|
||
|
||
const steel = steelBearing[steelType];
|
||
const fu = steel.fu;
|
||
const dHole = d + 2;
|
||
|
||
// Net tension area
|
||
const Ant = (edgeLeft + edgeRight) * thickness - (1 * dHole * thickness);
|
||
|
||
// Net shear area (vertical length)
|
||
const vertLength = (vQty - 1) * hSpace;
|
||
const Agv = vertLength * thickness - ((vQty - 1) * dHole * thickness);
|
||
|
||
// Block shear capacity (AISC 360-16)
|
||
const Rbs = (0.6 * fu * Agv + 0.3 * fu * Ant) / 1000;
|
||
|
||
const utilization = (force / Rbs) * 100;
|
||
|
||
let status = '✅ ATENDE';
|
||
let alertClass = 'alert-success';
|
||
let recommendation = 'Resistência ao bloco adequada';
|
||
|
||
if (utilization > 100) {
|
||
alertClass = 'alert-error';
|
||
status = '⚠️ NÃO ATENDE';
|
||
recommendation = 'Aumentar distância de borda ou espessura da chapa';
|
||
} else if (utilization > 85) {
|
||
alertClass = 'alert-warning';
|
||
status = '⚠️ ATENÇÃO';
|
||
recommendation = 'Utilização elevada, considere reforço';
|
||
}
|
||
|
||
document.getElementById('bolt-block-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-6); border-left: 4px solid var(--color-warning);">
|
||
<div class="result-title">✅ RUPTURA EM BLOCO - RESULTADO</div>
|
||
<div style="margin-bottom: 20px;">
|
||
<p><strong>Área Líquida Tração (Ant):</strong> ${Ant.toFixed(0)} mm²</p>
|
||
<p><strong>Área Líquida Cisalhamento (Agv):</strong> ${Agv.toFixed(0)} mm²</p>
|
||
</div>
|
||
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>Resistência Ruptura (AISC 360-16):</strong><br>
|
||
Rbs = 0.6×fu×Agv + 0.3×fu×Ant<br>
|
||
Rbs = 0.6×${fu}×${Agv.toFixed(0)} + 0.3×${fu}×${Ant.toFixed(0)}<br>
|
||
Rbs = ${(0.6 * fu * Agv / 1000).toFixed(1)} + ${(0.3 * fu * Ant / 1000).toFixed(1)} = <strong>${Rbs.toFixed(1)} kN</strong>
|
||
</div>
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Resistência Bloco</div>
|
||
<div class="result-value">${Rbs.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Força Aplicada</div>
|
||
<div class="result-value">${force.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Utilização</div>
|
||
<div class="result-value" style="color: ${utilization > 100 ? 'var(--color-error)' : utilization > 85 ? 'var(--color-warning)' : 'var(--color-success)'}">${utilization.toFixed(0)}%</div>
|
||
</div>
|
||
</div>
|
||
<div class="alert ${alertClass}" style="margin-top: 16px;">
|
||
<strong>STATUS: ${status}</strong><br>
|
||
${recommendation}
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Bloco Ruptura', `Rbs=${Rbs.toFixed(1)}kN, Util=${utilization.toFixed(0)}%`);
|
||
}
|
||
|
||
// Tab 4: Layout de Furação Completo
|
||
function verificarLayoutCompleto() {
|
||
const d = parseFloat(document.getElementById('layout2-d').value);
|
||
const edgeLeft = parseFloat(document.getElementById('layout2-edge-left').value);
|
||
const edgeRight = parseFloat(document.getElementById('layout2-edge-right').value);
|
||
const edgeTop = parseFloat(document.getElementById('layout2-edge-top').value);
|
||
const edgeBottom = parseFloat(document.getElementById('layout2-edge-bottom').value);
|
||
const hSpace = parseFloat(document.getElementById('layout2-h-space').value);
|
||
const vSpace = parseFloat(document.getElementById('layout2-v-space').value);
|
||
const thickness = parseFloat(document.getElementById('layout2-thickness').value);
|
||
|
||
// NBR 8800 limits
|
||
const minEdge = 1.5 * d;
|
||
const maxEdge = Math.min(12 * thickness, 150);
|
||
const minSpacing = 2.67 * d;
|
||
const maxSpacing = 300;
|
||
|
||
// Check each parameter
|
||
const checks = [
|
||
{name: 'Esquerda', value: edgeLeft, min: minEdge, max: maxEdge},
|
||
{name: 'Direita', value: edgeRight, min: minEdge, max: maxEdge},
|
||
{name: 'Topo', value: edgeTop, min: minEdge, max: maxEdge},
|
||
{name: 'Base', value: edgeBottom, min: minEdge, max: maxEdge},
|
||
{name: 'Horizontal', value: hSpace, min: minSpacing, max: maxSpacing, isSpacing: true},
|
||
{name: 'Vertical', value: vSpace, min: minSpacing, max: maxSpacing, isSpacing: true}
|
||
];
|
||
|
||
let allConform = true;
|
||
let checksList = '';
|
||
|
||
checks.forEach(check => {
|
||
let status = '✅ CONFORME';
|
||
let statusClass = 'color: var(--color-success);';
|
||
let detail = `(mín ${check.min.toFixed(1)}mm)`;
|
||
|
||
if (check.value < check.min) {
|
||
status = '❌ ABAIXO DO MÍNIMO';
|
||
statusClass = 'color: var(--color-error);';
|
||
detail = `(mín ${check.min.toFixed(1)}mm)`;
|
||
allConform = false;
|
||
} else if (check.value > check.max) {
|
||
status = '⚠️ ACIMA DO MÁXIMO';
|
||
statusClass = 'color: var(--color-warning);';
|
||
detail = `(máx ${check.max.toFixed(0)}mm)`;
|
||
allConform = false;
|
||
} else if (!check.isSpacing) {
|
||
detail = `(${check.min.toFixed(1)}-${check.max.toFixed(0)}mm)`;
|
||
} else {
|
||
detail = `(${check.min.toFixed(1)}-${check.max}mm)`;
|
||
}
|
||
|
||
checksList += `
|
||
<tr style="border-bottom: 1px solid var(--color-border);">
|
||
<td style="padding: 10px;"><strong>${check.name}</strong></td>
|
||
<td style="padding: 10px;">${check.value} mm</td>
|
||
<td style="padding: 10px; ${statusClass}">${status}</td>
|
||
<td style="padding: 10px; color: var(--color-text-secondary);">${detail}</td>
|
||
</tr>
|
||
`;
|
||
});
|
||
|
||
// Simple layout drawing
|
||
const drawing = `
|
||
<div style="margin-top: 20px; padding: 20px; background: var(--color-surface); border-radius: 12px; font-family: monospace;">
|
||
<div style="text-align: center; margin-bottom: 16px;"><strong>DESENHO DE LAYOUT</strong></div>
|
||
<pre style="background: var(--color-background); padding: 16px; border-radius: 8px; overflow-x: auto;">
|
||
┌───────────────────────┐
|
||
│ ${edgeTop} ${edgeTop} ${edgeTop} │
|
||
│ ●─────●─────● │ ${edgeRight}
|
||
│ │ ${hSpace} │ ${hSpace} │ │
|
||
│ ●─────●─────● │ ${vSpace}
|
||
│ │ │ │ │
|
||
│ ●─────●─────● │ ${vSpace}
|
||
│ ${edgeLeft} ${edgeLeft} ${edgeLeft} │
|
||
└───────────────────────┘
|
||
${edgeBottom} ${edgeBottom} ${edgeBottom}
|
||
</pre>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('layout-full-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-5); border-left: 4px solid #a855f7;">
|
||
<div class="result-title">✅ LAYOUT DE FURAÇÃO - VERIFICAÇÃO</div>
|
||
<div style="margin-bottom: 20px;">
|
||
<p><strong>Diâmetro do Parafuso:</strong> ${d} mm</p>
|
||
<p><strong>Espessura da Chapa:</strong> ${thickness} mm</p>
|
||
</div>
|
||
<table style="width: 100%; border-collapse: collapse;">
|
||
<thead>
|
||
<tr style="background: var(--color-primary); color: white;">
|
||
<th style="padding: 10px; text-align: left;">Parâmetro</th>
|
||
<th style="padding: 10px; text-align: left;">Valor</th>
|
||
<th style="padding: 10px; text-align: left;">Status</th>
|
||
<th style="padding: 10px; text-align: left;">Limites NBR 8800</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
${checksList}
|
||
</tbody>
|
||
</table>
|
||
<div class="alert ${allConform ? 'alert-success' : 'alert-error'}" style="margin-top: 20px;">
|
||
<strong>${allConform ? '✅ 100% CONFORME COM NBR 8800' : '⚠️ AJUSTES NECESSÁRIOS'}</strong><br>
|
||
${allConform ? 'Todos os parâmetros estão dentro dos limites normativos' : 'Alguns parâmetros precisam ser ajustados'}
|
||
</div>
|
||
${drawing}
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Layout Furação', `Ø${d}mm, ${allConform ? 'CONFORME' : 'NÃO CONFORME'}`);
|
||
}
|
||
|
||
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`);
|
||
}
|
||
|
||
// Tab 5: Parafuso vs Solda Completo
|
||
function compararParafusoSoldaCompleto() {
|
||
const force = parseFloat(document.getElementById('comp2-force').value);
|
||
const length = parseFloat(document.getElementById('comp2-length').value);
|
||
const steelType = document.getElementById('comp2-steel').value;
|
||
const boltType = document.getElementById('comp2-bolt-type').value;
|
||
const boltD = parseFloat(document.getElementById('comp2-bolt-d').value);
|
||
|
||
const steel = steelBearing[steelType];
|
||
const bolt = boltDatabase[boltType];
|
||
|
||
// BOLT SOLUTION
|
||
const boltCapacity = bolt.capacidade[boltD] * 2; // 2 planes
|
||
const boltQty = Math.ceil(force / boltCapacity);
|
||
const boltTotalCap = boltCapacity * boltQty;
|
||
const boltMaterialCost = boltQty * bolt.custo;
|
||
const boltTimeMin = boltQty * 5;
|
||
const boltLaborCost = (boltTimeMin / 60) * 30;
|
||
const boltTotalCost = boltMaterialCost + boltLaborCost;
|
||
|
||
// WELD SOLUTION
|
||
const fyWeld = steel.fy * 0.6;
|
||
const weldLeg = (force * 1000) / (0.707 * length * 0.65 * fyWeld);
|
||
const weldLegRounded = Math.max(Math.ceil(weldLeg), 5);
|
||
const weldVolume = (weldLegRounded * weldLegRounded * 0.5 * length) / 1000; // cm³
|
||
const weldMass = (weldVolume / 1000) * 7.85; // kg
|
||
const electrodeKg = weldMass * 1.15 * 1.15; // losses
|
||
const electrodeCost = electrodeKg * 45;
|
||
const weldTimeMin = (length / 1000) * 30; // ~30 min per meter
|
||
const weldLaborCost = (weldTimeMin / 60) * 60;
|
||
const weldTotalCost = electrodeCost + weldLaborCost;
|
||
const weldCapacity = (0.707 * weldLegRounded * length * 0.65 * fyWeld) / 1000;
|
||
|
||
// Comparison
|
||
const cheaper = boltTotalCost < weldTotalCost ? 'PARAFUSO' : 'SOLDA';
|
||
const savings = Math.abs(boltTotalCost - weldTotalCost);
|
||
const timeSaved = Math.abs(boltTimeMin - weldTimeMin);
|
||
|
||
// Chart data
|
||
setTimeout(() => {
|
||
if (currentChart) currentChart.destroy();
|
||
const ctx = document.getElementById('comparison-chart').getContext('2d');
|
||
currentChart = new Chart(ctx, {
|
||
type: 'scatter',
|
||
data: {
|
||
datasets: [
|
||
{
|
||
label: 'Parafuso',
|
||
data: [{x: boltTimeMin, y: boltTotalCost}],
|
||
backgroundColor: '#16a34a',
|
||
pointRadius: 10,
|
||
pointHoverRadius: 12
|
||
},
|
||
{
|
||
label: 'Solda',
|
||
data: [{x: weldTimeMin, y: weldTotalCost}],
|
||
backgroundColor: '#ea580c',
|
||
pointRadius: 10,
|
||
pointHoverRadius: 12
|
||
}
|
||
]
|
||
},
|
||
options: {
|
||
responsive: true,
|
||
maintainAspectRatio: false,
|
||
plugins: {
|
||
title: {
|
||
display: true,
|
||
text: 'Custo vs Tempo de Instalação'
|
||
},
|
||
legend: {
|
||
display: true,
|
||
position: 'top'
|
||
}
|
||
},
|
||
scales: {
|
||
x: {
|
||
title: {
|
||
display: true,
|
||
text: 'Tempo (minutos)'
|
||
}
|
||
},
|
||
y: {
|
||
title: {
|
||
display: true,
|
||
text: 'Custo (R$)'
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}, 100);
|
||
|
||
document.getElementById('comparison-full-result').innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-4); border-left: 4px solid var(--color-error);">
|
||
<div class="result-title">⚖️ COMPARAÇÃO: PARAFUSO vs SOLDA</div>
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin: 20px 0;">
|
||
<div style="padding: 20px; background: var(--color-bg-1); border-radius: 12px; border: 2px solid var(--color-success);">
|
||
<h3 style="color: var(--color-success); margin-bottom: 16px;">🔩 PARAFUSO</h3>
|
||
<table style="width: 100%; font-size: 14px;">
|
||
<tr><td><strong>Tipo:</strong></td><td>${boltType.toUpperCase()} Ø${boltD}mm</td></tr>
|
||
<tr><td><strong>Quantidade:</strong></td><td>${boltQty} un</td></tr>
|
||
<tr><td><strong>Capacidade:</strong></td><td>${boltTotalCap.toFixed(1)} kN</td></tr>
|
||
<tr style="height: 10px;"></tr>
|
||
<tr style="background: var(--color-surface);"><td><strong>Custo Material:</strong></td><td>R$ ${boltMaterialCost.toFixed(2)}</td></tr>
|
||
<tr style="background: var(--color-surface);"><td><strong>Custo Mão de Obra:</strong></td><td>R$ ${boltLaborCost.toFixed(2)}</td></tr>
|
||
<tr><td><strong>Tempo Instalação:</strong></td><td>${boltTimeMin} min</td></tr>
|
||
<tr style="height: 10px;"></tr>
|
||
<tr style="background: var(--color-success); color: white;"><td><strong>CUSTO TOTAL:</strong></td><td><strong>R$ ${boltTotalCost.toFixed(2)}</strong></td></tr>
|
||
</table>
|
||
<div style="margin-top: 16px; padding: 12px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>Vantagens:</strong><br>
|
||
✅ Mais rápido<br>
|
||
✅ Reversível<br>
|
||
✅ Inspeção visual simples
|
||
</div>
|
||
</div>
|
||
<div style="padding: 20px; background: var(--color-bg-6); border-radius: 12px; border: 2px solid var(--color-warning);">
|
||
<h3 style="color: var(--color-warning); margin-bottom: 16px;">🔥 SOLDA</h3>
|
||
<table style="width: 100%; font-size: 14px;">
|
||
<tr><td><strong>Tipo:</strong></td><td>Filete</td></tr>
|
||
<tr><td><strong>Perna:</strong></td><td>${weldLegRounded} mm</td></tr>
|
||
<tr><td><strong>Comprimento:</strong></td><td>${length} mm</td></tr>
|
||
<tr style="height: 10px;"></tr>
|
||
<tr style="background: var(--color-surface);"><td><strong>Custo Material:</strong></td><td>R$ ${electrodeCost.toFixed(2)}</td></tr>
|
||
<tr style="background: var(--color-surface);"><td><strong>Custo Mão de Obra:</strong></td><td>R$ ${weldLaborCost.toFixed(2)}</td></tr>
|
||
<tr><td><strong>Tempo Soldagem:</strong></td><td>${Math.round(weldTimeMin)} min</td></tr>
|
||
<tr style="height: 10px;"></tr>
|
||
<tr style="background: var(--color-warning); color: white;"><td><strong>CUSTO TOTAL:</strong></td><td><strong>R$ ${weldTotalCost.toFixed(2)}</strong></td></tr>
|
||
</table>
|
||
<div style="margin-top: 16px; padding: 12px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>Vantagens:</strong><br>
|
||
✅ Maior rigidez<br>
|
||
✅ Melhor aparência<br>
|
||
✅ Distribuição de tensões
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="alert alert-success" style="margin-top: 20px;">
|
||
<strong>⭐ RECOMENDAÇÃO: ${cheaper}</strong><br>
|
||
Economia de R$ ${savings.toFixed(2)} | ${Math.abs(timeSaved).toFixed(0)} min ${boltTimeMin < weldTimeMin ? 'mais rápido' : 'mais lento'}
|
||
</div>
|
||
<div style="margin-top: 20px;">
|
||
<strong>📊 Gráfico Comparativo:</strong>
|
||
<div class="chart-container" style="height: 300px; margin-top: 10px;">
|
||
<canvas id="comparison-chart"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
addToHistory('Parafuso vs Solda', `${cheaper} mais econômico (R$${savings.toFixed(2)})`);
|
||
|
||
// Add button to send recommended option to budget
|
||
const resultDiv = document.getElementById('comparison-full-result');
|
||
const existingButton = resultDiv.querySelector('.add-to-budget-btn');
|
||
if (!existingButton && cheaper === 'PARAFUSO') {
|
||
const button = document.createElement('button');
|
||
button.className = 'btn btn-success add-to-budget-btn';
|
||
button.style.marginTop = '16px';
|
||
button.textContent = '💰 Adicionar Parafusos ao Orçamento';
|
||
button.onclick = () => addBoltsToOrcamento(boltQty, boltType, boltD);
|
||
resultDiv.querySelector('.result-box').appendChild(button);
|
||
}
|
||
}
|
||
|
||
function addBoltsToOrcamento(qty, type, diameter) {
|
||
showSection('orcamento');
|
||
|
||
setTimeout(() => {
|
||
document.getElementById('budget-category').value = 'consumivel';
|
||
updateBudgetTypeOptions();
|
||
|
||
setTimeout(() => {
|
||
document.getElementById('budget-type').value = 'parafusos';
|
||
updateBudgetSpecOptions();
|
||
|
||
setTimeout(() => {
|
||
document.getElementById('budget-qty').value = qty;
|
||
updateBudgetTotal();
|
||
|
||
alert(`✅ Parafusos transferidos!\n\n${qty} parafusos ${type.toUpperCase()} M${diameter}\n\nSelecione na lista e adicione.`);
|
||
}, 200);
|
||
}, 200);
|
||
}, 300);
|
||
}
|
||
|
||
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;
|
||
|
||
const boltCapacity = 60;
|
||
const boltQty = Math.ceil(force / boltCapacity);
|
||
const boltCost = boltQty * 15;
|
||
|
||
const fyWeld = fy * 0.6;
|
||
const weldLeg = (force * 1000) / (0.707 * length * 0.65 * fyWeld);
|
||
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`);
|
||
}
|
||
|
||
// ========================================
|
||
// WELDING PROCESS TO CONSUMABLES MAPPING
|
||
// ========================================
|
||
|
||
const processoConsumiveisMap = {
|
||
smaw: {
|
||
nome: 'SMAW (Eletrodo Revestido)',
|
||
consumiveis: ['e7018', 'e6013', 'e8018', 'e7016', 'e8016'],
|
||
defaultConsumivel: 'e7018'
|
||
},
|
||
gmaw: {
|
||
nome: 'GMAW (MIG/MAG)',
|
||
consumiveis: ['er70s2', 'er70s6'],
|
||
defaultConsumivel: 'er70s6'
|
||
},
|
||
fcaw: {
|
||
nome: 'FCAW (Arame Tubular)',
|
||
consumiveis: ['er70s2', 'er70s6'],
|
||
defaultConsumivel: 'er70s6'
|
||
},
|
||
gtaw: {
|
||
nome: 'GTAW (TIG)',
|
||
consumiveis: ['er70s2', 'er70s6', 'er4043', 'er5356'],
|
||
defaultConsumivel: 'er70s2'
|
||
},
|
||
saw: {
|
||
nome: 'SAW (Soldagem Submersa)',
|
||
consumiveis: ['er70s2', 'er70s6'],
|
||
defaultConsumivel: 'er70s6'
|
||
},
|
||
esw: {
|
||
nome: 'ESW (Soldagem por Escória)',
|
||
consumiveis: ['er70s2', 'er70s6'],
|
||
defaultConsumivel: 'er70s6'
|
||
}
|
||
};
|
||
|
||
// ========================================
|
||
// WELDING DATABASE
|
||
// ========================================
|
||
|
||
const weldingElectrodes = {
|
||
e7018: {
|
||
nome: 'E7018',
|
||
tipo: 'Básico',
|
||
processo: 'SMAW',
|
||
resistencia_tracao_min: 485,
|
||
resistencia_tracao_max: 620,
|
||
limite_escoamento: 345,
|
||
alongamento: 17,
|
||
charpy: 47,
|
||
posicoes: 'Todas (1F, 2F, 3F, 4F)',
|
||
corrente_min: 100,
|
||
corrente_max: 180,
|
||
voltagem_min: 24,
|
||
voltagem_max: 28,
|
||
rendimento: 0.68,
|
||
taxa_deposicao: 3.5,
|
||
custo_kg: 45,
|
||
diametros: [2.0, 2.4, 3.2, 4.0]
|
||
},
|
||
e6013: {
|
||
nome: 'E6013',
|
||
tipo: 'Rutílico',
|
||
processo: 'SMAW',
|
||
resistencia_tracao_min: 420,
|
||
resistencia_tracao_max: 550,
|
||
limite_escoamento: 300,
|
||
alongamento: 22,
|
||
charpy: 27,
|
||
posicoes: 'Todas',
|
||
corrente_min: 70,
|
||
corrente_max: 140,
|
||
voltagem_min: 22,
|
||
voltagem_max: 26,
|
||
rendimento: 0.62,
|
||
taxa_deposicao: 2.8,
|
||
custo_kg: 28,
|
||
diametros: [2.0, 2.4, 3.2, 4.0]
|
||
},
|
||
e8018: {
|
||
nome: 'E8018',
|
||
tipo: 'Básico Alta Resistência',
|
||
processo: 'SMAW',
|
||
resistencia_tracao_min: 550,
|
||
resistencia_tracao_max: 680,
|
||
limite_escoamento: 450,
|
||
alongamento: 15,
|
||
charpy: 68,
|
||
posicoes: 'Todas',
|
||
corrente_min: 120,
|
||
corrente_max: 200,
|
||
voltagem_min: 26,
|
||
voltagem_max: 30,
|
||
rendimento: 0.72,
|
||
taxa_deposicao: 4.2,
|
||
custo_kg: 65,
|
||
diametros: [2.4, 3.2, 4.0, 5.0]
|
||
},
|
||
e7016: {
|
||
nome: 'E7016',
|
||
tipo: 'Básico',
|
||
processo: 'SMAW',
|
||
resistencia_tracao_min: 485,
|
||
resistencia_tracao_max: 620,
|
||
limite_escoamento: 345,
|
||
alongamento: 17,
|
||
charpy: 47,
|
||
posicoes: 'Todas',
|
||
corrente_min: 90,
|
||
corrente_max: 170,
|
||
voltagem_min: 24,
|
||
voltagem_max: 28,
|
||
rendimento: 0.65,
|
||
taxa_deposicao: 3.2,
|
||
custo_kg: 38,
|
||
diametros: [2.0, 2.4, 3.2, 4.0]
|
||
},
|
||
e8016: {
|
||
nome: 'E8016',
|
||
tipo: 'Básico',
|
||
processo: 'SMAW',
|
||
resistencia_tracao_min: 550,
|
||
resistencia_tracao_max: 680,
|
||
limite_escoamento: 450,
|
||
alongamento: 15,
|
||
charpy: 54,
|
||
posicoes: 'Todas',
|
||
corrente_min: 110,
|
||
corrente_max: 190,
|
||
voltagem_min: 26,
|
||
voltagem_max: 30,
|
||
rendimento: 0.68,
|
||
taxa_deposicao: 3.8,
|
||
custo_kg: 58,
|
||
diametros: [2.4, 3.2, 4.0, 5.0]
|
||
},
|
||
er70s2: {
|
||
nome: 'ER70S-2',
|
||
tipo: 'MIG',
|
||
processo: 'GMAW',
|
||
resistencia_tracao_min: 490,
|
||
resistencia_tracao_max: 550,
|
||
limite_escoamento: 400,
|
||
alongamento: 22,
|
||
charpy: 27,
|
||
posicoes: 'Todas',
|
||
corrente_min: 150,
|
||
corrente_max: 250,
|
||
voltagem_min: 22,
|
||
voltagem_max: 28,
|
||
rendimento: 0.88,
|
||
taxa_deposicao: 5.5,
|
||
custo_kg: 35,
|
||
diametros: [0.8, 1.0, 1.2, 1.6]
|
||
},
|
||
er70s6: {
|
||
nome: 'ER70S-6',
|
||
tipo: 'MIG',
|
||
processo: 'GMAW',
|
||
resistencia_tracao_min: 490,
|
||
resistencia_tracao_max: 550,
|
||
limite_escoamento: 400,
|
||
alongamento: 22,
|
||
charpy: 27,
|
||
posicoes: 'Todas',
|
||
corrente_min: 150,
|
||
corrente_max: 250,
|
||
voltagem_min: 22,
|
||
voltagem_max: 28,
|
||
rendimento: 0.90,
|
||
taxa_deposicao: 6.0,
|
||
custo_kg: 32,
|
||
diametros: [0.8, 1.0, 1.2, 1.6]
|
||
},
|
||
er4043: {
|
||
nome: 'ER4043',
|
||
tipo: 'TIG - Alumínio',
|
||
processo: 'GTAW',
|
||
resistencia_tracao_min: 145,
|
||
resistencia_tracao_max: 185,
|
||
limite_escoamento: 70,
|
||
alongamento: 10,
|
||
charpy: 0,
|
||
posicoes: 'Todas',
|
||
corrente_min: 80,
|
||
corrente_max: 180,
|
||
voltagem_min: 10,
|
||
voltagem_max: 15,
|
||
rendimento: 0.95,
|
||
taxa_deposicao: 1.8,
|
||
custo_kg: 120,
|
||
diametros: [1.6, 2.0, 2.4, 3.2]
|
||
},
|
||
er5356: {
|
||
nome: 'ER5356',
|
||
tipo: 'TIG - Alumínio',
|
||
processo: 'GTAW',
|
||
resistencia_tracao_min: 290,
|
||
resistencia_tracao_max: 345,
|
||
limite_escoamento: 150,
|
||
alongamento: 12,
|
||
charpy: 0,
|
||
posicoes: 'Todas',
|
||
corrente_min: 90,
|
||
corrente_max: 200,
|
||
voltagem_min: 10,
|
||
voltagem_max: 15,
|
||
rendimento: 0.92,
|
||
taxa_deposicao: 2.2,
|
||
custo_kg: 135,
|
||
diametros: [1.6, 2.0, 2.4, 3.2]
|
||
}
|
||
};
|
||
|
||
const weldingProcesses = {
|
||
smaw: { nome: 'SMAW (Eletrodo Revestido)', ajuste_temp: 20 },
|
||
gmaw: { nome: 'GMAW (MIG/MAG)', ajuste_temp: 10 },
|
||
fcaw: { nome: 'FCAW (Arame Tubular)', ajuste_temp: 15 },
|
||
gtaw: { nome: 'GTAW (TIG)', ajuste_temp: 0 },
|
||
saw: { nome: 'SAW (Soldagem Submersa)', ajuste_temp: 25 },
|
||
esw: { nome: 'ESW (Soldagem por Escória)', ajuste_temp: 30 }
|
||
};
|
||
|
||
let currentWeldProcess = 'smaw';
|
||
let currentWeldElectrode = 'e7018';
|
||
|
||
// ========================================
|
||
// WELDING FUNCTIONS
|
||
// ========================================
|
||
|
||
function updateWeldingProcess() {
|
||
currentWeldProcess = document.getElementById('weld-process').value;
|
||
updateElectrodeOptions();
|
||
|
||
// Auto-update all tabs display after process change
|
||
const processName = weldingProcesses[currentWeldProcess]?.nome || 'SMAW';
|
||
const electrodeName = weldingElectrodes[currentWeldElectrode]?.nome || 'E7018';
|
||
const display = `${processName} (${electrodeName})`;
|
||
|
||
document.getElementById('preheat-process-display').textContent = display;
|
||
document.getElementById('filete-process-display').textContent = display;
|
||
document.getElementById('hi-process-display').textContent = display;
|
||
document.getElementById('consumo-electrode-display').textContent = electrodeName;
|
||
}
|
||
|
||
function updateWeldingElectrode() {
|
||
currentWeldElectrode = document.getElementById('weld-electrode').value;
|
||
}
|
||
|
||
function updateElectrodeOptions() {
|
||
const select = document.getElementById('weld-electrode');
|
||
const process = currentWeldProcess;
|
||
|
||
// Get valid consumables for this process
|
||
const processData = processoConsumiveisMap[process];
|
||
if (!processData) {
|
||
select.innerHTML = '<option value="e7018">E7018 (Padrão)</option>';
|
||
currentWeldElectrode = 'e7018';
|
||
return;
|
||
}
|
||
|
||
// Build options only with valid consumables
|
||
let options = '';
|
||
processData.consumiveis.forEach(consumivelId => {
|
||
const elec = weldingElectrodes[consumivelId];
|
||
if (elec) {
|
||
options += `<option value="${consumivelId}">${elec.nome} - ${elec.tipo}</option>`;
|
||
}
|
||
});
|
||
|
||
select.innerHTML = options || '<option value="e7018">E7018 (Padrão)</option>';
|
||
|
||
// Set default consumable for this process
|
||
select.value = processData.defaultConsumivel;
|
||
currentWeldElectrode = select.value;
|
||
|
||
// Update electrode display in consumption tab
|
||
const electrodeName = weldingElectrodes[currentWeldElectrode]?.nome || 'E7018';
|
||
document.getElementById('consumo-electrode-display').textContent = electrodeName;
|
||
}
|
||
|
||
function applyToAllTabs() {
|
||
const processName = weldingProcesses[currentWeldProcess]?.nome || 'SMAW';
|
||
const electrodeName = weldingElectrodes[currentWeldElectrode]?.nome || 'E7018';
|
||
const display = `${processName} (${electrodeName})`;
|
||
|
||
document.getElementById('preheat-process-display').textContent = display;
|
||
document.getElementById('filete-process-display').textContent = display;
|
||
document.getElementById('hi-process-display').textContent = display;
|
||
document.getElementById('consumo-electrode-display').textContent = electrodeName;
|
||
|
||
alert(`✅ Processo e consumível atualizados em todas as abas!\n\n${display}`);
|
||
}
|
||
|
||
function showElectrodeProperties() {
|
||
const elec = weldingElectrodes[currentWeldElectrode];
|
||
if (!elec) return;
|
||
|
||
const html = `
|
||
<div class="card" style="background: var(--color-bg-3); margin-top: 20px;">
|
||
<div class="card-title">📋 Propriedades do ${elec.nome}</div>
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Resistência Tração</div>
|
||
<div class="result-value" style="font-size: 18px;">${elec.resistencia_tracao_min}-${elec.resistencia_tracao_max} MPa</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Limite Escoamento</div>
|
||
<div class="result-value" style="font-size: 18px;">≥ ${elec.limite_escoamento} MPa</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Alongamento</div>
|
||
<div class="result-value" style="font-size: 18px;">≥ ${elec.alongamento}%</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Charpy (-20°C)</div>
|
||
<div class="result-value" style="font-size: 18px;">${elec.charpy > 0 ? '≥ ' + elec.charpy + ' J' : 'N/A'}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Corrente Recomendada</div>
|
||
<div class="result-value" style="font-size: 18px;">${elec.corrente_min}-${elec.corrente_max} A</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Voltagem</div>
|
||
<div class="result-value" style="font-size: 18px;">${elec.voltagem_min}-${elec.voltagem_max} V</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Rendimento de Deposição</div>
|
||
<div class="result-value" style="font-size: 18px;">${(elec.rendimento * 100).toFixed(0)}%</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Custo</div>
|
||
<div class="result-value" style="font-size: 18px;">R$ ${elec.custo_kg}/kg</div>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top: 16px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<p><strong>Tipo de Revestimento:</strong> ${elec.tipo}</p>
|
||
<p><strong>Posição Soldagem:</strong> ${elec.posicoes}</p>
|
||
<p><strong>Taxa de Deposição:</strong> ${elec.taxa_deposicao} kg/h</p>
|
||
<p><strong>Diâmetros Comerciais:</strong> ${elec.diametros.join(', ')} mm</p>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('electrode-properties').innerHTML = html;
|
||
}
|
||
|
||
function switchWeldTab(index) {
|
||
document.querySelectorAll('.tabs-nav .tab-btn').forEach((btn, i) => {
|
||
if (btn.textContent.includes('Pré-Aquecimento') || btn.textContent.includes('Filete') ||
|
||
btn.textContent.includes('Energia') || btn.textContent.includes('Consumo') ||
|
||
btn.textContent.includes('Sequência') || btn.textContent.includes('Padrões')) {
|
||
btn.classList.toggle('active', i === index);
|
||
}
|
||
});
|
||
|
||
for (let i = 0; i < 6; i++) {
|
||
const tab = document.getElementById(`weld-tab-${i}`);
|
||
if (tab) {
|
||
tab.classList.toggle('active', i === index);
|
||
}
|
||
}
|
||
|
||
// Update help button for the active tab
|
||
const tabIds = ['preaquecimento', 'filete', 'energia', 'consumo-eletrodo', 'sequencia-soldagem', 'padroes-soldagem'];
|
||
addHelpButton(tabIds[index]);
|
||
}
|
||
|
||
function calcularPreaquecimentoCompleto() {
|
||
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 restraint = parseFloat(document.getElementById('preheat-restraint').value) || 1.0;
|
||
const calcInterpass = document.getElementById('preheat-interpass').checked;
|
||
|
||
const processAdjust = weldingProcesses[currentWeldProcess]?.ajuste_temp || 0;
|
||
|
||
// AWS D1.1 Formula
|
||
const cevFactor = cev * 50;
|
||
const thicknessFactor = (thickness / 10) * 20;
|
||
const ambientFactor = (20 - ambient) / 2;
|
||
|
||
let preheatTemp = 50 + cevFactor + thicknessFactor + ambientFactor + processAdjust;
|
||
preheatTemp = preheatTemp * restraint;
|
||
|
||
const interpassTemp = preheatTemp + 25;
|
||
const maxInterpass = 200;
|
||
|
||
let cevClass = '';
|
||
let cevInterpretation = '';
|
||
if (cev < 0.40) {
|
||
cevClass = 'Baixo';
|
||
cevInterpretation = 'Excelente soldabilidade';
|
||
} else if (cev < 0.50) {
|
||
cevClass = 'Médio';
|
||
cevInterpretation = 'Boa soldabilidade com cuidados';
|
||
} else if (cev < 0.60) {
|
||
cevClass = 'Alto';
|
||
cevInterpretation = 'Soldabilidade moderada';
|
||
} else {
|
||
cevClass = 'Crítico';
|
||
cevInterpretation = 'Requer procedimento especial';
|
||
}
|
||
|
||
let thicknessClass = thickness > 50 ? 'Crítica' : thickness > 25 ? 'Alta' : 'Normal';
|
||
|
||
const html = `
|
||
<div class="result-box" style="background: var(--color-bg-1); border-left: 4px solid var(--color-warning);">
|
||
<div class="result-title">🔥 PRÉ-AQUECIMENTO AWS D1.1 - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>DADOS RESUMIDOS:</strong><br>
|
||
Processo: ${weldingProcesses[currentWeldProcess].nome}<br>
|
||
Consumível: ${weldingElectrodes[currentWeldElectrode].nome}<br>
|
||
CEV: ${cev.toFixed(2)} (${cevClass} - ${cevInterpretation})<br>
|
||
Espessura: ${thickness} mm (${thicknessClass})<br>
|
||
Ambiente: ${ambient}°C<br>
|
||
Restrição: ${restraint === 1.0 ? 'Não restrita' : restraint === 1.1 ? 'Parcial' : 'Total'}
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>CÁLCULOS:</strong><br>
|
||
CEV Factor: ${cev.toFixed(2)} × 50 = ${cevFactor.toFixed(1)}°C<br>
|
||
Esp Factor: (${thickness}/10) × 20 = ${thicknessFactor.toFixed(1)}°C<br>
|
||
Amb Factor: (20 - ${ambient}) / 2 = ${ambientFactor.toFixed(1)}°C<br>
|
||
Processo Adj: +${processAdjust}°C (${currentWeldProcess.toUpperCase()})<br>
|
||
Restrição: ×${restraint} = Multiplica por ${restraint}
|
||
</div>
|
||
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">PRÉ-AQUECIMENTO MÍNIMO</div>
|
||
<div class="result-value">${Math.round(preheatTemp)}°C</div>
|
||
</div>
|
||
${calcInterpass ? `
|
||
<div class="result-item">
|
||
<div class="result-label">INTERPASS (entre passes)</div>
|
||
<div class="result-value">${Math.round(interpassTemp)}°C</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Temperatura Máxima</div>
|
||
<div class="result-value">${maxInterpass}°C</div>
|
||
</div>
|
||
` : ''}
|
||
</div>
|
||
|
||
<div class="alert alert-warning" style="margin-top: 20px;">
|
||
<strong>⚠️ RECOMENDAÇÕES CRÍTICAS:</strong><br>
|
||
1. Pré-aqueça todo o acesso de soldagem (min 75mm da junta)<br>
|
||
${calcInterpass ? `2. Manter interpass entre ${Math.round(preheatTemp)}-${Math.round(interpassTemp)}°C<br>` : ''}
|
||
${calcInterpass ? `3. Não exceder ${maxInterpass}°C (risco de fragilização ZTA)<br>` : ''}
|
||
${calcInterpass ? '4' : '2'}. Usar termômetro de contato ou pirômetro<br>
|
||
${calcInterpass ? '5' : '3'}. ${thickness > 50 || cev > 0.60 ? 'PWHT (Tratamento Térmico Pós) RECOMENDADO' : 'Considerar PWHT para maior confiabilidade'}
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
|
||
<strong>📊 TABELA AWS D1.1 REFERÊNCIA:</strong>
|
||
<table style="width: 100%; margin-top: 12px; font-size: 12px;">
|
||
<thead>
|
||
<tr style="background: var(--color-primary); color: white;">
|
||
<th style="padding: 8px;">Espessura</th>
|
||
<th>CEV < 0.40</th>
|
||
<th>CEV 0.40-0.60</th>
|
||
<th>CEV > 0.60</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td style="padding: 8px;">< 12mm</td><td>Não req.</td><td>50°C</td><td>100°C</td></tr>
|
||
<tr style="background: ${thickness >= 12 && thickness < 25 ? 'var(--color-bg-3)' : ''};"><td style="padding: 8px;">12-25mm</td><td>50°C</td><td>100°C</td><td>150°C</td></tr>
|
||
<tr style="background: ${thickness >= 25 && thickness < 50 ? 'var(--color-bg-3)' : ''};"><td style="padding: 8px;">25-50mm</td><td>50°C</td><td>100°C</td><td>165°C</td></tr>
|
||
<tr style="background: ${thickness >= 50 ? 'var(--color-bg-3)' : ''};"><td style="padding: 8px;">> 50mm</td><td>100°C</td><td>150°C</td><td>225°C</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('preheat-result').innerHTML = html;
|
||
addToHistory('Pré-Aquecimento', `${Math.round(preheatTemp)}°C (CEV=${cev.toFixed(2)}, esp=${thickness}mm)`);
|
||
}
|
||
|
||
function calcularFileteCompleto() {
|
||
const force = parseFloat(document.getElementById('filete-force').value) || 0;
|
||
const length = parseFloat(document.getElementById('filete-length').value) || 0;
|
||
const jointType = parseInt(document.getElementById('filete-joint').value) || 1;
|
||
const fy = parseFloat(document.getElementById('filete-steel').value) || 345;
|
||
const positionFactor = parseFloat(document.getElementById('filete-position').value) || 1.0;
|
||
|
||
const elec = weldingElectrodes[currentWeldElectrode];
|
||
|
||
// Weld capacity calculation
|
||
const fyWeld = fy * 0.6;
|
||
const legTheoretical = (force * 1000) / (0.707 * length * jointType * 0.65 * fyWeld * positionFactor);
|
||
const legCommercial = Math.max(Math.ceil(legTheoretical), 3);
|
||
const throat = legCommercial * 0.707;
|
||
|
||
// Number of passes
|
||
let passes = 1;
|
||
let maxDiameter = 3.25;
|
||
if (legCommercial <= 5) {
|
||
passes = 1;
|
||
maxDiameter = 3.25;
|
||
} else if (legCommercial <= 8) {
|
||
passes = 2;
|
||
maxDiameter = 4.0;
|
||
} else {
|
||
passes = Math.ceil(legCommercial / 4);
|
||
maxDiameter = 4.0;
|
||
}
|
||
|
||
// Real capacity
|
||
const realCapacity = (0.707 * legCommercial * length * jointType * 0.65 * fyWeld * positionFactor) / 1000;
|
||
const safetyMargin = realCapacity - force;
|
||
const utilization = (force / realCapacity) * 100;
|
||
|
||
// Time and consumption estimate
|
||
const timePerPass = (length / 1000) * 30; // 30 min/m
|
||
const totalTime = timePerPass * passes;
|
||
const volume = (legCommercial * legCommercial * 0.5 * length * jointType) / 1000; // cm³
|
||
const mass = (volume / 1000) * 7.85; // kg
|
||
const consumption = mass / elec.rendimento * 1.15; // with losses
|
||
|
||
const positionName = positionFactor === 1.0 ? 'Plana (1F)' : positionFactor === 0.9 ? 'Horizontal (2F)' : positionFactor === 0.8 ? 'Vertical (3F)' : 'Sobrecabeça (4F)';
|
||
|
||
let status = '✅ VIÁVEL';
|
||
let alertClass = 'alert-success';
|
||
if (utilization > 100) {
|
||
status = '❌ INSUFICIENTE';
|
||
alertClass = 'alert-error';
|
||
} else if (utilization > 85) {
|
||
status = '⚠️ ATENÇÃO';
|
||
alertClass = 'alert-warning';
|
||
}
|
||
|
||
const html = `
|
||
<div class="result-box" style="background: var(--color-bg-3); border-left: 4px solid var(--color-success);">
|
||
<div class="result-title">⚡ DIMENSIONAMENTO DE FILETE - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>DADOS:</strong><br>
|
||
Processo: ${weldingProcesses[currentWeldProcess].nome}<br>
|
||
Eletrodo: ${elec.nome}<br>
|
||
Força: ${force} kN | Comprimento: ${length} mm<br>
|
||
Aço Base: fy = ${fy} MPa<br>
|
||
Junta: ${jointType === 1 ? 'Filete Simples' : 'Filete Duplo'} | Posição: ${positionName}
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px; font-family: var(--font-family-mono); font-size: 13px;">
|
||
<strong>CÁLCULO:</strong><br>
|
||
Fv unitário = 0.707 × perna × comp × 0.65 × fy / 1000<br>
|
||
Fv = 0.707 × perna × ${length} × 0.65 × ${fy}/1000<br>
|
||
Fv = ${(0.707 * length * 0.65 * fy / 1000).toFixed(2)} × perna (kN)<br><br>
|
||
Para ${jointType} filete(s): ${jointType} × Fv = ${(jointType * 0.707 * length * 0.65 * fy / 1000).toFixed(2)} × perna<br><br>
|
||
Perna necessária: ${force} / ${(jointType * 0.707 * length * 0.65 * fy / 1000).toFixed(2)} = ${legTheoretical.toFixed(2)} mm
|
||
</div>
|
||
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Perna Teórica</div>
|
||
<div class="result-value">${legTheoretical.toFixed(2)} mm</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Perna Comercial</div>
|
||
<div class="result-value" style="color: var(--color-success);">${legCommercial} mm</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Capacidade Real</div>
|
||
<div class="result-value">${realCapacity.toFixed(1)} kN</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Margem de Segurança</div>
|
||
<div class="result-value">${safetyMargin.toFixed(1)} kN (${((realCapacity/force - 1) * 100).toFixed(0)}%)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-1); border-radius: 8px;">
|
||
<strong>⚙️ DIMENSIONAMENTO DE PASSES:</strong><br>
|
||
Eletrodo Máximo: ${maxDiameter}mm (para ${passes} passa${passes > 1 ? 's' : ''})
|
||
</div>
|
||
|
||
<div style="margin-top: 16px; padding: 16px; background: var(--color-surface); border-radius: 8px; border: 2px solid var(--color-primary);">
|
||
<strong>OPÇÃO ${passes === 1 ? 'RECOMENDADA' : '1'}: ${passes} PASSA${passes > 1 ? 'S' : ''}:</strong><br>
|
||
Perna: ${passes === 1 ? legCommercial : passes + '×' + Math.ceil(legCommercial/passes)} mm (diâmetro ${maxDiameter}mm)<br>
|
||
Corrente: ${elec.corrente_min}-${elec.corrente_max} A<br>
|
||
Tempo: ${Math.round(totalTime)} min<br>
|
||
Consumo: ${consumption.toFixed(2)} kg<br>
|
||
${status === '✅ VIÁVEL' ? '✅ VIÁVEL (Margem de ' + ((realCapacity/force - 1) * 100).toFixed(0) + '%)' : status}
|
||
</div>
|
||
|
||
${passes === 1 && legCommercial >= 5 ? `
|
||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
|
||
<strong>OPÇÃO 2: 2 PASSES (Maior Confiabilidade):</strong><br>
|
||
Perna: 2×${Math.ceil(legCommercial/2)} = ${legCommercial} mm<br>
|
||
Corrente: ${elec.corrente_min} A × 2<br>
|
||
Tempo: ${Math.round(totalTime * 2)} min<br>
|
||
Consumo: ${(consumption * 2).toFixed(2)} kg<br>
|
||
✅ RECOMENDADO (Maior qualidade e resistência)
|
||
</div>
|
||
` : ''}
|
||
|
||
<div class="alert ${alertClass}" style="margin-top: 20px;">
|
||
<strong>RECOMENDAÇÕES:</strong><br>
|
||
- ${elec.nome} é ${elec.tipo === 'Básico' ? 'excelente' : 'adequado'} para essa aplicação<br>
|
||
- ${passes > 1 ? 'Usar ' + passes + ' passes garante melhor qualidade' : 'Soldagem em 1 passa é viável'}<br>
|
||
- Manter interpass 150°C (vindo da Aba Pré-Aquecimento)<br>
|
||
- Utilização: ${utilization.toFixed(1)}% ${status}
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('filete-result').innerHTML = html;
|
||
addToHistory('Filete', `Perna ${legCommercial}mm, ${passes} passe(s), ${force}kN`);
|
||
}
|
||
|
||
function calcularEnergiaCompleta() {
|
||
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 efficiency = parseFloat(document.getElementById('hi-efficiency').value) || 0.75;
|
||
const steelType = document.getElementById('hi-steel').value;
|
||
|
||
// Heat Input calculation
|
||
const heatInput = (voltage * current * 60 * efficiency) / (speed * 1000);
|
||
|
||
const steelLimits = {
|
||
'a36': { min: 1.5, max: 3.0, name: 'A36' },
|
||
'a572': { min: 1.0, max: 2.5, name: 'A572' },
|
||
's355': { min: 0.8, max: 2.0, name: 'S355' }
|
||
};
|
||
|
||
const limits = steelLimits[steelType];
|
||
|
||
let hiStatus = '';
|
||
let alertClass = '';
|
||
let recommendations = [];
|
||
|
||
if (heatInput < limits.min) {
|
||
hiStatus = 'BAIXO';
|
||
alertClass = 'alert-warning';
|
||
recommendations.push('Aumentar corrente ou reduzir velocidade');
|
||
recommendations.push('Risco de falta de fusão ou trincas a frio');
|
||
} else if (heatInput <= limits.max) {
|
||
hiStatus = 'ADEQUADO ✅';
|
||
alertClass = 'alert-success';
|
||
recommendations.push('Energia dentro da faixa recomendada');
|
||
recommendations.push('Manter os parâmetros atuais');
|
||
} else {
|
||
hiStatus = 'MUITO ALTO ⚠️';
|
||
alertClass = 'alert-error';
|
||
const newSpeed = Math.ceil((voltage * current * 60 * efficiency) / (limits.max * 1000));
|
||
const newCurrent = Math.ceil((limits.max * 1000 * speed) / (voltage * 60 * efficiency));
|
||
recommendations.push('AUMENTAR VELOCIDADE para ' + newSpeed + ' cm/min → HI = ' + limits.max.toFixed(2) + ' kJ/mm ✅');
|
||
recommendations.push('OU REDUZIR CORRENTE para ' + newCurrent + ' A → HI = ' + limits.max.toFixed(2) + ' kJ/mm ✅');
|
||
recommendations.push('OPÇÃO 3: Usar processo GMAW (mais eficiente) → HI ≈ ' + (heatInput * 0.6).toFixed(2) + ' kJ/mm ✅');
|
||
}
|
||
|
||
const html = `
|
||
<div class="result-box" style="background: var(--color-bg-6); border-left: 4px solid var(--color-warning);">
|
||
<div class="result-title">🔥 ENERGIA DE SOLDAGEM - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>PARÂMETROS:</strong><br>
|
||
Voltagem: ${voltage} V<br>
|
||
Corrente: ${current} A<br>
|
||
Velocidade: ${speed} cm/min<br>
|
||
Eficiência: ${(efficiency * 100).toFixed(0)}%
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px; font-family: var(--font-family-mono); font-size: 13px;">
|
||
<strong>CÁLCULO:</strong><br>
|
||
HI = (V × I × 60 × η) / (v × 1000)<br>
|
||
HI = (${voltage} × ${current} × 60 × ${efficiency}) / (${speed} × 1000)<br>
|
||
HI = ${(voltage * current * 60 * efficiency).toFixed(1)} / ${speed * 1000} = ${heatInput.toFixed(2)} kJ/mm
|
||
</div>
|
||
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Energia de Soldagem</div>
|
||
<div class="result-value" style="color: ${heatInput <= limits.max && heatInput >= limits.min ? 'var(--color-success)' : 'var(--color-error)'}">${heatInput.toFixed(2)} kJ/mm</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Classificação</div>
|
||
<div class="result-value" style="font-size: 20px;">${hiStatus}</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
|
||
<strong>⚠️ ANÁLISE POR TIPO DE AÇO:</strong>
|
||
<table style="width: 100%; margin-top: 12px; font-size: 13px;">
|
||
<thead>
|
||
<tr style="background: var(--color-primary); color: white;">
|
||
<th style="padding: 8px;">Aço</th>
|
||
<th>Ideal (kJ/mm)</th>
|
||
<th>Valor</th>
|
||
<th>Status</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr style="background: ${steelType === 'a36' ? 'var(--color-bg-3)' : ''};">
|
||
<td style="padding: 8px;">A36</td>
|
||
<td>1.5-3.0</td>
|
||
<td>${heatInput.toFixed(2)}</td>
|
||
<td>${heatInput >= 1.5 && heatInput <= 3.0 ? '✅ OK' : heatInput > 3.0 ? '❌ ALTO' : '⚠️ BAIXO'}</td>
|
||
</tr>
|
||
<tr style="background: ${steelType === 'a572' ? 'var(--color-bg-3)' : ''};">
|
||
<td style="padding: 8px;">A572</td>
|
||
<td>1.0-2.5</td>
|
||
<td>${heatInput.toFixed(2)}</td>
|
||
<td>${heatInput >= 1.0 && heatInput <= 2.5 ? '✅ OK' : heatInput > 2.5 ? '❌ ALTO' : '⚠️ BAIXO'}</td>
|
||
</tr>
|
||
<tr style="background: ${steelType === 's355' ? 'var(--color-bg-3)' : ''};">
|
||
<td style="padding: 8px;">S355</td>
|
||
<td>0.8-2.0</td>
|
||
<td>${heatInput.toFixed(2)}</td>
|
||
<td>${heatInput >= 0.8 && heatInput <= 2.0 ? '✅ OK' : heatInput > 2.0 ? '❌ CRÍTICO' : '⚠️ BAIXO'}</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
${heatInput > limits.max ? `
|
||
<div style="margin-top: 16px; padding: 16px; background: var(--color-bg-4); border-radius: 8px; border: 2px solid var(--color-error);">
|
||
<strong>⚠️ RISCOS:</strong><br>
|
||
1. Aquecimento excessivo da ZTA<br>
|
||
2. Possível fragilização por alívio<br>
|
||
3. Risco de trincas pelo resfriamento rápido<br>
|
||
4. Redução de tenacidade
|
||
</div>
|
||
` : ''}
|
||
|
||
<div class="alert ${alertClass}" style="margin-top: 20px;">
|
||
<strong>✅ RECOMENDAÇÕES:</strong><br>
|
||
${recommendations.map((rec, i) => `${i + 1}. ${rec}`).join('<br>')}
|
||
</div>
|
||
|
||
<div style="margin-top: 16px; padding: 12px; background: var(--color-surface); border-radius: 8px; text-align: center;">
|
||
<strong>🔧 CALCULADORA INTERATIVA:</strong><br>
|
||
<small>Teste diferentes velocidades/correntes acima para encontrar HI ideal!</small>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('hi-result').innerHTML = html;
|
||
addToHistory('Energia Soldagem', `HI=${heatInput.toFixed(2)} kJ/mm (${hiStatus})`);
|
||
}
|
||
|
||
function calcularPreaquecimento() {
|
||
const getVal = (id, fallback = 0) => {
|
||
const el = document.getElementById(id);
|
||
return el ? parseFloat(el.value) : fallback;
|
||
};
|
||
|
||
const cev = getVal('preheat-cev');
|
||
const thickness = getVal('preheat-thickness');
|
||
const ambient = getVal('preheat-ambient', 20);
|
||
|
||
if (cev < 0 || cev > 2) {
|
||
const resultEl = document.getElementById('preheat-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ CEV inválido. Use valores entre 0 e 2.</div>';
|
||
return;
|
||
}
|
||
if (thickness <= 0 || thickness > 300) {
|
||
const resultEl = document.getElementById('preheat-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Espessura inválida. Use valores entre 1mm e 300mm.</div>';
|
||
return;
|
||
}
|
||
if (ambient < -50 || ambient > 60) {
|
||
const resultEl = document.getElementById('preheat-result');
|
||
if (resultEl) resultEl.innerHTML = '<div class="alert alert-error">⚠️ Temperatura ambiente inválida. Use valores entre -50°C e 60°C.</div>';
|
||
return;
|
||
}
|
||
|
||
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>
|
||
`;
|
||
|
||
addToHistory('Pré-Aquecimento', `CEV=${cev}, esp=${thickness}mm → ${Math.round(preheatTemp)}°C`);
|
||
}
|
||
|
||
function calcularConsumoCompleto() {
|
||
const leg = parseFloat(document.getElementById('consumo-leg').value) || 0;
|
||
const length = parseFloat(document.getElementById('consumo-length').value) || 0;
|
||
const loss = parseFloat(document.getElementById('consumo-loss').value) || 15;
|
||
const scrap = parseFloat(document.getElementById('consumo-scrap').value) || 5;
|
||
|
||
const elec = weldingElectrodes[currentWeldElectrode];
|
||
|
||
// Volume calculation
|
||
const throat = leg * 0.707;
|
||
const volumeCm3 = (throat * leg * length * 1000 * 0.5) / 1000;
|
||
const massKg = (volumeCm3 / 1000000) * 7850;
|
||
|
||
// Consumption with efficiency
|
||
const massConsumable = massKg / elec.rendimento;
|
||
const lossKg = massConsumable * (loss / 100);
|
||
const scrapKg = massConsumable * (scrap / 100);
|
||
const totalKg = massConsumable + lossKg + scrapKg;
|
||
|
||
// Time estimation
|
||
const timeHours = totalKg / elec.taxa_deposicao;
|
||
const timeMin = timeHours * 60;
|
||
|
||
// Cost
|
||
const costMaterial = totalKg * elec.custo_kg;
|
||
const costLabor = timeHours * 60; // R$ 60/h average
|
||
const costTotal = costMaterial + costLabor;
|
||
|
||
// Compare with other electrodes
|
||
let comparisons = [];
|
||
Object.keys(weldingElectrodes).forEach(key => {
|
||
const e = weldingElectrodes[key];
|
||
if (e.processo === 'SMAW' && key !== currentWeldElectrode) {
|
||
const altMass = massKg / e.rendimento * (1 + loss/100) * (1 + scrap/100);
|
||
const altTime = (altMass / e.taxa_deposicao) * 60;
|
||
const altCost = altMass * e.custo_kg + (altTime / 60) * 60;
|
||
comparisons.push({
|
||
name: e.nome,
|
||
mass: altMass,
|
||
time: altTime,
|
||
cost: altCost
|
||
});
|
||
}
|
||
});
|
||
|
||
const html = `
|
||
<div class="result-box" style="background: var(--color-bg-5); border-left: 4px solid #a855f7;">
|
||
<div class="result-title">📊 CONSUMO DE ELETRODOS - RESULTADO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>CONSUMÍVEL SELECIONADO:</strong><br>
|
||
Eletrodo ${elec.nome} (AWS A5.1)<br>
|
||
Rendimento: ${(elec.rendimento * 100).toFixed(0)}%<br>
|
||
Taxa Deposição: ${elec.taxa_deposicao} kg/h<br>
|
||
Custo: R$ ${elec.custo_kg}/kg
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-background); border-radius: 8px; margin-bottom: 16px; font-family: var(--font-family-mono); font-size: 13px;">
|
||
<strong>CÁLCULOS:</strong><br>
|
||
Volume de Solda: ${volumeCm3.toFixed(0)} mm³<br>
|
||
Massa Teórica: ${massKg.toFixed(3)} kg<br>
|
||
Fator Rendimento: ${(elec.rendimento * 100).toFixed(0)}% = ÷${elec.rendimento.toFixed(2)}<br>
|
||
Massa Consumível: ${massKg.toFixed(3)} ÷ ${elec.rendimento.toFixed(2)} = ${massConsumable.toFixed(3)} kg<br><br>
|
||
Perdas (Respingos): ${loss}% × ${massConsumable.toFixed(3)} = ${lossKg.toFixed(4)}kg<br>
|
||
Sucata (Pontas): ${scrap}% × ${massConsumable.toFixed(3)} = ${scrapKg.toFixed(4)}kg<br><br>
|
||
TOTAL NECESSÁRIO: ${totalKg.toFixed(4)} kg
|
||
</div>
|
||
|
||
<div class="result-grid">
|
||
<div class="result-item">
|
||
<div class="result-label">Consumo de Eletrodo</div>
|
||
<div class="result-value">${(totalKg * 1000).toFixed(0)} g (${totalKg.toFixed(3)} kg)</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Caixas de 5kg</div>
|
||
<div class="result-value">${Math.ceil(totalKg / 5)} caixa${Math.ceil(totalKg / 5) > 1 ? 's' : ''}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Custo Total Material</div>
|
||
<div class="result-value">R$ ${costMaterial.toFixed(2)}</div>
|
||
</div>
|
||
<div class="result-item">
|
||
<div class="result-label">Tempo de Soldagem</div>
|
||
<div class="result-value">${Math.round(timeMin)} min</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-2); border-radius: 8px;">
|
||
<strong>📊 COMPARAÇÃO DE ELETRODOS PARA MESMO TRABALHO:</strong>
|
||
<table style="width: 100%; margin-top: 12px; font-size: 13px;">
|
||
<thead>
|
||
<tr style="background: var(--color-primary); color: white;">
|
||
<th style="padding: 8px;">Eletrodo</th>
|
||
<th>Consumo</th>
|
||
<th>Custo</th>
|
||
<th>Tempo</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr style="background: var(--color-bg-3);">
|
||
<td style="padding: 8px;"><strong>${elec.nome}</strong></td>
|
||
<td>${totalKg.toFixed(3)}kg</td>
|
||
<td>R$ ${costTotal.toFixed(2)}</td>
|
||
<td>${Math.round(timeMin)} min</td>
|
||
</tr>
|
||
${comparisons.map(c => `
|
||
<tr>
|
||
<td style="padding: 8px;">${c.name}</td>
|
||
<td>${c.mass.toFixed(3)}kg</td>
|
||
<td>R$ ${c.cost.toFixed(2)} ${c.cost < costTotal ? '✅' : ''}</td>
|
||
<td>${Math.round(c.time)} min ${c.time < timeMin ? '✅' : ''}</td>
|
||
</tr>
|
||
`).join('')}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<div class="alert alert-success" style="margin-top: 20px;">
|
||
<strong>✅ RECOMENDAÇÃO:</strong><br>
|
||
${comparisons.length > 0 && comparisons[0].cost < costTotal ?
|
||
`${comparisons[0].name} é mais barato (${((1 - comparisons[0].cost/costTotal) * 100).toFixed(0)}% economia!)` :
|
||
`${elec.nome} é a melhor opção considerando custo e qualidade`}
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('consumo-result').innerHTML = html;
|
||
addToHistory('Consumo Eletrodos', `${totalKg.toFixed(3)}kg ${elec.nome} para ${length}m`);
|
||
|
||
// Add button to send to budget
|
||
const resultDiv = document.getElementById('consumo-result');
|
||
const existingButton = resultDiv.querySelector('.add-to-budget-btn');
|
||
if (!existingButton) {
|
||
const button = document.createElement('button');
|
||
button.className = 'btn btn-success add-to-budget-btn';
|
||
button.style.marginTop = '16px';
|
||
button.textContent = '💰 Adicionar ao Orçamento';
|
||
button.onclick = () => addConsumoToOrcamento(totalKg, elec.nome, elec.custo_kg);
|
||
resultDiv.querySelector('.result-box').appendChild(button);
|
||
}
|
||
}
|
||
|
||
function addConsumoToOrcamento(kg, electrodeNome, custoKg) {
|
||
// Switch to orcamento section
|
||
showSection('orcamento');
|
||
|
||
setTimeout(() => {
|
||
document.getElementById('budget-category').value = 'consumivel';
|
||
updateBudgetTypeOptions();
|
||
|
||
setTimeout(() => {
|
||
document.getElementById('budget-type').value = 'consumiveis';
|
||
updateBudgetSpecOptions();
|
||
|
||
setTimeout(() => {
|
||
// Find matching electrode
|
||
const electrodeId = electrodeNome.toLowerCase().replace(/[^a-z0-9]/g, '').substring(0, 6);
|
||
const specSelect = document.getElementById('budget-spec');
|
||
const option = Array.from(specSelect.options).find(opt => opt.value.includes(electrodeId));
|
||
|
||
if (option) {
|
||
specSelect.value = option.value;
|
||
autoFillBudgetData();
|
||
}
|
||
|
||
document.getElementById('budget-qty').value = kg.toFixed(2);
|
||
updateBudgetTotal();
|
||
|
||
alert(`✅ Eletrodo transferido para Orçamento!\n\n${electrodeNome}: ${kg.toFixed(2)} kg\n\nClique em Adicionar.`);
|
||
}, 200);
|
||
}, 200);
|
||
}, 300);
|
||
}
|
||
|
||
function gerarDiagramaSequencia() {
|
||
const jointType = document.getElementById('seq-joint').value;
|
||
const length = parseFloat(document.getElementById('seq-length').value) || 0;
|
||
const leg = parseFloat(document.getElementById('seq-leg').value) || 0;
|
||
const passes = parseInt(document.getElementById('seq-passes').value) || 1;
|
||
const pattern = document.getElementById('seq-pattern').value;
|
||
|
||
let patternName = '';
|
||
let distortionReduction = 0;
|
||
let description = '';
|
||
|
||
switch(pattern) {
|
||
case 'skip':
|
||
patternName = 'Skip Welding';
|
||
distortionReduction = 80;
|
||
description = 'Soldagem alternada em segmentos';
|
||
break;
|
||
case 'backstep':
|
||
patternName = 'Backstep Welding';
|
||
distortionReduction = 60;
|
||
description = 'Soldagem em segmentos na direção oposta';
|
||
break;
|
||
case 'pulsed':
|
||
patternName = 'Pulsado';
|
||
distortionReduction = 50;
|
||
description = 'Corrente pulsada para controle térmico';
|
||
break;
|
||
case 'continuous':
|
||
patternName = 'Contínuo';
|
||
distortionReduction = 0;
|
||
description = 'Soldagem contínua sem paradas';
|
||
break;
|
||
}
|
||
|
||
const timePerPass = (length / 1000) * 30;
|
||
const totalTime = timePerPass * passes;
|
||
|
||
const skipDiagram = `
|
||
<pre style="background: var(--color-surface); padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 11px;">
|
||
VISTA SUPERIOR (Plano Vertical):
|
||
|
||
LADO ESQUERDO (1º Lado):
|
||
┌──────────────────────────────┐
|
||
│ PASSA 1 (1ª Metade): │
|
||
│ ━━━ ━━━ ━━━ ━━━ (Skip) │
|
||
│ 1 2 3 4 5 6 7 8 │ ${length}mm
|
||
│ [${Math.round(length/8)}mm segmentos, ${Math.round(length/8)}mm espaços] │
|
||
│ │
|
||
│ PASSA 2 (2ª Metade): │
|
||
│ ━━━ ━━━ ━━━ ━━━ (Reverso) │
|
||
│ 16 15 14 13 12 11 10 9 │
|
||
│ [Preenchimento dos espaços] │
|
||
│ │
|
||
│ RESULTADO: Distorção mínima ✅ │
|
||
└──────────────────────────────┘
|
||
|
||
LADO DIREITO: [Sequência idêntica]
|
||
</pre>
|
||
`;
|
||
|
||
const html = `
|
||
<div class="result-box" style="background: var(--color-bg-7); border-left: 4px solid #ec4899;">
|
||
<div class="result-title">📐 SEQUÊNCIA DE SOLDAGEM - PLANO VISUAL</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>JUNTA:</strong> ${jointType === 'filete' ? 'Filete Duplo' : jointType === 'topo' ? 'Topo' : 'Angular'} (${length}mm × ${leg}mm × ${passes} passa${passes > 1 ? 's' : ''})<br>
|
||
<strong>PADRÃO:</strong> ${patternName} (${description})<br>
|
||
<strong>PROCESSO:</strong> ${weldingProcesses[currentWeldProcess].nome}
|
||
</div>
|
||
|
||
${pattern === 'skip' ? skipDiagram : `
|
||
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; text-align: center;">
|
||
<strong>Padrão ${patternName}</strong><br>
|
||
<p style="margin-top: 12px; color: var(--color-text-secondary);">${description}</p>
|
||
</div>
|
||
`}
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-1); border-radius: 8px;">
|
||
<strong>⏱️ CRONOGRAMA:</strong><br>
|
||
Sequência 1º Lado: ${Math.round(totalTime)} min<br>
|
||
Sequência 2º Lado: ${Math.round(totalTime)} min<br>
|
||
Tempo Total: ${Math.round(totalTime * 2)} min (com pausas)
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-6); border-radius: 8px;">
|
||
<strong>📊 ANÁLISE DE DISTORÇÃO:</strong><br><br>
|
||
<strong>Método ${patternName}:</strong><br>
|
||
- Distorção Angular Esperada: ±${pattern === 'continuous' ? '2.5' : '0.5'}°<br>
|
||
- Distorção Longitudinal: ±${pattern === 'continuous' ? '8' : '2'}mm<br>
|
||
- Avaliação: ${distortionReduction > 60 ? 'EXCELENTE ✅' : distortionReduction > 40 ? 'BOA ✅' : 'NÃO RECOMENDADO ⚠️'}<br><br>
|
||
|
||
${pattern !== 'continuous' ? `
|
||
<strong>vs Método Contínuo (sem otimização):</strong><br>
|
||
- Distorção Angular: ±2.5° ⚠️<br>
|
||
- Distorção Longitudinal: ±8mm ⚠️<br>
|
||
- Avaliação: NÃO RECOMENDADO<br><br>
|
||
` : ''}
|
||
|
||
<strong>✅ VANTAGENS ${patternName.toUpperCase()}:</strong><br>
|
||
1. Reduz distorções em ${distortionReduction}%<br>
|
||
2. Controla melhor a temperatura<br>
|
||
3. Facilita inspeção entre passes<br>
|
||
4. Reduz stress residual
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px; border: 2px solid var(--color-primary);">
|
||
<strong>🔧 INSTRUÇÕES PARA SOLDADOR:</strong><br>
|
||
1. Marcar posições com giz (0, ${Math.round(length/8)}, ${Math.round(length/4)}...)<br>
|
||
2. Soldar segmentos 1-8 (1ª passa)<br>
|
||
3. Aguardar resfriamento (espaços resfriem)<br>
|
||
4. Soldar segmentos 9-16 (preencher vazios)<br>
|
||
5. Controlar temperatura: 150-200°C (interpass)<br>
|
||
6. Inspeção visual entre passes
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('sequencia-result').innerHTML = html;
|
||
addToHistory('Sequência Soldagem', `${patternName}, ${length}mm, ${passes} passes`);
|
||
}
|
||
|
||
function buscarPadraoIdeal() {
|
||
const app = document.getElementById('padrao-app').value;
|
||
const criticality = document.getElementById('padrao-criticality').value;
|
||
const env = document.getElementById('padrao-env').value;
|
||
|
||
let standardClass = 'B';
|
||
let electrode = 'E7018';
|
||
let passes = 2;
|
||
let leg = 4;
|
||
let preheat = 100;
|
||
let inspection = 'Visual 100% + Ultrassom 10%';
|
||
let costIndex = 140;
|
||
|
||
if (criticality === 'baixa') {
|
||
standardClass = 'A';
|
||
electrode = 'E6013';
|
||
passes = 1;
|
||
leg = 3;
|
||
preheat = 60;
|
||
inspection = 'Visual 100%';
|
||
costIndex = 100;
|
||
} else if (criticality === 'critica' || app === 'ponte' || app === 'offshore') {
|
||
standardClass = 'C';
|
||
electrode = 'E8018';
|
||
passes = 3;
|
||
leg = 6;
|
||
preheat = 125;
|
||
inspection = 'Visual 100% + UT 100% + RT 20%';
|
||
costIndex = 200;
|
||
}
|
||
|
||
const elec = weldingElectrodes[electrode.toLowerCase()];
|
||
const consumptionPerMeter = (leg * leg * 0.5 * 1000) / 1000000 * 7.85 / elec.rendimento * 1.2;
|
||
const timePerMeter = (consumptionPerMeter / elec.taxa_deposicao) * 60;
|
||
const costPerMeter = consumptionPerMeter * elec.custo_kg + (timePerMeter / 60) * 60;
|
||
|
||
const html = `
|
||
<div class="result-box" style="background: var(--color-bg-8); border-left: 4px solid #06b6d4;">
|
||
<div class="result-title">📋 PADRÕES DE SOLDA POR APLICAÇÃO</div>
|
||
|
||
<div style="margin-bottom: 20px; padding: 16px; background: var(--color-surface); border-radius: 8px;">
|
||
<strong>APLICAÇÃO:</strong> ${app === 'edificio' ? 'Edifício Múltiplos Andares' : app === 'ponte' ? 'Ponte Rodoviária' : app === 'industrial' ? 'Estrutura Industrial' : app === 'tubulacao' ? 'Tubulação de Pressão' : app === 'equipamento' ? 'Equipamento Mecânico' : 'Marinha/Offshore'}<br>
|
||
<strong>Criticidade:</strong> ${criticality === 'baixa' ? 'Baixa' : criticality === 'media' ? 'Média' : criticality === 'alta' ? 'Alta' : 'Crítica'} | <strong>Ambiente:</strong> ${env === 'interno' ? 'Interno Seco' : env === 'externo' ? 'Externo Temperado' : env === 'agressivo' ? 'Agressivo/Marinho' : 'Baixas Temperaturas'}<br>
|
||
<strong>Norma:</strong> AISC 360-16, AWS D1.1
|
||
</div>
|
||
|
||
<div style="padding: 20px; background: ${standardClass === 'A' ? 'var(--color-bg-2)' : standardClass === 'B' ? 'var(--color-bg-1)' : 'var(--color-bg-6)'}; border-radius: 12px; border: 2px solid var(--color-primary);">
|
||
<h3 style="color: var(--color-primary); margin-bottom: 16px;">✅ PADRÃO RECOMENDADO: Classe ${standardClass}</h3>
|
||
<strong>Processo:</strong> ${weldingProcesses[currentWeldProcess].nome}<br>
|
||
<strong>Eletrodo:</strong> ${electrode} (${elec.tipo})<br>
|
||
<strong>Processo Secundário:</strong> ${standardClass === 'C' ? 'SAW (se volume alto)' : 'SMAW padrão'}<br><br>
|
||
|
||
<strong>ESPECIFICAÇÃO:</strong><br>
|
||
• Número de Passes: ${passes}<br>
|
||
• Perna Filete: ${leg} mm<br>
|
||
• Pré-aquecimento: ${preheat}°C<br>
|
||
• Interpass: 150-200°C<br>
|
||
• Velocidade: 20-30 cm/min<br>
|
||
• Posição: Plana e Horizontal preferida<br>
|
||
• Inspeção: ${inspection}<br><br>
|
||
|
||
<strong>CONSUMO POR METRO LINEAR:</strong><br>
|
||
• Eletrodos: ${consumptionPerMeter.toFixed(2)} kg<br>
|
||
• Tempo: ${Math.round(timePerMeter)} min/m<br>
|
||
• Custo: R$ ${costPerMeter.toFixed(2)}/m (material + mão de obra)<br><br>
|
||
|
||
<strong>QUALIDADE ESPERADA:</strong><br>
|
||
✓ Resistência à tração: >${elec.resistencia_tracao_min} MPa<br>
|
||
✓ Alongamento: >${elec.alongamento}%<br>
|
||
✓ Charpy (-20°C): >${elec.charpy} J<br>
|
||
✓ Dureza ZTA: <260 HV<br><br>
|
||
|
||
<strong>⚠️ RESTRIÇÕES:</strong><br>
|
||
• Não usar em posição overhead sem suporte<br>
|
||
• Temperatura mínima: ${env === 'baixatemp' ? '-20' : '-10'}°C<br>
|
||
• Não esticar além de 2x o comprimento
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; padding: 16px; background: var(--color-bg-5); border-radius: 8px;">
|
||
<strong>📊 ALTERNATIVAS:</strong><br><br>
|
||
|
||
${standardClass !== 'A' ? `
|
||
<strong>⭐ OPÇÃO INFERIOR (Economia):</strong><br>
|
||
PADRÃO: Classe A (Soldagem Econômica)<br>
|
||
Eletrodo: E6013 (mais barato)<br>
|
||
Passes: 1 | Perna: 3mm<br>
|
||
Custo: R$ ${(costPerMeter * 0.56).toFixed(2)}/m (${((1 - 0.56) * 100).toFixed(0)}% menos)<br>
|
||
⚠️ Tenacidade reduzida - Use em estruturas baixas<br><br>
|
||
` : ''}
|
||
|
||
${standardClass !== 'C' ? `
|
||
<strong>🏆 OPÇÃO PREMIUM (Máxima Qualidade):</strong><br>
|
||
PADRÃO: Classe C (Soldagem Crítica)<br>
|
||
Eletrodo: E8018 (maior tenacidade)<br>
|
||
Passes: 3-4 | Perna: 6mm<br>
|
||
Processo: SAW (qualidade automática)<br>
|
||
Inspeção: Visual 100% + UT 100% + RT 20%<br>
|
||
Custo: R$ ${(costPerMeter * 1.89).toFixed(2)}/m (${((1.89 - 1) * 100).toFixed(0)}% mais)<br>
|
||
✅ Máxima confiabilidade - Use em pontes/crítico
|
||
` : ''}
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('padrao-result').innerHTML = html;
|
||
addToHistory('Padrões Solda', `Classe ${standardClass}, ${electrode}, ${app}`);
|
||
}
|
||
|
||
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)`);
|
||
}
|
||
|
||
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>
|
||
`;
|
||
|
||
addToHistory('Energia de Soldagem', `HI = ${heatInput.toFixed(2)} kJ/mm`);
|
||
}
|
||
|
||
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>
|
||
`;
|
||
|
||
addToHistory('Consumo de Eletrodos', `${consumption.toFixed(2)} kg para ${length}m de solda`);
|
||
}
|
||
|
||
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>
|
||
`;
|
||
}
|
||
|
||
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`);
|
||
}
|
||
|
||
function gerarChecklistCertificado() {
|
||
const normSelect = document.getElementById('cert-norm');
|
||
const resultDiv = document.getElementById('cert-result');
|
||
|
||
// Verificar se os elementos existem
|
||
if (!normSelect || !resultDiv) return;
|
||
|
||
const norm = normSelect.value;
|
||
const requirements = certRequirements[norm] || [];
|
||
|
||
resultDiv.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>
|
||
`;
|
||
}
|
||
|
||
function updatePaintFields() {
|
||
const typeSelect = document.getElementById('paint-type');
|
||
const field3 = document.getElementById('paint-field3');
|
||
const label1 = document.getElementById('paint-label1');
|
||
const label2 = document.getElementById('paint-label2');
|
||
|
||
// Verificar se os elementos existem
|
||
if (!typeSelect || !field3 || !label1 || !label2) return;
|
||
|
||
const type = typeSelect.value;
|
||
|
||
if (type === 'chapa') {
|
||
label1.textContent = 'Comprimento (mm)';
|
||
label2.textContent = 'Largura (mm)';
|
||
field3.style.display = 'none';
|
||
} else if (type === 'perfilW') {
|
||
label1.textContent = 'Comprimento (mm)';
|
||
label2.textContent = 'Altura (mm)';
|
||
field3.style.display = 'none';
|
||
} else if (type === 'tubo') {
|
||
label1.textContent = 'Comprimento (mm)';
|
||
label2.textContent = 'Diâmetro (mm)';
|
||
field3.style.display = 'none';
|
||
} else if (type === 'rhs') {
|
||
const label3 = document.getElementById('paint-label3');
|
||
label1.textContent = 'Comprimento (mm)';
|
||
label2.textContent = 'Largura (mm)';
|
||
if (label3) 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)`);
|
||
|
||
// Add button to send to budget
|
||
const resultDiv = document.getElementById('paint-area-result');
|
||
const existingButton = resultDiv.querySelector('.add-to-budget-btn');
|
||
if (!existingButton) {
|
||
const button = document.createElement('button');
|
||
button.className = 'btn btn-success add-to-budget-btn';
|
||
button.style.marginTop = '16px';
|
||
button.textContent = '💰 Adicionar ao Orçamento';
|
||
button.onclick = () => addAreaPinturaToOrcamento(totalArea, type, dim1, dim2);
|
||
resultDiv.querySelector('.result-box').appendChild(button);
|
||
}
|
||
}
|
||
|
||
function addAreaPinturaToOrcamento(area, type, dim1, dim2) {
|
||
// Switch to orcamento section
|
||
showSection('orcamento');
|
||
|
||
// Set values
|
||
setTimeout(() => {
|
||
document.getElementById('budget-category').value = 'servico';
|
||
updateBudgetTypeOptions();
|
||
|
||
setTimeout(() => {
|
||
const qtyInput = document.getElementById('budget-qty');
|
||
const priceInput = document.getElementById('budget-price');
|
||
const unitInput = document.getElementById('budget-unit');
|
||
|
||
qtyInput.value = area.toFixed(2);
|
||
unitInput.value = 'm²';
|
||
priceInput.value = '40.00';
|
||
priceInput.removeAttribute('readonly');
|
||
priceInput.style.background = 'var(--color-surface)';
|
||
|
||
updateBudgetTotal();
|
||
|
||
alert(`✅ Dados transferidos para Orçamento!\n\nÁrea: ${area.toFixed(2)} m²\n\nAjuste o preço e clique em Adicionar.`);
|
||
}, 200);
|
||
}, 300);
|
||
}
|
||
|
||
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>
|
||
`;
|
||
|
||
addToHistory('Consumo de Tinta', `${volumeTotal.toFixed(2)}L para ${area}m²`);
|
||
}
|
||
|
||
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`);
|
||
}
|
||
|
||
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 atualizarTabelaOrcamentoV2() {
|
||
const tbody = document.getElementById('budget-tbody');
|
||
|
||
if (appState.budgetItems.length === 0) {
|
||
tbody.innerHTML = '<tr><td colspan="8" style="text-align: center; color: var(--color-text-secondary);">Nenhum item adicionado</td></tr>';
|
||
} else {
|
||
// Group by category
|
||
const grouped = {
|
||
material: [],
|
||
servico: [],
|
||
consumivel: [],
|
||
indireto: []
|
||
};
|
||
|
||
appState.budgetItems.forEach(item => {
|
||
grouped[item.category].push(item);
|
||
});
|
||
|
||
let html = '';
|
||
let itemNumber = 1;
|
||
|
||
Object.keys(grouped).forEach(cat => {
|
||
if (grouped[cat].length > 0) {
|
||
const catName = {
|
||
material: 'MATERIAIS',
|
||
servico: 'SERVIÇOS',
|
||
consumivel: 'CONSUMÍVEIS',
|
||
indireto: 'INDIRETOS'
|
||
}[cat];
|
||
|
||
html += `<tr style="background: var(--color-primary); color: var(--color-btn-primary-text); font-weight: bold;">
|
||
<td colspan="8" style="padding: 12px;">📁 ${catName}</td>
|
||
</tr>`;
|
||
|
||
grouped[cat].forEach(item => {
|
||
html += `
|
||
<tr style="border-bottom: 1px solid var(--color-border);">
|
||
<td style="padding: 10px;">${itemNumber++}</td>
|
||
<td>${item.category.toUpperCase()}</td>
|
||
<td><strong>${item.spec}</strong></td>
|
||
<td>${item.qty.toFixed(2)}</td>
|
||
<td>${item.unit}</td>
|
||
<td>R$ ${item.price.toFixed(2)}</td>
|
||
<td style="font-weight: bold; color: var(--color-success);">R$ ${item.total.toFixed(2)}</td>
|
||
<td><button class="btn btn-secondary" style="padding: 6px 12px; font-size: 12px;" onclick="removerItemOrcamento(${item.id})">🗑️</button></td>
|
||
</tr>
|
||
`;
|
||
});
|
||
}
|
||
});
|
||
|
||
tbody.innerHTML = html;
|
||
}
|
||
|
||
atualizarTotalOrcamentoV2();
|
||
}
|
||
|
||
function atualizarTabelaOrcamento() {
|
||
// Legacy function - redirect to new version
|
||
atualizarTabelaOrcamentoV2();
|
||
}
|
||
|
||
function atualizarTotalOrcamentoV2() {
|
||
// Calculate subtotals by category
|
||
const grouped = {
|
||
material: 0,
|
||
servico: 0,
|
||
consumivel: 0,
|
||
indireto: 0
|
||
};
|
||
|
||
appState.budgetItems.forEach(item => {
|
||
grouped[item.category] += item.total;
|
||
});
|
||
|
||
const subtotal = Object.values(grouped).reduce((sum, val) => sum + val, 0);
|
||
const bdi = parseFloat(document.getElementById('budget-bdi').value) || 25;
|
||
const bdiValue = subtotal * (bdi / 100);
|
||
const total = subtotal + bdiValue;
|
||
|
||
const resultDiv = document.getElementById('budget-total');
|
||
resultDiv.innerHTML = `
|
||
<div class="result-box" style="background: var(--color-bg-3); border-left: 4px solid var(--color-success);">
|
||
<div class="result-title">📊 RESUMO FINANCEIRO</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-surface); border-radius: 8px; margin-bottom: 16px;">
|
||
<strong>Subtotais por Categoria:</strong><br><br>
|
||
${grouped.material > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
||
<span>📦 Materiais:</span>
|
||
<strong>R$ ${grouped.material.toFixed(2)}</strong>
|
||
</div>` : ''}
|
||
${grouped.servico > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
||
<span>🔧 Serviços:</span>
|
||
<strong>R$ ${grouped.servico.toFixed(2)}</strong>
|
||
</div>` : ''}
|
||
${grouped.consumivel > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
||
<span>🧰 Consumíveis:</span>
|
||
<strong>R$ ${grouped.consumivel.toFixed(2)}</strong>
|
||
</div>` : ''}
|
||
${grouped.indireto > 0 ? `<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
||
<span>💼 Indiretos:</span>
|
||
<strong>R$ ${grouped.indireto.toFixed(2)}</strong>
|
||
</div>` : ''}
|
||
<hr style="margin: 12px 0; border: 1px solid var(--color-border);">
|
||
<div style="display: flex; justify-content: space-between; font-size: 16px;">
|
||
<span><strong>Subtotal Geral:</strong></span>
|
||
<strong style="color: var(--color-primary);">R$ ${subtotal.toFixed(2)}</strong>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="padding: 16px; background: var(--color-bg-2); border-radius: 8px; margin-bottom: 16px;">
|
||
<div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
|
||
<span>BDI (${bdi}%):</span>
|
||
<strong>R$ ${bdiValue.toFixed(2)}</strong>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="padding: 24px; background: var(--color-bg-3); border-radius: 12px; border: 3px solid var(--color-success); text-align: center;">
|
||
<div style="font-size: 14px; color: var(--color-text-secondary); margin-bottom: 8px;">TOTAL DO ORÇAMENTO</div>
|
||
<div style="font-size: 42px; font-weight: bold; color: var(--color-success);">R$ ${total.toFixed(2)}</div>
|
||
</div>
|
||
|
||
<div style="margin-top: 20px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
|
||
<button class="btn btn-primary" onclick="gerarAnaliseDetalhada()" style="padding: 12px 24px;">📊 Análise Detalhada</button>
|
||
<button class="btn btn-primary" onclick="gerarPDFOrcamento()" style="padding: 12px 24px;">📄 Gerar PDF</button>
|
||
<button class="btn btn-success" onclick="salvarOrcamento()" style="padding: 12px 24px;">💾 Salvar Orçamento</button>
|
||
<button class="btn btn-secondary" onclick="limparOrcamento()" style="padding: 12px 24px;">🗑️ Limpar Tudo</button>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
function atualizarTotalOrcamento() {
|
||
// Legacy function - redirect to new version
|
||
atualizarTotalOrcamentoV2();
|
||
}
|
||
|
||
function gerarPDFOrcamento() {
|
||
const project = document.getElementById('budget-project').value || 'Projeto Sem Nome';
|
||
const date = document.getElementById('budget-date').value || '2025-11-07';
|
||
const region = document.getElementById('budget-region').value;
|
||
|
||
alert(`📄 Gerando PDF do Orçamento:\n\nProjeto: ${project}\nData: ${date}\nRegião: ${region}\n\nTotal de Itens: ${appState.budgetItems.length}\n\nEm ambiente real, isto geraria um PDF profissional.`);
|
||
|
||
addToHistory('PDF Orçamento', `${project} - ${appState.budgetItems.length} itens`);
|
||
}
|
||
|
||
function salvarOrcamento() {
|
||
const project = document.getElementById('budget-project').value || 'Projeto Sem Nome';
|
||
alert(`💾 Orçamento "${project}" salvo com sucesso!\n\nTotal: R$ ${appState.budgetItems.reduce((sum, item) => sum + item.total, 0).toFixed(2)}`);
|
||
addToHistory('Orçamento Salvo', project);
|
||
}
|
||
|
||
function limparOrcamento() {
|
||
if (confirm('⚠️ Deseja realmente limpar todo o orçamento?')) {
|
||
appState.budgetItems = [];
|
||
atualizarTabelaOrcamentoV2();
|
||
alert('✅ Orçamento limpo!');
|
||
}
|
||
}
|
||
|
||
function gerarAnaliseDetalhada() {
|
||
if (appState.budgetItems.length === 0) {
|
||
alert('⚠️ Adicione itens ao orçamento primeiro!');
|
||
return;
|
||
}
|
||
|
||
// Calculate by category
|
||
const grouped = {
|
||
material: 0,
|
||
servico: 0,
|
||
consumivel: 0,
|
||
indireto: 0
|
||
};
|
||
|
||
appState.budgetItems.forEach(item => {
|
||
grouped[item.category] += item.total;
|
||
});
|
||
|
||
const subtotal = Object.values(grouped).reduce((sum, val) => sum + val, 0);
|
||
const bdi = parseFloat(document.getElementById('budget-bdi').value) || 25;
|
||
const total = subtotal * (1 + bdi / 100);
|
||
|
||
// Percentages
|
||
const percMaterial = (grouped.material / subtotal) * 100;
|
||
const percServico = (grouped.servico / subtotal) * 100;
|
||
const percConsumivel = (grouped.consumivel / subtotal) * 100;
|
||
const percIndireto = (grouped.indireto / subtotal) * 100;
|
||
|
||
// Estimate project area (rough estimate)
|
||
const estimatedArea = 1500; // m²
|
||
const costPerM2 = total / estimatedArea;
|
||
|
||
// Timeline estimate
|
||
const weeks = Math.ceil(appState.budgetItems.length / 2) + 2;
|
||
|
||
const html = `
|
||
<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); z-index: 2000; display: flex; align-items: center; justify-content: center; padding: 20px;" onclick="this.remove()">
|
||
<div style="background: var(--color-surface); border-radius: 16px; padding: 32px; max-width: 900px; max-height: 90vh; overflow-y: auto; box-shadow: var(--shadow-lg);" onclick="event.stopPropagation()">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px;">
|
||
<h2 style="color: var(--color-primary); font-size: 28px;">📊 ANÁLISE DETALHADA DO ORÇAMENTO</h2>
|
||
<button onclick="this.closest('div[style*=fixed]').remove()" style="background: none; border: none; font-size: 32px; cursor: pointer; color: var(--color-text-secondary);">×</button>
|
||
</div>
|
||
|
||
<div style="padding: 20px; background: var(--color-bg-1); border-radius: 12px; margin-bottom: 20px;">
|
||
<h3 style="margin-bottom: 16px; color: var(--color-primary);">Composição por Categoria</h3>
|
||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
|
||
${grouped.material > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
|
||
<div style="font-size: 12px; color: var(--color-text-secondary);">Materiais</div>
|
||
<div style="font-size: 24px; font-weight: bold; color: var(--color-success);">${percMaterial.toFixed(0)}%</div>
|
||
<div style="font-size: 14px;">R$ ${grouped.material.toFixed(2)}</div>
|
||
</div>` : ''}
|
||
${grouped.servico > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
|
||
<div style="font-size: 12px; color: var(--color-text-secondary);">Serviços</div>
|
||
<div style="font-size: 24px; font-weight: bold; color: var(--color-warning);">${percServico.toFixed(0)}%</div>
|
||
<div style="font-size: 14px;">R$ ${grouped.servico.toFixed(2)}</div>
|
||
</div>` : ''}
|
||
${grouped.consumivel > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
|
||
<div style="font-size: 12px; color: var(--color-text-secondary);">Consumíveis</div>
|
||
<div style="font-size: 24px; font-weight: bold; color: var(--color-info);">${percConsumivel.toFixed(0)}%</div>
|
||
<div style="font-size: 14px;">R$ ${grouped.consumivel.toFixed(2)}</div>
|
||
</div>` : ''}
|
||
${grouped.indireto > 0 ? `<div style="padding: 12px; background: var(--color-surface); border-radius: 8px;">
|
||
<div style="font-size: 12px; color: var(--color-text-secondary);">Indiretos</div>
|
||
<div style="font-size: 24px; font-weight: bold; color: var(--color-text);">${percIndireto.toFixed(0)}%</div>
|
||
<div style="font-size: 14px;">R$ ${grouped.indireto.toFixed(2)}</div>
|
||
</div>` : ''}
|
||
</div>
|
||
</div>
|
||
|
||
<div style="padding: 20px; background: var(--color-bg-3); border-radius: 12px; margin-bottom: 20px;">
|
||
<h3 style="margin-bottom: 16px; color: var(--color-success);">Custo por Área</h3>
|
||
<p>Considerando área estimada de <strong>${estimatedArea} m²</strong>:</p>
|
||
<div style="font-size: 32px; font-weight: bold; color: var(--color-success); margin: 12px 0;">R$ ${costPerM2.toFixed(2)}/m²</div>
|
||
<p style="font-size: 12px; color: var(--color-text-secondary);">Este valor é uma média estimada baseada no orçamento total</p>
|
||
</div>
|
||
|
||
<div style="padding: 20px; background: var(--color-bg-6); border-radius: 12px; margin-bottom: 20px;">
|
||
<h3 style="margin-bottom: 16px; color: var(--color-warning);">Cronograma Estimado</h3>
|
||
<ul style="list-style: none; padding: 0;">
|
||
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana 1: Fornecimento de Materiais</li>
|
||
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana 2-${Math.min(weeks-2, 3)}: Fabricação</li>
|
||
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana ${Math.min(weeks-1, 4)}-${weeks}: Montagem e Soldagem</li>
|
||
<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">✅ Semana ${weeks+1}: Pintura e Acabamento</li>
|
||
<li style="padding: 8px 0;">✅ Semana ${weeks+2}: Inspeção Final</li>
|
||
</ul>
|
||
<p style="margin-top: 12px; font-weight: bold;">Prazo Total Estimado: ${weeks+2} semanas</p>
|
||
</div>
|
||
|
||
<div style="padding: 20px; background: var(--color-bg-5); border-radius: 12px;">
|
||
<h3 style="margin-bottom: 16px; color: #a855f7;">Fornecedores Envolvidos</h3>
|
||
<ul style="list-style: none; padding: 0;">
|
||
${grouped.material > 0 ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🏭 <strong>Gerdau/Usiminas</strong> - Perfis e Chapas</li>' : ''}
|
||
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('E70') || i.spec.includes('E60')) ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🔥 <strong>Esab/Lincoln</strong> - Eletrodos</li>' : ''}
|
||
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('TINTA')) ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🎨 <strong>Sherwin-Williams/Coral</strong> - Tintas</li>' : ''}
|
||
${grouped.consumivel > 0 && appState.budgetItems.some(i => i.spec.includes('Parafuso')) ? '<li style="padding: 8px 0; border-bottom: 1px solid var(--color-border);">🔩 <strong>Distribuidores Locais</strong> - Parafusos</li>' : ''}
|
||
${grouped.servico > 0 ? '<li style="padding: 8px 0;">👷 <strong>Mão de Obra Especializada</strong> - Soldadores e Montadores</li>' : ''}
|
||
</ul>
|
||
</div>
|
||
|
||
<div style="text-align: center; margin-top: 24px;">
|
||
<button class="btn btn-primary" onclick="this.closest('div[style*=fixed]').remove()" style="padding: 12px 32px;">Fechar Análise</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
|
||
document.body.insertAdjacentHTML('beforeend', html);
|
||
addToHistory('Análise Orçamento', `${appState.budgetItems.length} itens, R$ ${total.toFixed(2)}`);
|
||
}
|
||
|
||
function carregarOrcamentoExemplo() {
|
||
if (appState.budgetItems.length > 0) {
|
||
if (!confirm('Já existem itens no orçamento. Deseja substituí-los com o exemplo?')) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Clear existing items
|
||
appState.budgetItems = [];
|
||
|
||
// Example budget items
|
||
const exampleItems = [
|
||
{id: Date.now() + 1, category: 'material', type: 'perfil_w', spec: 'W250×38', qty: 50, unit: 'm', price: 285, total: 14250},
|
||
{id: Date.now() + 2, category: 'material', type: 'chapa', spec: 'CHAPA 9.5mm', qty: 200, unit: 'm²', price: 74.6, total: 14920},
|
||
{id: Date.now() + 3, category: 'material', type: 'cantoneira', spec: 'L100×100×10', qty: 80, unit: 'm', price: 112.5, total: 9000},
|
||
{id: Date.now() + 4, category: 'consumivel', type: 'consumiveis', spec: 'E7018 (Eletrodo)', qty: 50, unit: 'kg', price: 45, total: 2250},
|
||
{id: Date.now() + 5, category: 'consumivel', type: 'consumiveis', spec: 'TINTA C3 Epóxi', qty: 100, unit: 'L', price: 80, total: 8000},
|
||
{id: Date.now() + 6, category: 'consumivel', type: 'parafusos', spec: 'Parafuso A325 M16', qty: 200, unit: 'un', price: 1.20, total: 240},
|
||
{id: Date.now() + 7, category: 'servico', type: 'servico_custom', spec: 'Soldagem', qty: 1000, unit: 'h', price: 65, total: 65000},
|
||
{id: Date.now() + 8, category: 'servico', type: 'servico_custom', spec: 'Pintura', qty: 500, unit: 'm²', price: 40, total: 20000},
|
||
{id: Date.now() + 9, category: 'indireto', type: 'indireto_custom', spec: 'Transporte', qty: 1, unit: 'un', price: 5000, total: 5000},
|
||
{id: Date.now() + 10, category: 'indireto', type: 'indireto_custom', spec: 'EPI e Segurança', qty: 1, unit: 'un', price: 2000, total: 2000}
|
||
];
|
||
|
||
appState.budgetItems = exampleItems;
|
||
atualizarTabelaOrcamentoV2();
|
||
|
||
alert('✅ Orçamento exemplo carregado com sucesso!\n\n10 itens adicionados\nTotal: R$ 140.660,00');
|
||
}
|
||
|
||
function updateWeightFields() {
|
||
const typeSelect = document.getElementById('weight-type');
|
||
const field3 = document.getElementById('weight-field3');
|
||
const field4 = document.getElementById('weight-field4');
|
||
const label1 = document.getElementById('weight-label1');
|
||
const label2 = document.getElementById('weight-label2');
|
||
const label3 = document.getElementById('weight-label3');
|
||
|
||
// Verificar se os elementos existem
|
||
if (!typeSelect || !field3 || !field4 || !label1 || !label2) return;
|
||
|
||
const type = typeSelect.value;
|
||
|
||
if (type === 'perfilW') {
|
||
label1.textContent = 'Altura (mm)';
|
||
label2.textContent = 'Comprimento (m)';
|
||
field3.style.display = 'none';
|
||
field4.style.display = 'none';
|
||
} else if (type === 'chapa') {
|
||
label1.textContent = 'Largura (mm)';
|
||
label2.textContent = 'Altura (mm)';
|
||
if (label3) label3.textContent = 'Espessura (mm)';
|
||
field3.style.display = 'block';
|
||
field4.style.display = 'none';
|
||
} else if (type === 'tubo') {
|
||
label1.textContent = 'Diâmetro Externo (mm)';
|
||
label2.textContent = 'Comprimento (m)';
|
||
if (label3) label3.textContent = 'Espessura Parede (mm)';
|
||
field3.style.display = 'block';
|
||
field4.style.display = 'none';
|
||
} else if (type === 'barra') {
|
||
label1.textContent = 'Diâmetro (mm)';
|
||
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>
|
||
`;
|
||
|
||
addToHistory('Rigging', `${weight}kg, ${points} pontos, ${angle}° → ${forcePerCable.toFixed(1)}kN/cabo`);
|
||
}
|
||
|
||
// ========================================
|
||
// BUDGET v6.6 FUNCTIONS WITH CSV INTEGRATION
|
||
// ========================================
|
||
|
||
function updateBudgetTypeOptions() {
|
||
const category = document.getElementById('budget-category').value;
|
||
const typeSelect = document.getElementById('budget-type');
|
||
|
||
let options = '<option value="">Selecione...</option>';
|
||
|
||
if (category === 'material') {
|
||
options += '<option value="perfil_w">Perfil W</option>';
|
||
options += '<option value="perfil_i">Perfil I (IPE)</option>';
|
||
options += '<option value="perfil_hp">Perfil HP</option>';
|
||
options += '<option value="cantoneira">Cantoneira</option>';
|
||
options += '<option value="tubo_circ">Tubo Circular</option>';
|
||
options += '<option value="tubo_rhs">Tubo Retangular (RHS)</option>';
|
||
options += '<option value="chapa">Chapa</option>';
|
||
options += '<option value="barra">Barra Redonda</option>';
|
||
} else if (category === 'consumivel') {
|
||
options += '<option value="eletrodo">Eletrodos</option>';
|
||
options += '<option value="parafuso">Parafusos</option>';
|
||
options += '<option value="tinta">Tintas</option>';
|
||
} else if (category === 'servico') {
|
||
options += '<option value="servico_custom">Serviço Customizado</option>';
|
||
} else if (category === 'indireto') {
|
||
options += '<option value="indireto_custom">Custo Indireto</option>';
|
||
}
|
||
|
||
typeSelect.innerHTML = options;
|
||
updateBudgetSpecOptions();
|
||
}
|
||
|
||
async function updateBudgetSpecOptions() {
|
||
const type = document.getElementById('budget-type').value;
|
||
const specSelect = document.getElementById('budget-spec');
|
||
const productInfo = document.getElementById('product-info-display');
|
||
|
||
specSelect.innerHTML = '<option value="">Selecione...</option>';
|
||
productInfo.style.display = 'none';
|
||
|
||
if (!type || type.includes('custom')) {
|
||
return;
|
||
}
|
||
|
||
// Show loading state
|
||
specSelect.innerHTML = '<option value="">Carregando...</option>';
|
||
|
||
// Load data from CSV
|
||
const dados = await carregarCSV(type);
|
||
|
||
specSelect.innerHTML = '<option value="">Selecione...</option>';
|
||
|
||
dados.forEach(item => {
|
||
const option = document.createElement('option');
|
||
option.value = item.id;
|
||
option.textContent = item.nome;
|
||
option.dataset.itemData = JSON.stringify(item);
|
||
specSelect.appendChild(option);
|
||
});
|
||
|
||
if (dados.length === 0) {
|
||
specSelect.innerHTML = '<option value="">Nenhum item encontrado</option>';
|
||
}
|
||
}
|
||
|
||
function autoFillBudgetData() {
|
||
const specSelect = document.getElementById('budget-spec');
|
||
const selectedOption = specSelect.options[specSelect.selectedIndex];
|
||
|
||
if (!selectedOption || !selectedOption.value) {
|
||
document.getElementById('product-info-display').style.display = 'none';
|
||
return;
|
||
}
|
||
|
||
const itemData = JSON.parse(selectedOption.dataset.itemData || '{}');
|
||
const type = document.getElementById('budget-type').value;
|
||
const region = document.getElementById('budget-region').value;
|
||
|
||
// Display product info
|
||
const productDetails = document.getElementById('product-details');
|
||
const productInfo = document.getElementById('product-info-display');
|
||
|
||
let detailsHtml = `<strong>${itemData.nome}</strong><br>`;
|
||
|
||
if (itemData.peso_kg_m) {
|
||
detailsHtml += `Peso: ${itemData.peso_kg_m} kg/m<br>`;
|
||
}
|
||
if (itemData.altura_mm) {
|
||
detailsHtml += `Altura: ${itemData.altura_mm} mm<br>`;
|
||
}
|
||
if (itemData.diametro_mm) {
|
||
detailsHtml += `Diâmetro: ${itemData.diametro_mm} mm<br>`;
|
||
}
|
||
if (itemData.espessura_mm) {
|
||
detailsHtml += `Espessura: ${itemData.espessura_mm} mm<br>`;
|
||
}
|
||
|
||
productDetails.innerHTML = detailsHtml;
|
||
productInfo.style.display = 'block';
|
||
|
||
// Auto-fill unit
|
||
const unitInput = document.getElementById('budget-unit');
|
||
unitInput.value = itemData.unidade || 'm';
|
||
|
||
// Calculate and fill price
|
||
const priceInput = document.getElementById('budget-price');
|
||
let price = 0;
|
||
|
||
if (itemData.custo_kg) {
|
||
price = parseFloat(itemData.custo_kg);
|
||
} else if (itemData.custo_unitario_r) {
|
||
price = parseFloat(itemData.custo_unitario_r);
|
||
} else if (itemData.custo_litro_r) {
|
||
price = parseFloat(itemData.custo_litro_r);
|
||
} else if (itemData.peso_kg_m && regionalPricing[region]) {
|
||
const categoryKey = type.replace('perfil_', '').replace('tubo_', '');
|
||
const pricePerKg = regionalPricing[region][type] || regionalPricing[region][categoryKey] || 7.5;
|
||
price = parseFloat(itemData.peso_kg_m) * pricePerKg;
|
||
}
|
||
|
||
priceInput.value = price.toFixed(2);
|
||
priceInput.removeAttribute('readonly');
|
||
priceInput.style.background = 'var(--color-surface)';
|
||
|
||
updateBudgetTotal();
|
||
}
|
||
|
||
function updateBudgetTotal() {
|
||
const qty = parseFloat(document.getElementById('budget-qty').value) || 0;
|
||
const price = parseFloat(document.getElementById('budget-price').value) || 0;
|
||
const total = qty * price;
|
||
|
||
document.getElementById('budget-item-total').value = `R$ ${total.toFixed(2)}`;
|
||
}
|
||
|
||
function adicionarItemOrcamentoV2() {
|
||
const category = document.getElementById('budget-category').value;
|
||
const type = document.getElementById('budget-type').value;
|
||
const specSelect = document.getElementById('budget-spec');
|
||
const spec = specSelect.options[specSelect.selectedIndex]?.text || 'Item Customizado';
|
||
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 (!type || qty <= 0 || price <= 0) {
|
||
alert('⚠️ Preencha todos os campos corretamente:\n\n- Tipo de Produto\n- Quantidade > 0\n- Preço > 0');
|
||
return;
|
||
}
|
||
|
||
const item = {
|
||
id: Date.now(),
|
||
category: category,
|
||
type: type,
|
||
spec: spec,
|
||
qty: qty,
|
||
unit: unit,
|
||
price: price,
|
||
total: qty * price
|
||
};
|
||
|
||
appState.budgetItems.push(item);
|
||
atualizarTabelaOrcamentoV2();
|
||
|
||
// Clear form
|
||
document.getElementById('budget-spec').value = '';
|
||
document.getElementById('budget-qty').value = '1';
|
||
document.getElementById('budget-price').value = '0';
|
||
document.getElementById('product-info-display').style.display = 'none';
|
||
|
||
alert('✅ Item adicionado ao orçamento com sucesso!');
|
||
}
|
||
|
||
function updateRegionalPricing() {
|
||
// Trigger price recalculation when region changes
|
||
const specSelect = document.getElementById('budget-spec');
|
||
if (specSelect && specSelect.value) {
|
||
autoFillBudgetData();
|
||
}
|
||
}
|
||
|
||
// Initialize budget on load
|
||
function initializeBudget() {
|
||
if (document.getElementById('budget-region')) {
|
||
updateBudgetTypeOptions();
|
||
updateBudgetSpecOptions();
|
||
}
|
||
}
|
||
|
||
// Removido: funções de modal Admin legado (openAdminModal/closeAdminModal)
|
||
|
||
// Preview functions for customization
|
||
function previewColorScheme(scheme) {
|
||
userPreferences.colorScheme = scheme;
|
||
applyUserPreferences();
|
||
savePreferences();
|
||
}
|
||
|
||
function previewFontSize(size) {
|
||
userPreferences.fontSize = size;
|
||
applyUserPreferences();
|
||
savePreferences();
|
||
}
|
||
|
||
function previewFontFamily(family) {
|
||
userPreferences.fontFamily = family;
|
||
applyUserPreferences();
|
||
savePreferences();
|
||
}
|
||
|
||
// Load admin preferences into form
|
||
function loadAdminPreferences() {
|
||
const colorScheme = document.getElementById('adminColorScheme');
|
||
const fontSize = document.getElementById('adminFontSize');
|
||
const fontFamily = document.getElementById('adminFontFamily');
|
||
const themeDefault = document.getElementById('adminThemeDefault');
|
||
const modeDefault = document.getElementById('adminModeDefault');
|
||
|
||
if (colorScheme) colorScheme.value = userPreferences.colorScheme;
|
||
if (fontSize) fontSize.value = userPreferences.fontSize;
|
||
if (fontFamily) fontFamily.value = userPreferences.fontFamily;
|
||
if (themeDefault) themeDefault.value = userPreferences.theme === 'dark' ? 'escuro' : 'claro';
|
||
if (modeDefault) modeDefault.value = appState.expertMode ? 'expert' : 'simples';
|
||
}
|
||
|
||
// Save admin preferences when form changes
|
||
function saveAdminPreferences() {
|
||
const themeDefault = document.getElementById('adminThemeDefault');
|
||
const modeDefault = document.getElementById('adminModeDefault');
|
||
|
||
if (themeDefault) {
|
||
const newTheme = themeDefault.value === 'escuro' ? 'dark' : 'light';
|
||
if (newTheme !== userPreferences.theme) {
|
||
userPreferences.theme = newTheme;
|
||
appState.currentTheme = newTheme;
|
||
applyTheme();
|
||
savePreferences();
|
||
}
|
||
}
|
||
|
||
if (modeDefault) {
|
||
const newMode = modeDefault.value === 'expert';
|
||
if (newMode !== appState.expertMode) {
|
||
appState.expertMode = newMode;
|
||
filterToolsByMode();
|
||
}
|
||
}
|
||
}
|
||
|
||
// Removido: saveAdminConfig legado. Configuração agora é gerenciada por AdminConfigManager
|
||
|
||
// Removido: resetAdminDefaults legado. Reset é feito via AdminConfigManager.resetConfig()
|
||
|
||
function applyAdminConfig() {
|
||
// Update branding elements
|
||
const logoEl = document.getElementById('appLogo');
|
||
const subtitleEl = document.getElementById('appSubtitle');
|
||
const footerEl = document.getElementById('appFooter');
|
||
|
||
if (logoEl) {
|
||
if (adminConfig?.branding?.logo) {
|
||
logoEl.innerHTML = `<img src="${adminConfig.branding.logo}" alt="Logo" class="app-logo-img">`;
|
||
} else {
|
||
logoEl.textContent = '🏗️ ' + adminConfig.appName;
|
||
}
|
||
}
|
||
if (subtitleEl) subtitleEl.textContent = adminConfig.appSubtitle;
|
||
if (footerEl) {
|
||
const p = footerEl.querySelector('p');
|
||
if (p) p.textContent = adminConfig.footerText;
|
||
}
|
||
|
||
// Update page title
|
||
document.title = '🏗️ ' + adminConfig.appName + ' - Plataforma Técnica';
|
||
|
||
// Apply theme
|
||
if (adminConfig.themeDefault === 'escuro') {
|
||
appState.currentTheme = 'dark';
|
||
} else {
|
||
appState.currentTheme = 'light';
|
||
}
|
||
applyTheme();
|
||
|
||
// Apply mode
|
||
if (adminConfig.modeDefault === 'expert' && !appState.expertMode) {
|
||
toggleExpertMode();
|
||
} else if (adminConfig.modeDefault === 'simples' && appState.expertMode) {
|
||
toggleExpertMode();
|
||
}
|
||
|
||
// Filter tools
|
||
filterToolsByMode();
|
||
}
|
||
|
||
// ========================================
|
||
// HELP SYSTEM & USER MANUAL
|
||
// ========================================
|
||
|
||
let currentHelpSection = null;
|
||
|
||
const ajudaDatabase = {
|
||
cev: {
|
||
titulo: '⛗️ CEV Avançado (IIW + Pcm)',
|
||
oQueE: 'CEV (Carbono Equivalente) é um valor calculado que representa a capacidade de endurecimento de um aço durante a soldagem. Valores mais altos indicam maior dificuldade de soldagem e maior risco de trincas.',
|
||
paraQueServe: 'Determinar a dificuldade de soldagem de um aço e recomendar: temperatura de pré-aquecimento necessária, velocidade de soldagem, tipo de eletrodo apropriado e necessidade de PWHT (tratamento térmico pós-soldagem).',
|
||
quandoUsar: 'Sempre que for soldar um aço estrutural ou de alta resistência para verificar a soldabilidade e determinar os cuidados necessários antes de iniciar o processo.',
|
||
avisos: [
|
||
'CEV é apenas um indicador - sempre consulte o fabricante do aço',
|
||
'Valores altos (>0.55) requerem rigoroso controle de processo',
|
||
'Não substitui ensaios de qualidade na prática',
|
||
'Considere ambiente, espessura e restrição da junta'
|
||
],
|
||
campos: [
|
||
{ nome: 'Carbono (C)', unidade: '%', significado: 'Elemento principal que aumenta dureza e reduz ductilidade', intervalo: '0.15-0.35', dica: 'Valores mais altos = mais difícil soldar' },
|
||
{ nome: 'Manganês (Mn)', unidade: '%', significado: 'Aumenta resistência e temperabilidade', intervalo: '0.80-1.50', dica: 'Fator multiplicador do carbono' },
|
||
{ nome: 'Cromo (Cr)', unidade: '%', significado: 'Aumenta resistência à corrosão e dureza', intervalo: '0.05-0.20', dica: 'Elemento de liga menor' },
|
||
{ nome: 'Molibdênio (Mo)', unidade: '%', significado: 'Aumenta temperabilidade', intervalo: '0.02-0.10', dica: 'Forte efeito na temperabilidade' },
|
||
{ nome: 'Vanádio (V)', unidade: '%', significado: 'Aumenta resistência e dureza', intervalo: '0.02-0.05', dica: 'Elemento de liga menor' },
|
||
{ nome: 'Níquel (Ni)', unidade: '%', significado: 'Aumenta tenacidade e resistência ao impacto', intervalo: '0.05-0.15', dica: 'Melhora ductilidade' },
|
||
{ nome: 'Cobre (Cu)', unidade: '%', significado: 'Aumenta resistência à corrosão atmosférica', intervalo: '0.05-0.15', dica: 'Residual do processo' },
|
||
{ nome: 'Espessura', unidade: 'mm', significado: 'Quanto mais espesso, maior resfriamento = maior dureza', intervalo: '10-50', dica: 'Chapa mais espessa = maior pré-aquecimento' }
|
||
],
|
||
resultados: '<h4>CEV IIW (Instituto Internacional de Soldagem)</h4><p><strong>Fórmula:</strong> CEV = C + (Mn/6) + (Cr+Mo+V)/5 + (Ni+Cu)/15</p><p><strong>Interpretação:</strong></p><ul><li><0.35: Excelente soldabilidade, sem pré-aquecimento</li><li>0.35-0.45: Boa soldabilidade, considerar pré-aquecimento</li><li>0.45-0.55: Soldabilidade moderada, pré-aquecimento necessário</li><li>>0.55: Soldabilidade difícil, controle rigoroso necessário</li></ul>',
|
||
referencias: [
|
||
{ titulo: 'IIW - Classification of high strength weld metals', ano: 1988, url: 'https://www.iiw.net' },
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020, url: 'https://www.aws.org' },
|
||
{ titulo: 'NBR 16239 - Soldagem de Aços', ano: 2013 }
|
||
],
|
||
manualRelacionado: ['aco_introducao', 'cev_entendimento', 'preaquecimento_guia']
|
||
},
|
||
preaquecimento: {
|
||
titulo: '🔥 Pré-Aquecimento AWS D1.1',
|
||
oQueE: 'Pré-aquecimento é o processo de elevar a temperatura do material base antes da soldagem para reduzir a taxa de resfriamento e aumentar a ductilidade, prevenindo trincas.',
|
||
paraQueServe: 'Prevenir trincas por resfriamento rápido em aços com alto CEV ou em seções espessas, controlando a formação de estruturas metastabiláveis como martensita.',
|
||
quandoUsar: 'Quando o CEV > 0.35, temperatura ambiente < 5°C, espessura > 20mm, ou conforme especificação do projeto.',
|
||
avisos: [
|
||
'Aplicar pré-aquecimento de forma uniforme em toda a zona afetada pelo calor',
|
||
'Medir com termômetro de contato para garantir temperatura correta',
|
||
'Manter interpass durante toda a soldagem',
|
||
'Não exceder 200°C de temperatura máxima'
|
||
],
|
||
campos: [
|
||
{ nome: 'CEV', unidade: '-', significado: 'Carbono Equivalente do aço', intervalo: '0.2-0.8', dica: 'Calcule com a ferramenta CEV Avançado' },
|
||
{ nome: 'Espessura', unidade: 'mm', significado: 'Espessura da chapa ou seção', intervalo: '5-100', dica: 'Seções maiores exigem mais pré-aq' },
|
||
{ nome: 'Temperatura Ambiente', unidade: '°C', significado: 'Temperatura do local de soldagem', intervalo: '-10 a 40', dica: 'Frio aumenta necessidade de pré-aq' },
|
||
{ nome: 'Tipo de Junta', unidade: '-', significado: 'Configuração da junta', intervalo: 'Simples/Dupla', dica: 'Junta dupla restringe mais' },
|
||
{ nome: 'Restrição', unidade: '-', significado: 'Liberdade de movimento do material', intervalo: 'Baixa/Média/Alta', dica: 'Maior restrição = mais pré-aq' }
|
||
],
|
||
resultados: '<h4>Temperatura de Pré-aquecimento</h4><p><strong>Fórmula AWS D1.1:</strong> T_preaq = 50 + (CEV × 50) + (Espessura/10 × 20)</p><p><strong>Interpass:</strong> Temperatura entre passes: Pré-aq + 25°C (máximo 200°C)</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code - Steel', ano: 2020, url: 'https://www.aws.org' },
|
||
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
|
||
],
|
||
manualRelacionado: ['cev_entendimento', 'soldagem_introducao', 'preaquecimento_guia']
|
||
},
|
||
parafusos: {
|
||
titulo: '🔩 Ligações Parafusadas',
|
||
oQueE: 'Ligações parafusadas são conexões mecânicas que utilizam parafusos de alta resistência para transmitir forças entre elementos estruturais.',
|
||
paraQueServe: 'Dimensionar conexões seguras e verificar capacidade ao cisalhamento, esmagamento e ruptura em bloco conforme NBR 8800 e AISC 360.',
|
||
quandoUsar: 'Quando necessitar de conexões desmontáveis, rápida montagem em campo, ou quando soldagem não é viável.',
|
||
avisos: [
|
||
'Verificar todos os modos de falha: cisalhamento, esmagamento e bloco',
|
||
'Respeitar distâncias mínimas de borda (1.5d)',
|
||
'Espaçamento mínimo entre furos (2.67d)',
|
||
'Usar torque adequado na instalação'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo de Parafuso', unidade: '-', significado: 'Classe de resistência (A325, A490, ISO 8.8, ISO 10.9)', intervalo: 'A325/A490', dica: 'A325 é padrão para estruturas' },
|
||
{ nome: 'Diâmetro', unidade: 'mm', significado: 'Diâmetro nominal do parafuso', intervalo: '12-24', dica: 'Diâmetros maiores = maior capacidade' },
|
||
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de parafusos na ligação', intervalo: '1-20', dica: 'Distribua uniformemente' },
|
||
{ nome: 'Planos de Corte', unidade: '-', significado: 'Quantidade de interfaces cisalhadas', intervalo: '1-2', dica: '2 planos dobra a capacidade' },
|
||
{ nome: 'Força Aplicada', unidade: 'kN', significado: 'Força total a ser transmitida', intervalo: '10-500', dica: 'Força de cálculo (fatorada)' }
|
||
],
|
||
resultados: '<h4>Capacidade ao Cisalhamento</h4><p><strong>Fórmula:</strong> Fv = 0.6 × fy × A × n_planos</p><p>Verifica se capacidade total > força aplicada</p><h4>Verificações Adicionais</h4><ul><li>Esmagamento da chapa</li><li>Ruptura em bloco de cisalhamento</li><li>Distâncias mínimas NBR 8800</li></ul>',
|
||
referencias: [
|
||
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 },
|
||
{ titulo: 'AISC 360-16 - Specification for Structural Steel Buildings', ano: 2016, url: 'https://www.aisc.org' }
|
||
],
|
||
manualRelacionado: ['parafusos_basico', 'cisalhamento_analise']
|
||
},
|
||
'consumo-tinta': {
|
||
titulo: '🎯 Consumo de Tinta',
|
||
oQueE: 'Consumo de tinta é o volume total (em litros) de tinta necessária para pintar uma área com determinada espessura seca (DFT).',
|
||
paraQueServe: 'Calcular a quantidade de tinta para orçamentos e planejar compras de material, considerando perdas e número de demãos.',
|
||
quandoUsar: 'Sempre na fase inicial de planejamento de um projeto de pintura, após calcular a área total a pintar.',
|
||
avisos: [
|
||
'Não esqueça de adicionar perda de 15-25% por respingos e cantos',
|
||
'DFT mínimo garante durabilidade adequada',
|
||
'Cada demão requer intervalo mínimo antes da próxima',
|
||
'Verifique % de sólidos na ficha técnica da tinta'
|
||
],
|
||
campos: [
|
||
{ nome: 'Área Total', unidade: 'm²', significado: 'Área a pintar', intervalo: '10-10000', dica: 'Use ferramenta de cálculo de área antes' },
|
||
{ nome: 'DFT', unidade: 'μm', significado: 'Dry Film Thickness - Espessura da película seca', intervalo: '80-250', dica: 'Confira norma ISO 12944 para sua aplicação' },
|
||
{ nome: '% Sólidos', unidade: '%', significado: 'Percentual de sólidos na tinta', intervalo: '30-95', dica: 'Tipicamente 60% para epóxis' },
|
||
{ nome: 'Número de Demãos', unidade: '-', significado: 'Quantas camadas serão aplicadas', intervalo: '1-4', dica: 'Mais camadas = melhor proteção' },
|
||
{ nome: 'Perdas', unidade: '%', significado: 'Percentual de perda por respingos e cantos', intervalo: '5-25', dica: 'Tipicamente 15%' }
|
||
],
|
||
resultados: '<h4>Cálculo do Volume</h4><p><strong>V_teórico = (DFT × Área) / (1000 × % Sólidos)</strong></p><p><strong>V_com_perdas = V_teórico / (1 - % Perdas)</strong></p><p><strong>V_total = V_com_perdas × Número de Demãos</strong></p>',
|
||
referencias: [
|
||
{ titulo: 'ISO 12944 - Paints and Coatings - Corrosion Protection', ano: 2018, url: 'https://www.iso.org' },
|
||
{ titulo: 'ASTM D3276 - Standard Practice for Paint Application', ano: 2021 }
|
||
],
|
||
manualRelacionado: ['pintura_introducao', 'iso12944']
|
||
},
|
||
dureza: {
|
||
titulo: '🔨 Conversor de Dureza',
|
||
oQueE: 'Conversor que transforma valores entre diferentes escalas de dureza (Brinell, Rockwell C e Vickers) usando correlações normativas.',
|
||
paraQueServe: 'Permitir comparação de valores de dureza medidos em diferentes escalas e estimar propriedades mecânicas do material.',
|
||
quandoUsar: 'Quando tiver medida em uma escala e precisar converter para outra, ou quando quiser estimar resistência a partir da dureza.',
|
||
avisos: [
|
||
'Conversões são aproximadas, use como referência',
|
||
'Para aços carbonos, conversões são mais precisas',
|
||
'HRC só é válido para HB > 200',
|
||
'Estimativas de resistência são aproximadas'
|
||
],
|
||
campos: [
|
||
{ nome: 'Brinell (HB)', unidade: 'HB', significado: 'Dureza Brinell - teste com esfera', intervalo: '100-650', dica: 'Mais comum em certificados' },
|
||
{ nome: 'Rockwell C (HRC)', unidade: 'HRC', significado: 'Dureza Rockwell C - teste com cone de diamante', intervalo: '20-70', dica: 'Comum em ferramentas' },
|
||
{ nome: 'Vickers (HV)', unidade: 'HV', significado: 'Dureza Vickers - teste com pirâmide', intervalo: '100-1000', dica: 'Versátil para todos os materiais' }
|
||
],
|
||
resultados: '<h4>Conversões</h4><p><strong>HRC = HB × 0.0338 - 9.8</strong></p><p><strong>HV = HB × 0.95</strong></p><h4>Estimativa de Resistência</h4><p><strong>fu ≈ HB × 10 MPa</strong></p>',
|
||
referencias: [
|
||
{ titulo: 'ASTM E140 - Hardness Conversion Tables', ano: 2019 },
|
||
{ titulo: 'ISO 18265 - Conversion of hardness values', ano: 2013 }
|
||
],
|
||
manualRelacionado: ['ensaios_introducao', 'dureza_escalas']
|
||
},
|
||
charpy: {
|
||
titulo: '📉 Análise de Charpy',
|
||
oQueE: 'Análise que gera a curva de transição dúctil-frágil a partir de ensaios de impacto Charpy em diferentes temperaturas.',
|
||
paraQueServe: 'Determinar a temperatura de transição dúctil-frágil (TTDF) e avaliar se o material é adequado para serviço em baixas temperaturas.',
|
||
quandoUsar: 'Para estruturas que operam em baixas temperaturas, estruturas offshore, pontes em regiões frias, ou quando especificado em projeto.',
|
||
avisos: [
|
||
'Insira pelo menos 2 pontos temperatura/energia',
|
||
'Ideal: 4 pontos cobrindo ampla faixa de temperatura',
|
||
'TTDF ideal deve ser menor que temperatura de serviço',
|
||
'Energia mínima 27J @ temperatura de projeto'
|
||
],
|
||
campos: [
|
||
{ nome: 'Temperatura', unidade: '°C', significado: 'Temperatura do ensaio Charpy', intervalo: '-60 a +40', dica: 'Cubra ampla faixa de temperatura' },
|
||
{ nome: 'Energia', unidade: 'J', significado: 'Energia absorvida no impacto', intervalo: '5-150', dica: 'Valores altos = mais tenáz' }
|
||
],
|
||
resultados: '<h4>Curva de Transição</h4><p>Gráfico mostra como energia absorvida varia com temperatura</p><p><strong>TTDF (27J):</strong> Temperatura onde energia = 27J</p><p>Material é dúctil acima da TTDF e frágil abaixo</p>',
|
||
referencias: [
|
||
{ titulo: 'ASTM E23 - Standard Test Methods for Notched Bar Impact Testing', ano: 2018, url: 'https://www.astm.org' },
|
||
{ titulo: 'ISO 148-1 - Charpy pendulum impact test', ano: 2016 }
|
||
],
|
||
manualRelacionado: ['ensaios_introducao', 'impacto_charpy']
|
||
},
|
||
orcamento: {
|
||
titulo: '💵 Orçamento Detalhado',
|
||
oQueE: 'Sistema completo de orçamento com base de dados integrada de materiais brasileiros (100+ produtos) e preços regionais.',
|
||
paraQueServe: 'Criar orçamentos detalhados de projetos de estruturas metálicas com materiais, serviços, consumíveis e custos indiretos.',
|
||
quandoUsar: 'Na fase de proposta comercial ou planejamento de compras de um projeto estrutural.',
|
||
avisos: [
|
||
'Selecione a região correta (preços variam)',
|
||
'BDI/Margem deve cobrir custos indiretos e lucro',
|
||
'Verifique preços atualizados com fornecedores',
|
||
'Adicione itens indiretos (transporte, EPI, etc)'
|
||
],
|
||
campos: [
|
||
{ nome: 'Categoria', unidade: '-', significado: 'Tipo do item (Material, Serviço, Consumível, Indireto)', intervalo: '4 opções', dica: 'Organize por categoria' },
|
||
{ nome: 'Tipo de Produto', unidade: '-', significado: 'Categoria específica (Perfil W, Chapa, Eletrodo, etc)', intervalo: '15+ tipos', dica: 'Define lista de produtos' },
|
||
{ nome: 'Especificação', unidade: '-', significado: 'Produto específico do banco de dados', intervalo: '100+ produtos', dica: 'Preço preenche automaticamente' },
|
||
{ nome: 'Quantidade', unidade: 'variável', significado: 'Quantidade do item', intervalo: '> 0', dica: 'Use unidade correta (m, kg, un, m²)' },
|
||
{ nome: 'BDI / Margem', unidade: '%', significado: 'Margem de lucro e custos indiretos', intervalo: '15-35', dica: 'Tipicamente 25%' }
|
||
],
|
||
resultados: '<h4>Cálculo de Total</h4><p><strong>Subtotal = ∑(Quantidade × Preço Unitário)</strong></p><p><strong>BDI = Subtotal × (% BDI)</strong></p><p><strong>TOTAL = Subtotal + BDI</strong></p>',
|
||
referencias: [
|
||
{ titulo: 'SINAPI - Sistema Nacional de Pesquisa de Custos', url: 'https://www.caixa.gov.br' },
|
||
{ titulo: 'Tabela Gerdau - Preços de Aços', ano: 2025 }
|
||
],
|
||
manualRelacionado: ['orcamento_basico', 'bdi_margem']
|
||
},
|
||
seletor: {
|
||
titulo: '🎯 Seletor de Aço Inteligente',
|
||
oQueE: 'Ferramenta que recomenda o aço estrutural mais adequado com base nos requisitos do projeto (carga, ambiente, soldabilidade).',
|
||
paraQueServe: 'Auxiliar na escolha do aço correto considerando resistência mecânica, ambiente corrosivo, custo e disponibilidade.',
|
||
quandoUsar: 'Na fase inicial de projeto, ao especificar materiais para estruturas metálicas.',
|
||
avisos: [
|
||
'Considere sempre o ambiente de exposição (C1-C5)',
|
||
'Verifique disponibilidade regional do aço',
|
||
'Consulte fornecedores para preços atualizados',
|
||
'CEV alto requer cuidados especiais na soldagem'
|
||
],
|
||
campos: [
|
||
{ nome: 'Resistência Requerida', unidade: 'MPa', significado: 'Limite de escoamento mínimo necessário', intervalo: '200-500', dica: 'Conforme cálculo estrutural' },
|
||
{ nome: 'Ambiente', unidade: '-', significado: 'Categoria de corrosividade ISO 12944', intervalo: 'C1-C5', dica: 'C1=interior, C5=marinho' },
|
||
{ nome: 'Soldabilidade', unidade: '-', significado: 'Facilidade de soldagem desejada', intervalo: 'Fácil/Moderada/Difícil', dica: 'Fácil para obra de campo' },
|
||
{ nome: 'Custo', unidade: '-', significado: 'Prioridade de custo', intervalo: 'Baixo/Médio/Alto', dica: 'Baixo = A36, Alto = aços especiais' }
|
||
],
|
||
resultados: '<h4>Recomendação</h4><p>Sistema analisa requisitos e sugere aços compatíveis com propriedades, custo relativo e observações.</p>',
|
||
referencias: [
|
||
{ titulo: 'ASTM A36/A572 - Structural Steel Specifications', ano: 2019 },
|
||
{ titulo: 'EN 10025 - Hot rolled products of structural steels', ano: 2019 }
|
||
],
|
||
manualRelacionado: ['aco_introducao', 'acos_estruturais']
|
||
},
|
||
equivalencias: {
|
||
titulo: '📊 Equivalências Internacionais',
|
||
oQueE: 'Tabela de equivalências entre normas de aços estruturais (ASTM, EN, JIS, NBR) com base em propriedades mecânicas.',
|
||
paraQueServe: 'Identificar aços equivalentes quando especificação original não está disponível ou para comparação entre normas.',
|
||
quandoUsar: 'Ao trabalhar com projetos internacionais ou quando precisar substituir um aço por equivalente de outra norma.',
|
||
avisos: [
|
||
'Equivalências são aproximadas, não exatas',
|
||
'Sempre verifique composição química',
|
||
'Consulte engenheiro para aplicações críticas',
|
||
'Propriedades mecânicas podem variar ligeiramente'
|
||
],
|
||
campos: [
|
||
{ nome: 'Norma Origem', unidade: '-', significado: 'Norma do aço especificado', intervalo: 'ASTM/EN/JIS/NBR', dica: 'Norma do projeto original' },
|
||
{ nome: 'Designação', unidade: '-', significado: 'Código do aço na norma origem', intervalo: 'A36/S235/SS400', dica: 'Conforme certificado' }
|
||
],
|
||
resultados: '<h4>Aços Equivalentes</h4><p>Lista de aços equivalentes em outras normas com propriedades mecânicas comparativas.</p>',
|
||
referencias: [
|
||
{ titulo: 'ISO 4952 - Structural steel - Comparison of grades', ano: 2006 },
|
||
{ titulo: 'Worldwide Guide to Equivalent Irons and Steels', ano: 2006 }
|
||
],
|
||
manualRelacionado: ['equivalencias_normas', 'acos_estruturais']
|
||
},
|
||
comparativo: {
|
||
titulo: '📈 Comparativo de Aços',
|
||
oQueE: 'Ferramenta que compara lado a lado as propriedades de diferentes aços estruturais.',
|
||
paraQueServe: 'Facilitar a escolha entre opções de aços mostrando diferenças em resistência, soldabilidade, custo e aplicações.',
|
||
quandoUsar: 'Quando tiver múltiplas opções de aço e precisar decidir qual é mais adequado para o projeto.',
|
||
avisos: [
|
||
'Compare aços de mesma categoria (estrutural com estrutural)',
|
||
'Considere não apenas resistência, mas também soldabilidade',
|
||
'Custo pode variar significativamente por região',
|
||
'Disponibilidade é fator crítico no Brasil'
|
||
],
|
||
campos: [
|
||
{ nome: 'Aço 1', unidade: '-', significado: 'Primeiro aço para comparação', intervalo: 'Lista de aços', dica: 'Selecione da base de dados' },
|
||
{ nome: 'Aço 2', unidade: '-', significado: 'Segundo aço para comparação', intervalo: 'Lista de aços', dica: 'Selecione da base de dados' },
|
||
{ nome: 'Aço 3', unidade: '-', significado: 'Terceiro aço (opcional)', intervalo: 'Lista de aços', dica: 'Opcional' }
|
||
],
|
||
resultados: '<h4>Tabela Comparativa</h4><p>Mostra fy, fu, alongamento, CEV, tenacidade, custo relativo e aplicações típicas.</p>',
|
||
referencias: [
|
||
{ titulo: 'AISC Steel Construction Manual', ano: 2017 },
|
||
{ titulo: 'Gerdau - Catálogo de Produtos', ano: 2025 }
|
||
],
|
||
manualRelacionado: ['aco_introducao', 'acos_estruturais']
|
||
},
|
||
layout: {
|
||
titulo: '🎯 Layout de Furação',
|
||
oQueE: 'Verificador de distâncias mínimas e máximas para furos de parafusos conforme NBR 8800 e AISC 360.',
|
||
paraQueServe: 'Garantir que o layout de furação atende requisitos normativos de distância de borda e espaçamento entre furos.',
|
||
quandoUsar: 'Ao detalhar conexões parafusadas, antes de executar furação em chapas e perfis.',
|
||
avisos: [
|
||
'Distância mínima de borda: 1.5 × diâmetro',
|
||
'Distância máxima de borda: 12 × espessura',
|
||
'Espaçamento mínimo entre furos: 2.67 × diâmetro',
|
||
'Espaçamento máximo: 300 mm ou 24 × espessura'
|
||
],
|
||
campos: [
|
||
{ nome: 'Diâmetro Parafuso', unidade: 'mm', significado: 'Diâmetro nominal do parafuso', intervalo: '12-30', dica: 'Diâmetro do furo = d + 2mm' },
|
||
{ nome: 'Distância Borda', unidade: 'mm', significado: 'Distância do centro do furo até borda', intervalo: '20-150', dica: 'Mínimo 1.5d' },
|
||
{ nome: 'Espaçamento', unidade: 'mm', significado: 'Distância entre centros de furos', intervalo: '30-300', dica: 'Mínimo 2.67d' },
|
||
{ nome: 'Espessura Chapa', unidade: 'mm', significado: 'Espessura do material furado', intervalo: '5-50', dica: 'Afeta distância máxima' }
|
||
],
|
||
resultados: '<h4>Verificação NBR 8800</h4><p>Indica se layout está conforme, com valores mínimos e máximos permitidos.</p>',
|
||
referencias: [
|
||
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 },
|
||
{ titulo: 'AISC 360-16 - Specification for Structural Steel Buildings', ano: 2016 }
|
||
],
|
||
manualRelacionado: ['parafusos_basico', 'layout_furacao']
|
||
},
|
||
'parafuso-vs-solda': {
|
||
titulo: '⚙️ Parafuso vs Solda',
|
||
oQueE: 'Comparador técnico e econômico entre soluções parafusadas e soldadas para conexões estruturais.',
|
||
paraQueServe: 'Auxiliar na decisão entre parafusar ou soldar, considerando capacidade, custo, prazo e manutenibilidade.',
|
||
quandoUsar: 'Na fase de projeto de conexões, ao avaliar alternativas de ligação.',
|
||
avisos: [
|
||
'Parafusos permitem desmontagem, soldas são permanentes',
|
||
'Soldagem requer qualificação e inspeção rigorosa',
|
||
'Parafusos são mais rápidos em campo',
|
||
'Custo varia conforme região e disponibilidade'
|
||
],
|
||
campos: [
|
||
{ nome: 'Força a Transmitir', unidade: 'kN', significado: 'Esforço total na conexão', intervalo: '10-500', dica: 'Força de cálculo (fatorada)' },
|
||
{ nome: 'Comprimento Conexão', unidade: 'mm', significado: 'Extensão da ligação', intervalo: '100-2000', dica: 'Comprimento disponível' },
|
||
{ nome: 'Tipo Aço', unidade: '-', significado: 'Material base', intervalo: 'A36/A572', dica: 'Afeta resistência da solda' }
|
||
],
|
||
resultados: '<h4>Comparação</h4><p>Mostra solução parafusada (quantidade, tipo) vs soldada (perna, comprimento) com custos estimados.</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
|
||
{ titulo: 'AISC Design Guide 21 - Welded Connections', ano: 2006 }
|
||
],
|
||
manualRelacionado: ['parafusos_basico', 'soldagem_introducao']
|
||
},
|
||
certificado: {
|
||
titulo: '📋 Checklist Certificado',
|
||
oQueE: 'Lista de verificação para análise de certificados de qualidade de materiais (Mill Test Report).',
|
||
paraQueServe: 'Garantir que certificados de aço atendem requisitos normativos e de projeto.',
|
||
quandoUsar: 'Ao receber materiais, antes de liberar para fabricação.',
|
||
avisos: [
|
||
'Verifique correspondência entre lote e certificado',
|
||
'Confirme que propriedades atendem especificação',
|
||
'Análise química deve estar dentro dos limites',
|
||
'Certificado tipo 3.1 requer laboratório independente'
|
||
],
|
||
campos: [
|
||
{ nome: 'Norma Especificada', unidade: '-', significado: 'Norma do material no projeto', intervalo: 'ASTM/EN/NBR', dica: 'Conforme projeto' },
|
||
{ nome: 'Tipo Certificado', unidade: '-', significado: 'Classificação EN 10204', intervalo: '2.1/2.2/3.1/3.2', dica: '3.1 é mais rigoroso' }
|
||
],
|
||
resultados: '<h4>Checklist</h4><p>Lista de itens obrigatórios a verificar no certificado com status de conformidade.</p>',
|
||
referencias: [
|
||
{ titulo: 'EN 10204 - Metallic products - Types of inspection documents', ano: 2004 },
|
||
{ titulo: 'ASTM A6 - General Requirements for Rolled Steel', ano: 2019 }
|
||
],
|
||
manualRelacionado: ['aco_introducao', 'ensaios_introducao']
|
||
},
|
||
ultrassom: {
|
||
titulo: '🏥 Interpretação Ultrassom',
|
||
oQueE: 'Ferramenta para interpretar resultados de ensaios ultrassônicos (UT) em soldas conforme AWS D1.1.',
|
||
paraQueServe: 'Avaliar se descontinuidades detectadas por UT são aceitáveis ou requerem reparo.',
|
||
quandoUsar: 'Após ensaio ultrassônico, para determinar aceitação ou rejeição de soldas.',
|
||
avisos: [
|
||
'Trincas nunca são aceitáveis',
|
||
'Porosidade tem limites de tamanho e quantidade',
|
||
'Falta de fusão é defeito crítico',
|
||
'Sempre consulte norma específica do projeto'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo Descontinuidade', unidade: '-', significado: 'Natureza do defeito', intervalo: 'Poro/Trinca/Fusão', dica: 'Conforme laudo UT' },
|
||
{ nome: 'Tamanho', unidade: 'mm', significado: 'Dimensão da descontinuidade', intervalo: '0.5-10', dica: 'Maior dimensão' },
|
||
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de descontinuidades', intervalo: '1-20', dica: 'Em área de 25mm' },
|
||
{ nome: 'Localização', unidade: '-', significado: 'Posição na solda', intervalo: 'Raiz/Face/Meio', dica: 'Conforme laudo' }
|
||
],
|
||
resultados: '<h4>Avaliação AWS D1.1</h4><p>Indica se defeito é aceitável, requer análise de engenharia ou deve ser reparado.</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
|
||
{ titulo: 'ASME Sec V - Nondestructive Examination', ano: 2019 }
|
||
],
|
||
manualRelacionado: ['ensaios_introducao', 'soldagem_introducao']
|
||
},
|
||
'area-pintura': {
|
||
titulo: '📐 Cálculo de Área',
|
||
oQueE: 'Calculadora de área superficial para diferentes tipos de perfis e elementos estruturais.',
|
||
paraQueServe: 'Determinar área total a pintar para cálculo de consumo de tinta e custo.',
|
||
quandoUsar: 'Antes de orçar pintura, para quantificar área de aplicação.',
|
||
avisos: [
|
||
'Considere todas as faces expostas',
|
||
'Perfis têm área maior que aparentam',
|
||
'Não esqueça de somar áreas internas',
|
||
'Use resultado para ferramenta Consumo de Tinta'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo Elemento', unidade: '-', significado: 'Geometria do elemento', intervalo: 'Chapa/Perfil/Tubo', dica: 'Define cálculo de área' },
|
||
{ nome: 'Dimensões', unidade: 'mm', significado: 'Medidas do elemento', intervalo: 'Variável', dica: 'Conforme tipo selecionado' },
|
||
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de elementos', intervalo: '1-1000', dica: 'Total de peças iguais' }
|
||
],
|
||
resultados: '<h4>Área Total</h4><p>Área superficial em m² considerando todas as faces expostas.</p>',
|
||
referencias: [
|
||
{ titulo: 'ISO 8501-1 - Preparation of steel substrates', ano: 2007 },
|
||
{ titulo: 'Gerdau - Tabela de Perfis', ano: 2025 }
|
||
],
|
||
manualRelacionado: ['pintura_introducao']
|
||
},
|
||
galvanizacao: {
|
||
titulo: '🛡️ Galvanização',
|
||
oQueE: 'Calculadora de espessura de camada de zinco e vida útil esperada para galvanização por imersão a quente.',
|
||
paraQueServe: 'Especificar galvanização adequada e estimar durabilidade conforme ambiente de exposição.',
|
||
quandoUsar: 'Ao especificar proteção anticorrosiva por galvanização.',
|
||
avisos: [
|
||
'Espessura mínima conforme NBR 6323',
|
||
'Ambiente marinho requer camadas mais espessas',
|
||
'Galvanização + pintura (duplex) aumenta vida útil',
|
||
'Verifique se geometria permite imersão'
|
||
],
|
||
campos: [
|
||
{ nome: 'Ambiente', unidade: '-', significado: 'Categoria de exposição', intervalo: 'C1-C5', dica: 'Conforme ISO 12944' },
|
||
{ nome: 'Área Total', unidade: 'm²', significado: 'Área a galvanizar', intervalo: '1-10000', dica: 'Use ferramenta Área' },
|
||
{ nome: 'Espessura Zinco', unidade: 'μm', significado: 'Camada de zinco especificada', intervalo: '45-150', dica: 'Mínimo 85μm para C3' }
|
||
],
|
||
resultados: '<h4>Vida Útil Estimada</h4><p>Anos de proteção esperados conforme ambiente e espessura de zinco.</p>',
|
||
referencias: [
|
||
{ titulo: 'NBR 6323 - Galvanização por imersão a quente', ano: 2020 },
|
||
{ titulo: 'ASTM A123 - Zinc Coating on Iron and Steel', ano: 2017 }
|
||
],
|
||
manualRelacionado: ['pintura_introducao', 'iso12944']
|
||
},
|
||
'custo-pintura': {
|
||
titulo: '💰 Custo Total',
|
||
oQueE: 'Calculadora de custo completo de pintura incluindo material, mão de obra e preparação de superfície.',
|
||
paraQueServe: 'Orçar serviços de pintura com todos os custos envolvidos.',
|
||
quandoUsar: 'Na elaboração de propostas comerciais ou planejamento de custos.',
|
||
avisos: [
|
||
'Inclua custo de preparação de superfície',
|
||
'Mão de obra varia por região',
|
||
'Considere acesso e altura (andaimes)',
|
||
'Adicione margem para imprevistos (10-15%)'
|
||
],
|
||
campos: [
|
||
{ nome: 'Área Total', unidade: 'm²', significado: 'Área a pintar', intervalo: '10-10000', dica: 'Use ferramenta Área' },
|
||
{ nome: 'Sistema Pintura', unidade: '-', significado: 'Esquema de pintura', intervalo: 'C2/C3/C4/C5', dica: 'Conforme ISO 12944' },
|
||
{ nome: 'Preparação', unidade: '-', significado: 'Tipo de preparo', intervalo: 'Manual/Jato', dica: 'Jato é mais caro' },
|
||
{ nome: 'Região', unidade: '-', significado: 'Localização da obra', intervalo: 'SE/S/NE/CO', dica: 'Afeta preços' }
|
||
],
|
||
resultados: '<h4>Custo Total</h4><p>Discrimina custos de material, preparação, aplicação e total geral.</p>',
|
||
referencias: [
|
||
{ titulo: 'SINAPI - Tabela de Preços', ano: 2025 },
|
||
{ titulo: 'ISO 12944 - Paints and varnishes', ano: 2018 }
|
||
],
|
||
manualRelacionado: ['pintura_introducao', 'orcamento_basico']
|
||
},
|
||
secagem: {
|
||
titulo: '⏱️ Tempo de Secagem',
|
||
oQueE: 'Calculadora de tempos de secagem e intervalos entre demãos para diferentes tipos de tinta.',
|
||
paraQueServe: 'Planejar cronograma de pintura respeitando tempos mínimos e máximos entre camadas.',
|
||
quandoUsar: 'Ao programar atividades de pintura em obra.',
|
||
avisos: [
|
||
'Temperatura e umidade afetam secagem',
|
||
'Respeite tempo mínimo entre demãos',
|
||
'Tempo máximo evita perda de aderência',
|
||
'Ventilação acelera secagem'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo Tinta', unidade: '-', significado: 'Resina da tinta', intervalo: 'Epóxi/PU/Alquídica', dica: 'Conforme ficha técnica' },
|
||
{ nome: 'Temperatura', unidade: '°C', significado: 'Temperatura ambiente', intervalo: '5-40', dica: 'Temperatura no local' },
|
||
{ nome: 'Umidade', unidade: '%', significado: 'Umidade relativa', intervalo: '40-85', dica: 'Máximo 85% para PU' },
|
||
{ nome: 'Espessura', unidade: 'μm', significado: 'DFT aplicado', intervalo: '50-200', dica: 'Camadas espessas demoram mais' }
|
||
],
|
||
resultados: '<h4>Tempos de Secagem</h4><p>Ao toque, manuseio, próxima demão e cura total.</p>',
|
||
referencias: [
|
||
{ titulo: 'ISO 9117 - Paints - Drying tests', ano: 2009 },
|
||
{ titulo: 'ASTM D1640 - Drying of Organic Coatings', ano: 2014 }
|
||
],
|
||
manualRelacionado: ['pintura_introducao']
|
||
},
|
||
'inspecao-pintura': {
|
||
titulo: '✔️ Inspeção de Qualidade',
|
||
oQueE: 'Checklist de inspeção de pintura conforme ISO 12944 e NBR 15239.',
|
||
paraQueServe: 'Verificar qualidade da pintura aplicada e identificar não-conformidades.',
|
||
quandoUsar: 'Durante e após aplicação de pintura, antes de liberação final.',
|
||
avisos: [
|
||
'Inspecione cada camada antes da próxima',
|
||
'Meça DFT em múltiplos pontos',
|
||
'Verifique aderência por amostragem',
|
||
'Documente com fotos'
|
||
],
|
||
campos: [
|
||
{ nome: 'Etapa', unidade: '-', significado: 'Fase da inspeção', intervalo: 'Preparo/Aplicação/Final', dica: 'Cada etapa tem checklist' },
|
||
{ nome: 'DFT Medido', unidade: 'μm', significado: 'Espessura medida', intervalo: '50-300', dica: 'Média de 5 pontos' },
|
||
{ nome: 'DFT Especificado', unidade: 'μm', significado: 'Espessura requerida', intervalo: '50-300', dica: 'Conforme projeto' }
|
||
],
|
||
resultados: '<h4>Status Inspeção</h4><p>Indica conformidade e lista não-conformidades encontradas.</p>',
|
||
referencias: [
|
||
{ titulo: 'ISO 12944-7 - Execution and supervision', ano: 2017 },
|
||
{ titulo: 'NBR 15239 - Pintura industrial', ano: 2005 }
|
||
],
|
||
manualRelacionado: ['pintura_introducao', 'iso12944']
|
||
},
|
||
'peso-rigging': {
|
||
titulo: '⚖️ Peso e Rigging',
|
||
oQueE: 'Calculadora de peso de elementos estruturais e planejamento de içamento (rigging).',
|
||
paraQueServe: 'Determinar peso para transporte e especificar equipamentos de elevação adequados.',
|
||
quandoUsar: 'No planejamento de logística, transporte e montagem.',
|
||
avisos: [
|
||
'Adicione margem de segurança (15-25%)',
|
||
'Considere peso de acessórios (lingas, ganchos)',
|
||
'Verifique capacidade do guindaste',
|
||
'Identifique centro de gravidade'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo Elemento', unidade: '-', significado: 'Categoria do elemento', intervalo: 'Perfil/Chapa/Tubo', dica: 'Define cálculo de peso' },
|
||
{ nome: 'Dimensões', unidade: 'mm', significado: 'Medidas do elemento', intervalo: 'Variável', dica: 'Conforme tipo' },
|
||
{ nome: 'Material', unidade: '-', significado: 'Tipo de aço', intervalo: 'A36/A572/Inox', dica: 'Densidade varia' },
|
||
{ nome: 'Quantidade', unidade: 'un', significado: 'Número de elementos', intervalo: '1-1000', dica: 'Total de peças' }
|
||
],
|
||
resultados: '<h4>Peso e Rigging</h4><p>Peso total, capacidade mínima de guindaste e recomendações de içamento.</p>',
|
||
referencias: [
|
||
{ titulo: 'NR-12 - Segurança em Máquinas', ano: 2019 },
|
||
{ titulo: 'ASME B30.20 - Below-the-Hook Lifting Devices', ano: 2018 }
|
||
],
|
||
manualRelacionado: ['orcamento_basico']
|
||
},
|
||
referencia: {
|
||
titulo: '📖 Referência Técnica',
|
||
oQueE: 'Biblioteca de referências técnicas, normas, tabelas e fórmulas para consulta rápida.',
|
||
paraQueServe: 'Acesso rápido a informações técnicas essenciais durante projeto e execução.',
|
||
quandoUsar: 'Sempre que precisar consultar dados técnicos, propriedades de materiais ou requisitos normativos.',
|
||
avisos: [
|
||
'Sempre consulte norma original para aplicações críticas',
|
||
'Dados são para referência, não substituem projeto',
|
||
'Verifique edição atualizada das normas',
|
||
'Propriedades podem variar por fornecedor'
|
||
],
|
||
campos: [
|
||
{ nome: 'Categoria', unidade: '-', significado: 'Tipo de referência', intervalo: 'Normas/Tabelas/Fórmulas', dica: 'Selecione categoria' },
|
||
{ nome: 'Assunto', unidade: '-', significado: 'Tema específico', intervalo: 'Variável', dica: 'Conforme categoria' }
|
||
],
|
||
resultados: '<h4>Informação Técnica</h4><p>Dados, tabelas, fórmulas e referências normativas relevantes.</p>',
|
||
referencias: [
|
||
{ titulo: 'AISC Steel Construction Manual', ano: 2017 },
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
|
||
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
|
||
],
|
||
manualRelacionado: ['aco_introducao', 'parafusos_basico', 'soldagem_introducao']
|
||
},
|
||
|
||
// ABAS DE SOLDAGEM
|
||
filete: {
|
||
titulo: '⚡ Dimensionamento de Soldas de Filete',
|
||
oQueE: 'Solda de filete é uma solda de seção triangular que une duas superfícies aproximadamente perpendiculares. É o tipo mais comum de solda estrutural.',
|
||
paraQueServe: 'Calcular a perna necessária da solda de filete para transmitir uma força específica, considerando o processo de soldagem e o número de passes necessários.',
|
||
quandoUsar: 'Em ligações de vigas a pilares, cantoneiras, reforços, e qualquer conexão onde as peças formam um ângulo (geralmente 90°).',
|
||
avisos: [
|
||
'Perna mínima: 3mm para chapas até 6mm, 5mm para chapas de 6-12mm',
|
||
'Perna máxima: espessura da chapa mais fina',
|
||
'Considerar acessibilidade para soldagem',
|
||
'Verificar distorção em soldas longas'
|
||
],
|
||
campos: [
|
||
{ nome: 'Força a Transmitir', unidade: 'kN', significado: 'Carga que a solda deve suportar', intervalo: '10-500', dica: 'Obtenha do cálculo estrutural' },
|
||
{ nome: 'Comprimento da Solda', unidade: 'mm', significado: 'Extensão total da solda', intervalo: '50-1000', dica: 'Perímetro da conexão' },
|
||
{ nome: 'Tipo de Eletrodo', unidade: '-', significado: 'Resistência do metal de adição', intervalo: 'E60-E100', dica: 'E7018 é o mais comum' },
|
||
{ nome: 'Número de Lados', unidade: '-', significado: 'Solda em um ou ambos os lados', intervalo: '1-2', dica: '2 lados dobra a capacidade' }
|
||
],
|
||
resultados: '<h4>Perna Necessária</h4><p><strong>Fórmula:</strong> a = F / (0.707 × L × f_w × n)</p><p>Onde: a=perna, F=força, L=comprimento, f_w=tensão admissível, n=número de lados</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020, url: 'https://www.aws.org' },
|
||
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
|
||
],
|
||
manualRelacionado: ['soldagem_introducao', 'eletrodos_tipos', 'preaquecimento_guia']
|
||
},
|
||
|
||
energia: {
|
||
titulo: '🔥 Energia de Soldagem (Heat Input)',
|
||
oQueE: 'Energia de soldagem (heat input) é a quantidade de energia térmica transferida para o material base por unidade de comprimento de solda.',
|
||
paraQueServe: 'Controlar a taxa de resfriamento da solda para evitar formação de estruturas frágeis (martensita) e garantir propriedades mecânicas adequadas.',
|
||
quandoUsar: 'Em aços de alta resistência, seções espessas, ou quando especificado em procedimento de soldagem (WPS).',
|
||
avisos: [
|
||
'Heat input muito alto: grão grosseiro, perda de resistência',
|
||
'Heat input muito baixo: resfriamento rápido, trincas',
|
||
'Medir tensão e corrente reais durante soldagem',
|
||
'Considerar eficiência do processo (η)'
|
||
],
|
||
campos: [
|
||
{ nome: 'Voltagem', unidade: 'V', significado: 'Tensão elétrica do arco', intervalo: '20-35', dica: 'Ler no equipamento durante soldagem' },
|
||
{ nome: 'Corrente', unidade: 'A', significado: 'Corrente elétrica do arco', intervalo: '80-300', dica: 'Ajustar conforme diâmetro do eletrodo' },
|
||
{ nome: 'Velocidade', unidade: 'cm/min', significado: 'Velocidade de avanço da soldagem', intervalo: '10-40', dica: 'Medir tempo para soldar 10cm' },
|
||
{ nome: 'Eficiência', unidade: '%', significado: 'Eficiência térmica do processo', intervalo: '60-90', dica: 'SMAW=60%, GMAW=80%, SAW=90%' }
|
||
],
|
||
resultados: '<h4>Heat Input</h4><p><strong>Fórmula:</strong> HI = (V × I × 60 × η) / (1000 × v)</p><p>Resultado em kJ/mm. Típico: 0.5-2.5 kJ/mm</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Heat Input Requirements', ano: 2020 },
|
||
{ titulo: 'ISO 17663 - Welding Heat Input', ano: 2009 }
|
||
],
|
||
manualRelacionado: ['soldagem_introducao', 'preaquecimento_guia', 'cev_entendimento']
|
||
},
|
||
|
||
'consumo-eletrodo': {
|
||
titulo: '📊 Consumo de Eletrodos',
|
||
oQueE: 'Cálculo da quantidade de eletrodos necessários para executar uma determinada quantidade de soldagem, considerando perdas e eficiência.',
|
||
paraQueServe: 'Estimar custos de materiais de soldagem e planejar compras para o projeto.',
|
||
quandoUsar: 'Na fase de orçamento e planejamento de projetos com soldagem.',
|
||
avisos: [
|
||
'Considerar perdas por pontas (15-20%)',
|
||
'Considerar respingos e escória (10-15%)',
|
||
'Adicionar margem de segurança (10%)',
|
||
'Variar conforme habilidade do soldador'
|
||
],
|
||
campos: [
|
||
{ nome: 'Volume de Solda', unidade: 'cm³', significado: 'Volume total de metal depositado', intervalo: '10-10000', dica: 'Calcule: comprimento × área da seção' },
|
||
{ nome: 'Diâmetro Eletrodo', unidade: 'mm', significado: 'Diâmetro do eletrodo usado', intervalo: '2.5-5.0', dica: '3.25mm é o mais comum' },
|
||
{ nome: 'Eficiência', unidade: '%', significado: 'Aproveitamento do eletrodo', intervalo: '50-70', dica: '60% é típico para SMAW' },
|
||
{ nome: 'Densidade', unidade: 'g/cm³', significado: 'Densidade do metal de solda', intervalo: '7.8-7.9', dica: 'Aço: 7.85 g/cm³' }
|
||
],
|
||
resultados: '<h4>Consumo de Eletrodos</h4><p><strong>Fórmula:</strong> Peso = Volume × Densidade / Eficiência</p><p>Resultado em kg de eletrodos necessários</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS Welding Handbook - Consumables', ano: 2020 },
|
||
{ titulo: 'Guia de Consumo de Eletrodos', ano: 2018 }
|
||
],
|
||
manualRelacionado: ['soldagem_introducao', 'eletrodos_tipos', 'orcamento_basico']
|
||
},
|
||
|
||
'sequencia-soldagem': {
|
||
titulo: '🔄 Sequência de Soldagem',
|
||
oQueE: 'Ordem e direção em que os cordões de solda são depositados para minimizar distorções e tensões residuais.',
|
||
paraQueServe: 'Planejar a execução da soldagem para reduzir empenamento, controlar distorções e garantir qualidade dimensional.',
|
||
quandoUsar: 'Em estruturas com múltiplas soldas, chapas finas, ou quando tolerâncias dimensionais são críticas.',
|
||
avisos: [
|
||
'Soldar do centro para as extremidades reduz distorção',
|
||
'Alternar lados em soldas simétricas',
|
||
'Evitar concentração de calor em uma região',
|
||
'Usar gabaritos para peças críticas'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo de Estrutura', unidade: '-', significado: 'Configuração da peça', intervalo: 'Viga/Pilar/Chapa', dica: 'Define estratégia de soldagem' },
|
||
{ nome: 'Número de Soldas', unidade: '-', significado: 'Quantidade de cordões', intervalo: '2-20', dica: 'Mais soldas = mais planejamento' },
|
||
{ nome: 'Espessura', unidade: 'mm', significado: 'Espessura do material', intervalo: '3-50', dica: 'Chapas finas distorcem mais' },
|
||
{ nome: 'Restrição', unidade: '-', significado: 'Liberdade de movimento', intervalo: 'Livre/Restrita', dica: 'Restrita gera mais tensões' }
|
||
],
|
||
resultados: '<h4>Recomendações de Sequência</h4><p>Baseado nas entradas, o sistema sugere a melhor ordem de soldagem e técnicas para minimizar distorções.</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Welding Sequence', ano: 2020 },
|
||
{ titulo: 'Distortion Control in Welding', ano: 2015 }
|
||
],
|
||
manualRelacionado: ['soldagem_introducao', 'sequencia_soldagem', 'preaquecimento_guia']
|
||
},
|
||
|
||
'padroes-soldagem': {
|
||
titulo: '📋 Padrões e Normas de Soldagem',
|
||
oQueE: 'Referências normativas e requisitos técnicos para soldagem estrutural conforme AWS, ASME, NBR e outras normas.',
|
||
paraQueServe: 'Consultar requisitos normativos, símbolos de soldagem, qualificação de procedimentos e inspeção.',
|
||
quandoUsar: 'Durante elaboração de WPS, qualificação de soldadores, inspeção e controle de qualidade.',
|
||
avisos: [
|
||
'Sempre consultar a norma aplicável ao projeto',
|
||
'Verificar edição e ano da norma',
|
||
'Considerar requisitos do cliente',
|
||
'Documentar todos os procedimentos'
|
||
],
|
||
campos: [
|
||
{ nome: 'Norma Aplicável', unidade: '-', significado: 'Código de soldagem do projeto', intervalo: 'AWS/ASME/NBR', dica: 'Definido no projeto' },
|
||
{ nome: 'Tipo de Estrutura', unidade: '-', significado: 'Aplicação da soldagem', intervalo: 'Edifício/Ponte/Vaso', dica: 'Define requisitos específicos' },
|
||
{ nome: 'Categoria', unidade: '-', significado: 'Criticidade da junta', intervalo: 'A/B/C/D', dica: 'A é mais crítica' }
|
||
],
|
||
resultados: '<h4>Requisitos Normativos</h4><p>Consulta de requisitos específicos da norma selecionada, incluindo qualificação, inspeção e aceitação.</p>',
|
||
referencias: [
|
||
{ titulo: 'AWS D1.1 - Structural Welding Code', ano: 2020 },
|
||
{ titulo: 'ASME Section IX - Welding Qualifications', ano: 2021 },
|
||
{ titulo: 'NBR 8800 - Projeto de estruturas de aço', ano: 2008 }
|
||
],
|
||
manualRelacionado: ['soldagem_introducao', 'eletrodos_tipos', 'ensaios_introducao']
|
||
},
|
||
|
||
// ABAS DE PARAFUSOS/CONEXÕES
|
||
'parafusos-cisalhamento': {
|
||
titulo: '🔩 Parafusos ao Cisalhamento',
|
||
oQueE: 'Verificação da resistência de parafusos quando submetidos a forças cortantes (cisalhamento) perpendiculares ao eixo do parafuso.',
|
||
paraQueServe: 'Dimensionar o número e diâmetro de parafusos necessários para resistir a uma força cortante específica.',
|
||
quandoUsar: 'Em ligações onde a força é perpendicular ao eixo dos parafusos (maioria das ligações estruturais).',
|
||
avisos: [
|
||
'Verificar número de planos de corte (simples ou duplo)',
|
||
'Usar parafusos de alta resistência (A325/A490)',
|
||
'Considerar rosca no plano de corte (reduz capacidade)',
|
||
'Aplicar fator de segurança adequado'
|
||
],
|
||
campos: [
|
||
{ nome: 'Tipo de Parafuso', unidade: '-', significado: 'Classe de resistência', intervalo: 'A325/A490/ISO', dica: 'A325 é o mais comum' },
|
||
{ nome: 'Diâmetro', unidade: 'mm', significado: 'Diâmetro nominal do parafuso', intervalo: '12-24', dica: '20mm (3/4") é típico' },
|
||
{ nome: 'Quantidade', unidade: '-', significado: 'Número de parafusos', intervalo: '2-20', dica: 'Mínimo 2 por conexão' },
|
||
{ nome: 'Planos de Corte', unidade: '-', significado: 'Superfícies de cisalhamento', intervalo: '1-2', dica: '2 planos dobra capacidade' },
|
||
{ nome: 'Força Aplicada', unidade: 'kN', significado: 'Carga de projeto', intervalo: '10-500', dica: 'Do cálculo estrutural' }
|
||
],
|
||
resultados: '<h4>Resistência ao Cisalhamento</h4><p><strong>Fórmula:</strong> V_r = n × m × 0.50 × F_u × A_b</p><p>Onde: n=quantidade, m=planos, F_u=resistência, A_b=área</p>',
|
||
referencias: [
|
||
{ titulo: 'NBR 8800 - Ligações Parafusadas', ano: 2008 },
|
||
{ titulo: 'AISC 360 - Specification for Structural Steel Buildings', ano: 2016 }
|
||
],
|
||
manualRelacionado: ['parafusos_basico', 'cisalhamento_analise', 'layout_furacao']
|
||
},
|
||
|
||
'parafusos-esmagamento': {
|
||
titulo: '🔨 Esmagamento de Chapas (Bearing)',
|
||
oQueE: 'Verificação da resistência da chapa ao esmagamento (bearing) causado pela pressão do parafuso contra a parede do furo.',
|
||
paraQueServe: 'Garantir que a chapa não será esmagada ou deformada excessivamente pela pressão dos parafusos.',
|
||
quandoUsar: 'Sempre em conjunto com verificação ao cisalhamento, especialmente em chapas finas ou aços de menor resistência.',
|
||
avisos: [
|
||
'Distância de borda mínima: 1.5d',
|
||
'Espaçamento mínimo entre furos: 2.67d',
|
||
'Chapas finas são mais críticas',
|
||
'Verificar rasgamento da borda'
|
||
],
|
||
campos: [
|
||
{ nome: 'Diâmetro Parafuso', unidade: 'mm', significado: 'Diâmetro do parafuso', intervalo: '12-24', dica: 'Mesmo da verificação ao cisalhamento' },
|
||
{ nome: 'Espessura Chapa', unidade: 'mm', significado: 'Espessura do material', intervalo: '5-25', dica: 'Chapas finas são críticas' },
|
||
{ nome: 'Quantidade', unidade: '-', significado: 'Número de parafusos', intervalo: '2-20', dica: 'Distribuir carga uniformemente' },
|
||
{ nome: 'Tipo de Aço', unidade: '-', significado: 'Resistência do material', intervalo: 'A36/A572/S355', dica: 'Afeta capacidade de esmagamento' },
|
||
{ nome: 'Distância de Borda', unidade: 'mm', significado: 'Distância do furo à borda', intervalo: '20-100', dica: 'Mínimo 1.5 × diâmetro' },
|
||
{ nome: 'Espaçamento', unidade: 'mm', significado: 'Distância entre furos', intervalo: '40-150', dica: 'Mínimo 2.67 × diâmetro' }
|
||
],
|
||
resultados: '<h4>Resistência ao Esmagamento</h4><p><strong>Fórmula:</strong> R_b = 2.4 × d × t × F_u</p><p>Onde: d=diâmetro, t=espessura, F_u=resistência última</p>',
|
||
referencias: [
|
||
{ titulo: 'NBR 8800 - Ligações Parafusadas', ano: 2008 },
|
||
{ titulo: 'AISC 360 - Bearing Strength', ano: 2016 }
|
||
],
|
||
manualRelacionado: ['parafusos_basico', 'layout_furacao', 'acos_estruturais']
|
||
},
|
||
|
||
'parafusos-bloco': {
|
||
titulo: '⚠️ Ruptura em Bloco de Cisalhamento',
|
||
oQueE: 'Modo de falha onde um bloco de material se destaca da chapa por combinação de cisalhamento e tração ao longo de um caminho definido pelos furos.',
|
||
paraQueServe: 'Verificar se a chapa tem resistência suficiente para evitar ruptura em bloco, especialmente em ligações com múltiplos parafusos.',
|
||
quandoUsar: 'Em ligações com 3 ou mais parafusos em linha, cantoneiras, e conexões de extremidade.',
|
||
avisos: [
|
||
'Crítico em cantoneiras e chapas de extremidade',
|
||
'Aumentar distância de borda se necessário',
|
||
'Considerar ambos os modos: cisalhamento e tração',
|
||
'Usar furos padrão (não oversized)'
|
||
],
|
||
campos: [
|
||
{ nome: 'Diâmetro Parafuso', unidade: 'mm', significado: 'Diâmetro dos parafusos', intervalo: '12-24', dica: 'Afeta área líquida' },
|
||
{ nome: 'Quantidade Horizontal', unidade: '-', significado: 'Parafusos na direção da força', intervalo: '2-6', dica: 'Mais parafusos = maior risco' },
|
||
{ nome: 'Quantidade Vertical', unidade: '-', significado: 'Parafusos perpendiculares', intervalo: '1-4', dica: 'Afeta área de cisalhamento' },
|
||
{ nome: 'Espaçamento', unidade: 'mm', significado: 'Distância entre furos', intervalo: '50-100', dica: 'Típico: 3d' },
|
||
{ nome: 'Distância de Borda', unidade: 'mm', significado: 'Distância à borda livre', intervalo: '25-75', dica: 'Crítico para tração' },
|
||
{ nome: 'Espessura', unidade: 'mm', significado: 'Espessura da chapa', intervalo: '6-20', dica: 'Afeta área resistente' },
|
||
{ nome: 'Tipo de Aço', unidade: '-', significado: 'Resistência do material', intervalo: 'A36/A572', dica: 'Define F_u e F_y' }
|
||
],
|
||
resultados: '<h4>Resistência à Ruptura em Bloco</h4><p><strong>Fórmula AISC:</strong> R_bs = 0.6×F_u×A_nv + U_bs×F_u×A_nt</p><p>Onde: A_nv=área líquida cisalhamento, A_nt=área líquida tração</p>',
|
||
referencias: [
|
||
{ titulo: 'AISC 360 - Block Shear Rupture', ano: 2016 },
|
||
{ titulo: 'NBR 8800 - Ruptura em Bloco', ano: 2008 }
|
||
],
|
||
manualRelacionado: ['parafusos_basico', 'cisalhamento_analise', 'layout_furacao']
|
||
}
|
||
};
|
||
|
||
const manualConteudo = {
|
||
aco_introducao: {
|
||
titulo: '📦 Introdução aos Aços',
|
||
secao: 'MATERIAIS',
|
||
conteudo: `
|
||
<h2>O que é um Aço?</h2>
|
||
<p>Aço é uma liga de ferro e carbono, com teor de carbono entre 0.04% e 2%, que oferece propriedades superiores ao ferro puro em termos de resistência, dureza e ductilidade.</p>
|
||
|
||
<h3>Classificação dos Aços</h3>
|
||
<ul>
|
||
<li><strong>Aços Simples (Carbono):</strong> Apenas Fe + C, sem elementos de liga adicionados</li>
|
||
<li><strong>Aços Ligados:</strong> Contêm Mn, Cr, Mo, V, Ni, etc para melhorar propriedades</li>
|
||
<li><strong>Aços Inoxidáveis:</strong> Alto teor de Cr (>10%), excelente resistência à corrosão</li>
|
||
<li><strong>Aços Estruturais:</strong> Otimizados para uso em estruturas (edifícios, pontes, etc)</li>
|
||
</ul>
|
||
|
||
<h3>Propriedades Principais</h3>
|
||
<table class="propriedades-tabela">
|
||
<tr><th>Propriedade</th><th>Definição</th><th>Unidade</th></tr>
|
||
<tr><td>Resistência à Tração (fu)</td><td>Máxima tensão que o aço aguenta</td><td>MPa</td></tr>
|
||
<tr><td>Limite de Escoamento (fy)</td><td>Tensão a partir da qual começa deformação permanente</td><td>MPa</td></tr>
|
||
<tr><td>Alongamento</td><td>Quanto o aço se alonga antes de quebrar</td><td>%</td></tr>
|
||
<tr><td>Dureza</td><td>Resistência ao risco/deformação superficial</td><td>HB, HRC</td></tr>
|
||
<tr><td>Tenacidade</td><td>Capacidade de absorver impactos sem quebrar</td><td>J (Joules)</td></tr>
|
||
</table>
|
||
|
||
<h3>Aços Estruturais Mais Comuns</h3>
|
||
<table>
|
||
<tr><th>Norma</th><th>Designação</th><th>fy (MPa)</th><th>fu (MPa)</th><th>Aplicação</th></tr>
|
||
<tr><td>ASTM</td><td>A36</td><td>250</td><td>400-550</td><td>Uso geral, estruturas comuns</td></tr>
|
||
<tr><td>ASTM</td><td>A572 Gr.50</td><td>345</td><td>450-620</td><td>Estruturas de alta resistência</td></tr>
|
||
<tr><td>EN</td><td>S235</td><td>235</td><td>360-510</td><td>Estruturas gerais (Europa)</td></tr>
|
||
<tr><td>EN</td><td>S355</td><td>355</td><td>510-680</td><td>Estruturas exigentes (Europa)</td></tr>
|
||
</table>
|
||
`
|
||
},
|
||
cev_entendimento: {
|
||
titulo: '⛗️ Entendendo Carbono Equivalente',
|
||
secao: 'MATERIAIS',
|
||
conteudo: `
|
||
<h2>O que é CEV?</h2>
|
||
<p>Carbono Equivalente (CEV) é um valor calculado que representa a "capacidade de endurecimento" de um aço durante a soldagem. Quanto maior o CEV, mais difícil é soldar.</p>
|
||
|
||
<h3>Por que CEV importa?</h3>
|
||
<p>Durante a soldagem, o material próximo à solda esfria muito rapidamente (taxa de resfriamento). Aços com alto CEV endurecem muito durante este resfriamento rápido, podendo desenvolver trincas.</p>
|
||
|
||
<h3>Fórmulas de CEV</h3>
|
||
<div class="formulas-container">
|
||
<h4>CEV IIW (Internacional)</h4>
|
||
<p><strong>CEV = C + (Mn/6) + (Cr+Mo+V)/5 + (Ni+Cu)/15</strong></p>
|
||
</div>
|
||
|
||
<h3>Interpretação de Valores</h3>
|
||
<table class="tabela-interpretacao">
|
||
<tr><th>CEV</th><th>Soldabilidade</th><th>Recomendação</th></tr>
|
||
<tr><td><0.35</td><td style="background: #4caf50; color: white">Excelente</td><td>Nenhuma restrição, soldagem direta</td></tr>
|
||
<tr><td>0.35-0.45</td><td style="background: #ffc107; color: black">Boa</td><td>Considerar pré-aquecimento</td></tr>
|
||
<tr><td>0.45-0.55</td><td style="background: #ff9800; color: white">Moderada</td><td>Pré-aquecimento necessário</td></tr>
|
||
<tr><td>>0.55</td><td style="background: #f44336; color: white">Difícil</td><td>Controle rigoroso + especialista</td></tr>
|
||
</table>
|
||
|
||
<h3>Exemplos Práticos</h3>
|
||
<div class="exemplos-box">
|
||
<p><strong>Exemplo 1: A36</strong></p>
|
||
<p>C=0.20, Mn=0.95, Cr=0.10, Mo=0, V=0, Ni=0, Cu=0</p>
|
||
<p>CEV = 0.20 + (0.95/6) + 0 = <strong>0.36</strong> (Soldável)</p>
|
||
</div>
|
||
`
|
||
},
|
||
preaquecimento_guia: {
|
||
titulo: '🌡️ Guia Completo de Pré-Aquecimento',
|
||
secao: 'SOLDAGEM',
|
||
conteudo: `
|
||
<h2>O que é Pré-Aquecimento?</h2>
|
||
<p>Pré-aquecimento é o processo de elevar a temperatura do material base (e zona ao redor) ANTES de iniciar a soldagem.</p>
|
||
|
||
<h3>Por que Pré-aquecer?</h3>
|
||
<p>Durante a soldagem, o material próximo à solda esfria muito rapidamente. Este resfriamento rápido pode causar:</p>
|
||
<ul>
|
||
<li>📉 Aumento de dureza excessiva</li>
|
||
<li>🔨 Formação de estrutura frágil (martensita)</li>
|
||
<li>⚠️ Risco de trincas (especialmente em aços com alto CEV)</li>
|
||
</ul>
|
||
<p>Pré-aquecimento <strong>reduz a taxa de resfriamento</strong>, permitindo transformação metalúrgica adequada.</p>
|
||
|
||
<h3>Quando Usar?</h3>
|
||
<table>
|
||
<tr><th>Situação</th><th>CEV</th><th>Recomendação</th></tr>
|
||
<tr><td>Aço simples + espessura fina</td><td><0.35</td><td>❌ Não necessário</td></tr>
|
||
<tr><td>Aço estrutural comum</td><td>0.35-0.45</td><td>⚠️ Considerar</td></tr>
|
||
<tr><td>Aço de alta resistência</td><td>0.45-0.55</td><td>✅ Necessário</td></tr>
|
||
<tr><td>Aço muito ligado</td><td>>0.55</td><td>🔴 Crítico</td></tr>
|
||
</table>
|
||
|
||
<h3>Instruções Práticas</h3>
|
||
<ol>
|
||
<li><strong>Medir:</strong> Use termômetro de contato em vários pontos</li>
|
||
<li><strong>Aquecer:</strong> Maçarico, resistência, forno - qualquer método vale</li>
|
||
<li><strong>Verificar:</strong> Confirme temperatura antes de soldar</li>
|
||
<li><strong>Manter:</strong> Mantenha interpass durante toda soldagem</li>
|
||
<li><strong>Esfriar:</strong> Deixe esfriar lentamente (não molhe bruscamente!)</li>
|
||
</ol>
|
||
`
|
||
},
|
||
soldagem_introducao: {
|
||
titulo: '🔥 Introdução à Soldagem',
|
||
secao: 'SOLDAGEM',
|
||
conteudo: `
|
||
<h2>O que é Soldagem?</h2>
|
||
<p>Soldagem é um processo de união de materiais metálicos por fusão, onde as peças são aquecidas até o ponto de fusão, permitindo que se fundam e formem uma junta única e contínua.</p>
|
||
|
||
<h3>Processos de Soldagem Principais</h3>
|
||
<ul>
|
||
<li><strong>SMAW (Eletrodo Revestido):</strong> Processo manual mais comum</li>
|
||
<li><strong>GMAW (MIG/MAG):</strong> Soldagem com arame contínuo e gás de proteção</li>
|
||
<li><strong>GTAW (TIG):</strong> Alta qualidade, ideal para aços inoxidáveis</li>
|
||
<li><strong>FCAW:</strong> Arame tubular, produtivo</li>
|
||
</ul>
|
||
|
||
<h3>Fatores Críticos</h3>
|
||
<p>Para uma boa solda, considere:</p>
|
||
<ol>
|
||
<li>Limpeza da superfície</li>
|
||
<li>Pré-aquecimento adequado</li>
|
||
<li>Velocidade de soldagem controlada</li>
|
||
<li>Energia de soldagem (Heat Input) apropriada</li>
|
||
<li>Proteção gasosa eficaz</li>
|
||
</ol>
|
||
`
|
||
}
|
||
};
|
||
|
||
const manualNavStructure = {
|
||
'MATERIAIS': ['aco_introducao', 'cev_entendimento', 'equivalencias_normas', 'acos_estruturais'],
|
||
'CONEXÕES': ['parafusos_basico', 'cisalhamento_analise', 'layout_furacao'],
|
||
'SOLDAGEM': ['soldagem_introducao', 'preaquecimento_guia', 'eletrodos_tipos', 'sequencia_soldagem'],
|
||
'ENSAIOS': ['ensaios_introducao', 'dureza_escalas', 'impacto_charpy'],
|
||
'PINTURA': ['pintura_introducao', 'iso12944', 'preparo_superficie'],
|
||
'ORÇAMENTO': ['orcamento_basico', 'bdi_margem', 'precos_mercado']
|
||
};
|
||
|
||
// Add more manual content
|
||
manualConteudo.parafusos_basico = {
|
||
titulo: '🔩 Introdução a Parafusos',
|
||
secao: 'CONEXÕES',
|
||
conteudo: `
|
||
<h2>O que são Parafusos Estruturais?</h2>
|
||
<p>Parafusos estruturais são elementos de fixação de alta resistência projetados para transmitir forças entre componentes de estruturas metálicas.</p>
|
||
|
||
<h3>Tipos Principais</h3>
|
||
<table>
|
||
<tr><th>Tipo</th><th>fy (MPa)</th><th>fu (MPa)</th><th>Aplicação</th></tr>
|
||
<tr><td><strong>ASTM A325</strong></td><td>400</td><td>635</td><td>Estruturas gerais (padrão)</td></tr>
|
||
<tr><td><strong>ASTM A490</strong></td><td>565</td><td>895</td><td>Alta resistência</td></tr>
|
||
<tr><td><strong>ISO 8.8</strong></td><td>640</td><td>800</td><td>Padrão métrico</td></tr>
|
||
<tr><td><strong>ISO 10.9</strong></td><td>900</td><td>1000</td><td>Máxima resistência</td></tr>
|
||
</table>
|
||
|
||
<h3>Componentes da Ligação</h3>
|
||
<ul>
|
||
<li><strong>Parafuso:</strong> Elemento principal com rosca</li>
|
||
<li><strong>Porca:</strong> Elemento de fixação roscado</li>
|
||
<li><strong>Arruela:</strong> Distribui tensão e protege superfície</li>
|
||
</ul>
|
||
|
||
<h3>Modos de Falha</h3>
|
||
<ol>
|
||
<li><strong>Cisalhamento do Parafuso:</strong> Ruptura do corpo do parafuso</li>
|
||
<li><strong>Esmagamento da Chapa:</strong> Deformação da chapa no furo</li>
|
||
<li><strong>Ruptura em Bloco:</strong> Ruptura de seção da chapa</li>
|
||
<li><strong>Tração:</strong> Ruptura do parafuso por tração</li>
|
||
</ol>
|
||
`
|
||
};
|
||
|
||
manualConteudo.cisalhamento_analise = {
|
||
titulo: '🔧 Análise de Cisalhamento',
|
||
secao: 'CONEXÕES',
|
||
conteudo: `
|
||
<h2>Cisalhamento em Parafusos</h2>
|
||
<p>O cisalhamento é o modo de falha mais comum em ligações parafusadas, onde o parafuso é cortado transversalmente pela força aplicada.</p>
|
||
|
||
<h3>Fórmula de Verificação</h3>
|
||
<div class="formulas-container">
|
||
<p><strong>Fv = 0.6 × fy × A × n</strong></p>
|
||
<p>Onde:</p>
|
||
<ul>
|
||
<li>Fv = Resistência ao cisalhamento (kN)</li>
|
||
<li>fy = Limite de escoamento do parafuso (MPa)</li>
|
||
<li>A = Área do parafuso (mm²)</li>
|
||
<li>n = Número de planos de corte (1 ou 2)</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<h3>Planos de Corte</h3>
|
||
<p><strong>Plano Simples (n=1):</strong> Parafuso cortado em um ponto</p>
|
||
<p><strong>Plano Duplo (n=2):</strong> Parafuso cortado em dois pontos - DOBRA a capacidade!</p>
|
||
|
||
<h3>Exemplo Prático</h3>
|
||
<div class="exemplos-box">
|
||
<p><strong>Parafuso A325 Ø16mm</strong></p>
|
||
<p>fy = 400 MPa, A = π(16/2)² = 201 mm²</p>
|
||
<p><strong>Plano Simples:</strong> Fv = 0.6 × 400 × 201 / 1000 = 48.2 kN</p>
|
||
<p><strong>Plano Duplo:</strong> Fv = 48.2 × 2 = 96.4 kN ✅</p>
|
||
</div>
|
||
`
|
||
};
|
||
|
||
manualConteudo.pintura_introducao = {
|
||
titulo: '🎨 Introdução à Pintura Industrial',
|
||
secao: 'PINTURA',
|
||
conteudo: `
|
||
<h2>Sistemas de Pintura</h2>
|
||
<p>Pintura industrial é um sistema de proteção anticorrosiva composto por múltiplas camadas (demãos) que protegem o aço contra degradação.</p>
|
||
|
||
<h3>Componentes do Sistema</h3>
|
||
<ol>
|
||
<li><strong>Fundo (Primer):</strong> Primeira camada, aderência e proteção</li>
|
||
<li><strong>Intermediário:</strong> Aumenta espessura e proteção</li>
|
||
<li><strong>Acabamento:</strong> Proteção UV e estética</li>
|
||
</ol>
|
||
|
||
<h3>Tipos de Tinta</h3>
|
||
<table>
|
||
<tr><th>Tipo</th><th>Características</th><th>Aplicação</th></tr>
|
||
<tr><td><strong>Epóxi</strong></td><td>Excelente adesão, química</td><td>Fundo e intermediário</td></tr>
|
||
<tr><td><strong>Poliuretano</strong></td><td>Resistência UV, brilho</td><td>Acabamento</td></tr>
|
||
<tr><td><strong>Alquídica</strong></td><td>Econômica, secagem lenta</td><td>Ambientes leves</td></tr>
|
||
<tr><td><strong>Zinc-Rich</strong></td><td>Proteção galvânica</td><td>Ambientes agressivos</td></tr>
|
||
</table>
|
||
`
|
||
};
|
||
|
||
manualConteudo.iso12944 = {
|
||
titulo: '🎯 ISO 12944 - Classificação de Ambientes',
|
||
secao: 'PINTURA',
|
||
conteudo: `
|
||
<h2>ISO 12944 - Padrão Internacional</h2>
|
||
<p>ISO 12944 classifica ambientes de corrosividade e especifica sistemas de pintura adequados para cada categoria.</p>
|
||
|
||
<h3>Categorias de Corrosividade</h3>
|
||
<table>
|
||
<tr><th>Classe</th><th>Ambiente</th><th>DFT Mín (μm)</th><th>Vida Útil</th></tr>
|
||
<tr><td><strong>C1</strong></td><td>Interior seco (escritório)</td><td>80</td><td>5-10 anos</td></tr>
|
||
<tr><td><strong>C2</strong></td><td>Interior úmido (ginásio)</td><td>120</td><td>5-10 anos</td></tr>
|
||
<tr><td><strong>C3</strong></td><td>Exterior urbano/costeiro</td><td>160</td><td>10-15 anos</td></tr>
|
||
<tr><td><strong>C4</strong></td><td>Industrial/marinho moderado</td><td>200</td><td>15-20 anos</td></tr>
|
||
<tr><td><strong>C5</strong></td><td>Marinho agressivo/offshore</td><td>250</td><td>20+ anos</td></tr>
|
||
</table>
|
||
|
||
<h3>Sistemas Recomendados por Categoria</h3>
|
||
<div class="exemplos-box">
|
||
<p><strong>C3 (Padrão Indústria):</strong></p>
|
||
<ul>
|
||
<li>Fundo: Epóxi 60μm</li>
|
||
<li>Intermediário: Epóxi 60μm</li>
|
||
<li>Acabamento: Poliuretano 40μm</li>
|
||
<li><strong>Total: 160μm</strong></li>
|
||
</ul>
|
||
</div>
|
||
`
|
||
};
|
||
|
||
manualConteudo.orcamento_basico = {
|
||
titulo: '💰 Conceitos Básicos de Orçamento',
|
||
secao: 'ORÇAMENTO',
|
||
conteudo: `
|
||
<h2>Estrutura de um Orçamento</h2>
|
||
<p>Orçamento é a estimativa detalhada de todos os custos envolvidos em um projeto.</p>
|
||
|
||
<h3>Categorias de Custos</h3>
|
||
<ol>
|
||
<li><strong>Materiais:</strong> Perfis, chapas, parafusos</li>
|
||
<li><strong>Serviços:</strong> Mão de obra especializada</li>
|
||
<li><strong>Consumíveis:</strong> Eletrodos, tintas, gases</li>
|
||
<li><strong>Indiretos:</strong> Transporte, EPI, aluguel de equipamentos</li>
|
||
</ol>
|
||
|
||
<h3>Como Calcular Preço de Materiais</h3>
|
||
<p>Para perfis e chapas: <strong>Preço = Peso × Preço/kg</strong></p>
|
||
<p>Preços variam por região do Brasil:</p>
|
||
<ul>
|
||
<li>Sudeste: R$ 7.50/kg (referência)</li>
|
||
<li>Sul: R$ 7.20/kg (mais barato)</li>
|
||
<li>Nordeste: R$ 8.00/kg</li>
|
||
<li>Centro-Oeste: R$ 7.70/kg</li>
|
||
</ul>
|
||
`
|
||
};
|
||
|
||
manualConteudo.bdi_margem = {
|
||
titulo: '📊 BDI e Margem de Lucro',
|
||
secao: 'ORÇAMENTO',
|
||
conteudo: `
|
||
<h2>O que é BDI?</h2>
|
||
<p>BDI (Benefícios e Despesas Indiretas) é um percentual aplicado sobre os custos diretos para cobrir:</p>
|
||
|
||
<h3>Componentes do BDI</h3>
|
||
<ul>
|
||
<li><strong>Administração Central:</strong> Escritório, contabilidade (5-8%)</li>
|
||
<li><strong>Lucro:</strong> Margem de lucro da empresa (8-15%)</li>
|
||
<li><strong>Impostos:</strong> ISS, PIS, COFINS (5-10%)</li>
|
||
<li><strong>Riscos:</strong> Contingência para imprevistos (2-5%)</li>
|
||
</ul>
|
||
|
||
<h3>BDI Típico por Tipo de Obra</h3>
|
||
<table>
|
||
<tr><th>Tipo de Obra</th><th>BDI Típico</th></tr>
|
||
<tr><td>Pequenas estruturas</td><td>20-25%</td></tr>
|
||
<tr><td>Edifícios comerciais</td><td>25-30%</td></tr>
|
||
<tr><td>Pontes e obras públicas</td><td>25-28%</td></tr>
|
||
<tr><td>Offshore e projetos complexos</td><td>30-35%</td></tr>
|
||
</table>
|
||
|
||
<h3>Exemplo de Cálculo</h3>
|
||
<div class="exemplos-box">
|
||
<p><strong>Custos Diretos:</strong> R$ 100.000,00</p>
|
||
<p><strong>BDI:</strong> 25%</p>
|
||
<p><strong>Valor BDI:</strong> R$ 100.000 × 0.25 = R$ 25.000,00</p>
|
||
<p><strong>TOTAL:</strong> R$ 125.000,00</p>
|
||
</div>
|
||
`
|
||
};
|
||
|
||
manualConteudo.ensaios_introducao = {
|
||
titulo: '✅ Introdução a Ensaios',
|
||
secao: 'ENSAIOS',
|
||
conteudo: `
|
||
<h2>Por que Ensaiar?</h2>
|
||
<p>Ensaios são testes realizados em materiais e soldas para verificar conformidade com especificações e normas.</p>
|
||
|
||
<h3>Tipos de Ensaios</h3>
|
||
<h4>Ensaios Destrutivos</h4>
|
||
<ul>
|
||
<li><strong>Tração:</strong> Mede fy, fu e alongamento</li>
|
||
<li><strong>Dureza:</strong> Mede resistência à penetração</li>
|
||
<li><strong>Charpy:</strong> Mede tenacidade ao impacto</li>
|
||
<li><strong>Dobramento:</strong> Verifica ductilidade da solda</li>
|
||
</ul>
|
||
|
||
<h4>Ensaios Não Destrutivos (END)</h4>
|
||
<ul>
|
||
<li><strong>Ultrassom (UT):</strong> Detecta defeitos internos</li>
|
||
<li><strong>Radiografia (RT):</strong> Imagem de defeitos</li>
|
||
<li><strong>Partículas Magnéticas (MT):</strong> Defeitos superficiais</li>
|
||
<li><strong>Líquido Penetrante (PT):</strong> Trincas superficiais</li>
|
||
</ul>
|
||
`
|
||
};
|
||
|
||
manualConteudo.dureza_escalas = {
|
||
titulo: '🔨 Escalas de Dureza',
|
||
secao: 'ENSAIOS',
|
||
conteudo: `
|
||
<h2>Escalas de Dureza</h2>
|
||
<p>Dureza mede a resistência de um material à deformação permanente por indentação.</p>
|
||
|
||
<h3>Brinell (HB)</h3>
|
||
<p><strong>Método:</strong> Esfera de aço ou tungstênio pressionada na superfície</p>
|
||
<p><strong>Faixa:</strong> 100-650 HB</p>
|
||
<p><strong>Aplicação:</strong> Aços estruturais, ferro fundido</p>
|
||
|
||
<h3>Rockwell C (HRC)</h3>
|
||
<p><strong>Método:</strong> Cone de diamante</p>
|
||
<p><strong>Faixa:</strong> 20-70 HRC</p>
|
||
<p><strong>Aplicação:</strong> Aços temperados, ferramentas</p>
|
||
|
||
<h3>Vickers (HV)</h3>
|
||
<p><strong>Método:</strong> Pirâmide de diamante</p>
|
||
<p><strong>Faixa:</strong> 100-1000+ HV</p>
|
||
<p><strong>Aplicação:</strong> Universal, todos os materiais</p>
|
||
|
||
<h3>Correlação com Resistência</h3>
|
||
<p>Para aços carbono:</p>
|
||
<p><strong>fu (MPa) ≈ HB × 10</strong></p>
|
||
<div class="exemplos-box">
|
||
<p>HB 250 → fu ≈ 2500 MPa</p>
|
||
</div>
|
||
`
|
||
};
|
||
|
||
manualConteudo.impacto_charpy = {
|
||
titulo: '📉 Ensaio de Impacto Charpy',
|
||
secao: 'ENSAIOS',
|
||
conteudo: `
|
||
<h2>O que é o Ensaio Charpy?</h2>
|
||
<p>Ensaio que mede a energia absorvida por um corpo de prova entalhado ao ser rompido por um pêndulo.</p>
|
||
|
||
<h3>Por que é Importante?</h3>
|
||
<p>Materiais podem se comportar de forma <strong>dúctil</strong> (absorvem energia) ou <strong>frágil</strong> (quebram subitamente) dependendo da temperatura.</p>
|
||
|
||
<h3>Temperatura de Transição (TTDF)</h3>
|
||
<p>Temperatura onde o material muda de comportamento dúctil para frágil.</p>
|
||
<p><strong>Critério comum:</strong> TTDF = temperatura onde energia = 27J</p>
|
||
|
||
<h3>Requisitos por Aplicação</h3>
|
||
<table>
|
||
<tr><th>Aplicação</th><th>Energia Mín</th><th>Temperatura</th></tr>
|
||
<tr><td>Estruturas internas</td><td>27J</td><td>0°C</td></tr>
|
||
<tr><td>Estruturas externas</td><td>27J</td><td>-20°C</td></tr>
|
||
<tr><td>Offshore/Ártico</td><td>40J</td><td>-40°C</td></tr>
|
||
</table>
|
||
`
|
||
};
|
||
|
||
manualConteudo.layout_furacao = {
|
||
titulo: '📍 Layout de Furação',
|
||
secao: 'CONEXÕES',
|
||
conteudo: `
|
||
<h2>Distâncias e Espaçamentos</h2>
|
||
<p>NBR 8800 e AISC 360 estabelecem limites para garantir resistência adequada.</p>
|
||
|
||
<h3>Distância de Borda</h3>
|
||
<p><strong>Mínimo:</strong> 1.5d (evita ruptura da borda)</p>
|
||
<p><strong>Máximo:</strong> 12t ou 150mm (evita empenamento)</p>
|
||
|
||
<h3>Espaçamento entre Furos</h3>
|
||
<p><strong>Mínimo:</strong> 2.67d (evita interferência de tensões)</p>
|
||
<p><strong>Máximo:</strong> 300mm (evita correlação local)</p>
|
||
|
||
<h3>Exemplo</h3>
|
||
<div class="exemplos-box">
|
||
<p><strong>Parafuso Ø20mm, Chapa 10mm</strong></p>
|
||
<p>Mínimo borda: 1.5 × 20 = 30mm</p>
|
||
<p>Máximo borda: 12 × 10 = 120mm</p>
|
||
<p>Mínimo espaçamento: 2.67 × 20 = 53.4mm</p>
|
||
</div>
|
||
`
|
||
};
|
||
|
||
manualConteudo.eletrodos_tipos = {
|
||
titulo: '🔥 Tipos de Eletrodos',
|
||
secao: 'SOLDAGEM',
|
||
conteudo: `
|
||
<h2>Eletrodos Revestidos (SMAW)</h2>
|
||
<p>Eletrodo revestido é composto por alma metálica + revestimento que gera escória protetora e gás.</p>
|
||
|
||
<h3>Classificação AWS</h3>
|
||
<table>
|
||
<tr><th>Eletrodo</th><th>Revestimento</th><th>Resistência</th><th>Aplicação</th></tr>
|
||
<tr><td><strong>E6013</strong></td><td>Rutílico</td><td>420 MPa</td><td>Geral, fácil</td></tr>
|
||
<tr><td><strong>E7018</strong></td><td>Básico</td><td>485 MPa</td><td>Estrutural (padrão)</td></tr>
|
||
<tr><td><strong>E8018</strong></td><td>Básico</td><td>550 MPa</td><td>Alta resistência</td></tr>
|
||
</table>
|
||
|
||
<h3>Vantagens do Básico (E7018)</h3>
|
||
<ul>
|
||
<li>✅ Baixo hidrogênio (previne trincas)</li>
|
||
<li>✅ Alta tenacidade (Charpy 47J)</li>
|
||
<li>✅ Excelente para estruturas críticas</li>
|
||
</ul>
|
||
`
|
||
};
|
||
|
||
manualConteudo.sequencia_soldagem = {
|
||
titulo: '🔄 Sequência de Soldagem',
|
||
secao: 'SOLDAGEM',
|
||
conteudo: `
|
||
<h2>Por que Sequência Importa?</h2>
|
||
<p>A ordem de deposição da solda afeta diretamente as distorções e tensões residuais na estrutura.</p>
|
||
|
||
<h3>Padrões de Soldagem</h3>
|
||
<h4>1. Skip Welding (Recomendado)</h4>
|
||
<p>Solda em segmentos alternados, deixando espaços que são preenchidos depois.</p>
|
||
<p><strong>Vantagem:</strong> Reduz distorções em 80%</p>
|
||
|
||
<h4>2. Backstep Welding</h4>
|
||
<p>Soldagem em segmentos curtos na direção oposta ao avanço geral.</p>
|
||
<p><strong>Vantagem:</strong> Reduz distorções em 60%</p>
|
||
|
||
<h4>3. Contínuo (Não Recomendado)</h4>
|
||
<p>Soldagem contínua sem paradas.</p>
|
||
<p><strong>Desvantagem:</strong> Máxima distorção</p>
|
||
`
|
||
};
|
||
|
||
manualConteudo.equivalencias_normas = {
|
||
titulo: '🌍 Equivalências Internacionais',
|
||
secao: 'MATERIAIS',
|
||
conteudo: `
|
||
<h2>Por que Equivalências?</h2>
|
||
<p>Projetos internacionais podem especificar aços de diferentes normas. Conhecer equivalências permite substituição adequada.</p>
|
||
|
||
<h3>Principais Equivalências</h3>
|
||
<table>
|
||
<tr><th>ASTM</th><th>EN</th><th>JIS</th><th>NBR</th></tr>
|
||
<tr><td>A36</td><td>S235JR</td><td>SS400</td><td>-</td></tr>
|
||
<tr><td>A572 Gr.50</td><td>S355J2</td><td>SM490</td><td>AR350</td></tr>
|
||
<tr><td>A588</td><td>S355K2G3</td><td>-</td><td>-</td></tr>
|
||
</table>
|
||
|
||
<h3>⚠️ Cuidados na Substituição</h3>
|
||
<ul>
|
||
<li>Verificar composição química</li>
|
||
<li>Confirmar propriedades mecânicas</li>
|
||
<li>Checar soldabilidade (CEV)</li>
|
||
<li>Validar com engenheiro responsável</li>
|
||
</ul>
|
||
`
|
||
};
|
||
|
||
manualConteudo.acos_estruturais = {
|
||
titulo: '🏭 Aços Estruturais Comuns',
|
||
secao: 'MATERIAIS',
|
||
conteudo: `
|
||
<h2>Aços Mais Usados no Brasil</h2>
|
||
|
||
<h3>ASTM A36 - O "Trabalhador"</h3>
|
||
<p><strong>Propriedades:</strong> fy=250 MPa, fu=400 MPa</p>
|
||
<p><strong>Aplicação:</strong> Estruturas gerais, baixa responsabilidade</p>
|
||
<p><strong>Vantagens:</strong> Barato, muito soldável, disponível</p>
|
||
|
||
<h3>ASTM A572 Gr.50 - O "Profissional"</h3>
|
||
<p><strong>Propriedades:</strong> fy=345 MPa, fu=450 MPa</p>
|
||
<p><strong>Aplicação:</strong> Edifícios altos, pontes, estruturas pesadas</p>
|
||
<p><strong>Vantagens:</strong> Ótima relação custo/benefício</p>
|
||
|
||
<h3>EN S355J2 - O "Europeu"</h3>
|
||
<p><strong>Propriedades:</strong> fy=355 MPa, fu=490 MPa</p>
|
||
<p><strong>Aplicação:</strong> Projetos internacionais</p>
|
||
<p><strong>Vantagens:</strong> Boa tenacidade, amplamente especificado</p>
|
||
`
|
||
};
|
||
|
||
manualConteudo.preparo_superficie = {
|
||
titulo: '🧹 Preparação de Superfície',
|
||
secao: 'PINTURA',
|
||
conteudo: `
|
||
<h2>A Preparação É Fundamental!</h2>
|
||
<p>90% dos problemas de pintura vem de preparação inadequada da superfície.</p>
|
||
|
||
<h3>Graus de Limpeza ISO 8501-1</h3>
|
||
<table>
|
||
<tr><th>Grau</th><th>Descrição</th><th>Uso</th></tr>
|
||
<tr><td><strong>Sa 1</strong></td><td>Jateamento ligeiro</td><td>Não recomendado</td></tr>
|
||
<tr><td><strong>Sa 2</strong></td><td>Jateamento comercial</td><td>Ambientes leves</td></tr>
|
||
<tr><td><strong>Sa 2½</strong></td><td>Jateamento ao metal quase branco</td><td><strong>Padrão indústria</strong></td></tr>
|
||
<tr><td><strong>Sa 3</strong></td><td>Jateamento ao metal branco</td><td>Ambientes severos</td></tr>
|
||
</table>
|
||
|
||
<h3>Métodos de Preparação</h3>
|
||
<ul>
|
||
<li><strong>Jateamento Abrasivo:</strong> Método mais eficaz</li>
|
||
<li><strong>Lixamento Mecânico:</strong> Para pequenas áreas</li>
|
||
<li><strong>Escovamento:</strong> Manutenção apenas</li>
|
||
<li><strong>Desengraxe:</strong> Sempre necessário</li>
|
||
</ul>
|
||
`
|
||
};
|
||
|
||
manualConteudo.precos_mercado = {
|
||
titulo: '💲 Preços do Mercado Brasileiro',
|
||
secao: 'ORÇAMENTO',
|
||
conteudo: `
|
||
<h2>Preços Médios 2025</h2>
|
||
<p>Valores de referência para orçamentos (sujeitos a variação).</p>
|
||
|
||
<h3>Aços Estruturais</h3>
|
||
<table>
|
||
<tr><th>Região</th><th>A36 (R$/kg)</th><th>A572 (R$/kg)</th></tr>
|
||
<tr><td>Sudeste (SP/RJ)</td><td>7.50</td><td>8.50</td></tr>
|
||
<tr><td>Sul (RS/SC/PR)</td><td>7.20</td><td>8.20</td></tr>
|
||
<tr><td>Nordeste</td><td>8.00</td><td>9.00</td></tr>
|
||
<tr><td>Centro-Oeste</td><td>7.70</td><td>8.70</td></tr>
|
||
</table>
|
||
|
||
<h3>Serviços</h3>
|
||
<ul>
|
||
<li><strong>Soldagem:</strong> R$ 60-70/h (soldador qualificado)</li>
|
||
<li><strong>Pintura:</strong> R$ 35-45/m²</li>
|
||
<li><strong>Montagem:</strong> R$ 50-65/h</li>
|
||
</ul>
|
||
|
||
<h3>Consumíveis</h3>
|
||
<ul>
|
||
<li><strong>E7018:</strong> R$ 45/kg</li>
|
||
<li><strong>Tinta Epóxi C3:</strong> R$ 80/L</li>
|
||
<li><strong>Parafuso A325 M16:</strong> R$ 1.20/un</li>
|
||
</ul>
|
||
`
|
||
};
|
||
|
||
function addHelpButton(sectionId) {
|
||
const mainContent = document.getElementById('main-content');
|
||
if (!mainContent) return;
|
||
|
||
const existingBtn = mainContent.querySelector('.btn-help');
|
||
if (existingBtn) existingBtn.remove();
|
||
|
||
if (ajudaDatabase[sectionId]) {
|
||
const btnHelp = document.createElement('button');
|
||
btnHelp.className = 'btn-help';
|
||
btnHelp.textContent = '❓';
|
||
btnHelp.onclick = () => openAjudaModal(sectionId);
|
||
btnHelp.title = 'Clique para ajuda';
|
||
mainContent.style.position = 'relative';
|
||
mainContent.appendChild(btnHelp);
|
||
}
|
||
}
|
||
|
||
function openAjudaModal(sectionId) {
|
||
currentHelpSection = sectionId;
|
||
const ajuda = ajudaDatabase[sectionId];
|
||
if (!ajuda) return;
|
||
|
||
document.getElementById('ajudaTitulo').textContent = ajuda.titulo;
|
||
|
||
// Tab 0: Explicação
|
||
document.getElementById('help-tab-0').innerHTML = `
|
||
<div class="ajuda-secao">
|
||
<h3>O que é?</h3>
|
||
<p>${ajuda.oQueE}</p>
|
||
</div>
|
||
<div class="ajuda-secao">
|
||
<h3>Para que serve?</h3>
|
||
<p>${ajuda.paraQueServe}</p>
|
||
</div>
|
||
<div class="ajuda-secao">
|
||
<h3>Quando usar?</h3>
|
||
<p>${ajuda.quandoUsar}</p>
|
||
</div>
|
||
<div class="ajuda-secao">
|
||
<h3>⚠️ Avisos Importantes</h3>
|
||
<ul>${ajuda.avisos.map(a => `<li>${a}</li>`).join('')}</ul>
|
||
</div>
|
||
`;
|
||
|
||
// Tab 1: Campos
|
||
document.getElementById('help-tab-1').innerHTML = `
|
||
<table class="tabela-campos">
|
||
<thead>
|
||
<tr>
|
||
<th>Campo</th>
|
||
<th>Unidade</th>
|
||
<th>Significado</th>
|
||
<th>Intervalo Típico</th>
|
||
<th>Dica</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
${ajuda.campos.map(c => `
|
||
<tr>
|
||
<td><strong>${c.nome}</strong></td>
|
||
<td>${c.unidade}</td>
|
||
<td>${c.significado}</td>
|
||
<td>${c.intervalo}</td>
|
||
<td>${c.dica}</td>
|
||
</tr>
|
||
`).join('')}
|
||
</tbody>
|
||
</table>
|
||
`;
|
||
|
||
// Tab 2: Resultados
|
||
document.getElementById('help-tab-2').innerHTML = `
|
||
<div class="ajuda-secao">
|
||
<h3>O que significam os resultados?</h3>
|
||
${ajuda.resultados}
|
||
</div>
|
||
`;
|
||
|
||
// Tab 3: Referências
|
||
document.getElementById('help-tab-3').innerHTML = `
|
||
<div class="ajuda-secao">
|
||
<h3>📚 Referências Bibliográficas</h3>
|
||
<div class="referencias-list">
|
||
${ajuda.referencias.map(r => `
|
||
<div class="referencia-item">
|
||
<strong>${r.titulo}</strong><br>
|
||
${r.ano ? `Ano: ${r.ano}<br>` : ''}
|
||
${r.url ? `<a href="${r.url}" target="_blank">${r.url}</a>` : ''}
|
||
</div>
|
||
`).join('')}
|
||
</div>
|
||
|
||
<h3>📖 Leia também no Manual</h3>
|
||
<ul class="manual-links">
|
||
${ajuda.manualRelacionado.map(tema => {
|
||
const conteudo = manualConteudo[tema];
|
||
return conteudo ? `<li><a href="#" onclick="abrirManualNoTema('${tema}'); return false;">${conteudo.titulo}</a></li>` : '';
|
||
}).join('')}
|
||
</ul>
|
||
</div>
|
||
`;
|
||
|
||
document.getElementById('modalAjuda').classList.add('active');
|
||
}
|
||
|
||
function closeAjudaModal() {
|
||
document.getElementById('modalAjuda').classList.remove('active');
|
||
// Clear search when closing
|
||
document.getElementById('helpSearch').value = '';
|
||
}
|
||
|
||
// Global search index - all tools and tabs
|
||
const globalSearchIndex = [
|
||
// MATERIAIS
|
||
{ id: 'cev', title: 'CEV Avançado', category: 'MATERIAIS', icon: '⚗️', description: 'Cálculo de Carbono Equivalente (IIW + Pcm)', keywords: ['carbono', 'equivalente', 'soldabilidade', 'cev', 'pcm'] },
|
||
{ id: 'seletor', title: 'Seletor de Aço', category: 'MATERIAIS', icon: '🔍', description: 'Selecione o aço ideal para seu projeto', keywords: ['aço', 'material', 'seleção', 'astm', 'nbr'] },
|
||
{ id: 'equivalencias', title: 'Equivalências', category: 'MATERIAIS', icon: '🔄', description: 'Equivalências entre normas ASTM, EN, NBR', keywords: ['equivalência', 'norma', 'conversão', 'astm', 'en', 'nbr'] },
|
||
{ id: 'comparativo', title: 'Comparativo', category: 'MATERIAIS', icon: '⚖️', description: 'Compare propriedades de diferentes aços', keywords: ['comparar', 'propriedades', 'resistência'] },
|
||
|
||
// CONEXÕES - Main
|
||
{ id: 'parafusos', title: 'Ligações Parafusadas', category: 'CONEXÕES', icon: '🔩', description: 'Sistema completo de dimensionamento de parafusos', keywords: ['parafuso', 'conexão', 'ligação', 'bolt'] },
|
||
{ id: 'parafusos-cisalhamento', title: 'Cisalhamento de Parafusos', category: 'CONEXÕES', icon: '🔩', description: 'Resistência ao cisalhamento de parafusos', keywords: ['cisalhamento', 'shear', 'cortante', 'parafuso'], path: 'parafusos > Aba 1', tabIndex: 0 },
|
||
{ id: 'parafusos-esmagamento', title: 'Esmagamento (Bearing)', category: 'CONEXÕES', icon: '🔨', description: 'Verificação de esmagamento da chapa', keywords: ['esmagamento', 'bearing', 'chapa'], path: 'parafusos > Aba 2', tabIndex: 1 },
|
||
{ id: 'parafusos-bloco', title: 'Ruptura em Bloco', category: 'CONEXÕES', icon: '⚠️', description: 'Verificação de ruptura em bloco', keywords: ['bloco', 'ruptura', 'block', 'shear'], path: 'parafusos > Aba 3', tabIndex: 2 },
|
||
{ id: 'layout', title: 'Layout de Furação', category: 'CONEXÕES', icon: '📐', description: 'Dimensionamento de layout de furos', keywords: ['layout', 'furação', 'furo', 'espaçamento'], path: 'parafusos > Aba 4', tabIndex: 3 },
|
||
{ id: 'parafuso-vs-solda', title: 'Parafuso vs Solda', category: 'CONEXÕES', icon: '⚖️', description: 'Comparação econômica parafuso vs solda', keywords: ['comparação', 'custo', 'economia'], path: 'parafusos > Aba 5', tabIndex: 4 },
|
||
|
||
// SOLDAGEM - Main
|
||
{ id: 'preaquecimento', title: 'Pré-Aquecimento', category: 'SOLDAGEM', icon: '🌡️', description: 'Cálculo de temperatura de pré-aquecimento AWS D1.1', keywords: ['pré-aquecimento', 'preaquecimento', 'temperatura', 'preheat'], path: 'soldagem > Aba 1', tabIndex: 0 },
|
||
{ id: 'filete', title: 'Soldas de Filete', category: 'SOLDAGEM', icon: '⚡', description: 'Dimensionamento de soldas de filete', keywords: ['filete', 'fillet', 'perna', 'solda'], path: 'soldagem > Aba 2', tabIndex: 1 },
|
||
{ id: 'energia', title: 'Energia de Soldagem', category: 'SOLDAGEM', icon: '🔥', description: 'Cálculo de Heat Input', keywords: ['energia', 'heat', 'input', 'calor'], path: 'soldagem > Aba 3', tabIndex: 2 },
|
||
{ id: 'consumo-eletrodo', title: 'Consumo de Eletrodos', category: 'SOLDAGEM', icon: '📊', description: 'Cálculo de consumo de eletrodos', keywords: ['consumo', 'eletrodo', 'quantidade'], path: 'soldagem > Aba 4', tabIndex: 3 },
|
||
{ id: 'sequencia-soldagem', title: 'Sequência de Soldagem', category: 'SOLDAGEM', icon: '🔄', description: 'Planejamento de sequência de soldagem', keywords: ['sequência', 'ordem', 'distorção'], path: 'soldagem > Aba 5', tabIndex: 4 },
|
||
{ id: 'padroes-soldagem', title: 'Padrões e Normas', category: 'SOLDAGEM', icon: '📋', description: 'Normas e requisitos de soldagem', keywords: ['norma', 'padrão', 'aws', 'asme'], path: 'soldagem > Aba 6', tabIndex: 5 },
|
||
|
||
// ENSAIOS
|
||
{ id: 'dureza', title: 'Conversão de Dureza', category: 'ENSAIOS', icon: '💎', description: 'Conversão entre escalas de dureza', keywords: ['dureza', 'hardness', 'rockwell', 'brinell', 'vickers'] },
|
||
{ id: 'charpy', title: 'Ensaio Charpy', category: 'ENSAIOS', icon: '🔨', description: 'Análise de tenacidade ao impacto', keywords: ['charpy', 'impacto', 'tenacidade', 'energia'] },
|
||
{ id: 'certificado', title: 'Checklist de Certificado', category: 'ENSAIOS', icon: '📜', description: 'Verificação de certificados de qualidade', keywords: ['certificado', 'qualidade', 'inspeção'] },
|
||
{ id: 'ultrassom', title: 'Ultrassom', category: 'ENSAIOS', icon: '📡', description: 'Interpretação de ensaios ultrassônicos', keywords: ['ultrassom', 'us', 'ensaio', 'não destrutivo'] },
|
||
|
||
// PINTURA
|
||
{ id: 'area-pintura', title: 'Área de Pintura', category: 'PINTURA', icon: '📏', description: 'Cálculo de área para pintura', keywords: ['área', 'superfície', 'pintura'] },
|
||
{ id: 'consumo-tinta', title: 'Consumo de Tinta', category: 'PINTURA', icon: '🎨', description: 'Cálculo de consumo de tinta', keywords: ['consumo', 'tinta', 'quantidade', 'litros'] },
|
||
{ id: 'galvanizacao', title: 'Galvanização', category: 'PINTURA', icon: '⚡', description: 'Análise de galvanização', keywords: ['galvanização', 'zinco', 'proteção'] },
|
||
{ id: 'custo-pintura', title: 'Custo de Pintura', category: 'PINTURA', icon: '💰', description: 'Estimativa de custos de pintura', keywords: ['custo', 'preço', 'orçamento', 'pintura'] },
|
||
{ id: 'secagem', title: 'Tempo de Secagem', category: 'PINTURA', icon: '⏱️', description: 'Cálculo de tempo de secagem', keywords: ['secagem', 'tempo', 'cura'] },
|
||
{ id: 'inspecao-pintura', title: 'Inspeção de Pintura', category: 'PINTURA', icon: '🔍', description: 'Checklist de inspeção de pintura', keywords: ['inspeção', 'qualidade', 'verificação'] },
|
||
|
||
// ORÇAMENTO
|
||
{ id: 'orcamento', title: 'Orçamento Detalhado', category: 'ORÇAMENTO', icon: '💼', description: 'Orçamento completo de estruturas', keywords: ['orçamento', 'custo', 'preço', 'budget'] },
|
||
{ id: 'peso-rigging', title: 'Peso e Rigging', category: 'ORÇAMENTO', icon: '⚖️', description: 'Cálculo de peso e içamento', keywords: ['peso', 'rigging', 'içamento', 'transporte'] },
|
||
{ id: 'referencia', title: 'Referências Técnicas', category: 'ORÇAMENTO', icon: '📚', description: 'Biblioteca de referências técnicas', keywords: ['referência', 'manual', 'documentação'] }
|
||
];
|
||
|
||
// Open global search modal
|
||
function openGlobalSearchModal() {
|
||
document.getElementById('globalSearchModal').classList.add('active');
|
||
document.getElementById('globalSearchInput').value = '';
|
||
document.getElementById('globalSearchResults').innerHTML = `
|
||
<p style="color: var(--color-text-secondary); text-align: center; padding: 40px;">
|
||
Digite algo para começar a buscar...
|
||
</p>
|
||
`;
|
||
setTimeout(() => document.getElementById('globalSearchInput').focus(), 100);
|
||
}
|
||
|
||
// Close global search modal
|
||
function closeGlobalSearchModal() {
|
||
document.getElementById('globalSearchModal').classList.remove('active');
|
||
}
|
||
|
||
// Search tools globally
|
||
function buscarFerramentasGlobal() {
|
||
const searchTerm = document.getElementById('globalSearchInput').value.toLowerCase().trim();
|
||
const resultsContainer = document.getElementById('globalSearchResults');
|
||
|
||
if (!searchTerm) {
|
||
resultsContainer.innerHTML = `
|
||
<p style="color: var(--color-text-secondary); text-align: center; padding: 40px;">
|
||
Digite algo para começar a buscar...
|
||
</p>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
// Search in index
|
||
const results = globalSearchIndex.filter(item => {
|
||
const titleMatch = item.title.toLowerCase().includes(searchTerm);
|
||
const descMatch = item.description.toLowerCase().includes(searchTerm);
|
||
const keywordMatch = item.keywords.some(k => k.includes(searchTerm));
|
||
const categoryMatch = item.category.toLowerCase().includes(searchTerm);
|
||
|
||
return titleMatch || descMatch || keywordMatch || categoryMatch;
|
||
});
|
||
|
||
if (results.length === 0) {
|
||
resultsContainer.innerHTML = `
|
||
<div class="no-results">
|
||
<div class="no-results-icon">🔍</div>
|
||
<p><strong>Nenhum resultado encontrado</strong></p>
|
||
<p>Tente buscar por: "solda", "parafuso", "charpy", "pintura", etc.</p>
|
||
</div>
|
||
`;
|
||
return;
|
||
}
|
||
|
||
// Display results
|
||
resultsContainer.innerHTML = results.map(item => {
|
||
const highlightedTitle = item.title.replace(new RegExp(`(${searchTerm})`, 'gi'), '<mark class="highlight">$1</mark>');
|
||
const highlightedDesc = item.description.replace(new RegExp(`(${searchTerm})`, 'gi'), '<mark class="highlight">$1</mark>');
|
||
|
||
return `
|
||
<div class="search-result-item" onclick="navegarParaFerramenta('${item.id}', ${item.tabIndex || 'null'})">
|
||
<div class="search-result-item-header">
|
||
<span class="search-result-item-icon">${item.icon}</span>
|
||
<span class="search-result-item-title">${highlightedTitle}</span>
|
||
<span class="search-result-item-category">${item.category}</span>
|
||
</div>
|
||
<div class="search-result-item-description">${highlightedDesc}</div>
|
||
${item.path ? `<div class="search-result-item-path">📍 ${item.path}</div>` : ''}
|
||
</div>
|
||
`;
|
||
}).join('');
|
||
}
|
||
|
||
// Navigate to a specific tool/tab
|
||
function navegarParaFerramenta(toolId, tabIndex) {
|
||
closeGlobalSearchModal();
|
||
|
||
// Determine which section to show
|
||
let sectionId = toolId;
|
||
|
||
// Handle tabs within sections
|
||
if (toolId.startsWith('parafusos-')) {
|
||
sectionId = 'parafusos';
|
||
} else if (['filete', 'energia', 'consumo-eletrodo', 'sequencia-soldagem', 'padroes-soldagem'].includes(toolId)) {
|
||
sectionId = 'preaquecimento'; // SOLDAGEM section
|
||
}
|
||
|
||
// Show the section
|
||
showSection(sectionId);
|
||
|
||
// Switch to specific tab if needed
|
||
setTimeout(() => {
|
||
if (tabIndex !== null && tabIndex !== undefined) {
|
||
if (sectionId === 'parafusos') {
|
||
switchTab(tabIndex);
|
||
} else if (sectionId === 'preaquecimento') {
|
||
switchWeldTab(tabIndex);
|
||
}
|
||
}
|
||
|
||
// Scroll to top
|
||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||
}, 200);
|
||
}
|
||
|
||
// Filter help content based on search
|
||
function filtrarConteudoAjuda() {
|
||
const searchTerm = document.getElementById('helpSearch').value.toLowerCase();
|
||
const activeTab = document.querySelector('.help-tab-content.active');
|
||
|
||
if (!activeTab || !searchTerm) {
|
||
// Remove all highlights if search is empty
|
||
if (activeTab) {
|
||
const content = activeTab.innerHTML;
|
||
activeTab.innerHTML = content.replace(/<mark class="highlight">(.*?)<\/mark>/g, '$1');
|
||
}
|
||
return;
|
||
}
|
||
|
||
// Get original content without highlights
|
||
const ajuda = ajudaDatabase[currentHelpSection];
|
||
if (!ajuda) return;
|
||
|
||
// Re-render current tab with highlights
|
||
const activeTabIndex = Array.from(document.querySelectorAll('.help-tab-content')).indexOf(activeTab);
|
||
|
||
// Helper function to highlight text
|
||
const highlightText = (text) => {
|
||
if (!searchTerm) return text;
|
||
const regex = new RegExp(`(${searchTerm})`, 'gi');
|
||
return text.replace(regex, '<mark class="highlight">$1</mark>');
|
||
};
|
||
|
||
if (activeTabIndex === 0) {
|
||
// Tab 0: Explicação
|
||
activeTab.innerHTML = `
|
||
<div class="ajuda-secao">
|
||
<h3>O que é?</h3>
|
||
<p>${highlightText(ajuda.oQueE)}</p>
|
||
</div>
|
||
<div class="ajuda-secao">
|
||
<h3>Para que serve?</h3>
|
||
<p>${highlightText(ajuda.paraQueServe)}</p>
|
||
</div>
|
||
<div class="ajuda-secao">
|
||
<h3>Quando usar?</h3>
|
||
<p>${highlightText(ajuda.quandoUsar)}</p>
|
||
</div>
|
||
<div class="ajuda-secao">
|
||
<h3>⚠️ Avisos Importantes</h3>
|
||
<ul>${ajuda.avisos.map(a => `<li>${highlightText(a)}</li>`).join('')}</ul>
|
||
</div>
|
||
`;
|
||
} else if (activeTabIndex === 1) {
|
||
// Tab 1: Campos
|
||
activeTab.innerHTML = `
|
||
<table class="tabela-campos">
|
||
<thead>
|
||
<tr>
|
||
<th>Campo</th>
|
||
<th>Unidade</th>
|
||
<th>Significado</th>
|
||
<th>Intervalo Típico</th>
|
||
<th>Dica</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
${ajuda.campos.map(c => `
|
||
<tr>
|
||
<td><strong>${highlightText(c.nome)}</strong></td>
|
||
<td>${highlightText(c.unidade)}</td>
|
||
<td>${highlightText(c.significado)}</td>
|
||
<td>${highlightText(c.intervalo)}</td>
|
||
<td>${highlightText(c.dica)}</td>
|
||
</tr>
|
||
`).join('')}
|
||
</tbody>
|
||
</table>
|
||
`;
|
||
} else if (activeTabIndex === 2) {
|
||
// Tab 2: Resultados
|
||
activeTab.innerHTML = `
|
||
<div class="ajuda-secao">
|
||
<h3>O que significam os resultados?</h3>
|
||
${highlightText(ajuda.resultados)}
|
||
</div>
|
||
`;
|
||
} else if (activeTabIndex === 3) {
|
||
// Tab 3: Referências
|
||
activeTab.innerHTML = `
|
||
<div class="ajuda-secao">
|
||
<h3>📚 Referências Bibliográficas</h3>
|
||
<div class="referencias-list">
|
||
${ajuda.referencias.map(r => `
|
||
<div class="referencia-item">
|
||
<strong>${highlightText(r.titulo)}</strong><br>
|
||
${r.ano ? `Ano: ${r.ano}<br>` : ''}
|
||
${r.url ? `<a href="${r.url}" target="_blank">${r.url}</a>` : ''}
|
||
</div>
|
||
`).join('')}
|
||
</div>
|
||
|
||
<h3>📖 Leia também no Manual</h3>
|
||
<ul class="manual-links">
|
||
${ajuda.manualRelacionado.map(tema => {
|
||
const conteudo = manualConteudo[tema];
|
||
return conteudo ? `<li><a href="#" onclick="abrirManualNoTema('${tema}'); return false;">${highlightText(conteudo.titulo)}</a></li>` : '';
|
||
}).join('')}
|
||
</ul>
|
||
</div>
|
||
`;
|
||
}
|
||
}
|
||
|
||
function switchHelpTab(index) {
|
||
document.querySelectorAll('.help-tab-btn').forEach((btn, i) => {
|
||
btn.classList.toggle('active', i === index);
|
||
});
|
||
document.querySelectorAll('.help-tab-content').forEach((content, i) => {
|
||
content.classList.toggle('active', i === index);
|
||
});
|
||
}
|
||
|
||
function abrirManualRelacionado() {
|
||
if (currentHelpSection && ajudaDatabase[currentHelpSection]) {
|
||
const temas = ajudaDatabase[currentHelpSection].manualRelacionado;
|
||
if (temas && temas.length > 0) {
|
||
closeAjudaModal();
|
||
abrirManualNoTema(temas[0]);
|
||
}
|
||
}
|
||
}
|
||
|
||
function openManualUsuario() {
|
||
carregarManualNav();
|
||
abrirManualNoTema('aco_introducao');
|
||
document.getElementById('modalManual').classList.add('active');
|
||
}
|
||
|
||
function closeManualModal() {
|
||
document.getElementById('modalManual').classList.remove('active');
|
||
}
|
||
|
||
function carregarManualNav() {
|
||
const nav = document.getElementById('manualNav');
|
||
let html = '';
|
||
|
||
Object.keys(manualNavStructure).forEach(secao => {
|
||
html += `
|
||
<div class="manual-secao">
|
||
<button class="manual-secao-btn" onclick="toggleManualSecao(this)">
|
||
${secao}
|
||
</button>
|
||
<div class="manual-items">
|
||
${manualNavStructure[secao].map(tema => {
|
||
const conteudo = manualConteudo[tema];
|
||
return conteudo ? `
|
||
<button class="manual-item" onclick="abrirManualNoTema('${tema}')">
|
||
• ${conteudo.titulo}
|
||
</button>
|
||
` : '';
|
||
}).join('')}
|
||
</div>
|
||
</div>
|
||
`;
|
||
});
|
||
|
||
nav.innerHTML = html;
|
||
}
|
||
|
||
function toggleManualSecao(btn) {
|
||
const items = btn.nextElementSibling;
|
||
items.classList.toggle('active');
|
||
}
|
||
|
||
function abrirManualNoTema(temaId) {
|
||
const conteudo = manualConteudo[temaId];
|
||
if (!conteudo) return;
|
||
|
||
document.getElementById('manualConteudo').innerHTML = `
|
||
<h2>${conteudo.titulo}</h2>
|
||
<div class="manual-secao-badge" style="display: inline-block; background: var(--color-primary); color: var(--color-btn-primary-text); padding: 4px 12px; border-radius: 4px; font-size: 12px; margin-bottom: 20px;">
|
||
${conteudo.secao}
|
||
</div>
|
||
${conteudo.conteudo}
|
||
`;
|
||
|
||
// Mark active item
|
||
document.querySelectorAll('.manual-item').forEach(item => {
|
||
item.classList.remove('active');
|
||
});
|
||
const activeBtn = Array.from(document.querySelectorAll('.manual-item')).find(btn =>
|
||
btn.textContent.includes(conteudo.titulo)
|
||
);
|
||
if (activeBtn) {
|
||
activeBtn.classList.add('active');
|
||
// Open parent section
|
||
const items = activeBtn.parentElement;
|
||
if (items) items.classList.add('active');
|
||
}
|
||
|
||
document.getElementById('modalManual').classList.add('active');
|
||
|
||
// Scroll to top
|
||
document.querySelector('.manual-content').scrollTop = 0;
|
||
}
|
||
|
||
function buscarNoManual() {
|
||
const searchTerm = document.getElementById('manualSearch').value.toLowerCase();
|
||
const items = document.querySelectorAll('.manual-item');
|
||
|
||
items.forEach(item => {
|
||
const text = item.textContent.toLowerCase();
|
||
if (text.includes(searchTerm)) {
|
||
item.style.display = 'block';
|
||
} else {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
console.log('🚀 SteelBase v7.5 - Inicializando...');
|
||
|
||
try {
|
||
// Load admin config from localStorage
|
||
try {
|
||
const savedConfig = localStorage.getItem('acoCalcProAdminConfig');
|
||
if (savedConfig) {
|
||
const parsed = JSON.parse(savedConfig);
|
||
|
||
// Merge configurations, but keep new default values for missing keys
|
||
// This ensures new tools added to the code are visible by default
|
||
if (parsed.toolsVisibility) {
|
||
// Merge toolsVisibility: keep saved values but add new defaults
|
||
Object.keys(adminConfig.toolsVisibility).forEach(key => {
|
||
if (parsed.toolsVisibility[key] === undefined) {
|
||
// New tool not in saved config, keep default
|
||
parsed.toolsVisibility[key] = adminConfig.toolsVisibility[key];
|
||
}
|
||
});
|
||
}
|
||
|
||
Object.assign(adminConfig, parsed);
|
||
|
||
// FORCE UPDATE: Ensure catalog items are visible (v7.5 update)
|
||
const catalogoItems = ['cantoneiras', 'barras-redondas', 'tubos-circulares', 'perfis-i', 'perfis-w', 'tubos-rhs', 'chapas', 'perfis-hp', 'barras-roscadas', 'barras-chatas'];
|
||
catalogoItems.forEach(item => {
|
||
adminConfig.toolsVisibility[item] = true;
|
||
});
|
||
|
||
// Save updated config back to localStorage
|
||
localStorage.setItem('acoCalcProAdminConfig', JSON.stringify(adminConfig));
|
||
|
||
console.log('✅ Configurações do Admin carregadas e atualizadas');
|
||
}
|
||
} catch (error) {
|
||
console.warn('⚠️ Erro ao carregar configurações do Admin:', error);
|
||
}
|
||
|
||
// Apply admin config
|
||
if (typeof applyAdminConfig === 'function') {
|
||
applyAdminConfig();
|
||
}
|
||
|
||
// Load preferences first
|
||
if (typeof loadPreferences === 'function') {
|
||
loadPreferences();
|
||
}
|
||
if (typeof applyUserPreferences === 'function') {
|
||
applyUserPreferences();
|
||
}
|
||
|
||
// Initialize app
|
||
showSection('cev');
|
||
|
||
// Initialize optional functions safely
|
||
if (typeof mostrarEquivalencias === 'function') {
|
||
mostrarEquivalencias();
|
||
}
|
||
if (typeof gerarChecklistCertificado === 'function') {
|
||
gerarChecklistCertificado();
|
||
}
|
||
if (typeof updatePaintFields === 'function') {
|
||
updatePaintFields();
|
||
}
|
||
if (typeof updateWeightFields === 'function') {
|
||
updateWeightFields();
|
||
}
|
||
|
||
// Apply admin config and filter (no forced expansion)
|
||
applyAdminConfig();
|
||
|
||
// Debug: verificar configuração do catálogo
|
||
console.log('📋 Verificando configuração do Catálogo de Perfis:');
|
||
const catalogoItems = ['cantoneiras', 'barras-redondas', 'tubos-circulares', 'perfis-i', 'perfis-w', 'tubos-rhs', 'chapas', 'perfis-hp', 'barras-roscadas', 'barras-chatas'];
|
||
catalogoItems.forEach(item => {
|
||
const isVisible = adminConfig.toolsVisibility[item];
|
||
console.log(` ${item}: ${isVisible ? '✅ visível' : '❌ escondido'}`);
|
||
});
|
||
|
||
filterToolsByMode();
|
||
// Initialize sidebar expansion based on visibility and manual state
|
||
initializeSidebarExpansion();
|
||
|
||
addHelpButton('cev');
|
||
|
||
console.log('✅ SteelBase carregado com sucesso!');
|
||
} catch (error) {
|
||
console.error('❌ Erro na inicialização:', error);
|
||
} finally {
|
||
// Remove loading screen after initialization
|
||
setTimeout(() => {
|
||
const loadingScreen = document.getElementById('app-loading');
|
||
if (loadingScreen) {
|
||
loadingScreen.style.opacity = '0';
|
||
loadingScreen.style.transition = 'opacity 0.3s ease';
|
||
setTimeout(() => loadingScreen.remove(), 300);
|
||
}
|
||
}, 500);
|
||
}
|
||
|
||
// Initialize budget when switching to orcamento section
|
||
const observer = new MutationObserver(() => {
|
||
if (appState.currentSection === 'orcamento') {
|
||
setTimeout(initializeBudget, 100);
|
||
}
|
||
});
|
||
|
||
// Removido: listener de fechamento do modal Admin legado
|
||
})(); |