<commit_before>/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/* global _playground */

define(function (require, exports, module) {
    "use strict";

    var EventEmitter = require("eventEmitter"),
        util = require("../util"),
        Promise = require("bluebird");

    /**
     * Promisified version of low-level keyboard focus functions
     */
    var _ui = Promise.promisifyAll(_playground.ps.ui);

    /* jshint bitwise: false */
    /**
     * Bitmask of all of the classic UI widgets we want to hide in DesignShop mode
     *
     * @const
     * @type {number}
     */
    var ALL_NONWINDOW_WIDGETS_BITMASK =
        _ui.widgetTypes.CONTROLBAR |
        _ui.widgetTypes.DOCUMENT_TABS |
        _ui.widgetTypes.PALETTE |
        _ui.widgetTypes.TOOLBAR;
    /* jshint bitwise: true */

    /**
     * The UI object provides helper methods for dealing with the
     * low-level native binding to Photoshop. This object will typically
     * not be used by user-level code.
     *
     * Emits low-level Photoshop events such as "select" with
     * the following parameters:
     *    1. @param {?} info about the event, dependent on event type (Note:
     *           this should become more specific as the native interface is
     *           further defined.)
     *
     * @extends EventEmitter
     * @constructor
     * @private
     */
    var UI = function () {
        EventEmitter.call(this);

        this._menuEventHandler = this._menuEventHandler.bind(this);
    };
    util.inherits(UI, EventEmitter);

    /**
     * Event handler for menu events from the native bridge.
     *
     * @private
     * @param {*=} err Error information
     * @param {string} menuCommand
     * @param {object} info
     */
    UI.prototype._menuEventHandler = function (err, menuCommand, info) {
        if (err) {
            this.emit("error", "Failed to handle menu event: " + err);
            return;
        }

        this.emit("menu", {
            command: menuCommand,
            info: info
        });
    };

    /**
     * Overscroll modes
     *
     * @const
     * @type{object.<number>}
     */
    UI.prototype.overscrollMode = _playground.ps.ui.overscrollMode;

    /**
     * Get the current Photoshop overscroll mode.
     *
     * @see UI.prototype.overscrollMode
     * @return {Promise.<number>} Resolves with the overscroll mode
     */
    UI.prototype.getOverscrollMode = function () {
        return _ui.getOverscrollModeAsync();
    };

    /**
     * Set the current Photoshop overscroll mode.
     *
     * @see UI.prototype.overscrollMode
     * @param {number} mode The desired overscroll model
     * @return {Promise.<number>} Resolves once the overscroll mode is set
     */
    UI.prototype.setOverscrollMode = function (mode) {
        var options = {
            mode: mode
        };

        return _ui.setOverscrollModeAsync(options);
    };

    /**
     * Determines whether the scrollbars are currently suppressed.
     *
     * @return {Promise.<boolean>}
     */
    UI.prototype.getSuppressScrollbars = function () {
        return _ui.getSuppressScrollbarsAsync();
    };

    /**
     * Sets whether or not the scrollbars should be suppressed.
     *
     * @param {boolean} suppress Whether or not the scrollbars should be suppressed
     * @return {Promise}
     */
    UI.prototype.setSuppressScrollbars = function (suppress) {
        return _ui.setSuppressScrollbarsAsync(suppress);
    };

    /**
     * Determines whether target path drawing is currently suppressed.
     *
     * @return {Promise.<boolean>}
     */
    UI.prototype.getSuppressTargetPaths = function () {
        return _ui.getSuppressTargetPathsAsync();
    };

    /**
     * Sets whether or not target path drawing should be suppressed.
     *
     * @param {boolean} suppress Whether or not target path drawing should be suppressed
     * @return {Promise}
     */
    UI.prototype.setSuppressTargetPaths = function (suppress) {
        return _ui.setSuppressTargetPathsAsync(suppress);
    };

    /**
     * Sets whether or not the Photoshop classic chrome is visible
     *
     * @param {boolean} visible Whether or not the chrome should be visible
     * @return {Promise}
     */
    UI.prototype.setClassicChromeVisibility = function (visible) {
        return this.setSuppressScrollbars(!visible).then(function () {
            _ui.setWidgetTypeVisibilityAsync(ALL_NONWINDOW_WIDGETS_BITMASK, visible);
        });

    };

    /**
     * Pointer propagation modes - Used for the default mouse policy
     * ALPHA_PROPAGATE: Default behavior, events will be sent to Playground
     * if they're clicking on a Playground view
     * ALWAYS_PROPAGATE: Playground will never get a pointer event
     * NEVER_PROPAGATE: Playground consumes all pointer events
     */
    UI.prototype.pointerPropagationMode = _playground.ps.ui.pointerPropagationMode;

    /**
     * Keyboard propagation modes - Used for the default keyboard policy
     * FOCUS_PROPAGATE: Default behavior, events will be sent to in focus element
     * ALWAYS_PROPAGATE: Playground will never get a keyboard event
     * NEVER_PROPAGATE: Playground consumes all keyboard events
     */
    UI.prototype.keyboardPropagationMode = _playground.ps.ui.keyboardPropagationMode;

    /**
     * Policy action modes - Used for custom policies
     * Numerically, they're identical for keyboard and pointer
     * ALPHA_PROPAGATE (applies as FOCUS_PROPAGATE on Keyboard events)
     * ALWAYS_PROPAGATE
     * NEVER_PROPAGATE
     */
    UI.prototype.policyAction = _playground.ps.ui.policyAction;

    /**
     * Command kinds - Used for certain commands that are also used in
     * OS dialogs (like copy/paste), with USER_DEFINED as extra
     */
    UI.prototype.commandKind = _playground.ps.ui.commandKind;

    /**
     * Gets the mode of pointer propagation determining the rules of
     * what mouse events will be trickled down to Playground layer.
     *
     * @return {Promise.<number>} Resolves to a value in pointerPropagationMode
     */
    UI.prototype.getPointerPropagationMode = function () {
        return _ui.getPointerPropagationModeAsync();
    };

    /**
     * Set the pointer propagation mode
     *
     * @param {number} mode What level of mouse events to pass to Playground
     *  possible values defined in UI.prototype.pointerPropagationMode
     * @return {Promise}
     */
    UI.prototype.setPointerPropagationMode = function (mode) {
        return _ui.setPointerPropagationModeAsync(mode);
    };

    /**
     * Gets the mode of keyboard propagation determining the rules of
     * what keyboard events will be trickled down to Playground layer.
     *
     * @return {Promise.<number>} Resolves to a value in keyboardPropagationMode
     */
    UI.prototype.getKeyboardPropagationMode = function () {
        return _ui.getKeyboardPropagationModeAsync();
    };

    /**
     * Set the keyboard propagation mode
     *
     * @param {number} mode What level of keyboard events to pass to Playground
     *  possible values defined in UI.prototype.keyboardPropagationMode
     * @return {Promise}
     */
    UI.prototype.setKeyboardPropagationMode = function (mode) {
        return _ui.setKeyboardPropagationModeAsync(mode);
    };

    /**
     * Installs the given list of pointer event policies into Photoshop
     * Each policy is an object with this structure:
     * {    eventKind: _playground.os.eventKind,
     *      modifiers: _playground.os.eventModifiers,
     *      keyCode: _playground.os.keyCode,
     *      action: _playground.ps.ui.policyAction
     * }
     *
     * @param {Array.<{eventKind: number, modifiers: number, keyCode: number, action: number}>} policyList
     */
    UI.prototype.setPointerEventPropagationPolicy = function (policyList) {
        return _ui.setPointerEventPropagationPolicyAsync({policyList: policyList});
    };

    /**
     * Installs the given list of keyboard event policies into Photoshop
     * Each policy is an object with this structure:
     * {    eventKind: _playground.os.eventKind,
     *      modifiers: _playground.os.eventModifiers,
     *      keyCode: _playground.os.keyCode,
     *      action: _playground.ps.ui.policyAction
     * }
     *
     * @param {Array.<{eventKind: number, modifiers: number, keyCode: number, action: number}>} policyList
     */
    UI.prototype.setKeyboardEventPropagationPolicy = function (policyList) {
        return _ui.setKeyboardEventPropagationPolicyAsync({policyList: policyList});
    };

    /**
     * Install a menu bar, which consists of an array of MenuEntry objects, an
     * example of which follows:
     *
     * {
     *      "id": "example-menu",
     *      "menu": [
     *           {
     *               "label": "Functions",
     *               "submenu": [
     *                   { "label": "Tool", "shortcut": {"key": "t", "modifiers": 2 }, "command": "application:tool" },
     *                   { "type": "separator" },
     *                   { "label": "More Tool", "command": "application:more-tool" }
     *               ]
     *           },
     *           {
     *               "label": "Frunctions",
     *               "submenu": [
     *                   { "label": "Tool", "shortcut": {"key": "t", "modifiers": 3 }, "command": "application:tool" },
     *                   { "type": "separator" },
     *                   { "label": "More Tool", "command": "application:more-tool" }
     *               ]
     *           }
     *      ]
     * }
     *
     * @param {object=} options Currently unused
     * @param {{id: string, menu: Array.<MenuEntry>}} description Menu description
     */
    UI.prototype.installMenu = function (options, description) {
        if (description === undefined) {
            description = options;
            options = {};
        }

        return _ui.installMenuAsync(options, description);
    };

    /**
     * Define the bounds of the non-UI portion of the application window.
     *
     * @param {{top: number, left: number, right:number, bottom: number}} offset
     * @return {Promise.<{top: number, left: number, right:number, bottom: number}>}
     */
    UI.prototype.setOverlayOffsets = function (offset) {
        return _ui.setOverlayOffsetsAsync({
            offset: offset
        });
    };

    /**
     * @type {UI} The UI singleton
     */
    var ui = new UI();

    // Install the menu notifier group handler
    _playground.setNotifier(_playground.notifierGroup.MENU, {}, ui._menuEventHandler);

    module.exports = ui;
});
<commit_msg>Suppress "options" dialogs, e.g., Create Rectangle.<commit_after>/*
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

/* global _playground */

define(function (require, exports, module) {
    "use strict";

    var EventEmitter = require("eventEmitter"),
        util = require("../util"),
        Promise = require("bluebird");

    /**
     * Promisified version of low-level keyboard focus functions
     */
    var _ui = Promise.promisifyAll(_playground.ps.ui);

    /* jshint bitwise: false */
    /**
     * Bitmask of all of the classic UI widgets we want to hide in DesignShop mode
     *
     * @const
     * @type {number}
     */
    var ALL_NONWINDOW_WIDGETS_BITMASK =
        _ui.widgetTypes.CONTROLBAR |
        _ui.widgetTypes.DOCUMENT_TABS |
        _ui.widgetTypes.PALETTE |
        _ui.widgetTypes.TOOLBAR;
    /* jshint bitwise: true */

    /**
     * The UI object provides helper methods for dealing with the
     * low-level native binding to Photoshop. This object will typically
     * not be used by user-level code.
     *
     * Emits low-level Photoshop events such as "select" with
     * the following parameters:
     *    1. @param {?} info about the event, dependent on event type (Note:
     *           this should become more specific as the native interface is
     *           further defined.)
     *
     * @extends EventEmitter
     * @constructor
     * @private
     */
    var UI = function () {
        EventEmitter.call(this);

        this._menuEventHandler = this._menuEventHandler.bind(this);
        this._interactionEventHandler = this._interactionEventHandler.bind(this);
    };
    util.inherits(UI, EventEmitter);

    /**
     * Event handler for menu events from the native bridge.
     *
     * @private
     * @param {*=} err Error information
     * @param {string} menuCommand
     * @param {object} info
     */
    UI.prototype._menuEventHandler = function (err, menuCommand, info) {
        if (err) {
            this.emit("error", "Failed to handle menu event: " + err);
            return;
        }

        this.emit("menu", {
            command: menuCommand,
            info: info
        });
    };

    /**
     * Event handler for interaction events (e.g., display of progress, error
     * or options dialogs) from the native bridge.
     *
     * @private
     * @param {*=} err Error information
     * @param {number} type
     * @param {object} info
     */
    UI.prototype._interactionEventHandler = function (err, type, info) {
        if (err) {
            this.emit("error", "Failed to handle interaction event: " + err);
            return;
        }

        var eventKind;
        switch (type) {
        case "progress":
            eventKind = "interactionProgress";
            break;
        case "error":
            eventKind = "interactionError";
            break;
        case "options":
            eventKind = "interactionOptions";
            break;
        default:
            return; // setNotifier registration callback
        }

        this.emit(eventKind, {
            info: info
        });
    };

    /**
     * Overscroll modes
     *
     * @const
     * @type{object.<number>}
     */
    UI.prototype.overscrollMode = _playground.ps.ui.overscrollMode;

    /**
     * Get the current Photoshop overscroll mode.
     *
     * @see UI.prototype.overscrollMode
     * @return {Promise.<number>} Resolves with the overscroll mode
     */
    UI.prototype.getOverscrollMode = function () {
        return _ui.getOverscrollModeAsync();
    };

    /**
     * Set the current Photoshop overscroll mode.
     *
     * @see UI.prototype.overscrollMode
     * @param {number} mode The desired overscroll model
     * @return {Promise.<number>} Resolves once the overscroll mode is set
     */
    UI.prototype.setOverscrollMode = function (mode) {
        var options = {
            mode: mode
        };

        return _ui.setOverscrollModeAsync(options);
    };

    /**
     * Determines whether the scrollbars are currently suppressed.
     *
     * @return {Promise.<boolean>}
     */
    UI.prototype.getSuppressScrollbars = function () {
        return _ui.getSuppressScrollbarsAsync();
    };

    /**
     * Sets whether or not the scrollbars should be suppressed.
     *
     * @param {boolean} suppress Whether or not the scrollbars should be suppressed
     * @return {Promise}
     */
    UI.prototype.setSuppressScrollbars = function (suppress) {
        return _ui.setSuppressScrollbarsAsync(suppress);
    };

    /**
     * Determines whether target path drawing is currently suppressed.
     *
     * @return {Promise.<boolean>}
     */
    UI.prototype.getSuppressTargetPaths = function () {
        return _ui.getSuppressTargetPathsAsync();
    };

    /**
     * Sets whether or not target path drawing should be suppressed.
     *
     * @param {boolean} suppress Whether or not target path drawing should be suppressed
     * @return {Promise}
     */
    UI.prototype.setSuppressTargetPaths = function (suppress) {
        return _ui.setSuppressTargetPathsAsync(suppress);
    };

    /**
     * Sets whether or not the Photoshop classic chrome is visible
     *
     * @param {boolean} visible Whether or not the chrome should be visible
     * @return {Promise}
     */
    UI.prototype.setClassicChromeVisibility = function (visible) {
        return this.setSuppressScrollbars(!visible).then(function () {
            _ui.setWidgetTypeVisibilityAsync(ALL_NONWINDOW_WIDGETS_BITMASK, visible);
        });

    };

    /**
     * Pointer propagation modes - Used for the default mouse policy
     * ALPHA_PROPAGATE: Default behavior, events will be sent to Playground
     * if they're clicking on a Playground view
     * ALWAYS_PROPAGATE: Playground will never get a pointer event
     * NEVER_PROPAGATE: Playground consumes all pointer events
     */
    UI.prototype.pointerPropagationMode = _playground.ps.ui.pointerPropagationMode;

    /**
     * Keyboard propagation modes - Used for the default keyboard policy
     * FOCUS_PROPAGATE: Default behavior, events will be sent to in focus element
     * ALWAYS_PROPAGATE: Playground will never get a keyboard event
     * NEVER_PROPAGATE: Playground consumes all keyboard events
     */
    UI.prototype.keyboardPropagationMode = _playground.ps.ui.keyboardPropagationMode;

    /**
     * Policy action modes - Used for custom policies
     * Numerically, they're identical for keyboard and pointer
     * ALPHA_PROPAGATE (applies as FOCUS_PROPAGATE on Keyboard events)
     * ALWAYS_PROPAGATE
     * NEVER_PROPAGATE
     */
    UI.prototype.policyAction = _playground.ps.ui.policyAction;

    /**
     * Command kinds - Used for certain commands that are also used in
     * OS dialogs (like copy/paste), with USER_DEFINED as extra
     */
    UI.prototype.commandKind = _playground.ps.ui.commandKind;

    /**
     * Gets the mode of pointer propagation determining the rules of
     * what mouse events will be trickled down to Playground layer.
     *
     * @return {Promise.<number>} Resolves to a value in pointerPropagationMode
     */
    UI.prototype.getPointerPropagationMode = function () {
        return _ui.getPointerPropagationModeAsync();
    };

    /**
     * Set the pointer propagation mode
     *
     * @param {number} mode What level of mouse events to pass to Playground
     *  possible values defined in UI.prototype.pointerPropagationMode
     * @return {Promise}
     */
    UI.prototype.setPointerPropagationMode = function (mode) {
        return _ui.setPointerPropagationModeAsync(mode);
    };

    /**
     * Gets the mode of keyboard propagation determining the rules of
     * what keyboard events will be trickled down to Playground layer.
     *
     * @return {Promise.<number>} Resolves to a value in keyboardPropagationMode
     */
    UI.prototype.getKeyboardPropagationMode = function () {
        return _ui.getKeyboardPropagationModeAsync();
    };

    /**
     * Set the keyboard propagation mode
     *
     * @param {number} mode What level of keyboard events to pass to Playground
     *  possible values defined in UI.prototype.keyboardPropagationMode
     * @return {Promise}
     */
    UI.prototype.setKeyboardPropagationMode = function (mode) {
        return _ui.setKeyboardPropagationModeAsync(mode);
    };

    /**
     * Installs the given list of pointer event policies into Photoshop
     * Each policy is an object with this structure:
     * {    eventKind: _playground.os.eventKind,
     *      modifiers: _playground.os.eventModifiers,
     *      keyCode: _playground.os.keyCode,
     *      action: _playground.ps.ui.policyAction
     * }
     *
     * @param {Array.<{eventKind: number, modifiers: number, keyCode: number, action: number}>} policyList
     */
    UI.prototype.setPointerEventPropagationPolicy = function (policyList) {
        return _ui.setPointerEventPropagationPolicyAsync({policyList: policyList});
    };

    /**
     * Installs the given list of keyboard event policies into Photoshop
     * Each policy is an object with this structure:
     * {    eventKind: _playground.os.eventKind,
     *      modifiers: _playground.os.eventModifiers,
     *      keyCode: _playground.os.keyCode,
     *      action: _playground.ps.ui.policyAction
     * }
     *
     * @param {Array.<{eventKind: number, modifiers: number, keyCode: number, action: number}>} policyList
     */
    UI.prototype.setKeyboardEventPropagationPolicy = function (policyList) {
        return _ui.setKeyboardEventPropagationPolicyAsync({policyList: policyList});
    };

    /**
     * Install a menu bar, which consists of an array of MenuEntry objects, an
     * example of which follows:
     *
     * {
     *      "id": "example-menu",
     *      "menu": [
     *           {
     *               "label": "Functions",
     *               "submenu": [
     *                   { "label": "Tool", "shortcut": {"key": "t", "modifiers": 2 }, "command": "application:tool" },
     *                   { "type": "separator" },
     *                   { "label": "More Tool", "command": "application:more-tool" }
     *               ]
     *           },
     *           {
     *               "label": "Frunctions",
     *               "submenu": [
     *                   { "label": "Tool", "shortcut": {"key": "t", "modifiers": 3 }, "command": "application:tool" },
     *                   { "type": "separator" },
     *                   { "label": "More Tool", "command": "application:more-tool" }
     *               ]
     *           }
     *      ]
     * }
     *
     * @param {object=} options Currently unused
     * @param {{id: string, menu: Array.<MenuEntry>}} description Menu description
     */
    UI.prototype.installMenu = function (options, description) {
        if (description === undefined) {
            description = options;
            options = {};
        }

        return _ui.installMenuAsync(options, description);
    };

    /**
     * Define the bounds of the non-UI portion of the application window.
     *
     * @param {{top: number, left: number, right:number, bottom: number}} offset
     * @return {Promise.<{top: number, left: number, right:number, bottom: number}>}
     */
    UI.prototype.setOverlayOffsets = function (offset) {
        return _ui.setOverlayOffsetsAsync({
            offset: offset
        });
    };

    /**
     * @type {UI} The UI singleton
     */
    var ui = new UI();

    // Install the menu notifier group handler
    _playground.setNotifier(_playground.notifierGroup.MENU, {}, ui._menuEventHandler);

    // Install the interaction notifier group handler. For now, only listen to "options"
    // events, but not "progress" or "error" events, because listening for a particular
    // class of events also suppresses the corresponding interaction dialog.
    _playground.setNotifier(_playground.notifierGroup.INTERACTION, {
        notificationKind: _playground.notifierOptions.interaction.OPTIONS
    }, ui._interactionEventHandler);

    module.exports = ui;
});
<|endoftext|>


<commit_before>/**
* Node dependencies
**/
import fs from 'fs';
import path from 'path';
import os from 'os';
import { fork } from 'child_process';

/**
* NPM dependencies
**/
import { CLIEngine } from 'eslint';
import glob from 'glob';

/**
* Local dependencies
**/
import { formatResults } from './formatter

const cpuCount = os.cpus().length;

function getIgnorePatterns(options) {
  let ignorePath = path.join(options.cwd || process.cwd(), '.eslintignore');
  try {
    const ignore = fs.readFileSync(
      ignorePath, 'utf8'
    ).trim().split('\n');

    if (options.ignorePattern) {
      ignore.push(options.ignorePattern);
    }
    return ignore;
  } catch (e) {
    return [];
  }
}

function hasEslintCache(options) {
  const cacheLocation = (
    options.cacheFile || options.cacheLocation || path.join(
      options.cwd || process.cwd(), '.eslintcache'
    )
  );
  try {
    fs.accessSync(path.resolve(cacheLocation), fs.F_OK);
    return true;
  } catch (e) {
    return false;
  }
}

function getFilesByPatterns(patterns, options) {
  const ignore = getIgnorePatterns(options);
  let files = [];

  patterns.forEach(pattern => {
    let isFile = false;
    let isFolder = false;
    try {
      const stats = fs.lstatSync(pattern);
      isFile = stats.isFile();
      isFolder = stats.isDirectory();
    } catch (e) {
      //no-op
    }

    if (isFile) {
      files.push(pattern);
    } else {
      const path = isFolder ? `${pattern.replace(/\'|\"|\/$/g, '')}/**` :
        pattern.replace(/\'|\"|\/$/g, '');
      const newFiles = glob.sync(
        path, { cwd: options.cwd || process.cwd(), nodir: true, ignore }
      );
      files = files.concat(newFiles);
    }
  });

  return files;
}

function eslintFork(options, files) {
  return new Promise((resolve, reject) => {
    const eslintChild = fork(path.resolve(__dirname, 'linter'));
    eslintChild.on('message', (report) => {
      if (report.errorCount || report.warningCount) {
        console.log(formatResults(report.results));
      }
      resolve(report);
    });
    eslintChild.on('exit', (code) => {
      if (code !== 0) {
        reject('Linting failed');
      }
    });
    eslintChild.send({options, files});
  });
}

export default class Linter {
  constructor (options) {
    this._options = options;
    this._engine = new CLIEngine(options);
  }

  run (files) {
    return new Promise((resolve) => {
      const report = this._engine.executeOnFiles(files);
      if (this._options.fix) {
        this._engine.outputFixes(report);
      }

      if (this._options.quiet) {
        report.results = this._engine.getErrorResults(report.results);
      }
      resolve(report);
    });
  }

  execute(patterns) {
    return new Promise((resolve, reject) => {
      const files = getFilesByPatterns(
        patterns, this._options
      );

      const hasCache = hasEslintCache(this._options);

      if (!hasCache && files.length > 50 && cpuCount >= 2) {
        // too many items, need to spawn process (if machine has multi-core)
        const totalCount = {
          errorCount: 0,
          warningCount: 0
        };
        const chunckedPromises = [];
        const chunkSize = Math.ceil(files.length / cpuCount);
        for (let i = 0; i < files.length; i += chunkSize) {
          const chunkedPaths = files.slice(i, i + chunkSize);
          const chunckedPromise = eslintFork(
            this._options, chunkedPaths
          );
          chunckedPromise.then((report) => {
            totalCount.errorCount += report.errorCount;
            totalCount.warningCount += report.warningCount;
          });
          chunckedPromises.push(chunckedPromise);
        }
        Promise.all(chunckedPromises).then(() => {
          resolve(totalCount);
        });
      } else {
        this.run(files).then((report) => {
          if (report.errorCount || report.warningCount) {
            console.log(formatResults(report.results));
          }
          resolve(report);
        }, reject);
      }
    });
  }
}

process.on('message', ({options, files}) => {
  // make sure to ignore message to other nested processes
  if (files) {
    new Linter(options).run(files).then((report) => {
      process.send(report);
    }, (err) => {
      console.log(err);
      process.exit(1);
    });
  }
});
<commit_msg>my first build<commit_after>/**
* Node dependencies
**/
import fs from 'fs';
import path from 'path';
import os from 'os';
import { fork } from 'child_process';

/**
* NPM dependencies
**/
import { CLIEngine } from 'eslint';
import glob from 'glob';

/**
* Local dependencies
**/
import { formatResults } from './formatter';

const cpuCount = os.cpus().length;

function getIgnorePatterns(options) {
  let ignorePath = path.join(options.cwd || process.cwd(), '.eslintignore');
  try {
    const ignore = fs.readFileSync(
      ignorePath, 'utf8'
    ).trim().split('\n');

    if (options.ignorePattern) {
      ignore.push(options.ignorePattern);
    }
    return ignore;
  } catch (e) {
    return [];
  }
}

function hasEslintCache(options) {
  const cacheLocation = (
    options.cacheFile || options.cacheLocation || path.join(
      options.cwd || process.cwd(), '.eslintcache'
    )
  );
  try {
    fs.accessSync(path.resolve(cacheLocation), fs.F_OK);
    return true;
  } catch (e) {
    return false;
  }
}

function getFilesByPatterns(patterns, options) {
  const ignore = getIgnorePatterns(options);
  let files = [];

  patterns.forEach(pattern => {
    let isFile = false;
    let isFolder = false;
    try {
      const stats = fs.lstatSync(pattern);
      isFile = stats.isFile();
      isFolder = stats.isDirectory();
    } catch (e) {
      //no-op
    }

    if (isFile) {
      files.push(pattern);
    } else {
      const path = isFolder ? `${pattern.replace(/\'|\"|\/$/g, '')}/**` :
        pattern.replace(/\'|\"|\/$/g, '');
      const newFiles = glob.sync(
        path, { cwd: options.cwd || process.cwd(), nodir: true, ignore }
      );
      files = files.concat(newFiles);
    }
  });

  return files;
}

function eslintFork(options, files) {
  return new Promise((resolve, reject) => {
    const eslintChild = fork(path.resolve(__dirname, 'linter'));
    eslintChild.on('message', (report) => {
      if (report.errorCount || report.warningCount) {
        console.log(formatResults(report.results));
      }
      resolve(report);
    });
    eslintChild.on('exit', (code) => {
      if (code !== 0) {
        reject('Linting failed');
      }
    });
    eslintChild.send({options, files});
  });
}

export default class Linter {
  constructor (options) {
    this._options = options;
    this._engine = new CLIEngine(options);
  }

  run (files) {
    return new Promise((resolve) => {
      const report = this._engine.executeOnFiles(files);
      if (this._options.fix) {
        this._engine.outputFixes(report);
      }

      if (this._options.quiet) {
        report.results = this._engine.getErrorResults(report.results);
      }
      resolve(report);
    });
  }

  execute(patterns) {
    return new Promise((resolve, reject) => {
      const files = getFilesByPatterns(
        patterns, this._options
      );

      const hasCache = hasEslintCache(this._options);

      if (!hasCache && files.length > 50 && cpuCount >= 2) {
        // too many items, need to spawn process (if machine has multi-core)
        const totalCount = {
          errorCount: 0,
          warningCount: 0
        };
        const chunckedPromises = [];
        const chunkSize = Math.ceil(files.length / cpuCount);
        for (let i = 0; i < files.length; i += chunkSize) {
          const chunkedPaths = files.slice(i, i + chunkSize);
          const chunckedPromise = eslintFork(
            this._options, chunkedPaths
          );
          chunckedPromise.then((report) => {
            totalCount.errorCount += report.errorCount;
            totalCount.warningCount += report.warningCount;
          });
          chunckedPromises.push(chunckedPromise);
        }
        Promise.all(chunckedPromises).then(() => {
          resolve(totalCount);
        });
      } else {
        this.run(files).then((report) => {
          if (report.errorCount || report.warningCount) {
            console.log(formatResults(report.results));
          }
          resolve(report);
        }, reject);
      }
    });
  }
}

process.on('message', ({options, files}) => {
  // make sure to ignore message to other nested processes
  if (files) {
    new Linter(options).run(files).then((report) => {
      process.send(report);
    }, (err) => {
      console.log(err);
      process.exit(1);
    });
  }
});
<|endoftext|>


<commit_before>import FeatureTrack from "./feature-track.js";
import HistogramRenderer from "../renderers/histogram-renderer.js";
import VariantRenderer from "../renderers/variant-renderer.js";

export default class OpenCGAVariantTrack extends FeatureTrack {

    constructor(config) {
        super(config);

        // Initialize Rendererers
        this.histogramRenderer = new HistogramRenderer(this.config.histogramRenderer);
        this.renderer = new VariantRenderer({
            ...this.config.renderer,
            // sampleNames: this.config.opencgaSamples,
        });
    }

    getData(options) {
        if (options.dataType === "histogram") {
            // Fetch aggregation stats for the current region
            return this.config.opencgaClient.variants().aggregationStats({
                studies: this.config.opencgaStudies,
                region: options.region.toString(),
                field: `start[${options.region.start}..${options.region.end}]:${this.config.histogramInterval}`,
            });
        } else {
            // Fetch variants
            return this.config.opencgaClient.variants().query({
                studies: this.config.opencgaStudies,
                limit: 5000,
                region: options.region.toString(),
                include: "id,chromosome,start,end,strand,type,annotation.displayConsequenceType",
            });
        }
    }

    // Get default config
    getDefaultConfig() {
        return {
            title: "",
            height: 200,
            maxHeight: 300,
            resizable: true,
            dataAdapter: null,
            opencgaClient: null,
            opencgaStudies: "",
            opencgaSamples: [],
            opencgaFiles: [],
            histogramMinRegionSize: 200000, // 300000000,
            histogramInterval: 10000,
            labelMaxRegionSize: 10000000,
            renderer: {}, // Renderer configuration
            histogramRenderer: {}, // Histogram renderer configuration
        };
    }

}
<commit_msg>gb: improve variant track for displaying samples names (#337)<commit_after>import UtilsNew from "../../core/utilsNew.js";
import FeatureTrack from "./feature-track.js";
import HistogramRenderer from "../renderers/histogram-renderer.js";
import VariantRenderer from "../renderers/variant-renderer.js";
import FeatureRenderer from "../renderers/feature-renderer.js";
import GenomeBrowserUtils from "../genome-browser-utils.js";

export default class OpenCGAVariantTrack extends FeatureTrack {

    constructor(config) {
        super(config);

        this.sampleNames = [];

        // Initialize Rendererers
        this.histogramRenderer = new HistogramRenderer(this.config.histogramRenderer);
        this.renderer = new FeatureRenderer({
            color: GenomeBrowserUtils.variantColorFormatter,
            label: GenomeBrowserUtils.variantLabelFormatter,
            tooltipTitle: GenomeBrowserUtils.variantTooltipTitleFormatter,
            tooltipText: GenomeBrowserUtils.variantTooltipTextFormatter,
            histogramColor: "#58f3f0",
            ...this.config.renderer,
        });

        // Check if samples has been provided in the query object
        if (this.config?.query?.sample) {
            this.sampleNames = this.config.query.sample.split(";")
                .map(item => item.split(":")[0])
                .filter(name => !!name);

            // Initialize samples DOM
            this.#initSamplesDOM();

            // Initialize variant renderer
            this.renderer = new VariantRenderer({
                sampleNames: this.sampleNames,
                sampleNamesHeight: this.config.sampleNamesHeight,
                ...this.config.renderer,
            });
        }
    }

    #initSamplesDOM() {
        const nameHeight = this.config.sampleNamesHeight;
        const template = UtilsNew.renderHTML(`

                ${this.sampleNames.map(name => `

                        ${name}

                `)}

        `);

        this.sampleNamesDiv = template.querySelector(`div#${this.prefix}SampleNames`);
        this.sampleNamesDiv.style.backgroundColor = "rgba(255,255,255,0.8)";
        this.sampleNamesDiv.style.paddingLeft = "16px";
        this.sampleNamesDiv.style.paddingRight = "8px";
        this.sampleNamesDiv.style.paddingTop = `${nameHeight}px`;

        // Append samples names
        this.content.appendChild(this.sampleNamesDiv);
    }

    getData(options) {
        if (options.dataType === "histogram") {
            // Fetch aggregation stats for the current region
            return this.config.opencgaClient.variants().aggregationStats({
                study: this.config.opencgaStudy,
                region: options.region.toString(),
                field: `start[${options.region.start}..${options.region.end}]:${this.config.histogramInterval}`,
            });
        } else {
            // Fetch variants
            return this.config.opencgaClient.variants().query({
                ...(this.config.query || {}),
                study: this.config.opencgaStudy,
                limit: 5000,
                region: options.region.toString(),
                include: "id,chromosome,start,end,strand,type,annotation.displayConsequenceType,studies",
            });
        }
    }

    // Get default config
    getDefaultConfig() {
        return {
            title: "",
            height: 200,
            maxHeight: 300,
            resizable: true,
            dataAdapter: null,
            opencgaClient: null,
            opencgaStudy: "",
            // opencgaSamples: [],
            // opencgaFiles: [],
            query: null,
            histogramMinRegionSize: 300000000,
            histogramInterval: 10000,
            labelMaxRegionSize: 10000000,
            renderer: {}, // Renderer configuration
            histogramRenderer: {}, // Histogram renderer configuration
            sampleNamesHeight: 20,
        };
    }

}
<|endoftext|>


<commit_before>define(function(require){
    var _ = require('underscore');

    templateObjProvider.$inject = ['templateDefaultContext'];
    function templateObjProvider(templateDefaultContext){

        function templateObj(obj, context, options){
            var skip = _.get(options, 'skip', []);
            var result = {};
            var key;
            var ctx = _.assign({}, context, templateDefaultContext);

            for (key in obj){
                result[key] = (skip.indexOf(key) == -1) ? expand(obj[key]) : obj[key];
            }

            return result;

            function expand(value){
                if (_.isString(value)) return template(value, ctx);
                if (_.isArray(value)) return value.map(expand);
                if (_.isPlainObject(value)) return _.mapValues(value, expand);
                return value;
            }

            function template(input){
                // if there is no template just return the string
                if (!~input.indexOf('<%')) return input;
                return _.template(input)(context);
            }
        }

        return templateObj;

    }

    return templateObjProvider;
});
<commit_msg>fix(database): use correct context for templateObj<commit_after>define(function(require){
    var _ = require('underscore');

    templateObjProvider.$inject = ['templateDefaultContext'];
    function templateObjProvider(templateDefaultContext){

        function templateObj(obj, context, options){
            var skip = _.get(options, 'skip', []);
            var result = {};
            var key;
            var ctx = _.assign({}, context, templateDefaultContext);

            for (key in obj){
                result[key] = (skip.indexOf(key) == -1) ? expand(obj[key]) : obj[key];
            }

            return result;

            function expand(value){
                if (_.isString(value)) return template(value);
                if (_.isArray(value)) return value.map(expand);
                if (_.isPlainObject(value)) return _.mapValues(value, expand);
                return value;
            }

            function template(input){
                // if there is no template just return the string
                if (!~input.indexOf('<%')) return input;
                return _.template(input)(ctx);
            }
        }

        return templateObj;
    }

    return templateObjProvider;
});
<|endoftext|>


<commit_before>import App from '../ui/App.jsx'

const _require = require
const requirePage = (callback, path) => {
    _require.ensure([], function (require) {
        callback(null, require('../ui/pages/' + path).default)
    })
}

let childRoutes = [
    {
        path: '/fleets',
        name: 'Fleet Emulator',
        getComponents(nextState, callback) {
            requirePage(callback, 'Fleet/List.jsx')
        }
    },
    {
        path: '/ships',
        name: 'Ship-girls',
        getComponents(nextState, callback) {
            requirePage(callback, 'Ship/List.jsx')
        }
    },
    {
        path: '/equipments',
        name: 'Equipments',
        getComponents(nextState, callback) {
            requirePage(callback, 'Equipment/List.jsx')
        }
    },
    {
        path: '/arsenal',
        name: 'Akashi\'s Arsenal',
        getComponents(nextState, callback) {
            requirePage(callback, 'Arsenal/Page.jsx')
        }
    },
    {
        path: '/entities',
        name: 'CV & Illustrators',
        getComponents(nextState, callback) {
            requirePage(callback, 'Entity/List.jsx')
        }
    },
    {
        path: '/calctp',
        name: 'Calculator: TP',
        getComponents(nextState, callback) {
            requirePage(callback, 'Calculator/TP.jsx')
        }
    },
    {
        path: '/donate',
        name: 'Donate',
        getComponents(nextState, callback) {
            requirePage(callback, 'Donate.jsx')
        }
    }
]

if (window.isDev)
    childRoutes.push({
        path: '/dev',
        getComponents(nextState, callback) {
            requirePage(callback, 'Dev.jsx')
        }
    })

export default {
    path: '/',
    component: App,

    getIndexRoute(partialNextState, callback) {
        _require.ensure([], function (require) {
            callback(null, {
                component: require('../ui/pages/Home.jsx').default,
            })
        })
    },

    // childRoutes: []
    childRoutes: childRoutes
}<commit_msg>try fixing router issues<commit_after>import App from '../ui/App.jsx'

const _require = require
const pathPages = '../ui/pages/'
const requirePage = (callback, file) => {
    _require.ensure([], function (require) {
        callback(null, require('../ui/pages/' + file).default)
    })
}

let childRoutes = [
    {
        path: '/fleets',
        name: 'Fleet Emulator',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Fleet/List.jsx').default)
            })
        }
    },
    {
        path: '/ships',
        name: 'Ship-girls',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Ship/List.jsx').default)
            })
        }
    },
    {
        path: '/equipments',
        name: 'Equipments',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Equipment/List.jsx').default)
            })
        }
    },
    {
        path: '/arsenal',
        name: 'Akashi\'s Arsenal',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Arsenal/Page.jsx').default)
            })
        }
    },
    {
        path: '/entities',
        name: 'CV & Illustrators',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Entity/List.jsx').default)
            })
        }
    },
    {
        path: '/calctp',
        name: 'Calculator: TP',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Calculator/TP.jsx').default)
            })
        }
    },
    {
        path: '/donate',
        name: 'Donate',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Donate.jsx').default)
            })
        }
    }
]

if (window.isDev)
    childRoutes.push({
        path: '/dev',
        getComponents(nextState, callback) {
            _require.ensure([], function (require) {
                callback(null, require(pathPages + 'Dev.jsx').default)
            })
        }
    })

export default {
    path: '/',
    component: App,

    getIndexRoute(partialNextState, callback) {
        _require.ensure([], function (require) {
            callback(null, {
                component: require(pathPages + 'Home.jsx').default,
            })
        })
    },

    // childRoutes: []
    childRoutes: childRoutes
}<|endoftext|>


<commit_before>/* Function to check if view passed in is the current view */
function isCurrentView(v) {
  if(Session.get('currentView') === v) {
     return true;
  } else {
    return false;
  }
}

/* Function to get the userId of the other user (not current user) */
function getOtherUserId(fromId, toId) {
  if(fromId === Meteor.userId())
  {
    return toId;
  } else {
    return fromId;
  }
}

/* Function to get the username of the other user (not current user) */
function getOtherUsername(fromName, toName) {
  if(fromName === Meteor.user().username)
  {
    Session.set('originating', 'from');
    return toName;
  } else {
    Session.set('originating', 'to');
    return fromName;
  }
}

/* Function to format the passed in date */
function performFormatting(date) {
  let currDate = moment(new Date()),
      msgDate = moment(new Date(date));

  let diff = currDate.diff(msgDate, 'days');

  if(diff === 0 && currDate.day() === msgDate.day()) {
    return moment(date).format('h:mm a');
  } else if(diff < 7 && currDate.day() !== msgDate.day()) {
    return moment(date).format('dddd');
  } else {
    if(currDate.year() != msgDate.year()) {
      return moment(date).format('MM/DD/YY');
    } else {
      return moment(date).format('MMM DD');
    }
  }
}

/* Helper function available to all templates that calls getOtherUsername */
Template.registerHelper('getOtherUsername', function(fromName, toName) {
  return getOtherUsername(fromName, toName);
});

/* On messages template created */
Template.messages.onCreated(function () {
  this.searchQuery = new ReactiveVar('');
  this.limit = new ReactiveVar(20);
  this.usersCount = new ReactiveVar(0);

  this.autorun(() => {
    //Set subscriptions
    this.subscribe('users.all', this.searchQuery.get(), this.limit.get());
    this.usersCount.set(Counts.get('users.all'));
    this.subscribe('messages.all');

    //Set session variables
    Session.set('currentView', 'allMessages');
    Session.set('selectedMsg', '');
    Session.set('originating', '');
    $('#allMessagesButton').addClass('active');
  });
});

/* messages template helpers */
Template.messages.helpers({
  showAllMessages: () => {
    return isCurrentView('allMessages');
  },
  showSingleMessage: () => {
    return isCurrentView('singleMessage');
  },
  showCompose: () => {
    return isCurrentView('compose');
  }
});

/* messages template events */
Template.messages.events({
  'click #allMessagesButton, click #composeButton': (event, template) => {
    //Set template based on button that was clicked
    $('button').removeClass('active');
    $('#' + event.target.id).addClass('active');
    Session.set('currentView', event.target.id.toString().replace('Button', ''));
  }
});

/* allMessages helpers */
Template.allMessages.helpers({
  getAllMessages: () => {
    //Find all messages that current user is involved in
    return Messages.find({$or: [{ 'originatingFromId': Meteor.userId(), 'conversation.originatingFromDeleted': false }, {'originatingToId': Meteor.userId(), 'conversation.originatingToDeleted': false}]}, {sort: {'conversation.sentOn': -1} });
  },
  messagesEmpty: () => {
    //Check if current user has any messages
    if(Messages.find({$or: [{ 'originatingFromId': Meteor.userId(), 'conversation.originatingFromDeleted': false }, {'originatingToId': Meteor.userId(), 'conversation.originatingToDeleted': false}]}).count() === 0) {
      return true;
    } else {
      return false;
    }
  },
  formatDate: (conversation) => {
    if(conversation.length > 0)
    {
      let date = conversation[conversation.length - 1].sentOn;

      return performFormatting(date);
    }
  },
  getMostRecentBody: (conversation) => {
    if(conversation.length > 0) {
      return conversation[conversation.length - 1].body;
    }
  },
  getMostRecentRead: (conversation) => {
    //Determine if message has been read
    if(conversation.length > 0) {
      if(conversation[conversation.length - 1].to.userId === Meteor.userId()) {
        if(!conversation[conversation.length - 1].to.read) {
          return 'notRead';
        }
      }
    }

    return '';
  }
});

/* allMessages template events */
Template.allMessages.events({
  'click .msg': (event, template) => {
    //Make sure selected message exists
    let selectedMsg = Messages.findOne({_id: event.currentTarget.id});
    if(selectedMsg) {
      if(selectedMsg.conversation[selectedMsg.conversation.length - 1].to.userId === Meteor.userId()) {
        //Check if most recent message is TO the current user
        if(!selectedMsg.conversation[selectedMsg.conversation.length - 1].to.read) {
          //Update read field to true
          Meteor.call('messages.updateRead', selectedMsg._id, true, (error, result) => {
            //Do nothing
          });
        }

      }
    }

    //Set current view to singleMssage template
    $('button').removeClass('active');
    Session.set('selectedMsg', event.currentTarget.id);
    Session.set('currentView', 'singleMessage');
  },
  'click .remove-message': (event, template) => {
    event.stopPropagation();

    //Sweet Alert delete confirmation
    swal({
      title: 'Delete message?',
      text: 'Are you sure that you want to delete this message?',
      type: 'error',
      showCancelButton: true,
      closeOnConfirm: true,
      cancelButtonText: 'No',
      confirmButtonText: 'Yes, delete it!',
      confirmButtonColor: '#da5347'
    }, function() {
      //Get the id of the message to be deleted
      let msgId = event.currentTarget.parentNode.parentNode.id;

      //Make sure message exists
      let msg = Messages.findOne({ '_id': msgId } );
      let whoDeleted;

      //If message exists
      if(msg) {
        //Set deleted correctly
        if(msg.originatingFromId === Meteor.userId()) {
          whoDeleted = 'from';
        } else {
          whoDeleted = 'to';
        }

        //Remove selected message
        Meteor.call('messages.remove', msgId, whoDeleted, (error, result) => {
          if(error) {
            Bert.alert('Message couldn\'t be deleted.', 'danger', 'growl-top-right');
          } else {
            Bert.alert('Message deleted', 'success', 'growl-top-right');
          }
        });
      } else {
        Bert.alert('Message couldn\'t be deleted.', 'danger', 'growl-top-right');
      }
    });
  }
});

/* singleMessage template on rendered */
Template.singleMessage.onRendered(function() {
  //Move to bottom of div so most recent message is shown
  $('#singleMessageArea').scrollTop($('#singleMessageArea')[0].scrollHeight);

  //Set focus to the reply body text area
  $('[data-id=reply-body]').focus();
});

/* singleMessage template helpers */
Template.singleMessage.helpers({
  getSingleMessage: () => {
    return Messages.findOne({ '_id': Session.get('selectedMsg') } );
  },
  showMessage: (originatingFromDeleted, originatingToDeleted) => {
    //Don't show messages that have been previously deleted
    if(Session.equals('originating', 'from')) {
      return !originatingFromDeleted;
    } else {
      return !originatingToDeleted;
    }
  },
  fromOtherUser: (from, to) => {
    if(from.userId !== Meteor.userId()) {
      return true;
    } else {
      return false;
    }
  },
  formatDate: (date) => {
    return performFormatting(date);
  }
});

/* singleMessage template events */
Template.singleMessage.events({
    'submit [data-id=reply-message-form]': (event, template) => {
      event.preventDefault();

      let body = template.find('[data-id=reply-body]').value,
          currMessage = Messages.findOne({_id: Session.get('selectedMsg')}),
          toUserId = getOtherUserId(currMessage.originatingFromId, currMessage.originatingToId),
          fieldEmpty = false;

      //Make sure fields arent empty
      if(!body.toString().trim()) {
        fieldEmpty = true;
        Bert.alert('Please enter a message.', 'danger', 'growl-top-right');
      }
      if(!fieldEmpty && !toUserId) {
        fieldEmpty = true;
        Bert.alert('Error sending message.', 'danger', 'growl-top-right');
      }

      //Continue if the fields aren't empty
      if(!fieldEmpty) {
        //Add reply to the conversation array of the existing message
        Meteor.call('messages.addMessage', Session.get('selectedMsg'), toUserId, body, (error, result) => {
          if(error) {
            Bert.alert(error.reason, 'danger', 'growl-top-right');
          } else {
            //Display success message and reset form values
            Bert.alert('Message sent', 'success', 'growl-top-right');
            template.find('[data-id=reply-body]').value = '';

            //Switch the to allMessages view
            $('button').removeClass('active');
            $('#allMessagesButton').addClass('active');
            Session.set('currentView', 'allMessages');
          }
        });
      }
    }
});

/* compose template on rendered */
Template.compose.onRendered(function() {
  //Set focus to the to text area
  $('[data-id=message-to]').focus();
});

/* compose template events */
Template.compose.events({
  'submit [data-id=send-message-form]': (event, template) => {
    event.preventDefault();

    //Get text from To and Body fields
    let to = template.find('[data-id=message-to]').value.toString().trim(),
        body = template.find('[data-id=message-body]').value,
        fieldEmpty = false;

    //Verify that both fields contain text
    if(!to) {
        fieldEmpty = true;
        Bert.alert('Please enter a username in the To field.', 'danger', 'growl-top-right');
    }
    if(!fieldEmpty && !body.toString().trim()) {
        fieldEmpty = true;
        Bert.alert('Please enter a message.', 'danger', 'growl-top-right');
    }

    //Continue if the fields aren't empty
    if(!fieldEmpty) {
      //Try to find user in Users collection
      let toUser = Meteor.users.findOne({username: to});

      //If user was found then it is a valid user
      if(toUser) {
        //If user is not the current user then send the message
        if(toUser._id != Meteor.userId())
        {
          //If message between these two users already exists, add this message to the current conversation, else create a new message
          let existingMessage = Messages.findOne({$or: [{'originatingFromId': Meteor.userId()}, {'originatingToId': Meteor.userId()}], $or: [{'originatingFromId': toUser._id}, {'originatingToId': toUser._id}]});

          if(existingMessage) {
            //Add message to existing conversation
            Meteor.call('messages.addMessage', existingMessage._id, toUser._id, body, (error, result) => {
              if(error) {
                Bert.alert(error.reason, 'danger', 'growl-top-right');
              } else {
                //Display success message and reset form values
                Bert.alert('Message sent', 'success', 'growl-top-right');
                template.find('[data-id=message-to]').value = '';
                template.find('[data-id=message-body]').value = '';

                //Switch the to allMessages view
                $('button').removeClass('active');
                $('#allMessagesButton').addClass('active');
                Session.set('currentView', 'allMessages');
              }
            });
          } else {
            //Create new message
            Meteor.call('messages.insert', toUser._id, toUser.username, body, (error, result) => {
              if(error) {
                Bert.alert(error.reason, 'danger', 'growl-top-right');
              } else {
                //Display success message and reset form values
                Bert.alert('Message sent', 'success', 'growl-top-right');

                //Switch the to allMessages view
                $('button').removeClass('active');
                $('#allMessagesButton').addClass('active');
                Session.set('currentView', 'allMessages');
              }
            });
          }
        } else {
          //Can't send a message to yourself, display error
          Bert.alert('Sorry, you can only send messages to other users.', 'danger', 'growl-top-right');
        }
      } else {
        //Wasn't a valid user, display error
        Bert.alert('Sorry, we can\'t find that user.  Please verify the username and try again.', 'danger', 'growl-top-right');
      }
    }
  }
});

<commit_msg>Stay in message section after replying to a message, #89<commit_after>/* Function to check if view passed in is the current view */
function isCurrentView(v) {
  if(Session.get('currentView') === v) {
     return true;
  } else {
    return false;
  }
}

/* Function to get the userId of the other user (not current user) */
function getOtherUserId(fromId, toId) {
  if(fromId === Meteor.userId())
  {
    return toId;
  } else {
    return fromId;
  }
}

/* Function to get the username of the other user (not current user) */
function getOtherUsername(fromName, toName) {
  if(fromName === Meteor.user().username)
  {
    Session.set('originating', 'from');
    return toName;
  } else {
    Session.set('originating', 'to');
    return fromName;
  }
}

/* Function to format the passed in date */
function performFormatting(date) {
  let currDate = moment(new Date()),
      msgDate = moment(new Date(date));

  let diff = currDate.diff(msgDate, 'days');

  if(diff === 0 && currDate.day() === msgDate.day()) {
    return moment(date).format('h:mm a');
  } else if(diff < 7 && currDate.day() !== msgDate.day()) {
    return moment(date).format('dddd');
  } else {
    if(currDate.year() != msgDate.year()) {
      return moment(date).format('MM/DD/YY');
    } else {
      return moment(date).format('MMM DD');
    }
  }
}

/* Helper function available to all templates that calls getOtherUsername */
Template.registerHelper('getOtherUsername', function(fromName, toName) {
  return getOtherUsername(fromName, toName);
});

/* On messages template created */
Template.messages.onCreated(function () {
  this.searchQuery = new ReactiveVar('');
  this.limit = new ReactiveVar(20);
  this.usersCount = new ReactiveVar(0);

  this.autorun(() => {
    //Set subscriptions
    this.subscribe('users.all', this.searchQuery.get(), this.limit.get());
    this.usersCount.set(Counts.get('users.all'));
    this.subscribe('messages.all');

    //Set session variables
    Session.set('currentView', 'allMessages');
    Session.set('selectedMsg', '');
    Session.set('originating', '');
    $('#allMessagesButton').addClass('active');
  });
});

/* messages template helpers */
Template.messages.helpers({
  showAllMessages: () => {
    return isCurrentView('allMessages');
  },
  showSingleMessage: () => {
    return isCurrentView('singleMessage');
  },
  showCompose: () => {
    return isCurrentView('compose');
  }
});

/* messages template events */
Template.messages.events({
  'click #allMessagesButton, click #composeButton': (event, template) => {
    //Set template based on button that was clicked
    $('button').removeClass('active');
    $('#' + event.target.id).addClass('active');
    Session.set('currentView', event.target.id.toString().replace('Button', ''));
  }
});

/* allMessages helpers */
Template.allMessages.helpers({
  getAllMessages: () => {
    //Find all messages that current user is involved in
    return Messages.find({$or: [{ 'originatingFromId': Meteor.userId(), 'conversation.originatingFromDeleted': false }, {'originatingToId': Meteor.userId(), 'conversation.originatingToDeleted': false}]}, {sort: {'conversation.sentOn': -1} });
  },
  messagesEmpty: () => {
    //Check if current user has any messages
    if(Messages.find({$or: [{ 'originatingFromId': Meteor.userId(), 'conversation.originatingFromDeleted': false }, {'originatingToId': Meteor.userId(), 'conversation.originatingToDeleted': false}]}).count() === 0) {
      return true;
    } else {
      return false;
    }
  },
  formatDate: (conversation) => {
    if(conversation.length > 0)
    {
      let date = conversation[conversation.length - 1].sentOn;

      return performFormatting(date);
    }
  },
  getMostRecentBody: (conversation) => {
    if(conversation.length > 0) {
      return conversation[conversation.length - 1].body;
    }
  },
  getMostRecentRead: (conversation) => {
    //Determine if message has been read
    if(conversation.length > 0) {
      if(conversation[conversation.length - 1].to.userId === Meteor.userId()) {
        if(!conversation[conversation.length - 1].to.read) {
          return 'notRead';
        }
      }
    }

    return '';
  }
});

/* allMessages template events */
Template.allMessages.events({
  'click .msg': (event, template) => {
    //Make sure selected message exists
    let selectedMsg = Messages.findOne({_id: event.currentTarget.id});
    if(selectedMsg) {
      if(selectedMsg.conversation[selectedMsg.conversation.length - 1].to.userId === Meteor.userId()) {
        //Check if most recent message is TO the current user
        if(!selectedMsg.conversation[selectedMsg.conversation.length - 1].to.read) {
          //Update read field to true
          Meteor.call('messages.updateRead', selectedMsg._id, true, (error, result) => {
            //Do nothing
          });
        }

      }
    }

    //Set current view to singleMssage template
    $('button').removeClass('active');
    Session.set('selectedMsg', event.currentTarget.id);
    Session.set('currentView', 'singleMessage');
  },
  'click .remove-message': (event, template) => {
    event.stopPropagation();

    //Sweet Alert delete confirmation
    swal({
      title: 'Delete message?',
      text: 'Are you sure that you want to delete this message?',
      type: 'error',
      showCancelButton: true,
      closeOnConfirm: true,
      cancelButtonText: 'No',
      confirmButtonText: 'Yes, delete it!',
      confirmButtonColor: '#da5347'
    }, function() {
      //Get the id of the message to be deleted
      let msgId = event.currentTarget.parentNode.parentNode.id;

      //Make sure message exists
      let msg = Messages.findOne({ '_id': msgId } );
      let whoDeleted;

      //If message exists
      if(msg) {
        //Set deleted correctly
        if(msg.originatingFromId === Meteor.userId()) {
          whoDeleted = 'from';
        } else {
          whoDeleted = 'to';
        }

        //Remove selected message
        Meteor.call('messages.remove', msgId, whoDeleted, (error, result) => {
          if(error) {
            Bert.alert('Message couldn\'t be deleted.', 'danger', 'growl-top-right');
          } else {
            Bert.alert('Message deleted', 'success', 'growl-top-right');
          }
        });
      } else {
        Bert.alert('Message couldn\'t be deleted.', 'danger', 'growl-top-right');
      }
    });
  }
});

/* singleMessage template on rendered */
Template.singleMessage.onRendered(function() {
  //Move to bottom of div so most recent message is shown
  $('#singleMessageArea').scrollTop($('#singleMessageArea')[0].scrollHeight);

  //Set focus to the reply body text area
  $('[data-id=reply-body]').focus();
});

/* singleMessage template helpers */
Template.singleMessage.helpers({
  getSingleMessage: () => {
    return Messages.findOne({ '_id': Session.get('selectedMsg') } );
  },
  showMessage: (originatingFromDeleted, originatingToDeleted) => {
    //Don't show messages that have been previously deleted
    if(Session.equals('originating', 'from')) {
      return !originatingFromDeleted;
    } else {
      return !originatingToDeleted;
    }
  },
  fromOtherUser: (from, to) => {
    if(from.userId !== Meteor.userId()) {
      return true;
    } else {
      return false;
    }
  },
  formatDate: (date) => {
    return performFormatting(date);
  }
});

/* singleMessage template events */
Template.singleMessage.events({
    'submit [data-id=reply-message-form]': (event, template) => {
      event.preventDefault();

      let body = template.find('[data-id=reply-body]').value,
          currMessage = Messages.findOne({_id: Session.get('selectedMsg')}),
          toUserId = getOtherUserId(currMessage.originatingFromId, currMessage.originatingToId),
          fieldEmpty = false;

      //Make sure fields arent empty
      if(!body.toString().trim()) {
        fieldEmpty = true;
        Bert.alert('Please enter a message.', 'danger', 'growl-top-right');
      }
      if(!fieldEmpty && !toUserId) {
        fieldEmpty = true;
        Bert.alert('Error sending message.', 'danger', 'growl-top-right');
      }

      //Continue if the fields aren't empty
      if(!fieldEmpty) {
        //Add reply to the conversation array of the existing message
        Meteor.call('messages.addMessage', Session.get('selectedMsg'), toUserId, body, (error, result) => {
          if(error) {
            Bert.alert(error.reason, 'danger', 'growl-top-right');
          } else {
            //Display success message and reset form values
            Bert.alert('Message sent', 'success', 'growl-top-right');
            template.find('[data-id=reply-body]').value = '';

            //Scroll to bottom of message area and set focus back to reply text area
            $('#singleMessageArea').scrollTop($('#singleMessageArea')[0].scrollHeight);
            $('[data-id=reply-body]').focus();
          }
        });
      }
    }
});

/* compose template on rendered */
Template.compose.onRendered(function() {
  //Set focus to the to text area
  $('[data-id=message-to]').focus();
});

/* compose template events */
Template.compose.events({
  'submit [data-id=send-message-form]': (event, template) => {
    event.preventDefault();

    //Get text from To and Body fields
    let to = template.find('[data-id=message-to]').value.toString().trim(),
        body = template.find('[data-id=message-body]').value,
        fieldEmpty = false;

    //Verify that both fields contain text
    if(!to) {
        fieldEmpty = true;
        Bert.alert('Please enter a username in the To field.', 'danger', 'growl-top-right');
    }
    if(!fieldEmpty && !body.toString().trim()) {
        fieldEmpty = true;
        Bert.alert('Please enter a message.', 'danger', 'growl-top-right');
    }

    //Continue if the fields aren't empty
    if(!fieldEmpty) {
      //Try to find user in Users collection
      let toUser = Meteor.users.findOne({username: to});

      //If user was found then it is a valid user
      if(toUser) {
        //If user is not the current user then send the message
        if(toUser._id != Meteor.userId())
        {
          //If message between these two users already exists, add this message to the current conversation, else create a new message
          let existingMessage = Messages.findOne({$or: [{'originatingFromId': Meteor.userId()}, {'originatingToId': Meteor.userId()}], $or: [{'originatingFromId': toUser._id}, {'originatingToId': toUser._id}]});

          if(existingMessage) {
            //Add message to existing conversation
            Meteor.call('messages.addMessage', existingMessage._id, toUser._id, body, (error, result) => {
              if(error) {
                Bert.alert(error.reason, 'danger', 'growl-top-right');
              } else {
                //Display success message and reset form values
                Bert.alert('Message sent', 'success', 'growl-top-right');
                template.find('[data-id=message-to]').value = '';
                template.find('[data-id=message-body]').value = '';

                //Switch the to allMessages view
                $('button').removeClass('active');
                $('#allMessagesButton').addClass('active');
                Session.set('currentView', 'allMessages');
              }
            });
          } else {
            //Create new message
            Meteor.call('messages.insert', toUser._id, toUser.username, body, (error, result) => {
              if(error) {
                Bert.alert(error.reason, 'danger', 'growl-top-right');
              } else {
                //Display success message and reset form values
                Bert.alert('Message sent', 'success', 'growl-top-right');

                //Switch the to allMessages view
                $('button').removeClass('active');
                $('#allMessagesButton').addClass('active');
                Session.set('currentView', 'allMessages');
              }
            });
          }
        } else {
          //Can't send a message to yourself, display error
          Bert.alert('Sorry, you can only send messages to other users.', 'danger', 'growl-top-right');
        }
      } else {
        //Wasn't a valid user, display error
        Bert.alert('Sorry, we can\'t find that user.  Please verify the username and try again.', 'danger', 'growl-top-right');
      }
    }
  }
});

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012 Francisco Salavert (ICM-CIPF)
 * Copyright (c) 2012 Ruben Sanchez (ICM-CIPF)
 * Copyright (c) 2012 Ignacio Medina (ICM-CIPF)
 *
 * This file is part of JS Common Libs.
 *
 * JS Common Libs is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * JS Common Libs is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JS Common Libs. If not, see <http://www.gnu.org/licenses/>.
 */

function SequenceAdapter(args) {

    _.extend(this, Backbone.Events);

    this.id = Utils.genId("TrackListPanel");

    //set default args
    this.host;
    this.gzip = true;

    //set instantiation args, must be last
    _.extend(this, args);

    this.sequence = {};
    this.start = {};
    this.end = {};

    this.on(this.handlers);
}

SequenceAdapter.prototype.clearData = function () {
    this.sequence = {};
    this.start = {};
    this.end = {};
};

SequenceAdapter.prototype.getData = function (args) {
    var _this = this;

    this.sender = args.sender;
    var region = args.region;
    var chromosome = region.chromosome;

    region.start = (region.start < 1) ? 1 : region.start;
    region.end = (region.end > 300000000) ? 300000000 : region.end;

    //clean when the new position is too far from current
    if (region.start < this.start[chromosome] - 5000 || region.end > this.end[chromosome] + 5000) {
        this.clearData();
    }

    var params = {};
    _.extend(params, this.params);

    var queryString = this._getSequenceQuery(region);

    if (queryString != "") {

        CellBaseManager.get({
            host: this.host,
            species: this.species,
            category: this.category,
            subCategory: this.subCategory,
            query: queryString,
            resource: this.resource,
            params: params,
            success: function (data) {
                _this._processSequenceQuery(data, true);
            }
        });

    } else {
        if (this.sender != "move") {
            this.trigger('data:ready', {
                items: {
                    sequence: this.sequence[chromosome],
                    start: this.start[chromosome],
                    end: this.end[chromosome]
                },
                params: params
            });
            this.trigger('data:ready', {
                items: {
                    sequence: this.sequence[chromosome],
                    start: this.start[chromosome],
                    end: this.end[chromosome]
                },
                params: params,
                sender: this
            });
        }
    }

};

SequenceAdapter.prototype._getSequenceQuery = function (region) {
    var _this = this;
    var chromosome = region.chromosome;

    var s, e, query, querys = [];
    if (_this.start[chromosome] == null && _this.end[chromosome] == null) {
        //args.start -= 100;
        //args.end += 100;
        _this.start[chromosome] = region.start;
        _this.end[chromosome] = region.end;
        s = region.start;
        e = region.end;
        query = chromosome + ":" + s + "-" + e;
        querys.push(query);
    } else {
        if (region.start <= _this.start[chromosome]) {
            s = region.start;
            e = _this.start[chromosome] - 1;
            e = (e < 1) ? region.end = 1 : e;
            _this.start[chromosome] = s;
            query = region.chromosome + ":" + s + "-" + e;
            querys.push(query);
        }
        if (region.end >= _this.end[chromosome]) {
            e = region.end;
            s = _this.end[chromosome] + 1;
            _this.end[chromosome] = e;
            query = region.chromosome + ":" + s + "-" + e;
            querys.push(query);
        }
    }
    return querys.toString();
};

SequenceAdapter.prototype._processSequenceQuery = function (data, throwNotify) {
    var _this = this;
    var params = data.params;

    for (var i = 0; i < data.response.length; i++) {
        var queryResponse = data.response[i];
        var splitDots = queryResponse.id.split(":");
        var splitDash = splitDots[1].split("-");
        var queryStart = parseInt(splitDash[0]);
        var queryEnd = parseInt(splitDash[1]);

        var queryId = queryResponse.id;
        var seqResponse = queryResponse.result;

        var chromosome = seqResponse.chromosome;
        if(typeof chromosome === 'undefined'){
            chromosome = seqResponse.sequenceName;
        }

        if (this.sequence[chromosome] == null) {
            this.sequence[chromosome] = seqResponse.sequence;
        } else {
            if (queryStart == this.start[chromosome]) {
                this.sequence[chromosome] = seqResponse.sequence + this.sequence[chromosome];
            } else {
                this.sequence[chromosome] = this.sequence[chromosome] + seqResponse.sequence;
            }
        }

        if (this.sender == "move" && throwNotify == true) {
            this.trigger('data:ready', {
                items: {
                    sequence: seqResponse.sequence,
                    start: queryStart,
                    end: queryEnd
                },
                params: params,
                sender: this
            });
        }
    }

    if (this.sender != "move" && throwNotify == true) {
        this.trigger('data:ready', {
            items: {
                sequence: this.sequence[chromosome],
                start: this.start[chromosome],
                end: this.end[chromosome]
            },
            params: params,
            sender: this
        });
    }
};

//Used by bam to get the mutations
SequenceAdapter.prototype.getNucleotidByPosition = function (args) {
    var _this = this;
    if (args.start > 0 && args.end > 0) {
        var queryString = this._getSequenceQuery(args);

        var chromosome = args.chromosome;

        if (queryString != "") {

            var data = CellBaseManager.get({
                host: this.host,
                species: this.species,
                category: this.category,
                subCategory: this.subCategory,
                query: queryString,
                resource: this.resource,
                params: this.params,
                async: false
            });
            _this._processSequenceQuery(data);

        }
        if (this.sequence[chromosome] != null) {
            var referenceSubStr = this.sequence[chromosome].substr((args.start - this.start[chromosome]), 1);
            return referenceSubStr;
        } else {
            console.log("SequenceRender: this.sequence[chromosome] is undefined");
            return "";
        }
    }
};
<commit_msg>fixed sequence adapter region check<commit_after>/*
 * Copyright (c) 2012 Francisco Salavert (ICM-CIPF)
 * Copyright (c) 2012 Ruben Sanchez (ICM-CIPF)
 * Copyright (c) 2012 Ignacio Medina (ICM-CIPF)
 *
 * This file is part of JS Common Libs.
 *
 * JS Common Libs is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * JS Common Libs is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with JS Common Libs. If not, see <http://www.gnu.org/licenses/>.
 */

function SequenceAdapter(args) {

    _.extend(this, Backbone.Events);

    this.id = Utils.genId("TrackListPanel");

    //set default args
    this.host;
    this.gzip = true;

    //set instantiation args, must be last
    _.extend(this, args);

    this.sequence = {};
    this.start = {};
    this.end = {};

    this.on(this.handlers);
}

SequenceAdapter.prototype.clearData = function () {
    this.sequence = {};
    this.start = {};
    this.end = {};
};

SequenceAdapter.prototype.getData = function (args) {
    var _this = this;

    this.sender = args.sender;
    var region = args.region;
    var chromosome = region.chromosome;

    region.start = (region.start < 1) ? 1 : region.start;
    region.end = (region.end > 300000000) ? 300000000 : region.end;

    //clean when the new position is too far from current
    if (region.start < this.start[chromosome] - 5000 || region.end > this.end[chromosome] + 5000) {
        this.clearData();
    }

    var params = {};
    _.extend(params, this.params);

    var queryString = this._getSequenceQuery(region);

    if (queryString != "") {

        CellBaseManager.get({
            host: this.host,
            species: this.species,
            category: this.category,
            subCategory: this.subCategory,
            query: queryString,
            resource: this.resource,
            params: params,
            success: function (data) {
                _this._processSequenceQuery(data, true);
            }
        });

    } else {
        if (this.sender != "move") {
            this.trigger('data:ready', {
                items: {
                    sequence: this.sequence[chromosome],
                    start: this.start[chromosome],
                    end: this.end[chromosome]
                },
                params: params
            });
            this.trigger('data:ready', {
                items: {
                    sequence: this.sequence[chromosome],
                    start: this.start[chromosome],
                    end: this.end[chromosome]
                },
                params: params,
                sender: this
            });
        }
    }

};

SequenceAdapter.prototype._getSequenceQuery = function (region) {
    var _this = this;
    var chromosome = region.chromosome;

    var s, e, query, querys = [];
    if (_this.start[chromosome] == null && _this.end[chromosome] == null) {
        //args.start -= 100;
        //args.end += 100;
        _this.start[chromosome] = region.start;
        _this.end[chromosome] = region.end;
        s = region.start;
        e = region.end;
        query = chromosome + ":" + s + "-" + e;
        querys.push(query);
    } else {
        if (region.start < _this.start[chromosome] ) {
            s = region.start;
            e = _this.start[chromosome] - 1;
            e = (e < 1) ? region.end = 1 : e;
            _this.start[chromosome] = s;
            query = region.chromosome + ":" + s + "-" + e;
            querys.push(query);
        }
        if (region.end > _this.end[chromosome]) {
            e = region.end;
            s = _this.end[chromosome] + 1;
            _this.end[chromosome] = e;
            query = region.chromosome + ":" + s + "-" + e;
            querys.push(query);
        }
    }
    return querys.toString();
};

SequenceAdapter.prototype._processSequenceQuery = function (data, throwNotify) {
    var _this = this;
    var params = data.params;

    for (var i = 0; i < data.response.length; i++) {
        var queryResponse = data.response[i];
        var splitDots = queryResponse.id.split(":");
        var splitDash = splitDots[1].split("-");
        var queryStart = parseInt(splitDash[0]);
        var queryEnd = parseInt(splitDash[1]);

        var queryId = queryResponse.id;
        var seqResponse = queryResponse.result;

        var chromosome = seqResponse.chromosome;
        if(typeof chromosome === 'undefined'){
            chromosome = seqResponse.sequenceName;
        }

        if (this.sequence[chromosome] == null) {
            this.sequence[chromosome] = seqResponse.sequence;
        } else {
            if (queryStart == this.start[chromosome]) {
                this.sequence[chromosome] = seqResponse.sequence + this.sequence[chromosome];
            } else {
                this.sequence[chromosome] = this.sequence[chromosome] + seqResponse.sequence;
            }
        }

        if (this.sender == "move" && throwNotify == true) {
            this.trigger('data:ready', {
                items: {
                    sequence: seqResponse.sequence,
                    start: queryStart,
                    end: queryEnd
                },
                params: params,
                sender: this
            });
        }
    }

    if (this.sender != "move" && throwNotify == true) {
        this.trigger('data:ready', {
            items: {
                sequence: this.sequence[chromosome],
                start: this.start[chromosome],
                end: this.end[chromosome]
            },
            params: params,
            sender: this
        });
    }
};

//Used by bam to get the mutations
SequenceAdapter.prototype.getNucleotidByPosition = function (args) {
    var _this = this;
    if (args.start > 0 && args.end > 0) {
        var queryString = this._getSequenceQuery(args);

        var chromosome = args.chromosome;

        if (queryString != "") {
            var data = CellBaseManager.get({
                host: this.host,
                species: this.species,
                category: this.category,
                subCategory: this.subCategory,
                query: queryString,
                resource: this.resource,
                params: this.params,
                async: false
            });
            _this._processSequenceQuery(data);
        }
        if (this.sequence[chromosome] != null) {
            var referenceSubStr = this.sequence[chromosome].substr((args.start - this.start[chromosome]), 1);
            return referenceSubStr;
        } else {
            console.log("SequenceRender: this.sequence[chromosome] is undefined");
            return "";
        }
    }
};
<|endoftext|>