body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
}
.calc-container {
max-width: 900px;
margin: 20px auto;
padding: 20px;
}
/* ── Header ── */
.calc-header {
margin-bottom: 30px;
padding: 25px;
background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
color: white;
}
.calc-header h2 {
margin-top: 0;
color: white;
font-size: 28px;
margin-bottom: 10px;
}
.calc-header p {
margin: 10px 0 20px 0;
opacity: 0.95;
font-size: 15px;
}
/* ── Form controls inside header ── */
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 15px;
margin-top: 20px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.form-group label {
font-weight: 600;
font-size: 14px;
color: white;
}
.form-group input,
.form-group select {
padding: 12px;
font-size: 15px;
border: 2px solid rgba(255,255,255,0.3);
border-radius: 6px;
background: rgba(255,255,255,0.95);
transition: all 0.3s ease;
font-family: 'Courier New', monospace;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #4CAF50;
background: white;
box-shadow: 0 0 0 3px rgba(76,175,80,0.15);
}
.form-group select {
cursor: pointer;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
/* ── Buttons ── */
.btn {
padding: 12px 24px;
font-size: 15px;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.btn-primary {
background: #4CAF50;
color: white;
}
.btn-primary:hover {
background: #45a049;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.25);
}
.btn-primary:active {
background: #3d8b40;
transform: translateY(0);
}
.btn-secondary {
background: rgba(255,255,255,0.2);
color: white;
border: 2px solid rgba(255,255,255,0.4);
}
.btn-secondary:hover {
background: rgba(255,255,255,0.3);
transform: translateY(-1px);
}
.btn-danger {
background: #f44336;
color: white;
}
.btn-danger:hover {
background: #d32f2f;
transform: translateY(-1px);
}
.btn-sm {
padding: 6px 14px;
font-size: 13px;
}
.submit-btn {
padding: 14px 35px;
font-size: 16px;
background: #4CAF50;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
margin-top: 15px;
width: 100%;
}
.submit-btn:hover {
background: #45a049;
transform: translateY(-1px);
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.submit-btn:active {
background: #3d8b40;
transform: translateY(0);
}
/* ── Result sections ── */
.result-section {
background: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
margin-top: 20px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
transition: all 0.3s ease;
display: none;
}
.result-section.show {
display: block;
}
.result-section:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.section-header {
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
color: white;
padding: 15px 20px;
}
.section-header h3 {
margin: 0;
font-size: 18px;
display: flex;
align-items: center;
gap: 10px;
}
.section-header.blue {
background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
}
.section-header.orange {
background: linear-gradient(135deg, #FF9800 0%, #F57C00 100%);
}
.section-header.purple {
background: linear-gradient(135deg, #9C27B0 0%, #7B1FA2 100%);
}
.section-content {
padding: 20px;
background: #fafafa;
}
.data-row {
display: flex;
margin: 10px 0;
padding: 10px;
background: white;
border-radius: 4px;
border-left: 3px solid #4CAF50;
align-items: flex-start;
}
.data-label {
font-weight: bold;
color: #555;
min-width: 200px;
flex-shrink: 0;
font-size: 14px;
padding-top: 1px;
}
.data-value {
color: #333;
font-family: 'Courier New', monospace;
word-break: break-word;
font-size: 15px;
}
.data-value.highlight {
color: #1976D2;
font-weight: bold;
font-size: 18px;
}
/* ── Help text ── */
.help-text {
margin-top: 15px;
font-size: 14px;
color: rgba(255,255,255,0.9);
background: rgba(0,0,0,0.1);
padding: 10px 15px;
border-radius: 4px;
}
.help-text strong {
color: white;
}
/* ── Topology canvas area ── */
#cy-container {
width: 100%;
height: 380px;
background: #1a2332;
border-radius: 8px;
border: 2px solid #2d3d52;
position: relative;
overflow: hidden;
}
#cy {
width: 100%;
height: 100%;
}
/* ── Switch list ── */
.switch-list,
.link-list {
list-style: none;
margin: 0;
padding: 0;
}
.switch-item,
.link-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: white;
border-radius: 5px;
margin-bottom: 6px;
border-left: 4px solid #2196F3;
font-size: 14px;
flex-wrap: wrap;
}
.switch-item .sw-id {
font-family: 'Courier New', monospace;
font-weight: bold;
color: #1976D2;
min-width: 40px;
}
.switch-item .sw-name {
flex: 1;
font-weight: 600;
}
.switch-item .sw-priority,
.switch-item .sw-mac {
font-family: 'Courier New', monospace;
font-size: 13px;
color: #666;
}
.link-item {
border-left-color: #FF9800;
}
.link-item .lk-label {
flex: 1;
font-family: 'Courier New', monospace;
font-size: 13px;
}
.tag {
display: inline-block;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}
.tag-root { background: #FFF3CD; color: #856404; }
.tag-fwd { background: #D4EDDA; color: #155724; }
.tag-blk { background: #F8D7DA; color: #721C24; }
.tag-disc { background: #D1ECF1; color: #0C5460; }
.tag-lrn { background: #CCE5FF; color: #004085; }
.tag-edge { background: #E2D9F3; color: #491F8A; }
/* ── Port state table ── */
.port-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
margin-top: 8px;
}
.port-table th {
background: #E3F2FD;
color: #1565C0;
padding: 8px 12px;
text-align: left;
font-weight: 600;
border-bottom: 2px solid #BBDEFB;
}
.port-table td {
padding: 7px 12px;
border-bottom: 1px solid #f0f0f0;
font-family: 'Courier New', monospace;
font-size: 13px;
}
.port-table tr:last-child td {
border-bottom: none;
}
.port-table tr:nth-child(even) td {
background: #f8f9fa;
}
/* ── Timeline ── */
.timeline {
position: relative;
padding-left: 28px;
}
.timeline::before {
content: '';
position: absolute;
left: 8px;
top: 0;
bottom: 0;
width: 2px;
background: #BBDEFB;
}
.timeline-event {
position: relative;
margin-bottom: 12px;
background: white;
border-radius: 6px;
padding: 10px 14px;
border: 1px solid #e8e8e8;
font-size: 13px;
}
.timeline-event::before {
content: '';
position: absolute;
left: -24px;
top: 12px;
width: 10px;
height: 10px;
border-radius: 50%;
background: #2196F3;
border: 2px solid white;
box-shadow: 0 0 0 2px #2196F3;
}
.timeline-event.root-election::before { background: #FFC107; box-shadow: 0 0 0 2px #FFC107; }
.timeline-event.port-change::before { background: #4CAF50; box-shadow: 0 0 0 2px #4CAF50; }
.timeline-event.port-blocked::before { background: #f44336; box-shadow: 0 0 0 2px #f44336; }
.timeline-event.convergence::before { background: #9C27B0; box-shadow: 0 0 0 2px #9C27B0; }
.timeline-event .te-time {
font-weight: bold;
color: #1976D2;
font-family: 'Courier New', monospace;
margin-right: 8px;
}
.timeline-event .te-desc {
color: #333;
}
/* ── BPDU Inspector ── */
.bpdu-panel {
background: #0d1117;
border-radius: 6px;
padding: 15px;
font-family: 'Courier New', monospace;
font-size: 13px;
color: #79c0ff;
max-height: 300px;
overflow-y: auto;
}
.bpdu-row {
display: flex;
gap: 8px;
margin-bottom: 3px;
line-height: 1.5;
}
.bpdu-field {
color: #d2a8ff;
min-width: 180px;
flex-shrink: 0;
}
.bpdu-val {
color: #a5f3fc;
}
.bpdu-val.root { color: #fbbf24; }
.bpdu-val.bridge { color: #86efac; }
/* ── Scenario selector ── */
.scenario-bar {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
margin-top: 10px;
}
.scenario-bar label {
font-weight: 600;
font-size: 14px;
color: white;
}
.scenario-bar select {
padding: 8px 12px;
border: 2px solid rgba(255,255,255,0.3);
border-radius: 6px;
background: rgba(255,255,255,0.95);
font-size: 14px;
cursor: pointer;
flex: 1;
min-width: 200px;
}
/* ── Legend ── */
.legend {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 8px;
font-size: 13px;
}
.legend-item {
display: flex;
align-items: center;
gap: 5px;
}
.legend-dot {
width: 12px;
height: 12px;
border-radius: 50%;
flex-shrink: 0;
}
/* ── Inline error / info messages ── */
.msg {
padding: 10px 14px;
border-radius: 6px;
font-size: 14px;
margin-top: 8px;
}
.msg-error {
background: #FFEBEE;
color: #C62828;
border-left: 4px solid #f44336;
}
.msg-info {
background: #E3F2FD;
color: #1565C0;
border-left: 4px solid #2196F3;
}
.msg-success {
background: #E8F5E9;
color: #1B5E20;
border-left: 4px solid #4CAF50;
}
/* ── STP concept panel ── */
.concept-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.concept-card {
background: white;
border-radius: 6px;
padding: 14px;
border-top: 3px solid #2196F3;
font-size: 13px;
}
.concept-card h4 {
margin: 0 0 6px 0;
color: #1976D2;
font-size: 14px;
}
.concept-card p {
margin: 0;
color: #555;
line-height: 1.5;
}
.concept-card.rstp {
border-top-color: #9C27B0;
}
.concept-card.rstp h4 {
color: #7B1FA2;
}
/* ── Mode toggle ── */
.mode-toggle {
display: flex;
gap: 0;
margin-top: 15px;
background: rgba(0,0,0,0.15);
border-radius: 6px;
padding: 4px;
}
.mode-btn {
flex: 1;
padding: 8px 16px;
border: none;
background: transparent;
color: rgba(255,255,255,0.7);
cursor: pointer;
border-radius: 4px;
font-size: 14px;
font-weight: 600;
transition: all 0.2s ease;
}
.mode-btn.active {
background: white;
color: #1976D2;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
/* ── Pulse animation for root bridge ── */
@keyframes rootPulse {
0% { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.7); }
70% { box-shadow: 0 0 0 10px rgba(255, 193, 7, 0); }
100% { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0); }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(12px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in-up {
animation: fadeInUp 0.35s ease both;
}
/* ── Responsive ── */
@media (max-width: 768px) {
.form-grid {
grid-template-columns: 1fr;
}
.data-row {
flex-direction: column;
}
.data-label {
margin-bottom: 4px;
min-width: auto;
}
.concept-grid {
grid-template-columns: 1fr;
}
#cy-container {
height: 280px;
}
.port-table {
font-size: 12px;
}
.port-table th,
.port-table td {
padding: 6px 8px;
}
.mode-btn {
padding: 8px 8px;
font-size: 13px;
}
.scenario-bar {
flex-direction: column;
align-items: stretch;
}
.scenario-bar label {
display: block;
}
}
@media (max-width: 480px) {
.calc-header {
padding: 18px;
}
.calc-header h2 {
font-size: 22px;
}
.switch-item,
.link-item {
flex-wrap: wrap;
}
}
═════════════════════════════ ═════════════════════════════
ہیڈر / کنفیگریشن
═════════════════════════════ ═════════════════════════════
/.calc-ہیڈر
═════════════════════════════ ═════════════════════════════
موجودہ ٹپوولوجی کی فہرست
═════════════════════════════ ═════════════════════════════
سوئچ کرتا ہے۔
- ابھی تک کوئی سوئچ شامل نہیں کیا گیا۔
لنکس
- ابھی تک کوئی لنکس شامل نہیں کیے گئے ہیں۔
═════════════════════════════ ═════════════════════════════
ٹوپولوجی ویژولائزیشن
═════════════════════════════ ═════════════════════════════
لیجنڈ
پورٹ کو مسدود کرنا / خارج کرنا
ڈیشڈ لائن = مسدود لنک
═════════════════════════════ ═════════════════════════════
روٹ برج الیکشن
═════════════════════════════ ═════════════════════════════
═════════════════════════════ ═════════════════════════════
پورٹ سٹیٹس
═════════════════════════════ ═════════════════════════════
═════════════════════════════ ═════════════════════════════
بی پی ڈی یو انسپکٹر
═════════════════════════════ ═════════════════════════════
═════════════════════════════ ═════════════════════════════
کنورجینس ٹائم لائن
═════════════════════════════ ═════════════════════════════
═════════════════════════════ ═════════════════════════════
STP تصورات
═════════════════════════════ ═════════════════════════════
روٹ برج الیکشن
سب سے کم برج ID والا سوئچ جیت جاتا ہے۔ برج ID = ترجیح (پہلے سے طے شدہ 32768) + MAC پتہ۔ ترجیحی تعلقات عددی طور پر کم MAC پر جاتے ہیں۔ صرف ایک روٹ برج فی VLAN۔
روٹ پورٹ
ہر نان روٹ سوئچ ایک روٹ پورٹ کا انتخاب کرتا ہے — وہ بندرگاہ جس کی روٹ برج تک سب سے کم مجموعی راستے کی لاگت ہوتی ہے۔ پڑوسی برج ID، پھر پورٹ ID سے تعلقات ٹوٹ جاتے ہیں۔
نامزد پورٹ
ہر نیٹ ورک کے حصے میں بالکل ایک نامزد پورٹ ہوتا ہے — وہ بندرگاہ جو جڑ تک بہترین (کم قیمت) راستہ پیش کرتی ہے۔ روٹ پل پر تمام بندرگاہوں کو نامزد کیا گیا ہے۔
بندرگاہوں کو مسدود / مسترد کرنا
کوئی بھی پورٹ جو نہ تو روٹ پورٹ ہے اور نہ ہی نامزد پورٹ بلاک (STP) یا ڈسکارڈنگ (RSTP) ہے۔ یہ لوپ فری ٹوپولوجی کو برقرار رکھتے ہوئے پرت-2 لوپس کو توڑ دیتے ہیں۔
RSTP (802.1w) ایج پورٹس
RSTP کنارے کی بندرگاہیں اختتامی میزبانوں سے جڑتی ہیں، دوسرے سوئچز سے نہیں۔ وہ فوری طور پر فارورڈنگ (سننے/سیکھنے میں تاخیر نہیں) کی طرف منتقل ہو جاتے ہیں، جو STP کی پورٹ فاسٹ خصوصیت کے برابر ہے۔
RSTP کنورجنسی کی رفتار
STP کنورژنس میں 30-50 سیکنڈ لگتے ہیں (سننا 15s + لرننگ 15s فی پورٹ)۔ RSTP ایک تجویز/ایگریمنٹ ہینڈ شیک کا استعمال کرتا ہے، جو 2 سیکنڈ سے کم فی ہاپ میں بدلتا ہے۔
راستے کی قیمت (IEEE 802.1D)
10 Gbps = 2، 1 Gbps = 4، 100 Mbps = 19، 10 Mbps = 100، 1.5 Mbps = 1000۔ کم قیمت = ترجیحی راستہ۔ روٹ برج کے اشتہار کی قیمت 0؛ ہر ہاپ اس کی پورٹ لاگت کا اضافہ کرتی ہے۔
BPDU (برج پروٹوکول ڈیٹا یونٹ)
بی پی ڈی یوز لے جاتے ہیں: روٹ برج آئی ڈی، روٹ پاتھ کاسٹ، بھیجنے والے برج آئی ڈی، پورٹ آئی ڈی، اور ٹائمر۔ روٹ برج ہر ہیلو ٹائم (2s) BPDUs سے نکلتا ہے۔ دوسرے پل انہیں نامزد بندرگاہوں پر باہر کی طرف لے جاتے ہیں۔
/.calc-کنٹینر
Cytoscape.js CDN