<commit_before>/*
 * Copyright (c) 2012 Joyent Inc., All rights reserved.
 *
 * DHCP server daemon: uses networking information and boot parameters from
 * SDC APIs to create DHCP replies suitable for booting SDC Compute Nodes.
 *
 */

var assert = require('assert');
var dgram = require('dgram');
var fs = require('fs');

var vasync = require('vasync');
var uuid = require('node-uuid');

var dhcp = require('./dhcp');
var menulst = require('./menulst');
var sprintf = require('sprintf').sprintf;
var bootparams = require('./bootparams');

// --- DHCPD object and methods

/**
 * DHCPD constructor
 */
function DHCPD(opts) {
  var self = this;
  this.log = opts.log;
  this.config = opts.config;

  this.sock = dgram.createSocket('udp4',
    function (msg, peer) { self.handleMessage(msg, peer); });

  this.napi = bootparams.createNAPIclient(this.config);
  this.cnapi = bootparams.createCNAPIclient(this.config);
}

/**
 * Starts the server
 */
DHCPD.prototype.start = function () {
  var self = this;
  this.sock.on('listening', function () {
      self.sock.setTTL(128);  // XXX Doesn't work! :( Bug in node?
      self.sock.setBroadcast(true);
      self.log.info('dhcpd started on %s:%d',
        self.config.listenIp, self.config.port);
  });
  this.sock.bind(this.config.port, this.config.listenIp);
};

/**
 * Handles an incoming DHCP message, sending out a response if necessary.
 */
DHCPD.prototype.handleMessage = function (msg, peer) {
    var self = this;
    var packet = dhcp.DHCPPacket.parse(msg);
    var mac = packet.chaddr;
    var log = this.log.child({ mac: mac, req_id: uuid()});
    log.info('source address="%s:%d"', peer.address, peer.port);

    // Print the whole packet in hex
    if (log.trace()) {
        for (var i = 0; i < msg.length; i += 4) {
          // XXX
          this.log.trace(sprintf('[%03d]: 0x%02x 0x%02x 0x%02x 0x%02x',
            i, msg[i], msg[i+1], msg[i+2], msg[i+3]));
        }
    }

    packet.dump(function (dumpMsg) {
      log.info(dumpMsg);
    });

    var msgType = dhcp.DHCP_MESSAGE_TYPE[packet.options[53]];
    if (msgType != 'DHCPDISCOVER' && msgType != 'DHCPREQUEST') {
      log.info('message type="%s": not responding', msgType);
      return;
    }

    var packetOpts;
    var params;

    vasync.pipeline({
      'funcs': [
        // Get the boot params from NAPI / CNAPI
        function _params(arg, cb) {
          bootparams.getBootParams(
            mac, self.napi, self.cnapi, log, function (err, res) {
              if (err) {
                return cb(err);
              }
              params = res;
              return cb(null);
          });
        },
        // Write out the menu.lst
        function _menulst(arg, cb) {
          packetOpts = self.buildResponse(packet, log);
          menulst.writeMenuLst(
            mac, params, self.config.tftpRoot, log, function (err) {
              if (err) {
                return cb(err);
              }

              return cb(null);
            });
        },
        // Send back the reply
        function _reply(arg, cb) {
          self.sendReply(packet, packetOpts, params, log, cb);
        }
      ]
    }, function (err, res) {
      if (err) {
        log.error(err, 'Error while processing boot params');
      } else {
        log.info('Reply sent');
      }
    });
};

/*
 * Sends the DHCP reply
 */
DHCPD.prototype.sendReply = function (packet, packetOpts, params, log,
  callback) {
  var mac = packet.chaddr;
  var port = 68;
  var broadcastAddr = '255.255.255.255';

  packetOpts['yiaddr'] = params.ip;
  packetOpts.options['1'] = params.netmask;
  if (params.resolvers && params.resolvers.length) {
    packetOpts.options['6'] = params.resolvers;
  }

  var outPacket = dhcp.DHCPPacket.build_reply(packet, packetOpts);
  var outRaw = outPacket.raw();
  if (log.debug()) {
    log.debug(outPacket.dump(), 'Packet options');
  }

  log.info('Sending broadcast ("%s:%d") reply to MAC "%s"',
      broadcastAddr, port, mac);

  this.sock.send(outRaw, 0, outRaw.length, port, broadcastAddr,
      function (err, bytes) {
    if (err) {
      log.error(err, 'Error sending reply to "%s"', mac);
      return callback(err);
    } else {
      log.info('Sent reply to "%s" (%d bytes)', mac, bytes);
      return callback(null);
    }
  });
};

/*
 * Builds the DHCP response options
 */
DHCPD.prototype.buildResponse = function (packet, log) {
    var msgType = dhcp.DHCP_MESSAGE_TYPE[packet.options[53]];
    var responseType = msgType == 'DHCPDISCOVER' ? 'DHCPOFFER' : 'DHCPACK';
    var mac = packet.chaddr;

    var packetOpts = {
      'siaddr': this.config.serverIp,
      'file': 'pxegrub',
      'options': {
        '1': this.config.netmask,
        '51': this.config.leaseTime,
        '53': responseType,
        '54': this.config.serverIp
      }
    };

    if (this.config.defaultGateway) {
      packetOpts['options']['3'] = this.config.defaultGateway;
    }

    if (packet.options[77]) {
        var userClass = new Buffer(packet.options[77]).toString();
        if (userClass === 'gPXE') {
            packetOpts.file = 'boot.gpxe.01' +
              mac.split(':').join('').toUpperCase();
            log.info('Detected gPXE, setting file to "%s"',
                packetOpts.file);
        } else {
          log.warn('Unknown user-class: "%s", ignoring', userClass);
        }
    }

    log.info('message type="%s", response type="%s"',
        msgType, responseType);

    return packetOpts;
};

// --- Exports

/**
 * Creates the dhcpd server
 */
function createServer(opts) {
  assert.ok(opts, 'Must supply options');
  assert.ok(opts.hasOwnProperty('log'), 'Must supply logger');
  assert.ok(opts.hasOwnProperty('configFile'), 'Must supply configFile');

  var log = opts.log;
  log.info('Loading config from "%s"', opts.configFile);
  var config = JSON.parse(fs.readFileSync(opts.configFile, 'utf-8'));

  var required = ['listenIp', 'tftpRoot', 'defaultGateway', 'serverIp',
    'leaseTime', 'netmask', 'port'];
  for (var r in required) {
    var req = required[r];
    assert.ok(config.hasOwnProperty(req),
      'config: "' + req + '" value required');
  }

  return new DHCPD({
    log: log,
    config: config
  });
}

module.exports = {
  createServer: createServer
};
<commit_msg>HEAD-1438 booter should support iPXE as for gPXE<commit_after>/*
 * Copyright (c) 2012 Joyent Inc., All rights reserved.
 *
 * DHCP server daemon: uses networking information and boot parameters from
 * SDC APIs to create DHCP replies suitable for booting SDC Compute Nodes.
 *
 */

var assert = require('assert');
var dgram = require('dgram');
var fs = require('fs');

var vasync = require('vasync');
var uuid = require('node-uuid');

var dhcp = require('./dhcp');
var menulst = require('./menulst');
var sprintf = require('sprintf').sprintf;
var bootparams = require('./bootparams');

// --- DHCPD object and methods

/**
 * DHCPD constructor
 */
function DHCPD(opts) {
  var self = this;
  this.log = opts.log;
  this.config = opts.config;

  this.sock = dgram.createSocket('udp4',
    function (msg, peer) { self.handleMessage(msg, peer); });

  this.napi = bootparams.createNAPIclient(this.config);
  this.cnapi = bootparams.createCNAPIclient(this.config);
}

/**
 * Starts the server
 */
DHCPD.prototype.start = function () {
  var self = this;
  this.sock.on('listening', function () {
      self.sock.setTTL(128);  // XXX Doesn't work! :( Bug in node?
      self.sock.setBroadcast(true);
      self.log.info('dhcpd started on %s:%d',
        self.config.listenIp, self.config.port);
  });
  this.sock.bind(this.config.port, this.config.listenIp);
};

/**
 * Handles an incoming DHCP message, sending out a response if necessary.
 */
DHCPD.prototype.handleMessage = function (msg, peer) {
    var self = this;
    var packet = dhcp.DHCPPacket.parse(msg);
    var mac = packet.chaddr;
    var log = this.log.child({ mac: mac, req_id: uuid()});
    log.info('source address="%s:%d"', peer.address, peer.port);

    // Print the whole packet in hex
    if (log.trace()) {
        for (var i = 0; i < msg.length; i += 4) {
          // XXX
          this.log.trace(sprintf('[%03d]: 0x%02x 0x%02x 0x%02x 0x%02x',
            i, msg[i], msg[i+1], msg[i+2], msg[i+3]));
        }
    }

    packet.dump(function (dumpMsg) {
      log.info(dumpMsg);
    });

    var msgType = dhcp.DHCP_MESSAGE_TYPE[packet.options[53]];
    if (msgType != 'DHCPDISCOVER' && msgType != 'DHCPREQUEST') {
      log.info('message type="%s": not responding', msgType);
      return;
    }

    var packetOpts;
    var params;

    vasync.pipeline({
      'funcs': [
        // Get the boot params from NAPI / CNAPI
        function _params(arg, cb) {
          bootparams.getBootParams(
            mac, self.napi, self.cnapi, log, function (err, res) {
              if (err) {
                return cb(err);
              }
              params = res;
              return cb(null);
          });
        },
        // Write out the menu.lst
        function _menulst(arg, cb) {
          packetOpts = self.buildResponse(packet, log);
          menulst.writeMenuLst(
            mac, params, self.config.tftpRoot, log, function (err) {
              if (err) {
                return cb(err);
              }

              return cb(null);
            });
        },
        // Send back the reply
        function _reply(arg, cb) {
          self.sendReply(packet, packetOpts, params, log, cb);
        }
      ]
    }, function (err, res) {
      if (err) {
        log.error(err, 'Error while processing boot params');
      } else {
        log.info('Reply sent');
      }
    });
};

/*
 * Sends the DHCP reply
 */
DHCPD.prototype.sendReply = function (packet, packetOpts, params, log,
  callback) {
  var mac = packet.chaddr;
  var port = 68;
  var broadcastAddr = '255.255.255.255';

  packetOpts['yiaddr'] = params.ip;
  packetOpts.options['1'] = params.netmask;
  if (params.resolvers && params.resolvers.length) {
    packetOpts.options['6'] = params.resolvers;
  }

  var outPacket = dhcp.DHCPPacket.build_reply(packet, packetOpts);
  var outRaw = outPacket.raw();
  if (log.debug()) {
    log.debug(outPacket.dump(), 'Packet options');
  }

  log.info('Sending broadcast ("%s:%d") reply to MAC "%s"',
      broadcastAddr, port, mac);

  this.sock.send(outRaw, 0, outRaw.length, port, broadcastAddr,
      function (err, bytes) {
    if (err) {
      log.error(err, 'Error sending reply to "%s"', mac);
      return callback(err);
    } else {
      log.info('Sent reply to "%s" (%d bytes)', mac, bytes);
      return callback(null);
    }
  });
};

/*
 * Builds the DHCP response options
 */
DHCPD.prototype.buildResponse = function (packet, log) {
    var msgType = dhcp.DHCP_MESSAGE_TYPE[packet.options[53]];
    var responseType = msgType == 'DHCPDISCOVER' ? 'DHCPOFFER' : 'DHCPACK';
    var mac = packet.chaddr;

    var packetOpts = {
      'siaddr': this.config.serverIp,
      'file': 'pxegrub',
      'options': {
        '1': this.config.netmask,
        '51': this.config.leaseTime,
        '53': responseType,
        '54': this.config.serverIp
      }
    };

    if (this.config.defaultGateway) {
      packetOpts['options']['3'] = this.config.defaultGateway;
    }

    if (packet.options[77]) {
        var userClass = new Buffer(packet.options[77]).toString();
        if (userClass === 'gPXE' || userClass === 'iPXE') {
            packetOpts.file = 'boot.gpxe.01' +
              mac.split(':').join('').toUpperCase();
            log.info('Detected iPXE/gPXE, setting file to "%s"',
                packetOpts.file);
        } else {
          log.warn('Unknown user-class: "%s", ignoring', userClass);
        }
    }

    log.info('message type="%s", response type="%s"',
        msgType, responseType);

    return packetOpts;
};

// --- Exports

/**
 * Creates the dhcpd server
 */
function createServer(opts) {
  assert.ok(opts, 'Must supply options');
  assert.ok(opts.hasOwnProperty('log'), 'Must supply logger');
  assert.ok(opts.hasOwnProperty('configFile'), 'Must supply configFile');

  var log = opts.log;
  log.info('Loading config from "%s"', opts.configFile);
  var config = JSON.parse(fs.readFileSync(opts.configFile, 'utf-8'));

  var required = ['listenIp', 'tftpRoot', 'defaultGateway', 'serverIp',
    'leaseTime', 'netmask', 'port'];
  for (var r in required) {
    var req = required[r];
    assert.ok(config.hasOwnProperty(req),
      'config: "' + req + '" value required');
  }

  return new DHCPD({
    log: log,
    config: config
  });
}

module.exports = {
  createServer: createServer
};
<|endoftext|>


<commit_before>"use strict";

define([], function(){
    // procedure dscom
    // ===============
    // This procedure provides deep space common items used by both the secular
    // and periodics subroutines.  input is provided as shown. this routine
    // used to be called dpper, but the functions inside weren't well organized.

    return function (epoch, ep, argpp, tc, inclp, nodep, np) {
        // inputs:
        //
        //     epoch       -
        //     ep          - eccentricity
        //     argpp       - argument of perigee
        //     tc          -
        //     inclp       - inclination
        //     nodep       - right ascension of ascending node
        //     np          - mean motion
        //
        // constants
        // ----------
        var zes     =  0.01675,
        zel     =  0.05490,
        c1ss    =  2.9864797e-6,
        c1l     =  4.7968065e-7,
        zsinis  =  0.39785416,
        zcosis  =  0.91744867,
        zcosgs  =  0.1945905,
        zsings  = -0.98088458,
        twopi   =  2.0 * Math.PI,
            // local variables
            // ---------------
            // locals:
            //
            //     a1, a2, a3, a4, a5, a6, a7, a8, a9, a10         -
            //     betasq      -
            //     cc          -
            //     ctem, stem        -
            //     x1, x2, x3, x4, x5, x6, x7, x8          -
            //     xnodce      -
            //     xnoi        -
            //     zcosg  , zsing  , zcosgl , zsingl , zcosh  , zsinh  , zcoshl , zsinhl ,
            //     zcosi  , zsini  , zcosil , zsinil ,
            //     zx          -
            //     zy          -
            nm     = np,
            em     = ep,
            snodm  = Math.sin(nodep),
            cnodm  = Math.cos(nodep),
            sinomm = Math.sin(argpp),
            cosomm = Math.cos(argpp),
            sinim  = Math.sin(inclp),
            cosim  = Math.cos(inclp),
            emsq   = em * em,
            betasq = 1.0 - emsq,
            rtemsq = Math.sqrt(betasq),
            // initialize lunar solar terms
            // ----------------------------
            peo    = 0.0,
            pinco  = 0.0,
            plo    = 0.0,
            pgho   = 0.0,
            pho    = 0.0,
            day    = epoch + 18261.5 + tc / 1440.0,
            xnodce = (4.5236020 - 9.2422029e-4 * day) % twopi,
            stem   = Math.sin(xnodce),
            ctem   = Math.cos(xnodce),
            zcosil = 0.91375164 - 0.03568096 * ctem,
            zsinil = Math.sqrt(1.0 - zcosil * zcosil),
            zsinhl = 0.089683511 * stem / zsinil,
            zcoshl = Math.sqrt(1.0 - zsinhl * zsinhl),
            gam    = 5.8351514 + 0.0019443680 * day,
            zx     = 0.39785416 * stem / zsinil,
            zy     = zcoshl * ctem + 0.91744867 * zsinhl * stem,
            //
            zcosgl, zsingl, zcosg, zsing, zcosi, zsini, zcosh, zsinh,
            cc, xnoi,
            lsflg,
            a1, a3, a7, a8, a9, a10, a2, a4, a5, a6,
            x1, x2, x3, x4, x5, x6, x7, x8,
            z31, z32, z33, z1, z2, z3, z11, z12, z13, z21, z22, z23,
            s3, s2, s4, s1, s5, s6, s7,
            ss1, ss2, ss3, ss4, ss5, ss6, ss7,
            sz1, sz2, sz3, sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33,
            zmol, zmos,
            se2, se3, si2, si3, sl2, sl3, sl4, sgh2, sgh3, sgh4, sh2, sh3,
            ee2, e3, xi2, xi3, xl2, xl3, xl4, xgh2, xgh3, xgh4, xh2, xh3;

            zx     = Math.atan2(zx, zy);
            zx     = gam + zx - xnodce;
            zcosgl = Math.cos(zx);
            zsingl = Math.sin(zx);

        // do solar terms
        // --------------
        zcosg = zcosgs;
        zsing = zsings;
        zcosi = zcosis;
        zsini = zsinis;
        zcosh = cnodm;
        zsinh = snodm;
        cc    = c1ss;
        xnoi  = 1.0 / nm;

        for (lsflg = 1; lsflg <= 2; lsflg += 1) { // =1:2
            a1  =   zcosg * zcosh + zsing * zcosi * zsinh;
            a3  =  -zsing * zcosh + zcosg * zcosi * zsinh;
            a7  =  -zcosg * zsinh + zsing * zcosi * zcosh;
            a8  =   zsing * zsini;
            a9  =   zsing * zsinh + zcosg * zcosi * zcosh;
            a10 =   zcosg * zsini;
            a2  =   cosim * a7 + sinim * a8;
            a4  =   cosim * a9 + sinim * a10;
            a5  =  -sinim * a7 + cosim * a8;
            a6  =  -sinim * a9 + cosim * a10;

            x1  =  a1 * cosomm + a2 * sinomm;
            x2  =  a3 * cosomm + a4 * sinomm;
            x3  = -a1 * sinomm + a2 * cosomm;
            x4  = -a3 * sinomm + a4 * cosomm;
            x5  =  a5 * sinomm;
            x6  =  a6 * sinomm;
            x7  =  a5 * cosomm;
            x8  =  a6 * cosomm;

            z31 = 12.0 * x1 * x1 - 3.0 * x3 * x3;
            z32 = 24.0 * x1 * x2 - 6.0 * x3 * x4;
            z33 = 12.0 * x2 * x2 - 3.0 * x4 * x4;
            z1  =  3.0 *  (a1 * a1 + a2 * a2) + z31 * emsq;
            z2  =  6.0 *  (a1 * a3 + a2 * a4) + z32 * emsq;
            z3  =  3.0 *  (a3 * a3 + a4 * a4) + z33 * emsq;
            z11 = -6.0 * a1 * a5 + emsq *  (-24.0 * x1 * x7 - 6.0 * x3 * x5);
            z12 = -6.0 *  (a1 * a6 + a3 * a5) + emsq * (-24.0 * (x2 * x7 + x1 * x8) - 6.0 * (x3 * x6 + x4 * x5));
            z13 = -6.0 * a3 * a6 + emsq * (-24.0 * x2 * x8 - 6.0 * x4 * x6);
            z21 =  6.0 * a2 * a5 + emsq * (24.0 * x1 * x5 - 6.0 * x3 * x7);
            z22 =  6.0 *  (a4 * a5 + a2 * a6) + emsq * (24.0 * (x2 * x5 + x1 * x6) - 6.0 * (x4 * x7 + x3 * x8));
            z23 =  6.0 * a4 * a6 + emsq * (24.0 * x2 * x6 - 6.0 * x4 * x8);
            z1  = z1 + z1 + betasq * z31;
            z2  = z2 + z2 + betasq * z32;
            z3  = z3 + z3 + betasq * z33;
            s3  = cc * xnoi;
            s2  = -0.5 * s3 / rtemsq;
            s4  = s3 * rtemsq;
            s1  = -15.0 * em * s4;
            s5  = x1 * x3 + x2 * x4;
            s6  = x2 * x3 + x1 * x4;
            s7  = x2 * x4 - x1 * x3;

            // do lunar terms
            // --------------
            if (lsflg === 1) {
                ss1   = s1;
                ss2   = s2;
                ss3   = s3;
                ss4   = s4;
                ss5   = s5;
                ss6   = s6;
                ss7   = s7;
                sz1   = z1;
                sz2   = z2;
                sz3   = z3;
                sz11  = z11;
                sz12  = z12;
                sz13  = z13;
                sz21  = z21;
                sz22  = z22;
                sz23  = z23;
                sz31  = z31;
                sz32  = z32;
                sz33  = z33;
                zcosg = zcosgl;
                zsing = zsingl;
                zcosi = zcosil;
                zsini = zsinil;
                zcosh = zcoshl * cnodm + zsinhl * snodm;
                zsinh = snodm * zcoshl - cnodm * zsinhl;
                cc    = c1l;
            }
        }

        zmol = (4.7199672 + 0.22997150  * day - gam) % twopi;
        zmos = (6.2565837 + 0.017201977 * day) % twopi;

        // do solar terms
        // --------------
        se2  =   2.0 * ss1 * ss6;
        se3  =   2.0 * ss1 * ss7;
        si2  =   2.0 * ss2 * sz12;
        si3  =   2.0 * ss2 * (sz13 - sz11);
        sl2  =  -2.0 * ss3 * sz2;
        sl3  =  -2.0 * ss3 * (sz3 - sz1);
        sl4  =  -2.0 * ss3 * (-21.0 - 9.0 * emsq) * zes;
        sgh2 =   2.0 * ss4 * sz32;
        sgh3 =   2.0 * ss4 * (sz33 - sz31);
        sgh4 = -18.0 * ss4 * zes;
        sh2  =  -2.0 * ss2 * sz22;
        sh3  =  -2.0 * ss2 * (sz23 - sz21);

        // do lunar terms
        // --------------
        ee2  =   2.0 * s1 * s6;
        e3   =   2.0 * s1 * s7;
        xi2  =   2.0 * s2 * z12;
        xi3  =   2.0 * s2 * (z13 - z11);
        xl2  =  -2.0 * s3 * z2;
        xl3  =  -2.0 * s3 * (z3 - z1);
        xl4  =  -2.0 * s3 * (-21.0 - 9.0 * emsq) * zel;
        xgh2 =   2.0 * s4 * z32;
        xgh3 =   2.0 * s4 * (z33 - z31);
        xgh4 = -18.0 * s4 * zel;
        xh2  =  -2.0 * s2 * z22;
        xh3  =  -2.0 * s2 * (z23 - z21);

        return [sinim, cosim, sinomm, cosomm, snodm, cnodm, day, e3, ee2, em, emsq, gam,
        peo, pgho, pho, pinco, plo, rtemsq, se2, se3, sgh2, sgh3, sgh4, sh2, sh3, si2,
        si3, sl2, sl3, sl4, s1, s2, s3, s4, s5, s6, s7, ss1, ss2, ss3, ss4, ss5, ss6, ss7,
        sz1, sz2, sz3, sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33, xgh2, xgh3,
        xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4, nm, z1, z2, z3, z11, z12, z13, z21, z22,
        z23, z31, z32, z33, zmol, zmos];
        // outputs:
        //
        //     sinim  , cosim  , sinomm , cosomm , snodm  , cnodm
        //     day         -
        //     e3          -
        //     ee2         -
        //     em          - eccentricity
        //     emsq        - eccentricity squared
        //     gam         -
        //     peo         -
        //     pgho        -
        //     pho         -
        //     pinco       -
        //     plo         -
        //     rtemsq      -
        //     se2, se3         -
        //     sgh2, sgh3, sgh4        -
        //     sh2, sh3, si2, si3, sl2, sl3, sl4         -
        //     s1, s2, s3, s4, s5, s6, s7          -
        //     ss1, ss2, ss3, ss4, ss5, ss6, ss7, sz1, sz2, sz3         -
        //     sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33        -
        //     xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4         -
        //     nm          - mean motion
        //     z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33         -
        //     zmol        -
        //     zmos        -
    };
});
<commit_msg>Add a note to refactor the return list to be an object. Refs #162<commit_after>"use strict";

define([], function(){
    // procedure dscom
    // ===============
    // This procedure provides deep space common items used by both the secular
    // and periodics subroutines.  input is provided as shown. this routine
    // used to be called dpper, but the functions inside weren't well organized.

    return function (epoch, ep, argpp, tc, inclp, nodep, np) {
        // inputs:
        //
        //     epoch       -
        //     ep          - eccentricity
        //     argpp       - argument of perigee
        //     tc          -
        //     inclp       - inclination
        //     nodep       - right ascension of ascending node
        //     np          - mean motion
        //
        // constants
        // ----------
        var zes     =  0.01675,
        zel     =  0.05490,
        c1ss    =  2.9864797e-6,
        c1l     =  4.7968065e-7,
        zsinis  =  0.39785416,
        zcosis  =  0.91744867,
        zcosgs  =  0.1945905,
        zsings  = -0.98088458,
        twopi   =  2.0 * Math.PI,
            // local variables
            // ---------------
            // locals:
            //
            //     a1, a2, a3, a4, a5, a6, a7, a8, a9, a10         -
            //     betasq      -
            //     cc          -
            //     ctem, stem        -
            //     x1, x2, x3, x4, x5, x6, x7, x8          -
            //     xnodce      -
            //     xnoi        -
            //     zcosg  , zsing  , zcosgl , zsingl , zcosh  , zsinh  , zcoshl , zsinhl ,
            //     zcosi  , zsini  , zcosil , zsinil ,
            //     zx          -
            //     zy          -
            nm     = np,
            em     = ep,
            snodm  = Math.sin(nodep),
            cnodm  = Math.cos(nodep),
            sinomm = Math.sin(argpp),
            cosomm = Math.cos(argpp),
            sinim  = Math.sin(inclp),
            cosim  = Math.cos(inclp),
            emsq   = em * em,
            betasq = 1.0 - emsq,
            rtemsq = Math.sqrt(betasq),
            // initialize lunar solar terms
            // ----------------------------
            peo    = 0.0,
            pinco  = 0.0,
            plo    = 0.0,
            pgho   = 0.0,
            pho    = 0.0,
            day    = epoch + 18261.5 + tc / 1440.0,
            xnodce = (4.5236020 - 9.2422029e-4 * day) % twopi,
            stem   = Math.sin(xnodce),
            ctem   = Math.cos(xnodce),
            zcosil = 0.91375164 - 0.03568096 * ctem,
            zsinil = Math.sqrt(1.0 - zcosil * zcosil),
            zsinhl = 0.089683511 * stem / zsinil,
            zcoshl = Math.sqrt(1.0 - zsinhl * zsinhl),
            gam    = 5.8351514 + 0.0019443680 * day,
            zx     = 0.39785416 * stem / zsinil,
            zy     = zcoshl * ctem + 0.91744867 * zsinhl * stem,
            //
            zcosgl, zsingl, zcosg, zsing, zcosi, zsini, zcosh, zsinh,
            cc, xnoi,
            lsflg,
            a1, a3, a7, a8, a9, a10, a2, a4, a5, a6,
            x1, x2, x3, x4, x5, x6, x7, x8,
            z31, z32, z33, z1, z2, z3, z11, z12, z13, z21, z22, z23,
            s3, s2, s4, s1, s5, s6, s7,
            ss1, ss2, ss3, ss4, ss5, ss6, ss7,
            sz1, sz2, sz3, sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33,
            zmol, zmos,
            se2, se3, si2, si3, sl2, sl3, sl4, sgh2, sgh3, sgh4, sh2, sh3,
            ee2, e3, xi2, xi3, xl2, xl3, xl4, xgh2, xgh3, xgh4, xh2, xh3;

            zx     = Math.atan2(zx, zy);
            zx     = gam + zx - xnodce;
            zcosgl = Math.cos(zx);
            zsingl = Math.sin(zx);

        // do solar terms
        // --------------
        zcosg = zcosgs;
        zsing = zsings;
        zcosi = zcosis;
        zsini = zsinis;
        zcosh = cnodm;
        zsinh = snodm;
        cc    = c1ss;
        xnoi  = 1.0 / nm;

        for (lsflg = 1; lsflg <= 2; lsflg += 1) { // =1:2
            a1  =   zcosg * zcosh + zsing * zcosi * zsinh;
            a3  =  -zsing * zcosh + zcosg * zcosi * zsinh;
            a7  =  -zcosg * zsinh + zsing * zcosi * zcosh;
            a8  =   zsing * zsini;
            a9  =   zsing * zsinh + zcosg * zcosi * zcosh;
            a10 =   zcosg * zsini;
            a2  =   cosim * a7 + sinim * a8;
            a4  =   cosim * a9 + sinim * a10;
            a5  =  -sinim * a7 + cosim * a8;
            a6  =  -sinim * a9 + cosim * a10;

            x1  =  a1 * cosomm + a2 * sinomm;
            x2  =  a3 * cosomm + a4 * sinomm;
            x3  = -a1 * sinomm + a2 * cosomm;
            x4  = -a3 * sinomm + a4 * cosomm;
            x5  =  a5 * sinomm;
            x6  =  a6 * sinomm;
            x7  =  a5 * cosomm;
            x8  =  a6 * cosomm;

            z31 = 12.0 * x1 * x1 - 3.0 * x3 * x3;
            z32 = 24.0 * x1 * x2 - 6.0 * x3 * x4;
            z33 = 12.0 * x2 * x2 - 3.0 * x4 * x4;
            z1  =  3.0 *  (a1 * a1 + a2 * a2) + z31 * emsq;
            z2  =  6.0 *  (a1 * a3 + a2 * a4) + z32 * emsq;
            z3  =  3.0 *  (a3 * a3 + a4 * a4) + z33 * emsq;
            z11 = -6.0 * a1 * a5 + emsq *  (-24.0 * x1 * x7 - 6.0 * x3 * x5);
            z12 = -6.0 *  (a1 * a6 + a3 * a5) + emsq * (-24.0 * (x2 * x7 + x1 * x8) - 6.0 * (x3 * x6 + x4 * x5));
            z13 = -6.0 * a3 * a6 + emsq * (-24.0 * x2 * x8 - 6.0 * x4 * x6);
            z21 =  6.0 * a2 * a5 + emsq * (24.0 * x1 * x5 - 6.0 * x3 * x7);
            z22 =  6.0 *  (a4 * a5 + a2 * a6) + emsq * (24.0 * (x2 * x5 + x1 * x6) - 6.0 * (x4 * x7 + x3 * x8));
            z23 =  6.0 * a4 * a6 + emsq * (24.0 * x2 * x6 - 6.0 * x4 * x8);
            z1  = z1 + z1 + betasq * z31;
            z2  = z2 + z2 + betasq * z32;
            z3  = z3 + z3 + betasq * z33;
            s3  = cc * xnoi;
            s2  = -0.5 * s3 / rtemsq;
            s4  = s3 * rtemsq;
            s1  = -15.0 * em * s4;
            s5  = x1 * x3 + x2 * x4;
            s6  = x2 * x3 + x1 * x4;
            s7  = x2 * x4 - x1 * x3;

            // do lunar terms
            // --------------
            if (lsflg === 1) {
                ss1   = s1;
                ss2   = s2;
                ss3   = s3;
                ss4   = s4;
                ss5   = s5;
                ss6   = s6;
                ss7   = s7;
                sz1   = z1;
                sz2   = z2;
                sz3   = z3;
                sz11  = z11;
                sz12  = z12;
                sz13  = z13;
                sz21  = z21;
                sz22  = z22;
                sz23  = z23;
                sz31  = z31;
                sz32  = z32;
                sz33  = z33;
                zcosg = zcosgl;
                zsing = zsingl;
                zcosi = zcosil;
                zsini = zsinil;
                zcosh = zcoshl * cnodm + zsinhl * snodm;
                zsinh = snodm * zcoshl - cnodm * zsinhl;
                cc    = c1l;
            }
        }

        zmol = (4.7199672 + 0.22997150  * day - gam) % twopi;
        zmos = (6.2565837 + 0.017201977 * day) % twopi;

        // do solar terms
        // --------------
        se2  =   2.0 * ss1 * ss6;
        se3  =   2.0 * ss1 * ss7;
        si2  =   2.0 * ss2 * sz12;
        si3  =   2.0 * ss2 * (sz13 - sz11);
        sl2  =  -2.0 * ss3 * sz2;
        sl3  =  -2.0 * ss3 * (sz3 - sz1);
        sl4  =  -2.0 * ss3 * (-21.0 - 9.0 * emsq) * zes;
        sgh2 =   2.0 * ss4 * sz32;
        sgh3 =   2.0 * ss4 * (sz33 - sz31);
        sgh4 = -18.0 * ss4 * zes;
        sh2  =  -2.0 * ss2 * sz22;
        sh3  =  -2.0 * ss2 * (sz23 - sz21);

        // do lunar terms
        // --------------
        ee2  =   2.0 * s1 * s6;
        e3   =   2.0 * s1 * s7;
        xi2  =   2.0 * s2 * z12;
        xi3  =   2.0 * s2 * (z13 - z11);
        xl2  =  -2.0 * s3 * z2;
        xl3  =  -2.0 * s3 * (z3 - z1);
        xl4  =  -2.0 * s3 * (-21.0 - 9.0 * emsq) * zel;
        xgh2 =   2.0 * s4 * z32;
        xgh3 =   2.0 * s4 * (z33 - z31);
        xgh4 = -18.0 * s4 * zel;
        xh2  =  -2.0 * s2 * z22;
        xh3  =  -2.0 * s2 * (z23 - z21);

        // TODO: FIXME: Make this return an object and update callers to take an
        // TODO: FIXME: as a return value.
        return [sinim, cosim, sinomm, cosomm, snodm, cnodm, day, e3, ee2, em, emsq, gam,
        peo, pgho, pho, pinco, plo, rtemsq, se2, se3, sgh2, sgh3, sgh4, sh2, sh3, si2,
        si3, sl2, sl3, sl4, s1, s2, s3, s4, s5, s6, s7, ss1, ss2, ss3, ss4, ss5, ss6, ss7,
        sz1, sz2, sz3, sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33, xgh2, xgh3,
        xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4, nm, z1, z2, z3, z11, z12, z13, z21, z22,
        z23, z31, z32, z33, zmol, zmos];
        // outputs:
        //
        //     sinim  , cosim  , sinomm , cosomm , snodm  , cnodm
        //     day         -
        //     e3          -
        //     ee2         -
        //     em          - eccentricity
        //     emsq        - eccentricity squared
        //     gam         -
        //     peo         -
        //     pgho        -
        //     pho         -
        //     pinco       -
        //     plo         -
        //     rtemsq      -
        //     se2, se3         -
        //     sgh2, sgh3, sgh4        -
        //     sh2, sh3, si2, si3, sl2, sl3, sl4         -
        //     s1, s2, s3, s4, s5, s6, s7          -
        //     ss1, ss2, ss3, ss4, ss5, ss6, ss7, sz1, sz2, sz3         -
        //     sz11, sz12, sz13, sz21, sz22, sz23, sz31, sz32, sz33        -
        //     xgh2, xgh3, xgh4, xh2, xh3, xi2, xi3, xl2, xl3, xl4         -
        //     nm          - mean motion
        //     z1, z2, z3, z11, z12, z13, z21, z22, z23, z31, z32, z33         -
        //     zmol        -
        //     zmos        -
    };
});
<|endoftext|>


<commit_before>/**
 *
 * Created by Dominik on 25.04.2016.
 * Based on sample_client.js from https://github.com/node-opcua/node-opcua/blob/master/documentation/sample_client.js
 *
 */

/*global require,console,setTimeout */
var opcua = require("node-opcua");
var async = require("async");
var Q = require("q");
var should = require("should");
var EventEmitter = require('events').EventEmitter;
var util = require('util');
//var the_session, the_subscription, eventEmitter;

util.inherits(OpcuaClient, EventEmitter);

function OpcuaClient(endpointUrl, callback){
	self = this;
	EventEmitter.call(this);
	client = new opcua.OPCUAClient();

	connect(client, endpointUrl)
		.then(createSession)
		.then(subscribe)
		.then(function(){
			self.emit('connect');
			callback();
		})
		.catch(function(err){
			console.error(err);
			self.emit('error', err);
			callback(err);

		});
}

function connect(client, endpointUrl){
	var deferred = Q.defer();

	client.connect(endpointUrl,function (err) {
		if(err) {
			deferred.reject(err);
		} else {
			console.log("connected to opcua server at " + endpointUrl);
			deferred.resolve();
		}
	});

	return deferred.promise;

}

function createSession(){
	var deferred = Q.defer();

	client.createSession(function(err,session) {
		if(!err) {
			the_session = session;
			deferred.resolve();
		} else {
			deferred.reject(err);
		}
	});

	return deferred.promise;
}

function subscribe(){
	var deferred = Q.defer();

	the_subscription = new opcua.ClientSubscription(the_session,{
	   requestedPublishingInterval: 1000,
	   requestedLifetimeCount: 10,
	   requestedMaxKeepAliveCount: 2,
	   maxNotificationsPerPublish: 10,
	   publishingEnabled: true,
	   priority: 10
    });

    the_subscription.on("started",function(){
	   console.log("subscription started - subscriptionId = ",the_subscription.subscriptionId);
	   deferred.resolve();
    }).on("keepalive",function(){
	   //console.log("keepalive");
    }).on("terminated",function(){
	   console.log("terminated");
    });

	return deferred.promise;
}

OpcuaClient.prototype.readVariable = function(nodeId, callback){
	//console.log('nodeId: '+nodeId);
	the_session.readVariableValue(nodeId, function(err,dataValue) {
		//dataValue.statusCode.should.eql(opcua.StatusCodes.Good);
		if(!err) callback(err, dataValue.value.value);
		else callback(err);
	});
};

OpcuaClient.prototype.readDatatype = function(nodeId, callback){
	the_session.readVariableValue(nodeId, function(err,dataValue) {
		if(!err) {
			console.log(dataValue.statusCode);
			callback(err, dataValue.value.dataType.key);
		} else {callback(err);}
	});
};

OpcuaClient.prototype.monitorItem = function(nodeId){
    var monitoredItem  = the_subscription.monitor({
 	   nodeId: opcua.resolveNodeId(nodeId),
 	   attributeId: opcua.AttributeIds.Value
    },
    {
 	   samplingInterval: 100,
 	   discardOldest: true,
 	   queueSize: 10
    },
    opcua.read_service.TimestampsToReturn.Both
    );

	return monitoredItem;
};

OpcuaClient.prototype.onChange = function(nodeId, callback){
	var monitoredItem = this.monitorItem(nodeId);
  setTimeout(function(){monitoredItem.on("changed",function(dataValue){
   	  var value = dataValue.value.value;
	  //console.log(new Date().toString(), nodeId, value);
	  callback(value);
    });},10000);
};

OpcuaClient.prototype.writeNodeValue = function(nodeId, value, dataType, callback) {

    var nodesToWrite = [
        {
            nodeId: nodeId,
            attributeId: opcua.AttributeIds.Value,
            indexRange: null,
            value: { /* dataValue*/
				// note: most servers reject timestamps written manually here
                value: { /* Variant */
                    dataType: opcua.DataType[dataType],
                    value: value
                }
          }
        }
    ];

    the_session.write(nodesToWrite, function (err, statusCodes) {
        if (!err) {
					// console.log('statusCodes:'+statusCodes);
					statusCodes.length.should.equal(nodesToWrite.length);
					statusCodes.forEach(function(item){
						item.should.eql(opcua.StatusCodes.Good);
					});
        }
		callback(err);
    });

};

module.exports = OpcuaClient;<commit_msg>added check for status codes<commit_after>/**
 *
 * Created by Dominik on 25.04.2016.
 * Based on sample_client.js from https://github.com/node-opcua/node-opcua/blob/master/documentation/sample_client.js
 *
 */

/*global require,console,setTimeout */
var opcua = require("node-opcua");
var async = require("async");
var Q = require("q");
var should = require("should");
var EventEmitter = require('events').EventEmitter;
var util = require('util');
//var the_session, the_subscription, eventEmitter;

util.inherits(OpcuaClient, EventEmitter);

function OpcuaClient(endpointUrl, callback){
	self = this;
	EventEmitter.call(this);
	client = new opcua.OPCUAClient();

	connect(client, endpointUrl)
		.then(createSession)
		.then(subscribe)
		.then(function(){
			self.emit('connect');
			callback();
		})
		.catch(function(err){
			console.error(err);
			self.emit('error', err);
			callback(err);

		});
}

function connect(client, endpointUrl){
	var deferred = Q.defer();

	client.connect(endpointUrl,function (err) {
		if(err) {
			deferred.reject(err);
		} else {
			console.log("connected to opcua server at " + endpointUrl);
			deferred.resolve();
		}
	});

	return deferred.promise;

}

function createSession(){
	var deferred = Q.defer();

	client.createSession(function(err,session) {
		if(!err) {
			the_session = session;
			deferred.resolve();
		} else {
			deferred.reject(err);
		}
	});

	return deferred.promise;
}

function subscribe(){
	var deferred = Q.defer();

	the_subscription = new opcua.ClientSubscription(the_session,{
	   requestedPublishingInterval: 1000,
	   requestedLifetimeCount: 10,
	   requestedMaxKeepAliveCount: 2,
	   maxNotificationsPerPublish: 10,
	   publishingEnabled: true,
	   priority: 10
    });

    the_subscription.on("started",function(){
	   console.log("subscription started - subscriptionId = ",the_subscription.subscriptionId);
	   deferred.resolve();
    }).on("keepalive",function(){
	   //console.log("keepalive");
    }).on("terminated",function(){
	   console.log("terminated");
    });

	return deferred.promise;
}

OpcuaClient.prototype.readVariable = function(nodeId, callback){
	//console.log('nodeId: '+nodeId);
	the_session.readVariableValue(nodeId, function(err,dataValue) {
		dataValue.statusCode.should.eql(opcua.StatusCodes.Good);
		if(!err) callback(err, dataValue.value.value);
		else callback(err);
	});
};

OpcuaClient.prototype.readDatatype = function(nodeId, callback){
	the_session.readVariableValue(nodeId, function(err,dataValue) {
		if(!err) {
			dataValue.statusCode.should.eql(opcua.StatusCodes.Good);
			callback(err, dataValue.value.dataType.key);
		} else {callback(err);}
	});
};

OpcuaClient.prototype.monitorItem = function(nodeId){
    var monitoredItem  = the_subscription.monitor({
 	   nodeId: opcua.resolveNodeId(nodeId),
 	   attributeId: opcua.AttributeIds.Value
    },
    {
 	   samplingInterval: 100,
 	   discardOldest: true,
 	   queueSize: 10
    },
    opcua.read_service.TimestampsToReturn.Both
    );

	return monitoredItem;
};

OpcuaClient.prototype.onChange = function(nodeId, callback){
	var monitoredItem = this.monitorItem(nodeId);
  setTimeout(function(){monitoredItem.on("changed",function(dataValue){
   	  var value = dataValue.value.value;
	  //console.log(new Date().toString(), nodeId, value);
	  callback(value);
    });},10000);
};

OpcuaClient.prototype.writeNodeValue = function(nodeId, value, dataType, callback) {

    var nodesToWrite = [
        {
            nodeId: nodeId,
            attributeId: opcua.AttributeIds.Value,
            indexRange: null,
            value: { /* dataValue*/
				// note: most servers reject timestamps written manually here
                value: { /* Variant */
                    dataType: opcua.DataType[dataType],
                    value: value
                }
          }
        }
    ];

    the_session.write(nodesToWrite, function (err, statusCodes) {
        if (!err) {
					// console.log('statusCodes:'+statusCodes);
					statusCodes.length.should.equal(nodesToWrite.length);
					statusCodes.forEach(function(item){
						item.should.eql(opcua.StatusCodes.Good);
					});
        }
		callback(err);
    });

};

module.exports = OpcuaClient;<|endoftext|>


<commit_before>/* This sample code will fade the color of your HUE Lights from green to red depending on your health */
// Dependencies:
// - cs-gamtestate
// - request

var CSGameState = require('cs-gamestate')(3000, '0.0.0.0');
var request = require('request');

CSGameState.on('player.state.health', function(health) {
	var hue = health / 100 * 21845;

	request({
		'method': 'PUT',
		'uri': 'http://<ip_of_your_bridge>:<port>/api/csgameint/lights/<id_of_your_light>/state',
		'body': JSON.stringify({
			'transitiontime': 0,
			'bri': 254,
			'sat': 254,
			'hue': hue,
			'on': health > 0 ? true : false
		})
	});
});
<commit_msg>Added comments<commit_after>/* This sample code will fade the color of your HUE Lights from green to red depending on your health */
// Dependencies:
// - cs-gamestate
// - request

const CSGameState = new (require('cs-gamestate'))(3000, '0.0.0.0');
const request = require('request');

CSGameState.on('player.state.health', function(health) {
	// Fade the color from GREEN to RED according to the players health
	const hue = health / 100 * 21845;

	request({
		'method': 'PUT',
		'uri': 'http://<ip_of_your_bridge>:<port>/api/csgameint/lights/<id_of_your_light>/state',
		'body': JSON.stringify({
			'transitiontime': 0,
			'bri': 254,
			'sat': 254,
			'hue': hue,
			'on': health > 0 ? true : false
		})
	});
});
<|endoftext|>


<commit_before>/* Base phone module for Odoo
   Copyright (C) 2013-2015 Alexis de Lattre <alexis@via.ecp.fr>
   The licence is in the file __openerp__.py */

odoo.define('base_phone.phone_widget', function (require) {
"use strict";

var core = require('web.core');
var formwidgets = require('web.form_widgets');
var web_client = require('web.web_client');
var _t = core._t;

var FieldPhone = formwidgets.FieldChar.extend({
        template: 'FieldPhone',
        initialize_content: function() {
            this._super();
            var $button = this.$el.find('button');
            $button.click(this.on_button_clicked);
            this.setupFocus($button);
        },
        render_value: function() {
            if (!this.get('effective_readonly')) {
                this._super();
            } else {
                var self = this;
                var phone_num = this.get('value');
                console.log('BASE_PHONE phone_num = %s', phone_num);
                var href = '#';
                if (phone_num) {
                  href = 'tel:' + phone_num;
                }
                if (phone_num) {
                    this.$el.find('a').attr('href', href).text(phone_num);
                }
                else {
                    this.$el.find('a').attr('href', '').text('');
                }
                /*
                var click2dial_text = '';
                if (formatted_phone_num && !this.options.dial_button_invisible) {
                  click2dial_text = _t('Dial');
                }
                this.$el.find('#click2dial').off('click');
                this.$el.find('#click2dial')
                    .text(click2dial_text)
                    .on('click', function(ev) {
                        self.do_notify(
                            _t('Click2dial started'),
                            _t('Unhook your ringing phone'));
                        var arg = {
                            'phone_number': phone_num,
                            'click2dial_model': self.view.dataset.model,
                            'click2dial_id': self.view.datarecord.id};
                        self.rpc('/base_phone/click2dial', arg).done(function(r) {
                            // console.log('Click2dial r=%s', JSON.stringify(r));
                            if (r === false) {
                                self.do_warn("Click2dial failed");
                            } else if (typeof r === 'object') {
                                self.do_notify(
                                    _t('Click2dial successfull'),
                                    _t('Number dialed:') + ' ' + r.dialed_number);
                                if (r.action_model) {
                                    var context = {
                                        'click2dial_model': self.view.dataset.model,
                                        'click2dial_id': self.view.datarecord.id,
                                        'phone_number': phone_num,
                                        };
                                    var action = {
                                        name: r.action_name,
                                        type: 'ir.actions.act_window',
                                        res_model: r.action_model,
                                        view_mode: 'form',
                                        views: [[false, 'form']],
                                        target: 'new',
                                        context: context,
                                        };
                                    web_client.action_manager.do_action(action);
                                }
                            }
                        });
                    }); */
            }
        },
        on_button_clicked: function() {
            location.href = 'tel:' + this.get('value');
        }
    });

var FieldFax = formwidgets.FieldChar.extend({
        template: 'FieldFax',
        initialize_content: function() {
            this._super();
            var $button = this.$el.find('button');
            $button.click(this.on_button_clicked);
            this.setupFocus($button);
        },
        render_value: function() {
            if (!this.get('effective_readonly')) {
                this._super();
            } else {
                var fax_num = this.get('value');
                // console.log('BASE_PHONE fax_num = %s', fax_num);
                var href = '#';
                if (fax_num) {
                    href = 'fax:' + fax_num;
                }
                if (fax_num) {
                    this.$el.find('a').attr('href', href).text(fax_num);
                }
                else {
                    this.$el.find('a').attr('href', '').text('');
                }
            }
        },
        on_button_clicked: function() {
            location.href = 'fax:' + this.get('value');
        }
    });

// To avoid conflicts, we check that widgets do not exist before using

console.log("core.form_widget_registry.get('fax')=" + core.form_widget_registry.get('fax'));
console.log("core.form_widget_registry.get('PHONE')=" + core.form_widget_registry.get('phone'));

if(!core.form_widget_registry.get('fax')){
    core.form_widget_registry.add('fax', FieldFax);
}

if(!core.form_widget_registry.get('phone')){
    core.form_widget_registry.add('phone', FieldPhone);
}

var treewidgets = require('web.ListView');

var ColumnPhone = treewidgets.Column.extend({
    // ability to add widget="phone" in TREE view
    _format: function(row_data, options) {
        var value = row_data[this.id].value;
        if (value) {
            return _.template("<a href='tel:<%-href%>'><%-text%>")({
                href: value.replace(' ', ''),
                text: value
            });
        }
        return this._super(row_data, options);
    }
});

if (!core.list_widget_registry.get('phone')) {
    core.list_widget_registry.add('field.phone', ColumnPhone);
}

});
<commit_msg>JS code cleanup: no spaces in href links<commit_after>/* Base phone module for Odoo
   Copyright (C) 2013-2015 Alexis de Lattre <alexis@via.ecp.fr>
   The licence is in the file __openerp__.py */

odoo.define('base_phone.phone_widget', function (require) {
"use strict";

var core = require('web.core');
var formwidgets = require('web.form_widgets');
var web_client = require('web.web_client');
var _t = core._t;

var FieldPhone = formwidgets.FieldChar.extend({
        template: 'FieldPhone',
        initialize_content: function() {
            this._super();
            var $button = this.$el.find('button');
            $button.click(this.on_button_clicked);
            this.setupFocus($button);
        },
        render_value: function() {
            if (!this.get('effective_readonly')) {
                this._super();
            } else {
                var self = this;
                var phone_num = this.get('value');
                // console.log('BASE_PHONE phone_num = %s', phone_num);
                if (phone_num) {
                    var raw_phone_num = phone_num.replace(/ /g, '');
                    this.$el.find('a').attr('href', 'tel:' + raw_phone_num).text(phone_num);
                }
                else {
                    this.$el.find('a').attr('href', '').text('');
                }
                /*
                var click2dial_text = '';
                if (formatted_phone_num && !this.options.dial_button_invisible) {
                  click2dial_text = _t('Dial');
                }
                this.$el.find('#click2dial').off('click');
                this.$el.find('#click2dial')
                    .text(click2dial_text)
                    .on('click', function(ev) {
                        self.do_notify(
                            _t('Click2dial started'),
                            _t('Unhook your ringing phone'));
                        var arg = {
                            'phone_number': phone_num,
                            'click2dial_model': self.view.dataset.model,
                            'click2dial_id': self.view.datarecord.id};
                        self.rpc('/base_phone/click2dial', arg).done(function(r) {
                            // console.log('Click2dial r=%s', JSON.stringify(r));
                            if (r === false) {
                                self.do_warn("Click2dial failed");
                            } else if (typeof r === 'object') {
                                self.do_notify(
                                    _t('Click2dial successfull'),
                                    _t('Number dialed:') + ' ' + r.dialed_number);
                                if (r.action_model) {
                                    var context = {
                                        'click2dial_model': self.view.dataset.model,
                                        'click2dial_id': self.view.datarecord.id,
                                        'phone_number': phone_num,
                                        };
                                    var action = {
                                        name: r.action_name,
                                        type: 'ir.actions.act_window',
                                        res_model: r.action_model,
                                        view_mode: 'form',
                                        views: [[false, 'form']],
                                        target: 'new',
                                        context: context,
                                        };
                                    web_client.action_manager.do_action(action);
                                }
                            }
                        });
                    }); */
            }
        },
        on_button_clicked: function() {
            location.href = 'tel:' + this.get('value');
        }
    });

var FieldFax = formwidgets.FieldChar.extend({
        template: 'FieldFax',
        initialize_content: function() {
            this._super();
            var $button = this.$el.find('button');
            $button.click(this.on_button_clicked);
            this.setupFocus($button);
        },
        render_value: function() {
            if (!this.get('effective_readonly')) {
                this._super();
            } else {
                var fax_num = this.get('value');
                // console.log('BASE_PHONE fax_num = %s', fax_num);
                if (fax_num) {
                    var raw_fax_num = fax_num.replace(/ /g, '');
                    this.$el.find('a').attr('href', 'fax:' + raw_fax_num).text(fax_num);
                }
                else {
                    this.$el.find('a').attr('href', '').text('');
                }
            }
        },
        on_button_clicked: function() {
            location.href = 'fax:' + this.get('value');
        }
    });

// To avoid conflicts, we check that widgets do not exist before using
if(!core.form_widget_registry.get('fax')){
    core.form_widget_registry.add('fax', FieldFax);
}

if(!core.form_widget_registry.get('phone')){
    core.form_widget_registry.add('phone', FieldPhone);
}

var treewidgets = require('web.ListView');

var ColumnPhone = treewidgets.Column.extend({
    // ability to add widget="phone" in TREE view
    _format: function(row_data, options) {
        var phone_num = row_data[this.id].value;
        if (phone_num) {
            var raw_phone_num = phone_num.replace(/ /g, '');
            return _.template("<a href='tel:<%-href%>'><%-text%>")({
                href: raw_phone_num,
                text: phone_num
            });
        }
        return this._super(row_data, options);
    }
});

if (!core.list_widget_registry.get('phone')) {
    core.list_widget_registry.add('field.phone', ColumnPhone);
}

});
<|endoftext|>


<commit_before>function Tacho(){
	this.info = {
		title: "fancy Tacho",
		preferredSize: [400,380],
		streams: ["engineInfo","wheelInfo", "electrics"]
	};

	this.hudMemoryCanvas = {};
	this.hudFont = ' "Lucida Console", Monaco, monospace ';
	this.hudRpmInfo = {
		rpm: 0,
		bigStep: 500,
		smallStep: 250,
		numberFactor: 0.01
	};
}

Tacho.prototype.initialize = function(){
	$(this.rootElement).append('<canvas id="hudCanvas"></canvas>');

	$("#hudCanvas").css({
		width: '100%',
		height: '100%'
	});

	c = $("#hudCanvas")[0];
	c.width = 300;
	c.height = 300;

	this.hudAddMemoryCanvas('background');
};

Tacho.prototype.resize = function(){
	//console.log($(this.rootElement).height());
	//var c = $("#hudCanvas")[0];
	//c.width = $(this.rootElement).width();
	//c.height = $(this.rootElement).height();
	//this.update();
}

Tacho.prototype.update = function(streams){
//	$(this.rootElement).html("rpm: "+streams["vehicleInfo"][1][4].toFixed() + "<br /> Speed: "+(streams["electrics"]["wheelspeed"]*3.6).toFixed());//streams["vehicleinfo"]);
	wheelInfo = streams['wheelInfo'];
	engineInfo = streams['engineInfo'];

		this.hudUpdateRPM();

	ctx = $("#hudCanvas")[0].getContext('2d');

	ctx.drawImage(this.hudMemoryCanvas['background'],0,0);

	ctx.save();

	// rpm needle

	ctx.strokeStyle = 'rgb(255,0,0)';
	ctx.lineWidth = 5;

	ctx.translate(150,150);
	ctx.rotate(rpmConverter.convertValue(streams["electrics"].rpm));
	ctx.beginPath();
	ctx.moveTo(0,-140);
	ctx.lineTo(0,-100);
	ctx.stroke();
	ctx.closePath();
	ctx.restore();

	// speed
	speed = streams["electrics"].wheelspeed;
	if (isNaN(speed)) speed = streams["electrics"].airspeed;
	speed *= 3.6;

	ctx.save();
	ctx.fillStyle = 'rgb(200,200,200)';
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '70px'+this.hudFont;
	ctx.fillText((speed).toFixed(),150,150);
	ctx.font = '20px'+this.hudFont;
	ctx.fillText('km/h',150,185);

	// gear

	if (engineInfo[5] == 0)
	{
		gear = "N";
	}else if(engineInfo[5] < 0)
	{
		gear = "R";
	}else
	{
		gear = engineInfo[5].toString();
	}

	ctx.fillStyle = 'rgb(200,200,200)';
	ctx.font = '35px'+this.hudFont;
	ctx.fillText(gear,150,220);

	if (engineInfo[5]<0 && engineInfo[7]>1) // more than one reversegear and in reverse
	{
		ctx.font = '20px'+hudFont;
		ctx.textAlign = 'left';
		ctx.fillText((engineInfo[5]*-1).toString(),162,224);
	}

	//reflection yo

	grad = ctx.createLinearGradient(0,150,150,0);
	grad.addColorStop(0,'rgba(255,255,255,0)');
	grad.addColorStop(0.5,'rgba(255,255,255,0)');
	grad.addColorStop(1,'rgba(255,255,255,0.3)');

	ctx.fillStyle = grad;

	ctx.beginPath();
	ctx.arc(150,150,147,0,2*Math.PI,true);
    ctx.fill();
	ctx.closePath();

	ctx.restore();
};

Tacho.prototype.hudAddMemoryCanvas = function(name)
{
	c = document.createElement('canvas');
	c.width = 300;
	c.height = 300;

	this.hudMemoryCanvas[name] = c;
};

Tacho.prototype.hudUpdateRPM = function()
{
	if(this.hudRpmInfo.rpm == engineInfo[1]) return;

	this.hudRpmInfo.rpm = engineInfo[1];
	rpmConverter = new Converter(0,engineInfo[1],-(Math.PI/4)*3,(Math.PI/4)*3);

	if(this.hudRpmInfo.rpm <= 3000)
	{
		this.hudRpmInfo.bigStep = 500;
		this.hudRpmInfo.smallStep = 100;
		this.hudRpmInfo.numberFactor = 0.01;

	}else if(this.hudRpmInfo.rpm <= 5000)
	{
		this.hudRpmInfo.bigStep = 500;
		this.hudRpmInfo.smallStep = 250;
		this.hudRpmInfo.numberFactor = 0.01;
	}else if(this.hudRpmInfo.rpm <= 20000)
	{
		this.hudRpmInfo.bigStep = 1000;
		this.hudRpmInfo.smallStep = 250;
		this.hudRpmInfo.numberFactor = 0.001;
	}else
	{
		this.hudRpmInfo.bigStep = 100000;
		this.hudRpmInfo.smallStep = 20000;
		this.hudRpmInfo.numberFactor = 0.0001;
	}

	this.hudDrawBackground();

};

Tacho.prototype.hudDrawBackground = function()
{
	// Draw background
	ctx = this.hudMemoryCanvas['background'].getContext('2d');
	// background
	ctx.save();

	ctx.beginPath();
	ctx.arc(150,150,147,0,2*Math.PI,true);
    ctx.fill();
	ctx.closePath();

	// dial

	grad = ctx.createRadialGradient(150,150,100,150,150,140);
	grad.addColorStop(0,'rgb(100,100,100)');
	grad.addColorStop(0.15,'rgb(200,200,200)');
	grad.addColorStop(0.85,'rgb(200,200,200)');
	grad.addColorStop(1,'rgb(100,100,100)');

	ctx.strokeStyle = grad;
	ctx.lineWidth = 40;

	ctx.beginPath();
	ctx.arc(150,150,120,0,2*Math.PI,false);
	ctx.stroke();
	ctx.closePath();

	// Unit
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '15px bold'+this.hudFont;
	ctx.fillText('1/min',150,263);
	ctx.fillText('x'+(1/this.hudRpmInfo.numberFactor).toFixed(),150,277);
	ctx.restore();

	// redline

	ctx.save();
	ctx.strokeStyle = 'rgb(255,0,0)';
	ctx.lineWidth = 5;

	ctx.translate(150,150);
	ctx.rotate(rpmConverter.convertValue(this.hudRpmInfo.rpm));
	ctx.beginPath();
	ctx.moveTo(0,-140);
	ctx.lineTo(0,-100);
	ctx.stroke();
	ctx.closePath();
	ctx.restore();

	// rpm markers
	ctx.save();
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '25px'+this.hudFont;
	ctx.lineWidth = 3;

	ctx.translate(150,150);
	ctx.rotate(rpmConverter.convertValue(0));
	for(var i = 0 ; i<=engineInfo[1]; i+=this.hudRpmInfo.smallStep)
	{
		if(i % this.hudRpmInfo.bigStep==0)
		{
			ctx.fillText((i*this.hudRpmInfo.numberFactor).toFixed(),0,-118);
			ctx.beginPath();
			ctx.moveTo(0,-140);
			ctx.lineTo(0,-132);
			ctx.moveTo(0,-108);
			ctx.lineTo(0,-100);
			ctx.stroke();
			ctx.closePath();
		}else
		{
			ctx.beginPath();
			ctx.moveTo(0,-140);
			ctx.lineTo(0,-135);
			ctx.moveTo(0,-105);
			ctx.lineTo(0,-100);
			ctx.stroke();
			ctx.closePath();
		}
		ctx.rotate(rpmConverter.convertLength(this.hudRpmInfo.smallStep));
	}
	ctx.restore();
};

function Converter(inMin, inMax, outMin, outMax)
{
	this.inMin = inMin;
	this.inMax = inMax;
	this.inLength = inMax - inMin;
	this.outMin = outMin;
	this.outMax = outMax;
	this.outLength = outMax- outMin;
}
Converter.prototype.convertValue = function(value)
{
	if(value<this.inMin) valueIn = this.inMin;
	if(value>this.inMax) valueIn = this.inMax;
	return (value/this.inLength)*this.outLength + this.outMin;
};
Converter.prototype.convertLength = function(length)
{
	return (length/this.inLength)*this.outLength;
};<commit_msg>[improved] Tacho<commit_after>function Tacho(){
	this.info = {
		title: "fancy Tacho",
		preferredSize: [400,380],
		streams: ["engineInfo","wheelInfo", "electrics"]
	};

	this.hudMemoryCanvas = {};
	this.hudFont = ' "Lucida Console", Monaco, monospace ';
	this.hudRpmInfo = {
		rpm: 0,
		bigStep: 500,
		smallStep: 250,
		numberFactor: 0.01
	};
}

Tacho.prototype.initialize = function(){
	this.canvas = $('<canvas></canvas>').appendTo(this.rootElement);

	this.canvas.css({
		width: '100%',
		height: '100%'
	});

	c = this.canvas[0];
	c.width = 300;
	c.height = 300;

	this.hudAddMemoryCanvas('background');
	this.hudUpdateRPM();
	this.resize();
};

Tacho.prototype.resize = function(){
	// canvas
	c = this.canvas[0];
	c.width = this.canvas.width();
	c.height = this.canvas.height();

	ctx = c.getContext('2d');
	ctx.restore();
	ctx.setTransform(1, 0, 0, 1, 0, 0);
	ctx.scale(this.canvas.width()/300,this.canvas.height()/300);
	ctx.save();
};

Tacho.prototype.update = function(streams){
	wheelInfo = streams['wheelInfo'];
	engineInfo = streams['engineInfo'];

		this.hudUpdateRPM();

	ctx = this.canvas[0].getContext('2d');

	ctx.drawImage(this.hudMemoryCanvas['background'],0,0);

	ctx.save();

	// rpm needle

	ctx.strokeStyle = 'rgb(255,0,0)';
	ctx.lineWidth = 5;

	ctx.translate(150,150);
	ctx.rotate(rpmConverter.convertValue(streams["electrics"].rpm));
	ctx.beginPath();
	ctx.moveTo(0,-140);
	ctx.lineTo(0,-100);
	ctx.stroke();
	ctx.closePath();
	ctx.restore();

	// speed
	speed = streams["electrics"].wheelspeed;
	if (isNaN(speed)) speed = streams["electrics"].airspeed;
	speed *= 3.6;

	ctx.save();
	ctx.fillStyle = 'rgb(200,200,200)';
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '70px'+this.hudFont;
	ctx.fillText((speed).toFixed(),150,150);
	ctx.font = '20px'+this.hudFont;
	ctx.fillText('km/h',150,185);

	// gear

	if (engineInfo[5] === 0)
	{
		gear = "N";
	}else if(engineInfo[5] < 0)
	{
		gear = "R";
	}else
	{
		gear = engineInfo[5].toString();
	}

	ctx.fillStyle = 'rgb(200,200,200)';
	ctx.font = '35px'+this.hudFont;
	ctx.fillText(gear,150,220);

	if (engineInfo[5]<0 && engineInfo[7]>1) // more than one reversegear and in reverse
	{
		ctx.font = '20px'+hudFont;
		ctx.textAlign = 'left';
		ctx.fillText((engineInfo[5]*-1).toString(),162,224);
	}

	//reflection yo

	grad = ctx.createLinearGradient(0,150,150,0);
	grad.addColorStop(0,'rgba(255,255,255,0)');
	grad.addColorStop(0.5,'rgba(255,255,255,0)');
	grad.addColorStop(1,'rgba(255,255,255,0.3)');

	ctx.fillStyle = grad;

	ctx.beginPath();
	ctx.arc(150,150,147,0,2*Math.PI,true);
    ctx.fill();
	ctx.closePath();

	ctx.restore();
};

Tacho.prototype.hudAddMemoryCanvas = function(name)
{
	c = document.createElement('canvas');
	c.width = 300;
	c.height = 300;

	this.hudMemoryCanvas[name] = c;
};

Tacho.prototype.hudUpdateRPM = function()
{
	if(this.hudRpmInfo.rpm == engineInfo[1]) return;

	this.hudRpmInfo.rpm = engineInfo[1];
	rpmConverter = new Converter(0,engineInfo[1],-(Math.PI/4)*3,(Math.PI/4)*3);

	if(this.hudRpmInfo.rpm <= 3000)
	{
		this.hudRpmInfo.bigStep = 500;
		this.hudRpmInfo.smallStep = 100;
		this.hudRpmInfo.numberFactor = 0.01;

	}else if(this.hudRpmInfo.rpm <= 5000)
	{
		this.hudRpmInfo.bigStep = 500;
		this.hudRpmInfo.smallStep = 250;
		this.hudRpmInfo.numberFactor = 0.01;
	}else if(this.hudRpmInfo.rpm <= 20000)
	{
		this.hudRpmInfo.bigStep = 1000;
		this.hudRpmInfo.smallStep = 250;
		this.hudRpmInfo.numberFactor = 0.001;
	}else
	{
		this.hudRpmInfo.bigStep = 100000;
		this.hudRpmInfo.smallStep = 20000;
		this.hudRpmInfo.numberFactor = 0.0001;
	}

	this.hudDrawBackground();

};

Tacho.prototype.hudDrawBackground = function()
{
	// Draw background
	ctx = this.hudMemoryCanvas['background'].getContext('2d');
	// background
	ctx.save();

	ctx.beginPath();
	ctx.arc(150,150,147,0,2*Math.PI,true);
    ctx.fill();
	ctx.closePath();

	// dial

	grad = ctx.createRadialGradient(150,150,100,150,150,140);
	grad.addColorStop(0,'rgb(100,100,100)');
	grad.addColorStop(0.15,'rgb(200,200,200)');
	grad.addColorStop(0.85,'rgb(200,200,200)');
	grad.addColorStop(1,'rgb(100,100,100)');

	ctx.strokeStyle = grad;
	ctx.lineWidth = 40;

	ctx.beginPath();
	ctx.arc(150,150,120,0,2*Math.PI,false);
	ctx.stroke();
	ctx.closePath();

	// Unit
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '15px bold'+this.hudFont;
	ctx.fillText('1/min',150,263);
	ctx.fillText('x'+(1/this.hudRpmInfo.numberFactor).toFixed(),150,277);
	ctx.restore();

	// redline

	ctx.save();
	ctx.strokeStyle = 'rgb(255,0,0)';
	ctx.lineWidth = 5;

	ctx.translate(150,150);
	ctx.rotate(rpmConverter.convertValue(this.hudRpmInfo.rpm));
	ctx.beginPath();
	ctx.moveTo(0,-140);
	ctx.lineTo(0,-100);
	ctx.stroke();
	ctx.closePath();
	ctx.restore();

	// rpm markers
	ctx.save();
	ctx.textAlign = 'center';
	ctx.textBaseline = 'middle';
	ctx.font = '25px'+this.hudFont;
	ctx.lineWidth = 3;

	ctx.translate(150,150);
	ctx.rotate(rpmConverter.convertValue(0));
	for(var i = 0 ; i <= engineInfo[1]; i += this.hudRpmInfo.smallStep)
	{
		if(i % this.hudRpmInfo.bigStep === 0)
		{
			ctx.fillText((i*this.hudRpmInfo.numberFactor).toFixed(),0,-118);
			ctx.beginPath();
			ctx.moveTo(0,-140);
			ctx.lineTo(0,-132);
			ctx.moveTo(0,-108);
			ctx.lineTo(0,-100);
			ctx.stroke();
			ctx.closePath();
		}else
		{
			ctx.beginPath();
			ctx.moveTo(0,-140);
			ctx.lineTo(0,-135);
			ctx.moveTo(0,-105);
			ctx.lineTo(0,-100);
			ctx.stroke();
			ctx.closePath();
		}
		ctx.rotate(rpmConverter.convertLength(this.hudRpmInfo.smallStep));
	}
	ctx.restore();
};

function Converter(inMin, inMax, outMin, outMax)
{
	this.inMin = inMin;
	this.inMax = inMax;
	this.inLength = inMax - inMin;
	this.outMin = outMin;
	this.outMax = outMax;
	this.outLength = outMax- outMin;
}
Converter.prototype.convertValue = function(value)
{
	if(value<this.inMin) valueIn = this.inMin;
	if(value>this.inMax) valueIn = this.inMax;
	return (value/this.inLength)*this.outLength + this.outMin;
};
Converter.prototype.convertLength = function(length)
{
	return (length/this.inLength)*this.outLength;
};<|endoftext|>


<commit_before>/*!
 * InferenceEngine - inference.js
 * MIT License (c) 2014
 * codenameyau.github.io
 *
 * Description:
 * InferenceEngine is capable of learning facts and making
 * logical deductions based on facts that it already knows.
 *
 * Implementation:
 * InferenceEngine is implemented as a weighted directed graph,
 * where the vertices represent properties and the edges represent
 * relationships between two properties. Each property has an
 * relationship with its inverse property with a weight of -1.
 *
 * The weights indicate whether a relationship is always true (weight = 1),
 * sometimes true (weight = 0), or never true (weight = -1).
 * Weights function more as labels rather than costs.
 */
'use strict';

var Graph = require('directed-graph');

/*******************************
 * InferenceEngine Constructor *
 *******************************/
function InferenceEngine() {
  this.graph = new Graph();
  this.truth = {
    always: 1,
    sometimes: 0,
    never: -1
  };
}

/**********************************
 * InferenceEngine Public Methods *
 **********************************/
InferenceEngine.prototype.getGraph = function() {
  return this.graph;
};

InferenceEngine.prototype.negate = function(definition) {
  return (definition === true) ? false : true;
};

InferenceEngine.prototype.inverse = function(noun) {
  return this.replaceSpaces('no ' + noun);
};

InferenceEngine.prototype.addNoun = function(noun) {
  noun = this.replaceSpaces(noun);
  var inverseNoun = this.inverse(noun);
  this.graph.addVertex(noun);
  this.graph.addVertex(inverseNoun);
  this.graph.addEdge(noun, noun, 1);
  this.graph.addEdge(inverseNoun, inverseNoun, 1);
  this.graph.addEdge(noun, inverseNoun, 0);
  this.graph.addEdge(inverseNoun, noun, 0);
};

InferenceEngine.prototype.hasNoun = function(noun) {
  return (this.graph.hasVertex(noun) && this.graph.hasVertex(this.inverse(noun)));
};

InferenceEngine.prototype.hasDirectRelationship = function(nounA, nounB) {
  return this.graph.hasEdge(nounA, nounB);
};

InferenceEngine.prototype.getRelationship = function(nounA, nounB) {
  return this.graph.getWeight(nounA, nounB);
};

/************************************
 * InferenceEngine Teaching Methods *
 ************************************/
InferenceEngine.prototype.teachAllAre = function(nounA, nounB) {
  // [TODO]: check for contradictions
  var inverseA = this.inverse(nounA);
  var inverseB = this.inverse(nounB);
  this.graph.addEdge(nounA, nounB, 1);
  this.graph.addEdge(inverseB, inverseA, 1);
  this.graph.addEdge(inverseA, nounB, 0);
  this.graph.addEdge(inverseB, nounA, 0);
  this.graph.addEdge(nounA, inverseB, 0);
  this.graph.addEdge(nounB, inverseA, 0);
};

InferenceEngine.prototype.teachNoAre = function() {

};

InferenceEngine.prototype.teachSomeAre = function() {

};

InferenceEngine.prototype.teachSomeAreNot = function() {

};

/*********************************
 * InferenceEngine Query Methods *
 *********************************/
InferenceEngine.prototype.queryAreAll = function() {

};

InferenceEngine.prototype.queryAreNo = function() {

};

InferenceEngine.prototype.queryAreSome = function() {

};

InferenceEngine.prototype.queryAreSomeNot = function() {

};

/************************************
 * InferenceEngine Internal Methods *
 ************************************/
InferenceEngine.prototype.replaceSpaces = function(noun) {
  return noun.replace(/[\-\s]+/g, '_');
};

module.exports = InferenceEngine;
<commit_msg>Adding assert statement<commit_after>/*!
 * InferenceEngine - inference.js
 * MIT License (c) 2014
 * codenameyau.github.io
 *
 * Description:
 * InferenceEngine is capable of learning facts and making
 * logical deductions based on facts that it already knows.
 *
 * Implementation:
 * InferenceEngine is implemented as a weighted directed graph,
 * where the vertices represent properties and the edges represent
 * relationships between two properties.
 */
'use strict';

var Graph = require('directed-graph');

/*******************************
 * InferenceEngine Constructor *
 *******************************/
function InferenceEngine() {
  this.graph = new Graph();
}

/**********************************
 * InferenceEngine Public Methods *
 **********************************/
InferenceEngine.prototype.getGraph = function() {
  return this.graph;
};

InferenceEngine.prototype.negate = function(definition) {
  return (definition === true) ? false : true;
};

InferenceEngine.prototype.inverse = function(noun) {
  return this.replaceSpaces('no ' + noun);
};

InferenceEngine.prototype.addNoun = function(noun) {
  noun = this.replaceSpaces(noun);
  var inverseNoun = this.inverse(noun);
  this.graph.addVertex(noun);
  this.graph.addVertex(inverseNoun);
  this.graph.addEdge(noun, noun, 1);
  this.graph.addEdge(inverseNoun, inverseNoun, 1);
  this.graph.addEdge(noun, inverseNoun, 0);
  this.graph.addEdge(inverseNoun, noun, 0);
};

InferenceEngine.prototype.hasNoun = function(noun) {
  return (this.graph.hasVertex(noun) && this.graph.hasVertex(this.inverse(noun)));
};

InferenceEngine.prototype.hasDirectRelationship = function(nounA, nounB) {
  return this.graph.hasEdge(nounA, nounB);
};

InferenceEngine.prototype.getRelationship = function(nounA, nounB) {
  return this.graph.getWeight(nounA, nounB);
};

InferenceEngine.prototype.assertStatement = function(nounA, nounB, bool) {
  return (this.getRelationship(nounA, nounB) === bool);
};

/************************************
 * InferenceEngine Teaching Methods *
 ************************************/
InferenceEngine.prototype.teachAllAre = function(nounA, nounB) {
  // [TODO]: check for contradictions
  var inverseA = this.inverse(nounA);
  var inverseB = this.inverse(nounB);
  this.graph.addEdge(nounA, nounB, 1);
  this.graph.addEdge(inverseB, inverseA, 1);
  this.graph.addEdge(inverseA, nounB, 0);
  this.graph.addEdge(inverseB, nounA, 0);
  this.graph.addEdge(nounA, inverseB, 0);
  this.graph.addEdge(nounB, inverseA, 0);
};

InferenceEngine.prototype.teachNoAre = function() {

};

InferenceEngine.prototype.teachSomeAre = function() {

};

InferenceEngine.prototype.teachSomeAreNot = function() {

};

/*********************************
 * InferenceEngine Query Methods *
 *********************************/
InferenceEngine.prototype.queryAreAll = function() {

};

InferenceEngine.prototype.queryAreNo = function() {

};

InferenceEngine.prototype.queryAreSome = function() {

};

InferenceEngine.prototype.queryAreSomeNot = function() {

};

/************************************
 * InferenceEngine Internal Methods *
 ************************************/
InferenceEngine.prototype.replaceSpaces = function(noun) {
  return noun.replace(/[\-\s]+/g, '_');
};

module.exports = InferenceEngine;
<|endoftext|>


<commit_before>var selectedFeature = null;

$(document).ready(function() {

    // Start with the map page
    if (window.location.hash && window.location.hash!='#mappage') {
        $.mobile.changePage('mappage');
    }

    // fix height of content
    function fixContentHeight() {
        var footer = $("div[data-role='footer']:visible"),
        content = $("div[data-role='content']:visible:visible"),
        viewHeight = $(window).height(),
        contentHeight = viewHeight - footer.outerHeight();

        if ((content.outerHeight() + footer.outerHeight()) !== viewHeight) {
            contentHeight -= (content.outerHeight() - content.height());
            content.height(contentHeight);
        }
        if (window.map) {
            map.updateSize();
        } else {
            // initialize map
            init();
        }
    }
    $(window).bind("orientationchange resize pageshow", fixContentHeight);
    fixContentHeight();
    //init();

    // Map zoom
    $("#plus").click(function(){
        map.zoomIn();
    });
    $("#minus").click(function(){
        map.zoomOut();
    });
    $("#locate").click(function(){
        var control = map.getControlsBy("id", "locate-control")[0];
        if (control.active) {
            control.getCurrentLocation();
        } else {
            control.activate();
        }
    });

    var sprintersLayer = new OpenLayers.Layer.Vector("Sprinters", {
        styleMap: new OpenLayers.StyleMap({
            externalGraphic : "img/mobile-loc.png",
            graphicOpacity : 1.0,
            graphicWith:16,
            graphicHeight:26
        })
    });

    var sprinters = getFeatures();
    sprintersLayer.addFeatures(sprinters);

    map.addLayer(sprintersLayer);

    var selectControl = new OpenLayers.Control.SelectFeature(sprintersLayer, {onSelect: function(feature){
        selectedFeature = feature;
        $.mobile.changePage($("#popup"), "pop");
    }});

    map.addControl(selectControl);
    selectControl.activate();

    $('div#popup').live('pageshow',function(event, ui){
        var li = "";
        for(var attr in selectedFeature.attributes){
            li += "

" + attr + "

"
            + selectedFeature.attributes[attr] + "

";
        }
        $("ul#details-list").empty().append(li).listview("refresh");
    });

    $('#searchpage').live('pageshow',function(event, ui){
        $('#query').bind('change', function(e){
            $('#search_results').empty();
            if ($('#query')[0].value === '') {
                return;
            }
            $.mobile.pageLoading();

            // Prevent form send
            e.preventDefault();

            var searchUrl = 'http://ws.geonames.org/searchJSON?featureClass=P&maxRows=10';
            searchUrl += '&name_startsWith=' + $('#query')[0].value;
            $.getJSON(searchUrl, function(data) {
                $.each(data.geonames, function() {
                    var place = this;
                    $('
')
                        .hide()
                        .append($('
', {
                            text: place.name
                        }))
                        .append($('
', {
                            html: '' + place.countryName + ' ' + place.fcodeName
                        }))
                        .appendTo('#search_results')
                        .click(function() {
                            $.mobile.changePage('mappage');
                            var lonlat = new OpenLayers.LonLat(place.lng, place.lat);
                            map.setCenter(lonlat.transform(gg, sm), 10);
                        })
                        .show();
                });
                $('#search_results').listview('refresh');
                $.mobile.pageLoading(true);
            });
        });
        // only listen to the first event triggered
        $('#searchpage').die('pageshow', arguments.callee);
    });

    $('#layerslist').listview();
    $('
', {
            "data-role": "list-divider",
            text: "Base Layers"
        })
        .appendTo('#layerslist');
    var baseLayers = map.getLayersBy("isBaseLayer", true);
    $.each(baseLayers, function() {
        addLayerToList(this);
    });

    $('
', {
            "data-role": "list-divider",
            text: "Overlay Layers"
        })
        .appendTo('#layerslist');
    var overlayLayers = map.getLayersBy("isBaseLayer", false);
    $.each(overlayLayers, function() {
        addLayerToList(this);
    });
    $('#layerslist').listview('refresh');

    map.events.register("addlayer", this, function(e) {
        addLayerToList(e.layer);
    });
});

function addLayerToList(layer) {
    var item = $('
', {
            "data-icon": "check",
            "class": layer.visibility ? "checked" : ""
        })
        .append($('', {
            text: layer.name
        })
            .click(function() {
                $.mobile.changePage('mappage');
                if (layer.isBaseLayer) {
                    layer.map.setBaseLayer(layer);
                } else {
                    layer.setVisibility(!layer.getVisibility());
                }
            })
        )
        .appendTo('#layerslist');
    layer.events.on({
        'visibilitychanged': function() {
            $(item).toggleClass('checked');
        }
    });
}

function getFeatures(){
    var features = {
      "type": "FeatureCollection",
      "features": [
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [1332700, 7906300]},
            "properties": {"Name": "Igor Tihonov", "Country":"Sweden", "City":"Gothenburg"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [790300, 6573900]},
            "properties": {"Name": "Marc Jansen", "Country":"Germany", "City":"Bonn"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [568600, 6817300]},
            "properties": {"Name": "Bart van den Eijnden", "Country":"Netherlands", "City":"Utrecht"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-7909900, 5215100]},
            "properties": {"Name": "Christopher Schmidt", "Country":"United States of America", "City":"Boston"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-937400, 5093200]},
            "properties": {"Name": "Jorge Gustavo Rocha", "Country":"Portugal", "City":"Braga"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-355300, 7547800]},
            "properties": {"Name": "Jennie Fletcher ", "Country":"Scotland", "City":"Edinburgh"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [657068.53608487, 5712321.2472725]},
            "properties": {"Name": "Bruno Binet ", "Country":"France", "City":"Chambéry"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [667250.8958124, 5668048.6072737]},
            "properties": {"Name": "Eric Lemoine", "Country":"France", "City":"Theys"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [653518.03606319, 5721118.5122914]},
            "properties": {"Name": "Antoine Abt", "Country":"France", "City":"La Motte Servolex"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [657985.78042416, 5711862.6251028]},
            "properties": {"Name": "Pierre Giraud", "Country":"France", "City":"Chambéry"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [742941.93818208, 5861818.9477535]},
            "properties": {"Name": "Stéphane Brunner", "Country":"Switzerland", "City":"Paudex"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [736082.61064069, 5908165.4649505]},
            "properties": {"Name": "Frédéric Junod", "Country":"Switzerland", "City":"Montagny"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [771595.97057525, 5912284.7041793]},
            "properties": {"Name": "Cédric Moullet", "Country":"Switzerland", "City":"Payerne"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [744205.23922364, 5861277.319748]},
            "properties": {"Name": "Benoit Quartier", "Country":"Switzerland", "City":"Lutry"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [1717430.147101, 5954568.7127565]},
            "properties": {"Name": "Andreas Hocevar", "Country":"Austria", "City":"Graz"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-12362007.067301,5729082.2365672]},
            "properties": {"Name": "Tim Schaub", "Country":"United States of America", "City":"Bozeman"}}
       ]
    };

    var reader = new OpenLayers.Format.GeoJSON();

    return reader.read(features);
}
<commit_msg>fixup my city name<commit_after>var selectedFeature = null;

$(document).ready(function() {

    // Start with the map page
    if (window.location.hash && window.location.hash!='#mappage') {
        $.mobile.changePage('mappage');
    }

    // fix height of content
    function fixContentHeight() {
        var footer = $("div[data-role='footer']:visible"),
        content = $("div[data-role='content']:visible:visible"),
        viewHeight = $(window).height(),
        contentHeight = viewHeight - footer.outerHeight();

        if ((content.outerHeight() + footer.outerHeight()) !== viewHeight) {
            contentHeight -= (content.outerHeight() - content.height());
            content.height(contentHeight);
        }
        if (window.map) {
            map.updateSize();
        } else {
            // initialize map
            init();
        }
    }
    $(window).bind("orientationchange resize pageshow", fixContentHeight);
    fixContentHeight();
    //init();

    // Map zoom
    $("#plus").click(function(){
        map.zoomIn();
    });
    $("#minus").click(function(){
        map.zoomOut();
    });
    $("#locate").click(function(){
        var control = map.getControlsBy("id", "locate-control")[0];
        if (control.active) {
            control.getCurrentLocation();
        } else {
            control.activate();
        }
    });

    var sprintersLayer = new OpenLayers.Layer.Vector("Sprinters", {
        styleMap: new OpenLayers.StyleMap({
            externalGraphic : "img/mobile-loc.png",
            graphicOpacity : 1.0,
            graphicWith:16,
            graphicHeight:26
        })
    });

    var sprinters = getFeatures();
    sprintersLayer.addFeatures(sprinters);

    map.addLayer(sprintersLayer);

    var selectControl = new OpenLayers.Control.SelectFeature(sprintersLayer, {onSelect: function(feature){
        selectedFeature = feature;
        $.mobile.changePage($("#popup"), "pop");
    }});

    map.addControl(selectControl);
    selectControl.activate();

    $('div#popup').live('pageshow',function(event, ui){
        var li = "";
        for(var attr in selectedFeature.attributes){
            li += "

" + attr + "

"
            + selectedFeature.attributes[attr] + "

";
        }
        $("ul#details-list").empty().append(li).listview("refresh");
    });

    $('#searchpage').live('pageshow',function(event, ui){
        $('#query').bind('change', function(e){
            $('#search_results').empty();
            if ($('#query')[0].value === '') {
                return;
            }
            $.mobile.pageLoading();

            // Prevent form send
            e.preventDefault();

            var searchUrl = 'http://ws.geonames.org/searchJSON?featureClass=P&maxRows=10';
            searchUrl += '&name_startsWith=' + $('#query')[0].value;
            $.getJSON(searchUrl, function(data) {
                $.each(data.geonames, function() {
                    var place = this;
                    $('
')
                        .hide()
                        .append($('
', {
                            text: place.name
                        }))
                        .append($('
', {
                            html: '' + place.countryName + ' ' + place.fcodeName
                        }))
                        .appendTo('#search_results')
                        .click(function() {
                            $.mobile.changePage('mappage');
                            var lonlat = new OpenLayers.LonLat(place.lng, place.lat);
                            map.setCenter(lonlat.transform(gg, sm), 10);
                        })
                        .show();
                });
                $('#search_results').listview('refresh');
                $.mobile.pageLoading(true);
            });
        });
        // only listen to the first event triggered
        $('#searchpage').die('pageshow', arguments.callee);
    });

    $('#layerslist').listview();
    $('
', {
            "data-role": "list-divider",
            text: "Base Layers"
        })
        .appendTo('#layerslist');
    var baseLayers = map.getLayersBy("isBaseLayer", true);
    $.each(baseLayers, function() {
        addLayerToList(this);
    });

    $('
', {
            "data-role": "list-divider",
            text: "Overlay Layers"
        })
        .appendTo('#layerslist');
    var overlayLayers = map.getLayersBy("isBaseLayer", false);
    $.each(overlayLayers, function() {
        addLayerToList(this);
    });
    $('#layerslist').listview('refresh');

    map.events.register("addlayer", this, function(e) {
        addLayerToList(e.layer);
    });
});

function addLayerToList(layer) {
    var item = $('
', {
            "data-icon": "check",
            "class": layer.visibility ? "checked" : ""
        })
        .append($('', {
            text: layer.name
        })
            .click(function() {
                $.mobile.changePage('mappage');
                if (layer.isBaseLayer) {
                    layer.map.setBaseLayer(layer);
                } else {
                    layer.setVisibility(!layer.getVisibility());
                }
            })
        )
        .appendTo('#layerslist');
    layer.events.on({
        'visibilitychanged': function() {
            $(item).toggleClass('checked');
        }
    });
}

function getFeatures(){
    var features = {
      "type": "FeatureCollection",
      "features": [
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [1332700, 7906300]},
            "properties": {"Name": "Igor Tihonov", "Country":"Sweden", "City":"Gothenburg"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [790300, 6573900]},
            "properties": {"Name": "Marc Jansen", "Country":"Germany", "City":"Bonn"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [568600, 6817300]},
            "properties": {"Name": "Bart van den Eijnden", "Country":"Netherlands", "City":"Utrecht"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-7909900, 5215100]},
            "properties": {"Name": "Christopher Schmidt", "Country":"United States of America", "City":"Boston"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-937400, 5093200]},
            "properties": {"Name": "Jorge Gustavo Rocha", "Country":"Portugal", "City":"Braga"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-355300, 7547800]},
            "properties": {"Name": "Jennie Fletcher ", "Country":"Scotland", "City":"Edinburgh"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [657068.53608487, 5712321.2472725]},
            "properties": {"Name": "Bruno Binet ", "Country":"France", "City":"Chambéry"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [667250.8958124, 5668048.6072737]},
            "properties": {"Name": "Eric Lemoine", "Country":"France", "City":"Theys"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [653518.03606319, 5721118.5122914]},
            "properties": {"Name": "Antoine Abt", "Country":"France", "City":"La Motte Servolex"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [657985.78042416, 5711862.6251028]},
            "properties": {"Name": "Pierre Giraud", "Country":"France", "City":"Chambéry"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [742941.93818208, 5861818.9477535]},
            "properties": {"Name": "Stéphane Brunner", "Country":"Switzerland", "City":"Paudex"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [736082.61064069, 5908165.4649505]},
            "properties": {"Name": "Frédéric Junod", "Country":"Switzerland", "City":"Montagny-près-Yverdon"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [771595.97057525, 5912284.7041793]},
            "properties": {"Name": "Cédric Moullet", "Country":"Switzerland", "City":"Payerne"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [744205.23922364, 5861277.319748]},
            "properties": {"Name": "Benoit Quartier", "Country":"Switzerland", "City":"Lutry"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [1717430.147101, 5954568.7127565]},
            "properties": {"Name": "Andreas Hocevar", "Country":"Austria", "City":"Graz"}},
            { "type": "Feature", "geometry": {"type": "Point", "coordinates": [-12362007.067301,5729082.2365672]},
            "properties": {"Name": "Tim Schaub", "Country":"United States of America", "City":"Bozeman"}}
       ]
    };

    var reader = new OpenLayers.Format.GeoJSON();

    return reader.read(features);
}
<|endoftext|>


<commit_before>// Error class based on http://stackoverflow.com/questions/8458984
//
'use strict'

const inherits = require('util').inherits

function UnshortError (message, code, statusCode) {
  // Super constructor
  Error.call(this)

  // Super helper method to include stack trace in error object
  Error.captureStackTrace(this, this.constructor)

  // Set our function’s name as error name
  this.name = this.constructor.name

  // Set the error message
  this.message = message

  if (code) this.code = code

  if (statusCode) this.statusCode = statusCode
}

// Inherit from Error
inherits(UnshortError, Error)

module.exports = UnshortError
<commit_msg>Rewrite UnshortError to es6<commit_after>// Error class based on http://stackoverflow.com/questions/8458984
//
'use strict'

class UnshortError extends Error {
  constructor (message, code, statusCode) {
    super(message)
    this.name = this.constructor.name
    Error.captureStackTrace(this, this.constructor)

    if (code) this.code = code
    if (statusCode) this.statusCode = statusCode
  }
}

module.exports = UnshortError
<|endoftext|>