@sciexpr/chemistry 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,448 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ELEMENT_BY_NUMBER: () => ELEMENT_BY_NUMBER,
24
+ ELEMENT_MAP: () => ELEMENT_MAP,
25
+ FormulaValidator: () => FormulaValidator,
26
+ OxidationCalculator: () => OxidationCalculator,
27
+ PERIODIC_TABLE: () => PERIODIC_TABLE,
28
+ ReactionBalancer: () => ReactionBalancer
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/periodic-table.ts
33
+ var PERIODIC_TABLE = [
34
+ // Period 1
35
+ { symbol: "H", atomicNumber: 1, atomicMass: 1.008, nameCN: "\u6C22", nameEN: "Hydrogen", group: 1, period: 1, block: "s", electronegativity: 2.2, oxidationStates: [1, -1], electronConfiguration: "1s\xB9" },
36
+ { symbol: "He", atomicNumber: 2, atomicMass: 4.0026, nameCN: "\u6C26", nameEN: "Helium", group: 18, period: 1, block: "s", electronConfiguration: "1s\xB2" },
37
+ // Period 2
38
+ { symbol: "Li", atomicNumber: 3, atomicMass: 6.94, nameCN: "\u9502", nameEN: "Lithium", group: 1, period: 2, block: "s", electronegativity: 0.98, oxidationStates: [1], electronConfiguration: "[He] 2s\xB9" },
39
+ { symbol: "Be", atomicNumber: 4, atomicMass: 9.0122, nameCN: "\u94CD", nameEN: "Beryllium", group: 2, period: 2, block: "s", electronegativity: 1.57, oxidationStates: [2], electronConfiguration: "[He] 2s\xB2" },
40
+ { symbol: "B", atomicNumber: 5, atomicMass: 10.81, nameCN: "\u787C", nameEN: "Boron", group: 13, period: 2, block: "p", electronegativity: 2.04, oxidationStates: [3], electronConfiguration: "[He] 2s\xB22p\xB9" },
41
+ { symbol: "C", atomicNumber: 6, atomicMass: 12.011, nameCN: "\u78B3", nameEN: "Carbon", group: 14, period: 2, block: "p", electronegativity: 2.55, oxidationStates: [4, 2, -4], electronConfiguration: "[He] 2s\xB22p\xB2", commonCompounds: ["CO2", "CH4", "C6H12O6"] },
42
+ { symbol: "N", atomicNumber: 7, atomicMass: 14.007, nameCN: "\u6C2E", nameEN: "Nitrogen", group: 15, period: 2, block: "p", electronegativity: 3.04, oxidationStates: [5, 3, -3], electronConfiguration: "[He] 2s\xB22p\xB3", commonCompounds: ["NH3", "HNO3", "N2"] },
43
+ { symbol: "O", atomicNumber: 8, atomicMass: 15.999, nameCN: "\u6C27", nameEN: "Oxygen", group: 16, period: 2, block: "p", electronegativity: 3.44, oxidationStates: [-2, -1], electronConfiguration: "[He] 2s\xB22p\u2074", commonCompounds: ["H2O", "CO2", "O2"] },
44
+ { symbol: "F", atomicNumber: 9, atomicMass: 18.998, nameCN: "\u6C1F", nameEN: "Fluorine", group: 17, period: 2, block: "p", electronegativity: 3.98, oxidationStates: [-1], electronConfiguration: "[He] 2s\xB22p\u2075", commonCompounds: ["HF", "NaF"] },
45
+ { symbol: "Ne", atomicNumber: 10, atomicMass: 20.18, nameCN: "\u6C16", nameEN: "Neon", group: 18, period: 2, block: "p", electronConfiguration: "[He] 2s\xB22p\u2076" },
46
+ // Period 3
47
+ { symbol: "Na", atomicNumber: 11, atomicMass: 22.99, nameCN: "\u94A0", nameEN: "Sodium", group: 1, period: 3, block: "s", electronegativity: 0.93, oxidationStates: [1], electronConfiguration: "[Ne] 3s\xB9", commonCompounds: ["NaCl", "NaOH", "Na2CO3"] },
48
+ { symbol: "Mg", atomicNumber: 12, atomicMass: 24.305, nameCN: "\u9541", nameEN: "Magnesium", group: 2, period: 3, block: "s", electronegativity: 1.31, oxidationStates: [2], electronConfiguration: "[Ne] 3s\xB2", commonCompounds: ["MgO", "MgCl2"] },
49
+ { symbol: "Al", atomicNumber: 13, atomicMass: 26.982, nameCN: "\u94DD", nameEN: "Aluminium", group: 13, period: 3, block: "p", electronegativity: 1.61, oxidationStates: [3], electronConfiguration: "[Ne] 3s\xB23p\xB9", commonCompounds: ["Al2O3", "AlCl3"] },
50
+ { symbol: "Si", atomicNumber: 14, atomicMass: 28.085, nameCN: "\u7845", nameEN: "Silicon", group: 14, period: 3, block: "p", electronegativity: 1.9, oxidationStates: [4], electronConfiguration: "[Ne] 3s\xB23p\xB2", commonCompounds: ["SiO2", "SiH4"] },
51
+ { symbol: "P", atomicNumber: 15, atomicMass: 30.974, nameCN: "\u78F7", nameEN: "Phosphorus", group: 15, period: 3, block: "p", electronegativity: 2.19, oxidationStates: [5, 3, -3], electronConfiguration: "[Ne] 3s\xB23p\xB3", commonCompounds: ["H3PO4", "P4"] },
52
+ { symbol: "S", atomicNumber: 16, atomicMass: 32.06, nameCN: "\u786B", nameEN: "Sulfur", group: 16, period: 3, block: "p", electronegativity: 2.58, oxidationStates: [6, 4, -2], electronConfiguration: "[Ne] 3s\xB23p\u2074", commonCompounds: ["H2SO4", "SO2", "H2S"] },
53
+ { symbol: "Cl", atomicNumber: 17, atomicMass: 35.45, nameCN: "\u6C2F", nameEN: "Chlorine", group: 17, period: 3, block: "p", electronegativity: 3.16, oxidationStates: [7, 5, 3, 1, -1], electronConfiguration: "[Ne] 3s\xB23p\u2075", commonCompounds: ["NaCl", "HCl", "Cl2"] },
54
+ { symbol: "Ar", atomicNumber: 18, atomicMass: 39.948, nameCN: "\u6C29", nameEN: "Argon", group: 18, period: 3, block: "p", electronConfiguration: "[Ne] 3s\xB23p\u2076" },
55
+ // Period 4
56
+ { symbol: "K", atomicNumber: 19, atomicMass: 39.098, nameCN: "\u94BE", nameEN: "Potassium", group: 1, period: 4, block: "s", electronegativity: 0.82, oxidationStates: [1], electronConfiguration: "[Ar] 4s\xB9", commonCompounds: ["KCl", "KNO3"] },
57
+ { symbol: "Ca", atomicNumber: 20, atomicMass: 40.078, nameCN: "\u9499", nameEN: "Calcium", group: 2, period: 4, block: "s", electronegativity: 1, oxidationStates: [2], electronConfiguration: "[Ar] 4s\xB2", commonCompounds: ["CaCO3", "CaO", "Ca(OH)2"] },
58
+ { symbol: "Sc", atomicNumber: 21, atomicMass: 44.956, nameCN: "\u94AA", nameEN: "Scandium", group: 3, period: 4, block: "d", electronegativity: 1.36, oxidationStates: [3], electronConfiguration: "[Ar] 3d\xB94s\xB2" },
59
+ { symbol: "Ti", atomicNumber: 22, atomicMass: 47.867, nameCN: "\u949B", nameEN: "Titanium", group: 4, period: 4, block: "d", electronegativity: 1.54, oxidationStates: [4, 3], electronConfiguration: "[Ar] 3d\xB24s\xB2", commonCompounds: ["TiO2"] },
60
+ { symbol: "V", atomicNumber: 23, atomicMass: 50.942, nameCN: "\u9492", nameEN: "Vanadium", group: 5, period: 4, block: "d", electronegativity: 1.63, oxidationStates: [5, 4, 3, 2], electronConfiguration: "[Ar] 3d\xB34s\xB2" },
61
+ { symbol: "Cr", atomicNumber: 24, atomicMass: 51.996, nameCN: "\u94EC", nameEN: "Chromium", group: 6, period: 4, block: "d", electronegativity: 1.66, oxidationStates: [6, 3, 2], electronConfiguration: "[Ar] 3d\u20754s\xB9", commonCompounds: ["K2Cr2O7", "Cr2O3"] },
62
+ { symbol: "Mn", atomicNumber: 25, atomicMass: 54.938, nameCN: "\u9530", nameEN: "Manganese", group: 7, period: 4, block: "d", electronegativity: 1.55, oxidationStates: [7, 4, 2], electronConfiguration: "[Ar] 3d\u20754s\xB2", commonCompounds: ["MnO2", "KMnO4"] },
63
+ { symbol: "Fe", atomicNumber: 26, atomicMass: 55.845, nameCN: "\u94C1", nameEN: "Iron", group: 8, period: 4, block: "d", electronegativity: 1.83, oxidationStates: [3, 2], electronConfiguration: "[Ar] 3d\u20764s\xB2", commonCompounds: ["Fe2O3", "Fe3O4", "FeSO4"] },
64
+ { symbol: "Co", atomicNumber: 27, atomicMass: 58.933, nameCN: "\u94B4", nameEN: "Cobalt", group: 9, period: 4, block: "d", electronegativity: 1.88, oxidationStates: [3, 2], electronConfiguration: "[Ar] 3d\u20774s\xB2" },
65
+ { symbol: "Ni", atomicNumber: 28, atomicMass: 58.693, nameCN: "\u954D", nameEN: "Nickel", group: 10, period: 4, block: "d", electronegativity: 1.91, oxidationStates: [2], electronConfiguration: "[Ar] 3d\u20784s\xB2", commonCompounds: ["Ni(CO)4"] },
66
+ { symbol: "Cu", atomicNumber: 29, atomicMass: 63.546, nameCN: "\u94DC", nameEN: "Copper", group: 11, period: 4, block: "d", electronegativity: 1.9, oxidationStates: [2, 1], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB9", commonCompounds: ["CuSO4", "CuO", "Cu2O"] },
67
+ { symbol: "Zn", atomicNumber: 30, atomicMass: 65.38, nameCN: "\u950C", nameEN: "Zinc", group: 12, period: 4, block: "d", electronegativity: 1.65, oxidationStates: [2], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB2", commonCompounds: ["ZnO", "ZnSO4"] },
68
+ { symbol: "Ga", atomicNumber: 31, atomicMass: 69.723, nameCN: "\u9553", nameEN: "Gallium", group: 13, period: 4, block: "p", electronegativity: 1.81, oxidationStates: [3], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\xB9" },
69
+ { symbol: "Ge", atomicNumber: 32, atomicMass: 72.63, nameCN: "\u9517", nameEN: "Germanium", group: 14, period: 4, block: "p", electronegativity: 2.01, oxidationStates: [4], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\xB2" },
70
+ { symbol: "As", atomicNumber: 33, atomicMass: 74.922, nameCN: "\u7837", nameEN: "Arsenic", group: 15, period: 4, block: "p", electronegativity: 2.18, oxidationStates: [5, 3, -3], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\xB3" },
71
+ { symbol: "Se", atomicNumber: 34, atomicMass: 78.971, nameCN: "\u7852", nameEN: "Selenium", group: 16, period: 4, block: "p", electronegativity: 2.55, oxidationStates: [6, 4, -2], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\u2074" },
72
+ { symbol: "Br", atomicNumber: 35, atomicMass: 79.904, nameCN: "\u6EB4", nameEN: "Bromine", group: 17, period: 4, block: "p", electronegativity: 2.96, oxidationStates: [7, 5, 1, -1], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\u2075", commonCompounds: ["NaBr", "HBr"] },
73
+ { symbol: "Kr", atomicNumber: 36, atomicMass: 83.798, nameCN: "\u6C2A", nameEN: "Krypton", group: 18, period: 4, block: "p", electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\u2076" },
74
+ // Period 5
75
+ { symbol: "Rb", atomicNumber: 37, atomicMass: 85.468, nameCN: "\u94F7", nameEN: "Rubidium", group: 1, period: 5, block: "s", electronegativity: 0.82, oxidationStates: [1], electronConfiguration: "[Kr] 5s\xB9" },
76
+ { symbol: "Sr", atomicNumber: 38, atomicMass: 87.62, nameCN: "\u9536", nameEN: "Strontium", group: 2, period: 5, block: "s", electronegativity: 0.95, oxidationStates: [2], electronConfiguration: "[Kr] 5s\xB2" },
77
+ { symbol: "Y", atomicNumber: 39, atomicMass: 88.906, nameCN: "\u9487", nameEN: "Yttrium", group: 3, period: 5, block: "d", electronegativity: 1.22, oxidationStates: [3], electronConfiguration: "[Kr] 4d\xB95s\xB2" },
78
+ { symbol: "Zr", atomicNumber: 40, atomicMass: 91.224, nameCN: "\u9506", nameEN: "Zirconium", group: 4, period: 5, block: "d", electronegativity: 1.33, oxidationStates: [4], electronConfiguration: "[Kr] 4d\xB25s\xB2" },
79
+ { symbol: "Nb", atomicNumber: 41, atomicMass: 92.906, nameCN: "\u94CC", nameEN: "Niobium", group: 5, period: 5, block: "d", electronegativity: 1.6, oxidationStates: [5], electronConfiguration: "[Kr] 4d\u20745s\xB9" },
80
+ { symbol: "Mo", atomicNumber: 42, atomicMass: 95.95, nameCN: "\u94BC", nameEN: "Molybdenum", group: 6, period: 5, block: "d", electronegativity: 2.16, oxidationStates: [6], electronConfiguration: "[Kr] 4d\u20755s\xB9" },
81
+ { symbol: "Tc", atomicNumber: 43, atomicMass: 98, nameCN: "\u951D", nameEN: "Technetium", group: 7, period: 5, block: "d", electronegativity: 1.9, oxidationStates: [7], electronConfiguration: "[Kr] 4d\u20755s\xB2" },
82
+ { symbol: "Ru", atomicNumber: 44, atomicMass: 101.07, nameCN: "\u948C", nameEN: "Ruthenium", group: 8, period: 5, block: "d", electronegativity: 2.2, oxidationStates: [4, 3], electronConfiguration: "[Kr] 4d\u20775s\xB9" },
83
+ { symbol: "Rh", atomicNumber: 45, atomicMass: 102.91, nameCN: "\u94D1", nameEN: "Rhodium", group: 9, period: 5, block: "d", electronegativity: 2.28, oxidationStates: [3], electronConfiguration: "[Kr] 4d\u20785s\xB9" },
84
+ { symbol: "Pd", atomicNumber: 46, atomicMass: 106.42, nameCN: "\u94AF", nameEN: "Palladium", group: 10, period: 5, block: "d", electronegativity: 2.2, oxidationStates: [2], electronConfiguration: "[Kr] 4d\xB9\u2070" },
85
+ { symbol: "Ag", atomicNumber: 47, atomicMass: 107.87, nameCN: "\u94F6", nameEN: "Silver", group: 11, period: 5, block: "d", electronegativity: 1.93, oxidationStates: [1], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB9", commonCompounds: ["AgNO3", "AgCl"] },
86
+ { symbol: "Cd", atomicNumber: 48, atomicMass: 112.41, nameCN: "\u9549", nameEN: "Cadmium", group: 12, period: 5, block: "d", electronegativity: 1.69, oxidationStates: [2], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB2" },
87
+ { symbol: "In", atomicNumber: 49, atomicMass: 114.82, nameCN: "\u94DF", nameEN: "Indium", group: 13, period: 5, block: "p", electronegativity: 1.78, oxidationStates: [3], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\xB9" },
88
+ { symbol: "Sn", atomicNumber: 50, atomicMass: 118.71, nameCN: "\u9521", nameEN: "Tin", group: 14, period: 5, block: "p", electronegativity: 1.96, oxidationStates: [4, 2], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\xB2" },
89
+ { symbol: "Sb", atomicNumber: 51, atomicMass: 121.76, nameCN: "\u9511", nameEN: "Antimony", group: 15, period: 5, block: "p", electronegativity: 2.05, oxidationStates: [5, 3], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\xB3" },
90
+ { symbol: "Te", atomicNumber: 52, atomicMass: 127.6, nameCN: "\u78B2", nameEN: "Tellurium", group: 16, period: 5, block: "p", electronegativity: 2.1, oxidationStates: [6, 4, -2], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\u2074" },
91
+ { symbol: "I", atomicNumber: 53, atomicMass: 126.9, nameCN: "\u7898", nameEN: "Iodine", group: 17, period: 5, block: "p", electronegativity: 2.66, oxidationStates: [7, 5, 1, -1], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\u2075", commonCompounds: ["KI", "I2"] },
92
+ { symbol: "Xe", atomicNumber: 54, atomicMass: 131.29, nameCN: "\u6C19", nameEN: "Xenon", group: 18, period: 5, block: "p", electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\u2076" },
93
+ // Period 6
94
+ { symbol: "Cs", atomicNumber: 55, atomicMass: 132.91, nameCN: "\u94EF", nameEN: "Cesium", group: 1, period: 6, block: "s", electronegativity: 0.79, oxidationStates: [1], electronConfiguration: "[Xe] 6s\xB9" },
95
+ { symbol: "Ba", atomicNumber: 56, atomicMass: 137.33, nameCN: "\u94A1", nameEN: "Barium", group: 2, period: 6, block: "s", electronegativity: 0.89, oxidationStates: [2], electronConfiguration: "[Xe] 6s\xB2", commonCompounds: ["BaSO4"] },
96
+ { symbol: "La", atomicNumber: 57, atomicMass: 138.91, nameCN: "\u9567", nameEN: "Lanthanum", group: 3, period: 6, block: "f", electronegativity: 1.1, oxidationStates: [3], electronConfiguration: "[Xe] 5d\xB96s\xB2" },
97
+ { symbol: "Ce", atomicNumber: 58, atomicMass: 140.12, nameCN: "\u94C8", nameEN: "Cerium", group: 3, period: 6, block: "f", electronegativity: 1.12, oxidationStates: [4, 3], electronConfiguration: "[Xe] 4f\xB95d\xB96s\xB2" },
98
+ { symbol: "Pr", atomicNumber: 59, atomicMass: 140.91, nameCN: "\u9568", nameEN: "Praseodymium", group: 3, period: 6, block: "f", electronegativity: 1.13, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB36s\xB2" },
99
+ { symbol: "Nd", atomicNumber: 60, atomicMass: 144.24, nameCN: "\u9495", nameEN: "Neodymium", group: 3, period: 6, block: "f", electronegativity: 1.14, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20746s\xB2" },
100
+ { symbol: "Pm", atomicNumber: 61, atomicMass: 145, nameCN: "\u94B7", nameEN: "Promethium", group: 3, period: 6, block: "f", electronegativity: 1.13, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20756s\xB2" },
101
+ { symbol: "Sm", atomicNumber: 62, atomicMass: 150.36, nameCN: "\u9490", nameEN: "Samarium", group: 3, period: 6, block: "f", electronegativity: 1.17, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20766s\xB2" },
102
+ { symbol: "Eu", atomicNumber: 63, atomicMass: 151.96, nameCN: "\u94D5", nameEN: "Europium", group: 3, period: 6, block: "f", electronegativity: 1.2, oxidationStates: [3, 2], electronConfiguration: "[Xe] 4f\u20776s\xB2" },
103
+ { symbol: "Gd", atomicNumber: 64, atomicMass: 157.25, nameCN: "\u9486", nameEN: "Gadolinium", group: 3, period: 6, block: "f", electronegativity: 1.2, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20775d\xB96s\xB2" },
104
+ { symbol: "Tb", atomicNumber: 65, atomicMass: 158.93, nameCN: "\u94FD", nameEN: "Terbium", group: 3, period: 6, block: "f", electronegativity: 1.2, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20796s\xB2" },
105
+ { symbol: "Dy", atomicNumber: 66, atomicMass: 162.5, nameCN: "\u955D", nameEN: "Dysprosium", group: 3, period: 6, block: "f", electronegativity: 1.22, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\u20706s\xB2" },
106
+ { symbol: "Ho", atomicNumber: 67, atomicMass: 164.93, nameCN: "\u94AC", nameEN: "Holmium", group: 3, period: 6, block: "f", electronegativity: 1.23, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\xB96s\xB2" },
107
+ { symbol: "Er", atomicNumber: 68, atomicMass: 167.26, nameCN: "\u94D2", nameEN: "Erbium", group: 3, period: 6, block: "f", electronegativity: 1.24, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\xB26s\xB2" },
108
+ { symbol: "Tm", atomicNumber: 69, atomicMass: 168.93, nameCN: "\u94E5", nameEN: "Thulium", group: 3, period: 6, block: "f", electronegativity: 1.25, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\xB36s\xB2" },
109
+ { symbol: "Yb", atomicNumber: 70, atomicMass: 173.05, nameCN: "\u9571", nameEN: "Ytterbium", group: 3, period: 6, block: "f", electronegativity: 1.1, oxidationStates: [3, 2], electronConfiguration: "[Xe] 4f\xB9\u20746s\xB2" },
110
+ { symbol: "Lu", atomicNumber: 71, atomicMass: 174.97, nameCN: "\u9565", nameEN: "Lutetium", group: 3, period: 6, block: "d", electronegativity: 1.27, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB96s\xB2" },
111
+ { symbol: "Hf", atomicNumber: 72, atomicMass: 178.49, nameCN: "\u94EA", nameEN: "Hafnium", group: 4, period: 6, block: "d", electronegativity: 1.3, oxidationStates: [4], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB26s\xB2" },
112
+ { symbol: "Ta", atomicNumber: 73, atomicMass: 180.95, nameCN: "\u94BD", nameEN: "Tantalum", group: 5, period: 6, block: "d", electronegativity: 1.5, oxidationStates: [5], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB36s\xB2" },
113
+ { symbol: "W", atomicNumber: 74, atomicMass: 183.84, nameCN: "\u94A8", nameEN: "Tungsten", group: 6, period: 6, block: "d", electronegativity: 2.36, oxidationStates: [6], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20746s\xB2" },
114
+ { symbol: "Re", atomicNumber: 75, atomicMass: 186.21, nameCN: "\u94FC", nameEN: "Rhenium", group: 7, period: 6, block: "d", electronegativity: 1.9, oxidationStates: [7, 4], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20756s\xB2" },
115
+ { symbol: "Os", atomicNumber: 76, atomicMass: 190.23, nameCN: "\u9507", nameEN: "Osmium", group: 8, period: 6, block: "d", electronegativity: 2.2, oxidationStates: [4], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20766s\xB2" },
116
+ { symbol: "Ir", atomicNumber: 77, atomicMass: 192.22, nameCN: "\u94F1", nameEN: "Iridium", group: 9, period: 6, block: "d", electronegativity: 2.2, oxidationStates: [4, 3], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20776s\xB2" },
117
+ { symbol: "Pt", atomicNumber: 78, atomicMass: 195.08, nameCN: "\u94C2", nameEN: "Platinum", group: 10, period: 6, block: "d", electronegativity: 2.28, oxidationStates: [4, 2], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20796s\xB9" },
118
+ { symbol: "Au", atomicNumber: 79, atomicMass: 196.97, nameCN: "\u91D1", nameEN: "Gold", group: 11, period: 6, block: "d", electronegativity: 2.54, oxidationStates: [3, 1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB9" },
119
+ { symbol: "Hg", atomicNumber: 80, atomicMass: 200.59, nameCN: "\u6C5E", nameEN: "Mercury", group: 12, period: 6, block: "d", electronegativity: 2, oxidationStates: [2, 1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB2" },
120
+ { symbol: "Tl", atomicNumber: 81, atomicMass: 204.38, nameCN: "\u94CA", nameEN: "Thallium", group: 13, period: 6, block: "p", electronegativity: 1.62, oxidationStates: [3, 1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\xB9" },
121
+ { symbol: "Pb", atomicNumber: 82, atomicMass: 207.2, nameCN: "\u94C5", nameEN: "Lead", group: 14, period: 6, block: "p", electronegativity: 2.33, oxidationStates: [4, 2], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\xB2", commonCompounds: ["PbO", "PbO2"] },
122
+ { symbol: "Bi", atomicNumber: 83, atomicMass: 208.98, nameCN: "\u94CB", nameEN: "Bismuth", group: 15, period: 6, block: "p", electronegativity: 2.02, oxidationStates: [5, 3], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\xB3" },
123
+ { symbol: "Po", atomicNumber: 84, atomicMass: 209, nameCN: "\u948B", nameEN: "Polonium", group: 16, period: 6, block: "p", electronegativity: 2, oxidationStates: [4, 2], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\u2074" },
124
+ { symbol: "At", atomicNumber: 85, atomicMass: 210, nameCN: "\u7839", nameEN: "Astatine", group: 17, period: 6, block: "p", electronegativity: 2.2, oxidationStates: [7, 5, 3, 1, -1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\u2075" },
125
+ { symbol: "Rn", atomicNumber: 86, atomicMass: 222, nameCN: "\u6C21", nameEN: "Radon", group: 18, period: 6, block: "p", electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\u2076" },
126
+ // Period 7
127
+ { symbol: "Fr", atomicNumber: 87, atomicMass: 223, nameCN: "\u94AB", nameEN: "Francium", group: 1, period: 7, block: "s", electronegativity: 0.7, oxidationStates: [1], electronConfiguration: "[Rn] 7s\xB9" },
128
+ { symbol: "Ra", atomicNumber: 88, atomicMass: 226, nameCN: "\u956D", nameEN: "Radium", group: 2, period: 7, block: "s", electronegativity: 0.9, oxidationStates: [2], electronConfiguration: "[Rn] 7s\xB2" },
129
+ { symbol: "Ac", atomicNumber: 89, atomicMass: 227, nameCN: "\u9515", nameEN: "Actinium", group: 3, period: 7, block: "f", electronegativity: 1.1, oxidationStates: [3], electronConfiguration: "[Rn] 6d\xB97s\xB2" },
130
+ { symbol: "Th", atomicNumber: 90, atomicMass: 232.04, nameCN: "\u948D", nameEN: "Thorium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [4], electronConfiguration: "[Rn] 6d\xB27s\xB2" },
131
+ { symbol: "Pa", atomicNumber: 91, atomicMass: 231.04, nameCN: "\u9564", nameEN: "Protactinium", group: 3, period: 7, block: "f", electronegativity: 1.5, oxidationStates: [5], electronConfiguration: "[Rn] 5f\xB26d\xB97s\xB2" },
132
+ { symbol: "U", atomicNumber: 92, atomicMass: 238.03, nameCN: "\u94C0", nameEN: "Uranium", group: 3, period: 7, block: "f", electronegativity: 1.38, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\xB36d\xB97s\xB2", commonCompounds: ["UO2", "UF6"] },
133
+ { symbol: "Np", atomicNumber: 93, atomicMass: 237, nameCN: "\u954E", nameEN: "Neptunium", group: 3, period: 7, block: "f", electronegativity: 1.36, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\u20746d\xB97s\xB2" },
134
+ { symbol: "Pu", atomicNumber: 94, atomicMass: 244, nameCN: "\u949A", nameEN: "Plutonium", group: 3, period: 7, block: "f", electronegativity: 1.28, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\u20767s\xB2" },
135
+ { symbol: "Am", atomicNumber: 95, atomicMass: 243, nameCN: "\u9545", nameEN: "Americium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\u20777s\xB2" },
136
+ { symbol: "Cm", atomicNumber: 96, atomicMass: 247, nameCN: "\u9514", nameEN: "Curium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\u20776d\xB97s\xB2" },
137
+ { symbol: "Bk", atomicNumber: 97, atomicMass: 247, nameCN: "\u952B", nameEN: "Berkelium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [4, 3], electronConfiguration: "[Rn] 5f\u20797s\xB2" },
138
+ { symbol: "Cf", atomicNumber: 98, atomicMass: 251, nameCN: "\u950E", nameEN: "Californium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\u20707s\xB2" },
139
+ { symbol: "Es", atomicNumber: 99, atomicMass: 252, nameCN: "\u953F", nameEN: "Einsteinium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\xB97s\xB2" },
140
+ { symbol: "Fm", atomicNumber: 100, atomicMass: 257, nameCN: "\u9544", nameEN: "Fermium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\xB27s\xB2" },
141
+ { symbol: "Md", atomicNumber: 101, atomicMass: 258, nameCN: "\u9494", nameEN: "Mendelevium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\xB37s\xB2" },
142
+ { symbol: "No", atomicNumber: 102, atomicMass: 259, nameCN: "\u9518", nameEN: "Nobelium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [2], electronConfiguration: "[Rn] 5f\xB9\u20747s\xB2" },
143
+ { symbol: "Lr", atomicNumber: 103, atomicMass: 266, nameCN: "\u94F9", nameEN: "Lawrencium", group: 3, period: 7, block: "d", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\u20747s\xB27p\xB9" },
144
+ { symbol: "Rf", atomicNumber: 104, atomicMass: 267, nameCN: "\u{2CB3B}", nameEN: "Rutherfordium", group: 4, period: 7, block: "d", oxidationStates: [4], electronConfiguration: "[Rn] 5f\xB9\u20746d\xB27s\xB2" },
145
+ { symbol: "Db", atomicNumber: 105, atomicMass: 268, nameCN: "\u{2CB4A}", nameEN: "Dubnium", group: 5, period: 7, block: "d", oxidationStates: [5], electronConfiguration: "[Rn] 5f\xB9\u20746d\xB37s\xB2" },
146
+ { symbol: "Sg", atomicNumber: 106, atomicMass: 269, nameCN: "\u{2CB73}", nameEN: "Seaborgium", group: 6, period: 7, block: "d", oxidationStates: [6], electronConfiguration: "[Rn] 5f\xB9\u20746d\u20747s\xB2" },
147
+ { symbol: "Bh", atomicNumber: 107, atomicMass: 270, nameCN: "\u{2CB5B}", nameEN: "Bohrium", group: 7, period: 7, block: "d", oxidationStates: [7], electronConfiguration: "[Rn] 5f\xB9\u20746d\u20757s\xB2" },
148
+ { symbol: "Hs", atomicNumber: 108, atomicMass: 269, nameCN: "\u{2CB76}", nameEN: "Hassium", group: 8, period: 7, block: "d", oxidationStates: [8], electronConfiguration: "[Rn] 5f\xB9\u20746d\u20767s\xB2" },
149
+ { symbol: "Mt", atomicNumber: 109, atomicMass: 278, nameCN: "\u9FCF", nameEN: "Meitnerium", group: 9, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\u20777s\xB2" },
150
+ { symbol: "Ds", atomicNumber: 110, atomicMass: 281, nameCN: "\u{2B7FC}", nameEN: "Darmstadtium", group: 10, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\u20797s\xB9" },
151
+ { symbol: "Rg", atomicNumber: 111, atomicMass: 282, nameCN: "\u{2CB2D}", nameEN: "Roentgenium", group: 11, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB9" },
152
+ { symbol: "Cn", atomicNumber: 112, atomicMass: 285, nameCN: "\u9FD4", nameEN: "Copernicium", group: 12, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB2" },
153
+ { symbol: "Nh", atomicNumber: 113, atomicMass: 286, nameCN: "\u9FED", nameEN: "Nihonium", group: 13, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\xB9" },
154
+ { symbol: "Fl", atomicNumber: 114, atomicMass: 289, nameCN: "\u{2B4E7}", nameEN: "Flerovium", group: 14, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\xB2" },
155
+ { symbol: "Mc", atomicNumber: 115, atomicMass: 290, nameCN: "\u9546", nameEN: "Moscovium", group: 15, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\xB3" },
156
+ { symbol: "Lv", atomicNumber: 116, atomicMass: 293, nameCN: "\u{2B7F7}", nameEN: "Livermorium", group: 16, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\u2074" },
157
+ { symbol: "Ts", atomicNumber: 117, atomicMass: 294, nameCN: "\u9FEC", nameEN: "Tennessine", group: 17, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\u2075" },
158
+ { symbol: "Og", atomicNumber: 118, atomicMass: 294, nameCN: "\u9FEB", nameEN: "Oganesson", group: 18, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\u2076" }
159
+ ];
160
+ var ELEMENT_MAP = /* @__PURE__ */ new Map();
161
+ for (const el of PERIODIC_TABLE) {
162
+ ELEMENT_MAP.set(el.symbol.toLowerCase(), el);
163
+ }
164
+ var ELEMENT_BY_NUMBER = /* @__PURE__ */ new Map();
165
+ for (const el of PERIODIC_TABLE) {
166
+ ELEMENT_BY_NUMBER.set(el.atomicNumber, el);
167
+ }
168
+
169
+ // src/validator.ts
170
+ var FormulaValidator = class {
171
+ /**
172
+ * 验证化学元素符号是否有效
173
+ */
174
+ isValidSymbol(symbol) {
175
+ return ELEMENT_MAP.has(symbol.toLowerCase());
176
+ }
177
+ /**
178
+ * 获取元素信息
179
+ */
180
+ getElement(symbol) {
181
+ return ELEMENT_MAP.get(symbol.toLowerCase());
182
+ }
183
+ /**
184
+ * 验证 AST 节点是否为有效化学式
185
+ */
186
+ validate(node) {
187
+ const errors = [];
188
+ const warnings = [];
189
+ this.validateNode(node, errors, warnings);
190
+ return {
191
+ valid: errors.length === 0,
192
+ errors,
193
+ warnings
194
+ };
195
+ }
196
+ validateNode(node, errors, warnings) {
197
+ switch (node.kind) {
198
+ case "root":
199
+ for (const child of node.children) {
200
+ this.validateNode(child, errors, warnings);
201
+ }
202
+ break;
203
+ case "chem-element": {
204
+ const el = node;
205
+ if (!ELEMENT_MAP.has(el.symbol.toLowerCase())) {
206
+ errors.push({
207
+ code: "INVALID_ELEMENT",
208
+ message: `Unknown element symbol: ${el.symbol}`,
209
+ node
210
+ });
211
+ }
212
+ break;
213
+ }
214
+ case "chem-group": {
215
+ const group = node;
216
+ for (const atom of group.atoms) {
217
+ this.validateNode(atom, errors, warnings);
218
+ }
219
+ break;
220
+ }
221
+ case "chem-bond": {
222
+ const bond = node;
223
+ this.validateNode(bond.left, errors, warnings);
224
+ this.validateNode(bond.right, errors, warnings);
225
+ break;
226
+ }
227
+ case "chem-reaction": {
228
+ const reaction = node;
229
+ for (const r of reaction.reactants) {
230
+ this.validateNode(r, errors, warnings);
231
+ }
232
+ for (const p of reaction.products) {
233
+ this.validateNode(p, errors, warnings);
234
+ }
235
+ break;
236
+ }
237
+ }
238
+ }
239
+ /**
240
+ * 解析化学式文本并验证
241
+ * @param formula 化学式文本(如 "H2SO4", "NaOH", "Ca(OH)2")
242
+ */
243
+ validateText(formula) {
244
+ const errors = [];
245
+ const warnings = [];
246
+ let i = 0;
247
+ while (i < formula.length) {
248
+ const ch = formula[i];
249
+ if (/[A-Z]/.test(ch)) {
250
+ let symbol = ch;
251
+ i++;
252
+ while (i < formula.length && /[a-z]/.test(formula[i])) {
253
+ symbol += formula[i];
254
+ i++;
255
+ }
256
+ if (!ELEMENT_MAP.has(symbol.toLowerCase())) {
257
+ errors.push({
258
+ code: "INVALID_ELEMENT",
259
+ message: `Unknown element symbol: ${symbol}`
260
+ });
261
+ }
262
+ while (i < formula.length && /[0-9]/.test(formula[i])) i++;
263
+ continue;
264
+ }
265
+ if (ch === "(") {
266
+ let depth = 1;
267
+ i++;
268
+ while (i < formula.length && depth > 0) {
269
+ if (formula[i] === "(") depth++;
270
+ else if (formula[i] === ")") depth--;
271
+ i++;
272
+ }
273
+ if (depth !== 0) {
274
+ errors.push({
275
+ code: "UNBALANCED_PAREN",
276
+ message: "Unbalanced parentheses in formula"
277
+ });
278
+ }
279
+ continue;
280
+ }
281
+ i++;
282
+ }
283
+ return { valid: errors.length === 0, errors, warnings };
284
+ }
285
+ };
286
+
287
+ // src/balancer.ts
288
+ var ReactionBalancer = class {
289
+ /**
290
+ * 检查化学方程式元素守恒
291
+ * @param reactants 反应物(化学式文本数组)
292
+ * @param products 生成物(化学式文本数组)
293
+ */
294
+ checkConservation(reactants, products) {
295
+ const reactantsCount = this.countElements(reactants);
296
+ const productsCount = this.countElements(products);
297
+ const allElements = /* @__PURE__ */ new Set([
298
+ ...reactantsCount.keys(),
299
+ ...productsCount.keys()
300
+ ]);
301
+ const imbalances = [];
302
+ for (const symbol of allElements) {
303
+ const reactantCount = reactantsCount.get(symbol) ?? 0;
304
+ const productCount = productsCount.get(symbol) ?? 0;
305
+ if (reactantCount !== productCount) {
306
+ imbalances.push({
307
+ symbol,
308
+ reactantCount,
309
+ productCount,
310
+ difference: productCount - reactantCount
311
+ });
312
+ }
313
+ }
314
+ return {
315
+ balanced: imbalances.length === 0,
316
+ reactantsCount: Object.fromEntries(reactantsCount),
317
+ productsCount: Object.fromEntries(productsCount),
318
+ imbalances
319
+ };
320
+ }
321
+ /**
322
+ * 计算化学式中各元素的原子数
323
+ */
324
+ countElements(formulas) {
325
+ const total = /* @__PURE__ */ new Map();
326
+ for (const formula of formulas) {
327
+ const count = this.parseFormula(formula);
328
+ for (const [symbol, n] of count) {
329
+ total.set(symbol, (total.get(symbol) ?? 0) + n);
330
+ }
331
+ }
332
+ return total;
333
+ }
334
+ /**
335
+ * 解析化学式,返回元素计数
336
+ */
337
+ parseFormula(formula) {
338
+ const result = /* @__PURE__ */ new Map();
339
+ let coefficient = 1;
340
+ let i = 0;
341
+ if (/^[0-9]/.test(formula)) {
342
+ let coeff = "";
343
+ while (i < formula.length && /[0-9]/.test(formula[i])) {
344
+ coeff += formula[i];
345
+ i++;
346
+ }
347
+ coefficient = parseInt(coeff, 10) || 1;
348
+ }
349
+ this.parseFormulaPart(formula.slice(i), (symbol, count) => {
350
+ result.set(symbol, (result.get(symbol) ?? 0) + count * coefficient);
351
+ });
352
+ return result;
353
+ }
354
+ parseFormulaPart(formula, callback) {
355
+ let i = 0;
356
+ while (i < formula.length) {
357
+ const ch = formula[i];
358
+ if (/[A-Z]/.test(ch)) {
359
+ let symbol = ch;
360
+ i++;
361
+ while (i < formula.length && /[a-z]/.test(formula[i])) {
362
+ symbol += formula[i];
363
+ i++;
364
+ }
365
+ let count = 1;
366
+ if (i < formula.length && /[0-9]/.test(formula[i])) {
367
+ let numStr = "";
368
+ while (i < formula.length && /[0-9]/.test(formula[i])) {
369
+ numStr += formula[i];
370
+ i++;
371
+ }
372
+ count = parseInt(numStr, 10);
373
+ }
374
+ callback(symbol, count);
375
+ continue;
376
+ }
377
+ if (ch === "(") {
378
+ i++;
379
+ const start = i;
380
+ let depth = 1;
381
+ while (i < formula.length && depth > 0) {
382
+ if (formula[i] === "(") depth++;
383
+ else if (formula[i] === ")") depth--;
384
+ if (depth > 0) i++;
385
+ }
386
+ const groupContent = formula.slice(start, i);
387
+ i++;
388
+ let groupCount = 1;
389
+ if (i < formula.length && /[0-9]/.test(formula[i])) {
390
+ let numStr = "";
391
+ while (i < formula.length && /[0-9]/.test(formula[i])) {
392
+ numStr += formula[i];
393
+ i++;
394
+ }
395
+ groupCount = parseInt(numStr, 10);
396
+ }
397
+ this.parseFormulaPart(groupContent, (symbol, count) => {
398
+ callback(symbol, count * groupCount);
399
+ });
400
+ continue;
401
+ }
402
+ i++;
403
+ }
404
+ }
405
+ };
406
+ var OxidationCalculator = class {
407
+ /**
408
+ * 获取元素的常见氧化态
409
+ */
410
+ getOxidationStates(symbol) {
411
+ const el = ELEMENT_MAP.get(symbol.toLowerCase());
412
+ return el?.oxidationStates ?? [];
413
+ }
414
+ /**
415
+ * 判断元素是否为金属
416
+ */
417
+ isMetal(symbol) {
418
+ const el = ELEMENT_MAP.get(symbol.toLowerCase());
419
+ if (!el) return false;
420
+ if (el.block === "p") {
421
+ return ["Al", "Ga", "In", "Tl", "Sn", "Pb", "Bi", "Po"].includes(el.symbol);
422
+ }
423
+ return el.symbol !== "H" && el.symbol !== "He";
424
+ }
425
+ /**
426
+ * 判断元素是否为非金属
427
+ */
428
+ isNonMetal(symbol) {
429
+ const el = ELEMENT_MAP.get(symbol.toLowerCase());
430
+ if (!el) return false;
431
+ return el.block === "p" && !this.isMetal(symbol);
432
+ }
433
+ /**
434
+ * 获取电负性
435
+ */
436
+ getElectronegativity(symbol) {
437
+ return ELEMENT_MAP.get(symbol.toLowerCase())?.electronegativity;
438
+ }
439
+ };
440
+ // Annotate the CommonJS export names for ESM import in node:
441
+ 0 && (module.exports = {
442
+ ELEMENT_BY_NUMBER,
443
+ ELEMENT_MAP,
444
+ FormulaValidator,
445
+ OxidationCalculator,
446
+ PERIODIC_TABLE,
447
+ ReactionBalancer
448
+ });
@@ -0,0 +1,134 @@
1
+ import { ExpressionNode } from '@sciexpr/core';
2
+
3
+ /** 元素完整信息 */
4
+ interface ElementData {
5
+ /** 元素符号 (H, He, Na, ...) */
6
+ symbol: string;
7
+ /** 原子序数 */
8
+ atomicNumber: number;
9
+ /** 相对原子质量 */
10
+ atomicMass: number;
11
+ /** 中文名 */
12
+ nameCN: string;
13
+ /** 英文名 */
14
+ nameEN: string;
15
+ /** 族 */
16
+ group: number;
17
+ /** 周期 */
18
+ period: number;
19
+ /** 区块 */
20
+ block: 's' | 'p' | 'd' | 'f';
21
+ /** 电负性 (Pauling) */
22
+ electronegativity?: number;
23
+ /** 常见氧化态 */
24
+ oxidationStates?: number[];
25
+ /** 电子排布 */
26
+ electronConfiguration?: string;
27
+ /** 常见化合物 */
28
+ commonCompounds?: string[];
29
+ }
30
+ /** 完整 118 元素周期表 */
31
+ declare const PERIODIC_TABLE: ElementData[];
32
+ /** 按符号索引的元素 Map */
33
+ declare const ELEMENT_MAP: Map<string, ElementData>;
34
+ /** 按原子序数索引的元素 Map */
35
+ declare const ELEMENT_BY_NUMBER: Map<number, ElementData>;
36
+
37
+ /**
38
+ * 化学式验证器
39
+ */
40
+ declare class FormulaValidator {
41
+ /**
42
+ * 验证化学元素符号是否有效
43
+ */
44
+ isValidSymbol(symbol: string): boolean;
45
+ /**
46
+ * 获取元素信息
47
+ */
48
+ getElement(symbol: string): ElementData | undefined;
49
+ /**
50
+ * 验证 AST 节点是否为有效化学式
51
+ */
52
+ validate(node: ExpressionNode): FormulaValidationResult;
53
+ private validateNode;
54
+ /**
55
+ * 解析化学式文本并验证
56
+ * @param formula 化学式文本(如 "H2SO4", "NaOH", "Ca(OH)2")
57
+ */
58
+ validateText(formula: string): FormulaValidationResult;
59
+ }
60
+ /** 验证结果 */
61
+ interface FormulaValidationResult {
62
+ valid: boolean;
63
+ errors: FormulaError[];
64
+ warnings: FormulaWarning[];
65
+ }
66
+ /** 验证错误 */
67
+ interface FormulaError {
68
+ code: string;
69
+ message: string;
70
+ node?: ExpressionNode;
71
+ }
72
+ /** 验证警告 */
73
+ interface FormulaWarning {
74
+ code: string;
75
+ message: string;
76
+ }
77
+
78
+ /**
79
+ * 化学反应式平衡检查器
80
+ */
81
+ declare class ReactionBalancer {
82
+ /**
83
+ * 检查化学方程式元素守恒
84
+ * @param reactants 反应物(化学式文本数组)
85
+ * @param products 生成物(化学式文本数组)
86
+ */
87
+ checkConservation(reactants: string[], products: string[]): BalanceResult;
88
+ /**
89
+ * 计算化学式中各元素的原子数
90
+ */
91
+ private countElements;
92
+ /**
93
+ * 解析化学式,返回元素计数
94
+ */
95
+ private parseFormula;
96
+ private parseFormulaPart;
97
+ }
98
+ /** 平衡检查结果 */
99
+ interface BalanceResult {
100
+ balanced: boolean;
101
+ reactantsCount: Record<string, number>;
102
+ productsCount: Record<string, number>;
103
+ imbalances: ElementImbalance[];
104
+ }
105
+ /** 元素不平衡 */
106
+ interface ElementImbalance {
107
+ symbol: string;
108
+ reactantCount: number;
109
+ productCount: number;
110
+ difference: number;
111
+ }
112
+ /**
113
+ * 氧化数计算工具
114
+ */
115
+ declare class OxidationCalculator {
116
+ /**
117
+ * 获取元素的常见氧化态
118
+ */
119
+ getOxidationStates(symbol: string): number[];
120
+ /**
121
+ * 判断元素是否为金属
122
+ */
123
+ isMetal(symbol: string): boolean;
124
+ /**
125
+ * 判断元素是否为非金属
126
+ */
127
+ isNonMetal(symbol: string): boolean;
128
+ /**
129
+ * 获取电负性
130
+ */
131
+ getElectronegativity(symbol: string): number | undefined;
132
+ }
133
+
134
+ export { type BalanceResult, ELEMENT_BY_NUMBER, ELEMENT_MAP, type ElementData, type ElementImbalance, type FormulaError, type FormulaValidationResult, FormulaValidator, type FormulaWarning, OxidationCalculator, PERIODIC_TABLE, ReactionBalancer };
@@ -0,0 +1,134 @@
1
+ import { ExpressionNode } from '@sciexpr/core';
2
+
3
+ /** 元素完整信息 */
4
+ interface ElementData {
5
+ /** 元素符号 (H, He, Na, ...) */
6
+ symbol: string;
7
+ /** 原子序数 */
8
+ atomicNumber: number;
9
+ /** 相对原子质量 */
10
+ atomicMass: number;
11
+ /** 中文名 */
12
+ nameCN: string;
13
+ /** 英文名 */
14
+ nameEN: string;
15
+ /** 族 */
16
+ group: number;
17
+ /** 周期 */
18
+ period: number;
19
+ /** 区块 */
20
+ block: 's' | 'p' | 'd' | 'f';
21
+ /** 电负性 (Pauling) */
22
+ electronegativity?: number;
23
+ /** 常见氧化态 */
24
+ oxidationStates?: number[];
25
+ /** 电子排布 */
26
+ electronConfiguration?: string;
27
+ /** 常见化合物 */
28
+ commonCompounds?: string[];
29
+ }
30
+ /** 完整 118 元素周期表 */
31
+ declare const PERIODIC_TABLE: ElementData[];
32
+ /** 按符号索引的元素 Map */
33
+ declare const ELEMENT_MAP: Map<string, ElementData>;
34
+ /** 按原子序数索引的元素 Map */
35
+ declare const ELEMENT_BY_NUMBER: Map<number, ElementData>;
36
+
37
+ /**
38
+ * 化学式验证器
39
+ */
40
+ declare class FormulaValidator {
41
+ /**
42
+ * 验证化学元素符号是否有效
43
+ */
44
+ isValidSymbol(symbol: string): boolean;
45
+ /**
46
+ * 获取元素信息
47
+ */
48
+ getElement(symbol: string): ElementData | undefined;
49
+ /**
50
+ * 验证 AST 节点是否为有效化学式
51
+ */
52
+ validate(node: ExpressionNode): FormulaValidationResult;
53
+ private validateNode;
54
+ /**
55
+ * 解析化学式文本并验证
56
+ * @param formula 化学式文本(如 "H2SO4", "NaOH", "Ca(OH)2")
57
+ */
58
+ validateText(formula: string): FormulaValidationResult;
59
+ }
60
+ /** 验证结果 */
61
+ interface FormulaValidationResult {
62
+ valid: boolean;
63
+ errors: FormulaError[];
64
+ warnings: FormulaWarning[];
65
+ }
66
+ /** 验证错误 */
67
+ interface FormulaError {
68
+ code: string;
69
+ message: string;
70
+ node?: ExpressionNode;
71
+ }
72
+ /** 验证警告 */
73
+ interface FormulaWarning {
74
+ code: string;
75
+ message: string;
76
+ }
77
+
78
+ /**
79
+ * 化学反应式平衡检查器
80
+ */
81
+ declare class ReactionBalancer {
82
+ /**
83
+ * 检查化学方程式元素守恒
84
+ * @param reactants 反应物(化学式文本数组)
85
+ * @param products 生成物(化学式文本数组)
86
+ */
87
+ checkConservation(reactants: string[], products: string[]): BalanceResult;
88
+ /**
89
+ * 计算化学式中各元素的原子数
90
+ */
91
+ private countElements;
92
+ /**
93
+ * 解析化学式,返回元素计数
94
+ */
95
+ private parseFormula;
96
+ private parseFormulaPart;
97
+ }
98
+ /** 平衡检查结果 */
99
+ interface BalanceResult {
100
+ balanced: boolean;
101
+ reactantsCount: Record<string, number>;
102
+ productsCount: Record<string, number>;
103
+ imbalances: ElementImbalance[];
104
+ }
105
+ /** 元素不平衡 */
106
+ interface ElementImbalance {
107
+ symbol: string;
108
+ reactantCount: number;
109
+ productCount: number;
110
+ difference: number;
111
+ }
112
+ /**
113
+ * 氧化数计算工具
114
+ */
115
+ declare class OxidationCalculator {
116
+ /**
117
+ * 获取元素的常见氧化态
118
+ */
119
+ getOxidationStates(symbol: string): number[];
120
+ /**
121
+ * 判断元素是否为金属
122
+ */
123
+ isMetal(symbol: string): boolean;
124
+ /**
125
+ * 判断元素是否为非金属
126
+ */
127
+ isNonMetal(symbol: string): boolean;
128
+ /**
129
+ * 获取电负性
130
+ */
131
+ getElectronegativity(symbol: string): number | undefined;
132
+ }
133
+
134
+ export { type BalanceResult, ELEMENT_BY_NUMBER, ELEMENT_MAP, type ElementData, type ElementImbalance, type FormulaError, type FormulaValidationResult, FormulaValidator, type FormulaWarning, OxidationCalculator, PERIODIC_TABLE, ReactionBalancer };
package/dist/index.js ADDED
@@ -0,0 +1,416 @@
1
+ // src/periodic-table.ts
2
+ var PERIODIC_TABLE = [
3
+ // Period 1
4
+ { symbol: "H", atomicNumber: 1, atomicMass: 1.008, nameCN: "\u6C22", nameEN: "Hydrogen", group: 1, period: 1, block: "s", electronegativity: 2.2, oxidationStates: [1, -1], electronConfiguration: "1s\xB9" },
5
+ { symbol: "He", atomicNumber: 2, atomicMass: 4.0026, nameCN: "\u6C26", nameEN: "Helium", group: 18, period: 1, block: "s", electronConfiguration: "1s\xB2" },
6
+ // Period 2
7
+ { symbol: "Li", atomicNumber: 3, atomicMass: 6.94, nameCN: "\u9502", nameEN: "Lithium", group: 1, period: 2, block: "s", electronegativity: 0.98, oxidationStates: [1], electronConfiguration: "[He] 2s\xB9" },
8
+ { symbol: "Be", atomicNumber: 4, atomicMass: 9.0122, nameCN: "\u94CD", nameEN: "Beryllium", group: 2, period: 2, block: "s", electronegativity: 1.57, oxidationStates: [2], electronConfiguration: "[He] 2s\xB2" },
9
+ { symbol: "B", atomicNumber: 5, atomicMass: 10.81, nameCN: "\u787C", nameEN: "Boron", group: 13, period: 2, block: "p", electronegativity: 2.04, oxidationStates: [3], electronConfiguration: "[He] 2s\xB22p\xB9" },
10
+ { symbol: "C", atomicNumber: 6, atomicMass: 12.011, nameCN: "\u78B3", nameEN: "Carbon", group: 14, period: 2, block: "p", electronegativity: 2.55, oxidationStates: [4, 2, -4], electronConfiguration: "[He] 2s\xB22p\xB2", commonCompounds: ["CO2", "CH4", "C6H12O6"] },
11
+ { symbol: "N", atomicNumber: 7, atomicMass: 14.007, nameCN: "\u6C2E", nameEN: "Nitrogen", group: 15, period: 2, block: "p", electronegativity: 3.04, oxidationStates: [5, 3, -3], electronConfiguration: "[He] 2s\xB22p\xB3", commonCompounds: ["NH3", "HNO3", "N2"] },
12
+ { symbol: "O", atomicNumber: 8, atomicMass: 15.999, nameCN: "\u6C27", nameEN: "Oxygen", group: 16, period: 2, block: "p", electronegativity: 3.44, oxidationStates: [-2, -1], electronConfiguration: "[He] 2s\xB22p\u2074", commonCompounds: ["H2O", "CO2", "O2"] },
13
+ { symbol: "F", atomicNumber: 9, atomicMass: 18.998, nameCN: "\u6C1F", nameEN: "Fluorine", group: 17, period: 2, block: "p", electronegativity: 3.98, oxidationStates: [-1], electronConfiguration: "[He] 2s\xB22p\u2075", commonCompounds: ["HF", "NaF"] },
14
+ { symbol: "Ne", atomicNumber: 10, atomicMass: 20.18, nameCN: "\u6C16", nameEN: "Neon", group: 18, period: 2, block: "p", electronConfiguration: "[He] 2s\xB22p\u2076" },
15
+ // Period 3
16
+ { symbol: "Na", atomicNumber: 11, atomicMass: 22.99, nameCN: "\u94A0", nameEN: "Sodium", group: 1, period: 3, block: "s", electronegativity: 0.93, oxidationStates: [1], electronConfiguration: "[Ne] 3s\xB9", commonCompounds: ["NaCl", "NaOH", "Na2CO3"] },
17
+ { symbol: "Mg", atomicNumber: 12, atomicMass: 24.305, nameCN: "\u9541", nameEN: "Magnesium", group: 2, period: 3, block: "s", electronegativity: 1.31, oxidationStates: [2], electronConfiguration: "[Ne] 3s\xB2", commonCompounds: ["MgO", "MgCl2"] },
18
+ { symbol: "Al", atomicNumber: 13, atomicMass: 26.982, nameCN: "\u94DD", nameEN: "Aluminium", group: 13, period: 3, block: "p", electronegativity: 1.61, oxidationStates: [3], electronConfiguration: "[Ne] 3s\xB23p\xB9", commonCompounds: ["Al2O3", "AlCl3"] },
19
+ { symbol: "Si", atomicNumber: 14, atomicMass: 28.085, nameCN: "\u7845", nameEN: "Silicon", group: 14, period: 3, block: "p", electronegativity: 1.9, oxidationStates: [4], electronConfiguration: "[Ne] 3s\xB23p\xB2", commonCompounds: ["SiO2", "SiH4"] },
20
+ { symbol: "P", atomicNumber: 15, atomicMass: 30.974, nameCN: "\u78F7", nameEN: "Phosphorus", group: 15, period: 3, block: "p", electronegativity: 2.19, oxidationStates: [5, 3, -3], electronConfiguration: "[Ne] 3s\xB23p\xB3", commonCompounds: ["H3PO4", "P4"] },
21
+ { symbol: "S", atomicNumber: 16, atomicMass: 32.06, nameCN: "\u786B", nameEN: "Sulfur", group: 16, period: 3, block: "p", electronegativity: 2.58, oxidationStates: [6, 4, -2], electronConfiguration: "[Ne] 3s\xB23p\u2074", commonCompounds: ["H2SO4", "SO2", "H2S"] },
22
+ { symbol: "Cl", atomicNumber: 17, atomicMass: 35.45, nameCN: "\u6C2F", nameEN: "Chlorine", group: 17, period: 3, block: "p", electronegativity: 3.16, oxidationStates: [7, 5, 3, 1, -1], electronConfiguration: "[Ne] 3s\xB23p\u2075", commonCompounds: ["NaCl", "HCl", "Cl2"] },
23
+ { symbol: "Ar", atomicNumber: 18, atomicMass: 39.948, nameCN: "\u6C29", nameEN: "Argon", group: 18, period: 3, block: "p", electronConfiguration: "[Ne] 3s\xB23p\u2076" },
24
+ // Period 4
25
+ { symbol: "K", atomicNumber: 19, atomicMass: 39.098, nameCN: "\u94BE", nameEN: "Potassium", group: 1, period: 4, block: "s", electronegativity: 0.82, oxidationStates: [1], electronConfiguration: "[Ar] 4s\xB9", commonCompounds: ["KCl", "KNO3"] },
26
+ { symbol: "Ca", atomicNumber: 20, atomicMass: 40.078, nameCN: "\u9499", nameEN: "Calcium", group: 2, period: 4, block: "s", electronegativity: 1, oxidationStates: [2], electronConfiguration: "[Ar] 4s\xB2", commonCompounds: ["CaCO3", "CaO", "Ca(OH)2"] },
27
+ { symbol: "Sc", atomicNumber: 21, atomicMass: 44.956, nameCN: "\u94AA", nameEN: "Scandium", group: 3, period: 4, block: "d", electronegativity: 1.36, oxidationStates: [3], electronConfiguration: "[Ar] 3d\xB94s\xB2" },
28
+ { symbol: "Ti", atomicNumber: 22, atomicMass: 47.867, nameCN: "\u949B", nameEN: "Titanium", group: 4, period: 4, block: "d", electronegativity: 1.54, oxidationStates: [4, 3], electronConfiguration: "[Ar] 3d\xB24s\xB2", commonCompounds: ["TiO2"] },
29
+ { symbol: "V", atomicNumber: 23, atomicMass: 50.942, nameCN: "\u9492", nameEN: "Vanadium", group: 5, period: 4, block: "d", electronegativity: 1.63, oxidationStates: [5, 4, 3, 2], electronConfiguration: "[Ar] 3d\xB34s\xB2" },
30
+ { symbol: "Cr", atomicNumber: 24, atomicMass: 51.996, nameCN: "\u94EC", nameEN: "Chromium", group: 6, period: 4, block: "d", electronegativity: 1.66, oxidationStates: [6, 3, 2], electronConfiguration: "[Ar] 3d\u20754s\xB9", commonCompounds: ["K2Cr2O7", "Cr2O3"] },
31
+ { symbol: "Mn", atomicNumber: 25, atomicMass: 54.938, nameCN: "\u9530", nameEN: "Manganese", group: 7, period: 4, block: "d", electronegativity: 1.55, oxidationStates: [7, 4, 2], electronConfiguration: "[Ar] 3d\u20754s\xB2", commonCompounds: ["MnO2", "KMnO4"] },
32
+ { symbol: "Fe", atomicNumber: 26, atomicMass: 55.845, nameCN: "\u94C1", nameEN: "Iron", group: 8, period: 4, block: "d", electronegativity: 1.83, oxidationStates: [3, 2], electronConfiguration: "[Ar] 3d\u20764s\xB2", commonCompounds: ["Fe2O3", "Fe3O4", "FeSO4"] },
33
+ { symbol: "Co", atomicNumber: 27, atomicMass: 58.933, nameCN: "\u94B4", nameEN: "Cobalt", group: 9, period: 4, block: "d", electronegativity: 1.88, oxidationStates: [3, 2], electronConfiguration: "[Ar] 3d\u20774s\xB2" },
34
+ { symbol: "Ni", atomicNumber: 28, atomicMass: 58.693, nameCN: "\u954D", nameEN: "Nickel", group: 10, period: 4, block: "d", electronegativity: 1.91, oxidationStates: [2], electronConfiguration: "[Ar] 3d\u20784s\xB2", commonCompounds: ["Ni(CO)4"] },
35
+ { symbol: "Cu", atomicNumber: 29, atomicMass: 63.546, nameCN: "\u94DC", nameEN: "Copper", group: 11, period: 4, block: "d", electronegativity: 1.9, oxidationStates: [2, 1], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB9", commonCompounds: ["CuSO4", "CuO", "Cu2O"] },
36
+ { symbol: "Zn", atomicNumber: 30, atomicMass: 65.38, nameCN: "\u950C", nameEN: "Zinc", group: 12, period: 4, block: "d", electronegativity: 1.65, oxidationStates: [2], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB2", commonCompounds: ["ZnO", "ZnSO4"] },
37
+ { symbol: "Ga", atomicNumber: 31, atomicMass: 69.723, nameCN: "\u9553", nameEN: "Gallium", group: 13, period: 4, block: "p", electronegativity: 1.81, oxidationStates: [3], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\xB9" },
38
+ { symbol: "Ge", atomicNumber: 32, atomicMass: 72.63, nameCN: "\u9517", nameEN: "Germanium", group: 14, period: 4, block: "p", electronegativity: 2.01, oxidationStates: [4], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\xB2" },
39
+ { symbol: "As", atomicNumber: 33, atomicMass: 74.922, nameCN: "\u7837", nameEN: "Arsenic", group: 15, period: 4, block: "p", electronegativity: 2.18, oxidationStates: [5, 3, -3], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\xB3" },
40
+ { symbol: "Se", atomicNumber: 34, atomicMass: 78.971, nameCN: "\u7852", nameEN: "Selenium", group: 16, period: 4, block: "p", electronegativity: 2.55, oxidationStates: [6, 4, -2], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\u2074" },
41
+ { symbol: "Br", atomicNumber: 35, atomicMass: 79.904, nameCN: "\u6EB4", nameEN: "Bromine", group: 17, period: 4, block: "p", electronegativity: 2.96, oxidationStates: [7, 5, 1, -1], electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\u2075", commonCompounds: ["NaBr", "HBr"] },
42
+ { symbol: "Kr", atomicNumber: 36, atomicMass: 83.798, nameCN: "\u6C2A", nameEN: "Krypton", group: 18, period: 4, block: "p", electronConfiguration: "[Ar] 3d\xB9\u20704s\xB24p\u2076" },
43
+ // Period 5
44
+ { symbol: "Rb", atomicNumber: 37, atomicMass: 85.468, nameCN: "\u94F7", nameEN: "Rubidium", group: 1, period: 5, block: "s", electronegativity: 0.82, oxidationStates: [1], electronConfiguration: "[Kr] 5s\xB9" },
45
+ { symbol: "Sr", atomicNumber: 38, atomicMass: 87.62, nameCN: "\u9536", nameEN: "Strontium", group: 2, period: 5, block: "s", electronegativity: 0.95, oxidationStates: [2], electronConfiguration: "[Kr] 5s\xB2" },
46
+ { symbol: "Y", atomicNumber: 39, atomicMass: 88.906, nameCN: "\u9487", nameEN: "Yttrium", group: 3, period: 5, block: "d", electronegativity: 1.22, oxidationStates: [3], electronConfiguration: "[Kr] 4d\xB95s\xB2" },
47
+ { symbol: "Zr", atomicNumber: 40, atomicMass: 91.224, nameCN: "\u9506", nameEN: "Zirconium", group: 4, period: 5, block: "d", electronegativity: 1.33, oxidationStates: [4], electronConfiguration: "[Kr] 4d\xB25s\xB2" },
48
+ { symbol: "Nb", atomicNumber: 41, atomicMass: 92.906, nameCN: "\u94CC", nameEN: "Niobium", group: 5, period: 5, block: "d", electronegativity: 1.6, oxidationStates: [5], electronConfiguration: "[Kr] 4d\u20745s\xB9" },
49
+ { symbol: "Mo", atomicNumber: 42, atomicMass: 95.95, nameCN: "\u94BC", nameEN: "Molybdenum", group: 6, period: 5, block: "d", electronegativity: 2.16, oxidationStates: [6], electronConfiguration: "[Kr] 4d\u20755s\xB9" },
50
+ { symbol: "Tc", atomicNumber: 43, atomicMass: 98, nameCN: "\u951D", nameEN: "Technetium", group: 7, period: 5, block: "d", electronegativity: 1.9, oxidationStates: [7], electronConfiguration: "[Kr] 4d\u20755s\xB2" },
51
+ { symbol: "Ru", atomicNumber: 44, atomicMass: 101.07, nameCN: "\u948C", nameEN: "Ruthenium", group: 8, period: 5, block: "d", electronegativity: 2.2, oxidationStates: [4, 3], electronConfiguration: "[Kr] 4d\u20775s\xB9" },
52
+ { symbol: "Rh", atomicNumber: 45, atomicMass: 102.91, nameCN: "\u94D1", nameEN: "Rhodium", group: 9, period: 5, block: "d", electronegativity: 2.28, oxidationStates: [3], electronConfiguration: "[Kr] 4d\u20785s\xB9" },
53
+ { symbol: "Pd", atomicNumber: 46, atomicMass: 106.42, nameCN: "\u94AF", nameEN: "Palladium", group: 10, period: 5, block: "d", electronegativity: 2.2, oxidationStates: [2], electronConfiguration: "[Kr] 4d\xB9\u2070" },
54
+ { symbol: "Ag", atomicNumber: 47, atomicMass: 107.87, nameCN: "\u94F6", nameEN: "Silver", group: 11, period: 5, block: "d", electronegativity: 1.93, oxidationStates: [1], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB9", commonCompounds: ["AgNO3", "AgCl"] },
55
+ { symbol: "Cd", atomicNumber: 48, atomicMass: 112.41, nameCN: "\u9549", nameEN: "Cadmium", group: 12, period: 5, block: "d", electronegativity: 1.69, oxidationStates: [2], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB2" },
56
+ { symbol: "In", atomicNumber: 49, atomicMass: 114.82, nameCN: "\u94DF", nameEN: "Indium", group: 13, period: 5, block: "p", electronegativity: 1.78, oxidationStates: [3], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\xB9" },
57
+ { symbol: "Sn", atomicNumber: 50, atomicMass: 118.71, nameCN: "\u9521", nameEN: "Tin", group: 14, period: 5, block: "p", electronegativity: 1.96, oxidationStates: [4, 2], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\xB2" },
58
+ { symbol: "Sb", atomicNumber: 51, atomicMass: 121.76, nameCN: "\u9511", nameEN: "Antimony", group: 15, period: 5, block: "p", electronegativity: 2.05, oxidationStates: [5, 3], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\xB3" },
59
+ { symbol: "Te", atomicNumber: 52, atomicMass: 127.6, nameCN: "\u78B2", nameEN: "Tellurium", group: 16, period: 5, block: "p", electronegativity: 2.1, oxidationStates: [6, 4, -2], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\u2074" },
60
+ { symbol: "I", atomicNumber: 53, atomicMass: 126.9, nameCN: "\u7898", nameEN: "Iodine", group: 17, period: 5, block: "p", electronegativity: 2.66, oxidationStates: [7, 5, 1, -1], electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\u2075", commonCompounds: ["KI", "I2"] },
61
+ { symbol: "Xe", atomicNumber: 54, atomicMass: 131.29, nameCN: "\u6C19", nameEN: "Xenon", group: 18, period: 5, block: "p", electronConfiguration: "[Kr] 4d\xB9\u20705s\xB25p\u2076" },
62
+ // Period 6
63
+ { symbol: "Cs", atomicNumber: 55, atomicMass: 132.91, nameCN: "\u94EF", nameEN: "Cesium", group: 1, period: 6, block: "s", electronegativity: 0.79, oxidationStates: [1], electronConfiguration: "[Xe] 6s\xB9" },
64
+ { symbol: "Ba", atomicNumber: 56, atomicMass: 137.33, nameCN: "\u94A1", nameEN: "Barium", group: 2, period: 6, block: "s", electronegativity: 0.89, oxidationStates: [2], electronConfiguration: "[Xe] 6s\xB2", commonCompounds: ["BaSO4"] },
65
+ { symbol: "La", atomicNumber: 57, atomicMass: 138.91, nameCN: "\u9567", nameEN: "Lanthanum", group: 3, period: 6, block: "f", electronegativity: 1.1, oxidationStates: [3], electronConfiguration: "[Xe] 5d\xB96s\xB2" },
66
+ { symbol: "Ce", atomicNumber: 58, atomicMass: 140.12, nameCN: "\u94C8", nameEN: "Cerium", group: 3, period: 6, block: "f", electronegativity: 1.12, oxidationStates: [4, 3], electronConfiguration: "[Xe] 4f\xB95d\xB96s\xB2" },
67
+ { symbol: "Pr", atomicNumber: 59, atomicMass: 140.91, nameCN: "\u9568", nameEN: "Praseodymium", group: 3, period: 6, block: "f", electronegativity: 1.13, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB36s\xB2" },
68
+ { symbol: "Nd", atomicNumber: 60, atomicMass: 144.24, nameCN: "\u9495", nameEN: "Neodymium", group: 3, period: 6, block: "f", electronegativity: 1.14, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20746s\xB2" },
69
+ { symbol: "Pm", atomicNumber: 61, atomicMass: 145, nameCN: "\u94B7", nameEN: "Promethium", group: 3, period: 6, block: "f", electronegativity: 1.13, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20756s\xB2" },
70
+ { symbol: "Sm", atomicNumber: 62, atomicMass: 150.36, nameCN: "\u9490", nameEN: "Samarium", group: 3, period: 6, block: "f", electronegativity: 1.17, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20766s\xB2" },
71
+ { symbol: "Eu", atomicNumber: 63, atomicMass: 151.96, nameCN: "\u94D5", nameEN: "Europium", group: 3, period: 6, block: "f", electronegativity: 1.2, oxidationStates: [3, 2], electronConfiguration: "[Xe] 4f\u20776s\xB2" },
72
+ { symbol: "Gd", atomicNumber: 64, atomicMass: 157.25, nameCN: "\u9486", nameEN: "Gadolinium", group: 3, period: 6, block: "f", electronegativity: 1.2, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20775d\xB96s\xB2" },
73
+ { symbol: "Tb", atomicNumber: 65, atomicMass: 158.93, nameCN: "\u94FD", nameEN: "Terbium", group: 3, period: 6, block: "f", electronegativity: 1.2, oxidationStates: [3], electronConfiguration: "[Xe] 4f\u20796s\xB2" },
74
+ { symbol: "Dy", atomicNumber: 66, atomicMass: 162.5, nameCN: "\u955D", nameEN: "Dysprosium", group: 3, period: 6, block: "f", electronegativity: 1.22, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\u20706s\xB2" },
75
+ { symbol: "Ho", atomicNumber: 67, atomicMass: 164.93, nameCN: "\u94AC", nameEN: "Holmium", group: 3, period: 6, block: "f", electronegativity: 1.23, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\xB96s\xB2" },
76
+ { symbol: "Er", atomicNumber: 68, atomicMass: 167.26, nameCN: "\u94D2", nameEN: "Erbium", group: 3, period: 6, block: "f", electronegativity: 1.24, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\xB26s\xB2" },
77
+ { symbol: "Tm", atomicNumber: 69, atomicMass: 168.93, nameCN: "\u94E5", nameEN: "Thulium", group: 3, period: 6, block: "f", electronegativity: 1.25, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\xB36s\xB2" },
78
+ { symbol: "Yb", atomicNumber: 70, atomicMass: 173.05, nameCN: "\u9571", nameEN: "Ytterbium", group: 3, period: 6, block: "f", electronegativity: 1.1, oxidationStates: [3, 2], electronConfiguration: "[Xe] 4f\xB9\u20746s\xB2" },
79
+ { symbol: "Lu", atomicNumber: 71, atomicMass: 174.97, nameCN: "\u9565", nameEN: "Lutetium", group: 3, period: 6, block: "d", electronegativity: 1.27, oxidationStates: [3], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB96s\xB2" },
80
+ { symbol: "Hf", atomicNumber: 72, atomicMass: 178.49, nameCN: "\u94EA", nameEN: "Hafnium", group: 4, period: 6, block: "d", electronegativity: 1.3, oxidationStates: [4], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB26s\xB2" },
81
+ { symbol: "Ta", atomicNumber: 73, atomicMass: 180.95, nameCN: "\u94BD", nameEN: "Tantalum", group: 5, period: 6, block: "d", electronegativity: 1.5, oxidationStates: [5], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB36s\xB2" },
82
+ { symbol: "W", atomicNumber: 74, atomicMass: 183.84, nameCN: "\u94A8", nameEN: "Tungsten", group: 6, period: 6, block: "d", electronegativity: 2.36, oxidationStates: [6], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20746s\xB2" },
83
+ { symbol: "Re", atomicNumber: 75, atomicMass: 186.21, nameCN: "\u94FC", nameEN: "Rhenium", group: 7, period: 6, block: "d", electronegativity: 1.9, oxidationStates: [7, 4], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20756s\xB2" },
84
+ { symbol: "Os", atomicNumber: 76, atomicMass: 190.23, nameCN: "\u9507", nameEN: "Osmium", group: 8, period: 6, block: "d", electronegativity: 2.2, oxidationStates: [4], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20766s\xB2" },
85
+ { symbol: "Ir", atomicNumber: 77, atomicMass: 192.22, nameCN: "\u94F1", nameEN: "Iridium", group: 9, period: 6, block: "d", electronegativity: 2.2, oxidationStates: [4, 3], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20776s\xB2" },
86
+ { symbol: "Pt", atomicNumber: 78, atomicMass: 195.08, nameCN: "\u94C2", nameEN: "Platinum", group: 10, period: 6, block: "d", electronegativity: 2.28, oxidationStates: [4, 2], electronConfiguration: "[Xe] 4f\xB9\u20745d\u20796s\xB9" },
87
+ { symbol: "Au", atomicNumber: 79, atomicMass: 196.97, nameCN: "\u91D1", nameEN: "Gold", group: 11, period: 6, block: "d", electronegativity: 2.54, oxidationStates: [3, 1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB9" },
88
+ { symbol: "Hg", atomicNumber: 80, atomicMass: 200.59, nameCN: "\u6C5E", nameEN: "Mercury", group: 12, period: 6, block: "d", electronegativity: 2, oxidationStates: [2, 1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB2" },
89
+ { symbol: "Tl", atomicNumber: 81, atomicMass: 204.38, nameCN: "\u94CA", nameEN: "Thallium", group: 13, period: 6, block: "p", electronegativity: 1.62, oxidationStates: [3, 1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\xB9" },
90
+ { symbol: "Pb", atomicNumber: 82, atomicMass: 207.2, nameCN: "\u94C5", nameEN: "Lead", group: 14, period: 6, block: "p", electronegativity: 2.33, oxidationStates: [4, 2], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\xB2", commonCompounds: ["PbO", "PbO2"] },
91
+ { symbol: "Bi", atomicNumber: 83, atomicMass: 208.98, nameCN: "\u94CB", nameEN: "Bismuth", group: 15, period: 6, block: "p", electronegativity: 2.02, oxidationStates: [5, 3], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\xB3" },
92
+ { symbol: "Po", atomicNumber: 84, atomicMass: 209, nameCN: "\u948B", nameEN: "Polonium", group: 16, period: 6, block: "p", electronegativity: 2, oxidationStates: [4, 2], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\u2074" },
93
+ { symbol: "At", atomicNumber: 85, atomicMass: 210, nameCN: "\u7839", nameEN: "Astatine", group: 17, period: 6, block: "p", electronegativity: 2.2, oxidationStates: [7, 5, 3, 1, -1], electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\u2075" },
94
+ { symbol: "Rn", atomicNumber: 86, atomicMass: 222, nameCN: "\u6C21", nameEN: "Radon", group: 18, period: 6, block: "p", electronConfiguration: "[Xe] 4f\xB9\u20745d\xB9\u20706s\xB26p\u2076" },
95
+ // Period 7
96
+ { symbol: "Fr", atomicNumber: 87, atomicMass: 223, nameCN: "\u94AB", nameEN: "Francium", group: 1, period: 7, block: "s", electronegativity: 0.7, oxidationStates: [1], electronConfiguration: "[Rn] 7s\xB9" },
97
+ { symbol: "Ra", atomicNumber: 88, atomicMass: 226, nameCN: "\u956D", nameEN: "Radium", group: 2, period: 7, block: "s", electronegativity: 0.9, oxidationStates: [2], electronConfiguration: "[Rn] 7s\xB2" },
98
+ { symbol: "Ac", atomicNumber: 89, atomicMass: 227, nameCN: "\u9515", nameEN: "Actinium", group: 3, period: 7, block: "f", electronegativity: 1.1, oxidationStates: [3], electronConfiguration: "[Rn] 6d\xB97s\xB2" },
99
+ { symbol: "Th", atomicNumber: 90, atomicMass: 232.04, nameCN: "\u948D", nameEN: "Thorium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [4], electronConfiguration: "[Rn] 6d\xB27s\xB2" },
100
+ { symbol: "Pa", atomicNumber: 91, atomicMass: 231.04, nameCN: "\u9564", nameEN: "Protactinium", group: 3, period: 7, block: "f", electronegativity: 1.5, oxidationStates: [5], electronConfiguration: "[Rn] 5f\xB26d\xB97s\xB2" },
101
+ { symbol: "U", atomicNumber: 92, atomicMass: 238.03, nameCN: "\u94C0", nameEN: "Uranium", group: 3, period: 7, block: "f", electronegativity: 1.38, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\xB36d\xB97s\xB2", commonCompounds: ["UO2", "UF6"] },
102
+ { symbol: "Np", atomicNumber: 93, atomicMass: 237, nameCN: "\u954E", nameEN: "Neptunium", group: 3, period: 7, block: "f", electronegativity: 1.36, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\u20746d\xB97s\xB2" },
103
+ { symbol: "Pu", atomicNumber: 94, atomicMass: 244, nameCN: "\u949A", nameEN: "Plutonium", group: 3, period: 7, block: "f", electronegativity: 1.28, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\u20767s\xB2" },
104
+ { symbol: "Am", atomicNumber: 95, atomicMass: 243, nameCN: "\u9545", nameEN: "Americium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [6, 5, 4, 3], electronConfiguration: "[Rn] 5f\u20777s\xB2" },
105
+ { symbol: "Cm", atomicNumber: 96, atomicMass: 247, nameCN: "\u9514", nameEN: "Curium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\u20776d\xB97s\xB2" },
106
+ { symbol: "Bk", atomicNumber: 97, atomicMass: 247, nameCN: "\u952B", nameEN: "Berkelium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [4, 3], electronConfiguration: "[Rn] 5f\u20797s\xB2" },
107
+ { symbol: "Cf", atomicNumber: 98, atomicMass: 251, nameCN: "\u950E", nameEN: "Californium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\u20707s\xB2" },
108
+ { symbol: "Es", atomicNumber: 99, atomicMass: 252, nameCN: "\u953F", nameEN: "Einsteinium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\xB97s\xB2" },
109
+ { symbol: "Fm", atomicNumber: 100, atomicMass: 257, nameCN: "\u9544", nameEN: "Fermium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\xB27s\xB2" },
110
+ { symbol: "Md", atomicNumber: 101, atomicMass: 258, nameCN: "\u9494", nameEN: "Mendelevium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\xB37s\xB2" },
111
+ { symbol: "No", atomicNumber: 102, atomicMass: 259, nameCN: "\u9518", nameEN: "Nobelium", group: 3, period: 7, block: "f", electronegativity: 1.3, oxidationStates: [2], electronConfiguration: "[Rn] 5f\xB9\u20747s\xB2" },
112
+ { symbol: "Lr", atomicNumber: 103, atomicMass: 266, nameCN: "\u94F9", nameEN: "Lawrencium", group: 3, period: 7, block: "d", electronegativity: 1.3, oxidationStates: [3], electronConfiguration: "[Rn] 5f\xB9\u20747s\xB27p\xB9" },
113
+ { symbol: "Rf", atomicNumber: 104, atomicMass: 267, nameCN: "\u{2CB3B}", nameEN: "Rutherfordium", group: 4, period: 7, block: "d", oxidationStates: [4], electronConfiguration: "[Rn] 5f\xB9\u20746d\xB27s\xB2" },
114
+ { symbol: "Db", atomicNumber: 105, atomicMass: 268, nameCN: "\u{2CB4A}", nameEN: "Dubnium", group: 5, period: 7, block: "d", oxidationStates: [5], electronConfiguration: "[Rn] 5f\xB9\u20746d\xB37s\xB2" },
115
+ { symbol: "Sg", atomicNumber: 106, atomicMass: 269, nameCN: "\u{2CB73}", nameEN: "Seaborgium", group: 6, period: 7, block: "d", oxidationStates: [6], electronConfiguration: "[Rn] 5f\xB9\u20746d\u20747s\xB2" },
116
+ { symbol: "Bh", atomicNumber: 107, atomicMass: 270, nameCN: "\u{2CB5B}", nameEN: "Bohrium", group: 7, period: 7, block: "d", oxidationStates: [7], electronConfiguration: "[Rn] 5f\xB9\u20746d\u20757s\xB2" },
117
+ { symbol: "Hs", atomicNumber: 108, atomicMass: 269, nameCN: "\u{2CB76}", nameEN: "Hassium", group: 8, period: 7, block: "d", oxidationStates: [8], electronConfiguration: "[Rn] 5f\xB9\u20746d\u20767s\xB2" },
118
+ { symbol: "Mt", atomicNumber: 109, atomicMass: 278, nameCN: "\u9FCF", nameEN: "Meitnerium", group: 9, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\u20777s\xB2" },
119
+ { symbol: "Ds", atomicNumber: 110, atomicMass: 281, nameCN: "\u{2B7FC}", nameEN: "Darmstadtium", group: 10, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\u20797s\xB9" },
120
+ { symbol: "Rg", atomicNumber: 111, atomicMass: 282, nameCN: "\u{2CB2D}", nameEN: "Roentgenium", group: 11, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB9" },
121
+ { symbol: "Cn", atomicNumber: 112, atomicMass: 285, nameCN: "\u9FD4", nameEN: "Copernicium", group: 12, period: 7, block: "d", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB2" },
122
+ { symbol: "Nh", atomicNumber: 113, atomicMass: 286, nameCN: "\u9FED", nameEN: "Nihonium", group: 13, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\xB9" },
123
+ { symbol: "Fl", atomicNumber: 114, atomicMass: 289, nameCN: "\u{2B4E7}", nameEN: "Flerovium", group: 14, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\xB2" },
124
+ { symbol: "Mc", atomicNumber: 115, atomicMass: 290, nameCN: "\u9546", nameEN: "Moscovium", group: 15, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\xB3" },
125
+ { symbol: "Lv", atomicNumber: 116, atomicMass: 293, nameCN: "\u{2B7F7}", nameEN: "Livermorium", group: 16, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\u2074" },
126
+ { symbol: "Ts", atomicNumber: 117, atomicMass: 294, nameCN: "\u9FEC", nameEN: "Tennessine", group: 17, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\u2075" },
127
+ { symbol: "Og", atomicNumber: 118, atomicMass: 294, nameCN: "\u9FEB", nameEN: "Oganesson", group: 18, period: 7, block: "p", electronConfiguration: "[Rn] 5f\xB9\u20746d\xB9\u20707s\xB27p\u2076" }
128
+ ];
129
+ var ELEMENT_MAP = /* @__PURE__ */ new Map();
130
+ for (const el of PERIODIC_TABLE) {
131
+ ELEMENT_MAP.set(el.symbol.toLowerCase(), el);
132
+ }
133
+ var ELEMENT_BY_NUMBER = /* @__PURE__ */ new Map();
134
+ for (const el of PERIODIC_TABLE) {
135
+ ELEMENT_BY_NUMBER.set(el.atomicNumber, el);
136
+ }
137
+
138
+ // src/validator.ts
139
+ var FormulaValidator = class {
140
+ /**
141
+ * 验证化学元素符号是否有效
142
+ */
143
+ isValidSymbol(symbol) {
144
+ return ELEMENT_MAP.has(symbol.toLowerCase());
145
+ }
146
+ /**
147
+ * 获取元素信息
148
+ */
149
+ getElement(symbol) {
150
+ return ELEMENT_MAP.get(symbol.toLowerCase());
151
+ }
152
+ /**
153
+ * 验证 AST 节点是否为有效化学式
154
+ */
155
+ validate(node) {
156
+ const errors = [];
157
+ const warnings = [];
158
+ this.validateNode(node, errors, warnings);
159
+ return {
160
+ valid: errors.length === 0,
161
+ errors,
162
+ warnings
163
+ };
164
+ }
165
+ validateNode(node, errors, warnings) {
166
+ switch (node.kind) {
167
+ case "root":
168
+ for (const child of node.children) {
169
+ this.validateNode(child, errors, warnings);
170
+ }
171
+ break;
172
+ case "chem-element": {
173
+ const el = node;
174
+ if (!ELEMENT_MAP.has(el.symbol.toLowerCase())) {
175
+ errors.push({
176
+ code: "INVALID_ELEMENT",
177
+ message: `Unknown element symbol: ${el.symbol}`,
178
+ node
179
+ });
180
+ }
181
+ break;
182
+ }
183
+ case "chem-group": {
184
+ const group = node;
185
+ for (const atom of group.atoms) {
186
+ this.validateNode(atom, errors, warnings);
187
+ }
188
+ break;
189
+ }
190
+ case "chem-bond": {
191
+ const bond = node;
192
+ this.validateNode(bond.left, errors, warnings);
193
+ this.validateNode(bond.right, errors, warnings);
194
+ break;
195
+ }
196
+ case "chem-reaction": {
197
+ const reaction = node;
198
+ for (const r of reaction.reactants) {
199
+ this.validateNode(r, errors, warnings);
200
+ }
201
+ for (const p of reaction.products) {
202
+ this.validateNode(p, errors, warnings);
203
+ }
204
+ break;
205
+ }
206
+ }
207
+ }
208
+ /**
209
+ * 解析化学式文本并验证
210
+ * @param formula 化学式文本(如 "H2SO4", "NaOH", "Ca(OH)2")
211
+ */
212
+ validateText(formula) {
213
+ const errors = [];
214
+ const warnings = [];
215
+ let i = 0;
216
+ while (i < formula.length) {
217
+ const ch = formula[i];
218
+ if (/[A-Z]/.test(ch)) {
219
+ let symbol = ch;
220
+ i++;
221
+ while (i < formula.length && /[a-z]/.test(formula[i])) {
222
+ symbol += formula[i];
223
+ i++;
224
+ }
225
+ if (!ELEMENT_MAP.has(symbol.toLowerCase())) {
226
+ errors.push({
227
+ code: "INVALID_ELEMENT",
228
+ message: `Unknown element symbol: ${symbol}`
229
+ });
230
+ }
231
+ while (i < formula.length && /[0-9]/.test(formula[i])) i++;
232
+ continue;
233
+ }
234
+ if (ch === "(") {
235
+ let depth = 1;
236
+ i++;
237
+ while (i < formula.length && depth > 0) {
238
+ if (formula[i] === "(") depth++;
239
+ else if (formula[i] === ")") depth--;
240
+ i++;
241
+ }
242
+ if (depth !== 0) {
243
+ errors.push({
244
+ code: "UNBALANCED_PAREN",
245
+ message: "Unbalanced parentheses in formula"
246
+ });
247
+ }
248
+ continue;
249
+ }
250
+ i++;
251
+ }
252
+ return { valid: errors.length === 0, errors, warnings };
253
+ }
254
+ };
255
+
256
+ // src/balancer.ts
257
+ var ReactionBalancer = class {
258
+ /**
259
+ * 检查化学方程式元素守恒
260
+ * @param reactants 反应物(化学式文本数组)
261
+ * @param products 生成物(化学式文本数组)
262
+ */
263
+ checkConservation(reactants, products) {
264
+ const reactantsCount = this.countElements(reactants);
265
+ const productsCount = this.countElements(products);
266
+ const allElements = /* @__PURE__ */ new Set([
267
+ ...reactantsCount.keys(),
268
+ ...productsCount.keys()
269
+ ]);
270
+ const imbalances = [];
271
+ for (const symbol of allElements) {
272
+ const reactantCount = reactantsCount.get(symbol) ?? 0;
273
+ const productCount = productsCount.get(symbol) ?? 0;
274
+ if (reactantCount !== productCount) {
275
+ imbalances.push({
276
+ symbol,
277
+ reactantCount,
278
+ productCount,
279
+ difference: productCount - reactantCount
280
+ });
281
+ }
282
+ }
283
+ return {
284
+ balanced: imbalances.length === 0,
285
+ reactantsCount: Object.fromEntries(reactantsCount),
286
+ productsCount: Object.fromEntries(productsCount),
287
+ imbalances
288
+ };
289
+ }
290
+ /**
291
+ * 计算化学式中各元素的原子数
292
+ */
293
+ countElements(formulas) {
294
+ const total = /* @__PURE__ */ new Map();
295
+ for (const formula of formulas) {
296
+ const count = this.parseFormula(formula);
297
+ for (const [symbol, n] of count) {
298
+ total.set(symbol, (total.get(symbol) ?? 0) + n);
299
+ }
300
+ }
301
+ return total;
302
+ }
303
+ /**
304
+ * 解析化学式,返回元素计数
305
+ */
306
+ parseFormula(formula) {
307
+ const result = /* @__PURE__ */ new Map();
308
+ let coefficient = 1;
309
+ let i = 0;
310
+ if (/^[0-9]/.test(formula)) {
311
+ let coeff = "";
312
+ while (i < formula.length && /[0-9]/.test(formula[i])) {
313
+ coeff += formula[i];
314
+ i++;
315
+ }
316
+ coefficient = parseInt(coeff, 10) || 1;
317
+ }
318
+ this.parseFormulaPart(formula.slice(i), (symbol, count) => {
319
+ result.set(symbol, (result.get(symbol) ?? 0) + count * coefficient);
320
+ });
321
+ return result;
322
+ }
323
+ parseFormulaPart(formula, callback) {
324
+ let i = 0;
325
+ while (i < formula.length) {
326
+ const ch = formula[i];
327
+ if (/[A-Z]/.test(ch)) {
328
+ let symbol = ch;
329
+ i++;
330
+ while (i < formula.length && /[a-z]/.test(formula[i])) {
331
+ symbol += formula[i];
332
+ i++;
333
+ }
334
+ let count = 1;
335
+ if (i < formula.length && /[0-9]/.test(formula[i])) {
336
+ let numStr = "";
337
+ while (i < formula.length && /[0-9]/.test(formula[i])) {
338
+ numStr += formula[i];
339
+ i++;
340
+ }
341
+ count = parseInt(numStr, 10);
342
+ }
343
+ callback(symbol, count);
344
+ continue;
345
+ }
346
+ if (ch === "(") {
347
+ i++;
348
+ const start = i;
349
+ let depth = 1;
350
+ while (i < formula.length && depth > 0) {
351
+ if (formula[i] === "(") depth++;
352
+ else if (formula[i] === ")") depth--;
353
+ if (depth > 0) i++;
354
+ }
355
+ const groupContent = formula.slice(start, i);
356
+ i++;
357
+ let groupCount = 1;
358
+ if (i < formula.length && /[0-9]/.test(formula[i])) {
359
+ let numStr = "";
360
+ while (i < formula.length && /[0-9]/.test(formula[i])) {
361
+ numStr += formula[i];
362
+ i++;
363
+ }
364
+ groupCount = parseInt(numStr, 10);
365
+ }
366
+ this.parseFormulaPart(groupContent, (symbol, count) => {
367
+ callback(symbol, count * groupCount);
368
+ });
369
+ continue;
370
+ }
371
+ i++;
372
+ }
373
+ }
374
+ };
375
+ var OxidationCalculator = class {
376
+ /**
377
+ * 获取元素的常见氧化态
378
+ */
379
+ getOxidationStates(symbol) {
380
+ const el = ELEMENT_MAP.get(symbol.toLowerCase());
381
+ return el?.oxidationStates ?? [];
382
+ }
383
+ /**
384
+ * 判断元素是否为金属
385
+ */
386
+ isMetal(symbol) {
387
+ const el = ELEMENT_MAP.get(symbol.toLowerCase());
388
+ if (!el) return false;
389
+ if (el.block === "p") {
390
+ return ["Al", "Ga", "In", "Tl", "Sn", "Pb", "Bi", "Po"].includes(el.symbol);
391
+ }
392
+ return el.symbol !== "H" && el.symbol !== "He";
393
+ }
394
+ /**
395
+ * 判断元素是否为非金属
396
+ */
397
+ isNonMetal(symbol) {
398
+ const el = ELEMENT_MAP.get(symbol.toLowerCase());
399
+ if (!el) return false;
400
+ return el.block === "p" && !this.isMetal(symbol);
401
+ }
402
+ /**
403
+ * 获取电负性
404
+ */
405
+ getElectronegativity(symbol) {
406
+ return ELEMENT_MAP.get(symbol.toLowerCase())?.electronegativity;
407
+ }
408
+ };
409
+ export {
410
+ ELEMENT_BY_NUMBER,
411
+ ELEMENT_MAP,
412
+ FormulaValidator,
413
+ OxidationCalculator,
414
+ PERIODIC_TABLE,
415
+ ReactionBalancer
416
+ };
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@sciexpr/chemistry",
3
+ "version": "0.1.0",
4
+ "description": "Scientific Expression Engine - Chemistry utilities (periodic table, validator, reaction balancer)",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "sideEffects": false,
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "keywords": [
21
+ "scientific",
22
+ "expression",
23
+ "chemistry",
24
+ "periodic-table",
25
+ "chemical-formula"
26
+ ],
27
+ "license": "MIT",
28
+ "author": {
29
+ "name": "haoguodong09-svg",
30
+ "email": "haoguodong09@gmail.com"
31
+ },
32
+ "homepage": "https://github.com/haoguodong09-svg/scientific-expression-engine#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/haoguodong09-svg/scientific-expression-engine/issues"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/haoguodong09-svg/scientific-expression-engine",
39
+ "directory": "packages/chemistry"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "dependencies": {
45
+ "@sciexpr/core": "0.1.0"
46
+ },
47
+ "devDependencies": {
48
+ "tsup": "^8.0.0",
49
+ "typescript": "^5.5.0",
50
+ "vitest": "^2.0.0",
51
+ "rimraf": "^5.0.0"
52
+ },
53
+ "scripts": {
54
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
55
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
56
+ "lint": "tsc --noEmit",
57
+ "clean": "rimraf dist",
58
+ "test": "vitest run"
59
+ }
60
+ }