<commit_before>'use strict'
var sodium      = require('chloride')

var keypair     = sodium.crypto_box_seed_keypair
var from_seed   = sodium.crypto_sign_seed_keypair
var shared      = sodium.crypto_scalarmult
var hash        = sodium.crypto_hash_sha256
var sign        = sodium.crypto_sign_detached
var verify      = sodium.crypto_sign_verify_detached
var auth        = sodium.crypto_auth
var verify_auth = sodium.crypto_auth_verify
var curvify_pk  = sodium.crypto_sign_ed25519_pk_to_curve25519
var curvify_sk  = sodium.crypto_sign_ed25519_sk_to_curve25519
var box         = sodium.crypto_secretbox_easy
var unbox       = sodium.crypto_secretbox_open_easy

var concat = Buffer.concat

var nonce = new Buffer(24); nonce.fill(0)

var isBuffer = Buffer.isBuffer

exports.challenge_length = 64
exports.client_auth_length = 16+32+64
exports.server_auth_length = 16+64
exports.mac_length = 16

//both client and server

function assert_length(buf, name, length) {
  if(buf.length !== length)
    throw new Error('expected '+name+' to have length' + length + ', but was:'+buf.length)
}

exports.initialize = function (state) {

  if(state.seed) state.local = from_seed(state.seed)

  //TODO: sodium is missing box_seed_keypair. should make PR for that.

  var _key = from_seed(state.random)
//  var kx = keypair(random)
  var kx_pk = curvify_pk(_key.publicKey)
  var kx_sk = curvify_sk(_key.secretKey)

  state.local = {
    kx_pk: kx_pk,
    kx_sk: kx_sk,
    publicKey: state.local.publicKey,
    secretKey: state.local.secretKey,
    app_mac: auth(kx_pk, state.app_key)
  }

  state.remote = state.remote || {}

  return state
}

exports.createChallenge = function (state) {
  return concat([state.local.app_mac, state.local.kx_pk])
}

exports.verifyChallenge = function (state, challenge) {
  assert_length(challenge, 'challenge', exports.challenge_length)

  var mac = challenge.slice(0, 32)
  var remote_pk = challenge.slice(32, exports.challenge_length)

  if(0 !== verify_auth(mac, remote_pk, state.app_key))
    return null

  state.remote.kx_pk = remote_pk
  state.remote.app_mac = mac
  state.secret = shared(state.local.kx_sk, state.remote.kx_pk)
  state.shash = hash(state.secret)

  return state
}

exports.clean = function (state) {
  // clean away all the secrets for forward security.
  // use a different secret hash(secret3) in the rest of the session,
  // and so that a sloppy application cannot compromise the handshake.

  state.shash.fill(0)
  state.secret.fill(0)
  state.a_bob.fill(0)
  state.b_alice.fill(0)

  state.secret = hash(state.secret3)
  state.encryptKey = hash(concat([state.secret, state.remote.publicKey]))
  state.decryptKey = hash(concat([state.secret, state.local.publicKey]))

  state.secret2.fill(0)
  state.secret3.fill(0)
  state.local.kx_sk.fill(0)

  state.shash = null
  state.secret2 = null
  state.secret3 = null
  state.a_bob = null
  state.b_alice = null
  state.local.kx_sk = null
  return state
}

//client side only (Alice)

exports.clientVerifyChallenge = function (state, challenge) {
  assert_length(challenge, 'challenge', exports.challenge_length)
  state = exports.verifyChallenge(state, challenge)
  if(!state) return null

  //now we have agreed on the secret.
  //this can be an encryption secret,
  //or a hmac secret.

  var a_bob = shared(state.local.kx_sk, curvify_pk(state.remote.publicKey))
  state.a_bob = a_bob
  state.secret2 = hash(concat([state.app_key, state.secret, a_bob]))

  var signed = concat([state.app_key, state.remote.publicKey, state.shash])
  var sig = sign(signed, state.local.secretKey)

  state.local.hello = Buffer.concat([sig, state.local.publicKey])
  return state
}

exports.clientCreateAuth = function (state) {
  return box(state.local.hello, nonce, state.secret2)
}

exports.clientVerifyAccept = function (state, boxed_okay) {
  assert_length(boxed_okay, 'server_auth', exports.server_auth_length)

  var b_alice = shared(curvify_sk(state.local.secretKey), state.remote.kx_pk)
  state.b_alice = b_alice
  state.secret3 = hash(concat([state.app_key, state.secret, state.a_bob, state.b_alice]))

  var sig = unbox(boxed_okay, nonce, state.secret3)
  if(!sig) return null
  var signed = concat([state.app_key, state.local.hello, state.shash])
  if(!verify(sig, signed, state.remote.publicKey))
      return null
  return state
}

//server side only (Bob)

exports.serverVerifyAuth = function (state, data) {
  assert_length(data, 'client_auth', exports.client_auth_length)

  var a_bob = shared(curvify_sk(state.local.secretKey), state.remote.kx_pk)
  state.a_bob = a_bob
  state.secret2 = hash(concat([state.app_key, state.secret, a_bob]))

  state.remote.hello = unbox(data, nonce, state.secret2)
  if(!state.remote.hello)
    return null

  var sig = state.remote.hello.slice(0, 64)
  var publicKey = state.remote.hello.slice(64, exports.client_auth_length)

  var signed = concat([state.app_key, state.local.publicKey, state.shash])
  if(!verify(sig, signed, publicKey))
    return null

  state.remote.publicKey = publicKey
  //shared key between my local ephemeral key + remote public
  var b_alice = shared(state.local.kx_sk, curvify_pk(state.remote.publicKey))
  state.b_alice = b_alice
  state.secret3 = hash(concat([state.app_key, state.secret, state.a_bob, state.b_alice]))

  return state

}

exports.serverCreateAccept = function (state) {
  var signed = concat([state.app_key, state.remote.hello, state.shash])
  var okay = sign(signed, state.local.secretKey)
  return box(okay, nonce, state.secret3)
}

exports.toKeys = function (keys) {
  if(isBuffer(keys, 32))
    return sodium.crypto_sign_seed_keypair(keys)
  return keys
}

<commit_msg>Slice to correct length<commit_after>'use strict'
var sodium      = require('chloride')

var keypair     = sodium.crypto_box_seed_keypair
var from_seed   = sodium.crypto_sign_seed_keypair
var shared      = sodium.crypto_scalarmult
var hash        = sodium.crypto_hash_sha256
var sign        = sodium.crypto_sign_detached
var verify      = sodium.crypto_sign_verify_detached
var auth        = sodium.crypto_auth
var verify_auth = sodium.crypto_auth_verify
var curvify_pk  = sodium.crypto_sign_ed25519_pk_to_curve25519
var curvify_sk  = sodium.crypto_sign_ed25519_sk_to_curve25519
var box         = sodium.crypto_secretbox_easy
var unbox       = sodium.crypto_secretbox_open_easy

var concat = Buffer.concat

var nonce = new Buffer(24); nonce.fill(0)

var isBuffer = Buffer.isBuffer

exports.challenge_length = 64
exports.client_auth_length = 16+32+64
exports.server_auth_length = 16+64
exports.mac_length = 16

//both client and server

function assert_length(buf, name, length) {
  if(buf.length !== length)
    throw new Error('expected '+name+' to have length' + length + ', but was:'+buf.length)
}

exports.initialize = function (state) {

  if(state.seed) state.local = from_seed(state.seed)

  //TODO: sodium is missing box_seed_keypair. should make PR for that.

  var _key = from_seed(state.random)
//  var kx = keypair(random)
  var kx_pk = curvify_pk(_key.publicKey)
  var kx_sk = curvify_sk(_key.secretKey)

  state.local = {
    kx_pk: kx_pk,
    kx_sk: kx_sk,
    publicKey: state.local.publicKey,
    secretKey: state.local.secretKey,
    app_mac: auth(kx_pk, state.app_key)
  }

  state.remote = state.remote || {}

  return state
}

exports.createChallenge = function (state) {
  return concat([state.local.app_mac, state.local.kx_pk])
}

exports.verifyChallenge = function (state, challenge) {
  assert_length(challenge, 'challenge', exports.challenge_length)

  var mac = challenge.slice(0, 32)
  var remote_pk = challenge.slice(32, exports.challenge_length)

  if(0 !== verify_auth(mac, remote_pk, state.app_key))
    return null

  state.remote.kx_pk = remote_pk
  state.remote.app_mac = mac
  state.secret = shared(state.local.kx_sk, state.remote.kx_pk)
  state.shash = hash(state.secret)

  return state
}

exports.clean = function (state) {
  // clean away all the secrets for forward security.
  // use a different secret hash(secret3) in the rest of the session,
  // and so that a sloppy application cannot compromise the handshake.

  state.shash.fill(0)
  state.secret.fill(0)
  state.a_bob.fill(0)
  state.b_alice.fill(0)

  state.secret = hash(state.secret3)
  state.encryptKey = hash(concat([state.secret, state.remote.publicKey]))
  state.decryptKey = hash(concat([state.secret, state.local.publicKey]))

  state.secret2.fill(0)
  state.secret3.fill(0)
  state.local.kx_sk.fill(0)

  state.shash = null
  state.secret2 = null
  state.secret3 = null
  state.a_bob = null
  state.b_alice = null
  state.local.kx_sk = null
  return state
}

//client side only (Alice)

exports.clientVerifyChallenge = function (state, challenge) {
  assert_length(challenge, 'challenge', exports.challenge_length)
  state = exports.verifyChallenge(state, challenge)
  if(!state) return null

  //now we have agreed on the secret.
  //this can be an encryption secret,
  //or a hmac secret.

  var a_bob = shared(state.local.kx_sk, curvify_pk(state.remote.publicKey))
  state.a_bob = a_bob
  state.secret2 = hash(concat([state.app_key, state.secret, a_bob]))

  var signed = concat([state.app_key, state.remote.publicKey, state.shash])
  var sig = sign(signed, state.local.secretKey)

  state.local.hello = Buffer.concat([sig, state.local.publicKey])
  return state
}

exports.clientCreateAuth = function (state) {
  return box(state.local.hello, nonce, state.secret2)
}

exports.clientVerifyAccept = function (state, boxed_okay) {
  assert_length(boxed_okay, 'server_auth', exports.server_auth_length)

  var b_alice = shared(curvify_sk(state.local.secretKey), state.remote.kx_pk)
  state.b_alice = b_alice
  state.secret3 = hash(concat([state.app_key, state.secret, state.a_bob, state.b_alice]))

  var sig = unbox(boxed_okay, nonce, state.secret3)
  if(!sig) return null
  var signed = concat([state.app_key, state.local.hello, state.shash])
  if(!verify(sig, signed, state.remote.publicKey))
      return null
  return state
}

//server side only (Bob)

exports.serverVerifyAuth = function (state, data) {
  assert_length(data, 'client_auth', exports.client_auth_length)

  var a_bob = shared(curvify_sk(state.local.secretKey), state.remote.kx_pk)
  state.a_bob = a_bob
  state.secret2 = hash(concat([state.app_key, state.secret, a_bob]))

  state.remote.hello = unbox(data, nonce, state.secret2)
  if(!state.remote.hello)
    return null

  var sig = state.remote.hello.slice(0, 64)
  var publicKey = state.remote.hello.slice(64, 96)

  var signed = concat([state.app_key, state.local.publicKey, state.shash])
  if(!verify(sig, signed, publicKey))
    return null

  state.remote.publicKey = publicKey
  //shared key between my local ephemeral key + remote public
  var b_alice = shared(state.local.kx_sk, curvify_pk(state.remote.publicKey))
  state.b_alice = b_alice
  state.secret3 = hash(concat([state.app_key, state.secret, state.a_bob, state.b_alice]))

  return state

}

exports.serverCreateAccept = function (state) {
  var signed = concat([state.app_key, state.remote.hello, state.shash])
  var okay = sign(signed, state.local.secretKey)
  return box(okay, nonce, state.secret3)
}

exports.toKeys = function (keys) {
  if(isBuffer(keys, 32))
    return sodium.crypto_sign_seed_keypair(keys)
  return keys
}

<|endoftext|>


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

// https://github.com/gruntjs/grunt-contrib-uglify

// Minify files with UglifyJS.

module.exports = function (config) {
  return {
    app: {
      src: [
        config.static + 'js/shaders.develop.js',
        config.static + 'js/app.develop.js'
      ],
      dest: config.static + 'js/app.min.js'
    },
    libs: {
      src: config.static + 'js/libs.develop.js',
      dest: config.static + 'js/libs.min.js'
    }
  };
};
<commit_msg>Add shader-chunks to built app<commit_after>/*jshint node:true*/
'use strict';

// https://github.com/gruntjs/grunt-contrib-uglify

// Minify files with UglifyJS.

module.exports = function (config) {
  return {
    app: {
      src: [
        config.static + 'js/shader-chunks.develop.js',
        config.static + 'js/shaders.develop.js',
        config.static + 'js/app.develop.js'
      ],
      dest: config.static + 'js/app.min.js'
    },
    libs: {
      src: config.static + 'js/libs.develop.js',
      dest: config.static + 'js/libs.min.js'
    }
  };
};
<|endoftext|>


<commit_before>/**
 * ComboBox
 */
(function() {

    Ext.define('HatimeriaCore.form.field.TreePicker', {
        extend: 'Ext.tree.Panel',

        startWidth: undefined,

        initComponent: function()
        {
            var config = {
                floating: true,
                title: false,
                width: 200,
                height: 150
            };

            Ext.apply(this, Ext.apply(config, this.initialConfig || {}));
            this.callParent();

            this.on({
                itemcollapse: function() {
                    this.adjustTo(this.getEl().down('table'));
                },
                itemexpand: function() {
                    this.adjustTo(this.getEl().down('table'));
                },
                afterender: function() {
                    this.startWidth = this.ownerCt.getWidth();
                }
            });
        },

        /**
         * Selects current node
         *
         * @param Ext.data.Store.ImplicitModel
         */
        getNode: function()
        {

        },

        /**
         * Adjust tree to dimmensions of table - best fit
         *
         * @param Ext.Element table
         */
        adjustTo: function(table)
        {
            var _this = this;
            window.setTimeout(function() {
                _this.setHeight(table.getHeight()+5);

                if (table.getWidth() > _this.startWidth)
                {
                    _this.setWidth(table.getWidth()+5);
                }
            }, 600);
        }

    });

    Ext.define('HatimeriaCore.store.TreeStore', {
        extend: 'Ext.data.TreeStore',

        paramsAsHash: true,

        /**
         * Loads all nodes
         *
         * @param {} nodes
         */
        loadNodes: function(nodes)
        {
            this.getRootNode().appendChild(nodes);
            this.fireEvent('load', this);
        },

        /**
         * Count of nodes (always one)
         *
         * @return int
         */
        getCount: function()
        {
            return 1;
        },

        /**
         * Search node
         */
        findExact: function(field, value)
        {
            var find = function(nodes, field, value)
            {
                for (var i in nodes)
                {
                    if (nodes[i].get(field) == value)
                    {
                        return nodes[i];
                    }
                    else
                    {
                        return find(nodes[i].childNodes, field, value);
                    }
                }
            };

            var record = find(this.getRootNode().childNodes, field, value);

            return record;
        },

        /**
         * Get node from a pases position
         */
        getAt: function(record)
        {
            return record;
        }
    });

    Ext.define('HatimeriaCore.form.field.Category', {
        extend: 'HatimeriaCore.form.ComboBox',
        alias: 'widget.ux-category',
        config: {
            directFn: Ext.emptyFn
        },

        /**
         * Constructor
         */
        constructor: function(config)
        {
            this.initConfig(config);
            this.callParent([config]);

            return this;
        },

        /**
         * Initialize component
         */
        initComponent: function()
        {
            var _this = this;
            var config = {
                valueField: 'id',
                queryMode: 'local',
                displayField: 'text',
                store: Ext.create('HatimeriaCore.store.TreeStore', {
                    root: {
                        id: 'root',
                        expanded: true,
                        text: 'Wszystkie',
                        children: []
                    }
                })
            };

            Ext.apply(this, Ext.apply(config, this.initialConfig || {}));
            this.callParent();

            this.on('afterrender', function() {
                Ext.create('HatimeriaCore.direct.ResponseHandler', {
                   fn: this.getDirectFn(),
                   scope: this,
                   success: function(result) {
                       var nodes = result.record;
                       var expand = function(nodes)
                       {
                           for (var i in nodes)
                           {
                               nodes[i].expanded = true;
                               expand(nodes[i].children)
                           }
                       }
                       expand(nodes);

                       _this.store.loadNodes(nodes);
                   }
                });
            });
        },

        /**
         * Creates a picker
         *
         * @return Ext.Component
         */
        createPicker: function()
        {
            var picker = Ext.create('HatimeriaCore.form.field.TreePicker', {
                ownerCt: this.ownerCt,
                store: this.store
            });

            this.mon(picker, {
                itemclick: this.onItemClick,
                scope: this
            });

            this.mon(picker.getSelectionModel(), {
                selectionChange: this.onListSelectionChange,
                scope: this
            });

            this.picker = picker;

            return picker;
        }

    });

})();<commit_msg>leafs in categoryselect<commit_after>/**
 * ComboBox
 */
(function() {

    Ext.define('HatimeriaCore.form.field.TreePicker', {
        extend: 'Ext.tree.Panel',

        startWidth: undefined,

        initComponent: function()
        {
            var config = {
                floating: true,
                title: false,
                width: 200,
                height: 150
            };

            Ext.apply(this, Ext.apply(config, this.initialConfig || {}));
            this.callParent();

            this.on({
                itemcollapse: function() {
                    this.adjustTo(this.getEl().down('table'));
                },
                itemexpand: function() {
                    this.adjustTo(this.getEl().down('table'));
                },
                afterender: function() {
                    this.startWidth = this.ownerCt.getWidth();
                }
            });
        },

        /**
         * Selects current node
         *
         * @param Ext.data.Store.ImplicitModel
         */
        getNode: function()
        {

        },

        /**
         * Adjust tree to dimmensions of table - best fit
         *
         * @param Ext.Element table
         */
        adjustTo: function(table)
        {
            var _this = this;
            window.setTimeout(function() {
                _this.setHeight(table.getHeight()+5);

                if (table.getWidth() > _this.startWidth)
                {
                    _this.setWidth(table.getWidth()+5);
                }
            }, 600);
        }

    });

    Ext.define('HatimeriaCore.store.TreeStore', {
        extend: 'Ext.data.TreeStore',

        paramsAsHash: true,

        /**
         * Loads all nodes
         *
         * @param {} nodes
         */
        loadNodes: function(nodes)
        {
            this.getRootNode().appendChild(nodes);
            this.fireEvent('load', this);
        },

        /**
         * Count of nodes (always one)
         *
         * @return int
         */
        getCount: function()
        {
            return 1;
        },

        /**
         * Search node
         */
        findExact: function(field, value)
        {
            var find = function(nodes, field, value)
            {
                for (var i in nodes)
                {
                    if (nodes[i].get(field) == value)
                    {
                        return nodes[i];
                    }
                    else
                    {
                        return find(nodes[i].childNodes, field, value);
                    }
                }
            };

            var record = find(this.getRootNode().childNodes, field, value);

            return record;
        },

        /**
         * Get node from a pases position
         */
        getAt: function(record)
        {
            return record;
        }
    });

    Ext.define('HatimeriaCore.form.field.Category', {
        extend: 'HatimeriaCore.form.ComboBox',
        alias: 'widget.ux-category',
        config: {
            directFn: Ext.emptyFn
        },

        /**
         * Constructor
         */
        constructor: function(config)
        {
            this.initConfig(config);
            this.callParent([config]);

            return this;
        },

        /**
         * Initialize component
         */
        initComponent: function()
        {
            var _this = this;
            var config = {
                valueField: 'id',
                queryMode: 'local',
                displayField: 'text',
                store: Ext.create('HatimeriaCore.store.TreeStore', {
                    root: {
                        id: 'root',
                        expanded: true,
                        text: 'Wszystkie',
                        children: []
                    }
                })
            };

            Ext.apply(this, Ext.apply(config, this.initialConfig || {}));
            this.callParent();

            this.on('afterrender', function() {
                Ext.create('HatimeriaCore.direct.ResponseHandler', {
                   fn: this.getDirectFn(),
                   scope: this,
                   success: function(result) {
                       var nodes = result.record;
                       var expand = function(nodes)
                       {
                           for (var i in nodes)
                           {
                               nodes[i].expanded = true;
                               if (!nodes[i].children || nodes[i].children.length == 0)
                               {
                                   nodes[i].leaf = true;
                               }
                               expand(nodes[i].children)
                           }
                       }
                       expand(nodes);

                       _this.store.loadNodes(nodes);
                   }
                });
            });
        },

        /**
         * Creates a picker
         *
         * @return Ext.Component
         */
        createPicker: function()
        {
            var picker = Ext.create('HatimeriaCore.form.field.TreePicker', {
                ownerCt: this.ownerCt,
                store: this.store
            });

            this.mon(picker, {
                itemclick: this.onItemClick,
                scope: this
            });

            this.mon(picker.getSelectionModel(), {
                selectionChange: this.onListSelectionChange,
                scope: this
            });

            this.picker = picker;

            return picker;
        }

    });

})();<|endoftext|>


<commit_before>Titanium.include("/aux/functions.js");

Ti.App.background = '#fff';
Ti.App.color = '#000';
Ti.App.button = 'red';
Ti.App.buttoncolor = '#000';

function ApplicationWindow(title,num) {
	var top = 10;
	var self = Ti.UI.createWindow({
		title:title,
		backgroundColor:Ti.App.background
	});

	if(num == 1) {
		window1(self);
	} else if(num == 2) {
		window2(self);
	} else if(num == 3) {
		window3(self);
	}
	return self;
};

function window1(winorg) {
	var win = Ti.UI.createScrollView({
		top : 0,
		left : 0,
		width: '100%',
		height: 'auto',
		backgroundColor : Ti.App.background,

	});

	var actind = Ti.UI.createActivityIndicator({
	  color: '#9C9C9C',
	  font: {fontFamily:'Helvetica Neue', fontSize:26, fontWeight:'bold'},
	  message: 'Loading...',
	  top:150,
	  left:80,
	  height:'auto',
	  width:'auto'
	});

	var top = 10;
	createPhotoObj(win, 'img1', top, 10);
	createPhotoObj(win, 'img2', top, 110);
	createPhotoObj(win, 'img3', top, 220);

	top = top + 50;
	createHeader(win,top, 10, 'Pictures');

	top = top + 30;
	maptop = top;
	Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
	Titanium.Geolocation.distanceFilter = 0;

	function createMapLocation(e) {
		if (!e.success || e.error) {
			createLocation(win,maptop, 0, 200, Ti.App.currentlat, Ti.App.currentlng);
//			var msg = 'error: ' + JSON.stringify(e.error);
//			alert(msg);
		}
		else {
			var accuracy = e.coords.accuracy;
			var timestamp = e.coords.timestamp;
			createLocation(win,maptop, 0, 200, e.coords.latitude, e.coords.longitude);
		}
	}
	Titanium.Geolocation.getCurrentPosition(createMapLocation);

	top = top + 210;
	var location = Titanium.UI.createLabel({top : top+4, left: 10, width: 20, height : 20, text: '', backgroundImage: '/images/location.png'
	});
	Ti.App.addr = createTextInput(win,top, 40, 'no location');

	Ti.App.location = location;
	location.addEventListener('click', function(e) {
		actind.show();
		Titanium.Geolocation.getCurrentPosition(function(e) {

			try {
				var lng = e.coords.longitude;
				var lat = e.coords.latitude;
				var altitude = e.coords.altitude;
				var heading = e.coords.heading;
				var accuracy = e.coords.accuracy;
				var speed = e.coords.speed;
				var timestamp = e.coords.timestamp;
				var altitudeAccuracy = e.coords.altitudeAccuracy;
				Ti.App.currentlat = lat;
				Ti.App.currentlng = lng;

				Titanium.Geolocation.reverseGeocoder(lat,lng,function(evt)
				{
					var place = evt.places[0];
					var address = place.address;
					var addressArry = address.split(',');
					var state = addressArry[(addressArry.length - 3)];
					var street = place.street; // + " " + place.streetname;
					var city = place.city;
					var zip = place.zipcode;
					var totaladdr = street + ", " + city + ", " + state + " " + zip;

					if (evt.success) {
						actind.hide();
						var text = "";
						Ti.App.addr.value = totaladdr;
					} else {
						actind.hide();
						Ti.UI.createAlertDialog({
							title:'Forward geo error',
							message:evt.error
						}).show();
						Ti.API.info("Code translation: "+translateErrorCode(e.code));
					}
				});
			} catch (e) {
				actind.hide();
				mysimpleAlert("","Address not found at this time. Please enter manually");
			}

		});
	});

	win.add(location);

	top = top + 40;
	var desc1 = createTextInput(win, top, 10, 'Description');

	top = top + 40;
	var desc2 = createTextInput(win, top, 10, 'Why');

	top = top + 50;
	var submit = Titanium.UI.createLabel({top : top, left: 26, width: 100, height : 24, text: 'Submit', backgroundColor: Ti.App.button,
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}, color: Ti.App.buttoncolor
	});

	submit.addEventListener('click', function(e) {

		alert("SUBMITTED");
		// var url = "https://api.tropo.com/1.0/sessions?action=create&token=18cdf0354dd2a548ae3633c86b397d7bdcdf6ed1e24b14395a39a19088114c869c9146f6f75eb20b0671deef&numberToDial=4043579411&msg=MESSAGE_GOES_HERE";
		// var client = Ti.Network.createHTTPClient({
			// // function called when the response data is available
			// onload : function(e) {
				// Ti.API.info("Received text: " + this.responseText);
				// //alert('success');
			// },
			// // function called when an error occurs, including a timeout
			// onerror : function(e) {
				// Ti.API.debug(e.error);
				// alert('error');
			// },
			// timeout : 5000 // in milliseconds
		// });
		// // Prepare the connection.
		// client.open("GET", url);
		// // Send the request.
		// client.send();

	});

	win.add(submit);
	var cancel = Titanium.UI.createLabel({top : top, left: 150, width: 100, height : 24, text: 'Cancel', backgroundColor: Ti.App.button,
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}, color: Ti.App.buttoncolor
	});

	cancel.addEventListener('click', function(e) {
		deleteImages(e.source.view);
//		desc1.value='';
	});

	win.add(cancel);

	top = top + 60;
	var but2 = Titanium.UI.createLabel({top : top, left: 26, right: 26, height : 24, text: '',
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}
	});

	win.add(but2);
//	winorg.add(actind);
	winorg.add(win);

}
function window2(win) {
	Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
	Titanium.Geolocation.distanceFilter = 0;

	function createMapLocation(e) {
		if (!e.success || e.error) {

//			createLocation(win,0, 0, 600, Ti.App.currentlat, Ti.App.currentlng);
		}
		else {
			var accuracy = e.coords.accuracy;
			var timestamp = e.coords.timestamp;
//			createLocation(win,0, 0, 600, e.coords.latitude, e.coords.longitude);
		}
	}
	Titanium.Geolocation.getCurrentPosition(createMapLocation);

}

function window3(win) {
	var top = 40;
	var desc1 = createTextInput(win, top, 10, 'Your phone number');
	//desc1.value = '';  // override phone # here for testing

	top = top + 50;
	var submit2 = Titanium.UI.createLabel({top : top, left: 26, width: 100, height : 24, text: 'Submit', backgroundColor: Ti.App.button,
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}, color: Ti.App.buttoncolor
	});

	submit2.addEventListener('click', function(e) {

		var strippedPhoneNum = desc1.value.replace(/[^0-9]/g, '');

		//alert("SUBMITTED");
		// msg_type=sms
		var url = "https://api.tropo.com/1.0/sessions?action=create&token=18cdf0354dd2a548ae3633c86b397d7bdcdf6ed1e24b14395a39a19088114c869c9146f6f75eb20b0671deef&numberToDial="+strippedPhoneNum+"&msg=THANK_YOU_FOR_REPORTING_A_SIDEWALK_HAZARD.,,YOUR_HELP_IS_GREATLY_APPRECIATED.,,PLEASE_PRESS_ONE_TO_CONFIRM_THAT_YOU_INITIATED_THIS_REQUEST&message_type=CALL";
		var client = Ti.Network.createHTTPClient({
			// function called when the response data is available
			onload : function(e) {
				Ti.API.info("Received text: " + this.responseText);
				alert('Thank you.  You will receive a confirmation call shortly.');
			},
			// function called when an error occurs, including a timeout
			onerror : function(e) {
				Ti.API.debug(e.error);
				alert('error');
			},
			timeout : 5000 // in milliseconds
		});
		// Prepare the connection.
		client.open("GET", url);
		// Send the request.
		client.send();

	});
	win.add(submit2);

}
module.exports = ApplicationWindow;
<commit_msg>add to Ti.Geolocation.purpose to hopefully fix geolocation on iOS<commit_after>Titanium.include("/aux/functions.js");

Ti.App.background = '#fff';
Ti.App.color = '#000';
Ti.App.button = 'red';
Ti.App.buttoncolor = '#000';

function ApplicationWindow(title,num) {
	var top = 10;
	var self = Ti.UI.createWindow({
		title:title,
		backgroundColor:Ti.App.background
	});

	if(num == 1) {
		window1(self);
	} else if(num == 2) {
		window2(self);
	} else if(num == 3) {
		window3(self);
	}
	return self;
};

function window1(winorg) {
	Ti.Geolocation.purpose = "Recieve User Location";

	var win = Ti.UI.createScrollView({
		top : 0,
		left : 0,
		width: '100%',
		height: 'auto',
		backgroundColor : Ti.App.background,

	});

	var actind = Ti.UI.createActivityIndicator({
	  color: '#9C9C9C',
	  font: {fontFamily:'Helvetica Neue', fontSize:26, fontWeight:'bold'},
	  message: 'Loading...',
	  top:150,
	  left:80,
	  height:'auto',
	  width:'auto'
	});

	var top = 10;
	createPhotoObj(win, 'img1', top, 10);
	createPhotoObj(win, 'img2', top, 110);
	createPhotoObj(win, 'img3', top, 220);

	top = top + 50;
	createHeader(win,top, 10, 'Pictures');

	top = top + 30;
	maptop = top;
	Ti.Geolocation.purpose = "Recieve User Location";
	Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
	Titanium.Geolocation.distanceFilter = 0;

	function createMapLocation(e) {
		if (!e.success || e.error) {
			createLocation(win,maptop, 0, 200, Ti.App.currentlat, Ti.App.currentlng);
//			var msg = 'error: ' + JSON.stringify(e.error);
//			alert(msg);
		}
		else {
			var accuracy = e.coords.accuracy;
			var timestamp = e.coords.timestamp;
			createLocation(win,maptop, 0, 200, e.coords.latitude, e.coords.longitude);
		}
	}

	Titanium.Geolocation.getCurrentPosition(createMapLocation);

	top = top + 210;
	var location = Titanium.UI.createLabel({top : top+4, left: 10, width: 20, height : 20, text: '', backgroundImage: '/images/location.png'
	});
	Ti.App.addr = createTextInput(win,top, 40, 'no location');

	Ti.App.location = location;
	location.addEventListener('click', function(e) {
		actind.show();
		Titanium.Geolocation.getCurrentPosition(function(e) {

			try {
				var lng = e.coords.longitude;
				var lat = e.coords.latitude;
				var altitude = e.coords.altitude;
				var heading = e.coords.heading;
				var accuracy = e.coords.accuracy;
				var speed = e.coords.speed;
				var timestamp = e.coords.timestamp;
				var altitudeAccuracy = e.coords.altitudeAccuracy;
				Ti.App.currentlat = lat;
				Ti.App.currentlng = lng;

				Titanium.Geolocation.reverseGeocoder(lat,lng,function(evt)
				{
					var place = evt.places[0];
					var address = place.address;
					var addressArry = address.split(',');
					var state = addressArry[(addressArry.length - 3)];
					var street = place.street; // + " " + place.streetname;
					var city = place.city;
					var zip = place.zipcode;
					var totaladdr = street + ", " + city + ", " + state + " " + zip;

					if (evt.success) {
						actind.hide();
						var text = "";
						Ti.App.addr.value = totaladdr;
					} else {
						actind.hide();
						Ti.UI.createAlertDialog({
							title:'Forward geo error',
							message:evt.error
						}).show();
						Ti.API.info("Code translation: "+translateErrorCode(e.code));
					}
				});
			} catch (e) {
				actind.hide();
				mysimpleAlert("","Address not found at this time. Please enter manually");
			}

		});
	});

	win.add(location);

	top = top + 40;
	var desc1 = createTextInput(win, top, 10, 'Description');

	top = top + 40;
	var desc2 = createTextInput(win, top, 10, 'Why');

	top = top + 50;
	var submit = Titanium.UI.createLabel({top : top, left: 26, width: 100, height : 24, text: 'Submit', backgroundColor: Ti.App.button,
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}, color: Ti.App.buttoncolor
	});

	submit.addEventListener('click', function(e) {

		alert("SUBMITTED");
		// var url = "https://api.tropo.com/1.0/sessions?action=create&token=18cdf0354dd2a548ae3633c86b397d7bdcdf6ed1e24b14395a39a19088114c869c9146f6f75eb20b0671deef&numberToDial=4043579411&msg=MESSAGE_GOES_HERE";
		// var client = Ti.Network.createHTTPClient({
			// // function called when the response data is available
			// onload : function(e) {
				// Ti.API.info("Received text: " + this.responseText);
				// //alert('success');
			// },
			// // function called when an error occurs, including a timeout
			// onerror : function(e) {
				// Ti.API.debug(e.error);
				// alert('error');
			// },
			// timeout : 5000 // in milliseconds
		// });
		// // Prepare the connection.
		// client.open("GET", url);
		// // Send the request.
		// client.send();

	});

	win.add(submit);
	var cancel = Titanium.UI.createLabel({top : top, left: 150, width: 100, height : 24, text: 'Cancel', backgroundColor: Ti.App.button,
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}, color: Ti.App.buttoncolor
	});

	cancel.addEventListener('click', function(e) {
		deleteImages(e.source.view);
//		desc1.value='';
	});

	win.add(cancel);

	top = top + 60;
	var but2 = Titanium.UI.createLabel({top : top, left: 26, right: 26, height : 24, text: '',
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}
	});

	win.add(but2);
//	winorg.add(actind);
	winorg.add(win);

}
function window2(win) {
	Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;
	Titanium.Geolocation.distanceFilter = 0;

	function createMapLocation(e) {
		if (!e.success || e.error) {

//			createLocation(win,0, 0, 600, Ti.App.currentlat, Ti.App.currentlng);
		}
		else {
			var accuracy = e.coords.accuracy;
			var timestamp = e.coords.timestamp;
//			createLocation(win,0, 0, 600, e.coords.latitude, e.coords.longitude);
		}
	}
	Titanium.Geolocation.getCurrentPosition(createMapLocation);

}

function window3(win) {
	var top = 40;
	var desc1 = createTextInput(win, top, 10, 'Your phone number');
	//desc1.value = '';  // override phone # here for testing

	top = top + 50;
	var submit2 = Titanium.UI.createLabel({top : top, left: 26, width: 100, height : 24, text: 'Submit', backgroundColor: Ti.App.button,
 		textAlign: 'center', font : {fontSize : '16', fontWeight : 'bold', fontFamily : 'Arial'}, color: Ti.App.buttoncolor
	});

	submit2.addEventListener('click', function(e) {

		var strippedPhoneNum = desc1.value.replace(/[^0-9]/g, '');

		//alert("SUBMITTED");
		// msg_type=sms
		var url = "https://api.tropo.com/1.0/sessions?action=create&token=18cdf0354dd2a548ae3633c86b397d7bdcdf6ed1e24b14395a39a19088114c869c9146f6f75eb20b0671deef&numberToDial="+strippedPhoneNum+"&msg=THANK_YOU_FOR_REPORTING_A_SIDEWALK_HAZARD.,,YOUR_HELP_IS_GREATLY_APPRECIATED.,,PLEASE_PRESS_ONE_TO_CONFIRM_THAT_YOU_INITIATED_THIS_REQUEST&message_type=CALL";
		var client = Ti.Network.createHTTPClient({
			// function called when the response data is available
			onload : function(e) {
				Ti.API.info("Received text: " + this.responseText);
				alert('Thank you.  You will receive a confirmation call shortly.');
			},
			// function called when an error occurs, including a timeout
			onerror : function(e) {
				Ti.API.debug(e.error);
				alert('error');
			},
			timeout : 5000 // in milliseconds
		});
		// Prepare the connection.
		client.open("GET", url);
		// Send the request.
		client.send();

	});
	win.add(submit2);

}
module.exports = ApplicationWindow;
<|endoftext|>


<commit_before>var currentTimeout;
function actionWrapper(searchAction){
  return function(){
    const DEFAULT_TIMEOUT = 5000;
    var context = this || {};
    var args = arguments;
    if(currentTimeout){
      //Cancel previous search action.
      window.clearTimeout(currentTimeout);
    }
    currentTimeout = window.setTimeout(
      function(){
        searchAction.apply(context, args)
      },
      DEFAULT_TIMEOUT
    );
    return currentTimeout;
  };
}
module.exports = actionWrapper;
<commit_msg>[action-wrapper] Add an action wrapper props.<commit_after>const DEFAULT_TIMEOUT = 5000;
var currentTimeout;
function actionWrapper(searchAction, context){
  return function(){
    context = context || this || {};
    var args = arguments;
    if(currentTimeout){
      //Cancel previous search action.
      window.clearTimeout(currentTimeout);
    }
    currentTimeout = window.setTimeout(
      function(){
        searchAction.apply(context, args)
      },
      DEFAULT_TIMEOUT
    );
    return currentTimeout;
  };
}
module.exports = actionWrapper;
<|endoftext|>


<commit_before>if( typeof module !== 'undefined' )
{
  // require( '../../wTools/staging/abase/wTools.s' )
  require( 'wTools' )
  require( '../staging/amid/file/Files.ss' )
  require( '../staging/amid/file/FileProviderSimpleStructure.s' )
  //require( '../../wDeployer/staging/amid/deployer/Deployer.ss' )

}

var _ = wTools;

// var deployer = new wDeployer();`
// deployer.read( __dirname );
//_.FileProvider.Abstract.readFileSync( { pathFile : __dirname + 'sample3.js' } );
var files = _.FileProvider.HardDrive();
var read = files.fileReadSync( { pathFile : __filename } );
console.log( 'read :',read );
<commit_msg>sample update<commit_after>if( typeof module !== 'undefined' )
{
  // require( '../../wTools/staging/abase/wTools.s' )
  require( 'wTools' )
  require( '../staging/amid/file/Files.ss' )
  require( '../staging/amid/file/FileProviderSimpleStructure.s' )
  // require( '../../wDeployer/staging/amid/deployer/Deployer.ss' )

}

var _ = wTools;

// var deployer = new wDeployer();
// deployer.read( __dirname );
//_.FileProvider.Abstract.readFileSync( { pathFile : __dirname + 'sample3.js' } );
var files = _.FileProvider.SimpleStructure();
var read = files.fileReadSync( { pathFile : __filename } );
console.log( 'read :',read );
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path');

function getStamp(dir, name, target) {
  return path.join(dir, name, target, 'timestamp');
}

function createTask(grunt, any) {
  return function(name, target) {
    if (!target) {
      var tasks = [];
      Object.keys(grunt.config(name)).forEach(function(target) {
        if (!/^_|^options$/.test(target)) {
          tasks.push('newer:' + name + ':' + target);
        }
      });
      return grunt.task.run(tasks);
    }
    var args = Array.prototype.slice.call(arguments, 2).join(':');
    var options = this.options({
      timestamps: path.join(__dirname, '..', '.cache')
    });
    var config = grunt.config.get([name, target]);

    /**
     * Special handling for watch task.  This is a multitask that expects
     * the `files` config to be a string or array of string source paths.
     */
    var srcFiles = true;
    if (typeof config.files === 'string') {
      config.src = [config.files];
      delete config.files;
      srcFiles = false;
    } else if (Array.isArray(config.files) &&
        typeof config.files[0] === 'string') {
      config.src = config.files;
      delete config.files;
      srcFiles = false;
    }

    var files = grunt.task.normalizeMultiTaskFiles(config, target);

    var newerFiles;
    var stamp = getStamp(options.timestamps, name, target);
    var repeat = grunt.file.exists(stamp);
    var modified = false;

    if (repeat) {
      // look for files that have been modified since last run
      var previous = fs.statSync(stamp).mtime;
      newerFiles = files.map(function(obj) {
        var src = obj.src.filter(function(filepath) {
          var newer = fs.statSync(filepath).mtime > previous;
          if (newer) {
            modified = true;
          }
          return newer;
        });
        return {src: src, dest: obj.dest};
      });
    }

    /**
     * If we started out with only src files in the files config, transform
     * the newerFiles array into an array of source files.
     */
    if (!srcFiles) {
      newerFiles = newerFiles.map(function(obj) {
        return obj.src;
      });
    }

    /**
     * Cases:
     *
     * 1) First run, process all.
     * 2) Repeat run, nothing modified, process none.
     * 3) Repeat run, something modified, any false, process modified.
     * 4) Repeat run, something modified, any true, process all.
     */

    var qualified = name + ':' + target;
    if (repeat && !modified) {
      // case 2
      grunt.log.writeln('No newer files to process.');
    } else {
      if (repeat && modified && !any) {
        // case 3
        config.files = newerFiles;
        delete config.src;
        delete config.dest;
        grunt.config.set([name, target], config);
      }
      // case 1, 3 or 4
      grunt.task.run([
        qualified + (args ? ':' + args : ''),
        'newer-timestamp:' + qualified + ':' + options.timestamps
      ]);
    }
  };
}

/** @param {Object} grunt Grunt. */
module.exports = function(grunt) {

  grunt.registerTask(
      'newer', 'Run a task with only those source files that have been ' +
      'modified since the last successful run.', createTask(grunt));

  grunt.registerTask(
      'any-newer', 'Run a task with all source files if any have been ' +
      'modified since the last successful run.', createTask(grunt, true));

  grunt.registerTask(
      'newer-timestamp', 'Internal task.', function(name, target, dir) {
        // if dir includes a ':', grunt will split it among multiple args
        dir = Array.prototype.slice.call(arguments, 2).join(':');
        grunt.file.write(getStamp(dir, name, target), '');
      });

};
<commit_msg>Use mtime of dest file if it is more recent<commit_after>var fs = require('fs');
var path = require('path');

function getStamp(dir, name, target) {
  return path.join(dir, name, target, 'timestamp');
}

function createTask(grunt, any) {
  return function(name, target) {
    if (!target) {
      var tasks = [];
      Object.keys(grunt.config(name)).forEach(function(target) {
        if (!/^_|^options$/.test(target)) {
          tasks.push('newer:' + name + ':' + target);
        }
      });
      return grunt.task.run(tasks);
    }
    var args = Array.prototype.slice.call(arguments, 2).join(':');
    var options = this.options({
      timestamps: path.join(__dirname, '..', '.cache')
    });
    var config = grunt.config.get([name, target]);

    /**
     * Special handling for watch task.  This is a multitask that expects
     * the `files` config to be a string or array of string source paths.
     */
    var srcFiles = true;
    if (typeof config.files === 'string') {
      config.src = [config.files];
      delete config.files;
      srcFiles = false;
    } else if (Array.isArray(config.files) &&
        typeof config.files[0] === 'string') {
      config.src = config.files;
      delete config.files;
      srcFiles = false;
    }

    var files = grunt.task.normalizeMultiTaskFiles(config, target);

    var newerFiles;
    var stamp = getStamp(options.timestamps, name, target);
    var repeat = grunt.file.exists(stamp);
    var modified = false;

    if (repeat) {
      // look for files that have been modified since last run
      var previous = fs.statSync(stamp).mtime;
      newerFiles = files.map(function(obj) {
        var time;
        /**
         * It is possible that there is a dest file that has been created
         * more recently than the last successful run.  This would happen if
         * a target with multiple dest files failed before all dest files were
         * created.  In this case, we don't need to re-run src files that map
         * to dest files that were already created.
         */
        if (obj.dest && grunt.file.exists(obj.dest)) {
          time = Math.max(fs.statSync(obj.dest).mtime, previous);
        } else {
          time = previous;
        }
        var src = obj.src.filter(function(filepath) {
          var newer = fs.statSync(filepath).mtime > time;
          if (newer) {
            modified = true;
          }
          return newer;
        });
        return {src: src, dest: obj.dest};
      });
    }

    /**
     * If we started out with only src files in the files config, transform
     * the newerFiles array into an array of source files.
     */
    if (!srcFiles) {
      newerFiles = newerFiles.map(function(obj) {
        return obj.src;
      });
    }

    /**
     * Cases:
     *
     * 1) First run, process all.
     * 2) Repeat run, nothing modified, process none.
     * 3) Repeat run, something modified, any false, process modified.
     * 4) Repeat run, something modified, any true, process all.
     */

    var qualified = name + ':' + target;
    if (repeat && !modified) {
      // case 2
      grunt.log.writeln('No newer files to process.');
    } else {
      if (repeat && modified && !any) {
        // case 3
        config.files = newerFiles;
        delete config.src;
        delete config.dest;
        grunt.config.set([name, target], config);
      }
      // case 1, 3 or 4
      grunt.task.run([
        qualified + (args ? ':' + args : ''),
        'newer-timestamp:' + qualified + ':' + options.timestamps
      ]);
    }
  };
}

/** @param {Object} grunt Grunt. */
module.exports = function(grunt) {

  grunt.registerTask(
      'newer', 'Run a task with only those source files that have been ' +
      'modified since the last successful run.', createTask(grunt));

  grunt.registerTask(
      'any-newer', 'Run a task with all source files if any have been ' +
      'modified since the last successful run.', createTask(grunt, true));

  grunt.registerTask(
      'newer-timestamp', 'Internal task.', function(name, target, dir) {
        // if dir includes a ':', grunt will split it among multiple args
        dir = Array.prototype.slice.call(arguments, 2).join(':');
        grunt.file.write(getStamp(dir, name, target), '');
      });

};
<|endoftext|>


<commit_before>'use strict';
var exec = require('child_process').exec;
var chalk = require('chalk');

module.exports = function (grunt) {
	grunt.registerMultiTask('shell', 'Run shell commands', function () {
		var cb = this.async();
		var options = this.options({
			stdout: true,
			stderr: true,
			stdin: true,
			failOnError: true
		});
		var cmd = this.data.command;

		if (cmd === undefined) {
			throw new Error('`command` required');
		}

		cmd = grunt.template.process(typeof cmd === 'function' ? cmd.apply(grunt, arguments) : cmd);

		var cp = exec(cmd, options.execOptions, function (err, stdout, stderr) {
			if (typeof options.callback === 'function') {
				options.callback.call(this, err, stdout, stderr, cb);
			} else {
				if (err && options.failOnError) {
					grunt.warn(err);
				}
				cb();
			}
		}.bind(this));

		var captureOutput = function (child, output) {
			if (grunt.option('color') === false) {
				child.on('data', function (data) {
					output.write(chalk.stripColor(data));
				});
			} else {
				child.pipe(output);
			}
		};

		grunt.verbose.writeln('Command:', chalk.yellow(cmd));

		if (options.stdout || grunt.option('verbose')) {
			captureOutput(cp.stdout, process.stdout);
		}

		if (options.stderr || grunt.option('verbose')) {
			captureOutput(cp.stderr, process.stderr);
		}

		if (options.stdin) {
			process.stdin.resume();
			process.stdin.setEncoding('utf8');
			process.stdin.setRawMode(true);
			process.stdin.pipe(cp.stdin);
		}
	});
};
<commit_msg>Use 'setRawMode' only when defined as a function<commit_after>'use strict';
var exec = require('child_process').exec;
var chalk = require('chalk');

module.exports = function (grunt) {
	grunt.registerMultiTask('shell', 'Run shell commands', function () {
		var cb = this.async();
		var options = this.options({
			stdout: true,
			stderr: true,
			stdin: true,
			failOnError: true
		});
		var cmd = this.data.command;

		if (cmd === undefined) {
			throw new Error('`command` required');
		}

		cmd = grunt.template.process(typeof cmd === 'function' ? cmd.apply(grunt, arguments) : cmd);

		var cp = exec(cmd, options.execOptions, function (err, stdout, stderr) {
			if (typeof options.callback === 'function') {
				options.callback.call(this, err, stdout, stderr, cb);
			} else {
				if (err && options.failOnError) {
					grunt.warn(err);
				}
				cb();
			}
		}.bind(this));

		var captureOutput = function (child, output) {
			if (grunt.option('color') === false) {
				child.on('data', function (data) {
					output.write(chalk.stripColor(data));
				});
			} else {
				child.pipe(output);
			}
		};

		grunt.verbose.writeln('Command:', chalk.yellow(cmd));

		if (options.stdout || grunt.option('verbose')) {
			captureOutput(cp.stdout, process.stdout);
		}

		if (options.stderr || grunt.option('verbose')) {
			captureOutput(cp.stderr, process.stderr);
		}

		if (options.stdin) {
			process.stdin.resume();
			process.stdin.setEncoding('utf8');
			if (typeof process.stdin.setRawMode === 'function') {
				process.stdin.setRawMode(true);
			}
			process.stdin.pipe(cp.stdin);
		}
	});
};
<|endoftext|>


<commit_before>/**
 * grunt-uncss
 * https://github.com/addyosmani/grunt-uncss
 *
 * Copyright (c) 2015 Addy Osmani
 * Licensed under the MIT license.
 */

'use strict';
var uncss  = require( 'uncss' ),
    chalk  = require( 'chalk' ),
    maxmin = require( 'maxmin' );

module.exports = function ( grunt ) {
    grunt.registerMultiTask( 'uncss', 'Remove unused CSS', function () {

        var done    = this.async(),
            options = this.options({
                report: 'min'
            });

        options.urls = options.urls || [];

        this.files.forEach(function ( file ) {

            var src = file.src.filter(function ( filepath ) {
                // Warn on and remove invalid source files (if nonull was set).
                if ( !grunt.file.exists( filepath ) ) {
                    grunt.log.warn( 'Source file ' + chalk.cyan( filepath ) + ' not found.' );
                    return false;
                } else {
                    return true;
                }
            });

            if ( src.length === 0 && file.orig.src.length === 0 ) {
                grunt.fail.warn( 'Destination (' + file.dest + ') not written because src files were empty.' );
            }

            file.orig.src.forEach(function (source) {
                if (/^https?/.test(source)) {
                    src.push(source);
                    options.urls.push(source);
                }
            });

            try {
                uncss( src, options, function ( error, output, report ) {
                    if ( error ) {
                        throw error;
                    }

                    grunt.file.write( file.dest, output );
                    grunt.log.writeln('File ' + chalk.cyan( file.dest ) + ' created: ' + maxmin( report.original, output, options.report === 'gzip' ) );
                    if (typeof(options.reportFile) !== 'undefined' && options.reportFile.length > 0) {
                        grunt.file.write(options.reportFile, JSON.stringify(report));
                    }
                    done();
                });
            } catch ( e ) {
                var err = new Error( 'Uncss failed.' );
                if ( e.msg ) {
                    err.message += ', ' + e.msg + '.';
                }
                err.origError = e;
                grunt.log.warn( 'Uncssing source "' + src + '" failed.' );
                grunt.fail.warn( err );
            }

        });

    });

};
<commit_msg>Fix issue #141 Object has no method 'forEach'<commit_after>/**
 * grunt-uncss
 * https://github.com/addyosmani/grunt-uncss
 *
 * Copyright (c) 2015 Addy Osmani
 * Licensed under the MIT license.
 */

'use strict';
var uncss  = require( 'uncss' ),
    chalk  = require( 'chalk' ),
    maxmin = require( 'maxmin' );

module.exports = function ( grunt ) {
    grunt.registerMultiTask( 'uncss', 'Remove unused CSS', function () {

        var done    = this.async(),
            options = this.options({
                report: 'min'
            });

        options.urls = options.urls || [];

        this.files.forEach(function ( file ) {

            var src = file.src.filter(function ( filepath ) {
                // Warn on and remove invalid source files (if nonull was set).
                if ( !grunt.file.exists( filepath ) ) {
                    grunt.log.warn( 'Source file ' + chalk.cyan( filepath ) + ' not found.' );
                    return false;
                } else {
                    return true;
                }
            });

            if ( src.length === 0 && file.src.length === 0 ) {
                grunt.fail.warn( 'Destination (' + file.dest + ') not written because src files were empty.' );
            }

            file.src.forEach(function (source) {
                if (/^https?/.test(source)) {
                    src.push(source);
                    options.urls.push(source);
                }
            });

            try {
                uncss( src, options, function ( error, output, report ) {
                    if ( error ) {
                        throw error;
                    }

                    grunt.file.write( file.dest, output );
                    grunt.log.writeln('File ' + chalk.cyan( file.dest ) + ' created: ' + maxmin( report.original, output, options.report === 'gzip' ) );
                    if (typeof(options.reportFile) !== 'undefined' && options.reportFile.length > 0) {
                        grunt.file.write(options.reportFile, JSON.stringify(report));
                    }
                    done();
                });
            } catch ( e ) {
                var err = new Error( 'Uncss failed.' );
                if ( e.msg ) {
                    err.message += ', ' + e.msg + '.';
                }
                err.origError = e;
                grunt.log.warn( 'Uncssing source "' + src + '" failed.' );
                grunt.fail.warn( err );
            }

        });

    });

};
<|endoftext|>


<commit_before><commit_msg>watching html, css, img, js  and svg files<commit_after>var pkg = require('../package.json')
var gulp = require('gulp')

gulp.task('watch', ['sync'], function () {
  global.isWatching = true

  gulp.watch(pkg.folders.src + '/html/**', ['html'])
  gulp.watch(pkg.folders.src + '/css/**', ['css'])
  gulp.watch(pkg.folders.src + '/img/**', ['img'])
  gulp.watch(pkg.folders.src + '/js/**', ['js'])
  gulp.watch(pkg.folders.src + '/svg/**', ['svg'])
})
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../../utils/Class');
var MultiPipeline = require('./MultiPipeline');

/**
 * @classdesc
 *
 * The Rope Pipeline is a variation of the Multi Pipeline that uses a `TRIANGLE_STRIP` for
 * its topology, instead of TRIANGLES. This is primarily used by the Rope Game Object,
 * or anything that extends it.
 *
 * Prior to Phaser v3.50 this pipeline was called the `TextureTintStripPipeline`.
 *
 * The fragment shader it uses can be found in `shaders/src/Multi.frag`.
 * The vertex shader it uses can be found in `shaders/src/Multi.vert`.
 *
 * The default shader attributes for this pipeline are:
 *
 * `inPosition` (vec2, offset 0)
 * `inTexCoord` (vec2, offset 8)
 * `inTexId` (float, offset 16)
 * `inTintEffect` (float, offset 20)
 * `inTint` (vec4, offset 24, normalized)
 *
 * The default shader uniforms for this pipeline are:
 *
 * `uProjectionMatrix` (mat4)
 * `uViewMatrix` (mat4)
 * `uModelMatrix` (mat4)
 * `uMainSampler` (sampler2D array)
 *
 * The pipeline is structurally identical to the Multi Pipeline and should be treated as such.
 *
 * @class RopePipeline
 * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline
 * @memberof Phaser.Renderer.WebGL.Pipelines
 * @constructor
 * @since 3.50.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
 */
var RopePipeline = new Class({

    Extends: MultiPipeline,

    initialize:

    function RopePipeline (config)
    {
        config.topology = config.game.renderer.gl.TRIANGLE_STRIP;

        MultiPipeline.call(this, config);
    }
});

module.exports = RopePipeline;
<commit_msg>Use GLenum value and limit batch size to 256<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

var Class = require('../../../utils/Class');
var GetFastValue = require('../../../utils/object/GetFastValue');
var MultiPipeline = require('./MultiPipeline');

/**
 * @classdesc
 *
 * The Rope Pipeline is a variation of the Multi Pipeline that uses a `TRIANGLE_STRIP` for
 * its topology, instead of TRIANGLES. This is primarily used by the Rope Game Object,
 * or anything that extends it.
 *
 * Prior to Phaser v3.50 this pipeline was called the `TextureTintStripPipeline`.
 *
 * The fragment shader it uses can be found in `shaders/src/Multi.frag`.
 * The vertex shader it uses can be found in `shaders/src/Multi.vert`.
 *
 * The default shader attributes for this pipeline are:
 *
 * `inPosition` (vec2, offset 0)
 * `inTexCoord` (vec2, offset 8)
 * `inTexId` (float, offset 16)
 * `inTintEffect` (float, offset 20)
 * `inTint` (vec4, offset 24, normalized)
 *
 * The default shader uniforms for this pipeline are:
 *
 * `uProjectionMatrix` (mat4)
 * `uViewMatrix` (mat4)
 * `uModelMatrix` (mat4)
 * `uMainSampler` (sampler2D array)
 *
 * The pipeline is structurally identical to the Multi Pipeline and should be treated as such.
 *
 * @class RopePipeline
 * @extends Phaser.Renderer.WebGL.Pipelines.MultiPipeline
 * @memberof Phaser.Renderer.WebGL.Pipelines
 * @constructor
 * @since 3.50.0
 *
 * @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration options for this pipeline.
 */
var RopePipeline = new Class({

    Extends: MultiPipeline,

    initialize:

    function RopePipeline (config)
    {
        //  GLenum 5 = TRIANGLE_STRIP
        config.topology = 5;
        config.batchSize = GetFastValue(config, 'batchSize', 256);

        MultiPipeline.call(this, config);
    }
});

module.exports = RopePipeline;
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var nunjucks = require('gulp-nunjucks');
var filecount = require('./filecount');

function templateStrings(target) {
  var requirejs = require('requirejs').config({
    baseUrl: 'scripts',
    paths: {
      options: `../${target}/scripts/options`,
      presets: `../${target}/scripts/presets`,
      strings: `../${target}/scripts/strings`
    },
    nodeRequire: require
  });

  var strings = requirejs('ui/strings');
  strings.version = require('./version');

  return strings;
}

module.exports = function (target, sources) {
  let target_templates = `${target}/templates/*.html`;
  let temp_template_dir = `tmp/templates/${target}/`;

  gulp.task(`template-${target}-sources`, function () {
    return gulp.src([sources.templates, target_templates])
      .pipe(filecount())
      .pipe(gulp.dest(temp_template_dir));
  });

  gulp.task(`template-${target}`, [`template-${target}-sources`],
    function () {
      return gulp.src(temp_template_dir + '/index.html')
        .pipe(filecount())
        .pipe(nunjucks.compile(templateStrings(target)))
        .pipe(filecount())
        .pipe(gulp.dest(target));
    });

  return `template-${target}`;
};
<commit_msg>templates: requirejs must be isolated by gulp-run<commit_after>'use strict';

var gulp = require('gulp');
var run = require('gulp-run');
var nunjucks = require('gulp-nunjucks');
var filecount = require('./filecount');

function templateStrings(target) {
  var requirejs = require('requirejs').config({
    baseUrl: 'scripts',
    paths: {
      'options': `../${target}/scripts/options`,
      'presets': `../${target}/scripts/presets`,
      'strings': `../${target}/scripts/strings`
    },
    nodeRequire: require
  });

  var strings = requirejs('ui/strings');
  strings.version = require('./version');

  return strings;
}

module.exports = function (target, sources) {
  let target_templates = `${target}/templates/*.html`;
  let temp_template_dir = `tmp/templates/${target}/`;

  gulp.task(`template-${target}-sources`, function () {
    return gulp.src([sources.templates, target_templates])
      .pipe(filecount())
      .pipe(gulp.dest(temp_template_dir));
  });

  gulp.task(`template-${target}-internal`, function () {
    return gulp.src(temp_template_dir + '/index.html')
      .pipe(filecount())
      .pipe(nunjucks.compile(templateStrings(target)))
      .pipe(filecount())
      .pipe(gulp.dest(target));
  });

  gulp.task(`template-${target}`, [`template-${target}-sources`], function () {
    return run(`gulp template-${target}-internal`).exec();
  });

  return `template-${target}`;
};
<|endoftext|>


<commit_before>var env = require('../env.js');
var gulp = require('gulp');
var iconfont = require('gulp-iconfont');
var iconfontcss = require('gulp-iconfont-css');
var consolidate = require('gulp-consolidate');

module.exports = function() {
  var fontName = 'OwFont';
  var className = 'OwIcon';

  gulp.src([env.folder.src + '/assets/icons/svgs/*.svg'])
    .pipe(iconfont({
      className: className,
      appendCodepoints: true,
      fontName: fontName,
      appendUnicode: true
    }))
    .on('glyphs', function(glyphs, options) {
      for(i = 0; i < glyphs.length; i++){
        glyphs[i].codepoint = 0xEA01 + i;
      }
      gulp.src([env.folder.src + '/assets/icons/template/iconsViewer.html'])
        .pipe(consolidate('lodash', {
          glyphs: glyphs,
          fontName: fontName,
          className: className
        }))
        .pipe(gulp.dest(env.folder.src + '/fonts/dev/'));

      gulp.src(env.folder.src + '/assets/icons/template/iconsViewer.css')
        .pipe(consolidate('lodash', {
          glyphs: glyphs,
          fontName: fontName,
          className: className,
          fontPath: '../fonts/'
        }))
        .pipe(gulp.dest(env.folder.src + '/fonts/dev/'));

      gulp.src(env.folder.src + '/assets/icons/template/_icons.scss')
        .pipe(consolidate('lodash', {
          glyphs: glyphs,
          fontName: fontName,
          className: className,
          fontPath: './fonts/'
        }))
        .pipe(gulp.dest(env.folder.src + '/styles/4-base/partials/'));
    })
    .on('error', function (err) {
      util.log(util.colors.yellow(err.message));
      this.emit('end');
    })
    .pipe(gulp.dest(env.folder.src + '/fonts/'));
};
<commit_msg>added util<commit_after>var env = require('../env.js');
var gulp = require('gulp');
var iconfont = require('gulp-iconfont');
var iconfontcss = require('gulp-iconfont-css');
var consolidate = require('gulp-consolidate');
var util = require('gulp-util');

module.exports = function() {
  var fontName = 'OwFont';
  var className = 'OwIcon';

  gulp.src([env.folder.src + '/assets/icons/svgs/*.svg'])
    .pipe(iconfont({
      className: className,
      appendCodepoints: true,
      fontName: fontName,
      appendUnicode: true
    }))
    .on('glyphs', function(glyphs, options) {
      for(i = 0; i < glyphs.length; i++){
        glyphs[i].codepoint = 0xEA01 + i;
      }
      gulp.src([env.folder.src + '/assets/icons/template/iconsViewer.html'])
        .pipe(consolidate('lodash', {
          glyphs: glyphs,
          fontName: fontName,
          className: className
        }))
        .pipe(gulp.dest(env.folder.src + '/fonts/dev/'));

      gulp.src(env.folder.src + '/assets/icons/template/iconsViewer.css')
        .pipe(consolidate('lodash', {
          glyphs: glyphs,
          fontName: fontName,
          className: className,
          fontPath: '../fonts/'
        }))
        .pipe(gulp.dest(env.folder.src + '/fonts/dev/'));

      gulp.src(env.folder.src + '/assets/icons/template/_icons.scss')
        .pipe(consolidate('lodash', {
          glyphs: glyphs,
          fontName: fontName,
          className: className,
          fontPath: './fonts/'
        }))
        .pipe(gulp.dest(env.folder.src + '/styles/4-base/partials/'));
    })
    .on('error', function (err) {
      util.log(util.colors.yellow(err.message));
      this.emit('end');
    })
    .pipe(gulp.dest(env.folder.src + '/fonts/'));
};
<|endoftext|>


<commit_before>/* @flow */
import React from 'react'
var LocalStorageMixin = require('react-localstorage');

const state_key = "togglol-api-state";

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

        if(localStorage.getItem(state_key) == null) {
            this.state = {
            value: ''
            };
        }
        else {
            this.state = JSON.parse(localStorage.getItem(state_key));
        }
    }
    render() {
        return(

                        <input value={this.state.value} maxlength="32" id="apikeyInput" placeholder="Toggl API key" className="form-control" type="text" onChange={this.handleChange.bind(this)}/>

                            <button className="btn btn-outline-primary" onClick={this.handlePress.bind(this)}>1. Set API key</button>
                            <button className="btn btn-outline-primary" onClick={this.handleLoadPress.bind(this)}>2. Load user info</button>

            );
    }

    handlePress(event) {
        event.preventDefault();
        //this.props.onSet(this.state.value);
        this.props.onSet(this.state.value);
        localStorage.setItem(state_key, JSON.stringify(this.state));
    }

    handleLoadPress(event) {
        event.preventDefault();
        this.props.onLoad();
    }

    handleChange(event) {
        this.setState({value: event.target.value})
    }
}

ApiKeyInput.propTypes = {
  onSet: React.PropTypes.func.isRequired,
  onLoad: React.PropTypes.func.isRequired
}

var inputStyle = {
    width: '300px'
}

export default ApiKeyInput<commit_msg>Simplify ApiKeyInput<commit_after>/* @flow */
import React from 'react'
var LocalStorageMixin = require('react-localstorage');

const state_key = "togglol-api-state";

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

        if(localStorage.getItem(state_key) == null) {
            this.state = {
            value: ''
            };
        }
        else {
            var savedState = JSON.parse(localStorage.getItem(state_key));
            this.state = savedState;
        }
    }

    componentDidMount() {
        this.enterApiKey(this.state.value);
    }

    render() {
        return(

                        <input value={this.state.value} maxlength="32" id="apikeyInput" placeholder="Toggl API key" className="form-control" type="text" onChange={(e) => this.onChange(e)}/>

                            <button className="btn btn-outline-primary" onClick={this.handleLoadPress.bind(this)}>Login</button>

            );
    }

    onChange(event) {
        var apiKey = event.target.value;
        this.enterApiKey(apiKey);
    }

    enterApiKey(apiKey) {
        // Store state
        var newState = {value: apiKey};
        this.setState(newState);
        localStorage.setItem(state_key, JSON.stringify(newState));

        // Send action
        this.props.onSet(apiKey);

    }

    handleLoadPress(event) {
        event.preventDefault();
        this.props.onLoad();
    }
}

ApiKeyInput.propTypes = {
  onSet: React.PropTypes.func.isRequired,
  onLoad: React.PropTypes.func.isRequired
}

var inputStyle = {
    width: '300px'
}

export default ApiKeyInput<|endoftext|>


<commit_before>import { calculate } from "specificity"
import _ from "lodash"
import selectorParser from "postcss-selector-parser"
import resolvedNestedSelector from "postcss-resolve-nested-selector"

import {
  cssNodeContextLookup,
  findMediaContext,
  isLowerSpecificity,
  report,
  ruleMessages,
  validateOptions,
} from "../../utils"

export const ruleName = "no-descending-specificity"

export const messages = ruleMessages(ruleName, {
  rejected: (a, b) => `Expected selector "${b}" to come before selector "${a}"`,
})

const selectorContextLookup = cssNodeContextLookup()

export default function (actual) {
  return (root, result) => {
    const validOptions = validateOptions(result, ruleName, { actual })
    if (!validOptions) { return }

    root.walkRules(rule => {
      const comparisonContext = selectorContextLookup.getContext(rule, findMediaContext(rule))

      rule.selectors.forEach(selector => {
        // The edge-case of duplicate selectors will act acceptably
        const index = rule.selector.indexOf(selector.trim())
        // Resolve any nested selectors before checking
        resolvedNestedSelector(selector, rule).forEach(resolvedSelector => {
          selectorParser(s => checkSelector(s, rule, index, comparisonContext)).process(resolvedSelector)
        })
      })
    })

    function checkSelector(selectorNode, rule, sourceIndex, comparisonContext) {
      const selector = selectorNode.toString()
      const lastNonPseudoSelectorNode = getLastNonPseudoSelectorNode(selectorNode)
      const selectorSpecificity = calculate(selector)[0].specificity.split(",")
      const entry = { selector, specificity: selectorSpecificity }

      if (!comparisonContext.has(lastNonPseudoSelectorNode)) {
        comparisonContext.set(lastNonPseudoSelectorNode, [entry])
        return
      }

      const priorComparableSelectors = comparisonContext.get(lastNonPseudoSelectorNode)

      priorComparableSelectors.forEach(priorEntry => {
        if (isLowerSpecificity(selectorSpecificity, priorEntry.specificity)) {
          report({
            ruleName,
            result,
            node: rule,
            message: messages.rejected(selector, priorEntry.selector),
            index: sourceIndex,
          })
        }
      })

      priorComparableSelectors.push(entry)
    }
  }
}

function getLastNonPseudoSelectorNode(selectorNode) {
  let s = _.last(selectorNode.nodes[0].nodes)
  while (s.type === "pseudo") {
    s = s.prev()
  }
  return s.toString()
}
<commit_msg>Fix :global selector<commit_after>import { calculate } from "specificity"
import _ from "lodash"
import selectorParser from "postcss-selector-parser"
import resolvedNestedSelector from "postcss-resolve-nested-selector"

import {
  cssNodeContextLookup,
  findMediaContext,
  isLowerSpecificity,
  report,
  ruleMessages,
  validateOptions,
} from "../../utils"

export const ruleName = "no-descending-specificity"

export const messages = ruleMessages(ruleName, {
  rejected: (a, b) => `Expected selector "${b}" to come before selector "${a}"`,
})

const selectorContextLookup = cssNodeContextLookup()

export default function (actual) {
  return (root, result) => {
    const validOptions = validateOptions(result, ruleName, { actual })
    if (!validOptions) { return }

    root.walkRules(rule => {
      const comparisonContext = selectorContextLookup.getContext(rule, findMediaContext(rule))

      rule.selectors.forEach(selector => {
        // The edge-case of duplicate selectors will act acceptably
        const index = rule.selector.indexOf(selector.trim())
        // Resolve any nested selectors before checking
        resolvedNestedSelector(selector, rule).forEach(resolvedSelector => {
          selectorParser(s => checkSelector(s, rule, index, comparisonContext)).process(resolvedSelector)
        })
      })
    })

    function checkSelector(selectorNode, rule, sourceIndex, comparisonContext) {
      const selector = selectorNode.toString()
      const lastNonPseudoSelectorNode = getLastNonPseudoSelectorNode(selectorNode)
      const selectorSpecificity = calculate(selector)[0].specificity.split(",")
      const entry = { selector, specificity: selectorSpecificity }

      if (!comparisonContext.has(lastNonPseudoSelectorNode)) {
        comparisonContext.set(lastNonPseudoSelectorNode, [entry])
        return
      }

      const priorComparableSelectors = comparisonContext.get(lastNonPseudoSelectorNode)

      priorComparableSelectors.forEach(priorEntry => {
        if (isLowerSpecificity(selectorSpecificity, priorEntry.specificity)) {
          report({
            ruleName,
            result,
            node: rule,
            message: messages.rejected(selector, priorEntry.selector),
            index: sourceIndex,
          })
        }
      })

      priorComparableSelectors.push(entry)
    }
  }
}

function getLastNonPseudoSelectorNode(selectorNode) {
  let s = _.last(selectorNode.nodes[0].nodes)
  while (s.type === "pseudo") {
    const prev = s.prev()
    if (!prev) { return s.toString() }
    s = s.prev()
  }
  return s.toString()
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import styles from './boardCard.css';

const BoardCard = ({
  alt,
  name,
  role,
  src
}) => (

      {name}

      Role:  {role}

);

BoardCard.propTypes = {
  name: PropTypes.string.isRequired,
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  role: PropTypes.string.isRequired
};

export default BoardCard;
<commit_msg>App paragraph place holder for bio information to be added. Other style changes will ensure format handles text and content gracefully.<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import styles from './boardCard.css';

const BoardCard = ({
  alt,
  name,
  role,
  src
}) => (

      {name}

      Role:  {role}

);

BoardCard.propTypes = {
  name: PropTypes.string.isRequired,
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired,
  role: PropTypes.string.isRequired
};

export default BoardCard;
<|endoftext|>


<commit_before>import { fastMap, fastObjects } from '../../../world';
import { clone, nextCoord } from '../../../utils';
import { collidableObjects } from '../../../collisions';
import config from '../../../config';

export default function findWork() {
  if (this.working || this.waitingOnPath) return;

  const collidables = collidableObjects.concat(['chopper', 'collector', 'planter']);

  const worker = this.pathFindWorker;
  const workerArgs = [
    fastMap, fastObjects, collidables,
    config.mapWidth, config.mapHeight,
    this.tile, ['log', 'pine-cone'], // start, target
    // NOTE will probably get tripped up on planted pine cones
      // need a way to exclude tiles or something
  ];

  this.waitingOnPath = true;
  worker.postMessage(workerArgs);
  worker.onmessage = (event) => {
    const pathToTree = event.data;

    if (pathToTree) {
      this.path = pathToTree;

      this.noPath = false;
      this.working = true;
    } else {
      // no available path to any trees
      this.cancelWork(true);
    }
    this.waitingOnPath = false;
  };

  // if a path to a tree can't be found, worker will try again next time update calls it
}
<commit_msg>Fix collector's doWork<commit_after>import { fastMap, fastObjects } from '../../../world';
import { clone, nextCoord } from '../../../utils';
import { collidableObjects } from '../../../collisions';
import config from '../../../config';

const directions = [ 'UP', 'DOWN', 'LEFT', 'RIGHT'];

function convertPath(path) {
  for (let i = 0; i < path.length; i++) {
    path[i] = directions[path[i]];
  }
  return path;
}

export default function findWork() {
  if (this.working || this.waitingOnPath) return;

  const collidables = collidableObjects.concat(['chopper', 'collector', 'planter']);

  const worker = this.pathFindWorker;
  const workerArgs = [
    fastMap, fastObjects, collidables,
    config.mapWidth, config.mapHeight,
    this.tile, ['log', 'pine-cone'], // start, target
  ];

  this.waitingOnPath = true;
  worker.postMessage(workerArgs);
  worker.onmessage = (event) => {
    const pathToTree = event.data;

    if (pathToTree) {
      this.path = convertPath(pathToTree);

      this.noPath = false;
      this.working = true;
    } else {
      // no available path to any trees
      this.cancelWork(true);
    }
    this.waitingOnPath = false;
  };

  // if a path to a tree can't be found, worker will try again next time update calls it
}
<|endoftext|>