<commit_before>// Stopgap atom.js file for handling normal browser things that atom
// does not yet have stable from the browser-side API.
// - Opening external links in default web browser
// - Saving files/downloads to disk
$(document).ready(function() {
    if (typeof process === 'undefined') return;
    if (typeof process.versions['atom-shell'] === undefined) return;

    var remote = require('remote');
    var shell = require('shell');
    var http = require('http');
    var url = require('url');
    var fs = require('fs');
    var path = require('path');
    var dialog = remote.require('dialog');

    $('body').on('click', 'a', function(ev) {
        var uri = url.parse(ev.currentTarget.href);

        // Opening external URLs.
        if (uri.hostname && uri.hostname !== 'localhost') {
            shell.openExternal(ev.currentTarget.href);
            return false;
        }

        // File saving.
        var fileTypes = {
            tm2z: 'Package',
            mbtiles: 'Tiles',
            png: 'Image',
            jpg: 'Image',
            jpeg: 'Image'
        }
        var typeExtension = (uri.pathname || '').split('.').pop().toLowerCase();
        var typeLabel = fileTypes[typeExtension];
        if (typeLabel) {
            // HOME is undefined on windows
            if (process.platform === 'win32') process.env.HOME = process.env.USERPROFILE;
            var defaultPath = path.join(process.env.HOME,'Untitled ' + typeLabel + '.' + typeExtension);
            dialog.showSaveDialog({
                title: 'Save ' + typeLabel,
                defaultPath: defaultPath,
                filters: [{ name: typeExtension.toUpperCase(), extensions: [typeExtension]}]
            }, function(filePath){
                if (!filePath) return error(new Error('No filepath specified'));

                window.Modal.show('atomexporting');

                uri.method = 'GET';
                try {
                    var writeStream = fs.createWriteStream(filePath);
                } catch(err) {
                    return error(err);
                }

                fs.writeFileSync(filePath, 'asdfasdf');

                var req = http.request(uri, function(res) {
                    if (res.statusCode !== 200) return error(new Error('Got HTTP code ' + res.statusCode));
                    res.on('error', error);
                    writeStream.on('error', error);
                    res.pipe(writeStream).on('finish', function() {
                        window.Modal.close();
                    });
                });
                req.on('error', error);
                req.end();

                function error(err) {
                    window.Modal.close();
                    window.Modal.show('err', err);
                    return false;
                }

                return false;
            });
            return false;
        }
        // Passthrough everything else.
    });

    if (window.Modal) {
        window.Modal.options.templates.modalatomexporting = function() {
            return "\

\

Exporting
\

\

";
        };
    }
});
<commit_msg>fs, http need to be remote modules.<commit_after>// Stopgap atom.js file for handling normal browser things that atom
// does not yet have stable from the browser-side API.
// - Opening external links in default web browser
// - Saving files/downloads to disk
$(document).ready(function() {
    if (typeof process === 'undefined') return;
    if (typeof process.versions['atom-shell'] === undefined) return;

    var remote = require('remote');
    var shell = require('shell');
    var url = require('url');
    var path = require('path');
    var fs = remote.require('fs');
    var http = remote.require('http');
    var dialog = remote.require('dialog');

    $('body').on('click', 'a', function(ev) {
        var uri = url.parse(ev.currentTarget.href);

        // Opening external URLs.
        if (uri.hostname && uri.hostname !== 'localhost') {
            shell.openExternal(ev.currentTarget.href);
            return false;
        }

        // File saving.
        var fileTypes = {
            tm2z: 'Package',
            mbtiles: 'Tiles',
            png: 'Image',
            jpg: 'Image',
            jpeg: 'Image'
        }
        var typeExtension = (uri.pathname || '').split('.').pop().toLowerCase();
        var typeLabel = fileTypes[typeExtension];
        if (typeLabel) {
            // HOME is undefined on windows
            if (process.platform === 'win32') process.env.HOME = process.env.USERPROFILE;
            var defaultPath = path.join(process.env.HOME,'Untitled ' + typeLabel + '.' + typeExtension);
            dialog.showSaveDialog({
                title: 'Save ' + typeLabel,
                defaultPath: defaultPath,
                filters: [{ name: typeExtension.toUpperCase(), extensions: [typeExtension]}]
            }, function(filePath){
                if (!filePath) return error(new Error('No filepath specified'));

                window.Modal.show('atomexporting');

                try {
                    var writeStream = fs.createWriteStream(filePath);
                } catch(err) {
                    return error(err);
                }

                uri.method = 'GET';
                var req = http.request(uri, function(res) {
                    if (res.statusCode !== 200) return error(new Error('Got HTTP code ' + res.statusCode));
                    res.on('error', error);
                    writeStream.on('error', error);
                    res.pipe(writeStream).on('finish', function() {
                        window.Modal.close();
                    });
                });
                req.on('error', error);
                req.end();

                function error(err) {
                    window.Modal.close();
                    window.Modal.show('err', err);
                    return false;
                }

                return false;
            });
            return false;
        }
        // Passthrough everything else.
    });

    if (window.Modal) {
        window.Modal.options.templates.modalatomexporting = function() {
            return "\

\

Exporting
\

\

";
        };
    }
});
<|endoftext|>


<commit_before>window.name = 'NG_DEFER_BOOTSTRAP!';

require.config({
    waitSeconds: 120,
    baseUrl : '/app',
    paths: {
      'authentication'   : 'services/authentication',
      'angular'          : 'libs/angular-flex/angular-flex',
      'ngRoute'          : 'libs/angular-route/angular-route.min',
      'ngSanitize'       : 'libs/angular-sanitize/angular-sanitize.min',
      'domReady'         : 'libs/requirejs-domready/domReady',
      'text'             : 'libs/requirejs-text/text',
      'bootstrap'        : 'libs/bootstrap/dist/js/bootstrap.min',
      'lodash'           : 'libs/lodash/lodash.min',
      'URIjs'            : 'libs/uri.js/src',
      'linqjs'           : 'libs/linqjs/linq.min',
      'leaflet'          : 'libs/leaflet/dist/leaflet',
      'jquery'           : 'libs/jquery/dist/jquery.min',
      'moment'           : 'libs/moment/moment',
      'leaflet-directive': 'js/libs/leaflet/angular-leaflet-directive',
      'ng-breadcrumbs'   : 'libs/ng-breadcrumbs/dist/ng-breadcrumbs.min',
      'bootstrap-datepicker': 'libs/bootstrap-datepicker/js/bootstrap-datepicker',
      'ionsound'         : 'libs/ionsound/js/ion.sound.min',
      'jqvmap'           : 'js/libs/jqvmap/jqvmap/jquery.vmap',
      'jqvmapworld'      : 'js/libs/jqvmap/jqvmap/maps/jquery.vmap.world',
      'ngAnimate'        : 'libs/angular-animate/angular-animate.min',
      'ngAria'           : 'libs/angular-aria/angular-aria.min',
      'ngMaterial'       : 'libs/angular-material/angular-material.min',
      'ngSmoothScroll'   : 'libs/ngSmoothScroll/angular-smooth-scroll.min',
      'ammap3WorldLow'   : 'libs/ammap3/ammap/maps/js/worldLow',
      'ammap3'           : 'libs/ammap3/ammap/ammap',
      'ammap-theme'      : 'libs/ammap3/ammap/themes/light',
      // "ammap-resp"       : 'libs/ammap3/ammap/plugins/responsive/responsive',

    },
    shim: {
      'libs/angular/angular'     : { deps: ['jquery'] },
      'angular'                  : { deps: ['libs/angular/angular'] },
      'ngRoute'                  : { deps: ['angular'] },
      'ngSanitize'               : { deps: ['angular'] },
      'leaflet-directive'        : { deps: ['angular', 'leaflet'], exports : 'L' },
      'ng-breadcrumbs'           : { deps: ['angular'] },
      'bootstrap'                : { deps: ['jquery'] },
      'linqjs'                   : { deps: [], exports : 'Enumerable' },
      'leaflet'                  : { deps: [], exports : 'L' },
      'bootstrap-datepicker'     : { deps: ['bootstrap'] },
      'jqvmap'                   : { deps: ['jquery'] },
      'jqvmapworld'              : { deps: ['jqvmap'] },
      'ionsound'                 : { deps: ['jquery'] },
      'ngAnimate'                : { deps: ['angular'] },
      'ngAria'                   : { deps: ['angular'] },
      'ngMaterial'               : { deps: ['angular', 'ngAnimate', 'ngAria'] },
      'ngSmoothScroll'           : { deps: ['angular'] },
      'ammap3WorldLow'           : { deps: ['ammap3'] },
      'ammap-theme'              : { deps: ['ammap3']},
      // "ammap-resp"               : { deps: ['ammap3']}
    },
});

// BOOT

require(['angular', 'domReady!', 'bootstrap', 'app', 'routes', 'index'], function(ng, doc){

    ng.bootstrap(doc, ['kmApp']);
    ng.resumeBootstrap();

});
<commit_msg>Turning on responsiveness on map after resolving version issues<commit_after>window.name = 'NG_DEFER_BOOTSTRAP!';

require.config({
    waitSeconds: 120,
    baseUrl : '/app',
    paths: {
      'authentication'   : 'services/authentication',
      'angular'          : 'libs/angular-flex/angular-flex',
      'ngRoute'          : 'libs/angular-route/angular-route.min',
      'ngSanitize'       : 'libs/angular-sanitize/angular-sanitize.min',
      'domReady'         : 'libs/requirejs-domready/domReady',
      'text'             : 'libs/requirejs-text/text',
      'bootstrap'        : 'libs/bootstrap/dist/js/bootstrap.min',
      'lodash'           : 'libs/lodash/lodash.min',
      'URIjs'            : 'libs/uri.js/src',
      'linqjs'           : 'libs/linqjs/linq.min',
      'leaflet'          : 'libs/leaflet/dist/leaflet',
      'jquery'           : 'libs/jquery/dist/jquery.min',
      'moment'           : 'libs/moment/moment',
      'leaflet-directive': 'js/libs/leaflet/angular-leaflet-directive',
      'ng-breadcrumbs'   : 'libs/ng-breadcrumbs/dist/ng-breadcrumbs.min',
      'bootstrap-datepicker': 'libs/bootstrap-datepicker/js/bootstrap-datepicker',
      'ionsound'         : 'libs/ionsound/js/ion.sound.min',
      'jqvmap'           : 'js/libs/jqvmap/jqvmap/jquery.vmap',
      'jqvmapworld'      : 'js/libs/jqvmap/jqvmap/maps/jquery.vmap.world',
      'ngAnimate'        : 'libs/angular-animate/angular-animate.min',
      'ngAria'           : 'libs/angular-aria/angular-aria.min',
      'ngMaterial'       : 'libs/angular-material/angular-material.min',
      'ngSmoothScroll'   : 'libs/ngSmoothScroll/angular-smooth-scroll.min',
      'ammap3WorldLow'   : 'libs/ammap3/ammap/maps/js/worldLow',
      'ammap3'           : 'libs/ammap3/ammap/ammap',
      'ammap-theme'      : 'libs/ammap3/ammap/themes/light',
      // "ammap-resp"       : 'libs/ammap3/ammap/plugins/responsive/responsive',

    },
    shim: {
      'libs/angular/angular'     : { deps: ['jquery'] },
      'angular'                  : { deps: ['libs/angular/angular'] },
      'ngRoute'                  : { deps: ['angular'] },
      'ngSanitize'               : { deps: ['angular'] },
      'leaflet-directive'        : { deps: ['angular', 'leaflet'], exports : 'L' },
      'ng-breadcrumbs'           : { deps: ['angular'] },
      'bootstrap'                : { deps: ['jquery'] },
      'linqjs'                   : { deps: [], exports : 'Enumerable' },
      'leaflet'                  : { deps: [], exports : 'L' },
      'bootstrap-datepicker'     : { deps: ['bootstrap'] },
      'jqvmap'                   : { deps: ['jquery'] },
      'jqvmapworld'              : { deps: ['jqvmap'] },
      'ionsound'                 : { deps: ['jquery'] },
      'ngAnimate'                : { deps: ['angular'] },
      'ngAria'                   : { deps: ['angular'] },
      'ngMaterial'               : { deps: ['angular', 'ngAnimate', 'ngAria'] },
      'ngSmoothScroll'           : { deps: ['angular'] },
      'ammap3WorldLow'           : { deps: ['ammap3'] },
      'ammap-theme'              : { deps: ['ammap3']},
      'ammap-resp'               : { deps: ['ammap3']}
    },
});

// BOOT

require(['angular', 'domReady!', 'bootstrap', 'app', 'routes', 'index'], function(ng, doc){

    ng.bootstrap(doc, ['kmApp']);
    ng.resumeBootstrap();

});
<|endoftext|>


<commit_before>
$('.play').click(checkForWin)
//array for player clicks
 let player1 = [0, 3, 6]
 let player2 = []

const xImage = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/black-ink-grunge-stamps-textures-icons-alphanumeric/068726-black-ink-grunge-stamp-textures-icon-alphanumeric-x-solid.png"
const oImage ="http://www.drodd.com/images14/o25.png"
const emptySquare = "http://1.bp.blogspot.com/-jJUO43k6ReU/T7ivfcr4fgI/AAAAAAAAQqU/8YdJwPwT4OE/s1600/transparent.png"

//the game starts with player x
let currentPlayer = xImage

//on click of square,
  //setup click events
  $("td").click(changeSquare) //calls function to change image

function changeSquare(evt) {
  //resets the image of the clicked on square to new value
   let clickedSquare = evt.target
  //if the square is empty and the game is still going allow changes
   if(clickedSquare.src === emptySquare && gameover !== true) {
    //assign it a new image
    //changes image to the player's image
    clickedSquare.src = currentPlayer
    //switches turn to other player
    changePlayer();
   }
//checks for game win
}

//change player
function changePlayer() {
  //if the current player is x, flip to o, otherwise, flip to x
  if (currentPlayer === xImage) {
    //let the next marker be an o
    currentPlayer = oImage;
    //set the player div to O
    $(".playerMarker").html("
It is O's turn
")
  } else {
    //let the next marker be an x
    currentPlayer = xImage;
    //set the player div to X
    $(".playerMarker").html("
It is X's turn
")
  }
}

//will have to have a feed from firebase as input
function checkForWin() {

  var winCombinations = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6],
                           [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ];
  var winingIndex = -1;

  // if (winingIndex !== -1) {
  //   // announce winner
  // } else if (moves === 9 ) {
  //   // announce tie
  // } else {
  //   // switch player
  // }

    for (var i = 0; i < winCombinations.length; i++) {
      let matchesFound = 0;
      for (var j = 0; j < winCombinations[i].length; j++) {
        console.log(matchesFound);
        if ($.inArray(winCombinations[i][j], player1) !== -1) {

          matchesFound += 1;
          // console.log(winCombinations[i][j]);
        }
      }
      if (matchesFound === 3) {
        console.log('declare winner');
        announceGameEnd("win")
        break
      }
    }
}

    // console.log();
    // if (player1 === possibleWin) {
    //
    // } else {
    //
    // }
//as long as the game is still on, gameover = false
let gameover = false;

function announceGameEnd(message) {
  //set the gameover value to true
  gameover = true;
  //if the current player = x, x is winner, else o is winner
  let winner = (currentPlayer === xImage) ? "X" : "O"

  if(message === "win") {
    $(".playerMarker").html(`<h1>${winner} won!</h1>`)
  } else {
    $(".playerMarker").html(`<h1>It's a draw!</h1>`)
  }
}

function updateBoard(array, player) {
  //for each value in the array
 for(var i = 0; i < array.length; i++) {
      //assign the array's value at that position to a var
    let arrayValue = array[i];
    //display the correct image for the corresponding player
    let playerImage = player
    //write that image to the html img tag
    let imageSquare = `<img src=${xImage} width="150" height="150">`
     //update that square with the player's image
    $(`td[data-position=${arrayValue}]`).html(imageSquare)
  }

}

updateBoard(player1, "x")
<commit_msg>removed hard coding of xImage, now based on current player<commit_after>
$('.play').click(checkForWin)
//array for player clicks
 let player1 = [0, 3, 6]
 let player2 = []

const xImage = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/black-ink-grunge-stamps-textures-icons-alphanumeric/068726-black-ink-grunge-stamp-textures-icon-alphanumeric-x-solid.png"
const oImage ="http://www.drodd.com/images14/o25.png"
const emptySquare = "http://1.bp.blogspot.com/-jJUO43k6ReU/T7ivfcr4fgI/AAAAAAAAQqU/8YdJwPwT4OE/s1600/transparent.png"

//the game starts with player x
let currentPlayer = xImage

//on click of square,
  //setup click events
  $("td").click(changeSquare) //calls function to change image

function changeSquare(evt) {
  //resets the image of the clicked on square to new value
   let clickedSquare = evt.target
  //if the square is empty and the game is still going allow changes
   if(clickedSquare.src === emptySquare && gameover !== true) {
    //assign it a new image
    //changes image to the player's image
    clickedSquare.src = currentPlayer
    //switches turn to other player
    changePlayer();
   }
//checks for game win
}

//change player
function changePlayer() {
  //if the current player is x, flip to o, otherwise, flip to x
  if (currentPlayer === xImage) {
    //let the next marker be an o
    currentPlayer = oImage;
    //set the player div to O
    $(".playerMarker").html("
It is O's turn
")
  } else {
    //let the next marker be an x
    currentPlayer = xImage;
    //set the player div to X
    $(".playerMarker").html("
It is X's turn
")
  }
}

//will have to have a feed from firebase as input
function checkForWin() {

  var winCombinations = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6],
                           [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ];
  var winingIndex = -1;

  // if (winingIndex !== -1) {
  //   // announce winner
  // } else if (moves === 9 ) {
  //   // announce tie
  // } else {
  //   // switch player
  // }

    for (var i = 0; i < winCombinations.length; i++) {
      let matchesFound = 0;
      for (var j = 0; j < winCombinations[i].length; j++) {
        console.log(matchesFound);
        if ($.inArray(winCombinations[i][j], player1) !== -1) {

          matchesFound += 1;
          // console.log(winCombinations[i][j]);
        }
      }
      if (matchesFound === 3) {
        console.log('declare winner');
        announceGameEnd("win")
        break
      }
    }
}

    // console.log();
    // if (player1 === possibleWin) {
    //
    // } else {
    //
    // }
//as long as the game is still on, gameover = false
let gameover = false;

function announceGameEnd(message) {
  //set the gameover value to true
  gameover = true;
  //if the current player = x, x is winner, else o is winner
  let winner = (currentPlayer === xImage) ? "X" : "O"

  if(message === "win") {
    $(".playerMarker").html(`<h1>${winner} won!</h1>`)
  } else {
    $(".playerMarker").html(`<h1>It's a draw!</h1>`)
  }
}

function updateBoard(array, player) {
  //for each value in the array
 for(var i = 0; i < array.length; i++) {
      //assign the array's value at that position to a var
    let arrayValue = array[i];
    //display the correct image for the corresponding player
    let playerImage = player
    //write that image to the html img tag
    let imageSquare = `<img src=${playerImage} width="150" height="150">`
     //update that square with the player's image
    $(`td[data-position=${arrayValue}]`).html(imageSquare)
  }

}

updateBoard(player1, currentPlayer)
<|endoftext|>


<commit_before>//general problem : when vendors are managed in vendor folder, asset path throws err :(
var React = require('react');
var L = require('leaflet');
var $ = require('jquery');

var polyline = require('polyline');
require('react-leaflet');
require('leafletCss');
require('./main.css');

//should replace to tangram later
//var sceneYaml = require("file!./scene.yaml");

var ResultRow = React.createClass({
  handleClick: function(){
    var markers = [];
    var marker = L.marker(this.props.loc.reverse());
    marker.bindPopup(this.props.name);
    markers.push(marker);
    this.props.addMarker(markers);
    this.props.setInputValue(this.props.name);
    this.props.deactivateSearching();
  },
  render: function(){
    var displayName = this.props.name;
    return(

         {displayName}

    );
  }
});

var ResultTable = React.createClass({
  render: function(){
    var rows = [];
      if(this.props.searchData.length > 0 && this.props.searching ){
        var self = this;
        this.props.searchData.forEach(function(result){
          rows.push(<ResultRow name = {result.properties.name}
                               loc= {result.geometry.coordinates}
                               key= {result.properties.id}
                               addMarker = {self.props.addMarker}
                               searching = {self.props.searching}
                               setInputValue = {self.props.setInputValue}
                               deactivateSearching = {self.props.deactivateSearching}/>)
        });
    }

    return(

{rows}

    );
  }
});

var SearchBox = React.createClass({

  getInitialState: function(){
    return{
      searchResult : [],
      searching : false
    };
  },

  handleChange: function(){
    var currentType = this.refs.filterTextInput.getDOMNode().value;
    this.makeCall(currentType);
    var searchResult = this.state.searchResult;
    this.props.onUserInput(currentType);
    this.setState({searching: true});
  },

  deactivateSearching:function(){
    this.setState({searching: false});
  },

  setInputValue: function(val){
    this.refs.filterTextInput.getDOMNode().value = val;
  },

  makeCall: function(currentInput){
    // pelias api form : https://pelias.mapzen.com/suggest?bbox=-74.18861389160156,40.62802447679272,-73.79173278808594,40.86134282702074&input=we+are&lat=40.7448&lon=-73.9902&size=10&zoom=12
    var self = this;
    if(currentInput.length > 0){
      var baseurl = '//pelias.mapzen.com';
      var bbox = '-74.18861389160156,40.62802447679272,-73.79173278808594,40.86134282702074';
      var input = currentInput;
      var lat = '40.744';
      var lon = '-73.990';
      var zoom = 12;
      var searchData;

      var callurl = baseurl + "/suggest?bbox=" + bbox + "&input="+ currentInput + "&lat="+lat+"&lon="+lon+"&zoom="+ zoom;
    $.get(callurl,function(data){
      //this is not the way react recommends
      self.setState({searchResult: data.features});
    });
  }else{
    self.setState({searchResult: []})
  }

  },

  render: function(){
    return(

        <input id="searchBox" ref = "filterTextInput" type = "text" value = {this.props.filterText}  onChange={this.handleChange}></input>
        <ResultTable searchData = {this.state.searchResult}
                      searching = {this.state.searching}
                      addMarker = {this.props.addMarker}
                      setInputValue = {this.setInputValue}
                      deactivateSearching = {this.deactivateSearching} />

    );
  }
});

var RouteWindow = React.createClass({
  //
  route: function(){

    //valhalla call form : https://valhalla.mapzen.com/route?json={%22locations%22:[{%22lat%22:39.42923221970601,%22lon%22:-76.6356897354126},{%22lat%22:39.30727282892593,%22lon%22:-76.77203178405762}],%22costing%22:%22auto%22}&api_key=valhalla-RfDii2g
    var serviceurl = "https://valhalla.mapzen.com/";
    var apikey = '&api_key=valhalla-RfDii2g';

    var transitM = 'auto';
    var locs = [];
    locs.push(this.props.startPoint);
    locs.push(this.props.destPoint);

    var self = this;

    var params = JSON.stringify({
      locations: locs,
      costing: transitM
    });

    var routeUrl = serviceurl +  'route?json=' + params + apikey;
    $.get(routeUrl,function(data){

      var coord = polyline.decode(data.trip.legs[0].shape,6);
      self.props.addRouteLayer(coord);
    });

  },

  buildRouteUrl: function(){

  },
  routeDone: function(){

  },

  render: function(){

    if(this.props.bringRouteWindow){
      return(

           <input type="button" id="autoRoute" value="auto" onClick= {this.route}></input>
           <input type="button" id="bikeRoute" value="bike" onClick= {this.route}></input>
           <input type="button" id="walkRoute" value="pedesterain" onClick= {this.route} ></input>

      )
    }else{
      return(

      )
    }
  }
});

var RouteButton = React.createClass({
  getInitialState : function(){
    return{
      //startPoint must be replaced current location // search result
      startPoint : {},
      destPoint : {},
      destPoint : this.props.destMarker,
      routePrirority : this.props.routePrirority,
      bringRouteWindow: false
    }
  },
  turnOffRoutingDetail:function(){
    //this.setState({bringRouteWindow:false});
  },
  route : function(){
    this.setState({
      bringRouteWindow : true,
      startPoint : {
        lat :  40.7410605,
        lon : -73.9896986
      },
      destPoint : {
       lat:this.props.destMarker.getLatLng().lat,
       lon:this.props.destMarker.getLatLng().lng,
      }
    });
  },

  render : function(){
    if(this.props.destMarker){
      return(

 route

          <RouteWindow
            bringRouteWindow = {this.state.bringRouteWindow}
            startPoint = {this.state.startPoint}
            destPoint = {this.state.destPoint}
            addMarker = {this.props.addMarker}
            addRouteLayer = {this.props.addRouteLayer}/>

      );
    }else{
      return(

      );
    }
  }
});

var Map = React.createClass({

  getInitialState: function(){
    return{
      // markerLyaer is being mutated, not the way react recommends
      markerLayer : L.layerGroup([L.marker([39.61, -105.02]).bindPopup('This is Littleton, CO.')]),
      routeLayer : L.layerGroup()
    }

  },

  handleUserInput: function(filterText) {
    this.setState({
      filterText: filterText
    });
  },

  addMarker: function(mrkrs){

    this.state.markerLayer.clearLayers();
    var newMarkerLayer = L.layerGroup();
    var self = this;
    //this.state.markerLayer.clearLayers()
    var centerMarker = mrkrs[0];
    mrkrs.forEach(function(marker){
      self.state.markerLayer.addLayer(marker);
    });

    //this.state.destMarker = centerMarker;
    this.map.setView(centerMarker.getLatLng(),14);
     this.setState({
       destMarker: centerMarker
     });
  },

  addRouteLayer : function(routes){
    this.state.routeLayer.clearLayers();
    var polylineRoute = L.polyline(routes, {color:'red'});
    this.state.routeLayer.addLayer(polylineRoute);
    this.map.fitBounds(polylineRoute.getBounds());
    this.render();
  },

  createMap: function (element) {
    var map = L.map(element,{
      zoomControl:false
    });
    var layer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    // loading scene yaml
    // var layer = Tangram.leafletLayer({
    //     scene: 'scene.yaml',//sceneYaml,
    //     attribution: 'Tangram | © OSM contributors | Mapzen'
    // });

    layer.addTo(map);
    //L.marker([40.729614,-73.993837]).addTo(map);
    return map;
    },

    setupMap: function () {
      this.map.setView([this.props.lat, this.props.lon], this.props.zoom);
    },

    componentDidMount: function () {
        if (this.props.createMap) {
            this.map = this.props.createMap(this.getDOMNode());
        } else {
            this.map = this.createMap(this.getDOMNode());
        }

        this.setupMap();
        this.state.markerLayer.addTo(this.map);
        this.state.routeLayer.addTo(this.map);
    },

    render: function () {
      return (

          <SearchBox onUserInput={this.handleUserInput}
          destMarker= {this.state.destMarker}
          addMarker = {this.addMarker} />
          <RouteButton destMarker= {this.state.destMarker} addRouteLayer = {this.addRouteLayer}/>

      );
    }

});

React.render(<Map lat="40.758" lon="-73.9174" zoom="4" />,document.body);
<commit_msg>test commit<commit_after>//general problem : when vendors are managed in vendor folder, asset path throws err :(
var React = require('react');
var L = require('leaflet');
var $ = require('jquery');

var polyline = require('polyline');
require('react-leaflet');
require('leafletCss');
require('./main.css');

//should replace to tangram later
//var sceneYaml = require("file!./scene.yaml");

var ResultRow = React.createClass({
  handleClick: function(){
    var markers = [];
    var marker = L.marker(this.props.loc.reverse());
    marker.bindPopup(this.props.name);
    markers.push(marker);
    this.props.addMarker(markers);
    this.props.setInputValue(this.props.name);
    this.props.deactivateSearching();
  },
  render: function(){
    var displayName = this.props.name;
    return(

         {displayName}

    );
  }
});

var ResultTable = React.createClass({
  render: function(){
    var rows = [];
      if(this.props.searchData.length > 0 && this.props.searching ){
        var self = this;
        this.props.searchData.forEach(function(result){
          rows.push(<ResultRow name = {result.properties.name}
                               loc= {result.geometry.coordinates}
                               key= {result.properties.id}
                               addMarker = {self.props.addMarker}
                               searching = {self.props.searching}
                               setInputValue = {self.props.setInputValue}
                               deactivateSearching = {self.props.deactivateSearching}/>)
        });
    }

    return(

{rows}

    );
  }
});

var SearchBox = React.createClass({

  getInitialState: function(){
    return{
      searchResult : [],
      searching : false
    };
  },

  handleChange: function(){
    var currentType = this.refs.filterTextInput.getDOMNode().value;
    this.makeCall(currentType);
    var searchResult = this.state.searchResult;
    this.props.onUserInput(currentType);
    this.setState({searching: true});
  },

  deactivateSearching:function(){
    this.setState({searching: false});
  },

  setInputValue: function(val){
    this.refs.filterTextInput.getDOMNode().value = val;
  },

  makeCall: function(currentInput){
    // pelias api form : https://pelias.mapzen.com/suggest?bbox=-74.18861389160156,40.62802447679272,-73.79173278808594,40.86134282702074&input=we+are&lat=40.7448&lon=-73.9902&size=10&zoom=12
    var self = this;
    if(currentInput.length > 0){
      var baseurl = '//pelias.mapzen.com';
      var bbox = '-74.18861389160156,40.62802447679272,-73.79173278808594,40.86134282702074';
      var input = currentInput;
      var lat = '40.744';
      var lon = '-73.990';
      var zoom = 12;
      var searchData;

      var callurl = baseurl + "/suggest?bbox=" + bbox + "&input="+ currentInput + "&lat="+lat+"&lon="+lon+"&zoom="+ zoom;
    $.get(callurl,function(data){
      //this is not the way react recommends
      self.setState({searchResult: data.features});
    });
  }else{
    self.setState({searchResult: []})
  }

  },

  render: function(){
    return(

        <input id="searchBox" ref = "filterTextInput" type = "text" value = {this.props.filterText}  onChange={this.handleChange}></input>
        <ResultTable searchData = {this.state.searchResult}
                      searching = {this.state.searching}
                     '' addMarker = {this.props.addMarker}
                      setInputValue = {this.setInputValue}
                      deactivateSearching = {this.deactivateSearching} />

    );
  }
});

var RouteWindow = React.createClass({
  //
  route: function(){

    //valhalla call form : https://valhalla.mapzen.com/route?json={%22locations%22:[{%22lat%22:39.42923221970601,%22lon%22:-76.6356897354126},{%22lat%22:39.30727282892593,%22lon%22:-76.77203178405762}],%22costing%22:%22auto%22}&api_key=valhalla-RfDii2g
    var serviceurl = "https://valhalla.mapzen.com/";
    var apikey = '&api_key=valhalla-RfDii2g';

    var transitM = 'auto';
    var locs = [];
    locs.push(this.props.startPoint);
    locs.push(this.props.destPoint);

    var self = this;

    var params = JSON.stringify({
      locations: locs,
      costing: transitM
    });

    var routeUrl = serviceurl +  'route?json=' + params + apikey;
    $.get(routeUrl,function(data){

      var coord = polyline.decode(data.trip.legs[0].shape,6);
      self.props.addRouteLayer(coord);
    });

  },

  buildRouteUrl: function(){

  },
  routeDone: function(){

  },

  render: function(){

    if(this.props.bringRouteWindow){
      return(

           <input type="button" id="autoRoute" value="auto" onClick= {this.route}></input>
           <input type="button" id="bikeRoute" value="bike" onClick= {this.route}></input>
           <input type="button" id="walkRoute" value="pedesterain" onClick= {this.route} ></input>

      )
    }else{
      return(

      )
    }
  }
});

var RouteButton = React.createClass({
  getInitialState : function(){
    return{
      //startPoint must be replaced current location // search result
      startPoint : {},
      destPoint : {},
      destPoint : this.props.destMarker,
      routePrirority : this.props.routePrirority,
      bringRouteWindow: false
    }
  },
  turnOffRoutingDetail:function(){
    //this.setState({bringRouteWindow:false});
  },
  route : function(){
    this.setState({
      bringRouteWindow : true,
      startPoint : {
        lat :  40.7410605,
        lon : -73.9896986
      },
      destPoint : {
       lat:this.props.destMarker.getLatLng().lat,
       lon:this.props.destMarker.getLatLng().lng,
      }
    });
  },

  render : function(){
    if(this.props.destMarker){
      return(

 route

          <RouteWindow
            bringRouteWindow = {this.state.bringRouteWindow}
            startPoint = {this.state.startPoint}
            destPoint = {this.state.destPoint}
            addMarker = {this.props.addMarker}
            addRouteLayer = {this.props.addRouteLayer}/>

      );
    }else{
      return(

      );
    }
  }
});

var Map = React.createClass({

  getInitialState: function(){
    return{
      // markerLyaer is being mutated, not the way react recommends
      markerLayer : L.layerGroup([L.marker([39.61, -105.02]).bindPopup('This is Littleton, CO.')]),
      routeLayer : L.layerGroup(),
      mode : "search"
    }

  },

  handleUserInput: function(filterText) {
    this.setState({
      filterText: filterText
    });
  },

  addMarker: function(mrkrs){

    this.state.markerLayer.clearLayers();
    var newMarkerLayer = L.layerGroup();
    var self = this;
    //this.state.markerLayer.clearLayers()
    var centerMarker = mrkrs[0];
    mrkrs.forEach(function(marker){
      self.state.markerLayer.addLayer(marker);
    });

    //this.state.destMarker = centerMarker;
    this.map.setView(centerMarker.getLatLng(),14);
     this.setState({
       destMarker: centerMarker
     });
  },

  addRouteLayer : function(routes){
    this.state.routeLayer.clearLayers();
    var polylineRoute = L.polyline(routes, {color:'red'});
    this.state.routeLayer.addLayer(polylineRoute);
    this.map.fitBounds(polylineRoute.getBounds());
    this.render();
  },

  createMap: function (element) {
    var map = L.map(element,{
      zoomControl:false
    });
    var layer = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors'
    }).addTo(map);

    // loading scene yaml
    // var layer = Tangram.leafletLayer({
    //     scene: 'scene.yaml',//sceneYaml,
    //     attribution: 'Tangram | © OSM contributors | Mapzen'
    // });

    layer.addTo(map);
    //L.marker([40.729614,-73.993837]).addTo(map);
    return map;
    },

    setupMap: function () {
      this.map.setView([this.props.lat, this.props.lon], this.props.zoom);
    },

    componentDidMount: function () {
        if (this.props.createMap) {
            this.map = this.props.createMap(this.getDOMNode());
        } else {
            this.map = this.createMap(this.getDOMNode());
        }

        this.setupMap();
        this.state.markerLayer.addTo(this.map);
        this.state.routeLayer.addTo(this.map);
    },

    render: function () {
      return (

          <SearchBox onUserInput={this.handleUserInput}
          destMarker= {this.state.destMarker}
          addMarker = {this.addMarker}
          mode = {this.state.mode}/>
          <RouteButton
          destMarker= {this.state.destMarker}
          addRouteLayer = {this.addRouteLayer}
          mode = {this.state.mode}/>

      );
    }

});

React.render(<Map lat="40.758" lon="-73.9174" zoom="4" />,document.body);
<|endoftext|>


<commit_before>const express = require('express');
const bunyan = require('bunyan');
const config = require('config');
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json({limit: '5mb'});
const uuidBase62 = require('uuid-base62');
const fs = require('fs');
const port = config.get('http.port');
const logger = bunyan.createLogger({ name: 'freemap-api' });
const app = express();
const USER_DATA_DIR = './user_data';

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.get('/tracklogs/:uid', function (req, res) {
  const fileUID = req.params.uid;
  if (!fileUID.match(/^[a-zA-Z0-9]*$/)) {
    res.status(400).json({ error: 'bad uid' });
  } else {
    const filePath = USER_DATA_DIR + '/tracklogs/' + fileUID + '.b64.gpx';
    fs.readFile(filePath, 'utf8', function read(err,  b64gpx) {
      if (err) {
        logger.error({ err }, `Failed to save gpx file to "${filePath}".`);
        res.status(404).json({ error: 'file with such uid not found' });
      } else {
        res.status(200).json({ uid: fileUID, data: b64gpx, mediaType: 'application/gpx+xml' });
      }
    });
  }
});

app.post('/tracklogs', jsonParser, function (req, res) {
  const b64gpx = req.body.data;
  if (b64gpx && b64gpx.length) {
    const fileUID = uuidBase62.v4();
    const filePath = USER_DATA_DIR + '/tracklogs/' + fileUID + '.b64.gpx';
    fs.writeFile(filePath, b64gpx, (err) => {
      if (err) {
        logger.error({ err }, `Failed to save gpx file to "${filePath}".`);
        res.status(500).json({ error: err });
      } else {
        res.status(201).json({ uid: fileUID });
      }
    });
  } else {
    res.status(400).send({error: 'no data found in request'});
  }

});

app.listen(port, function () {
  logger.info(`Freemap v3 API on port ${port}.`);
});<commit_msg>minor<commit_after>const express = require('express');
const bunyan = require('bunyan');
const config = require('config');
const bodyParser = require('body-parser');
const jsonParser = bodyParser.json({limit: '5mb'});
const uuidBase62 = require('uuid-base62');
const fs = require('fs');
const port = config.get('http.port');
const logger = bunyan.createLogger({ name: 'freemap-api' });
const app = express();
const USER_DATA_DIR = './user_data';

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.get('/tracklogs/:uid', function (req, res) {
  const fileUID = req.params.uid;
  if (!fileUID.match(/^[a-zA-Z0-9]*$/)) {
    res.status(400).json({ error: 'bad uid' });
  } else {
    const filePath = USER_DATA_DIR + '/tracklogs/' + fileUID + '.b64.gpx';
    fs.readFile(filePath, 'utf8', function read(err,  b64gpx) {
      if (err) {
        logger.error({ err }, `Failed to save gpx file to "${filePath}".`);
        res.status(404).json({ error: 'file with such uid not found' });
      } else {
        res.status(200).json({ uid: fileUID, data: b64gpx, mediaType: 'application/gpx+xml' });
      }
    });
  }
});

app.post('/tracklogs', jsonParser, function (req, res) {
  const b64gpx = req.body.data;
  if (b64gpx && b64gpx.length) {
    const fileUID = uuidBase62.v4();
    const filePath = USER_DATA_DIR + '/tracklogs/' + fileUID + '.b64.gpx';
    fs.writeFile(filePath, b64gpx, (err) => {
      if (err) {
        logger.error({ err }, `Failed to save gpx file to "${filePath}".`);
        res.status(500).json({ error: err });
      } else {
        res.status(201).json({ uid: fileUID });
      }
    });
  } else {
    res.status(400).send({ error: 'no data found in request' });
  }

});

app.listen(port, function () {
  logger.info(`Freemap v3 API on port ${port}.`);
});<|endoftext|>


<commit_before>'use strict';
var path = require('path');
var spawn = require('child_process').spawn;
var gui = require('nw.gui');
var _ = require('lodash');
var findupSync = require('findup-sync');
var currentPath = require('current-path');
var requireModify = require('require-modify');
var displayNotification = require('display-notification');
var nodeUtil = require('./node-util');
var dirname = nodeUtil.dirname;

var DEBUG = true;
var TRAY_UPDATE_INTERVAL = 1000;

function runTask(taskName) {
	var gulpPath = path.join(dirname, 'node_modules', 'gulp', 'bin', 'gulp.js');

	// TODO: find workaround for node-webkit bug:
	// https://github.com/rogerwang/node-webkit/issues/213
	// so I don't have to hardcode the node path
	var cp = spawn('/usr/local/bin/node', [gulpPath, taskName, '--no-color']);

	cp.stdout.setEncoding('utf8');
	cp.stdout.on('data', function (data) {
		console.log(data);
	});

	// TODO: show progress in menubar menu
	//tray.menu = createTrayMenu(name, [], 'progress here');

	cp.stderr.setEncoding('utf8');
	cp.stderr.on('data', function (data) {
		console.error(data);
		displayNotification({text: '[error] ' + data});
	});

	cp.on('exit', function (code) {
		if (code === 0) {
			displayNotification({
				title: 'gulp',
				subtitle: 'Finished running tasks'
			});
		} else {
			displayNotification({
				title: 'gulp',
				subtitle: 'Exited with error code ' + code,
				sound: 'Basso'
			});
		}
	});
}

function createTrayMenu(name, tasks, status) {
	var menu = new gui.Menu();

	menu.append(new gui.MenuItem({
		label: name,
		enabled: false
	}));

	if (status) {
		menu.append(new gui.MenuItem({type: 'separator'}));
		menu.append(new gui.MenuItem({
			label: status,
			enabled: false
		}));
	}

	if (tasks && tasks.length > 0) {
		menu.append(new gui.MenuItem({type: 'separator'}));

		tasks.forEach(function (el) {
			menu.append(new gui.MenuItem({
				label: el,
				click: function () {
					runTask(el);
				}
			}));
		});
	}

	menu.append(new gui.MenuItem({type: 'separator'}));
	menu.append(new gui.MenuItem({
		label: 'Quit',
		click: gui.App.quit
	}));

	return menu;
}

function updateTrayMenu() {
	tray.menu = createTrayMenu.apply(null, arguments);
}

function updateTray() {
	currentPath(function (err, dirPath) {
		setTimeout(updateTray, TRAY_UPDATE_INTERVAL);

		process.chdir(dirPath);

		try {
			var pkg = require(findupSync('package.json'));
			var name = pkg.name || path.basename(dirPath, path.extname(dirPath));
			var gulpfile = requireModify(findupSync('gulpfile.js'), function (src) {
				return src + ';module.exports = gulp';
			});

			var tasks = _.pull(Object.keys(gulpfile.tasks), 'default');
			tasks.unshift('default');

			updateTrayMenu(name, tasks);
		} catch (err) {
			updateTrayMenu('No gulpfile found');
			console.log(err);
		}
	});
}

var tray = new gui.Tray({
	icon: 'menubar-icon@2x.png',
	alticon: 'menubar-icon-alt@2x.png'
});

updateTray();

if (DEBUG) {
	gui.Window.get().showDevTools();
}
<commit_msg>only switch project when valid gulpfile is found - fixes #5<commit_after>'use strict';
var path = require('path');
var spawn = require('child_process').spawn;
var gui = require('nw.gui');
var _ = require('lodash');
var findupSync = require('findup-sync');
var currentPath = require('current-path');
var requireModify = require('require-modify');
var displayNotification = require('display-notification');
var nodeUtil = require('./node-util');
var dirname = nodeUtil.dirname;

var DEBUG = true;
var TRAY_UPDATE_INTERVAL = 1000;

function runTask(taskName) {
	var gulpPath = path.join(dirname, 'node_modules', 'gulp', 'bin', 'gulp.js');

	// TODO: find workaround for node-webkit bug:
	// https://github.com/rogerwang/node-webkit/issues/213
	// so I don't have to hardcode the node path
	var cp = spawn('/usr/local/bin/node', [gulpPath, taskName, '--no-color']);

	cp.stdout.setEncoding('utf8');
	cp.stdout.on('data', function (data) {
		console.log(data);
	});

	// TODO: show progress in menubar menu
	//tray.menu = createTrayMenu(name, [], 'progress here');

	cp.stderr.setEncoding('utf8');
	cp.stderr.on('data', function (data) {
		console.error(data);
		displayNotification({text: '[error] ' + data});
	});

	cp.on('exit', function (code) {
		if (code === 0) {
			displayNotification({
				title: 'gulp',
				subtitle: 'Finished running tasks'
			});
		} else {
			displayNotification({
				title: 'gulp',
				subtitle: 'Exited with error code ' + code,
				sound: 'Basso'
			});
		}
	});
}

function createTrayMenu(name, tasks, status) {
	var menu = new gui.Menu();

	menu.append(new gui.MenuItem({
		label: name,
		enabled: false
	}));

	if (status) {
		menu.append(new gui.MenuItem({type: 'separator'}));
		menu.append(new gui.MenuItem({
			label: status,
			enabled: false
		}));
	}

	if (tasks && tasks.length > 0) {
		menu.append(new gui.MenuItem({type: 'separator'}));

		tasks.forEach(function (el) {
			menu.append(new gui.MenuItem({
				label: el,
				click: function () {
					runTask(el);
				}
			}));
		});
	}

	menu.append(new gui.MenuItem({type: 'separator'}));
	menu.append(new gui.MenuItem({
		label: 'Quit',
		click: gui.App.quit
	}));

	return menu;
}

function updateTrayMenu() {
	tray.menu = createTrayMenu.apply(null, arguments);
}

function updateTray() {
	currentPath(function (err, dirPath) {
		setTimeout(updateTray, TRAY_UPDATE_INTERVAL);

		process.chdir(dirPath);

		try {
			var pkg = require(findupSync('package.json'));
			var name = pkg.name || path.basename(dirPath, path.extname(dirPath));
			var gulpfile = requireModify(findupSync('gulpfile.js'), function (src) {
				return src + ';module.exports = gulp';
			});

			var tasks = _.pull(Object.keys(gulpfile.tasks), 'default');
			tasks.unshift('default');

			updateTrayMenu(name, tasks);
		} catch (err) {
			console.log(err);
		}
	});
}

var tray = new gui.Tray({
	icon: 'menubar-icon@2x.png',
	alticon: 'menubar-icon-alt@2x.png'
});

updateTrayMenu('No gulpfile found');
updateTray();

if (DEBUG) {
	gui.Window.get().showDevTools();
}
<|endoftext|>


<commit_before>require('babel-polyfill')
const crypto = require('crypto')
const querystring = require('querystring')
require('isomorphic-fetch')

const accessToken
if (accessToken) {
  console.log(' we have an access token ')
  console.log('getting user\'s saved tracks')
  collectTracks().then(organizeTracks).then(createPlaylists)
}

// returns a Promise
function getTracks(offset) {
  const getTracksURL = 'https://api.spotify.com/v1/me/tracks'
  const headers = new Headers()
  headers.set('Authorization', `Bearer ${accessToken}`)
  const qs = querystring.stringify({ limit: 50, offset })
  return fetch(`${getTracksURL}?${qs}`, { headers }).then(r => r.json())
}

let tracksArr = []
// takes an HTTP response, returns total number of tracks
function storeTracks(response) {
  tracksArr =  tracksArr.concat(response.items)
  return response.total
}

function collectTracks() {
  return getTracks(0).then(r => {
    let totalTracks = storeTracks(r)
    let offset = 50
    const promises = []
    for (let offset = 50; offset < totalTracks; offset += 50) {
      promises.push(getTracks(offset))
    }
    return Promise.all(promises).then(responses => {
      responses.forEach(curr => {
        storeTracks(curr)
      })
      return Promise.resolve()
    })
  }).catch(e => {
    // TODO: handle error gracefully
    throw e
  })
}

/**
 * returns a promise with artistMap parameter
 *  tracks
 *  genres
 */
function organizeTracks() {
  const artistIDs = new Set()
  const artistMap = new Map()
  tracksArr.forEach(c => {
    artistIDs.add(c.track.artists[0].id)
    if (artistMap.has(c.track.artists[0].id)) {
      artistMap.get(c.track.artists[0].id).tracks.push(c.track.id)
    } else {
      artistMap.set(c.track.artists[0].id, { tracks: [c.track.id], genres: [] })
    }
  })
  const promises = []
  promises.push(getGenres(artistIDs).then(responses => {
    let populated = 0
    responses.forEach(r => {
      r.artists.forEach(c => {
        // NOTE: c.genres is empty on all entries!!!
        if (c.genres.length) populated++
        artistMap.get(c.id).genres = c.genres
      })
    })
    console.log(populated, '/', artistIDs.size)
    return Promise.resolve(artistMap)
  }))
  promises.push(getTerms(artistIDs).then(rArr => {
    let populated = 0
    rArr.forEach(r => {
      populated++
      console.log(r.id())
      artistMap.get(r.id()).terms = r.response.terms
    })
    console.log(populated, '/', artistIDs.size)
    return Promise.resolve(artistMap)
  }))
  return Promise.all(promises)
}

function getGenres(artists) {
  const artistsURL = 'https://api.spotify.com/v1/artists'
  const artistsArr = Array.from(artists)
  const promises = []

  const headers = new Headers()
  headers.set('Authorization', `Bearer ${accessToken}`)

  for (let i = 0; i < artistsArr.length; i += 50) {
    const qs = querystring.stringify({ ids: artistsArr.slice(i, i + 50).join() })
    promises.push(fetch(`${artistsURL}?${qs}`, { headers }).then(r => r.json()))
  }
  return Promise.all(promises)
}

function getTerms(artists) {
  const termsURL = 'http://developer.echonest.com/api/v4/artist/terms'
  const ECHONEST_API_KEY = process.env.ECHONEST_API_KEY
  const artistsArr = Array.from(artists).splice(0, 5)
  const promises = []

  artistsArr.forEach(a => {
    const qs = querystring.stringify({
      api_key: ECHONEST_API_KEY,
      id: `spotify:artist:${a}`,
    })
    promises.push(fetch(`${termsURL}?${qs}`).then(r => r.json()).then(r => {
      const r2 = r
      // enclose a
      r2.id = (retVal => () => retVal)(a)
      return Promise.resolve(r2)
    }))
  })
  return Promise.all(promises)
}

let playlists = new Map()
function createPlaylists(map) {
  console.log(map)
  map[0].forEach(v => {
    try {
      // organize by genre
      v.genres.forEach(g => {
        v.tracks.forEach(t => {
          if (playlists.has(g)) {
            playlists.get(g).push(t)
          } else {
            playlists.set(g, [t])
          }
        })
      })
      // organize by terms
      if (v.terms && v.terms.length) {
        const term = v.terms[0].name
        v.tracks.forEach(t => {
          if (playlists.has(term)) {
            playlists.get(term).push(t)
          } else {
            playlists.set(term, [t])
          }
        })
        console.log(term)
      }
    } catch (e) {
      console.error(e)
      console.error('failed on', v)
    }
  })
  console.log(playlists)
}

const authURL = 'https://accounts.spotify.com/authorize'
const stateString = crypto.randomBytes(64).toString('hex')
const authParams = {
  client_id: process.env.SPOTIFY_CLIENT_ID,
  response_type: 'token',
  redirect_uri: 'http://localhost:8080',
  state: stateString,
  scope: 'playlist-modify-public user-library-read',
  // show_dialog
}

//got(authURL, {query: authParams}).then(response => {
//  console.log(response.body)
//}).catch(e => {
//  console.error(e)
//})
<commit_msg>Some lint fixes<commit_after>require('babel-polyfill')
const crypto = require('crypto')
const querystring = require('querystring')
require('isomorphic-fetch')

let accessToken
;(() => {
  if (accessToken) {
    console.log(' we have an access token ')
    console.log('getting user\'s saved tracks')
    collectTracks().then(organizeTracks).then(createPlaylists)
  }
})()

// returns a Promise
function getTracks(offset) {
  const getTracksURL = 'https://api.spotify.com/v1/me/tracks'
  const headers = new Headers()
  headers.set('Authorization', `Bearer ${accessToken}`)
  const qs = querystring.stringify({ limit: 50, offset })
  return fetch(`${getTracksURL}?${qs}`, { headers }).then(r => r.json())
}

let tracksArr = []
// takes an HTTP response, returns total number of tracks
function storeTracks(response) {
  tracksArr = tracksArr.concat(response.items)
  return response.total
}

function collectTracks() {
  return getTracks(0).then(r => {
    const totalTracks = storeTracks(r)
    const promises = []
    for (let offset = 50; offset < totalTracks; offset += 50) {
      promises.push(getTracks(offset))
    }
    return Promise.all(promises).then(responses => {
      responses.forEach(curr => {
        storeTracks(curr)
      })
      return Promise.resolve()
    })
  }).catch(e => {
    // TODO: handle error gracefully
    throw e
  })
}

/**
 * returns a promise with artistMap parameter
 *  tracks
 *  genres
 */
function organizeTracks() {
  const artistIDs = new Set()
  const artistMap = new Map()
  tracksArr.forEach(c => {
    artistIDs.add(c.track.artists[0].id)
    if (artistMap.has(c.track.artists[0].id)) {
      artistMap.get(c.track.artists[0].id).tracks.push(c.track.id)
    } else {
      artistMap.set(c.track.artists[0].id, { tracks: [c.track.id], genres: [] })
    }
  })
  const promises = []
  promises.push(getGenres(artistIDs).then(responses => {
    let populated = 0
    responses.forEach(r => {
      r.artists.forEach(c => {
        // NOTE: c.genres is empty on all entries!!!
        if (c.genres.length) populated++
        artistMap.get(c.id).genres = c.genres
      })
    })
    console.log(populated, '/', artistIDs.size)
    return Promise.resolve(artistMap)
  }))
  promises.push(getTerms(artistIDs).then(rArr => {
    let populated = 0
    rArr.forEach(r => {
      populated++
      console.log(r.id())
      artistMap.get(r.id()).terms = r.response.terms
    })
    console.log(populated, '/', artistIDs.size)
    return Promise.resolve(artistMap)
  }))
  return Promise.all(promises)
}

function getGenres(artists) {
  const artistsURL = 'https://api.spotify.com/v1/artists'
  const artistsArr = Array.from(artists)
  const promises = []

  const headers = new Headers()
  headers.set('Authorization', `Bearer ${accessToken}`)

  for (let i = 0; i < artistsArr.length; i += 50) {
    const qs = querystring.stringify({ ids: artistsArr.slice(i, i + 50).join() })
    promises.push(fetch(`${artistsURL}?${qs}`, { headers }).then(r => r.json()))
  }
  return Promise.all(promises)
}

function getTerms(artists) {
  const termsURL = 'http://developer.echonest.com/api/v4/artist/terms'
  const ECHONEST_API_KEY = process.env.ECHONEST_API_KEY
  const artistsArr = Array.from(artists).splice(0, 5)
  const promises = []

  artistsArr.forEach(a => {
    const qs = querystring.stringify({
      api_key: ECHONEST_API_KEY,
      id: `spotify:artist:${a}`,
    })
    promises.push(fetch(`${termsURL}?${qs}`).then(r => r.json()).then(r => {
      const r2 = r
      // enclose a
      r2.id = (retVal => () => retVal)(a)
      return Promise.resolve(r2)
    }))
  })
  return Promise.all(promises)
}

const playlists = new Map()
function createPlaylists(map) {
  console.log(map)
  map[0].forEach(v => {
    try {
      // organize by genre
      v.genres.forEach(g => {
        v.tracks.forEach(t => {
          if (playlists.has(g)) {
            playlists.get(g).push(t)
          } else {
            playlists.set(g, [t])
          }
        })
      })
      // organize by terms
      if (v.terms && v.terms.length) {
        const term = v.terms[0].name
        v.tracks.forEach(t => {
          if (playlists.has(term)) {
            playlists.get(term).push(t)
          } else {
            playlists.set(term, [t])
          }
        })
        console.log(term)
      }
    } catch (e) {
      console.error(e)
      console.error('failed on', v)
    }
  })
  console.log(playlists)
}

const authURL = 'https://accounts.spotify.com/authorize'
const stateString = crypto.randomBytes(64).toString('hex')
const authParams = {
  client_id: process.env.SPOTIFY_CLIENT_ID,
  response_type: 'token',
  redirect_uri: 'http://localhost:8080',
  state: stateString,
  scope: 'playlist-modify-public user-library-read',
  // show_dialog
}

//got(authURL, {query: authParams}).then(response => {
//  console.log(response.body)
//}).catch(e => {
//  console.error(e)
//})
<|endoftext|>


<commit_before>// Disabling autoDiscover, otherwise Dropzone will try to attach twice.
Dropzone.autoDiscover = false;

$(function() {
    $('.ni-ub').each(function() {
        var $form = $(this);
        var $dropzone = $form.find('.ni-ub-dz');

        // we go read options from HTML data-* attributes
        var options = $dropzone.data();

        // But we force some
        $.extend(options, {
            fallback: null,
            paramName: 'file'
        });

        var dropzone = new Dropzone('#'+$dropzone.attr('id'), options);

        dropzone.on('error', function(file, errorMessage) {
            // Small inconsistency within Dropzone!
            if (typeof errorMessage === "object") {
                errorMessage = errorMessage.error;
            }

            $form.find('.ni-ub-error').html(errorMessage);

            dropzone.removeFile(file);
        });

        dropzone.on('addedfile', function() {
            $form.find('.ni-ub-error').html('');
        });

        /*
         Some handling is different depending whether under we have a single file
         or a collection
         */

        var $collection = $form.find('[data-collection]');
        var successHandler;
        var removeHandler;

        if ($collection) {
            successHandler = function(file, response) {
                var prototype = $collection.data('prototype');
                var number = $collection.length;
                var newChild = prototype.replace(/__name__/g, number);

                var $newChild = $(newChild).appendTo($collection);

                $newChild.find('input[data-path]').val(response.path);
                $newChild.find('input[data-temporary]').val(1);

                // Store some file properties we will reuse later
                file.ub = {
                    formId: $newChild.attr('id'),
                    number: response.number,
                    path: response.path,
                    temporary: true
                }
            };

            removeHandler = function(file) {
                // Temporary files must be removed from server sandbox
                if (file.ub.temporary) {
                    $.ajax(options.removeUrl, {
                        data: {
                            path: file.ub.path
                        }
                    });
                }
                // Non temporary will be removed via traditional form workflow

                $form.find('#'+file.ub.formId).remove();
            };
        } else {
            successHandler = function(file, response) {
                $form.find('input[data-path]').val(response.path);

                // Anyway a temporary file was stored
                $form.find('input[data-temporary]').val(1);

                // Store some file properties we will reuse later
                file.ub = {
                    path: response.path,
                    temporary: true
                }
            };

            removeHandler = function(file) {
                // Temporary files must be removed from server sandbox
                if (file.ub.temporary) {
                    $.ajax(options.removeUrl, {
                        data: {
                            path: file.ub.path
                        }
                    });
                }
                // Non temporary will be removed via traditional form workflow

                $form.find('input[data-path]').val('');
                $form.find('input[data-temporary]').val('');
            };
        }

        dropzone.on('success', successHandler);
        dropzone.on('removedfile', removeHandler);

        /*
         Dropzone.js provides no way to handle already uploaded files
         but manually!
         */

        var addExistingFile = function($form) {
            var mockFile = {
                name: 'file', // needed by Dropzone though unused in UI
                size: 0, // needed by Dropzone though unused in UI
                ub: {
                    formId: $form.attr('id'),
                    path: $form.find('input[data-path]').val(),
                    temporary: false, // they were already persisted
                    thumbnailUrl: $form.find('span[data-thumbnail]').data('url')
                }
            };

            dropzone.emit('addedfile', mockFile);

            dropzone.emit('thumbnail', mockFile, mockFile.ub.thumbnailUrl);

            dropzone.emit('complete', mockFile);

            // And we even have to update that one
            dropzone.options.maxFiles = dropzone.options.maxFiles--;
        };

        $form.find('.ni-ub-dz-image').each(function() {
            addExistingFile($(this));
        });
    });
});
<commit_msg>Fixed: JS error when cancelling upload<commit_after>// Disabling autoDiscover, otherwise Dropzone will try to attach twice.
Dropzone.autoDiscover = false;

$(function() {
    $('.ni-ub').each(function() {
        var $form = $(this);
        var $dropzone = $form.find('.ni-ub-dz');

        // we go read options from HTML data-* attributes
        var options = $dropzone.data();

        // But we force some
        $.extend(options, {
            fallback: null,
            paramName: 'file'
        });

        var dropzone = new Dropzone('#'+$dropzone.attr('id'), options);

        dropzone.on('error', function(file, errorMessage) {
            // Small inconsistency within Dropzone!
            if (typeof errorMessage === "object") {
                errorMessage = errorMessage.error;
            }

            $form.find('.ni-ub-error').html(errorMessage);

            dropzone.removeFile(file);
        });

        dropzone.on('addedfile', function() {
            $form.find('.ni-ub-error').html('');
        });

        /*
         Some handling is different depending whether under we have a single file
         or a collection
         */

        var $collection = $form.find('[data-collection]');
        var successHandler;
        var removeHandler;

        if ($collection) {
            successHandler = function(file, response) {
                var prototype = $collection.data('prototype');
                var number = $collection.length;
                var newChild = prototype.replace(/__name__/g, number);

                var $newChild = $(newChild).appendTo($collection);

                $newChild.find('input[data-path]').val(response.path);
                $newChild.find('input[data-temporary]').val(1);

                // Store some file properties we will reuse later
                file.ub = {
                    formId: $newChild.attr('id'),
                    number: response.number,
                    path: response.path,
                    temporary: true
                }
            };

            removeHandler = function(file) {
                // Temporary files must be removed from server sandbox
                // Watch out file properties may not have been dded, for instance if sending was unsuccessful
                if (typeof file.ub !== "undefined" && file.ub.temporary) {
                    $.ajax(options.removeUrl, {
                        data: {
                            path: file.ub.path
                        }
                    });
                }
                // Non temporary will be removed via traditional form workflow

                $form.find('#'+file.ub.formId).remove();
            };
        } else {
            successHandler = function(file, response) {
                $form.find('input[data-path]').val(response.path);

                // Anyway a temporary file was stored
                $form.find('input[data-temporary]').val(1);

                // Store some file properties we will reuse later
                file.ub = {
                    path: response.path,
                    temporary: true
                }
            };

            removeHandler = function(file) {
                // Temporary files must be removed from server sandbox
                if (file.ub.temporary) {
                    $.ajax(options.removeUrl, {
                        data: {
                            path: file.ub.path
                        }
                    });
                }
                // Non temporary will be removed via traditional form workflow

                $form.find('input[data-path]').val('');
                $form.find('input[data-temporary]').val('');
            };
        }

        dropzone.on('success', successHandler);
        dropzone.on('removedfile', removeHandler);

        /*
         Dropzone.js provides no way to handle already uploaded files
         but manually!
         */

        var addExistingFile = function($form) {
            var mockFile = {
                name: 'file', // needed by Dropzone though unused in UI
                size: 0, // needed by Dropzone though unused in UI
                ub: {
                    formId: $form.attr('id'),
                    path: $form.find('input[data-path]').val(),
                    temporary: false, // they were already persisted
                    thumbnailUrl: $form.find('span[data-thumbnail]').data('url')
                }
            };

            dropzone.emit('addedfile', mockFile);

            dropzone.emit('thumbnail', mockFile, mockFile.ub.thumbnailUrl);

            dropzone.emit('complete', mockFile);

            // And we even have to update that one
            dropzone.options.maxFiles = dropzone.options.maxFiles--;
        };

        $form.find('.ni-ub-dz-image').each(function() {
            addExistingFile($(this));
        });
    });
});
<|endoftext|>


<commit_before>import { Navigation } from 'react-native-navigation';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import Theme from 'config/theme';
import { registerScreens } from 'screens';

import * as reducers from 'redux-modules';
import offline from 'offline';

import Reactotron, { trackGlobalErrors, networking, openInEditor, asyncStorage } from 'reactotron-react-native'; // eslint-disable-line
import { reactotronRedux } from 'reactotron-redux'; // eslint-disable-line

// Disable ios warnings
// console.disableYellowBox = true;

// Show request in chrome network tool
// GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;

export default () => {
  function startApp() {
    Navigation.startSingleScreenApp({
      screen: {
        screen: 'ForestWatcher.Home',
        navigatorStyle: Theme.navigator.styles
      }
    });
  }

  const authMiddleware = ({ getState }) => next => action => next({ ...action, auth: getState().user.token });

  const reducer = combineReducers(reducers);
  const middleware = applyMiddleware(thunk, authMiddleware);

  let store = null;
  if (__DEV__) {
    Reactotron
      .configure()
      .use(reactotronRedux())
      .use(trackGlobalErrors())
      .use(networking())
      .use(openInEditor())
      .use(asyncStorage())
      .connect()
      .clear();
    window.tron = Reactotron; // eslint-disable-line
    store = offline({ persistCallback: startApp })(Reactotron.createStore)(reducer, undefined, middleware);
  } else {
    store = offline({ persistCallback: startApp })(createStore)(reducer, undefined, middleware);
  }

  registerScreens(store, Provider);
};
<commit_msg>fix: auth only on requests<commit_after>import { Navigation } from 'react-native-navigation';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import Theme from 'config/theme';
import { registerScreens } from 'screens';

import * as reducers from 'redux-modules';
import offline from 'offline';

import Reactotron, { trackGlobalErrors, networking, openInEditor, asyncStorage } from 'reactotron-react-native'; // eslint-disable-line
import { reactotronRedux } from 'reactotron-redux'; // eslint-disable-line

// Disable ios warnings
// console.disableYellowBox = true;

// Show request in chrome network tool
// GLOBAL.XMLHttpRequest = GLOBAL.originalXMLHttpRequest || GLOBAL.XMLHttpRequest;

export default () => {
  function startApp() {
    Navigation.startSingleScreenApp({
      screen: {
        screen: 'ForestWatcher.Home',
        navigatorStyle: Theme.navigator.styles
      }
    });
  }

  const authMiddleware = ({ getState }) => next => action => (
    action.type.endsWith('REQUEST') ? next({ ...action, auth: getState().user.token }) : next(action)
  );

  const reducer = combineReducers(reducers);
  const middleware = applyMiddleware(thunk, authMiddleware);

  let store = null;
  if (__DEV__) {
    Reactotron
      .configure()
      .use(reactotronRedux())
      .use(trackGlobalErrors())
      .use(networking())
      .use(openInEditor())
      .use(asyncStorage())
      .connect()
      .clear();
    window.tron = Reactotron; // eslint-disable-line
    store = offline({ persistCallback: startApp })(Reactotron.createStore)(reducer, undefined, middleware);
  } else {
    store = offline({ persistCallback: startApp })(createStore)(reducer, undefined, middleware);
  }

  registerScreens(store, Provider);
};
<|endoftext|>


<commit_before>const { app, BrowserWindow, globalShortcut, ipcMain, Menu } = require('electron')
const windowStateKeeper = require('electron-window-state');
let mainWindow;

// Main app menu
const name = app.getName();
const webviewId = 'overcast_webview';
const appWebsite = 'https://github.com/vitorgalvao/fog/';
const template = [
  {
    label: 'Application',
    submenu: [
      { label: 'About ' + name, role: 'about' },
      { type: 'separator' },
      { label: 'Hide ' + name, accelerator: 'Command+H', role: 'hide' },
      { label: 'Hide Others', accelerator: 'Command+Shift+H', role: 'hideothers' },
      { type: 'separator' },
      { label: 'Quit', accelerator: 'Command+Q', click: function() {app.quit();} }
    ]
  }, {
    label: 'Edit',
    submenu: [
      { label: 'Undo', accelerator: 'Command+Z', role: 'undo' },
      { label: 'Redo', accelerator: 'Shift+Command+Z', role: 'redo' },
      { type: 'separator' },
      { label: 'Cut', accelerator: 'Command+X', role: 'cut' },
      { label: 'Copy', accelerator: 'Command+C', role: 'copy' },
      { label: 'Paste', accelerator: 'Command+V', role: 'paste' },
      { label: 'Select All', accelerator: 'Command+A', role: 'selectall' }
    ]
  }, {
    label: 'View',
    submenu: [
      { label: 'Reload', accelerator: 'Command+R', click: function(item,focusedWindow) {if (focusedWindow) focusedWindow.webContents.executeJavaScript('document.getElementById(' + webviewId + ').reload()');} }
    ]
  }, {
    label: 'Window',
    role: 'window',
    submenu: [
      { label: 'Minimize', accelerator: 'Command+M', role: 'minimize' },
      { label: 'Close', accelerator: 'Command+W', role: 'close' }
    ]
  }, {
    label: 'Help',
    role: 'help',
    submenu: [
      { label: 'View Website', click: function() { require('electron').shell.openExternal(appWebsite) } },
      { type: 'separator' },
      { label: 'Toggle Developer Tools', click: function(item,focusedWindow) {if (focusedWindow) focusedWindow.toggleDevTools();} }
    ]
  }
];

function focus_webview() {
  mainWindow.webContents.executeJavaScript('document.getElementById("overcast_webview").focus();');
}

function get_hostname(url) {
  if (url.indexOf('://') > -1) {
    return url.split('/')[2];
  } else {
    return url.split('/')[0];
  }
}

app.on('ready', function() {
  const min_window_size = [352, 556]

  // Initial window state
  const mainWindowState = windowStateKeeper({
    defaultWidth: min_window_size[0],
    defaultHeight: min_window_size[1]
  });

  // Create the browser window.
  mainWindow = new BrowserWindow({
    x: mainWindowState.x,
    y: mainWindowState.y,
    width: mainWindowState.width,
    height: mainWindowState.height,
    minWidth: min_window_size[0],
    minHeight: min_window_size[1],
    titleBarStyle: 'hidden-inset',
    title: 'Fog',
    backgroundColor: '#fff',
    show: false // Avoid initial flash of no content by not showing window on start…
  });

  // … and only showing the window after the DOM is ready on the webview
  ipcMain.on('page-loaded', function() {
    mainWindow.show();
  });

  // Add listeners to check for window maximization and save state
  mainWindowState.manage(mainWindow);

  // Load the index.html of the app and focus on webview
  mainWindow.loadURL('file://' + __dirname + '/index.html');
  focus_webview();

  // If given an overcast.fm URL as the argument, try to load it
  const overcast_url = process.argv[1];
  if (overcast_url) {
    if (get_hostname(overcast_url) != 'overcast.fm') throw new Error('Argument needs to be an overcast.fm URL')
    mainWindow.webContents.executeJavaScript('document.getElementById("overcast_webview").src = "' + overcast_url + '"');
  }

  // Media keys shortcuts
  globalShortcut.register('MediaPreviousTrack', function() { mainWindow.webContents.send('media_keys', 'seekbackbutton') });
  globalShortcut.register('MediaNextTrack', function() { mainWindow.webContents.send('media_keys', 'seekforwardbutton'); });
  globalShortcut.register('MediaPlayPause', function() { mainWindow.webContents.send('media_keys', 'playpausebutton'); });

  // Set menu
  Menu.setApplicationMenu(Menu.buildFromTemplate(template));

  // Focus on webview when focusing on window, so we can use keyboard shortcuts
  app.on('browser-window-focus', function() {
    focus_webview();
  });

  // Prevent app from exiting (hide it instead) when window is closed (i.e. when we press the red close button)
  mainWindow.on('close', function(event) {
    event.preventDefault();
    mainWindow.hide();
    app.focus();
  });

  app.on('before-quit', function() {
    globalShortcut.unregisterAll();
    mainWindow.webContents.send('sync_podcast'); // Try to force a sync before closing

    setTimeout(function() { // Give enough time for the sync attempt to go through
      app.exit(0);
    }, 1500);
  });

  app.on('activate', function() {
    mainWindow.show();
  });
});
<commit_msg>Auto style fix<commit_after>const { app, BrowserWindow, globalShortcut, ipcMain, Menu } = require('electron')
const windowStateKeeper = require('electron-window-state');
let mainWindow;

// Main app menu
const name = app.getName();
const webviewId = 'overcast_webview';
const appWebsite = 'https://github.com/vitorgalvao/fog/';
const template = [
  {
    label: 'Application',
    submenu: [
      { label: 'About ' + name, role: 'about' },
      { type: 'separator' },
      { label: 'Hide ' + name, accelerator: 'Command+H', role: 'hide' },
      { label: 'Hide Others', accelerator: 'Command+Shift+H', role: 'hideothers' },
      { type: 'separator' },
      { label: 'Quit', accelerator: 'Command+Q', click: function () { app.quit(); } }
    ]
  }, {
    label: 'Edit',
    submenu: [
      { label: 'Undo', accelerator: 'Command+Z', role: 'undo' },
      { label: 'Redo', accelerator: 'Shift+Command+Z', role: 'redo' },
      { type: 'separator' },
      { label: 'Cut', accelerator: 'Command+X', role: 'cut' },
      { label: 'Copy', accelerator: 'Command+C', role: 'copy' },
      { label: 'Paste', accelerator: 'Command+V', role: 'paste' },
      { label: 'Select All', accelerator: 'Command+A', role: 'selectall' }
    ]
  }, {
    label: 'View',
    submenu: [
      { label: 'Reload', accelerator: 'Command+R', click: function (item, focusedWindow) { if (focusedWindow) focusedWindow.webContents.executeJavaScript('document.getElementById(' + webviewId + ').reload()'); } }
    ]
  }, {
    label: 'Window',
    role: 'window',
    submenu: [
      { label: 'Minimize', accelerator: 'Command+M', role: 'minimize' },
      { label: 'Close', accelerator: 'Command+W', role: 'close' }
    ]
  }, {
    label: 'Help',
    role: 'help',
    submenu: [
      { label: 'View Website', click: function () { require('electron').shell.openExternal(appWebsite) } },
      { type: 'separator' },
      { label: 'Toggle Developer Tools', click: function (item, focusedWindow) { if (focusedWindow) focusedWindow.toggleDevTools(); } }
    ]
  }
];

function focus_webview() {
  mainWindow.webContents.executeJavaScript('document.getElementById("overcast_webview").focus();');
}

function get_hostname(url) {
  if (url.indexOf('://') > -1) {
    return url.split('/')[2];
  } else {
    return url.split('/')[0];
  }
}

app.on('ready', function () {
  const min_window_size = [352, 556]

  // Initial window state
  const mainWindowState = windowStateKeeper({
    defaultWidth: min_window_size[0],
    defaultHeight: min_window_size[1]
  });

  // Create the browser window.
  mainWindow = new BrowserWindow({
    x: mainWindowState.x,
    y: mainWindowState.y,
    width: mainWindowState.width,
    height: mainWindowState.height,
    minWidth: min_window_size[0],
    minHeight: min_window_size[1],
    titleBarStyle: 'hidden-inset',
    title: 'Fog',
    backgroundColor: '#fff',
    show: false // Avoid initial flash of no content by not showing window on start…
  });

  // … and only showing the window after the DOM is ready on the webview
  ipcMain.on('page-loaded', function () {
    mainWindow.show();
  });

  // Add listeners to check for window maximization and save state
  mainWindowState.manage(mainWindow);

  // Load the index.html of the app and focus on webview
  mainWindow.loadURL('file://' + __dirname + '/index.html');
  focus_webview();

  // If given an overcast.fm URL as the argument, try to load it
  const overcast_url = process.argv[1];
  if (overcast_url) {
    if (get_hostname(overcast_url) != 'overcast.fm') throw new Error('Argument needs to be an overcast.fm URL')
    mainWindow.webContents.executeJavaScript('document.getElementById("overcast_webview").src = "' + overcast_url + '"');
  }

  // Media keys shortcuts
  globalShortcut.register('MediaPreviousTrack', function () { mainWindow.webContents.send('media_keys', 'seekbackbutton') });
  globalShortcut.register('MediaNextTrack', function () { mainWindow.webContents.send('media_keys', 'seekforwardbutton'); });
  globalShortcut.register('MediaPlayPause', function () { mainWindow.webContents.send('media_keys', 'playpausebutton'); });

  // Set menu
  Menu.setApplicationMenu(Menu.buildFromTemplate(template));

  // Focus on webview when focusing on window, so we can use keyboard shortcuts
  app.on('browser-window-focus', function () {
    focus_webview();
  });

  // Prevent app from exiting (hide it instead) when window is closed (i.e. when we press the red close button)
  mainWindow.on('close', function (event) {
    event.preventDefault();
    mainWindow.hide();
    app.focus();
  });

  app.on('before-quit', function () {
    globalShortcut.unregisterAll();
    mainWindow.webContents.send('sync_podcast'); // Try to force a sync before closing

    setTimeout(function () { // Give enough time for the sync attempt to go through
      app.exit(0);
    }, 1500);
  });

  app.on('activate', function () {
    mainWindow.show();
  });
});
<|endoftext|>


<commit_before>var counter;
var header = 150;
var effectiveWindowWidth, effectiveWindowHeight;

function setup() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    var canvas = createCanvas(effectiveWindowWidth, effectiveWindowHeight);

    canvas.parent('play');
    counter = new Counter();
    counter.new();
}

function draw() {
    background(255, 255, 255);
    counter.draw();
}

function windowResized() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    resizeCanvas(effectiveWindowWidth, effectiveWindowHeight);
}

function keyTyped() {
    if (key === ' ') {
        counter.new();
    }
    if (keyCode == ENTER) {
        if (counter.isValid()) {
            var div = select('#solution');
            div.html("Right");
            counter.new();
        }
        else{
            var div = select('#solution');
            div.html("Wrong");
        }
    }
    var numbers = ["1","2","3","4","5","6","7","8","9","0"];
    if (numbers.indexOf(key) > - 1) {
        counter.guess(key);
        var div = select('#solution');
        div.html(key);
    }
}

function touchStarted() {
    if (touches.length > 0) {
        var touch = touches[0];
        if (
            touch.x >= 0 && touch.x < effectiveWindowWidth &&
            touch.y >= 0 && touch.y < effectiveWindowHeight
        )
        {
            counter.new();
        }
    }
}

function Counter () {
    this.objects = [];
    this.number = 0;
    var gap = 45;
    this.new = function () {
        this.objects = [];
        this.number = floor(random(1, 10));
        while(this.objects.length < this.number) {
            var newObject = createVector(random(gap, effectiveWindowWidth - gap), random(gap, effectiveWindowHeight - gap));

            if (this.objects.every(function(item){
                return p5.Vector.sub(item, newObject).mag() > 85;
            }))
            {
                this.objects.push(newObject);
            }
        }
        var div = select('#solution');
        div.html("Count the circles and press ENTER!");
    }

    this.draw = function() {
        for(var i = 0; i < this.objects.length; i++) {
            var object = this.objects[i];
            fill(255,0,0);
            ellipse(object.x, object.y, 80);
        }
    }

    this.guess = function(guess) {
        this.lastGuess = guess;
    }

    this.isValid = function() {
        return this.lastGuess == this.number;
    }
}<commit_msg>Maintain and display score<commit_after>var counter;
var header = 150;
var effectiveWindowWidth, effectiveWindowHeight;

function setup() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    var canvas = createCanvas(effectiveWindowWidth, effectiveWindowHeight);

    canvas.parent('play');
    counter = new Counter();
    counter.new();
}

function draw() {
    background(255, 255, 255);
    counter.draw();
}

function windowResized() {
    effectiveWindowWidth = windowWidth - 16;
    effectiveWindowHeight = windowHeight - header;
    resizeCanvas(effectiveWindowWidth, effectiveWindowHeight);
}

function keyTyped() {
    if (key === ' ') {
        counter.new();
    }
    if (keyCode == ENTER) {
        if (counter.isValid()) {
            var div = select('#solution');
            div.html("Right");
            counter.new();
            counter.win();
        }
        else{
            var div = select('#solution');
            div.html("Wrong");
            counter.loose();
        }
    }
    var numbers = ["1","2","3","4","5","6","7","8","9","0"];
    if (numbers.indexOf(key) > - 1) {
        counter.guess(key);
        var div = select('#solution');
        div.html(key);
    }
}

function touchStarted() {
    if (touches.length > 0) {
        var touch = touches[0];
        if (
            touch.x >= 0 && touch.x < effectiveWindowWidth &&
            touch.y >= 0 && touch.y < effectiveWindowHeight
        )
        {
            counter.new();
        }
    }
}

function Counter () {
    this.objects = [];
    this.score = 0;
    this.number = 0;
    var gap = 45;
    this.new = function () {
        this.objects = [];
        this.number = floor(random(1, 10));
        while(this.objects.length < this.number) {
            var newObject = createVector(random(gap, effectiveWindowWidth - gap), random(gap, effectiveWindowHeight - gap));

            if (this.objects.every(function(item){
                return p5.Vector.sub(item, newObject).mag() > 85;
            }))
            {
                this.objects.push(newObject);
            }
        }
        var div = select('#solution');
        div.html("Count the circles and press ENTER!");
    }

    this.draw = function() {
        for(var i = 0; i < this.objects.length; i++) {
            var object = this.objects[i];
            fill(255,0,0);
            ellipse(object.x, object.y, 80);
        }
        fill(0,0,0);
        textSize(30);
        text(this.score, 10, 35);
    }

    this.guess = function(guess) {
        this.lastGuess = guess;
    }

    this.isValid = function() {
        return this.lastGuess == this.number;
    }

    this.win = function() {
        this.score += 1;
    }

    this.loose = function() {
        this.score = 0;
    }
}<|endoftext|>


<commit_before>function processLike(e) {
  var $likeForm = $(this);
  var dweetId = $likeForm.data('dweet_id');
  var $likeButton = $likeForm.find('.like-button');
  var processServerResponse = function(response) {
    if (response.not_authenticated) {
      $likeForm.parent().parent().find('.error-display')[0]
        .innerText = 'You have to be logged in to vote';
    } else {
      $likeButton.find('.score-text').html(response.likes);
      if (response.liked) {
        $likeButton.addClass('liked');
      } else {
        $likeButton.removeClass('liked');
      }
    }
  };

  var config = {
    url: '/d/' + dweetId + '/like',
    dataType: 'json',
    method: 'POST',
    headers: {
      'X-CSRFToken': $likeForm.data('csrf'),
    },
    success: processServerResponse,
  };

  e.preventDefault();
  $.ajax(config);
}

function processReport(e) {
  var $reportForm;
  var dweetId;
  var commentId;
  var processServerResponse;
  var config;
  e.preventDefault();
  if (!confirm('Are you sure you want to report this to a moderator?')) {  // eslint-disable-line
    return;
  }
  $reportForm = $(this);
  dweetId = $reportForm.data('dweet_id');
  commentId = $reportForm.data('comment_id');
  processServerResponse = function(response) {
    if (response.not_authenticated) {
      alert('You have to be logged in to report.'); // eslint-disable-line
    } else {
      alert('A moderator has been notified.'); // eslint-disable-line
    }
  };

  config = {
    dataType: 'json',
    method: 'POST',
    headers: {
      'X-CSRFToken': $reportForm.data('csrf'),
    },
    success: processServerResponse,
  };

  if (dweetId) {
    config.url = '/d/' + dweetId + '/report';
  } else {
    config.url = '/c/' + commentId + '/report';
  }

  $.ajax(config);
}

function getCommentHTML(comment) {
  return '
' +
    comment.author + ': ' +
    '<form class="report" data-comment_id="' + comment.id + '">' +
      '<button type="submit" class="report-button">' +
        '
' +
          '' +
          'report' +
        '
' +
      '</button>' +
    '</form>' +
    '' + comment.urlized_text +
    '' +
    '
';
}

function postComment(e) {
  var $postForm = $(this);
  var dweetId = $postForm.data('dweet_id');
  var csrf = $postForm.data('csrf');
  var $commentText = $postForm.find('.comment-input');
  var $commentSection = $postForm.closest('.comment-section').children('.comments');

  var postCommentSuccess = function(response) {
    $commentText[0].value = '';
    $commentSection[0].innerHTML += getCommentHTML(response);
  };

  var postCommentError = function() {
    // Do nothing at the moment. TODO: Clearer error message displayed to the user?
  };

  var comment = {
    reply_to: dweetId,
    text: $commentText[0].value,
    csrfmiddlewaretoken: csrf,
  };

  var config = {
    url: '/api/comments/',
    method: 'POST',
    success: postCommentSuccess,
    error: postCommentError,
    data: comment,
  };

  e.preventDefault();
  $.ajax(config);
}

$(document).ready(function() {
  $('body').on('submit', 'form.like', processLike);
  $('body').on('submit', 'form.report', processReport);
  $('body').on('submit', '.new-comment', postComment);
});
<commit_msg>added: open links in new tab - accidentally navigating away from current page is a pita!<commit_after>function processLike(e) {
  var $likeForm = $(this);
  var dweetId = $likeForm.data('dweet_id');
  var $likeButton = $likeForm.find('.like-button');
  var processServerResponse = function(response) {
    if (response.not_authenticated) {
      $likeForm.parent().parent().find('.error-display')[0]
        .innerText = 'You have to be logged in to vote';
    } else {
      $likeButton.find('.score-text').html(response.likes);
      if (response.liked) {
        $likeButton.addClass('liked');
      } else {
        $likeButton.removeClass('liked');
      }
    }
  };

  var config = {
    url: '/d/' + dweetId + '/like',
    dataType: 'json',
    method: 'POST',
    headers: {
      'X-CSRFToken': $likeForm.data('csrf'),
    },
    success: processServerResponse,
  };

  e.preventDefault();
  $.ajax(config);
}

function processReport(e) {
  var $reportForm;
  var dweetId;
  var commentId;
  var processServerResponse;
  var config;
  e.preventDefault();
  if (!confirm('Are you sure you want to report this to a moderator?')) {  // eslint-disable-line
    return;
  }
  $reportForm = $(this);
  dweetId = $reportForm.data('dweet_id');
  commentId = $reportForm.data('comment_id');
  processServerResponse = function(response) {
    if (response.not_authenticated) {
      alert('You have to be logged in to report.'); // eslint-disable-line
    } else {
      alert('A moderator has been notified.'); // eslint-disable-line
    }
  };

  config = {
    dataType: 'json',
    method: 'POST',
    headers: {
      'X-CSRFToken': $reportForm.data('csrf'),
    },
    success: processServerResponse,
  };

  if (dweetId) {
    config.url = '/d/' + dweetId + '/report';
  } else {
    config.url = '/c/' + commentId + '/report';
  }

  $.ajax(config);
}

function getCommentHTML(comment) {
  return '
' +
    comment.author + ': ' +
    '<form class="report" data-comment_id="' + comment.id + '">' +
      '<button type="submit" class="report-button">' +
        '
' +
          '' +
          'report' +
        '
' +
      '</button>' +
    '</form>' +
    '' + comment.urlized_text.replace('href=', 'target="_blank" href=') +
    '' +
    '
';
}

function postComment(e) {
  var $postForm = $(this);
  var dweetId = $postForm.data('dweet_id');
  var csrf = $postForm.data('csrf');
  var $commentText = $postForm.find('.comment-input');
  var $commentSection = $postForm.closest('.comment-section').children('.comments');

  var postCommentSuccess = function(response) {
    $commentText[0].value = '';
    $commentSection[0].innerHTML += getCommentHTML(response);
  };

  var postCommentError = function() {
    // Do nothing at the moment. TODO: Clearer error message displayed to the user?
  };

  var comment = {
    reply_to: dweetId,
    text: $commentText[0].value,
    csrfmiddlewaretoken: csrf,
  };

  var config = {
    url: '/api/comments/',
    method: 'POST',
    success: postCommentSuccess,
    error: postCommentError,
    data: comment,
  };

  e.preventDefault();
  $.ajax(config);
}

$(document).ready(function() {
  $('body').on('submit', 'form.like', processLike);
  $('body').on('submit', 'form.report', processReport);
  $('body').on('submit', '.new-comment', postComment);
});
<|endoftext|>


<commit_before>'use strict';

const electron = require('electron');
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600});

  // and load the index.html of the app.
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  // Open the DevTools.
  mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});
<commit_msg>do not open devtools by default<commit_after>'use strict';

const electron = require('electron');
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({width: 800, height: 600});

  // and load the index.html of the app.
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  // Open the DevTools.
  // mainWindow.webContents.openDevTools();

  // Emitted when the window is closed.
  mainWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', function () {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', function () {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});
<|endoftext|>