<commit_before>var https = require('https');
var reload_interval = 180000; // Interval (in milliseconds) to refresh
var location = {};

var valid_sources = [
	{
		name: 'forecast.io', // Human-readable name of the source (required)
		source_site: 'https://developer.forecast.io/', // Website of source for info. Developer site preferred (optional)
		api_key: '', // The API key... see api_key_name. This will be set later using the api_key_name.
		api_key_name: 'forecast_io', // ** Name of ** the API key in the settings file (if needed). The settings file is ignored in git, so we can keep our keys here
		forecast_uri: 'https://api.forecast.io/forecast/${api_key}/${latitude},${longitude}', // URI to get general forecast data (required)
		storm_array_uri: 'https://api.darkskyapp.com/v1/interesting/${api_key}', // URI to get wide-area storm data (optional)
		last_call: undefined, // Last time this source was called. Used for caching request results (esp. to keep from using up free API keys :)
		conversion: forecastio2wa // Function to populate our own variables from the API's. Should expect 1 argument - an object the API responded with (required)
	},
	{
		name: 'OpenWeatherMap',
		api_key: '',
		api_key_name: '',
		forecast_uri: '',
		storm_array_uri: '',
		last_call: undefined,
		conversion: undefined
	},
	{
		name: 'Weather Underground',
		api_key: '',
		api_key_name: '',
		forecast_uri: '',
		storm_array_uri: '',
		last_call: undefined,
		conversion: undefined
	},
	{
		name: 'test',
		api_key: '',
		api_key_name: '',
		forecast_uri: 'file://' + __dirname + '/test/local.json',
		storm_array_uri: '',
		last_call: undefined,
		conversion: test2wa
	}
];

function getWeather(lat, lon, source_obj) {
	if (source_obj === undefined) {
		source_obj = valid_sources[0];
	}

	return callAPI(parseAPIURI(source_obj), source_obj.conversion);
}

function setLocation(lat, lon) {
	location = { latitude: lat, longitude: lon };
}

/* Will be used as the entry-point for getting info from the API URI,
 * calling conversion functions, etc.
 */
function callAPI(uri, on_complete) {
	var output = '';

	if (uri.slice(0, 7) === 'file://') {
		return on_complete(JSON.parse(require('fs').readFileSync(uri.slice(7))));
	}

	https.get(uri, function (res) {
		res.setEncoding('UTF-8');

		res.on('data', function (data) {
			output += data;
		});

		res.on('end', function (data) {
			return on_complete(JSON.parse(data));
		});
	});
}

function parseAPIURI(source_object) {
	return source_object.forecast_uri.replace(/\$\{api_key\}/g, source_object.api_key)
	                                 .replace(/\$\{latitude\}/g, location.latitude)
	                                 .replace(/\$\{longitude\}/g, location.longitude);
}

/* Will be used to take a JavaScript object returned from forecast.io
 * to fill our own forecast variable(s)
 */
function forecastio2wa(result_object) {
	// FIXME
}

/* Will be used to keep from calling the other APIs during testing
 */
function test2wa(result_object) {
	return {
		location: {
			latitude: result_object.latitude,
			longitude: result_object.longitude
		},
		now: {
			temp: result_object.currently.temperature,
			temp_apparent: result_object.currently.apparentTemperature,
			conditions: result_object.currently.summary,
			icon: test2waIcon(result_object.currently.icon),
			nearest_storm: {
				bearing: result_object.currently.nearestStormBearing || 0,
				distance: result_object.currently.nearestStormDistance || 0
			},
			precipitation: {
				insensity: result_object.currently.precipIntensity,
				probability: result_object.currently.precipProbability,
				type: result_object.currently.precipType
			},
			wind: {
				speed: result_object.currently.windSpeed,
				bearing: result_object.currently.windBearing
			}
		},
		today: {
			temp: {
				hourly: [],
				high: result_object.daily.data[0].temperatureMax,
				low: result_object.daily.data[0].temperatureMin
			},
			sun: {
				rise_time: result_object.daily.data[0].sunriseTime,
				set_time: result_object.daily.data[0].sunsetTime
			}
		},
		week: {
			daily_temps: []
		},
		alerts: result_object.alerts,
		units: {
			temp: 'F',
			distance: 'mi'
		}
	};
}

function test2waIcon(origText) {
	switch (origText) {
		case 'partly-cloudy-day':
			return 'day-cloudy';
		case 'partly-cloudy-night ':
			return 'night-alt-cloudy';
		case 'cloudy':
			return 'cloudy';
		case 'wind':
			return 'strong-wind';
		case 'sleet':
			return 'rain-mix';
		case 'snow':
			return 'snow';
		case 'rain':
			return 'rain';
		case 'clear-night':
			return 'night-clear';
		case 'clear-day':
			return 'day-sunny';
		default:
			return origText;
	}
}

module.exports = {
	reload_interval: reload_interval,
	valid_sources: valid_sources,
	location: location,
	getWeather: getWeather,
	setLocation: setLocation
};

// This is only to show the expected layout, and will probably be removed soon.
// var forecast = {
// 	location: { // To keep up with where this forecast was for. Note to self: maybe useful for caching calls, too??
// 		latitude: '',
// 		longitude: ''
// 	},
// 	now: {
// 		temp: '',
// 		temp_apparent: '',
// 		conditions: '',
// 		icon: '',
// 		nearest_storm: {
// 			bearing: '', // A numerical value representing the direction of the nearest storm in degrees, with true north at 0° and progressing clockwise. (If nearestStormDistance is zero, then this value will not be defined. The caveats that apply to nearestStormDistance also apply to this value.)
// 			distance: '' // A numerical value representing the distance to the nearest storm in miles. (This value is very approximate and should not be used in scenarios requiring accurate results. In particular, a storm distance of zero doesn’t necessarily refer to a storm at the requested location, but rather a storm in the vicinity of that location.)
// 		},
// 		precipitation: {
// 			insensity: '', // A numerical value representing the average expected intensity (in inches of liquid water per hour) of precipitation occurring at the given time conditional on probability (that is, assuming any precipitation occurs at all). A very rough guide is that a value of 0 in./hr. corresponds to no precipitation, 0.002 in./hr. corresponds to very light precipitation, 0.017 in./hr. corresponds to light precipitation, 0.1 in./hr. corresponds to moderate precipitation, and 0.4 in./hr. corresponds to heavy precipitation.
// 			probability: '',
// 			type: ''
// 		},
// 		wind: {
// 			speed: '',
// 			bearing: ''
// 		}
// 	},
// 	today: {
// 		temp: {
// 			hourly: [],
// 			high: '',
// 			low: ''
// 		},
// 		sun: {
// 			rise_time: '',
// 			set_time: ''
// 		}
// 	},
// 	week: {
// 		daily_temps: []
// 	},
// 	alerts: [],
// 	units: {
// 		temp: '', // C, F, K, etc
// 		distance: '' // km, m, mi, etc.
// 	}
// };
<commit_msg>Add api_key_name to other sources; also add weather.gov as a potential source<commit_after>var https = require('https');
var reload_interval = 180000; // Interval (in milliseconds) to refresh
var location = {};

var valid_sources = [
	{
		name: 'forecast.io', // Human-readable name of the source (required)
		source_site: 'https://developer.forecast.io/', // Website of source for info. Developer site preferred (optional)
		api_key: '', // The API key... see api_key_name. This will be set later using the api_key_name.
		api_key_name: 'forecast_io', // ** Name of ** the API key in the settings file (if needed). The settings file is ignored in git, so we can keep our keys here
		forecast_uri: 'https://api.forecast.io/forecast/${api_key}/${latitude},${longitude}', // URI to get general forecast data (required)
		storm_array_uri: 'https://api.darkskyapp.com/v1/interesting/${api_key}', // URI to get wide-area storm data (optional)
		last_call: undefined, // Last time this source was called. Used for caching request results (esp. to keep from using up free API keys :)
		conversion: forecastio2wa // Function to populate our own variables from the API's. Should expect 1 argument - an object the API responded with (required)
	},
	{
		name: 'OpenWeatherMap',
		api_key: '',
		api_key_name: 'openweathermap',
		forecast_uri: '',
		storm_array_uri: '',
		last_call: undefined,
		conversion: undefined
	},
	{
		name: 'Weather Underground',
		api_key: '',
		api_key_name: 'wunderground',
		forecast_uri: '',
		storm_array_uri: '',
		last_call: undefined,
		conversion: undefined
	},
	{
		name: 'National Weather Service',
		api_key: '',
		api_key_name: 'weather_gov',
		forecast_uri: '',
		storm_array_uri: '',
		last_call: undefined,
		conversion: undefined
	},
	{
		name: 'test',
		api_key: '',
		api_key_name: '',
		forecast_uri: 'file://' + __dirname + '/test/local.json',
		storm_array_uri: '',
		last_call: undefined,
		conversion: test2wa
	}
];

function getWeather(lat, lon, source_obj) {
	if (source_obj === undefined) {
		source_obj = valid_sources[0];
	}

	return callAPI(parseAPIURI(source_obj), source_obj.conversion);
}

function setLocation(lat, lon) {
	location = { latitude: lat, longitude: lon };
}

/* Will be used as the entry-point for getting info from the API URI,
 * calling conversion functions, etc.
 */
function callAPI(uri, on_complete) {
	var output = '';

	if (uri.slice(0, 7) === 'file://') {
		return on_complete(JSON.parse(require('fs').readFileSync(uri.slice(7))));
	}

	https.get(uri, function (res) {
		res.setEncoding('UTF-8');

		res.on('data', function (data) {
			output += data;
		});

		res.on('end', function (data) {
			return on_complete(JSON.parse(data));
		});
	});
}

function parseAPIURI(source_object) {
	return source_object.forecast_uri.replace(/\$\{api_key\}/g, source_object.api_key)
	                                 .replace(/\$\{latitude\}/g, location.latitude)
	                                 .replace(/\$\{longitude\}/g, location.longitude);
}

/* Will be used to take a JavaScript object returned from forecast.io
 * to fill our own forecast variable(s)
 */
function forecastio2wa(result_object) {
	// FIXME
}

/* Will be used to keep from calling the other APIs during testing
 */
function test2wa(result_object) {
	return {
		location: {
			latitude: result_object.latitude,
			longitude: result_object.longitude
		},
		now: {
			temp: result_object.currently.temperature,
			temp_apparent: result_object.currently.apparentTemperature,
			conditions: result_object.currently.summary,
			icon: test2waIcon(result_object.currently.icon),
			nearest_storm: {
				bearing: result_object.currently.nearestStormBearing || 0,
				distance: result_object.currently.nearestStormDistance || 0
			},
			precipitation: {
				insensity: result_object.currently.precipIntensity,
				probability: result_object.currently.precipProbability,
				type: result_object.currently.precipType
			},
			wind: {
				speed: result_object.currently.windSpeed,
				bearing: result_object.currently.windBearing
			}
		},
		today: {
			temp: {
				hourly: [],
				high: result_object.daily.data[0].temperatureMax,
				low: result_object.daily.data[0].temperatureMin
			},
			sun: {
				rise_time: result_object.daily.data[0].sunriseTime,
				set_time: result_object.daily.data[0].sunsetTime
			}
		},
		week: {
			daily_temps: []
		},
		alerts: result_object.alerts,
		units: {
			temp: 'F',
			distance: 'mi'
		}
	};
}

function test2waIcon(origText) {
	switch (origText) {
		case 'partly-cloudy-day':
			return 'day-cloudy';
		case 'partly-cloudy-night ':
			return 'night-alt-cloudy';
		case 'cloudy':
			return 'cloudy';
		case 'wind':
			return 'strong-wind';
		case 'sleet':
			return 'rain-mix';
		case 'snow':
			return 'snow';
		case 'rain':
			return 'rain';
		case 'clear-night':
			return 'night-clear';
		case 'clear-day':
			return 'day-sunny';
		default:
			return origText;
	}
}

module.exports = {
	reload_interval: reload_interval,
	valid_sources: valid_sources,
	location: location,
	getWeather: getWeather,
	setLocation: setLocation
};

// This is only to show the expected layout, and will probably be removed soon.
// var forecast = {
// 	location: { // To keep up with where this forecast was for. Note to self: maybe useful for caching calls, too??
// 		latitude: '',
// 		longitude: ''
// 	},
// 	now: {
// 		temp: '',
// 		temp_apparent: '',
// 		conditions: '',
// 		icon: '',
// 		nearest_storm: {
// 			bearing: '', // A numerical value representing the direction of the nearest storm in degrees, with true north at 0° and progressing clockwise. (If nearestStormDistance is zero, then this value will not be defined. The caveats that apply to nearestStormDistance also apply to this value.)
// 			distance: '' // A numerical value representing the distance to the nearest storm in miles. (This value is very approximate and should not be used in scenarios requiring accurate results. In particular, a storm distance of zero doesn’t necessarily refer to a storm at the requested location, but rather a storm in the vicinity of that location.)
// 		},
// 		precipitation: {
// 			insensity: '', // A numerical value representing the average expected intensity (in inches of liquid water per hour) of precipitation occurring at the given time conditional on probability (that is, assuming any precipitation occurs at all). A very rough guide is that a value of 0 in./hr. corresponds to no precipitation, 0.002 in./hr. corresponds to very light precipitation, 0.017 in./hr. corresponds to light precipitation, 0.1 in./hr. corresponds to moderate precipitation, and 0.4 in./hr. corresponds to heavy precipitation.
// 			probability: '',
// 			type: ''
// 		},
// 		wind: {
// 			speed: '',
// 			bearing: ''
// 		}
// 	},
// 	today: {
// 		temp: {
// 			hourly: [],
// 			high: '',
// 			low: ''
// 		},
// 		sun: {
// 			rise_time: '',
// 			set_time: ''
// 		}
// 	},
// 	week: {
// 		daily_temps: []
// 	},
// 	alerts: [],
// 	units: {
// 		temp: '', // C, F, K, etc
// 		distance: '' // km, m, mi, etc.
// 	}
// };
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { View, Modal, TouchableWithoutFeedback } from "react-native";
import {
	Input,
	Item,
	List,
	ListItem,
	Text,
	Button,
	Header,
	Left,
	Right,
	Icon } from "native-base";
import { connect } from "react-redux";

import { addComponent, removeComponent, watchComponent, updateQuery } from "../actions";
import { isEqual, debounce, pushToAndClause } from "../utils/helper";

class DataSearch extends Component {
	constructor(props) {
		super(props);

		this.state = {
			currentValue: "",
			suggestions: [],
			showModal: false
		};
		this.internalComponent = this.props.componentId + "__internal";
	}

	componentDidMount() {
		this.props.addComponent(this.props.componentId);
		this.props.addComponent(this.internalComponent);
		this.setReact(this.props);

		this.updateQuery = debounce((component, value) => {
			const query = this.props.customQuery || this.defaultQuery;
			let callback = null;
			if (component === this.props.componentId && this.props.onQueryChange) {
				callback = this.props.onQueryChange;
			}
			this.props.updateQuery(component, query(value), callback);
		}, 300);
	}

	componentWillReceiveProps(nextProps) {
		if (!isEqual(nextProps.react, this.props.react)) {
			this.setReact(nextProps);
		}
		if (Array.isArray(nextProps.suggestions)
			&& !isEqual(this.props.suggestions, nextProps.suggestions)
			&& this.state.currentValue.trim() !== "") {
			this.setState({
				suggestions: nextProps.suggestions
			});
		}
	}

	componentWillUnmount() {
		this.props.removeComponent(this.props.componentId);
		this.props.removeComponent(this.internalComponent);
	}

	setReact(props) {
		const { react } = props;
		if (props.react) {
			newReact = pushToAndClause(react, this.internalComponent)
			props.watchComponent(props.componentId, newReact);
		} else {
			props.watchComponent(props.componentId, { and: this.internalComponent });
		}
	}

	defaultQuery(value) {
		let finalQuery = null,
			fields;
		if (value) {
			if (Array.isArray(this.props.dataField)) {
				fields = this.props.dataField;
			} else {
				fields = [this.props.dataField];
			}
			finalQuery = {
				bool: {
					should: this.shouldQuery(value, fields),
					minimum_should_match: "1"
				}
			};
		}

		if (value === "") {
			finalQuery = {
				"match_all": {}
			}
		}

		return finalQuery;
	}

	shouldQuery(value, dataFields) {
		const fields = dataFields.map(
			(field, index) => `${field}${(Array.isArray(this.props.weights) && this.props.weights[index]) ? ("^" + this.props.weights[index]) : ""}`
		);

		if (this.props.queryFormat === "and") {
			return [
				{
					multi_match: {
						query: value,
						fields,
						type: "cross_fields",
						operator: "and",
						fuzziness: this.props.fuzziness ? this.props.fuzziness : 0
					}
				},
				{
					multi_match: {
						query: value,
						fields,
						type: "phrase_prefix",
						operator: "and"
					}
				}
			];
		}

		return [
			{
				multi_match: {
					query: value,
					fields,
					type: "best_fields",
					operator: "or",
					fuzziness: this.props.fuzziness ? this.props.fuzziness : 0
				}
			},
			{
				multi_match: {
					query: value,
					fields,
					type: "phrase_prefix",
					operator: "or"
				}
			}
		];
	}

	setValue = (value) => {
		this.setState({
			currentValue: value
		});
		if (this.props.autoSuggest) {
			this.updateQuery(this.internalComponent, value);
		} else {
			this.updateQuery(this.props.componentId, value);
		}
	};

	selectSuggestion = (value) => {
		this.setState({
			currentValue: value,
			suggestions: []
		});
		this.updateQuery(this.props.componentId, value);
		this.toggleModal();
	};

	setSuggestions = () => {
		let suggestions = [];
		if (this.state.currentValue.trim() !== "") {
			suggestions = this.props.suggestions;
		}

		this.setState({
			suggestions
		});
	};

	toggleModal = () => {
		this.setState({
			showModal: !this.state.showModal
		})
	};

	renderSuggestions() {
		if (this.props.autoSuggest && Array.isArray(this.state.suggestions)) {
			return (<List
				dataArray={this.state.suggestions}
				keyboardShouldPersistTaps="always"
				renderRow={(item) =>
					<ListItem
						onPress={() => this.selectSuggestion(item._source.name)}
					>
						<Text>{item._source.name}</Text>
					</ListItem>
				}>
			</List>)
		}

		return null;
	}

	renderDataSearch = () => {
		if (this.state.showModal) {
			return (<Modal
				supportedOrientations={this.props.supportedOrientations || null}
				transparent={false}
				visible={this.state.showModal}
				onRequestClose={() => {
					this.toggleModal();
				}}
			>
				<Header>
					<Left>
						<Button transparent onPress={this.toggleModal}>
							<Icon name="arrow-back" />
						</Button>
					</Left>
					{
						this.state.currentValue
							? (<Right>
								<Button transparent onPress={() => this.selectSuggestion("")}><Text>Reset</Text></Button>
							</Right>)
							: null
					}
				</Header>
				<Item regular style={{ marginLeft: 10, margin: 10 }}>
					<Input
						placeholder={this.props.placeholder}
						onChangeText={this.setValue}
						value={this.state.currentValue}
						onFocus={this.setSuggestions}
						autoFocus
					/>
				</Item>
				{this.renderSuggestions()}
			</Modal>);
		}

		return (<Item regular style={{ marginLeft: 0 }}>
			<TouchableWithoutFeedback
				onPress={this.toggleModal}
			>
				<Text
					style={{
						flex: 1,
						alignItems: "center",
						color: this.state.currentValue && this.state.currentValue !== "" ? "#000" : "#555",
						flex: 1,
						fontSize: 17,
						height: 50,
						lineHeight: 24,
						paddingLeft: 8,
						paddingRight: 5,
						paddingTop: 12
					}}
				>
					{
						this.state.currentValue && this.state.currentValue !== ""
							? this.state.currentValue
							: this.props.placeholder
					}
				</Text>
			</TouchableWithoutFeedback>
		</Item>)
	}

	render() {
		return (
			<View>
				{
					this.props.autoSuggest
						? this.renderDataSearch()
						: <Item regular style={{ marginLeft: 0 }}>
							<Input
								placeholder={this.props.placeholder}
								onChangeText={this.setValue}
								value={this.state.currentValue}
							/>
						</Item>
				}
			</View>
		);
	}
}

DataSearch.defaultProps = {
	placeholder: "Search",
	autoSuggest: true,
	queryFormat: "or"
}

const mapStateToProps = (state, props) => ({
	suggestions: state.hits[props.componentId] && state.hits[props.componentId].hits
});

const mapDispatchtoProps = dispatch => ({
	addComponent: component => dispatch(addComponent(component)),
	removeComponent: component => dispatch(removeComponent(component)),
	watchComponent: (component, react) => dispatch(watchComponent(component, react)),
	updateQuery: (component, query, onQueryChange) => dispatch(updateQuery(component, query, onQueryChange))
});

export default connect(mapStateToProps, mapDispatchtoProps)(DataSearch);
<commit_msg>Extend DataSearch with defaultSelected<commit_after>import React, { Component } from "react";
import { View, Modal, TouchableWithoutFeedback } from "react-native";
import {
	Input,
	Item,
	List,
	ListItem,
	Text,
	Button,
	Header,
	Left,
	Right,
	Icon } from "native-base";
import { connect } from "react-redux";

import { addComponent, removeComponent, watchComponent, updateQuery } from "../actions";
import { isEqual, debounce, pushToAndClause } from "../utils/helper";

class DataSearch extends Component {
	constructor(props) {
		super(props);

		this.state = {
			currentValue: "",
			suggestions: [],
			showModal: false
		};
		this.internalComponent = this.props.componentId + "__internal";
	}

	componentDidMount() {
		this.props.addComponent(this.props.componentId);
		this.props.addComponent(this.internalComponent);
		this.setReact(this.props);

		this.updateQuery = debounce((component, value) => {
			const query = this.props.customQuery || this.defaultQuery;
			let callback = null;
			if (component === this.props.componentId && this.props.onQueryChange) {
				callback = this.props.onQueryChange;
			}
			this.props.updateQuery(component, query(value), callback);
		}, 300);
		if (this.props.defaultSelected) {
			this.setValue(this.props.defaultSelected);
		}
	}

	componentWillReceiveProps(nextProps) {
		if (!isEqual(nextProps.react, this.props.react)) {
			this.setReact(nextProps);
		}
		if (Array.isArray(nextProps.suggestions)
			&& !isEqual(this.props.suggestions, nextProps.suggestions)
			&& this.state.currentValue.trim() !== "") {
			this.setState({
				suggestions: nextProps.suggestions
			});
		}
		if (this.props.defaultSelected !== nextProps.defaultSelected) {
			this.setValue(nextProps.defaultSelected);
		}
	}

	componentWillUnmount() {
		this.props.removeComponent(this.props.componentId);
		this.props.removeComponent(this.internalComponent);
	}

	setReact(props) {
		const { react } = props;
		if (props.react) {
			newReact = pushToAndClause(react, this.internalComponent)
			props.watchComponent(props.componentId, newReact);
		} else {
			props.watchComponent(props.componentId, { and: this.internalComponent });
		}
	}

	defaultQuery = (value) => {
		let finalQuery = null,
			fields;
		if (value) {
			if (Array.isArray(this.props.dataField)) {
				fields = this.props.dataField;
			} else {
				fields = [this.props.dataField];
			}
			finalQuery = {
				bool: {
					should: this.shouldQuery(value, fields),
					minimum_should_match: "1"
				}
			};
		}

		if (value === "") {
			finalQuery = {
				"match_all": {}
			}
		}

		return finalQuery;
	}

	shouldQuery(value, dataFields) {
		const fields = dataFields.map(
			(field, index) => `${field}${(Array.isArray(this.props.weights) && this.props.weights[index]) ? ("^" + this.props.weights[index]) : ""}`
		);

		if (this.props.queryFormat === "and") {
			return [
				{
					multi_match: {
						query: value,
						fields,
						type: "cross_fields",
						operator: "and",
						fuzziness: this.props.fuzziness ? this.props.fuzziness : 0
					}
				},
				{
					multi_match: {
						query: value,
						fields,
						type: "phrase_prefix",
						operator: "and"
					}
				}
			];
		}

		return [
			{
				multi_match: {
					query: value,
					fields,
					type: "best_fields",
					operator: "or",
					fuzziness: this.props.fuzziness ? this.props.fuzziness : 0
				}
			},
			{
				multi_match: {
					query: value,
					fields,
					type: "phrase_prefix",
					operator: "or"
				}
			}
		];
	}

	setValue = (value) => {
		this.setState({
			currentValue: value
		});
		if (this.props.autoSuggest) {
			this.updateQuery(this.internalComponent, value);
		} else {
			this.updateQuery(this.props.componentId, value);
		}
	};

	selectSuggestion = (value) => {
		this.setState({
			currentValue: value,
			suggestions: []
		});
		this.updateQuery(this.props.componentId, value);
		this.toggleModal();
	};

	setSuggestions = () => {
		let suggestions = [];
		if (this.state.currentValue.trim() !== "") {
			suggestions = this.props.suggestions;
		}

		this.setState({
			suggestions
		});
	};

	toggleModal = () => {
		this.setState({
			showModal: !this.state.showModal
		})
	};

	renderSuggestions() {
		if (this.props.autoSuggest && Array.isArray(this.state.suggestions)) {
			return (<List
				dataArray={this.state.suggestions}
				keyboardShouldPersistTaps="always"
				renderRow={(item) =>
					<ListItem
						onPress={() => this.selectSuggestion(item._source.name)}
					>
						<Text>{item._source.name}</Text>
					</ListItem>
				}>
			</List>)
		}

		return null;
	}

	renderDataSearch = () => {
		if (this.state.showModal) {
			return (<Modal
				supportedOrientations={this.props.supportedOrientations || null}
				transparent={false}
				visible={this.state.showModal}
				onRequestClose={() => {
					this.toggleModal();
				}}
			>
				<Header>
					<Left>
						<Button transparent onPress={this.toggleModal}>
							<Icon name="arrow-back" />
						</Button>
					</Left>
					{
						this.state.currentValue
							? (<Right>
								<Button transparent onPress={() => this.selectSuggestion("")}><Text>Reset</Text></Button>
							</Right>)
							: null
					}
				</Header>
				<Item regular style={{ marginLeft: 10, margin: 10 }}>
					<Input
						placeholder={this.props.placeholder}
						onChangeText={this.setValue}
						value={this.state.currentValue}
						onFocus={this.setSuggestions}
						autoFocus
					/>
				</Item>
				{this.renderSuggestions()}
			</Modal>);
		}

		return (<Item regular style={{ marginLeft: 0 }}>
			<TouchableWithoutFeedback
				onPress={this.toggleModal}
			>
				<Text
					style={{
						flex: 1,
						alignItems: "center",
						color: this.state.currentValue && this.state.currentValue !== "" ? "#000" : "#555",
						flex: 1,
						fontSize: 17,
						height: 50,
						lineHeight: 24,
						paddingLeft: 8,
						paddingRight: 5,
						paddingTop: 12
					}}
				>
					{
						this.state.currentValue && this.state.currentValue !== ""
							? this.state.currentValue
							: this.props.placeholder
					}
				</Text>
			</TouchableWithoutFeedback>
		</Item>)
	}

	render() {
		return (
			<View>
				{
					this.props.autoSuggest
						? this.renderDataSearch()
						: <Item regular style={{ marginLeft: 0 }}>
							<Input
								placeholder={this.props.placeholder}
								onChangeText={this.setValue}
								value={this.state.currentValue}
							/>
						</Item>
				}
			</View>
		);
	}
}

DataSearch.defaultProps = {
	placeholder: "Search",
	autoSuggest: true,
	queryFormat: "or"
}

const mapStateToProps = (state, props) => ({
	suggestions: state.hits[props.componentId] && state.hits[props.componentId].hits
});

const mapDispatchtoProps = dispatch => ({
	addComponent: component => dispatch(addComponent(component)),
	removeComponent: component => dispatch(removeComponent(component)),
	watchComponent: (component, react) => dispatch(watchComponent(component, react)),
	updateQuery: (component, query, onQueryChange) => dispatch(updateQuery(component, query, onQueryChange))
});

export default connect(mapStateToProps, mapDispatchtoProps)(DataSearch);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Text } from 'react-native';

import styles from '../../styles/styles';
import InPageImage from '../inPageImage';
import AnimalText from '../animalText';
import AnimalTemplate from '../animalTemplate';

const IMAGES = [
  require('../../images/animals/krkavecVelky/01.jpg'),
];

const THUMBNAILS = [
  require('../../images/animals/krkavecVelky/01-thumb.jpg'),
];

var AnimalDetail = React.createClass({
  render() {
    return (
      <AnimalTemplate firstIndex={[0]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator}>
        <AnimalText>
          Nazdar krasavci!
        </AnimalText>
        <AnimalText>
          Jistě jste zdatní přírodovědci, přesto vás musíme upozornit, že ne každý zná naše opravdové jméno. Takže aby bylo jasno – nejsme havrani, protože ti jsou oproti nám menší, mají světlejší zobák a v zimě je někdy potkáte ve městech. Nejsme ani vrány, protože těm se neleskne peří. Jsme krkavci. Brázdíme lesy skoro celé severní polokoule, a tak se občas objevíme i v těch českých.
        </AnimalText>
        <AnimalText>
          Jeden takový hluboký hvozd obýval náš prapradědeček Krako. Už od malička se chtěl stát rytířem. Neohroženě se pral o každou kořist, zobákem naporcoval kdejakou mršinu a k tomu všemu byl vysoce inteligentní. Říká se, že dokonce uměl napočítat do osmi!
        </AnimalText>
        <AnimalText>
          Žádná z těchto schopností mu bohužel nezajistila to, po čem toužil nejvíc – správný rytíř musel patřit k nějakému řádu. Přijímací zkoušky se však vyhlašovaly jen do Řádu pěvců, kde na jeho krákání nebyl nikdo zvědav. Krako se rozhodl, že se do přijímaček prostě zpívat naučí.
        </AnimalText>
        <AnimalText>
          Sehnat v lese učitele nebylo jednoduché. Zvířata se krkavců bála, protože je často viděla na popravištích. Krako nechtěl nikoho vyděsit, a tak nakonec přestal hledat ptačího učitele a začal tajně poslouchat turisty. Člověčí hlas ho fascinoval.
        </AnimalText>
        <AnimalText>
          Zanedlouho přišel den přijímacích zkoušek. Krako stanul na větvi před odbornou porotou z Řádu pěvců a spustil: „Hele, hříbek! Pojďme doprava. Tady je krásně!“ Sice to bylo spíš mluvení než zpěv, ale porota byla ohromená. Ocenila Krakovu snahu a do Řádu pěvců ho přijala.
        </AnimalText>
        <AnimalText>
          Krako byl od té doby respektovaný rytíř. Odháněl turisty od zvířecích obydlí – vždycky se někam schoval, pronesl naučenou větu a lidé šli tam, kam je navedl. Za odměnu si mohl vystlat hnízdo jemným mechem a prvotřídním blátem, které zajistily pohodlí pro šest krkavčích ptáčat.
        </AnimalText>
        <AnimalText>
          Vědci od té doby říkají, že krkavci jsou dokonce největší ptáci patřící do řádu pěvců. Někteří se naučí napodobovat řeč nebo zpěv lidí víc, jiní se jen schovávají v přírodě, sedí na rameni čarodějnicím nebo radostně krákají v zoo. My krkavci z brněnské zoo jsme na svoje krákání pyšní. Když tu u nás chvilku počkáte, určitě vám svůj hlas předvedeme.
        </AnimalText>
      </AnimalTemplate>
    );
  }
});

module.exports = AnimalDetail;
<commit_msg>Update krkavecVelky.child.js<commit_after>import React, { Component } from 'react';
import { Text } from 'react-native';

import styles from '../../styles/styles';
import InPageImage from '../inPageImage';
import AnimalText from '../animalText';
import AnimalTemplate from '../animalTemplate';

const IMAGES = [
  require('../../images/animals/krkavecVelky/01.jpg'),
];

const THUMBNAILS = [
  require('../../images/animals/krkavecVelky/01-thumb.jpg'),
];

var AnimalDetail = React.createClass({
  render() {
    return (
      <AnimalTemplate firstIndex={[0]} thumbnails={THUMBNAILS} images={IMAGES} navigator={this.props.navigator}>
        <AnimalText>
          Nazdar krasavci!
        </AnimalText>
        <AnimalText>
          Jistě jste zdatní přírodovědci, přesto vás musíme upozornit, že ne každý zná naše opravdové jméno. Takže aby bylo jasno – nejsme havrani, protože ti jsou oproti nám menší a v zimě je někdy potkáte ve městech. Nejsme ani vrány. Jsme krkavci. Brázdíme lesy i otevřená prostředí skoro celé severní polokoule, a tak se občas objevíme i v těch českých.
        </AnimalText>
        <AnimalText>
          Jeden takový hluboký hvozd obýval náš prapradědeček Krako. Už od malička se chtěl stát rytířem. Neohroženě se pral o každou kořist, zobákem naporcoval kdejakou mršinu a k tomu všemu byl vysoce inteligentní. Říká se, že dokonce uměl napočítat do osmi!
        </AnimalText>
        <AnimalText>
          Žádná z těchto schopností mu bohužel nezajistila to, po čem toužil nejvíc – správný rytíř musel patřit k nějakému řádu. Přijímací zkoušky se však vyhlašovaly jen do Řádu pěvců, kde na jeho krákání nebyl nikdo zvědav. Krako se rozhodl, že se do přijímaček prostě zpívat naučí.
        </AnimalText>
        <AnimalText>
          Sehnat v lese učitele nebylo jednoduché. Zvířata se krkavců bála, protože je často viděla na popravištích. Krako nechtěl nikoho vyděsit, a tak nakonec přestal hledat ptačího učitele a začal tajně poslouchat turisty. Člověčí hlas ho fascinoval.
        </AnimalText>
        <AnimalText>
          Zanedlouho přišel den přijímacích zkoušek. Krako stanul na větvi před odbornou porotou z Řádu pěvců a spustil: „Hele, hříbek! Pojďme doprava. Tady je krásně!“ Sice to bylo spíš mluvení než zpěv, ale porota byla ohromená. Ocenila Krakovu snahu a do Řádu pěvců ho přijala.
        </AnimalText>
        <AnimalText>
          Krako byl od té doby respektovaný rytíř. Odháněl turisty od zvířecích obydlí – vždycky se někam schoval, pronesl naučenou větu a lidé šli tam, kam je navedl. Za odměnu si mohl vystlat hnízdo jemným mechem a prvotřídním blátem, které zajistily pohodlí pro šest krkavčích ptáčat.
        </AnimalText>
        <AnimalText>
          Vědci od té doby říkají, že krkavci jsou dokonce největší ptáci patřící do řádu pěvců. Někteří se naučí napodobovat řeč nebo zpěv lidí víc, jiní se jen schovávají v přírodě, sedí na rameni čarodějnicím nebo radostně krákají v zoo. My krkavci z brněnské zoo jsme na svoje krákání pyšní. Když tu u nás chvilku počkáte, určitě vám svůj hlas předvedeme.
        </AnimalText>
      </AnimalTemplate>
    );
  }
});

module.exports = AnimalDetail;
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular.module('scaleConfigModule', []).provider('scaleConfig', function () {
        var scaleConfig = {},
            scaleConfigLocal = {};

        this.$get = function () {
            var config = $.ajax({
                type: 'GET',
                url: '/config/scaleConfig.json',
                cache: false,
                async: false,
                contentType: 'application/json',
                dataType: 'json'
            });

            if (config.status === 200) {
                scaleConfig = config.responseJSON.scaleConfig;

                var configLocal = $.ajax({
                    type: 'GET',
                    url: '/config/scaleConfig.local.json',
                    cache: false,
                    async: false,
                    contentType: 'application/json',
                    dataType: 'json'
                });

                if (configLocal.status === 200) {
                    scaleConfigLocal = configLocal.responseJSON.scaleConfigLocal;
                }

                _.merge(scaleConfig, scaleConfigLocal);
            }

            return scaleConfig;
        }
    });
})();
<commit_msg>fixing urls for config files<commit_after>(function () {
    'use strict';

    angular.module('scaleConfigModule', []).provider('scaleConfig', function () {
        var scaleConfig = {},
            scaleConfigLocal = {};

        this.$get = function () {
            var config = $.ajax({
                type: 'GET',
                url: 'config/scaleConfig.json',
                cache: false,
                async: false,
                contentType: 'application/json',
                dataType: 'json'
            });

            if (config.status === 200) {
                scaleConfig = config.responseJSON.scaleConfig;

                var configLocal = $.ajax({
                    type: 'GET',
                    url: 'config/scaleConfig.local.json',
                    cache: false,
                    async: false,
                    contentType: 'application/json',
                    dataType: 'json'
                });

                if (configLocal.status === 200) {
                    scaleConfigLocal = configLocal.responseJSON.scaleConfigLocal;
                }

                _.merge(scaleConfig, scaleConfigLocal);
            }

            return scaleConfig;
        }
    });
})();
<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter,
    inherits = require('util').inherits,
    ErrorNotConnected = require('./DebuggerClient').ErrorNotConnected;

/**
 * FrontendClient encapsulates communication with front-end running in browser.
 * @param {{on: Function, send: Function}} connection
 *   Socket.io connection object.
 * @constructor
 * @extends EventEmitter
 */
function FrontendClient(connection) {
  this._connection = connection;
  this._registerEventHandlers();
}

inherits(FrontendClient, EventEmitter);

Object.defineProperties(FrontendClient.prototype, {
  /** @type {boolean} */
  isConnected: {
    get: function() {
      return this._connection != null;
    }
  }
});

FrontendClient.prototype._registerEventHandlers = function() {
  this._connection.on('disconnect', this._onConnectionClose.bind(this));
  this._connection.on('message', this._onConnectionMessage.bind(this));
};

FrontendClient.prototype._onConnectionClose = function() {
  this._connection = null;
  this.emit('close');
};

FrontendClient.prototype._onConnectionMessage = function(message) {
  this.emit('message', message);
};

/**
 * Send a message to front-end.
 * @param {!Object|string} message
 */
FrontendClient.prototype._sendMessage = function(message) {
  if (!this._connection) {
    console.log('Cannot send response - there is no front-end connection.');
    return;
  }

  var payload = typeof message == 'string' ? message : JSON.stringify(message);
  this._connection.send(payload);
};

/**
 * Send a response to a front-end request.
 * @param {number} requestId Id of the request.
 * @param {string} fullMethodName
 * @param {?string} error Error message or null/undefined on success.
 * @param {Object=} result Response data on success.
 */
FrontendClient.prototype.sendResponse = function(requestId,
                                                 fullMethodName,
                                                 error,
                                                 result) {
  if (requestId == null) {
    throw new Error(
      'Cannot send response to ' +
        fullMethodName +
        ' without a requestId');
  }

  var message = { id: requestId };
  if (error != null) {
    this._onErrorResponse(fullMethodName, error);
    message.error = error.toString();
  } else {
    message.result = result;
  }

  this._sendMessage(message);
};

FrontendClient.prototype._onErrorResponse = function(fullMethodName, error) {
  if (error instanceof ErrorNotConnected) {
    this.sendInspectorDetached(error.message);
  }
  this.sendLogToConsole('error', fullMethodName + ' failed.\n' + error);
};

/**
 * Send an event to the front-end.
 * @param {string} eventName Event name in form 'Agent.method'.
 * @param {Object=} data Event data (method arguments).
 */
FrontendClient.prototype.sendEvent = function(eventName, data) {
  var message = {
    method: eventName,
    params: data || {}
  };
  this._sendMessage(message);
};

/**
 * Ask frontend to add a new log into console window.
 * @param {string} level Message level (error, warning, log, debug).
 * @param {string} text
 */
FrontendClient.prototype.sendLogToConsole = function(level, text) {
  this._sendMessage('showConsole');
  this.sendEvent(
    'Console.messageAdded',
    {
      message: {
        source: 3,
        type: 0,
        level: level,
        line: 0,
        column: 0,
        url: '',
        groupLevel: 7,
        repeatCount: 1,
        text: text
      }
    }
  );
};

/**
 * Shortcut for sendEvent('Inspector.detached', reason)
 * @param {string} reason
 */
FrontendClient.prototype.sendInspectorDetached = function(reason) {
  this.sendEvent('Inspector.detached', { reason: reason });
};

exports.FrontendClient = FrontendClient;
<commit_msg>Fixes bug that causes a ton of error messages on reload<commit_after>var EventEmitter = require('events').EventEmitter,
    inherits = require('util').inherits,
    ErrorNotConnected = require('./DebuggerClient').ErrorNotConnected;

/**
 * FrontendClient encapsulates communication with front-end running in browser.
 * @param {{on: Function, send: Function}} connection
 *   Socket.io connection object.
 * @constructor
 * @extends EventEmitter
 */
function FrontendClient(connection) {
  this._connection = connection;
  this._registerEventHandlers();
}

inherits(FrontendClient, EventEmitter);

Object.defineProperties(FrontendClient.prototype, {
  /** @type {boolean} */
  isConnected: {
    get: function() {
      return this._connection != null;
    }
  }
});

FrontendClient.prototype._registerEventHandlers = function() {
  this._connection.on('disconnect', this._onConnectionClose.bind(this));
  this._connection.on('message', this._onConnectionMessage.bind(this));
};

FrontendClient.prototype._onConnectionClose = function() {
  this._connection = null;
  this.emit('close');
};

FrontendClient.prototype._onConnectionMessage = function(message) {
  this.emit('message', message);
};

/**
 * Send a message to front-end.
 * @param {!Object|string} message
 */
FrontendClient.prototype._sendMessage = function(message) {
  if (!this._connection) {
    if(!this._errorMessageDisplayed) {
      console.log('Cannot send response - there is no front-end connection.');
      this._errorMessageDisplayed = true;
      var that = this;
      setTimeout(function() { that._errorMessageDisplayed = false; }, 10000);
    }

    return;
  }

  var payload = typeof message == 'string' ? message : JSON.stringify(message);
  this._connection.send(payload);
};

/**
 * Send a response to a front-end request.
 * @param {number} requestId Id of the request.
 * @param {string} fullMethodName
 * @param {?string} error Error message or null/undefined on success.
 * @param {Object=} result Response data on success.
 */
FrontendClient.prototype.sendResponse = function(requestId,
                                                 fullMethodName,
                                                 error,
                                                 result) {
  if (requestId == null) {
    throw new Error(
      'Cannot send response to ' +
        fullMethodName +
        ' without a requestId');
  }

  var message = { id: requestId };
  if (error != null) {
    this._onErrorResponse(fullMethodName, error);
    message.error = error.toString();
  } else {
    message.result = result;
  }

  this._sendMessage(message);
};

FrontendClient.prototype._onErrorResponse = function(fullMethodName, error) {
  if (error instanceof ErrorNotConnected) {
    this.sendInspectorDetached(error.message);
  }
  this.sendLogToConsole('error', fullMethodName + ' failed.\n' + error);
};

/**
 * Send an event to the front-end.
 * @param {string} eventName Event name in form 'Agent.method'.
 * @param {Object=} data Event data (method arguments).
 */
FrontendClient.prototype.sendEvent = function(eventName, data) {
  var message = {
    method: eventName,
    params: data || {}
  };
  this._sendMessage(message);
};

/**
 * Ask frontend to add a new log into console window.
 * @param {string} level Message level (error, warning, log, debug).
 * @param {string} text
 */
FrontendClient.prototype.sendLogToConsole = function(level, text) {
  this._sendMessage('showConsole');
  this.sendEvent(
    'Console.messageAdded',
    {
      message: {
        source: 3,
        type: 0,
        level: level,
        line: 0,
        column: 0,
        url: '',
        groupLevel: 7,
        repeatCount: 1,
        text: text
      }
    }
  );
};

/**
 * Shortcut for sendEvent('Inspector.detached', reason)
 * @param {string} reason
 */
FrontendClient.prototype.sendInspectorDetached = function(reason) {
  this.sendEvent('Inspector.detached', { reason: reason });
};

exports.FrontendClient = FrontendClient;
<|endoftext|>


<commit_before>var $db = require('./mongo');
var debug = require('debug')('wol:leaderboard');
var Arpad = require('arpad');
var $q = require('q');

// TODO: move this whole function somewheres else
/* saves player and game data */
exports.process = function(game, match) {
    var deferred = $q.defer();

    /* fail if we're somehow missing players */
    if (!match.players || match.players.length < 1) return;

    // create player entry
    var $players = $db.get(game +'_players');
    match.players.forEach(function(player, i) {
        /* typically Computer */
        if (!player.nam) {
            player.nam = 'Computer';
            return;
        }

        /* remove spectators */
        if (player.spc && player.spc > 0) {
            delete match.players[i];
            return;
        }

        // TODO: increase player map count
        var stats = {
            $push: {games: match.idno},
            $inc: {}
        };

        /* evaluate completions */
        if (player.cmp) {
            switch (player.cmp) {
                case 2:
                    stats.$inc.losses = 1;
                    stats.$inc.disconnects = 1;
                break;

                case 256:
                    stats.$inc.wins = 1;
                break;

                case 512:
                case 528:
                    stats.$inc.losses = 1;
                break;
            }
        }

        /* remove unused info */
        delete player.ipa; /* could be tunnel or p2p (unreliable) */
        delete player.addr; /* same reason but for ra1 */
        delete player.ser; /* serials are not used on CnCNet */
        delete player.accn; /* funky's client specific */

        $players.update({name: player.nam}, stats, {upsert: true});

        /* tack on stats so it can be referenced in game object */
        player.__gains = stats.$inc;
    });

    /* handle any game specific processing (bonuses?) */
    // require('../game/' + game).process(match);

    /* handle elo only for 1v1 games */
    if (match.players.length == 2) {
        var elo = new Arpad();
        var winner, loser;
        match.players.forEach(function(player, index) {
            if (player.__gains.wins) winner = index;
            if (player.__gains.losses) loser = index;
        });

        if (typeof winner !== 'undefined' && typeof loser !== 'undefined') {
            $players.find({name: {$in: [match.players[0].nam, match.players[1].nam]}}, function(err, data) {
                if (data && data.length == 2) {
                    data.forEach(function(player, index) {
                        var opponent = (index === 0) ? 1 : 0;
                        if (player.name == match.players[winner].nam)  {
                            points = elo.newRatingIfWon(player.points || 1500, data[opponent].points || 1500);
                            match.players[winner].__gains.points = points - (player.points || 1500);
                        } else {
                            points = elo.newRatingIfLost(player.points || 1500, data[opponent].points || 1500);
                            match.players[loser].__gains.points = (player.points || 1500) - points;
                        }

                        $players.update({_id: player._id}, {$set: {points: points}});
                    });
                }

                deferred.resolve(match);
            });
        } else {
            deferred.reject({code: 1, msg: 'Missing winner or loser'});
        }
    } else {
        deferred.resolve(match);
    }

    return deferred.promise;
};

/* WOL Game Resolution interpreter */
exports.parse = function(packet) {
    var buffer = packet;
    if (typeof packet === 'string') {
        // remove any unnessiccary whitespace
        packet = packet.replace(/(\r|\n|\r\n|\s+)/gm, '');
        buffer = new Buffer(packet, 'hex');
    }

    var flat = {}, i = 4;
    flat.buffer = buffer;
    var slice = buffer.slice(0, 4);
    var bufferLength = slice.readUInt16BE(0);

    while (i < bufferLength) {
        var chunk = buffer.slice(i,  i + 4);
        var field = chunk.toString();

        i += 4;

        chunk = buffer.slice(i, i + 8);

        var type = chunk.readUInt16BE(0);
        var length = chunk.readUInt16BE(2);
        var data = 'Unprocessed Data';

        i += 4;

        var end = i + length >= bufferLength ? bufferLength : i + length;

        if (i <= end) {
            data = _type(type, buffer.slice(i, end));
            length = Math.ceil(length / 4) * 4;
            i += length;
        }

        flat[field] = data;
    }

    return _consolidate(flat);
};

/* WOL field type interpreter */
function _type(type, chunk) {
    var data = 'Unprocessed Type';

    switch (type) {
        case 1:
            // [15:39:10] <CCHyper> 1 = byte
            data = chunk.readInt8(0);
        break;

        case 2:
            // [15:39:24] <CCHyper> 2 = boolean
            data = chunk.readInt8(0) > 0 ? 1 : 0;
        break;

        case 3:
            // [15:38:14] <CCHyper> 3 = short
            data = chunk.readInt16BE(0);
        break;

        case 4:
            // [15:38:07] <CCHyper> 4 = unsigned short
            data = chunk.readUInt16BE(0);
        break;

        case 5:
            // [15:37:56] <CCHyper> 5 = long
            data = chunk.readInt32BE(0);
        break;

        case 6:
            // [15:37:49] <CCHyper> 6 = ulong/ unsigned long
            data = chunk.readUInt32BE(0);
        break;

        case 7:
            // [15:38:35] <CCHyper> 7= char
            data = chunk.toString('ascii').replace('\u0000', ''); // charCode(0) at end of string
            if (data == "ON") data = 1;
            else if (data == "OFF") data = 0;
        break;

        case 20:
            // [15:39:34] <CCHyper> 20 is a string
            // [15:40:28] <CCHyper> 0x14 is qword
            var _data = 0, x = -1;
            for (var i = 0; i < chunk.length; i += 4) {
                var end = i + 4 >= chunk.length ? chunk.length : i + 4;
                var slice = chunk.slice(i, end);
                _data += slice.readUInt32BE(0);
            }
            data = _data;
        break;
    }

    return data;
}

/* consolidate player stats */
function _consolidate(flat) {
    var consolidated = {players: [], settings: {}, client: {}};
    var settings = ['sped', 'plrs', 'scen', 'tech', 'unit', 'flag', 'shad', 'crat', 'tibr', 'base', 'cred', 'trny', 'shrt', 'supr', 'aipl', 'nump'];
    var client = ['vers', 'vidm', 'memo', 'proc', 'afps', 'oosy', 'gsku', 'spid', 'accn', 'cmpl', 'quit', 'unid'];

    if (flat.NAM0 || flat.NAM1) {
        for (var item in flat) {
            var value = flat[item];
            var key = item.toLowerCase();
            var index = parseInt(key.slice(-1));

            /* player stats */
            if (index > -1) {
                if (!consolidated.players[index]) consolidated.players[index] = {};
                consolidated.players[index][key.slice(0, -1)] = value;
                continue;
            }

            /* game settings */
            if (settings.indexOf(key) > -1) {
                consolidated.settings[key] = value;
                continue;
            }

            /* client settings */
            if (client.indexOf(key) > -1) {
                consolidated.client[key] = value;
                continue;
            }

            consolidated[key] = value;
        }
    }

    /* players[0] is sometimes undefined? h4x */
    if (consolidated.players[0] === undefined) {
        consolidated.players.shift();
    }

    /* overwrite date */
    consolidated.date = Math.floor(Date.now() / 1000);
    return consolidated;
}
<commit_msg>relocating point logic<commit_after>var $db = require('./mongo');
var debug = require('debug')('wol:leaderboard');

// TODO: move this whole function somewheres else
/* saves player and game data */
exports.process = function(game, match) {
    debug('game: %s, idno: %d processing', game, match.idno);

    /* fail if we're somehow missing players */
    if (!match.players || match.players.length < 1) return;

    match.winners = [];
    match.losers = [];

    // create player entry
    var $players = $db.get(game +'_players');
    match.players.forEach(function(player, i) {
        /* typically Computer */
        if (!player.nam) {
            player.nam = 'computer';
            return;
        }

        /* lowercase all usernames */
        player.nam = player.nam.toLowerCase();

        /* remove spectators */
        if (player.spc && player.spc > 0) {
            delete match.players[i];
            return;
        }

        // TODO: increase player map count
        var stats = {
            $push: {games: match.idno},
            $inc: {}
        };

        /* evaluate completions */
        if (player.cmp) {
            switch (player.cmp) {
                case 2:
                    stats.$inc.losses = 1;
                    stats.$inc.disconnects = 1;
                    match.losers.push({name: player.nam, index: i});
                break;

                case 256:
                    stats.$inc.wins = 1;
                    match.winners.push({name: player.nam, index: i});
                break;

                case 512:
                case 528:
                    stats.$inc.losses = 1;
                    match.losers.push({name: player.nam, index: i});
                break;
            }
        }

        /* remove unused info */
        delete player.ipa; /* could be tunnel or p2p (unreliable) */
        delete player.addr; /* same reason but for ra1 */
        delete player.ser; /* serials are not used on CnCNet */
        delete player.accn; /* funky's client specific */

        $players.update({name: player.nam}, stats, {upsert: true});
        debug('game: %s, idno: %s, player: %s updated', game, match.idno, player.nam);

        /* tack on stats so it can be referenced in game object */
        player.__gains = stats.$inc;
    });

    return match;
};

/* WOL Game Resolution interpreter */
exports.parse = function(packet) {
    var buffer = packet;
    if (typeof packet === 'string') {
        // remove any unnessiccary whitespace
        packet = packet.replace(/(\r|\n|\r\n|\s+)/gm, '');
        buffer = new Buffer(packet, 'hex');
    }

    var flat = {}, i = 4;
    flat.buffer = buffer;
    var slice = buffer.slice(0, 4);
    var bufferLength = slice.readUInt16BE(0);

    while (i < bufferLength) {
        var chunk = buffer.slice(i,  i + 4);
        var field = chunk.toString();

        i += 4;

        chunk = buffer.slice(i, i + 8);

        var type = chunk.readUInt16BE(0);
        var length = chunk.readUInt16BE(2);
        var data = 'Unprocessed Data';

        i += 4;

        var end = i + length >= bufferLength ? bufferLength : i + length;

        if (i <= end) {
            data = _type(type, buffer.slice(i, end));
            length = Math.ceil(length / 4) * 4;
            i += length;
        }

        flat[field] = data;
    }

    return _consolidate(flat);
};

/* WOL field type interpreter */
function _type(type, chunk) {
    var data = 'Unprocessed Type';

    switch (type) {
        case 1:
            // [15:39:10] <CCHyper> 1 = byte
            data = chunk.readInt8(0);
        break;

        case 2:
            // [15:39:24] <CCHyper> 2 = boolean
            data = chunk.readInt8(0) > 0 ? 1 : 0;
        break;

        case 3:
            // [15:38:14] <CCHyper> 3 = short
            data = chunk.readInt16BE(0);
        break;

        case 4:
            // [15:38:07] <CCHyper> 4 = unsigned short
            data = chunk.readUInt16BE(0);
        break;

        case 5:
            // [15:37:56] <CCHyper> 5 = long
            data = chunk.readInt32BE(0);
        break;

        case 6:
            // [15:37:49] <CCHyper> 6 = ulong/ unsigned long
            data = chunk.readUInt32BE(0);
        break;

        case 7:
            // [15:38:35] <CCHyper> 7= char
            data = chunk.toString('ascii').replace('\u0000', ''); // charCode(0) at end of string
            if (data == "ON") data = 1;
            else if (data == "OFF") data = 0;
        break;

        case 20:
            // [15:39:34] <CCHyper> 20 is a string
            // [15:40:28] <CCHyper> 0x14 is qword
            var _data = 0, x = -1;
            for (var i = 0; i < chunk.length; i += 4) {
                var end = i + 4 >= chunk.length ? chunk.length : i + 4;
                var slice = chunk.slice(i, end);
                _data += slice.readUInt32BE(0);
            }
            data = _data;
        break;
    }

    return data;
}

/* consolidate player stats */
function _consolidate(flat) {
    var consolidated = {players: [], settings: {}, client: {}};
    var settings = ['sped', 'plrs', 'scen', 'tech', 'unit', 'flag', 'shad', 'crat', 'tibr', 'base', 'cred', 'trny', 'shrt', 'supr', 'aipl', 'nump'];
    var client = ['vers', 'vidm', 'memo', 'proc', 'afps', 'oosy', 'gsku', 'spid', 'accn', 'cmpl', 'quit', 'unid'];

    if (flat.NAM0 || flat.NAM1) {
        for (var item in flat) {
            var value = flat[item];
            var key = item.toLowerCase();
            var index = parseInt(key.slice(-1));

            /* player stats */
            if (index > -1) {
                if (!consolidated.players[index]) consolidated.players[index] = {};
                consolidated.players[index][key.slice(0, -1)] = value;
                continue;
            }

            /* game settings */
            if (settings.indexOf(key) > -1) {
                consolidated.settings[key] = value;
                continue;
            }

            /* client settings */
            if (client.indexOf(key) > -1) {
                consolidated.client[key] = value;
                continue;
            }

            consolidated[key] = value;
        }
    }

    /* players[0] is sometimes undefined? h4x */
    if (consolidated.players[0] === undefined) {
        consolidated.players.shift();
    }

    /* overwrite date */
    consolidated.date = Math.floor(Date.now() / 1000);
    return consolidated;
}
<|endoftext|>


<commit_before>/*jshint node:true*/
"use strict";

var connect = require('connect');
var mongo = require('mongoskin');
var uuid = require('node-uuid');
var browserify = require('browserify');
var fs = require('fs');
var mainUrls = ['intro', 'dare', 'edit', 'full', 'learn', 'create', 'superheroes', 'about', 'blindfold'];

module.exports = function(server) {
	server.init = function(options) {
		var objects = {
			database: mongo.db(options.mongodb),
			mailer: new server.Mailer(options.mailer)
		};

		objects.common = new server.Common(options.api, objects);
		objects.api = new server.API(options.api, objects);

		objects.database.bind('users');
		objects.database.bind('collections');
		objects.database.bind('dares');
		objects.database.bind('instances');

		var noCache = function(req, res, next) {
			res.on('header', function(header) {
				res.setHeader('Cache-Control', 'private, max-age=0');
				res.setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT');
				res.setHeader('Pragma', 'no-cache');
			});
			next();
		};

		var indexFile = fs.readFileSync(options.assets + '/index.html').toString();

		objects.database.open(function(err, db) {
			if (err) {
				console.log('MongoDB error:', err);
				return;
			}

			server.dares(objects.database);

			var app = connect();
			if (options.logs.requests) app.use(connect.logger('tiny'));

			var b = browserify();
			b.add(options.browserify.entry);
			b.bundle(options.browserify, function(err, src) {
				if (err) {
					console.log("Error: " + err);
				} else {
					fs.writeFile(options.assets + '/browserify.js', src);
				}
			});

			app.use(noCache)
				.use(objects.common.getMiddleware())
				.use('/api', objects.api.getMiddleware())
				.use('', function(req, res, next) {
					if (mainUrls.indexOf(req.url.split('/')[1] || 'intro') >= 0 || req.url === '/') req.url = '/index.html';
					next();
				})
				.use('/index.html', function(req, res, next) {
					var loginData = {};
					if (req.session && req.session.loginData) loginData = req.session.loginData;
					res.end(indexFile.replace('{/*AUTOFILL in server.init.js*/}', JSON.stringify(loginData)));
				})
				.use(connect['static'](options.assets))
				.listen(options.port);
		});
	};
};
<commit_msg>Seperated mongo initializing from webserver starting.<commit_after>/*jshint node:true*/
"use strict";

var connect = require('connect');
var mongo = require('mongoskin');
var uuid = require('node-uuid');
var browserify = require('browserify');
var fs = require('fs');
var mainUrls = ['intro', 'dare', 'edit', 'full', 'learn', 'create', 'superheroes', 'about', 'blindfold'];

module.exports = function(server) {
	server.init = function(options) {
		var objects = {
			database: mongo.db(options.mongodb),
			mailer: new server.Mailer(options.mailer)
		};

		objects.common = new server.Common(options.api, objects);
		objects.api = new server.API(options.api, objects);

		objects.database.bind('users');
		objects.database.bind('collections');
		objects.database.bind('dares');
		objects.database.bind('instances');

		var noCache = function(req, res, next) {
			res.on('header', function(header) {
				res.setHeader('Cache-Control', 'private, max-age=0');
				res.setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT');
				res.setHeader('Pragma', 'no-cache');
			});
			next();
		};

		var indexFile = fs.readFileSync(options.assets + '/index.html').toString();

		objects.database.open(function(err, db) {
			if (err) {
				console.log('MongoDB error:', err);
				process.exit(1);
			}
		});

		server.dares(objects.database);

		var app = connect();
		if (options.logs.requests) app.use(connect.logger('tiny'));

		var b = browserify();
		b.add(options.browserify.entry);
		b.bundle(options.browserify, function(err, src) {
			if (err) {
				console.log("Error: " + err);
			} else {
				fs.writeFile(options.assets + '/browserify.js', src);
			}
		});

		app.use(noCache)
			.use(objects.common.getMiddleware())
			.use('/api', objects.api.getMiddleware())
			.use('', function(req, res, next) {
				if (mainUrls.indexOf(req.url.split('/')[1] || 'intro') >= 0 || req.url === '/') req.url = '/index.html';
				next();
			})
			.use('/index.html', function(req, res, next) {
				var loginData = {};
				if (req.session && req.session.loginData) loginData = req.session.loginData;
				res.end(indexFile.replace('{/*AUTOFILL in server.init.js*/}', JSON.stringify(loginData)));
			})
			.use(connect['static'](options.assets))
			.listen(options.port);
	};
};
<|endoftext|>


<commit_before>// https://eslint.org/docs/user-guide/configuring

module.exports = {
  root: true,
  parserOptions: {
    parser: "babel-eslint",
    sourceType: "module"
  },
  env: {
    browser: true
  },
  // required to lint *.vue files
  plugins: ["vue"],
  extends: ["plugin:vue/recommended", "airbnb-base"],
  // check if imports actually resolve
  settings: {
    "import/resolver": {
      webpack: {
        config: "build/webpack.base.conf.js"
      }
    }
  },
  // add your custom rules here
  rules: {
    // don't require .vue extension when importing
    "import/extensions": [
      "error",
      "always",
      {
        js: "never",
        vue: "never"
      }
    ],
    // disallow reassignment of function parameters
    // disallow parameter object manipulation except for specific exclusions
    "no-param-reassign": [
      "error",
      {
        props: true,
        ignorePropertyModificationsFor: [
          "state", // for vuex state
          "acc", // for reduce accumulators
          "e" // for e.returnvalue
        ]
      }
    ],
    "no-plusplus": [
      "error",
      {
        "allowForLoopAfterthoughts": true
      }
    ],
    // allow optionalDependencies
    "import/no-extraneous-dependencies": [
      "error",
      {
        optionalDependencies: ["test/unit/index.js"]
      }
    ],
    // allow debugger during development
    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
    "linebreak-style": ["error", "windows"]
  }
};
<commit_msg>Turn off linebreak-style rule in ESLint.<commit_after>// https://eslint.org/docs/user-guide/configuring

module.exports = {
  root: true,
  parserOptions: {
    parser: "babel-eslint",
    sourceType: "module"
  },
  env: {
    browser: true
  },
  // required to lint *.vue files
  plugins: ["vue"],
  extends: ["plugin:vue/recommended", "airbnb-base"],
  // check if imports actually resolve
  settings: {
    "import/resolver": {
      webpack: {
        config: "build/webpack.base.conf.js"
      }
    }
  },
  // add your custom rules here
  rules: {
    // don't require .vue extension when importing
    "import/extensions": [
      "error",
      "always",
      {
        js: "never",
        vue: "never"
      }
    ],
    // disallow reassignment of function parameters
    // disallow parameter object manipulation except for specific exclusions
    "no-param-reassign": [
      "error",
      {
        props: true,
        ignorePropertyModificationsFor: [
          "state", // for vuex state
          "acc", // for reduce accumulators
          "e" // for e.returnvalue
        ]
      }
    ],
    "no-plusplus": [
      "error",
      {
        "allowForLoopAfterthoughts": true
      }
    ],
    // allow optionalDependencies
    "import/no-extraneous-dependencies": [
      "error",
      {
        optionalDependencies: ["test/unit/index.js"]
      }
    ],
    // allow debugger during development
    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
    "linebreak-style": "off"
  }
};
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var DEFAULT_TIMEOUT = 500;

exports.default = function () {
  var React = arguments.length <= 0 || arguments[0] === undefined ? _react2.default : arguments[0];
  var ReactDom = arguments.length <= 1 || arguments[1] === undefined ? _reactDom2.default : arguments[1];
  return function (_React$Component) {
    _inherits(PageTransition, _React$Component);

    function PageTransition() {
      var _Object$getPrototypeO;

      _classCallCheck(this, PageTransition);

      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(PageTransition)).call.apply(_Object$getPrototypeO, [this].concat(args)));

      if (_this.props.animateOnInit) {
        _this.state = {
          child1: null,
          child2: null,
          nextChild: 1,
          initDone: false
        };
      } else {
        _this.state = {
          child1: _this.props.children,
          child2: null,
          nextChild: 2,
          initDone: true
        };
      }
      _this.transite = _this.transite.bind(_this);
      _this.getRef = _this.getRef.bind(_this);
      return _this;
    }

    _createClass(PageTransition, [{
      key: 'componentDidMount',
      value: function componentDidMount() {
        if (!this.props.animateOnInit) {
          var child = this.getRef('child1');
          if (child) {
            var dom = ReactDom.findDOMNode(child);
            child.onTransitionDidEnd && child.onTransitionDidEnd(this.props.data);
            dom.classList.remove('transition-item');
          }
        } else {
          this.transite(this.props.children, true);
        }
      }
    }, {
      key: 'componentWillReceiveProps',
      value: function componentWillReceiveProps(nextProps) {
        // If there is new children
        if (this.props.children !== nextProps.children) {
          this.transite(nextProps.children);
        }
      }
    }, {
      key: 'getRef',
      value: function getRef(ref) {
        var child = this.refs[ref];
        // Dirty way to check if the component is
        // wrapped with react-redux Connect
        if (child && child.getWrappedInstance) {
          child = child.getWrappedInstance();
        }
        return child;
      }
    }, {
      key: 'transite',
      value: function transite(nextChild, isInit) {
        var _this2 = this;

        // Render the new children
        this.state['child' + this.state.nextChild] = nextChild;
        this.forceUpdate(function () {
          var prevChild = _this2.getRef('child' + (_this2.state.nextChild === 1 ? 2 : 1));
          var newChild = _this2.getRef('child' + _this2.state.nextChild);
          var prevChildDom = ReactDom.findDOMNode(prevChild);
          var newChildDom = ReactDom.findDOMNode(newChild);
          var timeout = 0;

          // Before add appear class
          var willStart = function willStart() {
            if (newChild.onTransitionWillStart) {
              return newChild.onTransitionWillStart(_this2.props.data) || Promise.resolve();
            }
            if (prevChild && prevChild.onTransitionLeaveWillStart) {
              return prevChild.onTransitionLeaveWillStart(_this2.props.data) || Promise.resolve();
            }
            return Promise.resolve();
          };

          // Add appear class and active class (or trigger manual start)
          var start = function start() {
            if (newChildDom.classList.contains('transition-item')) {
              timeout = _this2.props.timeout || DEFAULT_TIMEOUT;
              newChildDom.classList.add('transition-appear');
              newChildDom.offsetHeight; // Trigger layout to make sure transition happen
              if (newChild.transitionManuallyStart) {
                return newChild.transitionManuallyStart(_this2.props.data, start) || Promise.resolve();
              }
              newChildDom.classList.add('transition-appear-active');
            }
            if (prevChildDom) {
              prevChildDom.classList.add('transition-leave');
              prevChildDom.classList.add('transition-item');
              timeout = _this2.props.timeout || DEFAULT_TIMEOUT;
              prevChildDom.offsetHeight; // Trigger layout to make sure transition happen
              if (prevChild.transitionManuallyLeaveStart) {
                return prevChild.transitionManuallyLeaveStart(_this2.props.data, start) || Promise.resolve();
              }
              prevChildDom.classList.add('transition-leave-active');
            }
            return Promise.resolve();
          };

          // After add classes
          var didStart = function didStart() {
            if (newChild.onTransitionDidStart) {
              return newChild.onTransitionDidStart(_this2.props.data) || Promise.resolve();
            }
            if (prevChild && prevChild.onTransitionDidStartLeave) {
              return prevChild.onTransitionLeaveDidStart(_this2.props.data) || Promise.resolve();
            }
            return Promise.resolve();
          };

          // Wait for transition
          var waitForTransition = function waitForTransition() {
            return new Promise(function (resolve) {
              setTimeout(function () {
                // Swap child and remove the old child
                _this2.state.nextChild = _this2.state.nextChild === 1 ? 2 : 1;
                _this2.state['child' + _this2.state.nextChild] = null;
                _this2.forceUpdate(resolve);
              }, timeout);
            });
          };

          // Before remove classes
          var willEnd = function willEnd() {
            if (newChild.onTransitionWillEnd) {
              return newChild.onTransitionWillEnd(_this2.props.data) || Promise.resolve();
            }
            if (prevChild && prevChild.onTransitionLeaveWillEnd) {
              return prevChild.onTransitionLeaveWillEnd(_this2.props.data) || Promise.resolve();
            }
            return Promise.resolve();
          };

          // Remove appear and active class (or trigger manual end)
          var end = function end() {
            if (newChildDom.classList.contains('transition-item')) {
              newChildDom.classList.remove('transition-appear');
              newChildDom.classList.remove('transition-item');

              if (newChild.transitionManuallyStop) {
                return newChild.transitionManuallyStop(_this2.props.data) || Promise.resolve();
              }
              newChildDom.classList.remove('transition-appear-active');
            }
            if (prevChildDom && prevChildDom.classList.contains('transition-item')) {
              prevChildDom.classList.remove('transition-leave');
              prevChildDom.classList.remove('transition-item');

              if (prevChild.transitionLeaveManuallyStop) {
                return prevChild.transitionLeaveManuallyStop(_this2.props.data) || Promise.resolve();
              }
              prevChildDom.classList.remove('transition-leave-active');
            }
            return Promise.resolve();
          };

          // After remove classes
          var didEnd = function didEnd() {
            _this2.props.onLoad && _this2.props.onLoad();

            if (newChild.onTransitionDidEnd) {
              return newChild.onTransitionDidEnd(_this2.props.data) || Promise.resolve();
            }
            if (prevChild && prevChild.onTransitionLeaveDidEnd) {
              return prevChild.onTransitionLeaveDidEnd(_this2.props.data) || Promise.resolve();
            }
            return Promise.resolve();
          };

          Promise.resolve().then(willStart).then(start).then(didStart).then(waitForTransition).then(willEnd).then(end).then(didEnd).then(function () {
            _this2.props.onLoad && _this2.props.onLoad();
            if (isInit) {
              // this.setState({ initDone: true });
            }
          });
        });
      }
    }, {
      key: 'render',
      value: function render() {
        return React.createElement(
          'div',
          { className: 'trasition-wrapper' },
          React.Children.map(this.state.child1, function (element) {
            return React.cloneElement(element, { ref: 'child1' });
          }),
          React.Children.map(this.state.child2, function (element) {
            return React.cloneElement(element, { ref: 'child2' });
          })
        );
      }
    }]);

    return PageTransition;
  }(React.Component);
};<commit_msg>Build<commit_after>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _reactDom = require('react-dom');

var _reactDom2 = _interopRequireDefault(_reactDom);

var _promiseQueue = require('promise-queue');

var _promiseQueue2 = _interopRequireDefault(_promiseQueue);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var DEFAULT_TIMEOUT = 500;

exports.default = function () {
  var React = arguments.length <= 0 || arguments[0] === undefined ? _react2.default : arguments[0];
  var ReactDom = arguments.length <= 1 || arguments[1] === undefined ? _reactDom2.default : arguments[1];
  return function (_React$Component) {
    _inherits(PageTransition, _React$Component);

    function PageTransition() {
      var _Object$getPrototypeO;

      _classCallCheck(this, PageTransition);

      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      var _this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(PageTransition)).call.apply(_Object$getPrototypeO, [this].concat(args)));

      if (_this.props.animateOnInit) {
        _this.state = {
          child1: null,
          child2: null,
          nextChild: 1
        };
      } else {
        _this.state = {
          child1: _this.props.children,
          child2: null,
          nextChild: 2
        };
      }
      _this.transite = _this.transite.bind(_this);
      _this.getRef = _this.getRef.bind(_this);

      _this.queue = new _promiseQueue2.default(1, Infinity); // max concurrent 1, max queue Inf
      return _this;
    }

    _createClass(PageTransition, [{
      key: 'componentDidMount',
      value: function componentDidMount() {
        if (!this.props.animateOnInit) {
          var child = this.getRef('child1');
          if (child) {
            var dom = ReactDom.findDOMNode(child);
            child.onTransitionDidEnd && child.onTransitionDidEnd(this.props.data);
            dom.classList.remove('transition-item');
          }
        } else {
          this.transite(this.props.children);
        }
      }
    }, {
      key: 'componentWillReceiveProps',
      value: function componentWillReceiveProps(nextProps) {
        var _this2 = this;

        // If there is new children
        if (this.props.children !== nextProps.children) {
          this.queue.add(function () {
            return _this2.transite(nextProps.children);
          });
        }
      }
    }, {
      key: 'getRef',
      value: function getRef(ref) {
        var child = this.refs[ref];
        // Dirty way to check if the component is
        // wrapped with react-redux Connect
        if (child && child.getWrappedInstance) {
          child = child.getWrappedInstance();
        }
        return child;
      }
    }, {
      key: 'transite',
      value: function transite(nextChild) {
        var _this3 = this;

        return new Promise(function (transiteDone, transiteFailed) {
          // Render the new children
          _this3.state['child' + _this3.state.nextChild] = nextChild;
          _this3.forceUpdate(function () {
            var prevChild = _this3.getRef('child' + (_this3.state.nextChild === 1 ? 2 : 1));
            var newChild = _this3.getRef('child' + _this3.state.nextChild);
            var prevChildDom = ReactDom.findDOMNode(prevChild);
            var newChildDom = ReactDom.findDOMNode(newChild);
            var timeout = 0;

            // Before add appear class
            var willStart = function willStart() {
              if (newChild.onTransitionWillStart) {
                return newChild.onTransitionWillStart(_this3.props.data) || Promise.resolve();
              }
              if (prevChild && prevChild.onTransitionLeaveWillStart) {
                return prevChild.onTransitionLeaveWillStart(_this3.props.data) || Promise.resolve();
              }
              return Promise.resolve();
            };

            // Add appear class and active class (or trigger manual start)
            var start = function start() {
              if (newChildDom.classList.contains('transition-item')) {
                timeout = _this3.props.timeout || DEFAULT_TIMEOUT;
                newChildDom.classList.add('transition-appear');
                newChildDom.offsetHeight; // Trigger layout to make sure transition happen
                if (newChild.transitionManuallyStart) {
                  return newChild.transitionManuallyStart(_this3.props.data, start) || Promise.resolve();
                }
                newChildDom.classList.add('transition-appear-active');
              }
              if (prevChildDom) {
                prevChildDom.classList.add('transition-leave');
                prevChildDom.classList.add('transition-item');
                timeout = _this3.props.timeout || DEFAULT_TIMEOUT;
                prevChildDom.offsetHeight; // Trigger layout to make sure transition happen
                if (prevChild.transitionLeaveManuallyStart) {
                  return prevChild.transitionLeaveManuallyStart(_this3.props.data, start) || Promise.resolve();
                }
                prevChildDom.classList.add('transition-leave-active');
              }
              return Promise.resolve();
            };

            // After add classes
            var didStart = function didStart() {
              if (newChild.onTransitionDidStart) {
                return newChild.onTransitionDidStart(_this3.props.data) || Promise.resolve();
              }
              if (prevChild && prevChild.onTransitionDidStartLeave) {
                return prevChild.onTransitionLeaveDidStart(_this3.props.data) || Promise.resolve();
              }
              return Promise.resolve();
            };

            // Wait for transition
            var waitForTransition = function waitForTransition() {
              return new Promise(function (resolve) {
                setTimeout(function () {
                  // Swap child and remove the old child
                  _this3.state.nextChild = _this3.state.nextChild === 1 ? 2 : 1;
                  _this3.state['child' + _this3.state.nextChild] = null;
                  _this3.forceUpdate(resolve);
                }, timeout);
              });
            };

            // Before remove classes
            var willEnd = function willEnd() {
              if (newChild.onTransitionWillEnd) {
                return newChild.onTransitionWillEnd(_this3.props.data) || Promise.resolve();
              }
              if (prevChild && prevChild.onTransitionLeaveWillEnd) {
                return prevChild.onTransitionLeaveWillEnd(_this3.props.data) || Promise.resolve();
              }
              return Promise.resolve();
            };

            // Remove appear and active class (or trigger manual end)
            var end = function end() {
              if (newChildDom.classList.contains('transition-item')) {
                newChildDom.classList.remove('transition-appear');
                newChildDom.classList.remove('transition-item');

                if (newChild.transitionManuallyStop) {
                  return newChild.transitionManuallyStop(_this3.props.data) || Promise.resolve();
                }
                newChildDom.classList.remove('transition-appear-active');
              }
              if (prevChildDom && prevChildDom.classList.contains('transition-item')) {
                prevChildDom.classList.remove('transition-leave');
                prevChildDom.classList.remove('transition-item');

                if (prevChild.transitionLeaveManuallyStop) {
                  return prevChild.transitionLeaveManuallyStop(_this3.props.data) || Promise.resolve();
                }
                prevChildDom.classList.remove('transition-leave-active');
              }
              return Promise.resolve();
            };

            // After remove classes
            var didEnd = function didEnd() {
              if (newChild.onTransitionDidEnd) {
                return newChild.onTransitionDidEnd(_this3.props.data) || Promise.resolve();
              }
              if (prevChild && prevChild.onTransitionLeaveDidEnd) {
                return prevChild.onTransitionLeaveDidEnd(_this3.props.data) || Promise.resolve();
              }
              return Promise.resolve();
            };

            Promise.resolve().then(willStart).then(start).then(didStart).then(waitForTransition).then(willEnd).then(end).then(didEnd).then(function () {
              _this3.props.onLoad && _this3.props.onLoad();
              transiteDone();
            }).catch(transiteFailed);
          });
        });
      }
    }, {
      key: 'render',
      value: function render() {
        return React.createElement(
          'div',
          { className: 'trasition-wrapper' },
          React.Children.map(this.state.child1, function (element) {
            return React.cloneElement(element, { ref: 'child1' });
          }),
          React.Children.map(this.state.child2, function (element) {
            return React.cloneElement(element, { ref: 'child2' });
          })
        );
      }
    }]);

    return PageTransition;
  }(React.Component);
};<|endoftext|>


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

'use strict';

/*eslint no-console: 0, no-sync: 0*/

// System.js bundler
// simple and yet reusable system.js bundler
// bundles, minifies and gzips

const fs = require('fs');
const del = require('del');
const path = require('path');
const zlib = require('zlib');
const async = require('async');
const Builder = require('systemjs-builder');

const pkg = require('../package.json');
const name = pkg.name;
const targetFolder = path.resolve('./bundles');

async.waterfall([
  cleanBundlesFolder,
  getSystemJsBundleConfig,
  buildSystemJs({minify: false, sourceMaps: true, mangle: false, noEmitHelpers: false, declaration: true}),
  getSystemJsBundleConfig,
  buildSystemJs({minify: true, sourceMaps: true, mangle: false, noEmitHelpers: false, declaration: true}),
  gzipSystemJsBundle
], err => {
  if (err) {
    throw err;
  }
});

function getSystemJsBundleConfig(cb) {
  const config = {
    baseURL: '..',
    transpiler: 'typescript',
    typescriptOptions: {
      module: 'cjs'
    },
    map: {
      typescript: path.resolve('node_modules/typescript/lib/typescript.js'),
      '@angular/core': path.resolve('node_modules/@angular/core/index.js'),
      '@angular/common': path.resolve('node_modules/@angular/common/index.js'),
      '@angular/compiler': path.resolve('node_modules/@angular/compiler/index.js'),
      '@angular/forms': path.resolve('node_modules/@angular/forms/index.js'),
      '@angular/platform-browser': path.resolve('node_modules/@angular/platform-browser/index.js'),
      '@angular/platform-browser-dynamic': path.resolve('node_modules/@angular/platform-browser-dynamic/'),
      rxjs: path.resolve('node_modules/rxjs')
    },
    paths: {
      '*': '*.js'
    }
  };

  config.meta = ['@angular/common','@angular/compiler','@angular/core', '@angular/forms',
    '@angular/platform-browser','@angular/platform-browser-dynamic', 'rxjs'].reduce((memo, currentValue) => {
    memo[path.resolve(`node_modules/${currentValue}/*`)] = {build: false};
    return memo;
  }, {});
  config.meta.moment = {build: false};
  return cb(null, config);
}

function cleanBundlesFolder(cb) {
  return del(targetFolder)
    .then(paths => {
      console.log('Deleted files and folders:\n', paths.join('\n'));
      cb();
    });
}

function buildSystemJs(options) {
  return (config, cb) => {
    const minPostFix = options && options.minify ? '.min' : '';
    const fileName = `${name}${minPostFix}.js`;
    const dest = path.resolve(__dirname, targetFolder, fileName);
    const builder = new Builder();

    console.log('Bundling system.js file:', fileName, options);
    builder.config(config);
    return builder
      .bundle([name, name].join('/'), dest, options)
      .then(() => cb())
      .catch(cb);
  };
}

function gzipSystemJsBundle(cb) {
  const files = fs
    .readdirSync(path.resolve(targetFolder))
    .map(file => path.resolve(targetFolder, file))
    .filter(file => fs.statSync(file).isFile())
    .filter(file => path.extname(file) !== 'gz');

  return async.eachSeries(files, (file, gzipcb) => {
    process.nextTick(() => {
      console.log('Gzipping ', file);
      const gzip = zlib.createGzip({level: 9});
      const inp = fs.createReadStream(file);
      const out = fs.createWriteStream(`${file}.gz`);

      inp.on('end', () => gzipcb());
      inp.on('error', err => gzipcb(err));
      return inp.pipe(gzip).pipe(out);
    });
  }, cb);
}
<commit_msg>Fixed chmod for travis build<commit_after>#!/usr/bin/env node

'use strict';

/*eslint no-console: 0, no-sync: 0*/

// System.js bundler
// simple and yet reusable system.js bundler
// bundles, minifies and gzips

const fs = require('fs');
const del = require('del');
const path = require('path');
const zlib = require('zlib');
const async = require('async');
const Builder = require('systemjs-builder');

const pkg = require('../package.json');
const name = pkg.name;
const targetFolder = path.resolve('./bundles');

async.waterfall([
  cleanBundlesFolder,
  getSystemJsBundleConfig,
  buildSystemJs({minify: false, sourceMaps: true, mangle: false, noEmitHelpers: false, declaration: true}),
  getSystemJsBundleConfig,
  buildSystemJs({minify: true, sourceMaps: true, mangle: false, noEmitHelpers: false, declaration: true}),
  gzipSystemJsBundle
], err => {
  if (err) {
    throw err;
  }
});

function getSystemJsBundleConfig(cb) {
  const config = {
    baseURL: '..',
    transpiler: 'typescript',
    typescriptOptions: {
      module: 'cjs'
    },
    map: {
      typescript: path.resolve('node_modules/typescript/lib/typescript.js'),
      '@angular/core': path.resolve('node_modules/@angular/core/index.js'),
      '@angular/common': path.resolve('node_modules/@angular/common/index.js'),
      '@angular/compiler': path.resolve('node_modules/@angular/compiler/index.js'),
      '@angular/forms': path.resolve('node_modules/@angular/forms/index.js'),
      '@angular/platform-browser': path.resolve('node_modules/@angular/platform-browser/index.js'),
      '@angular/platform-browser-dynamic': path.resolve('node_modules/@angular/platform-browser-dynamic/'),
      rxjs: path.resolve('node_modules/rxjs')
    },
    paths: {
      '*': '*.js'
    }
  };

  config.meta = ['@angular/common','@angular/compiler','@angular/core', '@angular/forms',
    '@angular/platform-browser','@angular/platform-browser-dynamic', 'rxjs'].reduce((memo, currentValue) => {
    memo[path.resolve(`node_modules/${currentValue}/*`)] = {build: false};
    return memo;
  }, {});
  config.meta.moment = {build: false};
  return cb(null, config);
}

function cleanBundlesFolder(cb) {
  return del(targetFolder)
    .then(paths => {
      console.log('Deleted files and folders:\n', paths.join('\n'));
      cb();
    });
}

function buildSystemJs(options) {
  return (config, cb) => {
    const minPostFix = options && options.minify ? '.min' : '';
    const fileName = `${name}${minPostFix}.js`;
    const dest = path.resolve(__dirname, targetFolder, fileName);
    const builder = new Builder();

    console.log('Bundling system.js file:', fileName, options);
    builder.config(config);
    return builder
      .bundle([name, name].join('/'), dest, options)
      .then(() => cb())
      .catch(cb);
  };
}

function gzipSystemJsBundle(cb) {
  const files = fs
    .readdirSync(path.resolve(targetFolder))
    .map(file => path.resolve(targetFolder, file))
    .filter(file => fs.statSync(file).isFile())
    .filter(file => path.extname(file) !== 'gz');

  return async.eachSeries(files, (file, gzipcb) => {
    process.nextTick(() => {
      console.log('Gzipping ', file);
      const gzip = zlib.createGzip({level: 9});
      const inp = fs.createReadStream(file);
      const out = fs.createWriteStream(`${file}.gz`);

      inp.on('end', () => gzipcb());
      inp.on('error', err => gzipcb(err));
      return inp.pipe(gzip).pipe(out);
    });
  }, cb);
}
<|endoftext|>