<commit_before>/*eslint camelcase: 0, no-use-before-define: 0 */
// Config UI for custom viz settings for heatmaps.
//
// State schema. This is the goal, not the current implementation. If
// the user has never modified the default settings, vizSettings is undefined.
//
// When the user modifies colNormalization or color parameters, they are
// written into vizSettings. vizSettings can have normalization or color
// parameters, or both. All color parameters are present if any are set.
// The minStart/maxStart are optional, so may be null if other color parameters
// are set.
//
// vizSettings = undefined |
//               {
//                 colNormalization: 'subset' | 'none'
//               } |
//               {
//                 min: float,
//                 minStart: float | null,
//                 maxStart: float | null,
//                 max: float
//               } |
//               {
//                 colNormalization: 'subset' | 'none'
//                 min: float,
//                 minStart: float | null,
//                 maxStart: float | null,
//                 max: float
//               }

// Refactoring notes:
// The default column normalization is fetched from the server. Instead it should come from
// the state, or from a data cache, because we've fetched that already.

'use strict';
var _ = require('../underscore_ext');
var floatImg = require('../../images/genomicFloatLegend.jpg');
var customFloatImg = require('../../images/genomicCustomFloatLegend.jpg');
var React = require('react');
var ReactDOM = require('react-dom');
var {Modal, DropdownButton, MenuItem, Row, Col, Button, ButtonToolbar, ButtonGroup} = require('react-bootstrap/lib/');
var Input = require('react-bootstrap/lib/Input');
var image = require('react-bootstrap/lib/Image');

function vizSettingsWidget(node, onVizSettings, vizState, id, hide, defaultNormalization, defaultColorClass, valueType) {
	var state = vizState;
	function datasetSetting() {
		var node, div = document.createElement("div");
		if (valueType === "float" || valueType === 'segmented') {
			node = document.createElement("div");
			allFloat(node);
			div.appendChild(node);

			node = document.createElement("span");
			ReactDOM.render(React.createElement(finishButtonBar), node);
			div.appendChild(node);
		}
		return div;
	}

	function allFloat(div) {
		var node;

		if (valueType === "float") {
			// normalization
			node = document.createElement("div");
			ReactDOM.render(React.createElement(normalizationDropDown), node);
			div.appendChild(node);
			div.appendChild(document.createElement("br"));
		}

		// color choice : green red or blue red
		node = document.createElement("div");
		ReactDOM.render(React.createElement(colorDropDown), node);
		div.appendChild(node);
		div.appendChild(document.createElement("br"));

		// color scale
		node = document.createElement("div");
		ReactDOM.render(React.createElement(scaleChoice), node);
		div.appendChild(node);
		div.appendChild(document.createElement("br"));
	}

	// discard user changes & close.
	var finishButtonBar = React.createClass({
		handleCancelClick () {
			hide();
			onVizSettings(id, state);
		},
		handleDoneClick () {
			hide();
		},
		render () {
			return (
				<ButtonToolbar>
					<Button onClick = {this.handleCancelClick}>Cancel</Button>
					<Button bsStyle="primary" onClick = {this.handleDoneClick}>Done</Button>
				</ButtonToolbar>
			);
		}
	});

	function getInputSettingsFloat(settings) {
		return _.fmap(settings, parseFloat);
	}

	var validateSettings = {
		float: s => {
			var vals = _.fmap(s, parseFloat),
				fmtErrors = _.fmap(vals, function (v, k) {
					return (isNaN(v) && s[k]) ? "Invalid number." : "";
				}),
				missing = _.fmap(s, _.constant(null)),
				rangeErrors;

			/*jshint -W018 */ /* allow xor idiom */
			if (!s.minStart !== !s.maxStart) { // xor
				missing.minStart = 'Both 0% values must be given to take effect.';
			}
			// XXX check for missin min & max

			if (s.minStart && s.maxStart && !fmtErrors.minStart && !fmtErrors.maxStart) {
				// wrong if missing maxStart: we compare against the wrong thing.
				rangeErrors = {
					max: null,
					maxStart: vals.maxStart <= vals.max ? null :  'Should be lower than max',
					minStart: vals.minStart <= vals.maxStart ? null : 'Should be lower than maxStart',
					min: vals.min <= vals.minStart ? null : 'Should be lower than minStart'
				};
			} else {
				rangeErrors = {
					max: null,
					min: vals.min <= vals.max ? null : 'Should be lower than max'
				};
			}

			return _.fmap(fmtErrors, function (err, k) {
				return _.filter([err, rangeErrors[k], missing[k]], _.identity).join(' ');
			});
		},
		segmented: s => {
			var vals = _.fmap(s, parseFloat),
				fmtErrors = _.fmap(vals, v => {
					return isNaN(v) ? "Invalid number." : "";
				}),
				rangeErrors = {
					thresh: vals.thresh >= 0 ? null : 'Should be positive',
					max: vals.max >= 0 ? null : 'Should be positive'
				};
			return _.fmap(fmtErrors, function (err, k) {
				return _.filter([err, rangeErrors[k]], _.identity).join(' ');
			});
		}
	};

	function settingsValid(errors) {
		return _.every(errors, function (s) { return !s; });
	}

	function valToStr(v) {
		return "" + v;
//		if (v === "-") {
//			return v;
//		}
//		return (!isNaN(v) && (v !== null) && (v !== undefined)) ? "" + v : "";
	}

	var scaleChoice = React.createClass({
		annotations: {
			float: {
				"max": "max: high color 100% saturation",
				"maxStart": "maxStart: high color 0% saturation",
				"minStart": "minStart: low color 0% saturation",
				"min": "min: low color 100% saturation"
			},
			segmented: {
				"origin": "origin: neutral or no-effect value",
				"thresh": "threshold: min absolute value from origin to draw color",
				"max": "saturation: absolute value from origin to draw full color"
			}
		},
		defaults: {
			float: {
				max: 1,
				maxStart: null,
				minStart: null,
				min: -1
			},
			segmented: {
				origin: 0,
				thresh: 0,
				max: 1
			}
		},
		getInitialState () {
			//check if there is custom value
			let custom = colorParams[valueType].some(function (param) {
					if (getVizSettings(param)) {
						return true;
					}
				});

			return {
				mode: custom ? "Custom" : "Auto",
				settings: custom ? _.pick(oldSettings, colorParams[valueType]) : this.defaults[valueType],
				errors: {}
			};
		},
		autoClick () {
			this.setState({mode: "Auto"});
			this.setState({settings: this.defaults[valueType]});
			this.setState({errors: {}});
			onVizSettings(id, _.omit(currentSettings.state, colorParams[valueType]));
		},
		customClick () {
			this.setState({mode: "Custom"});
			onVizSettings(id, _.merge(currentSettings.state, getInputSettingsFloat(this.state.settings)));
		},
		onScaleParamChange(ev) {
			var {settings} = this.state,
				param = ev.target.getAttribute('data-param'),
				newSettings = _.assoc(settings, param, ev.target.value),
				errors = validateSettings[valueType](newSettings);

			this.setState({settings: newSettings, errors});

			if (settingsValid(errors)) {
				onVizSettings(id, _.merge(currentSettings.state, getInputSettingsFloat(newSettings)));
			}
		},
		buildCustomColorScale () {
			var node = colorParams[valueType].map(param => {
					let value = valToStr(this.state.settings[param]),
						label = this.annotations[valueType][param],
						error = this.state.errors[param];

					return (
						<Row>
							<Col xs={4} md={4} lg={4}>{label}</Col>
							<Col xs={3} md={3} lg={3}>
								<Input type='textinput' placeholder={_.contains(['minThresh', 'maxThresh'], param) ? 'Auto' : ''}
									value={value} data-param={param} onChange={this.onScaleParamChange}/>
							</Col>
							<Col xs={5} md={5} lg={5}>
								{error}
							</Col>
						</Row>
					);
				});
			return node;
		},

		render () {
			let mode = this.state.mode,
				autoMode = (this.state.mode === "Auto"),
				modes = ["Auto", "Custom"],
				funcMapping = {
					"Auto": this.autoClick,
					"Custom": this.customClick
				},
				buttons = modes.map(mode => {
					let active = (this.state.mode === mode),
						func = funcMapping[mode];
					return active ? (<Button bsStyle="primary" onClick={func} active>{mode}</Button>) :
						(<Button onClick={func}>{mode}</Button>);
				}),
				picture = autoMode ? (<image src={floatImg} responsive/>) :
					(<image src={customFloatImg} responsive/>),
				enterInput = autoMode ? null : this.buildCustomColorScale();

			return (
				<Row>
					<Col xs={3} md={2} lg={2}>Scale</Col>
					<Col xs={15} md={10} lg={10}>
						<ButtonGroup>{buttons}</ButtonGroup>

							{valueType === 'float' ? picture : null}
							{enterInput}

					</Col>
				</Row>
			);
		}
	});

	function setVizSettings(key, value) {
		onVizSettings(id, _.assoc(currentSettings.state, key, value));
	}

	function getVizSettings(key) {
		return _.getIn(state, [key]);
	}

	var normalizationDropDown = React.createClass({
		getInitialState () {
			let	value = getVizSettings('colNormalization') || defaultNormalization || 'none',
				mapping = {
					"none": "none",
					"subset": "subset",
					true: "subset"
				};
			return {
				optionValue: mapping[value] || "none"
			};
		},
		handleSelect: function (evt, evtKey) {
			var key = "colNormalization";
			setVizSettings(key, evtKey);
			this.setState({optionValue: evtKey});
		},
		render () {
			let optionValue = this.state.optionValue,
				options = [
					{"key": "none", "label": "off"},
					{"key": "subset", "label": "mean subtracted per column across samples"},
				],
				activeOption = _.find(options, obj => {
					return obj.key === optionValue;
				}),
				title = activeOption ? activeOption.label : 'Select',
				menuItemList = options.map(obj => {
					var active = (obj.key === optionValue);
					return active ? (<MenuItem eventKey={obj.key} active>{obj.label}</MenuItem>) :
						(<MenuItem eventKey={obj.key}>{obj.label}</MenuItem>);
				});
			return (
				<Row>
					<Col xs={3} md={2} lg={2}>Transform</Col>
					<Col xs={15} md={10} lg={5}>
						<DropdownButton title={title} onSelect={this.handleSelect} >
							{menuItemList}
						</DropdownButton>
					</Col>
				</Row>
			);
		}
	});

	var colorDropDown = React.createClass({
		getInitialState () {
			let	value = getVizSettings('colorClass') || defaultColorClass || 'default',
				mapping = {
					"default": "default",
					"expression": "expression",
					"clinical": "default",
				};
			return {
				optionValue: mapping[value] || 'default'
			};
		},
		handleSelect: function (evt, evtKey) {
			var key = "colorClass";
			setVizSettings(key, evtKey);
			this.setState({optionValue: evtKey});
		},
		render () {
			let optionValue = this.state.optionValue,
				options = {
					float: [
						{"key": "default", "label": "red-white-blue"},
						{"key": "expression", "label": "red-black-green"},
						{"key": "blueBlackYellow", "label": "yellow-black-blue"},
						{"key": "whiteBlack", "label": "black-white"}
					],
					segmented: [
						{"key": "default", "label": "red-white-blue"},
						{"key": "expression", "label": "red-white-green"},
						{"key": "blueBlackYellow", "label": "yellow-white-blue"}
					],
				},
				activeOption = _.find(options[valueType], obj => {
					return obj.key === optionValue;
				}),
				title = activeOption ? activeOption.label : 'Select',
				menuItemList = options[valueType].map(obj => {
					var active = (obj.key === optionValue);
					return active ? (<MenuItem eventKey={obj.key} active>{obj.label}</MenuItem>) :
						(<MenuItem eventKey={obj.key}>{obj.label}</MenuItem>);
				});
			return (
				<Row>
					<Col xs={3} md={2} lg={2}>Color</Col>
					<Col xs={15} md={10} lg={5}>
						<DropdownButton title={title} onSelect={this.handleSelect} >
							{menuItemList}
						</DropdownButton>
					</Col>
				</Row>
			);
		}
	});

	var oldSettings = state,
		currentSettings = {state: state},
		colorParams = {
			float: ["max", "maxStart", "minStart", "min"],
			segmented: ["origin", "thresh", "max"]
		};

	node.appendChild(datasetSetting());
	return currentSettings;
}

// react wrapper for the legacy DOM code, above.
var SettingsWrapper = React.createClass({
	shouldComponentUpdate: () => false,
	componentWillReceiveProps(newProps) {
		this.currentSettings.state = newProps.vizSettings;
	},
	componentDidMount: function () {
		var {refs: {content}, props: {onVizSettings, vizSettings, id, defaultNormalization, colorClass, valueType, onRequestHide}} = this;
		this.currentSettings = vizSettingsWidget(content, onVizSettings, vizSettings, id, onRequestHide, defaultNormalization, colorClass, valueType);
	},
	render: function () {
		return
;
	}
});

var VizSettings = React.createClass({
	render: function() {
		var {onRequestHide} = this.props;
		return (
			<Modal show={true} onHide={onRequestHide}>
				<Modal.Header closeButton>
					<Modal.Title>Dataset Visualization Settings</Modal.Title>
				</Modal.Header>
				<Modal.Body>
					<SettingsWrapper {...this.props} />
				</Modal.Body>
			</Modal>
		);
	}
});

module.exports = VizSettings;
<commit_msg>wording change in vizsetting for copy number data<commit_after>/*eslint camelcase: 0, no-use-before-define: 0 */
// Config UI for custom viz settings for heatmaps.
//
// State schema. This is the goal, not the current implementation. If
// the user has never modified the default settings, vizSettings is undefined.
//
// When the user modifies colNormalization or color parameters, they are
// written into vizSettings. vizSettings can have normalization or color
// parameters, or both. All color parameters are present if any are set.
// The minStart/maxStart are optional, so may be null if other color parameters
// are set.
//
// vizSettings = undefined |
//               {
//                 colNormalization: 'subset' | 'none'
//               } |
//               {
//                 min: float,
//                 minStart: float | null,
//                 maxStart: float | null,
//                 max: float
//               } |
//               {
//                 colNormalization: 'subset' | 'none'
//                 min: float,
//                 minStart: float | null,
//                 maxStart: float | null,
//                 max: float
//               }

// Refactoring notes:
// The default column normalization is fetched from the server. Instead it should come from
// the state, or from a data cache, because we've fetched that already.

'use strict';
var _ = require('../underscore_ext');
var floatImg = require('../../images/genomicFloatLegend.jpg');
var customFloatImg = require('../../images/genomicCustomFloatLegend.jpg');
var React = require('react');
var ReactDOM = require('react-dom');
var {Modal, DropdownButton, MenuItem, Row, Col, Button, ButtonToolbar, ButtonGroup} = require('react-bootstrap/lib/');
var Input = require('react-bootstrap/lib/Input');
var image = require('react-bootstrap/lib/Image');

function vizSettingsWidget(node, onVizSettings, vizState, id, hide, defaultNormalization, defaultColorClass, valueType) {
	var state = vizState;
	function datasetSetting() {
		var node, div = document.createElement("div");
		if (valueType === "float" || valueType === 'segmented') {
			node = document.createElement("div");
			allFloat(node);
			div.appendChild(node);

			node = document.createElement("span");
			ReactDOM.render(React.createElement(finishButtonBar), node);
			div.appendChild(node);
		}
		return div;
	}

	function allFloat(div) {
		var node;

		if (valueType === "float") {
			// normalization
			node = document.createElement("div");
			ReactDOM.render(React.createElement(normalizationDropDown), node);
			div.appendChild(node);
			div.appendChild(document.createElement("br"));
		}

		// color choice : green red or blue red
		node = document.createElement("div");
		ReactDOM.render(React.createElement(colorDropDown), node);
		div.appendChild(node);
		div.appendChild(document.createElement("br"));

		// color scale
		node = document.createElement("div");
		ReactDOM.render(React.createElement(scaleChoice), node);
		div.appendChild(node);
		div.appendChild(document.createElement("br"));
	}

	// discard user changes & close.
	var finishButtonBar = React.createClass({
		handleCancelClick () {
			hide();
			onVizSettings(id, state);
		},
		handleDoneClick () {
			hide();
		},
		render () {
			return (
				<ButtonToolbar>
					<Button onClick = {this.handleCancelClick}>Cancel</Button>
					<Button bsStyle="primary" onClick = {this.handleDoneClick}>Done</Button>
				</ButtonToolbar>
			);
		}
	});

	function getInputSettingsFloat(settings) {
		return _.fmap(settings, parseFloat);
	}

	var validateSettings = {
		float: s => {
			var vals = _.fmap(s, parseFloat),
				fmtErrors = _.fmap(vals, function (v, k) {
					return (isNaN(v) && s[k]) ? "Invalid number." : "";
				}),
				missing = _.fmap(s, _.constant(null)),
				rangeErrors;

			/*jshint -W018 */ /* allow xor idiom */
			if (!s.minStart !== !s.maxStart) { // xor
				missing.minStart = 'Both 0% values must be given to take effect.';
			}
			// XXX check for missin min & max

			if (s.minStart && s.maxStart && !fmtErrors.minStart && !fmtErrors.maxStart) {
				// wrong if missing maxStart: we compare against the wrong thing.
				rangeErrors = {
					max: null,
					maxStart: vals.maxStart <= vals.max ? null :  'Should be lower than max',
					minStart: vals.minStart <= vals.maxStart ? null : 'Should be lower than maxStart',
					min: vals.min <= vals.minStart ? null : 'Should be lower than minStart'
				};
			} else {
				rangeErrors = {
					max: null,
					min: vals.min <= vals.max ? null : 'Should be lower than max'
				};
			}

			return _.fmap(fmtErrors, function (err, k) {
				return _.filter([err, rangeErrors[k], missing[k]], _.identity).join(' ');
			});
		},
		segmented: s => {
			var vals = _.fmap(s, parseFloat),
				fmtErrors = _.fmap(vals, v => {
					return isNaN(v) ? "Invalid number." : "";
				}),
				rangeErrors = {
					thresh: vals.thresh >= 0 ? null : 'Should be positive',
					max: vals.max >= 0 ? null : 'Should be positive'
				};
			return _.fmap(fmtErrors, function (err, k) {
				return _.filter([err, rangeErrors[k]], _.identity).join(' ');
			});
		}
	};

	function settingsValid(errors) {
		return _.every(errors, function (s) { return !s; });
	}

	function valToStr(v) {
		return "" + v;
//		if (v === "-") {
//			return v;
//		}
//		return (!isNaN(v) && (v !== null) && (v !== undefined)) ? "" + v : "";
	}

	var scaleChoice = React.createClass({
		annotations: {
			float: {
				"max": "max: high color 100% saturation",
				"maxStart": "maxStart: high color 0% saturation",
				"minStart": "minStart: low color 0% saturation",
				"min": "min: low color 100% saturation"
			},
			segmented: {
				"origin": "Origin: value for copy number normal (typical: 0 or 2)",
				"thresh": "Threshold: absolute value from origin to start showing color",
				"max": "Saturation: absolute value from origin to draw full color"
			}
		},
		defaults: {
			float: {
				max: 1,
				maxStart: null,
				minStart: null,
				min: -1
			},
			segmented: {
				origin: 0,
				thresh: 0,
				max: 1
			}
		},
		getInitialState () {
			//check if there is custom value
			let custom = colorParams[valueType].some(function (param) {
					if (getVizSettings(param)) {
						return true;
					}
				});

			return {
				mode: custom ? "Custom" : "Auto",
				settings: custom ? _.pick(oldSettings, colorParams[valueType]) : this.defaults[valueType],
				errors: {}
			};
		},
		autoClick () {
			this.setState({mode: "Auto"});
			this.setState({settings: this.defaults[valueType]});
			this.setState({errors: {}});
			onVizSettings(id, _.omit(currentSettings.state, colorParams[valueType]));
		},
		customClick () {
			this.setState({mode: "Custom"});
			onVizSettings(id, _.merge(currentSettings.state, getInputSettingsFloat(this.state.settings)));
		},
		onScaleParamChange(ev) {
			var {settings} = this.state,
				param = ev.target.getAttribute('data-param'),
				newSettings = _.assoc(settings, param, ev.target.value),
				errors = validateSettings[valueType](newSettings);

			this.setState({settings: newSettings, errors});

			if (settingsValid(errors)) {
				onVizSettings(id, _.merge(currentSettings.state, getInputSettingsFloat(newSettings)));
			}
		},
		buildCustomColorScale () {
			var node = colorParams[valueType].map(param => {
					let value = valToStr(this.state.settings[param]),
						label = this.annotations[valueType][param],
						error = this.state.errors[param];

					return (
						<Row>
							<Col xs={4} md={4} lg={4}>{label}</Col>
							<Col xs={3} md={3} lg={3}>
								<Input type='textinput' placeholder={_.contains(['minThresh', 'maxThresh'], param) ? 'Auto' : ''}
									value={value} data-param={param} onChange={this.onScaleParamChange}/>
							</Col>
							<Col xs={5} md={5} lg={5}>
								{error}
							</Col>
						</Row>
					);
				});
			return node;
		},

		render () {
			let mode = this.state.mode,
				autoMode = (this.state.mode === "Auto"),
				modes = ["Auto", "Custom"],
				funcMapping = {
					"Auto": this.autoClick,
					"Custom": this.customClick
				},
				buttons = modes.map(mode => {
					let active = (this.state.mode === mode),
						func = funcMapping[mode];
					return active ? (<Button bsStyle="primary" onClick={func} active>{mode}</Button>) :
						(<Button onClick={func}>{mode}</Button>);
				}),
				picture = autoMode ? (<image src={floatImg} responsive/>) :
					(<image src={customFloatImg} responsive/>),
				enterInput = autoMode ? null : this.buildCustomColorScale();

			return (
				<Row>
					<Col xs={3} md={2} lg={2}>Scale</Col>
					<Col xs={15} md={10} lg={10}>
						<ButtonGroup>{buttons}</ButtonGroup>

							{valueType === 'float' ? picture : null}
							{enterInput}

					</Col>
				</Row>
			);
		}
	});

	function setVizSettings(key, value) {
		onVizSettings(id, _.assoc(currentSettings.state, key, value));
	}

	function getVizSettings(key) {
		return _.getIn(state, [key]);
	}

	var normalizationDropDown = React.createClass({
		getInitialState () {
			let	value = getVizSettings('colNormalization') || defaultNormalization || 'none',
				mapping = {
					"none": "none",
					"subset": "subset",
					true: "subset"
				};
			return {
				optionValue: mapping[value] || "none"
			};
		},
		handleSelect: function (evt, evtKey) {
			var key = "colNormalization";
			setVizSettings(key, evtKey);
			this.setState({optionValue: evtKey});
		},
		render () {
			let optionValue = this.state.optionValue,
				options = [
					{"key": "none", "label": "off"},
					{"key": "subset", "label": "mean subtracted per column across samples"},
				],
				activeOption = _.find(options, obj => {
					return obj.key === optionValue;
				}),
				title = activeOption ? activeOption.label : 'Select',
				menuItemList = options.map(obj => {
					var active = (obj.key === optionValue);
					return active ? (<MenuItem eventKey={obj.key} active>{obj.label}</MenuItem>) :
						(<MenuItem eventKey={obj.key}>{obj.label}</MenuItem>);
				});
			return (
				<Row>
					<Col xs={3} md={2} lg={2}>Transform</Col>
					<Col xs={15} md={10} lg={5}>
						<DropdownButton title={title} onSelect={this.handleSelect} >
							{menuItemList}
						</DropdownButton>
					</Col>
				</Row>
			);
		}
	});

	var colorDropDown = React.createClass({
		getInitialState () {
			let	value = getVizSettings('colorClass') || defaultColorClass || 'default',
				mapping = {
					"default": "default",
					"expression": "expression",
					"clinical": "default",
				};
			return {
				optionValue: mapping[value] || 'default'
			};
		},
		handleSelect: function (evt, evtKey) {
			var key = "colorClass";
			setVizSettings(key, evtKey);
			this.setState({optionValue: evtKey});
		},
		render () {
			let optionValue = this.state.optionValue,
				options = {
					float: [
						{"key": "default", "label": "red-white-blue"},
						{"key": "expression", "label": "red-black-green"},
						{"key": "blueBlackYellow", "label": "yellow-black-blue"},
						{"key": "whiteBlack", "label": "black-white"}
					],
					segmented: [
						{"key": "default", "label": "red-white-blue"},
						{"key": "expression", "label": "red-white-green"},
						{"key": "blueBlackYellow", "label": "yellow-white-blue"}
					],
				},
				activeOption = _.find(options[valueType], obj => {
					return obj.key === optionValue;
				}),
				title = activeOption ? activeOption.label : 'Select',
				menuItemList = options[valueType].map(obj => {
					var active = (obj.key === optionValue);
					return active ? (<MenuItem eventKey={obj.key} active>{obj.label}</MenuItem>) :
						(<MenuItem eventKey={obj.key}>{obj.label}</MenuItem>);
				});
			return (
				<Row>
					<Col xs={3} md={2} lg={2}>Color</Col>
					<Col xs={15} md={10} lg={5}>
						<DropdownButton title={title} onSelect={this.handleSelect} >
							{menuItemList}
						</DropdownButton>
					</Col>
				</Row>
			);
		}
	});

	var oldSettings = state,
		currentSettings = {state: state},
		colorParams = {
			float: ["max", "maxStart", "minStart", "min"],
			segmented: ["origin", "thresh", "max"]
		};

	node.appendChild(datasetSetting());
	return currentSettings;
}

// react wrapper for the legacy DOM code, above.
var SettingsWrapper = React.createClass({
	shouldComponentUpdate: () => false,
	componentWillReceiveProps(newProps) {
		this.currentSettings.state = newProps.vizSettings;
	},
	componentDidMount: function () {
		var {refs: {content}, props: {onVizSettings, vizSettings, id, defaultNormalization, colorClass, valueType, onRequestHide}} = this;
		this.currentSettings = vizSettingsWidget(content, onVizSettings, vizSettings, id, onRequestHide, defaultNormalization, colorClass, valueType);
	},
	render: function () {
		return
;
	}
});

var VizSettings = React.createClass({
	render: function() {
		var {onRequestHide} = this.props;
		return (
			<Modal show={true} onHide={onRequestHide}>
				<Modal.Header closeButton>
					<Modal.Title>Dataset Visualization Settings</Modal.Title>
				</Modal.Header>
				<Modal.Body>
					<SettingsWrapper {...this.props} />
				</Modal.Body>
			</Modal>
		);
	}
});

module.exports = VizSettings;
<|endoftext|>


<commit_before><commit_msg>I didnt need a click handler for timeline<commit_after><|endoftext|>


<commit_before>(function(jQuery, window) {
	"use strict";

	var win = jQuery(window);
	var doc = jQuery(document);
	var fontSize = 16;
	var rules = [];
	var rem = /(\d*\.?\d+)r?em/;
	var rpercent = /(\d*\.?\d+)%/;
	var width, height, scrollTop, scrollHeight;

	function getStyle(node, name) {
		return window.getComputedStyle ?
			window
			.getComputedStyle(node, null)
			.getPropertyValue(name) :
			0 ;
	}

	function getFontSize() {
		return fontSize ||
			(fontSize = parseInt(getStyle(document.documentElement, "font-size"), 10));
	}

	function parse(query) {
		var data, n;

		if (typeof query === 'number') {
			return function numberQuery() { return query; };
		}

		if (typeof query === 'string') {
			data = rem.exec(query);
			if (data) {
				n = parseFloat(data[1]);
				return function remQuery() { return getFontSize() * n; };
			}

			data = rpercent.exec(query);
			if (data) {
				n = parseFloat(data[1]) / 100;
				return function percentQuery() { return width * n; };
			}

			throw new Error('[window.breakpoint] \'' + query + '\' cannot be parsed.');
		}

		// Assume query is a function
		return query;
	}

	function media(query, fn1, fn2) {
		var rule = {};
		var key;

		for (key in query) {
			if (!query.hasOwnProperty(key)) { continue; }
			rule[key] = parse(query[key]);
		}

		rule.enter = fn1;
		rule.exit = fn2;
		rules.push(rule);
	}

	function test(rule) {
		if (rule.minWidth        && width <  rule.minWidth()) { return false; }
		if (rule.maxWidth        && width >= rule.maxWidth()) { return false; }
		if (rule.minHeight       && height <  rule.minHeight()) { return false; }
		if (rule.maxHeight       && height >= rule.maxHeight()) { return false; }
		if (rule.minScrollTop    && scrollTop <  rule.minScrollTop()) { return false; }
		if (rule.maxScrollTop    && scrollTop >= rule.maxScrollTop()) { return false; }
		if (rule.minScrollBottom && (scrollHeight - height - scrollTop) <  rule.minScrollBottom()) { return false; }
		if (rule.maxScrollBottom && (scrollHeight - height - scrollTop) >= rule.maxScrollBottom()) { return false; }

		return true;
	}

	function update() {
		var l = rules.length;
		var rule;

		// Run exiting rules
		while (l--) {
			rule = rules[l];

			if (rule.state && !test(rule)) {
				rule.state = false;
				rule.exit();
			}
		}

		l = rules.length;

		// Run entering rules
		while (l--) {
			rule = rules[l];

			if (!rule.state && test(rule)) {
				rule.state = true;
				rule.enter();
			}
		}
	}

	function scroll(e) {
		scrollTop = document.documentElement.scrollTop || document.body.scrollTop;;
		update();
	}

	function resize(e) {
		width = window.innerWidth;
		height = window.innerHeight;
		scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
		update();
	}

	win
	.on('scroll', scroll)
	.on('resize', resize);

	doc
	.ready(update)
	.on('DOMContentLoaded', update);

	width = window.innerWidth;
	height = window.innerHeight;
	scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
	scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

	window.breakpoint = media;
})(jQuery, window);
<commit_msg>Enter or Exit fns not required<commit_after>(function(jQuery, window) {
	"use strict";

	var win = jQuery(window);
	var doc = jQuery(document);
	var fontSize = 16;
	var rules = [];
	var rem = /(\d*\.?\d+)r?em/;
	var rpercent = /(\d*\.?\d+)%/;
	var width, height, scrollTop, scrollHeight;

	function getStyle(node, name) {
		return window.getComputedStyle ?
			window
			.getComputedStyle(node, null)
			.getPropertyValue(name) :
			0 ;
	}

	function getFontSize() {
		return fontSize ||
			(fontSize = parseInt(getStyle(document.documentElement, "font-size"), 10));
	}

	function parse(query) {
		var data, n;

		if (typeof query === 'number') {
			return function numberQuery() { return query; };
		}

		if (typeof query === 'string') {
			data = rem.exec(query);
			if (data) {
				n = parseFloat(data[1]);
				return function remQuery() { return getFontSize() * n; };
			}

			data = rpercent.exec(query);
			if (data) {
				n = parseFloat(data[1]) / 100;
				return function percentQuery() { return width * n; };
			}

			throw new Error('[window.breakpoint] \'' + query + '\' cannot be parsed.');
		}

		// Assume query is a function
		return query;
	}

	function media(query, fn1, fn2) {
		var rule = {};
		var key;

		for (key in query) {
			if (!query.hasOwnProperty(key)) { continue; }
			rule[key] = parse(query[key]);
		}

		rule.enter = fn1;
		rule.exit = fn2;
		rules.push(rule);
	}

	function test(rule) {
		if (rule.minWidth        && width <  rule.minWidth()) { return false; }
		if (rule.maxWidth        && width >= rule.maxWidth()) { return false; }
		if (rule.minHeight       && height <  rule.minHeight()) { return false; }
		if (rule.maxHeight       && height >= rule.maxHeight()) { return false; }
		if (rule.minScrollTop    && scrollTop <  rule.minScrollTop()) { return false; }
		if (rule.maxScrollTop    && scrollTop >= rule.maxScrollTop()) { return false; }
		if (rule.minScrollBottom && (scrollHeight - height - scrollTop) <  rule.minScrollBottom()) { return false; }
		if (rule.maxScrollBottom && (scrollHeight - height - scrollTop) >= rule.maxScrollBottom()) { return false; }

		return true;
	}

	function update() {
		var l = rules.length;
		var rule;

		// Run exiting rules
		while (l--) {
			rule = rules[l];

			if (rule.state && !test(rule)) {
				rule.state = false;
				rule.exit && rule.exit();
			}
		}

		l = rules.length;

		// Run entering rules
		while (l--) {
			rule = rules[l];

			if (!rule.state && test(rule)) {
				rule.state = true;
				rule.enter && rule.enter();
			}
		}
	}

	function scroll(e) {
		scrollTop = document.documentElement.scrollTop || document.body.scrollTop;;
		update();
	}

	function resize(e) {
		width = window.innerWidth;
		height = window.innerHeight;
		scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
		update();
	}

	win
	.on('scroll', scroll)
	.on('resize', resize);

	doc
	.ready(update)
	.on('DOMContentLoaded', update);

	width = window.innerWidth;
	height = window.innerHeight;
	scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
	scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;

	window.breakpoint = media;
})(jQuery, window);
<|endoftext|>


<commit_before><commit_msg>ensure selectedItems is an array<commit_after><|endoftext|>


<commit_before><commit_msg>Provide better error messaging.<commit_after><|endoftext|>


<commit_before><commit_msg>switching over motion for new app<commit_after><|endoftext|>


<commit_before><commit_msg>thanks etcher for the tip<commit_after><|endoftext|>


<commit_before><commit_msg>changed consts to vars in main.js<commit_after><|endoftext|>


<commit_before><commit_msg>implemented main menu<commit_after><|endoftext|>


<commit_before><commit_msg>Fix irregularity<commit_after><|endoftext|>


<commit_before><commit_msg>simple<commit_after><|endoftext|>


<commit_before><commit_msg>Modified<commit_after><|endoftext|>


<commit_before>"use strict"
const ES_URL = process.env.ES_URL;
var elasticsearch = require('elasticsearch');

var exports = module.exports = {};

var esdb = new elasticsearch.Client( {
  hosts: [
    ES_URL,
  ]
});

function add_document (index, type, document, callback, id) {
  if (id == null) {
    esdb.index({
      index: index,
      type: type,
      body: document
    }, function(error, response) {
      callback(error, response);
    })
  } else {
    esdb.index({
      index: index,
      type: type,
      body: document,
      id : id
    }, function(error, response) {
      callback(error, response);
    })
  }
}

function search_document (index, type, query, callback) {
  let document = null;
  console.log(JSON.stringify(query));
  esdb.search({
    index: index,
    type: type,
    from : 0,
    size : 50,
    body: {
      query: query,
      sort:"request_id:desc"
    }
  },function (error, response, status) {
    if (error){
      console.log("search error: "+error)
    }
    else {
      console.log("--- Response ---");
      console.log(response);
      console.log("--- Hits ---");
      response.hits.hits.forEach(function(hit){
        console.log(hit);
      });
      document = response.hits.hits;
    }
    callback(document);
  });
}

exports.add_document = add_document;
exports.search_document = search_document;<commit_msg>Correction<commit_after>"use strict"
const ES_URL = process.env.ES_URL;
var elasticsearch = require('elasticsearch');

var exports = module.exports = {};

var esdb = new elasticsearch.Client( {
  hosts: [
    ES_URL,
  ]
});

function add_document (index, type, document, callback, id) {
  if (id == null) {
    esdb.index({
      index: index,
      type: type,
      body: document
    }, function(error, response) {
      callback(error, response);
    })
  } else {
    esdb.index({
      index: index,
      type: type,
      body: document,
      id : id
    }, function(error, response) {
      callback(error, response);
    })
  }
}

function search_document (index, type, query, callback) {
  let document = null;
  console.log(JSON.stringify(query));
  esdb.search({
    index: index,
    type: type,
    from : 0,
    size : 50,
    body: {
      query: query
    }
  },function (error, response, status) {
    if (error){
      console.log("search error: "+error)
    }
    else {
      console.log("--- Response ---");
      console.log(response);
      console.log("--- Hits ---");
      response.hits.hits.forEach(function(hit){
        console.log(hit);
      });
      document = response.hits.hits;
    }
    callback(document);
  });
}

exports.add_document = add_document;
exports.search_document = search_document;<|endoftext|>


<commit_before>importScripts('/lib/require.js');

var worker = self;

requirejs.config({
  baseUrl: "..",
  paths: {
    'underscore': '../node_modules/underscore/underscore',
    'backbone-events': '../node_modules/backbone-events/lib/backbone-events',
    'backbone': '../node_modules/backbone/backbone',
    'lathe': '../node_modules/lathe/lib',
    'gl-matrix': '../node_modules/lathe/node_modules/gl-matrix/dist/gl-matrix',
  },
  shim: {
    'underscore': {
      exports: '_'
    },
    'backbone': {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    },
  },
});
requirejs([
    'lathe/bsp',
    'lathe/primitives/cube',
    'lathe/primitives/sphere',
    'lathe/primitives/cylinder',
    'lathe/primitives/cone',
    'lathe/primitives/union3d',
    'lathe/primitives/subtract3d',
    'lathe/primitives/intersect3d',
    'lathe/conv',
  ],
  function(
    BSP,
    Cube,
    Sphere,
    Cylinder,
    Cone,
    Union3D,
    Subtract3D,
    Intersect3D,
    Conv) {

    var infoHandler = function(a,b,c,d) {
      postMessage({info: [a,b,c,d].join('')});
    }

    var errorHandler = function(a,b,c,d) {
      postMessage({error: [a,b,c,d].join('')});
    }

    var returnResult = function(id, sha, bsp) {
      if (!bsp) {
        postMessage({error: 'no BSP for ' + id});
        return;
      }

      var brep = Conv.bspToBrep(bsp);
      var polygons = brep.map(function(p) {
        return p.toVertices().map(function(v) {
          return v.toCoordinate();
        });
      });
      var jobResult = {
        id: id,
        sha: sha,
        bsp: BSP.serialize(bsp),
        polygons: polygons,
      }
      postMessage(jobResult);

    }

    var applyReverseWorkplane = function(bsp, workplane) {
      if (!((workplane.origin.x === 0) && (workplane.origin.y === 0) && (workplane.origin.z === 0))) {
        bsp = bsp.translate(-workplane.origin.x, -workplane.origin.y, -workplane.origin.z);
      }
      if (workplane.angle !== 0) {
        bsp = bsp.rotate(
          workplane.axis.x,
          workplane.axis.y,
          workplane.axis.z,
          -workplane.angle/180*Math.PI);
      }
      return bsp;
    }

    var applyTransformsAndWorkplane = function(bsp, transforms, workplane) {
      if (transforms.translation) {
        bsp = bsp.translate(transforms.translation.x, transforms.translation.y, transforms.translation.z);
      }
      if (transforms.rotation.angle !== 0) {
        bsp = bsp.translate(-transforms.rotation.origin.x, -transforms.rotation.origin.y, -transforms.rotation.origin.z);
        bsp = bsp.rotate(transforms.rotation.axis.x, transforms.rotation.axis.y, transforms.rotation.axis.z, transforms.rotation.angle/180*Math.PI);
        bsp = bsp.translate(transforms.rotation.origin.x, transforms.rotation.origin.y, transforms.rotation.origin.z);
      }
      if (transforms.scale.factor !== 1) {
        bsp = bsp.translate(-transforms.scale.origin.x, -transforms.scale.origin.y, -transforms.scale.origin.z);
        bsp = bsp.scale(transforms.scale.factor);
        bsp = bsp.translate(transforms.scale.origin.x, transforms.scale.origin.y, -transforms.scale.origin.z);
      }
      if (workplane.angle !== 0) {
        bsp = bsp.rotate(
          workplane.axis.x,
          workplane.axis.y,
          workplane.axis.z,
          workplane.angle/180*Math.PI);
      }
      if (!((workplane.origin.x === 0) && (workplane.origin.y === 0) && (workplane.origin.z === 0))) {
        bsp = bsp.translate(workplane.origin.x, workplane.origin.y, workplane.origin.z);
      }
      return bsp;
    }

    this.addEventListener('message', function(e) {

      // Create new with the arguments
      if (e.data.sphere) {
        var bsp = applyTransformsAndWorkplane(new Sphere(e.data.sphere).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.cylinder) {
        var bsp = applyTransformsAndWorkplane(new Cylinder(e.data.cylinder, 20).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.cone) {
        var bsp = applyTransformsAndWorkplane(new Cone(e.data.cone, 20).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.cube) {
        var bsp = applyTransformsAndWorkplane(new Cube(e.data.cube).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.union || e.data.subtract || e.data.intersect) {

        // The child BSPs start off as an array of SHAs,
        // and each SHA is replaced with the BSP from the DB
        var childBSPs = e.data.union || e.data.subtract || e.data.intersect;

        var remaining = childBSPs.length;

        var primitiveBsp = BSP.deserialize(childBSPs[0]);
        for (var i = 1; i < childBSPs.length; ++i) {
          var other = BSP.deserialize(childBSPs[i]);
          if (e.data.union) {
            primitiveBsp = new Union3D(primitiveBsp, other).bsp;
          } else if (e.data.subtract) {
            primitiveBsp = new Subtract3D(primitiveBsp, other).bsp;
          } else {
            primitiveBsp = new Intersect3D(primitiveBsp, other).bsp;
          }
        }
        var bsp = applyReverseWorkplane(primitiveBsp, e.data.workplane);
        bsp = applyTransformsAndWorkplane(bsp, e.data.transforms, e.data.workplane);

        returnResult(e.data.id, e.data.sha, bsp);

      } else {
        postMessage({error: 'unknown worker message:' + JSON.stringify(e.data)});
      }

    }, false);

    postMessage('initialized');
  }
);<commit_msg>Increase cylinder & cone resolution<commit_after>importScripts('/lib/require.js');

var worker = self;

requirejs.config({
  baseUrl: "..",
  paths: {
    'underscore': '../node_modules/underscore/underscore',
    'backbone-events': '../node_modules/backbone-events/lib/backbone-events',
    'backbone': '../node_modules/backbone/backbone',
    'lathe': '../node_modules/lathe/lib',
    'gl-matrix': '../node_modules/lathe/node_modules/gl-matrix/dist/gl-matrix',
  },
  shim: {
    'underscore': {
      exports: '_'
    },
    'backbone': {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    },
  },
});
requirejs([
    'lathe/bsp',
    'lathe/primitives/cube',
    'lathe/primitives/sphere',
    'lathe/primitives/cylinder',
    'lathe/primitives/cone',
    'lathe/primitives/union3d',
    'lathe/primitives/subtract3d',
    'lathe/primitives/intersect3d',
    'lathe/conv',
  ],
  function(
    BSP,
    Cube,
    Sphere,
    Cylinder,
    Cone,
    Union3D,
    Subtract3D,
    Intersect3D,
    Conv) {

    var infoHandler = function(a,b,c,d) {
      postMessage({info: [a,b,c,d].join('')});
    }

    var errorHandler = function(a,b,c,d) {
      postMessage({error: [a,b,c,d].join('')});
    }

    var returnResult = function(id, sha, bsp) {
      if (!bsp) {
        postMessage({error: 'no BSP for ' + id});
        return;
      }

      var brep = Conv.bspToBrep(bsp);
      var polygons = brep.map(function(p) {
        return p.toVertices().map(function(v) {
          return v.toCoordinate();
        });
      });
      var jobResult = {
        id: id,
        sha: sha,
        bsp: BSP.serialize(bsp),
        polygons: polygons,
      }
      postMessage(jobResult);

    }

    var applyReverseWorkplane = function(bsp, workplane) {
      if (!((workplane.origin.x === 0) && (workplane.origin.y === 0) && (workplane.origin.z === 0))) {
        bsp = bsp.translate(-workplane.origin.x, -workplane.origin.y, -workplane.origin.z);
      }
      if (workplane.angle !== 0) {
        bsp = bsp.rotate(
          workplane.axis.x,
          workplane.axis.y,
          workplane.axis.z,
          -workplane.angle/180*Math.PI);
      }
      return bsp;
    }

    var applyTransformsAndWorkplane = function(bsp, transforms, workplane) {
      if (transforms.translation) {
        bsp = bsp.translate(transforms.translation.x, transforms.translation.y, transforms.translation.z);
      }
      if (transforms.rotation.angle !== 0) {
        bsp = bsp.translate(-transforms.rotation.origin.x, -transforms.rotation.origin.y, -transforms.rotation.origin.z);
        bsp = bsp.rotate(transforms.rotation.axis.x, transforms.rotation.axis.y, transforms.rotation.axis.z, transforms.rotation.angle/180*Math.PI);
        bsp = bsp.translate(transforms.rotation.origin.x, transforms.rotation.origin.y, transforms.rotation.origin.z);
      }
      if (transforms.scale.factor !== 1) {
        bsp = bsp.translate(-transforms.scale.origin.x, -transforms.scale.origin.y, -transforms.scale.origin.z);
        bsp = bsp.scale(transforms.scale.factor);
        bsp = bsp.translate(transforms.scale.origin.x, transforms.scale.origin.y, -transforms.scale.origin.z);
      }
      if (workplane.angle !== 0) {
        bsp = bsp.rotate(
          workplane.axis.x,
          workplane.axis.y,
          workplane.axis.z,
          workplane.angle/180*Math.PI);
      }
      if (!((workplane.origin.x === 0) && (workplane.origin.y === 0) && (workplane.origin.z === 0))) {
        bsp = bsp.translate(workplane.origin.x, workplane.origin.y, workplane.origin.z);
      }
      return bsp;
    }

    this.addEventListener('message', function(e) {

      // Create new with the arguments
      if (e.data.sphere) {
        var bsp = applyTransformsAndWorkplane(new Sphere(e.data.sphere).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.cylinder) {
        var bsp = applyTransformsAndWorkplane(new Cylinder(e.data.cylinder, 24).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.cone) {
        var bsp = applyTransformsAndWorkplane(new Cone(e.data.cone, 24).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.cube) {
        var bsp = applyTransformsAndWorkplane(new Cube(e.data.cube).bsp, e.data.transforms, e.data.workplane);
        returnResult(e.data.id, e.data.sha, bsp);
      } else if (e.data.union || e.data.subtract || e.data.intersect) {

        // The child BSPs start off as an array of SHAs,
        // and each SHA is replaced with the BSP from the DB
        var childBSPs = e.data.union || e.data.subtract || e.data.intersect;

        var remaining = childBSPs.length;

        var primitiveBsp = BSP.deserialize(childBSPs[0]);
        for (var i = 1; i < childBSPs.length; ++i) {
          var other = BSP.deserialize(childBSPs[i]);
          if (e.data.union) {
            primitiveBsp = new Union3D(primitiveBsp, other).bsp;
          } else if (e.data.subtract) {
            primitiveBsp = new Subtract3D(primitiveBsp, other).bsp;
          } else {
            primitiveBsp = new Intersect3D(primitiveBsp, other).bsp;
          }
        }
        var bsp = applyReverseWorkplane(primitiveBsp, e.data.workplane);
        bsp = applyTransformsAndWorkplane(bsp, e.data.transforms, e.data.workplane);

        returnResult(e.data.id, e.data.sha, bsp);

      } else {
        postMessage({error: 'unknown worker message:' + JSON.stringify(e.data)});
      }

    }, false);

    postMessage('initialized');
  }
);<|endoftext|>


<commit_before>const path = require('path')
const fs = require('fs')
const requireHacker = require('require-hacker')

function setupRequireHacker () {
  requireHacker.resolver((filename, module) => {
    if (filename.endsWith('/style/css')) {
      return requireHacker.resolve(`${filename}.web.js`, module)
    }
  })

  requireHacker.hook('js', filename => {
    if (filename.endsWith('/node_modules/hammerjs/hammer.js')) {
      return `
        module.exports = {}
      `
    }

    if (
      filename.endsWith('.web.js') ||
      !filename.includes('/node_modules/') ||
      ['antd-mobile', 'rmc-picker'].every(p => !filename.includes(p))
    ) return

    const webjs = filename.replace(/\.js$/, '.web.js')
    if (!fs.existsSync(webjs)) return

    return fs.readFileSync(webjs, { encoding: 'utf8' })
  })

  requireHacker.hook('svg', filename => {
    const id = path.basename(filename).replace(/\.svg$/, '')
    return requireHacker.to_javascript_module_source(`#${id}`)
  })
}

setupRequireHacker()

function moduleDir (m) {
  return path.dirname(require.resolve(`${m}/package.json`))
}

module.exports = {
  webpack: (config, { dev }) => {
    config.resolve.extensions = ['.web.js', '.js', '.json']

    config.module.rules.push(
      {
        test: /\.(svg)$/i,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]'
        },
        include: [
          moduleDir('antd-mobile'),
          __dirname
        ]
      },
      {
        test: /\.(svg)$/i,
        loader: 'svg-sprite-loader',
        include: [
          moduleDir('antd-mobile'),
          __dirname
        ]
      }
    )

    return config
  }
}
<commit_msg>update with-antd-mobile example (#2425)<commit_after>const path = require('path')
const fs = require('fs')
const requireHacker = require('require-hacker')

function setupRequireHacker () {
  const webjs = '.web.js'
  const webModules = ['antd-mobile', 'rmc-picker'].map(m => path.join('node_modules', m))

  requireHacker.hook('js', filename => {
    if (filename.endsWith(webjs) || webModules.every(p => !filename.includes(p))) return

    const webFilename = filename.replace(/\.js$/, webjs)
    if (!fs.existsSync(webFilename)) return

    return fs.readFileSync(webFilename, { encoding: 'utf8' })
  })

  requireHacker.hook('svg', filename => {
    return requireHacker.to_javascript_module_source(`#${path.parse(filename).name}`)
  })
}

setupRequireHacker()

function moduleDir (m) {
  return path.dirname(require.resolve(`${m}/package.json`))
}

module.exports = {
  webpack: (config, { dev }) => {
    config.resolve.extensions = ['.web.js', '.js', '.json']

    config.module.rules.push(
      {
        test: /\.(svg)$/i,
        loader: 'emit-file-loader',
        options: {
          name: 'dist/[path][name].[ext]'
        },
        include: [
          moduleDir('antd-mobile'),
          __dirname
        ]
      },
      {
        test: /\.(svg)$/i,
        loader: 'svg-sprite-loader',
        include: [
          moduleDir('antd-mobile'),
          __dirname
        ]
      }
    )

    return config
  }
}
<|endoftext|>


<commit_before>var Factory = function (dialogs, options) {
  this.dialogs = dialogs;

  this.options = options || {};
  this.config = options.config || {};
  this.templates = options.templates || {};
};

Factory.prototype.createDialog = function (dialog, options) {
  var opts = options || {};
  opts.dialog = dialog;

  var Dialog = this.dialogs.get(dialog.type);

  // add any classname if defined
  if (dialog.className) {
    opts.className = Dialog.prototype.className + ' ' + dialog.className;
  }

  // instanciate dialog
  var view = new Dialog(opts);
  // we need to set the template before rendering the view
  // if no template has been attached to the view search for the main template registry
  if (!view.template) {
    view.template = this.templates[dialog.template || dialog.type];
  }

  return view;
};

Factory.prototype.create = function (slug, options) {
  if (!slug) {
    return;
  }

  // enable the slug to be defined as an object
  var dialog = '[object Object]' === slug.toString() ? slug : this.config.dialogs[slug];

  if (!dialog) {
    return;
  }

  return this.createDialog(dialog, options);
};

Factory.prototype.render = function (region, slug, options) {
  if (!region) {
    return;
  }

  // extract region options if any that will be passed to region.show call.
  var regionOptions = {};

  if (options && options.hasOwnProperty('region')) {
    regionOptions = options.region;
    // remove them from options are they are explicitly for region
    delete options.region;
  }

  var dialog = this.create(slug, options);

  if (!dialog) {
    return false;
  }

  region.show(dialog, regionOptions);

  return dialog;
};
<commit_msg>feat(factory): enable default when passing an object configuration<commit_after>var Factory = function (dialogs, options) {
  this.dialogs = dialogs;

  this.options = options || {};
  this.config = options.config || {};
  this.templates = options.templates || {};
};

Factory.prototype.createDialog = function (dialog, options) {
  var opts = options || {};
  opts.dialog = dialog;

  var Dialog = this.dialogs.get(dialog.type);

  // add any classname if defined
  if (dialog.className) {
    opts.className = Dialog.prototype.className + ' ' + dialog.className;
  }

  // instanciate dialog
  var view = new Dialog(opts);
  // we need to set the template before rendering the view
  // if no template has been attached to the view search for the main template registry
  if (!view.template) {
    view.template = this.templates[dialog.template || dialog.type];
  }

  return view;
};

Factory.prototype.create = function (slug, options) {
  if (!slug) {
    return;
  }

  // enable the slug to be defined as an object
  var dialog;

  if ('[object Object]' === slug.toString()) {
    var type = slug.type;
    if (this.config.dialogs[type]) {
      dialog = _.extend({}, this.config.dialogs[type], slug);
    }
  }
  else {
    dialog = this.config.dialogs[slug];
  }

  if (!dialog) {
    return;
  }

  return this.createDialog(dialog, options);
};

Factory.prototype.render = function (region, slug, options) {
  if (!region) {
    return;
  }

  // extract region options if any that will be passed to region.show call.
  var regionOptions = {};

  if (options && options.hasOwnProperty('region')) {
    regionOptions = options.region;
    // remove them from options are they are explicitly for region
    delete options.region;
  }

  var dialog = this.create(slug, options);

  if (!dialog) {
    return false;
  }

  region.show(dialog, regionOptions);

  return dialog;
};
<|endoftext|>


<commit_before>var ws = require('ws');
var WSServer = ws.Server;
var SCSocket = require('./scsocket');
var AuthEngine = require('./auth').AuthEngine;
var EventEmitter = require('events').EventEmitter;
var base64id = require('base64id');
var async = require('async');
var url = require('url');
var domain = require('domain');

var SCServer = function (options) {
  var self = this;

  var opts = {
    ackTimeout: 10000,
    allowClientPublish: true,
    path: '/socketcluster/'
  };

  var i;
  for (i in options) {
    opts[i] = options[i];
  }

  this.MIDDLEWARE_HANDSHAKE = 'handshake';
  this.MIDDLEWARE_EMIT = 'emit';
  this.MIDDLEWARE_SUBSCRIBE = 'subscribe';
  this.MIDDLEWARE_PUBLISH_IN = 'publishIn';
  this.MIDDLEWARE_PUBLISH_OUT = 'publishOut';

  // Deprecated
  this.MIDDLEWARE_PUBLISH = this.MIDDLEWARE_PUBLISH_IN;

  this.EVENT_PUBLISH = 'publish';

  this.ERROR_NO_PUBLISH = 'Error: Client publish feature is disabled';

  this._middleware = {};
  this._middleware[this.MIDDLEWARE_HANDSHAKE] = [];
  this._middleware[this.MIDDLEWARE_EMIT] = [];
  this._middleware[this.MIDDLEWARE_SUBSCRIBE] = [];
  this._middleware[this.MIDDLEWARE_PUBLISH_IN] = [];
  this._middleware[this.MIDDLEWARE_PUBLISH_OUT] = [];

  this.origins = opts.origins;
  this._allowAllOrigins = this.origins.indexOf('*:*') != -1;

  this.ackTimeout = opts.ackTimeout;
  this.pingInterval = opts.pingInterval;
  this.pingTimeout = opts.pingTimeout;
  this.allowClientPublish = opts.allowClientPublish;
  this.perMessageDeflate = opts.perMessageDeflate;
  this.httpServer = opts.httpServer;

  this._ioClusterClient = opts.ioClusterClient;
  this.appName = opts.appName || '';
  this._path = opts.path;

  if (opts.authCookieName == null) {
    this._authCookieName = 'n/' + this.appName + '/auth';
  } else {
    this._authCookieName = opts.authCookieName;
  }

  this.auth = new AuthEngine({
    cookieName: this._authCookieName,
    defaultExpiryInMinutes: opts.defaultAuthTokenExpiryInMinutes,
    key: opts.authKey
  });

  this.clients = {};
  this.clientsCount = 0;

  this.global = this._ioClusterClient.global();

  this.wsServer = new WSServer({
    server: this.httpServer,
    clientTracking: false,
    perMessageDeflate: this.perMessageDeflate,
    handleProtocols: opts.handleProtocols,
    verifyClient: this.verifyHandshake.bind(this)
  });

  this.wsServer.on('error', this._handleServerError.bind(this));
  this.wsServer.on('connection', this._handleSocketConnection.bind(this));
};

SCServer.prototype = Object.create(EventEmitter.prototype);

SCServer.errorStatuses = {
  0: 'Failed handshake'
};

SCServer.prototype.sendErrorMessage = function (res, code) {
  res.writeHead(400, {'Content-Type': 'application/json'});
  res.end(JSON.stringify({
    code: code,
    message: SCServer.errorStatuses[code]
  }));
};

SCServer.prototype._handleServerError = function (error) {
  this.emit('error', error);
};

SCServer.prototype._handleSocketError = function (error) {
  // We don't want to crash the entire worker on socket error
  // so we emit it as a notice instead.
  var errorPrefix = 'Socket Error: ';
  if (error.message) {
    error.message = errorPrefix + error.message;
  } else if (typeof error == 'string') {
    error = errorPrefix + error;
  }
  this.emit('notice', error);
};

SCServer.prototype.setAuthTokenVerifyOptionsFactory = function (factoryFn) {
  this.auth.setTokenVerifyOptionsFactory(factoryFn);
};

SCServer.prototype.getAuthTokenVerifyOptionsFactory = function () {
  return this.auth.getTokenVerifyOptionsFactory();
};

SCServer.prototype._handleSocketConnection = function (wsSocket) {
  var self = this;

  this.auth.parseToken(wsSocket.upgradeReq, function (err, authToken) {
    var id = self.generateId();

    // In case of an expired, malformed or invalid token, emit an event
    // and keep going without a token.
    if (err) {
      self.emit('badAuthToken', err);
    }

    var authData = {
      token: authToken
    };

    if (err) {
      authData.error = {
        name: err.name,
        message: err.message
      };
    }

    var socketDomain = domain.createDomain();
    var scSocket = new SCSocket(id, self, wsSocket, authData);

    self.clients[id] = scSocket;
    self.clientsCount++;

    socketDomain.on('error', function (err) {
      self._handleSocketError(err);
      scSocket.disconnect();
    });
    socketDomain.add(scSocket);

    self._ioClusterClient.bind(scSocket, function (err, sock, isNotice) {
      if (err) {
        var errorMessage = 'Failed to bind socket to io cluster - ' + err;
        scSocket.emit('fail', errorMessage);
        scSocket.disconnect();
        if (isNotice) {
          self.emit('notice', errorMessage);
        } else {
          self.emit('error', new Error(errorMessage));
        }
      } else {
        scSocket.global = self.global;
        self.emit('connection', scSocket);
      }
    });

    scSocket.once('_disconnect', function () {
      delete self.clients[id];
      self.clientsCount--;
      self._ioClusterClient.unbind(scSocket, function (err) {
        if (err) {
          self.emit('error', new Error('Failed to unbind socket from io cluster - ' + err));
        } else {
          self.emit('disconnection', scSocket);
        }
      });
    });
  });
};

SCServer.prototype.close = function () {
  this.wsServer.close();
};

SCServer.prototype.getPath = function () {
  return this._path;
};

SCServer.prototype.generateId = function () {
  return base64id.generateId();
};

SCServer.prototype.on = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.once(event, listener);
  } else {
    EventEmitter.prototype.on.apply(this, arguments);
  }
};

SCServer.prototype.removeListener = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.removeListener(event, listener);
  } else {
    EventEmitter.prototype.removeListener.apply(this, arguments);
  }
};

SCServer.prototype.addMiddleware = function (type, middleware) {
  this._middleware[type].push(middleware);
};

SCServer.prototype.verifyHandshake = function (info, cb) {
  var self = this;

  var req = info.req;
  var origin = info.origin;
  if (origin == 'null' || origin == null) {
    origin = '*';
  }
  var ok = false;

  if (this._allowAllOrigins) {
    ok = true;
  } else {
    try {
      var parts = url.parse(origin);
      parts.port = parts.port || 80;
      ok = ~this.origins.indexOf(parts.hostname + ':' + parts.port) ||
        ~this.origins.indexOf(parts.hostname + ':*') ||
        ~this.origins.indexOf('*:' + parts.port);
    } catch (e) {}
  }

  if (ok) {
    var handshakeMiddleware = this._middleware[this.MIDDLEWARE_HANDSHAKE];
    if (handshakeMiddleware.length) {
      async.applyEachSeries(handshakeMiddleware, req, function (err) {
        if (err) {
          self.emit('notice', err);
          cb(false, 401, err);
        } else {
          cb(true);
        }
      });
    } else {
      cb(true);
    }
  } else {
    var err = 'Failed to authorize socket handshake - Invalid origin: ' + origin;
    this.emit('notice', err);
    cb(false, 403, err);
  }
};

SCServer.prototype.verifyInboundEvent = function (socket, event, data, cb) {
  var self = this;

  if (event == this.MIDDLEWARE_SUBSCRIBE) {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_SUBSCRIBE], socket, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  } else if (event == this.EVENT_PUBLISH) {
    if (this.allowClientPublish) {
      async.applyEachSeries(this._middleware[this.MIDDLEWARE_PUBLISH_IN], socket, data.channel, data.data,
        function (err) {
          if (err) {
            self.emit('notice', err);
            cb(err);
          } else {
            var options = {};
            if (data.mid) {
              options.mid = data.mid;
            }
            self.global.publish(data.channel, data.data, function (err) {
              cb(err);
            });
          }
        }
      );
    } else {
      cb(this.ERROR_NO_PUBLISH);
    }
  } else {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_EMIT], socket, event, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  }
};

SCServer.prototype.verifyOutboundEvent = function (socket, event, data, cb) {
  var self = this;

  if (event == this.EVENT_PUBLISH) {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_PUBLISH_OUT], socket, data.channel, data.data,
      function (err) {
        if (err) {
          if (err !== true) {
            self.emit('notice', err);
          }
          cb(err);
        } else {
          cb();
        }
      }
    );
  } else {
    cb();
  }
};

module.exports = SCServer;
<commit_msg>Removed artifact from previous cleanup<commit_after>var ws = require('ws');
var WSServer = ws.Server;
var SCSocket = require('./scsocket');
var AuthEngine = require('./auth').AuthEngine;
var EventEmitter = require('events').EventEmitter;
var base64id = require('base64id');
var async = require('async');
var url = require('url');
var domain = require('domain');

var SCServer = function (options) {
  var self = this;

  var opts = {
    ackTimeout: 10000,
    allowClientPublish: true,
    path: '/socketcluster/'
  };

  var i;
  for (i in options) {
    opts[i] = options[i];
  }

  this.MIDDLEWARE_HANDSHAKE = 'handshake';
  this.MIDDLEWARE_EMIT = 'emit';
  this.MIDDLEWARE_SUBSCRIBE = 'subscribe';
  this.MIDDLEWARE_PUBLISH_IN = 'publishIn';
  this.MIDDLEWARE_PUBLISH_OUT = 'publishOut';

  // Deprecated
  this.MIDDLEWARE_PUBLISH = this.MIDDLEWARE_PUBLISH_IN;

  this.EVENT_PUBLISH = 'publish';

  this.ERROR_NO_PUBLISH = 'Error: Client publish feature is disabled';

  this._middleware = {};
  this._middleware[this.MIDDLEWARE_HANDSHAKE] = [];
  this._middleware[this.MIDDLEWARE_EMIT] = [];
  this._middleware[this.MIDDLEWARE_SUBSCRIBE] = [];
  this._middleware[this.MIDDLEWARE_PUBLISH_IN] = [];
  this._middleware[this.MIDDLEWARE_PUBLISH_OUT] = [];

  this.origins = opts.origins;
  this._allowAllOrigins = this.origins.indexOf('*:*') != -1;

  this.ackTimeout = opts.ackTimeout;
  this.pingInterval = opts.pingInterval;
  this.pingTimeout = opts.pingTimeout;
  this.allowClientPublish = opts.allowClientPublish;
  this.perMessageDeflate = opts.perMessageDeflate;
  this.httpServer = opts.httpServer;

  this._ioClusterClient = opts.ioClusterClient;
  this.appName = opts.appName || '';
  this._path = opts.path;

  if (opts.authCookieName == null) {
    this._authCookieName = 'n/' + this.appName + '/auth';
  } else {
    this._authCookieName = opts.authCookieName;
  }

  this.auth = new AuthEngine({
    cookieName: this._authCookieName,
    defaultExpiryInMinutes: opts.defaultAuthTokenExpiryInMinutes,
    key: opts.authKey
  });

  this.clients = {};
  this.clientsCount = 0;

  this.global = this._ioClusterClient.global();

  this.wsServer = new WSServer({
    server: this.httpServer,
    clientTracking: false,
    perMessageDeflate: this.perMessageDeflate,
    handleProtocols: opts.handleProtocols,
    verifyClient: this.verifyHandshake.bind(this)
  });

  this.wsServer.on('error', this._handleServerError.bind(this));
  this.wsServer.on('connection', this._handleSocketConnection.bind(this));
};

SCServer.prototype = Object.create(EventEmitter.prototype);

SCServer.errorStatuses = {
  0: 'Failed handshake'
};

SCServer.prototype.sendErrorMessage = function (res, code) {
  res.writeHead(400, {'Content-Type': 'application/json'});
  res.end(JSON.stringify({
    code: code,
    message: SCServer.errorStatuses[code]
  }));
};

SCServer.prototype._handleServerError = function (error) {
  this.emit('error', error);
};

SCServer.prototype._handleSocketError = function (error) {
  // We don't want to crash the entire worker on socket error
  // so we emit it as a notice instead.
  var errorPrefix = 'Socket Error: ';
  if (error.message) {
    error.message = errorPrefix + error.message;
  } else if (typeof error == 'string') {
    error = errorPrefix + error;
  }
  this.emit('notice', error);
};

SCServer.prototype.setAuthTokenVerifyOptionsFactory = function (factoryFn) {
  this.auth.setTokenVerifyOptionsFactory(factoryFn);
};

SCServer.prototype.getAuthTokenVerifyOptionsFactory = function () {
  return this.auth.getTokenVerifyOptionsFactory();
};

SCServer.prototype._handleSocketConnection = function (wsSocket) {
  var self = this;

  this.auth.parseToken(wsSocket.upgradeReq, function (err, authToken) {
    var id = self.generateId();

    // In case of an expired, malformed or invalid token, emit an event
    // and keep going without a token.
    if (err) {
      self.emit('badAuthToken', err);
    }

    var authData = {
      token: authToken
    };

    if (err) {
      authData.error = {
        name: err.name,
        message: err.message
      };
    }

    var socketDomain = domain.createDomain();
    var scSocket = new SCSocket(id, self, wsSocket, authData);

    self.clients[id] = scSocket;
    self.clientsCount++;

    socketDomain.on('error', function (err) {
      self._handleSocketError(err);
      scSocket.disconnect();
    });
    socketDomain.add(scSocket);

    self._ioClusterClient.bind(scSocket, function (err, sock, isNotice) {
      if (err) {
        var errorMessage = 'Failed to bind socket to io cluster - ' + err;
        scSocket.emit('fail', errorMessage);
        scSocket.disconnect();
        if (isNotice) {
          self.emit('notice', errorMessage);
        } else {
          self.emit('error', new Error(errorMessage));
        }
      } else {
        scSocket.global = self.global;
        self.emit('connection', scSocket);
      }
    });

    scSocket.once('_disconnect', function () {
      delete self.clients[id];
      self.clientsCount--;
      self._ioClusterClient.unbind(scSocket, function (err) {
        if (err) {
          self.emit('error', new Error('Failed to unbind socket from io cluster - ' + err));
        } else {
          self.emit('disconnection', scSocket);
        }
      });
    });
  });
};

SCServer.prototype.close = function () {
  this.wsServer.close();
};

SCServer.prototype.getPath = function () {
  return this._path;
};

SCServer.prototype.generateId = function () {
  return base64id.generateId();
};

SCServer.prototype.on = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.once(event, listener);
  } else {
    EventEmitter.prototype.on.apply(this, arguments);
  }
};

SCServer.prototype.removeListener = function (event, listener) {
  if (event == 'ready') {
    this._ioClusterClient.removeListener(event, listener);
  } else {
    EventEmitter.prototype.removeListener.apply(this, arguments);
  }
};

SCServer.prototype.addMiddleware = function (type, middleware) {
  this._middleware[type].push(middleware);
};

SCServer.prototype.verifyHandshake = function (info, cb) {
  var self = this;

  var req = info.req;
  var origin = info.origin;
  if (origin == 'null' || origin == null) {
    origin = '*';
  }
  var ok = false;

  if (this._allowAllOrigins) {
    ok = true;
  } else {
    try {
      var parts = url.parse(origin);
      parts.port = parts.port || 80;
      ok = ~this.origins.indexOf(parts.hostname + ':' + parts.port) ||
        ~this.origins.indexOf(parts.hostname + ':*') ||
        ~this.origins.indexOf('*:' + parts.port);
    } catch (e) {}
  }

  if (ok) {
    var handshakeMiddleware = this._middleware[this.MIDDLEWARE_HANDSHAKE];
    if (handshakeMiddleware.length) {
      async.applyEachSeries(handshakeMiddleware, req, function (err) {
        if (err) {
          self.emit('notice', err);
          cb(false, 401, err);
        } else {
          cb(true);
        }
      });
    } else {
      cb(true);
    }
  } else {
    var err = 'Failed to authorize socket handshake - Invalid origin: ' + origin;
    this.emit('notice', err);
    cb(false, 403, err);
  }
};

SCServer.prototype.verifyInboundEvent = function (socket, event, data, cb) {
  var self = this;

  if (event == this.MIDDLEWARE_SUBSCRIBE) {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_SUBSCRIBE], socket, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  } else if (event == this.EVENT_PUBLISH) {
    if (this.allowClientPublish) {
      async.applyEachSeries(this._middleware[this.MIDDLEWARE_PUBLISH_IN], socket, data.channel, data.data,
        function (err) {
          if (err) {
            self.emit('notice', err);
            cb(err);
          } else {
            self.global.publish(data.channel, data.data, function (err) {
              cb(err);
            });
          }
        }
      );
    } else {
      cb(this.ERROR_NO_PUBLISH);
    }
  } else {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_EMIT], socket, event, data,
      function (err) {
        if (err) {
          self.emit('notice', err);
        }
        cb(err);
      }
    );
  }
};

SCServer.prototype.verifyOutboundEvent = function (socket, event, data, cb) {
  var self = this;

  if (event == this.EVENT_PUBLISH) {
    async.applyEachSeries(this._middleware[this.MIDDLEWARE_PUBLISH_OUT], socket, data.channel, data.data,
      function (err) {
        if (err) {
          if (err !== true) {
            self.emit('notice', err);
          }
          cb(err);
        } else {
          cb();
        }
      }
    );
  } else {
    cb();
  }
};

module.exports = SCServer;
<|endoftext|>


<commit_before>var OAuth2 = require("./oauth2")
  , util = require("util")

function Github(options) {
  var url = require('url').parse(options.url || 'https://github.com')
  var protocol = url.protocol.split(':')[0]
  var apiHost = url.host === 'github.com' ? 'api.github.com' : url.host
  var apiPath = url.host === 'github.com' ? '' : '/api/v3'

  this.code = {
    protocol: protocol,
    host: url.host,
    pathname: "/login/oauth/authorize",
    query: {
      client_id: options.id,
      redirect_uri: options.redirect_uri,
      scope: options.scope,
      state: options.state
    }
  }

  this.token = {
    method: "POST",
    host:   url.host,
    path:   "/login/oauth/access_token",
    query: {
      client_id: options.id,
      client_secret: options.secret
    }
  }

  this.user = {
    host: apiHost,
    path: apiPath + "/user",
    query: {}
  }

  this.on("request", this.onRequest.bind(this))

  OAuth2.call(this);
}

util.inherits(Github, OAuth2)

module.exports = Github
<commit_msg>Forgot to fix OAuth2 inheritance for github<commit_after>var OAuth2 = require("./oauth2")
  , util = require("util")

function Github(options) {
  var url = require('url').parse(options.url || 'https://github.com')
  var protocol = url.protocol.split(':')[0]
  var apiHost = url.host === 'github.com' ? 'api.github.com' : url.host
  var apiPath = url.host === 'github.com' ? '' : '/api/v3'

  this.code = {
    protocol: protocol,
    host: url.host,
    pathname: "/login/oauth/authorize",
    query: {
      client_id: options.id,
      redirect_uri: options.redirect_uri,
      scope: options.scope,
      state: options.state
    }
  }

  this.token = {
    method: "POST",
    host:   url.host,
    path:   "/login/oauth/access_token",
    query: {
      client_id: options.id,
      client_secret: options.secret
    }
  }

  this.user = {
    host: apiHost,
    path: apiPath + "/user",
    query: {}
  }

  this.on("request", this.onRequest.bind(this))

  OAuth2.call(this, options);
}

util.inherits(Github, OAuth2)

module.exports = Github
<|endoftext|>


<commit_before>/*
JsUnit - a JUnit port for JavaScript
Copyright (C) 1999-2001 Joerg Schaible

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation in version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Test suites built with JsUnit are derivative works derived from tested
classes and functions in their production; they are not affected by this
license.
*/

/**
 * @@file
 * Test unit classes for Windows Scripting Host environment.
 * This file contains extensions for the test unit framework especially for
 * the Windows Scriptinh Host.
 */

/**
 * @@class
 * Class for an application running test suites with the Windows Scripting Host
 * using the console.
 */
function WshTestRunner()
{
	this._super = TextTestRunner;
	this._super();

	/**
	 * @@method
     * Write a line of text to the console via the Windows Scripting Host.
     * @param str The text to print on the line.
     */
	function writeLn( str ) { WScript.Echo( str ); }

	this.writeLn = writeLn;
}
<commit_msg>typo<commit_after>/*
JsUnit - a JUnit port for JavaScript
Copyright (C) 1999-2001 Joerg Schaible

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation in version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Test suites built with JsUnit are derivative works derived from tested
classes and functions in their production; they are not affected by this
license.
*/

/**
 * @@file
 * Test unit classes for Windows Scripting Host environment.
 * This file contains extensions for the test unit framework especially for
 * the Windows Scripting Host.
 */

/**
 * @@class
 * Class for an application running test suites with the Windows Scripting Host
 * using the console.
 */
function WshTestRunner()
{
	this._super = TextTestRunner;
	this._super();

	/**
	 * @@method
     * Write a line of text to the console via the Windows Scripting Host.
     * @param str The text to print on the line.
     */
	function writeLn( str ) { WScript.Echo( str ); }

	this.writeLn = writeLn;
}
<|endoftext|>


<commit_before>var SpotifySearch = require( 'spotify-metadata-search' ),
    LastfmAPI = require('lastfmapi'),
    async = require('async');

var errorHandler = function ( err, res ) {
    console.log( err );
    res.send( 500 );
};

var LastFM = new LastfmAPI({
    api_key : process.env.LAST_FM_KEY,
    secret : process.env.LAST_FM_SECRET
});

exports.byArtistURI = function ( req, res ) {

    var uri = req.query.uri;

    var search = SpotifySearch();
    search.lookup( uri, [ "albumdetail" ], function ( err, data ) {
        if ( err ) {
            return errorHandler( err, res );
        }
        // start building the output object
        var output = {
            name: data.artist.name,
            href: data.artist.href,
            albums: data.artist.albums
        };
        // Get more interesting data from other services
        var tasks = {
            lastFmArtist: function ( callback ) {
                var params = {
                    artist: data.artist.name
                };
                LastFM.artist.getInfo( params, function ( err, artist ) {
                    if ( err ) {
                        return callback( err );
                    }
                    callback( null, artist );
                } );
            }
        };
        async.parallel( tasks, function ( err, results ) {
            output.image = results.lastFmArtist.image[2]['#text'];
            if ( err ) {
                return errorHandler( err, res );
            }
            return res.json( output );
        } );

    } );

};

exports.byURI = function ( req, res ) {

    var uri = req.query.uri;
    var extras = req.query.extras;

    if ( extras ) {
        extras = extras.split( "," );
    }

    var search = SpotifySearch();
    search.lookup( uri, extras, function ( err, data ) {
        if ( err ) {
            return errorHandler( err, res );
        }
        // start building the output object
        var output = {
            artist: {
                name: data.artist.name,
                href: data.artist.href
            }
        };

        // Get more interesting data from other services
        var tasks = {
            lastFmArtist: function ( callback ) {
                var params = {
                    artist: data.artist.name
                };
                LastFM.artist.getInfo( params, function ( err, artist ) {
                    if ( err ) {
                        return callback( err );
                    }
                    callback( null, artist );
                } );
            }
        };
        async.parallel( tasks, function ( err, results ) {
            output.artist.image = results.lastFmArtist.image[2]['#text'];
            if ( err ) {
                return errorHandler( err, res );
            }
            return res.json( output );
        } );

    } );

};
<commit_msg>Get biggest artist image<commit_after>var SpotifySearch = require( 'spotify-metadata-search' ),
    LastfmAPI = require('lastfmapi'),
    async = require('async');

var errorHandler = function ( err, res ) {
    console.log( err );
    res.send( 500 );
};

var LastFM = new LastfmAPI({
    api_key : process.env.LAST_FM_KEY,
    secret : process.env.LAST_FM_SECRET
});

exports.byArtistURI = function ( req, res ) {

    var uri = req.query.uri;

    var search = SpotifySearch();
    search.lookup( uri, [ "albumdetail" ], function ( err, data ) {
        if ( err ) {
            return errorHandler( err, res );
        }
        // start building the output object
        var output = {
            name: data.artist.name,
            href: data.artist.href,
            albums: data.artist.albums
        };
        // Get more interesting data from other services
        var tasks = {
            lastFmArtist: function ( callback ) {
                var params = {
                    artist: data.artist.name
                };
                LastFM.artist.getInfo( params, function ( err, artist ) {
                    if ( err ) {
                        return callback( err );
                    }
                    callback( null, artist );
                } );
            }
        };
        async.parallel( tasks, function ( err, results ) {
            var biggestImage = results.lastFmArtist.image.pop();
            output.image = biggestImage['#text'];
            if ( err ) {
                return errorHandler( err, res );
            }
            return res.json( output );
        } );

    } );

};

exports.byURI = function ( req, res ) {

    var uri = req.query.uri;
    var extras = req.query.extras;

    if ( extras ) {
        extras = extras.split( "," );
    }

    var search = SpotifySearch();
    search.lookup( uri, extras, function ( err, data ) {
        if ( err ) {
            return errorHandler( err, res );
        }
        // start building the output object
        var output = {
            artist: {
                name: data.artist.name,
                href: data.artist.href
            }
        };

        // Get more interesting data from other services
        var tasks = {
            lastFmArtist: function ( callback ) {
                var params = {
                    artist: data.artist.name
                };
                LastFM.artist.getInfo( params, function ( err, artist ) {
                    if ( err ) {
                        return callback( err );
                    }
                    callback( null, artist );
                } );
            }
        };
        async.parallel( tasks, function ( err, results ) {
            output.artist.image = results.lastFmArtist.image[2]['#text'];
            if ( err ) {
                return errorHandler( err, res );
            }
            return res.json( output );
        } );

    } );

};
<|endoftext|>


<commit_before>import { reduce, camelCase, isArray } from "lodash"

const validators = []
const validatorsMap = {}

class GlobalValidator {
  isValid(module = null)
  {
    if (module)
      return validatorsMap[module].isValid()

    return reduce(
      validators.map((validator) => validator.isValid()),
      (all, self) =>
      {
        if (all === true && self === true)
          return true

        if (all !== true && self === true)
          return all

        if (all === true && self !== true)
          return self

        return all.concat(self)
      }
    )
  }
}

const validator = new GlobalValidator()

function computedValidation(context, id, rulesLength)
{
  return function()
  {
    let allResults = null
    for (let index = 0; index < rulesLength; index++)
    {
      const curResult = context[`${id}${index}`]

      if (curResult && curResult.valid === false)
        if (isArray(allResults))
          allResults = allResults.concat(curResult)
        else
          allResults = [ curResult ]
    }

    return allResults
  }
}

function callValidatorFunction(context, validatorFunction, state)
{
  return function()
  {
    return validatorFunction.call(context, state)
  }
}

function install(Vue, { validators: _validators } = { validators: [] })
{
  /* eslint no-invalid-this: 0, no-console:0 */
  if (_validators.length === 0)
    console.warn("[Vuex Validator] No validators found. Maybe you want to do Vue.use(validator, { validators: [myValidator] })")

  _validators.forEach((item) =>
  {
    validators.push(item)
    if (item.module)
      validatorsMap[item.module] = item
  })
  Vue.prototype.$validator = validator

  function validatorInit()
  {
    if (!this.$store)
      throw Error("[Vuex Validator] Vuex store not injected. Please execute Vue.use(store) before executing Vue.use(validator)")

    if (!this.$store.$validator)
    {
      this.$store.$validator = validator
      validators.forEach((item) => item.injectStore(this.$store))
    }

    const options = this.$options
    const getters = options.computed = options.computed || {}
    const state = this.$store.state
    const self = this

    validators.forEach((item) =>
    {
      item.getProperties().forEach((prop) =>
      {
        const id = `\$invalid\$${camelCase(prop)}`
        const rules = item.getRulesByProperty(prop)
        const rulesLength = rules.length
        const ruleContext = item.getRuleContext()

        if (rulesLength > 0)
        {
          // TODO: Cache generated getters like Vuex do
          rules.forEach((rule, index) =>
          {
            getters[`${id}${index}`] = callValidatorFunction(ruleContext, rule.validatorFunction, state)
          })
          getters[id] = computedValidation(self, id, rulesLength)
        }
      })
    })
  }

  const _init = Vue.prototype._init
  Vue.prototype._init = function(options = {})
  {
    options.init = options.init ?
      [ validatorInit ].concat(options.init) :
      [ validatorInit ]
    _init.call(this, options)
  }

  // option merging (found in vuex)
  const merge = Vue.config.optionMergeStrategies.computed
  Vue.config.optionMergeStrategies.vuexValidator = (toVal, fromVal) =>
  {
    if (!toVal) return fromVal
    if (!fromVal) return toVal
    return {
      getters: merge(toVal.getters, fromVal.getters)
    }
  }
}

export default {
  install
}
<commit_msg>Add computed module validation<commit_after>import { reduce, camelCase, isArray } from "lodash"

const validators = []
const validatorsMap = {}

class GlobalValidator {
  isValid(module = null)
  {
    if (module)
      return validatorsMap[module].isValid()

    return reduce(
      validators.map((validator) => validator.isValid()),
      (all, self) =>
      {
        if (all === true && self === true)
          return true

        if (all !== true && self === true)
          return all

        if (all === true && self !== true)
          return self

        return all.concat(self)
      }
    )
  }
}

const validator = new GlobalValidator()

function computedValidation(context, id, rulesLength)
{
  return function()
  {
    let allResults = null
    for (let index = 0; index < rulesLength; index++)
    {
      const curResult = context[`${id}${index}`]

      if (curResult && curResult.valid === false)
        if (isArray(allResults))
          allResults = allResults.concat(curResult)
        else
          allResults = [ curResult ]
    }

    return allResults
  }
}

function callValidatorFunction(context, validatorFunction, state)
{
  return function()
  {
    return validatorFunction.call(context, state)
  }
}

function computedModuleValidation(context, module)
{
  return function()
  {
    let isValid = validator.isValid(module)

    if (isValid === true)
      return null

    return isValid
  }
}

function install(Vue, { validators: _validators } = { validators: [] })
{
  /* eslint no-invalid-this: 0, no-console:0 */
  if (_validators.length === 0)
    console.warn("[Vuex Validator] No validators found. Maybe you want to do Vue.use(validator, { validators: [myValidator] })")

  _validators.forEach((item) =>
  {
    validators.push(item)
    if (item.module)
      validatorsMap[item.module] = item
  })
  Vue.prototype.$validator = validator

  function validatorInit()
  {
    if (!this.$store)
      throw Error("[Vuex Validator] Vuex store not injected. Please execute Vue.use(store) before executing Vue.use(validator)")

    if (!this.$store.$validator)
    {
      this.$store.$validator = validator
      validators.forEach((item) => item.injectStore(this.$store))
    }

    const options = this.$options
    const getters = options.computed = options.computed || {}
    const state = this.$store.state
    const self = this

    validators.forEach((item) =>
    {
      item.getProperties().forEach((prop) =>
      {
        const id = `\$invalid\$${camelCase(prop)}`
        const rules = item.getRulesByProperty(prop)
        const rulesLength = rules.length
        const ruleContext = item.getRuleContext()

        if (rulesLength > 0)
        {
          // TODO: Cache generated getters like Vuex do
          rules.forEach((rule, index) =>
          {
            getters[`${id}${index}`] = callValidatorFunction(ruleContext, rule.validatorFunction, state)
          })
          getters[id] = computedValidation(self, id, rulesLength)
        }
      })

      if (item.module)
        getters[`\$invalid\$module\$${item.module}`] = computedModuleValidation(self, item.module)
    })
  }

  const _init = Vue.prototype._init
  Vue.prototype._init = function(options = {})
  {
    options.init = options.init ?
      [ validatorInit ].concat(options.init) :
      [ validatorInit ]
    _init.call(this, options)
  }

  // option merging (found in vuex)
  const merge = Vue.config.optionMergeStrategies.computed
  Vue.config.optionMergeStrategies.vuexValidator = (toVal, fromVal) =>
  {
    if (!toVal) return fromVal
    if (!fromVal) return toVal
    return {
      getters: merge(toVal.getters, fromVal.getters)
    }
  }
}

export default {
  install
}
<|endoftext|>


<commit_before>'use strict'

var miss = require('mississippi')
var getAge = require('get-age')
var dateFromPersonalId = require('./birthdate-from-personal-id')

var setupRecipient = miss.through(function (chunck, encoding, callback) {
  var item = JSON.parse(chunck)

  console.log(item._id + ': setup-recipient')

  item.distribution.sendCopyToParents = getAge(dateFromPersonalId(item.studentId)) < 18
  item.distribution.recipientPersonalIdNumber = item.studentId
  item.distribution.recipientName = item.studentName
  item.distribution.svarUtTitle = 'Varsel fra videregående skole'

  return callback(null, JSON.stringify(item))
})

module.exports = setupRecipient
<commit_msg>Changes name to sendCopyToGuardian<commit_after>'use strict'

var miss = require('mississippi')
var getAge = require('get-age')
var dateFromPersonalId = require('./birthdate-from-personal-id')

var setupRecipient = miss.through(function (chunck, encoding, callback) {
  var item = JSON.parse(chunck)

  console.log(item._id + ': setup-recipient')

  item.distribution.sendCopyToGuardian = getAge(dateFromPersonalId(item.studentId)) < 18
  item.distribution.recipientPersonalIdNumber = item.studentId
  item.distribution.recipientName = item.studentName
  item.distribution.svarUtTitle = 'Varsel fra videregående skole'

  return callback(null, JSON.stringify(item))
})

module.exports = setupRecipient
<|endoftext|>


<commit_before>"use strict";

var Discord = require("discord.js");
var libxmljs = require("libxmljs");
var http = require("http");
var fs = require("fs");
var config = require("./config.json");
var state = null

// called every time we poll for RSS updates (see main)
function onRssPoll(botInstance, data) {
    var doc = libxmljs.parseXml(data);
    var title = doc.get("/rss/channel/item/title").text();
    var link = doc.get("/rss/channel/item/link").text();
    if (state !== link) {
        if (config.debug) console.log("New link: %s", link);
        if (config.sendMessage === false) {
            console.log("Would have sent: %s%s - %s", config.header, title, link);
            state = link;
            return;
        }
        botInstance.sendMessage(botInstance.channels.get("name", config.channel),
                                config.header + title + " - " + link, (err) => {
                                    if (err) {
                                        console.error(err);
                                        cleanupAndQuit(botInstance, state, "Couldn't send message");
                                    } else {
                                        state = link;
                                    }
        });
    } else if (config.debug) console.log("Nothing new...");
}

// quit cleanly-- save state info, properly logout, etc
function cleanupAndQuit(botInstance, state, errorInfo) {
    if (state != null) {
        fs.writeFileSync(config.state_dir + "/state", state);
    }
    console.error("Quitting, reason: %s", errorInfo);
    botInstance.destroy((err) => {
        if (err) console.error(err);
    });
    process.exit();
}

function main() {
    var bot = new Discord.Client();

    // make sure we exit cleanly on sigint (^C)
    process.on("SIGINT", () => {
       cleanupAndQuit(bot, null, "Caught interrupt signal");
    });

    // get last known state (if any)
    try {
        if (fs.statSync(config.state_dir + "/state").isFile()) {
            state = fs.readFileSync(config.state_dir + "/state");
        }
    } catch (e) {
        if (config.debug) console.log(e);
    }

    bot.on("ready", function () {
        // make sure the channel even exists before we bother with anything else
        if (config.debug) console.log("Readying... checking channel...");
        if (bot.channels.has("name", config.channel) === false) {
            console.error("Channel #%s does not exist", config.channel);
            cleanupAndQuit(bot, null, "Channel error");
        }
        if (config.debug) console.log("Ready!");
        setInterval(() => {
            if (config.debug) console.log("Getting %s", config.feed_url);
            http.get(config.feed_url, (res) => {
                var pageData = "";
                res.setEncoding("utf8");
                res.on("data", (rssData) => {
                    pageData += rssData;
                });
                res.on("end", () => {
                    onRssPoll(bot, pageData);
                });
                res.on("error", (err) => {
                    console.error(err);
                    cleanupAndQuit(bot, state, "HTTP Error");
                });
            });
        }, config.polling_time*1000);
    });

    bot.loginWithToken(config.token);
}

if (require.main === module) {
    main();
}
<commit_msg>Added more semicolons. Third time's the charm?<commit_after>"use strict";

var Discord = require("discord.js");
var libxmljs = require("libxmljs");
var http = require("http");
var fs = require("fs");
var config = require("./config.json");
var state = null;

// called every time we poll for RSS updates (see main)
function onRssPoll(botInstance, data) {
    var doc = libxmljs.parseXml(data);
    var title = doc.get("/rss/channel/item/title").text();
    var link = doc.get("/rss/channel/item/link").text();
    if (state !== link) {
        if (config.debug) console.log("New link: %s", link);
        if (config.sendMessage === false) {
            console.log("Would have sent: %s%s - %s", config.header, title, link);
            state = link;
            return;
        }
        botInstance.sendMessage(botInstance.channels.get("name", config.channel),
                                config.header + title + " - " + link, (err) => {
                                    if (err) {
                                        console.error(err);
                                        cleanupAndQuit(botInstance, state, "Couldn't send message");
                                    } else {
                                        state = link;
                                    }
        });
    } else if (config.debug) console.log("Nothing new...");
}

// quit cleanly-- save state info, properly logout, etc
function cleanupAndQuit(botInstance, state, errorInfo) {
    if (state !== null) {
        fs.writeFileSync(config.state_dir + "/state", state);
    }
    console.error("Quitting, reason: %s", errorInfo);
    botInstance.destroy((err) => {
        if (err) console.error(err);
    });
    process.exit();
}

function main() {
    var bot = new Discord.Client();

    // make sure we exit cleanly on sigint (^C)
    process.on("SIGINT", () => {
       cleanupAndQuit(bot, null, "Caught interrupt signal");
    });

    // get last known state (if any)
    try {
        if (fs.statSync(config.state_dir + "/state").isFile()) {
            state = fs.readFileSync(config.state_dir + "/state");
        }
    } catch (e) {
        if (config.debug) console.log(e);
    }

    bot.on("ready", function () {
        // make sure the channel even exists before we bother with anything else
        if (config.debug) console.log("Readying... checking channel...");
        if (bot.channels.has("name", config.channel) === false) {
            console.error("Channel #%s does not exist", config.channel);
            cleanupAndQuit(bot, null, "Channel error");
        }
        if (config.debug) console.log("Ready!");
        setInterval(() => {
            if (config.debug) console.log("Getting %s", config.feed_url);
            http.get(config.feed_url, (res) => {
                var pageData = "";
                res.setEncoding("utf8");
                res.on("data", (rssData) => {
                    pageData += rssData;
                });
                res.on("end", () => {
                    onRssPoll(bot, pageData);
                });
                res.on("error", (err) => {
                    console.error(err);
                    cleanupAndQuit(bot, state, "HTTP Error");
                });
            });
        }, config.polling_time*1000);
    });

    bot.loginWithToken(config.token);
}

if (require.main === module) {
    main();
}
<|endoftext|>


<commit_before><commit_msg>updated maps.js<commit_after><|endoftext|>