<commit_before>IonicModule
.controller('$ionicNavView', [
  '$scope',
  '$element',
  '$attrs',
  '$ionicNavBarDelegate',
  '$ionicHistory',
  '$ionicViewSwitcher',
  '$ionicConfig',
function($scope, $element, $attrs, $ionicNavBarDelegate, $ionicHistory, $ionicViewSwitcher, $ionicConfig) {
  var self = this;
  var direction;
  var isPrimary = false;
  var navBarDelegate;

  self.init = function() {
    var navViewName = $attrs.name || '';

    // Find the details of the parent view directive (if any) and use it
    // to derive our own qualified view name, then hang our own details
    // off the DOM so child directives can find it.
    var parent = $element.parent().inheritedData('$uiView');
    var parentViewName = ((parent && parent.state) ? parent.state.name : '');
    if (navViewName.indexOf('@') < 0) navViewName  = navViewName + '@' + parentViewName;

    var viewData = { name: navViewName, state: null };
    $element.data('$uiView', viewData);

    return viewData;
  };

  self.register = function(viewLocals) {
    // register that a view is coming in and get info on how it should transition
    var isAbstractView = viewLocals && viewLocals.$$state && viewLocals.$$state.self && viewLocals.$$state.self.abstract;
    var registerData = $ionicHistory.register($scope, isAbstractView);

    // update which direction
    self.update(registerData);

    // begin rendering and transitioning
    self.render(registerData, viewLocals);
  };

  self.update = function(registerData) {
    // always reset that this is the primary navView
    isPrimary = true;

    // remember what direction this navView should use
    // this may get updated later by a child navView
    direction = registerData.direction;

    var parentNavViewCtrl = $element.parent().inheritedData('$ionNavViewController');
    if (parentNavViewCtrl) {
      // this navView is nested inside another one
      // update the parent to use this direction and not
      // the other it originally was set to

      // inform the parent navView that it is not the primary navView
      parentNavViewCtrl.isPrimary(false);

      if (direction === 'enter' || direction === 'exit') {
        // they're entering/exiting a history
        // find parent navViewController
        parentNavViewCtrl.direction(direction);

        if (direction === 'enter') {
          // reset the direction so this navView doesn't animate
          // because it's parent will
          direction = 'none';
        }
      }
    }
  };

  self.render = function(registerData, viewLocals) {
    var enteringView = $ionicHistory.getViewById(registerData.viewId) || {};

    // register the view and figure out where it lives in the various
    // histories and nav stacks, along with how views should enter/leave
    var switcher = $ionicViewSwitcher.create($scope, $element, viewLocals, enteringView);

    // init the rendering of views for this navView directive
    switcher.init(registerData, function() {
      // the view is now compiled, in the dom and linked, now lets transition the views.
      // this uses a callback incase THIS nav-view has a nested nav-view, and after the NESTED
      // nav-view links, the NESTED nav-view would update which direction THIS nav-view should use
      switcher.transition(self.direction(), registerData.showBack);
    });

  };

  self.beforeEnter = function(transData) {
    if (isPrimary) {
      // only update this nav-view's nav-bar if this is the primary nav-view
      navBarDelegate = transData.navBarDelegate;
      var associatedNavBarCtrl = getAssociatedNavBarCtrl();
      associatedNavBarCtrl && associatedNavBarCtrl.update(transData);
    }
  };

  self.showBar = function(val) {
    var associatedNavBarCtrl = getAssociatedNavBarCtrl();
    associatedNavBarCtrl && associatedNavBarCtrl.showBar(val);
  };

  self.showBackButton = function(val) {
    var associatedNavBarCtrl = getAssociatedNavBarCtrl();
    associatedNavBarCtrl && associatedNavBarCtrl.showBackButton(val);
  };

  self.isPrimary = function(val) {
    if (arguments.length) {
      isPrimary = val;
    }
    return isPrimary;
  };

  self.direction = function(val) {
    if (arguments.length) {
      direction = val;
    }
    return direction;
  };

  function getAssociatedNavBarCtrl() {
    if (navBarDelegate) {
      for (var x=0; x < $ionicNavBarDelegate._instances.length; x++) {
        if ($ionicNavBarDelegate._instances[x].$$delegateHandle == navBarDelegate) {
          return $ionicNavBarDelegate._instances[x];
        }
      }
    }
    return $element.inheritedData('$ionNavBarController');
  }

}]);
<commit_msg>fix(navViewController): create navBarCtrl.title<commit_after>IonicModule
.controller('$ionicNavView', [
  '$scope',
  '$element',
  '$attrs',
  '$ionicNavBarDelegate',
  '$ionicHistory',
  '$ionicViewSwitcher',
  '$ionicConfig',
function($scope, $element, $attrs, $ionicNavBarDelegate, $ionicHistory, $ionicViewSwitcher, $ionicConfig) {
  var self = this;
  var direction;
  var isPrimary = false;
  var navBarDelegate;

  self.init = function() {
    var navViewName = $attrs.name || '';

    // Find the details of the parent view directive (if any) and use it
    // to derive our own qualified view name, then hang our own details
    // off the DOM so child directives can find it.
    var parent = $element.parent().inheritedData('$uiView');
    var parentViewName = ((parent && parent.state) ? parent.state.name : '');
    if (navViewName.indexOf('@') < 0) navViewName  = navViewName + '@' + parentViewName;

    var viewData = { name: navViewName, state: null };
    $element.data('$uiView', viewData);

    return viewData;
  };

  self.register = function(viewLocals) {
    // register that a view is coming in and get info on how it should transition
    var isAbstractView = viewLocals && viewLocals.$$state && viewLocals.$$state.self && viewLocals.$$state.self.abstract;
    var registerData = $ionicHistory.register($scope, isAbstractView);

    // update which direction
    self.update(registerData);

    // begin rendering and transitioning
    self.render(registerData, viewLocals);
  };

  self.update = function(registerData) {
    // always reset that this is the primary navView
    isPrimary = true;

    // remember what direction this navView should use
    // this may get updated later by a child navView
    direction = registerData.direction;

    var parentNavViewCtrl = $element.parent().inheritedData('$ionNavViewController');
    if (parentNavViewCtrl) {
      // this navView is nested inside another one
      // update the parent to use this direction and not
      // the other it originally was set to

      // inform the parent navView that it is not the primary navView
      parentNavViewCtrl.isPrimary(false);

      if (direction === 'enter' || direction === 'exit') {
        // they're entering/exiting a history
        // find parent navViewController
        parentNavViewCtrl.direction(direction);

        if (direction === 'enter') {
          // reset the direction so this navView doesn't animate
          // because it's parent will
          direction = 'none';
        }
      }
    }
  };

  self.render = function(registerData, viewLocals) {
    var enteringView = $ionicHistory.getViewById(registerData.viewId) || {};

    // register the view and figure out where it lives in the various
    // histories and nav stacks, along with how views should enter/leave
    var switcher = $ionicViewSwitcher.create($scope, $element, viewLocals, enteringView);

    // init the rendering of views for this navView directive
    switcher.init(registerData, function() {
      // the view is now compiled, in the dom and linked, now lets transition the views.
      // this uses a callback incase THIS nav-view has a nested nav-view, and after the NESTED
      // nav-view links, the NESTED nav-view would update which direction THIS nav-view should use
      switcher.transition(self.direction(), registerData.showBack);
    });

  };

  self.beforeEnter = function(transData) {
    if (isPrimary) {
      // only update this nav-view's nav-bar if this is the primary nav-view
      navBarDelegate = transData.navBarDelegate;
      var associatedNavBarCtrl = getAssociatedNavBarCtrl();
      associatedNavBarCtrl && associatedNavBarCtrl.update(transData);
    }
  };

  self.title = function(val) {
    var associatedNavBarCtrl = getAssociatedNavBarCtrl();
    associatedNavBarCtrl && associatedNavBarCtrl.title(val);
  };

  self.showBackButton = function(val) {
    var associatedNavBarCtrl = getAssociatedNavBarCtrl();
    associatedNavBarCtrl && associatedNavBarCtrl.showBackButton(val);
  };

  self.showBar = function(val) {
    var associatedNavBarCtrl = getAssociatedNavBarCtrl();
    associatedNavBarCtrl && associatedNavBarCtrl.showBar(val);
  };

  self.isPrimary = function(val) {
    if (arguments.length) {
      isPrimary = val;
    }
    return isPrimary;
  };

  self.direction = function(val) {
    if (arguments.length) {
      direction = val;
    }
    return direction;
  };

  function getAssociatedNavBarCtrl() {
    if (navBarDelegate) {
      for (var x=0; x < $ionicNavBarDelegate._instances.length; x++) {
        if ($ionicNavBarDelegate._instances[x].$$delegateHandle == navBarDelegate) {
          return $ionicNavBarDelegate._instances[x];
        }
      }
    }
    return $element.inheritedData('$ionNavBarController');
  }

}]);
<|endoftext|>


<commit_before>/* exported ArticlesForSet */

// Copyright 2016 Endless Mobile, Inc.

const Module = imports.app.interfaces.module;
const Pages = imports.app.pages;
const QueryObject = imports.search.queryObject;
const Xapian = imports.app.modules.selection.xapian;

const ArticleContext = new Module.Class({
    Name: 'Selection.ArticleContext',
    Extends: Xapian.Xapian,

    _init: function (props={}) {
        this.parent(props);
        this._item = {};
    },

    // Selection.Xapian implementation
    on_history_changed: function (history) {
        let item = history.get_current_item();
        if (!item)
            return;

        if ((item.query && item.query !== this._item.query) ||
            (item.page_type === Pages.SET && this._item.model != item.model)) {
            this._item = item;
            this._set_needs_refresh(true);
        }
    },

    construct_query_object: function (limit, query_index) {
        if (query_index > 0)
            return null;

        if (this._item.query) {
            return new QueryObject.QueryObject({
                limit: limit,
                query: this._item.query,
                tags_match_all: ['EknArticleObject'],
            });
        } else if (this._item.page_type === Pages.SET) {
            return new QueryObject.QueryObject({
                limit: limit,
                tags_match_all: ['EknArticleObject'],
                tags_match_any: this._item.model.child_tags,
            });
        } else {
            return null;
        }
        return null;
    },
});
<commit_msg>ArticleContext: sort by sequence number<commit_after>/* exported ArticlesForSet */

// Copyright 2016 Endless Mobile, Inc.

const Module = imports.app.interfaces.module;
const Pages = imports.app.pages;
const QueryObject = imports.search.queryObject;
const Xapian = imports.app.modules.selection.xapian;

const ArticleContext = new Module.Class({
    Name: 'Selection.ArticleContext',
    Extends: Xapian.Xapian,

    _init: function (props={}) {
        this.parent(props);
        this._item = {};
    },

    // Selection.Xapian implementation
    on_history_changed: function (history) {
        let item = history.get_current_item();
        if (!item)
            return;

        if ((item.query && item.query !== this._item.query) ||
            (item.page_type === Pages.SET && this._item.model != item.model)) {
            this._item = item;
            this._set_needs_refresh(true);
        }
    },

    construct_query_object: function (limit, query_index) {
        if (query_index > 0)
            return null;

        if (this._item.query) {
            return new QueryObject.QueryObject({
                limit: limit,
                query: this._item.query,
                tags_match_all: ['EknArticleObject'],
            });
        } else if (this._item.page_type === Pages.SET) {
            return new QueryObject.QueryObject({
                limit: limit,
                tags_match_all: ['EknArticleObject'],
                tags_match_any: this._item.model.child_tags,
                sort: QueryObject.QueryObjectSort.SEQUENCE_NUMBER,
            });
        } else {
            return null;
        }
        return null;
    },
});
<|endoftext|>


<commit_before>function iframeLoaded($iframe) {
	document.title = $iframe.contents().find('title').text();
	$('div').remove();

	if($iframe.contents().find('head base').length == 0) {
		$iframe.contents().find('head').prepend($('<head>'));
	}
	$iframe.contents().find('head base').attr('target', '_parent');

	setIframeHeight($iframe);
	setInterval(function() {
		setIframeHeight($iframe);
	}, 1000);
}

function setIframeHeight($iframe) {
	var targetHeight = $(window).height();
	if($iframe[0].contentWindow.window.document.body != null) {
		targetHeight = Math.max(
				targetHeight,
				$iframe[0].contentWindow.window.document.body.scrollHeight
		);
	}

	var actualHeight = $iframe.height()
	+ parseInt($iframe.contents().find('body').css('margin-top'))
	+ parseInt($iframe.contents().find('body').css('padding-top'))
	+ parseInt($iframe.contents().find('body').css('padding-bottom'))
	+ parseInt($iframe.contents().find('body').css('margin-bottom'));

	if(targetHeight > actualHeight || targetHeight < (actualHeight - 100)) {
		$iframe.height(targetHeight + 10);
	}
}

if (!window.console) {
	console = {	log : function() {}	};
}

if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function (str){
		return this.lastIndexOf(str, 0) === 0;
	};
}

var base_url = "";
var relative_url = "";
for(var i in alt_base_urls) {
	if(window.location.href.startsWith(alt_base_urls[i])) {
		base_url = alt_base_urls[i];
		relative_url = window.location.href.substring(alt_base_urls[i].length);
		break;
	}
}

$('iframe').height($(window).height());

var done = false;
$('iframe').load(function() {
	if(!done) {
		try {
			if($(this).contents().length > 0) {
				done = true;
				iframeLoaded($(this));
				return;
			}
		} catch (e) {
		}
	}
});

var ifrInt = setInterval(function() {
	if(!done && $('iframe').contents().find('p').length > 0) {
		done = true;
		iframeLoaded($('iframe'));
		clearInterval(ifrInt);
	}
}, 1000);

setTimeout(function() {
	if(!done) {
		console.log('emergency!');
		$('li a').each(function() {
			window.location = $(this).attr('href');
		});
	}
}, 20000);

for(var i in alt_base_urls) {
	(function(alt_base_url) {
		if(window.location.href.startsWith(alt_base_url)) {
			return;
		}

		var alt_url = alt_base_url + relative_url;

		var alt_url_parser = document.createElement('a');
		alt_url_parser.href = alt_url;
		if(alt_url_parser.search) {
			alt_url += '&';
		} else {
			alt_url += '?';
		}
		alt_url += get_param_name + '=' + output_type_jsonp + encodeURIComponent(alt_base_url);

		$.ajax({
			dataType: 'jsonp',
			url: alt_url
		}).success(function(data) {
			if(!done && data && data.html) {
				done = true;
				console.log(alt_url + ' succeeded');
				$iframe = $('iframe').clone();
				$('iframe').remove();
				$iframe.attr('src', '');
				$('body').append($iframe);

				var iframeDoc = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
				iframeDoc.open();
				iframeDoc.write(data.html);
				iframeDoc.close();

				iframeLoaded($iframe);
			}
		});
	})(alt_base_urls[i]);
}<commit_msg>better js check that data.html is set<commit_after>function iframeLoaded($iframe) {
	document.title = $iframe.contents().find('title').text();
	$('div').remove();

	if($iframe.contents().find('head base').length == 0) {
		$iframe.contents().find('head').prepend($('<head>'));
	}
	$iframe.contents().find('head base').attr('target', '_parent');

	setIframeHeight($iframe);
	setInterval(function() {
		setIframeHeight($iframe);
	}, 1000);
}

function setIframeHeight($iframe) {
	var targetHeight = $(window).height();
	if($iframe[0].contentWindow.window.document.body != null) {
		targetHeight = Math.max(
				targetHeight,
				$iframe[0].contentWindow.window.document.body.scrollHeight
		);
	}

	var actualHeight = $iframe.height()
	+ parseInt($iframe.contents().find('body').css('margin-top'))
	+ parseInt($iframe.contents().find('body').css('padding-top'))
	+ parseInt($iframe.contents().find('body').css('padding-bottom'))
	+ parseInt($iframe.contents().find('body').css('margin-bottom'));

	if(targetHeight > actualHeight || targetHeight < (actualHeight - 100)) {
		$iframe.height(targetHeight + 10);
	}
}

if (!window.console) {
	console = {	log : function() {}	};
}

if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function (str){
		return this.lastIndexOf(str, 0) === 0;
	};
}

var base_url = "";
var relative_url = "";
for(var i in alt_base_urls) {
	if(window.location.href.startsWith(alt_base_urls[i])) {
		base_url = alt_base_urls[i];
		relative_url = window.location.href.substring(alt_base_urls[i].length);
		break;
	}
}

$('iframe').height($(window).height());

var done = false;
$('iframe').load(function() {
	if(!done) {
		try {
			if($(this).contents().length > 0) {
				done = true;
				iframeLoaded($(this));
				return;
			}
		} catch (e) {
		}
	}
});

var ifrInt = setInterval(function() {
	if(!done && $('iframe').contents().find('p').length > 0) {
		done = true;
		iframeLoaded($('iframe'));
		clearInterval(ifrInt);
	}
}, 1000);

setTimeout(function() {
	if(!done) {
		console.log('emergency!');
		$('li a').each(function() {
			window.location = $(this).attr('href');
		});
	}
}, 20000);

for(var i in alt_base_urls) {
	(function(alt_base_url) {
		if(window.location.href.startsWith(alt_base_url)) {
			return;
		}

		var alt_url = alt_base_url + relative_url;

		var alt_url_parser = document.createElement('a');
		alt_url_parser.href = alt_url;
		if(alt_url_parser.search) {
			alt_url += '&';
		} else {
			alt_url += '?';
		}
		alt_url += get_param_name + '=' + output_type_jsonp + encodeURIComponent(alt_base_url);

		$.ajax({
			dataType: 'jsonp',
			url: alt_url
		}).success(function(data) {
			if(!done && typeof data.html !== 'undefined') {
				done = true;
				console.log(alt_url + ' succeeded');
				$iframe = $('iframe').clone();
				$('iframe').remove();
				$iframe.attr('src', '');
				$('body').append($iframe);

				var iframeDoc = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
				iframeDoc.open();
				iframeDoc.write(data.html);
				iframeDoc.close();

				iframeLoaded($iframe);
			}
		});
	})(alt_base_urls[i]);
}<|endoftext|>


<commit_before>/* @flow */
var React = require('react');
var AppActions = require('../actions.js');
var PlayerCell = require('./player_cell.js');
var Nav = require('react-bootstrap/Nav');
var Table = require('react-bootstrap/Table');
var Panel = require('react-bootstrap/Panel');
var Row = require('react-bootstrap/Row');
var Col = require('react-bootstrap/Col');
var ButtonGroup = require('react-bootstrap/ButtonGroup');
var Button = require('react-bootstrap/Button');
var PageHeader = require('react-bootstrap/PageHeader');

var GameRow = React.createClass({
	propTypes: {
		players: React.PropTypes.array.isRequired,
		weekNumber: React.PropTypes.number.isRequired,
		gameIndex: React.PropTypes.number,
		game: React.PropTypes.object,
		admin: React.PropTypes.bool
	},
	addGame: function(weekNumber, gameIndex) {
		return function() {
			var player1Name = this.refs.player1.getDOMNode().value;
			var player2Name = this.refs.player2.getDOMNode().value;
			var winnerNumber = this.refs.winner.getDOMNode().value;
			var winner = null;
			if(winnerNumber == 1)
				winner = player1Name;
			if(winnerNumber == 2)
				winner = player2Name;
			if(gameIndex !== null) {
				AppActions.updateGame(weekNumber, gameIndex, player1Name, player2Name, winner);
			} else {
				AppActions.addGame(weekNumber, player1Name, player2Name, winner);
			}
		}.bind(this);
	},
	deleteGame: function(weekNumber, gameIndex) {
		return function() {
			if(confirm('Are you sure you want to delete this game?')) {
				AppActions.deleteGame(weekNumber, gameIndex);
			}
		};
	},
	render: function() {
		var game = this.props.game;
		var player1 = game && game.Players[0];
		var player2 = game && game.Players[1];
		var winner = null;
		if(game && game.Winner) {
			if(game.Winner == player1)
				winner = 1;
			if(game.Winner == player2)
				winner = 2;
		}
		var admin = this.props.admin;
		var player1Options = this.props.players.map(function(player) { return <option key={player.Name}>{player.Name}</option>; });
		var player2Options = this.props.players.map(function(player) { return <option key={player.Name}>{player.Name}</option>; });
		if (admin) {
			var deleteButton = null;
			if(game) {
					deleteButton = <Button onClick={this.deleteGame(this.props.weekNumber, this.props.gameIndex)} bsStyle="danger">Delete</Button>;
			}
			return (

						<select ref="player1" defaultValue={player1 && player1.Name}>
							<option value="">-</option>
							{player1Options}
						</select>

						<select ref="player2" defaultValue={player2 && player2.Name}>
							<option value="">-</option>
							{player2Options}
						</select>

						<select ref="winner" defaultValue={winner}>
							<option value="">-</option>
							<option value={1}>Player 1</option>
							<option value={2}>Player 2</option>
						</select>

						<Button onClick={this.addGame(this.props.weekNumber, this.props.gameIndex)} bsStyle={game ? "default" : "warning"}>
							{game ? "Update" : "Add"}
						</Button>
						{deleteButton}

			);
		}
		return (

				<PlayerCell player={player1} />
				<PlayerCell player={player2} />
				<PlayerCell player={game && game.Winner} />

		);
	}
});

var WeekTable = React.createClass({
	propTypes: {
		players: React.PropTypes.array.isRequired,
		weekNumber: React.PropTypes.number.isRequired,
		week: React.PropTypes.object.isRequired,
		admin: React.PropTypes.bool,
	},
	render: function() {
		var rows = this.props.week.Games.map(function(game, i) {
			return <GameRow game={game} weekNumber={this.props.weekNumber}
				key={this.props.weekNumber + "-" + i + "-" + game.Players.join("-") + "-" + game.Winner}
				admin={this.props.admin}
				gameIndex={i}
				players={this.props.players} />;
		}.bind(this));
		var opsColumn = "";
		var addGameRow = "";
		if(this.props.admin) {
			opsColumn = 	;
			addGameRow = <GameRow weekNumber={this.props.weekNumber} key="add" admin={this.props.admin} players={this.props.players} />;
		}
		return (

					Player 1
					Player 2
					Winner
					{opsColumn}

					{rows}
					{addGameRow}

		);
	}
});

var WeekEditor = React.createClass({
	propTypes: {
		week: React.PropTypes.object,
		submitCallback: React.PropTypes.func.isRequired,
		cancelCallback: React.PropTypes.func,
	},
	updateWeek: function() {
		this.props.submitCallback(this.refs.playDate.getDOMNode().value, this.refs.scenarios.getDOMNode().value);
	},
	render: function() {
		var dateDefault = "";
		var cancelLink = this.props.cancelCallback &&  Cancel;
		var week = this.props.week;

		function pad(number) { return number < 10 ? '0' + number : number; }

		if(week) {
			var playDate = week.PlayDate;
			if(playDate) {
				playDate = new Date(playDate);
				dateDefault = playDate.getFullYear() + '-' + pad(playDate.getMonth() + 1) + '-' + pad(playDate.getDate());
			}
		}
		return (
			<Panel className="text-left">

					Play Date
					<input id="play-date" className="form-control" type="date" ref="playDate" placeholder="YYYY-MM-DD"
						defaultValue={dateDefault}  />

					Scenarios (comma separated)
					<input id="scenarios" className="form-control" type="text" ref="scenarios" pattern="((\d+)(,\d+)*)?"
						defaultValue={week && week.Scenarios && week.Scenarios.join(",")} />

				<Button onClick={this.updateWeek}>Submit</Button>
				{cancelLink}
			</Panel>
		);
	}
});

var WeekGroup = React.createClass({
	propTypes: {
		players: React.PropTypes.array.isRequired,
		weekNumber: React.PropTypes.number.isRequired,
		week: React.PropTypes.object.isRequired,
		admin: React.PropTypes.bool,
	},
	getInitialState: function() {
		return { showWeekEditor: false };
	},
	componentDidUpdate: function(prevProps) {
		if(prevProps.week != this.props.week) this.hideEditor();
	},
	updateWeek: function(weekNumber) {
		return function(playDate, scenarios) {
			AppActions.updateWeek(weekNumber, playDate, scenarios);
			this.hideEditor();
		}.bind(this);
	},
	showEditor: function() {
		this.setState({showWeekEditor: true});
	},
	hideEditor: function() {
		this.setState({showWeekEditor: false});
	},
	deleteWeek: function() {
		if(window.confirm("Are you sure you want to delete this week?")) {
			AppActions.deleteWeek(this.props.weekNumber);
			AppActions.viewWeek(1);
		}
	},
	scrollToSchedule: function() {
		this.refs.weekGroup.getDOMNode().scrollIntoView();
	},
	render: function() {
		var admin = this.props.admin;
		var weekEdit = null;
		if(admin) {
			if(this.state.showWeekEditor) {
				weekEdit = <WeekEditor week={this.props.week} cancelCallback={this.hideEditor} submitCallback={this.updateWeek(this.props.weekNumber)} />;
			} else {
				weekEdit = (

						<Button onClick={this.showEditor}>Edit Week</Button>
						<Button onClick={this.deleteWeek} bsStyle="danger">Delete Week</Button>

				);
			}
		}
		return (

				{weekEdit}
				<WeekTable week={this.props.week} weekNumber={this.props.weekNumber} admin={this.props.admin} players={this.props.players} />

		);
	}
});

module.exports = React.createClass({
	propTypes: {
		season: React.PropTypes.object.isRequired,
		admin: React.PropTypes.bool,
		activeWeekNumber: React.PropTypes.number.isRequired,
	},
	getInitialState: function() {
		return { showAddWeek: false };
	},
	// scroll to the schedule. useful when the schedule is below the button group, when the display width is small
	scrollToSchedule: function() {
		this.refs.weekGroup.scrollToSchedule();
	},
	viewWeek: function(weekNumber: number): Function {
		return function() {
			this.hideAddWeek();
			AppActions.viewWeek(weekNumber);
		}.bind(this);
	},
	showAddWeek: function() {
		this.setState({ showAddWeek: true });
	},
	hideAddWeek: function() {
		this.setState({ showAddWeek: false });
	},
	addWeek: function(playDate: string, scenarios: string) {
		AppActions.addWeek(playDate, scenarios);
		this.hideAddWeek();
	},
	render: function(): ?ReactElement {
		var activeWeek = this.props.season.Weeks[this.props.activeWeekNumber - 1];
		var admin = this.props.admin;
		var navButtons = this.props.season.Weeks.map(function(week, i) {
			var header = "Week " + (i+1);
			var playDateHtml = null;
			var scenariosHtml = null;
			var active = !this.state.showAddWeek && this.props.activeWeekNumber == i+1;
			if(week.PlayDate)
				playDateHtml =
{new Date(week.PlayDate).toLocaleDateString()};
			if(week.Scenarios)
				scenariosHtml =
Scenarios: {week.Scenarios.join(", ")};
			return (
				<Button active={active} onClick={this.viewWeek(i+1)}>
					Week {header}
					{playDateHtml}
					{scenariosHtml}
				</Button>
			);
		}.bind(this));
		var addWeekButton = "";
		if(admin) {
			addWeekButton = <Button onClick={this.showAddWeek}>Add Week</Button>;
		}
		var content;
		if(this.state.showAddWeek) {
			content =

Add Week

				<WeekEditor cancelCallback={this.hideAddWeek} submitCallback={this.addWeek} />

;
		} else {
			content = <WeekGroup ref="weekGroup" weekNumber={this.props.activeWeekNumber} week={activeWeek} admin={admin} players={this.props.season.Players} />;
		}
		return (

				<Row className="text-center">
					<PageHeader>{this.props.season.Name + " (" + this.props.season.Year + ")"}</PageHeader>
				</Row>
				<Row>
					<Col sm={2} xs={12}>
						<ButtonGroup vertical style={{width: "100%"}}>
							{navButtons}
							{addWeekButton}
						</ButtonGroup>
					</Col>
					<Col sm={10} xs={12}>
						{content}
					</Col>
				</Row>

		);
	}
});
<commit_msg>Show players' names in the winner select box instead of Player 1 and Player 2.<commit_after>/* @flow */
var React = require('react');
var AppActions = require('../actions.js');
var PlayerCell = require('./player_cell.js');
var Nav = require('react-bootstrap/Nav');
var Table = require('react-bootstrap/Table');
var Panel = require('react-bootstrap/Panel');
var Row = require('react-bootstrap/Row');
var Col = require('react-bootstrap/Col');
var ButtonGroup = require('react-bootstrap/ButtonGroup');
var Button = require('react-bootstrap/Button');
var PageHeader = require('react-bootstrap/PageHeader');

var GameRow = React.createClass({
	propTypes: {
		players: React.PropTypes.array.isRequired,
		weekNumber: React.PropTypes.number.isRequired,
		gameIndex: React.PropTypes.number,
		game: React.PropTypes.object,
		admin: React.PropTypes.bool
	},
	getInitialState: function() {
		var game = this.props.game;
		return {
			player1: game && game.Players[0] && game.Players[0].Name,
			player2: game && game.Players[1] && game.Players[1].Name
		};
	},
	addGame: function(weekNumber, gameIndex) {
		return function() {
			var player1Name = this.refs.player1.getDOMNode().value;
			var player2Name = this.refs.player2.getDOMNode().value;
			var winnerNumber = this.refs.winner.getDOMNode().value;
			var winner = null;
			if(winnerNumber == 1)
				winner = player1Name;
			if(winnerNumber == 2)
				winner = player2Name;
			if(gameIndex !== null) {
				AppActions.updateGame(weekNumber, gameIndex, player1Name, player2Name, winner);
			} else {
				AppActions.addGame(weekNumber, player1Name, player2Name, winner);
			}
		}.bind(this);
	},
	deleteGame: function(weekNumber, gameIndex) {
		return function() {
			if(confirm('Are you sure you want to delete this game?')) {
				AppActions.deleteGame(weekNumber, gameIndex);
			}
		};
	},
	player1Change: function() {
		this.setState({player1: this.refs.player1.getDOMNode().value});
	},
	player2Change: function() {
		this.setState({player2: this.refs.player2.getDOMNode().value});
	},
	render: function() {
		var game = this.props.game;
		var player1 = game && game.Players[0];
		var player2 = game && game.Players[1];
		var winner = null;
		if(game && game.Winner) {
			if(game.Winner == player1)
				winner = 1;
			if(game.Winner == player2)
				winner = 2;
		}
		var admin = this.props.admin;
		var player1Options = this.props.players.map(function(player) { return <option key={player.Name}>{player.Name}</option>; });
		var player2Options = this.props.players.map(function(player) { return <option key={player.Name}>{player.Name}</option>; });
		if (admin) {
			var deleteButton = null;
			if(game) {
					deleteButton = <Button onClick={this.deleteGame(this.props.weekNumber, this.props.gameIndex)} bsStyle="danger">Delete</Button>;
			}
			return (

						<select ref="player1" defaultValue={player1 && player1.Name} onChange={this.player1Change}>
							<option value="">-</option>
							{player1Options}
						</select>

						<select ref="player2" defaultValue={player2 && player2.Name} onChange={this.player2Change}>
							<option value="">-</option>
							{player2Options}
						</select>

						<select ref="winner" defaultValue={winner}>
							<option value="">-</option>
							<option value={1}>{this.state.player1 || "-"}</option>
							<option value={2}>{this.state.player2 || "-"}</option>
						</select>

						<Button onClick={this.addGame(this.props.weekNumber, this.props.gameIndex)} bsStyle={game ? "default" : "warning"}>
							{game ? "Update" : "Add"}
						</Button>
						{deleteButton}

			);
		}
		return (

				<PlayerCell player={player1} />
				<PlayerCell player={player2} />
				<PlayerCell player={game && game.Winner} />

		);
	}
});

var WeekTable = React.createClass({
	propTypes: {
		players: React.PropTypes.array.isRequired,
		weekNumber: React.PropTypes.number.isRequired,
		week: React.PropTypes.object.isRequired,
		admin: React.PropTypes.bool,
	},
	render: function() {
		var rows = this.props.week.Games.map(function(game, i) {
			return <GameRow game={game} weekNumber={this.props.weekNumber}
				key={this.props.weekNumber + "-" + i + "-" + game.Players.join("-") + "-" + game.Winner}
				admin={this.props.admin}
				gameIndex={i}
				players={this.props.players} />;
		}.bind(this));
		var opsColumn = "";
		var addGameRow = "";
		if(this.props.admin) {
			opsColumn = 	;
			addGameRow = <GameRow weekNumber={this.props.weekNumber} key="add" admin={this.props.admin} players={this.props.players} />;
		}
		return (

					Player 1
					Player 2
					Winner
					{opsColumn}

					{rows}
					{addGameRow}

		);
	}
});

var WeekEditor = React.createClass({
	propTypes: {
		week: React.PropTypes.object,
		submitCallback: React.PropTypes.func.isRequired,
		cancelCallback: React.PropTypes.func,
	},
	updateWeek: function() {
		this.props.submitCallback(this.refs.playDate.getDOMNode().value, this.refs.scenarios.getDOMNode().value);
	},
	render: function() {
		var dateDefault = "";
		var cancelLink = this.props.cancelCallback &&  Cancel;
		var week = this.props.week;

		function pad(number) { return number < 10 ? '0' + number : number; }

		if(week) {
			var playDate = week.PlayDate;
			if(playDate) {
				playDate = new Date(playDate);
				dateDefault = playDate.getFullYear() + '-' + pad(playDate.getMonth() + 1) + '-' + pad(playDate.getDate());
			}
		}
		return (
			<Panel className="text-left">

					Play Date
					<input id="play-date" className="form-control" type="date" ref="playDate" placeholder="YYYY-MM-DD"
						defaultValue={dateDefault}  />

					Scenarios (comma separated)
					<input id="scenarios" className="form-control" type="text" ref="scenarios" pattern="((\d+)(,\d+)*)?"
						defaultValue={week && week.Scenarios && week.Scenarios.join(",")} />

				<Button onClick={this.updateWeek}>Submit</Button>
				{cancelLink}
			</Panel>
		);
	}
});

var WeekGroup = React.createClass({
	propTypes: {
		players: React.PropTypes.array.isRequired,
		weekNumber: React.PropTypes.number.isRequired,
		week: React.PropTypes.object.isRequired,
		admin: React.PropTypes.bool,
	},
	getInitialState: function() {
		return { showWeekEditor: false };
	},
	componentDidUpdate: function(prevProps) {
		if(prevProps.week != this.props.week) this.hideEditor();
	},
	updateWeek: function(weekNumber) {
		return function(playDate, scenarios) {
			AppActions.updateWeek(weekNumber, playDate, scenarios);
			this.hideEditor();
		}.bind(this);
	},
	showEditor: function() {
		this.setState({showWeekEditor: true});
	},
	hideEditor: function() {
		this.setState({showWeekEditor: false});
	},
	deleteWeek: function() {
		if(window.confirm("Are you sure you want to delete this week?")) {
			AppActions.deleteWeek(this.props.weekNumber);
			AppActions.viewWeek(1);
		}
	},
	scrollToSchedule: function() {
		this.refs.weekGroup.getDOMNode().scrollIntoView();
	},
	render: function() {
		var admin = this.props.admin;
		var weekEdit = null;
		if(admin) {
			if(this.state.showWeekEditor) {
				weekEdit = <WeekEditor week={this.props.week} cancelCallback={this.hideEditor} submitCallback={this.updateWeek(this.props.weekNumber)} />;
			} else {
				weekEdit = (

						<Button onClick={this.showEditor}>Edit Week</Button>
						<Button onClick={this.deleteWeek} bsStyle="danger">Delete Week</Button>

				);
			}
		}
		return (

				{weekEdit}
				<WeekTable week={this.props.week} weekNumber={this.props.weekNumber} admin={this.props.admin} players={this.props.players} />

		);
	}
});

module.exports = React.createClass({
	propTypes: {
		season: React.PropTypes.object.isRequired,
		admin: React.PropTypes.bool,
		activeWeekNumber: React.PropTypes.number.isRequired,
	},
	getInitialState: function() {
		return { showAddWeek: false };
	},
	// scroll to the schedule. useful when the schedule is below the button group, when the display width is small
	scrollToSchedule: function() {
		this.refs.weekGroup.scrollToSchedule();
	},
	viewWeek: function(weekNumber: number): Function {
		return function() {
			this.hideAddWeek();
			AppActions.viewWeek(weekNumber);
		}.bind(this);
	},
	showAddWeek: function() {
		this.setState({ showAddWeek: true });
	},
	hideAddWeek: function() {
		this.setState({ showAddWeek: false });
	},
	addWeek: function(playDate: string, scenarios: string) {
		AppActions.addWeek(playDate, scenarios);
		this.hideAddWeek();
	},
	render: function(): ?ReactElement {
		var activeWeek = this.props.season.Weeks[this.props.activeWeekNumber - 1];
		var admin = this.props.admin;
		var navButtons = this.props.season.Weeks.map(function(week, i) {
			var header = "Week " + (i+1);
			var playDateHtml = null;
			var scenariosHtml = null;
			var active = !this.state.showAddWeek && this.props.activeWeekNumber == i+1;
			if(week.PlayDate)
				playDateHtml =
{new Date(week.PlayDate).toLocaleDateString()};
			if(week.Scenarios)
				scenariosHtml =
Scenarios: {week.Scenarios.join(", ")};
			return (
				<Button active={active} onClick={this.viewWeek(i+1)}>
					Week {header}
					{playDateHtml}
					{scenariosHtml}
				</Button>
			);
		}.bind(this));
		var addWeekButton = "";
		if(admin) {
			addWeekButton = <Button onClick={this.showAddWeek}>Add Week</Button>;
		}
		var content;
		if(this.state.showAddWeek) {
			content =

Add Week

				<WeekEditor cancelCallback={this.hideAddWeek} submitCallback={this.addWeek} />

;
		} else {
			content = <WeekGroup ref="weekGroup" weekNumber={this.props.activeWeekNumber} week={activeWeek} admin={admin} players={this.props.season.Players} />;
		}
		return (

				<Row className="text-center">
					<PageHeader>{this.props.season.Name + " (" + this.props.season.Year + ")"}</PageHeader>
				</Row>
				<Row>
					<Col sm={2} xs={12}>
						<ButtonGroup vertical style={{width: "100%"}}>
							{navButtons}
							{addWeekButton}
						</ButtonGroup>
					</Col>
					<Col sm={10} xs={12}>
						{content}
					</Col>
				</Row>

		);
	}
});
<|endoftext|>


<commit_before>'use strict';

var app = app || {};

(function (module){
  const graph = {};
  graph.closePrice = [];
  graph.labels = [];

  graph.createGraph = () => {
    $('#stock-graph').replaceWith('<canvas id="stock-graph"></canvas>'); // this will replace the current graph with the new one coming in
    let ctx = $('#stock-graph')[0].getContext('2d');
    graph.closePrice = []; // reset data arrays when changing date
    graph.labels = [];
    app.stock.stockData.results.forEach((dataPoint) => {
      graph.labels.push(dataPoint.tradingDay);
      graph.closePrice.push(dataPoint.close);
    });

    let min = graph.closePrice.reduce((cur, next) => {
      return Math.min(cur, next);
    });
    let max = graph.closePrice.reduce((cur, next) => {
      return Math.max(cur, next);
    });

    Chart.scaleService.updateScaleDefaults('linear', {
      ticks: { // graph range will be 10% below min to 10% above max
        min: Math.ceil((min - (min * 0.1)) / 10) * 10, // these 2 get rounded to the nearest 10
        max: Math.ceil((max + (max * 0.1)) / 10) * 10
      }
    });
    new Chart(ctx, {
      type: 'line',
      data: {
        labels: graph.labels,
        datasets: [{
          data: graph.closePrice,
        }],
      },
      options: {
        responsive: true,
        maintainAspectRatio: true,
      }
      // options:options,
    });
  };

  graph.changeStartDate = () => {
    app.stock.getStockInfo(app.stock.ticker, $('#graph-start-date').val(), app.stockView.index);
  };

  module.graph = graph;

})(app);
<commit_msg>graph color mods<commit_after>'use strict';

var app = app || {};

(function (module){
  const graph = {};
  graph.closePrice = [];
  graph.labels = [];

  graph.createGraph = () => {
    $('#stock-graph').replaceWith('<canvas id="stock-graph"></canvas>'); // this will replace the current graph with the new one coming in
    let ctx = $('#stock-graph')[0].getContext('2d');
    graph.closePrice = []; // reset data arrays when changing date
    graph.labels = [];
    app.stock.stockData.results.forEach((dataPoint) => {
      graph.labels.push(dataPoint.tradingDay);
      graph.closePrice.push(dataPoint.close);
    });

    let min = graph.closePrice.reduce((cur, next) => {
      return Math.min(cur, next);
    });
    let max = graph.closePrice.reduce((cur, next) => {
      return Math.max(cur, next);
    });

    Chart.scaleService.updateScaleDefaults('linear', {
      ticks: { // graph range will be 10% below min to 10% above max
        min: Math.ceil((min - (min * 0.1)) / 10) * 10, // these 2 get rounded to the nearest 10
        max: Math.ceil((max + (max * 0.1)) / 10) * 10
      }
    });
    new Chart(ctx, {
      type: 'line',
      data: {
        labels: graph.labels,
        datasets: [{
          label: 'Last Price ($)',
          data: graph.closePrice,
          pointBackgroundColor: 'black',
          fill: 'Disabled'
        }],
      },
      options: {
        responsive: true,
        maintainAspectRatio: true
      }
      // options:options,
    });
  };

  graph.changeStartDate = () => {
    app.stock.getStockInfo(app.stock.ticker, $('#graph-start-date').val(), app.stockView.index);
  };

  module.graph = graph;

})(app);
<|endoftext|>


<commit_before>/**
* build.js - compile playcanvas engine from source into single javascript library
* This uses the Closure Compiler which requires java to be installed
* Example usage:
*
* // regular release build
* node build.js -l 0 -o output/playcanvas-latest.js
* // production minified build
* node build.js -l 1 -o output/playcanvas-latest.min.js
* // include extra debug code
* node build.js -l 0 -d -o output/playcanvas-latest.dbg.js
*/

var fs = require("fs");
var util = require("util");
var path = require("path");
var cp = require("child_process");
var os = require("os");

try {
    var fse = require("fs-extra");
} catch (e) {
    console.error("Missing dependency: 'npm install fs-extra'");
    process.exit(1);
}
try {
    var ClosureCompiler = require("google-closure-compiler").compiler;
} catch (e) {
    console.error("Missing dependency: 'npm install google-closure-compiler'");
    process.exit(1);
}
try {
    var Preprocessor = require("preprocessor");
} catch (e) {
    console.error("Missing dependency: 'npm install preprocessor'");
    process.exit(1);
}

var DEFAULT_OUTPUT = "output/playcanvas-latest.js";
var DEFAULT_TEMP = "_tmp";
var SRC_DIR = "../";

var DEFAULT_PACKAGE = {
    "author": "PlayCanvas <support@playcanvas.com>",
    "description": "PlayCanvas WebGL Engine.",
    "engines": {
        "node": ">= 0.6.12"
    },
    "files": [
        "build/output/playcanvas-latest.js"
    ],
    "homepage": "https://playcanvas.com",
    "main": "build/output/playcanvas-latest.js",
    "name": "playcanvas",
    "repository": "https://github.com/playcanvas/engine",
    "version": ""
};

var COMPILER_LEVEL = [
    'WHITESPACE_ONLY',
    'SIMPLE',
    'ADVANCED'
];

var debug = false;
var profiler = false;
var outputPath = DEFAULT_OUTPUT;
var tempPath = DEFAULT_TEMP;
var compilerLevel = COMPILER_LEVEL[0];
var formattingLevel = undefined;

// LIB FUNCTIONS
if (!String.prototype.endsWith) {
  String.prototype.endsWith = function(searchString, position) {
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.indexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
  };
}

function directoryExists(path) {
  try {
    return fs.statSync(path).isDirectory();
  }
  catch (err) {
    return false;
  }
}

var replaceAll = function(target, search, replacement) {
    return target.replace(new RegExp(search, 'g'), replacement);
};
// END LIB FUNCTIONS

// get git revision
var getRevision = function (callback) {
    var command = "git rev-parse --short HEAD";

    cp.exec(command, function (err, stdout, stderr) {
        if (err) {
            callback(err, '-');
            return;
        }
        callback(null, stdout.trim());
    });
};

// get version from VERSION file
var getVersion = function (callback) {
    fs.readFile('../VERSION', function (err, buffer) {
        if (err) {
            callback(err, "__CURRENT_SDK_VERSION__");
        }
        callback(null, buffer.toString().trim());
    });
};

// load dependencies.txt
var loadDependencies = function (fullpath, callback) {
    fs.readFile(fullpath, function (err, data) {
        if (err) callback(err);
        callback(data.toString().trim().split(new RegExp("[\\r\\n]+", 'g')));
    });
};

// load shader chunks and combine into single javascript file
var concatentateShaders = function (callback) {
    output = '../src/graphics/program-lib/chunks/generated-shader-chunks.js';
    dir = '../src/graphics/program-lib/chunks/';

    fd = fs.openSync(output, 'w');

    fs.writeSync(fd, "// autogenerated at: " + new Date() + "\n");
    fs.readdir(dir, function (err, files) {
        files.forEach(function (file) {
            var ext = null;
            ext = file.endsWith(".vert") ? "VS" : ext;
            ext = file.endsWith(".frag") ? "PS" : ext;
            if (ext) {
                var fullpath = dir + file;

                var content = replaceAll(fs.readFileSync(fullpath).toString(), "[\\r\\n]+", "\\n");
                var name = file.split(".")[0] + ext;
                var data = util.format('pc.shaderChunks.%s = "%s";\n', name, content);
                fs.writeSync(fd, data);
            }
        });

        callback();
    });
};

// run all dependencies through
// preprocesor (for #ifdef's etc)
// output to temp directory
// and return list of paths
var preprocess = function (dependencies) {
    // make temp dir and clear
    if (directoryExists(tempPath)) {
        fse.removeSync(tempPath);
    }

    var dependenciesOut = [];
    dependencies.forEach(function (filepath) {
        var relpath = path.relative(SRC_DIR, filepath);
        var _out = path.join(tempPath, relpath);

        var buffer = fs.readFileSync(filepath);

        var pp = new Preprocessor(buffer.toString());
        var src = pp.process({
            PROFILER: profiler,
            DEBUG: debug
        });

        var dir = path.dirname(_out);
        fse.ensureDirSync(dir);

        fs.writeFileSync(_out, src);

        dependenciesOut.push(_out);
    });

    return dependenciesOut;
};

// insert version and revision into output source file
var insertVersions = function (filepath, callback) {
    getRevision(function (err, rev) {
        getVersion(function (err, ver) {
            fs.readFile(filepath, function (err, buffer) {
                if (err) {
                    callback(err);
                }

                var content = buffer.toString();

                content = replaceAll(content, "__CURRENT_SDK_VERSION__", ver);
                content = replaceAll(content, "__REVISION__", rev);

                fs.writeFile(filepath, content, function (err) {
                    callback(err, ver);
                });
            });
        });
    });
};

// write package.json needed for a nodejs package
var packageJson = function (version) {
    var json = DEFAULT_PACKAGE;
    json.version = version;
    fs.writeFileSync("package.json", JSON.stringify(json, null, 4));
};

// remove temporary files
var cleanup = function () {
    if (directoryExists(tempPath)) {
        fse.removeSync(tempPath);
    }
};

var run = function () {
    var start = new Date().getTime();

    // build shader file
    concatentateShaders(function (err) {
        loadDependencies("./dependencies.txt", function (lines) {
            // preprocess and get new dependency list
            var files = preprocess(lines);

            // set compiler options
            var options = {
              js: files,
              compilation_level: compilerLevel,
              language_in: "ECMASCRIPT5",
              js_output_file: outputPath,
              manage_closure_dependencies: true,
              jscomp_off: [
                  "nonStandardJsDocs",  // docs warnings
                  "checkTypes", // array types and other missing types
                  "misplacedTypeAnnotation", // temp: hide docs using @type on defineProperty
                  "globalThis", // temp: remove this again
                  "suspiciousCode" // temp: remove this again
              ],
              externs: "externs.js",
              warning_level: "VERBOSE"
            };

            if (compilerLevel === "WHITESPACE_ONLY") {
                options.formatting = "pretty_print";
            }
            var closureCompiler = new ClosureCompiler(options);

            // compile
            var compilerProcess = closureCompiler.run(function(exitCode, stdOut, stdErr) {

                if (exitCode) {
                    console.error(stdErr);
                    process.exit(exitCode);
                } else {
                    if (stdErr) console.error(stdErr);
                    // print compiler output
                    if (stdOut) console.log(stdOut);

                    insertVersions(outputPath, function (err, version) {
                        if (err) {
                            console.error(err);
                            process.exit();
                        }

                        packageJson(version);
                        cleanup();

                        // done
                        var time = (new Date().getTime() - start) / 1000;
                        console.log("Build completed in " + time + " seconds!");
                        process.exit(0);

                    });
                }
            });

        });
    });
};

// parse arguments
var arguments = function () {
    var _last = null;
    var _arg = null;
    process.argv.forEach(function (arg) {
        if (arg === '-h') {
            console.log("Build Script for PlayCanvas Engine\n");
            console.log("Usage: node build.js -l [COMPILER_LEVEL] -o [OUTPUT_PATH]\n");
            console.log("Arguments:");
            console.log("-h: show this help");
            console.log("-l COMPILER_LEVEL: Set compiler level");
            console.log("\t0: WHITESPACE_ONLY [default]");
            console.log("\t1: SIMPLE");
            console.log("\t2: ADVANCED OPTIMIZATIONS");
            console.log("-o PATH: output file path [output/playcanvas-latest.js]");
            console.log("-d: build debug engine configuration");
            console.log("-p: build profiler engine configuration");
            process.exit();
        }

        if (arg === '-d') {
            debug = true;
        }

        if (arg === '-p') {
            profiler = true;
        }

        if (_last === '-l') {
            var level = parseInt(arg, 10);
            if (!(level >= 0 && level <= 2)) {
                console.error("Invalid compiler level (-l) should be: 0, 1 or 2.");
                process.exit(1);
            }
            compilerLevel = COMPILER_LEVEL[level];
        }

        if (_last === '-o') {
            outputPath = arg;
        }

        _last = arg;
    });
};

// only run from build directory
var cwd = process.cwd();
if (!fs.existsSync(cwd + '/build.js')) {
    console.error("run build script from build directory");
    process.exit(1);
}

arguments();
run();
<commit_msg>debug build by should include profiler too<commit_after>/**
* build.js - compile playcanvas engine from source into single javascript library
* This uses the Closure Compiler which requires java to be installed
* Example usage:
*
* // regular release build
* node build.js -l 0 -o output/playcanvas-latest.js
* // production minified build
* node build.js -l 1 -o output/playcanvas-latest.min.js
* // include extra debug code
* node build.js -l 0 -d -o output/playcanvas-latest.dbg.js
*/

var fs = require("fs");
var util = require("util");
var path = require("path");
var cp = require("child_process");
var os = require("os");

try {
    var fse = require("fs-extra");
} catch (e) {
    console.error("Missing dependency: 'npm install fs-extra'");
    process.exit(1);
}
try {
    var ClosureCompiler = require("google-closure-compiler").compiler;
} catch (e) {
    console.error("Missing dependency: 'npm install google-closure-compiler'");
    process.exit(1);
}
try {
    var Preprocessor = require("preprocessor");
} catch (e) {
    console.error("Missing dependency: 'npm install preprocessor'");
    process.exit(1);
}

var DEFAULT_OUTPUT = "output/playcanvas-latest.js";
var DEFAULT_TEMP = "_tmp";
var SRC_DIR = "../";

var DEFAULT_PACKAGE = {
    "author": "PlayCanvas <support@playcanvas.com>",
    "description": "PlayCanvas WebGL Engine.",
    "engines": {
        "node": ">= 0.6.12"
    },
    "files": [
        "build/output/playcanvas-latest.js"
    ],
    "homepage": "https://playcanvas.com",
    "main": "build/output/playcanvas-latest.js",
    "name": "playcanvas",
    "repository": "https://github.com/playcanvas/engine",
    "version": ""
};

var COMPILER_LEVEL = [
    'WHITESPACE_ONLY',
    'SIMPLE',
    'ADVANCED'
];

var debug = false;
var profiler = false;
var outputPath = DEFAULT_OUTPUT;
var tempPath = DEFAULT_TEMP;
var compilerLevel = COMPILER_LEVEL[0];
var formattingLevel = undefined;

// LIB FUNCTIONS
if (!String.prototype.endsWith) {
  String.prototype.endsWith = function(searchString, position) {
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.indexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
  };
}

function directoryExists(path) {
  try {
    return fs.statSync(path).isDirectory();
  }
  catch (err) {
    return false;
  }
}

var replaceAll = function(target, search, replacement) {
    return target.replace(new RegExp(search, 'g'), replacement);
};
// END LIB FUNCTIONS

// get git revision
var getRevision = function (callback) {
    var command = "git rev-parse --short HEAD";

    cp.exec(command, function (err, stdout, stderr) {
        if (err) {
            callback(err, '-');
            return;
        }
        callback(null, stdout.trim());
    });
};

// get version from VERSION file
var getVersion = function (callback) {
    fs.readFile('../VERSION', function (err, buffer) {
        if (err) {
            callback(err, "__CURRENT_SDK_VERSION__");
        }
        callback(null, buffer.toString().trim());
    });
};

// load dependencies.txt
var loadDependencies = function (fullpath, callback) {
    fs.readFile(fullpath, function (err, data) {
        if (err) callback(err);
        callback(data.toString().trim().split(new RegExp("[\\r\\n]+", 'g')));
    });
};

// load shader chunks and combine into single javascript file
var concatentateShaders = function (callback) {
    output = '../src/graphics/program-lib/chunks/generated-shader-chunks.js';
    dir = '../src/graphics/program-lib/chunks/';

    fd = fs.openSync(output, 'w');

    fs.writeSync(fd, "// autogenerated at: " + new Date() + "\n");
    fs.readdir(dir, function (err, files) {
        files.forEach(function (file) {
            var ext = null;
            ext = file.endsWith(".vert") ? "VS" : ext;
            ext = file.endsWith(".frag") ? "PS" : ext;
            if (ext) {
                var fullpath = dir + file;

                var content = replaceAll(fs.readFileSync(fullpath).toString(), "[\\r\\n]+", "\\n");
                var name = file.split(".")[0] + ext;
                var data = util.format('pc.shaderChunks.%s = "%s";\n', name, content);
                fs.writeSync(fd, data);
            }
        });

        callback();
    });
};

// run all dependencies through
// preprocesor (for #ifdef's etc)
// output to temp directory
// and return list of paths
var preprocess = function (dependencies) {
    // make temp dir and clear
    if (directoryExists(tempPath)) {
        fse.removeSync(tempPath);
    }

    var dependenciesOut = [];
    dependencies.forEach(function (filepath) {
        var relpath = path.relative(SRC_DIR, filepath);
        var _out = path.join(tempPath, relpath);

        var buffer = fs.readFileSync(filepath);

        var pp = new Preprocessor(buffer.toString());
        var src = pp.process({
            PROFILER: profiler || debug,
            DEBUG: debug
        });

        var dir = path.dirname(_out);
        fse.ensureDirSync(dir);

        fs.writeFileSync(_out, src);

        dependenciesOut.push(_out);
    });

    return dependenciesOut;
};

// insert version and revision into output source file
var insertVersions = function (filepath, callback) {
    getRevision(function (err, rev) {
        getVersion(function (err, ver) {
            fs.readFile(filepath, function (err, buffer) {
                if (err) {
                    callback(err);
                }

                var content = buffer.toString();

                content = replaceAll(content, "__CURRENT_SDK_VERSION__", ver);
                content = replaceAll(content, "__REVISION__", rev);

                fs.writeFile(filepath, content, function (err) {
                    callback(err, ver);
                });
            });
        });
    });
};

// write package.json needed for a nodejs package
var packageJson = function (version) {
    var json = DEFAULT_PACKAGE;
    json.version = version;
    fs.writeFileSync("package.json", JSON.stringify(json, null, 4));
};

// remove temporary files
var cleanup = function () {
    if (directoryExists(tempPath)) {
        fse.removeSync(tempPath);
    }
};

var run = function () {
    var start = new Date().getTime();

    // build shader file
    concatentateShaders(function (err) {
        loadDependencies("./dependencies.txt", function (lines) {
            // preprocess and get new dependency list
            var files = preprocess(lines);

            // set compiler options
            var options = {
              js: files,
              compilation_level: compilerLevel,
              language_in: "ECMASCRIPT5",
              js_output_file: outputPath,
              manage_closure_dependencies: true,
              jscomp_off: [
                  "nonStandardJsDocs",  // docs warnings
                  "checkTypes", // array types and other missing types
                  "misplacedTypeAnnotation", // temp: hide docs using @type on defineProperty
                  "globalThis", // temp: remove this again
                  "suspiciousCode" // temp: remove this again
              ],
              externs: "externs.js",
              warning_level: "VERBOSE"
            };

            if (compilerLevel === "WHITESPACE_ONLY") {
                options.formatting = "pretty_print";
            }
            var closureCompiler = new ClosureCompiler(options);

            // compile
            var compilerProcess = closureCompiler.run(function(exitCode, stdOut, stdErr) {

                if (exitCode) {
                    console.error(stdErr);
                    process.exit(exitCode);
                } else {
                    if (stdErr) console.error(stdErr);
                    // print compiler output
                    if (stdOut) console.log(stdOut);

                    insertVersions(outputPath, function (err, version) {
                        if (err) {
                            console.error(err);
                            process.exit();
                        }

                        packageJson(version);
                        cleanup();

                        // done
                        var time = (new Date().getTime() - start) / 1000;
                        console.log("Build completed in " + time + " seconds!");
                        process.exit(0);

                    });
                }
            });

        });
    });
};

// parse arguments
var arguments = function () {
    var _last = null;
    var _arg = null;
    process.argv.forEach(function (arg) {
        if (arg === '-h') {
            console.log("Build Script for PlayCanvas Engine\n");
            console.log("Usage: node build.js -l [COMPILER_LEVEL] -o [OUTPUT_PATH]\n");
            console.log("Arguments:");
            console.log("-h: show this help");
            console.log("-l COMPILER_LEVEL: Set compiler level");
            console.log("\t0: WHITESPACE_ONLY [default]");
            console.log("\t1: SIMPLE");
            console.log("\t2: ADVANCED OPTIMIZATIONS");
            console.log("-o PATH: output file path [output/playcanvas-latest.js]");
            console.log("-d: build debug engine configuration");
            console.log("-p: build profiler engine configuration");
            process.exit();
        }

        if (arg === '-d') {
            debug = true;
        }

        if (arg === '-p') {
            profiler = true;
        }

        if (_last === '-l') {
            var level = parseInt(arg, 10);
            if (!(level >= 0 && level <= 2)) {
                console.error("Invalid compiler level (-l) should be: 0, 1 or 2.");
                process.exit(1);
            }
            compilerLevel = COMPILER_LEVEL[level];
        }

        if (_last === '-o') {
            outputPath = arg;
        }

        _last = arg;
    });
};

// only run from build directory
var cwd = process.cwd();
if (!fs.existsSync(cwd + '/build.js')) {
    console.error("run build script from build directory");
    process.exit(1);
}

arguments();
run();
<|endoftext|>


<commit_before>let SlackMember = React.createClass({
  render() {
    return (
      <p>{this.props.member.name}</p>
    );
  }
});
<commit_msg>remove slackmemberjs<commit_after><|endoftext|>


<commit_before>const babel = require('./babel');

const plugins = (babel.plugins || []).concat('react');

const rules = Object.assign({}, babel.rules, {
  'jsx-quotes': [2, 'prefer-single'],
  'react/jsx-boolean-value': [2, 'never'],
  'react/jsx-curly-spacing': [2, 'never'],
  'react/jsx-first-prop-new-line': [2, 'multiline'],
  'react/jsx-indent': [2, 2],
  'react/jsx-indent-props': [2, 2],
  'react/jsx-no-duplicate-props': 2,
  'react/jsx-no-undef': 2,
  'react/jsx-sort-props': 2,
  'react/jsx-tag-spacing': [2, { 'beforeSelfClosing': 'always' }],
  'react/jsx-uses-react': 2,
  'react/jsx-uses-vars': 2,
  'react/jsx-wrap-multilines': 2,
  'react/no-did-mount-set-state': 2,
  'react/no-did-update-set-state': 2,
  'react/no-multi-comp': 2,
  'react/no-unknown-property': 2,
  'react/prop-types': 2,
  'react/react-in-jsx-scope': 2,
  'react/self-closing-comp': 2,
  'react/sort-comp': [2, { order: [ 'static-methods', 'lifecycle', 'everything-else' ]}],
  'react/sort-prop-types': 2
});

module.exports = Object.assign({}, babel, {
  plugins: plugins,
  rules: rules
})
<commit_msg>update eslint rules for react (#11)<commit_after>const babel = require('./babel');

const plugins = (babel.plugins || []).concat('react');

const rules = Object.assign({}, babel.rules, {
  'jsx-quotes': [2, 'prefer-single'],
  'react/jsx-boolean-value': [2, 'never'],
  'react/jsx-curly-spacing': [2, 'never'],
  'react/jsx-first-prop-new-line': [2, 'multiline'],
  'react/jsx-indent': [2, 2],
  'react/jsx-indent-props': [2, 2],
  'react/jsx-key': 2,
  'react/jsx-no-comment-textnodes': 2,
  'react/jsx-no-duplicate-props': 2,
  'react/jsx-no-target-blank': 2,
  'react/jsx-no-undef': 2,
  'react/jsx-pascal-case': [2, { allowAllCaps: true }],
  'react/jsx-sort-props': 2,
  'react/jsx-tag-spacing': [2, { 'beforeSelfClosing': 'always' }],
  'react/jsx-uses-react': 2,
  'react/jsx-uses-vars': 2,
  'react/jsx-wrap-multilines': 2,
  'react/no-children-prop': 2,
  'react/no-danger-with-children': 2,
  'react/no-did-mount-set-state': 2,
  'react/no-did-update-set-state': 2,
  'react/no-direct-mutation-state': 2,
  'react/no-multi-comp': 2,
  'react/no-render-return-value': 2,
  'react/no-unknown-property': 2,
  'react/prop-types': 2,
  'react/react-in-jsx-scope': 2,
  'react/self-closing-comp': 2,
  'react/sort-comp': [2, { order: [ 'static-methods', 'lifecycle', 'everything-else' ]}],
  'react/sort-prop-types': 2
});

module.exports = Object.assign({}, babel, {
  plugins: plugins,
  rules: rules
})
<|endoftext|>


<commit_before>const Twitter = require('twitter');
const moment = require('moment');
const KEYS = require('./keys');

const twitterClient = new Twitter({
  consumer_key: KEYS.twitter.consumer_key,
  consumer_secret: KEYS.twitter.consumer_secret,
  access_token_key: KEYS.twitter.access_token_key,
  access_token_secret: KEYS.twitter.access_token_secret
});

module.exports.getTweetsForHashtags = function(hashtagsArray) {
	let hashtagsQuery = hashtagsArray.join(' OR ');
	console.log('requesting tweets for hashtags ' + hashtagsQuery);
	return new Promise((resolve, reject) => {
		twitterClient.get('search/tweets', {q: hashtagsQuery}, function(error, tweets, response) {
		   if (error) {
				 reject(error);
				 return null;
			 }

			 console.log('tweets received');
			 resolve(tweets, response);
		});
	})
}

module.exports.patchStatuses = function(twitterStatuses) {
	if (!(twitterStatuses instanceof Array) || twitterStatuses.length == 0) {
		return [];
	}

	twitterStatuses.forEach(status => {
		status.created_at_relative = moment(new Date(status.created_at)).fromNow();
	});
}
<commit_msg>Limit number of tweets to 9<commit_after>const Twitter = require('twitter');
const moment = require('moment');
const KEYS = require('./keys');

const twitterClient = new Twitter({
  consumer_key: KEYS.twitter.consumer_key,
  consumer_secret: KEYS.twitter.consumer_secret,
  access_token_key: KEYS.twitter.access_token_key,
  access_token_secret: KEYS.twitter.access_token_secret
});

module.exports.getTweetsForHashtags = function(hashtagsArray) {
	let hashtagsQuery = hashtagsArray.join(' OR ');
	console.log('requesting tweets for hashtags ' + hashtagsQuery);
	return new Promise((resolve, reject) => {
		twitterClient.get('search/tweets', {q: hashtagsQuery, count: 9}, function(error, tweets, response) {
		   if (error) {
				 reject(error);
				 return null;
			 }

			 console.log('tweets received');
			 resolve(tweets, response);
		});
	})
}

module.exports.patchStatuses = function(twitterStatuses) {
	if (!(twitterStatuses instanceof Array) || twitterStatuses.length == 0) {
		return [];
	}

	twitterStatuses.forEach(status => {
		status.created_at_relative = moment(new Date(status.created_at)).fromNow();
	});
}
<|endoftext|>


<commit_before>import { expect } from 'chai';
import { defineAction } from '../';

const ERROR = 'ERROR';
const LOADING = 'LOADING';
const SUCCESS = 'SUCCESS';

describe('defineAction()', () => {
  describe('resulting constant', () => {
    it('has the given value', () => {
      const CREATE = defineAction('CREATE');
      expect(`${CREATE}`).to.equal('CREATE');
      expect(CREATE.ACTION).to.equal('CREATE');
    });

    it('can be used in an reducer', () => {
      const CREATE = defineAction('CREATE');
      const state = 'foo';

      const reducer = {
        [CREATE]: (x) => x,
      };

      expect(reducer['CREATE'](state)).to.equal(state);
    });

    it('can define subactions', () => {
      const CREATE = defineAction('CREATE', [ERROR, SUCCESS]);
      expect(`${CREATE}`).to.equal('CREATE');
      expect(CREATE.ACTION).to.equal('CREATE');
      expect(CREATE.ERROR).to.equal('CREATE_ERROR');
      expect(CREATE.SUCCESS).to.equal('CREATE_SUCCESS');
    });

    it('subactions can be used in an reducer', () => {
      const CREATE = defineAction('CREATE', ['SUCCESS']);
      const state = 'foo';

      const reducer = {
        [CREATE]: (x) => x,
        [CREATE.SUCCESS]: (x) => x,
      };

      expect(reducer['CREATE'](state)).to.equal(state);
      expect(reducer['CREATE_SUCCESS'](state)).to.equal(state);
    });

    it('can create namespaces', () => {
      const todos = defineAction('todos', 'my-app');
      expect(`${todos}`).to.equal('my-app/todos');
    });

    it('can create namespaces with subactions', () => {
      const todos = defineAction('todos', [LOADING], 'my-app');
      const CREATE = defineAction('CREATE', [ERROR, SUCCESS], todos);

      expect(todos.LOADING).to.equal('my-app/todos_LOADING');
      expect(CREATE.ERROR).to.equal('my-app/todos/CREATE_ERROR');
      expect(CREATE.SUCCESS).to.equal('my-app/todos/CREATE_SUCCESS');
    });

    it('contains subactions within namespaces', () => {
      const myApp = defineAction('my-app');
      const todos = defineAction('todos', [LOADING], myApp);
      const CREATE = defineAction('CREATE', [ERROR, SUCCESS], todos);

      expect(myApp.ACTION).to.equal('my-app');
      expect(myApp.LOADING).to.equal(undefined);
      expect(myApp.ERROR).to.equal(undefined);
      expect(myApp.SUCCESS).to.equal(undefined);

      expect(todos.ACTION).to.equal('my-app/todos');
      expect(todos.LOADING).to.equal('my-app/todos_LOADING');
      expect(todos.ERROR).to.equal(undefined);
      expect(todos.SUCCESS).to.equal(undefined);

      expect(CREATE.ACTION).to.equal('my-app/todos/CREATE');
      expect(CREATE.LOADING).to.equal(undefined);
      expect(CREATE.ERROR).to.equal('my-app/todos/CREATE_ERROR');
      expect(CREATE.SUCCESS).to.equal('my-app/todos/CREATE_SUCCESS');
    });

    it('can use the extension method', () => {
      const myApp = defineAction('my-app');
      const todos = defineAction('todos', null, myApp);
      const CREATE1 = defineAction('CREATE', [ERROR, SUCCESS], todos);

      const CREATE2 = defineAction('CREATE', [ERROR, SUCCESS], 'my-app/todos');

      expect(`${CREATE1}`).to.equal(`${CREATE2}`);
      expect(`${CREATE1.ERROR}`).to.equal(`${CREATE2.ERROR}`);
      expect(`${CREATE1.SUCCESS}`).to.equal(`${CREATE1.SUCCESS}`);
    });
  });
});
<commit_msg>Fixed test<commit_after>import { expect } from 'chai';
import { defineAction } from '../';

const ERROR = 'ERROR';
const LOADING = 'LOADING';
const SUCCESS = 'SUCCESS';

describe('defineAction()', () => {
  describe('resulting constant', () => {
    it('has the given value', () => {
      const CREATE = defineAction('CREATE');
      expect(`${CREATE}`).to.equal('CREATE');
      expect(CREATE.ACTION).to.equal('CREATE');
    });

    it('can be used in an reducer', () => {
      const CREATE = defineAction('CREATE');
      const state = 'foo';

      const reducer = {
        [CREATE]: (x) => x,
      };

      expect(reducer['CREATE'](state)).to.equal(state);
    });

    it('can define subactions', () => {
      const CREATE = defineAction('CREATE', [ERROR, SUCCESS]);
      expect(`${CREATE}`).to.equal('CREATE');
      expect(CREATE.ACTION).to.equal('CREATE');
      expect(CREATE.ERROR).to.equal('CREATE_ERROR');
      expect(CREATE.SUCCESS).to.equal('CREATE_SUCCESS');
    });

    it('subactions can be used in an reducer', () => {
      const CREATE = defineAction('CREATE', ['SUCCESS']);
      const state = 'foo';

      const reducer = {
        [CREATE]: (x) => x,
        [CREATE.SUCCESS]: (x) => x,
      };

      expect(reducer['CREATE'](state)).to.equal(state);
      expect(reducer['CREATE_SUCCESS'](state)).to.equal(state);
    });

    it('can create namespaces', () => {
      const todos = defineAction('todos', 'my-app');
      expect(`${todos}`).to.equal('my-app/todos');
    });

    it('can create namespaces with subactions', () => {
      const todos = defineAction('todos', [LOADING], 'my-app');
      const CREATE = defineAction('CREATE', [ERROR, SUCCESS], todos);

      expect(todos.LOADING).to.equal('my-app/todos_LOADING');
      expect(CREATE.ERROR).to.equal('my-app/todos/CREATE_ERROR');
      expect(CREATE.SUCCESS).to.equal('my-app/todos/CREATE_SUCCESS');
    });

    it('contains subactions within namespaces', () => {
      const myApp = defineAction('my-app');
      const todos = defineAction('todos', [LOADING], myApp);
      const CREATE = defineAction('CREATE', [ERROR, SUCCESS], todos);

      expect(myApp.ACTION).to.equal('my-app');
      expect(myApp.LOADING).to.equal(undefined);
      expect(myApp.ERROR).to.equal(undefined);
      expect(myApp.SUCCESS).to.equal(undefined);

      expect(todos.ACTION).to.equal('my-app/todos');
      expect(todos.LOADING).to.equal('my-app/todos_LOADING');
      expect(todos.ERROR).to.equal(undefined);
      expect(todos.SUCCESS).to.equal(undefined);

      expect(CREATE.ACTION).to.equal('my-app/todos/CREATE');
      expect(CREATE.LOADING).to.equal(undefined);
      expect(CREATE.ERROR).to.equal('my-app/todos/CREATE_ERROR');
      expect(CREATE.SUCCESS).to.equal('my-app/todos/CREATE_SUCCESS');
    });

    it('can use the extension method', () => {
      const myApp = defineAction('my-app');
      const todos = defineAction('todos', null, myApp);
      const CREATE1 = defineAction('CREATE', [ERROR, SUCCESS], todos);

      const CREATE2 = defineAction('CREATE', [ERROR, SUCCESS], 'my-app/todos');

      expect(`${CREATE1}`).to.equal(`${CREATE2}`);
      expect(`${CREATE1.ERROR}`).to.equal(`${CREATE2.ERROR}`);
      expect(`${CREATE1.SUCCESS}`).to.equal(`${CREATE2.SUCCESS}`);
    });
  });
});
<|endoftext|>


<commit_before>'use strict'
/**
 * Created by tungtouch on 2/9/15.
 */
var redis = require('redis');
var rClient = redis.createClient();

var message = new Buffer("Some bytes hello world bo bo bo world HEHEHEHE ahhaha hohoho hehe ban kinh dai bakbakabk efefe");
var async = require('async');

var max = 200000;

for (var i = 0; i < max; i++) {
    rClient.hset("raw", "data"+i, message, redis.print);
}

console.log("Starting Benchmark!");
<commit_msg>change port 3000<commit_after>'use strict'
/**
 * Created by tungtouch on 2/9/15.
 */
var redis = require('redis');
var rClient = redis.createClient();

var message = new Buffer("Some bytes hello world bo bo bo world HEHEHEHE ahhaha hohoho hehe ban kinh dai bakbakabk efefe");
var async = require('async');

var max = 200000;

for (var i = 0; i < max; i++) {
    rClient.hset("raw", "data"+i, message, redis.print);
    console.log("Insert Data:", i);
}

console.log("Starting Benchmark!");
<|endoftext|>


<commit_before>Q = require('q');

var redis,
    rtg;

/* For using RedisToGo on Heroku. If you're not using RedisToGo or Heroku,
* feel free to remove this part and just use
* redis = require("redis").createClient();
*/
if(process.env.REDISTOGO_URL) {
  rtg   = require("url").parse(process.env.REDISTOGO_URL);
  redis = require("redis").createClient(rtg.port, rtg.hostname);

  redis.auth(rtg.auth.split(":")[1]);
} else {
  //then we're running locally
  redis = require("redis").createClient();
}

QRedis = {};

QRedis.sadd = Q.nbind(redis.sadd, redis);
QRedis.hmset = Q.nbind(redis.hmset, redis);
QRedis.hgetall = Q.nbind(redis.hgetall, redis);
QRedis.exists = Q.nbind(redis.exists, redis);
QRedis.del = Q.nbind(redis.del, redis);
QRedis.set = Q.nbind(redis.set, redis);
QRedis.get = Q.nbind(redis.get, redis);
QRedis.decrby = Q.nbind(redis.decrby, redis);
QRedis.smembers = Q.nbind(redis.smembers, redis);

module.exports = {};

var ret = null;

module.exports.newMatch = function(playerName, targetName) {
	var a, b;
	QRedis.exists(playerName)
    .then(function(exists){
      if(!exists) {
        a = 'no person found';
      } else {
        b = 'something exists';
      }
    })

	console.log('a = ' + a);
	console.log('b = ' + b);

	if (redis.exists(playerName)) {
		console.log('added new player');
      	// create a running game for the player who started the match
      	var success = redis.hmset(playerName, {
      		"targetName" : targetName,
      		"playersChoice" : "not chosen",
      		"targetsChoice" : "not chosen"
      	});
      	// create a running game for the targeted player
      	redis.hmset(targetName, {
      		"targetName" : playerName,
      		"playersChoice" : null,
      		"targetsChoice" : null
      	});

      	// return message to tell users game started
        return "Rock, Paper, Scissors, SHOOT!";
     } else {
      	ret = "You are already in a match";
      	console.log('already in a match');
        return ret;
    }
}

module.exports.shoot = function(playerName, playersChoice) {
	if ( QRedis.exists(playerName) ) {
        console.log('shoot');
        var targetName = null, targetsChoice = null;

    	// get your game
		redis.hgetall(playerName, function (err, results) {
		   if (err) {
		   		console.log('There was an error in hgetall in shoot');
		   } else {
		    	// do something with results
		    	targetName = results.targetName;
		    	targetsChoice = results.targetsChoice
		    	console.log('Results: ' + results);
		    	console.log('Target name: ' + results.targetName);
		   }
		});

		// set your choice
    	redis.hmset(playerName, {
    		"targetName" : targetName,
    		"playersChoice" : playersChoice,
    		"targetsChoice" : targetsChoice
    	});

    	// if both choices are filled in, return who won
    	if (playersChoice !== null && targetsChoice !== null) {
    		if (playersChoice === targetsChoice) {
    			redis.del(targetName);
    			redis.del(playerName);
    			return 'It\'s a tie!';
    		} else if (playersChoice == 'paper' && targetsChoice == 'rock'
    			|| playersChoice == 'rock' && targetsChoice == 'scissors'
    			|| playersChoice == 'scissors' && targetsChoice) {
    			redis.del(targetName);
    			redis.del(playerName);
    			return playerName + 'Wins!';

    		} else {
    			redis.del(targetName);
    			redis.del(playerName);
    			return targetName + "Wins!";
    		}
    	} else {
			return 'Waiting for other player to shoot';
    	}
    } else {
      	console.log('a new match needs to be started');
        ret = "Start a new match: 'rps I challenge ____'";
        return ret;
    }
}

module.exports.del = function(playerName) {
	return QRedis.exists(playerName)
	    .then(function(exists){
	      if(exists) {
	      	console.log('key deleted');
	      	return QRedis.del(playerName);
	      } else {
	      	console.log('nothing to delete');
	        throw new Error("No match by that player found");
	    }
    })
}<commit_msg>Changed log for shoot method<commit_after>Q = require('q');

var redis,
    rtg;

/* For using RedisToGo on Heroku. If you're not using RedisToGo or Heroku,
* feel free to remove this part and just use
* redis = require("redis").createClient();
*/
if(process.env.REDISTOGO_URL) {
  rtg   = require("url").parse(process.env.REDISTOGO_URL);
  redis = require("redis").createClient(rtg.port, rtg.hostname);

  redis.auth(rtg.auth.split(":")[1]);
} else {
  //then we're running locally
  redis = require("redis").createClient();
}

QRedis = {};

QRedis.sadd = Q.nbind(redis.sadd, redis);
QRedis.hmset = Q.nbind(redis.hmset, redis);
QRedis.hgetall = Q.nbind(redis.hgetall, redis);
QRedis.exists = Q.nbind(redis.exists, redis);
QRedis.del = Q.nbind(redis.del, redis);
QRedis.set = Q.nbind(redis.set, redis);
QRedis.get = Q.nbind(redis.get, redis);
QRedis.decrby = Q.nbind(redis.decrby, redis);
QRedis.smembers = Q.nbind(redis.smembers, redis);

module.exports = {};

var ret = null;

module.exports.newMatch = function(playerName, targetName) {
	var a, b;
	QRedis.exists(playerName)
    .then(function(exists){
      if(!exists) {
        a = 'no person found';
      } else {
        b = 'something exists';
      }
    })

	// console.log('a = ' + a);
	// console.log('b = ' + b);

	if (redis.exists(playerName)) {
		console.log('added new player');
      	// create a running game for the player who started the match
      	var success = redis.hmset(playerName, {
      		"targetName" : targetName,
      		"playersChoice" : "not chosen",
      		"targetsChoice" : "not chosen"
      	});
      	// create a running game for the targeted player
      	redis.hmset(targetName, {
      		"targetName" : playerName,
      		"playersChoice" : null,
      		"targetsChoice" : null
      	});

      	// return message to tell users game started
        return "Rock, Paper, Scissors, SHOOT!";
     } else {
      	ret = "You are already in a match";
      	console.log('already in a match');
        return ret;
    }
}

module.exports.shoot = function(playerName, playersChoice) {
	if ( QRedis.exists(playerName) ) {
        console.log('shoot');
        var targetName = null, targetsChoice = null;

    	// get your game
		redis.hgetall(playerName, function (err, results) {
		   if (err) {
		   		console.log('There was an error in hgetall in shoot');
		   } else {
		    	// do something with results
		    	targetName = results.targetName;
		   }
		});

		// see if your target has chosen something yet
		redis.hgetall(targetName, function (err, results) {
			if (err) {
				console.log('There was an error');
			} else {
				targetsChoice = results.playersChoice;
			}
		})

		// set your choice
    	redis.hmset(playerName, {
    		"targetName" : targetName,
    		"playersChoice" : playersChoice,
    		"targetsChoice" : targetsChoice
    	});

    	console.log("playersChoice: " + playersChoice);
    	console.log("targetsChoice: " + targetsChoice);

    	// if both choices are filled in, return who won
    	if (playersChoice !== null && targetsChoice !== null) {
    		if (playersChoice === targetsChoice) {
    			redis.del(targetName);
    			redis.del(playerName);
    			return 'It\'s a tie!';
    		} else if (playersChoice == 'paper' && targetsChoice == 'rock'
    			|| playersChoice == 'rock' && targetsChoice == 'scissors'
    			|| playersChoice == 'scissors' && targetsChoice) {
    			redis.del(targetName);
    			redis.del(playerName);
    			return playerName + 'Wins!';

    		} else {
    			redis.del(targetName);
    			redis.del(playerName);
    			return targetName + "Wins!";
    		}
    	} else {
			return 'Waiting for other player to shoot';
    	}
    } else {
      	console.log('a new match needs to be started');
        ret = "Start a new match: 'rps I challenge ____'";
        return ret;
    }
}

module.exports.del = function(playerName) {
	return QRedis.exists(playerName)
	    .then(function(exists){
	      if(exists) {
	      	console.log('key deleted');
	      	return QRedis.del(playerName);
	      } else {
	      	console.log('nothing to delete');
	        throw new Error("No match by that player found");
	    }
    })
}<|endoftext|>


<commit_before>'use strict';
var assert = require('assert');
var fs = require('fs');
var path = require('path');
var _ = require('lodash');

var async = require('async');
var cpr = require('cpr');
var cp = require('cp');

exports.copyExtraAssets = function(buildDir, assets, cb) {
  assets = assets || [];

  async.forEach(assets, function(asset, cb) {
    var from = asset.from;
    var stats = fs.statSync(from);

    if(from.indexOf('./') === 0 && stats.isFile()) {
        cp(from, path.join(buildDir, asset.to, from), cb);
    }
    else {
        cpr(from, path.join(buildDir, asset.to), cb);
    }
  }, cb);
};

exports.copyIfExists = function(from, to, cb) {
  fs.exists(from, function(exists) {
    if(exists) {
      cpr(from, to, cb);
    }
    else {
      cb();
    }
  });
};

function calculateRedirects(paths) {
  return [].concat.apply([], _.map(paths, function(values, path) {
    return _.map(values.redirects, function(v, k) {
      return {
        from: path + '/' + k,
        to: path + '/' + v
      };
    }).filter(_.identity);
  }));
}

exports.calculateRedirects = calculateRedirects;

// TODO: push to separate tests
assert.deepEqual(calculateRedirects({
  foo: {},
  demo: {
    redirects: {
      foo: 'bar'
    }
  }
}), [
  {
    from: 'demo/foo',
    to: 'demo/bar'
  }
]);
<commit_msg>Allow redirects to work across sections<commit_after>'use strict';
var assert = require('assert');
var fs = require('fs');
var path = require('path');
var _ = require('lodash');

var async = require('async');
var cpr = require('cpr');
var cp = require('cp');

exports.copyExtraAssets = function(buildDir, assets, cb) {
  assets = assets || [];

  async.forEach(assets, function(asset, cb) {
    var from = asset.from;
    var stats = fs.statSync(from);

    if(from.indexOf('./') === 0 && stats.isFile()) {
        cp(from, path.join(buildDir, asset.to, from), cb);
    }
    else {
        cpr(from, path.join(buildDir, asset.to), cb);
    }
  }, cb);
};

exports.copyIfExists = function(from, to, cb) {
  fs.exists(from, function(exists) {
    if(exists) {
      cpr(from, to, cb);
    }
    else {
      cb();
    }
  });
};

function calculateRedirects(paths) {
  return [].concat.apply([], _.map(paths, function(values, path) {
    return _.map(values.redirects, function(v, k) {
      const from = path + '/' + k;

      // Redirect to any other section
      if(v[0] === '/') {
        return {
          from : from,
          to: v.slice(1) // strip /
        };
      }

      // Redirect to the same section
      return {
        from: from,
        to: path + '/' + v
      };
    }).filter(_.identity);
  }));
}

exports.calculateRedirects = calculateRedirects;

// TODO: push to separate tests
assert.deepEqual(calculateRedirects({
  foo: {},
  demo: {
    redirects: {
      foo: 'bar'
    }
  }
}), [
  {
    from: 'demo/foo',
    to: 'demo/bar'
  }
]);
<|endoftext|>


<commit_before>import { Component, $$ } from '../dom'
import { keys, parseKeyEvent } from '../util'

export default class ModalCanvas extends Component {
  getActionHandlers () {
    return {
      cancel: this._cancel,
      confirm: this._confirm
    }
  }

  render () {
    const { renderModal } = this.state
    const el = $$('div', { class: 'sc-modal-canvas' })
    if (renderModal) {
      el.append(
        renderModal().ref('renderedModal')
      )
      el.on('keydown', this._onKeydown)
    }
    return el
  }

  openModal (renderModal) {
    // if (this._resolve) throw new Error('Previous modal has not been closed.')
    this.setState({ renderModal })
    return new Promise((resolve, reject) => {
      this._resolve = resolve
    })
  }

  close () {
    this._cancel()
  }

  _cancel () {
    this._resolve(null)
    this._resolve = null
    this.setState({})
  }

  _confirm () {
    this._resolve(this.refs.renderedModal)
    this._resolve = null
    this.setState({})
  }

  _onKeydown (event) {
    event.stopPropagation()
    // TODO: this is only working if the modal content has focus
    // we would need to add a global handler, or add a keytrap
    switch (event.keyCode) {
      case keys.ESCAPE: {
        this.close()
        break
      }
      case keys.ENTER: {
        const combo = parseKeyEvent(event, true)
        if (combo === 'META' || combo === 'ALT') {
          this._confirm()
        }
        break
      }
      default:
        //
    }
  }
}
<commit_msg>Stop bubbling contextmenu event in ModalCanvas.<commit_after>import { Component, $$, domHelpers } from '../dom'
import { keys, parseKeyEvent } from '../util'

export default class ModalCanvas extends Component {
  getActionHandlers () {
    return {
      cancel: this._cancel,
      confirm: this._confirm
    }
  }

  render () {
    const { renderModal } = this.state
    const el = $$('div', { class: 'sc-modal-canvas' })
    if (renderModal) {
      el.append(
        renderModal().ref('renderedModal')
      )
      el.on('keydown', this._onKeydown)
    }
    // do not let the global context menu handler handle this
    el.on('contextmenu', domHelpers.stopAndPrevent)
    return el
  }

  openModal (renderModal) {
    // if (this._resolve) throw new Error('Previous modal has not been closed.')
    this.setState({ renderModal })
    return new Promise((resolve, reject) => {
      this._resolve = resolve
    })
  }

  close () {
    this._cancel()
  }

  _cancel () {
    this._resolve(null)
    this._resolve = null
    this.setState({})
  }

  _confirm () {
    this._resolve(this.refs.renderedModal)
    this._resolve = null
    this.setState({})
  }

  _onKeydown (event) {
    event.stopPropagation()
    // TODO: this is only working if the modal content has focus
    // we would need to add a global handler, or add a keytrap
    switch (event.keyCode) {
      case keys.ESCAPE: {
        this.close()
        break
      }
      case keys.ENTER: {
        const combo = parseKeyEvent(event, true)
        if (combo === 'META' || combo === 'ALT') {
          this._confirm()
        }
        break
      }
      default:
        //
    }
  }
}
<|endoftext|>


<commit_before>// https://github.com/nuxt/nuxt.js/blob/dev/lib/common/options.js#L170
// console.log(process.env.NODE_ENV) // npm run dev: 'development', npm run build: 'production', npm run generate: 'production'
// const webpack = require('webpack')
const routerBase = '/'
module.exports = {
  /*
  ** Build configuration
  */
  build: {
    // analyze: true,
    extractCSS: true,
    vendor: ['uuid/v1', 'velocity-animate'], // 會被包在 common.[hash].js 裡面
    plugins: [
      // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 使用 moment without locale
      // new webpack.optimize.CommonsChunkPlugin({ // 在各 .vue 裡可視情況分類套件並載入
      //   async: 'common-in-lazy',
      //   minChunks: ({ resource } = {}) => (
      //     resource &&
      //     resource.includes('node_modules') &&
      //     (/moment/.test(resource) || /accounting/.test(resource))
      //   )
      // })
    ]
  },
  /*
  ** Create environment variables that will be shared for the client and server-side.
  ** 可在此設定任何參數, 任何一處 .js 都可利用 process.env 取得設定
  ** 但要注意不可以直接在 pug 中使用, 因為 pug 是預設使用 this 中的資料
  ** 必須要先在 data 中建立參數, 再把 process.env 中的參數指定到 data 中
  */
  env: {},
  /*
  ** Headers
  ** Common headers are already provided by @nuxtjs/pwa preset
  */
  head: {
    htmlAttrs: {
      lang: 'zh-Hant-TW'
    },
    titleTemplate: '%s - 網站名稱',
    title: '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'keywords', name: 'keywords', content: '' },
      { hid: 'description', name: 'description', content: '' },
      { property: 'og:type', content: 'website' },
      { property: 'og:site_name', content: '' },
      { hid: 'og:url', property: 'og:url', content: process.env.NODE_ENV === 'development' ? `http://${process.env.HOST}:${process.env.PORT}${routerBase}` : `https://${process.env.HOST}${routerBase}` },
      { hid: 'og:title', property: 'og:title', content: '' },
      { hid: 'og:description', property: 'og:description', content: '' },
      { hid: 'og:image', property: 'og:image', content: process.env.NODE_ENV === 'development' ? `http://${process.env.HOST}:${process.env.PORT}${routerBase}og.jpg` : `https://${process.env.HOST}${routerBase}og.jpg` },
      { hid: 'og:image:type', property: 'og:image:type', content: 'image/jpeg' },
      { property: 'og:image:width', content: '1200' },
      { property: 'og:image:height', content: '628' },
      { 'http-equiv': 'cache-control', content: 'max-age=900' } // 活動站需要時時更新，從 client 端指定沒有 cache 週期
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: './favicon.ico' },
      { rel: 'icon', type: 'image/png', href: './favicon.png' }
    ]
  },
  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#269384' },
  /*
  ** Customize app manifest
  */
  meta: {
    ogTitle: false, // 設定為 false，就不會跟頁面中的 head: { meta: [{ hid: 'og:title' }] } 資訊重複
    ogDescription: false // 設定為 false，就不會跟頁面中的 head: { meta: [{ hid: 'og:description' }] } 資訊重複
  },
  manifest: {
    start_url: 'http://taiwanfund.event-fundrich.com/?utm_source=web_app_manifest&utm_campaign=2017_taiwanfund_race',
    name: '創造勝利 fund 程式',
    short_name: 'fund 程式',
    background_color: '#FFF', // splash screen 背景色
    theme_color: '#269384', // 狀態列顏色
    orientation: 'portrait', // portrait: 直式, landscape: 橫式
    description: '全國大專院校基金投資模擬競賽',
    lang: 'zh-Hant-TW'
  },
  /*
  ** CSS
  */
  css: [
    'normalize.css',
    'hamburgers/dist/hamburgers.min.css',
    '@/assets/sass/main.sass'
  ],
  /*
  ** Plugins
  */
  plugins: [
    // 這裡只是註明 server 會不會用到這些 plugins, 為了省記憶體
    // 如果沒有將套件寫在 vendor 的設定裡, 就是包在各自的頁面裡
    // 除非利用 webpack.optimize.CommonsChunkPlugin, 才會再包在 common-in-lazy.[hash].js 裡
    // { src: '@/plugins/global-site-tag', ssr: false },
    // { src: '@/plugins/facebook-pixel', ssr: false },
    // { src: '@/plugins/facebook-sdk', ssr: false },
    { src: '@/plugins/velocity', ssr: false }
  ],
  /*
  ** Modules
  */
  modules: [
    // 自製 modules 時機：會利用到 NUXT 的 life circle, 或是想把一些邏輯當範本使用
    // '@nuxtjs/pwa',
    // '@/modules/tapable',
    // '@/modules/custom-loaders'
  ],
  /*
  ** Single page application is served under "./"
  */
  router: { base: routerBase },
  /*
  ** Customize runtime options for rendering pages
  */
  render: {
    // 尚無法得知此以下設定是否有效
    // bundleRenderer: {
    //   shouldPreload: (file, type) => ['script', 'style', 'font'].includes(type)
    // },
    http2: { push: true },
    static: { maxAge: '15m' },
    gzip: { threshold: 9 }
  }
}
<commit_msg>修改 maxAge 寫法, 設定 csp<commit_after>// https://github.com/nuxt/nuxt.js/blob/dev/lib/common/options.js#L170
// console.log(process.env.NODE_ENV) // npm run dev: 'development', npm run build: 'production', npm run generate: 'production'
// const webpack = require('webpack')
const routerBase = '/'
module.exports = {
  /*
  ** Build configuration
  */
  build: {
    // analyze: true,
    extractCSS: true,
    vendor: ['uuid/v1', 'velocity-animate'], // 會被包在 common.[hash].js 裡面
    plugins: [
      // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 使用 moment without locale
      // new webpack.optimize.CommonsChunkPlugin({ // 在各 .vue 裡可視情況分類套件並載入
      //   async: 'common-in-lazy',
      //   minChunks: ({ resource } = {}) => (
      //     resource &&
      //     resource.includes('node_modules') &&
      //     (/moment/.test(resource) || /accounting/.test(resource))
      //   )
      // })
    ]
  },
  /*
  ** Create environment variables that will be shared for the client and server-side.
  ** 可在此設定任何參數, 任何一處 .js 都可利用 process.env 取得設定
  ** 但要注意不可以直接在 pug 中使用, 因為 pug 是預設使用 this 中的資料
  ** 必須要先在 data 中建立參數, 再把 process.env 中的參數指定到 data 中
  */
  env: {},
  /*
  ** Headers
  ** Common headers are already provided by @nuxtjs/pwa preset
  */
  head: {
    htmlAttrs: {
      lang: 'zh-Hant-TW'
    },
    titleTemplate: '%s - 網站名稱',
    title: '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'keywords', name: 'keywords', content: '' },
      { hid: 'description', name: 'description', content: '' },
      { property: 'og:type', content: 'website' },
      { property: 'og:site_name', content: '' },
      { hid: 'og:url', property: 'og:url', content: process.env.NODE_ENV === 'development' ? `http://${process.env.HOST}:${process.env.PORT}${routerBase}` : `https://${process.env.HOST}${routerBase}` },
      { hid: 'og:title', property: 'og:title', content: '' },
      { hid: 'og:description', property: 'og:description', content: '' },
      { hid: 'og:image', property: 'og:image', content: process.env.NODE_ENV === 'development' ? `http://${process.env.HOST}:${process.env.PORT}${routerBase}og.jpg` : `https://${process.env.HOST}${routerBase}og.jpg` },
      { hid: 'og:image:type', property: 'og:image:type', content: 'image/jpeg' },
      { property: 'og:image:width', content: '1200' },
      { property: 'og:image:height', content: '628' },
      { 'http-equiv': 'cache-control', content: 'max-age=900' } // 活動站需要時時更新，從 client 端指定沒有 cache 週期
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: './favicon.ico' },
      { rel: 'icon', type: 'image/png', href: './favicon.png' }
    ]
  },
  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#269384' },
  /*
  ** Customize app manifest
  */
  meta: {
    ogTitle: false, // 設定為 false，就不會跟頁面中的 head: { meta: [{ hid: 'og:title' }] } 資訊重複
    ogDescription: false // 設定為 false，就不會跟頁面中的 head: { meta: [{ hid: 'og:description' }] } 資訊重複
  },
  manifest: {
    start_url: 'http://taiwanfund.event-fundrich.com/?utm_source=web_app_manifest&utm_campaign=2017_taiwanfund_race',
    name: '創造勝利 fund 程式',
    short_name: 'fund 程式',
    background_color: '#FFF', // splash screen 背景色
    theme_color: '#269384', // 狀態列顏色
    orientation: 'portrait', // portrait: 直式, landscape: 橫式
    description: '全國大專院校基金投資模擬競賽',
    lang: 'zh-Hant-TW'
  },
  /*
  ** CSS
  */
  css: [
    'normalize.css',
    'hamburgers/dist/hamburgers.min.css',
    '@/assets/sass/main.sass'
  ],
  /*
  ** Plugins
  */
  plugins: [
    // 這裡只是註明 server 會不會用到這些 plugins, 為了省記憶體
    // 如果沒有將套件寫在 vendor 的設定裡, 就是包在各自的頁面裡
    // 除非利用 webpack.optimize.CommonsChunkPlugin, 才會再包在 common-in-lazy.[hash].js 裡
    // { src: '@/plugins/global-site-tag', ssr: false },
    // { src: '@/plugins/facebook-pixel', ssr: false },
    // { src: '@/plugins/facebook-sdk', ssr: false },
    { src: '@/plugins/velocity', ssr: false }
  ],
  /*
  ** Modules
  */
  modules: [
    // 自製 modules 時機：會利用到 NUXT 的 life circle, 或是想把一些邏輯當範本使用
    // '@nuxtjs/pwa',
    // '@/modules/tapable',
    // '@/modules/custom-loaders'
  ],
  /*
  ** Single page application is served under "./"
  */
  router: { base: routerBase },
  /*
  ** Customize runtime options for rendering pages
  */
  render: {
    // 尚無法得知此以下設定是否有效
    // bundleRenderer: {
    //   shouldPreload: (file, type) => ['script', 'style', 'font'].includes(type)
    // },
    http2: { push: true, shouldPush: (file, type) => type === 'script' },
    static: { maxAge: 60 * 15 },
    gzip: { threshold: 9 },
    csp: true
  }
}
<|endoftext|>