<commit_before>'use strict';

var playerPatterns = {};

//knigth
playerPatterns["0"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 300,
	bulletDamage: 3,
	bulletSpeed: 1000,
	bulletLifespan: 300,
	maxHealth: 270
	};

//elf
playerPatterns["1"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 400,
	bulletDamage: 5,
	bulletSpeed: 1500,
	bulletLifespan: 750,
	maxHealth: 220
	};

//mage
playerPatterns["2"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 500,
	bulletDamage: 10,
	bulletSpeed: 2000,
	bulletLifespan: 500,
	maxHealth: 120
	};

//viking
playerPatterns["3"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 350,
	bulletDamage: 4,
	bulletSpeed: 800,
	bulletLifespan: 400,
	maxHealth: 250
	};

//ninja
playerPatterns["4"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 150,
	bulletDamage: 3,
	bulletSpeed: 1600,
	bulletLifespan: 150,
	maxHealth: 200
	};

//warlock
playerPatterns["5"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 250,
	bulletDamage: 4,
	bulletSpeed: 900,
	bulletLifespan: 700,
	maxHealth: 160
	};

<commit_msg>baseMovementSpeed updated<commit_after>'use strict';

var playerPatterns = {};

//knigth
playerPatterns["0"] =
	{
	baseMovementSpeed: 210,
	baseFireRate: 300,
	bulletDamage: 3,
	bulletSpeed: 1000,
	bulletLifespan: 300,
	maxHealth: 270
	};

//elf
playerPatterns["1"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 400,
	bulletDamage: 5,
	bulletSpeed: 1500,
	bulletLifespan: 750,
	maxHealth: 220
	};

//mage
playerPatterns["2"] =
	{
	baseMovementSpeed: 200,
	baseFireRate: 500,
	bulletDamage: 10,
	bulletSpeed: 2000,
	bulletLifespan: 500,
	maxHealth: 120
	};

//viking
playerPatterns["3"] =
	{
	baseMovementSpeed: 180,
	baseFireRate: 350,
	bulletDamage: 4,
	bulletSpeed: 800,
	bulletLifespan: 400,
	maxHealth: 250
	};

//ninja
playerPatterns["4"] =
	{
	baseMovementSpeed: 250,
	baseFireRate: 150,
	bulletDamage: 3,
	bulletSpeed: 1600,
	bulletLifespan: 150,
	maxHealth: 200
	};

//warlock
playerPatterns["5"] =
	{
	baseMovementSpeed: 220,
	baseFireRate: 250,
	bulletDamage: 4,
	bulletSpeed: 900,
	bulletLifespan: 700,
	maxHealth: 160
	};

<|endoftext|>


<commit_before>if (typeof NCI === 'undefined')
   NCI = {};

NCI.start_time; // no data exists on the server before
NCI.time_adjustment = 0; //difference between client and server time in milliseconds

NCI.Connection = new WebSocket("ws://" + 'nci.ilabs.inca.infoblox.com:28080' + "/clientsock.yaws");
NCI.Connection.onopen = function () {
	console.log('opened');
	NCI.Connection.send('START_DATA');
};

NCI.Connection.onmessage  = function (e) {
	var data = eval("tmp = " + e.data );
	if (data.start_time){
	    NCI.time_adjustment = new Date() - new Date(data.current_time);
		return;
	};

	if (NCI.slider[0].value == 0){
		console.log(data);
		var params = {};
		params.time = new Date(data.Time).getMinutes() + ":" + new Date(data.Time).getSeconds();
		if (data.NCI){
			NCI.setNciLatestValue(NCI.parceNumberForView(data.NCI), NCI.parceDateForLastUpdate(data.Time));
			params.NCI = data.NCI;
			NCI.addValueToChart(params);
		};
		if (data.QPS)
			NCI.setQpsLatestValue(NCI.parceNumberForView(data.QPS), NCI.parceDateForLastUpdate(data.Time));
		if (data.NEP)
			NCI.setNepLatestValue(NCI.parceNumberForView(data.NEP), NCI.parceDateForLastUpdate(data.Time));
	} else if (e.data.length > 60){
		NCI.chartData = [];
		//we recieve such format:
		// {"Time":"2013-10-27T13:01:09Z","NCI":99,
		// "Time":"2013-10-27T13:11:39Z","NCI":8,
		// "Time":"2013-10-27T13:22:15Z","NCI":18,
		// "Time":"2013-10-27T13:33:01Z","NCI":87}
		var dimention = NCI.slider.xAxesScale[NCI.slider[0].value].indexDim;
		var recievedDataArray = e.data.substring(1, e.data.length - 1).split(',');
		var chartDataArray = [];
		for (var i = 0; i < recievedDataArray.length/2; i++){
			var curIndex = 2 * i;
			var timeValue = recievedDataArray[curIndex].substring(7);
			timeValue = timeValue.substring(1, timeValue.length - 1);
			var nciValue = recievedDataArray[curIndex + 1];
			nciValue = parseInt(nciValue.split(":")[1]);
			chartDataArray.push([NCI.parceDateWithDimention(timeValue, dimention), nciValue]);
		};
	    NCI.chart.series[0].data = chartDataArray;
		NCI.chart.resetAxesScale();
	    NCI.chart.replot( {data: [ chartDataArray]});
	};

};

NCI.Connection.onerror= function (e) {
	console.log('error ' + e.data);
};

NCI.Connection.onclose = function (e) {
	console.log('close ' + e.data);
};<commit_msg>Add dimentions to live data<commit_after>if (typeof NCI === 'undefined')
   NCI = {};

NCI.start_time; // no data exists on the server before
NCI.time_adjustment = 0; //difference between client and server time in milliseconds

NCI.Connection = new WebSocket("ws://" + 'nci.ilabs.inca.infoblox.com:28080' + "/clientsock.yaws");
NCI.Connection.onopen = function () {
	console.log('opened');
	NCI.Connection.send('START_DATA');
};

NCI.Connection.onmessage  = function (e) {
	var data = eval("tmp = " + e.data );
	if (data.start_time){
	    NCI.time_adjustment = new Date() - new Date(data.current_time);
		return;
	};

	if (NCI.slider[0].value == 0){
		console.log(data);
		var params = {};
		params.time = new Date(data.Time).getMinutes() + "m" + new Date(data.Time).getSeconds() + "s";
		if (data.NCI){
			NCI.setNciLatestValue(NCI.parceNumberForView(data.NCI), NCI.parceDateForLastUpdate(data.Time));
			params.NCI = data.NCI;
			NCI.addValueToChart(params);
		};
		if (data.QPS)
			NCI.setQpsLatestValue(NCI.parceNumberForView(data.QPS), NCI.parceDateForLastUpdate(data.Time));
		if (data.NEP)
			NCI.setNepLatestValue(NCI.parceNumberForView(data.NEP), NCI.parceDateForLastUpdate(data.Time));
	} else if (e.data.length > 60){
		NCI.chartData = [];
		//we recieve such format:
		// {"Time":"2013-10-27T13:01:09Z","NCI":99,
		// "Time":"2013-10-27T13:11:39Z","NCI":8,
		// "Time":"2013-10-27T13:22:15Z","NCI":18,
		// "Time":"2013-10-27T13:33:01Z","NCI":87}
		var dimention = NCI.slider.xAxesScale[NCI.slider[0].value].indexDim;
		var recievedDataArray = e.data.substring(1, e.data.length - 1).split(',');
		var chartDataArray = [];
		for (var i = 0; i < recievedDataArray.length/2; i++){
			var curIndex = 2 * i;
			var timeValue = recievedDataArray[curIndex].substring(7);
			timeValue = timeValue.substring(1, timeValue.length - 1);
			var nciValue = recievedDataArray[curIndex + 1];
			nciValue = parseInt(nciValue.split(":")[1]);
			chartDataArray.push([NCI.parceDateWithDimention(timeValue, dimention), nciValue]);
		};
	    NCI.chart.series[0].data = chartDataArray;
		NCI.chart.resetAxesScale();
	    NCI.chart.replot( {data: [ chartDataArray]});
	};

};

NCI.Connection.onerror= function (e) {
	console.log('error ' + e.data);
};

NCI.Connection.onclose = function (e) {
	console.log('close ' + e.data);
};<|endoftext|>


<commit_before>$(document).ready(function() {
    $('[data-toggle="tooltip"]').tooltip();
    $('.progress').css('overflow', 'inherit');
    $('.del_btn').click(function() {
        return confirm("Are you sure you want to delete?");
    });
    $('.rejudge-btn').click(function() {
        var submission = $(this).attr('data-submission');
        return confirm("\
		The problem has " + submission + " submissions\n\
		Rejudge might take a long time\n\
		Are you sure to rejudge?");
    });
});
<commit_msg>force enter submission number<commit_after>$(document).ready(function() {
    $('[data-toggle="tooltip"]').tooltip();
    $('.progress').css('overflow', 'inherit');
    $('.del_btn').click(function() {
        return confirm("Are you sure you want to delete?");
    });
    $('.rejudge-btn').click(function() {
        var submission = $(this).attr('data-submission');
        var check = prompt("\
		The problem has " + submission + " submissions\n\
		Rejudge might take a long time\n\
		Enter the submission number of this problem to continue");
	return check == submission;
    });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
//@flow

// we only enable source maps while developing, since
// they have a small performance hit. for this, we
// look for `pkg`, which is only present in the final bin
// $FlowFixMe
if (!process.pkg) {
  require('@zeit/source-map-support').install();
}

// fix for EPIPE when piping to a truncated pipe
require('epipebomb')()

// Native
const { join } = require('path')

// Packages
const debug = require('debug')('now:main')
const { existsSync } = require('fs-extra')
const mkdirp = require('mkdirp-promise')
const mri = require('mri')
const fetch = require('node-fetch')
const chalk = require('chalk')
const updateNotifier = require('@zeit/check-updates')

// Utilities
const error = require('./util/output/error')
const param = require('./util/output/param')
const info = require('./util/output/info')
const getNowDir = require('./config/global-path')
const getDefaultCfg = require('./get-default-cfg')
const getDefaultAuthCfg = require('./get-default-auth-cfg')
const hp = require('./util/humanize-path')
const providers = require('./providers')
const configFiles = require('./util/config-files')
const getUser = require('./util/get-user')
const pkg = require('./util/pkg')

const NOW_DIR = getNowDir()
const NOW_CONFIG_PATH = configFiles.getConfigFilePath()
const NOW_AUTH_CONFIG_PATH = configFiles.getAuthConfigFilePath()

const GLOBAL_COMMANDS = new Set(['help'])

const main = async (argv_) => {
  updateNotifier(pkg, 'Now CLI')

  const argv = mri(argv_, {
    boolean: [
      'help',
      'version'
    ],
    string: [
      'token',
      'team',
      'api'
    ],
    alias: {
      help: 'h',
      version: 'v',
      token: 't',
      team: 'T'
    }
  })

  // the second argument to the command can be a path
  // (as in: `now path/`) or a subcommand / provider
  // (as in: `now ls` or `now aws help`)
  let targetOrSubcommand: ?string = argv._[2]

  // we want to handle version or help directly only
  if (!targetOrSubcommand) {
    if (argv.version) {
      console.log(require('../package').version + ` ${
        // $FlowFixMe
        process.pkg ? '' : chalk.magenta('(dev)')
      }`)
      return 0
    }
  }

  let nowDirExists

  try {
    nowDirExists = existsSync(NOW_DIR)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          'now global directory: ' +
          err.message
      )
    )

    return 1;
  }

  if (!nowDirExists) {
    try {
      await mkdirp(NOW_DIR)
    } catch (err) {
      console.error(error(
        'An unexpected error occurred while trying to create the ' +
          `now global directory "${hp(NOW_DIR)}" ` +
          err.message
      ))
    }
  }

  let migrated = false
  let configExists

  try {
    configExists = existsSync(NOW_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now config file "${hp(NOW_CONFIG_PATH)}" ` +
          err.message
      )
    )

    return 0;
  }

  let config

  if (configExists) {
    try {
      config = configFiles.readConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now config in "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )

      return 1;
    }
  } else {
    const results = await getDefaultCfg()

    config = results.config
    migrated = results.migrated

    try {
      configFiles.writeToConfigFile(config)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )

      return 1;
    }
  }

  let authConfigExists

  try {
    authConfigExists = existsSync(NOW_AUTH_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now auth file "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
          err.message
      )
    )

    return 1;
  }

  let authConfig = null

  if (authConfigExists) {
    try {
      authConfig = configFiles.readAuthConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now auth config in "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
            err.message
        )
      )

      return 1;
    }

    if (!Array.isArray(authConfig.credentials)) {
      console.error(
        error(
          `The content of "${hp(NOW_AUTH_CONFIG_PATH)}" is invalid. ` +
            'No `credentials` list found inside'
        )
      )
      return 1;
    }

    for (const [i, { provider }] of authConfig.credentials.entries()) {
      if (null == provider) {
        console.error(
          error(
            `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
              `Missing \`provider\` key in entry with index ${i}`
          )
        )
        return 1;
      }

      if (!(provider in providers)) {
        console.error(
          error(
            `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
              `Unknown provider "${provider}"`
          )
        )
        return 1;
      }
    }
  } else {
    const results = await getDefaultAuthCfg()

    authConfig = results.config
    migrated = results.migrated

    try {
      configFiles.writeToAuthConfigFile(authConfig)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return 1;
    }
  }

  // Let the user know we migrated the config
  if (migrated) {
    const directory = param(hp(NOW_DIR))
    console.log(info(`Your credentials and configuration were migrated to ${directory}`))
  }

  // the context object to supply to the providers or the commands
  const ctx: Object = {
    config,
    authConfig,
    argv: argv_
  }

  if (targetOrSubcommand === 'config') {
    const _config = require('./config')
    const subcommand = _config.subcommands.has(argv._[3]) ? argv._[3] : 'help'

    debug(`executing config %s`, subcommand)

    try {
      return _config[subcommand](ctx)
    } catch (err) {
      console.error(
        error(
          `An unexpected error occurred in config ${subcommand}: ${err.stack}`
        )
      )
      return 1;
    }
  }

  let suppliedProvider = null

  // if the target is something like `aws`
  if (targetOrSubcommand && targetOrSubcommand in providers) {
    debug('user supplied a known provider')
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    if (targetPathExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a provider are known'
        )
      )
      return 1;
    }

    suppliedProvider = targetOrSubcommand
    targetOrSubcommand = argv._[3]
  }

  // $FlowFixMe
  let { defaultProvider = null }: { defaultProvider: ?string } = config

  if (null === suppliedProvider) {
    if (null === defaultProvider) {
      debug(`falling back to default now provider 'sh'`)
      defaultProvider = 'sh'
    } else {
      debug('using provider supplied by user', defaultProvider)

      if (!(defaultProvider in providers)) {
        console.error(
          error(
            `The \`defaultProvider\` "${defaultProvider}" supplied in ` +
              `"${NOW_CONFIG_PATH}" is not a valid provider`
          )
        )
        return 1;
      }
    }
  }

  const providerName = suppliedProvider || defaultProvider
  const provider: Object = providers[providerName]

  let subcommand

  // we check if we are deploying something
  if (targetOrSubcommand) {
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    const subcommandExists =
      GLOBAL_COMMANDS.has(targetOrSubcommand) ||
      provider.subcommands.has(targetOrSubcommand)

    if (targetPathExists && subcommandExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a subcommand are known'
        )
      )
      return 1;
    }

    if (subcommandExists) {
      debug('user supplied known subcommand', targetOrSubcommand)
      subcommand = targetOrSubcommand
    } else {
      debug('user supplied a possible target for deployment')
      // our default command is deployment
      // at this point we're
      subcommand = 'deploy'
    }
  } else {
    debug('user supplied no target, defaulting to deploy')
    subcommand = 'deploy'
  }

  if (subcommand === 'help') {
    subcommand = argv._[3] || 'deploy'
    ctx.argv.push('-h')
  }

  const { sh } = ctx.config
  ctx.apiUrl = 'https://api.zeit.co'

  if (argv.api && typeof argv.api === 'string') {
    ctx.apiUrl = argv.api
  } else if (sh && sh.api) {
    ctx.apiUrl = sh.api
  }

  const localConfig = configFiles.readLocalConfig()

  if (localConfig) {
    if (localConfig.api) {
      ctx.apiUrl = localConfig.api
      delete localConfig.api
    }

    Object.assign(ctx.config, localConfig)
  }

  // $FlowFixMe
  const { isTTY } = process.stdout

  // If no credentials are set at all, prompt for
  // login to the .sh provider
  if (
    !authConfig.credentials.length &&
    !ctx.argv.includes('-h') && !ctx.argv.includes('--help') &&
    !argv.token &&
    subcommand !== 'login'
  ) {
    if (isTTY) {
      console.log(info(`No existing credentials found. Please log in:`))

      subcommand = 'login'
      ctx.argv[2] = 'login'

      // Ensure that sub commands lead to login as well, if
      // no credentials are defined
      ctx.argv = ctx.argv.splice(0, 3)
    } else {
      console.error(error({
        message: 'No existing credentials found. Please run ' +
        `${param('now login')} or pass ${param('--token')}`,
        slug: 'no-credentials-found'
      }))

      return 1;
    }
  }

  if (typeof argv.token === 'string' && subcommand === 'switch') {
    console.error(error({
      message: `This command doesn't work with ${param('--token')}. Please use ${param('--team')}.`,
      slug: 'no-token-allowed'
    }))

    return 1;
  }

  if (typeof argv.token === 'string') {
    const {token} = argv

    if (token.length === 0) {
      console.error(error({
        message: `You defined ${param('--token')}, but it's missing a value`,
        slug: 'missing-token-value'
      }))

      return 1;
    }

    const obj = {
      provider: 'sh',
      token
    }

    const credentialsIndex = ctx.authConfig.credentials.findIndex(
      cred => cred.provider === 'sh'
    )

    if (credentialsIndex === -1) {
      ctx.authConfig.credentials.push(obj)
    } else {
      ctx.authConfig.credentials[credentialsIndex] = obj
    }

    let user

    try {
      user = await getUser({
        apiUrl: ctx.apiUrl,
        token
      })
    } catch (err) {
      console.error(error(err))
      return 1;
    }

    // Don't use team from config if `--token` was set
    if (ctx.config.sh && ctx.config.sh.currentTeam) {
      delete ctx.config.sh.currentTeam
    }

    ctx.config.sh = Object.assign(ctx.config.sh || {}, { user })
  }

  if (typeof argv.team === 'string' && subcommand !== 'login') {
    const { team } = argv
    const { sh } = ctx.config

    if (team.length === 0) {
      console.error(error({
        message: `You defined ${param('--team')}, but it's missing a value`,
        slug: 'missing-team-value'
      }))

      return 1;
    }

    const cachedUser = sh && sh.user && sh.user.username === team

    if (cachedUser) {
      delete ctx.config.sh.currentTeam
    }

    const cachedTeam = sh && sh.currentTeam && sh.currentTeam.slug === team

    // Only download team data if not cached
    if (!cachedTeam && !cachedUser) {
      const { token } = ctx.authConfig.credentials.find(item => item.provider === 'sh')

      const headers = {
        Authorization: `Bearer ${token}`
      }

      const url = `https://api.zeit.co/teams/?slug=${team}`
      let body

      try {
        const res = await fetch(url, { headers })

        if (res.status === 403) {
          console.error(error({
            message: `You don't have access to the specified team`,
            slug: 'team-not-accessible'
          }))

          return 1;
        }

        body = await res.json()
      } catch (err) {
        console.error(error('Not able to load teams'))
        return 1;
      }

      if (!body || body.error) {
        console.error(error({
          message: 'The specified team doesn\'t exist',
          slug: 'team-not-existent'
        }))

        return 1;
      }

      // $FlowFixMe
      delete body.creator_id

      // $FlowFixMe
      delete body.created

      ctx.config.sh.currentTeam = body
    }
  }

  let exitCode;

  try {
    exitCode = await provider[subcommand](ctx);
  } catch (err) {
    console.error(
      error(
        `An unexpected error occurred in ${subcommand}: ${err.stack}`
      )
    )
    return 1;
  }

  return exitCode;
}

debug('start')

const handleRejection = err => {
  debug('handling rejection')

  if (err) {
    if (err instanceof Error) {
      handleUnexpected(err)
    } else {
      console.error(error(`An unexpected rejection occurred\n  ${err}`))
    }
  } else {
    console.error(error('An unexpected empty rejection occurred'))
  }

  process.exit(1)
}

const handleUnexpected = err => {
  debug('handling unexpected error')

  console.error(
    error(`An unexpected error occurred!\n  ${err.stack} ${err.stack}`)
  )

  process.exit(1)
}

process.on('unhandledRejection', handleRejection)
process.on('uncaughtException', handleUnexpected)

// Don't use `.then` here. We need to shutdown gracefully, otherwise
// sub commands waiting for further data won't work (like `logs` and `logout`)!
main(process.argv)
  .then(exitCode => {
    process.emit('nowExit');
    process.on('beforeExit', () => {
      process.exit(exitCode);
    })
  })
  .catch(handleUnexpected)
<commit_msg>Remove version trailin space (#1236)<commit_after>#!/usr/bin/env node
//@flow

// we only enable source maps while developing, since
// they have a small performance hit. for this, we
// look for `pkg`, which is only present in the final bin
// $FlowFixMe
if (!process.pkg) {
  require('@zeit/source-map-support').install();
}

// fix for EPIPE when piping to a truncated pipe
require('epipebomb')()

// Native
const { join } = require('path')

// Packages
const debug = require('debug')('now:main')
const { existsSync } = require('fs-extra')
const mkdirp = require('mkdirp-promise')
const mri = require('mri')
const fetch = require('node-fetch')
const chalk = require('chalk')
const updateNotifier = require('@zeit/check-updates')

// Utilities
const error = require('./util/output/error')
const param = require('./util/output/param')
const info = require('./util/output/info')
const getNowDir = require('./config/global-path')
const getDefaultCfg = require('./get-default-cfg')
const getDefaultAuthCfg = require('./get-default-auth-cfg')
const hp = require('./util/humanize-path')
const providers = require('./providers')
const configFiles = require('./util/config-files')
const getUser = require('./util/get-user')
const pkg = require('./util/pkg')

const NOW_DIR = getNowDir()
const NOW_CONFIG_PATH = configFiles.getConfigFilePath()
const NOW_AUTH_CONFIG_PATH = configFiles.getAuthConfigFilePath()

const GLOBAL_COMMANDS = new Set(['help'])

const main = async (argv_) => {
  updateNotifier(pkg, 'Now CLI')

  const argv = mri(argv_, {
    boolean: [
      'help',
      'version'
    ],
    string: [
      'token',
      'team',
      'api'
    ],
    alias: {
      help: 'h',
      version: 'v',
      token: 't',
      team: 'T'
    }
  })

  // the second argument to the command can be a path
  // (as in: `now path/`) or a subcommand / provider
  // (as in: `now ls` or `now aws help`)
  let targetOrSubcommand: ?string = argv._[2]

  // we want to handle version or help directly only
  if (!targetOrSubcommand) {
    if (argv.version) {
      console.log(require('../package').version + `${
        // $FlowFixMe
        process.pkg ? '' : chalk.magenta(' (dev)')
      }`)
      return 0
    }
  }

  let nowDirExists

  try {
    nowDirExists = existsSync(NOW_DIR)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          'now global directory: ' +
          err.message
      )
    )

    return 1;
  }

  if (!nowDirExists) {
    try {
      await mkdirp(NOW_DIR)
    } catch (err) {
      console.error(error(
        'An unexpected error occurred while trying to create the ' +
          `now global directory "${hp(NOW_DIR)}" ` +
          err.message
      ))
    }
  }

  let migrated = false
  let configExists

  try {
    configExists = existsSync(NOW_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now config file "${hp(NOW_CONFIG_PATH)}" ` +
          err.message
      )
    )

    return 0;
  }

  let config

  if (configExists) {
    try {
      config = configFiles.readConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now config in "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )

      return 1;
    }
  } else {
    const results = await getDefaultCfg()

    config = results.config
    migrated = results.migrated

    try {
      configFiles.writeToConfigFile(config)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )

      return 1;
    }
  }

  let authConfigExists

  try {
    authConfigExists = existsSync(NOW_AUTH_CONFIG_PATH)
  } catch (err) {
    console.error(
      error(
        'An unexpected error occurred while trying to find the ' +
          `now auth file "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
          err.message
      )
    )

    return 1;
  }

  let authConfig = null

  if (authConfigExists) {
    try {
      authConfig = configFiles.readAuthConfigFile()
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to read the ' +
            `now auth config in "${hp(NOW_AUTH_CONFIG_PATH)}" ` +
            err.message
        )
      )

      return 1;
    }

    if (!Array.isArray(authConfig.credentials)) {
      console.error(
        error(
          `The content of "${hp(NOW_AUTH_CONFIG_PATH)}" is invalid. ` +
            'No `credentials` list found inside'
        )
      )
      return 1;
    }

    for (const [i, { provider }] of authConfig.credentials.entries()) {
      if (null == provider) {
        console.error(
          error(
            `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
              `Missing \`provider\` key in entry with index ${i}`
          )
        )
        return 1;
      }

      if (!(provider in providers)) {
        console.error(
          error(
            `Invalid credential found in "${hp(NOW_AUTH_CONFIG_PATH)}". ` +
              `Unknown provider "${provider}"`
          )
        )
        return 1;
      }
    }
  } else {
    const results = await getDefaultAuthCfg()

    authConfig = results.config
    migrated = results.migrated

    try {
      configFiles.writeToAuthConfigFile(authConfig)
    } catch (err) {
      console.error(
        error(
          'An unexpected error occurred while trying to write the ' +
            `default now config to "${hp(NOW_CONFIG_PATH)}" ` +
            err.message
        )
      )
      return 1;
    }
  }

  // Let the user know we migrated the config
  if (migrated) {
    const directory = param(hp(NOW_DIR))
    console.log(info(`Your credentials and configuration were migrated to ${directory}`))
  }

  // the context object to supply to the providers or the commands
  const ctx: Object = {
    config,
    authConfig,
    argv: argv_
  }

  if (targetOrSubcommand === 'config') {
    const _config = require('./config')
    const subcommand = _config.subcommands.has(argv._[3]) ? argv._[3] : 'help'

    debug(`executing config %s`, subcommand)

    try {
      return _config[subcommand](ctx)
    } catch (err) {
      console.error(
        error(
          `An unexpected error occurred in config ${subcommand}: ${err.stack}`
        )
      )
      return 1;
    }
  }

  let suppliedProvider = null

  // if the target is something like `aws`
  if (targetOrSubcommand && targetOrSubcommand in providers) {
    debug('user supplied a known provider')
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    if (targetPathExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a provider are known'
        )
      )
      return 1;
    }

    suppliedProvider = targetOrSubcommand
    targetOrSubcommand = argv._[3]
  }

  // $FlowFixMe
  let { defaultProvider = null }: { defaultProvider: ?string } = config

  if (null === suppliedProvider) {
    if (null === defaultProvider) {
      debug(`falling back to default now provider 'sh'`)
      defaultProvider = 'sh'
    } else {
      debug('using provider supplied by user', defaultProvider)

      if (!(defaultProvider in providers)) {
        console.error(
          error(
            `The \`defaultProvider\` "${defaultProvider}" supplied in ` +
              `"${NOW_CONFIG_PATH}" is not a valid provider`
          )
        )
        return 1;
      }
    }
  }

  const providerName = suppliedProvider || defaultProvider
  const provider: Object = providers[providerName]

  let subcommand

  // we check if we are deploying something
  if (targetOrSubcommand) {
    const targetPath = join(process.cwd(), targetOrSubcommand)
    const targetPathExists = existsSync(targetPath)

    const subcommandExists =
      GLOBAL_COMMANDS.has(targetOrSubcommand) ||
      provider.subcommands.has(targetOrSubcommand)

    if (targetPathExists && subcommandExists) {
      console.error(
        error(
          `The supplied argument ${param(targetOrSubcommand)} is ambiguous. ` +
            'Both a directory and a subcommand are known'
        )
      )
      return 1;
    }

    if (subcommandExists) {
      debug('user supplied known subcommand', targetOrSubcommand)
      subcommand = targetOrSubcommand
    } else {
      debug('user supplied a possible target for deployment')
      // our default command is deployment
      // at this point we're
      subcommand = 'deploy'
    }
  } else {
    debug('user supplied no target, defaulting to deploy')
    subcommand = 'deploy'
  }

  if (subcommand === 'help') {
    subcommand = argv._[3] || 'deploy'
    ctx.argv.push('-h')
  }

  const { sh } = ctx.config
  ctx.apiUrl = 'https://api.zeit.co'

  if (argv.api && typeof argv.api === 'string') {
    ctx.apiUrl = argv.api
  } else if (sh && sh.api) {
    ctx.apiUrl = sh.api
  }

  const localConfig = configFiles.readLocalConfig()

  if (localConfig) {
    if (localConfig.api) {
      ctx.apiUrl = localConfig.api
      delete localConfig.api
    }

    Object.assign(ctx.config, localConfig)
  }

  // $FlowFixMe
  const { isTTY } = process.stdout

  // If no credentials are set at all, prompt for
  // login to the .sh provider
  if (
    !authConfig.credentials.length &&
    !ctx.argv.includes('-h') && !ctx.argv.includes('--help') &&
    !argv.token &&
    subcommand !== 'login'
  ) {
    if (isTTY) {
      console.log(info(`No existing credentials found. Please log in:`))

      subcommand = 'login'
      ctx.argv[2] = 'login'

      // Ensure that sub commands lead to login as well, if
      // no credentials are defined
      ctx.argv = ctx.argv.splice(0, 3)
    } else {
      console.error(error({
        message: 'No existing credentials found. Please run ' +
        `${param('now login')} or pass ${param('--token')}`,
        slug: 'no-credentials-found'
      }))

      return 1;
    }
  }

  if (typeof argv.token === 'string' && subcommand === 'switch') {
    console.error(error({
      message: `This command doesn't work with ${param('--token')}. Please use ${param('--team')}.`,
      slug: 'no-token-allowed'
    }))

    return 1;
  }

  if (typeof argv.token === 'string') {
    const {token} = argv

    if (token.length === 0) {
      console.error(error({
        message: `You defined ${param('--token')}, but it's missing a value`,
        slug: 'missing-token-value'
      }))

      return 1;
    }

    const obj = {
      provider: 'sh',
      token
    }

    const credentialsIndex = ctx.authConfig.credentials.findIndex(
      cred => cred.provider === 'sh'
    )

    if (credentialsIndex === -1) {
      ctx.authConfig.credentials.push(obj)
    } else {
      ctx.authConfig.credentials[credentialsIndex] = obj
    }

    let user

    try {
      user = await getUser({
        apiUrl: ctx.apiUrl,
        token
      })
    } catch (err) {
      console.error(error(err))
      return 1;
    }

    // Don't use team from config if `--token` was set
    if (ctx.config.sh && ctx.config.sh.currentTeam) {
      delete ctx.config.sh.currentTeam
    }

    ctx.config.sh = Object.assign(ctx.config.sh || {}, { user })
  }

  if (typeof argv.team === 'string' && subcommand !== 'login') {
    const { team } = argv
    const { sh } = ctx.config

    if (team.length === 0) {
      console.error(error({
        message: `You defined ${param('--team')}, but it's missing a value`,
        slug: 'missing-team-value'
      }))

      return 1;
    }

    const cachedUser = sh && sh.user && sh.user.username === team

    if (cachedUser) {
      delete ctx.config.sh.currentTeam
    }

    const cachedTeam = sh && sh.currentTeam && sh.currentTeam.slug === team

    // Only download team data if not cached
    if (!cachedTeam && !cachedUser) {
      const { token } = ctx.authConfig.credentials.find(item => item.provider === 'sh')

      const headers = {
        Authorization: `Bearer ${token}`
      }

      const url = `https://api.zeit.co/teams/?slug=${team}`
      let body

      try {
        const res = await fetch(url, { headers })

        if (res.status === 403) {
          console.error(error({
            message: `You don't have access to the specified team`,
            slug: 'team-not-accessible'
          }))

          return 1;
        }

        body = await res.json()
      } catch (err) {
        console.error(error('Not able to load teams'))
        return 1;
      }

      if (!body || body.error) {
        console.error(error({
          message: 'The specified team doesn\'t exist',
          slug: 'team-not-existent'
        }))

        return 1;
      }

      // $FlowFixMe
      delete body.creator_id

      // $FlowFixMe
      delete body.created

      ctx.config.sh.currentTeam = body
    }
  }

  let exitCode;

  try {
    exitCode = await provider[subcommand](ctx);
  } catch (err) {
    console.error(
      error(
        `An unexpected error occurred in ${subcommand}: ${err.stack}`
      )
    )
    return 1;
  }

  return exitCode;
}

debug('start')

const handleRejection = err => {
  debug('handling rejection')

  if (err) {
    if (err instanceof Error) {
      handleUnexpected(err)
    } else {
      console.error(error(`An unexpected rejection occurred\n  ${err}`))
    }
  } else {
    console.error(error('An unexpected empty rejection occurred'))
  }

  process.exit(1)
}

const handleUnexpected = err => {
  debug('handling unexpected error')

  console.error(
    error(`An unexpected error occurred!\n  ${err.stack} ${err.stack}`)
  )

  process.exit(1)
}

process.on('unhandledRejection', handleRejection)
process.on('uncaughtException', handleUnexpected)

// Don't use `.then` here. We need to shutdown gracefully, otherwise
// sub commands waiting for further data won't work (like `logs` and `logout`)!
main(process.argv)
  .then(exitCode => {
    process.emit('nowExit');
    process.on('beforeExit', () => {
      process.exit(exitCode);
    })
  })
  .catch(handleUnexpected)
<|endoftext|>


<commit_before>/**
 * Created by mingming on 17-3-8.
 */

jQuery(document).ready(function($)
{
    /* Global Settings */

    // Progress Bar
    var opts = {
        "closeButton": true,
        "debug": false,
        "positionClass": "toast-top-right",
        "onclick": null,
        "showDuration": "500",
        "hideDuration": "1000",
        "timeOut": "5000",
        "extendedTimeOut": "1000",
        "showEasing": "swing",
        "hideEasing": "linear",
        "showMethod": "fadeIn",
        "hideMethod": "fadeOut"
    };

    //Edit Project
    function editProject(data) {
            $.ajax({
            url: "/dashboard/api/edit",
            method: 'POST',
            dataType: 'json',
            data: data,
            success: function(resp) {
                show_loading_bar({
                    delay: .5,
                    pct: 100,
                    finish: function () {
                        // Redirect after successful login page (when progress bar reaches 100%)
                        if (resp.status == true) {
                            toastr.success(resp.message, "Message:", opts);
                            setTimeout(function(){ window.location.reload();},600);
                        }
                        else {
                            // alert(resp.reason);
                            toastr.error(resp.message, "Message:", opts);
                        }
                    }
                });
            },
            error: function(resp) {
                            show_loading_bar({
                                delay: .5,
                                pct: 100,
                                finish: function () {
                                    toastr.error("Network error.", "Message:", opts);
                                }
                            });
                        }
        });

    }

    // Create Project
    function createProject(data) {
        $.ajax({
                url: "/dashboard/api/create",
                method: 'POST',
                dataType: 'json',
                data: data,
                success: function(resp) {
                    show_loading_bar({
                        delay: .5,
                        pct: 100,
                        finish: function () {
                            // Redirect after successful login page (when progress bar reaches 100%)
                            if (resp.status == true) {
                                toastr.success(resp.message, "Message:", opts);
                                setTimeout(function(){ window.location.href = '/dashboard/debug/'+name;}, 600);
                            }
                            else {
                                // alert(resp.reason);
                                toastr.error(resp.message, "Message:", opts);
                            }
                        }
                    });
                },
                error: function(resp) {
                                show_loading_bar({
                                    delay: .5,
                                    pct: 100,
                                    finish: function () {
                                        toastr.error("Network error.", "Message:", opts);
                                    }
                                });
                            }
            });

    }

    /* Index page */

    // Edit Page
    $('.edit-btn').click(function () {

        var tds = $(this).closest("tr").find("td");
        var group = tds.eq(0).text();
        var name = tds.eq(1).text().trim();
        var status = tds.eq(2).find('span').attr("value");
        var interval = tds.eq(3).text();
        var number = tds.eq(4).text();
        var ip_limit = tds.eq(5).text();

        $("#field-1").attr("placeholder", group).val('');
        $("#field-2").attr("placeholder", name).val('');
        $("#field-3").attr("placeholder", null).val('');
        $("#field-4").attr("placeholder", interval).val('');
        $("#field-5").attr("placeholder", number).val('');
        $("#field-6").attr("placeholder", ip_limit).val('');
        $("#field-7").attr("value", status);
        $("#field-7").find("input").eq(status).prop("checked",true);

        // Styles
        $('input.icheck-11').iCheck({
            checkboxClass: 'icheckbox_square-blue',
            radioClass: 'iradio_square-pink'
        });

        // Edit Page Show
        $("#edit-page").modal('show', {backdrop: 'static'});
    });

    // Edit Submit
    $('.edit-save').click(function () {

        var flag = null;
        var inputs = $("#edit-page").find("input");
        var group = inputs.eq(0).val();
        var name = inputs.eq(1).attr('placeholder');
        var interval = inputs.eq(2).val();
        var number = inputs.eq(3).val();
        var ip_limit = inputs.eq(4).val();
        var status = $("#field-7").attr("value");
        var data = {
            command: true,
            project: name
        };
        $("#field-7 input").each(function(){

            if($(this).prop('checked')){
                var _status = $(this).attr("value");
                if(_status===status){
                    console.log(_status);
                }
                else{
                    data["status"]=_status;
                    flag = true;
                }
            }
            else{
            }
          });

        if(group){
            data['group']=group;
            flag = true
        }

        if(interval){
            data['interval']=interval;
            flag = true
        }

        if(number){
            data['number']=number;
            flag = true
        }

        if(ip_limit){
            data['ip_limit']=ip_limit;
            flag = true
        }

        // Save Edit
        if(flag){
            editProject(data);
        }
        else{
            toastr.warning("No parameters changed.", "Message:", opts);
        }
    });

    /*
    function showAjaxModal()
			{
				jQuery('#modal-7').modal('show', {backdrop: 'static'});

//				jQuery.ajax({
//					url: "data/ajax-content.txt",
//					success: function(response)
//					{
//						jQuery('#modal-7 .modal-body').html(response);
//					}
//				});
			}*/

    // Create Page
    $('.create-btn').click(function () {
        // Edit Page Show
        $("#create-page").modal('show', {backdrop: 'static'});
    });

    // Create Save
    $('.create-save').click(function () {

        var inputs = $("#create-page").find("input");
        var name = inputs.eq(0).val();
        var url = inputs.eq(1).val();

        var data = {
            command: true,
            project: name,
            url: url
        };
        console.log(data);

        if(/^[a-zA-Z]+$/.test(name)){
            createProject(data);
        }
        else{
            toastr.warning("Project name is invalid. Must be a-Z", "Message:", opts);
        }
    });

});

<commit_msg>Modified Create href<commit_after>/**
 * Created by mingming on 17-3-8.
 */

jQuery(document).ready(function($)
{
    /* Global Settings */

    // Progress Bar
    var opts = {
        "closeButton": true,
        "debug": false,
        "positionClass": "toast-top-right",
        "onclick": null,
        "showDuration": "500",
        "hideDuration": "1000",
        "timeOut": "5000",
        "extendedTimeOut": "1000",
        "showEasing": "swing",
        "hideEasing": "linear",
        "showMethod": "fadeIn",
        "hideMethod": "fadeOut"
    };

    //Edit Project
    function editProject(data) {
            $.ajax({
            url: "/dashboard/api/edit",
            method: 'POST',
            dataType: 'json',
            data: data,
            success: function(resp) {
                show_loading_bar({
                    delay: .5,
                    pct: 100,
                    finish: function () {
                        // Redirect after successful login page (when progress bar reaches 100%)
                        if (resp.status == true) {
                            toastr.success(resp.message, "Message:", opts);
                            setTimeout(function(){ window.location.reload();},600);
                        }
                        else {
                            // alert(resp.reason);
                            toastr.error(resp.message, "Message:", opts);
                        }
                    }
                });
            },
            error: function(resp) {
                            show_loading_bar({
                                delay: .5,
                                pct: 100,
                                finish: function () {
                                    toastr.error("Network error.", "Message:", opts);
                                }
                            });
                        }
        });

    }

    // Create Project
    function createProject(data) {
        $.ajax({
                url: "/dashboard/api/create",
                method: 'POST',
                dataType: 'json',
                data: data,
                success: function(resp) {
                    show_loading_bar({
                        delay: .5,
                        pct: 100,
                        finish: function () {
                            // Redirect after successful login page (when progress bar reaches 100%)
                            if (resp.status == true) {
                                toastr.success(resp.message, "Message:", opts);
                                setTimeout(function(){ window.location.href = '/dashboard/debug/'+data.project;}, 600);
                            }
                            else {
                                // alert(resp.reason);
                                toastr.error(resp.message, "Message:", opts);
                            }
                        }
                    });
                },
                error: function(resp) {
                                show_loading_bar({
                                    delay: .5,
                                    pct: 100,
                                    finish: function () {
                                        toastr.error("Network error.", "Message:", opts);
                                    }
                                });
                            }
            });

    }

    /* Index page */

    // Edit Page
    $('.edit-btn').click(function () {

        var tds = $(this).closest("tr").find("td");
        var group = tds.eq(0).text();
        var name = tds.eq(1).text().trim();
        var status = tds.eq(2).find('span').attr("value");
        var interval = tds.eq(3).text();
        var number = tds.eq(4).text();
        var ip_limit = tds.eq(5).text();

        $("#field-1").attr("placeholder", group).val('');
        $("#field-2").attr("placeholder", name).val('');
        $("#field-3").attr("placeholder", null).val('');
        $("#field-4").attr("placeholder", interval).val('');
        $("#field-5").attr("placeholder", number).val('');
        $("#field-6").attr("placeholder", ip_limit).val('');
        $("#field-7").attr("value", status);
        $("#field-7").find("input").eq(status).prop("checked",true);

        // Styles
        $('input.icheck-11').iCheck({
            checkboxClass: 'icheckbox_square-blue',
            radioClass: 'iradio_square-pink'
        });

        // Edit Page Show
        $("#edit-page").modal('show', {backdrop: 'static'});
    });

    // Edit Submit
    $('.edit-save').click(function () {

        var flag = null;
        var inputs = $("#edit-page").find("input");
        var group = inputs.eq(0).val();
        var name = inputs.eq(1).attr('placeholder');
        var interval = inputs.eq(2).val();
        var number = inputs.eq(3).val();
        var ip_limit = inputs.eq(4).val();
        var status = $("#field-7").attr("value");
        var data = {
            command: true,
            project: name
        };
        $("#field-7 input").each(function(){

            if($(this).prop('checked')){
                var _status = $(this).attr("value");
                if(_status===status){
                    console.log(_status);
                }
                else{
                    data["status"]=_status;
                    flag = true;
                }
            }
            else{
            }
          });

        if(group){
            data['group']=group;
            flag = true
        }

        if(interval){
            data['interval']=interval;
            flag = true
        }

        if(number){
            data['number']=number;
            flag = true
        }

        if(ip_limit){
            data['ip_limit']=ip_limit;
            flag = true
        }

        // Save Edit
        if(flag){
            editProject(data);
        }
        else{
            toastr.warning("No parameters changed.", "Message:", opts);
        }
    });

    /*
    function showAjaxModal()
			{
				jQuery('#modal-7').modal('show', {backdrop: 'static'});

//				jQuery.ajax({
//					url: "data/ajax-content.txt",
//					success: function(response)
//					{
//						jQuery('#modal-7 .modal-body').html(response);
//					}
//				});
			}*/

    // Create Page
    $('.create-btn').click(function () {
        // Edit Page Show
        $("#create-page").modal('show', {backdrop: 'static'});
    });

    // Create Save
    $('.create-save').click(function () {

        var inputs = $("#create-page").find("input");
        var name = inputs.eq(0).val();
        var url = inputs.eq(1).val();

        var data = {
            command: true,
            project: name,
            url: url
        };
        console.log(data);

        if(/^[a-zA-Z]+$/.test(name)){
            createProject(data);
        }
        else{
            toastr.warning("Project name is invalid. Must be a-Z", "Message:", opts);
        }
    });

});

<|endoftext|>


<commit_before>import Webiny from 'Webiny';
const Ui = Webiny.Ui.Components;
import Validator from './../Validation/Validator';

class Form extends Webiny.Ui.Component {

    constructor(props) {
        super(props);

        this.state = {
            model: {}
        };

        this.$isValid = null;
        this.fields = [];
        this.actions = [];
        this.layout = null;
        this.watches = {};

        this.bindMethods(
            'submit',
            'reset',
            'cancel',
            'attachToForm',
            'attachValidators',
            'detachFromForm',
            'validateInput',
            'validate'
        );
    }

    componentWillMount() {
        super.componentWillMount();
        this.inputs = {};
        this.setState({model: _.clone(this.props.data)});
        if (this.props.container) {
            this.props.container.registerForm(this);
        }
    }

    componentWillReceiveProps(props) {
        super.componentWillReceiveProps(props);
        this.setState({model: _.clone(props.data)});
    }

    componentWillUpdate(newProps, newState) {
        super.componentWillUpdate(newProps, newState);
    }

    bindTo(name, callback = _.noop, defaultValue = null) {
        return super.bindTo('model.' + name, callback, defaultValue);
    }

    watch(name, callback) {
        const watches = this.watches[name] || new Set();
        watches.add(callback);
        this.watches[name] = watches;
        return () => {
            this.watches[name].delete(callback);
        };
    }

    /**
     * @private
     * @param element
     * @returns {*}
     */
    replacePlaceholders(element) {
        if (typeof element !== 'object' || element === null) {
            return element;
        }

        if (element.type === 'fields') {
            return this.fields;
        }

        if (element.type === 'actions') {
            return this.actions;
        }

        if (element.props && element.props.children) {
            return React.cloneElement(element, _.omit(element.props, ['key', 'ref']), React.Children.map(element.props.children, item => {
                return this.replacePlaceholders(item);
            }));
        }

        return element;
    }

    /**
     * @private
     * @param input
     * @returns {*}
     */
    registerInput(input) {
        if (typeof input !== 'object' || input === null) {
            return input;
        }

        const newProps = {
            attachToForm: this.attachToForm,
            attachValidators: this.attachValidators,
            detachFromForm: this.detachFromForm,
            validateInput: this.validateInput,
            form: this
        };

        if (input.props && input.props.name) {
            // Add onChange callback to valueLink
            const name = _.upperFirst(_.camelCase(input.props.name));

            // Callback can be set on Container (which will pass it to Form), on Form or on input itself
            const callback = _.get(input.props, 'onChange', _.get(this.props, 'onChange' + name, _.noop));

            // Input changed callback, triggered on each input change
            const changeCallback = function inputChanged(newValue) {
                callback.call(this, newValue, this.inputs[input.props.name].component);
                // See if there is a watch registered for changed input
                const watches = this.watches[input.props.name] || new Set();
                _.map(Array.from(watches), w => w(newValue));
            };

            newProps['valueLink'] = this.bindTo(input.props.name, changeCallback.bind(this), input.props.defaultValue);

            // Add input renderer
            if (_.has(this.props, 'render' + name)) {
                newProps.renderer = this.props['render' + name];
            }

            // Add options source
            if (_.has(this.props, 'options' + name)) {
                newProps.options = this.props['options' + name];
            }

            // Add options source
            if (_.has(this.props, 'optionRenderer' + name)) {
                const selectRenderers = this.props['optionRenderer' + name];
                newProps.optionRenderer = selectRenderers.option || null;
                newProps.selectedRenderer = selectRenderers.selected || null;
            }
            return React.cloneElement(input, newProps, input.props && input.props.children);
        }
        return React.cloneElement(input, _.omit(input.props, ['key', 'ref']), this.registerInputs(input.props && input.props.children));
    }

    /**
     * @private
     * @param children
     * @returns {*}
     */
    registerInputs(children) {
        if (typeof children !== 'object' || children === null) {
            return children;
        }
        return React.Children.map(children, this.registerInput, this);
    }

    /**
     * Get data this form is responsible for.
     * Form may receive data through props that is not handled by any of form input elements,
     * so we only return the data handled by form input elements.
     *
     * This method also clears data of any system keys that are used for React optimization, like $key
     *
     * @returns {{}}
     */
    getModel() {
        const model = {};
        _.each(this.inputs, (input, name) => {
            _.set(model, name, _.get(this.state.model, name));
        });

        return Webiny.Tools.removeKeys(model);
    }

    /**
     * Set form model (merge current model with given model object)
     * @param key object or string key
     * @param value callable or value (if key is a string)
     * @param callback callable (if key is a string)
     * @returns {Form}
     */
    setModel(key, value = null, callback = null) {
        if (_.isObject(key)) {
            _.merge(this.state.model, key);
            this.setState({model: this.state.model}, value);
        }

        if (_.isString(key)) {
            _.set(this.state.model, key, value);
            this.setState({model: this.state.model}, callback);
        }
        return this;
    }

    /**
     * Get current form data including data from linked forms
     * @returns {Object|*}
     */
    getData() {
        const model = this.getModel();
        const forms = this.getLinkedForms();
        if (forms.length) {
            _.each(forms, form => {
                _.merge(model, form.getData());
            });
        }

        return model;
    }

    getLinkedForms() {
        if (this.props.container && this === this.props.container.mainForm) {
            return this.props.container.getLinkedForms();
        }

        if (!this.props.container && this.props.linkedForms) {
            return _.filter(this.props.linkedForms.split(',')).map(Webiny.Ui.Dispatcher.get);
        }

        return [];
    }

    submit(e) {
        if (e && e.preventDefault) {
            e.preventDefault();
        }

        // Validate main form first
        return this.validate().then(mainFormValid => {
            if (!mainFormValid) {
                this.props.onInvalid(this);
                return false;
            }

            // Now proceed to validation of linked forms, if any.
            const model = this.getModel();

            // Validate linked forms
            const forms = this.getLinkedForms();
            if (forms.length) {
                let valid = true;

                // Forms must be validated in a queue because we may have async validators
                let chain = Q();
                _.each(forms, form => {
                    chain = chain.then(() => {
                        return form.validate().then(formValid => {
                            if (formValid) {
                                _.merge(model, form.getData());
                                return true;
                            }

                            valid = false;
                            form.props.onInvalid(form);
                            return false;
                        });
                    });
                });

                return chain.then(() => {
                    if (valid) {
                        this.props.onSubmit(model, this.props.container);
                        return true;
                    }
                    return false;
                });
            }

            // If no linked forms are present...
            this.props.onSubmit(model, this.props.container);
            return true;
        });
    }

    reset() {
        // Reset all linked forms
        _.each(this.getLinkedForms(), form => form.reset());

        _.forIn(this.inputs, cmp => {
            cmp.component.setState({isValid: null});
        });
        this.$isValid = null;

        this.props.onReset();

        this.setState({model: _.clone(this.props.data)});
    }

    cancel() {
        this.props.onCancel();
    }

    isValid() {
        return this.$isValid;
    }

    attachValidators(props) {
        this.inputs[props.name].validators = Validator.parseValidateProperty(props.validate);
        this.inputs[props.name].messages = Validator.parseCustomValidationMessages(props.children);
    }

    attachToForm(component) {
        this.inputs[component.props.name] = {
            component,
            model: component.getValue()
        };
        this.attachValidators(component.props);
    }

    detachFromForm(component) {
        delete this.inputs[component.props.name];
    }

    validateInput(component) {
        const validators = this.inputs[component.props.name].validators;
        const hasValidators = Webiny.Tools.keys(validators).length;
        const messages = this.inputs[component.props.name].messages;
        // Validate input
        return Q(Validator.validate(component.getValue(), validators, this.inputs)).then(validationResults => {
            if (hasValidators) {
                const isValid = component.getValue() === null ? null : true;
                component.setState({isValid, validationResults});
            }
            return validationResults;
        }).catch(validationError => {
            // Set custom error message if defined
            const validator = validationError.validator;
            if (validator in messages) {
                validationError.setMessage(messages[validator]);
            }

            // Set component state to reflect validation error
            component.setState({
                isValid: false,
                validationMessage: validationError.message,
                validationResults: false
            });

            return false;
        });
    }

    validate() {
        let allIsValid = true;

        const inputs = this.inputs;
        // Inputs must be validated in a queue because we may have async validators
        let chain = Q(allIsValid).then(valid => valid);
        Object.keys(inputs).forEach(name => {
            const cmp = inputs[name].component;
            const hasValidators = inputs[name] && inputs[name].validators;
            const shouldValidate = (!cmp.hasValue() && cmp.isRequired()) || (cmp.hasValue() && cmp.state.isValid !== true);

            if (hasValidators && shouldValidate) {
                if (cmp.state.isValid === false || cmp.state.isValid === null) {
                    chain = chain.then(() => {
                        return this.validateInput(cmp).then(validationResult => {
                            if (validationResult === false) {
                                allIsValid = false;
                            }
                            return allIsValid;
                        });
                    });
                }
            }
        });

        return chain;
    }

    renderFields() {
        React.Children.map(this.props.children, child => {
            if (child.type === 'fields') {
                const fields = _.isFunction(child.props.children) ? child.props.children.call(this, this.state.model, this) : child.props.children;
                this.fields = this.registerInputs(fields);
            }
        }, this);

        return this.fields;
    }

    renderActions() {
        React.Children.map(this.props.children, child => {
            if (child.type === 'actions') {
                this.actions = _.isFunction(child.props.children) ? child.props.children(this.state.model, this) : child.props.children;
            }
        }, this);

        return this.actions;
    }

    renderLayout() {
        if (this.props.layout) {
            return this.props.layout.call(this);
        }

        return (
            <layout>
                <fields/>
            </layout>
        );
    }

    render() {
        const fields = this.renderFields.call(this, this.state.model, this);
        this.fields = this.registerInputs(fields);
        this.actions = this.renderActions.call(this, this.state.model, this);
        this.layout = this.renderLayout();
        return super.render();
    }
}

Form.defaultProps = {
    name: _.uniqueId('form-'),
    onSubmit: _.noop,
    onReset: _.noop,
    onCancel: _.noop,
    onInvalid: _.noop,
    showLoader: true,
    linkedForms: null,
    layout() {
        let title = this.props.title;
        if (_.isFunction(title)) {
            title = title();
        }

        return (
            <Ui.Panel.Panel>
                <Ui.Panel.Header title={title} icon={this.props.icon}/>
                <Ui.Panel.Body>
                    <fields/>
                </Ui.Panel.Body>
                <Ui.Panel.Footer className="text-right">
                    <actions/>
                </Ui.Panel.Footer>
            </Ui.Panel.Panel>
        );
    },
    renderer() {
        const loader = this.props.showLoader ? null : null;
        const css = this.props.layout === 'horizontal' ? 'form-horizontal' : '';

        const render = [];

        const formProps = {
            id: this.props.id,
            autoComplete: 'off',
            className: this.classSet(css, this.props.className),
            onSubmit: this.submit,
            name: this.props.name
        };

        React.Children.map(this.layout, (item, index) => {
            render.push(React.cloneElement(this.replacePlaceholders(item), {key: index}));
        });

        return (
            <form {...formProps}>
                {loader}
                {render}
                <button style={{position: 'absolute', left: '-5000px'}} type="submit"></button>
            </form>
        );
    }
};

export default Form;<commit_msg>Form will only fire onInvalid callback on the first form that failed the validation.<commit_after>import Webiny from 'Webiny';
const Ui = Webiny.Ui.Components;
import Validator from './../Validation/Validator';

class Form extends Webiny.Ui.Component {

    constructor(props) {
        super(props);

        this.state = {
            model: {}
        };

        this.$isValid = null;
        this.fields = [];
        this.actions = [];
        this.layout = null;
        this.watches = {};

        this.bindMethods(
            'submit',
            'reset',
            'cancel',
            'attachToForm',
            'attachValidators',
            'detachFromForm',
            'validateInput',
            'validate'
        );
    }

    componentWillMount() {
        super.componentWillMount();
        this.inputs = {};
        this.setState({model: _.clone(this.props.data)});
        if (this.props.container) {
            this.props.container.registerForm(this);
        }
    }

    componentWillReceiveProps(props) {
        super.componentWillReceiveProps(props);
        this.setState({model: _.clone(props.data)});
    }

    componentWillUpdate(newProps, newState) {
        super.componentWillUpdate(newProps, newState);
    }

    bindTo(name, callback = _.noop, defaultValue = null) {
        return super.bindTo('model.' + name, callback, defaultValue);
    }

    watch(name, callback) {
        const watches = this.watches[name] || new Set();
        watches.add(callback);
        this.watches[name] = watches;
        return () => {
            this.watches[name].delete(callback);
        };
    }

    /**
     * @private
     * @param element
     * @returns {*}
     */
    replacePlaceholders(element) {
        if (typeof element !== 'object' || element === null) {
            return element;
        }

        if (element.type === 'fields') {
            return this.fields;
        }

        if (element.type === 'actions') {
            return this.actions;
        }

        if (element.props && element.props.children) {
            return React.cloneElement(element, _.omit(element.props, ['key', 'ref']), React.Children.map(element.props.children, item => {
                return this.replacePlaceholders(item);
            }));
        }

        return element;
    }

    /**
     * @private
     * @param input
     * @returns {*}
     */
    registerInput(input) {
        if (typeof input !== 'object' || input === null) {
            return input;
        }

        const newProps = {
            attachToForm: this.attachToForm,
            attachValidators: this.attachValidators,
            detachFromForm: this.detachFromForm,
            validateInput: this.validateInput,
            form: this
        };

        if (input.props && input.props.name) {
            // Add onChange callback to valueLink
            const name = _.upperFirst(_.camelCase(input.props.name));

            // Callback can be set on Container (which will pass it to Form), on Form or on input itself
            const callback = _.get(input.props, 'onChange', _.get(this.props, 'onChange' + name, _.noop));

            // Input changed callback, triggered on each input change
            const changeCallback = function inputChanged(newValue) {
                callback.call(this, newValue, this.inputs[input.props.name].component);
                // See if there is a watch registered for changed input
                const watches = this.watches[input.props.name] || new Set();
                _.map(Array.from(watches), w => w(newValue));
            };

            newProps['valueLink'] = this.bindTo(input.props.name, changeCallback.bind(this), input.props.defaultValue);

            // Add input renderer
            if (_.has(this.props, 'render' + name)) {
                newProps.renderer = this.props['render' + name];
            }

            // Add options source
            if (_.has(this.props, 'options' + name)) {
                newProps.options = this.props['options' + name];
            }

            // Add options source
            if (_.has(this.props, 'optionRenderer' + name)) {
                const selectRenderers = this.props['optionRenderer' + name];
                newProps.optionRenderer = selectRenderers.option || null;
                newProps.selectedRenderer = selectRenderers.selected || null;
            }
            return React.cloneElement(input, newProps, input.props && input.props.children);
        }
        return React.cloneElement(input, _.omit(input.props, ['key', 'ref']), this.registerInputs(input.props && input.props.children));
    }

    /**
     * @private
     * @param children
     * @returns {*}
     */
    registerInputs(children) {
        if (typeof children !== 'object' || children === null) {
            return children;
        }
        return React.Children.map(children, this.registerInput, this);
    }

    /**
     * Get data this form is responsible for.
     * Form may receive data through props that is not handled by any of form input elements,
     * so we only return the data handled by form input elements.
     *
     * This method also clears data of any system keys that are used for React optimization, like $key
     *
     * @returns {{}}
     */
    getModel() {
        const model = {};
        _.each(this.inputs, (input, name) => {
            _.set(model, name, _.get(this.state.model, name));
        });

        return Webiny.Tools.removeKeys(model);
    }

    /**
     * Set form model (merge current model with given model object)
     * @param key object or string key
     * @param value callable or value (if key is a string)
     * @param callback callable (if key is a string)
     * @returns {Form}
     */
    setModel(key, value = null, callback = null) {
        if (_.isObject(key)) {
            _.merge(this.state.model, key);
            this.setState({model: this.state.model}, value);
        }

        if (_.isString(key)) {
            _.set(this.state.model, key, value);
            this.setState({model: this.state.model}, callback);
        }
        return this;
    }

    /**
     * Get current form data including data from linked forms
     * @returns {Object|*}
     */
    getData() {
        const model = this.getModel();
        const forms = this.getLinkedForms();
        if (forms.length) {
            _.each(forms, form => {
                _.merge(model, form.getData());
            });
        }

        return model;
    }

    getLinkedForms() {
        if (this.props.container && this === this.props.container.mainForm) {
            return this.props.container.getLinkedForms();
        }

        if (!this.props.container && this.props.linkedForms) {
            return _.filter(this.props.linkedForms.split(',')).map(Webiny.Ui.Dispatcher.get);
        }

        return [];
    }

    submit(e) {
        if (e && e.preventDefault) {
            e.preventDefault();
        }

        // Validate main form first
        return this.validate().then(mainFormValid => {
            if (!mainFormValid) {
                this.props.onInvalid(this);
                return false;
            }

            // Now proceed to validation of linked forms, if any.
            const model = this.getModel();

            // Validate linked forms
            const forms = this.getLinkedForms();
            if (forms.length) {
                let valid = true;

                // Forms must be validated in a queue because we may have async validators
                let chain = Q();
                _.each(forms, form => {
                    chain = chain.then(() => {
                        return form.validate().then(formValid => {
                            if (formValid) {
                                _.merge(model, form.getData());
                                return true;
                            }

                            // Only call onInvalid if this is the first form to be invalid
                            if (valid) {
                                form.props.onInvalid(form);
                            }

                            valid = false;
                            return false;
                        });
                    });
                });

                return chain.then(() => {
                    if (valid) {
                        this.props.onSubmit(model, this.props.container);
                        return true;
                    }
                    return false;
                });
            }

            // If no linked forms are present...
            this.props.onSubmit(model, this.props.container);
            return true;
        });
    }

    reset() {
        // Reset all linked forms
        _.each(this.getLinkedForms(), form => form.reset());

        _.forIn(this.inputs, cmp => {
            cmp.component.setState({isValid: null});
        });
        this.$isValid = null;

        this.props.onReset();

        this.setState({model: _.clone(this.props.data)});
    }

    cancel() {
        this.props.onCancel();
    }

    isValid() {
        return this.$isValid;
    }

    attachValidators(props) {
        this.inputs[props.name].validators = Validator.parseValidateProperty(props.validate);
        this.inputs[props.name].messages = Validator.parseCustomValidationMessages(props.children);
    }

    attachToForm(component) {
        this.inputs[component.props.name] = {
            component,
            model: component.getValue()
        };
        this.attachValidators(component.props);
    }

    detachFromForm(component) {
        delete this.inputs[component.props.name];
    }

    validateInput(component) {
        const validators = this.inputs[component.props.name].validators;
        const hasValidators = Webiny.Tools.keys(validators).length;
        const messages = this.inputs[component.props.name].messages;
        // Validate input
        return Q(Validator.validate(component.getValue(), validators, this.inputs)).then(validationResults => {
            if (hasValidators) {
                const isValid = component.getValue() === null ? null : true;
                component.setState({isValid, validationResults});
            }
            return validationResults;
        }).catch(validationError => {
            // Set custom error message if defined
            const validator = validationError.validator;
            if (validator in messages) {
                validationError.setMessage(messages[validator]);
            }

            // Set component state to reflect validation error
            component.setState({
                isValid: false,
                validationMessage: validationError.message,
                validationResults: false
            });

            return false;
        });
    }

    validate() {
        let allIsValid = true;

        const inputs = this.inputs;
        // Inputs must be validated in a queue because we may have async validators
        let chain = Q(allIsValid).then(valid => valid);
        Object.keys(inputs).forEach(name => {
            const cmp = inputs[name].component;
            const hasValidators = inputs[name] && inputs[name].validators;
            const shouldValidate = (!cmp.hasValue() && cmp.isRequired()) || (cmp.hasValue() && cmp.state.isValid !== true);

            if (hasValidators && shouldValidate) {
                if (cmp.state.isValid === false || cmp.state.isValid === null) {
                    chain = chain.then(() => {
                        return this.validateInput(cmp).then(validationResult => {
                            if (validationResult === false) {
                                allIsValid = false;
                            }
                            return allIsValid;
                        });
                    });
                }
            }
        });

        return chain;
    }

    renderFields() {
        React.Children.map(this.props.children, child => {
            if (child.type === 'fields') {
                const fields = _.isFunction(child.props.children) ? child.props.children.call(this, this.state.model, this) : child.props.children;
                this.fields = this.registerInputs(fields);
            }
        }, this);

        return this.fields;
    }

    renderActions() {
        React.Children.map(this.props.children, child => {
            if (child.type === 'actions') {
                this.actions = _.isFunction(child.props.children) ? child.props.children(this.state.model, this) : child.props.children;
            }
        }, this);

        return this.actions;
    }

    renderLayout() {
        if (this.props.layout) {
            return this.props.layout.call(this);
        }

        return (
            <layout>
                <fields/>
            </layout>
        );
    }

    render() {
        const fields = this.renderFields.call(this, this.state.model, this);
        this.fields = this.registerInputs(fields);
        this.actions = this.renderActions.call(this, this.state.model, this);
        this.layout = this.renderLayout();
        return super.render();
    }
}

Form.defaultProps = {
    name: _.uniqueId('form-'),
    onSubmit: _.noop,
    onReset: _.noop,
    onCancel: _.noop,
    onInvalid: _.noop,
    showLoader: true,
    linkedForms: null,
    layout() {
        let title = this.props.title;
        if (_.isFunction(title)) {
            title = title();
        }

        return (
            <Ui.Panel.Panel>
                <Ui.Panel.Header title={title} icon={this.props.icon}/>
                <Ui.Panel.Body>
                    <fields/>
                </Ui.Panel.Body>
                <Ui.Panel.Footer className="text-right">
                    <actions/>
                </Ui.Panel.Footer>
            </Ui.Panel.Panel>
        );
    },
    renderer() {
        const loader = this.props.showLoader ? null : null;
        const css = this.props.layout === 'horizontal' ? 'form-horizontal' : '';

        const render = [];

        const formProps = {
            id: this.props.id,
            autoComplete: 'off',
            className: this.classSet(css, this.props.className),
            onSubmit: this.submit,
            name: this.props.name
        };

        React.Children.map(this.layout, (item, index) => {
            render.push(React.cloneElement(this.replacePlaceholders(item), {key: index}));
        });

        return (
            <form {...formProps}>
                {loader}
                {render}
                <button style={{position: 'absolute', left: '-5000px'}} type="submit"></button>
            </form>
        );
    }
};

export default Form;<|endoftext|>


<commit_before>#!/usr/bin/env node

var config = require(process.env.HOME + "/.teleircConfig.js");
var net = require("net");
var spawn = require("child_process").spawn;

var handleTgLine = function(line) {
    if(line.match(new RegExp('\\[\\d\\d:\\d\\d\\]  ' + config.tgchat + ' .* >>> .*'))) {
        line = line.split(' ');
        line.shift(); line.shift(); line.shift();

        // line now contains [Firstname, Lastname, ..., >>>, msgword1, msgword2, ...]
        var name = "";
        temp = line.shift();
        while(temp !== '>>>') {
            name += temp;
            temp = line.shift();
        }

        line = line.join(' ');

        // check if msg was sent by bot telegram account && starts with 'irc: '
        // then don't send the msg back to irc
        if(name === config.tgnick.replace(' ', ''))
            if(line.indexOf('irc: ') === 0)
                return;

        sendIrcMsg('<' + name + '>: ' + line);
    }
};

var telegram = spawn(config.tgcli_path, ['-R', '-C', '-W', '-k', config.tgpubkey_path]);
var stdoutBuf = "";
telegram.stdout.on('data', function(data) {
    stdoutBuf += data.toString('utf8');
    var lastNL = stdoutBuf.lastIndexOf('\n');

    // have we received at least one whole line? else wait for more data
    if(lastNL !== -1) {
        var recvdLines = stdoutBuf.substr(0, lastNL + 1).split('\n');
        stdoutBuf = stdoutBuf.substr(lastNL + 1);

        for(var i = 0; i < recvdLines.length; i++) {
            if(recvdLines[i] !== '') {
                //console.log('irc server sent ' + recvdLines[i]);
                handleTgLine(recvdLines[i]);
            }
        }
    }
});
telegram.stdin.write('chat_with_peer ' + config.tgchat + '\n');

var ircServer;

var recvdIrcMsg = function(serverName, cmd, chan, nick, msgString, noBroadcast) {
    // check if first word contains config.nick, ie. is a hilight
    var firstWord = msgString.substr(0, msgString.indexOf(' '));
    if(firstWord.indexOf(config.nick) !== -1) {
        // remove first word
        msgString = msgString.substr(msgString.indexOf(' ') + 1);
        telegram.stdin.write('irc: <' + nick + '>: ' + msgString + '\n');
    }
};

var sendIrcMsg = function(msg) {
    ircServer.send('PRIVMSG ' + config.chan + ' :' + msg);
};

var handleIrcLine = function(line, server, ircServer) {
    var tokens = line.split(' ');

    //console.log(server.name + ': ' + line);
    if(tokens[0] === "PING") {
        //console.log('got PING, sending PONG to ' + tokens[1].substr(1));
        ircServer.send("PONG " + tokens[1].substr(1));
    } else if (tokens[0][0] === ":") {
        var prefix = tokens[0].substr(1);
        var nick = prefix.substr(0, prefix.indexOf('!'));
        var cmd = tokens[1];
        var chan = tokens[2];
        chan = chan.replace(':', '');

        var chanLongName = server.name + ':' + chan;
        chanLongName = chanLongName.toLowerCase();

        if(cmd === "PRIVMSG") {
            tokens.shift(); tokens.shift(); tokens.shift();
            var msg = tokens.join(' ').substr(1);

            if(chan.toLowerCase() === config.chan.toLowerCase()) {
                recvdIrcMsg(server.name, "message", chan, nick, msg);
            }
        }
    } else {
        console.log("got unknown msg on " + server.name + ": " + line);
    }
};

var ircConnect = function(serverConfig) {
    var buffer = "";

    ircServer = net.connect({
        "port": serverConfig.port,
        "host": serverConfig.address
    }, function() {
        // logging
        console.log('connected to irc server');

        var passString = "";
        if(serverConfig.password)
            passString = "PASS " + serverConfig.password + "\r\n";

        ircServer.write(passString +
                     "NICK " + (serverConfig.nick || config.nick) + "\r\n" +
                     "USER " + (serverConfig.nick || config.nick) + " " +
                     "localhost " + serverConfig.address + " :" +
                     (serverConfig.nick || config.nick) + "\r\n" +
                     "JOIN " + config.chan + "\r\n");

        ircServer.resetPingTimer();
    });

    ircServer.send = function(data) {
        //console.log("sending data to IRC: " + data);
        ircServer.write(data + '\r\n');
    };

    ircServer.on('data', function(data) {
        ircServer.resetPingTimer();

        buffer += data.toString('utf8');
        var lastNL = buffer.lastIndexOf('\n');

        // have we received at least one whole line? else wait for more data
        if(lastNL !== -1) {
            var recvdLines = buffer.substr(0, lastNL + 1).split('\r\n');
            buffer = buffer.substr(lastNL + 1);

            for(var i = 0; i < recvdLines.length; i++) {
                if(recvdLines[i] !== '') {
                    //console.log('irc server sent ' + recvdLines[i]);
                    handleIrcLine(recvdLines[i], serverConfig, ircServer);
                }
            }
        }
    });

    ircServer.reconnect = function(message) {
        // cleanup
        clearTimeout(ircServer.pingTimer);
        ircServer.removeAllListeners('end');
        ircServer.removeAllListeners('close');
        ircServer.removeAllListeners('error');

        ircServer.destroy();

        // delay reconnect by config.reconnectDelay ms
        ircServer.reconnectTimer = setTimeout(function() {
            console.log(serverConfig.name + ': reconnecting...');
            ircConnect(serverConfig);
        }, config.reconnectDelay);
    };

    ircServer.on('end', function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc ended.');
    });
    ircServer.on('close', function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc closed.');
    });
    ircServer.on('error', function(err) {
        ircServer.reconnect(serverConfig.name + ': irc socket error: ' + err.code);
    });

    // call whenever irc server sends data to postpone timeout timers
    ircServer.resetPingTimer = function() {
        // ping the server after config.pingDelay of inactivity
        clearTimeout(ircServer.pingTimer);
        ircServer.pingTimer = setTimeout(function() {
            ircServer.send('PING ' + ircServer.config.address);
        }, config.pingDelay);
    };

    ircServer.setTimeout(config.timeoutDelay, function() {
        ircServer.reconnect(serverConfig.name + ': connection to irc timed out.');
    });

    ircServer.config = serverConfig;
};

ircConnect(config.server);
<commit_msg>Use node "irc" module.<commit_after>#!/usr/bin/env node

var config = require(process.env.HOME + "/.teleircConfig.js");
var spawn = require("child_process").spawn;
var irc = require('irc');

var irc_client = irc.Client(config.server.address, config.nick, {
    secure: config.server.secure || false,
    port: config.server.port,
    userName: config.nick,
    realName: 'Telegram IRC Bot (teleirc)',
    channels: [config.chan]
});

irc.on('registered', function(message) {
    console.info('Connected to IRC server.');

    // Store the nickname assigned by the server
    config.realNick = message.args[0];
    console.info('Using nickname: ' + config.realNick);
});

irc.on('error', function(error) {
    // Error 421 comes up a lot on Mozilla servers, but isn't a problem.
    if (error.rawCommand !== '421') {
        return;
    }

    console.error(error);
    if (error.hasOwnProperty('stack')) {
        console.error(error.stack);
    }
});

// React to users quitting the IRC server
irc.on('quit', function(user) {
    if (user == config.nick) {
        irc.send('NICK', config.nick);
        config.realNick = config.nick
    }
});

/* Receive, parse, and handle messages from IRC.
 * - `user`: The nick of the user that send the message.
 * - `channel`: The channel the message was received in. Note, this might not be
 * a real channel, because it could be a PM. But this function ignores
 * those messages anyways.
 * - `message`: The text of the message sent.
 */
irc.on('message', function(user, channel, message){
    var cmdRe = new RegExp('^' + config.realNick + '[:,]? +(.*)$', 'i');
    var match = cmdRe.exec(message);
    if (match) {
        var message = match[1].trim();
        telegram.stdin.write('irc: <' + user + '>: ' + message + '\n');
    }
});

var handleTgLine = function(line) {
    if(line.match(new RegExp('\\[\\d\\d:\\d\\d\\]  ' + config.tgchat + ' .* >>> .*'))) {
        line = line.split(' ');
        line.shift(); line.shift(); line.shift();

        // line now contains [Firstname, Lastname, ..., >>>, msgword1, msgword2, ...]
        var name = "";
        temp = line.shift();
        while(temp !== '>>>') {
            name += temp;
            temp = line.shift();
        }

        line = line.join(' ');

        // check if msg was sent by bot telegram account && starts with 'irc: '
        // then don't send the msg back to irc
        if(name === config.tgnick.replace(' ', ''))
            if(line.indexOf('irc: ') === 0)
                return;

        sendIrcMsg('<' + name + '>: ' + line);
    }
};

var telegram = spawn(config.tgcli_path, ['-R', '-C', '-W', '-k', config.tgpubkey_path]);
var stdoutBuf = "";
telegram.stdout.on('data', function(data) {
    stdoutBuf += data.toString('utf8');
    var lastNL = stdoutBuf.lastIndexOf('\n');

    // have we received at least one whole line? else wait for more data
    if(lastNL !== -1) {
        var recvdLines = stdoutBuf.substr(0, lastNL + 1).split('\n');
        stdoutBuf = stdoutBuf.substr(lastNL + 1);

        for(var i = 0; i < recvdLines.length; i++) {
            if(recvdLines[i] !== '') {
                //console.log('irc server sent ' + recvdLines[i]);
                handleTgLine(recvdLines[i]);
            }
        }
    }
});
telegram.stdin.write('chat_with_peer ' + config.tgchat + '\n');

var sendIrcMsg = function(msg) {
    irc_client.say(config.chan, msg)
};

<|endoftext|>