<commit_before>var moment = require('moment'),
  parseArgs = require('minimist'),
  realtime = require('gtfs-realtime-bindings'),
  transit_api = require('transit-api');

// prepare GTFS-RT Protos
var curTripUpdates, curServiceAlerts, curVehiclePositions;

// prepare NextBus api
var args = parseArgs(process.argv.slice(2)),
  nextbus = new transit_api.NextBus(args.a);

var makeMessageTemplate = function() {
  return new realtime.FeedMessage({
    header: new realtime.FeedHeader({
      gtfs_realtime_version: '1.0',
      timestamp: moment().unix()
    })
  });
}

var makeSimpleEnglishTranslatedString = function(text) {
  var translation = new realtime.TranslatedString();
  translation.translation.push(new realtime.TranslatedString.Translation({
    language: 'en',
    text: text
  }));
  return translation;
}

var getEpochTime = function(timeStr) {
  return timeStr ? ( parseInt(timeStr, 10) / 1000 ) : null;
}

var ensureArray = function(obj) {
  if(!(obj instanceof Array)) {
    return [obj];
  }
  return obj;
}

var updateTrips = function() {
  var msg = makeMessageTemplate();
  curTripUpdates = msg;

  var getMultiPredictions = function(routeStopPairs) {
    console.log('getMultiPredictions');
    // requests predictions for each route/stop combo
    nextbus.predictionsForMultiStops(routeStopPairs).then(function(predictions) {
      predictions = ensureArray(predictions);
      for (var i = 0; i < predictions.length; i++) {
        predictions[i]
      };
    });
  }

  var getRouteStops = function(routeTags) {
    // requests list of all stops at each route
    nextbus.routeConfig(routeTags).then(function(routeStops) {
      routeStops = ensureArray(routeStops);
      var predictionStopsToRequest = {},
        curNumRouteStopPairs = 0;
      for (var i = 0; i < routeStops.length; i++) {
        var stops = ensureArray(routeStops[i].stop),
          curRouteTag = routeStops[i].tag;
        for (var j = 0; j < stops.length; j++) {
          if(!predictionStopsToRequest[curRouteTag]) {
            predictionStopsToRequest[curRouteTag] = []
          }
          predictionStopsToRequest[curRouteTag].push(stops[j].tag);
          curNumRouteStopPairs++;
          if(curNumRouteStopPairs == 150) {
            getMultiPredictions(predictionStopsToRequest);
            predictionStopsToRequest = {};
            curNumRouteStopPairs = 0;
          }
        };
      };
      if(curNumRouteStopPairs > 0) {
        getMultiPredictions(predictionStopsToRequest);
      }
    });
  }

  nextbus.routeList().then(function(routes) {
    routes = ensureArray(routes);
    var routesToRequest = [];
    for (var i = 0; i < routes.length; i++) {
      routesToRequest.push(routes[i].tag);
      if(routesToRequest.length == 100) {
        getRouteStops(routesToRequest);
        routesToRequest = [];
      }
    }
    if(routesToRequest.length > 0) {
      getRouteStops(routesToRequest);
    }
  });

}

var updateAlerts = function() {
  var msg = makeMessageTemplate(),
    nextBusMessageIds = [];
  nextbus.messages().then(function(messages) {
    var messagesByRoute = ensureArray(messages.route);
    console.log(messagesByRoute[4].message[0]);
    for (var i = 0; i < messagesByRoute.length; i++) {
      var routeMessages = ensureArray(messagesByRoute[i].message);

      for (var j = 0; j < routeMessages.length; j++) {
        curMsg = routeMessages[j];

        // check if message is already added elsewhere
        if(nextBusMessageIds.indexOf(curMsg.id) == -1) {

          // create alert message
          var alert = new realtime.Alert({
            header_text: makeSimpleEnglishTranslatedString(curMsg.text)
          });

          // add active_periods if provided
          if(curMsg.startBoundary || curMsg.endBoundary) {
            alert.active_period.push(new realtime.TimeRange({
              start: getEpochTime(curMsg.startBoundary),
              end: getEpochTime(curMsg.endBoundary)
            }));
          }

          // add route stop combos if provided
          if(curMsg.routeConfiguredForMessage) {
            var curMsgRoutes = ensureArray(curMsg.routeConfiguredForMessage);
            for (var k = 0; k < curMsgRoutes.length; k++) {
              var curRoute = curMsgRoutes[k];
              alert.informed_entity.push(new realtime.EntitySelector({
                route_id: curRoute.tag
              }));
              if(curRoute.stop) {
                curRouteStops = ensureArray(curRoute.stop);
                for (var l = 0; l < curRouteStops.length; l++) {
                  alert.informed_entity.push(new realtime.EntitySelector({
                    route_id: curRoute.tag,
                    stop_id: curRouteStops[l].tag
                  }));
                };
              }
            };
          }

          // add alert to overall feed message
          msg.entity.push(alert);

          // mark message id as processed
          nextBusMessageIds.push(curMsg.id);
        }
      }
    }
    curServiceAlerts = msg;
  });
}

var updateVehicles = function() {
  var msg = makeMessageTemplate();
  nextbus.vehicleLocations().then(function(data) {
    var vehicles = ensureArray(data.vehicle);
    for (var i = 0; i < vehicles.length; i++) {
      curVehicle = vehicles[i];
      msg.entity.push(new realtime.VehiclePosition({
        position: new realtime.Position({
          latitude: curVehicle.lat,
          longitude: curVehicle.lon,
          bearing: curVehicle.heading,
          speed: parseFloat(curVehicle.speedKmHr) * 0.277778
        }),
        timestamp: moment().unix() - parseInt(curVehicle.secsSinceReport, 10),
        vehicle: new realtime.VehicleDescriptor({
          id: curVehicle.id
        })
      }));
    };
    curVehiclePositions = msg;
    console.log(msg.entity);
  });
}

var updateAll = function() {
  updateTrips();
  updateAlerts();
  updateVehicles();
}

//setInterval(updateAll, 30000);
updateAlerts();

<commit_msg>Adding in trip translation, outputting vehicles, alerts to file<commit_after>var fs = require('fs')

var moment = require('moment'),
  parseArgs = require('minimist'),
  realtime = require('gtfs-realtime-bindings'),
  transitApi = require('transit-api');

// parse args
var args = parseArgs(process.argv.slice(2));

if(!args.a) {
  var err = new Error('No agency selected')
  throw err;
}

// prepare nextbus api
var nextbus = new transitApi.NextBus(args.a);
  destFolder = (args.d ? args.d : process.cwd())

var makeMessageTemplate = function() {
  return new realtime.FeedMessage({
    header: new realtime.FeedHeader({
      gtfs_realtime_version: '1.0',
      timestamp: moment().unix()
    })
  });
}

var makeSimpleEnglishTranslatedString = function(text) {
  var translation = new realtime.TranslatedString();
  translation.translation.push(new realtime.TranslatedString.Translation({
    language: 'en',
    text: text
  }));
  return translation;
}

var getEpochTime = function(timeStr) {
  return timeStr ? ( parseInt(timeStr, 10) / 1000 ) : null;
}

var ensureArray = function(obj) {
  if(!(obj instanceof Array)) {
    return [obj];
  }
  return obj;
}

var writeMsgToFile = function(filename, msg, callback) {
  try {
    var binaryData = msg.encode().toBuffer()
  } catch(e) {
    console.log(e)
    return callback(e)
  }
  fs.writeFile(destFolder + '/' + filename, binaryData, function(err) {
    console.log(err, filename, 'written')
  });
}

var updateTrips = function(callback) {
  var msg = makeMessageTemplate();
  curTripUpdates = msg;

  var tripUpdates = {}

  var getMultiPredictions = function(routeStopPairs) {
    console.log('getMultiPredictions');
    // requests predictions for each route/stop combo
    nextbus.predictionsForMultiStops(routeStopPairs).then(function(predictions) {
      predictions = ensureArray(predictions);
      console.log(JSON.stringify(predictions, null, 2))
      for (var i = 0; i < predictions.length; i++) {
        var curPrediction = predictions[i],
          directions = ensureArray(curPrediction.direction);
        for (var j = 0; j < directions.length; j++ ) {
          var directionPredictions = ensureArray(directions[j].prediction);
          for (var k = 0; k < directionPredictions.length; k++) {
            var tripPrediction = directionPredictions[k]
            if(!tripUpdates[tripPrediction.tripTag]) {
              var tripUpdate = new realtime.TripUpdate({
                trip: new realtime.TripDescriptor({
                  route_id: curPrediction.routeTag,
                  trip_id: tripPrediction.tripTag
                })
              });
              if(tripPrediction.vehicle) {
                tripUpdate.vehicle = new realtime.VehicleDescriptor({
                  id: tripPrediction.vehicle
                })
              }
              tripUpdates[tripPrediction.tripTag] = tripMessage
            }
            var stopTimeUpdate = new realtime.StopTimeUpdate({
              stop_id: curPrediction.stopTag
            })
            var stopTimeEvent = new realtime.StopTimeEvent({
              time: getEpochTime(tripPrediction.epochTime)
            })
            if(tripPrediction.isDeparture === 'false') {
              stopTimeUpdate.arrival = stopTimeEvent
            } else {
              stopTimeUpdate.departure = stopTimeEvent
            }
            tripUpdates[tripPrediction.tripTag].stop_time_update.push(stopTimeUpdate)
          }
        }
      }
    });
  }

  var getRouteStops = function(routeTags) {
    // requests list of all stops at each route
    nextbus.routeConfig(routeTags).then(function(routeStops) {
      routeStops = ensureArray(routeStops);
      var predictionStopsToRequest = {},
        curNumRouteStopPairs = 0;
      for (var i = 0; i < routeStops.length; i++) {
        var stops = ensureArray(routeStops[i].stop),
          curRouteTag = routeStops[i].tag;
        for (var j = 0; j < stops.length; j++) {
          if(!predictionStopsToRequest[curRouteTag]) {
            predictionStopsToRequest[curRouteTag] = []
          }
          predictionStopsToRequest[curRouteTag].push(stops[j].tag);
          curNumRouteStopPairs++;
          if(curNumRouteStopPairs == 150) {
            getMultiPredictions(predictionStopsToRequest);
            predictionStopsToRequest = {};
            curNumRouteStopPairs = 0;
          }
        };
      };
      if(curNumRouteStopPairs > 0) {
        getMultiPredictions(predictionStopsToRequest);
      }
    });
  }

  nextbus.routeList().then(function(routes) {
    routes = ensureArray(routes);
    var routesToRequest = [];
    for (var i = 0; i < routes.length; i++) {
      routesToRequest.push(routes[i].tag);
      if(routesToRequest.length == 100) {
        getRouteStops(routesToRequest);
        routesToRequest = [];
      }
    }
    if(routesToRequest.length > 0) {
      getRouteStops(routesToRequest);
    }
  });

}

var updateAlerts = function(callback) {
  var msg = makeMessageTemplate(),
    nextBusMessageIds = {};
  nextbus.messages().then(function(messages) {
    var messagesByRoute = ensureArray(messages.route);
    //console.log(messagesByRoute[4].message[0]);
    for (var i = 0; i < messagesByRoute.length; i++) {
      var routeMessages = ensureArray(messagesByRoute[i].message);

      for (var j = 0; j < routeMessages.length; j++) {
        curMsg = routeMessages[j];

        // check if message is already added elsewhere
        if(!nextBusMessageIds[curMsg.id]) {

          // create alert message
          var alert = new realtime.Alert({
            header_text: makeSimpleEnglishTranslatedString(curMsg.text)
          });

          // add active_periods if provided
          if(curMsg.startBoundary || curMsg.endBoundary) {
            alert.active_period.push(new realtime.TimeRange({
              start: getEpochTime(curMsg.startBoundary),
              end: getEpochTime(curMsg.endBoundary)
            }));
          }

          // add route stop combos if provided
          if(curMsg.routeConfiguredForMessage) {
            var curMsgRoutes = ensureArray(curMsg.routeConfiguredForMessage);
            for (var k = 0; k < curMsgRoutes.length; k++) {
              var curRoute = curMsgRoutes[k];
              alert.informed_entity.push(new realtime.EntitySelector({
                route_id: curRoute.tag
              }));
              if(curRoute.stop) {
                curRouteStops = ensureArray(curRoute.stop);
                for (var l = 0; l < curRouteStops.length; l++) {
                  alert.informed_entity.push(new realtime.EntitySelector({
                    route_id: curRoute.tag,
                    stop_id: curRouteStops[l].tag
                  }));
                };
              }
            };
          }

          // add alert to overall feed message
          msg.add('entity', new realtime.FeedEntity({
            id: curMsg.id,
            alert: alert
          }));

          // mark message id as processed
          nextBusMessageIds[curMsg.id] = true;
        }
      }
    }
    writeMsgToFile('alerts.proto', msg, callback)
  });
}

var updateVehicles = function(callback) {
  var msg = makeMessageTemplate();
  nextbus.vehicleLocations().then(function(data) {
    var vehicles = ensureArray(data.vehicle);
    for (var i = 0; i < vehicles.length; i++) {
      curVehicle = vehicles[i];
      msg.add('entity', new realtime.FeedEntity({
        id: 'Vehicle Position ' + i,
        vehicle: new realtime.VehiclePosition({
          position: new realtime.Position({
            latitude: curVehicle.lat,
            longitude: curVehicle.lon,
            bearing: curVehicle.heading,
            speed: curVehicle.speedKmHr ? parseFloat(curVehicle.speedKmHr) * 0.277778 : 0
          }),
          timestamp: moment().unix() - parseInt(curVehicle.secsSinceReport, 10),
          vehicle: new realtime.VehicleDescriptor({
            id: curVehicle.id
          })
        })
      }));
    };
    writeMsgToFile('vehicles.proto', msg, callback)
  });
}

var updateAll = function() {
  updateAlerts();
  updateVehicles();
  updateTrips();
}

//setInterval(updateAll, 30000);
updateAlerts();

<|endoftext|>


<commit_before>'use strict';

module.exports.config = require('./lib/config');
module.exports.loadbalancer = require('./lib/loadbalancer');
module.exports.microservice = require('./lib/microservice');
module.exports.grpc = require('./lib/transport/provider/grpc');
module.exports.endpoint = require('./lib/endpoint');
module.exports.events = require('./lib/events');
module.exports.kafka = require('./lib/events/provider/kafka');
<commit_msg>Add database to index<commit_after>'use strict';

module.exports.config = require('./lib/config');
module.exports.database = require('./lib/database');
module.exports.gss = require('./lib/database/provider/gss');
module.exports.loadbalancer = require('./lib/loadbalancer');
module.exports.microservice = require('./lib/microservice');
module.exports.grpc = require('./lib/transport/provider/grpc');
module.exports.endpoint = require('./lib/endpoint');
module.exports.events = require('./lib/events');
module.exports.kafka = require('./lib/events/provider/kafka');
<|endoftext|>


<commit_before>module.exports = {
    parser: 'babel-eslint',
    extends: ['airbnb', 'plugin:ava/recommended'],
    plugins: ['import', 'ava'],
    rules: {
        indent: [
            'error',
            4,
            {
                SwitchCase: 1,
                MemberExpression: 1,
                VariableDeclarator: 1,
                outerIIFEBody: 1,
                FunctionDeclaration: { parameters: 1, body: 1 },
                FunctionExpression: { parameters: 1, body: 1 },
            },
        ],
        // Allow same precedence until https://github.com/airbnb/javascript/issues/1071 is solved
        'no-mixed-operators': ['error', { allowSamePrecedence: true }],
        strict: 'error',
        'no-sync': 'error',
        'no-inline-comments': 'error',
        'no-use-before-define': ['error', 'nofunc'],
        'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
        'import/order': [
            'error',
            { groups: ['builtin', 'external', 'parent', 'sibling', 'index'] },
        ],
        'import/named': 'error',
        'import/default': 'error',
        'import/namespace': 'error',
        'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
        'react/jsx-indent': ['error', 4],
        'react/jsx-indent-props': ['error', 4],
    },
};
<commit_msg>Allow consistent function-paren-newline<commit_after>module.exports = {
    parser: 'babel-eslint',
    extends: ['airbnb', 'plugin:ava/recommended'],
    plugins: ['import', 'ava'],
    rules: {
        indent: [
            'error',
            4,
            {
                SwitchCase: 1,
                MemberExpression: 1,
                VariableDeclarator: 1,
                outerIIFEBody: 1,
                FunctionDeclaration: { parameters: 1, body: 1 },
                FunctionExpression: { parameters: 1, body: 1 },
            },
        ],
        // Allow same precedence until https://github.com/airbnb/javascript/issues/1071 is solved
        'no-mixed-operators': ['error', { allowSamePrecedence: true }],
        strict: 'error',
        'no-sync': 'error',
        'no-inline-comments': 'error',
        'no-use-before-define': ['error', 'nofunc'],
        'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
        'import/order': [
            'error',
            { groups: ['builtin', 'external', 'parent', 'sibling', 'index'] },
        ],
        'import/named': 'error',
        'import/default': 'error',
        'import/namespace': 'error',
        'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx'] }],
        'react/jsx-indent': ['error', 4],
        'react/jsx-indent-props': ['error', 4],
        'function-paren-newline': ['error', 'consistent'],
    },
};
<|endoftext|>


<commit_before>'use strict'
const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const process = require('process')
const send = require('./send')
const Datastore = require('nedb')
const users = new Datastore({ filename: './data/users', autoload: true  })
const eventSpeech = require('./src/speech')
const app = express()
const verifyToken = process.env.verifyToken
const mapsApiKey = process.env.mapsApiKey

app.use(bodyParser.json())
app.set('json spaces', 2)

app.get('/*', (req, res) => {
  const q = req.query
  // If the token doesn't match...
  if (q['hub.verify_token'] !== verifyToken) {
    res.sendStatus(401)
  }
  if (q['hub.mode'] === 'subscribe') {
    console.log('s', q['hub.challenge'])
    res.send(q['hub.challenge'])
  } else {
    res.send(req.headers)
  }
})

app.post('/*', (req, res) => {
  const q = req.query
  const messaging = req.body.entry[0].messaging
  if (messaging) {
    messaging.forEach((item) => {
      if (item.message && item.message.text) {
        users.findOne({id: item.sender.id }, function (err, doc) {
          if (doc === null) {
            db.insert({ id: item.sender.id })
          }
        })
        processMessageText(item.sender.id, item.message.text)
      } else if (item.postback && item.postback.payload) {
        processPayload(senderId, item.postback.payload)
      }
    })
  }
  res.sendStatus(200)
})

function processPayload (senderId, payload) {
  if (payload.startsWith('EVENT_')) {
    const jsonPayload = payload.slice(6) // because event_ is 6 characters
  }
}

function processMessageText (senderId, text) {
  const eventRequest = eventSpeech.getParsedRequest(text)
  if (eventRequest.mode === 'event') {
    upcomingEvent(senderId, eventRequest)
  } else if (eventRequest.mode === 'repo') {
    latestRepo(senderId)
  }
}

/**
 * Fetches the latest 5 repositories
 * @param  {[type]} senderId [description]
 */
function latestRepo (senderId) {
  request('https://webuild.sg/api/v1/repos?n=5', (err, resp, body) => {
    if (!err) {
      const parsed = JSON.parse(body)
      parsed.repos.forEach((repo) => {
        send.text(
          senderId,
          `${repo.owner.login}/${repo.name}
${repo.html_url}
          `
        )
      })
    }
  })
}

function generateFbPayload (events) {
  const nomap = 'https://avatars0.githubusercontent.com/u/7611825?v=3&s=500'
  return events.map((event) => {
    let payload = {
      'title': `${event.name}`,
      'image_url': nomap,
      'subtitle': `${event.group_name} | ${event.formatted_time}`,
      'buttons': [
        {
          'type': 'web_url',
          'url': event.url,
          'title': 'View Event'
        },
        {
          'type': 'web_url',
          'url': event.group_url,
          'title': 'View Group'
        }
      ]
    }
    if (event.latitude && event.longitude) {
      payload.image_url = `https://maps.googleapis.com/maps/api/staticmap?zoom=13&size=500x500&maptype=roadmap&markers=color:red%7C${event.latitude},${event.longitude}&key=${mapsApiKey}`
      payload.buttons.unshift({
        'type': 'web_url',
        'url': `https://maps.google.com/maps?f=q&hl=en&q=${event.latitude},${event.longitude}`,
        'title': 'Get Directions'
      })
    }
    return payload
  })
}

function sendEvent (senderId, events) {
  const eventCount = +events.meta.total_events
  if (eventCount === 0) {
    send.text(senderId, `No events found :( Try another day`)
  } else if (eventCount > 0) {
    const eventsDisplay = events.meta.total_events === 1 ? 'event' : 'events'
    if (eventCount === 1) {
    }
    send.text(senderId, `We found you ${eventCount} cool ${eventsDisplay} for you to join!`)
    var eventElements = generateFbPayload(events.events)
    send.genericTemplate(senderId, eventElements)
  }
}

/**
 * Fetches 5 upcoming events or by event date
 * @param  {[type]} senderId [description]
 */
function upcomingEvent (senderId, eventRequest) {
  if (eventRequest.dates) {
    request(`https://webuild.sg/api/v1/check/${eventRequest.dates.year}-${eventRequest.dates.month + 1}-${eventRequest.dates.day}?n=5`, (err, resp, body) => {
      if (!err) {
        const parsed = JSON.parse(body)
        sendEvent(senderId, parsed)
      }
    })
  } else {
    request('https://webuild.sg/api/v1/events?n=5', (err, resp, body) => {
      if (!err) {
        const parsed = JSON.parse(body)
        sendEvent(senderId, parsed)
      }
    })
  }
}

app.listen(3124, () => {
  console.log('Example app listening on port 3124!')
})
<commit_msg>change logo backdrop<commit_after>'use strict'
const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
const process = require('process')
const send = require('./send')
const Datastore = require('nedb')
const users = new Datastore({ filename: './data/users', autoload: true  })
const eventSpeech = require('./src/speech')
const app = express()
const verifyToken = process.env.verifyToken
const mapsApiKey = process.env.mapsApiKey

app.use(bodyParser.json())
app.set('json spaces', 2)

app.get('/*', (req, res) => {
  const q = req.query
  // If the token doesn't match...
  if (q['hub.verify_token'] !== verifyToken) {
    res.sendStatus(401)
  }
  if (q['hub.mode'] === 'subscribe') {
    console.log('s', q['hub.challenge'])
    res.send(q['hub.challenge'])
  } else {
    res.send(req.headers)
  }
})

app.post('/*', (req, res) => {
  const q = req.query
  const messaging = req.body.entry[0].messaging
  if (messaging) {
    messaging.forEach((item) => {
      if (item.message && item.message.text) {
        users.findOne({id: item.sender.id }, function (err, doc) {
          if (doc === null) {
            db.insert({ id: item.sender.id })
          }
        })
        processMessageText(item.sender.id, item.message.text)
      } else if (item.postback && item.postback.payload) {
        processPayload(senderId, item.postback.payload)
      }
    })
  }
  res.sendStatus(200)
})

function processPayload (senderId, payload) {
  if (payload.startsWith('EVENT_')) {
    const jsonPayload = payload.slice(6) // because event_ is 6 characters
  }
}

function processMessageText (senderId, text) {
  const eventRequest = eventSpeech.getParsedRequest(text)
  if (eventRequest.mode === 'event') {
    upcomingEvent(senderId, eventRequest)
  } else if (eventRequest.mode === 'repo') {
    latestRepo(senderId)
  }
}

/**
 * Fetches the latest 5 repositories
 * @param  {[type]} senderId [description]
 */
function latestRepo (senderId) {
  request('https://webuild.sg/api/v1/repos?n=5', (err, resp, body) => {
    if (!err) {
      const parsed = JSON.parse(body)
      parsed.repos.forEach((repo) => {
        send.text(
          senderId,
          `${repo.owner.login}/${repo.name}
${repo.html_url}
          `
        )
      })
    }
  })
}

function generateFbPayload (events) {
  const nomap = 'https://raw.githubusercontent.com/webuildsg/bot/master/logo2.png'
  return events.map((event) => {
    let payload = {
      'title': `${event.name}`,
      'image_url': nomap,
      'subtitle': `${event.group_name} | ${event.formatted_time}`,
      'buttons': [
        {
          'type': 'web_url',
          'url': event.url,
          'title': 'View Event'
        },
        {
          'type': 'web_url',
          'url': event.group_url,
          'title': 'View Group'
        }
      ]
    }
    if (event.latitude && event.longitude) {
      payload.image_url = `https://maps.googleapis.com/maps/api/staticmap?zoom=13&size=500x500&maptype=roadmap&markers=color:red%7C${event.latitude},${event.longitude}&key=${mapsApiKey}`
      payload.buttons.unshift({
        'type': 'web_url',
        'url': `https://maps.google.com/maps?f=q&hl=en&q=${event.latitude},${event.longitude}`,
        'title': 'Get Directions'
      })
    }
    return payload
  })
}

function sendEvent (senderId, events) {
  const eventCount = +events.meta.total_events
  if (eventCount === 0) {
    send.text(senderId, `No events found :( Try another day`)
  } else if (eventCount > 0) {
    const eventsDisplay = events.meta.total_events === 1 ? 'event' : 'events'
    if (eventCount === 1) {
    }
    send.text(senderId, `We found you ${eventCount} cool ${eventsDisplay} for you to join!`)
    var eventElements = generateFbPayload(events.events)
    send.genericTemplate(senderId, eventElements)
  }
}

/**
 * Fetches 5 upcoming events or by event date
 * @param  {[type]} senderId [description]
 */
function upcomingEvent (senderId, eventRequest) {
  if (eventRequest.dates) {
    request(`https://webuild.sg/api/v1/check/${eventRequest.dates.year}-${eventRequest.dates.month + 1}-${eventRequest.dates.day}?n=5`, (err, resp, body) => {
      if (!err) {
        const parsed = JSON.parse(body)
        sendEvent(senderId, parsed)
      }
    })
  } else {
    request('https://webuild.sg/api/v1/events?n=5', (err, resp, body) => {
      if (!err) {
        const parsed = JSON.parse(body)
        sendEvent(senderId, parsed)
      }
    })
  }
}

app.listen(3124, () => {
  console.log('Example app listening on port 3124!')
})
<|endoftext|>


<commit_before>//'use strict';

var uuid          = require('uuid'),
    io            = require('socket.io')(8000),
    roomGenerator = require('./roomGenerator'),
    helpers       = require('./helpers'),
    entities      = require('./entities'),
    Player        = entities.player;

var numberOfRooms = Math.round(Math.random() * 50);
var rooms = roomGenerator(numberOfRooms);
var connections = {};

io.on('connection', function(socket) {
    var playerId = uuid.v4();
    connections[playerId] = socket;
    connection = connections[playerId];

    connection.on('send', function(data) {
        io.emit('message', data);
    });
    connection.on('playerEnter', function(data) {
        var rooms = this.rooms;
        this.userName = data.userName;
        var roomNames = Object.keys(rooms);
        var randomRoomIndex = helpers.randomIntegerBetween(roomNames.length-1);
        var randomRoomName = roomNames[randomRoomIndex];

        var player = new Player(data.userName, playerId);
        rooms[randomRoomName].players[player.id] = player;

        connection.emit('enterRoom', rooms[randomRoomName]);
    }.bind(this))
    socket.on('disconnect', function() {
        io.emit('message', {
            type   : 'notice',
            message: this.userName + ' has left the game.'
        });
    }.bind(this));
}.bind({rooms}));<commit_msg>Bind individual socket connection context<commit_after>//'use strict';

var uuid          = require('uuid'),
    io            = require('socket.io')(8000),
    roomGenerator = require('./roomGenerator'),
    helpers       = require('./helpers'),
    entities      = require('./entities'),
    Player        = entities.player;

var numberOfRooms = Math.round(Math.random() * 50),
    rooms         = roomGenerator(numberOfRooms),
    connections   = {};

io.on('connection', function(socket) {
    var playerId          = uuid.v4(),
        connectionContext = {
            playerId: playerId,
            userName: 'A player',
            rooms   : this.rooms
        };

    connections[playerId] = socket;
    connection = connections[playerId];

    connection.on('send', function(data) {
        io.emit('message', data);
    }.bind(connectionContext));
    connection.on('playerEnter', function(data) {
        var rooms = this.rooms;
        this.userName = data.userName;
        var roomNames = Object.keys(rooms);
        var randomRoomIndex = helpers.randomIntegerBetween(roomNames.length-1);
        var randomRoomName = roomNames[randomRoomIndex];

        var player = new Player(data.userName, playerId);
        rooms[randomRoomName].players[player.id] = player;

        connection.emit('enterRoom', rooms[randomRoomName]);
    }.bind(connectionContext));
    connection.on('disconnect', function() {
        io.emit('message', {
            type   : 'notice',
            message: this.userName + ' has left the game.'
        });
    }.bind(connectionContext));
}.bind({rooms}));<|endoftext|>


<commit_before>
console.log('App started');

var bleno = require('bleno');

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');

// Connection URL
var url = 'mongodb://localhost:9000/steamworks';

var attendees = [];
var settings = {
  service_id: '12ab',
  characteristic_id: '34cd'
};

bleno.on('stateChange', function(state){
  if(state === 'poweredOn'){
    console.log('powered on!');
    bleno.startAdvertising('scoutingDatabaseApp', ['12ab']);
  }else{
    bleno.stopAdvertising();
  }
});

bleno.on('advertisingStart', function(error){
    if(error){
      console.log(error);
      // error on advertise start
    }else{
      console.log('started..');
      bleno.setServices([
        new bleno.PrimaryService({
          uuid : settings.service_id,
          characteristics : [
            new bleno.Characteristic({
              value : null,
              uuid : settings.characteristic_id,
              properties : ['read', 'write'],
              onWriteRequest : function(data, offset, withoutResponse, callback){
                MongoClient.connect(url, function(err, db) {
                  var match = JSON.parse(data.toString());

                  var col = db.collection('westLafayette');

                  col.insertOne(match, function(err, res) {
                    if(err){
                      console.log(err);
                    }
                    console.log('New match inserted');
                    db.close();
                  });
                });

                callback(this.RESULT_SUCCESS);
              }
            })
          ]
        })
      ]);
    }
});
<commit_msg>advertising logs<commit_after>
console.log('App started');

var bleno = require('bleno');

var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');

// Connection URL
var url = 'mongodb://localhost:9000/steamworks';

var attendees = [];
var settings = {
  service_id: '12ab',
  characteristic_id: '34cd'
};

bleno.on('stateChange', function(state){
  if(state === 'poweredOn'){
    console.log('powered on!');
    bleno.startAdvertising('scoutingDatabaseApp', ['12ab']);
  }else{
    console.log('stopped advertising');
    console.log(state);
    bleno.stopAdvertising();
  }
});

bleno.on('advertisingStart', function(error){
    if(error){
      console.log(error);
      // error on advertise start
    }else{
      console.log('started..');
      bleno.setServices([
        new bleno.PrimaryService({
          uuid : settings.service_id,
          characteristics : [
            new bleno.Characteristic({
              value : null,
              uuid : settings.characteristic_id,
              properties : ['read', 'write'],
              onWriteRequest : function(data, offset, withoutResponse, callback){
                MongoClient.connect(url, function(err, db) {
                  var match = JSON.parse(data.toString());

                  var col = db.collection('westLafayette');

                  col.insertOne(match, function(err, res) {
                    if(err){
                      console.log(err);
                    }
                    console.log('New match inserted');
                    db.close();
                  });
                });

                callback(this.RESULT_SUCCESS);
              }
            })
          ]
        })
      ]);
    }
});
<|endoftext|>


<commit_before>var engine = require('player-engine')
var fs = require('file-system')(64 * 1024 * 1024, ['audio/mp3', 'audio/wav', 'audio/ogg'])
var async = require('async')
var rusha = new (require('rusha'))()
var musicMetadata = require('music-metadata')

var seeking = false
var current_song_index = -1

// In-memory storage with persistence through localStorage
var meta_storage = {
  cache: JSON.parse(window.localStorage.getItem('metadata')) || {},
  get: function (key) {
    return this.cache[key]
  },
  set: function (key, meta) {
    this.cache[key] = meta
    window.localStorage.setItem('metadata', JSON.stringify(this.cache))
  }
}

// Initialize the player engine & event listeners
engine = engine()

// Setup the volume bar
engine.volume(0.2)
document.querySelector('#volumeBar').min = 0
document.querySelector('#volumeBar').max = 1
document.querySelector('#volumeBar').step = 0.01
document.querySelector('#volumeBar').value = 0.2

// Toggle the playing state
engine.on('playingState', function (playing) {
  document.querySelector('#play').innerHTML = playing ? '' : ''
})

// Toggle the "back" state
engine.on('backState', function (back_possible) {
  document.querySelector('#previous').disabled = !back_possible
})

// Update songs
engine.on('songState', function (song) {
  var meta = meta_storage.get(song.name)
  document.querySelector('#fileContainer').innerHTML = 'Currently playing: ' + meta.album + ' - ' + meta.artist + ' - ' + meta.title
  document.querySelector('#currentTime').innerHTML = duration(0)
  document.querySelector('#progressBar').min = 0
  document.querySelector('#progressBar').value = 0
  document.querySelector('#progressBar').max = song.duration
  document.querySelector('#songLength').innerHTML = duration(song.duration)
  current_song_index = song.index
  renderView()
})

// Update progress
engine.on('progress', function (progress) {
  if (!seeking) {
    document.querySelector('#currentTime').innerHTML = duration(progress)
    document.querySelector('#progressBar').value = Math.floor(progress)
  }
})

function hash (string) {
  return rusha.digestFromString(string)
}

// Add files to the file system
function addFiles (files) {
  // Asynchronously map the files with the hash function over their contents
  async.map(files, function (file, callback) {
    var reader = new window.FileReader()
    reader.readAsDataURL(file)
    reader.onloadend = function () {
      file.hashName = hash(this.result) + file.name.replace(/^.*(\.[A-Za-z0-9]{3})$/, '$1')
      musicMetadata(file, function (meta) {
        meta.originalName = file.name
        meta_storage.set(file.hashName, meta)
        callback(null, file)
      })
    }
  }, function (error, results) {
    // Add the files into the file system, which uses "hashName" as a priority
    if (error) throw error
    fs.add(results, attachFiles)
  })
}

// Update the engine's files with the one's from the file system
function attachFiles () {
  fs.list(function (files) {
    engine.setFiles(files)
    renderView()
  })
}

// Read the files from the engine and write them into the view
function renderView () {
  renderTracks()
  renderQueuedTracks()
}

function renderTracks () {
  var tracks = engine.getTracks()
  document.querySelector('#list').innerHTML = trackTableHtml(tracks)
}

function renderQueuedTracks () {
  var tracks = engine.getQueuedTracks()
  document.querySelector('#queued').innerHTML = trackTableHtml(tracks, true)
}

function trackTableHtml (tracks, queue) {
  if (tracks.length === 0) {
    return ''
  }

  var rows = []

  var headers = []
  headers.push('')

  if (!queue) {
    headers.push('')
  }

  headers.push('Title')
  headers.push('Artist')
  headers.push('Album')
  headers.push('')
  rows.push(headers.map(function (x) { return '' + x + '	' }).join(''))

  for (var i = 0; i !== tracks.length; i++) {
    var track = tracks[i]
    var meta = meta_storage.get(track.name)
    var columns = []

    columns.push('')

    if (!queue) {
      columns.push('')
    }

    columns.push(meta.title || '')
    columns.push(meta.artist || '')
    columns.push(meta.album || '')
    columns.push('')

    if (!queue && current_song_index === i) {
      columns = columns.map(function (x) { return '' + x + '' })
    }

    rows.push(columns.map(function (x) { return '' + x + '	' }).join(''))
  }

  return rows.map(function (x) { return '
' + x + '
' }).join('')
}

// Format a second value as minutes:seconds
function duration (seconds) {
  seconds = Math.floor(seconds)
  var minutes = Math.floor(seconds / 60)
  seconds = seconds - minutes * 60
  seconds = seconds < 10 ? '0' + seconds : seconds
  return minutes + ':' + seconds
}

// Bind the window events
window.addEventListener('load', function () {
  attachFiles()

  // Add files
  document.querySelector('#myfile').onchange = function () {
    addFiles(this.files)
  }

  // Clear files
  document.querySelector('#deleteFSContent').onclick = function () {
    fs.clear(attachFiles)
  }

  // Play/pause toggle
  document.querySelector('#play').onclick = function () {
    engine.toggle()
  }

  // "Back" button
  document.querySelector('#previous').onclick = function () {
    engine.back()
  }

  // "Skip" button
  document.querySelector('#next').onclick = function () {
    engine.next()
  }

  // Progress bar sliding updates the time
  document.querySelector('#progressBar').oninput = function () {
    document.querySelector('#currentTime').innerHTML = duration(document.querySelector('#progressBar').value)
  }

  // Stop updating the progress bar while seeking
  document.querySelector('#progressBar').onmousedown = function () {
    seeking = true
  }

  // Done with seeking, skip to that position in the song
  document.querySelector('#progressBar').onmouseup = function () {
    engine.seek(document.querySelector('#progressBar').value)
    seeking = false
  }

  // Change the volume
  document.querySelector('#volumeBar').oninput = function () {
    engine.volume(document.querySelector('#volumeBar').value)
  }
})

// Bind interface events
window.playTrack = function (index) {
  engine.setTrack(index)
}

// Delete a track
window.removeTrack = function (filename) {
  engine.removeTrack(filename)
  fs.delete(filename, renderView)
}

// Queue a track
window.queueTrack = function (index) {
  engine.queueTrack(index)
  renderView()
}

// Handle drag & drop by adding the dropped files
function windowDrop (event) {
  // get window.event if e argument missing (in IE)
  event = event || window.event

  // stops the browser from redirecting off to the image.
  if (event.preventDefault) {
    event.preventDefault()
  }

  var files = event.dataTransfer.files

  // Check if the item is a folder
  if (files[0].type === '') {
    console.error("Folder are not supported for drag 'n' drop yet")
    return
  }

  addFiles(files)
}

// Cancel this event
function cancel (e) {
  if (e.preventDefault) {
    e.preventDefault()
  }

  return false
}

// Event listeners -------------------------------------------------------------

window.addEventListener('dragover', cancel)
window.addEventListener('dragenter', cancel)
window.addEventListener('dragleave', cancel)
window.addEventListener('dragdrop', windowDrop)
window.addEventListener('drop', windowDrop)
<commit_msg>Support directories via drag & drop<commit_after>var engine = require('player-engine')
var fs = require('file-system')(64 * 1024 * 1024, ['audio/mp3', 'audio/wav', 'audio/ogg'])
var async = require('async')
var rusha = new (require('rusha'))()
var musicMetadata = require('music-metadata')

var seeking = false
var current_song_index = -1

// In-memory storage with persistence through localStorage
var meta_storage = {
  cache: JSON.parse(window.localStorage.getItem('metadata')) || {},
  get: function (key) {
    return this.cache[key]
  },
  set: function (key, meta) {
    this.cache[key] = meta
    window.localStorage.setItem('metadata', JSON.stringify(this.cache))
  }
}

// Initialize the player engine & event listeners
engine = engine()

// Setup the volume bar
engine.volume(0.2)
document.querySelector('#volumeBar').min = 0
document.querySelector('#volumeBar').max = 1
document.querySelector('#volumeBar').step = 0.01
document.querySelector('#volumeBar').value = 0.2

// Toggle the playing state
engine.on('playingState', function (playing) {
  document.querySelector('#play').innerHTML = playing ? '' : ''
})

// Toggle the "back" state
engine.on('backState', function (back_possible) {
  document.querySelector('#previous').disabled = !back_possible
})

// Update songs
engine.on('songState', function (song) {
  var meta = meta_storage.get(song.name)
  document.querySelector('#fileContainer').innerHTML = 'Currently playing: ' + meta.album + ' - ' + meta.artist + ' - ' + meta.title
  document.querySelector('#currentTime').innerHTML = duration(0)
  document.querySelector('#progressBar').min = 0
  document.querySelector('#progressBar').value = 0
  document.querySelector('#progressBar').max = song.duration
  document.querySelector('#songLength').innerHTML = duration(song.duration)
  current_song_index = song.index
  renderView()
})

// Update progress
engine.on('progress', function (progress) {
  if (!seeking) {
    document.querySelector('#currentTime').innerHTML = duration(progress)
    document.querySelector('#progressBar').value = Math.floor(progress)
  }
})

function hash (string) {
  return rusha.digestFromString(string)
}

// Add files to the file system
function addFiles (files) {
  console.log('Adding ' + files.length + ' files...')
  // Asynchronously map the files with the hash function over their contents
  async.map(files, function (file, callback) {
    var reader = new window.FileReader()
    reader.readAsDataURL(file)
    reader.onloadend = function () {
      file.hashName = hash(this.result) + file.name.replace(/^.*(\.[A-Za-z0-9]{3})$/, '$1')
      musicMetadata(file, function (meta) {
        meta.originalName = file.name
        meta_storage.set(file.hashName, meta)
        console.log('File finished processing: ' + file.name)
        callback(null, file)
      })
    }
  }, function (error, results) {
    // Add the files into the file system, which uses "hashName" as a priority
    if (error) throw error
    fs.add(results, attachFiles)
  })
}

// Update the engine's files with the one's from the file system
function attachFiles () {
  fs.list(function (files) {
    engine.setFiles(files)
    renderView()
  })
}

// Read the files from the engine and write them into the view
function renderView () {
  renderTracks()
  renderQueuedTracks()
}

function renderTracks () {
  var tracks = engine.getTracks()
  document.querySelector('#list').innerHTML = trackTableHtml(tracks)
}

function renderQueuedTracks () {
  var tracks = engine.getQueuedTracks()
  document.querySelector('#queued').innerHTML = trackTableHtml(tracks, true)
}

function trackTableHtml (tracks, queue) {
  if (tracks.length === 0) {
    return ''
  }

  var rows = []

  var headers = []
  headers.push('')

  if (!queue) {
    headers.push('')
  }

  headers.push('Title')
  headers.push('Artist')
  headers.push('Album')
  headers.push('')
  rows.push(headers.map(function (x) { return '' + x + '	' }).join(''))

  for (var i = 0; i !== tracks.length; i++) {
    var track = tracks[i]
    var meta = meta_storage.get(track.name)
    var columns = []

    columns.push('')

    if (!queue) {
      columns.push('')
    }

    columns.push(meta.title || '')
    columns.push(meta.artist || '')
    columns.push(meta.album || '')
    columns.push('')

    if (!queue && current_song_index === i) {
      columns = columns.map(function (x) { return '' + x + '' })
    }

    rows.push(columns.map(function (x) { return '' + x + '	' }).join(''))
  }

  return rows.map(function (x) { return '
' + x + '
' }).join('')
}

// Format a second value as minutes:seconds
function duration (seconds) {
  seconds = Math.floor(seconds)
  var minutes = Math.floor(seconds / 60)
  seconds = seconds - minutes * 60
  seconds = seconds < 10 ? '0' + seconds : seconds
  return minutes + ':' + seconds
}

// Bind the window events
window.addEventListener('load', function () {
  attachFiles()

  // Add files
  document.querySelector('#myfile').onchange = function () {
    addFiles(this.files)
  }

  // Clear files
  document.querySelector('#deleteFSContent').onclick = function () {
    fs.clear(attachFiles)
  }

  // Play/pause toggle
  document.querySelector('#play').onclick = function () {
    engine.toggle()
  }

  // "Back" button
  document.querySelector('#previous').onclick = function () {
    engine.back()
  }

  // "Skip" button
  document.querySelector('#next').onclick = function () {
    engine.next()
  }

  // Progress bar sliding updates the time
  document.querySelector('#progressBar').oninput = function () {
    document.querySelector('#currentTime').innerHTML = duration(document.querySelector('#progressBar').value)
  }

  // Stop updating the progress bar while seeking
  document.querySelector('#progressBar').onmousedown = function () {
    seeking = true
  }

  // Done with seeking, skip to that position in the song
  document.querySelector('#progressBar').onmouseup = function () {
    engine.seek(document.querySelector('#progressBar').value)
    seeking = false
  }

  // Change the volume
  document.querySelector('#volumeBar').oninput = function () {
    engine.volume(document.querySelector('#volumeBar').value)
  }
})

// Bind interface events
window.playTrack = function (index) {
  engine.setTrack(index)
}

// Delete a track
window.removeTrack = function (filename) {
  engine.removeTrack(filename)
  fs.delete(filename, renderView)
}

// Queue a track
window.queueTrack = function (index) {
  engine.queueTrack(index)
  renderView()
}

// Handle drag & drop by adding the dropped files
function windowDrop (event) {
  // Get the event from the window, if it is missing
  // and stop the default event handling (= showing the file)
  event = event || window.event
  if (event.preventDefault) {
    event.preventDefault()
  }

  // Get all entries from the event
  var items = event.dataTransfer.items
  var entries = []
  for (var i = 0; i < items.length; i++) {
    var entry = items[i].webkitGetAsEntry()
    if (entry) { entries.push(entry) }
  }

  // Get all files from the entries, even if they are deep in directories
  getFilesFromEntries(entries, addFiles)
}

// Get the files of the webkit entries
function getFilesFromEntries (entries, callback) {
  async.map(entries, function (entry, callback) {
    traverseEntryTree(entry, function (files) { callback(null, files) })
  }, function (error, results) {
    if (error) throw error
    var files = results.concat().reduce(function (x, y) { return x.concat(y) })
    callback(files)
  })
}

// Go through tree of entries and return a list of files
function traverseEntryTree (entry, callback) {
  // this entry is a file, so we are done here
  if (entry.isFile) {
    entry.file(function (file) { callback([file]) })
  }

  // this entry is a directory, we have to go deeper
  if (entry.isDirectory) {
    var dirReader = entry.createReader()
    dirReader.readEntries(function (entries) { getFilesFromEntries(entries, callback) })
  }
}

// Cancel this event
function cancel (e) {
  if (e.preventDefault) {
    e.preventDefault()
  }

  return false
}

// Event listeners -------------------------------------------------------------

window.addEventListener('dragover', cancel)
window.addEventListener('dragenter', cancel)
window.addEventListener('dragleave', cancel)
window.addEventListener('dragdrop', windowDrop)
window.addEventListener('drop', windowDrop)
<|endoftext|>


<commit_before>var url           = require('url'),
    http          = require('http'),
    https         = require('https'),
    parseXML      = require('xml2js').parseString,
    XMLprocessors = require('xml2js/lib/processors');

/**
 * The CAS authentication types.
 * @enum {number}
 */
var AUTH_TYPE = {
    BOUNCE          : 0,
    BOUNCE_REDIRECT : 1,
    BLOCK           : 2
};

/**
 * @typedef {Object} CAS_options
 * @property {string}  cas_url
 * @property {string}  service_url
 * @property {('1.0'|'2.0'|'3.0'|'saml1.1')} [cas_version='3.0']
 * @property {boolean} [renew=false]
 * @property {boolean} [is_dev_mode=false]
 * @property {string}  [dev_mode_user='']
 * @property {string}  [session_name='cas_user']
 * @property {string}  [session_info=false]
 * @property {boolean} [destroy_session=false]
 */

/**
 * @param {CAS_options} options
 * @constructor
 */
function CASAuthentication(options) {

    if (!options || typeof options !== 'object') {
        throw new Error( 'CAS Authentication was not given a valid configuration object.');
    }
    if (options.cas_url === undefined) {
        throw new Error('CAS Authentication requires a cas_url parameter.');
    }
    if (options.service_url === undefined) {
        throw new Error( 'CAS Authentication requires a service_url parameter.');
    }

    this.cas_version = options.cas_version !== undefined ? options.cas_version : '3.0';

    if (this.cas_version === '1.0') {
        this._validateUri = '/validate';
        this._validate = function(body, callback) {
            var lines = body.split('\n');
            if (lines[ 0 ] === 'yes' && lines.length >= 2) {
                return callback(null, lines[ 1 ]);
            }
            else if (lines[ 0 ] === 'no') {
                return callback( new Error('CAS authentication failed.'));
            }
            else {
                return callback( new Error('Response from CAS server was bad.'));
            }
        }
    }
    else if (this.cas_version === '2.0' || this.cas_version === '3.0') {
        this._validateUri = (this.cas_version === '2.0' ? '/serviceValidate' : '/p3/serviceValidate');
        this._validate = function(body, callback) {
            parseXML(body, {
                trim: true,
                normalize: true,
                explicitArray: false,
                tagNameProcessors: [ XMLprocessors.normalize, XMLprocessors.stripPrefix ]
            }, function(err, result) {
                if (err) {
                    return callback(new Error('Response from CAS server was bad.'));
                }
                try {
                    var failure = result.serviceresponse.authenticationfailure;
                    if (failure) {
                        return callback(new Error('CAS authentication failed (' + failure.$.code + ').'));
                    }
                    var success = result.serviceresponse.authenticationsuccess;
                    if (success) {
                        return callback(null, success.user, success.attributes);
                    }
                    else {
                        return callback(new Error( 'CAS authentication failed.'));
                    }
                }
                catch (err) {
                    console.log(err);
                    return callback(new Error('CAS authentication failed.'));
                }
            });
        }
    }
    else if(this.cas_version === 'saml1.1') {
        this._validateUri = '/samlValidate';
        this._validate = function(body, callback) {
            parseXML(body, {
                trim: true,
                normalize: true,
                explicitArray: false,
                tagNameProcessors: [ XMLprocessors.normalize, XMLprocessors.stripPrefix ]
            }, function(err, result) {
                if(err) {
                    return callback(new Error('Response from CAS server was bad.'));
                }
                try {
                    var samlResponse = result.envelope.body.response;
                    var success = samlResponse.status.statuscode.$.Value.split(':')[1];
                    if(success !== 'Success'){
                        return callback(new Error('CAS authentication failed (' + result.status.statuscode.$.Value + ').'));
                    }
                    if(success === 'Success'){
                        var attributes = {};

                        samlResponse.assertion.attributestatement.attribute.forEach(function( attr ){
                            var thisAttrValue;
                            if(attr.attributevalue instanceof Array){
                                thisAttrValue = [];
                                attr.attributevalue.forEach(function( v ) {
                                    thisAttrValue.push(v._);
                                });
                            } else {
                                thisAttrValue = attr.attributevalue._;
                            }
                            attributes[attr.$.AttributeName] = thisAttrValue;
                        });
                        return callback(null, samlResponse.assertion.authenticationstatement.subject.nameidentifier, attributes);
                    }
                    else {
                        return callback(new Error( 'CAS authentication failed.'));
                    }
                }
                catch (err) {
                    console.log(err);
                    return callback(new Error('CAS authentication failed.'));
                }
            });
        }
    }
    else {
        throw new Error('The supplied CAS version ("' + this.cas_version + '") is not supported.');
    }

    this.cas_url         = options.cas_url;
    var parsed_cas_url   = url.parse(this.cas_url);
    this.request_client  = parsed_cas_url.protocol === 'http:' ? http : https;
    this.cas_host        = parsed_cas_url.hostname;
    this.cas_port        = parsed_cas_url.protocol === 'http:' ? 80 : 443;
    this.cas_path        = parsed_cas_url.pathname;

    this.service_url     = options.service_url;

    this.renew           = options.renew !== undefined ? !!options.renew : false;

    this.is_dev_mode     = options.is_dev_mode !== undefined ? !!options.is_dev_mode : false;
    this.dev_mode_user   = options.dev_mode_user !== undefined ? options.dev_mode_user : '';

    this.session_name    = options.session_name !== undefined ? options.session_name : 'cas_user';
    this.session_info    = ['2.0', '3.0', 'saml1.1'].indexOf(this.cas_version) >= 0 && options.session_info !== undefined ? options.session_info : false ;
    this.destroy_session = options.destroy_session !== undefined ? !!options.destroy_session : false;

    // Bind the prototype routing methods to this instance of CASAuthentication.
    this.bounce          = this.bounce.bind(this);
    this.bounce_redirect = this.bounce_redirect.bind(this);
    this.block           = this.block.bind(this);
    this.logout          = this.logout.bind(this);
}

/**
 * Bounces a request with CAS authentication. If the user's session is not
 * already validated with CAS, their request will be redirected to the CAS
 * login page.
 */
CASAuthentication.prototype.bounce = function(req, res, next) {

    // Handle the request with the bounce authorization type.
    this._handle(req, res, next, AUTH_TYPE.BOUNCE);
};

/**
 * Bounces a request with CAS authentication. If the user's session is not
 * already validated with CAS, their request will be redirected to the CAS
 * login page.
 */
CASAuthentication.prototype.bounce_redirect = function(req, res, next) {

    // Handle the request with the bounce authorization type.
    this._handle(req, res, next, AUTH_TYPE.BOUNCE_REDIRECT);
};

/**
 * Blocks a request with CAS authentication. If the user's session is not
 * already validated with CAS, they will receive a 401 response.
 */
CASAuthentication.prototype.block = function(req, res, next) {

    // Handle the request with the block authorization type.
    this._handle(req, res, next, AUTH_TYPE.BLOCK);
};

/**
 * Handle a request with CAS authentication.
 */
CASAuthentication.prototype._handle = function(req, res, next, authType) {

    // If the session has been validated with CAS, no action is required.
    if (req.session[ this.session_name ]) {
        // If this is a bounce redirect, redirect the authenticated user.
        if (authType === AUTH_TYPE.BOUNCE_REDIRECT) {
            res.redirect(req.session.cas_return_to);
        }
        // Otherwise, allow them through to their request.
        else {
            next();
        }
    }
    // If dev mode is active, set the CAS user to the specified dev user.
    else if (this.is_dev_mode) {
        req.session[ this.session_name ] = this.dev_mode_user;
        next();
    }
    // If the authentication type is BLOCK, simply send a 401 response.
    else if (authType === AUTH_TYPE.BLOCK) {
        res.sendStatus(401);
    }
    // If there is a CAS ticket in the query string, validate it with the CAS server.
    else if (req.query && req.query.ticket) {
        this._handleTicket(req, res, next);
    }
    // Otherwise, redirect the user to the CAS login.
    else {
        this._login(req, res, next);
    }
};

/**
 * Redirects the client to the CAS login.
 */
CASAuthentication.prototype._login = function(req, res, next) {

    // Save the return URL in the session. If an explicit return URL is set as a
    // query parameter, use that. Otherwise, just use the URL from the request.
    req.session.cas_return_to = req.query.returnTo || url.parse(req.url).path;

    // Set up the query parameters.
    var query = {
        service: this.service_url + url.parse(req.url).pathname,
        renew: this.renew
    };

    // Redirect to the CAS login.
    res.redirect( this.cas_url + url.format({
        pathname: '/login',
        query: query
    }));
};

/**
 * Logout the currently logged in CAS user.
 */
CASAuthentication.prototype.logout = function(req, res, next) {

    // Destroy the entire session if the option is set.
    if (this.destroy_session) {
        req.session.destroy(function(err) {
            if (err) {
                console.log(err);
            }
        });
    }
    // Otherwise, just destroy the CAS session variables.
    else {
        delete req.session[ this.session_name ];
        if (this.session_info) {
          delete req.session[ this.session_info ];
        }
    }

    // Redirect the client to the CAS logout.
    res.redirect(this.cas_url + '/logout');
};

/**
 * Handles the ticket generated by the CAS login requester and validates it with the CAS login acceptor.
 */
CASAuthentication.prototype._handleTicket = function(req, res, next) {

    var requestOptions = {
        host: this.cas_host,
        port: this.cas_port,
    }

    if (['1.0', '2.0', '3.0'].indexOf(this.cas_version) >= 0){
        requestOptions.method = 'GET';
        requestOptions.path = url.format({
            pathname: this.cas_path + this._validateUri,
            query: {
                service: this.service_url + url.parse(req.url).pathname,
                ticket: req.query.ticket
            }
        });
    } else if (this.cas_version === 'saml1.1'){
        var now = new Date();
        var post_data =
'<?xml version="1.0" encoding="utf-8"?>\n' +
'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n' +
'  <SOAP-ENV:Header/>\n' +
'  <SOAP-ENV:Body>\n' +
'    <samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" MajorVersion="1"\n' +
'      MinorVersion="1" RequestID="_' + req.host + '.' + now.getTime() + '"\n' +
'      IssueInstant="' + now.toISOString() + '">\n' +
'      <samlp:AssertionArtifact>\n' +
'        ' + req.query.ticket + '\n' +
'      </samlp:AssertionArtifact>\n' +
'    </samlp:Request>\n' +
'  </SOAP-ENV:Body>\n' +
'</SOAP-ENV:Envelope>';

        requestOptions.method = 'POST';
        requestOptions.path = url.format({
            pathname: this.cas_path + this._validateUri,
            query : {
                TARGET : this.service_url + url.parse(req.url).pathname,
                ticket: ''
            }
        });
        requestOptions.headers = {
            'Content-Type' : 'text/xml',
            'Content-Length': Buffer.byteLength(post_data)
        }
    }

    var request = this.request_client.request(requestOptions, function(response) {
        response.setEncoding( 'utf8' );
        var body = '';
        response.on( 'data', function(chunk) {
            return body += chunk;
        }.bind(this));
        response.on('end', function() {
            this._validate(body, function(err, user, attributes) {
                if (err) {
                    console.log(err);
                    res.sendStatus(401);
                }
                else {
                    req.session[ this.session_name ] = user;
                    if (this.session_info) {
                        req.session[ this.session_info ] = attributes || {};
                    }
                    res.redirect(req.session.cas_return_to);
                }
            }.bind(this));
        }.bind(this));
        response.on('error', function(err) {
            console.log('Response error from CAS: ', err);
            res.sendStatus(401);
        }.bind(this));
    }.bind(this));

    request.on('error', function(err) {
        console.log('Request error with CAS: ', err);
        res.sendStatus(401);
    }.bind(this));

    if (this.cas_version === 'saml1.1') {
        request.write(post_data);
    }
    request.end();
};

module.exports = CASAuthentication;
<commit_msg>code indentation cleanup<commit_after>var url           = require('url'),
    http          = require('http'),
    https         = require('https'),
    parseXML      = require('xml2js').parseString,
    XMLprocessors = require('xml2js/lib/processors');

/**
 * The CAS authentication types.
 * @enum {number}
 */
var AUTH_TYPE = {
    BOUNCE          : 0,
    BOUNCE_REDIRECT : 1,
    BLOCK           : 2
};

/**
 * @typedef {Object} CAS_options
 * @property {string}  cas_url
 * @property {string}  service_url
 * @property {('1.0'|'2.0'|'3.0'|'saml1.1')} [cas_version='3.0']
 * @property {boolean} [renew=false]
 * @property {boolean} [is_dev_mode=false]
 * @property {string}  [dev_mode_user='']
 * @property {string}  [session_name='cas_user']
 * @property {string}  [session_info=false]
 * @property {boolean} [destroy_session=false]
 */

/**
 * @param {CAS_options} options
 * @constructor
 */
function CASAuthentication(options) {

    if (!options || typeof options !== 'object') {
        throw new Error( 'CAS Authentication was not given a valid configuration object.');
    }
    if (options.cas_url === undefined) {
        throw new Error('CAS Authentication requires a cas_url parameter.');
    }
    if (options.service_url === undefined) {
        throw new Error( 'CAS Authentication requires a service_url parameter.');
    }

    this.cas_version = options.cas_version !== undefined ? options.cas_version : '3.0';

    if (this.cas_version === '1.0') {
        this._validateUri = '/validate';
        this._validate = function(body, callback) {
            var lines = body.split('\n');
            if (lines[ 0 ] === 'yes' && lines.length >= 2) {
                return callback(null, lines[ 1 ]);
            }
            else if (lines[ 0 ] === 'no') {
                return callback( new Error('CAS authentication failed.'));
            }
            else {
                return callback( new Error('Response from CAS server was bad.'));
            }
        }
    }
    else if (this.cas_version === '2.0' || this.cas_version === '3.0') {
        this._validateUri = (this.cas_version === '2.0' ? '/serviceValidate' : '/p3/serviceValidate');
        this._validate = function(body, callback) {
            parseXML(body, {
                trim: true,
                normalize: true,
                explicitArray: false,
                tagNameProcessors: [ XMLprocessors.normalize, XMLprocessors.stripPrefix ]
            }, function(err, result) {
                if (err) {
                    return callback(new Error('Response from CAS server was bad.'));
                }
                try {
                    var failure = result.serviceresponse.authenticationfailure;
                    if (failure) {
                        return callback(new Error('CAS authentication failed (' + failure.$.code + ').'));
                    }
                    var success = result.serviceresponse.authenticationsuccess;
                    if (success) {
                        return callback(null, success.user, success.attributes);
                    }
                    else {
                        return callback(new Error( 'CAS authentication failed.'));
                    }
                }
                catch (err) {
                    console.log(err);
                    return callback(new Error('CAS authentication failed.'));
                }
            });
        }
    }
    else if(this.cas_version === 'saml1.1') {
        this._validateUri = '/samlValidate';
        this._validate = function(body, callback) {
            parseXML(body, {
                trim: true,
                normalize: true,
                explicitArray: false,
                tagNameProcessors: [ XMLprocessors.normalize, XMLprocessors.stripPrefix ]
            }, function(err, result) {
                if(err) {
                    return callback(new Error('Response from CAS server was bad.'));
                }
                try {
                    var samlResponse = result.envelope.body.response;
                    var success = samlResponse.status.statuscode.$.Value.split(':')[1];
                    if(success !== 'Success'){
                        return callback(new Error('CAS authentication failed (' + result.status.statuscode.$.Value + ').'));
                    }
                    if(success === 'Success'){
                        var attributes = {};

                        samlResponse.assertion.attributestatement.attribute.forEach(function( attr ){
                            var thisAttrValue;
                            if(attr.attributevalue instanceof Array){
                                thisAttrValue = [];
                                attr.attributevalue.forEach(function( v ) {
                                    thisAttrValue.push(v._);
                                });
                            } else {
                                thisAttrValue = attr.attributevalue._;
                            }
                            attributes[attr.$.AttributeName] = thisAttrValue;
                        });
                        return callback(null, samlResponse.assertion.authenticationstatement.subject.nameidentifier, attributes);
                    }
                    else {
                        return callback(new Error( 'CAS authentication failed.'));
                    }
                }
                catch (err) {
                    console.log(err);
                    return callback(new Error('CAS authentication failed.'));
                }
            });
        }
    }
    else {
        throw new Error('The supplied CAS version ("' + this.cas_version + '") is not supported.');
    }

    this.cas_url         = options.cas_url;
    var parsed_cas_url   = url.parse(this.cas_url);
    this.request_client  = parsed_cas_url.protocol === 'http:' ? http : https;
    this.cas_host        = parsed_cas_url.hostname;
    this.cas_port        = parsed_cas_url.protocol === 'http:' ? 80 : 443;
    this.cas_path        = parsed_cas_url.pathname;

    this.service_url     = options.service_url;

    this.renew           = options.renew !== undefined ? !!options.renew : false;

    this.is_dev_mode     = options.is_dev_mode !== undefined ? !!options.is_dev_mode : false;
    this.dev_mode_user   = options.dev_mode_user !== undefined ? options.dev_mode_user : '';

    this.session_name    = options.session_name !== undefined ? options.session_name : 'cas_user';
    this.session_info    = ['2.0', '3.0', 'saml1.1'].indexOf(this.cas_version) >= 0 && options.session_info !== undefined ? options.session_info : false ;
    this.destroy_session = options.destroy_session !== undefined ? !!options.destroy_session : false;

    // Bind the prototype routing methods to this instance of CASAuthentication.
    this.bounce          = this.bounce.bind(this);
    this.bounce_redirect = this.bounce_redirect.bind(this);
    this.block           = this.block.bind(this);
    this.logout          = this.logout.bind(this);
}

/**
 * Bounces a request with CAS authentication. If the user's session is not
 * already validated with CAS, their request will be redirected to the CAS
 * login page.
 */
CASAuthentication.prototype.bounce = function(req, res, next) {

    // Handle the request with the bounce authorization type.
    this._handle(req, res, next, AUTH_TYPE.BOUNCE);
};

/**
 * Bounces a request with CAS authentication. If the user's session is not
 * already validated with CAS, their request will be redirected to the CAS
 * login page.
 */
CASAuthentication.prototype.bounce_redirect = function(req, res, next) {

    // Handle the request with the bounce authorization type.
    this._handle(req, res, next, AUTH_TYPE.BOUNCE_REDIRECT);
};

/**
 * Blocks a request with CAS authentication. If the user's session is not
 * already validated with CAS, they will receive a 401 response.
 */
CASAuthentication.prototype.block = function(req, res, next) {

    // Handle the request with the block authorization type.
    this._handle(req, res, next, AUTH_TYPE.BLOCK);
};

/**
 * Handle a request with CAS authentication.
 */
CASAuthentication.prototype._handle = function(req, res, next, authType) {

    // If the session has been validated with CAS, no action is required.
    if (req.session[ this.session_name ]) {
        // If this is a bounce redirect, redirect the authenticated user.
        if (authType === AUTH_TYPE.BOUNCE_REDIRECT) {
            res.redirect(req.session.cas_return_to);
        }
        // Otherwise, allow them through to their request.
        else {
            next();
        }
    }
    // If dev mode is active, set the CAS user to the specified dev user.
    else if (this.is_dev_mode) {
        req.session[ this.session_name ] = this.dev_mode_user;
        next();
    }
    // If the authentication type is BLOCK, simply send a 401 response.
    else if (authType === AUTH_TYPE.BLOCK) {
        res.sendStatus(401);
    }
    // If there is a CAS ticket in the query string, validate it with the CAS server.
    else if (req.query && req.query.ticket) {
        this._handleTicket(req, res, next);
    }
    // Otherwise, redirect the user to the CAS login.
    else {
        this._login(req, res, next);
    }
};

/**
 * Redirects the client to the CAS login.
 */
CASAuthentication.prototype._login = function(req, res, next) {

    // Save the return URL in the session. If an explicit return URL is set as a
    // query parameter, use that. Otherwise, just use the URL from the request.
    req.session.cas_return_to = req.query.returnTo || url.parse(req.url).path;

    // Set up the query parameters.
    var query = {
        service: this.service_url + url.parse(req.url).pathname,
        renew: this.renew
    };

    // Redirect to the CAS login.
    res.redirect( this.cas_url + url.format({
        pathname: '/login',
        query: query
    }));
};

/**
 * Logout the currently logged in CAS user.
 */
CASAuthentication.prototype.logout = function(req, res, next) {

    // Destroy the entire session if the option is set.
    if (this.destroy_session) {
        req.session.destroy(function(err) {
            if (err) {
                console.log(err);
            }
        });
    }
    // Otherwise, just destroy the CAS session variables.
    else {
        delete req.session[ this.session_name ];
        if (this.session_info) {
          delete req.session[ this.session_info ];
        }
    }

    // Redirect the client to the CAS logout.
    res.redirect(this.cas_url + '/logout');
};

/**
 * Handles the ticket generated by the CAS login requester and validates it with the CAS login acceptor.
 */
CASAuthentication.prototype._handleTicket = function(req, res, next) {

    var requestOptions = {
        host: this.cas_host,
        port: this.cas_port,
    }

    if (['1.0', '2.0', '3.0'].indexOf(this.cas_version) >= 0){
        requestOptions.method = 'GET';
        requestOptions.path = url.format({
            pathname: this.cas_path + this._validateUri,
            query: {
                service: this.service_url + url.parse(req.url).pathname,
                ticket: req.query.ticket
            }
        });
    } else if (this.cas_version === 'saml1.1'){
        var now = new Date();
        var post_data = '<?xml version="1.0" encoding="utf-8"?>\n' +
                        '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">\n' +
                        '  <SOAP-ENV:Header/>\n' +
                        '  <SOAP-ENV:Body>\n' +
                        '    <samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" MajorVersion="1"\n' +
                        '      MinorVersion="1" RequestID="_' + req.host + '.' + now.getTime() + '"\n' +
                        '      IssueInstant="' + now.toISOString() + '">\n' +
                        '      <samlp:AssertionArtifact>\n' +
                        '        ' + req.query.ticket + '\n' +
                        '      </samlp:AssertionArtifact>\n' +
                        '    </samlp:Request>\n' +
                        '  </SOAP-ENV:Body>\n' +
                        '</SOAP-ENV:Envelope>';

        requestOptions.method = 'POST';
        requestOptions.path = url.format({
            pathname: this.cas_path + this._validateUri,
            query : {
                TARGET : this.service_url + url.parse(req.url).pathname,
                ticket: ''
            }
        });
        requestOptions.headers = {
            'Content-Type' : 'text/xml',
            'Content-Length': Buffer.byteLength(post_data)
        }
    }

    var request = this.request_client.request(requestOptions, function(response) {
        response.setEncoding( 'utf8' );
        var body = '';
        response.on( 'data', function(chunk) {
            return body += chunk;
        }.bind(this));
        response.on('end', function() {
            this._validate(body, function(err, user, attributes) {
                if (err) {
                    console.log(err);
                    res.sendStatus(401);
                }
                else {
                    req.session[ this.session_name ] = user;
                    if (this.session_info) {
                        req.session[ this.session_info ] = attributes || {};
                    }
                    res.redirect(req.session.cas_return_to);
                }
            }.bind(this));
        }.bind(this));
        response.on('error', function(err) {
            console.log('Response error from CAS: ', err);
            res.sendStatus(401);
        }.bind(this));
    }.bind(this));

    request.on('error', function(err) {
        console.log('Request error with CAS: ', err);
        res.sendStatus(401);
    }.bind(this));

    if (this.cas_version === 'saml1.1') {
        request.write(post_data);
    }
    request.end();
};

module.exports = CASAuthentication;
<|endoftext|>


<commit_before>var SassCompiler = require('broccoli-sass-source-maps');
var path = require('path');
var checker = require('ember-cli-version-checker');
var Funnel = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');
var merge = require('merge');
var fs = require('fs');

function SASSPlugin(optionsFn) {
  this.name = 'ember-cli-sass';
  this.optionsFn = optionsFn;
  this.ext = ['scss', 'sass'];
}

SASSPlugin.prototype.toTree = function(tree, inputPath, outputPath, inputOptions) {
  var options = merge({}, this.optionsFn(), inputOptions);
  var inputTrees;

  if (options.onlyIncluded) {
    inputTrees = [new Funnel(tree, {
      include: ['app/styles/**/*'],
      annotation: 'Funnel (styles)'
    })];
  }
  else {
    inputTrees = [tree];
  }

  if (options.includePaths) {
    inputTrees = inputTrees.concat(options.includePaths);
  }

  var ext = options.extension || 'scss';
  var paths = options.outputPaths;
  var trees = Object.keys(paths).map(function(file) {
    var input = path.join(inputPath, file + '.' + ext);
    var output = paths[file];
    return new SassCompiler(inputTrees, input, output, options);
  });

  return mergeTrees(trees);
};

module.exports = {
  name:  'ember-cli-sass',

  shouldSetupRegistryInIncluded: function() {
    return !checker.isAbove(this, '0.2.0');
  },

  sassOptions: function () {
    var env  = process.env.EMBER_ENV;
    var options = (this.app && this.app.options && this.app.options.sassOptions) || {};
    var envConfig = this.project.config(env).sassOptions;
    if (envConfig) {
      console.warn("Deprecation warning: sassOptions should be moved to your ember-cli-build");
      merge(options, envConfig);
    }

    if ((options.sourceMap === undefined) && (env == 'development')) {
      options.sourceMap = true;
    }

    if (options.sourceMap || options.sourceMapEmbed) {
      // we need to embed the sourcesContent in the source map until libsass has better support for broccoli-sass
      options.sourceMapContents = true;
    }

    options.outputFile = options.outputFile || this.project.name() + '.css';
    options.sourceMapRoot = path.join(this.project.root, 'app/styles');

    return options;
  },

  setupPreprocessorRegistry: function(type, registry) {
    registry.add('css', new SASSPlugin(this.sassOptions.bind(this)));

    // prevent conflict with broccoli-sass if it's installed
    if (registry.remove) registry.remove('css', 'broccoli-sass');
  },

  included: function included(app) {
    this._super.included.apply(this, arguments);

    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;

    if (this.shouldSetupRegistryInIncluded()) {
      this.setupPreprocessorRegistry('parent', app.registry);
    }
  }
};
<commit_msg>Include Parent App support<commit_after>var SassCompiler = require('broccoli-sass-source-maps');
var path = require('path');
var checker = require('ember-cli-version-checker');
var Funnel = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');
var merge = require('merge');
var fs = require('fs');

function SASSPlugin(optionsFn) {
  this.name = 'ember-cli-sass';
  this.optionsFn = optionsFn;
  this.ext = ['scss', 'sass'];
}

SASSPlugin.prototype.toTree = function(tree, inputPath, outputPath, inputOptions) {
  var options = merge({}, this.optionsFn(), inputOptions);
  var inputTrees;

  if (options.onlyIncluded) {
    inputTrees = [new Funnel(tree, {
      include: ['app/styles/**/*'],
      annotation: 'Funnel (styles)'
    })];
  }
  else {
    inputTrees = [tree];
  }

  if (options.includePaths) {
    inputTrees = inputTrees.concat(options.includePaths);
  }

  var ext = options.extension || 'scss';
  var paths = options.outputPaths;
  var trees = Object.keys(paths).map(function(file) {
    var input = path.join(inputPath, file + '.' + ext);
    var output = paths[file];
    return new SassCompiler(inputTrees, input, output, options);
  });

  return mergeTrees(trees);
};

module.exports = {
  name:  'ember-cli-sass',

  shouldSetupRegistryInIncluded: function() {
    return !checker.isAbove(this, '0.2.0');
  },

  sassOptions: function () {
    var env  = process.env.EMBER_ENV;
    var options = (this.app && this.app.options && this.app.options.sassOptions) || {};
    var parentOption = (this.parent && this.parent.app && this.parent.app.options && this.parent.app.options.sassOptions) || {};
    var envConfig = this.project.config(env).sassOptions;

    merge(options, parentOption);

    if (envConfig) {
      console.warn("Deprecation warning: sassOptions should be moved to your ember-cli-build");
      merge(options, envConfig);
    }

    if ((options.sourceMap === undefined) && (env == 'development')) {
      options.sourceMap = true;
    }

    if (options.sourceMap || options.sourceMapEmbed) {
      // we need to embed the sourcesContent in the source map until libsass has better support for broccoli-sass
      options.sourceMapContents = true;
    }

    options.outputFile = options.outputFile || this.project.name() + '.css';
    options.sourceMapRoot = path.join(this.project.root, 'app/styles');

    return options;
  },

  setupPreprocessorRegistry: function(type, registry) {
    registry.add('css', new SASSPlugin(this.sassOptions.bind(this)));

    // prevent conflict with broccoli-sass if it's installed
    if (registry.remove) registry.remove('css', 'broccoli-sass');
  },

  included: function included(app) {
    this._super.included.apply(this, arguments);

    // see: https://github.com/ember-cli/ember-cli/issues/3718
    if (typeof app.import !== 'function' && app.app) {
      app = app.app;
    }

    this.app = app;

    if (this.shouldSetupRegistryInIncluded()) {
      this.setupPreprocessorRegistry('parent', app.registry);
    }
  }
};
<|endoftext|>


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

var README_MAXLEN = 64 * 1024

module.exports = readmeTrim

function readmeTrim(doc) {
  var changed = false
  var readme = doc.readme || ''
  var readmeFilename = doc.readmeFilename || ''
  if (doc['dist-tags'] && doc['dist-tags'].latest) {
    var latest = doc.versions[doc['dist-tags'].latest]
    if (latest && latest.readme) {
      readme = latest.readme
      readmeFilename = latest.readmeFilename || ''
    }
  }

  for (var v in doc.versions) {
    // If we still don't have one, just take the first one.
    if (doc.versions[v].readme && !readme)
      readme = doc.versions[v].readme
    if (doc.versions[v].readmeFilename && !readmeFilename)
      readmeFilename = doc.versions[v].readmeFilename

    if (doc.versions[v].readme)
      changed = true

    delete doc.versions[v].readme
    delete doc.versions[v].readmeFilename
  }

  if (readme && readme.length > README_MAXLEN) {
    changed = true
    readme = readme.slice(0, README_MAXLEN)
  }
  doc.readme = readme
  doc.readmeFilename = readmeFilename

  return changed
}

if (module === require.main) {
  var json = ''
  process.stdin.setEncoding('utf8')
  process.stdin.on('data', function(c) {
    json += c
  })
  process.stdin.on('end', function() {
    var obj = JSON.parse(json)
    readmeTrim(obj)
    console.log(JSON.stringify(obj, null, 2))
  })
}
<commit_msg>Add bin usage<commit_after>#!/usr/bin/env node

var README_MAXLEN = 64 * 1024

module.exports = readmeTrim

function readmeTrim(doc) {
  var changed = false
  var readme = doc.readme || ''
  var readmeFilename = doc.readmeFilename || ''
  if (doc['dist-tags'] && doc['dist-tags'].latest) {
    var latest = doc.versions[doc['dist-tags'].latest]
    if (latest && latest.readme) {
      readme = latest.readme
      readmeFilename = latest.readmeFilename || ''
    }
  }

  for (var v in doc.versions) {
    // If we still don't have one, just take the first one.
    if (doc.versions[v].readme && !readme)
      readme = doc.versions[v].readme
    if (doc.versions[v].readmeFilename && !readmeFilename)
      readmeFilename = doc.versions[v].readmeFilename

    if (doc.versions[v].readme)
      changed = true

    delete doc.versions[v].readme
    delete doc.versions[v].readmeFilename
  }

  if (readme && readme.length > README_MAXLEN) {
    changed = true
    readme = readme.slice(0, README_MAXLEN)
  }
  doc.readme = readme
  doc.readmeFilename = readmeFilename

  return changed
}

if (module === require.main) {
  if (process.argv.length > 2) {
    console.error('No args. Just pipe a doc to stdin, trimmed on stdout')
    process.exit(1)
  }

  var json = ''
  process.stdin.setEncoding('utf8')
  process.stdin.on('data', function(c) {
    json += c
  })
  process.stdin.on('end', function() {
    var obj = JSON.parse(json)
    readmeTrim(obj)
    console.log(JSON.stringify(obj, null, 2))
  })
}
<|endoftext|>


<commit_before>var TYPE = {
	Error: 0,
	Warn: 1,
	Info: 2,
	Debug: 3
}
var log = {
	print: function(msgType, msg) {
		switch(msgType){
			case TYPE.Error:
				console.log('\033[31m[ERROR]' + msg + '\033[0m');
				break;
			case TYPE.Warn:
				console.log('\033[1;33m[WARN]' + msg + '\033[0m');
				break;
			case TYPE.INfo:
				console.log('\033[36m[INFO]' + msg + '\033[0m');
				break;
			case TYPE.Debug:
				console.log('\033[1;32m[DEBUG]' + msg + '\033[0m');
				break;
		}
	},

	error:function(msg){
		log.print(TYPE.Error,msg);
	},

	warn:function(msg){
		log.print(TYPE.Warn,msg);
	},

	info:function(msg){
		log.print(TYPE.Info,msg);
	},

	debug:function(msg){
		log.print(TYPE.Debug,msg);
	}
}
     exports.print = log.print;
     exports.error = log.error;
     exports.warn = log.warn;
     exports.info = log.info;
     exports.debug = log.debug;<commit_msg>release<commit_after>var TYPE = {
	Error: 0,
	Warn: 1,
	Info: 2,
	Debug: 3
}
var log = {
	print: function(msgType, msg) {
		switch(msgType){
			case TYPE.Error:
				console.log('\033[31m[ERROR]' + msg + '\033[0m');
				break;
			case TYPE.Warn:
				console.log('\033[1;33m[WARN]' + msg + '\033[0m');
				break;
			case TYPE.Info:
				console.log('\033[36m[INFO]' + msg + '\033[0m');
				break;
			case TYPE.Debug:
				console.log('\033[1;32m[DEBUG]' + msg + '\033[0m');
				break;
		}
	},

	error:function(msg){
		log.print(TYPE.Error,msg);
	},

	warn:function(msg){
		log.print(TYPE.Warn,msg);
	},

	info:function(msg){
		log.print(TYPE.Info,msg);
	},

	debug:function(msg){
		log.print(TYPE.Debug,msg);
	}
}
     exports.print = log.print;
     exports.error = log.error;
     exports.warn = log.warn;
     exports.info = log.info;
     exports.debug = log.debug;<|endoftext|>


<commit_before>'use strict';

var login = require('./lib/login');
var getLiveData = require('./lib/getlivedata');

module.exports.login = login;

module.exports.getLiveData = getLiveData;<commit_msg>Fixes code style<commit_after>'use strict';

var login = require('./lib/login');
var getLiveData = require('./lib/getlivedata');

module.exports.login = login;

module.exports.getLiveData = getLiveData;
<|endoftext|>


<commit_before>var mustache = require('mustache');
var template = 'hello {{#world}}moon{{/world}}';

var ast = mustache.parse(template);
var content = mustache.render(template, {world: true});

// console.log(ast[1]);
// console.log(content);

// TODO: We should still probably draw out an automata diagram
// But... let's re-invent regular expressions with booleans

// Works well in prolog. I am sure there is a better way to do it.
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] = ['h', 'e', 'l', 'l', 'o', X1, X2, X3, X4, X5]

// TODO: We probably want one of these http://en.wikipedia.org/wiki/Backtracking

// Bleh, not straight forward.

// This says depth first traversal. Let's do that and aim for the first working solution.

function dfs(content, tokens) {
  var i = 0;
  var len = tokens.length;
  for (; i < len; i++) {
    var token = tokens[i];
    var type = token[0];
    switch (type) {
      case '#': // If/loop
        // Treat as `if` for now
        // TODO: Recurse but I am out of time
        var subtokens = token[4];
        var matches = dfs(content, subtokens);

        // Try out using content as `true`
        console.log('matches', matches);

        // Try out using content as `false`

        // If neither worked, reject it
        console.log(token, content);
        break;
      case 'text': // Text
        // Slice the next snippet of text
        var expectedText = token[1];
        // TODO: We should have a progressive portion of content
        var actualText = content.slice(0, expectedText.length);
        console.log(actualText);

        // If it does not match, reject it
        if (actualText !== expectedText) {
          return false;
        } else {
          content = content.slice(expectedText.length);
        }
        break;
    }
  }
  return true;
}
console.log('result ', dfs(content, ast));
<commit_msg>Moving to returning an object and more realizations<commit_after>var mustache = require('mustache');
var template = 'hello {{#world}}moon{{/world}}';

var ast = mustache.parse(template);
var content = mustache.render(template, {world: true});

// console.log(ast[1]);
// console.log(content);

// TODO: We should still probably draw out an automata diagram
// But... let's re-invent regular expressions with booleans

// Works well in prolog. I am sure there is a better way to do it.
// ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] = ['h', 'e', 'l', 'l', 'o', X1, X2, X3, X4, X5]

// TODO: We probably want one of these http://en.wikipedia.org/wiki/Backtracking

// Bleh, not straight forward.

// This says depth first traversal. Let's do that and aim for the first working solution.

function dfs(content, tokens) {
  var i = 0;
  var len = tokens.length;
  var retObj = {};
  for (; i < len; i++) {
    var token = tokens[i];
    var type = token[0];
    switch (type) {
      case '#': // If/loop
        // Treat as `if` for now
        // TODO: Recurse but I am out of time
        // TODO: This is going to have to stop matching the subcontent at some point
        // hello {{moon}} and more
        var subtokens = token[4];
        var matches = dfs(content, subtokens);

        // Try out using content as `true`
        console.log('matches', matches);

        // Try out using content as `false`

        // If neither worked, reject it
        console.log(token, content);
        break;
      case 'text': // Text
        // Slice the next snippet of text
        var expectedText = token[1];
        // TODO: We should have a progressive portion of content
        var actualText = content.slice(0, expectedText.length);
        console.log(actualText);

        // If it does not match, reject it
        if (actualText !== expectedText) {
          return false;
        } else {
          content = content.slice(expectedText.length);
        }
        break;
    }
  }
  return retObj;
}
console.log('result ', dfs(content, ast));
<|endoftext|>


<commit_before>
module.exports = {

  /**
   * busses
   */

  Bus               : require('./bus/base'),
  MapBus            : require('./bus/map'),
  NoopBus           : require('./bus/noop'),
  WrapBus           : require('./bus/wrap'),
  RaceBus           : require('./bus/race'),
  RetryBus          : require('./bus/retry'),
  RandomBus         : require('./bus/random'),
  AcceptBus         : require('./bus/accept'),
  RejectBus         : require('./bus/reject'),
  DelayedBus        : require('./bus/delayed'),
  SequenceBus       : require('./bus/sequence'),
  ParallelBus       : require('./bus/parallel'),
  BufferedBus       : require('./bus/buffered'),
  FallbackBus       : require('./bus/fallback'),
  CatchErrorBus     : require('./bus/catch-error'),
  RoundRobinBus     : require('./bus/round-robin'),
  AttachDefaultsBus : require('./bus/attach-defaults'),

  // TODO
  // TimeoutBus:require('./bus/timeout'),
  // ReduceBus:require('./bus/reduce'),

  /**
   * responses
   */

  Response           : require('./response'),
  EmptyResponse      : require('./response/empty'),

  // deprecated
  AsyncResponse      : require('./response'),
  ErrorResponse      : require('./response/error'),
  BufferedResponse   : require('./response/buffered'),
  NodeStreamResponse : require('./response/node-stream'),

  /**
   */

  WritableStream     : require('./stream/writable')
}
<commit_msg>remove comment<commit_after>
module.exports = {

  /**
   * busses
   */

  Bus               : require('./bus/base'),
  MapBus            : require('./bus/map'),
  NoopBus           : require('./bus/noop'),
  WrapBus           : require('./bus/wrap'),
  RaceBus           : require('./bus/race'),
  RetryBus          : require('./bus/retry'),
  RandomBus         : require('./bus/random'),
  AcceptBus         : require('./bus/accept'),
  RejectBus         : require('./bus/reject'),
  DelayedBus        : require('./bus/delayed'),
  SequenceBus       : require('./bus/sequence'),
  ParallelBus       : require('./bus/parallel'),
  BufferedBus       : require('./bus/buffered'),
  FallbackBus       : require('./bus/fallback'),
  CatchErrorBus     : require('./bus/catch-error'),
  RoundRobinBus     : require('./bus/round-robin'),
  AttachDefaultsBus : require('./bus/attach-defaults'),

  // TODO
  // ReduceBus:require('./bus/reduce'),

  /**
   * responses
   */

  Response           : require('./response'),
  EmptyResponse      : require('./response/empty'),

  // deprecated
  AsyncResponse      : require('./response'),
  ErrorResponse      : require('./response/error'),
  BufferedResponse   : require('./response/buffered'),
  NodeStreamResponse : require('./response/node-stream'),

  /**
   */

  WritableStream     : require('./stream/writable')
}
<|endoftext|>