<commit_before>'use strict'

const test = require('tape')
const fs = require('fs')
const os = require('os')
const path = require('path')
const concat = require('concat-stream')
const Netcat = require('../')
const NetcatServer = Netcat.server
const NetcatClient = Netcat.client

test('Client and Server constructor', function (t) {
  t.plan(2) // plan assertions

  try {
    var nc = new NetcatServer()
    var nc2 = new NetcatClient()
    t.ok(nc, 'Server constructor')
    t.ok(nc2, 'Client constructor')
  } catch (e) {
    t.fail(e)
  }
})

test('Server basic methods', function (t) {
  t.plan(15)

  try {
    var nc = new NetcatServer()
    /* checking default values */
    t.equal(nc._port, null, 'port null by default')
    t.equal(nc._protocol, 'tcp', 'protocol is tcp by default')
    t.equal(nc._address, '0.0.0.0', '0.0.0.0 default address')
    t.equal(nc._keepalive, false, 'no keepalive')
    t.equal(Object.keys(nc._clients).length, 0, 'no clients')
    /* set methods */
    nc.udp()
    t.equal(nc._protocol, 'udp', 'setting udp as protocol')
    nc.tcp()
    t.equal(nc._protocol, 'tcp', 'setting tcp as protocol')
    nc.address('192.168.1.101')
    t.equal(nc._address, '192.168.1.101', 'setting address xxx')
    nc.addr('0.0.0.0')
    t.equal(nc._address, '0.0.0.0', 'using addr alias')
    nc.port(2389)
    t.equal(nc._port, 2389, 'setting port 2389')
    nc.keepalive()
    t.equal(nc._keepalive, true, 'set keepalive true')
    nc.k(false)
    t.equal(nc._keepalive, false, 'set keepalive false')
    nc.exec('/bin/sh')
    t.equal(nc._exec, '/bin/sh', 'setting exec to /bin/sh')
    nc.exec(null)

    nc.listen()
    t.ok(nc.server, 'server listen')
    nc.close(function () {
      t.ok(true, 'close server')
    })
  } catch (e) {
    console.log(e)
    t.fail(e)
  }
})

test('Client basic methods', function (t) {
  t.plan(15)
  t.timeoutAfter(5000)

  try {
    var srv = new NetcatServer().port(2390).listen() // server
    var nc = new NetcatClient()
    /* checking default values */
    t.equal(nc._port, null, 'port null by default')
    t.equal(nc._protocol, 'tcp', 'protocol is tcp by default')
    t.equal(nc._address, '127.0.0.1', '127.0.0.1 default address')
    t.equal(nc._interval, false, 'no interval by default')
    /* set methods */
    nc.udp()
    t.equal(nc._protocol, 'udp', 'setting udp as protocol')
    nc.tcp()
    t.equal(nc._protocol, 'tcp', 'setting tcp as protocol')
    nc.address('localhost')
    t.equal(nc._address, 'localhost', 'setting address localhost')
    nc.addr('127.0.0.1')
    t.equal(nc._address, '127.0.0.1', 'using addr alias')
    nc.port(2390)
    t.equal(nc._port, 2390, 'setting port 2390')
    nc.retry(0)
    t.equal(nc._retry, 0, 'setting retry to 0')
    nc.exec('/bin/sh')
    t.equal(nc._exec, '/bin/sh', 'setting exec to /bin/sh')
    nc.exec(null)

    nc.connect(function () {
      t.ok(nc.client, 'client connected')
      t.ok(nc.stream(), 'stream available')
      nc.close(function () {
        t.ok(true, 'close client')
        srv.close(function () {
          t.ok(true, 'close server')
        })
      })
    })
  } catch (e) {
    console.log(e)
    t.fail(e)
  }
})

test('TCP Client Server connection', function (t) {
  t.plan(4)
  t.timeoutAfter(5000)

  var nc = new NetcatServer()
  var nc2 = new NetcatClient()

  nc.port(2391).listen().on('data', function (socket, data) {
    t.ok(socket.id, 'Socket got an ID assigned')
    t.equal(data.toString(), 'Hello World', 'got expected string')
    close()
  })

  nc2.addr('127.0.0.1').port(2391).connect(function () {
    t.equal(this, nc2, 'Got client istance')
    console.log('Sending message')
    this.send('Hello World')
  })

  function close () {
    nc.close(function () {
      t.ok(true, 'close server')
    })
  }
})

test('Client: send raw buffer', function (t) {
  t.plan(4)
  t.timeoutAfter(4000)

  var nc = new NetcatServer()
  var nc2 = new NetcatClient()

  nc.port(2391).listen().on('data', function (socket, data) {
    t.ok(socket.id, 'Socket got an ID assigned')
    t.deepEqual(data, Buffer.from('hello world'), 'got expected Buffer')
    close()
  })

  nc2.addr('127.0.0.1').port(2391).connect(function () {
    t.equal(this, nc2, 'Got client istance')
    console.log('Sending Buffer')
    this.send(Buffer.from('hello world'))
  })

  function close () {
    nc.close(function () {
      t.ok(true, 'close server')
    })
  }
})

test('Transfer a file (stream)', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var nc = new NetcatServer()
  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)

  var concatStream = concat(function (file) {
    t.equal(file.toString(), inputFile.toString(), 'server got expected file')
  })

  nc.port(2391).listen().pipe(concatStream).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var nc2 = new NetcatClient()
  fs.createReadStream(testFile).pipe(nc2.addr('127.0.0.1').port(2391).connect().stream())
})

test('Serving a file with serve()', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)

  var nc = new NetcatServer()
  nc.port(2392).listen().serve(testFile).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var concatStream = concat(function (file) {
    t.equal(file.toString(), inputFile.toString(), 'client got expected file')
  })

  var nc2 = new NetcatClient()
  nc2.addr('127.0.0.1').port(2392).connect().pipe(concatStream)
})

test('Serving a file using keepalive to multiple clients', function (t) {
  var nClients = 10 // 10 clients
  t.plan(nClients + 1)
  t.timeoutAfter(5000)
  var k = 0

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)

  var nc = new NetcatServer()
  nc.port(2393).keepalive().listen().serve(testFile)

  var NCs = {}
  for (var i = 0; i < nClients; i++) {
    NCs[i] = new NetcatClient()
    NCs[i].addr('127.0.0.1').port(2393).connect().pipe(concat(function (file) {
      t.equal(file.toString(), inputFile.toString(), 'client got expected file')
      if (++k === nClients) {
        nc.close(function () {
          t.ok(true, 'server closed')
        })
      }
    }))
  }
})

test('Serving an istance of stream', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)
  var inputStream = fs.createReadStream(testFile)

  var nc = new NetcatServer()
  nc.port(2392).listen().serve(inputStream).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var concatStream = concat(function (file) {
    t.equal(file.toString(), inputFile.toString(), 'client got expected stream')
  })

  var nc2 = new NetcatClient()
  nc2.addr('127.0.0.1').port(2392).connect().pipe(concatStream)
})

test('Serving a stream using keepalive to multiple clients', function (t) {
  var nClients = 10 // 10 clients
  t.plan(nClients + 1)
  t.timeoutAfter(5000)
  var k = 0

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)
  var inputStream = fs.createReadStream(testFile)

  var nc = new NetcatServer()
  nc.port(2394).k().listen().serve(inputStream)

  var NCs = {}
  for (var i = 0; i < nClients; i++) {
    NCs[i] = new NetcatClient()
    NCs[i].addr('127.0.0.1').port(2394).connect().pipe(concat(function (file) {
      t.equal(file.toString(), inputFile.toString(), 'client got expected file')
      if (++k === nClients) {
        nc.close(function () {
          t.ok(true, 'server closed')
        })
      }
    }))
  }
})

test('Serving a raw Buffer', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var nc = new NetcatServer()
  nc.port(2392).listen().serve(Buffer.from('Hello World')).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var concatStream = concat(function (buf) {
    t.equal(buf.toString(), 'Hello World', 'client got expected Buffer')
  })

  var nc2 = new NetcatClient()
  nc2.addr('127.0.0.1').port(2392).connect().pipe(concatStream)
})

test('Server exec()', function (t) {
  t.plan(3)
  t.timeoutAfter(5000)

  var cmd = (os.platform() === 'win32') ? 'type' : 'cat'

  var nc = new NetcatServer()
  nc.port(2400).listen()
  .exec(cmd)
  .on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })
  t.equal(nc._exec, cmd, 'spawning process')

  var nc2 = new NetcatClient()
  nc2.port(2400).connect(function () {
    var self = this
    setTimeout(function () {
      self.send('Hello World')
    }, 1000)
  }).on('data', function (buf) { // one chunk
    t.equal(buf.toString(), 'Hello World', 'got expected stdout')
    nc2.close()
  })
})

test('Client exec()', function (t) {
  t.plan(5)
  t.timeoutAfter(5000)

  var cmd = (os.platform() === 'win32') ? 'type' : 'cat'

  var nc = new NetcatServer()
  nc.port(2401).listen()
  .once('connection', function (socket) {
    t.ok(socket, 'client connected')
    socket.write('Hello World')
  })
  .once('data', function (sock, buf) { // one chunk
    t.ok(sock, 'got socket istance')
    t.equal(buf.toString(), 'Hello World', 'got expected stdout')
    nc.close()
  })
  .once('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var nc2 = new NetcatClient()
  nc2.port(2401).exec(cmd).connect()
  t.equal(nc2._exec, cmd, 'exec set')
})

/*
// Test client .retry(...)

// Test proxy Server

test('Proxy server', function (t) {
  t.plan(5)
  t.timeoutAfter(5000)

  var nc = new NetcatServer()
  var nc2 = new NetcatClient()

  // Proxying SSH

  nc2.addr('192.168.1.88').port(22).connect()
  nc.port(8080).k().listen().proxy(nc2.stream())

})
*/
<commit_msg>proxy server test added<commit_after>'use strict'

const test = require('tape')
const fs = require('fs')
const os = require('os')
const path = require('path')
const concat = require('concat-stream')
const Netcat = require('../')
const NetcatServer = Netcat.server
const NetcatClient = Netcat.client

test('Client and Server constructor', function (t) {
  t.plan(2) // plan assertions

  try {
    var nc = new NetcatServer()
    var nc2 = new NetcatClient()
    t.ok(nc, 'Server constructor')
    t.ok(nc2, 'Client constructor')
  } catch (e) {
    t.fail(e)
  }
})

test('Server basic methods', function (t) {
  t.plan(15)

  try {
    var nc = new NetcatServer()
    /* checking default values */
    t.equal(nc._port, null, 'port null by default')
    t.equal(nc._protocol, 'tcp', 'protocol is tcp by default')
    t.equal(nc._address, '0.0.0.0', '0.0.0.0 default address')
    t.equal(nc._keepalive, false, 'no keepalive')
    t.equal(Object.keys(nc._clients).length, 0, 'no clients')
    /* set methods */
    nc.udp()
    t.equal(nc._protocol, 'udp', 'setting udp as protocol')
    nc.tcp()
    t.equal(nc._protocol, 'tcp', 'setting tcp as protocol')
    nc.address('192.168.1.101')
    t.equal(nc._address, '192.168.1.101', 'setting address xxx')
    nc.addr('0.0.0.0')
    t.equal(nc._address, '0.0.0.0', 'using addr alias')
    nc.port(2389)
    t.equal(nc._port, 2389, 'setting port 2389')
    nc.keepalive()
    t.equal(nc._keepalive, true, 'set keepalive true')
    nc.k(false)
    t.equal(nc._keepalive, false, 'set keepalive false')
    nc.exec('/bin/sh')
    t.equal(nc._exec, '/bin/sh', 'setting exec to /bin/sh')
    nc.exec(null)

    nc.listen()
    t.ok(nc.server, 'server listen')
    nc.close(function () {
      t.ok(true, 'close server')
    })
  } catch (e) {
    console.log(e)
    t.fail(e)
  }
})

test('Client basic methods', function (t) {
  t.plan(15)
  t.timeoutAfter(5000)

  try {
    var srv = new NetcatServer().port(2390).listen() // server
    var nc = new NetcatClient()
    /* checking default values */
    t.equal(nc._port, null, 'port null by default')
    t.equal(nc._protocol, 'tcp', 'protocol is tcp by default')
    t.equal(nc._address, '127.0.0.1', '127.0.0.1 default address')
    t.equal(nc._interval, false, 'no interval by default')
    /* set methods */
    nc.udp()
    t.equal(nc._protocol, 'udp', 'setting udp as protocol')
    nc.tcp()
    t.equal(nc._protocol, 'tcp', 'setting tcp as protocol')
    nc.address('localhost')
    t.equal(nc._address, 'localhost', 'setting address localhost')
    nc.addr('127.0.0.1')
    t.equal(nc._address, '127.0.0.1', 'using addr alias')
    nc.port(2390)
    t.equal(nc._port, 2390, 'setting port 2390')
    nc.retry(0)
    t.equal(nc._retry, 0, 'setting retry to 0')
    nc.exec('/bin/sh')
    t.equal(nc._exec, '/bin/sh', 'setting exec to /bin/sh')
    nc.exec(null)

    nc.connect(function () {
      t.ok(nc.client, 'client connected')
      t.ok(nc.stream(), 'stream available')
      nc.close(function () {
        t.ok(true, 'close client')
        srv.close(function () {
          t.ok(true, 'close server')
        })
      })
    })
  } catch (e) {
    console.log(e)
    t.fail(e)
  }
})

test('TCP Client Server connection', function (t) {
  t.plan(4)
  t.timeoutAfter(5000)

  var nc = new NetcatServer()
  var nc2 = new NetcatClient()

  nc.port(2391).listen().on('data', function (socket, data) {
    t.ok(socket.id, 'Socket got an ID assigned')
    t.equal(data.toString(), 'Hello World', 'got expected string')
    close()
  })

  nc2.addr('127.0.0.1').port(2391).connect(function () {
    t.equal(this, nc2, 'Got client istance')
    console.log('Sending message')
    this.send('Hello World')
  })

  function close () {
    nc.close(function () {
      t.ok(true, 'close server')
    })
  }
})

test('Client: send raw buffer', function (t) {
  t.plan(4)
  t.timeoutAfter(4000)

  var nc = new NetcatServer()
  var nc2 = new NetcatClient()

  nc.port(2391).listen().on('data', function (socket, data) {
    t.ok(socket.id, 'Socket got an ID assigned')
    t.deepEqual(data, Buffer.from('hello world'), 'got expected Buffer')
    close()
  })

  nc2.addr('127.0.0.1').port(2391).connect(function () {
    t.equal(this, nc2, 'Got client istance')
    console.log('Sending Buffer')
    this.send(Buffer.from('hello world'))
  })

  function close () {
    nc.close(function () {
      t.ok(true, 'close server')
    })
  }
})

test('Transfer a file (stream)', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var nc = new NetcatServer()
  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)

  var concatStream = concat(function (file) {
    t.equal(file.toString(), inputFile.toString(), 'server got expected file')
  })

  nc.port(2391).listen().pipe(concatStream).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var nc2 = new NetcatClient()
  fs.createReadStream(testFile).pipe(nc2.addr('127.0.0.1').port(2391).connect().stream())
})

test('Serving a file with serve()', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)

  var nc = new NetcatServer()
  nc.port(2392).listen().serve(testFile).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var concatStream = concat(function (file) {
    t.equal(file.toString(), inputFile.toString(), 'client got expected file')
  })

  var nc2 = new NetcatClient()
  nc2.addr('127.0.0.1').port(2392).connect().pipe(concatStream)
})

test('Serving a file using keepalive to multiple clients', function (t) {
  var nClients = 10 // 10 clients
  t.plan(nClients + 1)
  t.timeoutAfter(5000)
  var k = 0

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)

  var nc = new NetcatServer()
  nc.port(2393).keepalive().listen().serve(testFile)

  var NCs = {}
  for (var i = 0; i < nClients; i++) {
    NCs[i] = new NetcatClient()
    NCs[i].addr('127.0.0.1').port(2393).connect().pipe(concat(function (file) {
      t.equal(file.toString(), inputFile.toString(), 'client got expected file')
      if (++k === nClients) {
        nc.close(function () {
          t.ok(true, 'server closed')
        })
      }
    }))
  }
})

test('Serving an istance of stream', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)
  var inputStream = fs.createReadStream(testFile)

  var nc = new NetcatServer()
  nc.port(2392).listen().serve(inputStream).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var concatStream = concat(function (file) {
    t.equal(file.toString(), inputFile.toString(), 'client got expected stream')
  })

  var nc2 = new NetcatClient()
  nc2.addr('127.0.0.1').port(2392).connect().pipe(concatStream)
})

test('Serving a stream using keepalive to multiple clients', function (t) {
  var nClients = 10 // 10 clients
  t.plan(nClients + 1)
  t.timeoutAfter(5000)
  var k = 0

  var testFile = path.join(__dirname, 'tcp.js')
  var inputFile = fs.readFileSync(testFile)
  var inputStream = fs.createReadStream(testFile)

  var nc = new NetcatServer()
  nc.port(2394).k().listen().serve(inputStream)

  var NCs = {}
  for (var i = 0; i < nClients; i++) {
    NCs[i] = new NetcatClient()
    NCs[i].addr('127.0.0.1').port(2394).connect().pipe(concat(function (file) {
      t.equal(file.toString(), inputFile.toString(), 'client got expected file')
      if (++k === nClients) {
        nc.close(function () {
          t.ok(true, 'server closed')
        })
      }
    }))
  }
})

test('Serving a raw Buffer', function (t) {
  t.plan(2)
  t.timeoutAfter(4000)

  var nc = new NetcatServer()
  nc.port(2392).listen().serve(Buffer.from('Hello World')).on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var concatStream = concat(function (buf) {
    t.equal(buf.toString(), 'Hello World', 'client got expected Buffer')
  })

  var nc2 = new NetcatClient()
  nc2.addr('127.0.0.1').port(2392).connect().pipe(concatStream)
})

test('Server exec()', function (t) {
  t.plan(3)
  t.timeoutAfter(5000)

  var cmd = (os.platform() === 'win32') ? 'type' : 'cat'

  var nc = new NetcatServer()
  nc.port(2400).listen()
  .exec(cmd)
  .on('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })
  t.equal(nc._exec, cmd, 'spawning process')

  var nc2 = new NetcatClient()
  nc2.port(2400).connect(function () {
    var self = this
    setTimeout(function () {
      self.send('Hello World')
    }, 1000)
  }).on('data', function (buf) { // one chunk
    t.equal(buf.toString(), 'Hello World', 'got expected stdout')
    nc2.close()
  })
})

test('Client exec()', function (t) {
  t.plan(5)
  t.timeoutAfter(5000)

  var cmd = (os.platform() === 'win32') ? 'type' : 'cat'

  var nc = new NetcatServer()
  nc.port(2401).listen()
  .once('connection', function (socket) {
    t.ok(socket, 'client connected')
    socket.write('Hello World')
  })
  .once('data', function (sock, buf) { // one chunk
    t.ok(sock, 'got socket istance')
    t.equal(buf.toString(), 'Hello World', 'got expected stdout')
    nc.close()
  })
  .once('srvClose', function () {
    t.ok(true, 'server closed (no keepalive)')
  })

  var nc2 = new NetcatClient()
  nc2.port(2401).exec(cmd).connect()
  t.equal(nc2._exec, cmd, 'exec set')
})

test('Proxy server', function (t) {
  t.plan(1)
  t.timeoutAfter(5000)

  var nc = new NetcatServer()
  var nc2 = new NetcatClient()
  var srv = new NetcatServer()
  var client = new NetcatClient()

  // target server
  srv.port(2222).serve(Buffer.from('Cool stuff')).listen()
  // proxy server
  nc2.addr('127.0.0.1').port(2222).connect()
  nc.port(8080).k().listen().proxy(nc2.stream())
  // client
  client.addr('127.0.0.1').port(8080).connect().on('data', function (d) {
    t.equal(d.toString(), 'Cool stuff', 'got expected data from proxy server')
    client.close()
    nc.close()
    nc2.close()
    srv.close()
  })
})
<|endoftext|>


<commit_before>/**
@module ember
@submodule ember-routing
*/

var get = Ember.get, set = Ember.set;
var popstateReady = false;

/**
  Ember.HistoryLocation implements the location API using the browser's
  history.pushState API.

  @class HistoryLocation
  @namespace Ember
  @extends Ember.Object
*/
Ember.HistoryLocation = Ember.Object.extend({

  init: function() {
    set(this, 'location', get(this, 'location') || window.location);
    this.initState();
  },

  /**
    @private

    Used to set state on first call to setURL

    @method initState
  */
  initState: function() {
    this.replaceState(get(this, 'location').pathname);
    set(this, 'history', window.history);
  },

  /**
    Will be pre-pended to path upon state change

    @property rootURL
    @default '/'
  */
  rootURL: '/',

  /**
    @private

    Returns the current `location.pathname`.

    @method getURL
  */
  getURL: function() {
    return get(this, 'location').pathname;
  },

  /**
    @private

    Uses `history.pushState` to update the url without a page reload.

    @method setURL
    @param path {String}
  */
  setURL: function(path) {
    path = this.formatURL(path);

    if (this.getState().path !== path) {
      popstateReady = true;
      this.pushState(path);
    }
  },

  /**
   @private

   Get the current `history.state`

   @method getState
  */
  getState: function() {
    return get(this, 'history').state;
  },

  /**
   @private

   Pushes a new state

   @method pushState
   @param path {String}
  */
  pushState: function(path) {
    window.history.pushState({ path: path }, null, path);
  },

  /**
   @private

   Replaces the current state

   @method replaceState
   @param path {String}
  */
  replaceState: function(path) {
    window.history.replaceState({ path: path }, null, path);
  },

  /**
    @private

    Register a callback to be invoked whenever the browser
    history changes, including using forward and back buttons.

    @method onUpdateURL
    @param callback {Function}
  */
  onUpdateURL: function(callback) {
    var guid = Ember.guidFor(this);

    Ember.$(window).bind('popstate.ember-location-'+guid, function(e) {
      if(!popstateReady) {
        return;
      }
      callback(location.pathname);
    });
  },

  /**
    @private

    Used when using `{{action}}` helper.  The url is always appended to the rootURL.

    @method formatURL
    @param url {String}
  */
  formatURL: function(url) {
    var rootURL = get(this, 'rootURL');

    if (url !== '') {
      rootURL = rootURL.replace(/\/$/, '');
    }

    return rootURL + url;
  },

  willDestroy: function() {
    var guid = Ember.guidFor(this);

    Ember.$(window).unbind('popstate.ember-location-'+guid);
  }
});

Ember.Location.registerImplementation('history', Ember.HistoryLocation);
<commit_msg>Update packages/ember-routing/lib/location/history_location.js<commit_after>/**
@module ember
@submodule ember-routing
*/

var get = Ember.get, set = Ember.set;
var popstateReady = false;

/**
  Ember.HistoryLocation implements the location API using the browser's
  history.pushState API.

  @class HistoryLocation
  @namespace Ember
  @extends Ember.Object
*/
Ember.HistoryLocation = Ember.Object.extend({

  init: function() {
    set(this, 'location', get(this, 'location') || window.location);
    this.initState();
  },

  /**
    @private

    Used to set state on first call to setURL

    @method initState
  */
  initState: function() {
    this.replaceState(get(this, 'location').pathname);
    set(this, 'history', window.history);
  },

  /**
    Will be pre-pended to path upon state change

    @property rootURL
    @default '/'
  */
  rootURL: '/',

  /**
    @private

    Returns the current `location.pathname`.

    @method getURL
  */
  getURL: function() {
    return get(this, 'location').pathname;
  },

  /**
    @private

    Uses `history.pushState` to update the url without a page reload.

    @method setURL
    @param path {String}
  */
  setURL: function(path) {
    path = this.formatURL(path);

    if (this.getState() && this.getState().path !== path) {
      popstateReady = true;
      this.pushState(path);
    }
  },

  /**
   @private

   Get the current `history.state`

   @method getState
  */
  getState: function() {
    return get(this, 'history').state;
  },

  /**
   @private

   Pushes a new state

   @method pushState
   @param path {String}
  */
  pushState: function(path) {
    window.history.pushState({ path: path }, null, path);
  },

  /**
   @private

   Replaces the current state

   @method replaceState
   @param path {String}
  */
  replaceState: function(path) {
    window.history.replaceState({ path: path }, null, path);
  },

  /**
    @private

    Register a callback to be invoked whenever the browser
    history changes, including using forward and back buttons.

    @method onUpdateURL
    @param callback {Function}
  */
  onUpdateURL: function(callback) {
    var guid = Ember.guidFor(this);

    Ember.$(window).bind('popstate.ember-location-'+guid, function(e) {
      if(!popstateReady) {
        return;
      }
      callback(location.pathname);
    });
  },

  /**
    @private

    Used when using `{{action}}` helper.  The url is always appended to the rootURL.

    @method formatURL
    @param url {String}
  */
  formatURL: function(url) {
    var rootURL = get(this, 'rootURL');

    if (url !== '') {
      rootURL = rootURL.replace(/\/$/, '');
    }

    return rootURL + url;
  },

  willDestroy: function() {
    var guid = Ember.guidFor(this);

    Ember.$(window).unbind('popstate.ember-location-'+guid);
  }
});

Ember.Location.registerImplementation('history', Ember.HistoryLocation);
<|endoftext|>


<commit_before>var wifi = require('node-wifi'); //require('../src/os/modules/wifi');

//Initialize wifi module
wifi.init({
    debug : true, //verbose output
    iface : null //set network interface
});

wifi.scan(function(err, networks) {
    if (err) {
        console.log(err);
    } else {
        console.log(networks);
    }
});

wifi.connect(function (err) {
    if (err) {
        console.log('wifi failed', err);
    } else {
        console.log('connected');
    }
});
<commit_msg>update test node-wifi<commit_after>var wifi = require('node-wifi'); //require('../src/os/modules/wifi');

//Initialize wifi module
wifi.init({
    iface : 'wlan0' //set network interface
});

wifi.scan(function(err, networks) {
    if (err) {
        console.log(err);
    } else {
        console.log(networks);
    }
});

/*
wifi.connect(function (err) {
    if (err) {
        console.log('wifi failed', err);
    } else {
        console.log('connected');
    }
});*/
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        sass: {
            options: {
                includePaths: ['components/foundation/scss']
            },
            dist: {
                options: {
                    outputStyle: 'compressed'
                },
                files: {
                    'css/app.css': 'scss/app.scss'
                }
            }
        },

        watch: {
            grunt: { files: ['Gruntfile.js'] },

            sass: {
                options: { livereload: true },
                files: 'scss/**/*.scss',
                tasks: ['sass']
            },

            html: {
                options: { livereload: true },
                files: '**/*.html'
            },

            js: {
                options: { livereload: true },
                files: 'js-source/**/*.js',
                tasks: ['uglify']
            }
        },

        open: {
            server: {
                path: 'http://localhost:9000'
            }
        },

        connect: {
            server: {
                options: {
                    port: 9000,
                    hostname: "*",
                    base: "./",
                    middleware: function (connect, options) {
                        var path = require('path');
                        return [
                            require('connect-livereload')(),
                            connect.static(path.resolve('.'))
                        ];
                    }
                }
            }
        },

        uglify: {
            js: {
                options: {
                    sourceMap: 'js/app.js.map'
                },
                files: {
                    'js/app.js': ['js-source/app.js']
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-open');
    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('build', ['sass', 'uglify']);
    grunt.registerTask('default', ['build', 'connect', 'open', 'watch']);
}<commit_msg>Fix path to source map for uglify task<commit_after>module.exports = function (grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        sass: {
            options: {
                includePaths: ['components/foundation/scss']
            },
            dist: {
                options: {
                    outputStyle: 'compressed'
                },
                files: {
                    'css/app.css': 'scss/app.scss'
                }
            }
        },

        watch: {
            grunt: { files: ['Gruntfile.js'] },

            sass: {
                options: { livereload: true },
                files: 'scss/**/*.scss',
                tasks: ['sass']
            },

            html: {
                options: { livereload: true },
                files: '**/*.html'
            },

            js: {
                options: { livereload: true },
                files: 'js-source/**/*.js',
                tasks: ['uglify']
            }
        },

        open: {
            server: {
                path: 'http://localhost:9000'
            }
        },

        connect: {
            server: {
                options: {
                    port: 9000,
                    hostname: "*",
                    base: "./",
                    middleware: function (connect, options) {
                        var path = require('path');
                        return [
                            require('connect-livereload')(),
                            connect.static(path.resolve('.'))
                        ];
                    }
                }
            }
        },

        uglify: {
            js: {
                options: {
                    sourceMap: 'js/app.js.map',
                    sourceMappingURL: './app.js.map'
                },
                files: {
                    'js/app.js': ['js-source/app.js']
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-contrib-connect');
    grunt.loadNpmTasks('grunt-open');
    grunt.loadNpmTasks('grunt-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-uglify');

    grunt.registerTask('build', ['sass', 'uglify']);
    grunt.registerTask('default', ['build', 'connect', 'open', 'watch']);
}
<|endoftext|>


<commit_before>var generators = require('yeoman-generator');
var mkdirp = require('mkdirp');

const WEB = 'Web';
const DESKTOP = 'Desktop';
const CLICK_ONCE = 'ClickOnce';
const WINDOWS_SERVICE = 'Windows Service';

module.exports = generators.Base.extend({
    constructor: function () {
        generators.Base.apply(this, arguments);

        this.installModule = function (name) {
            this.log('Installing ' + name + ' module...');
            this.spawnCommandSync('powershell', ['-Command', '&{ Save-Module ' + name + ' -Path ' + this.modulesPath + ' }']);
            this.log('OK');
        };
    },
    initializing: function () {
        this.modulesPath = this.destinationPath('scripts/modules');
        this.adminTasksEnabled = false;
    },
    prompting: function () {
        return this.prompt([{
            type: 'checkbox',
            name: 'projectTypes',
            message: 'Select all used project types:',
            choices: [WEB, DESKTOP, CLICK_ONCE, WINDOWS_SERVICE]
        }]).then(function (answers) {
            this.projectTypes = answers.projectTypes;

            if (this.projectTypes.indexOf(WEB) > -1) {
                return this.prompt({
                    type: 'confirm',
                    name: 'adminTasksEnabled',
                    message: 'Do you need admin tasks, remote management capabilities?',
                    default: true
                });
            }
        }.bind(this)).then(function (answers) {
            if (answers !== undefined) {
                this.adminTasksEnabled = answers.adminTasksEnabled;
            }
        }.bind(this));
    },
    writing: function () {
        mkdirp.sync(this.modulesPath);

        this.fs.copy(this.templatePath('default.ps1'), this.destinationPath('default.ps1'));
        this.fs.copy(this.templatePath('Scripts/Saritasa.PsakeTasks.ps1'), this.destinationPath('Scripts/Saritasa.PsakeTasks.ps1'));

        this.projectTypes = this.projectTypes || [];
        var webEnabled = this.projectTypes.indexOf(WEB) > -1;
        var desktopEnabled = this.projectTypes.indexOf(DESKTOP) > -1;
        var clickOnceEnabled = this.projectTypes.indexOf(CLICK_ONCE) > -1;
        var windowsServiceEnabled = this.projectTypes.indexOf(WINDOWS_SERVICE) > -1;

        this.installModule('Saritasa.Build');

        if (webEnabled) {
            this.installModule('Saritasa.WebDeploy');
        }

        if (clickOnceEnabled) {
            this.installModule('Saritasa.Publish');
        }

        if (desktopEnabled || windowsServiceEnabled) {
            this.installModule('Saritasa.AppDeploy');
        }

        if (this.adminTasksEnabled) {
            this.fs.copy(this.templatePath('Scripts/Saritasa.AdminTasks.ps1'), this.destinationPath('Scripts/Saritasa.AdminTasks.ps1'));
            this.installModule('Saritasa.RemoteManagement');
        }
    }
});
<commit_msg>Allow to install NewRelic, PRTG, Redis modules<commit_after>var generators = require('yeoman-generator');
var mkdirp = require('mkdirp');

const WEB = 'Web';
const DESKTOP = 'Desktop';
const CLICK_ONCE = 'ClickOnce';
const WINDOWS_SERVICE = 'Windows Service';

const NEWRELIC = 'NewRelic';
const PRTG = 'PRTG';
const REDIS = 'Redis';

module.exports = generators.Base.extend({
    constructor: function () {
        generators.Base.apply(this, arguments);

        this.installModule = function (name) {
            this.log('Installing ' + name + ' module...');
            this.spawnCommandSync('powershell', ['-Command', '&{ Save-Module ' + name + ' -Path ' + this.modulesPath + ' }']);
            this.log('OK');
        };
    },
    initializing: function () {
        this.modulesPath = this.destinationPath('scripts/modules');
        this.adminTasksEnabled = false;
    },
    prompting: function () {
        return this.prompt({
            type: 'checkbox',
            name: 'projectTypes',
            message: 'Select all used project types:',
            choices: [WEB, DESKTOP, CLICK_ONCE, WINDOWS_SERVICE]
        }).then(function (answers) {
            this.projectTypes = answers.projectTypes;

            if (this.projectTypes.indexOf(WEB) > -1) {
                return this.prompt([{
                    type: 'confirm',
                    name: 'adminTasksEnabled',
                    message: 'Do you need admin tasks, remote management capabilities?',
                    default: true
                }, {
                    type: 'checkbox',
                    name: 'webServices',
                    message: 'Select services which you want to control from PowerShell:',
                    choices: [NEWRELIC, PRTG, REDIS]
                }]);
            }
        }.bind(this)).then(function (answers) {
            if (answers !== undefined) {
                this.adminTasksEnabled = answers.adminTasksEnabled;
                this.webServices = answers.webServices;
            }
        }.bind(this));
    },
    writing: function () {
        mkdirp.sync(this.modulesPath);

        this.fs.copy(this.templatePath('default.ps1'), this.destinationPath('default.ps1'));
        this.fs.copy(this.templatePath('Scripts/Saritasa.PsakeTasks.ps1'), this.destinationPath('Scripts/Saritasa.PsakeTasks.ps1'));

        this.projectTypes = this.projectTypes || [];
        this.webServices = this.webServices || [];

        var webEnabled = this.projectTypes.indexOf(WEB) > -1;
        var desktopEnabled = this.projectTypes.indexOf(DESKTOP) > -1;
        var clickOnceEnabled = this.projectTypes.indexOf(CLICK_ONCE) > -1;
        var windowsServiceEnabled = this.projectTypes.indexOf(WINDOWS_SERVICE) > -1;

        this.installModule('Saritasa.Build');

        if (webEnabled) {
            this.installModule('Saritasa.WebDeploy');
        }

        if (clickOnceEnabled) {
            this.installModule('Saritasa.Publish');
        }

        if (desktopEnabled || windowsServiceEnabled) {
            this.installModule('Saritasa.AppDeploy');
        }

        if (this.adminTasksEnabled) {
            this.fs.copy(this.templatePath('Scripts/Saritasa.AdminTasks.ps1'), this.destinationPath('Scripts/Saritasa.AdminTasks.ps1'));
            this.installModule('Saritasa.RemoteManagement');
        }

        if (this.webServices.indexOf(NEWRELIC) > -1) {
            this.installModule('Saritasa.NewRelic');
        }

        if (this.webServices.indexOf(PRTG) > -1) {
            this.installModule('Saritasa.Prtg');
        }

        if (this.webServices.indexOf(REDIS) > -1) {
            this.installModule('Saritasa.Redis');
        }
    }
});
<|endoftext|>


<commit_before>module.exports = function (grunt) {
	require('grunt-dojo2').initConfig(grunt, {
		dtsGenerator: {
			options: {
				main: 'dojo-store-prototype/main'
			}
		}
	});
};
<commit_msg>Add grunt watch task registered as the default task.<commit_after>module.exports = function (grunt) {
	const gruntConfig = {
		dtsGenerator: {
			options: {
				main: 'dojo-store-prototype/main'
			}
		},
		watch: {
			dev: {
				files: '**/*.ts',
				tasks: ['dev'],
				options: {
					spawn: false
				}
			}
		}
	};
	grunt.initConfig(gruntConfig);
	require('grunt-dojo2').initConfig(grunt, gruntConfig);

	grunt.loadNpmTasks('grunt-contrib-watch');
};
<|endoftext|>


<commit_before>/*global module, process, require*/

"use strict";

var request = require("request");

module.exports = function(grunt) {
    var browsers = [
        {platform: "linux", browserName: "chrome", version: "36"},
        {platform: "linux", browserName: "chrome", version: "35"},
        {platform: "linux", browserName: "firefox", version: "31"},
        {platform: "linux", browserName: "firefox", version: "30"},
        {platform: "linux", browserName: "firefox", version: "29"},
        {platform: "WIN8.1", browserName: "firefox", version: "31"},
        {platform: "WIN8.1", browserName: "chrome", version: "36"},
        {platform: "WIN8.1", browserName: "internet explorer", version: "11"},
        {platform: "WIN8", browserName: "internet explorer", version: "10"},
        // {platform: "WIN7", browserName: "internet explorer", version: "9"},
        {platform: "WIN7", browserName: "internet explorer", version: "10"},
        // {platform: "VISTA", browserName: "internet explorer", version: "9"},
        {platform: "OS X 10.8", browserName: "safari", version: "6"},
        {platform: "OS X 10.8", browserName: "chrome", version: "35"},
        {platform: "OS X 10.9", browserName: "chrome", version: "35"},
        {platform: "OS X 10.9", browserName: "safari", version: "7"},
        {platform: "OS X 10.9", browserName: "firefox", version: "28"},
        {platform: "OS X 10.9", browserName: "firefox", version: "29"},
        {platform: "OS X 10.9", browserName: "firefox", version: "30"},
        {platform: "OS X 10.9", browserName: "iphone", version: "7.1"},
        {platform: "linux", browserName: "android", version: "4.3"},
        {platform: "linux", browserName: "android", version: "4.4"}
        ];

        grunt.initConfig({
            connect: {
                server: {
                    options: {
                        base: "",
                        port: 9999
                    }
                }
            },
            "saucelabs-jasmine": {
                all: {
                    options: {
                        urls: ["http://127.0.0.1:9999/jasmine/SpecRunner.html"],
                        tunnelTimeout: 5,
                        build: process.env.TRAVIS_JOB_ID,
                        concurrency: 3,
                        browsers: browsers,
                        capabilities: {
                            browserName: "chrome",
                            "chromeOptions":{
                                args: ["--test-type"]
                            }
                        },
                        testname: "iSat Unit tests",
                        tags: ["master"],
                        sauceConfig: {
                            "video-upload-on-pass": false
                        },
                        onTestComplete: function(result, cb){
                         // returning undefined doesn't alter the test result
                         //   but returning true or false does.
                         //   See: https://github.com/axemclion/grunt-saucelabs

                        var user = process.env.SAUCE_USERNAME;
                        var pass = process.env.SAUCE_ACCESS_KEY;
                        request.put({
                            url: ["https://saucelabs.com/rest/v1", user, "jobs", result.job_id].join("/"),
                            auth: { user: user, pass: pass },
                            json: { passed: !result.passed }
                        }, function (error, response, body) {
                          if (error) {
                            cb(error);
                        } else if (response.statusCode !== 200) {
                            cb(new Error("Unexpected response status:" + response.statusCode));
                        } else {
                            cb(null, !result.passed);
                        }
                        body=body; // Shuts up JSHint
                    });
                        // if (result.passed === false) {
                        //     cb(null, true);
                        // } else {
                        //    cb(null,undefined);
                        // }
                    }
                }
            }
        },
        watch: {}
    });

    // Loading dependencies
    for (var key in grunt.file.readJSON("package.json").devDependencies) {
        if (key !== "grunt" && key.indexOf("grunt") === 0) grunt.loadNpmTasks(key);
    }

    grunt.registerTask("dev", ["connect", "watch"]);
    grunt.registerTask("test", ["connect", "saucelabs-jasmine"]);
};
<commit_msg>Try increasing timeout - sgp4Spec still not finishing. #162<commit_after>/*global module, process, require*/

"use strict";

var request = require("request");

module.exports = function(grunt) {
    var browsers = [
        {platform: "linux", browserName: "chrome", version: "36"},
        {platform: "linux", browserName: "chrome", version: "35"},
        {platform: "linux", browserName: "firefox", version: "31"},
        {platform: "linux", browserName: "firefox", version: "30"},
        {platform: "linux", browserName: "firefox", version: "29"},
        {platform: "WIN8.1", browserName: "firefox", version: "31"},
        {platform: "WIN8.1", browserName: "chrome", version: "36"},
        {platform: "WIN8.1", browserName: "internet explorer", version: "11"},
        {platform: "WIN8", browserName: "internet explorer", version: "10"},
        // {platform: "WIN7", browserName: "internet explorer", version: "9"},
        {platform: "WIN7", browserName: "internet explorer", version: "10"},
        // {platform: "VISTA", browserName: "internet explorer", version: "9"},
        {platform: "OS X 10.8", browserName: "safari", version: "6"},
        {platform: "OS X 10.8", browserName: "chrome", version: "35"},
        {platform: "OS X 10.9", browserName: "chrome", version: "35"},
        {platform: "OS X 10.9", browserName: "safari", version: "7"},
        {platform: "OS X 10.9", browserName: "firefox", version: "28"},
        {platform: "OS X 10.9", browserName: "firefox", version: "29"},
        {platform: "OS X 10.9", browserName: "firefox", version: "30"},
        {platform: "OS X 10.9", browserName: "iphone", version: "7.1"},
        {platform: "linux", browserName: "android", version: "4.3"},
        {platform: "linux", browserName: "android", version: "4.4"}
        ];

        grunt.initConfig({
            connect: {
                server: {
                    options: {
                        base: "",
                        port: 9999
                    }
                }
            },
            "saucelabs-jasmine": {
                all: {
                    options: {
                        urls: ["http://127.0.0.1:9999/jasmine/SpecRunner.html"],
                        tunnelTimeout: 5,
                        build: process.env.TRAVIS_JOB_ID,
                        concurrency: 3,
                        browsers: browsers,
                        capabilities: {
                            browserName: "chrome",
                            "chromeOptions":{
                                args: ["--test-type"]
                            }
                        },
                        testname: "iSat Unit tests",
                        tags: ["master"],
                        sauceConfig: {
                            "video-upload-on-pass": false,
                            "idle-timeout": 600
                        },
                        onTestComplete: function(result, cb){
                         // returning undefined doesn't alter the test result
                         //   but returning true or false does.
                         //   See: https://github.com/axemclion/grunt-saucelabs

                        var user = process.env.SAUCE_USERNAME;
                        var pass = process.env.SAUCE_ACCESS_KEY;
                        request.put({
                            url: ["https://saucelabs.com/rest/v1", user, "jobs", result.job_id].join("/"),
                            auth: { user: user, pass: pass },
                            json: { passed: !result.passed }
                        }, function (error, response, body) {
                          if (error) {
                            cb(error);
                        } else if (response.statusCode !== 200) {
                            cb(new Error("Unexpected response status:" + response.statusCode));
                        } else {
                            cb(null, !result.passed);
                        }
                        body=body; // Shuts up JSHint
                    });
                        // if (result.passed === false) {
                        //     cb(null, true);
                        // } else {
                        //    cb(null,undefined);
                        // }
                    }
                }
            }
        },
        watch: {}
    });

    // Loading dependencies
    for (var key in grunt.file.readJSON("package.json").devDependencies) {
        if (key !== "grunt" && key.indexOf("grunt") === 0) grunt.loadNpmTasks(key);
    }

    grunt.registerTask("dev", ["connect", "watch"]);
    grunt.registerTask("test", ["connect", "saucelabs-jasmine"]);
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
;(function() {
  'use strict';

  /** Load Node modules */
  var execFile = require('child_process').execFile,
      fs = require('fs'),
      https = require('https'),
      path = require('path'),
      tar = require('../vendor/tar/tar.js'),
      zlib = require('zlib');

  /** The path of the directory that is the base of the repository */
  var basePath = fs.realpathSync(path.join(__dirname, '..'));

  /** The path of the `vendor` directory */
  var vendorPath = path.join(basePath, 'vendor');

  /** The Git object ID of `closure-compiler.tar.gz` */
  var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';

  /** The Git object ID of `uglifyjs.tar.gz` */
  var uglifyId = '505f1be36ef60fd25a992a522f116d5179ab317f';

  /** The media type for raw blob data */
  var mediaType = 'application/vnd.github.v3.raw';

  /** Used to reference parts of the blob href */
  var location = (function() {
    var host = 'api.github.com',
        origin = 'https://api.github.com',
        pathname = '/repos/bestiejs/lodash/git/blobs';

    return {
      'host': host,
      'href': host + origin + pathname,
      'origin': origin,
      'pathname': pathname
    };
  }());

  /** The message to display when the install mode is undetectable */
  var oopsMessage = [
    'Oops! There was a problem detecting the install mode. If you’re installing the',
    'Lo-Dash command-line executable (via `npm install -g lodash`), you’ll need to',
    'manually install UglifyJS and the Closure Compiler by running:',
    '',
    "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
    "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId  + " | tar xvz -C '" + vendorPath + "'",
    '',
    'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
  ].join('\n');

  /** Reassign `existsSync` for older versions of Node */
  fs.existsSync || (fs.existsSync = path.existsSync);

  /*--------------------------------------------------------------------------*/

  /**
   * Fetches a required `.tar.gz` dependency with the given Git object ID from
   * the Lo-Dash repo on GitHub. The object ID may be obtained by running
   * `git hash-object path/to/dependency.tar.gz`.
   *
   * @private
   * @param {Object} options The options object.
   *  id - The Git object ID of the `.tar.gz` file.
   *  onComplete - The function, invoked with one argument (exception),
   *   called once the extraction has finished.
   *  path - The path of the extraction directory.
   *  title - The dependency's title used in status updates logged to the console.
   */
  function getDependency(options) {
    options || (options = {});

    var id = options.id,
        onComplete = options.onComplete,
        path = options.path,
        title = options.title;

    function callback(exception) {
      if (exception) {
        console.error([
          'There was a problem installing ' + title + '. To manually install, run:',
          '',
          "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
        ].join('\n'));
      }
      onComplete(exception);
    }

    console.log('Downloading ' + title + '...');

    https.get({
      'host': location.host,
      'path': location.pathname + '/' + id,
      'headers': {
        // By default, all GitHub blob API endpoints return a JSON document
        // containing Base64-encoded blob data. Overriding the `Accept` header
        // with the GitHub raw media type returns the blob data directly.
        // See http://developer.github.com/v3/media/.
        'Accept': mediaType
      }
    }, function(response) {
      var decompressor = zlib.createUnzip(),
          parser = new tar.Extract({ 'path': path });

      decompressor.on('error', callback)
      parser.on('end', callback).on('error', callback);
      response.pipe(decompressor).pipe(parser);
    })
    .on('error', callback);
  }

  /**
   * The `child_process.execFile` callback.
   *
   * @private
   * @param {Object|Undefined} exception The error object.
   * @param {String} stdout The stdout buffer.
   */
  function onExecFile(exception, stdout) {
    if (!exception) {
      try {
        var root = stdout.trim(),
            isGlobal = fs.existsSync(root) && path.resolve(basePath, '..') == fs.realpathSync(root);
      } catch(e) {
        exception = e;
      }
    }
    if (exception) {
      console.error(oopsMessage);
      console.error(exception);
    }
    if (!isGlobal) {
      return;
    }
    // download the Closure Compiler
    getDependency({
      'title': 'the Closure Compiler',
      'id': closureId,
      'path': vendorPath,
      'onComplete': function() {
        // download UglifyJS
        getDependency({
          'title': 'UglifyJS',
          'id': uglifyId,
          'path': vendorPath,
          'onComplete': function() {
            process.exit();
          }
        });
      }
    });
  }

  /*--------------------------------------------------------------------------*/

  try {
    execFile('npm', [ '-g', 'root' ], onExecFile);
  } catch(e) {
    console.error(oopsMessage);
    console.error(e);
  }
}());
<commit_msg>Correct `href` value in post-install.js.<commit_after>#!/usr/bin/env node
;(function() {
  'use strict';

  /** Load Node modules */
  var execFile = require('child_process').execFile,
      fs = require('fs'),
      https = require('https'),
      path = require('path'),
      tar = require('../vendor/tar/tar.js'),
      zlib = require('zlib');

  /** The path of the directory that is the base of the repository */
  var basePath = fs.realpathSync(path.join(__dirname, '..'));

  /** The path of the `vendor` directory */
  var vendorPath = path.join(basePath, 'vendor');

  /** The Git object ID of `closure-compiler.tar.gz` */
  var closureId = 'a2787b470c577cee2404d186c562dd9835f779f5';

  /** The Git object ID of `uglifyjs.tar.gz` */
  var uglifyId = '505f1be36ef60fd25a992a522f116d5179ab317f';

  /** The media type for raw blob data */
  var mediaType = 'application/vnd.github.v3.raw';

  /** Used to reference parts of the blob href */
  var location = (function() {
    var host = 'api.github.com',
        origin = 'https://api.github.com',
        pathname = '/repos/bestiejs/lodash/git/blobs';

    return {
      'host': host,
      'href': origin + pathname,
      'origin': origin,
      'pathname': pathname
    };
  }());

  /** The message to display when the install mode is undetectable */
  var oopsMessage = [
    'Oops! There was a problem detecting the install mode. If you’re installing the',
    'Lo-Dash command-line executable (via `npm install -g lodash`), you’ll need to',
    'manually install UglifyJS and the Closure Compiler by running:',
    '',
    "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + closureId + " | tar xvz -C '" + vendorPath + "'",
    "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + uglifyId  + " | tar xvz -C '" + vendorPath + "'",
    '',
    'Please submit an issue on the GitHub issue tracker: ' + process.env.npm_package_bugs_url
  ].join('\n');

  /** Reassign `existsSync` for older versions of Node */
  fs.existsSync || (fs.existsSync = path.existsSync);

  /*--------------------------------------------------------------------------*/

  /**
   * Fetches a required `.tar.gz` dependency with the given Git object ID from
   * the Lo-Dash repo on GitHub. The object ID may be obtained by running
   * `git hash-object path/to/dependency.tar.gz`.
   *
   * @private
   * @param {Object} options The options object.
   *  id - The Git object ID of the `.tar.gz` file.
   *  onComplete - The function, invoked with one argument (exception),
   *   called once the extraction has finished.
   *  path - The path of the extraction directory.
   *  title - The dependency's title used in status updates logged to the console.
   */
  function getDependency(options) {
    options || (options = {});

    var id = options.id,
        onComplete = options.onComplete,
        path = options.path,
        title = options.title;

    function callback(exception) {
      if (exception) {
        console.error([
          'There was a problem installing ' + title + '. To manually install, run:',
          '',
          "curl -H 'Accept: " + mediaType + "' " + location.href + '/' + id + " | tar xvz -C '" + path + "'"
        ].join('\n'));
      }
      onComplete(exception);
    }

    console.log('Downloading ' + title + '...');

    https.get({
      'host': location.host,
      'path': location.pathname + '/' + id,
      'headers': {
        // By default, all GitHub blob API endpoints return a JSON document
        // containing Base64-encoded blob data. Overriding the `Accept` header
        // with the GitHub raw media type returns the blob data directly.
        // See http://developer.github.com/v3/media/.
        'Accept': mediaType
      }
    }, function(response) {
      var decompressor = zlib.createUnzip(),
          parser = new tar.Extract({ 'path': path });

      decompressor.on('error', callback)
      parser.on('end', callback).on('error', callback);
      response.pipe(decompressor).pipe(parser);
    })
    .on('error', callback);
  }

  /**
   * The `child_process.execFile` callback.
   *
   * @private
   * @param {Object|Undefined} exception The error object.
   * @param {String} stdout The stdout buffer.
   */
  function onExecFile(exception, stdout) {
    if (!exception) {
      try {
        var root = stdout.trim(),
            isGlobal = fs.existsSync(root) && path.resolve(basePath, '..') == fs.realpathSync(root);
      } catch(e) {
        exception = e;
      }
    }
    if (exception) {
      console.error(oopsMessage);
      console.error(exception);
    }
    if (!isGlobal) {
      return;
    }
    // download the Closure Compiler
    getDependency({
      'title': 'the Closure Compiler',
      'id': closureId,
      'path': vendorPath,
      'onComplete': function() {
        // download UglifyJS
        getDependency({
          'title': 'UglifyJS',
          'id': uglifyId,
          'path': vendorPath,
          'onComplete': function() {
            process.exit();
          }
        });
      }
    });
  }

  /*--------------------------------------------------------------------------*/

  try {
    execFile('npm', [ '-g', 'root' ], onExecFile);
  } catch(e) {
    console.error(oopsMessage);
    console.error(e);
  }
}());
<|endoftext|>


<commit_before>import React from 'react'
import moment from 'moment'
import { Grid, Row, Col, Button, Table, Input, Panel, Glyphicon, Badge, ButtonInput, form } from 'react-bootstrap'
import { Link, browserHistory } from 'react-router'
import { LinkContainer } from 'react-router-bootstrap'
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table'
import RegionSearch from './RegionSearch'

import PublicPage from './PublicPage'
import FeedsMap from './FeedsMap'

export default class PublicFeedsViewer extends React.Component {

  constructor (props) {
    super(props)
    this.state = {

    }
  }

  componentWillMount () {
    this.props.onComponentMount(this.props)
  }

  render () {
    if (!this.props.projects) {
      return <PublicPage />
    }
    let position = this.state.position
    let explore =
      <Row>
        <Col xs={12} sm={6} md={4}>
          Explore Transit Data
        </Col>
        <Col xs={12} sm={6} md={4}>
          <Input type='text' bsSize='large' placeholder='Search for regions or agencies' />
        </Col>
      </Row>
    let exploreHeader =

        Explore Transit Data
        <Input style={{width: '300px'}} type='text' bsSize='large' placeholder='Search for regions or agencies' />

    let feeds = []
    const feedArray = this.props.projects.map(p => {
      const regions = p.name.split(', ')
      if (p.feedSources) {
        return p.feedSources.map(f => {
          feeds.push(f)
          return f
        })
      }
    })
    return (
      <PublicPage ref='publicPage'>
        <Grid>
          <Row>
            <Col xs={12} sm={6} md={4}>
              <RegionSearch
                feeds={feeds}
                limit={100}
                entities={['regions', 'feeds']}
                minimumInput={0}
                bsSize='large'
                clearable={true}
                onChange={(evt) => {
                  console.log(evt)
                  if (evt && evt.region) {
                    this.setState({
                      position: [evt.region.lat, evt.region.lon],
                      bounds: [[evt.region.north, evt.region.east], [evt.region.south, evt.region.west]]
                    })
                  }
                  if (evt && evt.feed) {
                    browserHistory.push('/public/feed/' + evt.feed.id)
                  }
                  else if (evt == null)
                    this.setState({position: null, bounds: null})
                }}
              />
            </Col>
          </Row>
        </Grid>
        <FeedsMap
          projects={this.props.projects}
          onFeedClick={(feedId) => browserHistory.push('/public/feed/' + feedId) }
          bounds={this.state.bounds}
        />
        <Grid>
          <Row>
            <Col xs={12}>

            </Col>
          </Row>
          <Row>
            <Col xs={12}>
              {!DT_CONFIG.extensions.mtc.enabled
                ? <FeedTable projects={this.props.projects} />
                : null
              }

            </Col>
          </Row>
        </Grid>
      </PublicPage>
    )
  }
}

class FeedTable extends React.Component {
  feedFormat (cell, row) {
    return cell ? <Link to={'/public/feed/' + row.id}>{cell}</Link> : ''
  }
  dateFormat (cell, row) {
    return cell ? moment(cell).format('MMMM Do YYYY, h:mm a') : ''
  }

  urlFormat (cell, row) {
    return cell ? <Glyphicon glyph='new-window' /> : ''
  }

  dateSort (a, b, order) {
    return b.lastUpdated - a.lastUpdated
  }

  constructor (props) {
    super(props)
  }

  render () {
    let feeds = []
    const feedArray = this.props.projects.map(p => {
      const regions = p.name.split(', ')
      if (p.feedSources) {
        return p.feedSources.map(f => {
          const feed = {
            name: f.name,
            id: f.id,
            lastUpdated: moment(f.lastUpdated).format('MMMM Do YYYY, h:mm a'),
            region: regions[regions.length - 3],
            state: regions[regions.length - 2],
            country: regions[regions.length - 1],
            url: f.url
          }
          feeds.push(feed)
          return feed
        })
      }
    })
    return  (
      <BootstrapTable
        data={feeds}
        pagination={true}
        striped={true}
        hover={true}
        search={true}
      >
        <TableHeaderColumn isKey={true} dataSort={true} hidden={true} dataField='id'>Feed ID</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='name' dataFormat={this.feedFormat}>Feed Name</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='region'>Region</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='state'>State or Province</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='country'>Country</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='lastUpdated' sortFunc={this.dateSort}>Last Updated</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='lastUpdated' hidden={true}>last_update</TableHeaderColumn>
        <TableHeaderColumn dataField='url' dataFormat={this.urlFormat}>Link to GTFS</TableHeaderColumn>
      </BootstrapTable>
    )
  }
}

class FeedRow extends React.Component {

  constructor (props) {
    super(props)
  }

  render () {
    var buttons;
    if (this.props.feed.url){
      // buttons = <Button {this.props.feed.url ? disabled} href={this.props.feed.url}><Glyphicon glyph="new-window" /></Button>
    }
    return (

        {this.props.feed.name}
        {moment(this.props.feed.lastUpdated).format('MMMM Do YYYY, h:mm:ss a')}

          <Button disabled={this.props.feed.url ? false : true} href={this.props.feed.url}><Glyphicon glyph="new-window" /></Button>
          <Button href="http://localhost:9001/"><Glyphicon glyph="edit" /></Button>

    )
  }
}
<commit_msg>fix public feeds bug (missing mtc config)<commit_after>import React from 'react'
import moment from 'moment'
import { Grid, Row, Col, Button, Table, Input, Panel, Glyphicon, Badge, ButtonInput, form } from 'react-bootstrap'
import { Link, browserHistory } from 'react-router'
import { LinkContainer } from 'react-router-bootstrap'
import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table'
import RegionSearch from './RegionSearch'

import PublicPage from './PublicPage'
import FeedsMap from './FeedsMap'

export default class PublicFeedsViewer extends React.Component {

  constructor (props) {
    super(props)
    this.state = {

    }
  }

  componentWillMount () {
    this.props.onComponentMount(this.props)
  }

  render () {
    if (!this.props.projects) {
      return <PublicPage />
    }
    let position = this.state.position
    let explore =
      <Row>
        <Col xs={12} sm={6} md={4}>
          Explore Transit Data
        </Col>
        <Col xs={12} sm={6} md={4}>
          <Input type='text' bsSize='large' placeholder='Search for regions or agencies' />
        </Col>
      </Row>
    let exploreHeader =

        Explore Transit Data
        <Input style={{width: '300px'}} type='text' bsSize='large' placeholder='Search for regions or agencies' />

    let feeds = []
    const feedArray = this.props.projects.map(p => {
      const regions = p.name.split(', ')
      if (p.feedSources) {
        return p.feedSources.map(f => {
          feeds.push(f)
          return f
        })
      }
    })
    return (
      <PublicPage ref='publicPage'>
        <Grid>
          <Row>
            <Col xs={12} sm={6} md={4}>
              <RegionSearch
                feeds={feeds}
                limit={100}
                entities={['regions', 'feeds']}
                minimumInput={0}
                bsSize='large'
                clearable={true}
                onChange={(evt) => {
                  console.log(evt)
                  if (evt && evt.region) {
                    this.setState({
                      position: [evt.region.lat, evt.region.lon],
                      bounds: [[evt.region.north, evt.region.east], [evt.region.south, evt.region.west]]
                    })
                  }
                  if (evt && evt.feed) {
                    browserHistory.push('/public/feed/' + evt.feed.id)
                  }
                  else if (evt == null)
                    this.setState({position: null, bounds: null})
                }}
              />
            </Col>
          </Row>
        </Grid>
        <FeedsMap
          projects={this.props.projects}
          onFeedClick={(feedId) => browserHistory.push('/public/feed/' + feedId) }
          bounds={this.state.bounds}
        />
        <Grid>
          <Row>
            <Col xs={12}>

            </Col>
          </Row>
          <Row>
            <Col xs={12}>
              {DT_CONFIG.extensions.mtc && DT_CONFIG.extensions.mtc.enabled
                ? null
                : <FeedTable projects={this.props.projects} />
              }

            </Col>
          </Row>
        </Grid>
      </PublicPage>
    )
  }
}

class FeedTable extends React.Component {
  feedFormat (cell, row) {
    return cell ? <Link to={'/public/feed/' + row.id}>{cell}</Link> : ''
  }
  dateFormat (cell, row) {
    return cell ? moment(cell).format('MMMM Do YYYY, h:mm a') : ''
  }

  urlFormat (cell, row) {
    return cell ? <Glyphicon glyph='new-window' /> : ''
  }

  dateSort (a, b, order) {
    return b.lastUpdated - a.lastUpdated
  }

  constructor (props) {
    super(props)
  }

  render () {
    let feeds = []
    const feedArray = this.props.projects.map(p => {
      const regions = p.name.split(', ')
      if (p.feedSources) {
        return p.feedSources.map(f => {
          const feed = {
            name: f.name,
            id: f.id,
            lastUpdated: moment(f.lastUpdated).format('MMMM Do YYYY, h:mm a'),
            region: regions[regions.length - 3],
            state: regions[regions.length - 2],
            country: regions[regions.length - 1],
            url: f.url
          }
          feeds.push(feed)
          return feed
        })
      }
    })
    return  (
      <BootstrapTable
        data={feeds}
        pagination={true}
        striped={true}
        hover={true}
        search={true}
      >
        <TableHeaderColumn isKey={true} dataSort={true} hidden={true} dataField='id'>Feed ID</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='name' dataFormat={this.feedFormat}>Feed Name</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='region'>Region</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='state'>State or Province</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='country'>Country</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='lastUpdated' sortFunc={this.dateSort}>Last Updated</TableHeaderColumn>
        <TableHeaderColumn dataSort={true} dataField='lastUpdated' hidden={true}>last_update</TableHeaderColumn>
        <TableHeaderColumn dataField='url' dataFormat={this.urlFormat}>Link to GTFS</TableHeaderColumn>
      </BootstrapTable>
    )
  }
}

class FeedRow extends React.Component {

  constructor (props) {
    super(props)
  }

  render () {
    var buttons;
    if (this.props.feed.url){
      // buttons = <Button {this.props.feed.url ? disabled} href={this.props.feed.url}><Glyphicon glyph="new-window" /></Button>
    }
    return (

        {this.props.feed.name}
        {moment(this.props.feed.lastUpdated).format('MMMM Do YYYY, h:mm:ss a')}

          <Button disabled={this.props.feed.url ? false : true} href={this.props.feed.url}><Glyphicon glyph="new-window" /></Button>
          <Button href="http://localhost:9001/"><Glyphicon glyph="edit" /></Button>

    )
  }
}
<|endoftext|>


<commit_before>// namespace for this "module"
var Newgame = {
  'activity': {},
};

////////////////////////////////////////////////////////////////////////
// Action flow through this page:
// * Newgame.showNewgamePage() is the landing function.  Always call
//   this first
// * Newgame.getNewgameOptions() asks the API for information about players
//   and buttons to be used when creating the game.  It clobbers
//   Newgame.api.  If successful, it calls
// * Newgame.showStatePage() determines what action to take next based on
//   the received data from getNewgameOptions().  It calls one of several
//   functions, Newgame.action<SomeAction>()
// * each Newgame.action<SomeAction>() function must set Newgame.page and
//   Newgame.form, then call Newgame.layoutPage()
// * Newgame.layoutPage() sets the contents of

//   on the live page
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
// GENERIC FUNCTIONS: these do not depend on the action being taken

Newgame.showNewgamePage = function() {

  // Setup necessary elements for displaying status messages
  $.getScript('js/Env.js');
  Env.setupEnvStub();

  // Make sure the div element that we will need exists in the page body
  if ($('#newgame_page').length === 0) {
    $('body').append($('
', {'id': 'newgame_page', }));
  }

  // Get all needed information, then display newgame page
  Newgame.getNewgameData(Newgame.showPage);

};

Newgame.getNewgameData = function(callback) {
  if (Login.logged_in) {

    Api.getButtonData(function() {
      Api.getPlayerData(callback);
    });
  } else {

    // The player needs to be logged in for anything good to happen here
    Newgame.actionLoggedOut();
  }
};

// This function is called after Api.player has been loaded with new data
Newgame.showPage = function() {
  if ((Api.button.load_status == 'ok') && (Api.player.load_status == 'ok')) {
    Newgame.actionCreateGame();
  } else {
    Newgame.actionInternalErrorPage();
  }
};

// Actually lay out the page
Newgame.layoutPage = function() {

  // If there is a message from a current or previous invocation of this
  // page, display it now
  Env.showStatusMessage();

  $('#newgame_page').empty();
  $('#newgame_page').append(Newgame.page);

  if (Newgame.form) {
    $('#newgame_action_button').click(Newgame.form);
  }
};

////////////////////////////////////////////////////////////////////////
// This section contains one page for each type of next action used for
// flow through the page being laid out by Newgame.js.
// Each function should start by populating Newgame.page and Newgame.form
// ane end by invoking Newgame.layoutPage();

Newgame.actionLoggedOut = function() {

  // Create empty page and undefined form objects to be filled later
  Newgame.page = $('
');
  Newgame.form = null;

  // Add the "logged out player" HTML contents
  Newgame.addLoggedOutPage();

  // Lay out the page
  Newgame.layoutPage();
};

Newgame.actionInternalErrorPage = function() {

  // Create empty page and undefined form objects to be filled later
  Newgame.page = $('
');
  Newgame.form = null;

  // Add the internal error HTML contents
  Newgame.addInternalErrorPage();

  // Lay out the page
  Newgame.layoutPage();
};

Newgame.actionCreateGame = function() {

  // Create empty page and undefined form objects to be filled later
  Newgame.page = $('
');
  Newgame.form = null;

  var creatediv = $('
');
  creatediv.append($('
', {
    'class': 'title2',
    'text': 'Create a new game',
  }));
  var createform = $('<form>', {
    'id': 'newgame_action_form',
    'action': 'javascript:void(0);',
  });

  // Table of game creation options
  var createtable = $('
', {'id': 'newgame_create_table', });

  var playerRow = $('
');
  playerRow.append($('', {'text': 'You:', }));
  playerRow.append($('', {'text': Login.player, }));
  createtable.append(playerRow);

  // Setup opponent choice, including autocomplete from a dropdown
  // FIXME: i couldn't get autocomplete to display properly, so
  // temporarily used a select for the opponent name
  var playerNames = {};
  for (var playerName in Api.player.list) {
    if ((playerName != Login.player) &&
        (Api.player.list[playerName].status == 'active')) {
      playerNames[playerName] = playerName;
    }
  }
  if (!('opponentName' in Newgame.activity)) {
    Newgame.activity.opponentName = null;
  }
  createtable.append(
    Newgame.getSelectRow('Opponent', 'opponent_name', playerNames,
                         null, Newgame.activity.opponentName));

  // Load buttons and recipes into a dict for use in selects
  var buttonRecipe = {};
  var buttonGreyed = {};
  var anyUnimplementedButtons = false;
  $.each(Api.button.list, function(button, buttoninfo) {
    if (buttoninfo.hasUnimplementedSkill) {
      buttonRecipe[button] = '-- ' + button + ': ' + buttoninfo.recipe;
      buttonGreyed[button] = true;
      anyUnimplementedButtons = true;
    } else {
      buttonRecipe[button] = button + ': ' + buttoninfo.recipe;
      buttonGreyed[button] = false;
    }
  });

  // Player button selection
  if (!('playerButton' in Newgame.activity)) {
    Newgame.activity.playerButton = null;
  }
  createtable.append(
    Newgame.getSelectRow(
      'Your button', 'player_button', buttonRecipe,
      buttonGreyed, Newgame.activity.playerButton));

  // Opponent button selection
  if (!('opponentButton' in Newgame.activity)) {
    Newgame.activity.opponentButton = null;
  }
  createtable.append(
    Newgame.getSelectRow(
      'Opponent\'s button', 'opponent_button', buttonRecipe,
      buttonGreyed, Newgame.activity.opponentButton));

  // Round selection
  if (!('nRounds' in Newgame.activity)) {
    Newgame.activity.nRounds = '3';
  }
  createtable.append(
    Newgame.getSelectRow('Winner is first player to win', 'n_rounds',
      {'1': '1 round', '2': '2 rounds', '3': '3 rounds',
       '4': '4 rounds', '5': '5 rounds', },
      null, Newgame.activity.nRounds));

  // Form submission button
  createform.append(createtable);
  createform.append($('
'));
  createform.append($('<button>', {
    'id': 'newgame_action_button',
    'text': 'Create game!',
  }));
  creatediv.append(createform);

  Newgame.page.append(creatediv);

  if (anyUnimplementedButtons) {
    var warningpar = $('
');
    warningpar.append($('', {
      'text': 'Note to testers: buttons whose names are prefixed with "--" ' +
              'contain unimplemented skills.  Selecting these buttons is not ' +
              'recommended.'
    }));
    Newgame.page.append(warningpar);
  }

  // Function to invoke on button click
  Newgame.form = Newgame.formCreateGame;

  // Lay out the page
  Newgame.layoutPage();
};

////////////////////////////////////////////////////////////////////////
// These functions define form submissions, one per action type

Newgame.formCreateGame = function() {

  Newgame.activity.opponentName = $('#opponent_name').val();
  Newgame.activity.playerButton = $('#player_button').val();
  Newgame.activity.opponentButton = $('#opponent_button').val();

// james: for Jota, for an open game, you want less validation here, more like:
// var validSelect = Newgame.activity.playerButton;
//  if (!validSelect) {
//    Env.message = {
//      'type': 'error',
//      'text':
//        'Please select your button',
//    };
//    Newgame.showNewgamePage();
//  }  else if (!(Newgame.activity.opponentName in Api.player.list) &&
//
// attn:Jota here, you'll need a check explicitly allowing empty opponent names
//
//              ) {
//   Env.message = {
//     'type': 'error',
//     'text': 'Specified opponent ' + Newgame.activity.opponentName +
//             ' is not recognized',
//   };
//   Newgame.showNewgamePage();
// ...

  var validSelect = Newgame.activity.opponentName &&
                    Newgame.activity.opponentButton &&
                    Newgame.activity.playerButton;

  if (!validSelect) {
    Env.message = {
      'type': 'error',
      'text':
        'Please select an opponent, your button, and your opponent\'s button',
    };
    Newgame.showNewgamePage();
  }  else if (!(Newgame.activity.opponentName in Api.player.list)) {
   Env.message = {
     'type': 'error',
     'text': 'Specified opponent ' + Newgame.activity.opponentName +
             ' is not recognized',
   };
   Newgame.showNewgamePage();

  } else {
    var playerNameArray = [
      Login.player,
      Newgame.activity.opponentName,
    ];
    var buttonNameArray = [
      Newgame.activity.playerButton,
      Newgame.activity.opponentButton,
    ];

    Newgame.activity.nRounds = $('#n_rounds').val();

    // N.B. Newgame.activity is always retained between loads: on
    // failure so the player can correct selections, on success in
    // case the player wants to create another similar game.
    // Therefore, it's fine to pass the form post the same function
    // (showNewgamePage) for both success and failure conditions.
    Api.apiFormPost(
      {
        type: 'createGame',
        playerNameArray: playerNameArray,
        buttonNameArray: buttonNameArray,
        maxWins: Newgame.activity.nRounds,
      },
      { 'ok':
        {
          'type': 'function',
          'msgfunc': Newgame.setCreateGameSuccessMessage,
        },
        'notok': { 'type': 'server', },
      },
      'newgame_action_button',
      Newgame.showNewgamePage,
      Newgame.showNewgamePage
    );
  }
};

////////////////////////////////////////////////////////////////////////
// These functions add pieces of HTML to Newgame.page

Newgame.addLoggedOutPage = function() {
  var errorDiv = $('
');
  errorDiv.append($('
', {
    'text': 'Can\'t create a game because you are not logged in',
  }));
  Newgame.page.append(errorDiv);
};

Newgame.addInternalErrorPage = function() {
  var errorDiv = $('
');
  errorDiv.append($('
', {
    'text': 'Can\'t create a game.  Something went wrong when ' +
            'loading data from server.',
  }));
  Newgame.page.append(errorDiv);
};

Newgame.setCreateGameSuccessMessage = function(message, data) {
  var gameId = data.gameId;
  var gameLink = $('', {
    'href': 'game.html?game=' + gameId,
    'text': 'Go to game page',
  });
  var gamePar = $('
', {'text': message + ' ', });
  gamePar.append(gameLink);
  Env.message = {
    'type': 'success',
    'text': '',
    'obj': gamePar,
  };
};

////////////////////////////////////////////////////////////////////////
// These functions generate and return pieces of HTML

Newgame.getSelectRow = function(rowname, selectname, valuedict,
                                greydict, selectedval) {
  var selectRow = $('
');
  selectRow.append($('', {'text': rowname + ':', }));

  var select = $('<select>', {
    'id': selectname,
    'name': selectname,
  });

  // If there's no default, put an invalid default value first
  if (selectedval === null) {
    select.append($('<option>', {
      'value': '',
      'class': 'yellowed',
      'text': 'Choose ' + rowname.toLowerCase(),
    }));
  }

  $.each(valuedict, function(key, value) {
    var selectopts = {
      'value': key,
      'label': value,
      'text': value,
    };
    if (selectedval == key) {
      selectopts.selected = 'selected';
    }
    if ((greydict !== null) && (greydict[key])) {
      selectopts['class'] = 'greyed';
    }
    select.append($('<option>', selectopts));
  });
  var selectTd = $('');
  selectTd.append(select);
  selectRow.append(selectTd);
  return selectRow;
};
<commit_msg>Fixed JSHint errors<commit_after>// namespace for this "module"
var Newgame = {
  'activity': {},
};

////////////////////////////////////////////////////////////////////////
// Action flow through this page:
// * Newgame.showNewgamePage() is the landing function.  Always call
//   this first
// * Newgame.getNewgameOptions() asks the API for information about players
//   and buttons to be used when creating the game.  It clobbers
//   Newgame.api.  If successful, it calls
// * Newgame.showStatePage() determines what action to take next based on
//   the received data from getNewgameOptions().  It calls one of several
//   functions, Newgame.action<SomeAction>()
// * each Newgame.action<SomeAction>() function must set Newgame.page and
//   Newgame.form, then call Newgame.layoutPage()
// * Newgame.layoutPage() sets the contents of

//   on the live page
////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
// GENERIC FUNCTIONS: these do not depend on the action being taken

Newgame.showNewgamePage = function() {

  // Setup necessary elements for displaying status messages
  $.getScript('js/Env.js');
  Env.setupEnvStub();

  // Make sure the div element that we will need exists in the page body
  if ($('#newgame_page').length === 0) {
    $('body').append($('
', {'id': 'newgame_page', }));
  }

  // Get all needed information, then display newgame page
  Newgame.getNewgameData(Newgame.showPage);

};

Newgame.getNewgameData = function(callback) {
  if (Login.logged_in) {

    Api.getButtonData(function() {
      Api.getPlayerData(callback);
    });
  } else {

    // The player needs to be logged in for anything good to happen here
    Newgame.actionLoggedOut();
  }
};

// This function is called after Api.player has been loaded with new data
Newgame.showPage = function() {
  if ((Api.button.load_status == 'ok') && (Api.player.load_status == 'ok')) {
    Newgame.actionCreateGame();
  } else {
    Newgame.actionInternalErrorPage();
  }
};

// Actually lay out the page
Newgame.layoutPage = function() {

  // If there is a message from a current or previous invocation of this
  // page, display it now
  Env.showStatusMessage();

  $('#newgame_page').empty();
  $('#newgame_page').append(Newgame.page);

  if (Newgame.form) {
    $('#newgame_action_button').click(Newgame.form);
  }
};

////////////////////////////////////////////////////////////////////////
// This section contains one page for each type of next action used for
// flow through the page being laid out by Newgame.js.
// Each function should start by populating Newgame.page and Newgame.form
// ane end by invoking Newgame.layoutPage();

Newgame.actionLoggedOut = function() {

  // Create empty page and undefined form objects to be filled later
  Newgame.page = $('
');
  Newgame.form = null;

  // Add the "logged out player" HTML contents
  Newgame.addLoggedOutPage();

  // Lay out the page
  Newgame.layoutPage();
};

Newgame.actionInternalErrorPage = function() {

  // Create empty page and undefined form objects to be filled later
  Newgame.page = $('
');
  Newgame.form = null;

  // Add the internal error HTML contents
  Newgame.addInternalErrorPage();

  // Lay out the page
  Newgame.layoutPage();
};

Newgame.actionCreateGame = function() {

  // Create empty page and undefined form objects to be filled later
  Newgame.page = $('
');
  Newgame.form = null;

  var creatediv = $('
');
  creatediv.append($('
', {
    'class': 'title2',
    'text': 'Create a new game',
  }));
  var createform = $('<form>', {
    'id': 'newgame_action_form',
    'action': 'javascript:void(0);',
  });

  // Table of game creation options
  var createtable = $('
', {'id': 'newgame_create_table', });

  var playerRow = $('
');
  playerRow.append($('', {'text': 'You:', }));
  playerRow.append($('', {'text': Login.player, }));
  createtable.append(playerRow);

  // Setup opponent choice, including autocomplete from a dropdown
  // FIXME: i couldn't get autocomplete to display properly, so
  // temporarily used a select for the opponent name
  var playerNames = {};
  for (var playerName in Api.player.list) {
    if ((playerName != Login.player) &&
        (Api.player.list[playerName].status == 'active')) {
      playerNames[playerName] = playerName;
    }
  }
  if (!('opponentName' in Newgame.activity)) {
    Newgame.activity.opponentName = null;
  }
  createtable.append(
    Newgame.getSelectRow('Opponent', 'opponent_name', playerNames,
                         null, Newgame.activity.opponentName));

  // Load buttons and recipes into a dict for use in selects
  var buttonRecipe = {};
  var buttonGreyed = {};
  var anyUnimplementedButtons = false;
  $.each(Api.button.list, function(button, buttoninfo) {
    if (buttoninfo.hasUnimplementedSkill) {
      buttonRecipe[button] = '-- ' + button + ': ' + buttoninfo.recipe;
      buttonGreyed[button] = true;
      anyUnimplementedButtons = true;
    } else {
      buttonRecipe[button] = button + ': ' + buttoninfo.recipe;
      buttonGreyed[button] = false;
    }
  });

  // Player button selection
  if (!('playerButton' in Newgame.activity)) {
    Newgame.activity.playerButton = null;
  }
  createtable.append(
    Newgame.getSelectRow(
      'Your button', 'player_button', buttonRecipe,
      buttonGreyed, Newgame.activity.playerButton));

  // Opponent button selection
  if (!('opponentButton' in Newgame.activity)) {
    Newgame.activity.opponentButton = null;
  }
  createtable.append(
    Newgame.getSelectRow(
      'Opponent\'s button', 'opponent_button', buttonRecipe,
      buttonGreyed, Newgame.activity.opponentButton));

  // Round selection
  if (!('nRounds' in Newgame.activity)) {
    Newgame.activity.nRounds = '3';
  }
  createtable.append(
    Newgame.getSelectRow('Winner is first player to win', 'n_rounds',
      {'1': '1 round', '2': '2 rounds', '3': '3 rounds',
       '4': '4 rounds', '5': '5 rounds', },
      null, Newgame.activity.nRounds));

  // Form submission button
  createform.append(createtable);
  createform.append($('
'));
  createform.append($('<button>', {
    'id': 'newgame_action_button',
    'text': 'Create game!',
  }));
  creatediv.append(createform);

  Newgame.page.append(creatediv);

  if (anyUnimplementedButtons) {
    var warningpar = $('
');
    warningpar.append($('', {
      'text': 'Note to testers: buttons whose names are prefixed with "--" ' +
              'contain unimplemented skills.  Selecting these buttons is not ' +
              'recommended.'
    }));
    Newgame.page.append(warningpar);
  }

  // Function to invoke on button click
  Newgame.form = Newgame.formCreateGame;

  // Lay out the page
  Newgame.layoutPage();
};

////////////////////////////////////////////////////////////////////////
// These functions define form submissions, one per action type

Newgame.formCreateGame = function() {

  Newgame.activity.opponentName = $('#opponent_name').val();
  Newgame.activity.playerButton = $('#player_button').val();
  Newgame.activity.opponentButton = $('#opponent_button').val();

// james: for Jota, for an open game, you want less validation here, more like:
// var validSelect = Newgame.activity.playerButton;
//  if (!validSelect) {
//    Env.message = {
//      'type': 'error',
//      'text':
//        'Please select your button',
//    };
//    Newgame.showNewgamePage();
//  }  else if (!(Newgame.activity.opponentName in Api.player.list) &&
//
// attn:Jota here, you'll need a check explicitly allowing empty opponent names
//
//              ) {
//   Env.message = {
//     'type': 'error',
//     'text': 'Specified opponent ' + Newgame.activity.opponentName +
//             ' is not recognized',
//   };
//   Newgame.showNewgamePage();
// ...

  var validSelect = Newgame.activity.opponentName &&
                    Newgame.activity.opponentButton &&
                    Newgame.activity.playerButton;

  if (!validSelect) {
    Env.message = {
      'type': 'error',
      'text':
        'Please select an opponent, your button, and your opponent\'s button',
    };
    Newgame.showNewgamePage();
  } else if (!(Newgame.activity.opponentName in Api.player.list)) {
    Env.message = {
      'type': 'error',
      'text': 'Specified opponent ' + Newgame.activity.opponentName +
              ' is not recognized',
    };
    Newgame.showNewgamePage();
  } else {
    var playerNameArray = [
      Login.player,
      Newgame.activity.opponentName,
    ];
    var buttonNameArray = [
      Newgame.activity.playerButton,
      Newgame.activity.opponentButton,
    ];

    Newgame.activity.nRounds = $('#n_rounds').val();

    // N.B. Newgame.activity is always retained between loads: on
    // failure so the player can correct selections, on success in
    // case the player wants to create another similar game.
    // Therefore, it's fine to pass the form post the same function
    // (showNewgamePage) for both success and failure conditions.
    Api.apiFormPost(
      {
        type: 'createGame',
        playerNameArray: playerNameArray,
        buttonNameArray: buttonNameArray,
        maxWins: Newgame.activity.nRounds,
      },
      { 'ok':
        {
          'type': 'function',
          'msgfunc': Newgame.setCreateGameSuccessMessage,
        },
        'notok': { 'type': 'server', },
      },
      'newgame_action_button',
      Newgame.showNewgamePage,
      Newgame.showNewgamePage
    );
  }
};

////////////////////////////////////////////////////////////////////////
// These functions add pieces of HTML to Newgame.page

Newgame.addLoggedOutPage = function() {
  var errorDiv = $('
');
  errorDiv.append($('
', {
    'text': 'Can\'t create a game because you are not logged in',
  }));
  Newgame.page.append(errorDiv);
};

Newgame.addInternalErrorPage = function() {
  var errorDiv = $('
');
  errorDiv.append($('
', {
    'text': 'Can\'t create a game.  Something went wrong when ' +
            'loading data from server.',
  }));
  Newgame.page.append(errorDiv);
};

Newgame.setCreateGameSuccessMessage = function(message, data) {
  var gameId = data.gameId;
  var gameLink = $('', {
    'href': 'game.html?game=' + gameId,
    'text': 'Go to game page',
  });
  var gamePar = $('
', {'text': message + ' ', });
  gamePar.append(gameLink);
  Env.message = {
    'type': 'success',
    'text': '',
    'obj': gamePar,
  };
};

////////////////////////////////////////////////////////////////////////
// These functions generate and return pieces of HTML

Newgame.getSelectRow = function(rowname, selectname, valuedict,
                                greydict, selectedval) {
  var selectRow = $('
');
  selectRow.append($('', {'text': rowname + ':', }));

  var select = $('<select>', {
    'id': selectname,
    'name': selectname,
  });

  // If there's no default, put an invalid default value first
  if (selectedval === null) {
    select.append($('<option>', {
      'value': '',
      'class': 'yellowed',
      'text': 'Choose ' + rowname.toLowerCase(),
    }));
  }

  $.each(valuedict, function(key, value) {
    var selectopts = {
      'value': key,
      'label': value,
      'text': value,
    };
    if (selectedval == key) {
      selectopts.selected = 'selected';
    }
    if ((greydict !== null) && (greydict[key])) {
      selectopts['class'] = 'greyed';
    }
    select.append($('<option>', selectopts));
  });
  var selectTd = $('');
  selectTd.append(select);
  selectRow.append(selectTd);
  return selectRow;
};
<|endoftext|>