7 Commits
7 changed files with 1892 additions and 697 deletions
+3
View File
@@ -32,3 +32,6 @@ node_modules/
# Backup files
*.bak
*.backup
# runtime-generated files
access_log.json
-667
View File
@@ -1,667 +0,0 @@
[
{
"timestamp": "2026-05-28T13:06:19.854940",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:06:58.223722",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:07:05.902636",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:07:51.345366",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:09:37.481260",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:14:02.867188",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:28:08.386403",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:29:06.541184",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:30:47.979071",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:46:05.447815",
"username": "beta",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T13:46:19.317688",
"username": "beta",
"endpoint": "/admin",
"method": "GET",
"status": 403
},
{
"timestamp": "2026-05-28T14:42:29.477028",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:43:31.374462",
"username": "admin",
"endpoint": "/admin",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:43:31.411860",
"username": "admin",
"endpoint": "/api/admin/stats",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:43:31.562482",
"username": "admin",
"endpoint": "/api/admin/logs",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:44:01.420524",
"username": "admin",
"endpoint": "/api/admin/stats",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:44:01.438789",
"username": "admin",
"endpoint": "/api/admin/logs",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:44:13.773466",
"username": "admin",
"endpoint": "/admin",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:44:13.817782",
"username": "admin",
"endpoint": "/api/admin/stats",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-05-28T14:44:13.894128",
"username": "admin",
"endpoint": "/api/admin/logs",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-06-03T05:20:48.808775",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:31:48.451519",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:31:48.676701",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:31:54.481445",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:31:58.011356",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:32:48.747837",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:33:07.753648",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:42:11.820817",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:43:37.598978",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T07:47:39.689201",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T08:25:47.585793",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:32:59.419063",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:35:05.236655",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:40:47.890997",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:41:02.461403",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:42:11.914989",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:42:57.125161",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T09:54:34.067541",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T10:02:39.927663",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:00:50.808697",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:09:28.615255",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:09:40.011779",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:09:53.681061",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:10:06.334747",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:17:18.862106",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:44:00.451943",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:44:20.277301",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:49:56.333142",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:50:11.692907",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:56:07.569410",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:59:03.417506",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T12:59:21.102453",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:04:52.131022",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:05:09.915771",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:09:55.899370",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:10:20.387853",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:10:20.736005",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:12:48.924277",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:15:13.236624",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:17:32.470202",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:23:23.613251",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:23:24.369105",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:26:48.783516",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:47:07.888072",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:52:38.653855",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:53:02.662397",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T13:57:19.316896",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T14:05:28.671663",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T14:06:26.413418",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T14:06:42.715163",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T14:12:15.337499",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T14:12:19.510992",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-01T14:13:17.018760",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-02T11:28:30.320494",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-02T11:28:46.119436",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-02T11:36:55.439798",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-02T11:41:31.868950",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-02T16:07:56.334163",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-02T16:08:38.097844",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-03T08:39:44.284544",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-03T08:41:57.673023",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-03T08:42:19.877155",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-06T10:34:02.710459",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-06T13:14:58.113794",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-06T13:15:20.071507",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-06T13:15:32.538576",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T11:44:53.524315",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T11:47:36.702455",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T12:18:47.866971",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T14:46:22.335316",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T16:13:42.026433",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T16:19:41.488752",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T16:34:58.280178",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T16:36:56.896657",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
},
{
"timestamp": "2026-07-07T16:41:46.568545",
"username": "mtazl",
"endpoint": "/",
"method": "GET",
"status": 200
}
]
+4 -4
View File
@@ -1,6 +1,6 @@
{
"version": "v0.4-dev",
"branch": "develop/v0.4",
"commit": "7a27fb8",
"timestamp": "2026-07-07T16:46:32+02:00"
"version": "v0.4",
"branch": "main",
"commit": "fe267b8",
"timestamp": "2026-07-27T11:08:47+02:00"
}
+39
View File
@@ -0,0 +1,39 @@
# Documentation Guidelines
## Language
The primary documentation language is German.
An English version will be maintained as a translation of the German master document.
## UI terminology
All user interface terms remain in English.
Examples:
- Direct Calculation
- Extrapolation
- Roll Diameter
- Product Length
- Capacity Summary
- Capacity Analysis
- Governing Constraint
Do not translate UI labels.
## Style
- Technical user manual
- Workflow-oriented
- Explain why, not only how
- Engineering language
- No marketing language
## Workflow
1. Write German chapter.
2. Technical review.
3. Add screenshots.
4. Approve.
5. Translate to English.
+1744
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -3,12 +3,13 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
VERSION="${1:-v0.4-dev}"
cd "$PROJECT_ROOT"
cat > build_info.json <<EOF
{
"version": "v0.4-dev",
"version": "$VERSION",
"branch": "$(git branch --show-current)",
"commit": "$(git rev-parse --short HEAD)",
"timestamp": "$(date -Iseconds)"
+100 -25
View File
@@ -289,6 +289,23 @@
border-left: 4px solid #2BAC70;
}
.lo-results-summary h4 { margin-top: 0; color: #333; font-size: 14px; margin-bottom: 12px; }
.lo-summary-section {
padding-top: 12px;
margin-top: 12px;
border-top: 1px solid #e6ece9;
}
.lo-summary-section:first-of-type {
padding-top: 0;
margin-top: 0;
border-top: 0;
}
.lo-summary-section-title {
margin-bottom: 8px;
color: #1F5438;
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
}
.lo-summary-item {
display: flex;
justify-content: space-between;
@@ -297,9 +314,23 @@
font-size: 13px;
}
.lo-summary-item:last-child { margin-bottom: 0; }
.lo-summary-item.lo-governing-summary {
background: #eef8f2;
border-left: 3px solid #2BAC70;
padding: 8px 10px;
border-radius: 4px;
}
.lo-value-highlight { color: #2BAC70; font-weight: bold; font-size: 16px; }
.lo-value-number { color: #1F5438; font-weight: bold; }
.lo-util-group { display: flex; flex-direction: column; gap: 4px; text-align: right; }
.lo-reserve-note {
margin-top: 4px;
color: #666;
font-size: 12px;
line-height: 1.35;
text-align: right;
max-width: 300px;
}
.lo-results-table {
background: white;
padding: 16px;
@@ -315,10 +346,15 @@
font-weight: 600;
color: #333;
border-bottom: 2px solid #2BAC70;
white-space: normal;
}
.lo-results-table td { padding: 8px; border-bottom: 1px solid #e0e0e0; }
.lo-results-table tbody tr:hover { background: #f9f9f9; }
.lo-results-table tbody tr.lo-recommended { background: #fffacd; font-weight: bold; }
.lo-results-table tbody tr.lo-governing {
background: #eef8f2;
font-weight: 600;
border-left: 3px solid #2BAC70;
}
.lo-warning {
background: #fff8e1;
border: 1px solid #f0b429;
@@ -396,6 +432,11 @@
}
.lo-sideview-section.show { display: block; }
.lo-sideview-section h4 { margin: 0 0 12px 0; font-size: 14px; color: #333; }
.lo-sideview-context {
margin: -6px 0 12px;
color: #666;
font-size: 12px;
}
.lo-sideview-wrap {
background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 4px; overflow: hidden;
}
@@ -807,38 +848,58 @@
<div class="lo-results" id="resultsContainer">
<div class="lo-results-summary">
<h4>Results:</h4>
<div class="lo-summary-item">
<span><strong>Limiting Factor:</strong></span>
<span id="limitingFactorValue" class="lo-value-highlight">–</span>
</div>
<div class="lo-summary-item">
<span><strong>Total Rolls:</strong></span>
<div style="text-align:right;">
<span id="totalRollsValue" class="lo-value-highlight">–</span>
<small id="rollsDetailValue" style="display:block;color:#888;"></small>
<h4>Capacity Summary:</h4>
<div class="lo-summary-section">
<div class="lo-summary-section-title">Governing Constraint</div>
<div class="lo-summary-item lo-governing-summary">
<span><strong>Constraint:</strong></span>
<span id="limitingFactorValue" class="lo-value-highlight">–</span>
</div>
</div>
<div class="lo-summary-item">
<span><strong>Utilization:</strong></span>
<div class="lo-util-group">
<div>Weight: <span id="weightUtilValue" class="lo-value-number">–</span> %</div>
<div>Volume: <span id="volumeUtilValue" class="lo-value-number">–</span> %</div>
<div>Product: <span id="productM2Value" class="lo-value-number">–</span> m²</div>
<div class="lo-summary-section">
<div class="lo-summary-section-title">Transport Result</div>
<div class="lo-summary-item">
<span><strong>Total Rolls:</strong></span>
<div style="text-align:right;">
<span id="totalRollsValue" class="lo-value-highlight">–</span>
<small id="rollsDetailValue" style="display:block;color:#888;"></small>
</div>
</div>
<div class="lo-summary-item">
<span><strong>Utilization:</strong></span>
<div class="lo-util-group">
<div>Weight Utilization: <span id="weightUtilValue" class="lo-value-number">–</span> %</div>
<div>Volume Utilization: <span id="volumeUtilValue" class="lo-value-number">–</span> %</div>
<div>Transported Product Area: <span id="productM2Value" class="lo-value-number">–</span> m²</div>
</div>
</div>
</div>
<div class="lo-summary-section">
<div class="lo-summary-section-title">Remaining Capacity</div>
<div class="lo-summary-item">
<span><strong>Remaining Capacity:</strong></span>
<div class="lo-util-group">
<div>Remaining Payload: <span id="remainingPayloadValue" class="lo-value-number">–</span> kg</div>
<div>Unused Payload: <span id="unusedPayloadValue" class="lo-value-number">–</span> %</div>
<div>Unused Volume: <span id="unusedVolumeValue" class="lo-value-number">–</span> %</div>
<div id="capacityInterpretationValue" class="lo-reserve-note"></div>
</div>
</div>
</div>
</div>
<div class="lo-results-table">
<h4>Comparison Table:</h4>
<h4>Capacity Analysis:</h4>
<table id="comparisonTable">
<thead>
<tr>
<th>Scenario</th>
<th>Rolls</th>
<th>kg</th>
<th>m²</th>
<th>Util. %</th>
<th>Constraint</th>
<th>Max Rolls</th>
<th>Total Weight</th>
<th>Transported Area [m²]</th>
<th>Payload Util. %</th>
</tr>
</thead>
<tbody></tbody>
@@ -847,6 +908,7 @@
<div class="lo-sideview-section" id="sideViewSection">
<h4>🔍 Front View – Cross-Section</h4>
<p class="lo-sideview-context">Cross-section of the actual loading configuration.</p>
<div class="lo-sideview-wrap">
<svg id="sideViewSVG" width="100%" viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg">
<text x="400" y="130" text-anchor="middle" fill="#aaa" font-size="14">Run a calculation to see the side view.</text>
@@ -1350,6 +1412,14 @@ class LoadOptimizerUI {
showResults(res, maxW) {
const m2PerRoll = this.optimizer.state.m2PerRoll || 0;
const remainingPayload = Math.max(0, maxW - res.finalWeight);
const unusedPayload = Math.max(0, 100 - res.utilizationWeight);
const unusedVolume = Math.max(0, 100 - res.utilizationVolume);
const interpretations = {
geometry: 'Geometry prevents loading additional rolls although payload capacity remains available.',
weight: 'Payload limit is reached before the available geometry or volume is fully used.',
volume: 'Volume capacity is reached before payload or geometric capacity is fully used.'
};
document.getElementById('limitingFactorValue').textContent = res.limiting.name;
document.getElementById('totalRollsValue').textContent = res.finalRolls;
document.getElementById('rollsDetailValue').textContent =
@@ -1357,16 +1427,21 @@ class LoadOptimizerUI {
document.getElementById('weightUtilValue').textContent = this.optimizer.fmt(res.utilizationWeight);
document.getElementById('volumeUtilValue').textContent = this.optimizer.fmt(res.utilizationVolume);
document.getElementById('productM2Value').textContent = this.optimizer.fmt(res.finalM2, 0);
document.getElementById('remainingPayloadValue').textContent = this.optimizer.fmt(remainingPayload, 0);
document.getElementById('unusedPayloadValue').textContent = this.optimizer.fmt(unusedPayload);
document.getElementById('unusedVolumeValue').textContent = this.optimizer.fmt(unusedVolume);
document.getElementById('capacityInterpretationValue').textContent =
interpretations[res.limiting.type] || '';
const tbody = document.querySelector('#comparisonTable tbody');
tbody.innerHTML = '';
res.scenarios.forEach(sc => {
const tr = document.createElement('tr');
const lim = (sc.type === res.limiting.type);
if (lim) tr.classList.add('lo-recommended');
if (lim) tr.classList.add('lo-governing');
const util = maxW > 0 ? (sc.weight / maxW * 100).toFixed(1) : '–';
const scM2 = isFinite(sc.rolls) && m2PerRoll > 0 ? Math.round(sc.rolls * m2PerRoll) : '–';
tr.innerHTML =
'<td>'+ sc.name +(lim?' ★':'')+'</td>'+
'<td>'+ sc.name +(lim?' &rarr; Governing Constraint':'')+'</td>'+
'<td>'+ (sc.rolls === Infinity ? '–' : sc.rolls) +'</td>'+
'<td>'+ (isFinite(sc.weight) ? Math.round(sc.weight) : '–') +'</td>'+
'<td>'+ scM2 +'</td>'+