{"id":17889,"date":"2026-06-29T14:27:30","date_gmt":"2026-06-29T07:27:30","guid":{"rendered":"https:\/\/chanh.me\/?page_id=17889"},"modified":"2026-06-29T14:27:30","modified_gmt":"2026-06-29T07:27:30","slug":"may-tinh","status":"publish","type":"page","link":"https:\/\/draff.sieuthitinhoc.com\/index.php\/may-tinh\/","title":{"rendered":"M\u00e1y t\u00ednh"},"content":{"rendered":"\n<!-- M\u00e1y t\u00ednh b\u1ecf t\u00fai - b\u1ea3n ch\u00e8n WordPress Custom HTML -->\n<style>\n.sth-calculator-shell *{box-sizing:border-box;margin:0;padding:0;-webkit-tap-highlight-color:transparent;}\n.sth-calculator-shell{--bg:#0a0a0f;\n  --glass:rgba(255,255,255,0.04);\n  --glass-border:rgba(255,255,255,0.08);\n  --display-bg:rgba(0,0,0,0.5);\n  --num:#f0f0f5;\n  --op-color:#ff9f0a;\n  --op-bg:rgba(255,159,10,0.15);\n  --op-border:rgba(255,159,10,0.3);\n  --eq-bg:#ff9f0a;\n  --func-bg:rgba(255,255,255,0.08);\n  --func-color:#c8c8d4;\n  --zero-bg:rgba(255,255,255,0.05);\n  --shadow:0 32px 80px rgba(0,0,0,0.8);\n  --glow:0 0 40px rgba(255,159,10,0.08);}\n.sth-calculator-shell{width:100%; min-height:640px;\n  background:var(--bg);\n  display:flex; align-items:center; justify-content:center;\n  font-family:Arial,'Helvetica Neue',sans-serif;\n  overflow:hidden; padding:24px 12px; border-radius:24px;}\n.sth-calculator-shell \/* Subtle background texture *\/\n.sth-calculator-shell::before{content:'';position:fixed;inset:0;\n  background:\n    radial-gradient(ellipse 60% 50% at 30% 20%, rgba(255,159,10,0.06) 0%, transparent 60%),\n    radial-gradient(ellipse 40% 60% at 80% 80%, rgba(100,80,255,0.05) 0%, transparent 60%);\n  pointer-events:none;}\n.sth-calculator-shell .calc-wrap{position:relative;\n  width:min(360px, 100vw);\n  padding:0 0 env(safe-area-inset-bottom,0);}\n.sth-calculator-shell .calc{background:rgba(18,18,28,0.95);\n  border:1px solid var(--glass-border);\n  border-radius:32px;\n  overflow:hidden;\n  box-shadow:var(--shadow), var(--glow);\n  backdrop-filter:blur(20px);\n  -webkit-backdrop-filter:blur(20px);}\n.sth-calculator-shell \/* \u2500\u2500 DISPLAY \u2500\u2500 *\/\n.display{background:var(--display-bg);\n  padding:28px 28px 20px;\n  min-height:140px;\n  display:flex;\n  flex-direction:column;\n  align-items:flex-end;\n  justify-content:flex-end;\n  gap:8px;\n  border-bottom:1px solid rgba(255,255,255,0.05);\n  position:relative;}\n.sth-calculator-shell .display::after{content:'';\n  position:absolute;bottom:0;left:0;right:0;height:1px;\n  background:linear-gradient(90deg,transparent,rgba(255,159,10,0.4),transparent);}\n.sth-calculator-shell .expr{font-family:'Consolas','Courier New',monospace;\n  font-size:1rem;\n  font-weight:300;\n  color:rgba(255,255,255,0.35);\n  min-height:22px;\n  word-break:break-all;\n  text-align:right;\n  transition:opacity .15s;\n  letter-spacing:0.02em;}\n.sth-calculator-shell .main-display{font-family:'Consolas','Courier New',monospace;\n  font-weight:300;\n  color:var(--num);\n  text-align:right;\n  line-height:1;\n  word-break:break-all;\n  transition:font-size .1s;\n  letter-spacing:-0.02em;}\n.sth-calculator-shell .main-display.size-xl{font-size:3.6rem;}\n.sth-calculator-shell .main-display.size-lg{font-size:2.8rem;}\n.sth-calculator-shell .main-display.size-md{font-size:2rem;}\n.sth-calculator-shell .main-display.size-sm{font-size:1.5rem;}\n.sth-calculator-shell .main-display.flash{animation:flash .12s ease;}\n@keyframes flash{\n  0%{opacity:1;}50%{opacity:.3;}100%{opacity:1;}\n}\n\n.display .status-row}\n.sth-calculator-shell .mem-indicator{font-family:'Consolas','Courier New',monospace;\n  font-size:.65rem;font-weight:400;\n  color:rgba(255,159,10,0.7);\n  opacity:0;transition:opacity .2s;\n  letter-spacing:.08em;\n  text-transform:uppercase;}\n.sth-calculator-shell .mem-indicator.show{opacity:1;}\n.sth-calculator-shell .err-indicator{font-size:.65rem;color:#ff453a;\n  font-family:'Consolas','Courier New',monospace;\n  opacity:0;transition:opacity .2s;\n  letter-spacing:.05em;}\n.sth-calculator-shell .err-indicator.show{opacity:1;}\n.sth-calculator-shell \/* \u2500\u2500 BUTTONS \u2500\u2500 *\/\n.btns{display:grid;\n  grid-template-columns:repeat(4,1fr);\n  gap:1px;\n  background:rgba(255,255,255,0.04);\n  padding:1px;}\n.sth-calculator-shell .btn{border:none;cursor:pointer;\n  font-family:Arial,'Helvetica Neue',sans-serif;\n  font-weight:400;\n  font-size:1.4rem;\n  height:78px;\n  display:flex;align-items:center;justify-content:center;\n  position:relative;\n  transition:filter .1s, transform .08s;\n  user-select:none;\n  -webkit-user-select:none;\n  outline:none;\n  background:rgba(28,28,40,0.9);\n  color:var(--num);}\n.sth-calculator-shell .btn:active{filter:brightness(1.4);\n  transform:scale(.94);}\n.sth-calculator-shell .btn::after{content:'';\n  position:absolute;inset:0;\n  background:white;opacity:0;\n  transition:opacity .12s;}\n.sth-calculator-shell .btn:active::after{opacity:.06;}\n.sth-calculator-shell \/* Number buttons *\/\n.btn.num{background:rgba(28,28,42,0.95);\n  color:var(--num);\n  font-size:1.5rem;\n  font-weight:300;\n  font-family:'Consolas','Courier New',monospace;}\n.sth-calculator-shell .btn.num:hover{background:rgba(40,40,58,0.95);}\n.sth-calculator-shell \/* Zero button spans 2 columns *\/\n.btn.zero{grid-column:span 2;\n  justify-content:flex-start;\n  padding-left:30px;\n  font-family:'Consolas','Courier New',monospace;\n  font-weight:300;\n  font-size:1.5rem;}\n.sth-calculator-shell \/* Function buttons (AC, .sth-calculator-shell +\/-, .sth-calculator-shell %) *\/\n.btn.func{background:rgba(48,48,64,0.95);\n  color:var(--func-color);\n  font-size:1.2rem;\n  font-weight:400;}\n.sth-calculator-shell .btn.func:hover{background:rgba(62,62,80,0.95);}\n.sth-calculator-shell \/* Operator buttons *\/\n.btn.op{background:rgba(255,159,10,0.12);\n  color:var(--op-color);\n  font-size:1.7rem;\n  font-weight:300;}\n.sth-calculator-shell .btn.op:hover{background:rgba(255,159,10,0.2);}\n.sth-calculator-shell .btn.op.active-op{background:var(--op-color);\n  color:#1a0e00;}\n.sth-calculator-shell \/* Equals *\/\n.btn.eq{background:var(--eq-bg);\n  color:#1a0e00;\n  font-size:1.7rem;\n  font-weight:400;}\n.sth-calculator-shell .btn.eq:hover{background:#ffb340;}\n.sth-calculator-shell .btn.eq:active{background:#e08800;}\n.sth-calculator-shell \/* Backspace button *\/\n.btn.back-btn{font-size:1.5rem;\n  color:#ff6b6b;}\n.sth-calculator-shell .btn.back-btn:hover{background:rgba(255,107,107,0.12);}\n.sth-calculator-shell \/* Decimal *\/\n.btn.dot{font-family:'Consolas','Courier New',monospace;\n  font-size:1.8rem;\n  font-weight:300;\n  color:var(--num);\n  background:rgba(28,28,42,0.95);}\n.sth-calculator-shell \/* Corner radius matching grid position *\/\n.btn:nth-child(1){border-radius:0;}\n.sth-calculator-shell .btn:nth-child(4){border-radius:0;}\n.sth-calculator-shell .btn:nth-last-child(2){border-radius:0 0 0 24px;}\n.sth-calculator-shell .btn:last-child{border-radius:0 0 24px 0;}\n.sth-calculator-shell \/* \u2500\u2500 HISTORY STRIP \u2500\u2500 *\/\n.history-strip{max-height:0;overflow:hidden;\n  transition:max-height .3s ease;\n  background:rgba(0,0,0,0.3);}\n.sth-calculator-shell .history-strip.open{max-height:120px;}\n.sth-calculator-shell .history-inner{padding:10px 20px;\n  display:flex;flex-direction:column;gap:4px;\n  overflow-y:auto;max-height:120px;}\n.sth-calculator-shell .history-item{font-family:'Consolas','Courier New',monospace;\n  font-size:.78rem;color:rgba(255,255,255,0.3);\n  text-align:right;cursor:pointer;\n  transition:color .15s;\n  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}\n.sth-calculator-shell .history-item:hover{color:rgba(255,255,255,0.6);}\n.sth-calculator-shell .history-item .h-result{color:rgba(255,159,10,0.6);}\n.sth-calculator-shell \/* \u2500\u2500 TOP BAR \u2500\u2500 *\/\n.topbar{display:flex;align-items:center;justify-content:space-between;\n  padding:14px 20px 0;}\n.sth-calculator-shell .calc-title{font-size:.7rem;font-weight:400;\n  color:rgba(255,255,255,0.2);letter-spacing:.15em;text-transform:uppercase;}\n.sth-calculator-shell .history-btn{background:none;border:none;cursor:pointer;\n  color:rgba(255,255,255,0.25);font-size:.75rem;\n  display:flex;align-items:center;gap:4px;\n  font-family:Arial,'Helvetica Neue',sans-serif;\n  transition:color .15s;padding:4px;}\n.sth-calculator-shell .history-btn:hover{color:rgba(255,255,255,0.5);}\n.sth-calculator-shell .history-btn svg{width:14px;height:14px;}\n.sth-calculator-shell \/* Keyboard hint *\/\n.kb-hint{text-align:center;padding:10px;\n  font-size:.6rem;color:rgba(255,255,255,0.1);\n  letter-spacing:.08em;font-family:'Consolas','Courier New',monospace;}\n.sth-calculator-shell button{box-shadow:none;text-decoration:none;}\n@media(max-width:480px){.sth-calculator-shell{min-height:auto;padding:14px 8px}.sth-calculator-shell .calc-wrap{width:100%}.sth-calculator-shell .btn{height:68px}.sth-calculator-shell .main-display.size-xl{font-size:3rem}}\n\n<\/style>\n\n<div class=\"sth-calculator-shell\">\n<div class=\"calc-wrap\">\n  <div class=\"calc\">\n\n    <div class=\"topbar\">\n      <span class=\"calc-title\">M\u00e1y T\u00ednh<\/span>\n      <button class=\"history-btn\" id=\"sthcalc-hist-toggle\" onclick=\"sthCalc_toggleHistory()\" title=\"L\u1ecbch s\u1eed\">\n        <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n          <polyline points=\"1 4 1 10 7 10\"><\/polyline>\n          <path d=\"M3.51 15a9 9 0 1 0 .49-5H1\"><\/path>\n        <\/svg>\n        L\u1ecbch s\u1eed\n      <\/button>\n    <\/div>\n\n    <!-- History strip -->\n    <div class=\"history-strip\" id=\"sthcalc-history-strip\">\n      <div class=\"history-inner\" id=\"sthcalc-history-list\"><\/div>\n    <\/div>\n\n    <!-- Display -->\n    <div class=\"display\">\n      <div class=\"status-row\">\n        <span class=\"mem-indicator\" id=\"sthcalc-mem-ind\">M<\/span>\n        <span class=\"err-indicator\" id=\"sthcalc-err-ind\">L\u1ed7i<\/span>\n      <\/div>\n      <div class=\"expr\" id=\"sthcalc-expr\"><\/div>\n      <div class=\"main-display size-xl\" id=\"sthcalc-disp\">0<\/div>\n    <\/div>\n\n    <!-- Buttons -->\n    <div class=\"btns\">\n      <!-- Row 1 -->\n      <button class=\"btn func\" id=\"sthcalc-btn-ac\"  onclick=\"sthCalc_pressAC()\">AC<\/button>\n      <button class=\"btn func\"               onclick=\"sthCalc_pressPlusMinus()\">+\/\u2212<\/button>\n      <button class=\"btn func back-btn\"      onclick=\"sthCalc_pressBack()\" title=\"X\u00f3a 1 ch\u1eef s\u1ed1 (Backspace)\">\u232b<\/button>\n      <button class=\"btn op\"   id=\"sthcalc-op-div\"  onclick=\"sthCalc_pressOp('\u00f7')\">\u00f7<\/button>\n\n      <!-- Row 2 -->\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('7')\">7<\/button>\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('8')\">8<\/button>\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('9')\">9<\/button>\n      <button class=\"btn op\"  id=\"sthcalc-op-mul\"  onclick=\"sthCalc_pressOp('\u00d7')\">\u00d7<\/button>\n\n      <!-- Row 3 -->\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('4')\">4<\/button>\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('5')\">5<\/button>\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('6')\">6<\/button>\n      <button class=\"btn op\"  id=\"sthcalc-op-sub\"  onclick=\"sthCalc_pressOp('\u2212')\">\u2212<\/button>\n\n      <!-- Row 4 -->\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('1')\">1<\/button>\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('2')\">2<\/button>\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('3')\">3<\/button>\n      <button class=\"btn op\"  id=\"sthcalc-op-add\"  onclick=\"sthCalc_pressOp('+')\">+<\/button>\n\n      <!-- Row 5 -->\n      <button class=\"btn num\"               onclick=\"sthCalc_pressNum('0')\">0<\/button>\n      <button class=\"btn func\"              onclick=\"sthCalc_pressPercent()\">%<\/button>\n      <button class=\"btn dot\"               onclick=\"sthCalc_pressDot()\">.<\/button>\n      <button class=\"btn eq\"                onclick=\"sthCalc_pressEquals()\">=<\/button>\n    <\/div>\n\n  <\/div>\n  <div class=\"kb-hint\">H\u1ed7 tr\u1ee3 b\u00e0n ph\u00edm \u2022 Backspace x\u00f3a \u2022 Esc reset<\/div>\n<\/div>\n<\/div>\n\n<script>\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  STATE\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nconst sthCalcState = {\n  cur:     '0',        \/\/ current input string\n  prev:    null,       \/\/ previous operand (number)\n  op:      null,       \/\/ pending operator: '+' '\u2212' '\u00d7' '\u00f7'\n  justEq:  false,      \/\/ just pressed =\n  newNum:  true,       \/\/ next digit starts a new number\n  memory:  0,\n  hasMemory: false,\n  history: [],\n  isError: false,\n};\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  SAFE MATH \u2014 no eval, full precision handling\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n\/**\n * Remove floating-point rounding noise.\n * e.g. 0.1 + 0.2 = 0.30000000000000004 \u2192 0.3\n *\/\nfunction sthCalc_cleanFloat(n) {\n  if (!isFinite(n)) return n;\n  \/\/ Round to 12 significant digits to eliminate floating-point noise\n  return parseFloat(n.toPrecision(12));\n}\n\nfunction sthCalc_calculate(a, op, b) {\n  a = parseFloat(a);\n  b = parseFloat(b);\n  switch (op) {\n    case '+': return sthCalc_cleanFloat(a + b);\n    case '\u2212': return sthCalc_cleanFloat(a - b);\n    case '\u00d7': return sthCalc_cleanFloat(a * b);\n    case '\u00f7':\n      if (b === 0) return (a === 0) ? NaN : Infinity;\n      return sthCalc_cleanFloat(a \/ b);\n  }\n  return b;\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  DISPLAY\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nconst dispEl  = document.getElementById('sthcalc-disp');\nconst exprEl  = document.getElementById('sthcalc-expr');\nconst acBtn   = document.getElementById('sthcalc-btn-ac');\nconst memInd  = document.getElementById('sthcalc-mem-ind');\nconst errInd  = document.getElementById('sthcalc-err-ind');\n\n\/**\n * Format number theo chu\u1ea9n Vietcombank:\n *   - D\u1ea5u ph\u1ea9y (,) ph\u00e2n c\u00e1ch h\u00e0ng ngh\u00ecn\n *   - D\u1ea5u ch\u1ea5m (.) ph\u1ea7n th\u1eadp ph\u00e2n\n *   - V\u00ed d\u1ee5: 15,000,000.01\n *\n * @param {string} str      - chu\u1ed7i s\u1ed1 n\u1ed9i b\u1ed9 (lu\u00f4n d\u00f9ng '.' l\u00e0m th\u1eadp ph\u00e2n)\n * @param {boolean} isTyping - true khi ng\u01b0\u1eddi d\u00f9ng \u0111ang g\u00f5 (gi\u1eef trailing zeros\/dot)\n *\/\nfunction sthCalc_formatNum(str, isTyping = false) {\n  if (str === 'Infinity' || str === '-Infinity') return '\u221e';\n  if (str === 'NaN') return 'L\u1ed7i';\n\n  const n = parseFloat(str);\n  if (!isFinite(n)) return '\u221e';\n\n  const abs = Math.abs(n);\n\n  \/\/ \u2500\u2500 S\u1ed1 r\u1ea5t l\u1edbn\/nh\u1ecf \u2192 scientific notation \u2500\u2500\n  if (abs >= 1e13 || (abs < 1e-6 &#038;&#038; abs > 0)) {\n    return n.toExponential(6).replace(\/\\.?0+e\/, 'e');\n  }\n\n  \/\/ \u2500\u2500 X\u00e1c \u0111\u1ecbnh intPart v\u00e0 decPart \u2500\u2500\n  let intPart, decPart;\n\n  if (isTyping && str.endsWith('.')) {\n    \/\/ V\u1eeba g\u00f5 d\u1ea5u ch\u1ea5m\n    intPart = str.slice(0, -1);\n    decPart = null;\n  } else if (isTyping && str.includes('.')) {\n    \/\/ \u0110ang g\u00f5 ph\u1ea7n th\u1eadp ph\u00e2n \u2014 gi\u1eef nguy\u00ean k\u1ec3 c\u1ea3 trailing zeros\n    const dot = str.indexOf('.');\n    intPart = str.slice(0, dot);\n    decPart = str.slice(dot + 1);\n  } else {\n    \/\/ K\u1ebft qu\u1ea3 ho\u00e0n ch\u1ec9nh: d\u00f9ng toPrecision(12) \u0111\u1ec3 tr\u00e1nh floating-point noise\n    \/\/ r\u1ed3i trim trailing zeros\n    let clean;\n    if (Number.isInteger(n)) {\n      clean = String(n);\n    } else {\n      \/\/ toPrecision(12) lo\u1ea1i b\u1ecf noise (vd: 0.1+0.2=0.3, kh\u00f4ng ph\u1ea3i 0.30000000000000004)\n      clean = parseFloat(n.toPrecision(12)).toString();\n    }\n    const dot = clean.indexOf('.');\n    if (dot === -1) {\n      intPart = clean; decPart = null;\n    } else {\n      intPart = clean.slice(0, dot);\n      decPart = clean.slice(dot + 1);\n    }\n  }\n\n  \/\/ \u2500\u2500 Th\u00eam d\u1ea5u ph\u1ea9y h\u00e0ng ngh\u00ecn \u2500\u2500\n  const sign = intPart.startsWith('-') ? '-' : '';\n  const absInt = intPart.replace('-', '');\n  const withCommas = absInt.replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, ',');\n\n  \/\/ \u2500\u2500 Gh\u00e9p l\u1ea1i \u2500\u2500\n  let result = sign + withCommas;\n  if (decPart !== null && decPart !== undefined) {\n    result += '.' + decPart;\n  } else if (isTyping && str.endsWith('.')) {\n    result += '.';\n  }\n\n  return result;\n}\n\nfunction sthCalc_updateDisplay() {\n  const raw = sthCalcState.cur;\n  \/\/ isTyping = true khi ng\u01b0\u1eddi d\u00f9ng \u0111ang nh\u1eadp s\u1ed1 (kh\u00f4ng ph\u1ea3i k\u1ebft qu\u1ea3 t\u00ednh)\n  const isTyping = !sthCalcState.newNum && !sthCalcState.justEq;\n  const formatted = sthCalc_formatNum(raw, isTyping);\n\n  dispEl.textContent = formatted;\n\n  \/\/ Font size d\u1ef1a tr\u00ean \u0111\u1ed9 d\u00e0i chu\u1ed7i c\u00f3 d\u1ea5u ph\u1ea9y\n  const len = formatted.length;\n  dispEl.className = 'main-display ' +\n    (len <= 11 ? 'size-xl' : len <= 15 ? 'size-lg' : len <= 20 ? 'size-md' : 'size-sm');\n\n  \/\/ AC \/ C\n  acBtn.textContent = (sthCalcState.cur !== '0' &#038;&#038; !sthCalcState.newNum &#038;&#038; !sthCalcState.justEq) ? 'C' : 'AC';\n\n  \/\/ Expression row \u2014 prev l\u00e0 s\u1ed1 \u0111\u00e3 ho\u00e0n ch\u1ec9nh, kh\u00f4ng c\u1ea7n isTyping\n  if (sthCalcState.op &#038;&#038; sthCalcState.prev !== null &#038;&#038; sthCalcState.newNum) {\n    exprEl.textContent = sthCalc_formatNum(String(sthCalcState.prev), false) + ' ' + sthCalcState.op;\n  } else if (sthCalcState.justEq) {\n    exprEl.textContent = '';\n  } else {\n    exprEl.textContent = '';\n  }\n\n  \/\/ Memory indicator\n  memInd.classList.toggle('show', sthCalcState.hasMemory &#038;&#038; sthCalcState.memory !== 0);\n\n  \/\/ Error indicator\n  const isErr = raw === 'NaN' || raw === 'Infinity' || raw === '-Infinity';\n  sthCalcState.isError = isErr;\n  errInd.classList.toggle('show', isErr &#038;&#038; raw !== 'Infinity');\n}\n\nfunction sthCalc_flash() {\n  dispEl.classList.remove('flash');\n  void dispEl.offsetWidth; \/\/ reflow\n  dispEl.classList.add('flash');\n  setTimeout(() => dispEl.classList.remove('flash'), 150);\n}\n\nfunction sthCalc_highlightOp(op) {\n  ['add','sub','mul','div'].forEach(id => {\n    document.getElementById('sthcalc-op-'+id)?.classList.remove('active-op');\n  });\n  const map = {'+':'sthcalc-op-add','\u2212':'sthcalc-op-sub','\u00d7':'sthcalc-op-mul','\u00f7':'sthcalc-op-div'};\n  if (op && map[op]) document.getElementById(map[op])?.classList.add('active-op');\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  BUTTON HANDLERS\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nfunction sthCalc_pressNum(d) {\n  if (sthCalcState.isError) return;\n\n  if (sthCalcState.justEq || sthCalcState.newNum) {\n    sthCalcState.cur = d === '0' ? '0' : d;\n    sthCalcState.justEq = false;\n    sthCalcState.newNum = false;\n  } else {\n    \/\/ Max 15 digits\n    const digits = sthCalcState.cur.replace(\/[^0-9]\/g, '').length;\n    if (digits >= 15) return;\n    sthCalcState.cur = sthCalcState.cur === '0' ? d : sthCalcState.cur + d;\n  }\n  sthCalc_updateDisplay();\n}\n\nfunction sthCalc_pressDot() {\n  if (sthCalcState.isError) return;\n  if (sthCalcState.justEq || sthCalcState.newNum) { sthCalcState.cur = '0.'; sthCalcState.justEq = false; sthCalcState.newNum = false; sthCalc_updateDisplay(); return; }\n  if (!sthCalcState.cur.includes('.')) { sthCalcState.cur += '.'; }\n  sthCalc_updateDisplay();\n}\n\nfunction sthCalc_pressOp(op) {\n  if (sthCalcState.isError && op !== 'AC') return;\n\n  \/\/ If we have a pending op and user types another op without =, calculate first\n  if (sthCalcState.op && !sthCalcState.newNum) {\n    const result = sthCalc_calculate(sthCalcState.prev, sthCalcState.op, sthCalcState.cur);\n    sthCalc_addHistory(sthCalcState.prev, sthCalcState.op, sthCalcState.cur, result);\n    sthCalcState.cur = String(result);\n    sthCalcState.prev = result;\n    sthCalc_flash();\n  } else {\n    sthCalcState.prev = parseFloat(sthCalcState.cur);\n  }\n\n  sthCalcState.op = op;\n  sthCalcState.newNum = true;\n  sthCalcState.justEq = false;\n  sthCalc_highlightOp(op);\n  sthCalc_updateDisplay();\n}\n\nfunction sthCalc_pressEquals() {\n  if (sthCalcState.isError) return;\n  if (sthCalcState.op === null) return; \/\/ nothing to compute\n\n  const b = sthCalcState.cur;\n  const result = sthCalc_calculate(sthCalcState.prev, sthCalcState.op, b);\n\n  \/\/ Build expression for display history\n  sthCalc_addHistory(sthCalcState.prev, sthCalcState.op, b, result);\n\n  sthCalcState.cur = String(result);\n  sthCalcState.prev = null;\n  sthCalcState.op = null;\n  sthCalcState.newNum = true;\n  sthCalcState.justEq = true;\n  sthCalc_highlightOp(null);\n  sthCalc_flash();\n  sthCalc_updateDisplay();\n}\n\nfunction sthCalc_pressAC() {\n  if (sthCalcState.cur !== '0' && !sthCalcState.newNum && !sthCalcState.justEq) {\n    \/\/ C: clear current entry only\n    sthCalcState.cur = '0';\n    sthCalcState.newNum = false;\n    sthCalcState.isError = false;\n  } else {\n    \/\/ AC: full reset\n    sthCalcState.cur = '0';\n    sthCalcState.prev = null;\n    sthCalcState.op = null;\n    sthCalcState.newNum = true;\n    sthCalcState.justEq = false;\n    sthCalcState.isError = false;\n    sthCalc_highlightOp(null);\n  }\n  sthCalc_updateDisplay();\n}\n\nfunction sthCalc_pressPlusMinus() {\n  if (sthCalcState.isError) return;\n  if (sthCalcState.cur === '0') return;\n  if (sthCalcState.cur.startsWith('-')) {\n    sthCalcState.cur = sthCalcState.cur.slice(1);\n  } else {\n    sthCalcState.cur = '-' + sthCalcState.cur;\n  }\n  sthCalcState.justEq = false;\n  sthCalc_updateDisplay();\n}\n\nfunction sthCalc_pressPercent() {\n  if (sthCalcState.isError) return;\n  const n = parseFloat(sthCalcState.cur);\n  if (sthCalcState.op && sthCalcState.prev !== null) {\n    \/\/ e.g. 200 + 5% = 200 + 10 (5% of 200)\n    sthCalcState.cur = String(sthCalc_cleanFloat(sthCalcState.prev * n \/ 100));\n  } else {\n    sthCalcState.cur = String(sthCalc_cleanFloat(n \/ 100));\n  }\n  sthCalcState.justEq = false;\n  sthCalcState.newNum = false;\n  sthCalc_updateDisplay();\n}\n\n\/\/ Backspace\nfunction sthCalc_pressBack() {\n  if (sthCalcState.isError) { sthCalc_pressAC(); return; }\n  if (sthCalcState.justEq || sthCalcState.newNum) return;\n  if (sthCalcState.cur.length <= 1 || (sthCalcState.cur.length === 2 &#038;&#038; sthCalcState.cur.startsWith('-'))) {\n    sthCalcState.cur = '0';\n    sthCalcState.newNum = false;\n  } else {\n    sthCalcState.cur = sthCalcState.cur.slice(0, -1);\n    if (sthCalcState.cur === '-') sthCalcState.cur = '0';\n  }\n  sthCalc_updateDisplay();\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  HISTORY\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nfunction sthCalc_addHistory(a, op, b, result) {\n  const rFormatted = sthCalc_formatNum(String(result), false);\n  const entry = {\n    expr: `${sthCalc_formatNum(String(a), false)} ${op} ${sthCalc_formatNum(String(b), false)}`,\n    result: rFormatted,\n  };\n  sthCalcState.history.unshift(entry);\n  if (sthCalcState.history.length > 20) sthCalcState.history.pop();\n  sthCalc_renderHistory();\n}\n\nfunction sthCalc_renderHistory() {\n  const list = document.getElementById('sthcalc-history-list');\n  if (!sthCalcState.history.length) {\n    list.innerHTML = '<div style=\"color:rgba(255,255,255,0.2);font-size:.75rem;text-align:center;padding:8px;\">Ch\u01b0a c\u00f3 l\u1ecbch s\u1eed<\/div>';\n    return;\n  }\n  list.innerHTML = sthCalcState.history.map((h, i) =>\n    `<div class=\"history-item\" onclick=\"sthCalc_recallHistory(${i})\">\n      ${h.expr} <span class=\"h-result\">= ${h.result}<\/span>\n    <\/div>`\n  ).join('');\n}\n\nfunction sthCalc_recallHistory(i) {\n  const h = sthCalcState.history[i];\n  sthCalcState.cur = String(parseFloat(h.result.replace('\u221e','Infinity')));\n  sthCalcState.newNum = true;\n  sthCalcState.justEq = true;\n  sthCalcState.op = null;\n  sthCalcState.prev = null;\n  sthCalc_highlightOp(null);\n  sthCalc_updateDisplay();\n}\n\nlet histOpen = false;\nfunction sthCalc_toggleHistory() {\n  histOpen = !histOpen;\n  document.getElementById('sthcalc-history-strip').classList.toggle('open', histOpen);\n  sthCalc_renderHistory();\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  KEYBOARD SUPPORT\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\ndocument.addEventListener('keydown', e => {\n  const k = e.key;\n  if (e.ctrlKey || e.metaKey || e.altKey) return;\n\n  const numMap = {'0':1,'1':1,'2':1,'3':1,'4':1,'5':1,'6':1,'7':1,'8':1,'9':1};\n  if (numMap[k]) { sthCalc_pressNum(k); sthCalc_animBtn(k); }\n  else if (k === '.') { sthCalc_pressDot(); sthCalc_animBtn('.'); }\n  else if (k === '+') { sthCalc_pressOp('+'); }\n  else if (k === '-') { sthCalc_pressOp('\u2212'); }\n  else if (k === '*') { sthCalc_pressOp('\u00d7'); }\n  else if (k === '\/') { e.preventDefault(); sthCalc_pressOp('\u00f7'); }\n  else if (k === 'Enter' || k === '=') { sthCalc_pressEquals(); sthCalc_animBtn('='); }\n  else if (k === 'Backspace') { sthCalc_pressBack(); }\n  else if (k === 'Escape') { sthCalc_pressAC(); }\n  else if (k === '%') { sthCalc_pressPercent(); }\n});\n\nfunction sthCalc_animBtn(key) {\n  \/\/ Find button by text content and briefly highlight\n  const btns = document.querySelectorAll('.btn');\n  for (const b of btns) {\n    if (b.textContent.trim() === key) {\n      b.style.filter = 'brightness(1.5)';\n      setTimeout(() => b.style.filter = '', 120);\n      break;\n    }\n  }\n}\n\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\/\/  INIT\n\/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\nsthCalc_updateDisplay();\n\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>M\u00e1y T\u00ednh L\u1ecbch s\u1eed M L\u1ed7i 0 AC +\/\u2212 \u232b \u00f7 7 8 9 \u00d7 4 5 6 \u2212 1 2 3 + 0 % . = H\u1ed7 tr\u1ee3 b\u00e0n ph\u00edm \u2022 Backspace x\u00f3a \u2022 Esc reset<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-17889","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/pages\/17889","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/comments?post=17889"}],"version-history":[{"count":0,"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/pages\/17889\/revisions"}],"wp:attachment":[{"href":"https:\/\/draff.sieuthitinhoc.com\/index.php\/wp-json\/wp\/v2\/media?parent=17889"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}