Mustafa7assan commited on
Commit
33cf488
·
verified ·
1 Parent(s): abfbce3

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +1149 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Adv
3
- emoji: 🦀
4
- colorFrom: purple
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: adv
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1149 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>ChemCalc Pro | Advanced Chemical Calculator</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <style>
9
+ :root {
10
+ --primary: #3a7bd5;
11
+ --secondary: #00d2ff;
12
+ --dark: #1a1a2e;
13
+ --light: #f5f7fa;
14
+ --success: #28a745;
15
+ --danger: #dc3545;
16
+ --warning: #fd7e14;
17
+ --info: #17a2b8;
18
+ }
19
+
20
+ * {
21
+ margin: 0;
22
+ padding: 0;
23
+ box-sizing: border-box;
24
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
25
+ }
26
+
27
+ body {
28
+ background: linear-gradient(135deg, #f5f7fa 0%, #e4e6e9 100%);
29
+ min-height: 100vh;
30
+ color: var(--dark);
31
+ }
32
+
33
+ .container {
34
+ max-width: 1200px;
35
+ margin: 0 auto;
36
+ padding: 20px;
37
+ }
38
+
39
+ header {
40
+ text-align: center;
41
+ margin-bottom: 30px;
42
+ padding: 20px;
43
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
44
+ color: white;
45
+ border-radius: 10px;
46
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
47
+ }
48
+
49
+ h1 {
50
+ font-size: 2.5rem;
51
+ margin-bottom: 10px;
52
+ }
53
+
54
+ h1 i {
55
+ margin-right: 15px;
56
+ }
57
+
58
+ .subtitle {
59
+ font-size: 1.1rem;
60
+ opacity: 0.9;
61
+ }
62
+
63
+ .tabs {
64
+ display: flex;
65
+ flex-wrap: wrap;
66
+ background: white;
67
+ border-radius: 10px;
68
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
69
+ margin-bottom: 30px;
70
+ overflow: hidden;
71
+ }
72
+
73
+ .tab-button {
74
+ flex: 1;
75
+ padding: 15px 20px;
76
+ text-align: center;
77
+ cursor: pointer;
78
+ transition: all 0.3s ease;
79
+ font-weight: 600;
80
+ border-bottom: 3px solid transparent;
81
+ }
82
+
83
+ .tab-button:hover {
84
+ background: rgba(0, 0, 0, 0.05);
85
+ }
86
+
87
+ .tab-button.active {
88
+ background: rgba(58, 123, 213, 0.1);
89
+ border-bottom: 3px solid var(--primary);
90
+ color: var(--primary);
91
+ }
92
+
93
+ .tab-content {
94
+ display: none;
95
+ padding: 30px;
96
+ background: white;
97
+ border-radius: 0 0 10px 10px;
98
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
99
+ }
100
+
101
+ .tab-content.active {
102
+ display: block;
103
+ animation: fadeIn 0.5s ease;
104
+ }
105
+
106
+ @keyframes fadeIn {
107
+ from { opacity: 0; transform: translateY(10px); }
108
+ to { opacity: 1; transform: translateY(0); }
109
+ }
110
+
111
+ .calculator-form {
112
+ display: grid;
113
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
114
+ gap: 20px;
115
+ }
116
+
117
+ .form-group {
118
+ margin-bottom: 20px;
119
+ }
120
+
121
+ label {
122
+ display: block;
123
+ margin-bottom: 8px;
124
+ font-weight: 600;
125
+ color: #555;
126
+ }
127
+
128
+ input, select {
129
+ width: 100%;
130
+ padding: 12px 15px;
131
+ border: 1px solid #ddd;
132
+ border-radius: 6px;
133
+ font-size: 16px;
134
+ transition: border 0.3s ease;
135
+ }
136
+
137
+ input:focus, select:focus {
138
+ border-color: var(--primary);
139
+ outline: none;
140
+ box-shadow: 0 0 0 3px rgba(58, 123, 213, 0.2);
141
+ }
142
+
143
+ .btn {
144
+ display: inline-block;
145
+ padding: 12px 24px;
146
+ background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
147
+ color: white;
148
+ border: none;
149
+ border-radius: 6px;
150
+ cursor: pointer;
151
+ font-size: 16px;
152
+ font-weight: 600;
153
+ transition: all 0.3s ease;
154
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
155
+ }
156
+
157
+ .btn:hover {
158
+ transform: translateY(-2px);
159
+ box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
160
+ }
161
+
162
+ .btn-calculate {
163
+ grid-column: 1 / -1;
164
+ justify-self: center;
165
+ margin-top: 20px;
166
+ min-width: 200px;
167
+ }
168
+
169
+ .result-container {
170
+ margin-top: 30px;
171
+ padding: 20px;
172
+ background: rgba(58, 123, 213, 0.1);
173
+ border-radius: 8px;
174
+ border-left: 4px solid var(--primary);
175
+ display: none;
176
+ }
177
+
178
+ .result-container.show {
179
+ display: block;
180
+ animation: fadeIn 0.5s ease;
181
+ }
182
+
183
+ .result-title {
184
+ font-weight: 700;
185
+ margin-bottom: 10px;
186
+ color: var(--primary);
187
+ }
188
+
189
+ .result-value {
190
+ font-size: 1.2rem;
191
+ font-weight: 600;
192
+ }
193
+
194
+ .periodic-table {
195
+ margin-top: 30px;
196
+ }
197
+
198
+ .periodic-table h3 {
199
+ margin-bottom: 15px;
200
+ color: var(--primary);
201
+ }
202
+
203
+ .elements-grid {
204
+ display: grid;
205
+ grid-template-columns: repeat(18, 1fr);
206
+ gap: 5px;
207
+ margin-bottom: 30px;
208
+ }
209
+
210
+ .element {
211
+ padding: 10px 5px;
212
+ background: white;
213
+ border-radius: 4px;
214
+ text-align: center;
215
+ cursor: pointer;
216
+ transition: all 0.3s ease;
217
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
218
+ }
219
+
220
+ .element:hover {
221
+ transform: scale(1.05);
222
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
223
+ z-index: 1;
224
+ }
225
+
226
+ .element-symbol {
227
+ font-weight: 700;
228
+ font-size: 0.9rem;
229
+ }
230
+
231
+ .element-number {
232
+ font-size: 0.6rem;
233
+ opacity: 0.7;
234
+ }
235
+
236
+ .nonmetal { background-color: #ade8af; }
237
+ .alkali { background-color: #ffb7b3; }
238
+ .alkaline { background-color: #ffdfba; }
239
+ .transition { background-color: #ffc8dd; }
240
+ .post-transition { background-color: #b8d0eb; }
241
+ .metalloid { background-color: #c2e0c6; }
242
+ .halogen { background-color: #caffbf; }
243
+ .noble { background-color: #cddafd; }
244
+ .lanthanide { background-color: #eac4d5; }
245
+ .actinide { background-color: #f1c0e8; }
246
+
247
+ .history-container {
248
+ margin-top: 30px;
249
+ max-height: 300px;
250
+ overflow-y: auto;
251
+ }
252
+
253
+ .history-item {
254
+ padding: 10px 15px;
255
+ margin-bottom: 10px;
256
+ background: white;
257
+ border-radius: 6px;
258
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
259
+ font-size: 0.9rem;
260
+ }
261
+
262
+ .history-item .time {
263
+ font-size: 0.8rem;
264
+ color: #777;
265
+ }
266
+
267
+ footer {
268
+ text-align: center;
269
+ margin-top: 50px;
270
+ padding: 20px;
271
+ color: #777;
272
+ font-size: 0.9rem;
273
+ }
274
+
275
+ @media (max-width: 768px) {
276
+ .elements-grid {
277
+ grid-template-columns: repeat(9, 1fr);
278
+ }
279
+
280
+ .tab-button {
281
+ flex: 0 0 50%;
282
+ }
283
+ }
284
+
285
+ @media (max-width: 480px) {
286
+ .tab-button {
287
+ flex: 0 0 100%;
288
+ }
289
+
290
+ .elements-grid {
291
+ grid-template-columns: repeat(6, 1fr);
292
+ }
293
+ }
294
+
295
+ /* Special styling for specific calculator types */
296
+ .concentration-controls, .reaction-controls {
297
+ display: flex;
298
+ gap: 15px;
299
+ align-items: center;
300
+ }
301
+
302
+ .reaction-arrow {
303
+ font-size: 1.5rem;
304
+ color: #777;
305
+ padding: 0 10px;
306
+ }
307
+
308
+ .formula-display {
309
+ font-size: 1.2rem;
310
+ font-family: 'Courier New', monospace;
311
+ padding: 10px;
312
+ background: #f5f5f5;
313
+ border-radius: 4px;
314
+ margin: 15px 0;
315
+ word-break: break-all;
316
+ }
317
+
318
+ .advanced-options {
319
+ margin-top: 20px;
320
+ padding-top: 20px;
321
+ border-top: 1px solid #eee;
322
+ }
323
+
324
+ .toggle-advanced {
325
+ background: none;
326
+ border: none;
327
+ color: var(--primary);
328
+ cursor: pointer;
329
+ font-weight: 600;
330
+ display: flex;
331
+ align-items: center;
332
+ margin-bottom: 10px;
333
+ }
334
+
335
+ .toggle-advanced i {
336
+ margin-right: 5px;
337
+ transition: transform 0.3s ease;
338
+ }
339
+
340
+ .toggle-advanced.collapsed i {
341
+ transform: rotate(-90deg);
342
+ }
343
+ </style>
344
+ </head>
345
+ <body>
346
+ <div class="container">
347
+ <header>
348
+ <h1><i class="fas fa-atom"></i> ChemCalc Pro</h1>
349
+ <p class="subtitle">Advanced Chemical Calculations for Professionals</p>
350
+ </header>
351
+
352
+ <div class="tabs">
353
+ <div class="tab-button active" data-tab="molar-mass"><i class="fas fa-weight-hanging"></i> Molar Mass</div>
354
+ <div class="tab-button" data-tab="concentration"><i class="fas fa-flask"></i> Concentration</div>
355
+ <div class="tab-button" data-tab="stoichiometry"><i class="fas fa-balance-scale"></i> Stoichiometry</div>
356
+ <div class="tab-button" data-tab="gas-laws"><i class="fas fa-wind"></i> Gas Laws</div>
357
+ <div class="tab-button" data-tab="thermochemistry"><i class="fas fa-temperature-high"></i> Thermochemistry</div>
358
+ <div class="tab-button" data-tab="redox"><i class="fas fa-bolt"></i> Redox</div>
359
+ </div>
360
+
361
+ <!-- Molar Mass Calculator -->
362
+ <div id="molar-mass" class="tab-content active">
363
+ <h2><i class="fas fa-weight-hanging"></i> Molar Mass Calculator</h2>
364
+ <p>Calculate the molar mass of any chemical compound by entering its formula.</p>
365
+
366
+ <div class="calculator-form">
367
+ <div class="form-group">
368
+ <label for="compound-formula">Chemical Formula</label>
369
+ <input type="text" id="compound-formula" placeholder="e.g. H2O, C6H12O6, Ca(OH)2">
370
+ </div>
371
+
372
+ <div class="form-group">
373
+ <label for="compound-mass">Mass (optional)</label>
374
+ <div class="concentration-controls">
375
+ <input type="number" id="compound-mass" placeholder="e.g. 5">
376
+ <select id="mass-unit">
377
+ <option value="g">g</option>
378
+ <option value="mg">mg</option>
379
+ <option value="kg">kg</option>
380
+ </select>
381
+ </div>
382
+ </div>
383
+
384
+ <button id="calculate-mass" class="btn btn-calculate">Calculate Molar Mass</button>
385
+ </div>
386
+
387
+ <div id="mass-result" class="result-container">
388
+ <div class="result-title">Results</div>
389
+ <div id="mass-value" class="result-value"></div>
390
+ <div id="moles-value" class="result-value" style="margin-top: 10px;"></div>
391
+ <div id="composition" style="margin-top: 15px;"></div>
392
+ </div>
393
+
394
+ <div class="periodic-table">
395
+ <h3>Periodic Table</h3>
396
+ <p>Click on elements to add them to the formula</p>
397
+ <div class="elements-grid" id="periodic-elements"></div>
398
+ </div>
399
+ </div>
400
+
401
+ <!-- Concentration Calculator -->
402
+ <div id="concentration" class="tab-content">
403
+ <h2><i class="fas fa-flask"></i> Concentration Calculator</h2>
404
+ <p>Calculate concentration, mass, volume, or dilution of solutions.</p>
405
+
406
+ <div class="calculator-form">
407
+ <div class="form-group">
408
+ <label>Calculation Type</label>
409
+ <select id="concentration-type" class="form-control">
410
+ <option value="conc-from-mass">Concentration from Mass</option>
411
+ <option value="mass-from-conc">Mass from Concentration</option>
412
+ <option value="dilution">Dilution</option>
413
+ <option value="mole-fraction">Mole Fraction</option>
414
+ </select>
415
+ </div>
416
+
417
+ <div id="conc-inputs">
418
+ <div class="form-group">
419
+ <label for="solute-formula">Solute Formula</label>
420
+ <input type="text" id="solute-formula" placeholder="e.g. NaCl">
421
+ </div>
422
+
423
+ <div class="form-group">
424
+ <label for="solute-mass">Mass of Solute</label>
425
+ <input type="number" id="solute-mass" placeholder="in grams">
426
+ </div>
427
+
428
+ <div class="form-group">
429
+ <label for="solution-volume">Solution Volume</label>
430
+ <div class="concentration-controls">
431
+ <input type="number" id="solution-volume" placeholder="e.g. 250">
432
+ <select id="vol-unit">
433
+ <option value="L">L</option>
434
+ <option value="mL">mL</option>
435
+ </select>
436
+ </div>
437
+ </div>
438
+ </div>
439
+
440
+ <div id="dilution-inputs" style="display: none;">
441
+ <div class="form-group">
442
+ <label for="initial-conc">Initial Concentration</label>
443
+ <div class="concentration-controls">
444
+ <input type="number" id="initial-conc">
445
+ <select id="initial-conc-unit">
446
+ <option value="M">M</option>
447
+ <option value="mM">mM</option>
448
+ </select>
449
+ </div>
450
+ </div>
451
+
452
+ <div class="form-group">
453
+ <label for="initial-vol">Initial Volume</label>
454
+ <div class="concentration-controls">
455
+ <input type="number" id="initial-vol">
456
+ <select id="initial-vol-unit">
457
+ <option value="L">L</option>
458
+ <option value="mL">mL</option>
459
+ </select>
460
+ </div>
461
+ </div>
462
+ </div>
463
+
464
+ <div id="conc-advanced" class="advanced-options" style="display: none;">
465
+ <div class="form-group">
466
+ <label for="solution-density">Solution Density (g/mL)</label>
467
+ <input type="number" id="solution-density" placeholder="Optional">
468
+ </div>
469
+
470
+ <div class="form-group">
471
+ <label for="solvent-mass">Solvent Mass (g)</label>
472
+ <input type="number" id="solvent-mass" placeholder="Optional">
473
+ </div>
474
+
475
+ <div class="form-group">
476
+ <label for="solution-temp">Temperature (°C)</label>
477
+ <input type="number" id="solution-temp" placeholder="25">
478
+ </div>
479
+ </div>
480
+
481
+ <button type="button" class="toggle-advanced" id="toggle-conc-advanced">
482
+ <i class="fas fa-chevron-down"></i> Advanced Options
483
+ </button>
484
+
485
+ <button id="calculate-conc" class="btn btn-calculate">Calculate</button>
486
+ </div>
487
+
488
+ <div id="conc-result" class="result-container">
489
+ <div class="result-title">Results</div>
490
+ <div id="conc-value" class="result-value"></div>
491
+ <div id="conc-details" style="margin-top: 15px;"></div>
492
+ </div>
493
+ </div>
494
+
495
+ <!-- Stoichiometry Calculator -->
496
+ <div id="stoichiometry" class="tab-content">
497
+ <h2><i class="fas fa-balance-scale"></i> Stoichiometry Calculator</h2>
498
+ <p>Balance chemical equations and perform stoichiometric calculations.</p>
499
+
500
+ <div class="calculator-form">
501
+ <div class="form-group">
502
+ <label>Reaction Type</label>
503
+ <select id="reaction-type" class="form-control">
504
+ <option value="balance">Balance Equation</option>
505
+ <option value="limiting-reactant">Limiting Reactant</option>
506
+ <option value="product-yield">Product Yield</option>
507
+ </select>
508
+ </div>
509
+
510
+ <div id="reaction-inputs">
511
+ <div class="form-group balanced-equation">
512
+ <label>Enter Chemical Equation</label>
513
+ <div class="formula-display" id="equation-display"></div>
514
+ <div class="reaction-controls">
515
+ <input type="text" id="reactant1" placeholder="Reactant 1 (e.g. H2)">
516
+ <div class="reaction-arrow">+</div>
517
+ <input type="text" id="reactant2" placeholder="Reactant 2 (e.g. O2)">
518
+ <div class="reaction-arrow">
519
+ <select id="reaction-direction">
520
+ <option value="→">→</option>
521
+ <option value="↔">↔</option>
522
+ </select>
523
+ </div>
524
+ <input type="text" id="product1" placeholder="Product 1 (e.g. H2O)">
525
+ <div class="reaction-arrow">+</div>
526
+ <input type="text" id="product2" placeholder="Product 2 (optional)">
527
+ </div>
528
+ </div>
529
+
530
+ <div id="stoich-inputs" style="display: none;">
531
+ <div class="form-group">
532
+ <label for="given-quantity">Given Quantity</label>
533
+ <input type="number" id="given-quantity" placeholder="Amount">
534
+ </div>
535
+
536
+ <div class="form-group">
537
+ <label for="given-compound">Given Compound</label>
538
+ <input type="text" id="given-compound" placeholder="Formula">
539
+ </div>
540
+
541
+ <div class="form-group">
542
+ <label for="desired-compound">Desired Compound</label>
543
+ <input type="text" id="desired-compound" placeholder="Formula">
544
+ </div>
545
+ </div>
546
+ </div>
547
+
548
+ <button id="balance-reaction" class="btn btn-calculate">Balance Equation</button>
549
+
550
+ <div id="stoich-result" class="result-container">
551
+ <div class="result-title">Results</div>
552
+ <div id="balanced-equation" class="result-value"></div>
553
+ <div id="stoich-details" style="margin-top: 15px;"></div>
554
+ </div>
555
+ </div>
556
+ </div>
557
+
558
+ <!-- Gas Laws Calculator -->
559
+ <div id="gas-laws" class="tab-content">
560
+ <h2><i class="fas fa-wind"></i> Gas Laws Calculator</h2>
561
+ <p>Perform calculations using the ideal gas law and other gas equations.</p>
562
+
563
+ <div class="calculator-form">
564
+ <div class="form-group">
565
+ <label>Gas Law</label>
566
+ <select id="gas-law" class="form-control">
567
+ <option value="ideal-gas">Ideal Gas Law (PV=nRT)</option>
568
+ <option value="boyles">Boyle's Law (P₁V₁=P₂V₂)</option>
569
+ <option value="charles">Charles's Law (V₁/T₁=V₂/T₂)</option>
570
+ <option value="gay-lussac">Gay-Lussac's Law (P₁/T₁=P₂/T₂)</option>
571
+ <option value="combined">Combined Gas Law (P₁V₁/T₁=P₂V₂/T₂)</option>
572
+ <option value="density">Gas Density (d=PM/RT)</option>
573
+ </select>
574
+ </div>
575
+
576
+ <div id="ideal-gas-inputs">
577
+ <div class="form-group">
578
+ <label for="gas-pressure">Pressure (P)</label>
579
+ <div class="concentration-controls">
580
+ <input type="number" id="gas-pressure" placeholder="e.g. 1">
581
+ <select id="pressure-unit">
582
+ <option value="atm">atm</option>
583
+ <option value="mmHg">mmHg</option>
584
+ <option value="kPa">kPa</option>
585
+ <option value="bar">bar</option>
586
+ </select>
587
+ </div>
588
+ </div>
589
+
590
+ <div class="form-group">
591
+ <label for="gas-volume">Volume (V)</label>
592
+ <div class="concentration-controls">
593
+ <input type="number" id="gas-volume" placeholder="e.g. 22.4">
594
+ <select id="volume-unit">
595
+ <option value="L">L</option>
596
+ <option value="mL">mL</option>
597
+ </select>
598
+ </div>
599
+ </div>
600
+
601
+ <div class="form-group">
602
+ <label for="gas-moles">Moles (n)</label>
603
+ <input type="number" id="gas-moles" placeholder="e.g. 1">
604
+ </div>
605
+
606
+ <div class="form-group">
607
+ <label for="gas-temp">Temperature (T)</label>
608
+ <div class="concentration-controls">
609
+ <input type="number" id="gas-temp" placeholder="e.g. 273">
610
+ <select id="temp-unit">
611
+ <option value="K">K</option>
612
+ <option value="°C">°C</option>
613
+ </select>
614
+ </div>
615
+ </div>
616
+ </div>
617
+
618
+ <button id="calculate-gas" class="btn btn-calculate">Calculate</button>
619
+
620
+ <div id="gas-result" class="result-container">
621
+ <div class="result-title">Results</div>
622
+ <div id="gas-value" class="result-value"></div>
623
+ <div id="gas-details" style="margin-top: 15px;"></div>
624
+ </div>
625
+ </div>
626
+ </div>
627
+
628
+ <!-- Thermochemistry Calculator -->
629
+ <div id="thermochemistry" class="tab-content">
630
+ <h2><i class="fas fa-temperature-high"></i> Thermochemistry Calculator</h2>
631
+ <p>Calculate enthalpy, heat transfer, and other thermochemical properties.</p>
632
+
633
+ <div class="calculator-form">
634
+ <div class="form-group">
635
+ <label>Calculation Type</label>
636
+ <select id="thermo-type" class="form-control">
637
+ <option value="enthalpy">Enthalpy Change</option>
638
+ <option value="heat">Heat Transfer (q=mcΔT)</option>
639
+ <option value="hess">Hess's Law</option>
640
+ <option value="calorimetry">Calorimetry</option>
641
+ </select>
642
+ </div>
643
+
644
+ <!-- Enthalpy inputs -->
645
+ <div id="enthalpy-inputs">
646
+ <div class="form-group">
647
+ <label for="reaction-enthalpy">Reaction Enthalpy (ΔH°)</label>
648
+ <div class="concentration-controls">
649
+ <input type="number" id="reaction-enthalpy" placeholder="kJ/mol">
650
+ </div>
651
+ </div>
652
+
653
+ <div class="form-group">
654
+ <label for="moles-reacted">Moles Reacted</label>
655
+ <input type="number" id="moles-reacted" placeholder="mol">
656
+ </div>
657
+ </div>
658
+
659
+ <!-- Heat inputs -->
660
+ <div id="heat-inputs" style="display: none;">
661
+ <div class="form-group">
662
+ <label for="thermo-mass">Mass</label>
663
+ <div class="concentration-controls">
664
+ <input type="number" id="thermo-mass" placeholder="g">
665
+ </div>
666
+ </div>
667
+
668
+ <div class="form-group">
669
+ <label for="specific-heat">Specific Heat Capacity (c)</label>
670
+ <div class="concentration-controls">
671
+ <input type="number" id="specific-heat" placeholder="J/g°C (4.18 for water)">
672
+ </div>
673
+ </div>
674
+
675
+ <div class="form-group">
676
+ <label for="temp-change">Temperature Change (ΔT)</label>
677
+ <div class="concentration-controls">
678
+ <input type="number" id="temp-change" placeholder="°C">
679
+ </div>
680
+ </div>
681
+ </div>
682
+
683
+ <button id="calculate-thermo" class="btn btn-calculate">Calculate</button>
684
+
685
+ <div id="thermo-result" class="result-container">
686
+ <div class="result-title">Results</div>
687
+ <div id="thermo-value" class="result-value"></div>
688
+ <div id="thermo-details" style="margin-top: 15px;"></div>
689
+ </div>
690
+ </div>
691
+ </div>
692
+
693
+ <!-- Redox Calculator -->
694
+ <div id="redox" class="tab-content">
695
+ <h2><i class="fas fa-bolt"></i> Redox Reaction Calculator</h2>
696
+ <p>Balance redox reactions and calculate electrochemical properties.</p>
697
+
698
+ <div class="calculator-form">
699
+ <div class="form-group">
700
+ <label>Calculation Type</label>
701
+ <select id="redox-type" class="form-control">
702
+ <option value="balance-redox">Balance Redox Reaction</option>
703
+ <option value="cell-potential">Cell Potential</option>
704
+ <option value="nernst">Nernst Equation</option>
705
+ </select>
706
+ </div>
707
+
708
+ <div id="redox-reaction-inputs">
709
+ <div class="form-group">
710
+ <label>Redox Reaction (Half-Reactions)</label>
711
+ <div class="reaction-controls">
712
+ <input type="text" id="redox-reactant1" placeholder="Oxidation (e.g. Fe → Fe²⁺)">
713
+ <div class="reaction-arrow">+</div>
714
+ <input type="text" id="redox-reactant2" placeholder="Reduction (e.g. O2 + 4e⁻ → 2O²⁻)">
715
+ </div>
716
+ </div>
717
+ </div>
718
+
719
+ <div id="redox-advanced" class="advanced-options" style="display: none;">
720
+ <div class="form-group">
721
+ <label for="redox-medium">Medium</label>
722
+ <select id="redox-medium">
723
+ <option value="acidic">Acidic</option>
724
+ <option value="basic">Basic</option>
725
+ <option value="neutral">Neutral</option>
726
+ </select>
727
+ </div>
728
+
729
+ <div class="form-group">
730
+ <label for="redox-temp">Temperature (°C)</label>
731
+ <input type="number" id="redox-temp" value="25">
732
+ </div>
733
+ </div>
734
+
735
+ <button type="button" class="toggle-advanced" id="toggle-redox-advanced">
736
+ <i class="fas fa-chevron-down"></i> Advanced Options
737
+ </button>
738
+
739
+ <button id="calculate-redox" class="btn btn-calculate">Balance Reaction</button>
740
+
741
+ <div id="redox-result" class="result-container">
742
+ <div class="result-title">Results</div>
743
+ <div id="redox-value" class="result-value"></div>
744
+ <div id="redox-details" style="margin-top: 15px;"></div>
745
+ </div>
746
+ </div>
747
+ </div>
748
+
749
+ <div class="history-container">
750
+ <h3>Calculation History</h3>
751
+ <div id="history-list"></div>
752
+ </div>
753
+
754
+ <footer>
755
+ <p>ChemCalc Pro &copy; 2023 | Advanced Chemical Calculator for Professionals</p>
756
+ <p>Disclaimer: Results should be verified with experimental data.</p>
757
+ </footer>
758
+ </div>
759
+
760
+ <script>
761
+ document.addEventListener('DOMContentLoaded', function() {
762
+ // Tab functionality
763
+ const tabButtons = document.querySelectorAll('.tab-button');
764
+ const tabContents = document.querySelectorAll('.tab-content');
765
+
766
+ tabButtons.forEach(button => {
767
+ button.addEventListener('click', () => {
768
+ const tabId = button.getAttribute('data-tab');
769
+
770
+ // Update active tab button
771
+ tabButtons.forEach(btn => btn.classList.remove('active'));
772
+ button.classList.add('active');
773
+
774
+ // Show corresponding content
775
+ tabContents.forEach(content => {
776
+ content.classList.remove('active');
777
+ if(content.id === tabId) {
778
+ content.classList.add('active');
779
+ }
780
+ });
781
+ });
782
+ });
783
+
784
+ // Advanced options toggle
785
+ const toggleConcAdvanced = document.getElementById('toggle-conc-advanced');
786
+ const concAdvanced = document.getElementById('conc-advanced');
787
+
788
+ toggleConcAdvanced.addEventListener('click', () => {
789
+ concAdvanced.style.display = concAdvanced.style.display === 'none' ? 'block' : 'none';
790
+ toggleConcAdvanced.classList.toggle('collapsed');
791
+ });
792
+
793
+ const toggleRedoxAdvanced = document.getElementById('toggle-redox-advanced');
794
+ const redoxAdvanced = document.getElementById('redox-advanced');
795
+
796
+ toggleRedoxAdvanced.addEventListener('click', () => {
797
+ redoxAdvanced.style.display = redoxAdvanced.style.display === 'none' ? 'block' : 'none';
798
+ toggleRedoxAdvanced.classList.toggle('collapsed');
799
+ });
800
+
801
+ // Periodic table elements
802
+ const periodicElements = document.getElementById('periodic-elements');
803
+ const compoundFormula = document.getElementById('compound-formula');
804
+
805
+ const elements = [
806
+ { symbol: 'H', name: 'Hydrogen', number: 1, group: 'nonmetal' },
807
+ { symbol: 'He', name: 'Helium', number: 2, group: 'noble' },
808
+ { symbol: 'Li', name: 'Lithium', number: 3, group: 'alkali' },
809
+ { symbol: 'Be', name: 'Beryllium', number: 4, group: 'alkaline' },
810
+ { symbol: 'B', name: 'Boron', number: 5, group: 'metalloid' },
811
+ { symbol: 'C', name: 'Carbon', number: 6, group: 'nonmetal' },
812
+ { symbol: 'N', name: 'Nitrogen', number: 7, group: 'nonmetal' },
813
+ { symbol: 'O', name: 'Oxygen', number: 8, group: 'nonmetal' },
814
+ { symbol: 'F', name: 'Fluorine', number: 9, group: 'halogen' },
815
+ { symbol: 'Ne', name: 'Neon', number: 10, group: 'noble' },
816
+ { symbol: 'Na', name: 'Sodium', number: 11, group: 'alkali' },
817
+ { symbol: 'Mg', name: 'Magnesium', number: 12, group: 'alkaline' },
818
+ { symbol: 'Al', name: 'Aluminum', number: 13, group: 'post-transition' },
819
+ { symbol: 'Si', name: 'Silicon', number: 14, group: 'metalloid' },
820
+ { symbol: 'P', name: 'Phosphorus', number: 15, group: 'nonmetal' },
821
+ { symbol: 'S', name: 'Sulfur', number: 16, group: 'nonmetal' },
822
+ { symbol: 'Cl', name: 'Chlorine', number: 17, group: 'halogen' },
823
+ { symbol: 'Ar', name: 'Argon', number: 18, group: 'noble' },
824
+ { symbol: 'K', name: 'Potassium', number: 19, group: 'alkali' },
825
+ { symbol: 'Ca', name: 'Calcium', number: 20, group: 'alkaline' },
826
+ { symbol: 'Sc', name: 'Scandium', number: 21, group: 'transition' },
827
+ { symbol: 'Ti', name: 'Titanium', number: 22, group: 'transition' },
828
+ { symbol: 'V', name: 'Vanadium', number: 23, group: 'transition' },
829
+ { symbol: 'Cr', name: 'Chromium', number: 24, group: 'transition' },
830
+ { symbol: 'Mn', name: 'Manganese', number: 25, group: 'transition' },
831
+ { symbol: 'Fe', name: 'Iron', number: 26, group: 'transition' },
832
+ { symbol: 'Co', name: 'Cobalt', number: 27, group: 'transition' },
833
+ { symbol: 'Ni', name: 'Nickel', number: 28, group: 'transition' },
834
+ { symbol: 'Cu', name: 'Copper', number: 29, group: 'transition' },
835
+ { symbol: 'Zn', name: 'Zinc', number: 30, group: 'transition' },
836
+ { symbol: 'Ga', name: 'Gallium', number: 31, group: 'post-transition' },
837
+ { symbol: 'Ge', name: 'Germanium', number: 32, group: 'metalloid' },
838
+ { symbol: 'As', name: 'Arsenic', number: 33, group: 'metalloid' },
839
+ { symbol: 'Se', name: 'Selenium', number: 34, group: 'nonmetal' },
840
+ { symbol: 'Br', name: 'Bromine', number: 35, group: 'halogen' },
841
+ { symbol: 'Kr', name: 'Krypton', number: 36, group: 'noble' },
842
+ { symbol: 'Rb', name: 'Rubidium', number: 37, group: 'alkali' },
843
+ { symbol: 'Sr', name: 'Strontium', number: 38, group: 'alkaline' },
844
+ { symbol: 'Y', name: 'Yttrium', number: 39, group: 'transition' },
845
+ { symbol: 'Zr', name: 'Zirconium', number: 40, group: 'transition' },
846
+ { symbol: 'Nb', name: 'Niobium', number: 41, group: 'transition' },
847
+ { symbol: 'Mo', name: 'Molybdenum', number: 42, group: 'transition' },
848
+ { symbol: 'Tc', name: 'Technetium', number: 43, group: 'transition' },
849
+ { symbol: 'Ru', name: 'Ruthenium', number: 44, group: 'transition' },
850
+ { symbol: 'Rh', name: 'Rhodium', number: 45, group: 'transition' },
851
+ { symbol: 'Pd', name: 'Palladium', number: 46, group: 'transition' },
852
+ { symbol: 'Ag', name: 'Silver', number: 47, group: 'transition' },
853
+ { symbol: 'Cd', name: 'Cadmium', number: 48, group: 'transition' },
854
+ { symbol: 'In', name: 'Indium', number: 49, group: 'post-transition' },
855
+ { symbol: 'Sn', name: 'Tin', number: 50, group: 'post-transition' },
856
+ { symbol: 'Sb', name: 'Antimony', number: 51, group: 'metalloid' },
857
+ { symbol: 'Te', name: 'Tellurium', number: 52, group: 'metalloid' },
858
+ { symbol: 'I', name: 'Iodine', number: 53, group: 'halogen' },
859
+ { symbol: 'Xe', name: 'Xenon', number: 54, group: 'noble' },
860
+ { symbol: 'Cs', name: 'Cesium', number: 55, group: 'alkali' },
861
+ { symbol: 'Ba', name: 'Barium', number: 56, group: 'alkaline' },
862
+ { symbol: 'La', name: 'Lanthanum', number: 57, group: 'lanthanide' },
863
+ { symbol: 'Ce', name: 'Cerium', number: 58, group: 'lanthanide' },
864
+ { symbol: 'Pr', name: 'Praseodymium', number: 59, group: 'lanthanide' },
865
+ { symbol: 'Nd', name: 'Neodymium', number: 60, group: 'lanthanide' },
866
+ { symbol: 'Pm', name: 'Promethium', number: 61, group: 'lanthanide' },
867
+ { symbol: 'Sm', name: 'Samarium', number: 62, group: 'lanthanide' },
868
+ { symbol: 'Eu', name: 'Europium', number: 63, group: 'lanthanide' },
869
+ { symbol: 'Gd', name: 'Gadolinium', number: 64, group: 'lanthanide' },
870
+ { symbol: 'Tb', name: 'Terbium', number: 65, group: 'lanthanide' },
871
+ { symbol: 'Dy', name: 'Dysprosium', number: 66, group: 'lanthanide' },
872
+ { symbol: 'Ho', name: 'Holmium', number: 67, group: 'lanthanide' },
873
+ { symbol: 'Er', name: 'Erbium', number: 68, group: 'lanthanide' },
874
+ { symbol: 'Tm', name: 'Thulium', number: 69, group: 'lanthanide' },
875
+ { symbol: 'Yb', name: 'Ytterbium', number: 70, group: 'lanthanide' },
876
+ { symbol: 'Lu', name: 'Lutetium', number: 71, group: 'lanthanide' },
877
+ { symbol: 'Hf', name: 'Hafnium', number: 72, group: 'transition' },
878
+ { symbol: 'Ta', name: 'Tantalum', number: 73, group: 'transition' },
879
+ { symbol: 'W', name: 'Tungsten', number: 74, group: 'transition' },
880
+ { symbol: 'Re', name: 'Rhenium', number: 75, group: 'transition' },
881
+ { symbol: 'Os', name: 'Osmium', number: 76, group: 'transition' },
882
+ { symbol: 'Ir', name: 'Iridium', number: 77, group: 'transition' },
883
+ { symbol: 'Pt', name: 'Platinum', number: 78, group: 'transition' },
884
+ { symbol: 'Au', name: 'Gold', number: 79, group: 'transition' },
885
+ { symbol: 'Hg', name: 'Mercury', number: 80, group: 'transition' },
886
+ { symbol: 'Tl', name: 'Thallium', number: 81, group: 'post-transition' },
887
+ { symbol: 'Pb', name: 'Lead', number: 82, group: 'post-transition' },
888
+ { symbol: 'Bi', name: 'Bismuth', number: 83, group: 'post-transition' },
889
+ { symbol: 'Po', name: 'Polonium', number: 84, group: 'metalloid' },
890
+ { symbol: 'At', name: 'Astatine', number: 85, group: 'halogen' },
891
+ { symbol: 'Rn', name: 'Radon', number: 86, group: 'noble' },
892
+ { symbol: 'Fr', name: 'Francium', number: 87, group: 'alkali' },
893
+ { symbol: 'Ra', name: 'Radium', number: 88, group: 'alkaline' },
894
+ { symbol: 'Ac', name: 'Actinium', number: 89, group: 'actinide' },
895
+ { symbol: 'Th', name: 'Thorium', number: 90, group: 'actinide' },
896
+ { symbol: 'Pa', name: 'Protactinium', number: 91, group: 'actinide' },
897
+ { symbol: 'U', name: 'Uranium', number: 92, group: 'actinide' },
898
+ { symbol: 'Np', name: 'Neptunium', number: 93, group: 'actinide' },
899
+ { symbol: 'Pu', name: 'Plutonium', number: 94, group: 'actinide' },
900
+ // ... more elements if needed
901
+ ];
902
+
903
+ // Create periodic table
904
+ elements.forEach(element => {
905
+ const elementDiv = document.createElement('div');
906
+ elementDiv.className = `element ${element.group}`;
907
+ elementDiv.innerHTML = `
908
+ <div class="element-symbol">${element.symbol}</div>
909
+ <div class="element-number">${element.number}</div>
910
+ `;
911
+ elementDiv.title = element.name;
912
+
913
+ elementDiv.addEventListener('click', () => {
914
+ if (compoundFormula) {
915
+ compoundFormula.value += element.symbol;
916
+ compoundFormula.focus();
917
+ }
918
+ });
919
+
920
+ periodicElements.appendChild(elementDiv);
921
+ });
922
+
923
+ // Molar mass calculation
924
+ const molarMasses = {
925
+ 'H': 1.008, 'He': 4.0026, 'Li': 6.94, 'Be': 9.0122, 'B': 10.81,
926
+ 'C': 12.011, 'N': 14.007, 'O': 15.999, 'F': 18.998, 'Ne': 20.180,
927
+ 'Na': 22.990, 'Mg': 24.305, 'Al': 26.982, 'Si': 28.085, 'P': 30.974,
928
+ 'S': 32.06, 'Cl': 35.45, 'Ar': 39.948, 'K': 39.098, 'Ca': 40.078,
929
+ 'Sc': 44.956, 'Ti': 47.867, 'V': 50.942, 'Cr': 51.996, 'Mn': 54.938,
930
+ 'Fe': 55.845, 'Co': 58.933, 'Ni': 58.693, 'Cu': 63.546, 'Zn': 65.38,
931
+ 'Ga': 69.723, 'Ge': 72.630, 'As': 74.922, 'Se': 78.971, 'Br': 79.904,
932
+ 'Kr': 83.798, 'Rb': 85.468, 'Sr': 87.62, 'Y': 88.906, 'Zr': 91.224,
933
+ 'Nb': 92.906, 'Mo': 95.95, 'Tc': 98, 'Ru': 101.07, 'Rh': 102.91,
934
+ 'Pd': 106.42, 'Ag': 107.87, 'Cd': 112.41, 'In': 114.82, 'Sn': 118.71,
935
+ 'Sb': 121.76, 'Te': 127.60, 'I': 126.90, 'Xe': 131.29, 'Cs': 132.91,
936
+ 'Ba': 137.33, 'La': 138.91, 'Ce': 140.12, 'Pr': 140.91, 'Nd': 144.24,
937
+ 'Pm': 145, 'Sm': 150.36, 'Eu': 151.96, 'Gd': 157.25, 'Tb': 158.93,
938
+ 'Dy': 162.50, 'Ho': 164.93, 'Er': 167.26, 'Tm': 168.93, 'Yb': 173.05,
939
+ 'Lu': 174.97, 'Hf': 178.49, 'Ta': 180.95, 'W': 183.84, 'Re': 186.21,
940
+ 'Os': 190.23, 'Ir': 192.22, 'Pt': 195.08, 'Au': 196.97, 'Hg': 200.59,
941
+ 'Tl': 204.38, 'Pb': 207.2, 'Bi': 208.98, 'Po': 209, 'At': 210, 'Rn': 222,
942
+ 'Fr': 223, 'Ra': 226, 'Ac': 227, 'Th': 232.04, 'Pa': 231.04, 'U': 238.03,
943
+ 'Np': 237, 'Pu': 244
944
+ };
945
+
946
+ document.getElementById('calculate-mass').addEventListener('click', calculateMolarMass);
947
+
948
+ function calculateMolarMass() {
949
+ const formula = document.getElementById('compound-formula').value.trim();
950
+ const massStr = document.getElementById('compound-mass').value;
951
+ const massUnit = document.getElementById('mass-unit').value;
952
+
953
+ if (!formula) {
954
+ alert('Please enter a chemical formula');
955
+ return;
956
+ }
957
+
958
+ try {
959
+ // Parse the chemical formula
960
+ const parsedFormula = parseFormula(formula);
961
+ let totalMass = 0;
962
+ let compositionHTML = '<div>Elemental Composition:</div><ul>';
963
+
964
+ // Calculate molar mass
965
+ for (const element in parsedFormula) {
966
+ const count = parsedFormula[element];
967
+ const elementMass = molarMasses[element] || 0;
968
+ totalMass += elementMass * count;
969
+
970
+ // Add to composition list
971
+ const elementObj = elements.find(e => e.symbol === element);
972
+ const percent = ((elementMass * count) / totalMass * 100).toFixed(2);
973
+ compositionHTML += `<li>${element} (${elementObj?.name || 'Unknown'}): ${count} atom${count > 1 ? 's' : ''} (${percent}%)</li>`;
974
+ }
975
+
976
+ compositionHTML += '</ul>';
977
+
978
+ // Display results
979
+ const resultDiv = document.getElementById('mass-result');
980
+ document.getElementById('mass-value').textContent = `Molar Mass: ${totalMass.toFixed(4)} g/mol`;
981
+
982
+ // Calculate moles if mass was provided
983
+ if (massStr) {
984
+ const mass = parseFloat(massStr);
985
+ let convertedMass = mass;
986
+
987
+ // Convert units if needed
988
+ switch(massUnit) {
989
+ case 'mg': convertedMass = mass / 1000; break;
990
+ case 'kg': convertedMass = mass * 1000; break;
991
+ }
992
+
993
+ const moles = convertedMass / totalMass;
994
+ document.getElementById('moles-value').textContent = `Moles: ${moles.toFixed(6)} mol`;
995
+ } else {
996
+ document.getElementById('moles-value').textContent = '';
997
+ }
998
+
999
+ document.getElementById('composition').innerHTML = compositionHTML;
1000
+ resultDiv.classList.add('show');
1001
+
1002
+ // Add to history
1003
+ addToHistory(`Calculated molar mass for ${formula}: ${totalMass.toFixed(4)} g/mol`);
1004
+ } catch (error) {
1005
+ alert('Error parsing formula: ' + error.message);
1006
+ }
1007
+ }
1008
+
1009
+ // Helper function to parse chemical formulas
1010
+ function parseFormula(formula) {
1011
+ const elements = {};
1012
+ let currentElement = '';
1013
+ let currentCount = 0;
1014
+ let i = 0;
1015
+
1016
+ while (i < formula.length) {
1017
+ const c = formula[i];
1018
+
1019
+ // Check for uppercase letter (new element)
1020
+ if (c === c.toUpperCase() && c !== c.toLowerCase()) {
1021
+ // If we have a current element, add it to the result
1022
+ if (currentElement) {
1023
+ elements[currentElement] = (elements[currentElement] || 0) + (currentCount || 1);
1024
+ }
1025
+
1026
+ // Start new element
1027
+ currentElement = c;
1028
+ i++;
1029
+
1030
+ // Check for lowercase letters (element symbol with 2 letters)
1031
+ while (i < formula.length && formula[i] === formula[i].toLowerCase() && formula[i] !== formula[i].toUpperCase()) {
1032
+ currentElement += formula[i];
1033
+ i++;
1034
+ }
1035
+
1036
+ currentCount = 0;
1037
+ }
1038
+ // Check for digits (count of atoms)
1039
+ else if (c >= '0' && c <= '9') {
1040
+ currentCount = currentCount * 10 + parseInt(c);
1041
+ i++;
1042
+ }
1043
+ // Check for parentheses (grouping)
1044
+ else if (c === '(') {
1045
+ // If we have a current element, add it to the result
1046
+ if (currentElement) {
1047
+ elements[currentElement] = (elements[currentElement] || 0) + (currentCount || 1);
1048
+ }
1049
+
1050
+ // Parse the group inside parentheses
1051
+ const groupEnd = findMatchingClosingParenthesis(formula, i);
1052
+ const groupContent = formula.substring(i + 1, groupEnd);
1053
+ const parsedGroup = parseFormula(groupContent);
1054
+
1055
+ // Parse the count after the group
1056
+ let groupCount = 0;
1057
+ let j = groupEnd + 1;
1058
+ while (j < formula.length && formula[j] >= '0' && formula[j] <= '9') {
1059
+ groupCount = groupCount * 10 + parseInt(formula[j]);
1060
+ j++;
1061
+ }
1062
+
1063
+ groupCount = groupCount || 1;
1064
+
1065
+ // Add all elements from the group to the result
1066
+ for (const element in parsedGroup) {
1067
+ elements[element] = (elements[element] || 0) + parsedGroup[element] * groupCount;
1068
+ }
1069
+
1070
+ i = j;
1071
+ currentElement = '';
1072
+ currentCount = 0;
1073
+ }
1074
+ else {
1075
+ throw new Error(`Invalid character in formula: ${c}`);
1076
+ }
1077
+ }
1078
+
1079
+ // Add the last element if it exists
1080
+ if (currentElement) {
1081
+ elements[currentElement] = (elements[currentElement] || 0) + (currentCount || 1);
1082
+ }
1083
+
1084
+ return elements;
1085
+ }
1086
+
1087
+ function findMatchingClosingParenthesis(str, pos) {
1088
+ let depth = 1;
1089
+ for (let i = pos + 1; i < str.length; i++) {
1090
+ if (str[i] === '(') depth++;
1091
+ else if (str[i] === ')') depth--;
1092
+
1093
+ if (depth === 0) return i;
1094
+ }
1095
+ throw new Error('No matching closing parenthesis found');
1096
+ }
1097
+
1098
+ // Concentration calculator
1099
+ const concTypeSelect = document.getElementById('concentration-type');
1100
+ concTypeSelect.addEventListener('change', updateConcInputs);
1101
+
1102
+ function updateConcInputs() {
1103
+ const type = concTypeSelect.value;
1104
+ const concInputs = document.getElementById('conc-inputs');
1105
+ const dilutionInputs = document.getElementById('dilution-inputs');
1106
+
1107
+ if (type === 'dilution') {
1108
+ concInputs.style.display = 'none';
1109
+ dilutionInputs.style.display = 'block';
1110
+ } else {
1111
+ concInputs.style.display = 'block';
1112
+ dilutionInputs.style.display = 'none';
1113
+ }
1114
+ }
1115
+
1116
+ document.getElementById('calculate-conc').addEventListener('click', calculateConcentration);
1117
+
1118
+ function calculateConcentration() {
1119
+ const type = concTypeSelect.value;
1120
+ const resultDiv = document.getElementById('conc-result');
1121
+
1122
+ try {
1123
+ if (type === 'dilution') {
1124
+ const initialConc = parseFloat(document.getElementById('initial-conc').value);
1125
+ const initialConcUnit = document.getElementById('initial-conc-unit').value;
1126
+ const initialVol = parseFloat(document.getElementById('initial-vol').value);
1127
+ const initialVolUnit = document.getElementById('initial-vol-unit').value;
1128
+
1129
+ if (!initialConc || !initialVol) {
1130
+ alert('Please enter both initial concentration and volume');
1131
+ return;
1132
+ }
1133
+
1134
+ // Convert units if needed
1135
+ let conc = initialConc;
1136
+ if (initialConcUnit === 'mM') conc = conc / 1000;
1137
+
1138
+ let vol = initialVol;
1139
+ if (initialVolUnit === 'mL') vol = vol / 1000;
1140
+
1141
+ // Calculate dilution (M1V1 = M2V2) assuming final volume is known
1142
+ // For simplicity, we'll calculate final concentration based on assuming final volume is known from dilution
1143
+ // In a real app, you'd want more detailed inputs
1144
+ const finalConc = (conc * vol) / (vol + vol); // Assuming doubling volume
1145
+
1146
+ document.getElementById('conc-value').innerHTML = `
1147
+ <div>Initial Concentration: ${initialConc} ${initialConcUnit}</div>
1148
+ <div>Final Concentration: ${finalConc.toFixed(6)} M</div
1149
+ </html>