UNPKG

ton-assembly

Version:

TON assembler and disassembler

106 lines 4.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateHtml = exports.calculateTotalGas = void 0; const data_1 = require("./data"); const templates_1 = require("./templates/templates"); const templates = { main: templates_1.MAIN_TEMPLATE, summary: templates_1.SUMMARY_TEMPLATE, }; const renderTemplate = (template, data) => { return template.replaceAll(/{{(\w+)}}/g, (_, key) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return data[key]?.toString() ?? ""; }); }; const formatGasCosts = (gasCosts) => { if (gasCosts.length === 0) return ""; if (gasCosts.length === 1) return gasCosts[0]?.toString() ?? "0"; const gasCount = new Map(); for (const gas of gasCosts) { gasCount.set(gas, (gasCount.get(gas) ?? 0) + 1); } if (gasCount.size === 1) { const firstEntry = [...gasCount.entries()][0]; return firstEntry?.[0]?.toString() ?? ""; } return [...gasCount.entries()] .sort(([gas1], [gas2]) => gas1 - gas2) .map(([gas, count]) => `${gas} x${count}`) .join(", "); }; const calculateTotalGas = (gasCosts) => { return gasCosts.reduce((sum, gas) => sum + gas, 0); }; exports.calculateTotalGas = calculateTotalGas; const generateLineHtml = (line, index, maxGasPerLine, totalGas) => { const lineNumber = index + 1; const className = line.info.$; let gasHtml = `<div class="gas"></div>`; let hitsHtml = `<div class="hits"></div>`; let gasPercentStyle = ""; if (line.info.$ === "Covered") { const gasInfo = line.info.gasCosts; const detailedGasCost = formatGasCosts(gasInfo); const totalGasCost = (0, exports.calculateTotalGas)(gasInfo); const gasPercentage = Math.sqrt(totalGasCost / maxGasPerLine) * 100; const totalGasPercentage = totalGas === 0 ? 0 : (totalGasCost / totalGas) * 100; gasPercentStyle = ` style="--gas-percent:${gasPercentage.toFixed(4)}%" data-gas-percent="${totalGasPercentage.toFixed(2)}%"`; gasHtml = `<div class="gas"> <span class="gas-detailed">${detailedGasCost}</span> <span class="gas-sum">${totalGasCost}</span> </div>`; hitsHtml = `<div class="hits" title="Number of times executed">${line.info.hits}</div>`; } return `<div class="line ${className}" id="L${lineNumber}"${gasPercentStyle} data-line-number="${lineNumber}"> <div class="line-number">${lineNumber}</div> ${gasHtml} ${hitsHtml} <pre>${line.line.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#039;")}</pre> </div>`; }; const generateInstructionRowsHtml = (summary) => { return summary.instructionStats .map(stat => { const percentValue = (stat.totalGas / summary.totalGas) * 100; return `<tr> <td data-value="${stat.name}"><code>${stat.name}</code></td> <td data-value="${stat.totalGas}">${stat.totalGas}</td> <td data-value="${stat.totalHits}">${stat.totalHits}</td> <td data-value="${stat.avgGas}">${stat.avgGas}</td> <td data-value="${percentValue}"> <div class="percent-container"> <div class="percent-text">${percentValue.toFixed(2)}%</div> <div class="percent-bar"> <div class="percent-fill" style="width: ${percentValue}%"></div> </div> </div> </td> </tr>`; }) .join("\n"); }; const generateHtml = (lines) => { const summary = (0, data_1.generateCoverageSummary)(lines); const maxGas = Math.max(...lines.map(line => line.info.$ === "Covered" ? line.info.gasCosts.reduce((sum, gas) => sum + gas, 0) : 0)); const htmlLines = lines .map((line, index) => generateLineHtml(line, index, maxGas, summary.totalGas)) .join("\n"); const templateData = { coverage_percentage: summary.coveragePercentage.toFixed(2), covered_lines: summary.coveredLines, total_lines: summary.totalLines, total_gas: summary.totalGas, total_hits: summary.totalHits, instruction_rows: generateInstructionRowsHtml(summary), }; const summaryHtml = renderTemplate(templates.summary, templateData); return renderTemplate(templates.main, { SUMMARY_CONTENT: summaryHtml, CODE_CONTENT: htmlLines, }); }; exports.generateHtml = generateHtml; //# sourceMappingURL=html.js.map