Java Code Examples for org.openqa.selenium.chrome.ChromeOptions#setBinary()

The following examples show how to use org.openqa.selenium.chrome.ChromeOptions#setBinary() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TestChromeDriver.java    From selenium with Apache License 2.0 6 votes vote down vote up
private static ChromeOptions chromeWithCustomCapabilities(Capabilities originalCapabilities) {
  ChromeOptions options = new ChromeOptions();
  options.addArguments("disable-extensions", "disable-infobars", "disable-breakpad");
  Map<String, Object> prefs = new HashMap<>();
  prefs.put("exit_type", "None");
  prefs.put("exited_cleanly", true);
  options.setExperimentalOption("prefs", prefs);
  String chromePath = System.getProperty("webdriver.chrome.binary");
  if (chromePath != null) {
    options.setBinary(new File(chromePath));
  }

  if (originalCapabilities != null) {
    options.merge(originalCapabilities);
  }

  return options;
}
 
Example 2
Source File: ChromeDevice.java    From agent with MIT License 6 votes vote down vote up
@Override
protected Capabilities newCaps(Capabilities capsToMerge) {
    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.addArguments("--ignore-certificate-errors");
    chromeOptions.addArguments("no-default-browser-check");

    // **** 以上capabilities可被传入的caps覆盖 ****

    chromeOptions.merge(capsToMerge);

    // **** 以下capabilities具有更高优先级,将覆盖传入的caps ****

    if (!StringUtils.isEmpty(browser.getPath())) {
        chromeOptions.setBinary(browser.getPath());
    }

    return chromeOptions;
}
 
Example 3
Source File: WebDriverCreator.java    From webtau with Apache License 2.0 6 votes vote down vote up
private static ChromeDriver createChromeDriver() {
    ChromeOptions options = new ChromeOptions();

    if (BrowserConfig.getChromeBinPath() != null) {
        options.setBinary(BrowserConfig.getChromeBinPath().toFile());
    }

    if (BrowserConfig.getChromeDriverPath() != null) {
        System.setProperty(CHROME_DRIVER_PATH_KEY, BrowserConfig.getChromeDriverPath().toString());
    }

    if (BrowserConfig.isHeadless()) {
        options.addArguments("--headless");
        options.addArguments("--disable-gpu");
    }

    if (System.getProperty(CHROME_DRIVER_PATH_KEY) == null) {
        setupDriverManagerConfig();
        downloadDriverMessage("chrome");
        WebDriverManager.chromedriver().setup();
    }

    return new ChromeDriver(options);
}
 
Example 4
Source File: IndexStep.java    From charles-rest with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * Use Google Chrome headless to fetch the content.
 * @return WebDriver.
 */
protected WebDriver chromeDriver() {
    final ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary("/usr/bin/google-chrome-stable");
    chromeOptions.addArguments("--headless");
    chromeOptions.addArguments("--no-sandbox");
    chromeOptions.addArguments("--ignore-certificate-errors");

    final DesiredCapabilities dc = new DesiredCapabilities();
    dc.setJavascriptEnabled(true);
    dc.setCapability(
        ChromeOptions.CAPABILITY, chromeOptions
    );
    WebDriver chrome = new ChromeDriver(dc);
    return chrome;
}
 
Example 5
Source File: BotWorker.java    From JYTB with GNU General Public License v3.0 5 votes vote down vote up
private void setChromeDriver() {
        ChromeOptions options = new ChromeOptions();
        List<String> chromeOptions = new ArrayList<>();
        LoggingPreferences logPrefs = new LoggingPreferences();

        chromeOptions.add(String.format("--proxy-server=%s", proxies.getCurrentProxyModel().getIp()));
        chromeOptions.add(String.format("--user-agent=%s", userAgent.randomUA()));
        chromeOptions.add("--mute-audio");

        logPrefs.enable(LogType.BROWSER, Level.ALL);
        logPrefs.enable(LogType.PERFORMANCE, Level.INFO);
        options.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);

        options.addArguments(chromeOptions);
        options.setBinary(this.driverLocation);
        options.setHeadless(true);
//        options.setProxy(this.proxies.getCurrentProxy());
        options.setCapability("proxy", this.proxies.getCurrentProxy());

        this.webDriver = new ChromeDriver(options);
        Log.WINFO(this.workerName, this.workerColor, "Chrome Driver Set.");
    }
 
Example 6
Source File: ElectronImpl.java    From frameworkium-core with Apache License 2.0 5 votes vote down vote up
@Override
public ChromeOptions getCapabilities() {
    if (!APP_PATH.isSpecified()) {
        throw new IllegalStateException(
                "App path must be specified when using Electron!");
    }

    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary(APP_PATH.getValue());
    return chromeOptions;
}
 
Example 7
Source File: ChromiumTest.java    From webdrivermanager with Apache License 2.0 5 votes vote down vote up
@Before
public void setupTest() {
    File chromium = new File(getChromiumBinary());
    assumeTrue(chromium.exists());

    ChromeOptions options = new ChromeOptions();
    options.setBinary(chromium);
    driver = new ChromeDriver(options);
}
 
Example 8
Source File: SitemapXmlCrawlITCase.java    From charles with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private WebDriver webDriver() {
	final ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary(System.getProperty("google.chrome"));
    chromeOptions.addArguments("--headless");
    chromeOptions.addArguments("--disable-gpu");
    final DesiredCapabilities dc = new DesiredCapabilities();
    dc.setJavascriptEnabled(true);
    dc.setCapability(
        ChromeOptions.CAPABILITY, chromeOptions
    );
    return new ChromeDriver(dc);

}
 
Example 9
Source File: LiveWebPageITCase.java    From charles with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private WebDriver webDriver() {
	final ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary(System.getProperty("google.chrome"));
    chromeOptions.addArguments("--headless");
    chromeOptions.addArguments("--disable-gpu");
    final DesiredCapabilities dc = new DesiredCapabilities();
    dc.setJavascriptEnabled(true);
    dc.setCapability(
        ChromeOptions.CAPABILITY, chromeOptions
    );
    return new ChromeDriver(dc);
}
 
Example 10
Source File: GraphCrawlITCase.java    From charles with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private WebDriver webDriver() {
    final ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary(System.getProperty("google.chrome"));
    chromeOptions.addArguments("--headless");
    chromeOptions.addArguments("--disable-gpu");
    final DesiredCapabilities dc = new DesiredCapabilities();
    dc.setJavascriptEnabled(true);
    dc.setCapability(
        ChromeOptions.CAPABILITY, chromeOptions
    );
    return new ChromeDriver(dc);
}
 
Example 11
Source File: EdgeDevTest.java    From webdrivermanager-examples with Apache License 2.0 5 votes vote down vote up
@Before
public void setupTest() {
    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary(
            "C:\\Program Files (x86)\\Microsoft\\Edge Dev\\Application\\msedge.exe");
    EdgeOptions edgeOptions = new EdgeOptions().merge(chromeOptions);
    driver = new EdgeDriver(edgeOptions);
}
 
Example 12
Source File: ChromeDriverOptions.java    From functional-tests-core with Apache License 2.0 5 votes vote down vote up
public ChromeOptions loadChromeDriverOptions(WebSettings webSettings) {
    ChromeOptions options = new ChromeOptions();

    if (webSettings.platform == PlatformType.VSCode) {
        options.setBinary(this.getFileLocation("code"));
    } else {
    }

    //String chromeDriverFullPath = OSUtils.runProcess("which chromedriver");
    //System.setProperty("webdriver.chrome.driver", "/usr/local/Cellar/chromedriver/2.22/bin/chromedriver");

    return options;
}
 
Example 13
Source File: ChromeDriverHandler.java    From selenium-jupiter with Apache License 2.0 5 votes vote down vote up
@Override
public MutableCapabilities getOptions(Parameter parameter,
        Optional<Object> testInstance)
        throws IOException, IllegalAccessException {
    ChromeOptions chromeOptions = new ChromeOptions();

    if (parameter != null) {
        // @Arguments
        Arguments arguments = parameter.getAnnotation(Arguments.class);
        if (arguments != null) {
            stream(arguments.value()).forEach(chromeOptions::addArguments);
        }

        // @Extensions
        Extensions extensions = parameter.getAnnotation(Extensions.class);
        if (extensions != null) {
            for (String extension : extensions.value()) {
                chromeOptions.addExtensions(getExtension(extension));
            }
        }

        // @Binary
        Binary binary = parameter.getAnnotation(Binary.class);
        if (binary != null) {
            chromeOptions.setBinary(binary.value());
        }

        // @Options
        ChromeOptions optionsFromAnnotatedField = annotationsReader
                .getFromAnnotatedField(testInstance, Options.class,
                        ChromeOptions.class);
        if (optionsFromAnnotatedField != null) {
            chromeOptions = optionsFromAnnotatedField.merge(chromeOptions);
        }
    }

    return chromeOptions;
}
 
Example 14
Source File: LambdaWebDriverFactory.java    From lambda-selenium with MIT License 5 votes vote down vote up
private ChromeOptions getLambdaChromeOptions() {
    ChromeOptions options = new ChromeOptions();
    options.setBinary(getLibLocation("chrome"));
    options.addArguments("--disable-gpu");
    options.addArguments("--headless");
    options.addArguments("--window-size=1366,768");
    options.addArguments("--single-process");
    options.addArguments("--no-sandbox");
    options.addArguments("--user-data-dir=/tmp/user-data");
    options.addArguments("--data-path=/tmp/data-path");
    options.addArguments("--homedir=/tmp");
    options.addArguments("--disk-cache-dir=/tmp/cache-dir");
    return options;
}
 
Example 15
Source File: WebDriverTypeTests.java    From vividus with Apache License 2.0 5 votes vote down vote up
@Test
@PrepareForTest(fullyQualifiedNames = "org.vividus.selenium.WebDriverType$3")
public void testGetChromeWebDriverWithAdditionalOptions() throws Exception
{
    Map<String, String> experimentalOptionValue = singletonMap(OPTION_KEY, OPTION_VALUE);
    WebDriverConfiguration configuration = new WebDriverConfiguration();
    configuration.setBinaryPath(Optional.of(PATH));
    configuration.setCommandLineArguments(new String[] { ARGUMENT });
    configuration.setExperimentalOptions(singletonMap(MOBILE_EMULATION, experimentalOptionValue));
    ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setBinary(PATH);
    chromeOptions.addArguments(ARGUMENT);
    chromeOptions.setExperimentalOption(MOBILE_EMULATION, experimentalOptionValue);
    testGetChromeWebDriver(configuration, chromeOptions);
}
 
Example 16
Source File: BrowserService.java    From collect-earth with MIT License 4 votes vote down vote up
private RemoteWebDriver startChromeBrowser() throws BrowserNotFoundException {

		final Properties props = System.getProperties();
		String chromedriverExe = null;
		if (StringUtils.isBlank(props.getProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY))) {
			if (SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_MAC_OSX) {
				chromedriverExe = "resources/chromedriver_mac";
			} else if (SystemUtils.IS_OS_UNIX) {
				chromedriverExe = "resources/chromedriver64";
			} else if (SystemUtils.IS_OS_WINDOWS) {
				chromedriverExe = "resources/chromedriver.exe";
			} else {
				throw new BrowserNotFoundException("Chromedriver is not supported in the current OS");
			}
			props.setProperty(ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY, chromedriverExe);
		}

		String chromeBinaryPath = localPropertiesService.getValue(EarthProperty.CHROME_BINARY_PATH);

		// Handle the special case when the user picks the Chrome or Firefox app files
		// for Mac
		if ((SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_MAC_OSX)
				&& (chromeBinaryPath.toLowerCase().endsWith("google chrome.app")
						|| chromeBinaryPath.toLowerCase().endsWith("chrome.app"))) {
			chromeBinaryPath = chromeBinaryPath + "/Contents/MacOS/Google Chrome";
		}

		ChromeOptions chromeOptions = new ChromeOptions();
		chromeOptions.addArguments("disable-infobars");
		chromeOptions.addArguments("disable-save-password-bubble");

		if (!StringUtils.isBlank(chromeBinaryPath)) {
			try {
				chromeOptions.setBinary(chromeBinaryPath);
			} catch (final WebDriverException e) {
				logger.error(
						"The chrome executable chrome.exe cannot be found, please edit earth.properties and correct the chrome.exe location at "
								+ EarthProperty.CHROME_BINARY_PATH + " pointing to the full path to chrome.exe",
								e);
			}
		}

		return new ChromeDriver(chromeOptions);

	}
 
Example 17
Source File: DockerDriverHandler.java    From selenium-jupiter with Apache License 2.0 4 votes vote down vote up
private DesiredCapabilities getCapabilities(BrowserInstance browserInstance,
        boolean enableVnc) throws IllegalAccessException, IOException {
    DesiredCapabilities capabilities = browserInstance.getCapabilities();
    if (enableVnc) {
        capabilities.setCapability("enableVNC", true);
        capabilities.setCapability("screenResolution",
                getConfig().getVncScreenResolution());
    }

    if (getConfig().isRecording() || getConfig().isRecordingWhenFailure()) {
        capabilities.setCapability("enableVideo", true);
        capabilities.setCapability("videoScreenSize",
                getConfig().getRecordingVideoScreenSize());
        capabilities.setCapability("videoFrameRate",
                getConfig().getRecordingVideoFrameRate());
    }

    Optional<Capabilities> optionalCapabilities = annotationsReader != null
            ? annotationsReader.getCapabilities(parameter, testInstance)
            : Optional.of(new DesiredCapabilities());
    MutableCapabilities options = browserInstance.getDriverHandler()
            .getOptions(parameter, testInstance);

    // Due to bug in operablink the binary path must be set
    if (browserInstance.getBrowserType() == OPERA
            && browserVersion.equals("62.0")) {
        String operaBinaryPathLinux = getConfig().getOperaBinaryPathLinux();
        ((OperaOptions) options).setBinary(operaBinaryPathLinux);
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.setBinary(operaBinaryPathLinux);

        OperaOptions operaOptions = new OperaOptions().merge(chromeOptions);
        operaOptions.setCapability("browserName", OPERA_NAME);
        options.merge(operaOptions);
        log.trace("Opera options: {}", options);
    }

    if (optionalCapabilities.isPresent()) {
        options.merge(optionalCapabilities.get());
    }
    capabilities.setCapability(browserInstance.getOptionsKey(), options);
    log.trace("Using {}", capabilities);
    return capabilities;
}
 
Example 18
Source File: DriverFactory.java    From NoraUi with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
 * Generates a chrome webdriver.
 *
 * @return
 *         A chrome webdriver
 * @throws TechnicalException
 *             if an error occured when Webdriver setExecutable to true.
 */
private WebDriver generateGoogleChromeDriver() throws TechnicalException {
    final String pathWebdriver = DriverFactory.getPath(Driver.CHROME);
    if (!new File(pathWebdriver).setExecutable(true)) {
        throw new TechnicalException(Messages.getMessage(TechnicalException.TECHNICAL_ERROR_MESSAGE_WEBDRIVER_SET_EXECUTABLE));
    }
    log.info("Generating Chrome driver ({}) ...", pathWebdriver);

    System.setProperty(Driver.CHROME.getDriverName(), pathWebdriver);

    final ChromeOptions chromeOptions = new ChromeOptions();
    chromeOptions.setCapability(CapabilityType.ForSeleniumServer.ENSURING_CLEAN_SESSION, true);
    chromeOptions.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR, UnexpectedAlertBehaviour.ACCEPT);
    chromeOptions.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
    chromeOptions.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, true);

    setLoggingLevel(chromeOptions);
    chromeOptions.addArguments("--ignore-certificate-errors");

    if (Context.isHeadless()) {
        chromeOptions.addArguments("--headless");
    }

    // Proxy configuration
    if (Context.getProxy().getProxyType() != ProxyType.UNSPECIFIED && Context.getProxy().getProxyType() != ProxyType.AUTODETECT) {
        chromeOptions.setCapability(CapabilityType.PROXY, Context.getProxy());
    }

    // add Modifyheader Extensions to Chrome
    if (Context.getWebdriversProperties(MODIFYHEADER_PATH) != null && !"".equals(Context.getWebdriversProperties(MODIFYHEADER_PATH))) {
        chromeOptions.addExtensions(new File(Context.getWebdriversProperties(MODIFYHEADER_PATH)));
    }

    // Set custom downloaded file path. When you check content of downloaded file by robot.
    final HashMap<String, Object> chromePrefs = new HashMap<>();
    chromePrefs.put("download.default_directory", System.getProperty(USER_DIR) + File.separator + DOWNLOADED_FILES_FOLDER);
    chromeOptions.setExperimentalOption("prefs", chromePrefs);

    // Set custom chromium (if you not use default chromium on your target device)
    final String targetBrowserBinaryPath = Context.getWebdriversProperties(TARGET_BROWSER_BINARY_PATH);
    if (targetBrowserBinaryPath != null && !"".equals(targetBrowserBinaryPath)) {
        chromeOptions.setBinary(targetBrowserBinaryPath);
    }

    log.info("addArguments [{}] to webdriver.", Context.getWebdriversProperties(WEBDRIVER_OPTIONS_ADDITIONAL_ARGS));
    for (String additionalArgument : Context.getWebdriversProperties(WEBDRIVER_OPTIONS_ADDITIONAL_ARGS).split(",")) {
        log.info("addArgument [{}] to webdriver.", additionalArgument);
        chromeOptions.addArguments(additionalArgument);
    }

    if (Context.getWebdriversProperties(REMOTE_WEBDRIVER_URL) != null && !"".equals(Context.getWebdriversProperties(REMOTE_WEBDRIVER_URL))
            && Context.getWebdriversProperties(REMOTE_WEBDRIVER_BROWSER_VERSION) != null && !"".equals(Context.getWebdriversProperties(REMOTE_WEBDRIVER_BROWSER_VERSION))
            && Context.getWebdriversProperties(REMOTE_WEBDRIVER_PLATFORM_NAME) != null && !"".equals(Context.getWebdriversProperties(REMOTE_WEBDRIVER_PLATFORM_NAME))) {
        chromeOptions.setCapability("browserVersion", Context.getWebdriversProperties(REMOTE_WEBDRIVER_BROWSER_VERSION));
        chromeOptions.setCapability("platformName", Context.getWebdriversProperties(REMOTE_WEBDRIVER_PLATFORM_NAME));
        try {
            return new RemoteWebDriver(new URL(Context.getWebdriversProperties(REMOTE_WEBDRIVER_URL)), chromeOptions);
        } catch (MalformedURLException e) {
            throw new TechnicalException(Messages.getMessage(TechnicalException.TECHNICAL_ERROR_MESSAGE_REMOTE_WEBDRIVER_URL));
        }
    } else {
        final String withWhitelistedIps = Context.getWebdriversProperties(WITH_WHITE_LISTED_IPS);
        if (withWhitelistedIps != null && !"".equals(withWhitelistedIps)) {
            final ChromeDriverService service = new ChromeDriverService.Builder().withWhitelistedIps(withWhitelistedIps).withVerbose(false).build();
            return new ChromeDriver(service, chromeOptions);
        } else {
            return new ChromeDriver(chromeOptions);
        }
    }
}
 
Example 19
Source File: Free_ssCrawlerServiceImpl.java    From ShadowSocks-Share with Apache License 2.0 4 votes vote down vote up
@Override
public WebDriver getDriver() throws IOException {
	/*System.setProperty("webdriver.chrome.logfile", "D:\\chromedriver.log");
	System.setProperty("webdriver.chrome.verboseLogging", "true");*/

	org.openqa.selenium.chrome.ChromeDriverService service;

	if (SystemUtils.IS_OS_WINDOWS) {
		service = new org.openqa.selenium.chrome.ChromeDriverService.Builder().usingAnyFreePort()
				.usingDriverExecutable(new File("D:\\chromedriver.exe"))
				.build();
	} else {
		service = new org.openqa.selenium.chrome.ChromeDriverService.Builder().usingAnyFreePort().build();
	}

	ChromeOptions options = new ChromeOptions();

	if (SystemUtils.IS_OS_WINDOWS) {
		options.setBinary("D:\\software\\CentBrowser\\chrome.exe");
		// options.addArguments("user-data-dir=D:\\software\\CentBrowser\\User Data");
		options.addArguments("--headless");
		options.addArguments("window-size=1200x600");
		options.addArguments("--disable-gpu");
	} else {
		String binaryPath = EnvironmentUtils.getProcEnvironment().get("GOOGLE_CHROME_SHIM");
		log.debug("GOOGLE_CHROME_SHIM : {}", binaryPath);
		log.debug("GOOGLE_CHROME_BIN : {}", EnvironmentUtils.getProcEnvironment().get("GOOGLE_CHROME_BIN"));
		options.setBinary(binaryPath);
		options.addArguments("--headless");
		options.addArguments("window-size=1200x600");
		options.addArguments("--disable-gpu");
		// options.addArguments("--no-sandbox");
		// options.addArguments("--remote-debugging-port=9222");
	}

	if (ssProxyEnable) {
		String proxyServer = ssProxyHost + ":" + ssProxyPort;
		Proxy proxy = new Proxy();
		// proxy.setAutodetect(true).setProxyType(Proxy.ProxyType.MANUAL);
		if (ssSocks) {
			proxy.setSocksProxy(proxyServer);
		} else {
			proxy.setHttpProxy(proxyServer);
		}
		options.setCapability(CapabilityType.PROXY, proxy);
	}

	return new ChromeDriver(service, options);
}
 
Example 20
Source File: WebDriverHandle.java    From caja with Apache License 2.0 4 votes vote down vote up
private static RemoteWebDriver makeDriver() {
  DesiredCapabilities dc = new DesiredCapabilities();

  String browserType = TestFlag.BROWSER.getString("firefox");

  if ("chrome".equals(browserType)) {
    // Chrome driver is odd in that the path to Chrome is specified
    // by a desiredCapability when you start a session. The other
    // browser drivers will read a java system property on start.
    // This applies to both remote Chrome and local Chrome.
    ChromeOptions chromeOpts = new ChromeOptions();
    String chromeBin = TestFlag.CHROME_BINARY.getString(null);
    if (chromeBin != null) {
      chromeOpts.setBinary(chromeBin);
    }
    String chromeArgs = TestFlag.CHROME_ARGS.getString(null);
    if (chromeArgs != null) {
      String[] args = chromeArgs.split(";");
      chromeOpts.addArguments(args);
    }
    dc.setCapability(ChromeOptions.CAPABILITY, chromeOpts);
  }

  String url = TestFlag.WEBDRIVER_URL.getString("");

  if (!"".equals(url)) {
    dc.setBrowserName(browserType);
    dc.setJavascriptEnabled(true);
    try {
      return new RemoteWebDriver(new URL(url), dc);
    } catch (MalformedURLException e) {
      throw new RuntimeException(e);
    }
  } else if ("chrome".equals(browserType)) {
    return new ChromeDriver(dc);
  } else if ("firefox".equals(browserType)) {
    return new FirefoxDriver();
  } else if ("safari".equals(browserType)) {
    // TODO(felix8a): local safari doesn't work yet
    return new SafariDriver();
  } else {
    throw new RuntimeException("No local driver for browser type '"
        + browserType + "'");
  }
}