{"id":1851,"date":"2025-10-23T00:19:42","date_gmt":"2025-10-22T15:19:42","guid":{"rendered":"https:\/\/steelcrucian.com\/?p=1851"},"modified":"2025-11-08T20:26:57","modified_gmt":"2025-11-08T11:26:57","slug":"online-keyboard-tester-in-post","status":"publish","type":"post","link":"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/","title":{"rendered":"\ud83c\udfb9 \uc628\ub77c\uc778 \ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud2b8 \u2013 \ubaa8\ub4e0 \ud0a4\uc758 \uc791\ub3d9\uc744 \ud55c\ub208\uc5d0 \ud655\uc778\ud558\uc138\uc694"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">\uac00\ub054 \uc774\ub7f0 \uacbd\ud5d8 \uc788\uc73c\uc2dc\uc8e0?<br>\u201c\ud0a4\ubcf4\ub4dc\uac00 \uba40\uca61\ud574 \ubcf4\uc774\ub294\ub370, \uac8c\uc784 \uc911\uc5d0 \uac11\uc790\uae30 \uc2a4\ud398\uc774\uc2a4\ubc14\uac00 \uc548 \uba39\uc5b4\uc694.\u201d<br>\ud639\uc740 \u201c\uc2a4\uc704\uce58\ub97c \uad50\uccb4\ud588\ub294\ub370 \uc81c\ub300\ub85c \uc778\uc2dd\ub418\ub294\uc9c0 \ud5f7\uac08\ub824\uc694.\u201d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\ub7f4 \ub54c \ubc14\ub85c \ud655\uc778\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4\uba74 \uc5bc\ub9c8\ub098 \uc88b\uc744\uae4c\uc694?<br>\uc774\ubc88 \uae00\uc5d0\uc11c\ub294 <strong>\ubcc4\ub3c4\uc758 \uc124\uce58 \uc5c6\uc774, \uc6f9 \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c \ubc14\ub85c \uc2e4\ud589\ub418\ub294 \uc628\ub77c\uc778 \ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud2b8 \ub3c4\uad6c<\/strong>\ub97c \uc18c\uac1c\ud574\ub4dc\ub9bd\ub2c8\ub2e4.<br>\ud2b9\ud788 \uc774 \ub3c4\uad6c\ub294 \ub2e8\uc21c\ud788 \ud0a4\uac00 \ub20c\ub9ac\ub294\uc9c0\ub9cc \ud655\uc778\ud558\ub294 \uac8c \uc544\ub2c8\ub77c,<br><strong>N-Key Rollover(\ub3d9\uc2dc \uc785\ub825 \ud55c\uacc4)<\/strong>, <strong>Ghosting(\uc720\ub839 \uc785\ub825)<\/strong> \ud604\uc0c1\uae4c\uc9c0 \ud55c\ub208\uc5d0 \uccb4\ud06c\ud560 \uc218 \uc788\ub3c4\ub85d \uc124\uacc4\ub418\uc5c8\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub9ac\uace0 \ubb34\uc5c7\ubcf4\ub2e4\ub3c4, \uc774 \ud398\uc774\uc9c0 \uc548\uc5d0\uc11c \ubc14\ub85c \ud0a4\ubcf4\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>\uc544\ub798\uc5d0 \uc900\ube44\ub41c \uc778\ud130\ub799\ud2f0\ube0c \ud0a4\ubcf4\ub4dc \uc601\uc5ed\uc744 \ud074\ub9ad\ud558\uace0 \uc9c1\uc811 \ud0a4\ub97c \ub20c\ub7ec\ubcf4\uc138\uc694.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1000\" height=\"300\" src=\"https:\/\/steelcrucian.com\/wp-content\/uploads\/2025\/10\/keyboard-layout.webp\" alt=\"\" class=\"wp-image-1871\" srcset=\"https:\/\/steelcrucian.com\/wp-content\/uploads\/2025\/10\/keyboard-layout.webp 1000w, https:\/\/steelcrucian.com\/wp-content\/uploads\/2025\/10\/keyboard-layout-300x90.webp 300w, https:\/\/steelcrucian.com\/wp-content\/uploads\/2025\/10\/keyboard-layout-768x230.webp 768w, https:\/\/steelcrucian.com\/wp-content\/uploads\/2025\/10\/keyboard-layout-624x187.webp 624w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_87_1 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"\ubaa9\ucc28 \ud1a0\uae00\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%E2%9A%99%EF%B8%8F_%EC%A3%BC%EC%9A%94_%EA%B8%B0%EB%8A%A5_%EC%9A%94%EC%95%BD\" >\u2699\ufe0f \uc8fc\uc694 \uae30\ub2a5 \uc694\uc57d<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%F0%9F%A7%AD_%EC%82%AC%EC%9A%A9_%EB%B0%A9%EB%B2%95\" >\ud83e\udded \uc0ac\uc6a9 \ubc29\ubc95<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%F0%9F%A7%A0_%EC%9D%B4%EB%9F%B0_%EB%B6%84%EA%BB%98_%EC%B6%94%EC%B2%9C%EB%93%9C%EB%A6%BD%EB%8B%88%EB%8B%A4\" >\ud83e\udde0 \uc774\ub7f0 \ubd84\uaed8 \ucd94\ucc9c\ub4dc\ub9bd\ub2c8\ub2e4<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%F0%9F%92%BB_%EC%A7%81%EC%A0%91_%ED%85%8C%EC%8A%A4%ED%8A%B8_%ED%95%B4%EB%B3%B4%EA%B8%B0\" >\ud83d\udcbb \uc9c1\uc811 \ud14c\uc2a4\ud2b8 \ud574\ubcf4\uae30<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%F0%9F%93%8A_%ED%85%8C%EC%8A%A4%ED%8A%B8_%ED%9B%84_%ED%95%B4%EC%84%9D_%EB%B0%A9%EB%B2%95\" >\ud83d\udcca \ud14c\uc2a4\ud2b8 \ud6c4 \ud574\uc11d \ubc29\ubc95<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%F0%9F%8E%A8_%EB%94%94%EC%9E%90%EC%9D%B8_%ED%8A%B9%EC%A7%95\" >\ud83c\udfa8 \ub514\uc790\uc778 \ud2b9\uc9d5<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/steelcrucian.com\/online-keyboard-tester-in-post\/#%F0%9F%A7%A9_%EB%A7%88%EB%AC%B4%EB%A6%AC\" >\ud83e\udde9 \ub9c8\ubb34\ub9ac<\/a><\/li><\/ul><\/nav><\/div>\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%E2%9A%99%EF%B8%8F_%EC%A3%BC%EC%9A%94_%EA%B8%B0%EB%8A%A5_%EC%9A%94%EC%95%BD\"><\/span>\u2699\ufe0f \uc8fc\uc694 \uae30\ub2a5 \uc694\uc57d<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 <strong>1. \ud3ec\uc2a4\ud305 \ub0b4 \uc9c1\uc811 \ud14c\uc2a4\ud2b8 \uac00\ub2a5<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ubcc4\ub3c4 \ud504\ub85c\uadf8\ub7a8 \uc124\uce58 \uc5c6\uc774, \uc6f9 \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c \ubc14\ub85c \uc2e4\ud589\ub429\ub2c8\ub2e4.<\/li>\n\n\n\n<li>\uc785\ub825\ub41c \ud0a4\ub294 \uc2e4\uc2dc\uac04\uc73c\ub85c \ucd08\ub85d\uc0c9 \ud558\uc774\ub77c\uc774\ud2b8 \ud45c\uc2dc\ub429\ub2c8\ub2e4.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 <strong>2. \ub808\uc774\uc544\uc6c3 \uc804\ud658 \uae30\ub2a5 (Full \/ TKL \/ 75% \/ 60%)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ubcf4\uc720\ud55c \ud0a4\ubcf4\ub4dc \ub808\uc774\uc544\uc6c3\uc5d0 \ub9de\ucdb0 \ud654\uba74\uc744 \ubcc0\uacbd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/li>\n\n\n\n<li>\ud150\ud0a4\ub9ac\uc2a4(TKL)\ub098 60% \ubc30\uc5f4\ub3c4 \uc2e4\uc81c\ucc98\ub7fc \ud14c\uc2a4\ud2b8 \uac00\ub2a5\ud569\ub2c8\ub2e4.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 <strong>3. \uc790\ub3d9 \ud3ed \ub9de\ucda4 (Responsive Scaling)<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>PC, \ud0dc\ube14\ub9bf, \ubaa8\ubc14\uc77c\uc5d0\uc11c\ub3c4 \ud3ed\uc774 \uc790\ub3d9\uc73c\ub85c \uc870\uc815\ub418\uc5b4<br>\ud654\uba74\uc774 \uc798\ub9ac\uac70\ub098 \ubc00\ub9ac\ub294 \uc77c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 <strong>4. \uc2e4\uc2dc\uac04 \ub85c\uadf8 &amp; \ub3d9\uc2dc \uc785\ub825 \uce74\uc6b4\ud130<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ub20c\ub9b0 \ud0a4\uc640 \ud574\uc81c\ub41c \ud0a4\uac00 \uc2dc\uac04\ubcc4\ub85c \uae30\ub85d\ub418\uc5b4,<br>\uc2a4\uc704\uce58 \uc774\uc0c1\uc774\ub098 \uc911\ubcf5 \uc785\ub825 \uc5ec\ubd80\ub97c \uc27d\uac8c \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/li>\n\n\n\n<li>\ud604\uc7ac \ub20c\ub824 \uc788\ub294 \ud0a4 \uac1c\uc218\uc640 \ucd5c\ub300 \ub3d9\uc2dc \uc785\ub825 \uc218\ub97c \uc790\ub3d9 \uc9d1\uacc4\ud569\ub2c8\ub2e4.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">\u2705 <strong>5. \ud0a4\ubcf4\ub4dc \uc2a4\uc704\uce58 \uc810\uac80\uc6a9\uc73c\ub85c \ucd5c\uc801\ud654<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\uc724\ud65c, \uc2a4\uc704\uce58 \uad50\uccb4, PCB \ub0a9\ub55c \ud6c4 \ud14c\uc2a4\ud2b8 \uc2dc<br>\uace0\uac00 \uc7a5\ube44 \uc5c6\uc774 \uc0c1\ud0dc\ub97c \ube60\ub974\uac8c \uc810\uac80\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%F0%9F%A7%AD_%EC%82%AC%EC%9A%A9_%EB%B0%A9%EB%B2%95\"><\/span>\ud83e\udded \uc0ac\uc6a9 \ubc29\ubc95<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">1\ufe0f\u20e3 \uc544\ub798\uc758 \u2018\ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud130\u2019 \uc601\uc5ed\uc744 \ud074\ub9ad\ud558\uc5ec <strong>\ud3ec\ucee4\uc2a4(Focus)<\/strong> \ub97c \ub9de\ucdb0 \uc8fc\uc138\uc694.<br>2\ufe0f\u20e3 \ud0a4\ubcf4\ub4dc\uc758 \uc544\ubb34 \ud0a4\ub098 \ub20c\ub7ec\ubcf4\uba74, \ud574\ub2f9 \ud0a4\uac00 \ucd08\ub85d\uc0c9\uc73c\ub85c \ud45c\uc2dc\ub429\ub2c8\ub2e4.<br>3\ufe0f\u20e3 \uc5ec\ub7ec \ud0a4\ub97c \ub3d9\uc2dc\uc5d0 \ub20c\ub7ec <strong>\ub3d9\uc2dc \uc785\ub825 \ud55c\uacc4(N-Key Rollover)<\/strong> \ub97c \ud14c\uc2a4\ud2b8\ud574\ubcf4\uc138\uc694.<br>4\ufe0f\u20e3 \ud2b9\uc815 \ud0a4\uac00 \ubc18\uc751\ud558\uc9c0 \uc54a\uc73c\uba74, \ud574\ub2f9 \uc2a4\uc704\uce58 \ub610\ub294 \ud0a4\ub9f5 \ubb38\uc81c\ub97c \uc758\uc2ec\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>5\ufe0f\u20e3 \ub85c\uadf8\ucc3d\uc5d0\uc11c\ub294 \ub20c\ub9bc(<code>keydown<\/code>), \ub5cc(<code>keyup<\/code>) \uc774\ubca4\ud2b8\uac00 \uc21c\uc11c\ub300\ub85c \uae30\ub85d\ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udca1 <strong>Tip:<\/strong><br>\ud55c\/\uc601 \uc804\ud658 \ud0a4\ub098 <code>PrintScreen<\/code> \uac19\uc740 \ud2b9\uc218\ud0a4\ub294 \uc6b4\uc601\uccb4\uc81c \uc815\ucc45\uc0c1 \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c \uac10\uc9c0\ub418\uc9c0 \uc54a\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>\ud14c\uc2a4\ud2b8\ub294 \uac00\ub2a5\ud558\uba74 <strong>\uc601\ubb38 \uc785\ub825 \uc0c1\ud0dc\uc5d0\uc11c \uc9c4\ud589<\/strong>\ud558\uc2dc\ub294 \uac83\uc774 \uc88b\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%F0%9F%A7%A0_%EC%9D%B4%EB%9F%B0_%EB%B6%84%EA%BB%98_%EC%B6%94%EC%B2%9C%EB%93%9C%EB%A6%BD%EB%8B%88%EB%8B%A4\"><\/span>\ud83e\udde0 \uc774\ub7f0 \ubd84\uaed8 \ucd94\ucc9c\ub4dc\ub9bd\ub2c8\ub2e4<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud0a4\ubcf4\ub4dc\ub97c \uc724\ud65c\u00b7\ubd84\ud574\ud55c \ub4a4 \uc815\uc0c1 \uc791\ub3d9\uc744 \uc810\uac80\ud558\uace0 \uc2f6\uc740 \ubd84<\/li>\n\n\n\n<li>\uc911\uace0 \ud0a4\ubcf4\ub4dc\ub97c \uac70\ub798 \uc804 \ud655\uc778\ud558\uace0 \uc2f6\uc740 \ubd84<\/li>\n\n\n\n<li>\uac8c\uc784\uc6a9 \ud0a4\ubcf4\ub4dc\uc758 <strong>N-Key Rollover \uc131\ub2a5<\/strong>\uc744 \uc9c1\uc811 \uce21\uc815\ud574\ubcf4\uace0 \uc2f6\uc740 \ubd84<\/li>\n\n\n\n<li>\ud0a4 \uc785\ub825 \ub51c\ub808\uc774\ub098 \uc2a4\uc704\uce58 \uc539\ud798 \ud604\uc0c1\uc744 \uc758\uc2ec\ud558\ub294 \ubd84<\/li>\n\n\n\n<li>\uc6f9\uc5d0\uc11c \uc190\uc27d\uac8c \ud558\ub4dc\uc6e8\uc5b4 \uac80\uc218\ub97c \ud558\uace0 \uc2f6\uc740 \uac1c\ubc1c\uc790\u00b7\ub514\uc790\uc774\ub108<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%F0%9F%92%BB_%EC%A7%81%EC%A0%91_%ED%85%8C%EC%8A%A4%ED%8A%B8_%ED%95%B4%EB%B3%B4%EA%B8%B0\"><\/span>\ud83d\udcbb \uc9c1\uc811 \ud14c\uc2a4\ud2b8 \ud574\ubcf4\uae30<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\uc544\ub798\uc758 \uc601\uc5ed\uc740 \uc2e4\uc81c \uc791\ub3d9\ud558\ub294 \uc628\ub77c\uc778 \ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud2b8\uc785\ub2c8\ub2e4.<br>\ub808\uc774\uc544\uc6c3\uc744 \uc120\ud0dd\ud558\uace0, \ud0a4\ub97c \ub20c\ub7ec\ubcf4\uc138\uc694!<br>\ud0a4\ubcf4\ub4dc \uadf8\ub9bc \uc544\ub798\uc5d0\ub294 <strong>\uc2e4\uc2dc\uac04 \ub85c\uadf8<\/strong>\uc640 <strong>\ud604\uc7ac \uc785\ub825 \ub370\uc774\ud130<\/strong>\uac00 \ud45c\uc2dc\ub429\ub2c8\ub2e4.<\/p>\n\n\n\n<section class=\"kb-tester-wrap\" aria-labelledby=\"kbd-tester-title\" tabindex=\"0\">\n  <style>\n    .kb-tester-wrap{\n      display:block;max-width:100%;\n      --bg:#0b0d10;--panel:#12151a;--line:#263140;--ok:#16a34a;--warn:#eab308;--bad:#ef4444;\n      --muted:#8a97a6;--text:#e9eef5;--key:#1a2028;--key-hover:#222a33;--key-pressed:#13321f;\n      --key-tested:#0f2430;\n      --bar:#1f2937;--bar-ok:#16a34a;--radius:14px;\n      --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,\"Liberation Mono\",monospace;\n      outline:none;\n    }\n    .kb-tester.kb-theme-light{\n      --panel:#ffffff; --line:#e5e7eb; --text:#1f2937;\n      --key:#f3f4f6; --key-hover:#e5e7eb; --key-pressed:#d1fae5;\n      --key-tested:#e8f2ff;\n      --muted:#6b7280; --bg:#f9fafb; --bar:#e5e7eb;\n    }\n    .kb-tester{\n      width:100%;max-width:1100px;margin:20px auto;padding:14px;background:var(--panel);\n      border:1px solid var(--line);border-radius:var(--radius);color:var(--text);\n      box-shadow:0 10px 30px rgba(0,0,0,.20)\n    }\n\n    \/* \ud5e4\ub354: \uc81c\ubaa9 + \uac00\ub85c \uc2a4\ud06c\ub864 \ud234\ubc14 *\/\n    .kb-header{display:grid;grid-template-columns:1fr;gap:8px;margin-bottom:8px}\n    .kb-title{font-size:1.05rem;font-weight:700;line-height:1.2}\n    .kb-toolbar{\n      display:flex;align-items:center;gap:8px;\n      overflow-x:auto;overflow-y:hidden;white-space:nowrap;\n      padding:6px;border:1px solid var(--line);border-radius:10px;background:rgba(0,0,0,.08);\n      scrollbar-width:thin;\n    }\n    .kb-toolbar::-webkit-scrollbar{height:8px}\n    .kb-toolbar::-webkit-scrollbar-thumb{background:var(--line);border-radius:6px}\n\n    .kb-select,.kb-btn,.kb-pill{\n      display:inline-flex;align-items:center;gap:6px;\n      border:1px solid var(--line);border-radius:10px;\n      padding:6px 10px;font-size:.85rem;height:34px;box-sizing:border-box\n    }\n    .kb-select,.kb-btn{cursor:pointer;background:#0f1318;color:#e9eef5}\n    .kb-btn:hover,.kb-select:hover{background:#131922}\n    .kb-tester.kb-theme-light .kb-select,.kb-tester.kb-theme-light .kb-btn{background:#f3f4f6;color:#1f2937}\n    .kb-pill{background:#0f1318;color:var(--text)}\n    .kb-tester.kb-theme-light .kb-pill{background:#f3f4f6}\n    .kb-pill strong{margin-left:4px}\n    .kb-divider{width:1px;height:22px;background:var(--line);display:inline-block}\n\n    \/* \uc694\uc57d \ubc15\uc2a4 *\/\n    .kb-summary{margin-top:6px;background:#0f1318;border:1px solid var(--line);border-radius:10px;padding:10px}\n    .kb-tester.kb-theme-light .kb-summary{background:#f9fafb}\n    .kb-summary-row{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:8px}\n    .kb-legend{display:flex;align-items:center;gap:10px;font-size:.85rem;color:var(--muted)}\n    .kb-legend .chip{display:inline-block;min-width:12px;min-height:12px;border:1px solid var(--line);border-radius:4px}\n    .kb-legend .chip.tested{background:var(--key-tested)}\n    .kb-legend .chip.pressed{background:var(--key-pressed)}\n    .kb-progress{width:100%;height:10px;background:var(--bar);border-radius:999px;overflow:hidden}\n    .kb-progress>span{display:block;height:100%;background:var(--bar-ok);width:0%}\n\n    \/* \ubcf4\ub4dc: \uace0\uc815 \uc124\uacc4\ud3ed + \ubc18\uc751\ud615 \uc2a4\ucf00\uc77c *\/\n    .kb-scale-outer{width:100%;overflow:hidden}\n    .kb-scale-inner{transform-origin:top left;will-change:transform}\n    .kb-board{width:980px;margin-bottom:4px}\n\n    \/* \ud0a4\ubcf4\ub4dc \uadf8\ub9ac\ub4dc *\/\n    .kb-grid{display:grid;gap:8px}\n    .kb-row{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(34px,1fr);gap:6px}\n    .kb-key{\n      user-select:none;background:var(--key);border:1px solid var(--line);border-radius:10px;\n      padding:10px 6px;text-align:center;font-size:.9rem;line-height:1.1;min-height:42px;\n      display:flex;align-items:center;justify-content:center;position:relative;transition:.08s ease\n    }\n    .kb-key:hover{background:var(--key-hover)}\n    .kb-key.pressed{background:var(--key-pressed);border-color:#1c7b3a;box-shadow:inset 0 0 0 2px rgba(22,163,74,.35)}\n    .kb-key.tested{background:var(--key-tested);box-shadow:inset 0 0 0 1px rgba(59,130,246,.35)}\n    .kb-key.tested::after{\n      content:\"\"; position:absolute; top:6px; right:6px; width:8px; height:8px;\n      border-radius:50%; background:#3b82f6; opacity:.8;\n    }\n    .kb-key[data-mod=\"mod\"]{background:#182131}\n    .kb-tester.kb-theme-light .kb-key[data-mod=\"mod\"]{background:#e5e7eb}\n    .kb-key[data-wide=\"2\"]{grid-column:span 2}\n    .kb-key[data-wide=\"3\"]{grid-column:span 3}\n    .kb-key[data-wide=\"4\"]{grid-column:span 4}\n    .kb-key[data-wide=\"5\"]{grid-column:span 5}\n    .kb-key .sub{position:absolute;bottom:6px;right:8px;font-size:.7rem;color:var(--muted)}\n\n    \/* \uc0c1\ud0dc\/\ub85c\uadf8 *\/\n    .kb-status{display:grid;grid-template-columns:2fr 1fr;gap:12px;margin-top:6px}\n    .kb-log{background:#0f1318;border:1px solid var(--line);border-radius:10px;padding:10px;height:120px;\n      overflow:auto;font-family:var(--mono);font-size:.9rem;color:#dbe6f4}\n    .kb-tester.kb-theme-light .kb-log{background:#f3f4f6;color:#111827}\n    .kb-hint{background:#0f1318;border:1px solid var(--line);border-radius:10px;padding:10px;color:#b8c2cf}\n    .kb-tester.kb-theme-light .kb-hint{background:#f9fafb;color:#374151}\n    .kb-warn{color:var(--warn)} .kb-bad{color:var(--bad)} .kb-ok{color:var(--ok)}\n\n    \/* \ucef4\ud329\ud2b8 \ud1a0\uae00 *\/\n    .kb-tester.kb-compact .kb-grid{gap:6px}\n    .kb-tester.kb-compact .kb-row{gap:4px}\n    .kb-tester.kb-compact .kb-key{min-height:36px;padding:8px 6px;font-size:.85rem}\n    .kb-tester.kb-compact .kb-log{height:100px}\n    .kb-tester.kb-compact .kb-status{margin-top:4px}\n\n    @media (max-width:880px){\n      .kb-status{grid-template-columns:1fr}\n      .kb-row .kb-key{min-height:38px;font-size:.85rem}\n    }\n  <\/style>\n\n  <div class=\"kb-tester kb-theme-dark\" role=\"application\" aria-label=\"Keyboard Tester\">\n    <div class=\"kb-header\">\n      <div class=\"kb-title\" id=\"kbd-tester-title\">\ud83c\udfb9 \ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud130 \u2013 \ub808\uc774\uc544\uc6c3\/\ud14c\ub9c8 \uc804\ud658 \u00b7 \uc790\ub3d9 \ud3ed \ub9de\ucda4 \u00b7 \uc9c0\uc5f0 \ub85c\uae45 \u00b7 \uc790\ub3d9 \uc694\uc57d<\/div>\n\n      <!-- \uac00\ub85c \uc2a4\ud06c\ub864 \ud234\ubc14 -->\n      <div class=\"kb-toolbar\" role=\"toolbar\" aria-label=\"Keyboard tester toolbar\">\n        <label for=\"kb-layout\" class=\"kb-pill\">\ub808\uc774\uc544\uc6c3<\/label>\n        <select id=\"kb-layout\" class=\"kb-select\" aria-label=\"\ub808\uc774\uc544\uc6c3 \uc120\ud0dd\">\n          <option value=\"full\">Full (104)<\/option>\n          <option value=\"tkl\">TKL<\/option>\n          <option value=\"75\">75%<\/option>\n          <option value=\"60\">60%<\/option>\n        <\/select>\n\n        <div class=\"kb-divider\" aria-hidden=\"true\"><\/div>\n\n        <button class=\"kb-btn\" id=\"kb-theme\" type=\"button\" title=\"\ub77c\uc774\ud2b8\/\ub2e4\ud06c \ud1a0\uae00\">\ub77c\uc774\ud2b8\/\ub2e4\ud06c<\/button>\n        <button class=\"kb-btn\" id=\"kb-density\" type=\"button\" title=\"\uac04\uaca9 \uc881\ud798 \ud1a0\uae00\">\uac04\uaca9 \uc881\ud798<\/button>\n\n        <div class=\"kb-divider\" aria-hidden=\"true\"><\/div>\n\n        <div class=\"kb-pill\">\ub3d9\uc2dc<strong id=\"kb-current\">0<\/strong><\/div>\n        <div class=\"kb-pill\">\ucd5c\ub300<strong id=\"kb-max\">0<\/strong><\/div>\n        <div class=\"kb-pill\">\uc9c0\uc5f0<strong id=\"kb-lat-last\">\u2013<\/strong>\/<strong id=\"kb-lat-avg\">\u2013<\/strong><\/div>\n        <div class=\"kb-pill\">\ud3ec\ucee4\uc2a4<strong id=\"kb-focus\">OUT<\/strong><\/div>\n        <div class=\"kb-pill\">\ud45c\uc2dc<strong id=\"kb-layout-label\">Full<\/strong><\/div>\n\n        <div class=\"kb-divider\" aria-hidden=\"true\"><\/div>\n\n        <button class=\"kb-btn\" id=\"kb-clear-log\" type=\"button\">\ub85c\uadf8 \uc9c0\uc6b0\uae30<\/button>\n        <button class=\"kb-btn\" id=\"kb-reset\" type=\"button\">\uc0c1\ud0dc \ucd08\uae30\ud654<\/button>\n      <\/div>\n    <\/div>\n\n    <!-- \uc694\uc57d \ubc15\uc2a4 -->\n    <div class=\"kb-summary\" id=\"kb-summary\">\n      <div class=\"kb-summary-row\">\n        <div><strong>\ud14c\uc2a4\ud2b8 \uacb0\uacfc:<\/strong> \uc815\uc0c1 <strong id=\"kb-ok-count\">0<\/strong> \/ \ucd1d <strong id=\"kb-total\">0<\/strong> keys (<span id=\"kb-progress-text\">0%<\/span>)<\/div>\n        <div class=\"kb-legend\">\n          <span class=\"chip tested\"><\/span> \ud14c\uc2a4\ud2b8 \uc644\ub8cc\n          <span class=\"chip pressed\"><\/span> \ud604\uc7ac \ub20c\ub9bc\n        <\/div>\n      <\/div>\n      <div class=\"kb-progress\" aria-label=\"\uc9c4\ud589\ub960\">\n        <span id=\"kb-progress-bar\" style=\"width:0%\"><\/span>\n      <\/div>\n    <\/div>\n\n    <!-- \uc2a4\ucf00\uc77c \ucee8\ud14c\uc774\ub108(\ud3ed \uc790\ub3d9 \ub9de\ucda4) -->\n    <div class=\"kb-scale-outer\" id=\"kb-scale-outer\">\n      <div class=\"kb-scale-inner\" id=\"kb-scale-inner\">\n        <div class=\"kb-board\">\n          <div class=\"kb-grid\" id=\"kb-grid\" aria-live=\"polite\"><\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n\n    <!-- Status & Log -->\n    <div class=\"kb-status\">\n      <div class=\"kb-log\" id=\"kb-log\" aria-label=\"\ud0a4 \uc774\ubca4\ud2b8 \ub85c\uadf8\" tabindex=\"0\"><\/div>\n      <div class=\"kb-hint\" id=\"kb-hint\">\n        <strong>\uc0ac\uc6a9 \ud301<\/strong><br>\n        \u2022 \ud14c\uc2a4\ud130 \uc601\uc5ed\uc744 \ud074\ub9ad\ud574 \ud3ec\ucee4\uc2a4\ub97c \uba3c\uc800 \uc8fc\uc138\uc694.<br>\n        \u2022 \uc88c\/\uc6b0 Shift\u00b7Ctrl\u00b7Alt\u00b7Meta \ud0a4\ub294 \uac01\uac01 \uad6c\ubd84\ub429\ub2c8\ub2e4.<br>\n        \u2022 \uc77c\ubd80 \ube0c\ub77c\uc6b0\uc800\/OS\uc5d0\uc11c <span class=\"kb-warn\">PrintScreen\/Pause<\/span> \ub4f1 \ud2b9\uc218\ud0a4\ub294 \uc81c\ud55c\ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>\n        \u2022 Numpad(\uc22b\uc790\ud328\ub4dc)\ub294 Full \ub808\uc774\uc544\uc6c3\uc5d0\uc11c\ub9cc \ud45c\uc2dc\ub429\ub2c8\ub2e4. NumLock \uc0c1\ud0dc\ub97c \ud655\uc778\ud558\uc138\uc694.<br>\n        \u2022 60%\/75% \ub808\uc774\uc544\uc6c3\uc740 \uc2e4\uc81c \uae30\uae30\ucc98\ub7fc \uae30\ub2a5\ud0a4 \uad70\uc744 \uc77c\ubd80 \uc0dd\ub7b5\/\uc555\ucd95\ud558\uc5ec \uc2dc\uac01\ud654\ud588\uc2b5\ub2c8\ub2e4.<br>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <script>\n    (()=>{\n      \/* ===================== \ub808\uc774\uc544\uc6c3 \uc815\uc758 ===================== *\/\n      const baseAlphaRows = [\n        [\n          {c:\"Backquote\",l:\"` ~\"},{c:\"Digit1\",l:\"1 !\"},{c:\"Digit2\",l:\"2 @\"},\n          {c:\"Digit3\",l:\"3 #\"},{c:\"Digit4\",l:\"4 $\"},{c:\"Digit5\",l:\"5 %\"},\n          {c:\"Digit6\",l:\"6 ^\"},{c:\"Digit7\",l:\"7 &\"},{c:\"Digit8\",l:\"8 *\"},\n          {c:\"Digit9\",l:\"9 (\"},{c:\"Digit0\",l:\"0 )\"},{c:\"Minus\",l:\"- _\"},{c:\"Equal\",l:\"= +\"},\n          {c:\"Backspace\",l:\"Backspace\",w:3}\n        ],\n        [\n          {c:\"Tab\",l:\"Tab\",w:2},{c:\"KeyQ\",l:\"Q\"},{c:\"KeyW\",l:\"W\"},{c:\"KeyE\",l:\"E\"},\n          {c:\"KeyR\",l:\"R\"},{c:\"KeyT\",l:\"T\"},{c:\"KeyY\",l:\"Y\"},{c:\"KeyU\",l:\"U\"},\n          {c:\"KeyI\",l:\"I\"},{c:\"KeyO\",l:\"O\"},{c:\"KeyP\",l:\"P\"},\n          {c:\"BracketLeft\",l:\"[ {\"},{c:\"BracketRight\",l:\"] }\"},{c:\"Backslash\",l:\"\\\\ |\",w:2}\n        ],\n        [\n          {c:\"CapsLock\",l:\"Caps\",w:3},{c:\"KeyA\",l:\"A\"},{c:\"KeyS\",l:\"S\"},{c:\"KeyD\",l:\"D\"},\n          {c:\"KeyF\",l:\"F\"},{c:\"KeyG\",l:\"G\"},{c:\"KeyH\",l:\"H\"},{c:\"KeyJ\",l:\"J\"},\n          {c:\"KeyK\",l:\"K\"},{c:\"KeyL\",l:\"L\"},{c:\"Semicolon\",l:\"; :\"},\n          {c:\"Quote\",l:\"' \\\"\"},{c:\"Enter\",l:\"Enter\",w:3}\n        ],\n        [\n          {c:\"ShiftLeft\",l:\"Shift\",w:3,mod:1},{c:\"KeyZ\",l:\"Z\"},{c:\"KeyX\",l:\"X\"},{c:\"KeyC\",l:\"C\"},\n          {c:\"KeyV\",l:\"V\"},{c:\"KeyB\",l:\"B\"},{c:\"KeyN\",l:\"N\"},{c:\"KeyM\",l:\"M\"},\n          {c:\"Comma\",l:\", <\"},{c:\"Period\",l:\". >\"},{c:\"Slash\",l:\"\/ ?\"},\n          {c:\"ShiftRight\",l:\"Shift\",w:3,mod:1}\n        ],\n        [\n          {c:\"ControlLeft\",l:\"Ctrl\",mod:1},{c:\"MetaLeft\",l:\"Meta\",mod:1},{c:\"AltLeft\",l:\"Alt\",mod:1},\n          {c:\"Space\",l:\"Space\",w:5},{c:\"AltRight\",l:\"Alt\",mod:1},{c:\"MetaRight\",l:\"Meta\",mod:1},\n          {c:\"ContextMenu\",l:\"Menu\"},{c:\"ControlRight\",l:\"Ctrl\",mod:1}\n        ],\n      ];\n\n      const fRow = [[\n        {c:\"Escape\", l:\"Esc\"},\n        {c:\"F1\",l:\"F1\"},{c:\"F2\",l:\"F2\"},{c:\"F3\",l:\"F3\"},{c:\"F4\",l:\"F4\"},\n        {c:\"F5\",l:\"F5\"},{c:\"F6\",l:\"F6\"},{c:\"F7\",l:\"F7\"},{c:\"F8\",l:\"F8\"},\n        {c:\"F9\",l:\"F9\"},{c:\"F10\",l:\"F10\"},{c:\"F11\",l:\"F11\"},{c:\"F12\",l:\"F12\"},\n        {c:\"PrintScreen\",l:\"PrtSc\"},{c:\"ScrollLock\",l:\"ScrLk\"},{c:\"Pause\",l:\"Pause\"}\n      ]];\n\n      const navCluster = [[\n        {c:\"Insert\",l:\"Ins\"},{c:\"Home\",l:\"Home\"},{c:\"PageUp\",l:\"PgUp\"},\n        {c:\"Delete\",l:\"Del\"},{c:\"End\",l:\"End\"},{c:\"PageDown\",l:\"PgDn\"},\n        {c:\"ArrowUp\",l:\"\u2191\"},{c:\"ArrowLeft\",l:\"\u2190\"},{c:\"ArrowDown\",l:\"\u2193\"},{c:\"ArrowRight\",l:\"\u2192\"}\n      ]];\n\n      const numpad = [\n        [\n          {c:\"NumLock\",l:\"Num\"},{c:\"NumpadDivide\",l:\"\/\"},{c:\"NumpadMultiply\",l:\"*\"},\n          {c:\"NumpadSubtract\",l:\"-\"},{c:\"Numpad7\",l:\"7\"},{c:\"Numpad8\",l:\"8\"},\n          {c:\"Numpad9\",l:\"9\"},{c:\"NumpadAdd\",l:\"+\",w:2}\n        ],\n        [\n          {c:\"Numpad4\",l:\"4\"},{c:\"Numpad5\",l:\"5\"},{c:\"Numpad6\",l:\"6\"},\n          {c:\"Numpad1\",l:\"1\"},{c:\"Numpad2\",l:\"2\"},{c:\"Numpad3\",l:\"3\"},\n          {c:\"NumpadEnter\",l:\"Enter\",w:2}\n        ],\n        [\n          {c:\"Numpad0\",l:\"0\",w:2},{c:\"NumpadDecimal\",l:\".\"}\n        ]\n      ];\n\n      const arrowOnly = [[{c:\"ArrowUp\",l:\"\u2191\"},{c:\"ArrowLeft\",l:\"\u2190\"},{c:\"ArrowDown\",l:\"\u2193\"},{c:\"ArrowRight\",l:\"\u2192\"}]];\n\n      \/\/ \u2705 \ub2e8\uc77c \uc120\uc5b8\ub9cc \uc720\uc9c0\n      const LAYOUTS = {\n        full: [...fRow, ...baseAlphaRows, ...navCluster, ...numpad],\n        tkl:  [...fRow, ...baseAlphaRows, ...navCluster],\n        \"75\": [...fRow, ...baseAlphaRows, ...arrowOnly],\n        \"60\": [...[], ...baseAlphaRows, ...arrowOnly]\n      };\n\n      \/* ===================== DOM refs ===================== *\/\n      const wrap = document.querySelector('.kb-tester-wrap');\n      const root = document.querySelector('.kb-tester');\n      const grid = document.getElementById('kb-grid');\n      const logEl = document.getElementById('kb-log');\n      const hintEl = document.getElementById('kb-hint');\n      const focusEl = document.getElementById('kb-focus');\n      const curEl = document.getElementById('kb-current');\n      const maxEl = document.getElementById('kb-max');\n      const selLayout = document.getElementById('kb-layout');\n      const layoutLabel = document.getElementById('kb-layout-label');\n      const scaleOuter = document.getElementById('kb-scale-outer');\n      const scaleInner = document.getElementById('kb-scale-inner');\n      const okCountEl = document.getElementById('kb-ok-count');\n      const totalEl = document.getElementById('kb-total');\n      const progTextEl = document.getElementById('kb-progress-text');\n      const progBarEl = document.getElementById('kb-progress-bar');\n      const latLastEl = document.getElementById('kb-lat-last');\n      const latAvgEl = document.getElementById('kb-lat-avg');\n\n      \/* ===================== \uc0c1\ud0dc\/\uc9c0\uc5f0 ===================== *\/\n      const pressed = new Set();\n      const pressedOnce = new Set();\n      let maxPressed = 0;\n      let totalKeys = 0;\n      const downTime = new Map();\n      let latencies = [];\n\n      \/* ===================== Util ===================== *\/\n      function setFocusState(v){ focusEl.textContent = v ? 'IN' : 'OUT'; }\n      setFocusState(false);\n      function keyEl(code){ return root.querySelector(`.kb-key[data-code=\"${code}\"]`); }\n      function isFormEl(el){\n        return !!el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.tagName === 'SELECT' || el.isContentEditable === true);\n      }\n      function log(msg, type=''){\n        const time = new Date().toLocaleTimeString();\n        const line = document.createElement('div');\n        line.textContent = `[${time}] ${msg}`;\n        if(type==='down') line.style.color = '#93e6a8';\n        if(type==='up') line.style.color = '#fca5a5';\n        logEl.prepend(line);\n        if(logEl.children.length>200) logEl.removeChild(logEl.children[logEl.children.length-1]);\n      }\n      function refreshCounts(){\n        curEl.textContent = pressed.size;\n        if(pressed.size>maxPressed){ maxPressed = pressed.size; maxEl.textContent = maxPressed; }\n        const unknowns = [...pressed].filter(c=>!keyEl(c));\n        if(unknowns.length){\n          hintEl.innerHTML = `<strong>\uc54c\ub9bc<\/strong><br>\ub9e4\ud551\ub418\uc9c0 \uc54a\uc740 \ucf54\ub4dc \uac10\uc9c0: <span class=\"kb-warn\">${unknowns.join(', ')}<\/span><br>\ube0c\ub77c\uc6b0\uc800\/OS \uc81c\ud55c \ub610\ub294 \ud2b9\uc218 \ud0a4\uc77c \uc218 \uc788\uc2b5\ub2c8\ub2e4.`;\n        }\n        okCountEl.textContent = pressedOnce.size;\n        totalEl.textContent = totalKeys;\n        const pct = totalKeys ? Math.round((pressedOnce.size\/totalKeys)*100) : 0;\n        progTextEl.textContent = pct + '%';\n        progBarEl.style.width = pct + '%';\n      }\n      function resetSummary(){\n        pressed.clear(); pressedOnce.clear(); maxPressed = 0; latencies = []; downTime.clear();\n        curEl.textContent='0'; maxEl.textContent='0';\n        okCountEl.textContent='0'; latLastEl.textContent='\u2013'; latAvgEl.textContent='\u2013';\n        progTextEl.textContent='0%'; progBarEl.style.width='0%';\n        root.querySelectorAll('.kb-key.tested').forEach(el=>el.classList.remove('tested'));\n        root.querySelectorAll('.kb-key.pressed').forEach(el=>el.classList.remove('pressed'));\n      }\n      function updateLatency(ms){\n        latLastEl.textContent = ms.toFixed(1);\n        latencies.push(ms);\n        const avg = latencies.reduce((a,b)=>a+b,0)\/latencies.length;\n        latAvgEl.textContent = avg.toFixed(1);\n      }\n      function applyTestedClasses(){\n        const allKeys = grid.querySelectorAll('.kb-key');\n        allKeys.forEach(el=>{\n          if(pressedOnce.has(el.dataset.code)) el.classList.add('tested');\n          else el.classList.remove('tested');\n        });\n      }\n\n      \/* ===================== \uc774\ubca4\ud2b8 ===================== *\/\n      wrap.addEventListener('click', (e)=>{\n        if (e.target.closest('.kb-toolbar, .kb-select, .kb-btn, select, input, textarea')) return;\n        if (e.target.closest('#kb-grid, .kb-board')) wrap.focus();\n      });\n      wrap.addEventListener('focusin', ()=>setFocusState(true));\n      wrap.addEventListener('focusout', ()=>{\n        pressed.clear();\n        root.querySelectorAll('.kb-key.pressed').forEach(el=>el.classList.remove('pressed'));\n        refreshCounts(); setFocusState(false);\n        downTime.clear();\n      });\n\n      function onDown(e){\n        if (isFormEl(document.activeElement)) return;\n        const code = e.code;\n        if(!pressed.has(code)){\n          pressed.add(code);\n          pressedOnce.add(code);\n          const el = keyEl(code);\n          if(el){ el.classList.add('pressed'); el.classList.add('tested'); }\n          downTime.set(code, performance.now());\n          log(`keydown: ${code}${e.key?` (key=\"${e.key}\")`:''}`, 'down');\n          refreshCounts();\n        }\n        if(['Space','ArrowUp','ArrowDown','ArrowLeft','ArrowRight'].includes(code)) e.preventDefault();\n      }\n      function onUp(e){\n        if (isFormEl(document.activeElement)) return;\n        const code = e.code;\n        if(pressed.has(code)){\n          pressed.delete(code);\n          const el = keyEl(code);\n          if(el) el.classList.remove('pressed');\n          if(downTime.has(code)){\n            const ms = performance.now() - downTime.get(code);\n            updateLatency(ms);\n            downTime.delete(code);\n            log(`keyup:   ${code} (\u0394 ${ms.toFixed(1)} ms)`, 'up');\n          }else{\n            log(`keyup:   ${code}`, 'up');\n          }\n          refreshCounts();\n        }\n      }\n      window.addEventListener('keydown', onDown);\n      window.addEventListener('keyup', onUp);\n\n      document.getElementById('kb-clear-log').addEventListener('click', ()=>{ logEl.innerHTML=''; });\n      document.getElementById('kb-reset').addEventListener('click', ()=>{\n        resetSummary();\n        hintEl.innerHTML = `<strong>\uc0ac\uc6a9 \ud301<\/strong><br>\n        \u2022 \ud14c\uc2a4\ud130 \uc601\uc5ed\uc744 \ud074\ub9ad\ud574 \ud3ec\ucee4\uc2a4\ub97c \uba3c\uc800 \uc8fc\uc138\uc694.<br>\n        \u2022 \uc88c\/\uc6b0 Shift\u00b7Ctrl\u00b7Alt\u00b7Meta \ud0a4\ub294 \uac01\uac01 \uad6c\ubd84\ub429\ub2c8\ub2e4.<br>\n        \u2022 \uc77c\ubd80 \ube0c\ub77c\uc6b0\uc800\/OS\uc5d0\uc11c <span class=\"kb-warn\">PrintScreen\/Pause<\/span> \ub4f1 \ud2b9\uc218\ud0a4\ub294 \uc81c\ud55c\ub420 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>\n        \u2022 Numpad(\uc22b\uc790\ud328\ub4dc)\ub294 Full \ub808\uc774\uc544\uc6c3\uc5d0\uc11c\ub9cc \ud45c\uc2dc\ub429\ub2c8\ub2e4. NumLock \uc0c1\ud0dc\ub97c \ud655\uc778\ud558\uc138\uc694.<br>\n        \u2022 60%\/75% \ub808\uc774\uc544\uc6c3\uc740 \uc2e4\uc81c \uae30\uae30\ucc98\ub7fc \uae30\ub2a5\ud0a4 \uad70\uc744 \uc77c\ubd80 \uc0dd\ub7b5\/\uc555\ucd95\ud558\uc5ec \uc2dc\uac01\ud654\ud588\uc2b5\ub2c8\ub2e4.<br>`;\n      });\n      document.getElementById('kb-density').addEventListener('click', ()=>{\n        root.classList.toggle('kb-compact');\n        scaleToFit();\n      });\n      document.getElementById('kb-theme').addEventListener('click', ()=>{\n        root.classList.toggle('kb-theme-light');\n        scaleToFit();\n      });\n      document.getElementById('kb-layout').addEventListener('change', (e)=>renderLayout(e.target.value));\n\n      \/* ===================== \ub80c\ub354\ub7ec & \uc694\uc57d ===================== *\/\n      function calculateTotalKeys(rows){\n        let count = 0; rows.forEach(r => r.forEach(()=>count++)); return count;\n      }\n      function renderLayout(layoutKey){\n        const rows = LAYOUTS[layoutKey];\n        grid.innerHTML = '';\n        rows.forEach(r=>{\n          const rowEl = document.createElement('div');\n          rowEl.className = 'kb-row';\n          r.forEach(k=>{\n            const key = document.createElement('div');\n            key.className = 'kb-key';\n            key.dataset.code = k.c;\n            if(k.w) key.dataset.wide = k.w;\n            if(k.mod) key.dataset.mod = 'mod';\n            key.innerHTML = `<span>${k.l}<\/span><span class=\"sub\">${k.c}<\/span>`;\n            rowEl.appendChild(key);\n          });\n          grid.appendChild(rowEl);\n        });\n        layoutLabel.textContent = ({full:'Full', tkl:'TKL', '75':'75%', '60':'60%'})[layoutKey] || layoutKey;\n\n        totalKeys = calculateTotalKeys(rows);\n        totalEl.textContent = totalKeys;\n        const validCodes = new Set([...grid.querySelectorAll('.kb-key')].map(el=>el.dataset.code));\n        [...pressedOnce].forEach(code => { if(!validCodes.has(code)) pressedOnce.delete(code); });\n        applyTestedClasses();\n        refreshCounts();\n        scaleToFit();\n      }\n\n      \/* ===================== \uc790\ub3d9 \ud3ed \ub9de\ucda4 ===================== *\/\n      function scaleToFit(){\n        const outerW = scaleOuter.clientWidth || scaleOuter.getBoundingClientRect().width;\n        const scale = Math.max(0.6, Math.min(1, outerW \/ 980));\n        scaleInner.style.transform = `scale(${scale})`;\n        const boardEl = document.querySelector('.kb-board');\n        const naturalHeight = boardEl.scrollHeight;\n        const scaledHeight = Math.ceil(naturalHeight * scale);\n        scaleOuter.style.paddingBottom = '0px';\n        scaleOuter.style.height = scaledHeight + 'px';\n      }\n      const ro = ('ResizeObserver' in window) ? new ResizeObserver(()=>scaleToFit()) : null;\n      if(ro) ro.observe(scaleOuter); else window.addEventListener('resize', scaleToFit);\n\n      \/\/ \ucd08\uae30 \ub80c\ub354\n      renderLayout('full');\n      setTimeout(scaleToFit, 0);\n    })();\n  <\/script>\n<\/section>\n\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%F0%9F%93%8A_%ED%85%8C%EC%8A%A4%ED%8A%B8_%ED%9B%84_%ED%95%B4%EC%84%9D_%EB%B0%A9%EB%B2%95\"><\/span>\ud83d\udcca \ud14c\uc2a4\ud2b8 \ud6c4 \ud574\uc11d \ubc29\ubc95<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\uad6c\ubd84<\/th><th>\uc758\ubbf8<\/th><th>\ud655\uc778 \ud3ec\uc778\ud2b8<\/th><\/tr><\/thead><tbody><tr><td><strong>\ub3d9\uc2dc \uc785\ub825 \uc218<\/strong><\/td><td>\ud55c \ubc88\uc5d0 \uc778\uc2dd\ub418\ub294 \ud0a4 \uac1c\uc218<\/td><td>\uac8c\uc774\ubc0d \ud0a4\ubcf4\ub4dc\ub294 \ubcf4\ud1b5 6~N-Key Rollover \uc9c0\uc6d0<\/td><\/tr><tr><td><strong>Ghosting \ud604\uc0c1<\/strong><\/td><td>\ub20c\ub9ac\uc9c0 \uc54a\uc740 \ud0a4\uac00 \uc785\ub825\ub418\ub294 \ud604\uc0c1<\/td><td>\uba64\ube0c\ub808\uc778 \ud0a4\ubcf4\ub4dc\uc5d0\uc11c \uc790\uc8fc \ubc1c\uc0dd<\/td><\/tr><tr><td><strong>\ub85c\uadf8 \uae30\ub85d<\/strong><\/td><td>\ub20c\ub9bc\/\ud574\uc81c \uc2dc\uc810<\/td><td>\uc2a4\uc704\uce58 \uc811\uc810 \ubd88\ub7c9 \uc5ec\ubd80 \ud655\uc778 \uac00\ub2a5<\/td><\/tr><tr><td><strong>\ud3ec\ucee4\uc2a4 \uc0c1\ud0dc<\/strong><\/td><td>\ube0c\ub77c\uc6b0\uc800\uac00 \uc785\ub825\uc744 \ubc1b\ub294 \uc911\uc778\uc9c0 \uc5ec\ubd80<\/td><td>OUT\uc774\uba74 \ud074\ub9ad \ud6c4 \ub2e4\uc2dc \ud65c\uc131\ud654 \ud544\uc694<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%F0%9F%8E%A8_%EB%94%94%EC%9E%90%EC%9D%B8_%ED%8A%B9%EC%A7%95\"><\/span>\ud83c\udfa8 \ub514\uc790\uc778 \ud2b9\uc9d5<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \ud14c\uc2a4\ud2b8 \ub3c4\uad6c\ub294 \uae30\ubcf8\uc801\uc73c\ub85c \ub2e4\ud06c\ud1a4\uc73c\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\uc73c\uba70,<br>\uc6cc\ub4dc\ud504\ub808\uc2a4 \ud14c\ub9c8\uc640 \uad00\uacc4\uc5c6\uc774 <strong>\uae54\ub054\ud55c \ub3c5\ub9bd\ud615 \ub514\uc790\uc778<\/strong>\uc73c\ub85c \ud45c\uc2dc\ub429\ub2c8\ub2e4.<br>\ub610\ud55c, \ud0a4\ubcf4\ub4dc \uac04\uaca9\uacfc \ub85c\uadf8\ucc3d \ub192\uc774\ub97c \ucd5c\uc801\ud654\ud558\uc5ec<br><strong>\ud55c\ub208\uc5d0 \ubcf4\uae30 \uc88b\uc740 \uade0\ud615 \uc7a1\ud78c \uc778\ud130\ud398\uc774\uc2a4<\/strong>\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud654\uba74 \ud3ed\uc774 \uc881\uc544\uc9c8 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ucd95\uc18c\ub418\uba70,<br><code>\uac04\uaca9 \uc881\ud798<\/code> \ubc84\ud2bc\uc73c\ub85c \ub354 \ucef4\ud329\ud2b8\ud558\uac8c \uc870\uc815\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"%F0%9F%A7%A9_%EB%A7%88%EB%AC%B4%EB%A6%AC\"><\/span>\ud83e\udde9 \ub9c8\ubb34\ub9ac<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">\uc628\ub77c\uc778 \ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud2b8\ub294 \ub2e8\uc21c\ud55c \uc7ac\ubbf8\uc6a9 \ub3c4\uad6c\ub97c \ub118\uc5b4,<br><strong>\ud558\ub4dc\uc6e8\uc5b4 \uc0c1\ud0dc\ub97c \ubc14\ub85c \uc810\uac80\ud560 \uc218 \uc788\ub294 \uc2e4\uc6a9\uc801\uc778 \ud234<\/strong>\uc785\ub2c8\ub2e4.<br>\ub204\uad6c\ub098 \uc27d\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d UI\ub97c \uac04\uc18c\ud654\ud588\uace0,<br>\uc6cc\ub4dc\ud504\ub808\uc2a4 \ud3ec\uc2a4\ud305\uc5d0\uc11c\ub3c4 \uc644\ubcbd\ud788 \ub3d9\uc791\ud558\ub3c4\ub85d \ucd5c\uc801\ud654\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\uc81c \ud0a4\ubcf4\ub4dc\uac00 \uc81c\ub300\ub85c \uc791\ub3d9\ud558\ub294\uc9c0 \uad81\uae08\ud558\ub2e4\uba74,<br>\uad73\uc774 \ubcc4\ub3c4 \ud504\ub85c\uadf8\ub7a8\uc744 \uae54 \ud544\uc694 \uc5c6\uc774 \uc774 \ud398\uc774\uc9c0\uc5d0\uc11c \ubc14\ub85c \ud14c\uc2a4\ud2b8\ud574\ubcf4\uc138\uc694.<br>\ud83d\udd11 \ud0a4\ubcf4\ub4dc\uc758 \ubaa8\ub4e0 \ube44\ubc00\uc774, \ub2f9\uc2e0\uc758 \uc190\ub05d\uc5d0\uc11c \ud655\uc778\ub429\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uac00\ub054 \uc774\ub7f0 \uacbd\ud5d8 \uc788\uc73c\uc2dc\uc8e0?\u201c\ud0a4\ubcf4\ub4dc\uac00 \uba40\uca61\ud574 \ubcf4\uc774\ub294\ub370, \uac8c\uc784 \uc911\uc5d0 \uac11\uc790\uae30 \uc2a4\ud398\uc774\uc2a4\ubc14\uac00 \uc548 \uba39\uc5b4\uc694.\u201d\ud639\uc740 \u201c\uc2a4\uc704\uce58\ub97c \uad50\uccb4\ud588\ub294\ub370 \uc81c\ub300\ub85c \uc778\uc2dd\ub418\ub294\uc9c0 \ud5f7\uac08\ub824\uc694.\u201d \uc774\ub7f4 \ub54c \ubc14\ub85c \ud655\uc778\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4\uba74 \uc5bc\ub9c8\ub098 \uc88b\uc744\uae4c\uc694?\uc774\ubc88 \uae00\uc5d0\uc11c\ub294 \ubcc4\ub3c4\uc758 \uc124\uce58 \uc5c6\uc774, \uc6f9 \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c \ubc14\ub85c \uc2e4\ud589\ub418\ub294 \uc628\ub77c\uc778 \ud0a4\ubcf4\ub4dc \ud14c\uc2a4\ud2b8 \ub3c4\uad6c\ub97c \uc18c\uac1c\ud574\ub4dc\ub9bd\ub2c8\ub2e4.\ud2b9\ud788 \uc774 \ub3c4\uad6c\ub294 \ub2e8\uc21c\ud788 \ud0a4\uac00 \ub20c\ub9ac\ub294\uc9c0\ub9cc \ud655\uc778\ud558\ub294 \uac8c \uc544\ub2c8\ub77c,N-Key Rollover(\ub3d9\uc2dc \uc785\ub825 \ud55c\uacc4), Ghosting(\uc720\ub839 \uc785\ub825) \ud604\uc0c1\uae4c\uc9c0 \ud55c\ub208\uc5d0&hellip;&nbsp;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":"","jetpack_post_was_ever_published":false},"categories":[696],"tags":[586,578,583,585,582,581,579,580,584],"class_list":["post-1851","post","type-post","status-publish","format-standard","hentry","category-software-tools","tag-n","tag-578","tag-583","tag-585","tag-582","tag-581","tag-579","tag-580","tag-584"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/posts\/1851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/comments?post=1851"}],"version-history":[{"count":15,"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/posts\/1851\/revisions"}],"predecessor-version":[{"id":1875,"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/posts\/1851\/revisions\/1875"}],"wp:attachment":[{"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/media?parent=1851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/categories?post=1851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/steelcrucian.com\/wp-json\/wp\/v2\/tags?post=1851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}