1+ ( function ( ) {
2+ const container = document . getElementById ( 'tool-binary' ) ;
3+ if ( ! container ) return ;
4+
5+ const lang = container . getAttribute ( 'data-lang' ) || 'zh-cn' ;
6+
7+ const i18n = {
8+ 'zh-cn' : {
9+ labelInput : '输入数值' ,
10+ labelBase : '源进制' ,
11+ labelBinary : '二进制 (2)' ,
12+ labelOctal : '八进制 (8)' ,
13+ labelDecimal : '十进制 (10)' ,
14+ labelHex : '十六进制 (16)' ,
15+ labelCustom : '自定义进制 (2-36)' ,
16+ placeholderInput : '在这里输入数值...' ,
17+ placeholderCustom : '例如: 32' ,
18+ invalidInput : '无效输入' ,
19+ copyBtn : '复制' ,
20+ copied : '已复制'
21+ } ,
22+ 'en' : {
23+ labelInput : 'Input Value' ,
24+ labelBase : 'Source Base' ,
25+ labelBinary : 'Binary (2)' ,
26+ labelOctal : 'Octal (8)' ,
27+ labelDecimal : 'Decimal (10)' ,
28+ labelHex : 'Hexadecimal (16)' ,
29+ labelCustom : 'Custom Base (2-36)' ,
30+ placeholderInput : 'Enter value here...' ,
31+ placeholderCustom : 'e.g., 32' ,
32+ invalidInput : 'Invalid Input' ,
33+ copyBtn : 'Copy' ,
34+ copied : 'Copied'
35+ }
36+ } ;
37+
38+ const t = i18n [ lang ] || i18n [ 'en' ] ;
39+
40+ container . innerHTML = `
41+ <style>
42+ #tool-binary .tool-container { display: flex; flex-direction: column; gap: 1.5rem; max-width: 600px; margin: 0 auto; }
43+ #tool-binary .input-group { display: flex; flex-direction: column; gap: 0.5rem; }
44+ #tool-binary .input-group label { font-weight: bold; font-size: 1.1rem; color: var(--card-text-color-main); }
45+ #tool-binary select, #tool-binary input {
46+ padding: 0.8rem;
47+ border: 1px solid var(--border-color);
48+ border-radius: 4px;
49+ background: var(--body-background);
50+ color: var(--card-text-color-main);
51+ font-size: 1rem;
52+ outline: none;
53+ transition: border-color 0.2s;
54+ }
55+ #tool-binary select:focus, #tool-binary input:focus { border-color: var(--accent-color); }
56+ #tool-binary .results-grid { display: grid; grid-template-columns: 1fr; gap: 1rem; margin-top: 1rem; }
57+ #tool-binary .result-item { display: flex; flex-direction: column; gap: 0.3rem; }
58+ #tool-binary .result-item label { font-size: 0.9rem; color: var(--card-text-color-secondary); }
59+ #tool-binary .result-row { display: flex; gap: 0.5rem; }
60+ #tool-binary .result-row input { flex: 1; }
61+ #tool-binary .copy-btn {
62+ padding: 0 1rem;
63+ background: var(--accent-color);
64+ color: #fff;
65+ border: none;
66+ border-radius: 4px;
67+ cursor: pointer;
68+ font-size: 0.9rem;
69+ transition: opacity 0.2s;
70+ }
71+ #tool-binary .copy-btn:hover { opacity: 0.8; }
72+ #tool-binary .custom-base-group { display: flex; gap: 1rem; }
73+ #tool-binary .custom-base-group .input-group { flex: 1; }
74+ </style>
75+ <div class="tool-container">
76+ <div class="custom-base-group">
77+ <div class="input-group">
78+ <label>${ t . labelBase } </label>
79+ <select id="source-base">
80+ <option value="2">2 (${ t . labelBinary } )</option>
81+ <option value="8">8 (${ t . labelOctal } )</option>
82+ <option value="10" selected>10 (${ t . labelDecimal } )</option>
83+ <option value="16">16 (${ t . labelHex } )</option>
84+ <option value="custom">${ t . labelCustom } </option>
85+ </select>
86+ </div>
87+ <div class="input-group" id="custom-source-group" style="display: none;">
88+ <label>${ t . labelCustom } </label>
89+ <input type="number" id="custom-source-base" min="2" max="36" value="32">
90+ </div>
91+ </div>
92+
93+ <div class="input-group">
94+ <label>${ t . labelInput } </label>
95+ <input type="text" id="binary-input" placeholder="${ t . placeholderInput } ">
96+ </div>
97+
98+ <div class="results-grid">
99+ <div class="result-item">
100+ <label>${ t . labelBinary } </label>
101+ <div class="result-row">
102+ <input type="text" id="res-2" readonly>
103+ <button class="copy-btn" data-target="res-2">${ t . copyBtn } </button>
104+ </div>
105+ </div>
106+ <div class="result-item">
107+ <label>${ t . labelOctal } </label>
108+ <div class="result-row">
109+ <input type="text" id="res-8" readonly>
110+ <button class="copy-btn" data-target="res-8">${ t . copyBtn } </button>
111+ </div>
112+ </div>
113+ <div class="result-item">
114+ <label>${ t . labelDecimal } </label>
115+ <div class="result-row">
116+ <input type="text" id="res-10" readonly>
117+ <button class="copy-btn" data-target="res-10">${ t . copyBtn } </button>
118+ </div>
119+ </div>
120+ <div class="result-item">
121+ <label>${ t . labelHex } </label>
122+ <div class="result-row">
123+ <input type="text" id="res-16" readonly>
124+ <button class="copy-btn" data-target="res-16">${ t . copyBtn } </button>
125+ </div>
126+ </div>
127+ <div class="result-item">
128+ <div style="display: flex; justify-content: space-between; align-items: center;">
129+ <label>${ t . labelCustom } </label>
130+ <input type="number" id="target-custom-base" min="2" max="36" value="32" style="width: 60px; padding: 0.2rem; font-size: 0.8rem;">
131+ </div>
132+ <div class="result-row">
133+ <input type="text" id="res-custom" readonly>
134+ <button class="copy-btn" data-target="res-custom">${ t . copyBtn } </button>
135+ </div>
136+ </div>
137+ </div>
138+ </div>
139+ ` ;
140+
141+ const sourceBaseSelect = document . getElementById ( 'source-base' ) ;
142+ const customSourceGroup = document . getElementById ( 'custom-source-group' ) ;
143+ const customSourceBaseInput = document . getElementById ( 'custom-source-base' ) ;
144+ const binaryInput = document . getElementById ( 'binary-input' ) ;
145+ const targetCustomBaseInput = document . getElementById ( 'target-custom-base' ) ;
146+
147+ const resultInputs = {
148+ 2 : document . getElementById ( 'res-2' ) ,
149+ 8 : document . getElementById ( 'res-8' ) ,
150+ 10 : document . getElementById ( 'res-10' ) ,
151+ 16 : document . getElementById ( 'res-16' ) ,
152+ custom : document . getElementById ( 'res-custom' )
153+ } ;
154+
155+ function updateConversion ( ) {
156+ const val = binaryInput . value . trim ( ) ;
157+ if ( ! val ) {
158+ Object . values ( resultInputs ) . forEach ( input => input . value = '' ) ;
159+ return ;
160+ }
161+
162+ let sourceBase = sourceBaseSelect . value === 'custom'
163+ ? parseInt ( customSourceBaseInput . value )
164+ : parseInt ( sourceBaseSelect . value ) ;
165+
166+ if ( isNaN ( sourceBase ) || sourceBase < 2 || sourceBase > 36 ) sourceBase = 10 ;
167+
168+ try {
169+ // Parse the input value based on source base
170+ const decimalValue = BigInt ( '0x' + parseInt ( val , sourceBase ) . toString ( 16 ) ) ; // Use BigInt for precision if possible, but simple parseInt for now
171+ // Standard parseInt is limited to 53-bit precision. For larger numbers, we might need a library or custom logic.
172+ // But for a simple tool, standard conversion is usually enough.
173+ const decimalNum = parseInt ( val , sourceBase ) ;
174+
175+ if ( isNaN ( decimalNum ) ) {
176+ throw new Error ( 'Invalid' ) ;
177+ }
178+
179+ resultInputs [ 2 ] . value = decimalNum . toString ( 2 ) . toUpperCase ( ) ;
180+ resultInputs [ 8 ] . value = decimalNum . toString ( 8 ) . toUpperCase ( ) ;
181+ resultInputs [ 10 ] . value = decimalNum . toString ( 10 ) . toUpperCase ( ) ;
182+ resultInputs [ 16 ] . value = decimalNum . toString ( 16 ) . toUpperCase ( ) ;
183+
184+ let targetCustomBase = parseInt ( targetCustomBaseInput . value ) ;
185+ if ( isNaN ( targetCustomBase ) || targetCustomBase < 2 || targetCustomBase > 36 ) targetCustomBase = 32 ;
186+ resultInputs [ 'custom' ] . value = decimalNum . toString ( targetCustomBase ) . toUpperCase ( ) ;
187+
188+ } catch ( e ) {
189+ Object . values ( resultInputs ) . forEach ( input => input . value = t . invalidInput ) ;
190+ }
191+ }
192+
193+ sourceBaseSelect . addEventListener ( 'change' , ( ) => {
194+ customSourceGroup . style . display = sourceBaseSelect . value === 'custom' ? 'flex' : 'none' ;
195+ updateConversion ( ) ;
196+ } ) ;
197+
198+ [ customSourceBaseInput , binaryInput , targetCustomBaseInput ] . forEach ( el => {
199+ el . addEventListener ( 'input' , updateConversion ) ;
200+ } ) ;
201+
202+ // Copy functionality
203+ container . querySelectorAll ( '.copy-btn' ) . forEach ( btn => {
204+ btn . addEventListener ( 'click' , ( ) => {
205+ const targetId = btn . getAttribute ( 'data-target' ) ;
206+ const input = document . getElementById ( targetId ) ;
207+ if ( input && input . value && input . value !== t . invalidInput ) {
208+ input . select ( ) ;
209+ document . execCommand ( 'copy' ) ;
210+ const originalText = btn . innerText ;
211+ btn . innerText = t . copied ;
212+ setTimeout ( ( ) => btn . innerText = originalText , 1500 ) ;
213+ }
214+ } ) ;
215+ } ) ;
216+ } ) ( ) ;
0 commit comments