<commit_before>// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

/**
 * @fileoverview Defines a {@linkplain Driver WebDriver} client for Microsoft's
 * Internet Explorer. Before using the IEDriver, you must download the latest
 * [IEDriverServer](http://selenium-release.storage.googleapis.com/index.html)
 * and place it on your
 * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). You must also apply
 * the system configuration outlined on the Selenium project
 * [wiki](https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver)
 */

'use strict';

const fs = require('fs');
const util = require('util');

const http = require('./http');
const io = require('./io');
const portprober = require('./net/portprober');
const promise = require('./lib/promise');
const remote = require('./remote');
const webdriver = require('./lib/webdriver');
const {Browser, Capabilities, Capability} = require('./lib/capabilities');

const IEDRIVER_EXE = 'IEDriverServer.exe';

/**
 * IEDriverServer logging levels.
 * @enum {string}
 */
const Level = {
  FATAL: 'FATAL',
  ERROR: 'ERROR',
  WARN: 'WARN',
  INFO: 'INFO',
  DEBUG: 'DEBUG',
  TRACE: 'TRACE'
};

/**
 * Option keys:
 * https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#ie-specific
 * @enum {string}
 */
const Key = {
  IGNORE_PROTECTED_MODE_SETTINGS: 'ignoreProtectedModeSettings',
  IGNORE_ZOOM_SETTING: 'ignoreZoomSetting',
  INITIAL_BROWSER_URL: 'initialBrowserUrl',
  ENABLE_PERSISTENT_HOVER: 'enablePersistentHover',
  ENABLE_ELEMENT_CACHE_CLEANUP: 'enableElementCacheCleanup',
  REQUIRE_WINDOW_FOCUS: 'requireWindowFocus',
  BROWSER_ATTACH_TIMEOUT: 'browserAttachTimeout',
  FORCE_CREATE_PROCESS: 'ie.forceCreateProcessApi',
  BROWSER_COMMAND_LINE_SWITCHES: 'ie.browserCommandLineSwitches',
  USE_PER_PROCESS_PROXY: 'ie.usePerProcessProxy',
  ENSURE_CLEAN_SESSION: 'ie.ensureCleanSession',
  LOG_FILE: 'logFile',
  LOG_LEVEL: 'logLevel',
  HOST: 'host',
  EXTRACT_PATH: 'extractPath',
  SILENT: 'silent'
};

/**
 * Class for managing IEDriver specific options.
 */
class Options extends Capabilities {
  /**
   * @param {(Capabilities|Map<string, ?>|Object)=} other Another set of
   *     capabilities to initialize this instance from.
   */
  constructor(other = undefined) {
    super(other);
    this.setBrowserName(Browser.IE);
  }

  /**
   * Whether to disable the protected mode settings check when the session is
   * created. Disbling this setting may lead to significant instability as the
   * browser may become unresponsive/hang. Only "best effort" support is provided
   * when using this capability.
   *
   * For more information, refer to the IEDriver's
   * [required system configuration](http://goo.gl/eH0Yi3).
   *
   * @param {boolean} ignoreSettings Whether to ignore protected mode settings.
   * @return {!Options} A self reference.
   */
  introduceFlakinessByIgnoringProtectedModeSettings(ignoreSettings) {
    this.set(Key.IGNORE_PROTECTED_MODE_SETTINGS, !!ignoreSettings);
    return this;
  }

  /**
   * Indicates whether to skip the check that the browser's zoom level is set to
   * 100%.
   *
   * @param {boolean} ignore Whether to ignore the browser's zoom level settings.
   * @return {!Options} A self reference.
   */
  ignoreZoomSetting(ignore) {
    this.set(Key.IGNORE_ZOOM_SETTING, !!ignore);
    return this;
  }

  /**
   * Sets the initial URL loaded when IE starts. This is intended to be used with
   * {@link #ignoreProtectedModeSettings} to allow the user to initialize IE in
   * the proper Protected Mode zone. Setting this option may cause browser
   * instability or flaky and unresponsive code. Only "best effort" support is
   * provided when using this option.
   *
   * @param {string} url The initial browser URL.
   * @return {!Options} A self reference.
   */
  initialBrowserUrl(url) {
    this.set(Key.INITIAL_BROWSER_URL, url);
    return this;
  }

  /**
   * Configures whether to enable persistent mouse hovering (true by default).
   * Persistent hovering is achieved by continuously firing mouse over events at
   * the last location the mouse cursor has been moved to.
   *
   * @param {boolean} enable Whether to enable persistent hovering.
   * @return {!Options} A self reference.
   */
  enablePersistentHover(enable) {
    this.set(Key.ENABLE_PERSISTENT_HOVER, !!enable);
    return this;
  }

  /**
   * Configures whether the driver should attempt to remove obsolete
   * {@linkplain webdriver.WebElement WebElements} from its internal cache on
   * page navigation (true by default). Disabling this option will cause the
   * driver to run with a larger memory footprint.
   *
   * @param {boolean} enable Whether to enable element reference cleanup.
   * @return {!Options} A self reference.
   */
  enableElementCacheCleanup(enable) {
    this.set(Key.ENABLE_ELEMENT_CACHE_CLEANUP, !!enable);
    return this;
  }

  /**
   * Configures whether to require the IE window to have input focus before
   * performing any user interactions (i.e. mouse or keyboard events). This
   * option is disabled by default, but delivers much more accurate interaction
   * events when enabled.
   *
   * @param {boolean} require Whether to require window focus.
   * @return {!Options} A self reference.
   */
  requireWindowFocus(require) {
    this.set(Key.REQUIRE_WINDOW_FOCUS, !!require);
    return this;
  }

  /**
   * Configures the timeout, in milliseconds, that the driver will attempt to
   * located and attach to a newly opened instance of Internet Explorer. The
   * default is zero, which indicates waiting indefinitely.
   *
   * @param {number} timeout How long to wait for IE.
   * @return {!Options} A self reference.
   */
  browserAttachTimeout(timeout) {
    this.set(Key.BROWSER_ATTACH_TIMEOUT, Math.max(timeout, 0));
    return this;
  }

  /**
   * Configures whether to launch Internet Explorer using the CreateProcess API.
   * If this option is not specified, IE is launched using IELaunchURL, if
   * available. For IE 8 and above, this option requires the TabProcGrowth
   * registry value to be set to 0.
   *
   * @param {boolean} force Whether to use the CreateProcess API.
   * @return {!Options} A self reference.
   */
  forceCreateProcessApi(force) {
    this.set(Key.FORCE_CREATE_PROCESS, !!force);
    return this;
  }

  /**
   * Specifies command-line switches to use when launching Internet Explorer.
   * This is only valid when used with {@link #forceCreateProcessApi}.
   *
   * @param {...(string|!Array.<string>)} args The arguments to add.
   * @return {!Options} A self reference.
   */
  addArguments(...args) {
    let current = this.get(Key.BROWSER_COMMAND_LINE_SWITCHES) || [];
    this.set(
        Key.BROWSER_COMMAND_LINE_SWITCHES,
        current.concat.apply(current, args));
    return this;
  }

  /**
   * Configures whether proxies should be configured on a per-process basis. If
   * not set, setting a {@linkplain #setProxy proxy} will configure the system
   * proxy. The default behavior is to use the system proxy.
   *
   * @param {boolean} enable Whether to enable per-process proxy settings.
   * @return {!Options} A self reference.
   */
  usePerProcessProxy(enable) {
    this.set(Key.USE_PER_PROCESS_PROXY, !!enable);
    return this;
  }

  /**
   * Configures whether to clear the cache, cookies, history, and saved form data
   * before starting the browser. _Using this capability will clear session data
   * for all running instances of Internet Explorer, including those started
   * manually._
   *
   * @param {boolean} cleanSession Whether to clear all session data on startup.
   * @return {!Options} A self reference.
   */
  ensureCleanSession(cleanSession) {
    this.set(Key.ENSURE_CLEAN_SESSION, !!cleanSession);
    return this;
  }

  /**
   * Sets the path to the log file the driver should log to.
   * @param {string} file The log file path.
   * @return {!Options} A self reference.
   */
  setLogFile(file) {
    this.set(Key.LOG_FILE, file);
    return this;
  }

  /**
   * Sets the IEDriverServer's logging {@linkplain Level level}.
   * @param {Level} level The logging level.
   * @return {!Options} A self reference.
   */
  setLogLevel(level) {
    this.set(Key.LOG_LEVEL, level);
    return this;
  }

  /**
   * Sets the IP address of the driver's host adapter.
   * @param {string} host The IP address to use.
   * @return {!Options} A self reference.
   */
  setHost(host) {
    this.set(Key.HOST, host);
    return this;
  }

  /**
   * Sets the path of the temporary data directory to use.
   * @param {string} path The log file path.
   * @return {!Options} A self reference.
   */
  setExtractPath(path) {
    this.set(Key.EXTRACT_PATH, path);
    return this;
  }

  /**
   * Sets whether the driver should start in silent mode.
   * @param {boolean} silent Whether to run in silent mode.
   * @return {!Options} A self reference.
   */
  silent(silent) {
    this.set(Key.SILENT, silent);
    return this;
  }
}

/**
 * _Synchronously_ attempts to locate the IE driver executable on the current
 * system.
 *
 * @return {?string} the located executable, or `null`.
 */
function locateSynchronously() {
  return process.platform === 'win32'
      ? io.findInPath(IEDRIVER_EXE, true) : null;
}

function createServiceFromCapabilities(capabilities) {
  if (process.platform !== 'win32') {
    throw Error(
        'The IEDriver may only be used on Windows, but you appear to be on ' +
        process.platform + '. Did you mean to run against a remote ' +
        'WebDriver server?');
  }

  let exe = locateSynchronously();
  if (!exe || !fs.existsSync(exe)) {
    throw Error(
        `${IEDRIVER_EXE} could not be found on the current PATH. Please ` +
        `download the latest version of ${IEDRIVER_EXE} from ` +
        'http://selenium-release.storage.googleapis.com/index.html and ' +
        'ensure it can be found on your system PATH.');
  }

  var args = [];
  if (capabilities.has(Key.HOST)) {
    args.push('--host=' + capabilities.get(Key.HOST));
  }
  if (capabilities.has(Key.LOG_FILE)) {
    args.push('--log-file=' + capabilities.get(Key.LOG_FILE));
  }
  if (capabilities.has(Key.LOG_LEVEL)) {
    args.push('--log-level=' + capabilities.get(Key.LOG_LEVEL));
  }
  if (capabilities.has(Key.EXTRACT_PATH)) {
    args.push('--extract-path=' + capabilities.get(Key.EXTRACT_PATH));
  }
  if (capabilities.get(Key.SILENT)) {
    args.push('--silent');
  }

  var port = portprober.findFreePort();
  return new remote.DriverService(exe, {
    loopback: true,
    port: port,
    args: port.then(function(port) {
      return args.concat('--port=' + port);
    }),
    stdio: 'ignore'
  });
}

/**
 * Creates {@link selenium-webdriver/remote.DriverService} instances that manage
 * an [IEDriverServer](https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver)
 * server in a child process.
 */
class ServiceBuilder extends remote.DriverService.Builder {
  /**
   * @param {string=} opt_exe Path to the server executable to use. If omitted,
   *     the builder will attempt to locate the IEDriverServer on the system PATH.
   */
  constructor(opt_exe) {
    super(opt_exe || IEDRIVER_EXE);
    this.setLoopback(true);  // Required.
  }
}

/**
 * A WebDriver client for Microsoft's Internet Explorer.
 */
class Driver extends webdriver.WebDriver {
  /**
   * Creates a new session for Microsoft's Internet Explorer.
   *
   * @param {(Capabilities|Options)=} options The configuration options.
   * @param {(remote.DriverService)=} opt_service The `DriverService` to use
   *   to start the IEDriverServer in a child process, optionally.
   * @return {!Driver} A new driver instance.
   */
  static createSession(options, opt_service) {
    options = options || new Options();

    let service;

    if (opt_service instanceof remote.DriverService) {
      service = opt_service;
    } else {
      service = createServiceFromCapabilities(options);
    }

    let client = service.start().then(url => new http.HttpClient(url));
    let executor = new http.Executor(client);

    return /** @type {!Driver} */(super.createSession(
        executor, options, () => service.kill()));
  }

  /**
   * This function is a no-op as file detectors are not supported by this
   * implementation.
   * @override
   */
  setFileDetector() {}
}

// PUBLIC API

exports.Driver = Driver;
exports.Options = Options;
exports.Level = Level;
exports.ServiceBuilder = ServiceBuilder;
exports.locateSynchronously = locateSynchronously;

<commit_msg>[JS] Fixing ieOptions in JS bindings (#8152)<commit_after>// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

/**
 * @fileoverview Defines a {@linkplain Driver WebDriver} client for Microsoft's
 * Internet Explorer. Before using the IEDriver, you must download the latest
 * [IEDriverServer](http://selenium-release.storage.googleapis.com/index.html)
 * and place it on your
 * [PATH](http://en.wikipedia.org/wiki/PATH_%28variable%29). You must also apply
 * the system configuration outlined on the Selenium project
 * [wiki](https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver)
 */

'use strict';

const fs = require('fs');
const util = require('util');

const http = require('./http');
const io = require('./io');
const portprober = require('./net/portprober');
const promise = require('./lib/promise');
const remote = require('./remote');
const webdriver = require('./lib/webdriver');
const {Browser, Capabilities, Capability} = require('./lib/capabilities');

const IEDRIVER_EXE = 'IEDriverServer.exe';
const OPTIONS_CAPABILITY_KEY = 'se:ieOptions';

/**
 * IEDriverServer logging levels.
 * @enum {string}
 */
const Level = {
  FATAL: 'FATAL',
  ERROR: 'ERROR',
  WARN: 'WARN',
  INFO: 'INFO',
  DEBUG: 'DEBUG',
  TRACE: 'TRACE'
};

/**
 * Option keys:
 * https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities#ie-specific
 * @enum {string}
 */
const Key = {
  IGNORE_PROTECTED_MODE_SETTINGS: 'ignoreProtectedModeSettings',
  IGNORE_ZOOM_SETTING: 'ignoreZoomSetting',
  INITIAL_BROWSER_URL: 'initialBrowserUrl',
  ENABLE_PERSISTENT_HOVER: 'enablePersistentHover',
  ENABLE_ELEMENT_CACHE_CLEANUP: 'enableElementCacheCleanup',
  REQUIRE_WINDOW_FOCUS: 'requireWindowFocus',
  BROWSER_ATTACH_TIMEOUT: 'browserAttachTimeout',
  FORCE_CREATE_PROCESS: 'ie.forceCreateProcessApi',
  BROWSER_COMMAND_LINE_SWITCHES: 'ie.browserCommandLineSwitches',
  USE_PER_PROCESS_PROXY: 'ie.usePerProcessProxy',
  ENSURE_CLEAN_SESSION: 'ie.ensureCleanSession',
  LOG_FILE: 'logFile',
  LOG_LEVEL: 'logLevel',
  HOST: 'host',
  EXTRACT_PATH: 'extractPath',
  SILENT: 'silent'
};

/**
 * Class for managing IEDriver specific options.
 */
class Options extends Capabilities {
  /**
   * @param {(Capabilities|Map<string, ?>|Object)=} other Another set of
   *     capabilities to initialize this instance from.
   */
  constructor(other = undefined) {
    super(other);

    /** @private {!Object} */
    this.options_ = this.get(OPTIONS_CAPABILITY_KEY) || {};

    this.set(OPTIONS_CAPABILITY_KEY, this.options_);
    this.setBrowserName(Browser.INTERNET_EXPLORER);
  }

  /**
   * Whether to disable the protected mode settings check when the session is
   * created. Disabling this setting may lead to significant instability as the
   * browser may become unresponsive/hang. Only "best effort" support is provided
   * when using this capability.
   *
   * For more information, refer to the IEDriver's
   * [required system configuration](http://goo.gl/eH0Yi3).
   *
   * @param {boolean} ignoreSettings Whether to ignore protected mode settings.
   * @return {!Options} A self reference.
   */
  introduceFlakinessByIgnoringProtectedModeSettings(ignoreSettings) {
    this.options_[Key.IGNORE_PROTECTED_MODE_SETTINGS] = !!ignoreSettings;
    return this;
  }

  /**
   * Indicates whether to skip the check that the browser's zoom level is set to
   * 100%.
   *
   * @param {boolean} ignore Whether to ignore the browser's zoom level settings.
   * @return {!Options} A self reference.
   */
  ignoreZoomSetting(ignore) {
    this.options_[Key.IGNORE_ZOOM_SETTING] = !!ignore;
    return this;
  }

  /**
   * Sets the initial URL loaded when IE starts. This is intended to be used with
   * {@link #ignoreProtectedModeSettings} to allow the user to initialize IE in
   * the proper Protected Mode zone. Setting this option may cause browser
   * instability or flaky and unresponsive code. Only "best effort" support is
   * provided when using this option.
   *
   * @param {string} url The initial browser URL.
   * @return {!Options} A self reference.
   */
  initialBrowserUrl(url) {
    this.options_[Key.INITIAL_BROWSER_URL] = url;
    return this;
  }

  /**
   * Configures whether to enable persistent mouse hovering (true by default).
   * Persistent hovering is achieved by continuously firing mouse over events at
   * the last location the mouse cursor has been moved to.
   *
   * @param {boolean} enable Whether to enable persistent hovering.
   * @return {!Options} A self reference.
   */
  enablePersistentHover(enable) {
    this.options_[Key.ENABLE_PERSISTENT_HOVER] = !!enable;
    return this;
  }

  /**
   * Configures whether the driver should attempt to remove obsolete
   * {@linkplain webdriver.WebElement WebElements} from its internal cache on
   * page navigation (true by default). Disabling this option will cause the
   * driver to run with a larger memory footprint.
   *
   * @param {boolean} enable Whether to enable element reference cleanup.
   * @return {!Options} A self reference.
   */
  enableElementCacheCleanup(enable) {
    this.options_[Key.ENABLE_ELEMENT_CACHE_CLEANUP] = !!enable;
    return this;
  }

  /**
   * Configures whether to require the IE window to have input focus before
   * performing any user interactions (i.e. mouse or keyboard events). This
   * option is disabled by default, but delivers much more accurate interaction
   * events when enabled.
   *
   * @param {boolean} require Whether to require window focus.
   * @return {!Options} A self reference.
   */
  requireWindowFocus(require) {
    this.options_[Key.REQUIRE_WINDOW_FOCUS] = !!require;
    return this;
  }

  /**
   * Configures the timeout, in milliseconds, that the driver will attempt to
   * located and attach to a newly opened instance of Internet Explorer. The
   * default is zero, which indicates waiting indefinitely.
   *
   * @param {number} timeout How long to wait for IE.
   * @return {!Options} A self reference.
   */
  browserAttachTimeout(timeout) {
    this.options_[Key.BROWSER_ATTACH_TIMEOUT] = Math.max(timeout, 0);
    return this;
  }

  /**
   * Configures whether to launch Internet Explorer using the CreateProcess API.
   * If this option is not specified, IE is launched using IELaunchURL, if
   * available. For IE 8 and above, this option requires the TabProcGrowth
   * registry value to be set to 0.
   *
   * @param {boolean} force Whether to use the CreateProcess API.
   * @return {!Options} A self reference.
   */
  forceCreateProcessApi(force) {
    this.options_[Key.FORCE_CREATE_PROCESS] = !!force;
    return this;
  }

  /**
   * Specifies command-line switches to use when launching Internet Explorer.
   * This is only valid when used with {@link #forceCreateProcessApi}.
   *
   * @param {...(string|!Array.<string>)} args The arguments to add.
   * @return {!Options} A self reference.
   */
  addArguments(...args) {
    let current = this.get(Key.BROWSER_COMMAND_LINE_SWITCHES) || [];
    this.options_[Key.BROWSER_COMMAND_LINE_SWITCHES] = current.concat.apply(current, args);
    return this;
  }

  /**
   * Configures whether proxies should be configured on a per-process basis. If
   * not set, setting a {@linkplain #setProxy proxy} will configure the system
   * proxy. The default behavior is to use the system proxy.
   *
   * @param {boolean} enable Whether to enable per-process proxy settings.
   * @return {!Options} A self reference.
   */
  usePerProcessProxy(enable) {
    this.options_[Key.USE_PER_PROCESS_PROXY] = !!enable;
    return this;
  }

  /**
   * Configures whether to clear the cache, cookies, history, and saved form data
   * before starting the browser. _Using this capability will clear session data
   * for all running instances of Internet Explorer, including those started
   * manually._
   *
   * @param {boolean} cleanSession Whether to clear all session data on startup.
   * @return {!Options} A self reference.
   */
  ensureCleanSession(cleanSession) {
    this.options_[Key.ENSURE_CLEAN_SESSION] = !!cleanSession;
    return this;
  }

  /**
   * Sets the path to the log file the driver should log to.
   * @param {string} file The log file path.
   * @return {!Options} A self reference.
   */
  setLogFile(file) {
    this.options_[Key.LOG_FILE] = file;
    return this;
  }

  /**
   * Sets the IEDriverServer's logging {@linkplain Level level}.
   * @param {Level} level The logging level.
   * @return {!Options} A self reference.
   */
  setLogLevel(level) {
    this.options_[Key.LOG_LEVEL] = level;
    return this;
  }

  /**
   * Sets the IP address of the driver's host adapter.
   * @param {string} host The IP address to use.
   * @return {!Options} A self reference.
   */
  setHost(host) {
    this.options_[Key.HOST] = host;
    return this;
  }

  /**
   * Sets the path of the temporary data directory to use.
   * @param {string} path The log file path.
   * @return {!Options} A self reference.
   */
  setExtractPath(path) {
    this.options_[Key.EXTRACT_PATH] = path;
    return this;
  }

  /**
   * Sets whether the driver should start in silent mode.
   * @param {boolean} silent Whether to run in silent mode.
   * @return {!Options} A self reference.
   */
  silent(silent) {
    this.options_[Key.SILENT] = silent;
    return this;
  }
}

/**
 * _Synchronously_ attempts to locate the IE driver executable on the current
 * system.
 *
 * @return {?string} the located executable, or `null`.
 */
function locateSynchronously() {
  return process.platform === 'win32'
      ? io.findInPath(IEDRIVER_EXE, true) : null;
}

function createServiceFromCapabilities(capabilities) {
  if (process.platform !== 'win32') {
    throw Error(
        'The IEDriver may only be used on Windows, but you appear to be on ' +
        process.platform + '. Did you mean to run against a remote ' +
        'WebDriver server?');
  }

  let exe = locateSynchronously();
  if (!exe || !fs.existsSync(exe)) {
    throw Error(
        `${IEDRIVER_EXE} could not be found on the current PATH. Please ` +
        `download the latest version of ${IEDRIVER_EXE} from ` +
        'http://selenium-release.storage.googleapis.com/index.html and ' +
        'ensure it can be found on your system PATH.');
  }

  var args = [];
  if (capabilities.has(Key.HOST)) {
    args.push('--host=' + capabilities.get(Key.HOST));
  }
  if (capabilities.has(Key.LOG_FILE)) {
    args.push('--log-file=' + capabilities.get(Key.LOG_FILE));
  }
  if (capabilities.has(Key.LOG_LEVEL)) {
    args.push('--log-level=' + capabilities.get(Key.LOG_LEVEL));
  }
  if (capabilities.has(Key.EXTRACT_PATH)) {
    args.push('--extract-path=' + capabilities.get(Key.EXTRACT_PATH));
  }
  if (capabilities.get(Key.SILENT)) {
    args.push('--silent');
  }

  var port = portprober.findFreePort();
  return new remote.DriverService(exe, {
    loopback: true,
    port: port,
    args: port.then(function(port) {
      return args.concat('--port=' + port);
    }),
    stdio: 'ignore'
  });
}

/**
 * Creates {@link selenium-webdriver/remote.DriverService} instances that manage
 * an [IEDriverServer](https://github.com/SeleniumHQ/selenium/wiki/InternetExplorerDriver)
 * server in a child process.
 */
class ServiceBuilder extends remote.DriverService.Builder {
  /**
   * @param {string=} opt_exe Path to the server executable to use. If omitted,
   *     the builder will attempt to locate the IEDriverServer on the system PATH.
   */
  constructor(opt_exe) {
    super(opt_exe || IEDRIVER_EXE);
    this.setLoopback(true);  // Required.
  }
}

/**
 * A WebDriver client for Microsoft's Internet Explorer.
 */
class Driver extends webdriver.WebDriver {
  /**
   * Creates a new session for Microsoft's Internet Explorer.
   *
   * @param {(Capabilities|Options)=} options The configuration options.
   * @param {(remote.DriverService)=} opt_service The `DriverService` to use
   *   to start the IEDriverServer in a child process, optionally.
   * @return {!Driver} A new driver instance.
   */
  static createSession(options, opt_service) {
    options = options || new Options();

    let service;

    if (opt_service instanceof remote.DriverService) {
      service = opt_service;
    } else {
      service = createServiceFromCapabilities(options);
    }

    let client = service.start().then(url => new http.HttpClient(url));
    let executor = new http.Executor(client);

    return /** @type {!Driver} */(super.createSession(
        executor, options, () => service.kill()));
  }

  /**
   * This function is a no-op as file detectors are not supported by this
   * implementation.
   * @override
   */
  setFileDetector() {}
}

// PUBLIC API

exports.Driver = Driver;
exports.Options = Options;
exports.Level = Level;
exports.ServiceBuilder = ServiceBuilder;
exports.locateSynchronously = locateSynchronously;

<|endoftext|>


<commit_before>const SearchCommand = require("../types/SearchCommand");
const Discord = require("discord.js");
const ItemModel = require("../models/Item");

module.exports = class Item extends SearchCommand{
	constructor(client){
		super(client, {
			name: "item",
			category: "5e",
			help: "Searches for an item by name.",
			helpArgs: "<Item Name>",
			elevation: 0,
			timeout: 15000
		});
	}

	async execute(msg, args){	// eslint-disable-line no-unused-vars
		console.log("Entered exec");
		let prefix;
		if(msg.guild){
			prefix = await this.client.fetchPrefix(msg.guild.id);
		}
		else{
			prefix = "";
		}
		if(!args){
			return msg.reply(`invalid command; please specify an item.\nProper usage: \`${prefix}${this.name} armor of invulnerability\``);
		}
		let toEdit = await msg.reply("fetching your item. . .");
		let items = await ItemModel.find({name: new RegExp(args.join(" "), "i")});
		if(!items || items.length === 0){
			return toEdit.edit("Unable to find your item. Sorry!");
		}
		let result;
		if(items.length > 1){
			try{
				result = await super.disambiguate(toEdit, msg.author, "item", items, "name");
			}
			catch(err){
				return toEdit.edit(err);
			}
		}
		else{
			result = items[0];
		}

		let text = result.text;
		let stringBuilder = [];
		while(text.length > 1024){
			let splitIndex = text.lastIndexOf("\n", 1024);
			stringBuilder.push(text.substring(0, splitIndex));
			text = text.substring(splitIndex + 1);
		}
		stringBuilder.push(text);

		let itemMeta = [];
		itemMeta.push(`*${result.type}*`);
		if(result.dmg1){
			itemMeta.push(`${result.dmg1} ${result.dmgType}${result.property ? " - " + result.property : ""}${result.dmg2 ? " (" + result.dmg2 + ")" : ""}`);
		}

		if(result.ac){
			itemMeta.push(`*AC ${result.ac}*`);
		}

		if(result.stealth){
			itemMeta.push("*Stealth Disadvantage*");
		}
		if(result.strength){
			itemMeta.push(`*Requires ${result.strength} STR*`);
		}

		if(!result.weight && result.weight !== 0){
			itemMeta.push(`*Weight ${result.weight}*`);
		}

		if(result.value){
			itemMeta.push(`*Value ${result.value}*`);
		}

		let embed = new Discord.RichEmbed().setTitle(`__**${result.name}**__`)
											.setDescription(itemMeta.join("\n"))
											.setColor(0x97ff43);

		embed = embed.addField("Description", stringBuilder.shift());
		stringBuilder.forEach((string) => {
			embed = embed.addField("\u200b", string);
		});

		return toEdit.edit("", {embed: embed});
	}
};
<commit_msg>memes<commit_after>const SearchCommand = require("../types/SearchCommand");
const Discord = require("discord.js");
const ItemModel = require("../models/Item");

module.exports = class Item extends SearchCommand{
	constructor(client){
		super(client, {
			name: "item",
			category: "5e",
			help: "Searches for an item by name.",
			helpArgs: "<Item Name>",
			elevation: 0,
			timeout: 15000
		});
	}

	async execute(msg, args){	// eslint-disable-line no-unused-vars
		console.log("Entered exec");
		let prefix;
		if(msg.guild){
			prefix = await this.client.fetchPrefix(msg.guild.id);
		}
		else{
			prefix = "";
		}
		if(!args){
			return msg.reply(`invalid command; please specify an item.\nProper usage: \`${prefix}${this.name} armor of invulnerability\``);
		}
		let toEdit = await msg.reply("fetching your item. . .");
		let items = await ItemModel.find({name: new RegExp(args.join(" "), "i")});
		if(!items || items.length === 0){
			return toEdit.edit("Unable to find your item. Sorry!");
		}
		let result;
		if(items.length > 1){
			try{
				result = await super.disambiguate(toEdit, msg.author, "item", items, "name");
			}
			catch(err){
				return toEdit.edit(err);
			}
		}
		else{
			result = items[0];
		}

		let text = result.text;
		let stringBuilder = [];
		while(text.length > 1024){
			let splitIndex = text.lastIndexOf("\n", 1024);
			stringBuilder.push(text.substring(0, splitIndex));
			text = text.substring(splitIndex + 1);
		}
		stringBuilder.push(text);

		let itemMeta = [];
		itemMeta.push(`*${result.type}*`);
		if(result.dmg1){
			itemMeta.push(`${result.dmg1} ${result.dmgType}${result.property ? " - " + result.property : ""}${result.dmg2 ? " (" + result.dmg2 + ")" : ""}`);
		}

		if(result.ac){
			itemMeta.push(`*AC ${result.ac}*`);
		}

		if(result.stealth){
			itemMeta.push("*Stealth Disadvantage*");
		}
		if(result.strength){
			itemMeta.push(`*Requires ${result.strength} STR*`);
		}

		if(result.weight){
			itemMeta.push(`*Weight ${result.weight}*`);
		}

		if(result.value){
			itemMeta.push(`*Value ${result.value}*`);
		}

		let embed = new Discord.RichEmbed().setTitle(`__**${result.name}**__`)
											.setDescription(itemMeta.join("\n"))
											.setColor(0x97ff43);

		embed = embed.addField("Description", stringBuilder.shift());
		stringBuilder.forEach((string) => {
			embed = embed.addField("\u200b", string);
		});

		return toEdit.edit("", {embed: embed});
	}
};
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

goog.module('tink.subtle.webcrypto.EcdhTest');
goog.setTestOnly('tink.subtle.webcrypto.EcdhTest');

const Bytes = goog.require('tink.subtle.Bytes');
const Ecdh = goog.require('tink.subtle.webcrypto.Ecdh');
const EllipticCurves = goog.require('tink.subtle.EllipticCurves');
const TestCase = goog.require('goog.testing.TestCase');
const testSuite = goog.require('goog.testing.testSuite');

testSuite({
  setUp() {
    // Use a generous promise timeout for running continuously.
    TestCase.getActiveTestCase().promiseTimeout = 1000 * 1000;  // 1000s
  },

  tearDown() {
    // Reset the promise timeout to default value.
    TestCase.getActiveTestCase().promiseTimeout = 1000;  // 1s
  },

  async testComputeSharedSecret() {
    const aliceKeyPair = await Ecdh.generateKeyPair('P-256');
    const bobKeyPair = await Ecdh.generateKeyPair('P-256');
    const sharedSecret1 = await Ecdh.computeSharedSecret(
        aliceKeyPair.privateKey, bobKeyPair.publicKey);
    const sharedSecret2 = await Ecdh.computeSharedSecret(
        bobKeyPair.privateKey, aliceKeyPair.publicKey);
    assertEquals(Bytes.toHex(sharedSecret1), Bytes.toHex(sharedSecret2));
  },

  async testWycheproof_wycheproofWebcrypto() {
    // Set longer time for promiseTimout as the test sometimes takes longer than
    // 1 second in Firefox.
    await runOnWycheproofTestVectors('ecdh_webcrypto_test.json');
  },

  // Test that both public and private key are defined in the result.
  async testGenerateKeyPair() {
    const curveTypes = Object.keys(EllipticCurves.CurveType);
    for (let curve of curveTypes) {
      const curveTypeString =
          EllipticCurves.curveToString(EllipticCurves.CurveType[curve]);
      const keyPair = await Ecdh.generateKeyPair(curveTypeString);
      assertTrue(keyPair.privateKey != null);
      assertTrue(keyPair.publicKey != null);
    }
  },

  // Test that when crypto key is exported and imported it gives the same key
  // as the original one.
  async testExportImportCryptoKey() {
    const curveTypes = Object.keys(EllipticCurves.CurveType);
    for (let curve of curveTypes) {
      const curveTypeString =
          EllipticCurves.curveToString(EllipticCurves.CurveType[curve]);
      const keyPair = await Ecdh.generateKeyPair(curveTypeString);

      const publicKey = keyPair.publicKey;
      const publicCryptoKey = await Ecdh.exportCryptoKey(publicKey);
      const importedPublicKey = await Ecdh.importPublicKey(publicCryptoKey);
      assertObjectEquals(publicKey, importedPublicKey);

      const privateKey = keyPair.privateKey;
      const privateCryptoKey = await Ecdh.exportCryptoKey(privateKey);
      const importedPrivateKey = await Ecdh.importPrivateKey(privateCryptoKey);
      assertObjectEquals(privateKey, importedPrivateKey);
    }
  },

  // Test that when JSON web key is imported and exported it gives the same key
  // as the original one.
  async testImportExportJsonKey() {
    for (let testKey of TEST_KEYS) {
      const jwk = /** @type{webCrypto.JsonWebKey} */ ({
        'kty': 'EC',
        'crv': testKey.curve,
        'x': Bytes.toBase64(Bytes.fromHex(testKey.x), true),
        'y': Bytes.toBase64(Bytes.fromHex(testKey.y), true),
        'ext': true,
      });

      let importedKey;
      if (!testKey.d) {
        jwk['key_ops'] = [];
        importedKey = await Ecdh.importPublicKey(jwk);
      } else {
        jwk['key_ops'] = ['deriveKey', 'deriveBits'];
        jwk['d'] = Bytes.toBase64(Bytes.fromHex(testKey.d), true);
        importedKey = await Ecdh.importPrivateKey(jwk);
      }

      const exportedKey = await Ecdh.exportCryptoKey(importedKey);
      assertObjectEquals(jwk, exportedKey);
    }
  },
});

/**
 * Runs all test cases from the given file.
 *
 * @param {string} fileName
 */
const runOnWycheproofTestVectors = async function(fileName) {
  const testVectorFile =
      '/google3/third_party/wycheproof/testvectors/' + fileName;
  const content = await (await fetch(testVectorFile)).text();
  const testVector = JSON.parse(content);
  for (let testGroup of testVector['testGroups']) {
    let errors = '';
    for (let test of testGroup['tests']) {
      errors += await runWycheproofTest(test);
    }
    if (errors !== '') {
      fail(errors);
    }
  }
};

/**
 * Runs the test with test vector given as an input and returns either empty
 * string or a text describing the failure.
 *
 * @param {!Object} test - JSON object with test data
 * @return {!Promise<string>}
 */
const runWycheproofTest = async function(test) {
  try {
    const publicKey = await Ecdh.importPublicKey(test['public']);
    const privateKey = await Ecdh.importPrivateKey(test['private']);
    const sharedSecret = await Ecdh.computeSharedSecret(privateKey, publicKey);
    if (test['result'] === 'invalid') {
      return 'Fail on test ' + test['tcId'] + ': No exception thrown.\n';
    }
    const sharedSecretHex = Bytes.toHex(sharedSecret);
    if (sharedSecretHex !== test['shared']) {
      return 'Fail on test ' + test['tcId'] + ': unexpected result was \"' +
          sharedSecretHex + '\".\n';
    }
  } catch (e) {
    if (test['result'] === 'valid') {
      return 'Fail on test ' + test['tcId'] + ': unexpected exception \"' +
          e.toString() + '\".\n';
    }
  }
  // If the test passes return an empty string.
  return '';
};

class TestKey {
  /**
   * @param {string} curve
   * @param {string} x
   * @param {string} y
   * @param {string=} opt_d
   */
  constructor(curve, x, y, opt_d) {
    /** @const {string} */
    this.curve = curve;
    /** @const {string} */
    this.x = x;
    /** @const {string} */
    this.y = y;
    /** @const {string|undefined} */
    this.d = opt_d;
  }
}

// This set of keys was generated by Java version of Tink.
// It contains one private and one public key for each curve type supported by
// Tink.
/** {!Array<!TestKey>} */
const TEST_KEYS = [
  new TestKey(
      /* curve = */ 'P-256',
      /* x = */
      '2eab800e5d8e9b15d0f87c55324b477ffc9382d7137599e0203113a4e41b50d0',
      /* y = */
      '50bb2c11cfb72f3c380c2f93ea088d6938b91bcf581cd94a73ed0a3f623a6b8b'),
  new TestKey(
      /* curve = */ 'P-256',
      /* x = */
      '844c085cc4450297b681126356e10da074dea817f69bc2b1f3d6b1fc82593c7d',
      /* y = */
      '3cdb41fc89867d2066cc9c4f9ad7e890152bad24de20621abfe608234cbe40f1',
      /* opt_d = */
      'f96796cc28b36038817cc5d7db01c52ee0411dd848dc0833e9e26e989e4a64db'),
  new TestKey(
      /* curve = */ 'P-384',
      /* x = */
      'f3290cc80faa65e8821b0bf835f51e3431a4d78dcebd81b74c53b9b704bd995df93b648d51057a9a96a654fb8332391e',
      /* y = */
      '7e52bb9f654781a6894ef5ae77869207fa32ddbcec4a02d27ba1ead5472b3b9f39b09e9bca7d936809c143e99c655401'),
  new TestKey(
      /* curve = */ 'P-384',
      /* x = */
      'be9df79abedb82fc0e527630955f63f2f74b4984f0a4ac063a089565393ed20ac7a784f4efa434f5b1fa1837c76c8472',
      /* y = */
      'cf34ad0d4f3f2cbd546780509ec7073bb26fa0547d09ed10b83bf9b90903037ac956dbd661d02ce3e397e0547356b331',
      /* opt_d = */
      '34d86595280a8bdca23ccd60eeac9581016e895c2bc867c26dc2f99f6d0f627ce586ad36d1d2981968d8852dc9276d12'),
  new TestKey(
      /* curve = */ 'P-521',
      /* x = */
      '012f2211ec7e634919857be3066becf20c438b84ff24501712c91c98f527b44c7b001f8611935cb1179541c2b3cc3a1fc9259d50cd4842a847ea0cafe22cd75fe788',
      /* y = */
      '016b5d3f5480122643a26ef9e7c7e36875f53c28167d6afc35777d32ea76127d34287325bf14779f2e4cf3864fcc951ba601cec92b03291e34db2e815d4bd6fc2045'),
  new TestKey(
      /* curve = */ 'P-521',
      /* x = */
      '01ee3aabecef323cb4581e044be21914b567c426eae18d71720a71a0b236f5324ef9666fe855f5d7986d3e33a9250396f63c780572b3ad9417d69c2a87773ce39194',
      /* y = */
      '0036bea90db019304719d269e5335f9790e730e241a1b02cfdab8bdcfd0bcff8bdcb3ddeb9c3a94ecff1ab6abb80b0c1655f871c6089d3a4bf8625cf6bd182897f1b',
      /* opt_d = */
      '00b9f9f5d91cbfa9b7f92b041b137ac9822ca4a38f71ce227f624cac6178ca8351fab24bc2cc3f85d7ab72f54a0f9d1bb11a888a79a9c7b1ca267ddc82043585e437')
];
<commit_msg>Internal change<commit_after>// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

goog.module('tink.subtle.webcrypto.EcdhTest');
goog.setTestOnly('tink.subtle.webcrypto.EcdhTest');

const Bytes = goog.require('tink.subtle.Bytes');
const Ecdh = goog.require('tink.subtle.webcrypto.Ecdh');
const EllipticCurves = goog.require('tink.subtle.EllipticCurves');
const TestCase = goog.require('goog.testing.TestCase');
const testSuite = goog.require('goog.testing.testSuite');
const wycheproofTestVectors = goog.require('tink.subtle.webcrypto.wycheproofTestVectors');

testSuite({
  setUp() {
    // Use a generous promise timeout for running continuously.
    TestCase.getActiveTestCase().promiseTimeout = 1000 * 1000;  // 1000s
  },

  tearDown() {
    // Reset the promise timeout to default value.
    TestCase.getActiveTestCase().promiseTimeout = 1000;  // 1s
  },

  async testComputeSharedSecret() {
    const aliceKeyPair = await Ecdh.generateKeyPair('P-256');
    const bobKeyPair = await Ecdh.generateKeyPair('P-256');
    const sharedSecret1 = await Ecdh.computeSharedSecret(
        aliceKeyPair.privateKey, bobKeyPair.publicKey);
    const sharedSecret2 = await Ecdh.computeSharedSecret(
        bobKeyPair.privateKey, aliceKeyPair.publicKey);
    assertEquals(Bytes.toHex(sharedSecret1), Bytes.toHex(sharedSecret2));
  },

  async testWycheproof_wycheproofWebcrypto() {
    for (let testGroup of wycheproofTestVectors['testGroups']) {
      let errors = '';
      for (let test of testGroup['tests']) {
        errors += await runWycheproofTest(test);
      }
      if (errors !== '') {
        fail(errors);
      }
    }
  },

  // Test that both public and private key are defined in the result.
  async testGenerateKeyPair() {
    const curveTypes = Object.keys(EllipticCurves.CurveType);
    for (let curve of curveTypes) {
      const curveTypeString =
          EllipticCurves.curveToString(EllipticCurves.CurveType[curve]);
      const keyPair = await Ecdh.generateKeyPair(curveTypeString);
      assertTrue(keyPair.privateKey != null);
      assertTrue(keyPair.publicKey != null);
    }
  },

  // Test that when crypto key is exported and imported it gives the same key
  // as the original one.
  async testExportImportCryptoKey() {
    const curveTypes = Object.keys(EllipticCurves.CurveType);
    for (let curve of curveTypes) {
      const curveTypeString =
          EllipticCurves.curveToString(EllipticCurves.CurveType[curve]);
      const keyPair = await Ecdh.generateKeyPair(curveTypeString);

      const publicKey = keyPair.publicKey;
      const publicCryptoKey = await Ecdh.exportCryptoKey(publicKey);
      const importedPublicKey = await Ecdh.importPublicKey(publicCryptoKey);
      assertObjectEquals(publicKey, importedPublicKey);

      const privateKey = keyPair.privateKey;
      const privateCryptoKey = await Ecdh.exportCryptoKey(privateKey);
      const importedPrivateKey = await Ecdh.importPrivateKey(privateCryptoKey);
      assertObjectEquals(privateKey, importedPrivateKey);
    }
  },

  // Test that when JSON web key is imported and exported it gives the same key
  // as the original one.
  async testImportExportJsonKey() {
    for (let testKey of TEST_KEYS) {
      const jwk = /** @type{webCrypto.JsonWebKey} */ ({
        'kty': 'EC',
        'crv': testKey.curve,
        'x': Bytes.toBase64(Bytes.fromHex(testKey.x), true),
        'y': Bytes.toBase64(Bytes.fromHex(testKey.y), true),
        'ext': true,
      });

      let importedKey;
      if (!testKey.d) {
        jwk['key_ops'] = [];
        importedKey = await Ecdh.importPublicKey(jwk);
      } else {
        jwk['key_ops'] = ['deriveKey', 'deriveBits'];
        jwk['d'] = Bytes.toBase64(Bytes.fromHex(testKey.d), true);
        importedKey = await Ecdh.importPrivateKey(jwk);
      }

      const exportedKey = await Ecdh.exportCryptoKey(importedKey);
      assertObjectEquals(jwk, exportedKey);
    }
  },
});

/**
 * Runs the test with test vector given as an input and returns either empty
 * string or a text describing the failure.
 *
 * @param {!Object} test - JSON object with test data
 * @return {!Promise<string>}
 */
const runWycheproofTest = async function(test) {
  try {
    const publicKey = await Ecdh.importPublicKey(test['public']);
    const privateKey = await Ecdh.importPrivateKey(test['private']);
    const sharedSecret = await Ecdh.computeSharedSecret(privateKey, publicKey);
    if (test['result'] === 'invalid') {
      return 'Fail on test ' + test['tcId'] + ': No exception thrown.\n';
    }
    const sharedSecretHex = Bytes.toHex(sharedSecret);
    if (sharedSecretHex !== test['shared']) {
      return 'Fail on test ' + test['tcId'] + ': unexpected result was \"' +
          sharedSecretHex + '\".\n';
    }
  } catch (e) {
    if (test['result'] === 'valid') {
      return 'Fail on test ' + test['tcId'] + ': unexpected exception \"' +
          e.toString() + '\".\n';
    }
  }
  // If the test passes return an empty string.
  return '';
};

class TestKey {
  /**
   * @param {string} curve
   * @param {string} x
   * @param {string} y
   * @param {string=} opt_d
   */
  constructor(curve, x, y, opt_d) {
    /** @const {string} */
    this.curve = curve;
    /** @const {string} */
    this.x = x;
    /** @const {string} */
    this.y = y;
    /** @const {string|undefined} */
    this.d = opt_d;
  }
}

// This set of keys was generated by Java version of Tink.
// It contains one private and one public key for each curve type supported by
// Tink.
/** {!Array<!TestKey>} */
const TEST_KEYS = [
  new TestKey(
      /* curve = */ 'P-256',
      /* x = */
      '2eab800e5d8e9b15d0f87c55324b477ffc9382d7137599e0203113a4e41b50d0',
      /* y = */
      '50bb2c11cfb72f3c380c2f93ea088d6938b91bcf581cd94a73ed0a3f623a6b8b'),
  new TestKey(
      /* curve = */ 'P-256',
      /* x = */
      '844c085cc4450297b681126356e10da074dea817f69bc2b1f3d6b1fc82593c7d',
      /* y = */
      '3cdb41fc89867d2066cc9c4f9ad7e890152bad24de20621abfe608234cbe40f1',
      /* opt_d = */
      'f96796cc28b36038817cc5d7db01c52ee0411dd848dc0833e9e26e989e4a64db'),
  new TestKey(
      /* curve = */ 'P-384',
      /* x = */
      'f3290cc80faa65e8821b0bf835f51e3431a4d78dcebd81b74c53b9b704bd995df93b648d51057a9a96a654fb8332391e',
      /* y = */
      '7e52bb9f654781a6894ef5ae77869207fa32ddbcec4a02d27ba1ead5472b3b9f39b09e9bca7d936809c143e99c655401'),
  new TestKey(
      /* curve = */ 'P-384',
      /* x = */
      'be9df79abedb82fc0e527630955f63f2f74b4984f0a4ac063a089565393ed20ac7a784f4efa434f5b1fa1837c76c8472',
      /* y = */
      'cf34ad0d4f3f2cbd546780509ec7073bb26fa0547d09ed10b83bf9b90903037ac956dbd661d02ce3e397e0547356b331',
      /* opt_d = */
      '34d86595280a8bdca23ccd60eeac9581016e895c2bc867c26dc2f99f6d0f627ce586ad36d1d2981968d8852dc9276d12'),
  new TestKey(
      /* curve = */ 'P-521',
      /* x = */
      '012f2211ec7e634919857be3066becf20c438b84ff24501712c91c98f527b44c7b001f8611935cb1179541c2b3cc3a1fc9259d50cd4842a847ea0cafe22cd75fe788',
      /* y = */
      '016b5d3f5480122643a26ef9e7c7e36875f53c28167d6afc35777d32ea76127d34287325bf14779f2e4cf3864fcc951ba601cec92b03291e34db2e815d4bd6fc2045'),
  new TestKey(
      /* curve = */ 'P-521',
      /* x = */
      '01ee3aabecef323cb4581e044be21914b567c426eae18d71720a71a0b236f5324ef9666fe855f5d7986d3e33a9250396f63c780572b3ad9417d69c2a87773ce39194',
      /* y = */
      '0036bea90db019304719d269e5335f9790e730e241a1b02cfdab8bdcfd0bcff8bdcb3ddeb9c3a94ecff1ab6abb80b0c1655f871c6089d3a4bf8625cf6bd182897f1b',
      /* opt_d = */
      '00b9f9f5d91cbfa9b7f92b041b137ac9822ca4a38f71ce227f624cac6178ca8351fab24bc2cc3f85d7ab72f54a0f9d1bb11a888a79a9c7b1ca267ddc82043585e437')
];
<|endoftext|>


<commit_before>// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 *@fileoverview Ready to inject atoms for querying the DOM.
 */

goog.provide('webdriver.atoms.inject.dom');

goog.require('bot.action');
goog.require('bot.dom');
goog.require('bot.inject');
goog.require('webdriver.atoms.element');

/**
 * Gets the visisble text for the given element.
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} The visible text wrapped in a JSON string as defined by the
 *     WebDriver wire protocol.
 */
webdriver.atoms.inject.dom.getText = function(element) {
  return bot.inject.executeScript(webdriver.atoms.element.getText, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} A boolean describing whether the element is
 *     checked or selected wrapped in a JSON string as defined by
 *     the wire protocol.
 */
webdriver.atoms.inject.dom.isSelected = function(element) {
  return bot.inject.executeScript(bot.dom.isSelected, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} The coordinates of the top left corner in a JSON
 *     string as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getTopLeftCoordinates = function(element) {
  return bot.inject.executeScript(bot.dom.getLocationInView, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @param {string} attribute The attribute to look up.
 * @return {string} The requested attribute value in a JSON string
 *     as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getAttributeValue = function(element, attribute) {
  return bot.inject.executeScript(
      webdriver.atoms.element.getAttribute, [element, attribute], true);
};

/**
 * @param {bot.inject.ELEMENT_KEY:string} element The element to query.
 * @return {string} The element size in a JSON string as
 *     defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getSize = function(element) {
  return bot.inject.executeScript(bot.dom.getElementSize, [element], true);
};

/**
 * @param {bot.inject.ELEMENT_KEY:string} element The element to query.
 * @param {string} property The property to look up.
 * @return {string} The value of the requested CSS property in a JSON
 *     string as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getValueOfCssProperty = function(element, property) {
  return bot.inject.executeScript(bot.dom.getEffectiveStyle,
      [element, property], true);
};

/**
 * @param {bot.inject.ELEMENT_KEY:string} element The element to query.
 * @return {string} A boolean describing whether the element is enabled
 *     in a JSON string as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.isEnabled = function(element) {
  return bot.inject.executeScript(bot.dom.isEnabled, [element], true);
};

/**
 * @param {bot.inject.ELEMENT_KEY:string} element The element to check.
 * @return {string} true if the element is visisble, false otherwise.
 *     The result is wrapped in a JSON string as defined by the wire
 *     protocol.
 */
webdriver.atoms.inject.dom.isDisplayed = function(element) {
  return bot.inject.executeScript(
      bot.dom.isShown, [element, /*ignoreOpacity=*/true], true);
};

<commit_msg>DanielWagnerHall: Fixing some types<commit_after>// Copyright 2011 WebDriver committers
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 *@fileoverview Ready to inject atoms for querying the DOM.
 */

goog.provide('webdriver.atoms.inject.dom');

goog.require('bot.action');
goog.require('bot.dom');
goog.require('bot.inject');
goog.require('webdriver.atoms.element');

/**
 * Gets the visisble text for the given element.
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} The visible text wrapped in a JSON string as defined by the
 *     WebDriver wire protocol.
 */
webdriver.atoms.inject.dom.getText = function(element) {
  return bot.inject.executeScript(webdriver.atoms.element.getText, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} A boolean describing whether the element is
 *     checked or selected wrapped in a JSON string as defined by
 *     the wire protocol.
 */
webdriver.atoms.inject.dom.isSelected = function(element) {
  return bot.inject.executeScript(bot.dom.isSelected, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} The coordinates of the top left corner in a JSON
 *     string as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getTopLeftCoordinates = function(element) {
  return bot.inject.executeScript(bot.dom.getLocationInView, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @param {string} attribute The attribute to look up.
 * @return {string} The requested attribute value in a JSON string
 *     as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getAttributeValue = function(element, attribute) {
  return bot.inject.executeScript(
      webdriver.atoms.element.getAttribute, [element, attribute], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} The element size in a JSON string as
 *     defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getSize = function(element) {
  return bot.inject.executeScript(bot.dom.getElementSize, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @param {string} property The property to look up.
 * @return {string} The value of the requested CSS property in a JSON
 *     string as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.getValueOfCssProperty = function(element, property) {
  return bot.inject.executeScript(bot.dom.getEffectiveStyle,
      [element, property], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to query.
 * @return {string} A boolean describing whether the element is enabled
 *     in a JSON string as defined by the wire protocol.
 */
webdriver.atoms.inject.dom.isEnabled = function(element) {
  return bot.inject.executeScript(bot.dom.isEnabled, [element], true);
};

/**
 * @param {!{bot.inject.ELEMENT_KEY:string}} element The element to check.
 * @return {string} true if the element is visisble, false otherwise.
 *     The result is wrapped in a JSON string as defined by the wire
 *     protocol.
 */
webdriver.atoms.inject.dom.isDisplayed = function(element) {
  return bot.inject.executeScript(
      bot.dom.isShown, [element, /*ignoreOpacity=*/true], true);
};

<|endoftext|>


<commit_before>//if leader dies before last player is in OR before performing ectobiology, it's a doomed timeline.
function SaveDoomedTimeLine(session){
	this.session=session;
	this.playerList = [];  //what players are already in the medium when i trigger?
	this.timePlayer = null;
	this.leaderPlayer = null;
	this.reason = "";
	this.doomedTimeClone = null;
	this.trigger = function(playerList){
		this.timePlayer = findAspectPlayer(session.players, "Time"); //they don't have to be in the medium, though
		this.leaderPlayer = getLeader(session.players);
		this.playerList = playerList;
		/*
		if(this.timePlayer.dead){  //a dead time player can't prevent shit.
			//console.log("time player is dead, not triggering")
			//console.log(this.timePlayer);
			return false;
		}*/
		//console.log("time player is not dead,  do i trigger?")
		return (this.ectoDoom() || this.playerDoom() || this.randomDoom());
	}

	this.makeDoomedSnapshot = function(){
		var timeClone = makeRenderingSnapshot(this.timePlayer);
		timeClone.dead = false;
		timeClone.doomed = true;
		//from a different timeline, things went differently.
		var rand = Math.seededRandom();
		if(rand>.8){
			timeClone.godTier = !timeClone.godTier;
		}else if(rand>.6){
			timeClone.isDreamSelf = !timeClone.isDreamSelf;
		}else if(rand>.4){
			timeClone.grimDark = !timeClone.grimDark;
		}else if(rand>.2){
			timeClone.murderMode = !timeClone.murderMode;
		}
		this.doomedTimeClone = timeClone;
	}

	this.renderContent = function(div){
		div.append("
"+this.content());
		var divID = (div.attr("id"))
		var canvasHTML = "
<canvas id='canvas" + divID+"' width='" +canvasWidth + "' height="+canvasHeight + "'>  </canvas>";
		div.append(canvasHTML);
		var canvas = document.getElementById("canvas"+ divID);
		drawTimeGears(canvas, this.doomedTimeClone);
		drawSinglePlayer(canvas, this.doomedTimeClone);

	}

	this.leaderIsFucked = function(){
		if(this.leaderPlayer.dead && !this.leaderPlayer.dreamSelf && !this.leaderPlayer.godTier && !this.leaderPlayer.godDestiny){
			//console.log('leader is fucked')
			return true;
		}
		return false;
	}

	this.ectoDoom = function(){
		if(this.leaderIsFucked() && !this.session.ectoBiologyStarted){
			this.reason = "Leader killed before ectobiology."
			//console.log(this.reason)
			return true; //paradox, the babies never get made.
		}
		return false;
	}

	this.playerDoom = function(){
		//greater time pressure for getting all players in, can't wait for a revive.
		if(this.leaderPlayer.dead && this.playerList.length < this.session.players.length && this.playerList.length != 1){ //if i die before entering, well, that's yellowYard bullshit
			this.reason = "Leader killed before all players in medium.";  //goddamn it past jr, there was a TYPO here, no WONDER it never happened.
			console.log("!!!!!!!!!!!!!!!oh hell YES " + this.session.session_id)
			return true; //not everybody is in, leader can't be server for final player
		}
		return false;
	}

	this.randomDoom = function(){
		this.reason = "Shenanigans"
		return Math.seededRandom() > .99
	}

	this.content = function(){
		var ret = "A " + this.timePlayer.htmlTitleBasic() + " suddenly warps in from the future. ";
		ret += " They come with a dire warning of a doomed timeline. ";

		if(this.reason == "Leader killed before ectobiology."){
			//alert("ecto doom")
			ret += " If the " + this.leaderPlayer.htmlTitleBasic() + " dies right now, ";
			ret += " none of the Players will even be born in the first place (Long story, just trust them). ";

			this.session.doomedTimelineReasons.push(this.reason)
			this.leaderPlayer.dead = false;
			var r = this.timePlayer.getRelationshipWith(this.leaderPlayer);
			if(r && r.value != 0){
					if(r.value > 0){
						console.log(" fully restoring leader health from time shenanigans: " + this.session.session_id)
						ret += " They make it so that never happened. Forget about it. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp;
					}else{
						console.log(" barely restoring leader health from time shenanigans: " + this.session.session_id)
						ret += " They take a twisted pleasure out of waiting until the last possible moment to pull the " + this.leaderPlayer.htmlTitleBasic() + "'s ass out of the danger zone. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp/10;
					}
			}else{
				console.log(" half restoring leader health from time shenanigans: " + this.session.session_id)
				ret += " They interupt things before the " + this.leaderPlayer.htmlTitleBasic() +  " gets hurt too bad. ";
			}

		}else if(this.reason == "Leader killed before all players in medium."){
			ret += " If the " + this.leaderPlayer.htmlTitleBasic() + " dies right now, ";
			ret += " the " +this.playerList[this.session.players.length-1].htmlTitleBasic() + " will never even make it into the medium. "; //only point of paradox is for last player
			ret += " after all, the " + this.leaderPlayer.htmlTitleBasic() + " is their server player. ";
			this.leaderPlayer.dead = false;
			var r = this.timePlayer.getRelationshipWith(this.leaderPlayer);
			if(r && r.value != 0){
					if(r.value > 0){
						console.log(" fully restoring leader health from time shenanigans before all players in session: " + this.session.session_id)
						ret += " They make it so that never happened. Forget about it. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp;
					}else{
						console.log(" barely restoring leader health from time shenanigans before all players in session : " + this.session.session_id)
						ret += " They take a twisted pleasure out of waiting until the last possible moment to pull the " + this.leaderPlayer.htmlTitleBasic() + "'s ass out of the danger zone. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp/10;
					}
			}else{
				console.log(" half restoring leader health from time shenanigans before all players in session: " + this.session.session_id)
				ret += " They interupt things before the " + this.leaderPlayer.htmlTitleBasic() +  " gets hurt too bad. ";
			}
			this.session.doomedTimelineReasons.push(this.reason)
		}else{
			if(this.timePlayer.leader && !this.session.ectoBiologyStarted ){
					console.log("time player doing time ectobiology: " + this.session.session_id)
					this.timePlayer.performEctobiology(this.session);
					this.reason = "Time player didn't do ectobiology."
					session.doomedTimelineReasons.push(this.reason)
					ret += " They need to do the ectobiology right freaking now, or none of the players will ever even be born.";
			}else{
				this.reason = "Shenanigans"
				session.doomedTimelineReasons.push(this.reason)
				ret += " It's too complicated to explain, but everyone has already screwed up beyond repair. Just trust them. ";
			}
		}

		var living = findLivingPlayers(this.session.players);
		if(living.length > 0){
			ret += " The " + this.timePlayer.htmlTitleBasic() + " has sacrificed themselves to change the timeline. ";
			ret += " YOUR session's " + this.timePlayer.htmlTitle() + " is fine, don't worry about it...but THIS one is now doomed. ";
			ret += " Least they can do after saving everyone is to time travel to where they can do the most good. ";
			ret += " After doing something inscrutable, they vanish in a cloud of clocks and gears. ";
		}else{
			console.log("death's hand maid in: " + this.session.session_id)
			ret += " Time really is the shittiest aspect. They make sure everybody is dead in this timeline, as per inevitability's requirements, then they sullenly vanish in a cloud of clocks and gears. "
		}
		this.makeDoomedSnapshot();
		this.timePlayer.doomedTimeClones.push(this.doomedTimeClone);
		return ret;
	}
}
<commit_msg>finally got server player paradoxes working right for the first time, basically ever<commit_after>//if leader dies before last player is in OR before performing ectobiology, it's a doomed timeline.
function SaveDoomedTimeLine(session){
	this.session=session;
	this.playerList = [];  //what players are already in the medium when i trigger?
	this.timePlayer = null;
	this.leaderPlayer = null;
	this.reason = "";
	this.doomedTimeClone = null;
	this.trigger = function(playerList){
		this.timePlayer = findAspectPlayer(session.players, "Time"); //they don't have to be in the medium, though
		this.leaderPlayer = getLeader(session.players);
		this.playerList = playerList;
		/*
		if(this.timePlayer.dead){  //a dead time player can't prevent shit.
			//console.log("time player is dead, not triggering")
			//console.log(this.timePlayer);
			return false;
		}*/
		//console.log("time player is not dead,  do i trigger?")
		return (this.ectoDoom() || this.playerDoom() || this.randomDoom());
	}

	this.makeDoomedSnapshot = function(){
		var timeClone = makeRenderingSnapshot(this.timePlayer);
		timeClone.dead = false;
		timeClone.doomed = true;
		//from a different timeline, things went differently.
		var rand = Math.seededRandom();
		if(rand>.8){
			timeClone.godTier = !timeClone.godTier;
		}else if(rand>.6){
			timeClone.isDreamSelf = !timeClone.isDreamSelf;
		}else if(rand>.4){
			timeClone.grimDark = !timeClone.grimDark;
		}else if(rand>.2){
			timeClone.murderMode = !timeClone.murderMode;
		}
		this.doomedTimeClone = timeClone;
	}

	this.renderContent = function(div){
		div.append("
"+this.content());
		var divID = (div.attr("id"))
		var canvasHTML = "
<canvas id='canvas" + divID+"' width='" +canvasWidth + "' height="+canvasHeight + "'>  </canvas>";
		div.append(canvasHTML);
		var canvas = document.getElementById("canvas"+ divID);
		drawTimeGears(canvas, this.doomedTimeClone);
		drawSinglePlayer(canvas, this.doomedTimeClone);

	}

	this.leaderIsFucked = function(){
		if(this.leaderPlayer.dead && !this.leaderPlayer.dreamSelf && !this.leaderPlayer.godTier && !this.leaderPlayer.godDestiny){
			//console.log('leader is fucked')
			return true;
		}
		return false;
	}

	this.ectoDoom = function(){
		if(this.leaderIsFucked() && !this.session.ectoBiologyStarted){
			this.reason = "Leader killed before ectobiology."
			//console.log(this.reason)
			return true; //paradox, the babies never get made.
		}
		return false;
	}

	this.playerDoom = function(){
		//greater time pressure for getting all players in, can't wait for a revive.
		if(this.leaderPlayer.dead && this.playerList.length < this.session.players.length && this.playerList.length != 1){ //if i die before entering, well, that's yellowYard bullshit
			this.reason = "Leader killed before all players in medium.";  //goddamn it past jr, there was a TYPO here, no WONDER it never happened.
			console.log("!!!!!!!!!!!!!!!oh hell YES " + this.session.session_id)
			return true; //not everybody is in, leader can't be server for final player
		}
		return false;
	}

	this.randomDoom = function(){
		this.reason = "Shenanigans"
		return Math.seededRandom() > .99
	}

	this.content = function(){
		var ret = "A " + this.timePlayer.htmlTitleBasic() + " suddenly warps in from the future. ";
		ret += " They come with a dire warning of a doomed timeline. ";

		if(this.reason == "Leader killed before ectobiology."){
			//alert("ecto doom")
			ret += " If the " + this.leaderPlayer.htmlTitleBasic() + " dies right now, ";
			ret += " none of the Players will even be born in the first place (Long story, just trust them). ";

			this.session.doomedTimelineReasons.push(this.reason)
			this.leaderPlayer.dead = false;
			var r = this.timePlayer.getRelationshipWith(this.leaderPlayer);
			if(r && r.value != 0){
					if(r.value > 0){
						console.log(" fully restoring leader health from time shenanigans: " + this.session.session_id)
						ret += " They make it so that never happened. Forget about it. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp;
					}else{
						console.log(" barely restoring leader health from time shenanigans: " + this.session.session_id)
						ret += " They take a twisted pleasure out of waiting until the last possible moment to pull the " + this.leaderPlayer.htmlTitleBasic() + "'s ass out of the danger zone. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp/10;
					}
			}else{
				console.log(" half restoring leader health from time shenanigans: " + this.session.session_id)
				ret += " They interupt things before the " + this.leaderPlayer.htmlTitleBasic() +  " gets hurt too bad. ";
			}

		}else if(this.reason == "Leader killed before all players in medium."){
			ret += " If the " + this.leaderPlayer.htmlTitleBasic() + " dies right now, ";
			ret += " the " +this.session.players[this.session.players.length-1].htmlTitleBasic() + " will never even make it into the medium. "; //only point of paradox is for last player
			ret += " After all, the " + this.leaderPlayer.htmlTitleBasic() + " is their server player. ";
			this.leaderPlayer.dead = false;
			var r = this.timePlayer.getRelationshipWith(this.leaderPlayer);
			if(r && r.value != 0){
					if(r.value > 0){
						console.log(" fully restoring leader health from time shenanigans before all players in session: " + this.session.session_id)
						ret += " They make it so that never happened. Forget about it. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp;
					}else{
						console.log(" barely restoring leader health from time shenanigans before all players in session : " + this.session.session_id)
						ret += " They take a twisted pleasure out of waiting until the last possible moment to pull the " + this.leaderPlayer.htmlTitleBasic() + "'s ass out of the danger zone. ";
						this.leaderPlayer.currentHP = this.leaderPlayer.hp/10;
					}
			}else{
				console.log(" half restoring leader health from time shenanigans before all players in session: " + this.session.session_id)
				ret += " They interupt things before the " + this.leaderPlayer.htmlTitleBasic() +  " gets hurt too bad. ";
			}
			this.session.doomedTimelineReasons.push(this.reason)
		}else{
			if(this.timePlayer.leader && !this.session.ectoBiologyStarted ){
					console.log("time player doing time ectobiology: " + this.session.session_id)
					this.timePlayer.performEctobiology(this.session);
					this.reason = "Time player didn't do ectobiology."
					session.doomedTimelineReasons.push(this.reason)
					ret += " They need to do the ectobiology right freaking now, or none of the players will ever even be born.";
			}else{
				this.reason = "Shenanigans"
				session.doomedTimelineReasons.push(this.reason)
				ret += " It's too complicated to explain, but everyone has already screwed up beyond repair. Just trust them. ";
			}
		}

		var living = findLivingPlayers(this.session.players);
		if(living.length > 0){
			ret += " The " + this.timePlayer.htmlTitleBasic() + " has sacrificed themselves to change the timeline. ";
			ret += " YOUR session's " + this.timePlayer.htmlTitle() + " is fine, don't worry about it...but THIS one is now doomed. ";
			ret += " Least they can do after saving everyone is to time travel to where they can do the most good. ";
			ret += " After doing something inscrutable, they vanish in a cloud of clocks and gears. ";
		}else{
			console.log("death's hand maid in: " + this.session.session_id)
			ret += " Time really is the shittiest aspect. They make sure everybody is dead in this timeline, as per inevitability's requirements, then they sullenly vanish in a cloud of clocks and gears. "
		}
		this.makeDoomedSnapshot();
		this.timePlayer.doomedTimeClones.push(this.doomedTimeClone);
		return ret;
	}
}
<|endoftext|>


<commit_before>var React = require('react');
var ReactDOM = require('react-dom');
var sinon = require('sinon');

function spyOnReactClass(reactClass, methodName) {
    var classProto = reactClassPrototype(reactClass);
    var spy = sinon.spy();

    if (classProto.__reactAutoBindMap) classProto.__reactAutoBindMap[methodName] = spy;
    return spy;
}

function reactClassPrototype(reactClass) {
    var ctor = reactClass.prototype && reactClass.prototype.constructor;
    if (typeof ctor === 'undefinied')
        throw 'A component constructor could not be found for this class. Are you sure you passed in a React component?';

    return ctor.prototype;
}

module.exports = spyOnReactClass;
<commit_msg>Throw Error instead of string<commit_after>var React = require('react');
var ReactDOM = require('react-dom');
var sinon = require('sinon');

function spyOnReactClass(reactClass, methodName) {
    var classProto = reactClassPrototype(reactClass);
    var spy = sinon.spy();

    if (classProto.__reactAutoBindMap) classProto.__reactAutoBindMap[methodName] = spy;
    return spy;
}

function reactClassPrototype(reactClass) {
    var ctor = reactClass.prototype && reactClass.prototype.constructor;
    if (typeof ctor === 'undefinied')
        throw new Error('A component constructor could not be found for this class. Are you sure you passed in a React component?');

    return ctor.prototype;
}

module.exports = spyOnReactClass;
<|endoftext|>


<commit_before>/**
 * Created by Salvador on 4/9/2015.
 */
var Util = (function() {
  var proto = {
    b: null,
    p: null,

    status: function() {
      if (arguments.length === 0) {
        return this.b[this.p[0]][this.p[1]];
      } else {
        var arg = arguments[0];
        return this.b[arg[0]][arg[1]];
      }

    },

    argue: {
      defArgP: function(args) {
        if (args.length === 0) {
          return this.p;
        } else {
          return args[0];
        }
      },

      retVal: function(func, args) {
        if (args.length === 0) {
          return func();
        } else {
          return func(args[0]);
        }
      },

      retVals: function(funcs, args) {
        var results = [];

        if (args.length === 0) {
          for (var i = 0; i < funcs.length; ++i) {
            results.push(funcs[i]());
          }
        } else {
          for (var k = 0; k < funcs.length; ++k) {
            results.push(funcs[k](args[0]));
          }
        }

        return results;
      }
    },

    is: {
      /**
       * @return {boolean}
       */
      Free: function() {
        return this.argue.retVal(this.status, arguments) === "null";
      },

      /**
       * @return {boolean}
       */
      Bot: function() {
        return this.argue.retVal(this.status, arguments) === "P";
      },

      /**
       * @return {boolean}
       */
      Other: function() {
        return this.argue.retVal(this.status, arguments) === "C";
      },

      /**
       * @return {boolean}
       */
      Visited: function() {
        return this.argue.retVal(this.status, arguments) === "XP";
      },

      /**
       * @return {boolean}
       */
      oVisited: function() {
        return this.argue.retVal(this.status, arguments) === "XC";
      }
    },

    area: {
      raw: {
        aRawL: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0], p[1] - 1];
        },

        aRawT: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0] - 1, p[1]];
        },

        aRawR: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0], p[1] + 1];
        },

        aRawB: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0] + 1, p[1]];
        }
      },

      refined: {
        refiners: null,

        arL: function() {
          var rawCoord = this.argue.retVal(this.area.raw.aRawL, arguments);

          if (rawCoord[1] < 0) {
            rawCoord = null;
          }

          return rawCoord;
        },

        arT: function() {
          var rawCoord = this.argue.retVal(this.area.raw.aRawT, arguments);

          if (rawCoord[0] < 0) {
            rawCoord = null;
          }

          return rawCoord;
        },

        arR: function() {
          var rawCoord = this.argue.retVal(this.area.raw.aRawR, arguments);

          if (rawCoord[1] > 15) {
            rawCoord = null;
          }

          return rawCoord;
        },

        arB: function() {
          var rawCoord = this.argue.retVal(this.area.raw.aRawB, arguments);

          if (rawCoord[0] > 15) {
            rawCoord = null;
          }

          return rawCoord;
        },

        all: function() {
          return this.argue.retVals(this.area.refined.refiners, arguments);
        }
      }
    },

    hazard: {
      canners: null,

      canLeft: function() {
        var left = this.argue.retVal(this.area.raw.aRawL, arguments);

        return left[1] !== -1 && this.is.Free(left);
      },

      canTop: function() {
        var top = this.argue.retVal(this.area.raw.aRawT, arguments);

        return top[0] !== -1 && this.is.Free(top);
      },

      canRight: function() {
        var right = this.argue.retVal(this.area.raw.aRawR, arguments);

        return right[0] !== 16 && this.is.Free(right);
      },

      canBot: function() {
        var bot = this.argue.retVal(this.area.raw.aRawB, arguments);

        return bot[1] !== 16 && this.is.Free(bot);
      }
    },

    edge: {
      directions: ["W", "N", "E", "S"],

      count: function() {
        var edgy = this.argue.retVals(this.hazard.canners, arguments);

        return edgy[0] + edgy[1] + edgy[2] + edgy[3];
      },

      countEdges: function() {
        var coords = this.argue.retVal(this.area.refined.all, arguments);

        var edges = [], mininal = 0;
        for (var point in coords) {
          if (point === null) {
            edges.push(Infinity);
          } else {
            var count = this.edge.count(point);
            edges.push(count);

            if (mininal > count) {
              mininal = edges.length - 1;
            }
          }
        }

        return mininal;
      },

      minimalEdge: function () {
        var idx = this.argue.retVal(this.edge.countEdges, arguments);

        return this.edge.directions[idx];
      }
    }
  };
  proto.area.refined.refiners = [proto.area.refined.arL, proto.area.refined.arT, proto.area.refined.arR, proto.area.refined.arB];
  proto.hazard.canners = [proto.hazard.canLeft, proto.hazard.canTop, proto.hazard.canRight, proto.hazard.canBot];

  var f_ = function(board, point) {
    this.b = board;
    this.p = point;
  };

  f_.prototype = proto;

  return f_;
});

// INPUT:  board   -> [RxC] multidimensional array with each element being either
//                    "null" (empty space),
//                    "P"    (your bot)
//                    "C"    (opponent bot),
//                    "XP"   (visited space by your bot),
//                    "XC"   (visited space by opponent bot)
//         bot_loc -> [r,c] where r=row and c=col of your bot on board
//         opp_loc -> [r,c] where r=row and c=col of opponent on board
// OUTPUT: N, E, S, W which signifies which direction to move

(function bot(board, bot_loc, opp_loc) {
  var util = new Util(board, bot_loc);

  return util.edge.minimalEdge();

})(readline());<commit_msg>fixed typos to satisfy webstorm<commit_after>/**
 * Created by Salvador on 4/9/2015.
 */
var Util = (function() {
  var proto = {
    b: null,
    p: null,

    status: function() {
      if (arguments.length === 0) {
        return this.b[this.p[0]][this.p[1]];
      } else {
        var arg = arguments[0];
        return this.b[arg[0]][arg[1]];
      }

    },

    argue: {
      defArgP: function(args) {
        if (args.length === 0) {
          return this.p;
        } else {
          return args[0];
        }
      },

      retVal: function(func, args) {
        if (args.length === 0) {
          return func();
        } else {
          return func(args[0]);
        }
      },

      returnValues: function(functions, args) {
        var results = [];

        if (args.length === 0) {
          for (var i = 0; i < functions.length; ++i) {
            results.push(functions[i]());
          }
        } else {
          for (var k = 0; k < functions.length; ++k) {
            results.push(functions[k](args[0]));
          }
        }

        return results;
      }
    },

    is: {
      /**
       * @return {boolean}
       */
      Free: function() {
        return this.argue.retVal(this.status, arguments) === "null";
      },

      /**
       * @return {boolean}
       */
      Bot: function() {
        return this.argue.retVal(this.status, arguments) === "P";
      },

      /**
       * @return {boolean}
       */
      Other: function() {
        return this.argue.retVal(this.status, arguments) === "C";
      },

      /**
       * @return {boolean}
       */
      Visited: function() {
        return this.argue.retVal(this.status, arguments) === "XP";
      },

      /**
       * @return {boolean}
       */
      oVisited: function() {
        return this.argue.retVal(this.status, arguments) === "XC";
      }
    },

    area: {
      raw: {
        aRawL: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0], p[1] - 1];
        },

        aRawT: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0] - 1, p[1]];
        },

        aRawR: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0], p[1] + 1];
        },

        aRawB: function() {
          var p = this.argue.defArgP(arguments);

          return [p[0] + 1, p[1]];
        }
      },

      refined: {
        refiners: null,

        arL: function() {
          var rawIndices = this.argue.retVal(this.area.raw.aRawL, arguments);

          if (rawIndices[1] < 0) {
            rawIndices = null;
          }

          return rawIndices;
        },

        arT: function() {
          var indices = this.argue.retVal(this.area.raw.aRawT, arguments);

          if (indices[0] < 0) {
            indices = null;
          }

          return indices;
        },

        arR: function() {
          var rawIndices = this.argue.retVal(this.area.raw.aRawR, arguments);

          if (rawIndices[1] > 15) {
            rawIndices = null;
          }

          return rawIndices;
        },

        arB: function() {
          var rawIndices = this.argue.retVal(this.area.raw.aRawB, arguments);

          if (rawIndices[0] > 15) {
            rawIndices = null;
          }

          return rawIndices;
        },

        all: function() {
          return this.argue.returnValues(this.area.refined.refiners, arguments);
        }
      }
    },

    hazard: {
      validateHazard: null,

      canLeft: function() {
        var left = this.argue.retVal(this.area.raw.aRawL, arguments);

        return left[1] !== -1 && this.is.Free(left);
      },

      canTop: function() {
        var top = this.argue.retVal(this.area.raw.aRawT, arguments);

        return top[0] !== -1 && this.is.Free(top);
      },

      canRight: function() {
        var right = this.argue.retVal(this.area.raw.aRawR, arguments);

        return right[0] !== 16 && this.is.Free(right);
      },

      canBot: function() {
        var bot = this.argue.retVal(this.area.raw.aRawB, arguments);

        return bot[1] !== 16 && this.is.Free(bot);
      }
    },

    edge: {
      directions: ["W", "N", "E", "S"],

      count: function() {
        var edgy = this.argue.returnValues(this.hazard.validateHazard, arguments);

        return edgy[0] + edgy[1] + edgy[2] + edgy[3];
      },

      countEdges: function() {
        var indices = this.argue.retVal(this.area.refined.all, arguments);

        var edges = [], minimal = 0;
        for (var idx = 0; idx < indices.length; ++idx) {
          var point = idx;

          if (point === null) {
            edges.push(Infinity);
          } else {
            var count = this.edge.count(point);
            edges.push(count);

            if (minimal > count) {
              minimal = edges.length - 1;
            }
          }
        }

        return minimal;
      },

      minimalEdge: function () {
        var idx = this.argue.retVal(this.edge.countEdges, arguments);

        return this.edge.directions[idx];
      }
    }
  };
  proto.area.refined.refiners = [proto.area.refined.arL, proto.area.refined.arT, proto.area.refined.arR, proto.area.refined.arB];
  proto.hazard.validateHazard = [proto.hazard.canLeft, proto.hazard.canTop, proto.hazard.canRight, proto.hazard.canBot];

  var f_ = function(board, point) {
    this.b = board;
    this.p = point;
  };

  f_.prototype = proto;

  return f_;
});

// INPUT:  board   -> [RxC] multidimensional array with each element being either
//                    "null" (empty space),
//                    "P"    (your bot)
//                    "C"    (opponent bot),
//                    "XP"   (visited space by your bot),
//                    "XC"   (visited space by opponent bot)
//         bot_loc -> [r,c] where r=row and c=col of your bot on board
//         opp_loc -> [r,c] where r=row and c=col of opponent on board
// OUTPUT: N, E, S, W which signifies which direction to move

(function bot(board, bot_loc, opp_loc) {
  var util = new Util(board, bot_loc);

  return util.edge.minimalEdge();

})(readline());<|endoftext|>


<commit_before>const gulp = require('gulp');
const postHTML = require('gulp-posthtml');
const attrsSorter = require('posthtml-attrs-sorter');
const pretty = require('gulp-pretty-html');
const ora = require('ora');

const hasher = require('../modules/posthtml/hasher');

module.exports = () => {
  const settings = require(`${process.cwd()}/marmelad/settings.marmelad`);

  const htmlFmtOpts = {
    html: {
      indent_size: 4,
      indent_char: '',
      indent_with_tabs: true,
      wrap_line_length: 0,
      preserve_newlines: false,
      unformatted: ['code', 'pre', 'em', 'strong', 'span', 'i', 'b', 'br', 'symbol'],
    },
    ...settings.pretty,
  };

  gulp.task('format:html', (done) => {
    const htmlSpinner = ora('Format HTML started').start();

    gulp.src(`${settings.paths.dist}/**/*.html`)
      .pipe(pretty(htmlFmtOpts.html))
      .pipe(gulp.dest(settings.paths.dist));

    htmlSpinner.succeed('Format HTML done');

    done();
  });

  gulp.task('posthtml', (done) => {
    const dist = settings.dist || {
      attrsSorter: {},
      hasher: {},
    };

    const attrsSorterOpts = {
      order: [
        'id', 'class', 'name',
        'data-.+', 'ng-.+', 'src',
        'for', 'type', 'href',
        'values', 'title', 'alt',
        'role', 'aria-.+',
        '$unknown$',
      ],
      ...dist.attrsSorter,
    };

    const hasherOpts = {
      attributes: [],
      path: settings.paths.dist,
      ...dist.hasher,
    };

    gulp.src(`${settings.paths.dist}/**/*.html`)
      .pipe(postHTML([
        attrsSorter(attrsSorterOpts),
        hasher(hasherOpts),
      ]))
      .pipe(gulp.dest(settings.paths.dist));

    done();
  });

  gulp.series('format:html', 'posthtml')();
};
<commit_msg>фикс неработающей цепочки команд mmd dist<commit_after>const gulp = require('gulp');
const postHTML = require('gulp-posthtml');
const attrsSorter = require('posthtml-attrs-sorter');
const pretty = require('gulp-pretty-html');
const ora = require('ora');

const hasher = require('../modules/posthtml/hasher');

module.exports = () => {
  const settings = require(`${process.cwd()}/marmelad/settings.marmelad`);

  const htmlFmtOpts = {
    html: {
      indent_size: 4,
      indent_char: '',
      indent_with_tabs: true,
      wrap_line_length: 0,
      preserve_newlines: false,
      unformatted: ['code', 'pre', 'em', 'strong', 'span', 'i', 'b', 'br', 'symbol'],
    },
    ...settings.pretty,
  };

  gulp.task('format:html', () => {
    // const htmlSpinner = ora('Format HTML started').start();

    return gulp.src(`${settings.paths.dist}/*.html`)
      .pipe(pretty(htmlFmtOpts))
      .pipe(gulp.dest(settings.paths.dist));

    // htmlSpinner.succeed('Format HTML done');
  });

  gulp.task('posthtml:tools', () => {
    const dist = settings.dist || {
      attrsSorter: {},
      hasher: {},
    };

    const attrsSorterOpts = {
      order: [
        'id', 'class', 'name',
        'data-.+', 'ng-.+', 'src',
        'for', 'type', 'href',
        'values', 'title', 'alt',
        'role', 'aria-.+',
        '$unknown$',
      ],
      ...dist.attrsSorter,
    };

    const hasherOpts = {
      attributes: [],
      path: settings.paths.dist,
      ...dist.hasher,
    };

    return gulp.src(`${settings.paths.dist}/*.html`)
      .pipe(postHTML([
        attrsSorter(attrsSorterOpts),
        hasher(hasherOpts),
      ]))
      .pipe(gulp.dest(settings.paths.dist));
  });

  gulp.series('format:html', 'posthtml:tools')();
};
<|endoftext|>


<commit_before>exports.names = ['.help'];
exports.hidden = false;
exports.enabled = true;
exports.matchStart = false;
exports.handler = function (data) {
    bot.sendChat('Need help? Ask a mod! No mods around? http://plug.dj/support');
};<commit_msg>Add .support<commit_after>exports.names = ['.help', '.support'];
exports.hidden = false;
exports.enabled = true;
exports.matchStart = false;
exports.handler = function (data) {
    bot.sendChat('Need help? Ask a mod! No mods around? Contact a Brand Ambassador: http://plug.dj/support - Hours: http://blog.plug.dj/brand-ambassadors/');
};<|endoftext|>


<commit_before>const help_topics = require('../json/help.json')
const cmdlist = require('../util/consts.json').cmdlist
var guilds_list = require('../json/guilds.json')
const util = require('util')

const help_embed = function (help_obj, prefix) {
  fields = []

  if (help_obj.usage) fields.push({
    "name": "Usage",
    "value": `\`${prefix}${help_obj.usage}\``,
    "inline": true
  })

  if (help_obj.example) fields.push({
    "name": "Example",
    "value": `\`${prefix}${help_obj.example}\``,
    "inline": true
  })

  return {
    'embed': {
      'author': {
        'name': help_obj.name
      },
      'fields': fields,
      'description': help_obj.text.join('')
    }
  }
}

module.exports = (message, client, helper) => {
  let options = message.content.split(' ')
  options.shift()
  let specific_topic = options.join(' ')
  if (specific_topic in help_topics) {
    client.createMessage(message.channel.id, help_embed(help_topics[specific_topic], helper.prefix)).then(new_message => {
      helper.log(new_message, `Helped with topic ${specific_topic}`)
    }).catch(err => helper.handle(message, err))
  } else {
    let help_list = ''
    for (topic in help_topics) {
      let disabled_list = client.guilds_list[message.channel.guild.id].disabled[message.channel.id]
      disabled_list = disabled_list ? disabled_list : []  // lol
      if (disabled_list && disabled_list.indexOf(topic) == -1 && topic != "eval") {
        help_list += `\`${topic}\` `;
      }
    }
    let conditional = specific_topic ? `Help topic not found: \`${specific_topic}\`. ` : null
    if (conditional) helper.log(message, 'could not help with ' + specific_topic)
    client.createMessage(message.channel.id, `${conditional}List of help topics: ${help_list}`).then(new_message => {
      helper.log(new_message, 'helped with all topics')
    }).catch(err => helper.handle(message, err))
  }
}
<commit_msg>double plus unfix help<commit_after>const help_topics = require('../json/help.json')
const cmdlist = require('../util/consts.json').cmdlist
var guilds_list = require('../json/guilds.json')
const util = require('util')

const help_embed = function (help_obj, prefix) {
  fields = []

  if (help_obj.usage) fields.push({
    "name": "Usage",
    "value": `\`${prefix}${help_obj.usage}\``,
    "inline": true
  })

  if (help_obj.example) fields.push({
    "name": "Example",
    "value": `\`${prefix}${help_obj.example}\``,
    "inline": true
  })

  return {
    'embed': {
      'author': {
        'name': help_obj.name
      },
      'fields': fields,
      'description': help_obj.text.join('')
    }
  }
}

module.exports = (message, client, helper) => {
  let options = message.content.split(' ')
  options.shift()
  let specific_topic = options.join(' ')
  if (specific_topic in help_topics) {
    client.createMessage(message.channel.id, help_embed(help_topics[specific_topic], helper.prefix)).then(new_message => {
      helper.log(new_message, `Helped with topic ${specific_topic}`)
    }).catch(err => helper.handle(message, err))
  } else {
    let help_list = ''
    for (topic in help_topics) {
      let disabled_list = client.guilds_list[message.channel.guild.id].disabled[message.channel.id]
      disabled_list = disabled_list ? disabled_list : []  // lol
      if (disabled_list && disabled_list.indexOf(topic) == -1 && topic != "eval") {
        if (topic.match('admin')) {
          if (message.member.permission.has('manageMessages')) help_list += `\`${topic}\` `;
        } else {
          help_list += `\`${topic}\` `;
        }
      }
    }
    let conditional = specific_topic ? `Help topic not found: \`${specific_topic}\`. ` : ''
    if (conditional != '') helper.log(message, 'could not help with ' + specific_topic)
    client.createMessage(message.channel.id, `${conditional}List of help topics: ${help_list}`).then(new_message => {
      helper.log(new_message, 'helped with all topics')
    }).catch(err => helper.handle(message, err))
  }
}
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  app: {
    title: 'skyees.com',
    description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
    keywords: 'mongodb, express, angularjs, node.js, mongoose, passport',
    googleAnalyticsTrackingID: process.env.GOOGLE_ANALYTICS_TRACKING_ID || 'GOOGLE_ANALYTICS_TRACKING_ID'
  },
  port: process.env.PORT || 3000,
  templateEngine: 'swig',
  // Session Cookie settings
  sessionCookie: {
    // session expiration is set by default to 24 hours
    maxAge: 24 * (60 * 60 * 1000),
    // httpOnly flag makes sure the cookie is only accessed
    // through the HTTP protocol and not JS/browser
    httpOnly: true,
    // secure cookie should be turned to true to provide additional
    // layer of security so that the cookie is set only when working
    // in HTTPS mode.
    secure: false
  },
  // sessionSecret should be changed for security measures and concerns
  sessionSecret: process.env.SESSION_SECRET||'rajs',
  // sessionKey is set to the generic sessionId key used by PHP applications
  // for obsecurity reasons
  sessionKey: 'sessionId',
  sessionCollection: 'sessions',
  logo: 'modules/core/client/img/brand/logo.png',
  favicon: 'modules/core/client/img/brand/favicon.ico'
};
<commit_msg>title changes to skyees.com<commit_after>'use strict';

module.exports = {
  app: {
    title: 'Skyees.com',
    description: 'Full-Stack JavaScript with MongoDB, Express, AngularJS, and Node.js',
    keywords: 'mongodb, express, angularjs, node.js, mongoose, passport',
    googleAnalyticsTrackingID: process.env.GOOGLE_ANALYTICS_TRACKING_ID || 'GOOGLE_ANALYTICS_TRACKING_ID'
  },
  port: process.env.PORT || 3000,
  templateEngine: 'swig',
  // Session Cookie settings
  sessionCookie: {
    // session expiration is set by default to 24 hours
    maxAge: 24 * (60 * 60 * 1000),
    // httpOnly flag makes sure the cookie is only accessed
    // through the HTTP protocol and not JS/browser
    httpOnly: true,
    // secure cookie should be turned to true to provide additional
    // layer of security so that the cookie is set only when working
    // in HTTPS mode.
    secure: false
  },
  // sessionSecret should be changed for security measures and concerns
  sessionSecret: process.env.SESSION_SECRET||'rajs',
  // sessionKey is set to the generic sessionId key used by PHP applications
  // for obsecurity reasons
  sessionKey: 'sessionId',
  sessionCollection: 'sessions',
  logo: 'modules/core/client/img/brand/logo.png',
  favicon: 'modules/core/client/img/brand/favicon.ico'
};
<|endoftext|>