from bfs.bfs10143.bfs10147 import LicensingError
from copy import copy
from decorator import decorator
from errno import ESRCH as bfs10455, EACCES as bfs10457
from helium.bfs10155.bfs10157 import bfs10160
from helium.bfs10155.bfs10171 import bfs10200
from helium.bfs10143.bfs10147 import bfs10201
from helium.bfs10143.bfs10221 import bfs10251, bfs10252
from helium.bfs10413 import bfs10436, bfs10420, bfs10437, bfs10445
from helium.bfs10063.bfs10450 import bfs10453
from helium.bfs10063.bfs10454 import bfs10456
from helium.bfs10063.system import bfs10163, bfs10164, bfs10162, bfs10167, bfs10165
from helium.bfs10063.bfs10146 import lower, predicate, bfs10154
from inspect import getargspec, ismethod, isfunction
from logging import getLogger
from os import access, X_OK
from os.path import exists
from selenium.common.exceptions import UnexpectedAlertPresentException, ElementNotVisibleException, MoveTargetOutOfBoundsException, WebDriverException, StaleElementReferenceException, NoAlertPresentException, NoSuchWindowException
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver import Firefox, Chrome, Ie, DesiredCapabilities, ChromeOptions
from time import sleep, time
import atexit
import re
@decorator
def bfs10466(bfs10104, self, *args, **bfs10461):
  driver = self.bfs10460()
  if (driver.bfs10426() and AlertImpl(driver).exists()):
    return bfs10104(self, *args, **bfs10461)

  bfs10462 = driver.window_handles[:]
  bfs10464 = bfs10104(self, *args, **bfs10461)
  if (not (driver.bfs10426() and AlertImpl(driver).exists())):
    bfs10463 = [bfs10465 for bfs10465 in driver.window_handles if (bfs10465 not in bfs10462) ]
    if bfs10463:
      driver.switch_to.window(bfs10463[0])


  return bfs10464

@decorator
def bfs10471(bfs10104, *args, **bfs10467):
  try:
    return bfs10104(*args, **bfs10467)
  except UnexpectedAlertPresentException:
    raise UnexpectedAlertPresentException("This command is not supported when an alert is present. To accept the alert (this usually corresponds to clicking 'OK') use `Alert().accept()`. To dismiss the alert (ie. 'cancel' it), use `Alert().dismiss()`. If the alert contains a text field, you can use write(...) to set its value. Eg.: `write('hi there!')`.")


class APIImpl(object):
  bfs10470 = 'This operation requires a browser window. Please call one of the following functions first:\n * start_chrome()\n * start_firefox()\n * start_ie()\n * set_driver(...)'
  def __init__(self, bfs10472, bfs10473, bfs10474=None):
    self.bfs10472 = bfs10472
    self.license = bfs10473
    self.bfs10474 = bfs10474
    self.driver = None

  def bfs10475(self, url=None):
    capabilities = DesiredCapabilities.FIREFOX.copy()
    capabilities['unexpectedAlertBehaviour'] = 'ignore'
    firefox = Firefox(capabilities=capabilities)
    return self.bfs10476(firefox, url)

  def bfs10506(self, url=None):
    bfs10477 = self.bfs10500()
    bfs10501 = ChromeOptions()
    bfs10501.add_argument('--test-type')
    bfs10503 = {'chrome_options': bfs10501}
    if exists(bfs10477):
      if (not access(bfs10477, X_OK)):
        try:
          bfs10456(bfs10477)
        except:
          raise RuntimeError(('The Chrome driver located at %s is not executable.' % bfs10477))


      getLogger(__name__).info('Using Chrome driver located at %s.', bfs10477)
      bfs10503['executable_path'] = bfs10477
    else:
      getLogger(__name__).warn('Could not find Chrome driver at expected location %s.', bfs10477)

    bfs10200()
    bfs10502 = Chrome(**bfs10503)
    atexit.register(self.bfs10504, bfs10502.service)
    return self.bfs10476(bfs10502, url)

  def bfs10500(self):
    if bfs10163():
      bfs10505 = 'chromedriver.exe'
    elif bfs10164():
      bfs10505 = ('chromedriver' + ('_x64' if bfs10167() else ''))
    else:
      assert bfs10162()
      bfs10505 = 'chromedriver'

    return self.bfs10472.bfs10507(bfs10165(), 'webdrivers', bfs10505)

  def bfs10504(self, service):
    if hasattr(service, 'process'):
      try:
        service.process.kill()
      except OSError, e:
        if (e.errno not in (bfs10455, bfs10457)):
          raise 




  def bfs10515(self, url=None):
    bfs10511 = self.bfs10472.bfs10507('win', 'webdrivers', 'IEDriverServer.exe')
    capabilities = DesiredCapabilities.INTERNETEXPLORER.copy()
    capabilities['ignoreZoomSetting'] = True
    bfs10510 = {'capabilities': capabilities}
    if exists(bfs10511):
      getLogger(__name__).info('Using IE driver located at %s.', bfs10511)
      bfs10510['executable_path'] = bfs10511
    else:
      getLogger(__name__).warn('Could not find IE driver at expected location %s.', bfs10511)

    try:
      bfs10512 = Ie(**bfs10510)
    except WebDriverException, e:
      bfs10513 = e
      msg = e.msg
      if ('Protected Mode settings are not the same for all zones.' in msg):
        bfs10513 = WebDriverException('Error launching IE: Protected Mode settings are not the same for all zones. Please follow these steps: http://heliumhq.com/docs/internet_explorer#protected_mode')

      raise bfs10513

    atexit.register(self.bfs10504, bfs10512.iedriver)
    return self.bfs10476(bfs10512, url)

  def bfs10476(self, bfs10514, url=None):
    try:
      self.bfs10516(bfs10514)
    except LicensingError:
      bfs10514.quit()
      raise 

    if (url is not None):
      self.bfs10517(url)

    return self.bfs10520()

  @bfs10466
  @bfs10471
  def bfs10517(self, url):
    if ('://' not in url):
      url = ('http://' + url)

    self.bfs10460().get(url)

  def bfs10516(self, driver):
    self.bfs10521(driver)
    self.driver = bfs10420(driver)

  def bfs10521(self, driver):
    try:
      self.license.bfs10523(bfs10251(self.bfs10474))
    except bfs10201:
      try:
        self.license.bfs10523(bfs10252(self.bfs10474, driver))
      except bfs10201:
        raise LicensingError('Unfortunately, Helium could not verify your license key. Please activate your internet connection and try again.')



  def bfs10520(self):
    if (self.driver is not None):
      return self.driver.unwrap()


  @bfs10466
  @bfs10471
  def bfs10526(self, text, into=None):
    if (into is not None):
      from helium.api import GUIElement
      if isinstance(into, GUIElement):
        into = into.bfs10522


    self.bfs10524(self.bfs10525, self.bfs10527, text, into=into)

  def bfs10525(self, text, into=None):
    if into:
      if isinstance(into, basestring):
        into = TextFieldImpl(self.bfs10460(), into)

      def bfs10531(bfs10530):
        if (hasattr(bfs10530, 'clear') and callable(bfs10530.clear)):
          bfs10530.clear()

        bfs10530.send_keys(text)

      self.bfs10532(into, bfs10531)
    else:
      self.bfs10460().switch_to.active_element.send_keys(text)


  def bfs10527(self, text, into=None):
    if (into is None):
      into = AlertImpl(self.bfs10460())

    if (not isinstance(into, AlertImpl)):
      raise UnexpectedAlertPresentException(('into=%r is not allowed when an alert is present.' % into))

    into.bfs10531(text)

  def bfs10524(self, bfs10534, bfs10533, *args, **bfs10535):
    driver = self.bfs10460()
    if (driver.bfs10427() or (not AlertImpl(driver).exists())):
      try:
        return bfs10534(*args, **bfs10535)
      except UnexpectedAlertPresentException:
        if (driver.bfs10427() and (not AlertImpl(driver).exists())):
          raise RuntimeError("An alert dialog was open but was closed by an expected exception. This normally happens when you called set_driver(...) with a Firefox driver you instantiated yourself without first setting selenium.webdriver.common.desired_capabilities.DesiredCapabilities.FIREFOX['unexpectedAlertBehaviour'] to 'ignore'. If this is not the case, please file a bug report at http://heliumhq.com.")



    return bfs10533(*args, **bfs10535)

  @bfs10466
  @bfs10471
  def bfs10536(self, key):
    self.bfs10460().switch_to.active_element.send_keys(key)

  def bfs10541(self, element):
    self.bfs10540(element, (lambda bfs10537: bfs10537.click()))

  def bfs10540(self, element, bfs10543, bfs10542=None):
    if (bfs10542 is None):
      bfs10542 = bfs10543

    element = self.bfs10544(element)
    self.bfs10546(element, bfs10543, bfs10542)

  def bfs10544(self, bfs10530):
    from helium.api import HTMLElement
    if isinstance(bfs10530, basestring):
      bfs10530 = bfs10545(self.bfs10460(), bfs10530)
    elif isinstance(bfs10530, HTMLElement):
      bfs10530 = bfs10530.bfs10522

    return bfs10530

  @bfs10466
  @bfs10471
  def bfs10546(self, element, bfs10547, bfs10550):
    offset = None
    from helium.api import Point
    if isinstance(element, Point):
      (element, offset) = self.bfs10551(element)

    if (offset is not None):
      bfs10421 = (lambda bfs10552: bfs10550(self.bfs10460().bfs10421().move_to_element_with_offset(bfs10552, *offset)).perform())
    else:
      bfs10421 = bfs10547

    self.bfs10532(element, bfs10421)

  def bfs10551(self, bfs10553):
    driver = self.bfs10460()
    element = bfs10436(driver.execute_script(('return document.elementFromPoint(%r, %r);' % (bfs10553.x, bfs10553.y))))
    offset = (bfs10553 - (element.location.bfs10257, element.location.bfs10261))
    if ((offset == (0, 0)) and driver.bfs10427()):
      offset = (1, 1)

    return (element, offset)

  def bfs10556(self, element):
    driver = self.bfs10460()
    self.bfs10540(element, (lambda bfs10555: driver.bfs10421().double_click(bfs10555).perform()), (lambda bfs10554: bfs10554.double_click()))

  def bfs10561(self, element, to):
    self.bfs10560(element)
    self.bfs10557(to)

  def bfs10560(self, element):
    driver = self.bfs10460()
    self.bfs10540(element, (lambda bfs10562: driver.bfs10421().click_and_hold(bfs10562).perform()), (lambda bfs10563: bfs10563.click_and_hold()))

  def bfs10557(self, element):
    bfs10565 = self.bfs10460()
    self.bfs10540(element, (lambda bfs10564: bfs10565.bfs10421().move_to_element(bfs10564).release().perform()), (lambda bfs10566: bfs10566.release()))

  @bfs10471
  def bfs10570(self, predicate):
    return [predicate.bfs10567(bfs10571) for bfs10571 in predicate.bfs10522.find_all()]

  def bfs10573(self, num_pixels):
    self.bfs10572(0, num_pixels)

  def bfs10574(self, num_pixels):
    self.bfs10572(0, (-num_pixels))

  def bfs10576(self, num_pixels):
    self.bfs10572(num_pixels, 0)

  def bfs10575(self, num_pixels):
    self.bfs10572((-num_pixels), 0)

  @bfs10471
  def bfs10572(self, bfs10577, bfs10600):
    self.bfs10460().execute_script('window.scrollBy(arguments[0], arguments[1]);', bfs10577, bfs10600)

  def bfs10603(self, element):
    driver = self.bfs10460()
    self.bfs10540(element, (lambda bfs10601: driver.bfs10421().move_to_element(bfs10601).perform()), (lambda bfs10602: bfs10602))

  def bfs10606(self, element):
    driver = self.bfs10460()
    self.bfs10540(element, (lambda bfs10605: driver.bfs10421().context_click(bfs10605).perform()), (lambda bfs10604: bfs10604.context_click()))

  @bfs10466
  @bfs10471
  def bfs10607(self, combo_box, value):
    from helium.api import ComboBox
    if isinstance(combo_box, basestring):
      combo_box = ComboBoxImpl(self.bfs10460(), combo_box)
    elif isinstance(combo_box, ComboBox):
      combo_box = combo_box.bfs10522

    def bfs10610(web_element):
      Select(web_element).select_by_visible_text(value)

    self.bfs10532(combo_box, bfs10610)

  def bfs10532(self, bfs10611, bfs10421):
    driver = self.bfs10460()
    if (hasattr(bfs10611, 'perform') and callable(bfs10611.perform)):
      driver.bfs10417 = bfs10611.perform(bfs10421)
    else:
      if isinstance(bfs10611, WebElement):
        bfs10611 = bfs10436(bfs10611)

      bfs10421(bfs10611)
      driver.bfs10417 = bfs10611


  @bfs10471
  def bfs10616(self, file_path, to):
    to = self.bfs10544(to)
    drag_and_drop = bfs10612(self.bfs10460(), file_path)
    drag_and_drop.begin()
    try:
      drag_and_drop.bfs10613()
      self.bfs10532(to, (lambda bfs10615: drag_and_drop.bfs10614(bfs10615)))
    finally:
      drag_and_drop.end()


  def bfs10622(self, file_path, to=None):
    driver = self.bfs10460()
    if (to is None):
      to = bfs10617(driver)
    elif isinstance(to, basestring):
      to = bfs10617(driver, to)

    bfs10621 = (lambda bfs10620: bfs10620.send_keys(file_path))
    self.bfs10546(to, bfs10621, bfs10621)

  def bfs10625(self):
    self.bfs10524(self.bfs10624, self.bfs10623)

  def bfs10624(self):
    self.bfs10460().refresh()

  def bfs10623(self):
    AlertImpl(self.bfs10460()).accept()
    self.bfs10624()

  def bfs10632(self, condition_fn, timeout_secs=10, interval_secs=0.5):
    if ismethod(condition_fn):
      bfs10626 = (condition_fn.im_self is not None)
      bfs10627 = getargspec(condition_fn).args
      bfs10631 = (len(bfs10627) - (1 if bfs10626 else 0))
    else:
      if (not isfunction(condition_fn)):
        condition_fn = condition_fn.__call__

      bfs10627 = getargspec(condition_fn).args
      bfs10631 = len(bfs10627)

    bfs10630 = (condition_fn if bfs10631 else (lambda driver: condition_fn()))
    wait = WebDriverWait(self.bfs10460().unwrap(), timeout_secs, poll_frequency=interval_secs)
    wait.until(bfs10630)

  @bfs10471
  def bfs10633(self, window):
    driver = self.bfs10460()
    from helium.api import Window
    if isinstance(window, basestring):
      window = WindowImpl(driver, window)
    elif isinstance(window, Window):
      window = window.bfs10522

    driver.switch_to.window(window.handle)

  def bfs10635(self):
    self.bfs10460().quit()
    self.driver = None

  @bfs10471
  def bfs10636(self, element):
    driver = self.bfs10460()
    from helium.api import HTMLElement, Text
    if isinstance(element, basestring):
      element = Text(element)

    if isinstance(element, HTMLElement):
      element = element.bfs10522

    try:
      element = element.first_occurrence
    except AttributeError:
      pass

    if isinstance(element, bfs10436):
      element = element.unwrap()

    bfs10634 = element.get_attribute('style')
    driver.execute_script("arguments[0].setAttribute('style', 'border: 2px solid red; font-weight: bold;');", element)
    driver.execute_script("var target = arguments[0];var previousStyle = arguments[1];setTimeout(function() {target.setAttribute('style', previousStyle);}, 2000);", element, bfs10634)

  def bfs10460(self):
    if (not self.driver):
      raise RuntimeError(self.bfs10470)

    return self.driver


class bfs10612(object):
  def __init__(self, driver, file_path):
    self.driver = driver
    self.file_path = file_path
    self.bfs10637 = None
    self.bfs10641 = None

  def begin(self):
    self.bfs10640()
    try:
      self.bfs10637.send_keys(self.file_path)
    except:
      self.end()
      raise 


  def bfs10640(self):
    self.bfs10637 = self.driver.execute_script("var input = document.createElement('input');input.type = 'file';input.style.display = 'block';input.style.opacity = '1';input.style.visibility = 'visible';input.style.height = '1px';input.style.width = '1px';if (document.body.childElementCount > 0) {   document.body.insertBefore(input, document.body.childNodes[0]);} else {   document.body.appendChild(input);}return input;")

  def bfs10613(self):
    self.bfs10642('dragenter', to='document.body')
    self.bfs10641 = self.bfs10643('dragover', 'document', interval_msecs=300)
    self.bfs10641.start()

  def bfs10642(self, bfs10645, to):
    (bfs10644, args) = self.bfs10646(bfs10645, to)
    self.driver.execute_script(bfs10644, *args)

  def bfs10643(self, bfs10647, to, interval_msecs):
    (bfs10650, args) = self.bfs10646(bfs10647, to)
    return bfs10651(self.driver, bfs10650, args, interval_msecs)

  def bfs10646(self, bfs10653, to):
    bfs10652 = "var files = arguments[0].files;var items = [];var types = [];for (var i = 0; i < files.length; i++) {   items[i] = {kind: 'file', type: files[i].type};   types[i] = 'Files';}var event = document.createEvent('CustomEvent');event.initCustomEvent(arguments[1], true, true, 0);event.dataTransfer = {\tfiles: files,\titems: items,\ttypes: types};arguments[2].dispatchEvent(event);"
    if isinstance(to, basestring):
      bfs10652 = bfs10652.replace('arguments[2]', to)
      args = (self.bfs10637, bfs10653)
    else:
      args = (self.bfs10637, bfs10653, to.unwrap())

    return (bfs10652, args)

  def bfs10614(self, target):
    self.bfs10641.stop()
    self.bfs10642('drop', to=target)

  def end(self):
    if (self.bfs10637 is not None):
      self.driver.execute_script('arguments[0].parentNode.removeChild(arguments[0]);', self.bfs10637)

    self.bfs10637 = None


class bfs10651(object):
  def __init__(self, driver, bfs10654, args, interval_msecs):
    self.driver = driver
    self.bfs10654 = bfs10654
    self.args = args
    self.interval_msecs = interval_msecs
    self.bfs10656 = None

  def start(self):
    bfs10655 = ('var originalArguments = arguments;return setInterval(function() {\targuments = originalArguments;\t%s}, %d);' % (self.bfs10654, self.interval_msecs))
    self.bfs10656 = self.driver.execute_script(bfs10655, *self.args)

  def stop(self):
    self.driver.execute_script('clearInterval(arguments[0]);', self.bfs10656)
    self.bfs10656 = None


class bfs10657(object):
  def __init__(self, driver):
    self.bfs10660 = None
    self.bfs10661 = driver

  def find_all(self):
    if self.bfs10662():
      yield self
    else:
      for bfs10663 in self.bfs10665():
        yield self.bfs10664(bfs10663)



  def bfs10662(self):
    return (self.bfs10660 is not None)

  def bfs10665(self):
    raise NotImplementedError()

  def bfs10664(self, bfs10666):
    bfs10670 = copy(self)
    bfs10670.bfs10660 = bfs10666
    return bfs10670

  def exists(self):
    try:
      next(self.find_all())
    except StopIteration:
      return False
    else:
      return True


  @property
  def first_occurrence(self):
    if (not self.bfs10662()):
      self.bfs10667()

    return self.bfs10660

  def bfs10667(self):
    self.perform((lambda bfs10671: None))

  def perform(self, bfs10421):
    from helium.api import Config
    bfs10672 = (time() + Config.implicit_wait_secs)
    bfs10674 = self.bfs10673(bfs10421)
    while ((bfs10674 is None) and (time() < bfs10672)):
      bfs10674 = self.bfs10673(bfs10421)

    if (bfs10674 is not None):
      return bfs10674

    raise LookupError()

  def bfs10673(self, bfs10421):
    for bfs10675 in self.find_all():
      bfs10677 = bfs10675.first_occurrence
      try:
        bfs10421(bfs10677)
      except Exception, e:
        if self.bfs10676(e):
          continue
        else:
          raise 

      else:
        self.bfs10660 = bfs10677
        return bfs10677



  def bfs10676(self, exception):
    if isinstance(exception, ElementNotVisibleException):
      return True

    if isinstance(exception, MoveTargetOutOfBoundsException):
      return True

    if isinstance(exception, WebDriverException):
      msg = exception.msg
      if (('Element is not clickable at point' in msg) and ('Other element would receive the click' in msg)):
        getLogger(__name__).info('Ignoring exception %r while trying to click element. It could be that the element has moved.', msg, exc_info=True)
        return True


    return False


class bfs10700(bfs10657):
  def __init__(self, driver, below=None, to_right_of=None, above=None, to_left_of=None):
    super(bfs10700, self).__init__(driver)
    self.below = self.bfs10702(below)
    self.to_right_of = self.bfs10702(to_right_of)
    self.above = self.bfs10702(above)
    self.to_left_of = self.bfs10702(to_left_of)
    self.bfs10701 = bfs10160()

  def bfs10702(self, element):
    if isinstance(element, basestring):
      return TextImpl(self.bfs10661, element)

    from helium.api import HTMLElement
    if isinstance(element, HTMLElement):
      return element.bfs10522

    return element

  @property
  def width(self):
    return self.first_occurrence.location.width

  @property
  def height(self):
    return self.first_occurrence.location.height

  @property
  def x(self):
    return self.first_occurrence.location.bfs10257

  @property
  def y(self):
    return self.first_occurrence.location.bfs10261

  @property
  def top_left(self):
    from helium.api import Point
    return Point(self.x, self.y)

  @property
  def web_element(self):
    return self.first_occurrence.unwrap()

  def bfs10665(self):
    self.bfs10703()
    bfs10705 = self.bfs10704()
    try:
      for bfs10706 in bfs10437(self.bfs10661):
        for bfs10707 in self.bfs10711():
          if self.bfs10710(bfs10707, bfs10705):
            yield bfs10707



    except bfs10445:
      pass


  def bfs10703(self):
    window_handles = self.bfs10661.window_handles
    try:
      bfs10712 = self.bfs10661.current_window_handle
    except NoSuchWindowException:
      bfs10714 = True
    else:
      bfs10714 = (bfs10712 not in window_handles)

    if bfs10714:
      self.bfs10661.switch_to_window(window_handles[0])


  def bfs10704(self):
    bfs10674 = []
    if self.below:
      bfs10674.append(map((lambda bfs10713: bfs10713.location.is_above), self.below.bfs10665()))

    if self.to_right_of:
      bfs10674.append(map((lambda bfs10715: bfs10715.location.is_to_left_of), self.to_right_of.bfs10665()))

    if self.above:
      bfs10674.append(map((lambda bfs10717: bfs10717.location.is_below), self.above.bfs10665()))

    if self.to_left_of:
      bfs10674.append(map((lambda bfs10716: bfs10716.location.is_to_right_of), self.to_left_of.bfs10665()))

    return bfs10674

  def bfs10710(self, bfs10720, bfs10722):
    return (bfs10720.is_displayed() and self.bfs10721(bfs10720, bfs10722))

  def bfs10721(self, element, bfs10723):
    for bfs10724 in bfs10723:
      bfs10725 = False
      for bfs10727 in bfs10724:
        if bfs10727(element.location):
          bfs10725 = True
          break


      if (not bfs10725):
        return False


    return True

  def bfs10711(self):
    raise NotImplementedError()

  def bfs10726(self):
    return (self.first_occurrence.get_attribute('disabled') is None)


class SImpl(bfs10700):
  def __init__(self, driver, bfs10730, **bfs10731):
    super(SImpl, self).__init__(driver, **bfs10731)
    self.bfs10730 = bfs10730

  def bfs10711(self):
    wrap = (lambda bfs10733: map(bfs10436, bfs10733))
    if self.bfs10730.startswith('@'):
      return wrap(self.bfs10661.find_elements_by_name(self.bfs10730[1:]))

    if self.bfs10730.startswith('//'):
      return wrap(self.bfs10661.find_elements_by_xpath(self.bfs10730))

    return wrap(self.bfs10661.find_elements_by_css_selector(self.bfs10730))


class bfs10732(bfs10700):
  def bfs10711(self):
    bfs10734 = self.bfs10735()
    getLogger(__name__).debug('Looking for HTML element using xpath: %s.', bfs10734)
    return self.bfs10736(map(bfs10436, self.bfs10661.find_elements_by_xpath(bfs10734)))

  def bfs10736(self, bfs10740):
    bfs10737 = []
    for bfs10741 in bfs10740:
      try:
        key = self.bfs10742(bfs10741)
      except StaleElementReferenceException:
        pass
      else:
        bfs10737.append((key, bfs10741))


    bfs10744 = (lambda bfs10743: bfs10743[0])
    bfs10737.sort(key=bfs10744)
    bfs10745 = (lambda bfs10746: bfs10746[1])
    return map(bfs10745, bfs10737)

  def bfs10735(self):
    raise NotImplementedError()

  def bfs10742(self, web_element):
    return (self.bfs10661.bfs10422(web_element) + 1)


class bfs10750(bfs10732):
  def __init__(self, driver, text=None, **bfs10747):
    super(bfs10750, self).__init__(driver, **bfs10747)
    self.search_text = text

  def bfs10735(self):
    bfs10751 = (('//' + self.bfs10752()) + predicate(self.bfs10701.bfs10146('.', self.search_text)))
    return ('%s[not(self::script)][not(.%s)]' % (bfs10751, bfs10751))

  def bfs10752(self):
    return '*'


class TextImpl(bfs10750):
  def __init__(self, driver, text=None, include_free_text=True, **bfs10754):
    super(TextImpl, self).__init__(driver, text, **bfs10754)
    self.include_free_text = include_free_text

  @property
  def value(self):
    return self.first_occurrence.text

  def bfs10735(self):
    bfs10753 = [(super(TextImpl, self).bfs10735() + '[not(self::option)]'), ButtonImpl(self.bfs10661, self.search_text).bfs10755(), LinkImpl(self.bfs10661, self.search_text).bfs10735()]
    if self.include_free_text:
      bfs10753.append(bfs10756(self.bfs10661, self.search_text).bfs10735())

    return ' | '.join(bfs10753)


class bfs10756(bfs10750):
  def bfs10752(self):
    return 'text()'

  def bfs10735(self):
    return (super(bfs10756, self).bfs10735() + '/..')


class LinkImpl(bfs10750):
  def bfs10752(self):
    return 'a'

  def bfs10735(self):
    return ((((((super(LinkImpl, self).bfs10735() + ' | ') + '//a') + predicate(self.bfs10701.bfs10146('@title', self.search_text))) + ' | ') + "//*[@role='link']") + predicate(self.bfs10701.bfs10146('.', self.search_text)))


class ListItemImpl(bfs10750):
  def bfs10752(self):
    return 'li'


class ButtonImpl(bfs10750):
  def bfs10752(self):
    return 'button'

  def is_enabled(self):
    bfs10757 = self.first_occurrence.get_attribute('aria-disabled')
    return (self.bfs10726() and ((not bfs10757) or (bfs10757.lower() == 'false')))

  def bfs10735(self):
    bfs10760 = self.bfs10701.bfs10146('@aria-label', self.search_text)
    bfs10762 = self.bfs10701.bfs10146('.', self.search_text)
    bfs10761 = bfs10154(bfs10760, bfs10762)
    return ' | '.join([super(ButtonImpl, self).bfs10735(), self.bfs10755(), ("//*[@role='button']" + bfs10761), ('//button' + predicate(bfs10760))])

  def bfs10755(self):
    if self.search_text:
      bfs10763 = self.bfs10701.bfs10146('@value', self.search_text)
      bfs10765 = self.bfs10701.bfs10146('@label', self.search_text)
      bfs10764 = self.bfs10701.bfs10146('@aria-label', self.search_text)
      bfs10766 = self.bfs10701.bfs10146('@title', self.search_text)
      bfs10770 = bfs10154(bfs10763, bfs10765, bfs10764, bfs10766)
    else:
      bfs10770 = ''

    return ("//input[@type='submit' or @type='button']" + bfs10770)


class ImageImpl(bfs10732):
  def __init__(self, driver, alt, **bfs10767):
    super(ImageImpl, self).__init__(driver, **bfs10767)
    self.alt = alt

  def bfs10735(self):
    return ('//img' + predicate(self.bfs10701.bfs10146('@alt', self.alt)))


class bfs10771(bfs10700):
  bfs10772 = 1.5
  def __init__(self, driver, label=None, **bfs10773):
    super(bfs10771, self).__init__(driver, **bfs10773)
    self.label = label

  def bfs10711(self):
    if (not self.label):
      bfs10775 = self.bfs10774()
    else:
      bfs10776 = TextImpl(self.bfs10661, self.label, include_free_text=False).bfs10711()
      if bfs10776:
        bfs10775 = list(self.bfs11000(self.bfs10774(), bfs10776))
      else:
        bfs10775 = self.bfs10777()


    return sorted(bfs10775, key=self.bfs10661.bfs10422)

  def bfs10774(self, bfs11001=None):
    if (bfs11001 is None):
      bfs11001 = self.bfs10735()

    return map(bfs10436, self.bfs10661.find_elements_by_xpath(bfs11001))

  def bfs10777(self):
    bfs11002 = [bfs10146.strip().lstrip('/') for bfs10146 in self.bfs10735().split('|')]
    bfs11004 = ('//text()' + predicate(self.bfs10701.bfs10146('.', self.label)))
    bfs10146 = ' | '.join([(((bfs11004 + '/following::') + bfs11003) + '[1]') for bfs11003 in bfs11002])
    return self.bfs10774(bfs10146)

  def bfs10735(self):
    raise NotImplementedError()

  def bfs11005(self):
    return 'to_right_of'

  def bfs11007(self):
    return 'below'

  def bfs11000(self, bfs11006, bfs11010):
    for (label, bfs11012) in self.bfs11011(bfs11006, bfs11010):
      yield bfs11012
      bfs11010.remove(label)
      bfs11006.remove(bfs11012)

    bfs11013 = self.bfs11014(bfs11006, bfs11010)
    bfs11013 = self.bfs11015(bfs11013)
    self.bfs11016(bfs11013)
    for bfs11020 in bfs11013.values():
      assert (len(bfs11020) <= 1)
      if bfs11020:
        yield next(iter(bfs11020))



  def bfs11011(self, bfs11017, bfs11021):
    for label in bfs11021:
      if (label.tag_name == 'label'):
        bfs11023 = label.get_attribute('for')
        if bfs11023:
          for bfs11022 in bfs11017:
            bfs11024 = bfs11022.get_attribute('id')
            if (bfs11024.lower() == bfs11023.lower()):
              yield (label, bfs11022)






  def bfs11014(self, bfs11025, bfs11026):
    bfs11027 = {}
    for label in bfs11026:
      for bfs11031 in bfs11025:
        if self.bfs11030(bfs11031, label):
          if (label not in bfs11027):
            bfs11027[label] = set()

          bfs11027[label].add(bfs11031)



    return bfs11027

  def bfs11030(self, bfs11032, label):
    if bfs11032.location.bfs10323(label.location):
      return True

    bfs11033 = self.bfs11005()
    bfs11034 = self.bfs11007()
    return ((label.location.bfs10351(bfs11032.location) <= 150) and (bfs11032.location.bfs10340(bfs11033, label.location) or bfs11032.location.bfs10340(bfs11034, label.location)))

  def bfs11015(self, bfs11036):
    bfs11035 = bfs10453(bfs11036)
    self.bfs11016(bfs11035)
    return bfs10453(bfs11035)

  def bfs11016(self, bfs11037):
    for (bfs11040, bfs11042) in bfs11037.items():
      if bfs11042:
        bfs11037[bfs11040] = set([self.bfs11041(bfs11040, bfs11042)])



  def bfs11041(self, bfs11043, bfs11044):
    bfs11045 = iter(bfs11044)
    bfs11047 = next(bfs11045)
    bfs11046 = self.bfs11050(bfs11047, bfs11043)
    for element in bfs11045:
      bfs11051 = self.bfs11050(element, bfs11043)
      if (bfs11051 < bfs11046):
        bfs11047 = element
        bfs11046 = bfs11051


    return bfs11047

  def bfs11050(self, bfs11053, bfs11052):
    bfs11054 = bfs11053.location
    bfs11056 = bfs11052.location
    if bfs11054.bfs10340(self.bfs11007(), bfs11056):
      bfs11055 = self.bfs10772
    else:
      bfs11055 = 1

    return (bfs11055 * bfs11054.bfs10351(bfs11056))


class bfs11057(bfs10700):
  def __init__(self, driver, *args, **bfs10106):
    super(bfs11057, self).__init__(driver, **bfs10106)
    self.args = ([driver] + list(args))
    self.bfs10106 = bfs10106
    self.bfs11061 = None

  @property
  def bfs11060(self):
    if (self.bfs11061 is None):
      self.bfs10667()

    return self.bfs11061

  def find_all(self):
    bfs11062 = []
    for element in self.bfs11064():
      for bfs11063 in element.find_all():
        if (self.bfs11061 is None):
          self.bfs11061 = element

        if (bfs11063 not in bfs11062):
          yield bfs11063
          bfs11062.append(bfs11063)




  def bfs11064(self):
    for bfs11065 in self.bfs11067():
      yield bfs11065(*self.args, **self.bfs10106)


  def bfs11067(self):
    raise NotImplementedError()


class bfs10545(bfs11057):
  def __init__(self, driver, text, **bfs11066):
    super(bfs10545, self).__init__(driver, text, **bfs11066)

  def bfs11067(self):
    return [ButtonImpl, TextImpl, ImageImpl]


class TextFieldImpl(bfs11057):
  def __init__(self, driver, label=None, **bfs11070):
    super(TextFieldImpl, self).__init__(driver, label, **bfs11070)

  def bfs11067(self):
    return [bfs11071, bfs11073, bfs11072]

  @property
  def value(self):
    return self.bfs11060.value

  def is_enabled(self):
    return self.bfs11060.is_enabled()

  def is_editable(self):
    return self.bfs11060.is_editable()


class bfs11073(bfs10771):
  @property
  def value(self):
    return (self.first_occurrence.get_attribute('value') or '')

  def is_enabled(self):
    return self.bfs10726()

  def is_editable(self):
    return (self.first_occurrence.get_attribute('readOnly') is None)

  def bfs10735(self):
    return (("//input[%s='text' or %s='email' or %s='password' or %s='number' or %s='tel' or string-length(@type)=0]" % ((lower('@type'),) * 5)) + " | //textarea | //*[@contenteditable='true']")


class bfs11072(bfs10771):
  @property
  def value(self):
    return self.first_occurrence.text

  def is_enabled(self):
    return self.bfs10726()

  def is_editable(self):
    return (self.first_occurrence.get_attribute('readOnly') is None)

  def bfs10735(self):
    return "//*[@role='textbox']"


class bfs11071(bfs10732):
  def __init__(self, driver, label, **bfs11074):
    super(bfs11071, self).__init__(driver, **bfs11074)
    self.label = label

  @property
  def value(self):
    return (self.first_occurrence.get_attribute('value') or '')

  def is_enabled(self):
    return self.bfs10726()

  def is_editable(self):
    return (self.first_occurrence.get_attribute('readOnly') is None)

  def bfs10735(self):
    return ('(%s)%s' % (bfs11073(self.label).bfs10735(), predicate(self.bfs10701.bfs10146('@placeholder', self.label))))


class bfs10617(bfs10771):
  def bfs10735(self):
    return "//input[@type='file']"


class ComboBoxImpl(bfs11057):
  def __init__(self, driver, label=None, **bfs11075):
    super(ComboBoxImpl, self).__init__(driver, label, **bfs11075)

  def bfs11067(self):
    return [bfs11077, bfs11076]

  def is_editable(self):
    return (self.first_occurrence.tag_name != 'select')

  @property
  def value(self):
    bfs11100 = self.bfs11102.first_selected_option
    if bfs11100:
      return bfs11100.text

    return None

  @property
  def options(self):
    return [bfs11101.text for bfs11101 in self.bfs11102.options]

  @property
  def bfs11102(self):
    return Select(self.web_element)


class bfs11077(bfs10771):
  def bfs10735(self):
    return '//select | //input[@list]'


class bfs11076(bfs10750):
  def bfs10752(self):
    return 'option'

  def bfs10735(self):
    bfs11103 = super(bfs11076, self).bfs10735()
    return (bfs11103 + '/ancestor::select[1]')

  def bfs10711(self):
    bfs11104 = super(bfs11076, self).bfs10711()
    bfs11105 = []
    for bfs11107 in bfs11104:
      for bfs11106 in Select(bfs11107.unwrap()).all_selected_options:
        if self.bfs10701.text(bfs11106.text, self.search_text):
          bfs11105.append(bfs11107)
          break



    return bfs11105


class CheckBoxImpl(bfs10771):
  def is_enabled(self):
    return self.bfs10726()

  def is_checked(self):
    return (self.first_occurrence.get_attribute('checked') is not None)

  def bfs10735(self):
    return "//input[@type='checkbox']"

  def bfs11005(self):
    return 'to_left_of'

  def bfs11007(self):
    return 'to_right_of'


class RadioButtonImpl(bfs10771):
  def is_selected(self):
    return (self.first_occurrence.get_attribute('checked') is not None)

  def bfs10735(self):
    return "//input[@type='radio']"

  def bfs11005(self):
    return 'to_left_of'

  def bfs11007(self):
    return 'to_right_of'


class WindowImpl(bfs10657):
  def __init__(self, driver, title=None):
    super(WindowImpl, self).__init__(driver)
    self.bfs11110 = title

  def bfs10665(self):
    bfs11112 = []
    for handle in self.bfs10661.window_handles:
      window = WindowImpl.bfs11111(self.bfs10661, handle)
      if (self.bfs11110 is None):
        bfs11112.append((0, window))
      else:
        title = window.title
        if title.startswith(self.bfs11110):
          bfs11113 = (len(title) - len(self.bfs11110))
          bfs11112.append((bfs11113, window))



    bfs11113 = (lambda bfs11115: bfs11115[0])
    bfs11112.sort(key=bfs11113)
    for (bfs11113, window) in bfs11112:
      yield window


  @property
  def title(self):
    return self.first_occurrence.title

  @property
  def handle(self):
    return self.first_occurrence.handle

  class bfs11111(object):
    def __init__(self, driver, handle):
      self.driver = driver
      self.handle = handle
      self.bfs11114 = None

    @property
    def title(self):
      with self:
        return self.driver.title


    def __enter__(self):
      self.bfs11114 = self.driver.current_window_handle
      if (self.driver.current_window_handle != self.handle):
        self.driver.switch_to.window(self.handle)


    def __exit__(self, *bfs11116):
      if (self.driver.current_window_handle != self.bfs11114):
        self.driver.switch_to.window(self.bfs11114)




class AlertImpl(bfs10657):
  def __init__(self, driver, search_text=None):
    super(AlertImpl, self).__init__(driver)
    self.search_text = search_text

  def bfs10665(self):
    bfs11117 = self.bfs10661.switch_to.alert
    try:
      text = bfs11117.text
      if ((self.search_text is None) or text.startswith(self.search_text)):
        yield bfs11117

    except NoAlertPresentException:
      pass


  @property
  def text(self):
    return self.first_occurrence.text

  def accept(self):
    first_occurrence = self.first_occurrence
    try:
      first_occurrence.accept()
    except WebDriverException, e:
      msg = e.msg
      if (msg and re.match('a\\.document\\.getElementsByTagName\\([^\\)]*\\)\\[0\\] is undefined', msg)):
        getLogger(__name__).warn('Got %r when trying to accept alert. Trying again after 0.25s.', e)
        sleep(0.25)
        first_occurrence.accept()
      else:
        raise 



  def dismiss(self):
    self.first_occurrence.dismiss()

  def bfs10531(self, text):
    self.first_occurrence.send_keys(text)


