<commit_before>var tower_Operate = {
    run: function(tower, thisRoom) {
        var thisTower = Game.getObjectById(tower);

        var UnderAttackPos = Memory.roomsUnderAttack.indexOf(thisRoom.name);
        if (UnderAttackPos >= 0 && thisTower.energy > 0) {
            var closestHostile = thisTower.pos.findInRange(FIND_HOSTILE_CREEPS, 15, {
                filter: (creep) => (creep.getActiveBodyparts(WORK) > 0 || creep.getActiveBodyparts(CARRY) > 0 || creep.getActiveBodyparts(ATTACK) > 0 || creep.getActiveBodyparts(RANGED_ATTACK) > 0 || creep.getActiveBodyparts(HEAL) > 0) || (creep.hits <= 500)
            });
            if (closestHostile.length > 0) {
                //Target healing creeps first
                closestHostile.sort(towerPartsCompare);
                thisTower.attack(closestHostile[0]);
            }
        } else if (thisTower.energy > (thisTower.energyCapacity * 0.5)) {
            //Save 50% of the tower's energy to use on repelling attackers
            var closestDamagedCreep = thisTower.pos.findClosestByRange(FIND_MY_CREEPS, {
                filter: (creep) => creep.hits < creep.hitsMax
            });
            if (closestDamagedCreep) {
                thisTower.heal(closestDamagedCreep);
            }
        }

        //thisRoom.visual.rect(tower.pos.x - 15, tower.pos.y - 15, 30, 30, {fill: '#ff0019', opacity: 0.2});
    }
};

module.exports = tower_Operate;

function towerPartsCompare(a, b) {
    if (a.getActiveBodyparts(HEAL) < b.getActiveBodyparts(HEAL))
        return 1;
    if (a.getActiveBodyparts(HEAL) > b.getActiveBodyparts(HEAL))
        return -1;
    return 0;
}<commit_msg>Bugfix 1<commit_after>var tower_Operate = {
    run: function(tower, thisRoom) {
        var thisTower = Game.getObjectById(tower);

        var UnderAttackPos = Memory.roomsUnderAttack.indexOf(thisRoom.name);
        if (UnderAttackPos >= 0 && thisTower.energy > 0) {
            var closestHostile = thisTower.pos.findInRange(FIND_HOSTILE_CREEPS, 15, {
                filter: (creep) => (creep.getActiveBodyparts(WORK) > 0 || creep.getActiveBodyparts(CARRY) > 0 || creep.getActiveBodyparts(ATTACK) > 0 || creep.getActiveBodyparts(RANGED_ATTACK) > 0 || creep.getActiveBodyparts(HEAL) > 0) || (creep.hits <= 500)
            });
            if (closestHostile.length > 0) {
                //Target healing creeps first
                closestHostile.sort(towerPartsCompare);
                thisTower.attack(closestHostile[0]);
            }
        } else if (thisTower.energy > (thisTower.energyCapacity * 0.5)) {
            //Save 50% of the tower's energy to use on repelling attackers
            var closestDamagedCreep = thisTower.pos.findClosestByRange(FIND_MY_CREEPS, {
                filter: (creep) => creep.hits < creep.hitsMax
            });
            if (closestDamagedCreep) {
                thisTower.heal(closestDamagedCreep);
            }
        }

        thisRoom.visual.rect(thisTower.pos.x - 15, thisTower.pos.y - 15, 30, 30, {fill: '#ff0019', opacity: 0.2});
    }
};

module.exports = tower_Operate;

function towerPartsCompare(a, b) {
    if (a.getActiveBodyparts(HEAL) < b.getActiveBodyparts(HEAL))
        return 1;
    if (a.getActiveBodyparts(HEAL) > b.getActiveBodyparts(HEAL))
        return -1;
    return 0;
}<|endoftext|>


<commit_before>module.exports = {
  'rules': {
    // require that all functions are run in strict mode
    'strict': [2, 'never']
  }
};
<commit_msg>Clarify strict ESLint rule<commit_after>module.exports = {
  'rules': {
    // babel inserts `'use strict';` for us
    'strict': [2, 'never']
  }
};
<|endoftext|>


<commit_before>//<script src="https://rawgit.com/mshoote/BTJSC/master/Markup/AutoTestingMRK4.js"></script>
//The following function sets up the downloading part of the Auto script nameing the
//downloadable file and the file type.

(function(console){
    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'pagingTime.txt'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)
//This function begins to create the data that the Auto script will be gathering to get the times
//of the webpage in the browser's Dev console.
window.onload = function() {
	window.setTimeout(function(){
  // Check for browser support
    if(!(window.performance && window.performance.timing)) {
    return;
  }
  console.log(console.save([
  performance.timing.loadEventEnd - performance.timing.fetchStart,
  performance.timing.fetchStart - performance.timing.navigationStart,
  performance.timing.redirectEnd - performance.timing.redirectStart,
  performance.timing.domainLookupStart - performance.timing.fetchStart,
  performance.timing.domainLookupEnd - performance.timing.domainLookupStart,
  performance.timing.connectEnd - performance.timing.connectStart,
  performance.timing.responseEnd - performance.timing.requestStart,
  performance.timing.unloadEventEnd - performance.timing.unloadEventStart,
  performance.timing.domContentLoadedEventEnd - performance.timing.domContentLoadedEventStart,
  performance.timing.domComplete - performance.timing.domInteractive,
  performance.timing.loadEventEnd - performance.timing.responseEnd,
  performance.timing.domInteractive - performance.timing.responseEnd,
  performance.timing.loadEventEnd - performance.timing.loadEventStart,
  performance.timing.domComplete - performance.timing.domLoading,
  performance.timing.domContentLoadedEventStart - performance.timing.domLoading,
  null
  ]));
  }, 0);
};
//This is the resfreshing function  of the Auto script, the time is in millaseconds (1000 = 1 sec).
//setTimeout(function(){window.location=window.location;},60000);
//setTimeout(function(){window.location=window.location;},30000);
//setTimeout(function(){window.location=window.location;},20000);
setTimeout(function(){window.location=window.location;},10000);
<commit_msg>Update AutoTestingMRK4.js<commit_after>//<script src="https://rawgit.com/mshoote/BTJSC/master/Markup/AutoTestingMRK4.js"></script>
//The following function sets up the downloading part of the Auto script nameing the
//downloadable file and the file type.

(function(console){
    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'pagingTime.txt'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)
//This function begins to create the data that the Auto script will be gathering to get the times
//of the webpage in the browser's Dev console.
window.onload = function() {
	window.setTimeout(function(){
  // Check for browser support
    if(!(window.performance && window.performance.timing)) {
    return;
  }
  console.log(console.save([
	  // Total time from start to load
  performance.timing.loadEventEnd - performance.timing.fetchStart,
	  // Time consumed preparing the new page
  performance.timing.fetchStart - performance.timing.navigationStart,
	  // Time spent during redirection
  performance.timing.redirectEnd - performance.timing.redirectStart,
	  // AppCache Time
  performance.timing.domainLookupStart - performance.timing.fetchStart,
	  // DNS query time
  performance.timing.domainLookupEnd - performance.timing.domainLookupStart,
	  // TCP connection time
  performance.timing.connectEnd - performance.timing.connectStart,
	  // Time spent during the request
  performance.timing.responseEnd - performance.timing.requestStart,
	  // Time spent unloading documents
  performance.timing.unloadEventEnd - performance.timing.unloadEventStart,
	  // Time spent DOMContentLoaded
  performance.timing.domContentLoadedEventEnd - performance.timing.domContentLoadedEventStart,
	  // Time spent constructing the DOM tree
  performance.timing.domComplete - performance.timing.domInteractive,
	  //Processing and loading time
  performance.timing.loadEventEnd - performance.timing.responseEnd,
	  // Request to completion of the DOM loading
  performance.timing.domInteractive - performance.timing.responseEnd,
	  // Load event time
  performance.timing.loadEventEnd - performance.timing.loadEventStart,
	  // Processing Time
  performance.timing.domComplete - performance.timing.domLoading,
	  //Painting time
  performance.timing.domContentLoadedEventStart - performance.timing.domLoading,
  null
  ]));
  }, 0);
};
//This is the resfreshing function  of the Auto script, the time is in millaseconds (1000 = 1 sec).
//setTimeout(function(){window.location=window.location;},60000);
//setTimeout(function(){window.location=window.location;},30000);
//setTimeout(function(){window.location=window.location;},20000);
//setTimeout(function(){window.location=window.location;},10000);
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import _ from 'lodash';
import async from 'async';

import CompSearchDB from './CompSearchDB';
import dbConn from '../store/db_connection.js';
import CircularProgress from 'material-ui/lib/circular-progress';
import * as layouts from '../store/db_layouts.js';
import Snackbar from 'material-ui/lib/snackbar';
import Divider from 'material-ui/lib/divider';
import Dialog from 'material-ui/lib/dialog';

import IconButton from 'material-ui/lib/icon-button';
import ActionSearch from 'material-ui/lib/svg-icons/action/search';
import ActionCopy from 'material-ui/lib/svg-icons/content/content-copy';
import ActionPaste from 'material-ui/lib/svg-icons/content/content-paste';
import ActionDelete from 'material-ui/lib/svg-icons/action/delete';
import ActionNew from 'material-ui/lib/svg-icons/action/open-in-new';
import ActionSave from 'material-ui/lib/svg-icons/content/save';
import ActionUndo from 'material-ui/lib/svg-icons/content/undo';

import CompSearchButton from './CompSearchButton';
import CompEditForm from './CompEditForm';
import RaisedButton from 'material-ui/lib/raised-button';
import CardActions from 'material-ui/lib/card/card-actions';

const layout = layouts.get( "proforma" );

function getPropertiesOfAChangedFromB( a, b ) {
  if( !a || !b )
    return {};
  var diffs = {};
  for( var k in a ) {
    if( ( typeof b[k] == undefined ) || b[k] !== a[k] )
      diffs[k] = b[k];
  }
  return diffs;
}

// -----------------------------------------------------------------
export default class CompRecambiosProformas extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      db_id:   null
    , db_data: null
    , db_orig_data: null
    , db_delta: null
    , db_changed_rec: false
    , db_creating_new: false
    , connected: dbConn.isConnected()
    , msg_visible: false
    , msg_text: "blah blah"
    , modal_dlg_open: false
    , search_state: null
    };
  }

  componentDidMount() {
    dbConn.on('DB.connectionStatusChanged', this.onDBConnectionChange.bind(this) );
  }

  componentWillUnmount() {
    dbConn.removeListener('DB.connectionStatusChanged', this.onDBConnectionChange );
  }

  // Register to db connection/disconnections
  onDBConnectionChange( ) {
    this.setState({connected:dbConn.isConnected()});
  }

  // e is the unique id of the selected row in the comp search results
  onClickSearchResult( e, search_state ) {
    console.log( "onClickSearchResult" );
    this.setState({db_id:e});

    // Prepare the main query and the subqueries
    var db_all_results = {};
    var tasks = [];
    tasks.push( (callback)=>{
      // Main query
      console.log( "Retrieving main data for key " + e );
      var resolved_filter = layout.search.exact.filter.replace( /__FIELD__/, e );
      dbConn.DBSelect( layout.table
                     , ["*"]
                     , resolved_filter
                     , this
                     , (data) => {
        console.log( "Main query recv");
        console.log( data );
        db_all_results = Object.assign({},db_all_results,data[0]);
        console.log( db_all_results );
        callback(null);
      });
    });

    //tasks.push( (callback)=>{ setTimeout( callback, 2000 ); } );

    // For subqueries if needed
    _.each( layout.fields, (f)=>{
      if( f.type === "array_table" ) {
        tasks.push( (callback)=>{
          console.log( "Retrieving data for field " + f.field );
          console.log( layout );
          var ext_layout = layouts.get( f.layout );
          console.log( "External layout" );
          console.log( ext_layout );
          console.log( "Local field to search is " + f.local );
          var searched_field = layouts.getFieldByname( layout, f.local );
          console.log( "searched_field " );
          console.log( searched_field );
          var searched_value = db_all_results[ searched_field.field ];
          console.log( "searched_value " + searched_value );
          var resolved_filter = ext_layout.search.join.filter.replace( /__FIELD__/, searched_value );
          dbConn.DBSelect( ext_layout.table
                         , ["*"]
                         , resolved_filter
                         , this
                         , (data) => {
            console.log( "Sub query for " + f.field + " recv");
            console.log( data );
            db_all_results[ f.field ] = data;
            console.log( db_all_results );
            callback(null);
          });
        });
      }
    });

    console.log( "Running tasks");
    console.log( tasks );
    async.series( tasks, (err)=>{
      console.log( "All data collected");
      console.log( db_all_results );
      this.validateData({
        db_data: db_all_results,
        db_orig_data:db_all_results,
        db_creating_new:false,
        search_state:search_state
      });
    });
  }

  validateData( ns ) {
    if( ns.db_data ) {
      layouts.validateDates( layout, ns.db_data );
      var ref = this.state.db_orig_data;
      if( ns.db_orig_data )
        ref = ns.db_orig_data;
      ns.db_delta = getPropertiesOfAChangedFromB( ref, ns.db_data );
      ns.db_changed_rec = ( Object.keys( ns.db_delta ).length != 0 );
    }
    //console.log( "ns is now")
    //console.log( ns );
    this.setState(ns);
  }

  onDataChange( new_db_data ) {
    //console.log( "onDataChange" );
    this.validateData({db_data:new_db_data});
  }

  // --------------------------------------------------------------
  onClickCancel( e, dummy  ) {
    console.log( "Restoring...");
    this.validateData({db_data:this.state.db_orig_data});
  }

  // --------------------------------------------------------------
  onClickSave( e, dummy ) {
    if( !this.state.db_changed_rec && !this.state.db_creating_new )
      return;
    console.log( "Saving...");
    var changes = this.state.db_delta;
    console.log( changes );

    var handler =
      (data)=>{
        console.log( "Save completed " + this.state.db_id);
        console.log( data );
        this.onClickSearchResult( this.state.db_id );
        this.setState({msg_visible:true, msg_text:"Registro grabado correctamente"});
       };

    if( this.state.db_creating_new ) {
      console.log( "Adding new register to the db...");
      dbConn.DBInsert( layout.table
                     , changes
                     , this
                     , handler );
    } else {
      delete changes[ layout.key_field ];
      dbConn.DBUpdate( layout.table
                     , changes
                     , layout.key_field + "='"+ this.state.db_id + "'"
                     , this
                     , handler );
    }

  }
  // --------------------------------------------------------------
  onClickNew( ) {
    console.log( "New register...");
    const new_db_data = layouts.getNewEmptyRegister( layout );
    const new_db_orig_data = new_db_data;
    this.validateData(
      { db_data: new_db_data
      , db_orig_data:new_db_orig_data
      , db_id:"new"
      , db_creating_new:true
      });
  }

  // --------------------------------------------------------------
  onClickDelete( ) {
    this.setState({modal_dlg_open:true}, {modal_dlg_msg:"¿Borrar completamente el registro?"});
  }

  // --------------------------------------------------------------
  onClickCopy( ) {
    console.log( "Copying to clipboard...");
  }

  // --------------------------------------------------------------
  onClickPaste( ) {
    console.log( "Pasting from clipboard...");
  }

  // --------------------------------------------------------------
  onClickSearchAgain() {
    this.setState( {db_id:null} );
  }

  // --------------------------------------------------------------
  onClick( e, dummy ) {
    console.log( "On click..." + e );
  }

  // ------------------------------------------------------------------
  renderDisconnected() {
    const style = {
      margin: "auto",
      textAlign: "center"
    };
    return (
Trying to connect to the database...<CircularProgress mode="indeterminate" />
);
  }

  renderSearchForm() {
    var code = JSON.stringify( layout, null, '  ' );
    return (<CompSearchDB
        data={layout}
        onClickNew={this.onClickNew.bind(this)}
        onClickSearchResult={this.onClickSearchResult.bind(this)}
        search_state={this.state.search_state}
        />);
    //return (
You are searching
{code}

);
  }

  // ----------------------------------------------------------------
  renderSearchButton( ) {
    return (<IconButton tooltip="Buscar de nuevo" onClick={this.onClickSearchAgain.bind(this)}><ActionSearch/></IconButton>);
  }

  // ----------------------------------------------------------------
  renderSaveButton() {
    const buttons_group_style = {float:"right"};
    var changed = this.state.db_changed_rec;
    var is_new = this.state.db_creating_new;
    return (
      <CardActions expandable style={buttons_group_style}>
        <IconButton tooltip="Buscar de nuevo" onClick={this.onClickSearchAgain.bind(this)}><ActionSearch/></IconButton>
        <IconButton tooltip="Copiar Valores" onClick={this.onClickCopy.bind(this)}><ActionCopy/></IconButton>
        <IconButton tooltip="Pegar Valores" onClick={this.onClickPaste.bind(this)}><ActionPaste/></IconButton>
        <IconButton disabled={changed || is_new} tooltip="Nuevo Registro" onClick={this.onClickNew.bind(this)}><ActionNew/></IconButton>
        <IconButton disabled={!changed && !is_new} tooltip="Guardar Cambios" onClick={this.onClickSave.bind(this)}><ActionSave/></IconButton>
        <IconButton disabled={!changed} tooltip="Deshacer Cambios" onClick={this.onClickCancel.bind(this)}><ActionUndo/></IconButton>
        <IconButton disabled={!changed} tooltip="Borrar Registro" onClick={this.onClickDelete.bind(this)}><ActionDelete/></IconButton>
      </CardActions>);
  }

  renderForm() {
    return(
      <CompEditForm
        data={this.state.db_data}
        onChange={this.onDataChange.bind(this)}
        onClick={this.onClick.bind(this)}
        layout={layout}
        creating_new={this.state.db_creating_new}
        />);
  }

  renderSnackBar() {
    var handler = ()=>{this.setState({msg_visible: false});};
    return (
      <Snackbar
        open={this.state.msg_visible}
        message={this.state.msg_text}
        autoHideDuration={1000}
        onRequestClose={handler}/>);
  }

  renderModalDialog() {
    var handler_no = ()=>{this.setState({modal_dlg_open: false});};
    var handler_yes = ()=>{this.setState({modal_dlg_open: false});};
    var actions = (
      <CardActions >
      <RaisedButton label="No" onClick={handler_no}/>
      <RaisedButton label="Yes" onClick={handler_yes}/>
      </CardActions>);
    return (<Dialog
          title={this.state.modal_dlg_msg}
          modal
          actions={actions}
          open={this.state.modal_dlg_open}
          />);
  }

  // ------------------------------------------------------------------
  render() {

    if( !this.state.connected )
      return this.renderDisconnected();

    if( !this.state.db_id )
      return this.renderSearchForm();

    if( !this.state.db_data ) {
      var search = this.renderSearchButton();
      return (
{search}Retrieving data from {this.state.db_id}
);
    }

    var dlg = this.renderModalDialog();
    var save = this.renderSaveButton();
    var msg = this.renderSnackBar();
    var form = this.renderForm();
    var json = JSON.stringify( this.state, null, '  ' );
    //console.log( this.state );
    return (
{save}{form}<Divider />{msg}{dlg}
{json}

);
  }
}

CompRecambiosProformas.propTypes = {
};

<commit_msg>Avoid flashing after saving a new register<commit_after>import React, {PropTypes} from 'react';
import _ from 'lodash';
import async from 'async';

import CompSearchDB from './CompSearchDB';
import dbConn from '../store/db_connection.js';
import CircularProgress from 'material-ui/lib/circular-progress';
import * as layouts from '../store/db_layouts.js';
import Snackbar from 'material-ui/lib/snackbar';
import Divider from 'material-ui/lib/divider';
import Dialog from 'material-ui/lib/dialog';

import IconButton from 'material-ui/lib/icon-button';
import ActionSearch from 'material-ui/lib/svg-icons/action/search';
import ActionCopy from 'material-ui/lib/svg-icons/content/content-copy';
import ActionPaste from 'material-ui/lib/svg-icons/content/content-paste';
import ActionDelete from 'material-ui/lib/svg-icons/action/delete';
import ActionNew from 'material-ui/lib/svg-icons/action/open-in-new';
import ActionSave from 'material-ui/lib/svg-icons/content/save';
import ActionUndo from 'material-ui/lib/svg-icons/content/undo';

import CompSearchButton from './CompSearchButton';
import CompEditForm from './CompEditForm';
import RaisedButton from 'material-ui/lib/raised-button';
import CardActions from 'material-ui/lib/card/card-actions';

const layout = layouts.get( "proforma" );

function getPropertiesOfAChangedFromB( a, b ) {
  if( !a || !b )
    return {};
  var diffs = {};
  for( var k in a ) {
    if( ( typeof b[k] == undefined ) || b[k] !== a[k] )
      diffs[k] = b[k];
  }
  return diffs;
}

// -----------------------------------------------------------------
export default class CompRecambiosProformas extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      db_id:   null
    , db_data: null
    , db_orig_data: null
    , db_delta: null
    , db_changed_rec: false
    , db_creating_new: false
    , connected: dbConn.isConnected()
    , msg_visible: false
    , msg_text: "blah blah"
    , modal_dlg_open: false
    , search_state: null
    };
  }

  componentDidMount() {
    dbConn.on('DB.connectionStatusChanged', this.onDBConnectionChange.bind(this) );
  }

  componentWillUnmount() {
    dbConn.removeListener('DB.connectionStatusChanged', this.onDBConnectionChange );
  }

  // Register to db connection/disconnections
  onDBConnectionChange( ) {
    this.setState({connected:dbConn.isConnected()});
  }

  // e is the unique id of the selected row in the comp search results
  onClickSearchResult( e, search_state ) {
    console.log( "onClickSearchResult" );
    this.setState({db_id:e});

    // Prepare the main query and the subqueries
    var db_all_results = {};
    var tasks = [];
    tasks.push( (callback)=>{
      // Main query
      console.log( "Retrieving main data for key " + e );
      var resolved_filter = layout.search.exact.filter.replace( /__FIELD__/, e );
      dbConn.DBSelect( layout.table
                     , ["*"]
                     , resolved_filter
                     , this
                     , (data) => {
        console.log( "Main query recv");
        console.log( data );
        db_all_results = Object.assign({},db_all_results,data[0]);
        console.log( db_all_results );
        callback(null);
      });
    });

    //tasks.push( (callback)=>{ setTimeout( callback, 2000 ); } );

    // For subqueries if needed
    _.each( layout.fields, (f)=>{
      if( f.type === "array_table" ) {
        tasks.push( (callback)=>{
          console.log( "Retrieving data for field " + f.field );
          console.log( layout );
          var ext_layout = layouts.get( f.layout );
          console.log( "External layout" );
          console.log( ext_layout );
          console.log( "Local field to search is " + f.local );
          var searched_field = layouts.getFieldByname( layout, f.local );
          console.log( "searched_field " );
          console.log( searched_field );
          var searched_value = db_all_results[ searched_field.field ];
          console.log( "searched_value " + searched_value );
          var resolved_filter = ext_layout.search.join.filter.replace( /__FIELD__/, searched_value );
          dbConn.DBSelect( ext_layout.table
                         , ["*"]
                         , resolved_filter
                         , this
                         , (data) => {
            console.log( "Sub query for " + f.field + " recv");
            console.log( data );
            db_all_results[ f.field ] = data;
            console.log( db_all_results );
            callback(null);
          });
        });
      }
    });

    console.log( "Running tasks");
    console.log( tasks );
    async.series( tasks, (err)=>{
      console.log( "All data collected");
      console.log( db_all_results );
      this.validateData({
        db_data: db_all_results,
        db_orig_data:db_all_results,
        db_creating_new:false,
        search_state:search_state
      });
    });
  }

  validateData( ns ) {
    if( ns.db_data ) {
      layouts.validateDates( layout, ns.db_data );
      var ref = this.state.db_orig_data;
      if( ns.db_orig_data )
        ref = ns.db_orig_data;
      ns.db_delta = getPropertiesOfAChangedFromB( ref, ns.db_data );
      ns.db_changed_rec = ( Object.keys( ns.db_delta ).length != 0 );
    }
    //console.log( "ns is now")
    //console.log( ns );
    this.setState(ns);
  }

  onDataChange( new_db_data ) {
    //console.log( "onDataChange" );
    this.validateData({db_data:new_db_data});
  }

  // --------------------------------------------------------------
  onClickCancel( e, dummy  ) {
    console.log( "Restoring...");
    this.validateData({db_data:this.state.db_orig_data});
  }

  // --------------------------------------------------------------
  onClickSave( e, dummy ) {
    if( !this.state.db_changed_rec && !this.state.db_creating_new )
      return;
    console.log( "Saving...");
    var changes = this.state.db_delta;
    console.log( changes );

    var handler =
      (data)=>{
        console.log( "Save completed " + this.state.db_id);
        console.log( data );
        this.onClickSearchResult( this.state.db_id );
        this.setState({msg_visible:true, msg_text:"Registro grabado correctamente"});
       };

    if( this.state.db_creating_new ) {
      const new_id = changes[ layout.key_field ];
      console.log( "Adding new register to the db... " + new_id);
      this.setState({db_id:new_id});
      dbConn.DBInsert( layout.table
                     , changes
                     , this
                     , handler );
    } else {
      delete changes[ layout.key_field ];
      dbConn.DBUpdate( layout.table
                     , changes
                     , layout.key_field + "='"+ this.state.db_id + "'"
                     , this
                     , handler );
    }

  }
  // --------------------------------------------------------------
  onClickNew( ) {
    console.log( "New register...");
    const new_db_data = layouts.getNewEmptyRegister( layout );
    const new_db_orig_data = new_db_data;
    this.validateData(
      { db_data: new_db_data
      , db_orig_data:new_db_orig_data
      , db_id:"new"
      , db_creating_new:true
      });
  }

  // --------------------------------------------------------------
  onClickDelete( ) {
    this.setState({modal_dlg_open:true}, {modal_dlg_msg:"¿Borrar completamente el registro?"});
  }

  // --------------------------------------------------------------
  onClickCopy( ) {
    console.log( "Copying to clipboard...");
  }

  // --------------------------------------------------------------
  onClickPaste( ) {
    console.log( "Pasting from clipboard...");
  }

  // --------------------------------------------------------------
  onClickSearchAgain() {
    this.setState( {db_id:null} );
  }

  // --------------------------------------------------------------
  onClick( e, dummy ) {
    console.log( "On click..." + e );
  }

  // ------------------------------------------------------------------
  renderDisconnected() {
    const style = {
      margin: "auto",
      textAlign: "center"
    };
    return (
Trying to connect to the database...<CircularProgress mode="indeterminate" />
);
  }

  renderSearchForm() {
    var code = JSON.stringify( layout, null, '  ' );
    return (<CompSearchDB
        data={layout}
        onClickNew={this.onClickNew.bind(this)}
        onClickSearchResult={this.onClickSearchResult.bind(this)}
        search_state={this.state.search_state}
        />);
    //return (
You are searching
{code}

);
  }

  // ----------------------------------------------------------------
  renderSearchButton( ) {
    return (<IconButton tooltip="Buscar de nuevo" onClick={this.onClickSearchAgain.bind(this)}><ActionSearch/></IconButton>);
  }

  // ----------------------------------------------------------------
  renderSaveButton() {
    const buttons_group_style = {float:"right"};
    var changed = this.state.db_changed_rec;
    var is_new = this.state.db_creating_new;
    return (
      <CardActions expandable style={buttons_group_style}>
        <IconButton tooltip="Buscar de nuevo" onClick={this.onClickSearchAgain.bind(this)}><ActionSearch/></IconButton>
        <IconButton tooltip="Copiar Valores" onClick={this.onClickCopy.bind(this)}><ActionCopy/></IconButton>
        <IconButton tooltip="Pegar Valores" onClick={this.onClickPaste.bind(this)}><ActionPaste/></IconButton>
        <IconButton disabled={changed || is_new} tooltip="Nuevo Registro" onClick={this.onClickNew.bind(this)}><ActionNew/></IconButton>
        <IconButton disabled={!changed && !is_new} tooltip="Guardar Cambios" onClick={this.onClickSave.bind(this)}><ActionSave/></IconButton>
        <IconButton disabled={!changed} tooltip="Deshacer Cambios" onClick={this.onClickCancel.bind(this)}><ActionUndo/></IconButton>
        <IconButton disabled={!changed} tooltip="Borrar Registro" onClick={this.onClickDelete.bind(this)}><ActionDelete/></IconButton>
      </CardActions>);
  }

  renderForm() {
    return(
      <CompEditForm
        data={this.state.db_data}
        onChange={this.onDataChange.bind(this)}
        onClick={this.onClick.bind(this)}
        layout={layout}
        creating_new={this.state.db_creating_new}
        />);
  }

  renderSnackBar() {
    var handler = ()=>{this.setState({msg_visible: false});};
    return (
      <Snackbar
        open={this.state.msg_visible}
        message={this.state.msg_text}
        autoHideDuration={1000}
        onRequestClose={handler}/>);
  }

  renderModalDialog() {
    var handler_no = ()=>{this.setState({modal_dlg_open: false});};
    var handler_yes = ()=>{this.setState({modal_dlg_open: false});};
    var actions = (
      <CardActions >
      <RaisedButton label="No" onClick={handler_no}/>
      <RaisedButton label="Yes" onClick={handler_yes}/>
      </CardActions>);
    return (<Dialog
          title={this.state.modal_dlg_msg}
          modal
          actions={actions}
          open={this.state.modal_dlg_open}
          />);
  }

  // ------------------------------------------------------------------
  render() {

    if( !this.state.connected )
      return this.renderDisconnected();

    if( !this.state.db_id )
      return this.renderSearchForm();

    if( !this.state.db_data ) {
      var search = this.renderSearchButton();
      return (
{search}Retrieving data from {this.state.db_id}
);
    }

    var dlg = this.renderModalDialog();
    var save = this.renderSaveButton();
    var msg = this.renderSnackBar();
    var form = this.renderForm();
    var json = JSON.stringify( this.state, null, '  ' );
    //console.log( this.state );
    return (
{save}{form}<Divider />{msg}{dlg}
{json}

);
  }
}

CompRecambiosProformas.propTypes = {
};

<|endoftext|>


<commit_before>function conjoin(strings, value) {
  if (!value) {
    return '';
  }
  const str0 = strings[0];
  const str1 = strings[1];
  if (Array.isArray(value)) {
    const o = value.map(x => x.value);
    const r = [];
    if (!value.length) {
      return '';
    }
    o.forEach((s) => {
      r.push(`${str0}${s}${str1}`);
    });
    return `AND (${r.join(' OR ')})`;
  }
  return `AND ${str0}${value.value !== undefined ? value.value : value}${str1}`;
}

function validateArray(p) {
  return Array.isArray(p) && p.length > 0;
}

const queryTemplate = (props) => {
  const {
    select,
    group,
    minPatch,
    maxPatch,
    hero,
    player,
    league,
    playerPurchased,
    minDuration,
    maxDuration,
    side,
    result,
    team,
    organization,
    laneRole,
    region,
    minDate,
    maxDate,
    order,
    tier,
    having,
    limit,
    isTi8Team,
    megaWin,
    minGoldAdvantage,
    maxGoldAdvantage,
  } = props;
  // array inputs
  // group
  // hero
  // player
  // league
  // team
  // organization
  let query;
  let groupArray = [];
  let selectArray = [];
  if (!(Array.isArray(group))) {
    groupArray.push(group);
  } else {
    groupArray = group;
  }
  if (!(Array.isArray(select))) {
    selectArray.push(select);
  } else {
    selectArray = select;
  }
  selectArray = selectArray.filter(x => x !== undefined);
  groupArray = groupArray.filter(x => x !== undefined);
  groupArray.forEach((x) => {
    if (x.json_each) {
      selectArray.push(x);
    }
  });
  groupArray = groupArray.filter(x => !x.json_each);
  selectArray.forEach((x, index) => {
    if (x && x.groupValue) {
      const a = {
        value: x.groupKey, groupKeySelect: x.groupKeySelect, alias: x.alias, key: `key${index.toString()}`,
      };
      if (x.groupKey === 'key') {
        const p = x;
        a.value = `key${index.toString()}.key`;
        p.value = `key${index.toString()}.key`;
        p.join = `${x.join} key${index.toString()}`;
        p.groupValue = `key${index.toString()}.${x.groupValue}`;
      }
      groupArray.push(a);
    }
  });
  if (validateArray(selectArray) && selectArray.some(p => p.template === 'picks_bans')) {
    query = `SELECT
hero_id,
count(1) total,
sum(is_pick::int) picks,
sum((NOT is_pick)::int) bans,
sum((is_pick IS TRUE AND ord < 8)::int) first_pick,
sum((is_pick IS FALSE AND ord < 8)::int) first_ban,
sum((is_pick IS TRUE AND ord >= 8 AND ord < 16)::int) second_pick,
sum((is_pick IS FALSE AND ord >= 8 AND ord < 16)::int) second_ban,
sum((is_pick IS TRUE AND ord >= 16)::int) third_pick,
sum((is_pick IS FALSE AND ord >= 16)::int) third_ban,
sum((radiant = radiant_win)::int)::float/count(1) winrate,
sum((radiant = radiant_win AND is_pick IS TRUE)::int)::float/NULLIF(sum(is_pick::int), 0) pick_winrate,
sum((radiant = radiant_win AND is_pick IS FALSE)::int)::float/NULLIF(sum((NOT is_pick)::int), 0) ban_winrate
FROM picks_bans
JOIN matches using(match_id)
JOIN match_patch using(match_id)
JOIN leagues using(leagueid)
JOIN team_match using(match_id)
JOIN teams using(team_id)
WHERE TRUE
${validateArray(selectArray) && selectArray.find(x => x.where) !== undefined ? selectArray.find(x => x.where).where : ''}
${conjoin`team_id = ${organization}`}
${conjoin`match_patch.patch >= '${minPatch}'`}
${conjoin`match_patch.patch <= '${maxPatch}'`}
${conjoin`matches.leagueid = ${league}`}
${conjoin`matches.duration >= ${minDuration}`}
${conjoin`matches.duration <= ${maxDuration}`}
${conjoin`team_match.radiant = ${side}`}
${conjoin`(team_match.radiant = matches.radiant_win) = ${result}`}
${conjoin`matches.cluster IN (${region})`}
${minDate ? conjoin`matches.start_time >= extract(epoch from timestamp '${new Date(minDate.value).toISOString()}')` : ''}
${maxDate ? conjoin`matches.start_time <= extract(epoch from timestamp '${new Date(maxDate.value).toISOString()}')` : ''}
${conjoin`leagues.tier = '${tier}'`}
${isTi8Team ? 'AND teams.team_id IN (5, 15, 39, 67, 2163, 350190, 543897, 726228, 1375614, 1838315, 1883502, 2108395, 2586976, 5026801, 5027210, 5066616, 5228654, 5229127)' : ''}
${megaWin ? 'AND ((matches.barracks_status_radiant = 0 AND matches.radiant_win) OR (matches.barracks_status_dire = 0 AND NOT matches.radiant_win))' : ''}
${maxGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] <= ${maxGoldAdvantage.value}` : ''}
${minGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] >= ${minGoldAdvantage.value}` : ''}
GROUP BY hero_id
ORDER BY total ${(order && order.value) || 'DESC'}`;
  } else {
    const selectVal = {};
    const groupVal = {};
    if (validateArray(groupArray)) {
      groupArray.forEach((x) => { groupVal[x.key] = `${x.value}${x.bucket ? ` / ${x.bucket} * ${x.bucket}` : ''}`; });
    }
    if (validateArray(selectArray)) {
      selectArray.forEach((x) => { selectVal[x.key] = x.groupValue || (x && x.value) || 1; });
    }
    query = `SELECT
    ${validateArray(selectArray) ? selectArray.map(x => (x.distinct && !validateArray(groupArray) ? `DISTINCT ON (${x.value})` : '')).join('') : ''}\
    ${(validateArray(groupArray)) ?
    groupArray.map(x =>
      [`${x.groupKeySelect || groupVal[x.key]} ${x.alias || ''},`].filter(Boolean).join(',\n')).join('') : ''}
${(validateArray(groupArray)) ?
    (validateArray(selectArray) && selectArray.map(x =>
      [
        (x && x.countValue) || '',
        (x && x.avgPerMatch) ? `sum(${selectVal[x.key]})::numeric/count(distinct matches.match_id) "AVG ${x.text}"` : `${x && x.avg ? x.avg : `avg(${selectVal[x.key]})`} "AVG ${x.text}"`,
        'count(distinct matches.match_id) count',
        'sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1) winrate',
        `((sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1))
+ 1.96 * 1.96 / (2 * count(1))
- 1.96 * sqrt((((sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1)) * (1 - (sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1))) + 1.96 * 1.96 / (4 * count(1))) / count(1))))
/ (1 + 1.96 * 1.96 / count(1)) winrate_wilson`,
        `sum(${selectVal[x.key]}) sum`,
        `min(${selectVal[x.key]}) min`,
        `max(${selectVal[x.key]}) max`,
        `stddev(${selectVal[x.key]}::numeric) stddev
  `,
      ].filter(Boolean).join(',\n'))) || '' : ''}
${!validateArray(groupArray) ?
    [validateArray(selectArray) ? selectArray.map(x => `${x.value} ${x.alias || ''}`) : '',
      'matches.match_id',
      'matches.start_time',
      '((player_matches.player_slot < 128) = matches.radiant_win) win',
      'player_matches.hero_id',
      'player_matches.account_id',
      'leagues.name leaguename',
    ].filter(Boolean).join(',\n') : ''}
FROM matches
JOIN match_patch using(match_id)
JOIN leagues using(leagueid)
JOIN player_matches using(match_id)
JOIN heroes on heroes.id = player_matches.hero_id
LEFT JOIN notable_players ON notable_players.account_id = player_matches.account_id AND notable_players.locked_until = (SELECT MAX(locked_until) FROM notable_players)
LEFT JOIN teams using(team_id)
${organization || (groupArray !== null && groupArray.length > 0 && groupArray[0] && groupArray.some(x => x.key === 'organization')) ?
    'JOIN team_match ON matches.match_id = team_match.match_id AND (player_matches.player_slot < 128) = team_match.radiant JOIN teams teams2 ON team_match.team_id = teams2.team_id' : ''}
${validateArray(selectArray) ? selectArray.map(x => (x.joinFn ? x.joinFn(props) : '')).join('') : ''}
${validateArray(selectArray) ? selectArray.map(x => (x.join ? x.join : '')).join('') : ''}
WHERE TRUE
${validateArray(selectArray) ? selectArray.map(x => `AND ${x.value} IS NOT NULL `).join('') : ''}
${conjoin`match_patch.patch >= '${minPatch}'`}
${conjoin`match_patch.patch <= '${maxPatch}'`}
${conjoin`player_matches.hero_id = ${hero}`}
${conjoin`player_matches.account_id = ${player}`}
${conjoin`matches.leagueid = ${league}`}
${conjoin`(player_matches.purchase->>'${playerPurchased}')::int > 0`}
${conjoin`matches.duration >= ${minDuration}`}
${conjoin`matches.duration <= ${maxDuration}`}
${conjoin`(player_matches.player_slot < 128) = ${side}`}
${conjoin`((player_matches.player_slot < 128) = matches.radiant_win) = ${result}`}
${conjoin`notable_players.team_id = ${team}`}
${conjoin`team_match.team_id = ${organization} AND (player_matches.player_slot < 128) = team_match.radiant`}
${conjoin`player_matches.lane_role = ${laneRole}`}
${conjoin`matches.cluster IN (${region})`}
${minDate ? conjoin`matches.start_time >= extract(epoch from timestamp '${new Date(minDate.value).toISOString()}')` : ''}
${maxDate ? conjoin`matches.start_time <= extract(epoch from timestamp '${new Date(maxDate.value).toISOString()}')` : ''}
${conjoin`leagues.tier = '${tier}'`}
${isTi8Team ? 'AND teams.team_id IN (5, 15, 39, 67, 2163, 350190, 543897, 726228, 1375614, 1838315, 1883502, 2108395, 2586976, 5026801, 5027210, 5066616, 5228654, 5229127)' : ''}
${megaWin ? 'AND ((matches.barracks_status_radiant = 0 AND matches.radiant_win) OR (matches.barracks_status_dire = 0 AND NOT matches.radiant_win))' : ''}
${maxGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] <= ${maxGoldAdvantage.value}` : ''}
${minGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] >= ${minGoldAdvantage.value}` : ''}
${validateArray(groupArray) ? 'GROUP BY' : ''}${(validateArray(groupArray) && groupArray.map(x => ` ${groupVal[x.key]}`)) || ''}
${validateArray(groupArray) ? `HAVING count(distinct matches.match_id) >= ${(having && having.value) || '1'}` : ''}
ORDER BY ${
  [`${(validateArray(groupArray) && validateArray(selectArray) && selectArray.map(x => `"AVG ${x.text}" ${order ? order.value : 'DESC'}`)) ||
    (validateArray(selectArray) && selectArray.map(x => `${x.value} ${order ? order.value : 'DESC'}`).join(',')) || 'matches.match_id'}`,
  validateArray(groupArray) ? 'count DESC' : '',
  ].filter(Boolean).join(',')} NULLS LAST
LIMIT ${limit ? limit.value : 200}`;
  }
  return query
  // Remove extra newlines
    .replace(/\n{2,}/g, '\n');
};

export default queryTemplate;
<commit_msg>Update queryTemplate.js<commit_after>function conjoin(strings, value) {
  if (!value) {
    return '';
  }
  const str0 = strings[0];
  const str1 = strings[1];
  if (Array.isArray(value)) {
    const o = value.map(x => x.value);
    const r = [];
    if (!value.length) {
      return '';
    }
    o.forEach((s) => {
      r.push(`${str0}${s}${str1}`);
    });
    return `AND (${r.join(' OR ')})`;
  }
  return `AND ${str0}${value.value !== undefined ? value.value : value}${str1}`;
}

function validateArray(p) {
  return Array.isArray(p) && p.length > 0;
}

const queryTemplate = (props) => {
  const {
    select,
    group,
    minPatch,
    maxPatch,
    hero,
    player,
    league,
    playerPurchased,
    minDuration,
    maxDuration,
    side,
    result,
    team,
    organization,
    laneRole,
    region,
    minDate,
    maxDate,
    order,
    tier,
    having,
    limit,
    isTi8Team,
    megaWin,
    minGoldAdvantage,
    maxGoldAdvantage,
  } = props;
  // array inputs
  // group
  // hero
  // player
  // league
  // team
  // organization
  let query;
  let groupArray = [];
  let selectArray = [];
  if (!(Array.isArray(group))) {
    groupArray.push(group);
  } else {
    groupArray = group;
  }
  if (!(Array.isArray(select))) {
    selectArray.push(select);
  } else {
    selectArray = select;
  }
  selectArray = selectArray.filter(x => x !== undefined);
  groupArray = groupArray.filter(x => x !== undefined);
  groupArray.forEach((x) => {
    if (x.json_each) {
      selectArray.push(x);
    }
  });
  groupArray = groupArray.filter(x => !x.json_each);
  selectArray.forEach((x, index) => {
    if (x && x.groupValue) {
      const a = {
        value: x.groupKey, groupKeySelect: x.groupKeySelect, alias: x.alias, key: `key${index.toString()}`,
      };
      if (x.groupKey === 'key') {
        const p = x;
        a.value = `key${index.toString()}.key`;
        p.value = `key${index.toString()}.key`;
        p.join = `${x.join} key${index.toString()}`;
        p.groupValue = `key${index.toString()}.${x.groupValue}`;
      }
      groupArray.push(a);
    }
  });
  if (validateArray(selectArray) && selectArray.some(p => p.template === 'picks_bans')) {
    query = `SELECT
hero_id,
count(1) total,
sum(is_pick::int) picks,
sum((NOT is_pick)::int) bans,
sum((is_pick IS TRUE AND ord < 8)::int) first_pick,
sum((is_pick IS FALSE AND ord < 8)::int) first_ban,
sum((is_pick IS TRUE AND ord >= 8 AND ord < 16)::int) second_pick,
sum((is_pick IS FALSE AND ord >= 8 AND ord < 16)::int) second_ban,
sum((is_pick IS TRUE AND ord >= 16)::int) third_pick,
sum((is_pick IS FALSE AND ord >= 16)::int) third_ban,
sum((radiant = radiant_win)::int)::float/count(1) winrate,
sum((radiant = radiant_win AND is_pick IS TRUE)::int)::float/NULLIF(sum(is_pick::int), 0) pick_winrate,
sum((radiant = radiant_win AND is_pick IS FALSE)::int)::float/NULLIF(sum((NOT is_pick)::int), 0) ban_winrate
FROM picks_bans
JOIN matches using(match_id)
JOIN match_patch using(match_id)
JOIN leagues using(leagueid)
JOIN team_match using(match_id)
JOIN teams using(team_id)
WHERE TRUE
${validateArray(selectArray) && selectArray.find(x => x.where) !== undefined ? selectArray.find(x => x.where).where : ''}
${conjoin`team_id = ${organization}`}
${conjoin`match_patch.patch >= '${minPatch}'`}
${conjoin`match_patch.patch <= '${maxPatch}'`}
${conjoin`matches.leagueid = ${league}`}
${conjoin`matches.duration >= ${minDuration}`}
${conjoin`matches.duration <= ${maxDuration}`}
${conjoin`team_match.radiant = ${side}`}
${conjoin`(team_match.radiant = matches.radiant_win) = ${result}`}
${conjoin`matches.cluster IN (${region})`}
${minDate ? conjoin`matches.start_time >= extract(epoch from timestamp '${new Date(minDate.value).toISOString()}')` : ''}
${maxDate ? conjoin`matches.start_time <= extract(epoch from timestamp '${new Date(maxDate.value).toISOString()}')` : ''}
${conjoin`leagues.tier = '${tier}'`}
${isTi8Team ? 'AND teams.team_id IN (5, 15, 39, 67, 2163, 350190, 543897, 726228, 1375614, 1838315, 1883502, 2108395, 2586976, 5026801, 5027210, 5066616, 5228654, 5229127)' : ''}
${megaWin ? 'AND ((matches.barracks_status_radiant = 0 AND matches.radiant_win) OR (matches.barracks_status_dire = 0 AND NOT matches.radiant_win))' : ''}
${maxGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] <= ${maxGoldAdvantage.value}` : ''}
${minGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] >= ${minGoldAdvantage.value}` : ''}
GROUP BY hero_id
ORDER BY total ${(order && order.value) || 'DESC'}`;
  } else {
    const selectVal = {};
    const groupVal = {};
    if (validateArray(groupArray)) {
      groupArray.forEach((x) => { groupVal[x.key] = `${x.value}${x.bucket ? ` / ${x.bucket} * ${x.bucket}` : ''}`; });
    }
    if (validateArray(selectArray)) {
      selectArray.forEach((x) => { selectVal[x.key] = x.groupValue || (x && x.value) || 1; });
    }
    query = `SELECT
    ${validateArray(selectArray) ? selectArray.map(x => (x.distinct && !validateArray(groupArray) ? `DISTINCT ON (${x.value})` : '')).join('') : ''}\
    ${(validateArray(groupArray)) ?
    groupArray.map(x =>
      [`${x.groupKeySelect || groupVal[x.key]} ${x.alias || ''},`].filter(Boolean).join(',\n')).join('') : ''}
${(validateArray(groupArray)) ?
    (validateArray(selectArray) && selectArray.map(x =>
      [
        (x && x.countValue) || '',
        (x && x.avgPerMatch) ? `sum(${selectVal[x.key]})::numeric/count(distinct matches.match_id) "AVG ${x.text}"` : `${x && x.avg ? x.avg : `avg(${selectVal[x.key]})`} "AVG ${x.text}"`,
        'count(distinct matches.match_id) count',
        'sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1) winrate',
        `((sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1))
+ 1.96 * 1.96 / (2 * count(1))
- 1.96 * sqrt((((sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1)) * (1 - (sum(case when (player_matches.player_slot < 128) = radiant_win then 1 else 0 end)::float/count(1))) + 1.96 * 1.96 / (4 * count(1))) / count(1))))
/ (1 + 1.96 * 1.96 / count(1)) winrate_wilson`,
        `sum(${selectVal[x.key]}) sum`,
        `min(${selectVal[x.key]}) min`,
        `max(${selectVal[x.key]}) max`,
        `stddev(${selectVal[x.key]}::numeric) stddev
  `,
      ].filter(Boolean).join(',\n'))) || '' : ''}
${!validateArray(groupArray) ?
    [validateArray(selectArray) ? selectArray.map(x => `${x.value} ${x.alias || ''}`) : '',
      'matches.match_id',
      'matches.start_time',
      '((player_matches.player_slot < 128) = matches.radiant_win) win',
      'player_matches.hero_id',
      'player_matches.account_id',
      'leagues.name leaguename',
    ].filter(Boolean).join(',\n') : ''}
FROM matches
JOIN match_patch using(match_id)
JOIN leagues using(leagueid)
JOIN player_matches using(match_id)
JOIN heroes on heroes.id = player_matches.hero_id
LEFT JOIN notable_players ON notable_players.account_id = player_matches.account_id
LEFT JOIN teams using(team_id)
${organization || (groupArray !== null && groupArray.length > 0 && groupArray[0] && groupArray.some(x => x.key === 'organization')) ?
    'JOIN team_match ON matches.match_id = team_match.match_id AND (player_matches.player_slot < 128) = team_match.radiant JOIN teams teams2 ON team_match.team_id = teams2.team_id' : ''}
${validateArray(selectArray) ? selectArray.map(x => (x.joinFn ? x.joinFn(props) : '')).join('') : ''}
${validateArray(selectArray) ? selectArray.map(x => (x.join ? x.join : '')).join('') : ''}
WHERE TRUE
${validateArray(selectArray) ? selectArray.map(x => `AND ${x.value} IS NOT NULL `).join('') : ''}
${conjoin`match_patch.patch >= '${minPatch}'`}
${conjoin`match_patch.patch <= '${maxPatch}'`}
${conjoin`player_matches.hero_id = ${hero}`}
${conjoin`player_matches.account_id = ${player}`}
${conjoin`matches.leagueid = ${league}`}
${conjoin`(player_matches.purchase->>'${playerPurchased}')::int > 0`}
${conjoin`matches.duration >= ${minDuration}`}
${conjoin`matches.duration <= ${maxDuration}`}
${conjoin`(player_matches.player_slot < 128) = ${side}`}
${conjoin`((player_matches.player_slot < 128) = matches.radiant_win) = ${result}`}
${conjoin`notable_players.team_id = ${team}`}
${conjoin`team_match.team_id = ${organization} AND (player_matches.player_slot < 128) = team_match.radiant`}
${conjoin`player_matches.lane_role = ${laneRole}`}
${conjoin`matches.cluster IN (${region})`}
${minDate ? conjoin`matches.start_time >= extract(epoch from timestamp '${new Date(minDate.value).toISOString()}')` : ''}
${maxDate ? conjoin`matches.start_time <= extract(epoch from timestamp '${new Date(maxDate.value).toISOString()}')` : ''}
${conjoin`leagues.tier = '${tier}'`}
${isTi8Team ? 'AND teams.team_id IN (5, 15, 39, 67, 2163, 350190, 543897, 726228, 1375614, 1838315, 1883502, 2108395, 2586976, 5026801, 5027210, 5066616, 5228654, 5229127)' : ''}
${megaWin ? 'AND ((matches.barracks_status_radiant = 0 AND matches.radiant_win) OR (matches.barracks_status_dire = 0 AND NOT matches.radiant_win))' : ''}
${maxGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] <= ${maxGoldAdvantage.value}` : ''}
${minGoldAdvantage ? `AND @ matches.radiant_gold_adv[array_upper(matches.radiant_gold_adv, 1)] >= ${minGoldAdvantage.value}` : ''}
${validateArray(groupArray) ? 'GROUP BY' : ''}${(validateArray(groupArray) && groupArray.map(x => ` ${groupVal[x.key]}`)) || ''}
${validateArray(groupArray) ? `HAVING count(distinct matches.match_id) >= ${(having && having.value) || '1'}` : ''}
ORDER BY ${
  [`${(validateArray(groupArray) && validateArray(selectArray) && selectArray.map(x => `"AVG ${x.text}" ${order ? order.value : 'DESC'}`)) ||
    (validateArray(selectArray) && selectArray.map(x => `${x.value} ${order ? order.value : 'DESC'}`).join(',')) || 'matches.match_id'}`,
  validateArray(groupArray) ? 'count DESC' : '',
  ].filter(Boolean).join(',')} NULLS LAST
LIMIT ${limit ? limit.value : 200}`;
  }
  return query
  // Remove extra newlines
    .replace(/\n{2,}/g, '\n');
};

export default queryTemplate;
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//     https://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.
//

'use strict';

module.exports = {
  opts: {
    readme: './README.md',
    package: './package.json',
    template: './node_modules/jsdoc-fresh',
    recurse: true,
    verbose: true,
    destination: './docs/'
  },
  plugins: [
    'plugins/markdown',
    'jsdoc-region-tag'
  ],
  source: {
    excludePattern: '(^|\\/|\\\\)[._]',
    include: [
      'build/src'
    ],
    includePattern: '\\.js$'
  },
  templates: {
    copyright: 'Copyright 2018 Google, LLC.',
    includeDate: false,
    sourceFiles: false,
    systemName: '@google-cloud/cloudbuild',
    theme: 'lumen'
  },
  markdown: {
    idInHeadings: true
  }
};
<commit_msg>chore: update jsdoc.js (#70)<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//     https://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.
//

'use strict';

module.exports = {
  opts: {
    readme: './README.md',
    package: './package.json',
    template: './node_modules/jsdoc-fresh',
    recurse: true,
    verbose: true,
    destination: './docs/'
  },
  plugins: [
    'plugins/markdown',
    'jsdoc-region-tag'
  ],
  source: {
    excludePattern: '(^|\\/|\\\\)[._]',
    include: [
      'build/src'
    ],
    includePattern: '\\.js$'
  },
  templates: {
    copyright: 'Copyright 2019 Google, LLC.',
    includeDate: false,
    sourceFiles: false,
    systemName: '@google-cloud/cloudbuild',
    theme: 'lumen',
    default: {
      "outputSourceFiles": false
    }
  },
  markdown: {
    idInHeadings: true
  }
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Container = styled.div`
  flex: 1 1 auto;

  &:first-of-type > label {
    border-radius: 3px 0 0 3px;
  }

  &:first-of-type > label::after {
    border-radius: 0 0 0 3px;
  }

  &:last-of-type > label {
    border-radius: 0 3px 3px 0;
  }

  &:last-of-type > label::after {
    border-radius: 0 0 3px 0;
  }
`;

const Input = styled.input`
  display: block;
  height: 0;
  width: 0;
  margin: 0;
  padding: 0;
  border: none;

  &:focus + label {
    border-color: ${({ theme }) => theme.colors.primary};
  }
`;

const Label = styled.label`
  opacity: ${({ active }) => active ? 1 : 0.5};
  border: ${({ theme }) => theme.radioButton.border};
  margin-right: -1px;
  padding: ${({ theme }) => theme.radioButton.padding};
  cursor: pointer;
  position: relative;
  display: flex;
  flex-direction: column;
  align-content: flex-start;
  background: ${({ theme }) => theme.radioButton.bg};
  color: ${({ theme }) => theme.radioButton.fg};
  transition: opacity 0.2s ease;
  text-transform: uppercase;
  font-weight: bold;
  height: 100%;

  &::after {
    content: "";
    background: ${({ theme }) => theme.radioButton.accent};
    width: calc(100% + 2px);
    height: ${({ active }) => active ? '5px' : 0};
    position: absolute;
    bottom: -1px;
    left: -1px;
    display: block;
    transition: height 0.2s ease, opacity 0.2s ease;
  }

  &:hover::after {
    height: 5px;
    opacity: ${({ active }) => active ? 1 : 0.5};
  }

  &:hover {
    border-color: ${({ active, theme }) => active ? theme.colors.borderLight : theme.colors.primary};
  }
`;

const Content = styled.figure`
  font-size: 2em;
  font-weight: 100;
  margin: auto auto auto 0;
`;

const LabelText = styled.span`
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  margin: auto auto auto 0;
`;

class RadioButton extends React.Component {
  static propTypes = {
    /**
     * Whether or not the button is currently selected.
     */
    checked: PropTypes.bool.isRequired,
    /**
     * Called when the checked state of the button changes.
     */
    onChange: PropTypes.func.isRequired,
    /**
     * Text to render inside the button's label.
     */
    label: PropTypes.string.isRequired,
    /**
     * Content to render inside the main part of the button.
     */
    content: PropTypes.node,
    /**
     * A field name for the input.
     */
    name: PropTypes.string.isRequired,
    /**
     * The input value.
     */
    value: PropTypes.string.isRequired,
    /**
     * Adds a class name to the input element.
     */
    className: PropTypes.string,
    /**
     * Adds an id to the input element.
     */
    id: PropTypes.string,
  };

  static defaultProps = {
    content: null,
    className: null,
    id: null,
  };

  render() {
    const { checked, label, name, value, onChange, content, className } = this.props;
    const id = this.props.id || `radio-${name}>${value}`;

    return (
      <Container>
        <Input
          type="radio"
          id={id}
          value={value}
          name={name}
          checked={checked}
          onChange={onChange}
          className={className}
        />
        <Label htmlFor={id} active={checked}>
          {content !== null ? <Content active={checked}>{content}</Content> : null}
          <LabelText>{label}</LabelText>
        </Label>
      </Container>
    );
  }
}

RadioButton.usage = `
Not really meant to be used alone, unless you just want the styling of it. Use RadioGroup to create a group of RadioButtons.
`;

export default RadioButton;
<commit_msg>Visibility fix for RadioButton on some browsers<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Container = styled.div`
  flex: 1 1 auto;
  position: relative;

  &:first-of-type > label {
    border-radius: 3px 0 0 3px;
  }

  &:first-of-type > label::after {
    border-radius: 0 0 0 3px;
  }

  &:last-of-type > label {
    border-radius: 0 3px 3px 0;
  }

  &:last-of-type > label::after {
    border-radius: 0 0 3px 0;
  }
`;

const Input = styled.input`
  display: block;
  height: 0;
  width: 0;
  margin: 0;
  padding: 0;
  border: none;
  position: absolute;
  opacity: 0;

  &:focus + label {
    border-color: ${({ theme }) => theme.colors.primary};
  }
`;

const Label = styled.label`
  opacity: ${({ active }) => active ? 1 : 0.5};
  border: ${({ theme }) => theme.radioButton.border};
  margin-right: -1px;
  padding: ${({ theme }) => theme.radioButton.padding};
  cursor: pointer;
  position: relative;
  display: flex;
  flex-direction: column;
  align-content: flex-start;
  background: ${({ theme }) => theme.radioButton.bg};
  color: ${({ theme }) => theme.radioButton.fg};
  transition: opacity 0.2s ease;
  text-transform: uppercase;
  font-weight: bold;
  height: 100%;

  &::after {
    content: "";
    background: ${({ theme }) => theme.radioButton.accent};
    width: calc(100% + 2px);
    height: ${({ active }) => active ? '5px' : 0};
    position: absolute;
    bottom: -1px;
    left: -1px;
    display: block;
    transition: height 0.2s ease, opacity 0.2s ease;
  }

  &:hover::after {
    height: 5px;
    opacity: ${({ active }) => active ? 1 : 0.5};
  }

  &:hover {
    border-color: ${({ active, theme }) => active ? theme.colors.borderLight : theme.colors.primary};
  }
`;

const Content = styled.figure`
  font-size: 2em;
  font-weight: 100;
  margin: auto auto auto 0;
`;

const LabelText = styled.span`
  font-size: inherit;
  font-weight: inherit;
  color: inherit;
  margin: auto auto auto 0;
`;

class RadioButton extends React.Component {
  static propTypes = {
    /**
     * Whether or not the button is currently selected.
     */
    checked: PropTypes.bool.isRequired,
    /**
     * Called when the checked state of the button changes.
     */
    onChange: PropTypes.func.isRequired,
    /**
     * Text to render inside the button's label.
     */
    label: PropTypes.string.isRequired,
    /**
     * Content to render inside the main part of the button.
     */
    content: PropTypes.node,
    /**
     * A field name for the input.
     */
    name: PropTypes.string.isRequired,
    /**
     * The input value.
     */
    value: PropTypes.string.isRequired,
    /**
     * Adds a class name to the input element.
     */
    className: PropTypes.string,
    /**
     * Adds an id to the input element.
     */
    id: PropTypes.string,
  };

  static defaultProps = {
    content: null,
    className: null,
    id: null,
  };

  render() {
    const { checked, label, name, value, onChange, content, className } = this.props;
    const id = this.props.id || `radio-${name}>${value}`;

    return (
      <Container>
        <Input
          type="radio"
          id={id}
          value={value}
          name={name}
          checked={checked}
          onChange={onChange}
          className={className}
        />
        <Label htmlFor={id} active={checked}>
          {content !== null ? <Content active={checked}>{content}</Content> : null}
          <LabelText>{label}</LabelText>
        </Label>
      </Container>
    );
  }
}

RadioButton.usage = `
Not really meant to be used alone, unless you just want the styling of it. Use RadioGroup to create a group of RadioButtons.
`;

export default RadioButton;
<|endoftext|>


<commit_before>// test utils
import { mount, shallow, render } from 'enzyme';
// Components
import ToolBar, {ToolbarGroup, ToolbarSort} from '../toolbar';

describe('ToolBar components ', () => {
    describe('<ToolBar />', ()=> {
        it('should be a div with a data-focus=toolbar', () => {
            const values = ['truc', 'machin', 'bidule'];
            const toolbarProps = {
                sort: sinon.spy(),
                group: sinon.spy(),
                sortList: values,
                groupList: values
            };
            const wrapper = render(<ToolBar toolbarProps={toolbarProps} selectState={false} toggleAllLine={() => sinon.spy()} />);
            expect(wrapper.find("div[data-focus='toolbar']")).to.exist;
        });
    });
    describe('<ToolbarGroup/>', () => {
        it("should have three options if the listeGroup have a length equal to 3 ", ()=> {
            const wrapper = mount(<ToolbarGroup groupList={['truc', 'machin', 'bidule']}/>)
            expect(wrapper.find("[data-focus='dropdown'] ul li")).to.have.length(3);
        });
        it('should call the props group on the change event', ()=> {
            const groupSpy = sinon.spy();
            const wrapper = mount(<ToolbarGroup group={groupSpy} groupList={['truc', 'machin', 'bidule']}/>)
            wrapper.find("[data-focus='dropdown'] ul li").at(0).simulate('click');
            expect(groupSpy).to.have.property('callCount', 1);
            expect(groupSpy).to.have.been.calledWith()
        });
    });
    describe('<ToolbarSort/>', () => {
        it('should call the props sort on the change event', ()=> {
            const sortSpy = sinon.spy();
            const wrapper = mount(<ToolbarSort sort={sortSpy} sortList={['truc', 'machin', 'bidule']} />)
            wrapper.find("[data-focus='dropdown'] ul li").at(0).simulate('click');
            expect(sortSpy).to.have.property('callCount', 1);
            expect(sortSpy).to.have.been.calledWith()
        });
        it('should have 6 options if the listeGroup have a length equal to 3', ()=> {
            const wrapper = mount(<ToolbarSort sortList={['truc', 'machin', 'bidule']}/>)
            expect(wrapper.find("[data-focus='dropdown'] ul li")).to.have.length(6);
        });
    });
});
<commit_msg>test react ref<commit_after>// test utils
import { mount, shallow, render } from 'enzyme';
// Components
import ToolBar, {ToolbarGroup, ToolbarSort} from '../toolbar';

describe('ToolBar components ', () => {
    describe('<ToolBar />', ()=> {
        it('should be a div with a data-focus=toolbar', () => {
            const values = ['truc', 'machin', 'bidule'];
            const toolbarProps = {
                sort: sinon.spy(),
                group: sinon.spy(),
                sortList: values,
                groupList: values
            };
            const wrapper = render(<ToolBar toolbarProps={toolbarProps} selectState={false} toggleAllLine={() => sinon.spy()} />);
            expect(wrapper.find("div[data-focus='toolbar']")).to.exist;
        });
    });
    describe('<ToolbarGroup/>', () => {
        it("should have three options if the listeGroup have a length equal to 3 ", ()=> {
            const wrapper = mount(<ToolbarGroup groupList={['truc', 'machin', 'bidule']}/>)
            expect(wrapper.find("[data-focus='dropdown'] ul li")).to.have.length(3);
        });
        it('should call the props group on the change event', ()=> {
            const groupSpy = sinon.spy();
            const wrapper = mount(<ToolbarGroup group={groupSpy} groupList={['truc', 'machin', 'bidule']}/>)
            wrapper.find("[data-focus='dropdown'] ul li").at(0).simulate('click');
            expect(groupSpy).to.have.property('callCount', 1);
            expect(groupSpy).to.have.been.calledWith()
        });
    });
    describe('<ToolbarSort/>', () => {
        it('should call the props sort on the change event', ()=> {
            const sortSpy = sinon.spy();
            const wrapper = mount(<ToolbarSort sort={sortSpy} sortList={['truc', 'machin', 'bidule']} />)
            wrapper.find("[data-focus='dropdown'] ul li").at(0).simulate('click');
            expect(sortSpy).to.have.property('callCount', 1);
            expect(sortSpy).to.have.been.calledWith()
        });
        it('should have 6 options if the listeGroup have a length equal to 3', ()=> {
            const wrapper = render(<ToolbarSort sortList={['truc', 'machin', 'bidule']}/>)
            expect(wrapper.find("[data-focus='dropdown'] ul li")).to.have.length(6);
        });
    });
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

const chalk = require('chalk');
const path = require('path');

class ModuleScopePlugin {
  constructor(appSrc) {
    this.appSrc = appSrc;
  }

  apply(resolver) {
    const { appSrc } = this;
    resolver.plugin('file', (request, callback) => {
      // Unknown issuer, probably webpack internals
      if (!request.context.issuer) {
        return callback();
      }
      if (
        // If this resolves to a node_module, we don't care what happens next
        request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
        request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
        // Make sure this request was manual
        !request.__innerRequest_request
      ) {
        return callback();
      }
      // Resolve the issuer from our appSrc and make sure it's one of our files
      // Maybe an indexOf === 0 would be better?
      const relative = path.relative(appSrc, request.context.issuer);
      // If it's not in src/ or a subdirectory, not our request!
      if (relative.startsWith('../') || relative.startsWith('..\\')) {
        return callback();
      }
      const descriptionFileRelativeToRoot = path.relative(
        request.descriptionFileRoot,
        request.descriptionFilePath
      );
      if (descriptionFileRelativeToRoot === 'package.json') {
        return callback();
      }
      // Find path from src to the requested file
      const requestRelative = path.relative(
        appSrc,
        path.resolve(
          path.dirname(request.context.issuer),
          request.__innerRequest_request
        )
      );
      // Error if in a parent directory of src/
      if (
        requestRelative.startsWith('../') || requestRelative.startsWith('..\\')
      ) {
        callback(
          new Error(
            `You attempted to import ${chalk.cyan(request.__innerRequest_request)} which falls outside of the project ${chalk.cyan('src/')} directory. ` +
              `Relative imports outside of ${chalk.cyan('src/')} are not supported. ` +
              `You can either move it inside ${chalk.cyan('src/')}, or add a symlink to it from project's ${chalk.cyan('node_modules/')}.`
          ),
          request
        );
      } else {
        callback();
      }
    });
  }
}

module.exports = ModuleScopePlugin;
<commit_msg>fix importing package.json<commit_after>/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

'use strict';

const chalk = require('chalk');
const path = require('path');

class ModuleScopePlugin {
  constructor(appSrc) {
    this.appSrc = appSrc;
  }

  apply(resolver) {
    const { appSrc } = this;
    resolver.plugin('file', (request, callback) => {
      // Unknown issuer, probably webpack internals
      if (!request.context.issuer) {
        return callback();
      }
      if (
        // If this resolves to a node_module, we don't care what happens next
        request.descriptionFileRoot.indexOf('/node_modules/') !== -1 ||
        request.descriptionFileRoot.indexOf('\\node_modules\\') !== -1 ||
        // Make sure this request was manual
        !request.__innerRequest_request
      ) {
        return callback();
      }
      // Resolve the issuer from our appSrc and make sure it's one of our files
      // Maybe an indexOf === 0 would be better?
      const relative = path.relative(appSrc, request.context.issuer);
      // If it's not in src/ or a subdirectory, not our request!
      if (relative.startsWith('../') || relative.startsWith('..\\')) {
        return callback();
      }
      const requestFullPath = path.resolve(
        path.dirname(request.context.issuer),
        request.__innerRequest_request
      );
      const descriptionFileRelativeToRoot = path.relative(
        request.descriptionFileRoot,
        requestFullPath
      );
      if (descriptionFileRelativeToRoot === 'package.json') {
        return callback();
      }
      // Find path from src to the requested file
      const requestRelative = path.relative(appSrc, requestFullPath);
      // Error if in a parent directory of src/
      if (
        requestRelative.startsWith('../') || requestRelative.startsWith('..\\')
      ) {
        callback(
          new Error(
            `You attempted to import ${chalk.cyan(request.__innerRequest_request)} which falls outside of the project ${chalk.cyan('src/')} directory. ` +
              `Relative imports outside of ${chalk.cyan('src/')} are not supported. ` +
              `You can either move it inside ${chalk.cyan('src/')}, or add a symlink to it from project's ${chalk.cyan('node_modules/')}.`
          ),
          request
        );
      } else {
        callback();
      }
    });
  }
}

module.exports = ModuleScopePlugin;
<|endoftext|>


<commit_before>var chalk = require('chalk');
var execSync = require('child_process').execSync;
var path = require('path');

var execOptions = {
  encoding: 'utf8',
  stdio: [
    'pipe', // stdin (default)
    'pipe', // stdout (default)
    'ignore' //stderr
  ]
};

function isProcessAReactApp(processCommand) {
  return /^node .*react-scripts\/scripts\/start\.js\s?$/.test(processCommand);
}

function getProcessIdOnPort(port) {
  return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions).trim();
}

function getPackageNameInDirectory(directory) {
  var packagePath = path.join(directory.trim(), 'package.json');

  try {
    return require(packagePath).name;
  } catch(e) {
    return null;
  }

}

function getProcessCommand(processId, processDirectory) {
  var command = execSync('ps -o command -p ' + processId + ' | sed -n 2p', execOptions);

  if (isProcessAReactApp(command)) {
    const packageName = getPackageNameInDirectory(processDirectory);
    return (packageName) ? packageName + '\n' : command;
  } else {
    return command;
  }

}

function getDirectoryOfProcessById(processId) {
  return execSync('lsof -p '+ processId + ' | grep cwd | awk \'{print $9}\'', execOptions).trim();
}

function getProcessForPort(port) {
  try {
    var processId = getProcessIdOnPort(port);
    var directory = getDirectoryOfProcessById(processId);
    var command = getProcessCommand(processId, directory);
    return chalk.cyan(command) + chalk.blue('  in ') + chalk.cyan(directory);
  } catch(e) {
    return null;
  }
}

module.exports = getProcessForPort;

<commit_msg>Improve reliability of port hint. (#1696)<commit_after>var chalk = require('chalk');
var execSync = require('child_process').execSync;
var path = require('path');

var execOptions = {
  encoding: 'utf8',
  stdio: [
    'pipe', // stdin (default)
    'pipe', // stdout (default)
    'ignore' //stderr
  ]
};

function isProcessAReactApp(processCommand) {
  return /^node .*react-scripts\/scripts\/start\.js\s?$/.test(processCommand);
}

function getProcessIdOnPort(port) {
  return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions).trim();
}

function getPackageNameInDirectory(directory) {
  var packagePath = path.join(directory.trim(), 'package.json');

  try {
    return require(packagePath).name;
  } catch(e) {
    return null;
  }

}

function getProcessCommand(processId, processDirectory) {
  var command = execSync('ps -o command -p ' + processId + ' | sed -n 2p', execOptions);

  if (isProcessAReactApp(command)) {
    const packageName = getPackageNameInDirectory(processDirectory);
    return (packageName) ? packageName + '\n' : command;
  } else {
    return command;
  }

}

function getDirectoryOfProcessById(processId) {
  return execSync('lsof -p '+ processId + ' | awk \'$4=="cwd" {print $9}\'', execOptions).trim();
}

function getProcessForPort(port) {
  try {
    var processId = getProcessIdOnPort(port);
    var directory = getDirectoryOfProcessById(processId);
    var command = getProcessCommand(processId, directory);
    return chalk.cyan(command) + chalk.blue('  in ') + chalk.cyan(directory);
  } catch(e) {
    return null;
  }
}

module.exports = getProcessForPort;

<|endoftext|>