<commit_before>import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { ListView, View, ActivityIndicator, TouchableHighlight, RefreshControl } from 'react-native'
import moment from 'moment'
import ProfileImage from '../profileImage/ProfileImage'
import SpendingHeader from './SpendingHeader'
import DefaultText from '../DefaultText'
import Price from '../Price'
import color from '../../util/colors'
import * as actions from '../../store/reducer/transaction'
import { openDetailsModal, navigateToTransactionTab } from '../../store/reducer/navigation'
import styles from './spendingStyle'

const renderSeparator = (sectionID, rowID) =>
  <View style={styles.separator} key={`sep:${sectionID}:${rowID}`}/>

const renderSectionHeader = (sectionData, sectionID) =>
  <View style={styles.sectionHeader.container} key={sectionID}>
    <DefaultText style={styles.sectionHeader.text}>
      {moment(sectionData[0].date).format('D MMMM YYYY').toUpperCase()}
    </DefaultText>
  </View>

const getTransactionImage = (transaction) =>
  transaction.relatedAccount.user && transaction.relatedAccount.user.image
    ? transaction.relatedAccount.user.image
    : undefined

const renderRow = (transaction, openDetailsModal) =>
  <TouchableHighlight
      onPress={() => transaction.relatedAccount.user && openDetailsModal(transaction.relatedAccount.user.id)}
      underlayColor={color.transparent}
      key={transaction.transactionNumber}>
    <View style={styles.row.container}>
      <ProfileImage
        img={getTransactionImage(transaction)}
        style={styles.row.image}
        category='shop'/>
      <View style={styles.row.textContainer}>
        <DefaultText style={styles.row.text}>
          { transaction.relatedAccount.user ? transaction.relatedAccount.user.display : 'System' }
        </DefaultText>
        <Price price={transaction.amount} style={styles.row.price} size={22}/>
      </View>
    </View>
  </TouchableHighlight>

const SpendingTab = (props) => {
  let bodyComponent
  if (props.loadingTransactions) {
    bodyComponent = <ActivityIndicator size='large' style={styles.loadingIndicator}/>
  } else if (props.transactions.length > 0) {
    bodyComponent = <ListView
        tabLabel='Transactions'
        style={styles.list}
        pageSize={10}
        renderSeparator={renderSeparator}
        enableEmptySections={true}
        renderRow={transaction => renderRow(transaction, props.openDetailsModal)}
        dataSource={props.transactionsDataSource}
        renderSectionHeader={renderSectionHeader}
        refreshControl={<RefreshControl
          refreshing={props.refreshing}
          onRefresh={() => !props.refreshing ? props.loadMoreTransactions() : undefined} />
        }/>
  } else {
    bodyComponent = <View style={styles.noTransactions.container}>
      <DefaultText style={styles.noTransactions.text}>You have made no transactions</DefaultText>
      <DefaultText style={styles.noTransactions.text}>this month</DefaultText>
    </View>
  }

  return <View style={styles.container}>
      <SpendingHeader />
      {bodyComponent}
    </View>
}

const mapDispatchToProps = (dispatch) =>
  bindActionCreators({
    ...actions,
    navigateToTransactionTab: navigateToTransactionTab,
    openDetailsModal: openDetailsModal
  }, dispatch)

const mapStateToProps = (state) => ({
  ...state.transaction
})

export default connect(mapStateToProps, mapDispatchToProps)(SpendingTab)
<commit_msg>340 - spending scroll position<commit_after>import React from 'react'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { ListView, View, ActivityIndicator, TouchableHighlight, RefreshControl } from 'react-native'
import moment from 'moment'
import ProfileImage from '../profileImage/ProfileImage'
import SpendingHeader from './SpendingHeader'
import DefaultText from '../DefaultText'
import Price from '../Price'
import color from '../../util/colors'
import * as actions from '../../store/reducer/transaction'
import { openDetailsModal, navigateToTransactionTab } from '../../store/reducer/navigation'
import styles from './spendingStyle'

const renderSeparator = (sectionID, rowID) =>
  <View style={styles.separator} key={`sep:${sectionID}:${rowID}`}/>

const renderSectionHeader = (sectionData, sectionID) =>
  <View style={styles.sectionHeader.container} key={sectionID}>
    <DefaultText style={styles.sectionHeader.text}>
      {moment(sectionData[0].date).format('D MMMM YYYY').toUpperCase()}
    </DefaultText>
  </View>

const getTransactionImage = (transaction) =>
  transaction.relatedAccount.user && transaction.relatedAccount.user.image
    ? transaction.relatedAccount.user.image
    : undefined

const renderRow = (transaction, openDetailsModal) =>
  <TouchableHighlight
      onPress={() => transaction.relatedAccount.user && openDetailsModal(transaction.relatedAccount.user.id)}
      underlayColor={color.transparent}
      key={transaction.transactionNumber}>
    <View style={styles.row.container}>
      <ProfileImage
        img={getTransactionImage(transaction)}
        style={styles.row.image}
        category='shop'/>
      <View style={styles.row.textContainer}>
        <DefaultText style={styles.row.text}>
          { transaction.relatedAccount.user ? transaction.relatedAccount.user.display : 'System' }
        </DefaultText>
        <Price price={transaction.amount} style={styles.row.price} size={22}/>
      </View>
    </View>
  </TouchableHighlight>

class SpendingTab extends React.Component {
  componentWillReceiveProps() {
    if (this.listViewRef) {
      // Yes, ListView really wants us to call this twice
      this.listViewRef.scrollTo({ y: 0 })
      this.listViewRef.scrollTo({ y: 0 })
    }
  }
  render() {
    let bodyComponent
    if (this.props.loadingTransactions) {
      bodyComponent = <ActivityIndicator size='large' style={styles.loadingIndicator}/>
    } else if (this.props.transactions.length > 0) {
      bodyComponent = <ListView
          ref={(lv) => this.listViewRef = lv}
          tabLabel='Transactions'
          style={styles.list}
          pageSize={10}
          renderSeparator={renderSeparator}
          enableEmptySections={true}
          renderRow={transaction => renderRow(transaction, this.props.openDetailsModal)}
          dataSource={this.props.transactionsDataSource}
          renderSectionHeader={renderSectionHeader}
          refreshControl={<RefreshControl
            refreshing={this.props.refreshing}
            onRefresh={() => !this.props.refreshing ? this.props.loadMoreTransactions() : undefined} />
          }/>
    } else {
      bodyComponent = <View style={styles.noTransactions.container}>
        <DefaultText style={styles.noTransactions.text}>You have made no transactions</DefaultText>
        <DefaultText style={styles.noTransactions.text}>this month</DefaultText>
      </View>
    }

    return (
      <View style={styles.container}>
        <SpendingHeader />
        {bodyComponent}
      </View>
    )
  }
}

const mapDispatchToProps = (dispatch) =>
  bindActionCreators({
    ...actions,
    navigateToTransactionTab: navigateToTransactionTab,
    openDetailsModal: openDetailsModal
  }, dispatch)

const mapStateToProps = (state) => ({
  ...state.transaction
})

export default connect(mapStateToProps, mapDispatchToProps)(SpendingTab)
<|endoftext|>


<commit_before>/*
 * Copyright 2017, Joachim Kuebart <joachim.kuebart@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the
 *      distribution.
 *
 *   3. Neither the name of the copyright holder nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

var GPXMAP = {};

GPXMAP.CSS = {
    'TRACK': 'gpxmap-track',
    'SELECT': 'gpxmap-select',
};

GPXMAP.gpxmap = function (id, options) {
    'use strict';
    var CSS = GPXMAP.CSS;

    // Create all configured tile layers.
    var tileLayers = options.tileLayers.map(function (layer) {
        return {
            'name': layer.name,
            'tileLayer': L.tileLayer(layer.url, layer.options),
        };
    });

    // Create layers control.
    var layersControl = L.control.layers(null, null, { 'hideSingleBase':true });
    tileLayers.forEach(function (layer) {
        layersControl.addBaseLayer(layer.tileLayer, layer.name);
    });

    // Create map with an initial tile layer and layers control.
    var gpxmap = L.map(id).
        addControl(L.control.scale()).
        addControl(layersControl).
        addLayer(tileLayers[0].tileLayer);

    UTIL.load(options.index).then(function (walks) {
        /*
         * Return a Promise that resolves to an array of GPX tracks once
         * all tracks have been loaded.
         */
        return Promise.all(walks.flatMap(function (walk) {
            // Load GPX file for each date.
            return walk.dates.map(function (date) {
                return UTIL.load(
                    options.gpx + date.substr(0, 10) +'.gpx', 'document'
                ).then(function (gpx) {
                    // Turn segments into MultiPolylines.
                    return {
                        'date': new Date(date),
                        'walk': walk,
                        'gpx': L.polyline(GPX.parse(gpx), {
                            'className': CSS.TRACK,
                            'color': 'currentColor',
                        }),
                    };
                });
            });
        }));
    }).then(function (layers) {
        var yearGpx = {}, year, lg;

        // Group GPX layers by year.
        layers.forEach(function (layer) {
            var year = layer.date.getFullYear();

            if (!yearGpx[year]) {
                yearGpx[year] = [];
            }
            yearGpx[year].push(layer.gpx);
        });

        // Create one layer group per year and add to the map.
        for (year in yearGpx) if (yearGpx.hasOwnProperty(year)) {
            lg = L.layerGroup(yearGpx[year]);
            gpxmap.addLayer(lg);
            layersControl.addOverlay(lg, year);
        }

        // Adjust the map's viewport when all GPX tracks are loaded
        var bounds = L.latLngBounds(layers.map(function (layer) {
            return layer.gpx.getBounds();
        }));
        gpxmap.setMaxBounds(bounds.pad(.05)).fitBounds(bounds);

        // Create a popup for all GPXs of each walk
        layers.forEach(function (layer) {
            var popup = document.createElement('div');
            var anchor = document.createElement('a');

            popup.textContent =
                    [ layer.date.getDate()
                    , layer.date.getMonth() + 1
                    , layer.date.getFullYear()
                    ].join('/') + ' ';
            anchor.setAttribute('href', layer.walk.link);
            anchor.textContent = layer.walk.title;
            popup.appendChild(anchor);
            popup.appendChild(document.createTextNode(
                ' ' + (Math.round(GPX.distance(layer.gpx.getLatLngs()) / 100) / 10) + 'km'
            ));
            layer.gpx.bindPopup(popup);
        });
    });
};
<commit_msg>Store list of latLngs parsed from GPX, postponing Polyline creation.<commit_after>/*
 * Copyright 2017, Joachim Kuebart <joachim.kuebart@gmail.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the
 *      distribution.
 *
 *   3. Neither the name of the copyright holder nor the names of its
 *      contributors may be used to endorse or promote products derived
 *      from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

var GPXMAP = {};

GPXMAP.CSS = {
    'TRACK': 'gpxmap-track',
    'SELECT': 'gpxmap-select',
};

GPXMAP.gpxmap = function (id, options) {
    'use strict';
    var CSS = GPXMAP.CSS;

    // Create all configured tile layers.
    var tileLayers = options.tileLayers.map(function (layer) {
        return {
            'name': layer.name,
            'tileLayer': L.tileLayer(layer.url, layer.options),
        };
    });

    // Create layers control.
    var layersControl = L.control.layers(null, null, { 'hideSingleBase':true });
    tileLayers.forEach(function (layer) {
        layersControl.addBaseLayer(layer.tileLayer, layer.name);
    });

    // Create map with an initial tile layer and layers control.
    var gpxmap = L.map(id).
        addControl(L.control.scale()).
        addControl(layersControl).
        addLayer(tileLayers[0].tileLayer);

    UTIL.load(options.index).then(function (walks) {
        /*
         * Return a Promise that resolves to an array of GPX tracks once
         * all tracks have been loaded.
         */
        return Promise.all(walks.flatMap(function (walk) {
            // Load GPX file for each date.
            return walk.dates.map(function (date) {
                return UTIL.load(
                    options.gpx + date.substr(0, 10) +'.gpx', 'document'
                ).then(function (gpx) {
                    // Turn segments into MultiPolylines.
                    return {
                        'date': new Date(date),
                        'walk': walk,
                        'lines': GPX.parse(gpx).map(function (line) {
                            return line.map(L.latLng);
                        }),
                    };
                });
            });
        }));
    }).then(function (layers) {
        var yearGpx = {}, year, lg;

        // Group GPX layers by year.
        layers.forEach(function (layer) {
            var year = layer.date.getFullYear();

            var line = L.polyline(layer.lines, {
                'className': CSS.TRACK,
                'color': 'currentColor',
            });

            // Create a popup for each walk
            var popup = document.createElement('div');
            var anchor = document.createElement('a');

            popup.textContent =
                    [ layer.date.getDate()
                    , layer.date.getMonth() + 1
                    , layer.date.getFullYear()
                    ].join('/') + ' ';
            anchor.setAttribute('href', layer.walk.link);
            anchor.textContent = layer.walk.title;
            popup.appendChild(anchor);
            popup.appendChild(document.createTextNode(
                ' ' + (Math.round(GPX.distance(layer.lines) / 100) / 10) + 'km'
            ));
            line.bindPopup(popup);

            if (!yearGpx[year]) {
                yearGpx[year] = [];
            }
            yearGpx[year].push(line);
        });

        // Create one layer group per year and add to the map.
        for (year in yearGpx) if (yearGpx.hasOwnProperty(year)) {
            lg = L.layerGroup(yearGpx[year]);
            gpxmap.addLayer(lg);
            layersControl.addOverlay(lg, year);
        }

        // Adjust the map's viewport when all GPX tracks are loaded
        var bounds = L.latLngBounds(layers.flatMap(function (layer) {
            return layer.lines;
        }));
        gpxmap.setMaxBounds(bounds.pad(.05)).fitBounds(bounds);
    });
};
<|endoftext|>


<commit_before>'use strict';

var User = require('../models/users');
var Poll = require('../models/polls');

var path = process.cwd();
var PollHandler = require(path + '/app/controllers/pollHandler.server.js');

module.exports = function (app, passport) {

	function isLoggedIn (req, res, next) {
		if (req.isAuthenticated()) {
			return next();
		} else {
			res.redirect('/login');
		}
	}

	var pollHandler = new PollHandler();

	app.route('/')
		.get(function (req, res) {
			console.log(req.params);
			Poll.find({}, {}, { sort: { 'created_at' : -1 } }, function(err, poll) {
				console.log(poll);
				res.render('index',{poll:poll});
			})
		});

	app.route('/login')
		.get(function (req, res) {
			console.log(req.params);
			Poll.find({}, {}, { sort: { 'created_at' : -1 } }, function(err, poll) {
				console.log(poll);
			res.render('login',{poll:poll, layout:'loggedout'});
			})
		});

	app.route('/logout')
		.get(function (req, res) {
			req.logout();
			res.redirect('/login');
		});

	app.route('/profile/:id')
		.get(isLoggedIn, function (req, res) {
			console.log(req.params);
			User.findOne({"twitter.username":req.params.id}, function(err, user) {
				console.log(user);
				res.render('profile',{user:user, time:Date.now()});
			})
		});

	app.route('/createpoll')
		.get(isLoggedIn, function (req, res) {
			console.log(req.params);
			User.findOne({"twitter.username":req.params.id}, function(err, user) {
				res.render('createpoll');
			})
		});

	app.route('/poll')
		.post(isLoggedIn, function (req, res) {
			console.log(req.body);
			var newpoll = {question : req.body.question};
			newpoll.choices = {};
			var choices = req.body.choices.split(',');
			choices.forEach(function(item) {
				newpoll.choices[item]=0;
			})
			newpoll.creator = req.user._id;
			console.log(newpoll);
			Poll.create(newpoll, function(err, poll) {
				if (err) {
					console.log(err);
				}
			User.findById(req.user._id, function(err, user){
				console.log(user);
				user.polls.push(poll._id);
    			user.save();
				res.redirect('/poll/' + poll._id);
			});
			});
		});

	app.route('/poll/:id/addchoices')
		.post(function (req, res) {
			var newchoices = {};
			var choices = req.body.choices.split(',');
			choices.forEach(function(item) {
				newchoices[item]=0;
			});
			Poll.findById(req.params.id, function(err, poll) {
			var idquery= { _id: req.params.id };
			newchoices = Object.assign(poll.choices, newchoices);
			console.log(newchoices);
			poll.update({ choices: newchoices });
			poll.markModified('choices');
			poll.save();
				res.redirect('/poll/' + poll._id);
});
		});

	app.route('/profile')
		.get(isLoggedIn, function (req, res) {
			res.render("profile",{user:req.user});
		});

	app.route('/poll/:id')
		.get(function (req, res) {
			Poll.findById(req.params.id, function(err, poll){
				console.log(poll.choices);
				var labelarray = Object.keys(toString(poll.choices));
				var valuearray = Object.keys(poll.choices).map(function(key) {
    			return poll.choices[key];
});
				console.log(labelarray);
				console.log(valuearray);
				res.render("poll",{
					poll:poll,
					labels:labelarray,
					values:valuearray

				});
			})
		})
		.delete(function (req, res) {
			console.log(req.params);
			Poll.findOne({"_id":req.params.id}, function(err, poll){
				console.log(poll);
				if (poll) {
					poll.remove();
				};
			User.findById(req.user._id, function(err, user){
				console.log(user);
				var index = user.polls.indexOf(req.params.id);
				console.log(index);
				if (index > -1) {
    				user.polls.splice(index, 1);
    				user.save();
				}
				res.redirect('/profile');
			})
			})
		})
		.post(function (req, res) {
			console.log(req.body);
			if (req.body.choice) {
				Poll.findOne({"_id": req.params.id}, function(err, poll) {
					poll.choices[req.body.choice]++;
					console.log(poll);
					poll.markModified('choices');
					poll.save();
					res.redirect('/poll/' + poll._id);
				})
			}
		});

	app.route('/auth/twitter')
		.get(passport.authenticate('twitter'));

	app.route('/auth/twitter/callback')
		.get(passport.authenticate('twitter', {
			successRedirect: '/',
			failureRedirect: '/login'
		}));

	app.route('/success')
		.get(function (req, res) {
		res.render('success');
		});

};
<commit_msg>displaying polls<commit_after>'use strict';

var User = require('../models/users');
var Poll = require('../models/polls');

var path = process.cwd();
var PollHandler = require(path + '/app/controllers/pollHandler.server.js');

module.exports = function (app, passport) {

	function isLoggedIn (req, res, next) {
		if (req.isAuthenticated()) {
			return next();
		} else {
			res.redirect('/login');
		}
	}

	var pollHandler = new PollHandler();

	app.route('/')
		.get(function (req, res) {
			console.log(req.params);
			Poll.find({}, {}, { sort: { 'created_at' : -1 } }, function(err, poll) {
				console.log(poll);
				res.render('index',{poll:poll});
			})
		});

	app.route('/login')
		.get(function (req, res) {
			console.log(req.params);
			Poll.find({}, {}, { sort: { 'created_at' : -1 } }, function(err, poll) {
				console.log(poll);
			res.render('login',{poll:poll, layout:'loggedout'});
			})
		});

	app.route('/logout')
		.get(function (req, res) {
			req.logout();
			res.redirect('/login');
		});

	app.route('/profile/:id')
		.get(isLoggedIn, function (req, res) {
			console.log(req.params);
			User.findOne({"twitter.username":req.params.id}, function(err, user) {
				console.log(user);
				res.render('profile',{user:user, time:Date.now()});
			})
		});

	app.route('/createpoll')
		.get(isLoggedIn, function (req, res) {
			console.log(req.params);
			User.findOne({"twitter.username":req.params.id}, function(err, user) {
				res.render('createpoll');
			})
		});

	app.route('/poll')
		.post(isLoggedIn, function (req, res) {
			console.log(req.body);
			var newpoll = {question : req.body.question};
			newpoll.choices = {};
			var choices = req.body.choices.split(',');
			choices.forEach(function(item) {
				newpoll.choices[item]=0;
			})
			newpoll.creator = req.user._id;
			console.log(newpoll);
			Poll.create(newpoll, function(err, poll) {
				if (err) {
					console.log(err);
				}
			User.findById(req.user._id, function(err, user){
				console.log(user);
				user.polls.push(poll._id);
    			user.save();
				res.redirect('/poll/' + poll._id);
			});
			});
		});

	app.route('/poll/:id/addchoices')
		.post(function (req, res) {
			var newchoices = {};
			var choices = req.body.choices.split(',');
			choices.forEach(function(item) {
				newchoices[item]=0;
			});
			Poll.findById(req.params.id, function(err, poll) {
			var idquery= { _id: req.params.id };
			newchoices = Object.assign(poll.choices, newchoices);
			console.log(newchoices);
			poll.update({ choices: newchoices });
			poll.markModified('choices');
			poll.save();
				res.redirect('/poll/' + poll._id);
});
		});

	app.route('/profile')
		.get(isLoggedIn, function (req, res) {
			res.render("profile",{user:req.user});
		});

	app.route('/poll/:id')
		.get(function (req, res) {
			Poll.findById(req.params.id, function(err, poll){
				console.log(poll.choices);
				var labelarray = [];
					for (var key in poll.choices) {
    				labelarray.push(key);
				}
				var valuearray = Object.keys(poll.choices).map(function(key) {
    			return poll.choices[key];
});
				console.log(labelarray);
				console.log(valuearray);
				res.render("poll",{
					poll:poll,
					labels:labelarray,
					values:valuearray

				});
			})
		})
		.delete(function (req, res) {
			console.log(req.params);
			Poll.findOne({"_id":req.params.id}, function(err, poll){
				console.log(poll);
				if (poll) {
					poll.remove();
				};
			User.findById(req.user._id, function(err, user){
				console.log(user);
				var index = user.polls.indexOf(req.params.id);
				console.log(index);
				if (index > -1) {
    				user.polls.splice(index, 1);
    				user.save();
				}
				res.redirect('/profile');
			})
			})
		})
		.post(function (req, res) {
			console.log(req.body);
			if (req.body.choice) {
				Poll.findOne({"_id": req.params.id}, function(err, poll) {
					poll.choices[req.body.choice]++;
					console.log(poll);
					poll.markModified('choices');
					poll.save();
					res.redirect('/poll/' + poll._id);
				})
			}
		});

	app.route('/auth/twitter')
		.get(passport.authenticate('twitter'));

	app.route('/auth/twitter/callback')
		.get(passport.authenticate('twitter', {
			successRedirect: '/',
			failureRedirect: '/login'
		}));

	app.route('/success')
		.get(function (req, res) {
		res.render('success');
		});

};
<|endoftext|>


<commit_before>var rainman = require('./rainman');

RANK_SCORES = {
  "2": 1,
  "3": 2,
  "4": 3,
  "5": 4,
  "6": 5,
  "7": 6,
  "8": 7,
  "9": 8,
  "10": 9,
  "J": 10,
  "Q": 11,
  "K": 12,
  "A": 13
};

function rankScore(rank1, rank2) {
  return RANK_SCORES[rank1] * RANK_SCORES[rank1] + RANK_SCORES[rank2] * RANK_SCORES[rank2];
}

/**
 * Return from 0.0 to 1.0
 * 0.0 - very bad hand
 * 1.0 = awesome hand
 * @param {object} hole_cards
 * @param {string} hole_cards.rank
 * @param {string} hole_cards.suit
 * @returns {number}
 * @private
 */
function _estimateHand(hole_cards) {
  var first = hole_cards[0];
  var second = hole_cards[1];
  if (first.rank === second.rank) {
    return 1;
  } else if (first.suit === second.suit) {
    return 0.75
  } else {
    if (rankScore(first.rank, second.rank) > 190) {
      return 0.5;
    } else {
      return 0;
    }
  }

  return 0;
}

function _estimateAllCards(cards) {
  return rainman(cards);
}

function _estimateState(game_state) {
  if(!game_state.community_cards || game_state.community_cards.length == 0) {
    // Without community cards
    var handEstimation = _estimateHand(game_state.players[game_state.in_action].hole_cards);
    return handEstimation;

  } else {
    // With community cards
    // TODO
    /*var hand = game_state.players[game_state.in_action].hole_cards;
    var communityCards = game_state.community_cards;
    var allCards = hand.concat(communityCards);
    var allCardsEstimation = _estimateAllCards(allCards);
    console.log("rainman", allCardsEstimation);*/

    var handEstimation = _estimateHand(game_state.players[game_state.in_action].hole_cards);
    return handEstimation;
  }
}

function _raise(game_state) {
  return game_state.current_buy_in - game_state.players[game_state.in_action]["bet"] + game_state.minimum_raise;
}

module.exports = {

  VERSION: "LeanNodeJS engineered player tuna",

  bet_request: function(game_state) {
    console.log(game_state);
    try {
      var inPlayers = game_state.players.filter(function(player) {
        return player.status != "out";
      });

      var stateEstimation = _estimateState(game_state);
      if(stateEstimation < 0.5
          && (stateEstimation / 0.5) < Math.random()) {
        return 0;
      }

      if(stateEstimation == 1) {
        if(game_state.current_buy_in > 500)
          return _raise(game_state);
        else
          return 500;
      }

      /*if(game_state.current_buy_in >= 1000 && inPlayers.length <= 2) {
        console.info("game_state.current_buy_in >= 1000 && inPlayers.length <= 2");
        if(Math.random() > 0.5 || stateEstimation == 1) {
          return 1000000000;
        } else {
          return 0;
        }
      }*/

      if(inPlayers.length > 2 && game_state.current_buy_in >= 1000) {
        if(stateEstimation > 0.5)
          return _raise(game_state);
        else
          return 0;
      }

      console.info("Default behaviour");
      return _raise(game_state);
    }
    catch(e) {
      console.error(e);
      return 1000000000;
    }
  },

  showdown: function(game_state) {

  }
};<commit_msg>call added<commit_after>var rainman = require('./rainman');

RANK_SCORES = {
  "2": 1,
  "3": 2,
  "4": 3,
  "5": 4,
  "6": 5,
  "7": 6,
  "8": 7,
  "9": 8,
  "10": 9,
  "J": 10,
  "Q": 11,
  "K": 12,
  "A": 13
};

function rankScore(rank1, rank2) {
  return RANK_SCORES[rank1] * RANK_SCORES[rank1] + RANK_SCORES[rank2] * RANK_SCORES[rank2];
}

/**
 * Return from 0.0 to 1.0
 * 0.0 - very bad hand
 * 1.0 = awesome hand
 * @param {object} hole_cards
 * @param {string} hole_cards.rank
 * @param {string} hole_cards.suit
 * @returns {number}
 * @private
 */
function _estimateHand(hole_cards) {
  var first = hole_cards[0];
  var second = hole_cards[1];
  if (first.rank === second.rank) {
    return 1;
  } else if (first.suit === second.suit) {
    return 0.75
  } else {
    if (rankScore(first.rank, second.rank) > 190) {
      return 0.5;
    } else {
      return 0;
    }
  }

  return 0;
}

function _estimateAllCards(cards) {
  return rainman(cards);
}

function _estimateState(game_state) {
  if(!game_state.community_cards || game_state.community_cards.length == 0) {
    // Without community cards
    var handEstimation = _estimateHand(game_state.players[game_state.in_action].hole_cards);
    return handEstimation;

  } else {
    // With community cards
    // TODO
    /*var hand = game_state.players[game_state.in_action].hole_cards;
    var communityCards = game_state.community_cards;
    var allCards = hand.concat(communityCards);
    var allCardsEstimation = _estimateAllCards(allCards);
    console.log("rainman", allCardsEstimation);*/

    var handEstimation = _estimateHand(game_state.players[game_state.in_action].hole_cards);
    return handEstimation;
  }
}

function _raise(game_state) {
  return game_state.current_buy_in - game_state.players[game_state.in_action]["bet"] + game_state.minimum_raise;
}

function _call(game_state) {
  return game_state.current_buy_in - game_state.players[game_state.in_action]["bet"];
}

module.exports = {

  VERSION: "LeanNodeJS engineered player tuna",

  bet_request: function(game_state) {
    console.log(game_state);
    try {
      var inPlayers = game_state.players.filter(function(player) {
        return player.status != "out";
      });

      var stateEstimation = _estimateState(game_state);

      if(stateEstimation < 0.5
          && (stateEstimation / 0.5) < Math.random()) {
        return 0;
      }
      else if(stateEstimation == 1) {
        if(game_state.current_buy_in > 500)
          return _raise(game_state);
        else
          return 500;
      }

      /*if(game_state.current_buy_in >= 1000 && inPlayers.length <= 2) {
        console.info("game_state.current_buy_in >= 1000 && inPlayers.length <= 2");
        if(Math.random() > 0.5 || stateEstimation == 1) {
          return 1000000000;
        } else {
          return 0;
        }
      }*/

      if(inPlayers.length > 2 && game_state.current_buy_in >= 1000) {
        if(stateEstimation > 0.5)
          return _raise(game_state);
        else
          return 0;
      }

      if(stateEstimation < 0.75) {
        return _call(game_state);
      }

      console.info("Default behaviour");
      return _raise(game_state);
    }
    catch(e) {
      console.error(e);
      return 1000000000;
    }
  },

  showdown: function(game_state) {

  }
};<|endoftext|>


<commit_before>"use strict";
var LWdb = require('../src/LWdb');
var BoxOfQuestions = require('../src/BoxOfQuestions');
var wordlist = require('../data/wordlist-en-ge.js');

var readline = require('readline');

// ----------------------------------------------
// LearnWords2 API usage
//
// creation:
//     LW = new BoxOfQuestions(new LWdb('learnWords'));
//
// methods and properties used
//
//     LW.db.loadWords(wordlist)
//     LW.question()
//     LW.answer()
//     LW.moveQuestionForward()
//     LW.moveQuestionBackwards()
//
// ----------------------------------------------

var LW = new BoxOfQuestions(new LWdb('learnWords'));

if (LW.db.numberOfWords() == 0) {LW.db.loadWords(wordlist)};

console.log('\x1Bc');

console.log('LearnWords2 demo');
console.log('');
console.log('Type the answers:');
console.log('');

// var aWord = {_id: 1, "word": "apple", "translate": "der Apfel"};

var aWord = LW.question();

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question(aWord.word + " = ", function(answer) {
     answer = answer.toString().trim();

     if (answer == LW.answer())
		{console.log('OK');
                 LW.moveQuestionForward()}
     else {console.log('the correct answer is:', LW.answer());
           LW.moveQuestionBackwards()};
rl.close();

});

<commit_msg>comment update<commit_after>// ----------------------------------------------
// LearnWords2 API usage
//
// creation:
//     LW = new BoxOfQuestions(new LWdb('learnWords'));
//
// methods and properties used
//
//     LW.db.loadWords(wordlist)
//     LW.question()
//     LW.answer()
//     LW.moveQuestionForward()
//     LW.moveQuestionBackwards()
//
//
//
// Asks one word and then terminates
// ----------------------------------------------

"use strict";
var readline = require('readline');

var LWdb = require('../src/LWdb');
var BoxOfQuestions = require('../src/BoxOfQuestions');

var wordlist = require('../data/wordlist-en-ge.js');

// set up the LW (learnwords) object

var LW = new BoxOfQuestions(new LWdb('learnWords'));

if (LW.db.numberOfWords() == 0) {LW.db.loadWords(wordlist)};

// clear console
console.log('\x1Bc');

// write title
console.log('LearnWords2 demo');
console.log('');

// get a question from the box

var aWord = LW.question();
// gives for example
// {_id: 1, "word": "apple", "translate": "der Apfel", "step": 0, "date": 0};

// if we got a question ask for the translation of the word

if (aWord) {

console.log('Type the answers:');
console.log('');

var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.question(aWord.word + " = ", function(answer) {
     answer = answer.toString().trim();

     if (answer == LW.answer())
		{console.log('OK');
                 LW.moveQuestionForward()}
     else {console.log('the correct answer is:', LW.answer());
           LW.moveQuestionBackwards()};
rl.close();
})
} else {console.log('As of now there are no more words to repeat.')};

// currently only one question is asked and then the program quits.
// you have to restart the program to get the next question.
//
// the db entries are in the 'scratch' subdirectory
<|endoftext|>


<commit_before><commit_msg>Default to empty string if no first or last name<commit_after><|endoftext|>


<commit_before>/*******************************************************************************

    ChromeTvViewer - a browser extension to open HbbTV,CE-HTML,BML,OHTV webpages
    instead of downloading them. A mere simulator is also provided.

    Copyright (C) 2015 Karl Rousseau

    MIT License:
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

    See the MIT License for more details: http://opensource.org/licenses/MIT

    HomePage: https://github.com/karl-rousseau/ChromeHybridTvViewer
*/

// If the extension is not activated for this web page then we do nothing and
// wait for the user to click on the extension icon ... otherwise we inject stuff in the DOM
var pageActivated = localStorage.getItem('tvViewer_active') == 'true';
if (pageActivated) {
    function addClass(element, className) {
        if (element.classList) {
            element.classList.add(className);
        } else {
            element.className += ' ' + className;
        }
    }

    function removeClass(element, className) {
        if (element.classList) {
            element.classList.remove(className);
        }
    }

    (function injectClass(document) {
        // Just tag current page as activated and also do CSS injection at the same time ...
        addClass(document.documentElement, "tvViewer");
    })(window.document);

    // UserAgent spoofing ----------------------------------------------------------

    var newUserAgent = "Mozilla/5.0 (Linux mipsel; U; HbbTV/1.1.1 (; TOSHIBA; DTV_L7300; 7.2.67.14.01.1; a5; ) ; ToshibaTP/2.0.0 (+DRM) ; xx) AppleWebKit/537.4 (KHTML, like Gecko) TOSHIBA-DTV (DTV_L7300; 7.2.67.14.01.1; 2013A; NA)";
    var modifiedNavigator;
    if ('userAgent' in Navigator.prototype) { // Chrome V43+ moved all properties from navigator to the prototype
        modifiedNavigator = Navigator.prototype;
    }
    Object.defineProperties(modifiedNavigator, {
        userAgent: {
            value: newUserAgent,
            configurable: false,
            enumerable: true,
            writable: false
        },
        appName: {
            value: "ChromeTvViewer",
            configurable: false,
            enumerable: true,
            writable: false
        },
        appVersion: {
            value: "AppleWebKit/537.4 (KHTML, like Gecko) TOSHIBA-DTV (DTV_L7300; 7.2.67.14.01.1; 2013A; NA)",
            configurable: false,
            enumerable: true,
            writable: false
        },
        platform: {
            value: 'Chrome',
            configurable: false,
            enumerable: true,
            writable: false
        }
    });

    // Button keys emulator --------------------------------------------------------

    (function injectButtons(document) {

        if (document.getElementById("redkey")) {
            return ;
        }

        function doKeyPress(key) {
            var event = document.createEvent('Event');
            event.keyCode = key;
            event.initEvent('keydown');
            document.dispatchEvent(event);
        }

        function doKeyChangeResolution(keyId) {
            // just verify that the click is not done on the same selected button ...
            var res = keyId.replace(/key/g, 'p');
            var storedResolution = localStorage.getItem('tvViewer_resolution') || "res720p";
            if (res == storedResolution) {
                return ;
            }

            removeClass(document.getElementById("res720key"), "focus");
            removeClass(document.getElementById("res1080key"), "focus");
            removeClass(document.getElementById("res1440key"), "focus");
            removeClass(document.getElementById("res2160key"), "focus");
            removeClass(document.body, "res720p");
            removeClass(document.body, "res1080p");
            removeClass(document.body, "res1440p");
            removeClass(document.body, "res2160p");
            addClass(document.body, res);
            addClass(document.getElementById(keyId), "focus");
            localStorage.setItem('tvViewer_resolution', res); // TODO: store this value in Chrome's extension
        }

        function generateButton(keyId, keyValue, optionClassName) {
            var keyButton = document.createElement('span');
            keyButton.setAttribute("id", keyId);
            keyButton.setAttribute("class", "keybutton" + (optionClassName ? ' ' + optionClassName : ''));
            keyButton.addEventListener('click', function() {
                if (keyValue) {
                    doKeyPress(keyValue);
                } else if (typeof keyValue == 'undefined') {
                    doKeyChangeResolution(keyId);
                }
            });
            var body = document.getElementsByTagName("body")[0];
            if (body) {
                body.appendChild(keyButton);
            }
        }

        // warning: here for ARTE, we can't use the KeyEvent object but only the global VK_xx
        window.KeyEvent = window.KeyEvent || {};
        var redValue = window.KeyEvent.VK_RED ? window.KeyEvent.VK_RED : (typeof VK_RED !== 'undefined' ? VK_RED : 403);
        var greenValue = window.KeyEvent.VK_GREEN ? window.KeyEvent.VK_GREEN : (typeof VK_GREEN !== 'undefined' ? VK_GREEN : 404);
        var yellowValue = window.KeyEvent.VK_YELLOW ? window.KeyEvent.VK_YELLOW : (typeof VK_YELLOW !== 'undefined' ? VK_YELLOW : 405);
        var blueValue = window.KeyEvent.VK_BLUE ? window.KeyEvent.VK_BLUE : (typeof VK_BLUE !== 'undefined' ? VK_BLUE : 406);
        generateButton("redkey", redValue);
        generateButton("greenkey", greenValue);
        generateButton("yellowkey", yellowValue);
        generateButton("bluekey", blueValue);

        // add F11 and F12 buttons ... (not clickable as the browser will handle their actions by default)
        generateButton("f11key", null, "btleftgradient btrightgradient");
        generateButton("f12key", null, "btleftgradient btrightgradient");

        // add resizing screen buttons ...
        generateButton("res720key");
        generateButton("res1080key");
        generateButton("res1440key");
        generateButton("res2160key");

        var pageResolution = localStorage.getItem('tvViewer_resolution') || "res720p";
        addClass(document.body, pageResolution);

        var resButton = document.getElementById(pageResolution.replace(/p/g, "key"));
        addClass(resButton, "focus");
    })(window.document);

    // OIPF objects mapping --------------------------------------------------------

    (function injectOipf(document) {
        console.log("Checking for OIPF objects ...");
        window.oipf = window.oipf || {};

        var int_objs = [];
        var int_objTypes = {
            oipfAppMan: "oipfApplicationManager",
            oipfAppConfig: "oipfConfiguration",
            oipfAppCapObj: "oipfCapabilities"
        };
        var int_objTypesClass = {
            oipfAppMan: window.oipfApplicationManager,
            oipfAppConfig: window.oipfConfiguration,
            oipfAppCapObj: window.oipfCapabilities
        };

        function mixin(source, target) { // soon we might use ES6 Object.assign()
            for (var prop in source) {
                if (source.hasOwnProperty(prop)) {
                    target[prop] = source[prop];
                }
            }
        }

        // Introspection: looking for existing objects ...
        var objects = document.getElementsByTagName("object");
        for (var i = 0; i < objects.length; i++) {
            var oipfPluginObject = objects.item(i);
            var sType = oipfPluginObject.getAttribute("type");
            console.log((i + 1) + " / " + objects.length + " : " + sType);
            for (var eType in int_objTypes) {
                var objType = int_objTypes[eType];
                if (sType === "application/" + objType) {
                    int_objs[objType] = oipfPluginObject;
                    if (objType === "oipfApplicationManager") {
                        console.log("re-using user-defined oipfApplicationManager");
                        mixin(window.oipfApplicationManager, int_objs[objType]);
                        break;
                    } else if (objType === "oipfConfiguration") {
                        console.log("re-using user-defined oipfConfiguration");
                        mixin(window.oipfConfiguration, int_objs[objType]);
                        break;
                    } else if (objType === "oipfCapabilities") {
                        console.log("re-using user-defined oipfCapabilities");
                        mixin(window.oipfCapabilities, int_objs[objType]);
                        break;
                    }
                }
            }
            if (sType.indexOf("video/") !== -1) {
                if (sType === "video/broadcast") {
                    console.log("re-using user-defined video object");
                    window.oipf.videoObject = oipfPluginObject;
                    var currentChannel = {
                        'TYPE_TV': 12,
                        'channelType': 12,
                        'sid': 1,
                        'onid': 1,
                        'tsid': 1,
                        'name': 'test'
                    };
                    oipfPluginObject.currentChannel = currentChannel;
                    oipfPluginObject.bindToCurrentChannel = function() {
                        return currentChannel;
                    };
                } else if (sType === "video/mp4" || sType === "video/mpeg4") {
                    window.oipf.videoObject = oipfPluginObject;
                    oipfPluginObject.play = function (speed) {
                    };

                }
            }
        }

        // create missing objects ... (not needed by default as the app is creating them)
        /*var oipfObjs = document.createElement("div");
        var objCreated = false;
        for (var typeId in int_objTypes) {
            var type = int_objTypes[typeId];
            if (!int_objs[type]) {
                var obj = document.createElement("object");
                obj.setAttribute("id", typeId);
                obj.setAttribute("type", "application/" + type);
                if (typeId == "oipfAppMan") {
                    if (oipfApplicationManager) {
                      mixin(window.oipfApplicationManager, obj);
                    } else {
                      obj.getOwnerApplication = function() { return {}; };
                      // ... see hbbtv.js code to replicate here ...
                    }
                }
                oipfObjs.appendChild(obj);
                int_objs[type] = obj;
                objCreated = true;
            }
        }
        if (objCreated) {
            oipfObjs.setAttribute("style", "visibility:hidden; width:0; height:0;");
            document.getElementsByTagName("body")[0].appendChild(oipfObjs);
        }*/
    })(window.document);

    console.log("DOM HbbTV emulator added.");
}
<commit_msg>Remove jshint warnings<commit_after>/*******************************************************************************

    ChromeTvViewer - a browser extension to open HbbTV,CE-HTML,BML,OHTV webpages
    instead of downloading them. A mere simulator is also provided.

    Copyright (C) 2015 Karl Rousseau

    MIT License:
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the "Software"),
    to deal in the Software without restriction, including without limitation
    the rights to use, copy, modify, merge, publish, distribute, sublicense,
    and/or sell copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

    See the MIT License for more details: http://opensource.org/licenses/MIT

    HomePage: https://github.com/karl-rousseau/ChromeHybridTvViewer
*/
// jshint -W082:true, -W083:true

// If the extension is not activated for this web page then we do nothing and
// wait for the user to click on the extension icon ... otherwise we inject stuff in the DOM
var pageActivated = localStorage.getItem('tvViewer_active') == 'true';
if (pageActivated) {
    function addClass(element, className) {
        if (element.classList) {
            element.classList.add(className);
        } else {
            element.className += ' ' + className;
        }
    }

    function removeClass(element, className) {
        if (element.classList) {
            element.classList.remove(className);
        }
    }

    (function injectClass(document) {
        // Just tag current page as activated and also do CSS injection at the same time ...
        addClass(document.documentElement, "tvViewer");
    })(window.document);

    // UserAgent spoofing ----------------------------------------------------------

    var newUserAgent = "Mozilla/5.0 (Linux mipsel; U; HbbTV/1.1.1 (; TOSHIBA; DTV_L7300; 7.2.67.14.01.1; a5; ) ; ToshibaTP/2.0.0 (+DRM) ; xx) AppleWebKit/537.4 (KHTML, like Gecko) TOSHIBA-DTV (DTV_L7300; 7.2.67.14.01.1; 2013A; NA)";
    var modifiedNavigator;
    if ('userAgent' in Navigator.prototype) { // Chrome V43+ moved all properties from navigator to the prototype
        modifiedNavigator = Navigator.prototype;
    }
    Object.defineProperties(modifiedNavigator, {
        userAgent: {
            value: newUserAgent,
            configurable: false,
            enumerable: true,
            writable: false
        },
        appName: {
            value: "ChromeTvViewer",
            configurable: false,
            enumerable: true,
            writable: false
        },
        appVersion: {
            value: "AppleWebKit/537.4 (KHTML, like Gecko) TOSHIBA-DTV (DTV_L7300; 7.2.67.14.01.1; 2013A; NA)",
            configurable: false,
            enumerable: true,
            writable: false
        },
        platform: {
            value: 'Chrome',
            configurable: false,
            enumerable: true,
            writable: false
        }
    });

    // Button keys emulator --------------------------------------------------------

    (function injectButtons(document) {

        if (document.getElementById("redkey")) {
            return ;
        }

        function doKeyPress(key) {
            var event = document.createEvent('Event');
            event.keyCode = key;
            event.initEvent('keydown');
            document.dispatchEvent(event);
        }

        function doKeyChangeResolution(keyId) {
            // just verify that the click is not done on the same selected button ...
            var res = keyId.replace(/key/g, 'p');
            var storedResolution = localStorage.getItem('tvViewer_resolution') || "res720p";
            if (res == storedResolution) {
                return ;
            }

            removeClass(document.getElementById("res720key"), "focus");
            removeClass(document.getElementById("res1080key"), "focus");
            removeClass(document.getElementById("res1440key"), "focus");
            removeClass(document.getElementById("res2160key"), "focus");
            removeClass(document.body, "res720p");
            removeClass(document.body, "res1080p");
            removeClass(document.body, "res1440p");
            removeClass(document.body, "res2160p");
            addClass(document.body, res);
            addClass(document.getElementById(keyId), "focus");
            localStorage.setItem('tvViewer_resolution', res); // TODO: store this value in Chrome's extension
        }

        function generateButton(keyId, keyValue, optionClassName) {
            var keyButton = document.createElement('span');
            keyButton.setAttribute("id", keyId);
            keyButton.setAttribute("class", "keybutton" + (optionClassName ? ' ' + optionClassName : ''));
            keyButton.addEventListener('click', function() {
                if (keyValue) {
                    doKeyPress(keyValue);
                } else if (typeof keyValue == 'undefined') {
                    doKeyChangeResolution(keyId);
                }
            });
            var body = document.getElementsByTagName("body")[0];
            if (body) {
                body.appendChild(keyButton);
            }
        }

        // warning: here for ARTE, we can't use the KeyEvent object but only the global VK_xx
        window.KeyEvent = window.KeyEvent || {};
        var redValue = window.KeyEvent.VK_RED ? window.KeyEvent.VK_RED : (typeof VK_RED !== 'undefined' ? VK_RED : 403);
        var greenValue = window.KeyEvent.VK_GREEN ? window.KeyEvent.VK_GREEN : (typeof VK_GREEN !== 'undefined' ? VK_GREEN : 404);
        var yellowValue = window.KeyEvent.VK_YELLOW ? window.KeyEvent.VK_YELLOW : (typeof VK_YELLOW !== 'undefined' ? VK_YELLOW : 405);
        var blueValue = window.KeyEvent.VK_BLUE ? window.KeyEvent.VK_BLUE : (typeof VK_BLUE !== 'undefined' ? VK_BLUE : 406);
        generateButton("redkey", redValue);
        generateButton("greenkey", greenValue);
        generateButton("yellowkey", yellowValue);
        generateButton("bluekey", blueValue);

        // add F11 and F12 buttons ... (not clickable as the browser will handle their actions by default)
        generateButton("f11key", null, "btleftgradient btrightgradient");
        generateButton("f12key", null, "btleftgradient btrightgradient");

        // add resizing screen buttons ...
        generateButton("res720key");
        generateButton("res1080key");
        generateButton("res1440key");
        generateButton("res2160key");

        var pageResolution = localStorage.getItem('tvViewer_resolution') || "res720p";
        addClass(document.body, pageResolution);

        var resButton = document.getElementById(pageResolution.replace(/p/g, "key"));
        addClass(resButton, "focus");
    })(window.document);

    // OIPF objects mapping --------------------------------------------------------

    (function injectOipf(document) {
        console.log("Checking for OIPF objects ...");
        window.oipf = window.oipf || {};

        var int_objs = [];
        var int_objTypes = {
            oipfAppMan: "oipfApplicationManager",
            oipfAppConfig: "oipfConfiguration",
            oipfAppCapObj: "oipfCapabilities"
        };
        var int_objTypesClass = {
            oipfAppMan: window.oipfApplicationManager,
            oipfAppConfig: window.oipfConfiguration,
            oipfAppCapObj: window.oipfCapabilities
        };

        function mixin(source, target) { // soon we might use ES6 Object.assign()
            for (var prop in source) {
                if (source.hasOwnProperty(prop)) {
                    target[prop] = source[prop];
                }
            }
        }

        // Introspection: looking for existing objects ...
        var objects = document.getElementsByTagName("object");
        for (var i = 0; i < objects.length; i++) {
            var oipfPluginObject = objects.item(i);
            var sType = oipfPluginObject.getAttribute("type");
            console.log((i + 1) + " / " + objects.length + " : " + sType);
            for (var eType in int_objTypes) {
                var objType = int_objTypes[eType];
                if (sType === "application/" + objType) {
                    int_objs[objType] = oipfPluginObject;
                    if (objType === "oipfApplicationManager") {
                        console.log("re-using user-defined oipfApplicationManager");
                        mixin(window.oipfApplicationManager, int_objs[objType]);
                        break;
                    } else if (objType === "oipfConfiguration") {
                        console.log("re-using user-defined oipfConfiguration");
                        mixin(window.oipfConfiguration, int_objs[objType]);
                        break;
                    } else if (objType === "oipfCapabilities") {
                        console.log("re-using user-defined oipfCapabilities");
                        mixin(window.oipfCapabilities, int_objs[objType]);
                        break;
                    }
                }
            }
            if (sType.indexOf("video/") !== -1) {
                if (sType === "video/broadcast") {
                    console.log("re-using user-defined video object");
                    window.oipf.videoObject = oipfPluginObject;
                    var currentChannel = {
                        'TYPE_TV': 12,
                        'channelType': 12,
                        'sid': 1,
                        'onid': 1,
                        'tsid': 1,
                        'name': 'test'
                    };
                    oipfPluginObject.currentChannel = currentChannel;
                    oipfPluginObject.bindToCurrentChannel = function() {
                        return currentChannel;
                    };
                } else if (sType === "video/mp4" || sType === "video/mpeg4") {
                    window.oipf.videoObject = oipfPluginObject;
                    oipfPluginObject.play = function (speed) {
                    };

                }
            }
        }
    })(window.document);

    console.log("DOM HbbTV emulator added.");
}
<|endoftext|>


<commit_before>var settings = require('../settings'),
    mongoose = require('mongoose')

mongoose.connect(settings.dbUrl)

var Book = new mongoose.Schema({
    title: String,
    author: String,
    releaseDate: Date,
    keywords: String
})

var BookModel = mongoose.model('Book', Book)

module.exports = function (app) {

    //Page routes
    app.get('/', function (req, res) {
        //
    })

    //RESTful API routes
    app.get('/api', function (req, res) {
        res.send('API is running.')
    })

    app.get('/api/books', function (req, res) {
        BookModel.find(function (err, books) {
            if (err) return next(err)
            res.send(books)
        })
    })

    app.post('/api/books', function (req, res) {
        var book = new BookModel({
            title: req.body.title,
            author: req.body.author,
            releaseDate: req.body.releaseDate,
            keywords: req.body.keywords
        })
        book.save(function (err) {
            if (err) return next(err)
            res.send(book)
        })
    })

    app.get('/api/books/:id', function (req, res) {
        BookModel.findById(req.params.id, function (err, book) {
            if (err) return next(err)
            res.send(book)
        })
    })

    app.put('/api/books/:id', function (req, res) {
        BookModel.findById(req.params.id, function (err, book) {
            book.title = req.body.title
            book.author = req.body.author
            book.releaseDate = req.boyd.releaseDate
            book.keywords = req.body.keywords
            book.save(function (err) {
                if (err) return next(err)
                res.send(book)
            })
        })
    })

    app.del('/api/books/:id', function (req, res) {
        BookModel.findById(req.params.id, function (err, book) {
            book.remove(function (err) {
                if (err) return next(err)
                res.send('')
            })
        })
    })

    app.all('*', function (req, res) {
        res.end('404')
    })

}
<commit_msg>update<commit_after>var settings = require('../settings'),
    mongoose = require('mongoose')

mongoose.connect(settings.dbUrl)

var Book = new mongoose.Schema({
    title: String,
    author: String,
    releaseDate: Date,
    keywords: String
})

var BookModel = mongoose.model('Book', Book)

module.exports = function (app) {

    //Page routes
    app.get('/', function (req, res) {
        //
    })

    //RESTful API routes
    app.get('/api', function (req, res) {
        res.send('API is running.')
    })

    app.get('/api/books', function (req, res) {
        BookModel.find(function (err, books) {
            if (err) return next(err)
            res.send(books)
        })
    })

    app.post('/api/books', function (req, res) {
        var book = new BookModel({
            title: req.body.title,
            author: req.body.author,
            releaseDate: req.body.releaseDate,
            keywords: req.body.keywords
        })
        book.save(function (err) {
            if (err) return next(err)
            res.send(book)
        })
    })

    app.get('/api/books/:id', function (req, res) {
        BookModel.findById(req.params.id, function (err, book) {
            if (err) return next(err)
            res.send(book)
        })
    })

    app.put('/api/books/:id', function (req, res) {
        BookModel.findById(req.params.id, function (err, book) {
            book.title = req.body.title
            book.author = req.body.author
            book.releaseDate = req.boyd.releaseDate
            book.keywords = req.body.keywords
            book.save(function (err) {
                if (err) return next(err)
                res.send(book)
            })
        })
    })

    app.del('/api/books/:id', function (req, res) {
        BookModel.findById(req.params.id, function (err, book) {
            book.remove(function (err) {
                if (err) return next(err)
                res.send('')
            })
        })
    })

}
<|endoftext|>


<commit_before>var _ = require('lodash')
var inherits = require('inherits')
var aabb = require('aabb-2d')
var math = require('mathjs')
var transform = require('./transform.js')
var circle = require('./geo/circle.js')
var Collision = require('./collision.js')
var Automove = require('./automove.js')
var Freemove = require('./freemove.js')
var Entity = require('crtrdg-entity')

module.exports = Player;
inherits(Player, Entity);

function Player(opts){
  this.geometry = circle({
    position: opts.position,
    angle: opts.angle,
    fill: opts.fill,
    stroke: opts.stroke,
    scale: opts.scale,
    thickness: opts.thickness,
    children: [
      circle({fill: opts.fill, stroke: opts.stroke, thickness: opts.thickness,
        position: [-0.7, -.9], scale: 0.6, angle: -45, aspect: 0.6}),
      circle({fill: opts.fill, stroke: opts.stroke, thickness: opts.thickness,
        position: [0.7, -.9], scale: 0.6, angle: 45, aspect: 0.6})
    ]
  })
  this.movement = {}
  this.movement.tile = new Automove({
    keymap: ['Q', 'W', 'E', 'A', 'S', 'D'],
    heading: [-60, 0, 60, -120, -180, 120],
    shift: 8
  })
  this.movement.path = new Automove({
    keymap: ['S'],
    heading: [-180],
    shift: 8
  })
  this.collision = new Collision()
}

Player.prototype.move = function(keyboard, world) {
  var self = this

  var current = self.geometry.transform
  var tile = world.tiles[world.locate(self.position())]
  var inside =  tile.children[0].contains(current.position())

  var delta
  if (inside) {
    delta = self.movement.tile.compute(keyboard.keysDown, current, tile.transform)
  } else {
    delta = self.movement.path.compute(keyboard.keysDown, current)
  }

  self.geometry.update(delta)
  self.collision.handle(world, self.geometry, delta)
}

Player.prototype.draw = function(context, camera) {
  this.geometry.draw(context, camera, {order: 'bottom'})
}

Player.prototype.position = function() {
  return this.geometry.transform.position()
}

Player.prototype.angle = function() {
  return this.geometry.transform.angle()
}

Player.prototype.scale = function() {
  return this.geometry.transform.scale()
}
<commit_msg>Use default shift<commit_after>var _ = require('lodash')
var inherits = require('inherits')
var aabb = require('aabb-2d')
var math = require('mathjs')
var transform = require('./transform.js')
var circle = require('./geo/circle.js')
var Collision = require('./collision.js')
var Automove = require('./automove.js')
var Freemove = require('./freemove.js')
var Entity = require('crtrdg-entity')

module.exports = Player;
inherits(Player, Entity);

function Player(opts){
  this.geometry = circle({
    position: opts.position,
    angle: opts.angle,
    fill: opts.fill,
    stroke: opts.stroke,
    scale: opts.scale,
    thickness: opts.thickness,
    children: [
      circle({fill: opts.fill, stroke: opts.stroke, thickness: opts.thickness,
        position: [-0.7, -.9], scale: 0.6, angle: -45, aspect: 0.6}),
      circle({fill: opts.fill, stroke: opts.stroke, thickness: opts.thickness,
        position: [0.7, -.9], scale: 0.6, angle: 45, aspect: 0.6})
    ]
  })
  this.movement = {}
  this.movement.tile = new Automove({
    keymap: ['Q', 'W', 'E', 'A', 'S', 'D'],
    heading: [-60, 0, 60, -120, -180, 120],
    shift: 8
  })
  this.movement.path = new Automove({
    keymap: ['S'],
    heading: [-180]
  })
  this.collision = new Collision()
}

Player.prototype.move = function(keyboard, world) {
  var self = this

  var current = self.geometry.transform
  var tile = world.tiles[world.locate(self.position())]
  var inside =  tile.children[0].contains(current.position())

  var delta
  if (inside) {
    delta = self.movement.tile.compute(keyboard.keysDown, current, tile.transform)
  } else {
    delta = self.movement.path.compute(keyboard.keysDown, current)
  }

  self.geometry.update(delta)
  self.collision.handle(world, self.geometry, delta)
}

Player.prototype.draw = function(context, camera) {
  this.geometry.draw(context, camera, {order: 'bottom'})
}

Player.prototype.position = function() {
  return this.geometry.transform.position()
}

Player.prototype.angle = function() {
  return this.geometry.transform.angle()
}

Player.prototype.scale = function() {
  return this.geometry.transform.scale()
}
<|endoftext|>


<commit_before>//Import dependencies
var gulp = require('gulp');
var sass = require('gulp-sass');

//Compile the scss files and generate the css files
var docsCss = function()
{
  //Get the scss files
  gulp.src('./docs/scss/**.scss')

  //Build the scss files
  .pipe(sass({ includePaths: [ 'bower_components', 'node_modules' ] }).on('error', sass.logError))

  //Save in the dist/css folder
  .pipe(gulp.dest('./docs/build/css/'));
};

//Copy the assets and other files
var docsCopy = function()
{
  //Copy the html files
  gulp.src(['./docs/**.html'], { base: './docs' }).pipe(gulp.dest('./docs/build/'));

  //Copy the yaml files
  gulp.src(['./docs/app.yaml']).pipe(gulp.dest('./docs/build/'));

  //Copy the javascript files
  //gulp.src('./src/js/*.js').pipe(gulp.dest('./dist/js'));

  //Copy media images
  gulp.src('./media/logo.png').pipe(gulp.dest('./docs/build/images/'));

  //Copy the siimple modules
  gulp.src('./bower_components/siimple/dist/siimple.css').pipe(gulp.dest('./docs/build/css'));
  gulp.src('./dist/siimple-colors.css').pipe(gulp.dest('./docs/build/css'));
};

//Build the css files
docsCss();

//Copy the intermediary files
docsCopy();
<commit_msg>Removed unused<commit_after><|endoftext|>


<commit_before>// helper.js
//
// a collection of helper and convenience functions for PickSix

(function() {

  /** Array Extensions **/

  // Array Remove - By John Resig (MIT Licensed)
  // http://ejohn.org/blog/javascript-array-remove/
  Array.prototype.remove = function(from, to) {
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
  };

  // Array Remove Item
  // http://davidwalsh.name/remove-item-array-javascript
  Array.prototype.removeItem = function(item) {
    var index = this.indexOf(item);
    if( index != -1 ) {
      this.splice(index, -1);
    }
  };

  /** end of Array Extensions **/

})();
<commit_msg>Update the implementation of the removeItem function.<commit_after>// helper.js
//
// a collection of helper and convenience functions for PickSix

(function() {

  /** Array Extensions **/

  // Array Remove - By John Resig (MIT Licensed)
  // http://ejohn.org/blog/javascript-array-remove/
  Array.prototype.remove = function(from, to) {
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
  };

  // Array Remove Item
  // http://davidwalsh.name/remove-item-array-javascript
  Array.prototype.removeItem = function(item) {
    var index = this.indexOf(item);
    if( index !== -1 ) {
      this.splice(index, 1);
    }
  };

  /** end of Array Extensions **/

})();
<|endoftext|>


<commit_before><commit_msg>Set default role to user for new person creation<commit_after><|endoftext|>


<commit_before>let Vue = require('vue/dist/vue.js')
let Store = require('store')
let Client = require('electron-rpc/client')
let client = new Client()

Vue.filter('time', function (value) {
  if (isNaN(value)) {
    return 'N/A'
  }

  if (!isFinite(value)) {
    return 'Live stream'
  }

  var d = Number(value)
  var h = Math.floor(d / 3600)
  var m = Math.floor(d % 3600 / 60)
  var s = Math.floor(d % 3600 % 60)
  return ((h > 0 ? h + ':' + (m < 10 ? '0' : '') : '') + m + ':' + (s < 10 ? '0' : '') + s)
})

var Player = Vue.component('player', {
  props: ['source'],
  template: '<audio id="player" v-bind:src="source.stream" controls autoplay></audio>'
})

// FIXME: Add loading animation: http://www.alessioatzeni.com/blog/css3-loading-animation-loop/
var Controls = Vue.component('controls', {
  props: ['playing'],
  computed: {
    stream: function () {
      var stream = this.source ? this.source.stream : ''
      console.log('Stream is: ', stream)
      return stream
    },

    label: function () {
      return this.playing ? 'Pause' : 'Play'
    }
  },

  /* eslint-disable rule-name */
  template: `

        skip_previous

        pause
        play_arrow

        skip_next

  `
})

/* eslint no-underscore-dangle: ["error", { "allow": ["_this"] }]*/
var vm = new Vue({
  el: '#app',

  data: {
    app: new Framework7(),
    current: { title: 'Paused', stream: '' },
    defaultCover: './images/cover.jpg',
    lastFmCover: true,
    playing: false,
    debug: true,
    index: 0,
    progress: 0,
    position: 0,
    duration: 0,
    muted: false,
    volume: 0.5,
    loading: false,
    loadingPlaylist: null,
    sources: [],
    playlist: [

      // { title: 'Stream 1', stream: 'http://tinyurl.com/jfdsl7s' },
      // { title: 'Stream 2', stream: 'http://tinyurl.com/jj4tysv' }
      // { title: 'UFO Takeoff', stream: 'http://soundbible.com/mp3/UFO_Takeoff-Sonidor-1604321570.mp3' },
      // { title: 'UFO Landing', stream: 'http://soundbible.com/mp3/descending_craft-Sonidor-991848481.mp3' }

    ]
  },

  computed: {
    cover() {
      return this.current.image ? this.current.image : this.defaultCover
    },

    firstItemInPlaylist() {
      return this.index === 0
    },

    lastItemInPlaylist() {
      return (this.index === this.playlist.length - 1)
    }
  },

  mounted: function () {
    let _this = this
    if(!this.debug) {
      console.log = function() {}
    }

    // FIXME: Move to function
    client.request('sources')
    this.setVolume(this.volume)

    if(this.playlist.length) {
      this.autoplay()
    } else {
      console.log('No playlist items, check last played playlist and load')
      setTimeout(function() {
        _this.loadLastPlaylist()
      }, 500)
    }

    $('body').keydown(function (e) {
      if (e.keyCode === 32) {
        _this.toggle()
      }
    })

    client.on('sources', function (err, response) {
      console.log('on source')
      _this.sources = response.sources
    })

    client.on('show', function (err, response) {
      console.log('on show')
      _this.app.closeModal('.popup-sources')
      _this.loadingPlaylist = null
      _this.loading = false

      _this.app.addNotification({
        message: response.playlist.length + ' items added to playlist!'
      })

      setTimeout(function () {
        _this.app.closeNotification('.notifications')
      }, 2000)

      _this.playlist = response.playlist
      _this.autoplay()
    })

    client.on('cover', function (err, response) {
      console.warn('*** Got cover image', response.image)
      _this.lastFmCover = !!response.image

      if (_this.lastFmCover) {
        Vue.set(_this.current, 'image', response.image)
      } else {
        console.warn('No cover image found!')
        // Vue.set(_this.current, 'skipImage', true)
      }
    })

    $('#player').on('play', function () {
      console.log('*** Playback started', _this.current.title)
      _this.loading = false
      _this.playing = true
      if (_this.current.track && _this.current.artist) {
        console.log('Request image from LastfmAPI for', _this.current.track, _this.current.artist)
        setTimeout(function () {
          var params = { track: _this.current.track, artist: _this.current.artist }
          client.request('cover', params)
        }, 2000)
      }
    })

    var $progressbar = $('.progressbar')
    $('#player').on('timeupdate', function () {
      _this.position = Math.floor(this.currentTime)
      _this.duration = Math.floor(this.duration)

      var progress = (_this.position * 100) / _this.duration
      _this.app.setProgressbar($progressbar, progress)
    })

    $('#player').on('ended', function () {
      _this.next()
    })
  },

  watch: {
    volume: function (val) {
      this.setVolume(val)
    }
  },

  methods: {
    autoplay: function () {
      if(this.playlist.length) {
        this.index = 0
        this.current = this.playlist[this.index]
        this.playing = true
      }
    },

    toggle: function () {
      if (this.playing) {
        this.pause()
      } else {
        this.resume()
      }
    },

    play: function (index) {
      var _this = this
      console.log('Play', index)

      var $player = $('#player')
      _this.current = _this.playlist[index]

      $player.trigger('pause')

      setTimeout(function () {
        $player.trigger('play')
        _this.playing = true
      }, 200)
    },

    mute() {
      this.muted = true
      this.volume = 0
    },

    umute() {
      this.muted = false
      this.volume = 0.5
    },

    setVolume(value) {
      this.muted = !value
      $('#player')[0].volume = value
    },

    resume: function () {
      console.log('Resume')
      $('#player').trigger('play')
      this.playing = true
    },

    pause: function () {
      console.log('Pause')
      $('#player').trigger('pause')
      this.playing = false
    },

    // FIXME: Refactor prev and next methods
    prev: function () {
      this.index = (this.index - 1) < 0 ? 0 : (this.index - 1)
      this.current = this.playlist[this.index]
      this.loading = true
      console.log('Previous', this.index, this.current.title)
    },

    // FIXME: Refactor prev and next methods
    next: function () {
      console.log(this.index)
      console.log(this.playlist.length)
      this.nextIndex = this.index + 1
      this.lastTrack = (this.nextIndex >= this.playlist.length)

      if(this.lastTrack) {
        console.warn('Last track in playlist')
      } else {
        this.index = this.nextIndex
        this.current = this.playlist[this.index]
        this.loading = true
        console.log('Next', this.index, this.current.title)
      }
    },

    title: function (song) {
      console.log('Decorate title', song.title, song.artist)
      var name = song.artist ? (song.artist + ' - ' + song.title) : song.title
      console.log(name)
      return name
    },

    reload: function () {
      console.log('Reload')
      location.reload()
    },

    favorite: function () {
      console.log('Add/remove to/from favorites')
    },

    open: function () {
      client.request('open')
    },

    load: function (playlist, index) {
      console.log('load playlist', playlist)
      this.loadingPlaylist = index
      client.request('load', playlist)

      this.rememberLastPlaylist(playlist)
    },

    loadLastPlaylist() {
      console.log('find last playlist')
      this.app.popup('.popup-sources')

      let playlist = Store.get('playlist')

      if(playlist) {
        console.log('load last playlist', playlist)
        this.load(playlist, this.sources.indexOf(playlist))
      }
    },

    rememberLastPlaylist(playlist) {
      console.log('remember playlist', playlist)
      Store.set('playlist', playlist)
    },

    quit: function () {
      client.request('terminate')
    }
  },

  components: {
    player: Player,
    controls: Controls
  }
})
<commit_msg>Code improvements and aslant fixes<commit_after>const Vue = require('vue/dist/vue.js')
const Store = require('store')
const Client = require('electron-rpc/client')
const client = new Client()

Vue.filter('time', function (value) {
  if (isNaN(value)) {
    return 'N/A'
  }

  if (!isFinite(value)) {
    return 'Live stream'
  }

  var d = Number(value)
  var h = Math.floor(d / 3600)
  var m = Math.floor(d % 3600 / 60)
  var s = Math.floor(d % 3600 % 60)
  return ((h > 0 ? h + ':' + (m < 10 ? '0' : '') : '') + m + ':' + (s < 10 ? '0' : '') + s)
})

var Player = Vue.component('player', {
  props: ['source'],
  template: '<audio id="player" v-bind:src="source.stream" controls autoplay></audio>'
})

// FIXME: Add loading animation: http://www.alessioatzeni.com/blog/css3-loading-animation-loop/
var Controls = Vue.component('controls', {
  props: ['playing'],
  computed: {
    stream: function () {
      var stream = this.source ? this.source.stream : ''
      console.log('Stream is: ', stream)
      return stream
    },

    label: function () {
      return this.playing ? 'Pause' : 'Play'
    }
  },

  /* eslint-disable rule-name */
  template: `

        skip_previous

        pause
        play_arrow

        skip_next

  `
})

/* eslint no-underscore-dangle: ["error", { "allow": ["_this"] }]*/
var vm = new Vue({
  el: '#app',

  data: {
    app: new Framework7(),
    current: { title: 'Paused', stream: '' },
    defaultCover: './images/cover.jpg',
    lastFmCover: null,
    playing: false,
    debug: true,
    index: 0,
    progress: 0,
    position: 0,
    duration: 0,
    muted: false,
    volume: 0.5,
    loading: false,
    loadingPlaylist: null,
    sources: [],
    playlist: [

      // { title: 'Stream 1', stream: 'http://tinyurl.com/jfdsl7s' },
      // { title: 'Stream 2', stream: 'http://tinyurl.com/jj4tysv' }
      // { title: 'UFO Takeoff', stream: 'http://soundbible.com/mp3/UFO_Takeoff-Sonidor-1604321570.mp3' },
      // { title: 'UFO Landing', stream: 'http://soundbible.com/mp3/descending_craft-Sonidor-991848481.mp3' }

    ]
  },

  computed: {
    state () {
      if (this.loading) {
        return 'LOADING...'
      }

      if (!this.playing) {
        return 'PAUSED'
      }
    },

    background () {
      return { 'background-image': `url(${this.cover})` }
    },

    cover () {
      return this.current.image ? this.current.image : this.defaultCover
    },

    firstItemInPlaylist () {
      return this.index === 0
    },

    lastItemInPlaylist () {
      return (this.index === this.playlist.length - 1)
    }
  },

  mounted: function () {
    const _this = this
    if (!this.debug) {
      console.log = function () {}
    }

    // FIXME: Move to function
    client.request('sources')
    this.setVolume(this.volume)

    if (this.playlist.length) {
      this.autoplay()
    } else {
      console.log('No playlist items, check last played playlist and load')
      setTimeout(function () {
        _this.loadLastPlaylist()
      }, 500)
    }

    $('body').keydown(function (e) {
      if (e.keyCode === 32) {
        _this.toggle()
      }
    })

    client.on('sources', function (err, response) {
      console.log('on source')
      _this.sources = response.sources
    })

    client.on('show', function (err, response) {
      console.log('on show')
      _this.app.closeModal('.popup-sources')
      _this.loadingPlaylist = null
      _this.loading = false

      _this.app.addNotification({
        message: response.playlist.length + ' items added to playlist!'
      })

      setTimeout(function () {
        _this.app.closeNotification('.notifications')
      }, 2000)

      _this.playlist = response.playlist
      _this.autoplay()
    })

    client.on('cover', function (err, response) {
      console.warn('*** Got cover image', response.image)
      if (response.image) {
        Vue.set(_this.current, 'lastFmCover', response.image)
      } else {
        console.warn('No cover image found!')
        // Vue.set(_this.current, 'skipImage', true)
      }
    })

    $('#player').on('play', function () {
      console.log('*** Playback started', _this.current.title)
      _this.loading = false
      _this.playing = true
      if (_this.current.track && _this.current.artist) {
        console.log('Request image from LastfmAPI for', _this.current.track, _this.current.artist)
        setTimeout(function () {
          var params = { track: _this.current.track, artist: _this.current.artist }
          client.request('cover', params)
        }, 2000)
      }
    })

    var $progressbar = $('.progressbar')
    $('#player').on('timeupdate', function () {
      _this.position = Math.floor(this.currentTime)
      _this.duration = Math.floor(this.duration)

      var progress = (_this.position * 100) / _this.duration
      _this.app.setProgressbar($progressbar, progress)
    })

    $('#player').on('ended', function () {
      _this.next()
    })
  },

  watch: {
    volume: function (val) {
      this.setVolume(val)
    }
  },

  methods: {
    autoplay: function () {
      if (this.playlist.length) {
        this.index = 0
        this.current = this.playlist[this.index]
        this.playing = true
      }
    },

    toggle: function () {
      if (this.playing) {
        this.pause()
      } else {
        this.resume()
      }
    },

    play: function (index) {
      var _this = this
      console.log('Play', index)

      var $player = $('#player')
      _this.current = _this.playlist[index]

      $player.trigger('pause')

      setTimeout(function () {
        $player.trigger('play')
        _this.playing = true
      }, 200)
    },

    mute () {
      this.muted = true
      this.volume = 0
    },

    umute () {
      this.muted = false
      this.volume = 0.5
    },

    setVolume (value) {
      this.muted = !value
      $('#player')[0].volume = value
    },

    resume: function () {
      console.log('Resume')
      $('#player').trigger('play')
      this.playing = true
    },

    pause: function () {
      console.log('Pause')
      $('#player').trigger('pause')
      this.playing = false
    },

    // FIXME: Refactor prev and next methods
    prev: function () {
      this.index = (this.index - 1) < 0 ? 0 : (this.index - 1)
      this.current = this.playlist[this.index]
      this.loading = true
      console.log('Previous', this.index, this.current.title)
    },

    // FIXME: Refactor prev and next methods
    next: function () {
      console.log(this.index)
      console.log(this.playlist.length)
      this.nextIndex = this.index + 1
      this.lastTrack = (this.nextIndex >= this.playlist.length)

      if (this.lastTrack) {
        console.warn('Last track in playlist')
      } else {
        this.index = this.nextIndex
        this.current = this.playlist[this.index]
        this.loading = true
        console.log('Next', this.index, this.current.title)
      }
    },

    title: function (song) {
      console.log('Decorate title', song.title, song.artist)
      var name = song.artist ? (song.artist + ' - ' + song.title) : song.title
      console.log(name)
      return name
    },

    reload: function () {
      console.log('Reload')
      location.reload()
    },

    favorite: function () {
      console.log('Add/remove to/from favorites')
    },

    open: function () {
      client.request('open')
    },

    load: function (playlist, index) {
      console.log('load playlist', playlist)
      this.loadingPlaylist = index
      client.request('load', playlist)

      this.rememberLastPlaylist(playlist)
    },

    loadLastPlaylist () {
      console.log('find last playlist')
      this.app.popup('.popup-sources')

      const playlist = Store.get('playlist')

      if (playlist) {
        console.log('load last playlist', playlist)
        this.load(playlist, this.sources.indexOf(playlist))
      }
    },

    rememberLastPlaylist (playlist) {
      console.log('remember playlist', playlist)
      Store.set('playlist', playlist)
    },

    quit: function () {
      client.request('terminate')
    }
  },

  components: {
    player: Player,
    controls: Controls
  }
})
<|endoftext|>


<commit_before>/* jshint devel:true */
/* global saveAs, require, CodeMirror, alertify, cytoscape */

(function() {
  'use strict';

  var myCodeMirror = new CodeMirror(document.getElementById('editor'), {
    value: '{}',
    lineNumbers: true,
    mode: 'application/json',
    foldGutter: true,
    gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
    lint: {
      onUpdateLinting: function(annotations) {
        if (template && (!annotations || annotations.length === 0)) {
          template.refreshGraph();
        }
      }
    }
  });
  myCodeMirror.setSize('100%', '800px');
  var graphArea = $('#graph_area');
  var template = require('./template').template({
    'editor': myCodeMirror,
    'cytolib': cytoscape,
    'graphContainer': graphArea[0],
    'jsonproxy': $.jsonp
  });
  $.ajax({
    url: 'styles/main.cycss',
    type: 'GET',
    dataType: 'text',
    success: function(responseText) {
      template.changeStyle(responseText);
    }
  });
  var isResizing = false,
    lastDownX = 0;

  var remoteInput = $('#remote_input');

  var loadTemplate = function(loadFn, arg) {
    loadFn(
      arg,
      function(location) {
        graphArea.css('background-image', '');
        alertify.success('Loaded template "' + location + '" successfully');
      },
      function(name, reason) {
        alertify.error('Unable to load template "' + location + '" because of ' + reason);
      }
    );
  };

  var saveImage = function() {
    var saveWindow = window.open('savegraph.html');
    saveWindow.onload = function() {
      saveWindow.document.getElementById('graphPNG').src = template.base64Image();
    };
  };
  var saveTemplate = function() {
    var blob = new Blob([template.text(2)], {
      type: 'text/plain;charset=utf-8'
    });
    saveAs(blob, template.description() + '.json');
  };
  var mainRow = document.getElementById('graph_area');
  mainRow.addEventListener('dragover', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy';
  }, false);
  mainRow.addEventListener('drop', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    loadTemplate(template.load, evt.dataTransfer.files[0]);
  }, false);
  $('#graph_area').css('background-image', 'url("images/aws-cloudformation-template.svg")');
  $('#open_template').click(function(event) {
    event.preventDefault();
    $('#template_input').click();
  });
  $('#open_url').click(function(event) {
    event.preventDefault();
    if (remoteInput.is(':visible')) {
      loadTemplate(template.fromURLInput, remoteInput);
    }
    else {
      remoteInput.show();
    }
  });
  $('#template_input').change(function(event) {
    loadTemplate(template.load, event.target.files[0]);
  });
  $('#save_template').click(function(event) {
    event.preventDefault();
    saveTemplate();
    return false;
  });
  $('#save_graph').click(function(event) {
    event.preventDefault();
    saveImage();
    return false;
  });
  $('#graph_layout').change(function() {
    template.setLayout($('#graph_layout').val());
  });

  $('#remote_input').keypress(function(e) {
    if (e.which === 13) {
      loadTemplate(template.fromURLInput, remoteInput);
      return false;
    }
  });
  var container = $('#container'),
    left = $('#graph_area'),
    right = $('#editor_pane'),
    handle = $('#border');

  handle.on('mousedown', function(e) {
    isResizing = true;
    lastDownX = e.clientX;
  });

  $(document).on('mousemove', function(e) {
    // we don't want to do anything if we aren't resizing.
    if (!isResizing) {
      return;
    }

    var offsetRight = container.width() - (e.clientX - container.offset().left);

    left.css('right', offsetRight);
    right.css('width', offsetRight);
  }).on('mouseup', function() {
    if (isResizing) {
      template.fitGraph();
    }
    // stop resizing
    isResizing = false;
  });
})();
<commit_msg>Remove mainRow because equal to graphArea<commit_after>/* jshint devel:true */
/* global saveAs, require, CodeMirror, alertify, cytoscape */

(function() {
  'use strict';

  var myCodeMirror = new CodeMirror(document.getElementById('editor'), {
    value: '{}',
    lineNumbers: true,
    mode: 'application/json',
    foldGutter: true,
    gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
    lint: {
      onUpdateLinting: function(annotations) {
        if (template && (!annotations || annotations.length === 0)) {
          template.refreshGraph();
        }
      }
    }
  });
  myCodeMirror.setSize('100%', '800px');

  var graphArea = $('#graph_area');

  graphArea.css('background-image', 'url("images/aws-cloudformation-template.svg")');
  graphArea[0].addEventListener('dragover', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy';
  }, false);
  graphArea[0].addEventListener('drop', function(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    loadTemplate(template.load, evt.dataTransfer.files[0]);
  }, false);

  var template = require('./template').template({
    'editor': myCodeMirror,
    'cytolib': cytoscape,
    'graphContainer': graphArea[0],
    'jsonproxy': $.jsonp
  });
  $.ajax({
    url: 'styles/main.cycss',
    type: 'GET',
    dataType: 'text',
    success: function(responseText) {
      template.changeStyle(responseText);
    }
  });
  var isResizing = false,
    lastDownX = 0;

  var remoteInput = $('#remote_input');

  var loadTemplate = function(loadFn, arg) {
    loadFn(
      arg,
      function(location) {
        graphArea.css('background-image', '');
        alertify.success('Loaded template "' + location + '" successfully');
      },
      function(name, reason) {
        alertify.error('Unable to load template "' + location + '" because of ' + reason);
      }
    );
  };

  var saveImage = function() {
    var saveWindow = window.open('savegraph.html');
    saveWindow.onload = function() {
      saveWindow.document.getElementById('graphPNG').src = template.base64Image();
    };
  };
  var saveTemplate = function() {
    var blob = new Blob([template.text(2)], {
      type: 'text/plain;charset=utf-8'
    });
    saveAs(blob, template.description() + '.json');
  };
  $('#open_template').click(function(event) {
    event.preventDefault();
    $('#template_input').click();
  });
  $('#open_url').click(function(event) {
    event.preventDefault();
    if (remoteInput.is(':visible')) {
      loadTemplate(template.fromURLInput, remoteInput);
    }
    else {
      remoteInput.show();
    }
  });
  $('#template_input').change(function(event) {
    loadTemplate(template.load, event.target.files[0]);
  });
  $('#save_template').click(function(event) {
    event.preventDefault();
    saveTemplate();
    return false;
  });
  $('#save_graph').click(function(event) {
    event.preventDefault();
    saveImage();
    return false;
  });
  $('#graph_layout').change(function() {
    template.setLayout($('#graph_layout').val());
  });

  $('#remote_input').keypress(function(e) {
    if (e.which === 13) {
      loadTemplate(template.fromURLInput, remoteInput);
      return false;
    }
  });
  var container = $('#container'),
    left = $('#graph_area'),
    right = $('#editor_pane'),
    handle = $('#border');

  handle.on('mousedown', function(e) {
    isResizing = true;
    lastDownX = e.clientX;
  });

  $(document).on('mousemove', function(e) {
    // we don't want to do anything if we aren't resizing.
    if (!isResizing) {
      return;
    }

    var offsetRight = container.width() - (e.clientX - container.offset().left);

    left.css('right', offsetRight);
    right.css('width', offsetRight);
  }).on('mouseup', function() {
    if (isResizing) {
      template.fitGraph();
    }
    // stop resizing
    isResizing = false;
  });
})();
<|endoftext|>