<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>JavaScript |</title><link>https://clementgodbarge.com/fa/tag/javascript/</link><atom:link href="https://clementgodbarge.com/fa/tag/javascript/index.xml" rel="self" type="application/rss+xml"/><description>JavaScript</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>fa</language><lastBuildDate>Thu, 13 Feb 2025 00:00:00 +0000</lastBuildDate><image><url>https://clementgodbarge.com/media/icon_hu_64a6c3bec25b3d7b.png</url><title>JavaScript</title><link>https://clementgodbarge.com/fa/tag/javascript/</link></image><item><title>شبیه‌ساز تلگراف ITA2</title><link>https://clementgodbarge.com/fa/code/baudot-emulator/</link><pubDate>Thu, 13 Feb 2025 00:00:00 +0000</pubDate><guid>https://clementgodbarge.com/fa/code/baudot-emulator/</guid><description>&lt;p&gt;این شبیه‌ساز ITA2 با دیدنی و لمس‌کردنی کردن مفاهیم انتزاعی رمزگذاری، ابزاری عملی برای تدریس است. وقتی دانشجویان متنی را تایپ می‌کنند و بی‌درنگ تبدیل آن را به الگوی سوراخ‌ها می‌بینند، چند مفهوم کلیدی رایانش و مخابرات را یک‌جا می‌آموزند.&lt;/p&gt;
&lt;h2 id="فایده-آموزشی"&gt;فایدهٔ آموزشی&lt;/h2&gt;
&lt;p&gt;نخست، بازنمایی دودویی را نشان می‌دهد؛ اینکه متن چگونه به الگویی از 1 و 0 بدل می‌شود. ما این درس را اغلب به‌شکل انتزاعی می‌دهیم؛ اما وقتی دانشجو سوراخ‌ها را به چشم می‌بیند که پدیدار می‌شوند، بهتر درمی‌یابد که یک سازوکار فیزیکی چگونه می‌تواند اطلاعات دیجیتال را در خود نگه دارد.&lt;/p&gt;
&lt;div class="baudot-emulator"&gt;
&lt;h2&gt;ITA2 (Baudot-Murray) Telegraph Type Emulator&lt;/h2&gt;
&lt;p&gt;Type a word in the input below to see its representation on the ITA2 tape.&lt;/p&gt;
&lt;div class="baudot-controls"&gt;
&lt;label for="baudot-input"&gt;Type word:&lt;/label&gt;
&lt;input id="baudot-input" class="text-input" size="50" maxlength="50" /&gt;
&lt;button type="button" id="baudot-ltr-button" class="control-button active"&gt;LTR&lt;/button&gt;
&lt;button type="button" id="baudot-fig-button" class="control-button"&gt;FIG&lt;/button&gt;
&lt;/div&gt;
&lt;div class="tape-outer-container"&gt;
&lt;div class="tape-container"&gt;
&lt;table&gt;
&lt;tbody id="baudot-tape"&gt;&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.baudot-emulator {
--light-color: #f3f4f6;
--dark-color: #1f2937;
--light-alt-color: #e5e7eb;
--dark-alt-color: #374151;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;
max-width: 100%;
margin: 2rem 0;
padding: 0;
box-sizing: border-box;
}
.baudot-emulator {
--tape-bg: var(--light-color);
--hole-bg: var(--light-color);
--hole-border: #d1d5db;
--punched-bg: var(--dark-color);
--punched-border: var(--dark-color);
--sprocket-bg: var(--light-color);
--sprocket-border: #9ca3af;
--button-bg: var(--light-color);
--button-bg-active: #d1d5db;
--button-text: var(--dark-color);
--button-border: #d1d5db;
--input-bg: white;
--input-border: #d1d5db;
--input-text: var(--dark-color);
--line-number: #6b7280;
}
html.dark .baudot-emulator,
html[data-theme='dark'] .baudot-emulator,
body.dark .baudot-emulator {
--tape-bg: var(--dark-alt-color);
--hole-bg: var(--dark-alt-color);
--hole-border: #4b5563;
--punched-bg: var(--light-color);
--punched-border: var(--light-color);
--sprocket-bg: var(--dark-alt-color);
--sprocket-border: #9ca3af;
--button-bg: var(--dark-alt-color);
--button-bg-active: #4b5563;
--button-text: var(--light-color);
--button-border: #4b5563;
--input-bg: var(--dark-alt-color);
--input-border: #4b5563;
--input-text: var(--light-color);
--line-number: #9ca3af;
}
.baudot-controls {
margin-bottom: 1.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.5rem;
}
.baudot-emulator .text-input {
flex: 1;
min-width: 200px;
padding: 0.5rem;
font-size: 1rem;
border: 1px solid var(--input-border);
border-radius: 4px;
background: var(--input-bg);
color: var(--input-text);
}
.baudot-emulator .control-button {
padding: 0.5rem 1rem;
background: var(--button-bg);
color: var(--button-text);
border: 1px solid var(--button-border);
border-radius: 4px;
cursor: pointer;
font-size: 0.9rem;
}
.baudot-emulator .control-button.active {
background: var(--button-bg-active);
font-weight: bold;
}
.tape-outer-container {
padding: 0;
margin-bottom: 1.5rem;
border-radius: 4px;
overflow: hidden;
}
.tape-container {
width: 100%;
overflow-x: auto;
background: var(--tape-bg);
padding: 1rem 0.5rem;
}
.baudot-emulator table {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
border: none;
}
.baudot-emulator tr {
height: 24px;
border: none;
}
.baudot-emulator td {
border: none;
padding: 0;
}
.baudot-emulator .line-number {
width: 20px;
text-align: center;
color: var(--line-number);
font-size: 0.8rem;
padding: 0 8px 0 0;
font-weight: bold;
}
.baudot-emulator .cell {
position: relative;
width: 20px;
height: 20px;
}
.baudot-emulator .cell-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--hole-bg);
border: 1px solid var(--hole-border);
}
.baudot-emulator .punched .cell-content {
background: var(--punched-bg);
border: 1px solid var(--punched-border);
}
.baudot-emulator .sprocket-hole {
position: absolute;
left: 50%;
top: 100%;
transform: translate(-50%, -50%);
width: 4px;
height: 4px;
border-radius: 50%;
background: var(--sprocket-bg);
border: 1px solid var(--sprocket-border);
z-index: 2;
}
&lt;/style&gt;
&lt;script&gt;
document.addEventListener('DOMContentLoaded', function() {
initBaudotEmulator();
});
function initBaudotEmulator() {
if (!document.getElementById('baudot-input')) return;
const textInput = document.getElementById('baudot-input');
const tape = document.getElementById('baudot-tape');
const ltrButton = document.getElementById('baudot-ltr-button');
const figButton = document.getElementById('baudot-fig-button');
const ita2Code = {
'A': '00011', 'B': '11001', 'C': '01110', 'D': '01001', 'E': '00001',
'F': '01101', 'G': '11010', 'H': '10100', 'I': '00110', 'J': '01011',
'K': '01111', 'L': '10010', 'M': '11100', 'N': '01100', 'O': '11000',
'P': '10110', 'Q': '10111', 'R': '01010', 'S': '00101', 'T': '10000',
'U': '00111', 'V': '11110', 'W': '10011', 'X': '11101', 'Y': '10101',
'Z': '10001',
'1': '00011', '2': '11001', '3': '01110', '4': '01001', '5': '00001',
'6': '01101', '7': '11010', '8': '10100', '9': '01011', '0': '11000',
'-': '00011', '?': '00100', ':': '01010', '(': '11000', ')': '11101',
'.': '01000', ',': '00010', "'": '10001', '=': '01111', '/': '10011',
'+': '11011', ' ': '00100',
'FIG': '11011', 'LTR': '11111',
};
function generateTape() {
let rows = '';
for (let row = 0; row &lt; 5; row++) {
rows += '&lt;tr&gt;';
rows += `&lt;td class="line-number"&gt;${row + 1}&lt;/td&gt;`;
for (let col = 0; col &lt; 50; col++) {
rows += `&lt;td id="baudot_${row}_${col}" class="cell unpunched"&gt;
&lt;div class="cell-content"&gt;&lt;/div&gt;
${row === 2 ? '&lt;div class="sprocket-hole"&gt;&lt;/div&gt;' : ''}
&lt;/td&gt;`;
}
rows += '&lt;/tr&gt;';
}
tape.innerHTML = rows;
}
function updateITA2Code(word) {
clearTape();
word = word.toUpperCase();
let tapePosition = 0;
let currentCharType = 'LTR';
ltrButton.classList.add('active');
figButton.classList.remove('active');
for (let i = 0; i &lt; word.length; i++) {
const char = word[i];
let code = ita2Code[char] || ita2Code[' '];
let requiredCharType = /[A-Z ]/.test(char) ? 'LTR' : 'FIG';
if (requiredCharType !== currentCharType) {
const shiftCode = requiredCharType === 'LTR' ? ita2Code['LTR'] : ita2Code['FIG'];
punchTape(shiftCode, tapePosition++);
currentCharType = requiredCharType;
ltrButton.classList.toggle('active', currentCharType === 'LTR');
figButton.classList.toggle('active', currentCharType === 'FIG');
}
punchTape(code, tapePosition++);
}
}
function punchTape(code, tapePosition) {
if (tapePosition &gt;= 50) return;
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${tapePosition}`);
if (cell) {
cell.className = code[bit] === '1' ? 'cell punched' : 'cell unpunched';
}
}
}
function clearTape() {
for (let i = 0; i &lt; 50; i++) {
for (let bit = 0; bit &lt; 5; bit++) {
const cell = document.getElementById(`baudot_${bit}_${i}`);
if (cell) {
cell.className = 'cell unpunched';
}
}
}
}
generateTape();
textInput.addEventListener('input', function() {
updateITA2Code(this.value);
});
ltrButton.addEventListener('click', function() {
this.classList.add('active');
figButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
figButton.addEventListener('click', function() {
this.classList.add('active');
ltrButton.classList.remove('active');
if (textInput.value) {
updateITA2Code(textInput.value);
}
});
if (textInput.value) {
updateITA2Code(textInput.value);
}
}
&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;سازوکار تغییر حالت LETTERS/FIGURES، ماشین‌های حالت را به طبیعی‌ترین شکل به میان می‌آورد. دانشجویان با آزمون و خطا کشف می‌کنند که یک الگوی واحد، بسته به حالت جاری، می‌تواند نمایندهٔ نویسه‌های متفاوتی باشد. این تجربهٔ عملی با رمزگذاری حالت‌محور، آنان را برای مفاهیم پیچیده‌تر رایانش آماده می‌کند.&lt;/p&gt;
&lt;h2 id="جزئیات-پیادهسازی"&gt;جزئیات پیاده‌سازی&lt;/h2&gt;
&lt;p&gt;شبیه‌ساز به JavaScript و HTML/CSS نوشته شده و از این رو به‌آسانی در هر صفحهٔ وبی جای می‌گیرد. کد آن پیمانه‌ای است و برای زمینه‌های آموزشی گوناگون قابل تطبیق.&lt;/p&gt;
&lt;p&gt;کد منبع را می‌توانید ببینید و خودتان شبیه‌ساز را در
بیازمایید.&lt;/p&gt;</description></item></channel></rss>