<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import omit from 'lodash/omit';
import { toastr } from 'react-redux-toastr';

// Redux
import { connect } from 'react-redux';

// Service
import DatasetsService from 'services/DatasetsService';

import { STATE_DEFAULT, FORM_ELEMENTS } from 'components/datasets/form/constants';

import Navigation from 'components/form/Navigation';
import Step1 from 'components/datasets/form/steps/Step1';
import Spinner from 'components/ui/Spinner';

// Utils
import { logEvent } from 'utils/analytics';

class DatasetsForm extends React.Component {
  constructor(props) {
    super(props);

    this.state = Object.assign({}, STATE_DEFAULT, {
      loading: !!props.dataset,
      loadingColumns: !!props.dataset,
      columns: [],
      form: Object.assign({}, STATE_DEFAULT.form, {
        application: props.application,
        authorization: props.authorization
      })
    });

    this.service = new DatasetsService({
      authorization: props.authorization,
      language: props.locale
    });

    // BINDINGS
    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
    this.onStepChange = this.onStepChange.bind(this);
  }

  componentDidMount() {
    // Get the dataset and fill the
    // state with its params if it exists
    if (this.props.dataset) {
      this.service.fetchData({ id: this.props.dataset })
        .then((data) => {
          const { provider, type, tableName } = data || {};
          this.setState({
            form: this.setFormFromParams(data),
            // Stop the loading
            loading: false,
            loadingColumns: true
          });

          if (provider !== 'wms') {
            // fetchs column fields based on dataset type
            this.service.fetchFields({
              id: this.props.dataset,
              type,
              provider,
              tableName
            })
              .then((columns) => {
                this.setState({
                  columns,
                  loadingColumns: false
                });
              })
              .catch((err) => {
                this.setState({ loadingColumns: false });
              });
          } else {
            this.setState({ loadingColumns: false });
          }
        })
        .catch((err) => {
          this.setState({ loading: false });
          toastr.error('Error', err);
        });
    }
  }

  /**
   * UI EVENTS
   * - onSubmit
   * - onChange
  */
  onSubmit(event) {
    event.preventDefault();

    // Validate the form
    FORM_ELEMENTS.validate(this.state.step);

    // Set a timeout due to the setState function of react
    setTimeout(() => {
      // Validate all the inputs on the current step
      const valid = FORM_ELEMENTS.isValid(this.state.step);

      if (valid) {
        // if we are in the last step we will submit the form
        if (this.state.step === this.state.stepLength && !this.state.submitting) {
          const dataset = this.props.dataset;

          logEvent('My RW', 'Add New Dataset', this.state.name);

          // Start the submitting
          this.setState({ submitting: true });

          // Set the request
          const requestOptions = {
            type: (dataset) ? 'PATCH' : 'POST',
            omit: (dataset) ? ['connectorUrlHint', 'authorization', 'connectorType', 'provider'] : ['connectorUrlHint', 'authorization']
          };

          const bodyObj = omit(this.state.form, requestOptions.omit);
          const newSubscribable = {};
          bodyObj.subscribable.forEach( elem => newSubscribable[elem.type] = elem.value);
          bodyObj.subscribable = newSubscribable;

          if (Object.keys(bodyObj.subscribable).length === 0) {
            delete bodyObj.subscribable;
          }

          // Save the data
          this.service.saveData({
            type: requestOptions.type,
            id: dataset,
            body: bodyObj
          })
            .then((data) => {
              toastr.success('Success', `The dataset "${data.id}" - "${data.name}" has been uploaded correctly`);
              if (this.props.onSubmit) {
                this.props.onSubmit();
              }
            })
            .catch((err) => {
              this.setState({ submitting: false });
              try {
                if (err && !!err.length) {
                  err.forEach((e) => {
                    toastr.error('Error', e.detail);
                  });
                } else {
                  toastr.error('Error', 'Oops! There was an error, try again');
                }
              } catch (e) {
                toastr.error('Error', 'Oops! There was an error, try again');
              }
            });
        } else {
          this.setState({
            step: this.state.step + 1
          });
        }
      } else {
        toastr.error('Error', 'Fill all the required fields or correct the invalid values');
      }
    }, 0);
  }

  onChange(obj) {
    const form = Object.assign({}, this.state.form, obj);
    this.setState({ form });
  }

  onStepChange(step) {
    this.setState({ step });
  }

  // HELPERS
  setFormFromParams(params) {
    const form = Object.keys(this.state.form);
    const newForm = {};

    form.forEach((f) => {
      if (params[f] || this.state.form[f]) {
        if (f === 'subscribable') {
          const subscribable = params[f] || this.state.form[f];
          newForm.subscribable = Object.keys(subscribable).map((prop, i) => ({ key: prop, value: subscribable[prop], id: i }));
        } else {
          newForm[f] = params[f] || this.state.form[f];
        }
      }
    });
    return newForm;
  }

  render() {
    return (
      <form className="c-form c-datasets-form" onSubmit={this.onSubmit} noValidate>
        <Spinner isLoading={this.state.loading} className="-light" />

        {(this.state.step === 1 && !this.state.loading) &&
          <Step1
            onChange={value => this.onChange(value)}
            basic={this.props.basic}
            form={this.state.form}
            dataset={this.props.dataset}
            columns={this.state.columns}
            loadingColumns={this.state.loadingColumns}
          />
        }

        {!this.state.loading &&
          <Navigation
            step={this.state.step}
            stepLength={this.state.stepLength}
            submitting={this.state.submitting}
            onStepChange={this.onStepChange}
          />
        }
      </form>
    );
  }
}

DatasetsForm.propTypes = {
  application: PropTypes.array,
  authorization: PropTypes.string,
  dataset: PropTypes.string,
  basic: PropTypes.bool,
  onSubmit: PropTypes.func,
  locale: PropTypes.string.isRequired
};

const mapStateToProps = state => ({
  locale: state.common.locale
});

export default connect(mapStateToProps, null)(DatasetsForm);
<commit_msg>Allow to send subscribable as an empty object to delete previous values<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import omit from 'lodash/omit';
import { toastr } from 'react-redux-toastr';

// Redux
import { connect } from 'react-redux';

// Service
import DatasetsService from 'services/DatasetsService';

import { STATE_DEFAULT, FORM_ELEMENTS } from 'components/datasets/form/constants';

import Navigation from 'components/form/Navigation';
import Step1 from 'components/datasets/form/steps/Step1';
import Spinner from 'components/ui/Spinner';

// Utils
import { logEvent } from 'utils/analytics';

class DatasetsForm extends React.Component {
  constructor(props) {
    super(props);

    this.state = Object.assign({}, STATE_DEFAULT, {
      loading: !!props.dataset,
      loadingColumns: !!props.dataset,
      columns: [],
      form: Object.assign({}, STATE_DEFAULT.form, {
        application: props.application,
        authorization: props.authorization
      })
    });

    this.service = new DatasetsService({
      authorization: props.authorization,
      language: props.locale
    });

    // BINDINGS
    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
    this.onStepChange = this.onStepChange.bind(this);
  }

  componentDidMount() {
    // Get the dataset and fill the
    // state with its params if it exists
    if (this.props.dataset) {
      this.service.fetchData({ id: this.props.dataset })
        .then((data) => {
          const { provider, type, tableName } = data || {};
          this.setState({
            form: this.setFormFromParams(data),
            // Stop the loading
            loading: false,
            loadingColumns: true
          });

          if (provider !== 'wms') {
            // fetchs column fields based on dataset type
            this.service.fetchFields({
              id: this.props.dataset,
              type,
              provider,
              tableName
            })
              .then((columns) => {
                this.setState({
                  columns,
                  loadingColumns: false
                });
              })
              .catch((err) => {
                this.setState({ loadingColumns: false });
              });
          } else {
            this.setState({ loadingColumns: false });
          }
        })
        .catch((err) => {
          this.setState({ loading: false });
          toastr.error('Error', err);
        });
    }
  }

  /**
   * UI EVENTS
   * - onSubmit
   * - onChange
  */
  onSubmit(event) {
    event.preventDefault();

    // Validate the form
    FORM_ELEMENTS.validate(this.state.step);

    // Set a timeout due to the setState function of react
    setTimeout(() => {
      // Validate all the inputs on the current step
      const valid = FORM_ELEMENTS.isValid(this.state.step);

      if (valid) {
        // if we are in the last step we will submit the form
        if (this.state.step === this.state.stepLength && !this.state.submitting) {
          const dataset = this.props.dataset;

          logEvent('My RW', 'Add New Dataset', this.state.name);

          // Start the submitting
          this.setState({ submitting: true });

          // Set the request
          const requestOptions = {
            type: (dataset) ? 'PATCH' : 'POST',
            omit: (dataset) ? ['connectorUrlHint', 'authorization', 'connectorType', 'provider'] : ['connectorUrlHint', 'authorization']
          };

          const bodyObj = omit(this.state.form, requestOptions.omit);
          const newSubscribable = {};
          bodyObj.subscribable.forEach( elem => newSubscribable[elem.type] = elem.value);
          bodyObj.subscribable = newSubscribable;

          // Save the data
          this.service.saveData({
            type: requestOptions.type,
            id: dataset,
            body: bodyObj
          })
            .then((data) => {
              toastr.success('Success', `The dataset "${data.id}" - "${data.name}" has been uploaded correctly`);
              if (this.props.onSubmit) {
                this.props.onSubmit();
              }
            })
            .catch((err) => {
              this.setState({ submitting: false });
              try {
                if (err && !!err.length) {
                  err.forEach((e) => {
                    toastr.error('Error', e.detail);
                  });
                } else {
                  toastr.error('Error', 'Oops! There was an error, try again');
                }
              } catch (e) {
                toastr.error('Error', 'Oops! There was an error, try again');
              }
            });
        } else {
          this.setState({
            step: this.state.step + 1
          });
        }
      } else {
        toastr.error('Error', 'Fill all the required fields or correct the invalid values');
      }
    }, 0);
  }

  onChange(obj) {
    const form = Object.assign({}, this.state.form, obj);
    this.setState({ form });
  }

  onStepChange(step) {
    this.setState({ step });
  }

  // HELPERS
  setFormFromParams(params) {
    const form = Object.keys(this.state.form);
    const newForm = {};

    form.forEach((f) => {
      if (params[f] || this.state.form[f]) {
        if (f === 'subscribable') {
          const subscribable = params[f] || this.state.form[f];
          newForm.subscribable = Object.keys(subscribable).map((prop, i) => ({ key: prop, value: subscribable[prop], id: i }));
        } else {
          newForm[f] = params[f] || this.state.form[f];
        }
      }
    });
    return newForm;
  }

  render() {
    return (
      <form className="c-form c-datasets-form" onSubmit={this.onSubmit} noValidate>
        <Spinner isLoading={this.state.loading} className="-light" />

        {(this.state.step === 1 && !this.state.loading) &&
          <Step1
            onChange={value => this.onChange(value)}
            basic={this.props.basic}
            form={this.state.form}
            dataset={this.props.dataset}
            columns={this.state.columns}
            loadingColumns={this.state.loadingColumns}
          />
        }

        {!this.state.loading &&
          <Navigation
            step={this.state.step}
            stepLength={this.state.stepLength}
            submitting={this.state.submitting}
            onStepChange={this.onStepChange}
          />
        }
      </form>
    );
  }
}

DatasetsForm.propTypes = {
  application: PropTypes.array,
  authorization: PropTypes.string,
  dataset: PropTypes.string,
  basic: PropTypes.bool,
  onSubmit: PropTypes.func,
  locale: PropTypes.string.isRequired
};

const mapStateToProps = state => ({
  locale: state.common.locale
});

export default connect(mapStateToProps, null)(DatasetsForm);
<|endoftext|>


<commit_before>/**
 * @license RequireJS css 0.0.1 Copyright (c) 2011, VIISON All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/viison/requirejs-css for details
 */
(function () {

	var head = document.head || document.getElementsByTagName('head')[0],
		body = document.body || document.getElementsByTagName('body')[0],
		// Eliminate browsers that admit to not support the link load event (e.g. Firefox)
		nativeLoad = document.createElement('link').onload === null ? undefined : false;

	function createLink(url) {
		var link = document.createElement('link');

		link.rel = "stylesheet";
		link.type = "text/css";
		link.href = url;

		return link;
	}

	define(function () {
		var css;

		css = {
			version: '0.0.1',

			testLoad: function (load) {
				// Test if the browser supports the link load event,
				// in case we don't know yet (mostly WebKit)
				if (nativeLoad === undefined) {
					// Create a link element with a data url,
					// it would fire a load event immediately
					var link = createLink('data:text/css,'),
						self = this;

					link.onload = function () {
						// Native link load event works
						nativeLoad = true;
					};

					head.appendChild(link);

					// Schedule function in event loop, this will
					// execute after a potential execution of the link onload
					setTimeout(function () {
						head.removeChild(link);

						if (nativeLoad !== true) {
							// Native link load event is broken
							nativeLoad = false;
						}

						self.loadSwitch(load);
					}, 0);
				} else {
					this.loadSwitch(load);
				}
			},

			loadSwitch: function (load) {
				if (nativeLoad) {
					load(this.loadLink);
				} else {
					load(this.loadImage);
				}
			},

			/**
			 * Load using the browsers built-in load event on link tags
			 */
			loadLink: function (url, load) {
				var link = createLink(url);

				link.onload = function () {
					load();
				};

				head.appendChild(link);
			},

			/**
			 * Insert an image tag and use it's onerror to know when the CSS
			 * is loaded, this will unfortunately also fire on other errors
			 * (file not found, network down)
			 */
			loadImage: function (url, load) {
				var link = createLink(url),
					img = document.createElement('img');

				head.appendChild(link);

				img.onerror = function (error) {
					load();

					body.removeChild(img);
				};
				img.src = url;
				img.style.display = 'none';

				body.appendChild(img);
			},

			load: function (name, req, load, config) {
				var url = name,
					self = this;

				// Append default extension
				if (url.search(/.(css|less|scss|sass)$/i) == -1)
					url += '.css';

				this.testLoad(function (callback) {
					callback.call(self, require.toUrl(url), load);
				});
			}
		};

		return css;
	});
}());<commit_msg>Refactor handling of internal plugin calls<commit_after>/**
 * @license RequireJS css 0.0.1 Copyright (c) 2011, VIISON All Rights Reserved.
 * Available via the MIT or new BSD license.
 * see: http://github.com/viison/requirejs-css for details
 */
(function () {

	var head = document.head || document.getElementsByTagName('head')[0],
		body = document.body || document.getElementsByTagName('body')[0],
		// Eliminate browsers that admit to not support the link load event (e.g. Firefox)
		nativeLoad = document.createElement('link').onload === null ? undefined : false;

	function createLink(url) {
		var link = document.createElement('link');

		link.rel = "stylesheet";
		link.type = "text/css";
		link.href = url;

		return link;
	}

	define(function () {
		var css;

		css = {
			version: '0.0.1',

			testLoad: function (url, load) {
				// Test if the browser supports the link load event,
				// in case we don't know yet (mostly WebKit)
				if (nativeLoad === undefined) {
					// Create a link element with a data url,
					// it would fire a load event immediately
					var link = createLink('data:text/css,');

					link.onload = function () {
						// Native link load event works
						nativeLoad = true;
					};

					head.appendChild(link);

					// Schedule function in event loop, this will
					// execute after a potential execution of the link onload
					setTimeout(function () {
						head.removeChild(link);

						if (nativeLoad !== true) {
							// Native link load event is broken
							nativeLoad = false;
						}

						css.loadSwitch(url, load);
					}, 0);
				} else {
					css.loadSwitch(url, load);
				}
			},

			loadSwitch: function (url, load) {
				if (nativeLoad) {
					css.loadLink(url, load);
				} else {
					css.loadImage(url, load);
				}
			},

			/**
			 * Load using the browsers built-in load event on link tags
			 */
			loadLink: function (url, load) {
				var link = createLink(url);

				link.onload = function () {
					load();
				};

				head.appendChild(link);
			},

			/**
			 * Insert an image tag and use it's onerror to know when the CSS
			 * is loaded, this will unfortunately also fire on other errors
			 * (file not found, network down)
			 */
			loadImage: function (url, load) {
				var link = createLink(url),
					img = document.createElement('img');

				head.appendChild(link);

				img.onerror = function (error) {
					load();

					body.removeChild(img);
				};
				img.src = url;
				img.style.display = 'none';

				body.appendChild(img);
			},

			load: function (name, req, load, config) {
				var url = name;

				// Append default extension
				if (url.search(/.(css|less|scss|sass)$/i) == -1)
					url += '.css';

				css.testLoad(require.toUrl(url), load);
			}
		};

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


<commit_before>/*
 * Require-CSS RequireJS css! loader plugin
 * 0.1.8
 * Guy Bedford 2014
 * MIT
 */

/*
 *
 * Usage:
 *  require(['css!./mycssFile']);
 *
 * Tested and working in (up to latest versions as of March 2013):
 * Android
 * iOS 6
 * IE 6 - 10
 * Chome 3 - 26
 * Firefox 3.5 - 19
 * Opera 10 - 12
 *
 * browserling.com used for virtual testing environment
 *
 * Credit to B Cavalier & J Hann for the IE 6 - 9 method,
 * refined with help from Martin Cermak
 *
 * Sources that helped along the way:
 * - https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
 * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/
 * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
 *
 */

define(function() {
//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  if (typeof window == 'undefined')
    return { load: function(n, r, load){ load() } };

  var head = document.getElementsByTagName('head')[0];

  var engine = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)|AndroidWebKit\/([^ ;]*)/) || 0;

  // use <style> @import load method (IE < 9, Firefox < 18)
  var useImportLoad = false;

  // set to false for explicit <link> load checking when onload doesn't work perfectly (webkit)
  var useOnload = true;

  // trident / msie
  if (engine[1] || engine[7])
    useImportLoad = parseInt(engine[1]) < 6 || parseInt(engine[7]) <= 9;
  // webkit
  else if (engine[2] || engine[8])
    useOnload = false;
  // gecko
  else if (engine[4])
    useImportLoad = parseInt(engine[4]) < 18;

//>>excludeEnd('excludeRequireCss')
  //main api object
  var cssAPI = {};

//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  cssAPI.pluginBuilder = './css-builder';

  // <style> @import load method
  var curStyle, curSheet;
  var createStyle = function () {
    curStyle = document.createElement('style');
    head.appendChild(curStyle);
    curSheet = curStyle.styleSheet || curStyle.sheet;
  }
  var ieCnt = 0;
  var ieLoads = [];
  var ieCurCallback;

  var createIeLoad = function(url) {
    curSheet.addImport(url);
    curStyle.onload = function(){ processIeLoad() };

    ieCnt++;
    if (ieCnt == 31) {
      createStyle();
      ieCnt = 0;
    }
  }
  var processIeLoad = function() {
    ieCurCallback();

    var nextLoad = ieLoads.shift();

    if (!nextLoad) {
      ieCurCallback = null;
      return;
    }

    ieCurCallback = nextLoad[1];
    createIeLoad(nextLoad[0]);
  }
  var importLoad = function(url, callback) {
    if (!curSheet || !curSheet.addImport)
      createStyle();

    if (curSheet && curSheet.addImport) {
      // old IE
      if (ieCurCallback) {
        ieLoads.push([url, callback]);
      }
      else {
        createIeLoad(url);
        ieCurCallback = callback;
      }
    }
    else {
      // old Firefox
      curStyle.textContent = '@import "' + url + '";';

      var loadInterval = setInterval(function() {
        try {
          curStyle.sheet.cssRules;
          clearInterval(loadInterval);
          callback();
        } catch(e) {}
      }, 10);
    }
  }

  // <link> load method
  var linkLoad = function(url, callback) {
    var link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    if (useOnload)
      link.onload = function() {
        link.onload = function() {};
        // for style dimensions queries, a short delay can still be necessary
        setTimeout(callback, 7);
      }
    else
      var loadInterval = setInterval(function() {
        for (var i = 0; i < document.styleSheets.length; i++) {
          var sheet = document.styleSheets[i];
          if (sheet.href == link.href) {
            clearInterval(loadInterval);
            return callback();
          }
        }
      }, 10);
    link.href = url;
    head.appendChild(link);
  }

//>>excludeEnd('excludeRequireCss')
  cssAPI.normalize = function(name, normalize) {
    if (name.substr(name.length - 4, 4) == '.css')
      name = name.substr(0, name.length - 4);

    return normalize(name);
  }

//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  cssAPI.load = function(cssId, req, load, config) {

    (useImportLoad ? importLoad : linkLoad)(req.toUrl(cssId + '.css'), load);

  }

//>>excludeEnd('excludeRequireCss')
  return cssAPI;
});
<commit_msg>Small change in comment section<commit_after>/*
 * Require-CSS RequireJS css! loader plugin
 * 0.1.8
 * Guy Bedford 2014
 * MIT
 */

/*
 *
 * Usage:
 *  require(['css!./mycssFile']);
 *
 * Tested and working in (up to latest versions as of March 2013):
 * Android
 * iOS 6
 * IE 6 - 10
 * Chrome 3 - 26
 * Firefox 3.5 - 19
 * Opera 10 - 12
 *
 * browserling.com used for virtual testing environment
 *
 * Credit to B Cavalier & J Hann for the IE 6 - 9 method,
 * refined with help from Martin Cermak
 *
 * Sources that helped along the way:
 * - https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
 * - http://www.phpied.com/when-is-a-stylesheet-really-loaded/
 * - https://github.com/cujojs/curl/blob/master/src/curl/plugin/css.js
 *
 */

define(function() {
//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  if (typeof window == 'undefined')
    return { load: function(n, r, load){ load() } };

  var head = document.getElementsByTagName('head')[0];

  var engine = window.navigator.userAgent.match(/Trident\/([^ ;]*)|AppleWebKit\/([^ ;]*)|Opera\/([^ ;]*)|rv\:([^ ;]*)(.*?)Gecko\/([^ ;]*)|MSIE\s([^ ;]*)|AndroidWebKit\/([^ ;]*)/) || 0;

  // use <style> @import load method (IE < 9, Firefox < 18)
  var useImportLoad = false;

  // set to false for explicit <link> load checking when onload doesn't work perfectly (webkit)
  var useOnload = true;

  // trident / msie
  if (engine[1] || engine[7])
    useImportLoad = parseInt(engine[1]) < 6 || parseInt(engine[7]) <= 9;
  // webkit
  else if (engine[2] || engine[8])
    useOnload = false;
  // gecko
  else if (engine[4])
    useImportLoad = parseInt(engine[4]) < 18;

//>>excludeEnd('excludeRequireCss')
  //main api object
  var cssAPI = {};

//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  cssAPI.pluginBuilder = './css-builder';

  // <style> @import load method
  var curStyle, curSheet;
  var createStyle = function () {
    curStyle = document.createElement('style');
    head.appendChild(curStyle);
    curSheet = curStyle.styleSheet || curStyle.sheet;
  }
  var ieCnt = 0;
  var ieLoads = [];
  var ieCurCallback;

  var createIeLoad = function(url) {
    curSheet.addImport(url);
    curStyle.onload = function(){ processIeLoad() };

    ieCnt++;
    if (ieCnt == 31) {
      createStyle();
      ieCnt = 0;
    }
  }
  var processIeLoad = function() {
    ieCurCallback();

    var nextLoad = ieLoads.shift();

    if (!nextLoad) {
      ieCurCallback = null;
      return;
    }

    ieCurCallback = nextLoad[1];
    createIeLoad(nextLoad[0]);
  }
  var importLoad = function(url, callback) {
    if (!curSheet || !curSheet.addImport)
      createStyle();

    if (curSheet && curSheet.addImport) {
      // old IE
      if (ieCurCallback) {
        ieLoads.push([url, callback]);
      }
      else {
        createIeLoad(url);
        ieCurCallback = callback;
      }
    }
    else {
      // old Firefox
      curStyle.textContent = '@import "' + url + '";';

      var loadInterval = setInterval(function() {
        try {
          curStyle.sheet.cssRules;
          clearInterval(loadInterval);
          callback();
        } catch(e) {}
      }, 10);
    }
  }

  // <link> load method
  var linkLoad = function(url, callback) {
    var link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    if (useOnload)
      link.onload = function() {
        link.onload = function() {};
        // for style dimensions queries, a short delay can still be necessary
        setTimeout(callback, 7);
      }
    else
      var loadInterval = setInterval(function() {
        for (var i = 0; i < document.styleSheets.length; i++) {
          var sheet = document.styleSheets[i];
          if (sheet.href == link.href) {
            clearInterval(loadInterval);
            return callback();
          }
        }
      }, 10);
    link.href = url;
    head.appendChild(link);
  }

//>>excludeEnd('excludeRequireCss')
  cssAPI.normalize = function(name, normalize) {
    if (name.substr(name.length - 4, 4) == '.css')
      name = name.substr(0, name.length - 4);

    return normalize(name);
  }

//>>excludeStart('excludeRequireCss', pragmas.excludeRequireCss)
  cssAPI.load = function(cssId, req, load, config) {

    (useImportLoad ? importLoad : linkLoad)(req.toUrl(cssId + '.css'), load);

  }

//>>excludeEnd('excludeRequireCss')
  return cssAPI;
});
<|endoftext|>


<commit_before>// @flow

import type { RunTimeState, Devices } from '../../types/fermenter';

import * as React from 'react';
import { connect } from 'react-redux';

import { withStyles } from 'material-ui/styles';
import Button from 'material-ui/Button';
import Card, { CardActions, CardContent } from 'material-ui/Card';
import Divider from 'material-ui/Divider';
import Grid from 'material-ui/Grid';
import StartIcon from 'material-ui-icons/PlayArrow';
import StopIcon from 'material-ui-icons/Stop';
import FermenterIndicator from './FermenterIndicator';
import FermenterDevice from './FermenterDevice';
import FermenterTempRangeControl from './FermenterTempRangeControl';

import { compose, mapObjIndexed, values } from 'ramda';

type Props = {
  rts: RunTimeState,
  devices: Devices,
  classes: Object,
  sendFermenterCmd: Function,
  sendFermenterTempLimits: Function,
};

const fermenterControlStyles = {
  controlsContainer: {
    flexGrow: 1,
    //     flexDirection: 'column',
  },
  controlItem: {
  },
  fermenterDetails: {
    display: 'flex',
    flexDirection: 'column',
    textAlign: 'center',
  },
  fermenterIcon: {
    display: 'block',
    margin: 'auto',
  },
  fermenterCard: {
    display: 'flex',
  },
  devControls: {
    display: 'flex',
    alignItems: 'center',
    padding: 20,
    flexDirection: 'column',
    height: 'auto',
  },
  tempRangeControl: {
    marginTop: 10,
  },
};

const FermenterControl = ({
  rts,
  devices,
  classes,
  sendFermenterCmd,
  sendFermenterTempLimits,
}: Props) => {
  const fermenterIsRunning = () => rts.active;

  const toggleDevice = name => {
    /* Only allow switching fermenter itself on/off for now */
    if (name !== 'fermenter') {
      return false;
    }
    return fermenterIsRunning()
      ? sendFermenterCmd('stop')
      : sendFermenterCmd('start');
  };

  return (
    <Grid container spacing={24} className={classes.controlsContainer}>
      <Grid item xs={12} sm={6} className={classes.controlItem}>
        <Card className={classes.fermenterCard}>

            <CardContent className={classes.fermenterIcon}>
              <FermenterIndicator isOn={fermenterIsRunning()} />
            </CardContent>
            <CardActions className={classes.devControls}>
              <Button
                color="default"
                raised
                onClick={() => toggleDevice('fermenter')}
              >
                {fermenterIsRunning() ? <StopIcon /> : <StartIcon />}
              </Button>

              <Divider className={classes.tempRangeControl} />

              <FermenterTempRangeControl
                tempLimits={rts.tempLimits}
                changeAction={sendFermenterTempLimits}
              />
            </CardActions>

        </Card>
      </Grid>
      {compose(
        values,
        mapObjIndexed((dev, name) => (
          <Grid item xs={6} sm={3} className={classes.controlItem} key={name}>
            <FermenterDevice name={name} isOn={dev.isOn} />
          </Grid>
        ))
      )(devices)}
    </Grid>
  );
};

export default compose(
  withStyles(fermenterControlStyles),
  connect(state => ({
    devices: state.fermenter.devices,
    rts: state.fermenter.rts,
  }))
)(FermenterControl);
<commit_msg>Fix button attribute that was changed upstream<commit_after>// @flow

import type { RunTimeState, Devices } from '../../types/fermenter';

import * as React from 'react';
import { connect } from 'react-redux';

import { withStyles } from 'material-ui/styles';
import Button from 'material-ui/Button';
import Card, { CardActions, CardContent } from 'material-ui/Card';
import Divider from 'material-ui/Divider';
import Grid from 'material-ui/Grid';
import StartIcon from 'material-ui-icons/PlayArrow';
import StopIcon from 'material-ui-icons/Stop';
import FermenterIndicator from './FermenterIndicator';
import FermenterDevice from './FermenterDevice';
import FermenterTempRangeControl from './FermenterTempRangeControl';

import { compose, mapObjIndexed, values } from 'ramda';

type Props = {
  rts: RunTimeState,
  devices: Devices,
  classes: Object,
  sendFermenterCmd: Function,
  sendFermenterTempLimits: Function,
};

const fermenterControlStyles = {
  controlsContainer: {
    flexGrow: 1,
    //     flexDirection: 'column',
  },
  controlItem: {
  },
  fermenterDetails: {
    display: 'flex',
    flexDirection: 'column',
    textAlign: 'center',
  },
  fermenterIcon: {
    display: 'block',
    margin: 'auto',
  },
  fermenterCard: {
    display: 'flex',
  },
  devControls: {
    display: 'flex',
    alignItems: 'center',
    padding: 20,
    flexDirection: 'column',
    height: 'auto',
  },
  tempRangeControl: {
    marginTop: 10,
  },
};

const FermenterControl = ({
  rts,
  devices,
  classes,
  sendFermenterCmd,
  sendFermenterTempLimits,
}: Props) => {
  const fermenterIsRunning = () => rts.active;

  const toggleDevice = name => {
    /* Only allow switching fermenter itself on/off for now */
    if (name !== 'fermenter') {
      return false;
    }
    return fermenterIsRunning()
      ? sendFermenterCmd('stop')
      : sendFermenterCmd('start');
  };

  return (
    <Grid container spacing={24} className={classes.controlsContainer}>
      <Grid item xs={12} sm={6} className={classes.controlItem}>
        <Card className={classes.fermenterCard}>

            <CardContent className={classes.fermenterIcon}>
              <FermenterIndicator isOn={fermenterIsRunning()} />
            </CardContent>
            <CardActions className={classes.devControls}>
              <Button
                color="default"
                variant="raised"
                onClick={() => toggleDevice('fermenter')}
              >
                {fermenterIsRunning() ? <StopIcon /> : <StartIcon />}
              </Button>

              <Divider className={classes.tempRangeControl} />

              <FermenterTempRangeControl
                tempLimits={rts.tempLimits}
                changeAction={sendFermenterTempLimits}
              />
            </CardActions>

        </Card>
      </Grid>
      {compose(
        values,
        mapObjIndexed((dev, name) => (
          <Grid item xs={6} sm={3} className={classes.controlItem} key={name}>
            <FermenterDevice name={name} isOn={dev.isOn} />
          </Grid>
        ))
      )(devices)}
    </Grid>
  );
};

export default compose(
  withStyles(fermenterControlStyles),
  connect(state => ({
    devices: state.fermenter.devices,
    rts: state.fermenter.rts,
  }))
)(FermenterControl);
<|endoftext|>


<commit_before>"use strict";

import React, {Component} from 'react';
import _ from 'lodash';
import DatePicker from './date-picker'
import TimePicker from './time-picker'

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = {
      year: this.props.year,
      month: this.props.month,
      day: this.props.day,
      hour: this.props.hour,
      minute: this.props.minute,
      name: this.props.name,
      except: this.props.except||[],
      type: "date"
    }
  }
  _onSelectDate(val) {
    this.setState( _.extend({type: "hour"}, val) )
  }
  _onSelectTime(val) {
    this.setState( _.extend({type: "date"}, val) )
    let date = new Date(this.state.year, this.state.month, this.state.day, val.hour, val.minute)
      , current = _.extend(this.state, val, {date})
    this.props.onSelect(current)
  }
  render() {
    return (

        {this.state.type === "date"
          && <DatePicker {...this.state} view="month" onSelect={this._onSelectDate.bind(this)}  />}
        {this.state.type === "hour"
          && <TimePicker {...this.state} onSelect={this._onSelectTime.bind(this)} />}

    )
  }
}
<commit_msg>remove console.log<commit_after>"use strict";

import React, {Component} from 'react';
import _ from 'lodash';
import DatePicker from './date-picker'
import TimePicker from './time-picker'

export default class extends Component {
  constructor(props) {
    super(props)
    this.state = {
      year: this.props.year,
      month: this.props.month,
      day: this.props.day,
      hour: this.props.hour,
      minute: this.props.minute,
      name: this.props.name,
      except: this.props.except||[],
      type: "date"
    }
  }
  _onSelectDate(val) {
    this.setState( _.extend({type: "hour"}, val) )
  }
  _onSelectTime(val) {
    console.log(val)
    this.setState( _.extend({type: "date"}, val) )
    let date = new Date(this.state.year, this.state.month, this.state.day, val.hour, val.minute)
      , current = _.extend(this.state, val, {date})
    this.props.onSelect(current)
  }
  render() {
    return (

        {this.state.type === "date"
          && <DatePicker {...this.state} view="month" onSelect={this._onSelectDate.bind(this)}  />}
        {this.state.type === "hour"
          && <TimePicker {...this.state} onSelect={this._onSelectTime.bind(this)} />}

    )
  }
}
<|endoftext|>


<commit_before>import React    from 'react';
import ReactDOM from 'react-dom';
import $        from 'jquery';

import common_formatTime from '../modules/common_format_time';
import common_getDomain  from '../modules/common_get_domain';

class SubmitContainer extends React.Component {
    constructor() {
        super();
        this.insertNewPaper = this.insertNewPaper.bind(this);
    };

    insertNewPaper(e) {
        var $paperTitle     = ReactDOM.findDOMNode(this.refs.paperTitle),
            $paperTag       = ReactDOM.findDOMNode(this.refs.paperTag),
            $paperSubtag    = ReactDOM.findDOMNode(this.refs.paperSubtag),
            $paperAbstract  = ReactDOM.findDOMNode(this.refs.paperAbstract),
            $paperPermitKey = ReactDOM.findDOMNode(this.refs.paperPermitKey);

        const paperTitle     = $paperTitle.value;
        const paperTag       = $paperTag.value;
        const paperSubtag    = $paperSubtag.value;
        const paperAbstract  = $paperAbstract.value;
        const paperPermitKey = $paperPermitKey.value;

        if (!Boolean(paperTitle) || !Boolean(paperTag) || !Boolean(paperAbstract) || !Boolean(paperPermitKey)) {
            console.info('miss something');
            return false;
        }
        /* check permit key */
        if (paperPermitKey !== '大佬的密钥') {
            console.info('wrong permit key value');
            return false;
        }

        const tmpTime     = new Date();
        const currentTime = common_formatTime(tmpTime.getFullYear() + '-' + (parseInt(tmpTime.getMonth()) + 1) + '-' + tmpTime.getDate() + ' ' + tmpTime.getHours() + ':' + tmpTime.getMinutes() + ':' + tmpTime.getSeconds(), 'full');
        const jsonData = {
                title       : paperTitle,
                tag         : paperTag,
                subtag      : paperSubtag,
                publish_data: currentTime,
                timeline    : currentTime.slice(0, 7),
                abstract    : paperAbstract,
                content     : this.props.contentList.join('')
            };

        /* submit one paper and save */
        const domain     = common_getDomain();
        const requestUrl = domain + '/addPaper.node';
        $.post(requestUrl, jsonData, function(data) {
            alert(data.status);
            if (data.status === 'success') {
                location.reload();
            }
        });
    };

    render() {
        return (

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入文章的标题"
                            ref         = "paperTitle"
                        />

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入文章的分类标签"
                            ref         = "paperTag"
                        />

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入文章的分类副标签"
                            ref         = "paperSubtag"
                        />

                        <textarea
                            className   = "form-control"
                            placeholder = "输入文章的摘要"
                            ref         = "paperAbstract"
                        ></textarea>

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入密钥代码，用于校验admin身份"
                            ref         = "paperPermitKey"
                        />

                    <button
                        type      = "button"
                        className = "btn btn-success"
                        onClick   = { (e) => this.insertNewPaper(e) }
                    >
                        提交文章
                    </button>

        );
    };
};

export default SubmitContainer;<commit_msg>tiny change<commit_after>import React    from 'react';
import ReactDOM from 'react-dom';
import $        from 'jquery';

import common_formatTime from '../modules/common_format_time';
import common_getDomain  from '../modules/common_get_domain';

class SubmitContainer extends React.Component {
    constructor() {
        super();
        this.insertNewPaper = this.insertNewPaper.bind(this);
    };

    insertNewPaper(e) {
        var $paperTitle     = ReactDOM.findDOMNode(this.refs.paperTitle),
            $paperTag       = ReactDOM.findDOMNode(this.refs.paperTag),
            $paperSubtag    = ReactDOM.findDOMNode(this.refs.paperSubtag),
            $paperAbstract  = ReactDOM.findDOMNode(this.refs.paperAbstract),
            $paperPermitKey = ReactDOM.findDOMNode(this.refs.paperPermitKey);

        const paperTitle     = $paperTitle.value;
        const paperTag       = $paperTag.value;
        const paperSubtag    = $paperSubtag.value;
        const paperAbstract  = $paperAbstract.value;
        const paperPermitKey = $paperPermitKey.value;

        if (!Boolean(paperTitle) || !Boolean(paperTag) || !Boolean(paperAbstract) || !Boolean(paperPermitKey)) {
            console.info('miss something');
            return false;
        }
        /* check permit key */
        if (paperPermitKey !== '大佬的密钥') {
            console.info('wrong permit key value');
            return false;
        }

        const tmpTime     = new Date();
        const currentTime = common_formatTime(tmpTime.getFullYear() + '-' + (parseInt(tmpTime.getMonth()) + 1) + '-' + tmpTime.getDate() + ' ' + tmpTime.getHours() + ':' + tmpTime.getMinutes() + ':' + tmpTime.getSeconds(), 'full');
        const jsonData = {
                title       : paperTitle,
                tag         : paperTag,
                subtag      : paperSubtag,
                publish_data: currentTime,
                abstract    : paperAbstract,
                content     : this.props.contentList.join('')
            };

        /* submit one paper and save */
        const domain     = common_getDomain();
        const requestUrl = domain + '/addPaper.node';
        $.post(requestUrl, jsonData, function(data) {
            alert(data.status);
            if (data.status === 'success') {
                location.reload();
            }
        });
    };

    render() {
        return (

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入文章的标题"
                            ref         = "paperTitle"
                        />

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入文章的分类标签"
                            ref         = "paperTag"
                        />

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入文章的分类副标签"
                            ref         = "paperSubtag"
                        />

                        <textarea
                            className   = "form-control"
                            placeholder = "输入文章的摘要"
                            ref         = "paperAbstract"
                        ></textarea>

                        <input
                            type        = "text"
                            className   = "form-control"
                            placeholder = "输入密钥代码，用于校验admin身份"
                            ref         = "paperPermitKey"
                        />

                    <button
                        type      = "button"
                        className = "btn btn-success"
                        onClick   = { (e) => this.insertNewPaper(e) }
                    >
                        提交文章
                    </button>

        );
    };
};

export default SubmitContainer;<|endoftext|>


<commit_before>var assert = require('assert');
var oftype = require('oftype');

function test(config) {
    var inputs = config.inputs;
    var outputs = config.outputs;
    var transform = config.transform;
    var validate = config.validate || defaultValidate;
    var groupName = config.groupName;
    var caseName = config.caseName;

    if (inputs && outputs && transform && validate) {
        if (!groupName) {
            testCase(caseName, inputs, outputs, transform, validate);
        } else {
            describe(groupName, function() {
                testCase(caseName, inputs, outputs, transform, validate);
            });
        }
    };
}

function testCase(caseName, inputs, outputs, transform, validate) {
    inputs.forEach(function(input, index) {
        var name = composeCaseName(caseName, index, inputs, outputs);
        it(name, function() {
            var result = transform(input);
            assert.ok(validate(outputs[index], result));
        });
    });
}

function composeCaseName(caseName, index, inputs, outputs) {
    if (!caseName) {
        return 'test case #' + index;
    } else if(oftype(caseName, String)) {
        return caseName;
    } else if (caseName instanceof Function) {
        return caseName(index, inputs, outputs);
    }
}

function defaultValidate(expected, actual) {
    return expected == actual;
}

exports.test = test;
<commit_msg>remove validation function check<commit_after>var assert = require('assert');
var oftype = require('oftype');

function test(config) {
    var inputs = config.inputs;
    var outputs = config.outputs;
    var transform = config.transform;
    var validate = config.validate || defaultValidate;
    var groupName = config.groupName;
    var caseName = config.caseName;

    if (inputs && outputs && transform) {
        if (!groupName) {
            testCase(caseName, inputs, outputs, transform, validate);
        } else {
            describe(groupName, function() {
                testCase(caseName, inputs, outputs, transform, validate);
            });
        }
    };
}

function testCase(caseName, inputs, outputs, transform, validate) {
    inputs.forEach(function(input, index) {
        var name = composeCaseName(caseName, index, inputs, outputs);
        it(name, function() {
            var result = transform(input);
            assert.ok(validate(outputs[index], result));
        });
    });
}

function composeCaseName(caseName, index, inputs, outputs) {
    if (!caseName) {
        return 'test case #' + index;
    } else if(oftype(caseName, String)) {
        return caseName;
    } else if (caseName instanceof Function) {
        return caseName(index, inputs, outputs);
    }
}

function defaultValidate(expected, actual) {
    return expected == actual;
}

exports.test = test;
<|endoftext|>


<commit_before>/*
 * Copyright 2011 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Externs for YouTube Player API for <iframe> Embeds.
 * @see http://code.google.com/apis/youtube/iframe_api_reference.html
 * @externs
 */

/** @return {undefined} */
var onYouTubePlayerAPIReady = function() {};

/** @return {undefined} */
window.onYouTubePlayerAPIReady = function() {};

/** @const */
var YT = {};

/**
 * @constructor
 * @param {(string|Element)} container
 * @param {Object.<string, *>} opts
 */
YT.Player = function(container, opts) {};

/**
 * @param {string} videoId
 * @param {number=} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.cueVideoById =
    function(videoId, startSeconds, suggestedQuality) {};

/**
 * @param {string} videoId
 * @param {number=} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.loadVideoById =
    function(videoId, startSeconds, suggestedQuality) {};

/**
 * @param {string} mediaContentUrl
 * @param {number} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.cueVideoByUrl =
    function(mediaContentUrl, startSeconds, suggestedQuality) {};

/**
 * @param {string} mediaContentUrl
 * @param {number} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.loadVideoByUrl =
    function(mediaContentUrl, startSeconds, suggestedQuality) {};

/**
 * @param {(String|Array.<String>)} playlist
 * @param {number=} index
 * @param {number=} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.cuePlaylist =
    function(playlist, index, startSeconds, suggestedQuality) {};

/**
 * @param {(String|Array.<String>)} playlist
 * @param {number=} index
 * @param {number=} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.loadPlaylist =
    function(playlist, index, startSeconds, suggestedQuality) {};

/** @return {undefined} */
YT.Player.prototype.playVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.pauseVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.stopVideo = function() {};

/**
 * @param {number} seconds
 * @param {boolean} allowSeekAhead
 */
YT.Player.prototype.seekTo = function(seconds, allowSeekAhead) {};

/** @return {undefined} */
YT.Player.prototype.clearVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.nextVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.previousVideo = function() {};

/** @param {number} index */
YT.Player.prototype.playVideoAt = function(index) {};

/** @return {undefined} */
YT.Player.prototype.mute = function() {};

/** @return {undefined} */
YT.Player.prototype.unMute = function() {};

/** @return {boolean} */
YT.Player.prototype.isMuted = function() {};

/** @param {number} volume */
YT.Player.prototype.setVolume = function(volume) {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVolume = function() {};

/** @param {boolean} loopPlaylists */
YT.Player.prototype.setLoop = function(loopPlaylists) {};

/** @param {boolean} shufflePlaylist */
YT.Player.prototype.setShuffle = function(shufflePlaylist) {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoBytesLoaded = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoBytesTotal = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoLoadedFraction = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoStartBytes = function() {};

/**
 * @return {YT.PlayerState|number}
 * @nosideeffects
 */
YT.Player.prototype.getPlayerState = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getCurrentTime = function() {};

/**
 * @return {(undefined|string)}
 * @nosideeffects
 */
YT.Player.prototype.getPlaybackQuality = function() {};

/** @param {string} suggestedQuality */
YT.Player.prototype.setPlaybackQuality = function(suggestedQuality) {};

/**
 * @return {Array.<string>}
 * @nosideeffects
 */
YT.Player.prototype.getAvailableQualityLevels = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getDuration = function() {};

/**
 * @return {string}
 * @nosideeffects
 */
YT.Player.prototype.getVideoUrl = function() {};

/**
 * @return {string}
 * @nosideeffects
 */
YT.Player.prototype.getVideoEmbedCode = function() {};

/**
 * @return {Array.<string>}
 * @nosideeffects
 */
YT.Player.prototype.getPlaylist = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getPlaylistIndex = function() {};

/**
 * @param {string} eventName
 * @param {string} listenerName
 */
YT.Player.prototype.addEventListener = function(eventName, listenerName) {};

/** Destroys the player reference. */
YT.Player.prototype.destroy = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getPlaybackRate = function() {};

/** @param {number} suggestedRate */
YT.Player.prototype.setPlaybackRate = function(suggestedRate) {};

/**
 * @return {!Array.<number>}
 * @nosideeffects
 */
YT.Player.prototype.getAvailablePlaybackRates = function() {};

/** @enum */
YT.PlayerState = {
  ENDED: 0,
  PLAYING: 1,
  PAUSED: 2,
  BUFFERING: 3,
  CUED: 4
};

/**
 * @constructor
 * @private
 */
YT.Event = function() {};

/** @type {string|number|undefined} */
YT.Event.prototype.data;

/** @type {YT.Player} */
YT.Event.prototype.target = null;
<commit_msg>Update cuePlaylist defintiion to allow object Syntax ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=124770881<commit_after>/*
 * Copyright 2011 The Closure Compiler Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Externs for YouTube Player API for <iframe> Embeds.
 * @see http://code.google.com/apis/youtube/iframe_api_reference.html
 * @externs
 */

/** @return {undefined} */
var onYouTubePlayerAPIReady = function() {};

/** @return {undefined} */
window.onYouTubePlayerAPIReady = function() {};

/** @const */
var YT = {};

/**
 * @constructor
 * @param {(string|Element)} container
 * @param {Object.<string, *>} opts
 */
YT.Player = function(container, opts) {};

/**
 * @param {string} videoId
 * @param {number=} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.cueVideoById =
    function(videoId, startSeconds, suggestedQuality) {};

/**
 * @param {string} videoId
 * @param {number=} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.loadVideoById =
    function(videoId, startSeconds, suggestedQuality) {};

/**
 * @param {string} mediaContentUrl
 * @param {number} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.cueVideoByUrl =
    function(mediaContentUrl, startSeconds, suggestedQuality) {};

/**
 * @param {string} mediaContentUrl
 * @param {number} startSeconds
 * @param {string=} suggestedQuality
 */
YT.Player.prototype.loadVideoByUrl =
    function(mediaContentUrl, startSeconds, suggestedQuality) {};

/**
 * Loads and cues a specified video in a playlist.
 *
 * @param {string|!Array<string>|!Object} playlistOrObject An object containing
 *     the parameters.  N.B. a String object will be treated as an object
 *     instead of as a string.  Otherwise, a string literal that is a playlist
 *     id (without the PL list prefix) or an array of video ids.
 * @param {number=} opt_index The index to begin playback at.
 * @param {number=} opt_startSeconds Float/integer that specifies the time
 *     from which the video should start playing.
 * @param {string=} opt_suggestedQuality The suggested playback quality for
 *     the video.
 */
YT.Player.prototype.cuePlaylist = function(
    playlistOrObject, opt_index, opt_startSeconds, opt_suggestedQuality) {};

/**
 * @param {string|!Array<string>|!Object} playlistOrObject An object
 *     containing the parameters.  N.B. a String object will be treated as an
 *     object instead of as a string.  Otherwise, a string literal that is a
 *     playlist id (without the PL list prefix) or an array of video ids.
 * @param {number=} opt_index The index to begin playback at.
 * @param {number=} opt_startSeconds Float/integer that specifies the time
 *     from which the video should start playing.
 * @param {string=} opt_suggestedQuality The suggested playback quality for
 *     the video.
 */
YT.Player.prototype.loadPlaylist = function(
    playlistOrObject, opt_index, opt_startSeconds, opt_suggestedQuality) {};

/** @return {undefined} */
YT.Player.prototype.playVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.pauseVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.stopVideo = function() {};

/**
 * @param {number} seconds
 * @param {boolean} allowSeekAhead
 */
YT.Player.prototype.seekTo = function(seconds, allowSeekAhead) {};

/** @return {undefined} */
YT.Player.prototype.clearVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.nextVideo = function() {};

/** @return {undefined} */
YT.Player.prototype.previousVideo = function() {};

/** @param {number} index */
YT.Player.prototype.playVideoAt = function(index) {};

/** @return {undefined} */
YT.Player.prototype.mute = function() {};

/** @return {undefined} */
YT.Player.prototype.unMute = function() {};

/** @return {boolean} */
YT.Player.prototype.isMuted = function() {};

/** @param {number} volume */
YT.Player.prototype.setVolume = function(volume) {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVolume = function() {};

/** @param {boolean} loopPlaylists */
YT.Player.prototype.setLoop = function(loopPlaylists) {};

/** @param {boolean} shufflePlaylist */
YT.Player.prototype.setShuffle = function(shufflePlaylist) {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoBytesLoaded = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoBytesTotal = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoLoadedFraction = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getVideoStartBytes = function() {};

/**
 * @return {YT.PlayerState|number}
 * @nosideeffects
 */
YT.Player.prototype.getPlayerState = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getCurrentTime = function() {};

/**
 * @return {(undefined|string)}
 * @nosideeffects
 */
YT.Player.prototype.getPlaybackQuality = function() {};

/** @param {string} suggestedQuality */
YT.Player.prototype.setPlaybackQuality = function(suggestedQuality) {};

/**
 * @return {Array.<string>}
 * @nosideeffects
 */
YT.Player.prototype.getAvailableQualityLevels = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getDuration = function() {};

/**
 * @return {string}
 * @nosideeffects
 */
YT.Player.prototype.getVideoUrl = function() {};

/**
 * @return {string}
 * @nosideeffects
 */
YT.Player.prototype.getVideoEmbedCode = function() {};

/**
 * @return {Array.<string>}
 * @nosideeffects
 */
YT.Player.prototype.getPlaylist = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getPlaylistIndex = function() {};

/**
 * @param {string} eventName
 * @param {string} listenerName
 */
YT.Player.prototype.addEventListener = function(eventName, listenerName) {};

/** Destroys the player reference. */
YT.Player.prototype.destroy = function() {};

/**
 * @return {number}
 * @nosideeffects
 */
YT.Player.prototype.getPlaybackRate = function() {};

/** @param {number} suggestedRate */
YT.Player.prototype.setPlaybackRate = function(suggestedRate) {};

/**
 * @return {!Array.<number>}
 * @nosideeffects
 */
YT.Player.prototype.getAvailablePlaybackRates = function() {};

/** @enum */
YT.PlayerState = {
  ENDED: 0,
  PLAYING: 1,
  PAUSED: 2,
  BUFFERING: 3,
  CUED: 4
};

/**
 * @constructor
 * @private
 */
YT.Event = function() {};

/** @type {string|number|undefined} */
YT.Event.prototype.data;

/** @type {YT.Player} */
YT.Event.prototype.target = null;
<|endoftext|>


<commit_before>#!/usr/bin/env node
// vi fiz.js
var Liftoff = require("liftoff");
var argv = require("minimist")(process.argv.slice(2));
var path = require("path");
var fs = require("fs");
var cli = new Liftoff({
  name: "fiz",
  processTitle: "fiz",
  moduleName: "fiz",
  configName: "fis-conf",

  //only js supported
  extensions: {
    ".js": null
  }
});

//同步生成文件夹
function mkdirsSync(dirpath, mode) {
  if (!fs.existsSync(dirpath)) {
    var pathtmp = "";
    dirpath.split(path.sep).forEach(function(dirname) {
      if (pathtmp) {
        pathtmp = path.join(pathtmp, dirname);
      } else {
        pathtmp = dirname;
      }

      if (!fs.existsSync(pathtmp)) {
        if (!fs.mkdirSync(pathtmp, mode)) {
          return false;
        }
      }
    });
  }
  return true;
}

cli.launch({
  cwd: argv.r || argv.root,
  configPath: argv.f || argv.file
}, function(env){
  //捕获命令行
  var command = argv["_"];

  //fiz get项目
  if("get" == command[0]){
    //提供的服务
    var targetHash = {
      "web": {
        name: "web-template",
        url: "https://git.oschina.net/luozt007/web-template.git"
      }
    };

    //检测是否存在该服务
    var cmd1 = command[1];
    var targetObj = targetHash[cmd1];
    if(!targetObj){
      console.log("Not such \"" + cmd1 + "\" get-target!");
      return false;
    }

    var noDir = !!argv["n"];
    var folder = targetObj.name;
    var childProcess = require("child_process");
    var exec = childProcess.exec;

    console.log("start get [ " + cmd1 + " ]");

    var child = exec("git clone " + targetObj.url, function(err, stdout, stderr){
      if(err){
        console.log("git clone err: " + err);
        return;
      }

      console.log("get [ " + cmd1 + " ] success");

      var child2 = exec("rm -rf " + folder + "/.git", function(err, stdout){
        if (err){
          console.log("rm "+ folder +"/.git error");
          return;
        }

        if (noDir){
          var child3 = exec("cp -rf " + folder + "/* ./", function(err, stdout){
            if(err){
              console.log("cp " + folder + " folder error");
              return;
            }

            var child4 = exec("rm -rf " + folder, function(err, stdout){
              if (err){
                console.log("rm "+ folder +" folder error")
                return;
              }
            });
          });
        }
      });
    });

  }

  //引用fis
  else{
    var fis;
    if(!env.modulePath){
      fis = require("./");
    }else{
      fis = require(env.modulePath);
    }

    fis.set("system.localNPMFolder", path.join(env.cwd, "node_modules/fiz"));
    //fis.set('system.globalNPMFolder', path.dirname(__dirname));
    fis.cli.run(argv, env);
  }

});

<commit_msg>修改web模板git clone地址<commit_after>#!/usr/bin/env node
// vi fiz.js
var Liftoff = require("liftoff");
var argv = require("minimist")(process.argv.slice(2));
var path = require("path");
var fs = require("fs");
var cli = new Liftoff({
  name: "fiz",
  processTitle: "fiz",
  moduleName: "fiz",
  configName: "fis-conf",

  //only js supported
  extensions: {
    ".js": null
  }
});

//同步生成文件夹
function mkdirsSync(dirpath, mode) {
  if (!fs.existsSync(dirpath)) {
    var pathtmp = "";
    dirpath.split(path.sep).forEach(function(dirname) {
      if (pathtmp) {
        pathtmp = path.join(pathtmp, dirname);
      } else {
        pathtmp = dirname;
      }

      if (!fs.existsSync(pathtmp)) {
        if (!fs.mkdirSync(pathtmp, mode)) {
          return false;
        }
      }
    });
  }
  return true;
}

cli.launch({
  cwd: argv.r || argv.root,
  configPath: argv.f || argv.file
}, function(env){
  //捕获命令行
  var command = argv["_"];

  //fiz get项目
  if("get" == command[0]){
    //提供的服务
    var targetHash = {
      "web": {
        name: "web-template",
        url: "https://github.com/luozt/web-template.git"
      }
    };

    //检测是否存在该服务
    var cmd1 = command[1];
    var targetObj = targetHash[cmd1];
    if(!targetObj){
      console.log("Not such \"" + cmd1 + "\" get-target!");
      return false;
    }

    var noDir = !!argv["n"];
    var folder = targetObj.name;
    var childProcess = require("child_process");
    var exec = childProcess.exec;

    console.log("start get [ " + cmd1 + " ]");

    var child = exec("git clone " + targetObj.url, function(err, stdout, stderr){
      if(err){
        console.log("git clone err: " + err);
        return;
      }

      console.log("get [ " + cmd1 + " ] success");

      var child2 = exec("rm -rf " + folder + "/.git", function(err, stdout){
        if (err){
          console.log("rm "+ folder +"/.git error");
          return;
        }

        if (noDir){
          var child3 = exec("cp -rf " + folder + "/* ./", function(err, stdout){
            if(err){
              console.log("cp " + folder + " folder error");
              return;
            }

            var child4 = exec("rm -rf " + folder, function(err, stdout){
              if (err){
                console.log("rm "+ folder +" folder error")
                return;
              }
            });
          });
        }
      });
    });

  }

  //引用fis
  else{
    var fis;
    if(!env.modulePath){
      fis = require("./");
    }else{
      fis = require(env.modulePath);
    }

    fis.set("system.localNPMFolder", path.join(env.cwd, "node_modules/fiz"));
    //fis.set('system.globalNPMFolder', path.dirname(__dirname));
    fis.cli.run(argv, env);
  }

});

<|endoftext|>


<commit_before>var express = require('express');
var app = express();

var express = require('redis');
var client = redis.createClient();

app.get('/', function (req, res) {
  client.incr("visitors") // increment visitors
  client.get("visitors", function(err, value) {
    res.send('Hello visitor number ' + value + '!');
});

var server = app.listen(process.env.PORT || 5000, function () {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

});<commit_msg>tried changing port from 5000 to 3000<commit_after>var express = require('express');
var app = express();

var express = require('redis');
var client = redis.createClient();

app.get('/', function (req, res) {
  client.incr("visitors") // increment visitors
  client.get("visitors", function(err, value) {
    res.send('Hello visitor number ' + value + '!');
});

var server = app.listen(process.env.PORT || 3000, function () {

  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);

});<|endoftext|>


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

	var CONFIG = {
		serverUid : "http",
		serverGid : "http",
		listenIPv4 : true,
		listenIPv6 : true,
		servicePort : 37320,
		workersKeepIdle : 3600,	// Unit: second
		workersTimeout : 60,	// Unit: second
		messageCap : 1024 * 16	// Unit: octet
	},

	Messenger = function(salt, type, payload){
		var messageTypeRegex = /^(?:header|body|end)$/;

		return {
			salt : salt,
			type : messageTypeRegex.test(type) ? type : "unknown",
			payload : payload
		};
	},
	RequestHeaderMessenger = function(salt, invoking, req){
		return new Messenger(salt, "header", {
			invoking : invoking,
			socket : {
				remoteAddress : req.socket.remoteAddress,
				remotePort : req.socket.remotePort,
				localAddress : req.socket.localAddress,
				localPort : req.socket.localPort
			},
			http : {
				version : req.httpVersion,
				method : req.method,
				uri : req.url,
				headers : req.headers,
			}
		});
	},
	ResponseHeaderMessenger = function(salt){
		return new Messenger(salt, "header", {
			statusCode : 200,
			reasonPhrase : undefined,
			headers : {}
		});
	},

	NodePool = function(){
	},

	cluster = require("cluster");

	NodePool.prototype.balancer = function(){
		var workers = {}, server = require("http").createServer(),

		terminateWorker = function(){
			workers[this.workFor].splice(workers[this.workFor].indexOf(this), 1);
			this.removeAllListeners();
			this.kill();
		},
		invokeWorker = function(path){
			var worker = null;

			if(typeof workers[path] === typeof []){
				for(let i = 0; i < workers[path].length; i += 1){
					if(workers[path][i].isIdle){
						worker = workers[path][i];
						clearTimeout(worker.stopIdling);
						break;
					}
				}
			}

			if(worker === null){
				worker = cluster.fork();
				worker.workFor = path;
				worker.terminate = terminateWorker;
				workers[path] = [worker];
			}

			worker.isIdle = false;

			return worker;
		},
		idleWorker = function(worker){
			worker.isIdle = true;
			worker.stopIdling = setTimeout(function(){
				worker.terminate();
			}, CONFIG.workersKeepIdle * 1000);
		},

		responder = function(req, res){
			var salt = Math.random(),
			invoking = require("url").parse(req.url).pathname,

			worker = invokeWorker(invoking),

			abortWorker = function(){
				res.end();
				worker.terminate();
			},

			workerMessageReceptor = function(workerMes){
				if(workerMes.salt !== salt){
					// console.log(workerMes);
					return;
				}

				switch(workerMes.type){
					case "header":
						if(typeof workerMes.payload.reasonPhrase === typeof ""){
							res.writeHead(
								workerMes.payload.statusCode,
								workerMes.payload.reasonPhrase,
								workerMes.payload.headers
							);
						}else{
							res.writeHead(workerMes.payload.statusCode, workerMes.payload.headers);
						}

						clearTimeout(worker.timeout);
						worker.timeout = setTimeout(abortWorker, CONFIG.workersTimeout * 1000);

						break;

					case "body":
						res.write(new Buffer(workerMes.payload));
						clearTimeout(worker.timeout);
						worker.timeout = setTimeout(abortWorker, CONFIG.workersTimeout * 1000);
						break;

					case "end":
						res.end();
						clearTimeout(worker.timeout);
						idleWorker(worker);
						break;

					default:
						// console.log(workerMes);
				}
			};

			worker.send(new RequestHeaderMessenger(salt, invoking, req));

			req.on("data", function(bodyChunk){
				var messageContainer = new Messenger(salt, "body", null), p = 0;

				while(p < bodyChunk.length){
					messageContainer.payload = bodyChunk.slice(
						p,
						p = p + CONFIG.messageCap < bodyChunk.length ? p + CONFIG.messageCap : bodyChunk.length
					);
					worker.send(messageContainer);
				}
			});

			req.on("end", function(){
				worker.send(new Messenger(salt, "end"));
				worker.on("message", workerMessageReceptor);
				worker.timeout = setTimeout(abortWorker, CONFIG.workersTimeout * 1000);
			});

			res.on("close", function(){
				clearTimeout(worker.timeout);
				worker.terminate();
			});
		};

		CONFIG.listenIPv4 && server.listen(CONFIG.servicePort, "0.0.0.0");
		CONFIG.listenIPv6 && server.listen(CONFIG.servicePort, "::");

		server.on("request", responder);
	};

	NodePool.prototype.worker = function(){
		var built = null, request = null,

		fs = require("fs"),

		genInstanceInterface = function(request){
			var salt = request.salt, responseHeaders = [], isHeaderSent = false,

			flushHeaders = function(){
				var messageContainer = new ResponseHeaderMessenger(salt);

				responseHeaders.forEach(function(expr){
					var parts = expr.split(":");

					if(parts.length < 2){
						return;
					}

					if(/^Status$/i.test(parts[0])){
						parts.shift();

						{
							let statusTerms = parts.join(":").trim().split(" ");

							messageContainer.payload.statusCode = parseInt(statusTerms[0], 10);

							statusTerms.shift();

							if(typeof statusTerms[0] !== typeof undefined){
								messageContainer.payload.reasonPhrase = statusTerms[0].toString();
							}
						}
					}else{
						messageContainer.payload.headers[parts.shift()] = parts.join(":");
					}
				});

				process.send(messageContainer);
			};

			return {
				request : {
					socket : request.header.socket,
					header : request.header.http,
					body : Buffer.concat(request.body)
				},
				writeHeader : function(expr){
					responseHeaders.push(expr);
				},
				echo : function(bodyChunk){
					var messageContainer = new Messenger(salt, "body", null), p = 0;

					if(!isHeaderSent){
						flushHeaders();
						isHeaderSent = true;
					}

					while(p < bodyChunk.length){
						messageContainer.payload = bodyChunk.slice(
							p,
							p = p + CONFIG.messageCap < bodyChunk.length ? p + CONFIG.messageCap : bodyChunk.length
						);
						process.send(messageContainer);
					}
				},
				end : function(){
					if(!isHeaderSent){
						flushHeaders();
						isHeaderSent = true;
					}

					process.send(new Messenger(salt, "end"));
				}
			};
		},
		respondBalancerRequest = function(request){
			var instanceInterface = genInstanceInterface(request);

			try{
				process.chdir(require("path").dirname(fs.realpathSync(request.header.invoking)));

				if(built === null || fs.statSync(request.header.invoking).ctime.getTime() > built.builtAt.getTime()){
					delete require.cache[fs.realpathSync(request.header.invoking)];
					built = require(request.header.invoking);
					built.builtAt = new Date();
				}

				instanceInterface.writeHeader("Content-Type: text/html; charset=UTF-8");
				built.exec(instanceInterface);
			}
			catch(e){
				instanceInterface.writeHeader("Status: 500");
				instanceInterface.end();
				// console.log(e);
			}
		},
		balancerMessageReceptor = function(messenger){
			switch(messenger.type){
				case "header":
					request = {
						salt : messenger.salt,
						header : messenger.payload,
						body : []
					};
					break;

				case "body":
					if(messenger.salt === request.salt){
						request.body.push(new Buffer(messenger.payload));
					}
					break;

				case "end":
					respondBalancerRequest(request);
					break;
				default:
					// console.log(messenger);
			}
		};

		process.on("message", balancerMessageReceptor);
	};

	process.setuid(CONFIG.serverUid) && process.setgid(CONFIG.serverGid);

	if(cluster.isMaster){
		new NodePool().balancer();
	}else if(cluster.isWorker){
		new NodePool().worker();
	}
})();
<commit_msg>* Now providing scheme information (i.e. whether HTTP or HTTPS)<commit_after>(function(){
	"use strict";

	var CONFIG = {
		serverUid : "http",
		serverGid : "http",
		listenIPv4 : true,
		listenIPv6 : true,
		servicePort : 37320,
		workersKeepIdle : 3600,	// Unit: second
		workersTimeout : 60,	// Unit: second
		messageCap : 1024 * 16	// Unit: octet
	},

	Messenger = function(salt, type, payload){
		var messageTypeRegex = /^(?:header|body|end)$/;

		return {
			salt : salt,
			type : messageTypeRegex.test(type) ? type : "unknown",
			payload : payload
		};
	},
	RequestHeaderMessenger = function(salt, invoking, req){
		return new Messenger(salt, "header", {
			invoking : invoking,
			socket : {
				remoteAddress : req.socket.remoteAddress,
				remotePort : req.socket.remotePort,
				localAddress : req.socket.localAddress,
				localPort : req.socket.localPort
			},
			http : {
				scheme : req.scheme.toUpperCase(),
				version : req.httpVersion,
				method : req.method,
				uri : req.url,
				headers : req.headers
			}
		});
	},
	ResponseHeaderMessenger = function(salt){
		return new Messenger(salt, "header", {
			statusCode : 200,
			reasonPhrase : undefined,
			headers : {}
		});
	},

	NodePool = function(){
	},

	cluster = require("cluster");

	NodePool.prototype.balancer = function(){
		var workers = {}, server = require("http").createServer(),

		url = require("url"),

		terminateWorker = function(){
			workers[this.workFor].splice(workers[this.workFor].indexOf(this), 1);
			this.removeAllListeners();
			this.kill();
		},
		invokeWorker = function(path){
			var worker = null;

			if(typeof workers[path] === typeof []){
				for(let i = 0; i < workers[path].length; i += 1){
					if(workers[path][i].isIdle){
						worker = workers[path][i];
						clearTimeout(worker.stopIdling);
						break;
					}
				}
			}

			if(worker === null){
				worker = cluster.fork();
				worker.workFor = path;
				worker.terminate = terminateWorker;
				workers[path] = [worker];
			}

			worker.isIdle = false;

			return worker;
		},
		idleWorker = function(worker){
			worker.isIdle = true;
			worker.stopIdling = setTimeout(function(){
				worker.terminate();
			}, CONFIG.workersKeepIdle * 1000);
		},

		responder = function(req, res){
			var salt = Math.random(),
			requested = url.parse(req.url.replace(/^\//, "")),
			invoking = url.parse(requested.pathname).pathname,

			worker = invokeWorker(invoking),

			abortWorker = function(){
				res.end();
				worker.terminate();
			},

			workerMessageReceptor = function(workerMes){
				if(workerMes.salt !== salt){
					// console.log(workerMes);
					return;
				}

				switch(workerMes.type){
					case "header":
						if(typeof workerMes.payload.reasonPhrase === typeof ""){
							res.writeHead(
								workerMes.payload.statusCode,
								workerMes.payload.reasonPhrase,
								workerMes.payload.headers
							);
						}else{
							res.writeHead(workerMes.payload.statusCode, workerMes.payload.headers);
						}

						clearTimeout(worker.timeout);
						worker.timeout = setTimeout(abortWorker, CONFIG.workersTimeout * 1000);

						break;

					case "body":
						res.write(new Buffer(workerMes.payload));
						clearTimeout(worker.timeout);
						worker.timeout = setTimeout(abortWorker, CONFIG.workersTimeout * 1000);
						break;

					case "end":
						res.end();
						clearTimeout(worker.timeout);
						idleWorker(worker);
						break;

					default:
						// console.log(workerMes);
				}
			};

			req.url = requested.path;
			req.scheme = requested.protocol.replace(/:$/, "");

			worker.send(new RequestHeaderMessenger(salt, invoking, req));

			req.on("data", function(bodyChunk){
				var messageContainer = new Messenger(salt, "body", null), p = 0;

				while(p < bodyChunk.length){
					messageContainer.payload = bodyChunk.slice(
						p,
						p = p + CONFIG.messageCap < bodyChunk.length ? p + CONFIG.messageCap : bodyChunk.length
					);
					worker.send(messageContainer);
				}
			});

			req.on("end", function(){
				worker.send(new Messenger(salt, "end"));
				worker.on("message", workerMessageReceptor);
				worker.timeout = setTimeout(abortWorker, CONFIG.workersTimeout * 1000);
			});

			res.on("close", function(){
				clearTimeout(worker.timeout);
				worker.terminate();
			});
		};

		CONFIG.listenIPv4 && server.listen(CONFIG.servicePort, "0.0.0.0");
		CONFIG.listenIPv6 && server.listen(CONFIG.servicePort, "::");

		server.on("request", responder);
	};

	NodePool.prototype.worker = function(){
		var built = null, request = null,

		fs = require("fs"),

		genInstanceInterface = function(request){
			var salt = request.salt, responseHeaders = [], isHeaderSent = false,

			flushHeaders = function(){
				var messageContainer = new ResponseHeaderMessenger(salt);

				responseHeaders.forEach(function(expr){
					var parts = expr.split(":");

					if(parts.length < 2){
						return;
					}

					if(/^Status$/i.test(parts[0])){
						parts.shift();

						{
							let statusTerms = parts.join(":").trim().split(" ");

							messageContainer.payload.statusCode = parseInt(statusTerms[0], 10);

							statusTerms.shift();

							if(typeof statusTerms[0] !== typeof undefined){
								messageContainer.payload.reasonPhrase = statusTerms[0].toString();
							}
						}
					}else{
						messageContainer.payload.headers[parts.shift()] = parts.join(":");
					}
				});

				process.send(messageContainer);
			};

			return {
				request : {
					socket : request.header.socket,
					header : request.header.http,
					body : Buffer.concat(request.body)
				},
				writeHeader : function(expr){
					responseHeaders.push(expr);
				},
				echo : function(bodyChunk){
					var messageContainer = new Messenger(salt, "body", null), p = 0;

					if(!isHeaderSent){
						flushHeaders();
						isHeaderSent = true;
					}

					while(p < bodyChunk.length){
						messageContainer.payload = bodyChunk.slice(
							p,
							p = p + CONFIG.messageCap < bodyChunk.length ? p + CONFIG.messageCap : bodyChunk.length
						);
						process.send(messageContainer);
					}
				},
				end : function(){
					if(!isHeaderSent){
						flushHeaders();
						isHeaderSent = true;
					}

					process.send(new Messenger(salt, "end"));
				}
			};
		},
		respondBalancerRequest = function(request){
			var instanceInterface = genInstanceInterface(request);

			try{
				process.chdir(require("path").dirname(fs.realpathSync(request.header.invoking)));

				if(built === null || fs.statSync(request.header.invoking).ctime.getTime() > built.builtAt.getTime()){
					delete require.cache[fs.realpathSync(request.header.invoking)];
					built = require(request.header.invoking);
					built.builtAt = new Date();
				}

				instanceInterface.writeHeader("Content-Type: text/html; charset=UTF-8");
				built.exec(instanceInterface);
			}
			catch(e){
				instanceInterface.writeHeader("Status: 500");
				instanceInterface.end();
				// console.log(e);
			}
		},
		balancerMessageReceptor = function(messenger){
			switch(messenger.type){
				case "header":
					request = {
						salt : messenger.salt,
						header : messenger.payload,
						body : []
					};
					break;

				case "body":
					if(messenger.salt === request.salt){
						request.body.push(new Buffer(messenger.payload));
					}
					break;

				case "end":
					respondBalancerRequest(request);
					break;
				default:
					// console.log(messenger);
			}
		};

		process.on("message", balancerMessageReceptor);
	};

	process.setuid(CONFIG.serverUid) && process.setgid(CONFIG.serverGid);

	if(cluster.isMaster){
		new NodePool().balancer();
	}else if(cluster.isWorker){
		new NodePool().worker();
	}
})();
<|endoftext|>


<commit_before>/**
 * keep this in crontab
 * 	    PATH=/usr/bin:/bin:/usr/local/bin
 * 		* * * * * node /pathto/cron.js >/somelogpath/.cronlog 2>&1
 */

var exec = require('child_process').exec;
var trim = require('trim');
var fs = require('fs');

var cmds=null;
var running=null;

process.chdir(__dirname);

exec('echo $PATH', function(err, stdout, stderr){
	console.log(stdout);

});

try{
	cmds=require('./.tcpmecommand.json');
}catch(e){

}

exec('ps -Af | grep \'examples/tcpme.js\' ', function(err, stdout, stderr){

	/*console.log(stdout);*/
	var lines=trim(stdout).split("\n").filter(function(l){return l.indexOf("grep")===-1});
	if(lines.length){
		console.log('Running ('+lines.length+')');

		var nodecmds=[];
		lines.forEach(function(line){
			running='node'+line.split('node').pop();
			console.log(running);
			nodecmds.push(running);

		});

		if(!(cmds&&cmds.length)){

			console.log('Wrote to keepalive file');
			fs.writeFile('./.tcpmecommand.json', JSON.stringify(nodecmds));

		}else{

		}

	}

	if(cmds){

		cmds.forEach(function(cmd){

			var isRunning=false;
			lines.forEach(function(line){

				if(line.indexOf(cmd)>=0){
					isRunning=true;
				}

			});

			if(!isRunning){

				console.log('Restarting: '+cmd);

				exec(cmd+' >.log 2>&1 &', function(err, stdout, stderr){

					console.log('ok');

				});
			}

		});

	}

});<commit_msg>add comments<commit_after>/**
 * keep this in crontab
 * 	    PATH=/usr/bin:/bin:/usr/local/bin
 * 		* * * * * node /pathto/cron.js >/somelogpath/.cronlog 2>&1
 */

/**
 * How to use.
 *
 * cron.js keeps track of running rpoxy processes. on first use, it checkes the running tasks and stores
 * the command to start/restart them is a json file. if cron.js is executed using a cron job, then every time it is run,
 * it checks to make sure that a matching process is running for each of the stored commands and restarts them if necessary.
 *
 * to make this work start a number of endpoint tasks: ie:
 *
 *    node examples/tcpme.js ws://user:pass@still-sea-5733.herokuapp.com/ssh 22 &
 *    node examples/tcpme.js ws://user:pass@still-sea-5733.herokuapp.com/ftp 21 &
 *    node examples/tcpme.js ws://user:pass@still-sea-5733.herokuapp.com/html 80 &
 *
 *    node cron.js
 *    # out >
 *    # Running (3)
 *	  # Wrote to keepalive file
 *
 *
 *
 */

var exec = require('child_process').exec;
var trim = require('trim');
var fs = require('fs');

var cmds=null;
var running=null;

process.chdir(__dirname);

exec('echo $PATH', function(err, stdout, stderr){
	console.log(stdout);

});

try{
	cmds=require('./.tcpmecommand.json');
}catch(e){

}

exec('ps -Af | grep \'examples/tcpme.js\' ', function(err, stdout, stderr){

	/*console.log(stdout);*/
	var lines=trim(stdout).split("\n").filter(function(l){return l.indexOf("grep")===-1});
	if(lines.length){
		console.log('Running ('+lines.length+')');

		var nodecmds=[];
		lines.forEach(function(line){
			running='node'+line.split('node').pop();
			console.log(running);
			nodecmds.push(running);

		});

		if(!(cmds&&cmds.length)){

			console.log('Wrote to keepalive file');
			fs.writeFile('./.tcpmecommand.json', JSON.stringify(nodecmds));

		}else{

		}

	}

	if(cmds){

		cmds.forEach(function(cmd){

			var isRunning=false;
			lines.forEach(function(line){

				if(line.indexOf(cmd)>=0){
					isRunning=true;
				}

			});

			if(!isRunning){

				console.log('Restarting: '+cmd);

				exec(cmd+' >.log 2>&1 &', function(err, stdout, stderr){

					console.log('ok');

				});
			}

		});

	}

});<|endoftext|>


<commit_before>$(document).ready(function (btc) {
  var bitcoinPrice = "https://blockchain.info/ticker?jsoncallback=?";
  $.getJSON(bitcoinPrice, function (cost){
    var usDollarPrice = cost.USD[15m];
    console.log('usd : ', usDollarPrice);
  });
});
<commit_msg>change js api call<commit_after>$(document).ready(function () {
  var bitcoinPrice = ("https://blockchain.info/q/24hrprice");
  $.getJSON(bitcoinPrice, function (cost){
    console.log('1 bitcoin = $',cost);
  });
});
<|endoftext|>