text: import discord
  import aiohttp
  import logging
  import re
  
  from redbot.core import commands
  from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
  
  from discord.ext.commands.converter import Converter
  from discord.ext.commands.errors import BadArgument
  
  from mendeleev import element as ELEMENTS
  
  from .data import IMAGES, LATTICES, UNITS
  
  log = logging.getLogger("red.trusty-cogs.elements")
  
  
  class ElementConverter(Converter):
      """Converts a given argument to an element object"""
  
      async def convert(self, ctx, argument):
          result = None
          if argument.isdigit():
              if int(argument) > 118 or int(argument) < 1:
                  raise BadArgument("`{}` is not a valid element!".format(argument))
              result = ELEMENTS(int(argument))
          else:
              try:
                  result = ELEMENTS(argument.title())
              except:
                  raise BadArgument("`{}` is not a valid element!".format(argument))
          if not result:
              raise BadArgument("`{}` is not a valid element!".format(argument))
          return result
  
  
  class MeasurementConverter(Converter):
      """Converts a given measurement type into usable strings"""
  
      async def convert(self, ctx, argument):
          result = []
          if argument.lower() in UNITS:
              result.append(
                  (
                      argument.lower(),
                      UNITS[argument.lower()]["name"],
                      UNITS[argument.lower()]["units"],
                  )
              )
          else:
              for k, v in UNITS.items():
                  if argument.lower() in v["name"].lower():
                      result.append((k, v["name"], v["units"]))
                  elif argument.lower() in k:
                      result.append((k, v["name"], v["units"]))
          if not result:
              raise BadArgument("`{}` is not a valid measurement!".format(argument))
          return result
  
  
  class Elements(commands.Cog):
      """Display information from the periodic table of elements"""
  
      __version__ = "1.0.1"
      __author__ = "TrustyJAID"
  
      def __init__(self, bot):
          self.bot = bot
  
      @staticmethod
      def get_lattice_string(element):
          if element.lattice_structure:
              name, link = LATTICES[element.lattice_structure]
              return "[{}]({})".format(name, link)
          else:
              return ""
  
      @staticmethod
      def get_xray_wavelength(element):
          try:
              ka = 1239.84 / (
                  13.6057 * ((element.atomic_number - 1) ** 2) * ((1 / 1 ** 2) - (1 / 2 ** 2))
              )
          except:
              ka = ""
          try:
              kb = 1239.84 / (
                  13.6057 * ((element.atomic_number - 1) ** 2) * ((1 / 1 ** 2) - (1 / 3 ** 2))
              )
          except:
              kb = ""
          try:
              la = 1239.84 / (
                  13.6057 * ((element.atomic_number - 7.4) ** 2) * ((1 / 1 ** 2) - (1 / 2 ** 3))
              )
          except:
              la = ""
          try:
              lb = 1239.84 / (
                  13.6057 * ((element.atomic_number - 7.4) ** 2) * ((1 / 1 ** 2) - (1 / 2 ** 4))
              )
          except:
              lb = ""
  
          data = "Kα {:.2}".format(ka) if ka else ""
          extra_1 = "Kβ {:.2}".format(kb) if kb else ""
          extra_2 = "Lα {:.2}".format(la) if la else ""
          extra_3 = "Lβ {:.2}".format(lb) if lb else ""
          return ", ".join(x for x in [data, extra_1, extra_2, extra_3] if x)
  
      @commands.command()
      @commands.bot_has_permissions(embed_links=True)
      async def element(
          self, ctx, element: ElementConverter, measurement: MeasurementConverter = None
      ):
          """
              Display information about an element
  
              `element` can be the name, symbol or atomic number of the element
              `measurement` can be any of the Elements data listed here
              https://mendeleev.readthedocs.io/en/stable/data.html#electronegativities
          """
          if measurement is None:
              await ctx.send(embed=await self.element_embed(element))
          else:
              msg = f"{element.name}: "
              for m in measurement:
                  extra_1 = ""
                  extra_2 = ""
                  data = getattr(element, m[0], "")
                  if m[0] == "lattice_structure":
                      extra_1, extra_2 = LATTICES[element.lattice_structure]
                  if m[0] == "xrf":
                      extra_2 = self.get_xray_wavelength(element)
  
                  msg += f"{m[1]} {data} {extra_1} {extra_2} {m[2]}\n"
              await ctx.send(msg)
  
      @commands.command()
      @commands.bot_has_permissions(embed_links=True)
      async def elements(self, ctx, *elements: ElementConverter):
          """
              Display information about multiple elements
  
              `elements` can be the name, symbol or atomic number of the element
              separated by spaces
          """
          if not elements:
              elements = [ELEMENTS(e) for e in range(1, 119)]
          await menu(ctx, [await self.element_embed(e) for e in elements], DEFAULT_CONTROLS)
  
      @commands.command()
      @commands.bot_has_permissions(embed_links=True)
      async def ptable(self, ctx):
          """Display a menu of all elements"""
          embeds = [await self.element_embed(ELEMENTS(e)) for e in range(1, 119)]
          await menu(ctx, embeds, DEFAULT_CONTROLS)
  
      async def element_embed(self, element):
          embed = discord.Embed(url=f"https://en.wikipedia.org/wiki/{element.name}")
          embed.title = f"{element.name} ({element.symbol}) - {element.atomic_number}"
          embed.description = ("{desc}\n\n{sources}\n\n{uses}").format(
              name=element.name, desc=element.description, sources=element.sources, uses=element.uses
          )
          if element.name in IMAGES:
              embed.set_thumbnail(url=IMAGES[element.name]["image"])
          if element.cpk_color:
              embed.colour = int(element.cpk_color.replace("#", ""), 16)
          attributes = {
              "atomic_weight": ("Atomic Weight", ""),
              "melting_point": ("Melting Point", "K"),
              "boiling_point": ("Boiling Point", "K"),
              "density": ("Density", "g/cm³"),
              "abundance_crust": ("Abundance in the Crust", "mg/kg"),
              "abundance_sea": ("Abundance in the Sea", "mg/L"),
              "name_origin": ("Name Origin", ""),
              "lattice_structure": ("Crystal Lattice", self.get_lattice_string(element)),
          }
          for attr, name in attributes.items():
              x = getattr(element, attr, "")
              if x:
                  embed.add_field(name=name[0], value=f"{x} {name[1]}")
          embed.add_field(name="X-ray Fluorescence", value=self.get_xray_wavelength(element))
          discovery = (
              f"{element.discoverers} ({element.discovery_year}) in {element.discovery_location}"
          )
          embed.add_field(name="Discovery", value=discovery)
  
          return embed
  