import { z } from "zod" import type { WidgetGenerator } from "@/widgets/types" import { theme } from "@/widgets/utils/theme" export const PeriodicTableWidgetPropsSchema = z .object({ type: z.literal("periodicTable"), alt: z .string() .min(1) .describe( "required alternative text describing the image for accessibility. this should be descriptive and meaningful." ), // Only caption is configurable; width/height are not exposed caption: z .string() .nullable() .transform((val) => (val === "null" || val === "NULL" ? null : val)) .describe("an optional caption to display below the image.") }) .strict() const PERIODIC_TABLE_SVG = ` image/svg+xml Periodic Table of the Elements en Periodic table of elements, using english wikipedia classifications. 15 December 2009, updated 2016, 2018 2012rc (Robert Campion) https://commons.wikimedia.org/wiki/File:Periodic_table_large.svg H Hydrogen 1s¹ 1.008 1 +1−1 2.20 1312.0 Li Lithium 1s² 2s¹ 6.94 3 +1−1 0.98 520.2 Be Beryllium 1s² 2s² 9.0122 4 +2 1.57 899.5 Na Sodium [Ne] 3s¹ 22.990 11 0.93 495.8 Mg Magnesium Magnesium [Ne] 3s² 24.305 12 +2+1 1.31 737.7 K Potassium [Ar] 4s¹ 39.098 19 +1 0.82 418.8 Ca Calcium [Ar] 4s² 40.078 20 +2 1.00 589.8 Rb Rubidium [Kr] 5s¹ 85.468 37 +1 0.82 403.0 Sr Strontium [Kr] 5s² 87.62 38 +2 0.95 549.5 Cs Caesium [Xe] 6s¹ 132.91 55 +1 0.79 375.7 Ba Barium [Xe] 6s² 137.33 56 +2 0.89 502.9 Fr Francium [Rn] 7s¹ (223) 87 +1 0.70 380.0 Ra Radium [Rn] 7s² (226) 88 +2 0.90 509.3 Sc Scandium [Ar] 3d¹ 4s² 44.956 21 +3+2+1 1.36 633.1 Y Yttrium [Kr] 4d¹ 5s² 88.906 39 +3+2+1 1.22 600.0 La Lanthanum [Xe] 5d¹ 6s² 138.91 57 +3+2 1.10 538.1 Ac Actinium [Rn] 6d¹ 7s² (227) 89 +3 1.10 499.0 Periodic Table of the Elements +1−1 Ce Cerium [Xe] 4f¹ 5d¹ 6s² 140.12 58 +4+3+2 1.12 534.4 Th Thorium [Rn] 6d² 7s² 232.04 90 +4+3+2 1.30 587.0 Pr [Xe] 4f³ 6s² 140.91 59 +4+3+2 1.13 527.0 Nd Neodymium [Xe] 4f⁴ 6s² 144.24 60 +3+2 1.14 533.1 Pa Protactinium [Rn] 5f² 6d¹ 7s² 231.04 91 +5+4+3 1.50 568.0 U Uranium [Rn] 5f³ 6d¹ 7s² 238.03 92 +6+5+4+3 1.38 597.6 Pm Promethium [Xe] 4f⁵ 6s² (145) 61 +3 540.0 Sm Samarium [Xe] 4f⁶ 6s² 150.36 62 1.17 544.5 Np Neptunium Neptunium [Rn] 5f⁴ 6d¹ 7s² (237) 93 +7+6+5+4+3 1.36 604.5 Pu Plutonium [Rn] 5f⁶ 7s² (244) 94 +7+6+5+4+3 1.28 584.7 Eu Europium [Xe] 4f⁷ 6s² 151.96 63 +3+2 547.1 Gd Gadolinium [Xe] 4f⁷ 5d¹ 6s² 157.25 64 +3+2+1 1.20 593.4 Am Americium [Rn] 5f⁷ 7s² (243) 95 +6+5+4+3+2 1.30 578.0 Cm Curium [Rn] 5f⁷ 6d¹ 7s² (247) 96 +4+3 1.30 581.0 Tb Terbium [Xe] 4f⁹ 6s² 158.93 65 +4+3+1 565.8 Dy Dysprosium Dysprosium [Xe] 4f¹⁰ 6s² 162.50 66 1.22 573.0 Bk Berkelium [Rn] 5f⁹ 7s² (247) 97 +4+3 1.30 601.0 Cf Californium [Rn] 5f¹⁰ 7s² (251) 98 1.30 608.0 Ho Holmium [Xe] 4f¹¹ 6s² 164.93 67 +3 1.23 581.0 Er Erbium [Xe] 4f¹² 6s² 167.26 68 +3 1.24 589.3 Es Einsteinium [Rn] 5f¹¹ 6s² (252) 99 1.30 619.0 Fm Fermium [Rn] 5f¹² 7s² (257) 100 1.30 627.0 Tm Thulium [Xe] 4f¹³ 6s² 168.93 69 1.25 596.7 Yb Ytterbium [Xe] 4f¹⁴ 6s² 173.05 70 603.4 Md Mendelevium [Rn] 5f¹³ 7s² (258) 101 1.30 635.0 No Nobelium [Rn] 5f¹⁴ 7s² (259) 102 1.30 642.0 Lu Lutetium [Xe] 4f¹⁴ 5d¹ 6s² 174.97 71 +3 1.27 523.5 Lr Lawrencium [Rn] 5f¹⁴ 7s² 7p¹ (266) 103 +3 470.0 Praseodymium +3+2 +3+2 +4+3+1 +3+2 +3+2 +3+2 +3+2 +3+2 +3+2 alkali metals alkaline earth metals post-transition metals transition metals lanthanides actinides unknown properties noble gases reactive nonmetals metalloids radioactive elements havemasses in parenthesis Fe Iron [Ar] 3d⁶ 4s² 55.845 26 +6+5+4+3+2+1−1−2 1.83 762.5 atomic number 1st ionization energy electronegativity oxidation states standard atomic weight chemical symbol name electron configuration most common are bold in kJ/mol or most stable mass number 3 2 1 Group Period 1 2 3 4 5 6 7 s d p f Electron configuration blocks Notes • 1 kJ/mol ≈ 0.0103636 eV • all elements are implied to have an oxidationstate of zero. Cl Ti Titanium [Ar] 3d² 4s² 47.867 22 +4+3+2+1−1 1.54 658.8 V Vanadium [Ar] 3d³ 4s² 50.942 23 +5+4+3+2+1−1 1.63 650.9 Zr Zirconium [Kr] 4d² 5s² 91.222 40 +4+3+2+1 1.33 640.1 Nb Niobium [Kr] 4d⁴ 5s¹ 92.906 41 +5+4+3+2−1 1.60 652.1 Hf Hafnium [Xe] 4f¹⁴ 5d² 6s² 178.49 72 +4+3+2 1.30 658.5 Ta Tantalum [Xe] 4f¹⁴ 5d³ 6s² 180.95 73 +5+4+3+2−1 1.50 761.0 Rf Rutherfordium [Rn] 5f¹⁴ 6d² 7s² [Rn] 5f¹⁴ 6d³ 7s² (267) 104 +4 580.0 Db Dubnium (268) 105 +5 Cr Chromium [Ar] 3d⁵ 4s¹ 51.996 24 +6+5+4+3+2+1−1−2 1.66 652.9 Mn Manganese [Ar] 3d⁵ 4s² 54.938 25 +7+6+5+4+3+2+1…−3 1.55 717.3 Mo Molybdenum [Kr] 4d⁵ 5s¹ 95.95 42 +6+5+4+3+2+1−1−2 2.16 684.3 Tc Technetium [Kr] 4d⁵ 5s² (97) 43 +7+6+5+4+3+2+1−1−3 1.90 702.0 W Tungsten [Xe] 4f¹⁴ 5d⁴ 6s² 183.84 74 +6+5+4+3+2+1−1−2 2.36 770.0 Re Rhenium [Xe] 4f¹⁴ 5d⁵ 6s² 186.21 75 +7+6+5+4+3+2+1−1−3 1.90 760.0 Sg Seaborgium Seaborgium (269) 106 +6 Bh Bohrium (270) 107 +7 Fe Iron [Ar] 3d⁶ 4s² 55.845 26 +6+5+4+3+2+1−1−2 1.83 762.5 Co Cobalt [Ar] 3d⁷ 4s² 58.933 27 +5+4+3+2+1−1−2 1.91 760.4 Ru Ruthenium [Kr] 4d⁷ 5s¹ 101.07 44 +8+7+6+5+4+3+2+1−2 2.20 710.2 Rh Rhodium [Kr] 4d⁸ 5s¹ 102.91 45 +6+5+4+3+2+1−1 2.28 719.7 Os Osmium [Xe] 4f¹⁴ 5d⁶ 6s² 190.23 76 +8+7+6+5+4+3+2+1−2 2.20 840.0 Ir Iridium [Xe] 4f¹⁴ 5d⁷ 6s² 192.22 77 +6+5+4+3+2+1−1−3 2.20 880.0 Hs Hassium (271) 108 +8 Mt Meitnerium (278) 109 Ni Nickel [Ar] 3d⁸ 4s² 58.693 28 +4+3+2+1−1 1.88 737.1 Cu Copper [Ar] 3d¹⁰ 4s¹ 63.546 29 +4+3+2+1 1.90 745.5 Pd Palladium [Kr] 4d¹⁰ 106.42 46 +4+2 2.20 804.4 Ag Silver Silver [Kr] 4d¹⁰ 5s¹ 107.87 47 +3+2+1 1.93 731.0 Pt Platinum [Xe] 4f¹⁴ 5d⁹ 6s¹ 195.08 78 +6+5+4+2 2.28 870.0 Au Gold [Xe] 4f¹⁴ 5d¹⁰ 6s¹ 196.97 79 +5+3+2+1−1 2.54 890.1 Ds Darmstadtium (281) 110 Rg Roentgenium Roentgenium (282) 111 Zn Zinc [Ar] 3d¹⁰ 4s² 65.38 30 +2 1.65 906.4 Ga Gallium [Ar] 3d¹⁰ 4s² 4p¹ 69.723 31 +3+2+1 1.81 578.8 Cd Cadmium [Kr] 4d¹⁰ 5s² 112.41 48 +2 1.69 867.8 In Indium [Kr] 4d¹⁰ 5s² 5p¹ 114.82 49 +3+2+1 1.78 558.3 Hg Mercury Mercury [Xe] 4f¹⁴ 5d¹⁰ 6s² 200.59 80 +4+2+1 2.00 1007.1 Tl Thallium [Xe] 4f¹⁴ 5d¹⁰ 6s² 6p¹ 204.38 81 +3+1 1.62 589.4 Cn Copernicium (285) 112 Nh Nihonium (286) 113 Ge Germanium [Ar] 3d¹⁰ 4s² 4p² 72.630 32 +4+3+2+1−4 2.01 762.0 As Arsenic [Ar] 3d¹⁰ 4s² 4p³ 74.922 33 +5+3+2−3 2.18 947.0 Sn Tin [Kr] 4d¹⁰ 5s² 5p² 118.71 50 +4+2−4 1.96 708.6 Sb Antimony [Kr] 4d¹⁰ 5s² 5p³ 121.76 51 +5+3−3 2.05 834.0 Pb Lead [Xe] 4f¹⁴ 5d¹⁰ 6s² 6p² 207.2 82 +4+2−4 2.33 715.6 Bi Bismuth [Xe] 4f¹⁴ 5d¹⁰ 6s² 6p³ 208.98 83 +5+3−3 2.02 703.0 Fl Flerovium Flerovium (289) 114 Mc Moscovium (290) 115 Se Selenium [Ar] 3d¹⁰ 4s² 4p⁴ 78.971 34 +6+4+2−2 2.55 941.0 Br Bromine [Ar] 3d¹⁰ 4s² 4p⁵ 79.904 35 +7+5+4+3+1−1 2.96 1139.9 Te Tellurium [Kr] 4d¹⁰ 5s² 5p⁴ 127.60 52 +6+5+4+2−2 2.10 869.3 I Iodine [Kr] 4d¹⁰ 5s² 5p⁵ 126.90 53 +7+5+3+1−1 2.66 1008.4 Po Polonium [Xe] 4f¹⁴ 5d¹⁰ 6s² 6p⁴ (209) 84 +6+4+2−2 2.00 812.1 At Astatine [Xe] 4f¹⁴ 5d¹⁰ 6s² 6p⁵ (210) 85 +1−1 2.20 890.0 Lv Livermorium (293) 116 Ts Tennessine 117 Kr Krypton [Ar] 3d¹⁰ 4s² 4p⁶ 83.798 36 3.00 1350.8 Xe Xenon [Kr] 4d¹⁰ 5s² 5p⁶ 131.29 54 2.60 Rn Radon [Xe] 4f¹⁴ 5d¹⁰ 6s² 6p⁶ (222) 86 1037.0 Og Oganesson Oganesson (294) 118 B Boron 1s² 2s² 2p¹ 10.81 5 +3+2+1 2.04 800.6 Al Aluminium [Ne] 3s² 3p¹ 26.982 13 +3+1 1.61 577.5 C Carbon 1s² 2s² 2p² 12.011 6 +4+3+2+1−1−2−3−4 2.55 1086.5 N Nitrogen 1s² 2s² 2p³ 14.007 7 +5+4+3+2+1−1−2−3 3.04 1402.3 Si Silicon [Ne] 3s² 3p² 28.085 14 +4+3+2+1−1−2−3−4 1.90 786.5 P Phosphorus [Ne] 3s² 3p³ 30.974 15 +5+4+3+2+1−1−2−3 2.19 1011.8 O Oxygen 1s² 2s² 2p⁴ 15.999 8 +2+1−1−2 3.44 1313.9 F Fluorine 1s² 2s² 2p⁵ 18.998 9 −1 3.98 1681.0 S Sulfur [Ne] 3s² 3p⁴ 32.06 16 +6+5+4+3+2+1−1−2 2.58 999.6 Chlorine [Ne] 3s² 3p⁵ 35.45 17 +7+6+5+4+3+2+1−1 3.16 1251.2 Ne Neon 1s² 2s² 2p⁶ 20.180 10 2080.7 Ar Argon [Ne] 3s² 3p⁶ 39.95 18 1520.6 He Helium 1s² 4.0026 2 2372.3 1170.4 +8+6+4+2 +2 6 by Robert Campion / updated 2016, 2018 5 4 7 8 9 10 11 12 13 14 15 16 17 18 (294) * * * * * * * * [Rn] 5f¹⁴ 6d⁴ 7s² [Rn] 5f¹⁴ 6d⁵ 7s² [Rn] 5f¹⁴ 6d⁶ 7s² [Rn] 5f¹⁴ 6d⁷ 7s² [Rn] 5f¹⁴ 6d⁸ 7s² [Rn] 5f¹⁴ 6d⁹ 7s² [Rn] 5f¹⁴ 6d¹⁰ 7s² [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p¹ [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p² [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p³ [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p⁴ [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p⁵ [Rn] 5f¹⁴ 6d¹⁰ 7s² 7p⁶ ` const PERIODIC_TABLE_SVG_BASE64 = Buffer.from(PERIODIC_TABLE_SVG).toString("base64") export const generatePeriodicTable: WidgetGenerator< typeof PeriodicTableWidgetPropsSchema > = async (props) => { const { alt, caption } = props const containerStyles = "display: inline-block; text-align: center;" // Always use default intrinsic SVG sizing; do not allow external width/height overrides const imgStyles = "display: block;" const captionStyles = "font-size: 0.9em; color: #555; margin-top: 4px;" const dataUrl = `data:image/svg+xml;base64,${PERIODIC_TABLE_SVG_BASE64}` const imgTag = `${alt}` const captionTag = caption ? `
${caption}
` : "" return `
${imgTag}${captionTag}
` } export type PeriodicTableWidgetProps = z.infer< typeof PeriodicTableWidgetPropsSchema >