docs: def calculate(ctx, slot, challenge, totp, digits):
      """
      Perform a challenge-response operation.
  
      Send a challenge (in hex) to a YubiKey slot with a challenge-response
      credential, and read the response. Supports output as a OATH-TOTP code.
      """
      controller = ctx.obj['controller']
      if not challenge and not totp:
          ctx.fail('No challenge provided.')
  
      # Check that slot is not empty
      slot1, slot2 = controller.slot_status
      if (slot == 1 and not slot1) or (slot == 2 and not slot2):
          ctx.fail('Cannot perform challenge-response on an empty slot.')
  
      # Timestamp challenge should be int
      if challenge and totp:
          try:
              challenge = int(challenge)
          except Exception as e:
              logger.error('Error', exc_info=e)
              ctx.fail('Timestamp challenge for TOTP must be an integer.')
      try:
          res = controller.calculate(
              slot, challenge, totp=totp,
              digits=int(digits), wait_for_touch=False)
      except YkpersError as e:
          # Touch is set
          if e.errno == 11:
              prompt_for_touch()
              try:
                  res = controller.calculate(
                      slot, challenge, totp=totp,
                      digits=int(digits), wait_for_touch=True)
              except YkpersError as e:
                  # Touch timed out
                  if e.errno == 4:
                      ctx.fail('The YubiKey timed out.')
                  else:
                      ctx.fail(e)
          else:
              ctx.fail('Failed to calculate challenge.')
      click.echo(res)