<commit_before>/**
 * Object2D represents an object of the scene.
 *   An Object2D is a simple scene object which the main
 *   purpose is to render a texture at a position. More
 *   complex behaviors should be implemented by others
 *   objects that inherit from Object2D.
 *
 * @param {!Grape2D.Vector=} options.position The position of the shape
 * @param {!boolean=} options.visible True to render the object, false
 *		otherwise.
 * @param {!Grape2D.Texture} options.texture The texture of the object.
 * @param {!Grape2D.Vector=} options.textureOffset The offset position
 *		of the texture relative to the objects position.
 * @param {!Grape2D.Shape} options.boundingBox The primary use of the
 *		bounding box is to select the items to display in the renderer,
 *		other behaviors such as collision detection can be done with
 *		this property, in some simple cases.
 * @param {!Grape2D.Vector=} options.boundingBoxOffset The offset
 *		position of the bounding box relative to the objects position.
 * @param {!boolean=} options.castShadow Used by the IlluminatedRenderer
 *		to render this object shadow.
 * @param {!boolean=} options.receiveLight Used by the IlluminatedRenderer
 *		to render the objects texture with a light overlay, if set to true.
 *
 * @constructor
 */
Grape2D.Object2D = function (options) {

	/**
	 * Object's position.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.position = options.position || new Grape2D.Vector();

	/**
	 * Visible property.
	 *
	 * @type {!boolean}
	 * @private
	 */
	this.visible = options.visible || true;

	/**
	 * The texture of the object.
	 *
	 * @type {!Grape2D.Texture}
	 * @private
	 */
	this.texture = options.texture;
	/**
	 * The offset of the texture.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.textureOffset = options.textureOffset || new Grape2D.Vector();
	/**
	 * The position of the texture. It is computed from the object's position and the texture offset.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.texturePosition = new Grape2D.Vector();
	//computes the texture position.
	this.computeTexturePosition();
	/**
	 * Object's bounding box.
	 *
	 * @type {!Grape2D.Shape}
	 * @private
	 */
	this.boundingBox = options.boundingBox;
	/**
	 * Bounding box offset.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.boundingBoxOffset = options.boundingBoxOffset || new Grape2D.Vector();

	this.computeBoundingBoxPosition();

	/**
	 * Object cast shadow.
	 *
	 * @type {!boolean}
	 * @private
	 */
	this.castShadow = options.castShadow || false;
	/**
	 * Object can receive light.
	 *
	 * @type {!boolean}
	 * @private
	 */
	this.receiveLight = options.receiveLight || false;

};

Grape2D.Object2D.prototype = {
	constructor: Grape2D.Object2D,
	/**
	 * Checks if the object should be rendered.
	 *
	 * @return {!boolean} True if it can be rendered.
	 * @public
	 */
	isVisible: function () {
		return this.visible;
	},
	/**
	 * Sets if an object should be rendered.
	 *
	 * @param  {!boolean} visible True, so that it renders, false
	 *   otherwise.
	 * @public
	 */
	setVisible: function (visible) {
		this.visible = visible;
		return;
	},
	/**
	 * Gets the texture of the object.
	 *
	 * @return {!Grape2D.Texture} The texture of the object.
	 * @public
	 */
	getTexture: function () {
		return this.texture;
	},
	/**
	 * Sets the texture of the object.
	 *
	 * @param  {!Grape2D.Texture} texture The texture.
	 * @public
	 */
	setTexture: function (texture) {
		this.texture = texture;
		return;
	},
	/**
	 * Gets the bounding box of the object.
	 *
	 * @return {!Grape2D.Shape} The shape of the object.
	 * @public
	 */
	getBoundingBox: function () {
		return this.boundingBox;
	},
	/**
	 * Sets the bounding box of the object.
	 * Also, the position of the new bounding box, will be transformed
	 *   in the default offset of the bounding box.
	 *
	 * @param  {!Grape2D.Shape} boundingBox The bounding box.
	 * @public
	 */
	setBoundingBox: function (boundingBox) {
		this.boundingBox = boundingBox;
		this.computeBoundingBoxPosition();
		return;
	},
	/**
	 * Checks if the object can cast shadows.
	 *
	 * @return {!boolean} True if it cast shadows, false otherwise.
	 * @public
	 */
	canCastShadow: function () {
		return this.castShadow;
	},
	/**
	 * Sets if an object can cast shadows.
	 *
	 * @param  {!boolean} castShadow True to cast shadows, false
	 *   otherwise.
	 * @public
	 */
	setCastShadow: function (castShadow) {
		this.castShadow = castShadow;
		return;
	},
	/**
	 * Checks if an object can receive light.
	 *
	 * @return {!boolean} True if it receives light.
	 * @public
	 */
	canReceiveLight: function () {
		return this.receiveLight;
	},
	/**
	 * Sets if the object can receive light.
	 *
	 * @param  {!boolean} receiveLight True if it receives light.
	 * @public
	 */
	setReceiveLight: function (receiveLight) {
		this.receiveLight = receiveLight;
		return;
	},
	/**
	 * Gets the object position. Be careful, because it returns the
	 *   vector used by the object, and not a copy. Use it wisely.
	 *
	 * @return {!Grape2D.Vector} The position of the object.
	 * @public
	 */
	getPosition: function () {
		return this.position;
	},
	/**
	 * Sets the object position.
	 *
	 * @param  {!Grape2D.Vector} position The position of the object.
	 * @public
	 */
	setPosition: function (position) {
		this.position.set(position);
		this.computeBoundingBoxPosition();
		this.computeTexturePosition();
	},
	/**
	 * Sets the texture offset.
	 *
	 * @param  {!Grape2D.Vector} offset The offset of the texture, from
	 *   the object's position.
	 * @public
	 */
	setTextureOffset: function (offset) {
		this.textureOffset.set(offset);
		this.computeTexturePosition();
	},
	/**
	 * Gets the texture offset
	 *
	 * @return {!Grape2D.Vector} The texture offset.
	 * @public
	 */
	getTextureOffset: function () {
		return this.textureOffset;
	},
	/**
	 * Sets the bounding box offset.
	 *
	 * @param  {!Grape2D.Vector} offset The offset of the bounding
	 *   box, from the object's position.
	 * @public
	 */
	setBoundingBoxOffset: function (offset) {
		this.boundingBoxOffset.set(offset);
		this.computeBoundingBoxPosition();
	},
	/**
	 * Gets the bounding box offset
	 *
	 * @return {!Grape2D.Vector} The bounding box offset.
	 * @public
	 */
	getBoundingBoxOffset: function () {
		return this.boundingBoxOffset;
	},
	/**
	 * Computes the bounding box position, from the object's position
	 *   and bounding box offset.
	 * @protected
	 */
	computeBoundingBoxPosition: function () {
		this.boundingBox.setPosition(this.position);
		this.boundingBox.getPosition().add(this.boundingBoxOffset);
	},
	/**
	 * Gets the bounding box position.
	 *
	 * @return {!Grape2D.Vector} The center position of the bounding box.
	 * @public
	 */
	getBoundingBoxPosition: function () {
		return this.boundingBox.getPosition();
	},
	/**
	 * Computes the texture position of the object, from the object's
	 *   position and texture offset.
	 * @protected
	 */
	computeTexturePosition: function () {
		this.texturePosition.set(this.position).add(this.textureOffset);
	},
	/**
	 * Gets the texture position.
	 *
	 * @return {!Grape2D.Vector} The position of the texture
	 * @public
	 */
	getTexturePosition: function () {
		return this.texturePosition;
	},
	/**
	 * Renders the object to a renderer.
	 *
	 * @param  {!Grape2D.Renderer} renderer The place to render the
	 *   object.
	 * @param  {!Grape2D.Camera} camera The camera, that will
	 *   transform the positions.
	 * @public
	 */
	render: function (renderer, camera) {
		renderer.renderObject2D(this, camera);
	},
	/**
	 * Updates the object. This method should be refined in further
	 *   subclasses if needed be.
	 *
	 * @param  {!number} dt Time interval.
	 * @param  {!Grape2D.Scene} scene Scene where this object is.
	 * @public
	 */
	update: function (dt, scene) {}
};<commit_msg>Clarified function of the bounding box.<commit_after>/**
 * Object2D represents an object of the scene.
 *   An Object2D is a simple scene object which the main
 *   purpose is to render a texture at a position. More
 *   complex behaviors should be implemented by others
 *   objects that inherit from Object2D.
 *
 * @param {!Grape2D.Vector=} options.position The position of the shape
 * @param {!boolean=} options.visible True to render the object, false
 *		otherwise.
 * @param {!Grape2D.Texture} options.texture The texture of the object.
 * @param {!Grape2D.Vector=} options.textureOffset The offset position
 *		of the texture relative to the objects position.
 * @param {!Grape2D.Shape} options.boundingBox The primary use of the
 *		bounding box is to select the items to display in the renderer,
 *		other behaviors such as collision detection can be done with
 *		this property, in some simple cases. So the bounding box should
 *		bounded tightly to what's supposed to be seen.
 * @param {!Grape2D.Vector=} options.boundingBoxOffset The offset
 *		position of the bounding box relative to the objects position.
 * @param {!boolean=} options.castShadow Used by the IlluminatedRenderer
 *		to render this object shadow.
 * @param {!boolean=} options.receiveLight Used by the IlluminatedRenderer
 *		to render the objects texture with a light overlay, if set to true.
 *
 * @constructor
 */
Grape2D.Object2D = function (options) {

	/**
	 * Object's position.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.position = options.position || new Grape2D.Vector();

	/**
	 * Visible property.
	 *
	 * @type {!boolean}
	 * @private
	 */
	this.visible = options.visible || true;

	/**
	 * The texture of the object.
	 *
	 * @type {!Grape2D.Texture}
	 * @private
	 */
	this.texture = options.texture;
	/**
	 * The offset of the texture.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.textureOffset = options.textureOffset || new Grape2D.Vector();
	/**
	 * The position of the texture. It is computed from the object's position and the texture offset.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.texturePosition = new Grape2D.Vector();
	//computes the texture position.
	this.computeTexturePosition();
	/**
	 * Object's bounding box.
	 *
	 * @type {!Grape2D.Shape}
	 * @private
	 */
	this.boundingBox = options.boundingBox;
	/**
	 * Bounding box offset.
	 *
	 * @type {!Grape2D.Vector}
	 * @private
	 */
	this.boundingBoxOffset = options.boundingBoxOffset || new Grape2D.Vector();

	this.computeBoundingBoxPosition();

	/**
	 * Object cast shadow.
	 *
	 * @type {!boolean}
	 * @private
	 */
	this.castShadow = options.castShadow || false;
	/**
	 * Object can receive light.
	 *
	 * @type {!boolean}
	 * @private
	 */
	this.receiveLight = options.receiveLight || false;

};

Grape2D.Object2D.prototype = {
	constructor: Grape2D.Object2D,
	/**
	 * Checks if the object should be rendered.
	 *
	 * @return {!boolean} True if it can be rendered.
	 * @public
	 */
	isVisible: function () {
		return this.visible;
	},
	/**
	 * Sets if an object should be rendered.
	 *
	 * @param  {!boolean} visible True, so that it renders, false
	 *   otherwise.
	 * @public
	 */
	setVisible: function (visible) {
		this.visible = visible;
		return;
	},
	/**
	 * Gets the texture of the object.
	 *
	 * @return {!Grape2D.Texture} The texture of the object.
	 * @public
	 */
	getTexture: function () {
		return this.texture;
	},
	/**
	 * Sets the texture of the object.
	 *
	 * @param  {!Grape2D.Texture} texture The texture.
	 * @public
	 */
	setTexture: function (texture) {
		this.texture = texture;
		return;
	},
	/**
	 * Gets the bounding box of the object.
	 *
	 * @return {!Grape2D.Shape} The shape of the object.
	 * @public
	 */
	getBoundingBox: function () {
		return this.boundingBox;
	},
	/**
	 * Sets the bounding box of the object.
	 * Also, the position of the new bounding box, will be transformed
	 *   in the default offset of the bounding box.
	 *
	 * @param  {!Grape2D.Shape} boundingBox The bounding box.
	 * @public
	 */
	setBoundingBox: function (boundingBox) {
		this.boundingBox = boundingBox;
		this.computeBoundingBoxPosition();
		return;
	},
	/**
	 * Checks if the object can cast shadows.
	 *
	 * @return {!boolean} True if it cast shadows, false otherwise.
	 * @public
	 */
	canCastShadow: function () {
		return this.castShadow;
	},
	/**
	 * Sets if an object can cast shadows.
	 *
	 * @param  {!boolean} castShadow True to cast shadows, false
	 *   otherwise.
	 * @public
	 */
	setCastShadow: function (castShadow) {
		this.castShadow = castShadow;
		return;
	},
	/**
	 * Checks if an object can receive light.
	 *
	 * @return {!boolean} True if it receives light.
	 * @public
	 */
	canReceiveLight: function () {
		return this.receiveLight;
	},
	/**
	 * Sets if the object can receive light.
	 *
	 * @param  {!boolean} receiveLight True if it receives light.
	 * @public
	 */
	setReceiveLight: function (receiveLight) {
		this.receiveLight = receiveLight;
		return;
	},
	/**
	 * Gets the object position. Be careful, because it returns the
	 *   vector used by the object, and not a copy. Use it wisely.
	 *
	 * @return {!Grape2D.Vector} The position of the object.
	 * @public
	 */
	getPosition: function () {
		return this.position;
	},
	/**
	 * Sets the object position.
	 *
	 * @param  {!Grape2D.Vector} position The position of the object.
	 * @public
	 */
	setPosition: function (position) {
		this.position.set(position);
		this.computeBoundingBoxPosition();
		this.computeTexturePosition();
	},
	/**
	 * Sets the texture offset.
	 *
	 * @param  {!Grape2D.Vector} offset The offset of the texture, from
	 *   the object's position.
	 * @public
	 */
	setTextureOffset: function (offset) {
		this.textureOffset.set(offset);
		this.computeTexturePosition();
	},
	/**
	 * Gets the texture offset
	 *
	 * @return {!Grape2D.Vector} The texture offset.
	 * @public
	 */
	getTextureOffset: function () {
		return this.textureOffset;
	},
	/**
	 * Sets the bounding box offset.
	 *
	 * @param  {!Grape2D.Vector} offset The offset of the bounding
	 *   box, from the object's position.
	 * @public
	 */
	setBoundingBoxOffset: function (offset) {
		this.boundingBoxOffset.set(offset);
		this.computeBoundingBoxPosition();
	},
	/**
	 * Gets the bounding box offset
	 *
	 * @return {!Grape2D.Vector} The bounding box offset.
	 * @public
	 */
	getBoundingBoxOffset: function () {
		return this.boundingBoxOffset;
	},
	/**
	 * Computes the bounding box position, from the object's position
	 *   and bounding box offset.
	 * @protected
	 */
	computeBoundingBoxPosition: function () {
		this.boundingBox.setPosition(this.position);
		this.boundingBox.getPosition().add(this.boundingBoxOffset);
	},
	/**
	 * Gets the bounding box position.
	 *
	 * @return {!Grape2D.Vector} The center position of the bounding box.
	 * @public
	 */
	getBoundingBoxPosition: function () {
		return this.boundingBox.getPosition();
	},
	/**
	 * Computes the texture position of the object, from the object's
	 *   position and texture offset.
	 * @protected
	 */
	computeTexturePosition: function () {
		this.texturePosition.set(this.position).add(this.textureOffset);
	},
	/**
	 * Gets the texture position.
	 *
	 * @return {!Grape2D.Vector} The position of the texture
	 * @public
	 */
	getTexturePosition: function () {
		return this.texturePosition;
	},
	/**
	 * Renders the object to a renderer.
	 *
	 * @param  {!Grape2D.Renderer} renderer The place to render the
	 *   object.
	 * @param  {!Grape2D.Camera} camera The camera, that will
	 *   transform the positions.
	 * @public
	 */
	render: function (renderer, camera) {
		renderer.renderObject2D(this, camera);
	},
	/**
	 * Updates the object. This method should be refined in further
	 *   subclasses if needed be.
	 *
	 * @param  {!number} dt Time interval.
	 * @param  {!Grape2D.Scene} scene Scene where this object is.
	 * @public
	 */
	update: function (dt, scene) {}
};<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types';
import { addCollectiveData } from '../graphql/queries';
import withData from '../lib/withData';
import withLoggedInUser from '../lib/withLoggedInUser';
import withIntl from '../lib/withIntl';
import ErrorPage from '../components/ErrorPage';
import Collective from '../components/Collective';
import UserCollective from '../components/UserCollective';

class CollectivePage extends React.Component {

  static getInitialProps ({ query, res }) {

    if (res){
      res.setHeader('Cache-Control','public, max-age=300');
    }

    return { slug: query && query.slug, query }
  }

  static propTypes = {
    getLoggedInUser: PropTypes.func.isRequired,
    data: PropTypes.object.isRequired,
    query: PropTypes.object,
  };

  constructor(props) {
    super(props);
    this.state = {};
  }

  async componentDidMount() {
    const { getLoggedInUser } = this.props;
    const LoggedInUser = getLoggedInUser && await getLoggedInUser();
    this.setState({ LoggedInUser });
    window.OC = window.OC || {};
    window.OC.LoggedInUser = LoggedInUser;
  }

  shouldComponentUpdate(nextProps) {
    // It can be that Apollo is reseting data when navigating from a page to another
    // We try to detect that and prevent rendering
    // This is a workaround and the root cause should be ultimately fixed
    if (this.props.data.Collective && !nextProps.data.Collective) {
      return false;
    }
    return true;
  }

  render() {
    const { data, query } = this.props;
    const { LoggedInUser } = this.state;

    if (!data.Collective) return (<ErrorPage data={data} />);

    const collective = data.Collective;

    return (

        { collective.type === 'COLLECTIVE' &&
          <Collective
            collective={collective}
            LoggedInUser={LoggedInUser}
            query={query}
            />
        }
        { ['USER', 'ORGANIZATION'].includes(collective.type) &&
          <UserCollective
            collective={collective}
            LoggedInUser={LoggedInUser}
            query={query}
            />
        }

    );
  }
}

export default withData(withLoggedInUser(addCollectiveData(withIntl(CollectivePage))));
<commit_msg>reseting -> resetting<commit_after>import React from 'react'
import PropTypes from 'prop-types';
import { addCollectiveData } from '../graphql/queries';
import withData from '../lib/withData';
import withLoggedInUser from '../lib/withLoggedInUser';
import withIntl from '../lib/withIntl';
import ErrorPage from '../components/ErrorPage';
import Collective from '../components/Collective';
import UserCollective from '../components/UserCollective';

class CollectivePage extends React.Component {

  static getInitialProps ({ query, res }) {

    if (res){
      res.setHeader('Cache-Control','public, max-age=300');
    }

    return { slug: query && query.slug, query }
  }

  static propTypes = {
    getLoggedInUser: PropTypes.func.isRequired,
    data: PropTypes.object.isRequired,
    query: PropTypes.object,
  };

  constructor(props) {
    super(props);
    this.state = {};
  }

  async componentDidMount() {
    const { getLoggedInUser } = this.props;
    const LoggedInUser = getLoggedInUser && await getLoggedInUser();
    this.setState({ LoggedInUser });
    window.OC = window.OC || {};
    window.OC.LoggedInUser = LoggedInUser;
  }

  shouldComponentUpdate(nextProps) {
    // It can be that Apollo is resetting data when navigating from a page to another
    // We try to detect that and prevent rendering
    // This is a workaround and the root cause should be ultimately fixed
    if (this.props.data.Collective && !nextProps.data.Collective) {
      return false;
    }
    return true;
  }

  render() {
    const { data, query } = this.props;
    const { LoggedInUser } = this.state;

    if (!data.Collective) return (<ErrorPage data={data} />);

    const collective = data.Collective;

    return (

        { collective.type === 'COLLECTIVE' &&
          <Collective
            collective={collective}
            LoggedInUser={LoggedInUser}
            query={query}
            />
        }
        { ['USER', 'ORGANIZATION'].includes(collective.type) &&
          <UserCollective
            collective={collective}
            LoggedInUser={LoggedInUser}
            query={query}
            />
        }

    );
  }
}

export default withData(withLoggedInUser(addCollectiveData(withIntl(CollectivePage))));
<|endoftext|>


<commit_before>define([
    'require',
    '../lib/jquery.form/jquery.form',
    './inject'
], function(require) {
    var init = function($form, opts) {
        // ajaxify form
        $form.ajaxForm({
            // in plone we use this to figure out whether a form is
            // requested or submitted
            // XXX: consider setting this via $.ajaxSetup in a
            // specific application
            data: {submit: "submit"}
        });

        $form.ajaxError(function(ev, xhr, opts, error) {
            // ajaxHandlers are global, we are only interested in our form
            if (!(ev.target === $form[0])) return;

            // XXX: this needs to be solved differently
            var msg = [xhr.status, xhr.statusText, error, opts.url].join(' '),
                // XXX: error notification pattern!
                $error = $('
'
                           + '
Error
'
                           + '
'+msg+'
'
                           + '
');
            var inject = require('./inject');
            inject.append($error, $('body'));
            console.error(msg, xhr, opts);
        });

        $form.ajaxSuccess(function(ev, xhr, opts, data) {
            // ajaxHandlers are global, we are only interested in our form
            if (!(ev.target === $form[0])) return;

            // XXX: this needs to be solved differently
            if (!data) return;
            var $forms = $(data).find('form[id]');
            $forms.each(function() {
                var $form = $(this),
                    id = $(this).attr('id'),
                    $ourform = $('#' + id);
                if ($ourform.length > 0) {
                    $ourform.attr({action: $form.attr('action')});
                } else {
                    console.warn(
                        'Ignored form in respone data: not matching id', $form);
                }
            });
        });
    };

    return {
        markup_trigger: 'form.ajaxify',
        initialised_class: 'ajaxified',
        init: init
    };
});<commit_msg>it's jqxhr not the real xhr<commit_after>define([
    'require',
    '../lib/jquery.form/jquery.form',
    './inject'
], function(require) {
    var init = function($form, opts) {
        // ajaxify form
        $form.ajaxForm({
            // in plone we use this to figure out whether a form is
            // requested or submitted
            // XXX: consider setting this via $.ajaxSetup in a
            // specific application
            data: {submit: "submit"}
        });

        $form.ajaxError(function(ev, jqxhr, opts, error) {
            // ajaxHandlers are global, we are only interested in our form
            if (!(ev.target === $form[0])) return;

            // XXX: this needs to be solved differently
            var msg = [jqxhr.status, jqxhr.statusText, error, opts.url].join(' '),
                // XXX: error notification pattern!
                $error = $('
'
                           + '
Error
'
                           + '
'+msg+'
'
                           + '
');
            var inject = require('./inject');
            inject.append($error, $('body'));
            console.error(msg, jqxhr, opts);
        });

        $form.ajaxSuccess(function(ev, jqxhr, opts, data) {
            // ajaxHandlers are global, we are only interested in our form
            if (!(ev.target === $form[0])) return;

            // XXX: this needs to be solved differently
            if (!data) return;
            var $forms = $(data).find('form[id]');
            $forms.each(function() {
                var $form = $(this),
                    id = $(this).attr('id'),
                    $ourform = $('#' + id);
                if ($ourform.length > 0) {
                    $ourform.attr({action: $form.attr('action')});
                } else {
                    console.warn(
                        'Ignored form in respone data: not matching id', $form);
                }
            });
        });
    };

    return {
        markup_trigger: 'form.ajaxify',
        initialised_class: 'ajaxified',
        init: init
    };
});<|endoftext|>


<commit_before>var browserify = require('browserify');
var brfs = require('brfs');
var through = require('through');
var fs = require('fs');

// enable if you are running:
//  sudo npm install -g corsproxy
//var CORS_PROXY = 'http://localhost:9292/';
var CORS_PROXY = undefined;

var browserify_builtins = require('browserify/lib/builtins');
browserify_builtins.child_process = 'child_process.js';
browserify_builtins.fs = require.resolve('browserify-fs'); // TODO: what is the api equivalent of cli -r fs:browserify-fs?
browserify_builtins['graceful-fs'] = browserify_builtins.fs;

var b = browserify();

//b.require('browserify-fs', {expose:'fs'});

//b.transform('brfs');

var textReplacements = [
  [/require\.resolve/g, 'require'], // TODO: what is require.resolve for browserify?

  // semi-dynamic fs.readFileSync()
  [/fs\.readFileSync/g, 'window.staticReadFileSync'],
  [/require\('fs'\)\.readFileSync/g, 'window.staticReadFileSync'],

  // semi-dynamic require()

  // node_modules/npm/lib/npm.js
  [/require\(__dirname\+"\/"\+a\+"\.js"\)/g, 'window.npmCommandRequire(__dirname+"/"+a+".js")'],

  // npm/node_modules/npm-registry-client/index.js
  [/client\[name\] = require\(entry\)/g, 'client[name] = window.npmRegistryClientRequire(entry)'],

  // npm/node_modules/npm-registry-client/lib/request.js
  [/(var req = request\(opts, decodeResponseBody\(done\)\))/g,
    'opts.followRedirect = false; ' // unsupported option by browser-request TODO: support it? via a corsproxy?
    + (CORS_PROXY ? 'opts.url = "' + CORS_PROXY + '" + opts.url.replace(/^https?:\\/\\//, ""); ' : '')
    + '$1;\n'
    // browser-request doesn't fully implement the request API :(
    + 'req.on = function(name,cb) {\n' // TODO: have browser-request inherit EventEmitter, or Stream..
    + '   if (name==="error") req.onerror = cb;\n'
    + '   else console.log("request on",name,cb);\n'
    + '};\n'
    + 'req.headers = {};\n' // browser-request missing headers too
  ],
  [/'followRedirect'/, "'followRedirectX'"], // suppress "option.followRedirect is not supported" error https://github.com/iriscouch/browser-request/issues/37

  // node_modules/npm/node_modules/npm-registry-client/lib/initialize.js
  //  workaround https://github.com/iriscouch/browser-request/pull/44 browser-request cannot request URL objects
  [/url          : uri/, 'url: (uri.href ? uri.href : uri)'],

  // node_modules/npm/node_modules/npm-registry-client/lib/fetch.js
  //  browser-request() requires a callback, even though request() doesn't
  [/cb\(null, request\(opts\)\)/g, 'cb(null, request(opts, function(){ console.log("request ",arguments); }));'],
];

// Included file data for staticReadFileSync; this is similar to
// brfs's fs.readFileSync transclusion but ours is looked up dynamically,
// because brfs can only replace files from static source code analysis.
var preloadedFilenames = [
  'node_modules/browserify/node_modules/umd/template.js',
  'node_modules/browserify/node_modules/browser-pack/_prelude.js',
  'node_modules/npm/package.json',
];

// directly include rfile TODO: use brfs, but it replaces fs.readFileSync
b.transform(function(s) {
  var data = '';
  return through(write, end);

  function write(buf) { data += buf; }
  function end() {
    for (var i = 0; i < textReplacements.length; i += 1) {
      var regex = textReplacements[i][0];
      var replacement = textReplacements[i][1];

      data  = data.replace(regex, replacement);
    }

    this.queue(data);
    this.queue(null);
  };
}, { global: true });

b.add('./webnpm.js');

var preloadedReadFileSyncs = {};
for (var i = 0; i < preloadedFilenames.length; i += 1) {
  var path = preloadedFilenames[i];
  preloadedReadFileSyncs['/' + path] = JSON.stringify(fs.readFileSync(path, 'utf8'));
}

process.stdout.write('window.preloadedReadFileSyncs = ' + JSON.stringify(preloadedReadFileSyncs) + '\n;');

b.bundle().pipe(process.stdout);

<commit_msg>Remove hacks for browser-request<commit_after>var browserify = require('browserify');
var brfs = require('brfs');
var through = require('through');
var fs = require('fs');

// enable if you are running:
//  sudo npm install -g corsproxy
//var CORS_PROXY = 'http://localhost:9292/';
var CORS_PROXY = undefined;

var browserify_builtins = require('browserify/lib/builtins');
browserify_builtins.child_process = 'child_process.js';
browserify_builtins.fs = require.resolve('browserify-fs'); // TODO: what is the api equivalent of cli -r fs:browserify-fs?
browserify_builtins['graceful-fs'] = browserify_builtins.fs;

var b = browserify();

//b.require('browserify-fs', {expose:'fs'});

//b.transform('brfs');

var textReplacements = [
  [/require\.resolve/g, 'require'], // TODO: what is require.resolve for browserify?

  // semi-dynamic fs.readFileSync()
  [/fs\.readFileSync/g, 'window.staticReadFileSync'],
  [/require\('fs'\)\.readFileSync/g, 'window.staticReadFileSync'],

  // semi-dynamic require()

  // node_modules/npm/lib/npm.js
  [/require\(__dirname\+"\/"\+a\+"\.js"\)/g, 'window.npmCommandRequire(__dirname+"/"+a+".js")'],

  // npm/node_modules/npm-registry-client/index.js
  [/client\[name\] = require\(entry\)/g, 'client[name] = window.npmRegistryClientRequire(entry)'],

  // npm/node_modules/npm-registry-client/lib/request.js
  [/(var req = request\(opts, decodeResponseBody\(done\)\))/g,
    (CORS_PROXY ? 'opts.url = "' + CORS_PROXY + '" + opts.url.replace(/^https?:\\/\\//, ""); ' : '')
    + '$1;\n'
  ],

  // node_modules/npm/node_modules/npm-registry-client/lib/initialize.js
  //  workaround https://github.com/iriscouch/browser-request/pull/44 browser-request cannot request URL objects
  [/url          : uri/, 'url: (uri.href ? uri.href : uri)'],

  // node_modules/npm/node_modules/npm-registry-client/lib/fetch.js
  //  browser-request() requires a callback, even though request() doesn't
  [/cb\(null, request\(opts\)\)/g, 'cb(null, request(opts, function(){ console.log("request ",arguments); }));'],
];

// Included file data for staticReadFileSync; this is similar to
// brfs's fs.readFileSync transclusion but ours is looked up dynamically,
// because brfs can only replace files from static source code analysis.
var preloadedFilenames = [
  'node_modules/browserify/node_modules/umd/template.js',
  'node_modules/browserify/node_modules/browser-pack/_prelude.js',
  'node_modules/npm/package.json',
];

// directly include rfile TODO: use brfs, but it replaces fs.readFileSync
b.transform(function(s) {
  var data = '';
  return through(write, end);

  function write(buf) { data += buf; }
  function end() {
    for (var i = 0; i < textReplacements.length; i += 1) {
      var regex = textReplacements[i][0];
      var replacement = textReplacements[i][1];

      data  = data.replace(regex, replacement);
    }

    this.queue(data);
    this.queue(null);
  };
}, { global: true });

b.add('./webnpm.js');

var preloadedReadFileSyncs = {};
for (var i = 0; i < preloadedFilenames.length; i += 1) {
  var path = preloadedFilenames[i];
  preloadedReadFileSyncs['/' + path] = JSON.stringify(fs.readFileSync(path, 'utf8'));
}

process.stdout.write('window.preloadedReadFileSyncs = ' + JSON.stringify(preloadedReadFileSyncs) + '\n;');

b.bundle().pipe(process.stdout);

<|endoftext|>


<commit_before>const _ = require('lodash');
var rewire = require("rewire");
var n = rewire(require.resolve('./newman-ext.js'));

let path = 'C:/tmp/euat.json';
let initparams = _.concat(process.argv, 'run', './tests/sample.postman_collection.json', '--demo');
// let initparams = _.concat(process.argv, 'run', 'C:/Users/aadm221/Documents/workspace/esb-automation-tests_git/TestCollections/Test Services.postman_collection.json', '--demo');
var program = rewire(require.resolve('commander'));
var cmd = rewire(require.resolve('./lib/cmd.js'));
cmd.__set__('program', program);
n.__set__('cmd', cmd);

// let options = n.run(_.concat(initparams, '-e', "C:/Users/aadm221/Documents/workspace/esb-automation-tests_git/TestEnvironments/EUAT.json", '-g', "C:/Users/aadm221/Documents/workspace/esb-automation-tests_git/TestEnvironments/globals.json", '-r', "cli,html", '--reporter-html-template', "C:/Users/aadm221/Documents/workspace/esb-automation-tests_git/TestResultTemplate/template-new-merged.hbs", '-k', '--ignore-redirects', '--folder', "Login to VSL - YearlyEvents", '--folder', "S01 - VHRV", '--folder', "Logout of VSL - YearlyEvents"));
let executions = n.run(_.concat(initparams, '--exclude', 'one'));
console.log(executions);
// console.log(options);<commit_msg>Delete demo.js<commit_after><|endoftext|>


<commit_before>"use strict";

module.exports = {
    evaldiff : evaldiff
}

var s3 = require('./s3.js');
var _ = require('underscore');

function evaldiff(current, prev) {

    console.log('DIFF');
    var delta = _.clone(current);

    // aggregates
    var p_agg = prev.data.aggregates[0];
    var c_agg = current.data.aggregates[0];
    var delta_agg = c_agg.value - p_agg.value;
    if (delta_agg != 0) {
            delta.data.aggregates[0].delta = delta_agg;
            console.log('Aggegate diff found: '+delta_agg);
    }
    // map each row to the first data cell value

    var objs = [];

    var p_row_map = mappifyRows(prev.data.rows, prev.headers, objs);
    var c_row_map = mappifyRows(current.data.rows, current.headers, objs);

    console.log('prev: '+JSON.stringify(p_row_map, null, 4));
    console.log('current: '+JSON.stringify(c_row_map, null, 4));

    var sobjs = _.union(_.keys(p_row_map), _.keys(c_row_map));

    console.log(sobjs);
    for (var i = 0; i < sobjs.length; i++ ) {
        var sobj = sobjs[i];
        console.log('eval: '+sobj);
        var p = p_row_map[sobj];
        var c = c_row_map[sobj];

        if (p && !c) {
            console.log('p has value, not c: '+p);
        }
        if (c && !p) {
            console.log('c has value, not p: '+c);
        }

        if (c && p) {
            for (var h = 0; h < current.headers.length; h++) {
                var header = current.headers[h].label;
                var pval = p[header];
                var cval = c[header];

                if (pval && !cval) {
                    console.log(header+' previous entry was deleted: '+pval);
                } else if (cval && !pval) {
                    console.log(header+' previous entry not present '+cval);
                } else {

                    if (_.isNumber(cval) && _.isNumber(pval)) {
                        var delta_val = cval - pval;
                        if (delta_val != 0) {
                            console.log('obj: '+sobj+' header: '+header+ ' delta: '+delta_val);
                            addDelta(delta, sobj, header, delta_val);
                        }
                    } else if (cval != pval) {
                        console.log('obj: '+sobj+' header: '+header+ ' new: '+cval+ ' old: '+pval);
                        addDelta(delta, sobj, header, {"old":pval});
                    }
                }

            }
        }

    }

    console.log('++++++++++++++++++++++++++');
    console.log(JSON.stringify(delta, null, 4));

    return delta;

}

// known to be super slow
function addDelta (delta, sobj, header, change) {
    var header_index = indexOfHeader(delta.headers, header);
    for (var row_i = 0; row_i < delta.data.rows.length; row_i++ ) {
        var value = delta.data.rows[row_i].dataCells[0].value;
        if (value === sobj) {
            delta.data.rows[row_i].dataCells[header_index].delta = change;
            return;
        }
    }
}

function indexOfHeader (headers, header) {
    for (var h = 0; h < headers.length; h++) {
        var label = headers[h].label;
        if (label === header) {
            return h;
        }
    }
}

function mappifyRows(rows, headers) {
    var row_map = {};
    for (var i = 0; i < rows.length; i++) {
        var rowmap = {};
        var row = rows[i].dataCells;
        var firstVal = row[0].value;

        for (var h = 0; h < headers.length; h++) {
            var header = headers[h].label;
            var value = row[h].value;

            // currency is stored w/ the currency type, we're ignoring that for now
            if (headers[h].dataType === 'currency') {
                value = row[h].value.amount;
            }
            rowmap[header] = value;
        }
        row_map[firstVal] = rowmap;
    }
    return row_map;
}
<commit_msg>handle null currency<commit_after>"use strict";

module.exports = {
    evaldiff : evaldiff
}

var s3 = require('./s3.js');
var _ = require('underscore');

function evaldiff(current, prev) {

    //console.log('DIFF');
    var delta = _.clone(current);

    // aggregates
    var p_agg = prev.data.aggregates[0];
    var c_agg = current.data.aggregates[0];
    var delta_agg = c_agg.value - p_agg.value;
    if (delta_agg != 0) {
            delta.data.aggregates[0].delta = delta_agg;
            console.log('Aggegate diff found: '+delta_agg);
    }
    // map each row to the first data cell value

    var objs = [];

    var p_row_map = mappifyRows(prev.data.rows, prev.headers, objs);
    var c_row_map = mappifyRows(current.data.rows, current.headers, objs);

    // console.log('prev: '+JSON.stringify(p_row_map, null, 4));
    // console.log('current: '+JSON.stringify(c_row_map, null, 4));

    var sobjs = _.union(_.keys(p_row_map), _.keys(c_row_map));

    //console.log(sobjs);
    for (var i = 0; i < sobjs.length; i++ ) {
        var sobj = sobjs[i];
        //console.log('eval: '+sobj);
        var p = p_row_map[sobj];
        var c = c_row_map[sobj];

        if (p && !c) {
            console.log('p has value, not c: '+p);
        }
        if (c && !p) {
            console.log('c has value, not p: '+c);
        }

        if (c && p) {
            for (var h = 0; h < current.headers.length; h++) {
                var header = current.headers[h].label;
                var pval = p[header];
                var cval = c[header];

                if (pval && !cval) {
                    console.log(header+' previous entry was deleted: '+pval);
                } else if (cval && !pval) {
                    console.log(header+' previous entry not present '+cval);
                } else {

                    if (_.isNumber(cval) && _.isNumber(pval)) {
                        var delta_val = cval - pval;
                        if (delta_val != 0) {
                            console.log('obj: '+sobj+' header: '+header+ ' delta: '+delta_val);
                            addDelta(delta, sobj, header, delta_val);
                        }
                    } else if (cval != pval) {
                        console.log('obj: '+sobj+' header: '+header+ ' new: '+cval+ ' old: '+pval);
                        addDelta(delta, sobj, header, {"old":pval});
                    }
                }

            }
        }

    }

    // console.log('++++++++++++++++++++++++++');
    // console.log(JSON.stringify(delta, null, 4));

    return delta;

}

// known to be super slow
function addDelta (delta, sobj, header, change) {
    var header_index = indexOfHeader(delta.headers, header);
    for (var row_i = 0; row_i < delta.data.rows.length; row_i++ ) {
        var value = delta.data.rows[row_i].dataCells[0].value;
        if (value === sobj) {
            delta.data.rows[row_i].dataCells[header_index].delta = change;
            return;
        }
    }
}

function indexOfHeader (headers, header) {
    for (var h = 0; h < headers.length; h++) {
        var label = headers[h].label;
        if (label === header) {
            return h;
        }
    }
}

function mappifyRows(rows, headers) {
    var row_map = {};
    for (var i = 0; i < rows.length; i++) {
        var rowmap = {};
        var row = rows[i].dataCells;
        var firstVal = row[0].value;

        for (var h = 0; h < headers.length; h++) {
            var header = headers[h].label;
            var value = row[h].value;

            // currency is stored w/ the currency type, we're ignoring that for now
            if (headers[h].dataType === 'currency') {

                //console.log('header: '+h+' row: '+JSON.stringify(row, null, 4));
                if (row[h].value) {
                    value = row[h].value.amount;
                }
            }
            rowmap[header] = value;
        }
        row_map[firstVal] = rowmap;
    }
    return row_map;
}
<|endoftext|>


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

var abbrev = require('abbrev')
  , request = require('request')
  , optimist = require('optimist')
  , colors = require('colors');

var checkers = { github: github, harvest: harvest }
  , services = Object.keys(checkers)
  , abbr = abbrev(services)
  , immediate = typeof setImmediate === 'function' ? setImmediate : process.nextTick;

abbr.gh = 'github';
abbr.hv = 'harvest';

var targets = optimist
  .usage('Usage: down [service]\n\nSupported Services:\n' + services.join('\n'))
  .demand(1).argv._;

targets.forEach(function start(service) {
  if (!(service in abbr)) {
    console.error("Unknown service: " + service);
    return false;
  }

  service = abbr[service];

  var checker = checkers[service];
  immediate(function checkOnce() {
    checker(function(e, result, message) {
      var tag = e ? '  ERR '.red : result ? '   UP '.green : ' DOWN '.red;

      console.log(tag + '[' + service + '] ' + message);
      setTimeout(checkOnce, 1000);
    });
  });
});

function github(callback) {
  request('https://status.github.com/api/last-message.json', function(e, resp, body) {
    if (e) return callback(e)
    if (!resp || resp.statusCode !== 200) return callback(new Error("Status not 200."));

    if (typeof body === 'string') body = JSON.parse(body);
    callback(null, body.status === 'good', body.body || '');
  });
}

function harvest(callback) {
  request('http://harveststatus.com/status.json', function(e, resp, body) {
    if (e) return callback(e);
    if (!resp || resp.statusCode !== 200) return callback(new Error("Status not 200."));

    if (typeof body === 'string') body = JSON.parse(body);
    callback(null, body.status === 'up',
      'last response time: ' + body['last_response_time']);
  });
}

<commit_msg>Properly prints error messages.<commit_after>#!/usr/bin/env node

var abbrev = require('abbrev')
  , request = require('request')
  , optimist = require('optimist')
  , colors = require('colors');

var checkers = { github: github, harvest: harvest }
  , services = Object.keys(checkers)
  , abbr = abbrev(services)
  , immediate = typeof setImmediate === 'function' ? setImmediate : process.nextTick;

abbr.gh = 'github';
abbr.hv = 'harvest';

var targets = optimist
  .usage('Usage: down [service]\n\nSupported Services:\n' + services.join('\n'))
  .demand(1).argv._;

targets.forEach(function start(service) {
  if (!(service in abbr)) {
    console.error("Unknown service: " + service);
    return false;
  }

  service = abbr[service];

  var checker = checkers[service];
  immediate(function checkOnce() {
    checker(function(e, result, message) {
      var tag = e ? '  ERR '.red : result ? '   UP '.green : ' DOWN '.red;

      message = e && e.message || message;
      console.log(tag + '[' + service + '] ' + message);
      setTimeout(checkOnce, 1000);
    });
  });
});

function github(callback) {
  request('https://status.github.com/api/last-message.json', function(e, resp, body) {
    if (e) return callback(e)
    if (!resp || resp.statusCode !== 200) return callback(new Error("Status not 200."));

    if (typeof body === 'string') body = JSON.parse(body);
    callback(null, body.status === 'good', body.body || '');
  });
}

function harvest(callback) {
  request('http://harveststatus.com/status.json', function(e, resp, body) {
    if (e) return callback(e);
    if (!resp || resp.statusCode !== 200) return callback(new Error("Status not 200."));

    if (typeof body === 'string') body = JSON.parse(body);
    callback(null, body.status === 'up',
      'last response time: ' + body['last_response_time']);
  });
}

<|endoftext|>


<commit_before>var NUMBER_OF_SQUARE = 17;
var PLAYGROUND_WIDTH = 600;
var SQUARE_WIDTH = PLAYGROUND_WIDTH / NUMBER_OF_SQUARE;
var MAX_CHARACTER = 5;

var CHARACTER_PARAMETER = [
  {
    "id": 0,
    "name": "daisyo",
    "cost": 1,
    "hitPoint": 3,
    "attack": 1,
    "attacableRange": 2,
    "move": 1
  },
  {
    "id": 1,
    "name": "pupepon",
    "cost": 3,
    "hitPoint": 7,
    "attack": 3,
    "attacableRange": 2,
    "move": 3
  },
  {
    "id": 2,
    "name": "haseaki",
    "cost": 2,
    "hitPoint": 3,
    "attack": 2,
    "attacableRange": 2,
    "move": 2
  },
  {
    "id": 3,
    "name": "miho",
    "cost": 5,
    "hitPoint": 8,
    "attack": 3,
    "attacableRange": 2,
    "move": 2
  }
]

character = function(id, posx, posy, charaId) {
  this.posx = posx;
  this.posy = posy;
  this.charaId = charaId;
  this.id = id;
  this.name = CHARACTER_PARAMETER[charaId].name;
  this.cost = CHARACTER_PARAMETER[charaId].cost;
  this.hitPoint = CHARACTER_PARAMETER[charaId].hitPoint;
  this.attack = CHARACTER_PARAMETER[charaId].attack;
  this.attacableRange = CHARACTER_PARAMETER[charaId].attacableRange;
  this.move = CHARACTER_PARAMETER[charaId].move;
}

test_Friend = [];
test_Friend[0] = new character(0, 9, 9, 0);
test_Friend[1] = new character(1, 8, 9, 3);
test_Friend[2] = new character(2, 10, 9, 3);
test_Friend[3] = new character(3, 9, 8, 3);
test_Friend[4] = new character(4, 9, 10, 3);

test_Enemy = [];
test_Enemy[0] = new character(100, 3, 3, 0);
test_Enemy[1] = new character(101, 2, 3, 2);
test_Enemy[2] = new character(102, 4, 3, 3);
test_Enemy[3] = new character(103, 3, 2, 1);
test_Enemy[4] = new character(104, 3, 4, 1);

var CHARACTER_PARAMETER = [
  {
    "name": "daisyo",
    "cost": 1,
    "hitPoint": 3,
    "attack": 1,
    "attacableRange": 2,
    "move": 1
  },
  {
    "name": "pupepon",
    "cost": 3,
    "hitPoint": 7,
    "attack": 3,
    "attacableRange": 2,
    "move": 3
  },
  {
    "name": "haseaki",
    "cost": 2,
    "hitPoint": 3,
    "attack": 2,
    "attacableRange": 2,
    "move": 2
  },
  {
    "name": "miho",
    "cost": 5,
    "hitPoint": 8,
    "attack": 3,
    "attacableRange": 2,
    "move": 2
  }
]

character = function(posx, posy,charaId) {
  this.posx = posx;
  this.posy = posy;
  this.charaId = charaId;
  this.name = CHARACTER_PARAMETER[charaId].name;
  this.cost = CHARACTER_PARAMETER[charaId].cost;
  this.hitPoint = CHARACTER_PARAMETER[charaId].hitPoint;
  this.attack = CHARACTER_PARAMETER[charaId].attack;
  this.attacableRange = CHARACTER_PARAMETER[charaId].attacableRange;
  this.move = CHARACTER_PARAMETER[charaId].move;
}

// Declarations
var selectX = -1;
var selectY = -1;
var selectedCharacter = -1;
var overX = -1;
var overY = -1;
var onFiled = false;
var moveFlg = -1;

// ==============================================================================================
$(function(){
  /* canvas */
  playGround = $("#play-ground").get(0);
  ctxCanvas  = playGround.getContext("2d");
  canvasPosition = $('#play-ground').position();

  /* Event */
  $('#play-ground').bind({
    "mousemove": function(e){
    	onFiled = true;
      redraw(e, onFiled);
    },
    "mouseout": function(e){
    	onFiled = false;
    	redraw(e, onFiled);
    },
    "click": function(e){
      selectCharacter(e, onFiled);
      redraw(e);
    }
  });

  /* For Debug */
  console.log(CHARACTER_PARAMETER[3].name);

});

// ==============================================================================================
function redraw(e, flag){
  ctxCanvas.clearRect(0, 0, PLAYGROUND_WIDTH, PLAYGROUND_WIDTH);
  if (flag === true) {
  	drawHoverMarker(e);
	}

  //drawCharacter();
  for (var i = 0; i < 5; i++){
      ctxCanvas.fillStyle = "blue";
      drawCharacter(test_Friend[i].posx, test_Friend[i].posy, test_Friend[i].charaId);
      ctxCanvas.fillStyle = "red";
      drawCharacter(test_Enemy[i].posx, test_Enemy[i].posy, test_Enemy[i].charaId);
  }

  drawField();
}

function drawHoverMarker(e){
    if (!e) {
      console.log("drawHoverMarker !e");
    } else {
      overX = (e.pageX - canvasPosition.left) / SQUARE_WIDTH;
      overY = (e.pageY - canvasPosition.top) / SQUARE_WIDTH;

      var obj = convertPosition(overX, overY, false);
      obj.x -= SQUARE_WIDTH / 2;
      obj.y -= SQUARE_WIDTH / 2;
    };

    ctxCanvas.lineWidth = 0.0;
    ctxCanvas.fillStyle = 'rgb(192, 80, 77)';
    ctxCanvas.globalAlpha = 0.7;
    ctxCanvas.beginPath();
    ctxCanvas.fillRect(obj.x, obj.y, SQUARE_WIDTH, SQUARE_WIDTH);
    ctxCanvas.stroke();
}

function drawCharacter(posx,posy,charaId){
  var obj = convertPosition(posx, posy, false);
  ctxCanvas.font = "18px 'MS Pゴシック'";
  switch(charaId){
    case 0:
      ctxCanvas.fillText("D", obj.x, obj.y);
      break;
    case 1:
      ctxCanvas.fillText("P", obj.x, obj.y);
      break;
    case 2:
      ctxCanvas.fillText("H", obj.x, obj.y);
      break;
    case 3:
      ctxCanvas.fillText("M", obj.x, obj.y);
      break;
  }
  ctxCanvas.stroke();
}

function drawField(){

  //setting
  ctxCanvas.globalAlpha = 1.0;

  for (var i = 0; i <= 17; i++) {
    if (i === 0 || i === NUMBER_OF_SQUARE) {
      ctxCanvas.beginPath();
      ctxCanvas.lineWidth = 10.0;
    } else {
      ctxCanvas.beginPath();
      ctxCanvas.lineWidth = 1.0;
    }

    //draw
    ctxCanvas.moveTo(i * SQUARE_WIDTH, 0);
    ctxCanvas.lineTo(i * SQUARE_WIDTH, PLAYGROUND_WIDTH);
    ctxCanvas.stroke();
    ctxCanvas.moveTo(0, i * SQUARE_WIDTH);
    ctxCanvas.lineTo(PLAYGROUND_WIDTH, i * SQUARE_WIDTH);
    ctxCanvas.stroke();
  }

}

function selectCharacter(e){
  /*
  (selectY, selectX)
  */
  if (e) {
    selectX = Math.floor((e.pageX - canvasPosition.left) / SQUARE_WIDTH);
    selectY = Math.floor((e.pageY - canvasPosition.top) / SQUARE_WIDTH);
  };

  // クリックしたとこのキャラを検索。
  // 同じキャラが選択されたとき or 見つからなかったとき、-1を代入。
  var temp = searchCharacter(selectX, selectY, 0, true);
  if (selectedCharacter === temp[1] || temp[0] === false) {
    selectedCharacter = -1;
  } else {
    selectedCharacter = temp[1];
  }

  moveCharacter(selectX,selectY,moveFlg);

  if (selectedCharacter < 100 && selectedCharacter != -1){
    moveFlg = selectedCharacter;
  } else {
    moveFlg = -1;
  }

  var targetCharacter = getCharacterState(selectedCharacter);
  attack(selectedCharacter);

  // クリックしたとこ以外の、距離が1(隣接する)キャラを検索。
  temp = searchCharacter(selectX, selectY, 1, false);
}

function moveCharacter(x,y,charaId){
  //前回味方が選択された状態で、何もない又は自機の場所が選択されたら
  if (moveFlg <100 && moveFlg != -1 && selectedCharacter== -1){
    var lx,ly;

    lx = test_Friend[charaId].posx;
    ly = test_Friend[charaId].posy;

    //x,yが移動範囲内なら
    if(Math.abs(x-lx) + Math.abs(y-ly) <= test_Friend[charaId].move){
    test_Friend[charaId].posx = x;
    test_Friend[charaId].posy = y;
    }else{
      console.log("This postion protruding from moverenge")
    }
  }

}

function searchCharacter(x, y, range, flag){
  /*
    x, y はマスの座標を取る。
    flag:
     true: クリックしたところを含む
     false: クリックしたところを含まない
  */
  var foundCharacter = [];
  foundCharacter.push(false);

    var tx = x - range; //検索範囲の一番左のマス
    var ty = y - range; //検索範囲の一番上のマス
    var range = 2 * range + 1;

    for (var i = 0; i < range; i++) {
      for (var j = 0; j < range; j++) {
        for (var k = 0; k < MAX_CHARACTER; k++){
          if(test_Friend[k].posx === tx + i && test_Friend[k].posy === ty + j){
            foundCharacter.push(test_Friend[k].id);
          }
          if(test_Enemy[k].posx === tx + i && test_Enemy[k].posy === ty + j){
            foundCharacter.push(test_Enemy[k].id);
          }
        }
      }
    }

  if (flag === false) {
    var temp = searchCharacter(x, y, 0, true);
    for(var i = 1; i <= foundCharacter.length; i++){
      if (foundCharacter[i] === temp[1]){
        foundCharacter.splice(i, 1);
      }
    }
  }

  if (typeof foundCharacter[1] === 'undefined') {
    return foundCharacter;
  } else {
    foundCharacter[0] = true;
    return foundCharacter;
  }

}

function getCharacterState(keyId){
  /*
    引数にidを取る。（配列不可）
    マッチしたキャラを返す。
  */
  for (var i = 0; i < MAX_CHARACTER; i++) {
    if (test_Enemy[i].id === keyId) {
      var result = test_Enemy[i];
    };
    if (test_Friend[i].id === keyId) {
      var result = test_Friend[i];
    };
  }

  if (!result) {
    return false;
  } else {
    return result;
  }
}
// ==============================================================================================
function attack(attakerId){
  var attaker = getCharacterState(attakerId);
  var defender = searchCharacter(attaker.posx, attaker.posy, attaker.attacableRange, false);

  // 味方のIDをdefenderリストから削除
  if (attakerId < 100) {
    for(var i = defender.length; i > 0; i--){
      if (defender[i] < 100){
        defender.splice(i, 1);
      }
    }
  } else {
    for(var i = defender.length; i > 0; i--){
      if (defender[i] >= 100){
        defender.splice(i, 1);
      }
    }
  }
  // 攻撃
  for (var i = 1; i <= defender.length; i++) {
    getCharacterState(defender[i]).hitPoint -= attaker.attack;
    if (getCharacterState(defender[i]).hitPoint <= 0) {
      console.log('dead');
    };
  };
}

// ==============================================================================================
/*
  posX: x座標,
  posY: y座標,
  flag:
    true : 座標 -> マス
    false: マス   -> 座標
*/
function convertPosition(posX, posY, flag) {
  var canvasPosition = $('#play-ground').position();
  var tx;
  var ty;

  posX = Math.floor(posX);
  posY = Math.floor(posY);

  if (flag === true) {
    tx = posX / SQUARE_WIDTH;
    ty = posY / SQUARE_WIDTH;

    return {x: Math.floor(tx), y: Math.floor(ty)}
  }
  else if (flag === false) {
    tx = (posX + 1) * (SQUARE_WIDTH) - (SQUARE_WIDTH / 2);
    ty = (posY + 1) * (SQUARE_WIDTH) - (SQUARE_WIDTH / 2);

    return {x: Math.floor(tx), y: Math.floor(ty)}
  }

  // 失敗したときのために
  return {x: -1, y: -1}
};
<commit_msg>delete CHARACTER_PARAMETER<commit_after>var NUMBER_OF_SQUARE = 17;
var PLAYGROUND_WIDTH = 600;
var SQUARE_WIDTH = PLAYGROUND_WIDTH / NUMBER_OF_SQUARE;
var MAX_CHARACTER = 5;

var CHARACTER_PARAMETER = [
  {
    "id": 0,
    "name": "daisyo",
    "cost": 1,
    "hitPoint": 3,
    "attack": 1,
    "attacableRange": 2,
    "move": 1
  },
  {
    "id": 1,
    "name": "pupepon",
    "cost": 3,
    "hitPoint": 7,
    "attack": 3,
    "attacableRange": 2,
    "move": 3
  },
  {
    "id": 2,
    "name": "haseaki",
    "cost": 2,
    "hitPoint": 3,
    "attack": 2,
    "attacableRange": 2,
    "move": 2
  },
  {
    "id": 3,
    "name": "miho",
    "cost": 5,
    "hitPoint": 8,
    "attack": 3,
    "attacableRange": 2,
    "move": 2
  }
]

character = function(id, posx, posy, charaId) {
  this.posx = posx;
  this.posy = posy;
  this.charaId = charaId;
  this.id = id;
  this.name = CHARACTER_PARAMETER[charaId].name;
  this.cost = CHARACTER_PARAMETER[charaId].cost;
  this.hitPoint = CHARACTER_PARAMETER[charaId].hitPoint;
  this.attack = CHARACTER_PARAMETER[charaId].attack;
  this.attacableRange = CHARACTER_PARAMETER[charaId].attacableRange;
  this.move = CHARACTER_PARAMETER[charaId].move;
}

test_Friend = [];
test_Friend[0] = new character(0, 9, 9, 0);
test_Friend[1] = new character(1, 8, 9, 3);
test_Friend[2] = new character(2, 10, 9, 3);
test_Friend[3] = new character(3, 9, 8, 3);
test_Friend[4] = new character(4, 9, 10, 3);

test_Enemy = [];
test_Enemy[0] = new character(100, 3, 3, 0);
test_Enemy[1] = new character(101, 2, 3, 2);
test_Enemy[2] = new character(102, 4, 3, 3);
test_Enemy[3] = new character(103, 3, 2, 1);
test_Enemy[4] = new character(104, 3, 4, 1);

character = function(posx, posy,charaId) {
  this.posx = posx;
  this.posy = posy;
  this.charaId = charaId;
  this.name = CHARACTER_PARAMETER[charaId].name;
  this.cost = CHARACTER_PARAMETER[charaId].cost;
  this.hitPoint = CHARACTER_PARAMETER[charaId].hitPoint;
  this.attack = CHARACTER_PARAMETER[charaId].attack;
  this.attacableRange = CHARACTER_PARAMETER[charaId].attacableRange;
  this.move = CHARACTER_PARAMETER[charaId].move;
}

// Declarations
var selectX = -1;
var selectY = -1;
var selectedCharacter = -1;
var overX = -1;
var overY = -1;
var onFiled = false;
var moveFlg = -1;

// ==============================================================================================
$(function(){
  /* canvas */
  playGround = $("#play-ground").get(0);
  ctxCanvas  = playGround.getContext("2d");
  canvasPosition = $('#play-ground').position();

  /* Event */
  $('#play-ground').bind({
    "mousemove": function(e){
    	onFiled = true;
      redraw(e, onFiled);
    },
    "mouseout": function(e){
    	onFiled = false;
    	redraw(e, onFiled);
    },
    "click": function(e){
      selectCharacter(e, onFiled);
      redraw(e);
    }
  });

  /* For Debug */
  console.log(CHARACTER_PARAMETER[3].name);

});

// ==============================================================================================
function redraw(e, flag){
  ctxCanvas.clearRect(0, 0, PLAYGROUND_WIDTH, PLAYGROUND_WIDTH);
  if (flag === true) {
  	drawHoverMarker(e);
	}

  //drawCharacter();
  for (var i = 0; i < 5; i++){
      ctxCanvas.fillStyle = "blue";
      drawCharacter(test_Friend[i].posx, test_Friend[i].posy, test_Friend[i].charaId);
      ctxCanvas.fillStyle = "red";
      drawCharacter(test_Enemy[i].posx, test_Enemy[i].posy, test_Enemy[i].charaId);
  }

  drawField();
}

function drawHoverMarker(e){
    if (!e) {
      console.log("drawHoverMarker !e");
    } else {
      overX = (e.pageX - canvasPosition.left) / SQUARE_WIDTH;
      overY = (e.pageY - canvasPosition.top) / SQUARE_WIDTH;

      var obj = convertPosition(overX, overY, false);
      obj.x -= SQUARE_WIDTH / 2;
      obj.y -= SQUARE_WIDTH / 2;
    };

    ctxCanvas.lineWidth = 0.0;
    ctxCanvas.fillStyle = 'rgb(192, 80, 77)';
    ctxCanvas.globalAlpha = 0.7;
    ctxCanvas.beginPath();
    ctxCanvas.fillRect(obj.x, obj.y, SQUARE_WIDTH, SQUARE_WIDTH);
    ctxCanvas.stroke();
}

function drawCharacter(posx,posy,charaId){
  var obj = convertPosition(posx, posy, false);
  ctxCanvas.font = "18px 'MS Pゴシック'";
  switch(charaId){
    case 0:
      ctxCanvas.fillText("D", obj.x, obj.y);
      break;
    case 1:
      ctxCanvas.fillText("P", obj.x, obj.y);
      break;
    case 2:
      ctxCanvas.fillText("H", obj.x, obj.y);
      break;
    case 3:
      ctxCanvas.fillText("M", obj.x, obj.y);
      break;
  }
  ctxCanvas.stroke();
}

function drawField(){

  //setting
  ctxCanvas.globalAlpha = 1.0;

  for (var i = 0; i <= 17; i++) {
    if (i === 0 || i === NUMBER_OF_SQUARE) {
      ctxCanvas.beginPath();
      ctxCanvas.lineWidth = 10.0;
    } else {
      ctxCanvas.beginPath();
      ctxCanvas.lineWidth = 1.0;
    }

    //draw
    ctxCanvas.moveTo(i * SQUARE_WIDTH, 0);
    ctxCanvas.lineTo(i * SQUARE_WIDTH, PLAYGROUND_WIDTH);
    ctxCanvas.stroke();
    ctxCanvas.moveTo(0, i * SQUARE_WIDTH);
    ctxCanvas.lineTo(PLAYGROUND_WIDTH, i * SQUARE_WIDTH);
    ctxCanvas.stroke();
  }

}

function selectCharacter(e){
  /*
  (selectY, selectX)
  */
  if (e) {
    selectX = Math.floor((e.pageX - canvasPosition.left) / SQUARE_WIDTH);
    selectY = Math.floor((e.pageY - canvasPosition.top) / SQUARE_WIDTH);
  };

  // クリックしたとこのキャラを検索。
  // 同じキャラが選択されたとき or 見つからなかったとき、-1を代入。
  var temp = searchCharacter(selectX, selectY, 0, true);
  if (selectedCharacter === temp[1] || temp[0] === false) {
    selectedCharacter = -1;
  } else {
    selectedCharacter = temp[1];
  }

  moveCharacter(selectX,selectY,moveFlg);

  if (selectedCharacter < 100 && selectedCharacter != -1){
    moveFlg = selectedCharacter;
  } else {
    moveFlg = -1;
  }

  var targetCharacter = getCharacterState(selectedCharacter);
  attack(selectedCharacter);

  // クリックしたとこ以外の、距離が1(隣接する)キャラを検索。
  temp = searchCharacter(selectX, selectY, 1, false);
}

function moveCharacter(x,y,charaId){
  //前回味方が選択された状態で、何もない又は自機の場所が選択されたら
  if (moveFlg <100 && moveFlg != -1 && selectedCharacter== -1){
    var lx,ly;

    lx = test_Friend[charaId].posx;
    ly = test_Friend[charaId].posy;

    //x,yが移動範囲内なら
    if(Math.abs(x-lx) + Math.abs(y-ly) <= test_Friend[charaId].move){
    test_Friend[charaId].posx = x;
    test_Friend[charaId].posy = y;
    }else{
      console.log("This postion protruding from moverenge")
    }
  }

}

function searchCharacter(x, y, range, flag){
  /*
    x, y はマスの座標を取る。
    flag:
     true: クリックしたところを含む
     false: クリックしたところを含まない
  */
  var foundCharacter = [];
  foundCharacter.push(false);

    var tx = x - range; //検索範囲の一番左のマス
    var ty = y - range; //検索範囲の一番上のマス
    var range = 2 * range + 1;

    for (var i = 0; i < range; i++) {
      for (var j = 0; j < range; j++) {
        for (var k = 0; k < MAX_CHARACTER; k++){
          if(test_Friend[k].posx === tx + i && test_Friend[k].posy === ty + j){
            foundCharacter.push(test_Friend[k].id);
          }
          if(test_Enemy[k].posx === tx + i && test_Enemy[k].posy === ty + j){
            foundCharacter.push(test_Enemy[k].id);
          }
        }
      }
    }

  if (flag === false) {
    var temp = searchCharacter(x, y, 0, true);
    for(var i = 1; i <= foundCharacter.length; i++){
      if (foundCharacter[i] === temp[1]){
        foundCharacter.splice(i, 1);
      }
    }
  }

  if (typeof foundCharacter[1] === 'undefined') {
    return foundCharacter;
  } else {
    foundCharacter[0] = true;
    return foundCharacter;
  }

}

function getCharacterState(keyId){
  /*
    引数にidを取る。（配列不可）
    マッチしたキャラを返す。
  */
  for (var i = 0; i < MAX_CHARACTER; i++) {
    if (test_Enemy[i].id === keyId) {
      var result = test_Enemy[i];
    };
    if (test_Friend[i].id === keyId) {
      var result = test_Friend[i];
    };
  }

  if (!result) {
    return false;
  } else {
    return result;
  }
}
// ==============================================================================================
function attack(attakerId){
  var attaker = getCharacterState(attakerId);
  var defender = searchCharacter(attaker.posx, attaker.posy, attaker.attacableRange, false);

  // 味方のIDをdefenderリストから削除
  if (attakerId < 100) {
    for(var i = defender.length; i > 0; i--){
      if (defender[i] < 100){
        defender.splice(i, 1);
      }
    }
  } else {
    for(var i = defender.length; i > 0; i--){
      if (defender[i] >= 100){
        defender.splice(i, 1);
      }
    }
  }
  // 攻撃
  for (var i = 1; i <= defender.length; i++) {
    getCharacterState(defender[i]).hitPoint -= attaker.attack;
    if (getCharacterState(defender[i]).hitPoint <= 0) {
      console.log('dead');
    };
  };
}

// ==============================================================================================
/*
  posX: x座標,
  posY: y座標,
  flag:
    true : 座標 -> マス
    false: マス   -> 座標
*/
function convertPosition(posX, posY, flag) {
  var canvasPosition = $('#play-ground').position();
  var tx;
  var ty;

  posX = Math.floor(posX);
  posY = Math.floor(posY);

  if (flag === true) {
    tx = posX / SQUARE_WIDTH;
    ty = posY / SQUARE_WIDTH;

    return {x: Math.floor(tx), y: Math.floor(ty)}
  }
  else if (flag === false) {
    tx = (posX + 1) * (SQUARE_WIDTH) - (SQUARE_WIDTH / 2);
    ty = (posY + 1) * (SQUARE_WIDTH) - (SQUARE_WIDTH / 2);

    return {x: Math.floor(tx), y: Math.floor(ty)}
  }

  // 失敗したときのために
  return {x: -1, y: -1}
};
<|endoftext|>


<commit_before>import { basename, extname } from 'path';
import _ from 'lodash';
import Vue from 'vue';
import NProgress from 'vue-nprogress';
import keycode from 'keycode';
import store from './lib/core-data/store';
import { decorateAll } from './lib/decorators';
import { add as addBehavior } from './lib/forms/behaviors';
import { add as addPane } from './lib/forms/panes';
import toolbar from './lib/toolbar/edit-toolbar.vue';
import { HIDE_STATUS } from './lib/toolbar/mutationTypes';
import { init as initValidators } from './lib/validators';

// TODO: Figure out saving/closing and reverting in panes
import { CLOSE_PANE } from './lib/panes/mutationTypes';

const behaviorReq = require.context('./behaviors', false, /\.vue$/),
  paneReq = require.context('./panes', false, /\.vue$/),
  // todo: in the future, we should queue up the saves
  connectionLostMessage = 'Connection Lost. Changes will NOT be saved.',
  progressOptions = {
    parent: '.nprogress-container',
    template: '

',
    showSpinner: false,
    easing: 'linear',
    speed: 500,
    trickle: false,
    minimum: 0.001
  },
  nprogress = new NProgress(progressOptions);

// Require all scss/css files needed
require.context('./styleguide', true, /^.*\.(scss|css)$/);

// Add behaviors
behaviorReq.keys().forEach(function (key) {
  addBehavior(basename(key, extname(key)), behaviorReq(key));
});

// Add panes
paneReq.keys().forEach(function (key) {
  addPane(basename(key, extname(key)), paneReq(key));
});

// init validators
initValidators();

// add progress bar
Vue.use(NProgress, {
  router: false,
  http: false
});

// kick off loading when DOM is ready
// note: preloaded data, external behaviors, decorators, and validation rules should already be added
// when this event fires
document.addEventListener('DOMContentLoaded', function () {
  new Vue({
    strict: true,
    el: '#kiln-app',
    render(h) {
      return h('edit-toolbar');
    },
    store,
    nprogress,
    components: {
      'edit-toolbar': toolbar
    }
  });

  store.dispatch('preload')
    .then(() => decorateAll())
    .then(() => store.dispatch('openHashedForm'))
    .then(() => {
      // test connection loss on page load
      if (!navigator.onLine) {
        store.dispatch('showStatus', { type: 'offline', message: connectionLostMessage, isPermanent: true});
      }
    });

  // when clicks bubble up to the document, close the current form or pane / unselect components
  document.body.addEventListener('click', (e) => {
    // always unselect if clicking out of the current selection
    // todo: handle panes where we want to stay selected
    if (_.get(store, 'state.ui.currentSelection') && !e.stopSelection) {
      // note: stopSelection is set in the 'select' action. see the comments there for details
      store.dispatch('unselect');
    }

    // always unfocus if clicking out of the current focus
    if (_.get(store, 'state.ui.currentFocus') && !e.stopFocus) {
      store.dispatch('unfocus');
    }

    // Close a pane
    if (_.get(store, 'state.ui.currentPane')) {
      store.commit(CLOSE_PANE, null);
    }
  });

  window.addEventListener('online', function () {
    store.commit(HIDE_STATUS); // in case there are any status messages open, close them
  });

  window.addEventListener('offline', function () {
    // todo: turn any progress indicators to grey and end them
    store.dispatch('showStatus', { type: 'offline', message: connectionLostMessage, isPermanent: true});
  });

  // navigate components when hitting ↑ / ↓ arrows (if there's a component selected)
  document.addEventListener('keydown', function (e) {
    const key = keycode(e);

    // don't navigate if they have a form open
    if (_.get(store, 'state.ui.currentFocus')) {
      return;
    }

    if (key === 'up') {
      store.dispatch('navigateComponents', 'prev');
    } else if (key === 'down') {
      store.dispatch('navigateComponents', 'next');
    }
  });
});
<commit_msg>Registering comma as a keycode for key events<commit_after>import { basename, extname } from 'path';
import _ from 'lodash';
import Vue from 'vue';
import NProgress from 'vue-nprogress';
import keycode from 'keycode';
import store from './lib/core-data/store';
import { decorateAll } from './lib/decorators';
import { add as addBehavior } from './lib/forms/behaviors';
import { add as addPane } from './lib/forms/panes';
import toolbar from './lib/toolbar/edit-toolbar.vue';
import { HIDE_STATUS } from './lib/toolbar/mutationTypes';
import { init as initValidators } from './lib/validators';

// TODO: Figure out saving/closing and reverting in panes
import { CLOSE_PANE } from './lib/panes/mutationTypes';

const behaviorReq = require.context('./behaviors', false, /\.vue$/),
  paneReq = require.context('./panes', false, /\.vue$/),
  // todo: in the future, we should queue up the saves
  connectionLostMessage = 'Connection Lost. Changes will NOT be saved.',
  progressOptions = {
    parent: '.nprogress-container',
    template: '

',
    showSpinner: false,
    easing: 'linear',
    speed: 500,
    trickle: false,
    minimum: 0.001
  },
  nprogress = new NProgress(progressOptions);

// Require all scss/css files needed
require.context('./styleguide', true, /^.*\.(scss|css)$/);

// Add behaviors
behaviorReq.keys().forEach(function (key) {
  addBehavior(basename(key, extname(key)), behaviorReq(key));
});

// Add panes
paneReq.keys().forEach(function (key) {
  addPane(basename(key, extname(key)), paneReq(key));
});

// init validators
initValidators();

// add progress bar
Vue.use(NProgress, {
  router: false,
  http: false
});

// Register keys to make key events easy to call
Vue.config.keyCodes.comma = 188;

// kick off loading when DOM is ready
// note: preloaded data, external behaviors, decorators, and validation rules should already be added
// when this event fires
document.addEventListener('DOMContentLoaded', function () {
  new Vue({
    strict: true,
    el: '#kiln-app',
    render(h) {
      return h('edit-toolbar');
    },
    store,
    nprogress,
    components: {
      'edit-toolbar': toolbar
    }
  });

  store.dispatch('preload')
    .then(() => decorateAll())
    .then(() => store.dispatch('openHashedForm'))
    .then(() => {
      // test connection loss on page load
      if (!navigator.onLine) {
        store.dispatch('showStatus', { type: 'offline', message: connectionLostMessage, isPermanent: true});
      }
    });

  // when clicks bubble up to the document, close the current form or pane / unselect components
  document.body.addEventListener('click', (e) => {
    // always unselect if clicking out of the current selection
    // todo: handle panes where we want to stay selected
    if (_.get(store, 'state.ui.currentSelection') && !e.stopSelection) {
      // note: stopSelection is set in the 'select' action. see the comments there for details
      store.dispatch('unselect');
    }

    // always unfocus if clicking out of the current focus
    if (_.get(store, 'state.ui.currentFocus') && !e.stopFocus) {
      store.dispatch('unfocus');
    }

    // Close a pane
    if (_.get(store, 'state.ui.currentPane')) {
      store.commit(CLOSE_PANE, null);
    }
  });

  window.addEventListener('online', function () {
    store.commit(HIDE_STATUS); // in case there are any status messages open, close them
  });

  window.addEventListener('offline', function () {
    // todo: turn any progress indicators to grey and end them
    store.dispatch('showStatus', { type: 'offline', message: connectionLostMessage, isPermanent: true});
  });

  // navigate components when hitting ↑ / ↓ arrows (if there's a component selected)
  document.addEventListener('keydown', function (e) {
    const key = keycode(e);

    // don't navigate if they have a form open
    if (_.get(store, 'state.ui.currentFocus')) {
      return;
    }

    if (key === 'up') {
      store.dispatch('navigateComponents', 'prev');
    } else if (key === 'down') {
      store.dispatch('navigateComponents', 'next');
    }
  });
});
<|endoftext|>


<commit_before>/*global window, document, jQuery, Handsontable, NVMetadata */
(function ($) {
  'use strict';

  function isString(val) {
    return (typeof val === 'string' || val instanceof String);
  }

  function cache() {
    var storage = {};
    return {
      get: function (key) {
        return storage[key];
      },
      set: function (key, value) {
        storage[key] = value;
      }
    }
  }

  function debounce(func, wait, immediate) {
    var timeout;
    return function () {
      var context = this,
        args = arguments;
      var later = function () {
        timeout = null;
        if (!immediate) func.apply(context, args);
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(context, args);
    };
  }

  function emptyOrSpaced(value) {
    return !(value && /\S/.test(value))
  }

  function stringRequiredValidator(value, callback) {
    if (emptyOrSpaced(value)) {
      return callback(false);
    } else {
      return callback(true);
    }
  }

  var requestData = debounce(function (source, success) {
    $.ajax({
      url: source,
      dataType: 'json',
      success: success
    });
  }, 500, true);

  var cache = cache();

  function cachedAjaxSource(source) {
    return function (query, process) {
      var data = cache.get(source);
      if (data) {
        process(data);
      } else {
        requestData(source, function (response) {
          cache.set(source, response.data);
          process(response.data);
        });
      }
    }
  }

  function headerNames(headers) {
    return headers.map(function (x) {
      if (x.required) {
        return x.name + '*';
      }
      return x.name;
    });
  }

  function guessFieldType(field) {
    if (field.datasource) {
      return 'autocomplete';
    } else {
      return 'text';
    }
  }

  function getDataSource(field) {
    var datasource = field.datasource;

    if (datasource) {
      if (datasource.choices) {
        return NVMetadata.datasources[datasource.choices];
      } else if (datasource.url) {
        return cachedAjaxSource(datasource.url);
      }
    } else {
      return undefined;
    }
  }

  function choiceValidator(choices) {
    return function(value, callback) {
      if (!value) {
        return callback(true);
      }
      var elems = NVMetadata.datasources[choices].filter(function(x) {
        return x === value;
      });
      if (elems.length === 0) {
        return callback(false);
      }
      return callback(true);
    };
  }

  function getFieldValidator(field) {
    if (field.required && !field.datasource) {
      return stringRequiredValidator;
    } else if (!field.required && field.datasource && field.datasource.choices) {
      return choiceValidator(field.datasource.choices);
    } else {
      return undefined;
    }
  }

  function columnSettings(headers) {
    return headers.map(function (x) {
      return {
        type: guessFieldType(x),
        source: getDataSource(x),
        strict: x.required,
        validator: getFieldValidator(x)
      }
    });
  }

  function getDefaultHeight(data) {
    var minHeight = 400,
      rowHeight = 24;

    if ((data.length + 1) * rowHeight < minHeight) {
      return minHeight;
    } else {
      return undefined;
    }
  }

  function columnExist(columnName) {
    var value = columnName.trim(),
      elems = NVMetadata.headers.filter(function (x) {
        return x.name === value;
      });

    return elems.length !== 0;
  }

  function isFixedColumn(index) {
    return NVMetadata.headers[index].fixed
  }

  function hasAnyValues(arr) {
    var i, len;
    for (i = 0, len = arr.length; i < len; i += 1) {
      if (!emptyOrSpaced(arr[i])) {
        return true;
      }
    }
    return false;
  }

  function filterEmptyRows(array) {
    return array.filter(function(x) {
      return hasAnyValues(x);
    });
  }

  function serializeTable(hotInstance) {
    return [window.NVMetadata.headers.map(function (x) {
      return x.name
    })].concat(filterEmptyRows(hotInstance.getData()));
  }

  function validateInput(value, success, failure) {
    if (emptyOrSpaced(value)) {
      failure();
    } else if (columnExist(value)) {
      failure("Column already exists");
    } else {
      success();
    }
  }

  function showError($el, msg) {
    $el.addClass('has-error');
    if (msg) {
      $('.help-block', $el).text(msg);
    }
  }

  function clearError($el) {
    $('.help-block', $el).empty();
    $el.removeClass('has-error');
  }

  function getNewColumnName(callback) {
    var $modalEl = $('#columnNameModal'),
      $submit = $('button[type="submit"]', $modalEl),
      $columnNameEl = $('#column-name'),
      $inputWrapper = $('.js-input-wrapper', $modalEl);

    $modalEl.on('shown.bs.modal', function () {
      $columnNameEl.focus().attr("autocomplete", "off");

      $columnNameEl.keyup(function (e) {
        validateInput($columnNameEl.val(), function () {
          $submit.prop('disabled', false);
          clearError($inputWrapper);
        }, function (msg) {
          $submit.prop('disabled', true);
          if (msg) {
            showError($inputWrapper, msg);
          }
        });
      });

      $('.js-name-form', $modalEl)
        .off('submit.modal')
        .on('submit.modal', function () {
          var name = $columnNameEl.val().trim();
          callback(name);
          $modalEl.modal('hide');
          $columnNameEl.val('');
          return false;
        });
    });

    $modalEl.on('hide.bs.modal', function () {
      $columnNameEl.val('');
      clearError($inputWrapper);
    });

    $modalEl.modal();
  }

  function insertDataColumn(index, name) {
    NVMetadata.headers.splice(index, 0, {
      name: name
    });
    NVMetadata.data.map(function (x) {
      x.splice(index, 0, '');
    });
  }

  function removeDataColumn(index) {
    NVMetadata.headers.splice(index, 1);
    NVMetadata.data.map(function (x) {
      x.splice(index, 1);
    });
  }

  function insertLocation(selection, key) {
    if (key === 'insert_column_left') {
      return selection[1];
    } else {
      return selection[3] + 1;
    }
  }

  function updateSettings(hotInstance) {
    hotInstance.updateSettings({
      data: window.NVMetadata.data,
      colHeaders: headerNames(window.NVMetadata.headers),
      columns: columnSettings(window.NVMetadata.headers)
    });
  }

  function handleInsertColumn(hotInstance, selection, key) {
    hotInstance.deselectCell();

    getNewColumnName(function (name) {
      var index = insertLocation(selection, key);

      insertDataColumn(index, name);
      updateSettings(hotInstance);
      hotInstance.render();
    });
  }

  function handleRemoveColumn(hotInstance, selection) {
    removeDataColumn(selection[1]);
    updateSettings(hotInstance);
    hotInstance.render();
  }

  $(document).ready(function () {

    var container = document.getElementById('hot'),
      hot = new Handsontable(container, {
        data: window.NVMetadata.data,
        colHeaders: headerNames(window.NVMetadata.headers),
        columns: columnSettings(window.NVMetadata.headers),
        rowHeaders: true,
        height: getDefaultHeight(window.NVMetadata.data),
        allowInsertRow: false,
        minSpareRows: 0,
        maxRows: window.NVMetadata.data.length,
        contextMenu: {
          callback: function (key) {
            if (key === 'insert_column_left' ||
              key === 'insert_column_right') {
              handleInsertColumn(hot, hot.getSelected(), key);
            } else if (key === 'remove_this_column') {
              handleRemoveColumn(hot, hot.getSelected());
            }
          },
          items: {
            'insert_column_left': {
              name: 'Insert column on the left',
              disabled: function () {
                return hot.getSelected()[1] === 0
              }
            },
            'insert_column_right': {
              name: 'Insert column on the right'
            },
            'hsep2': '---------',
            'remove_this_column': {
              name: 'Remove column',
              disabled: function () {
                return isFixedColumn(hot.getSelected()[1])
              }
            },
            'hsep3': '---------',
            'undo': {},
            'redo': {}
          }
        },
        cells: function (r, c, prop) {
          if (c === 0) {
            return {
              readOnly: true
            };
          }
        }
      });

    $('.btn-save-metadata').click(function (e) {
      var $this = $(this);
      $this.prop('disabled', true);

      $.ajax({
          type: 'POST',
          data: JSON.stringify(serializeTable(hot)),
          contentType: 'application/json; charset=utf-8'
        })
        .done(function () {
          var collectionId = NVMetadata.getCollectionIdFromURL(
            window.location.href
          );
          window.onbeforeunload = undefined;
          window.location.replace('/collections/' + collectionId);
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
          NVMetadata.displayErrors($('.errors'),
            NVMetadata.getErrors(jqXHR, textStatus, errorThrown));
        })
        .always(function () {
          $this.prop('disabled', false);
        });
    });

    window.onbeforeunload = function () {
      if (hot.isUndoAvailable()) {
        return 'You have pending unsaved changes. ' +
          'Do you really want to discard them ?';
      }
    };
  });

}(jQuery));
<commit_msg>enable button only on fail<commit_after>/*global window, document, jQuery, Handsontable, NVMetadata */
(function ($) {
  'use strict';

  function isString(val) {
    return (typeof val === 'string' || val instanceof String);
  }

  function cache() {
    var storage = {};
    return {
      get: function (key) {
        return storage[key];
      },
      set: function (key, value) {
        storage[key] = value;
      }
    }
  }

  function debounce(func, wait, immediate) {
    var timeout;
    return function () {
      var context = this,
        args = arguments;
      var later = function () {
        timeout = null;
        if (!immediate) func.apply(context, args);
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(context, args);
    };
  }

  function emptyOrSpaced(value) {
    return !(value && /\S/.test(value))
  }

  function stringRequiredValidator(value, callback) {
    if (emptyOrSpaced(value)) {
      return callback(false);
    } else {
      return callback(true);
    }
  }

  var requestData = debounce(function (source, success) {
    $.ajax({
      url: source,
      dataType: 'json',
      success: success
    });
  }, 500, true);

  var cache = cache();

  function cachedAjaxSource(source) {
    return function (query, process) {
      var data = cache.get(source);
      if (data) {
        process(data);
      } else {
        requestData(source, function (response) {
          cache.set(source, response.data);
          process(response.data);
        });
      }
    }
  }

  function headerNames(headers) {
    return headers.map(function (x) {
      if (x.required) {
        return x.name + '*';
      }
      return x.name;
    });
  }

  function guessFieldType(field) {
    if (field.datasource) {
      return 'autocomplete';
    } else {
      return 'text';
    }
  }

  function getDataSource(field) {
    var datasource = field.datasource;

    if (datasource) {
      if (datasource.choices) {
        return NVMetadata.datasources[datasource.choices];
      } else if (datasource.url) {
        return cachedAjaxSource(datasource.url);
      }
    } else {
      return undefined;
    }
  }

  function choiceValidator(choices) {
    return function(value, callback) {
      if (!value) {
        return callback(true);
      }
      var elems = NVMetadata.datasources[choices].filter(function(x) {
        return x === value;
      });
      if (elems.length === 0) {
        return callback(false);
      }
      return callback(true);
    };
  }

  function getFieldValidator(field) {
    if (field.required && !field.datasource) {
      return stringRequiredValidator;
    } else if (!field.required && field.datasource && field.datasource.choices) {
      return choiceValidator(field.datasource.choices);
    } else {
      return undefined;
    }
  }

  function columnSettings(headers) {
    return headers.map(function (x) {
      return {
        type: guessFieldType(x),
        source: getDataSource(x),
        strict: x.required,
        validator: getFieldValidator(x)
      }
    });
  }

  function getDefaultHeight(data) {
    var minHeight = 400,
      rowHeight = 24;

    if ((data.length + 1) * rowHeight < minHeight) {
      return minHeight;
    } else {
      return undefined;
    }
  }

  function columnExist(columnName) {
    var value = columnName.trim(),
      elems = NVMetadata.headers.filter(function (x) {
        return x.name === value;
      });

    return elems.length !== 0;
  }

  function isFixedColumn(index) {
    return NVMetadata.headers[index].fixed
  }

  function hasAnyValues(arr) {
    var i, len;
    for (i = 0, len = arr.length; i < len; i += 1) {
      if (!emptyOrSpaced(arr[i])) {
        return true;
      }
    }
    return false;
  }

  function filterEmptyRows(array) {
    return array.filter(function(x) {
      return hasAnyValues(x);
    });
  }

  function serializeTable(hotInstance) {
    return [window.NVMetadata.headers.map(function (x) {
      return x.name
    })].concat(filterEmptyRows(hotInstance.getData()));
  }

  function validateInput(value, success, failure) {
    if (emptyOrSpaced(value)) {
      failure();
    } else if (columnExist(value)) {
      failure("Column already exists");
    } else {
      success();
    }
  }

  function showError($el, msg) {
    $el.addClass('has-error');
    if (msg) {
      $('.help-block', $el).text(msg);
    }
  }

  function clearError($el) {
    $('.help-block', $el).empty();
    $el.removeClass('has-error');
  }

  function getNewColumnName(callback) {
    var $modalEl = $('#columnNameModal'),
      $submit = $('button[type="submit"]', $modalEl),
      $columnNameEl = $('#column-name'),
      $inputWrapper = $('.js-input-wrapper', $modalEl);

    $modalEl.on('shown.bs.modal', function () {
      $columnNameEl.focus().attr("autocomplete", "off");

      $columnNameEl.keyup(function (e) {
        validateInput($columnNameEl.val(), function () {
          $submit.prop('disabled', false);
          clearError($inputWrapper);
        }, function (msg) {
          $submit.prop('disabled', true);
          if (msg) {
            showError($inputWrapper, msg);
          }
        });
      });

      $('.js-name-form', $modalEl)
        .off('submit.modal')
        .on('submit.modal', function () {
          var name = $columnNameEl.val().trim();
          callback(name);
          $modalEl.modal('hide');
          $columnNameEl.val('');
          return false;
        });
    });

    $modalEl.on('hide.bs.modal', function () {
      $columnNameEl.val('');
      clearError($inputWrapper);
    });

    $modalEl.modal();
  }

  function insertDataColumn(index, name) {
    NVMetadata.headers.splice(index, 0, {
      name: name
    });
    NVMetadata.data.map(function (x) {
      x.splice(index, 0, '');
    });
  }

  function removeDataColumn(index) {
    NVMetadata.headers.splice(index, 1);
    NVMetadata.data.map(function (x) {
      x.splice(index, 1);
    });
  }

  function insertLocation(selection, key) {
    if (key === 'insert_column_left') {
      return selection[1];
    } else {
      return selection[3] + 1;
    }
  }

  function updateSettings(hotInstance) {
    hotInstance.updateSettings({
      data: window.NVMetadata.data,
      colHeaders: headerNames(window.NVMetadata.headers),
      columns: columnSettings(window.NVMetadata.headers)
    });
  }

  function handleInsertColumn(hotInstance, selection, key) {
    hotInstance.deselectCell();

    getNewColumnName(function (name) {
      var index = insertLocation(selection, key);

      insertDataColumn(index, name);
      updateSettings(hotInstance);
      hotInstance.render();
    });
  }

  function handleRemoveColumn(hotInstance, selection) {
    removeDataColumn(selection[1]);
    updateSettings(hotInstance);
    hotInstance.render();
  }

  $(document).ready(function () {

    var container = document.getElementById('hot'),
      hot = new Handsontable(container, {
        data: window.NVMetadata.data,
        colHeaders: headerNames(window.NVMetadata.headers),
        columns: columnSettings(window.NVMetadata.headers),
        rowHeaders: true,
        height: getDefaultHeight(window.NVMetadata.data),
        allowInsertRow: false,
        minSpareRows: 0,
        maxRows: window.NVMetadata.data.length,
        contextMenu: {
          callback: function (key) {
            if (key === 'insert_column_left' ||
              key === 'insert_column_right') {
              handleInsertColumn(hot, hot.getSelected(), key);
            } else if (key === 'remove_this_column') {
              handleRemoveColumn(hot, hot.getSelected());
            }
          },
          items: {
            'insert_column_left': {
              name: 'Insert column on the left',
              disabled: function () {
                return hot.getSelected()[1] === 0
              }
            },
            'insert_column_right': {
              name: 'Insert column on the right'
            },
            'hsep2': '---------',
            'remove_this_column': {
              name: 'Remove column',
              disabled: function () {
                return isFixedColumn(hot.getSelected()[1])
              }
            },
            'hsep3': '---------',
            'undo': {},
            'redo': {}
          }
        },
        cells: function (r, c, prop) {
          if (c === 0) {
            return {
              readOnly: true
            };
          }
        }
      });

    $('.btn-save-metadata').click(function (e) {
      var $this = $(this);
      $this.prop('disabled', true);

      $.ajax({
          type: 'POST',
          data: JSON.stringify(serializeTable(hot)),
          contentType: 'application/json; charset=utf-8'
        })
        .done(function () {
          var collectionId = NVMetadata.getCollectionIdFromURL(
            window.location.href
          );
          window.onbeforeunload = undefined;
          window.location.replace('/collections/' + collectionId);
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
          $this.prop('disabled', false);

          NVMetadata.displayErrors($('.errors'),
            NVMetadata.getErrors(jqXHR, textStatus, errorThrown));
        });
    });

    window.onbeforeunload = function () {
      if (hot.isUndoAvailable()) {
        return 'You have pending unsaved changes. ' +
          'Do you really want to discard them ?';
      }
    };
  });

}(jQuery));
<|endoftext|>