<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

registerManualTests('chrome.sockets.udp', function(rootEl, addButton) {

  function sendTo(data, addr, port) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, addr, 0, function(result) {
        chrome.sockets.udp.send(createInfo.socketId, data, addr, port, function(result) {
          if (result < 0) {
            logger('send fail: ' + result);
            chrome.sockets.udp.close(createInfo.socketId);
          } else {
            logger('sendTo: success ' + port);
            chrome.sockets.udp.close(createInfo.socketId);
          }
        });
      });
    });
  }

  function receiveErrorListener(info) {
    logger('RecvError on socket: ' + info.socketId);
    logger(info);
    chrome.sockets.udp.close(info.socketId);
  }

  function receiveListener(info) {
    logger('Recv: success Data: ' +
           String.fromCharCode.apply(null, new Uint16Array(info.data)));
    logger(info);
    chrome.sockets.udp.close(info.socketId);
  }

  function addReceiveListeners() {
    chrome.sockets.udp.onReceiveError.addListener(receiveErrorListener);
    chrome.sockets.udp.onReceive.addListener(receiveListener);
  }

  function removeReceiveListeners() {
    chrome.sockets.udp.onReceiveError.removeListener(receiveErrorListener);
    chrome.sockets.udp.onReceive.removeListener(receiveListener);
  }

  function bindRecvFromSendTo(data) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
          sendTo(data, socketInfo.localAddress, socketInfo.localPort);
        });
      });
    });
  }

  function bindRecvFromSendToWithTinyBuffer(data) {
    chrome.sockets.udp.create({bufferSize:8}, function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
          sendTo(data, socketInfo.localAddress, socketInfo.localPort);
        });
      });
    });
  }

  function pauseBindRecvFromSendTo(data) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.setPaused(createInfo.socketId, true, function() {
        chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
          chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
            sendTo(data, socketInfo.localAddress, socketInfo.localPort);
          });
        });
      });
    });
  }

  function bindPauseRecvFromSendTo(data) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.setPaused(createInfo.socketId, true, function() {
          chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
            sendTo(data, socketInfo.localAddress, socketInfo.localPort);
          });
        });
      });
    });
  }

  function getSockets() {
    chrome.sockets.udp.getSockets(function(socketsInfo) {
      if (!socketsInfo) return;
      for (var i = 0; i < socketsInfo.length; i++) {
        logger(socketsInfo[i]);
      }
    });
  }

  function updateSocket() {
    chrome.sockets.udp.create({}, function(createInfo) {
      updatedProperties = {
        persistent: true,
        name: 'testUpdate',
        bufferSize: 2048
      };
      chrome.sockets.udp.update(createInfo.socketId, updatedProperties);

      chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
        logger(socketInfo);
      });
    });
  }

  function setPaused() {
    chrome.sockets.udp.create({}, function(createInfo) {
      chrome.sockets.udp.setPaused(createInfo.socketId, true);
      chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
        logger(socketInfo);
      });
    });
  }

  function closeSockets() {
    chrome.sockets.udp.getSockets(function(socketsInfo) {
      if (!socketsInfo) return;
      for (var i = 0; i < socketsInfo.length; i++) {
        logger('closing socket: ' + socketsInfo[i].socketId);
        chrome.sockets.udp.close(socketsInfo[i].socketId);
      }
    });
  }

  function initPage() {

    var defaultAddr = '127.0.0.1';
    var defaultPort = 1234;

    var arr = new Uint8Array(256);
    for (var i = 0; i < arr.length; i++) {
      arr[i] = i;
    }

    addButton('send', function() {
      sendTo(arr.buffer, defaultAddr, defaultPort);
    });

    addButton('add receive listeners', function() {
      addReceiveListeners();
    });

    addButton('remove receive listeners', function() {
      removeReceiveListeners();
    });

    addButton('send to a bind socket', function() {
      bindRecvFromSendTo(arr.buffer);
    });

    addButton('send to a tiny buffer bind socket', function() {
      bindRecvFromSendToWithTinyBuffer(arr.buffer);
    });

    addButton('get sockets', function() {
      getSockets();
    });

    addButton('update socket', function() {
      updateSocket();
    });

    addButton('set paused', function() {
      setPaused();
    });

    addButton('send to a paused socket', function() {
      pauseBindRecvFromSendTo(arr.buffer);
      bindPauseRecvFromSendTo(arr.buffer);
    });

    addButton('close sockets', function() {
      closeSockets();
    });

  }

  initPage();

});
<commit_msg>Add manual tests for multicast<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

registerManualTests('chrome.sockets.udp', function(rootEl, addButton) {

  function sendTo(data, addr, port) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.send(createInfo.socketId, data, addr, port, function(result) {
          if (result < 0) {
            logger('send fail: ' + result);
            chrome.sockets.udp.close(createInfo.socketId);
          } else {
            logger('sendTo: success ' + port);
            chrome.sockets.udp.close(createInfo.socketId);
          }
        });
      });
    });
  }

  function receiveErrorListener(info) {
    logger('RecvError on socket: ' + info.socketId);
    logger(info);
    chrome.sockets.udp.close(info.socketId);
  }

  function receiveListener(info) {
    logger('Recv: success Data: ' +
           String.fromCharCode.apply(null, new Uint16Array(info.data)));
    logger(info);
    chrome.sockets.udp.close(info.socketId);
  }

  function addReceiveListeners() {
    chrome.sockets.udp.onReceiveError.addListener(receiveErrorListener);
    chrome.sockets.udp.onReceive.addListener(receiveListener);
  }

  function removeReceiveListeners() {
    chrome.sockets.udp.onReceiveError.removeListener(receiveErrorListener);
    chrome.sockets.udp.onReceive.removeListener(receiveListener);
  }

  function bindRecvFromSendTo(data) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
          sendTo(data, socketInfo.localAddress, socketInfo.localPort);
        });
      });
    });
  }

  function bindRecvFromSendToWithTinyBuffer(data) {
    chrome.sockets.udp.create({bufferSize:8}, function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
          sendTo(data, socketInfo.localAddress, socketInfo.localPort);
        });
      });
    });
  }

  function pauseBindRecvFromSendTo(data) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.setPaused(createInfo.socketId, true, function() {
        chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
          chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
            sendTo(data, socketInfo.localAddress, socketInfo.localPort);
          });
        });
      });
    });
  }

  function bindPauseRecvFromSendTo(data) {
    chrome.sockets.udp.create(function(createInfo) {
      chrome.sockets.udp.bind(createInfo.socketId, '0.0.0.0', 0, function(result) {
        chrome.sockets.udp.setPaused(createInfo.socketId, true, function() {
          chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
            sendTo(data, socketInfo.localAddress, socketInfo.localPort);
          });
        });
      });
    });
  }

  function stringToArrayBuffer(string) {
    // UTF-16LE
    var buf = new ArrayBuffer(string.length * 2);
    var bufView = new Uint16Array(buf);
    for (var i = 0, strLen = string.length; i < strLen; i++) {
      bufView[i] = string.charCodeAt(i);
    }
    return buf;
  }

  function joinMulticastGroup(address, loopback) {
    chrome.sockets.udp.create({bufferSize:1048576},function (socket) {
      var socketId = socket.socketId;
      logger(socket);
      chrome.sockets.udp.setMulticastTimeToLive(socketId, 12, function (result) {
        if (result != 0) {
          logger("Set TTL Error: " + result);
        }
        chrome.sockets.udp.setMulticastLoopbackMode(socketId, loopback, function (result) {
          if (result != 0) {
            logger("Set Multicast LoopbackMode" + result);
          }
          chrome.sockets.udp.bind(socketId, "0.0.0.0", 0, function (result) {
            if (result != 0) {
              chrome.sockets.udp.close(socketId);
              logger("Error on bind(): " + result);
            } else {
              chrome.sockets.udp.joinGroup(socketId, address, function (result) {
                if (result != 0) {
                  chrome.sockets.udp.close(socketId);
                  logger("Error on joinGroup(): " + result);
                } else {
                  chrome.sockets.udp.getInfo(socketId, function(socketInfo) {
                    message = stringToArrayBuffer(socketId + ' Joined Group');
                    chrome.sockets.udp.send(
                      socketId, message, address, socketInfo.localPort, function (result) {
                      if (result < 0) {
                        logger('send fail: ' + result);
                      } else {
                        logger('group sendTo: success');
                      }
                    });
                  });
                }
              });
            }
          });
        });
      });
    });
  }

  function getSockets() {
    chrome.sockets.udp.getSockets(function(socketsInfo) {
      if (!socketsInfo) return;
      for (var i = 0; i < socketsInfo.length; i++) {
        logger(socketsInfo[i]);
      }
    });
  }

  function updateSocket() {
    chrome.sockets.udp.create({}, function(createInfo) {
      updatedProperties = {
        persistent: true,
        name: 'testUpdate',
        bufferSize: 2048
      };
      chrome.sockets.udp.update(createInfo.socketId, updatedProperties);

      chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
        logger(socketInfo);
      });
    });
  }

  function setPaused() {
    chrome.sockets.udp.create({}, function(createInfo) {
      chrome.sockets.udp.setPaused(createInfo.socketId, true);
      chrome.sockets.udp.getInfo(createInfo.socketId, function(socketInfo) {
        logger(socketInfo);
      });
    });
  }

  function closeSockets() {
    chrome.sockets.udp.getSockets(function(socketsInfo) {
      if (!socketsInfo) return;
      for (var i = 0; i < socketsInfo.length; i++) {
        logger('closing socket: ' + socketsInfo[i].socketId);
        chrome.sockets.udp.close(socketsInfo[i].socketId);
      }
    });
  }

  function initPage() {

    var defaultAddr = '127.0.0.1';
    var defaultPort = 1234;
    var multicastAddr = '224.0.0.1';

    var arr = new Uint8Array(256);
    for (var i = 0; i < arr.length; i++) {
      arr[i] = i;
    }

    addButton('send', function() {
      sendTo(arr.buffer, defaultAddr, defaultPort);
    });

    addButton('add receive listeners', function() {
      addReceiveListeners();
    });

    addButton('remove receive listeners', function() {
      removeReceiveListeners();
    });

    addButton('send to a bind socket', function() {
      bindRecvFromSendTo(arr.buffer);
    });

    addButton('send to a tiny buffer bind socket', function() {
      bindRecvFromSendToWithTinyBuffer(arr.buffer);
    });

    addButton('get sockets', function() {
      getSockets();
    });

    addButton('update socket', function() {
      updateSocket();
    });

    addButton('set paused', function() {
      setPaused();
    });

    addButton('send to a paused socket', function() {
      pauseBindRecvFromSendTo(arr.buffer);
      bindPauseRecvFromSendTo(arr.buffer);
    });

    addButton('close sockets', function() {
      closeSockets();
    });

    addButton('Join multicast group', function() {
      joinMulticastGroup(multicastAddr, false);
    });

    addButton('Join multicast group with loopback', function() {
      joinMulticastGroup(multicastAddr, true);
    });
  }

  initPage();

});
<|endoftext|>


<commit_before>requirejs.config({
  paths: {
  },

  map: {
    '*': {
      // needed by a loader plugin, can't scope the mapping
      'timezone_core': 'canvas/timezone_core',
      'moment': 'canvas/moment',
      'moment_formats': 'canvas/moment_formats',
      'locale_converter': 'canvas/locale_converter',
      'bower': 'canvas/bower',
      'compiled': 'canvas/compiled',
      'jquery': 'canvas/vendor/jquery-1.7.2',
      'jqueryui': 'canvas/vendor/jqueryui',
      'vendor': 'canvas/vendor',
      'timezone': 'canvas/timezone',
      'jquery.instructure_date_and_time': 'canvas/jquery.instructure_date_and_time',
      'i18nObj': 'i18n'
    },

    'canvas/jquery.instructure_date_and_time': {
      'compiled/behaviors/authenticity_token': 'canvas/compiled/behaviors/authenticity_token',
      'jqueryui': 'canvas/vendor/jqueryui',
      'timezone': 'canvas/timezone',
      'str/htmlEscape': 'canvas/str/htmlEscape',
      'jquery.keycodes': 'canvas/jquery.keycodes',
      'vendor/date': 'canvas/vendor/date',
      'jsx/shared/render-datepicker-time': 'canvas/jsx/shared/render-datepicker-time'
    },

    'canvas/jsx/shared/render-datepicker-time': {
      'i18n': 'i18n',
    },

    'canvas/str/htmlEscape': {
      'INST': 'canvas/INST',
    },

    'canvas/jquery': {
      'jquery.instructure_jquery_patches': 'canvas/jquery.instructure_jquery_patches'
    },

    'canvas/jquery.instructure_jquery_patches': {
      'vendor': 'canvas/vendor',
    },

    'canvas/jquery.keycodes': {
      'jquery.instructure_date_and_time': 'canvas/jquery.instructure_date_and_time'
    },

    'canvas/timezone': {
      'timezone_plugin': 'canvas/timezone_plugin'
    },

    'canvas/vendor/date': {
      'vendor/date-js/parser': 'canvas/vendor/date-js/parser'
    },

    'canvas/vendor/date-js/parser': {
      'vendor/date-js/sugarpak': 'canvas/vendor/date-js/sugarpak'
    },

    'canvas/vendor/date-js/sugarpak': {
      'vendor/date-js/core': 'canvas/vendor/date-js/core'
    },

    'canvas/vendor/date-js/core': {
      'vendor/date-js/globalization/en-US': 'canvas/vendor/date-js/globalization/en-US'
    }
  }
});

define([ 'canvas/jquery.instructure_date_and_time' ], function() {
});
<commit_msg>stop referencing a JS file that doesn't exist anymore<commit_after>requirejs.config({
  paths: {
  },

  map: {
    '*': {
      // needed by a loader plugin, can't scope the mapping
      'timezone_core': 'canvas/timezone_core',
      'moment': 'canvas/moment',
      'moment_formats': 'canvas/moment_formats',
      'bower': 'canvas/bower',
      'compiled': 'canvas/compiled',
      'jquery': 'canvas/vendor/jquery-1.7.2',
      'jqueryui': 'canvas/vendor/jqueryui',
      'vendor': 'canvas/vendor',
      'timezone': 'canvas/timezone',
      'jquery.instructure_date_and_time': 'canvas/jquery.instructure_date_and_time',
      'i18nObj': 'i18n'
    },

    'canvas/jquery.instructure_date_and_time': {
      'compiled/behaviors/authenticity_token': 'canvas/compiled/behaviors/authenticity_token',
      'jqueryui': 'canvas/vendor/jqueryui',
      'timezone': 'canvas/timezone',
      'str/htmlEscape': 'canvas/str/htmlEscape',
      'jquery.keycodes': 'canvas/jquery.keycodes',
      'vendor/date': 'canvas/vendor/date',
      'jsx/shared/render-datepicker-time': 'canvas/jsx/shared/render-datepicker-time'
    },

    'canvas/jsx/shared/render-datepicker-time': {
      'i18n': 'i18n',
    },

    'canvas/str/htmlEscape': {
      'INST': 'canvas/INST',
    },

    'canvas/jquery': {
      'jquery.instructure_jquery_patches': 'canvas/jquery.instructure_jquery_patches'
    },

    'canvas/jquery.instructure_jquery_patches': {
      'vendor': 'canvas/vendor',
    },

    'canvas/jquery.keycodes': {
      'jquery.instructure_date_and_time': 'canvas/jquery.instructure_date_and_time'
    },

    'canvas/timezone': {
      'timezone_plugin': 'canvas/timezone_plugin'
    },

    'canvas/vendor/date': {
      'vendor/date-js/parser': 'canvas/vendor/date-js/parser'
    },

    'canvas/vendor/date-js/parser': {
      'vendor/date-js/sugarpak': 'canvas/vendor/date-js/sugarpak'
    },

    'canvas/vendor/date-js/sugarpak': {
      'vendor/date-js/core': 'canvas/vendor/date-js/core'
    },

    'canvas/vendor/date-js/core': {
      'vendor/date-js/globalization/en-US': 'canvas/vendor/date-js/globalization/en-US'
    }
  }
});

define([ 'canvas/jquery.instructure_date_and_time' ], function() {
});
<|endoftext|>


<commit_before>callback(
[
{ "name": "[Q] More info", "description": "Can you please edit your question and add more details about [type here]. Thanks!"},

{ "name": "[Q] Screenshots", "description": "Can you please edit your question and add code/error messages at text formatted using the `{}` button instead of as a screenshot. Thanks!"},

{ "name": "[Q] More than one question asked", "description": "It is preferred if you can post separate questions instead of combining your questions into one. That way, it helps the people answering your question and also others hunting for at least one of your questions. Thanks!"},

{ "name": "[Q] Duplicate Closure", "description": "This question will probably be closed as a duplicate soon. If the answers from the duplicates don't fully address your question please edit it to include why and flag this for re-opening. Thanks!"},

{ "name": "[A] Answers just to say Thanks!", "description": "Please don't add \"thanks\" as answers. Invest some time in the site and you will gain sufficient privileges to upvote answers you like, which is the $SITENAME$ way of saying thank you."},

{ "name": "[A] Nothing but a URL (and isn't spam)", "description": "Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference."},

{ "name": "[A] Requests to OP for further information", "description": "This is really a comment, not an answer. With a bit more rep, you will be able to post comments. For the moment I've added the comment for you, and I'm flagging this post for deletion."},

{ "name": "[A] OP using an answer for further information", "description": "Please use the Post answer button only for actual answers. You should modify your original question to add additional information."},

{ "name": "[A] OP adding a new question as an answer", "description": "If you have another question, please ask it by clicking the Ask Question button."},

{ "name": "[A] Another user adding a 'Me too!'", "description": "If you have a NEW question, please ask it by clicking the Ask Question button. If you have sufficient reputation, you may upvote the question. Alternatively, \"star\" it as a favorite and you will be notified of any new answers."},

{ "name": "[C] Too localized", "description": "This question appears to be off-topic because it is too localized."},

{ "name": "[EQ] Improper tagging", "description": "The tags you were using are not appropriate for this question. Please review What are tags, and how should I use them?"},

]
)
<commit_msg>Delete stack_comments.js<commit_after><|endoftext|>


<commit_before>/*
 * The contents of this file are subject to the OpenMRS Public License
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
define(
	[
		openhmis.url.backboneBase + 'js/lib/jquery',
		openhmis.url.backboneBase + 'js/lib/backbone',
		openhmis.url.backboneBase + 'js/lib/underscore',
		openhmis.url.backboneBase + 'js/model/generic',
		openhmis.url.backboneBase + 'js/lib/backbone-forms',
		openhmis.url.backboneBase + 'js/lib/labelOver',
		openhmis.url.backboneBase + 'js/view/list',
		openhmis.url.backboneBase + 'js/model/location',
		openhmis.url.backboneBase + 'js/model/user',
		openhmis.url.backboneBase + 'js/model/role'
	],
	function($, Backbone, _, openhmis) {
		var editors = Backbone.Form.editors;

		editors.isNumeric = function(strVal) {
			return /^-?[0-9]*\.?[0-9]*?$/.test(strVal);
		};

		editors.BasicNumber = editors.Number.extend({
			initialize: function(options) {
				this.defaultValue = null;
				editors.Text.prototype.initialize.call(this, options);
			},

			/**
			* Check value is numeric
			*/
			onKeyPress: function(event) {
				var self = this,
					delayedDetermineChange = function() {
					  setTimeout(function() {
						self.determineChange();
					  }, 0);
					}
				if (event.keyCode == 9) {
					return;
				}
				//Allow backspace && enter
				if (event.which == 8 || event.which == 13) {
					delayedDetermineChange();
					return;
				}

				//Get the whole new value so that we can prevent things like double decimals points etc.
				var newVal = this.$el.val() + String.fromCharCode(event.which);

				if (editors.isNumeric(newVal)) {
					delayedDetermineChange();
				} else {
					event.preventDefault();
				}
			},

			setValue: function(value) {
				if (value !== undefined && value !== null && this.schema.format) {
					this.$el.val(this.schema.format(value));
				} else {
					this.$el.val(value);
				}
			},

			focus: function(select) {
				editors.Number.prototype.focus.call(this);

				if (select === true) this.$el.select();
			}
		});

		editors.CustomNumber = editors.Number.extend({
			initialize: function(options) {
				this.events = _.extend(this.events, {
					'click': 'determineChange'
				});
				editors.Number.prototype.initialize.call(this, options);
				if (options && options.schema) this.minimum = options.schema.minimum;
			},

			onKeyPress: function(event) {
				var self = this,
					delayedDetermineChange = function() {
						setTimeout(function() {
							self.determineChange();
						}, 0);
					};
				if (event.keyCode == 9) {
					return;
				}
					//Allow backspace and minus character
				if (event.which == 8 || event.which == 45) {
					delayedDetermineChange();
					return;
				}

				//Get the whole new value so that we can prevent things like double decimals points etc.
				var newVal = this.$el.val() + String.fromCharCode(event.which);

				if (editors.isNumeric(newVal)) {
					delayedDetermineChange();
				} else {
					event.preventDefault();
				}
			},

			setValue: function(value) {
				this.el.defaultValue = value;
				editors.Number.prototype.setValue.call(this, value);
			},

			determineChange: function(event) {
				if (this.minimum && parseInt(this.$el.val()) < this.minimum) {
					this.$el.val(this.minimum);
					return;
				}
				editors.Number.prototype.determineChange.call(this, event);
			},

			focus: function(select) {
				editors.Number.prototype.focus.call(this);
				if (select === true) this.$el.select();
			}
		});

		editors.TrueFalseCheckbox = editors.Checkbox.extend({
			getValue: function() {
				var tmpValue = editors.Checkbox.prototype.getValue.call(this);
				return tmpValue == true ? true : false;
			}
		});

		/**
		 * "Abstract" editor class.  Extend and specify modelType and
		 * displayAttr properties.  See inventory module editors.js for examples.
		 **/
		editors.GenericModelSelect = editors.Select.extend({
			blankItem: null,

			initialize: function(options) {
				editors.Select.prototype.initialize.call(this, options);

				if (this.schema.modelType) {
					this.modelType = this.schema.modelType;
				}

				if (this.schema.displayAttr) {
					this.displayAttr = this.schema.displayAttr;
				}

				this.blankItem = new this.modelType({ name: "- Not Defined -"});
			},

			renderOptions: function(options) {
				// Add in the "Not Defined" item before rendering the options
				if (this.allowNull) {
					var item0 = options.at(0);
					if (!item0 || item0.id != this.blankItem.id) {
						options.add(this.blankItem, {
							at: 0,
							silent: true
						});
					}
				}

				editors.Select.prototype.renderOptions.call(this, options);
			},

		    getValue: function() {
				$selected = this.$('option:selected');

			    var model = new this.modelType({ uuid: $selected.val() });
			    var displayAttr = this.displayAttr || "display";
				if (model == this.blankItem) {
					model.set(displayAttr, null, { silent: true });
				} else {
			        model.set(displayAttr, $selected.text(), { silent: true });
				}

				return model;
			},

			setValue: function(value) {
				if (value === null) {
					return;
				}

				if (_.isString(value)) {
					this.$el.val(value);
				} else if (value.attributes) {
					this.$el.val(value.id); // Backbone model
				} else if (!isNaN(parseFloat(value))) {
				// This should be after Backbone model because it can evaluate
				// to a number :S
					this.$el.val(value);
				} else {
					this.$el.val(value.uuid); // bare object
				}
			},

			render: function() {
				if (this.options.options !== undefined) {
					this.setOptions(this.options.options);
				} else {
					this.setOptions(this.schema.options);
				}

				return this;
			}
		});

		editors.Autocomplete = editors.Select.extend({
			tagName: "span",
			previousValue: "",

			initialize: function(options) {
				_.bindAll(this, "onSelect");

				editors.Select.prototype.initialize.call(this, options);
				this.text = new editors.Text();

                this.minLength = options.schema.minLength ? options.schema.minLength : 2;

                var self = this;
                this.text.on("focus", function(event) { self.trigger("focus", self); });
				this.text.on("blur", function(event) { self.trigger("blur", self); });

                this.selectedItem = null;
			},

			onSelect: function(event, ui) {
				if (ui && ui.item) {
					this.selectedItem = ui.item;
					this.trigger("select", ui.item);
				}

				this.text.trigger("change", this);
			},

			getValue: function() {
				if (this.selectedItem && this.selectedItem.label === this.text.getValue()) {
					return this.selectedItem.value;
				} else {
					return this.text.getValue();
				}
			},

			setValue: function(value) {
				this.text.setValue(value);
			},

		    focus: function() {
				if (this.hasFocus) return; {
					this.text.focus();
			    }
			},

			blur: function() {
				if (this.hasFocus) {
					this.text.blur();
				}
			},

			renderOptions: function(options) {
				var source;
				var isBbCollection = false;

                if (options instanceof Backbone.Collection) {
					isBbCollection = true;
					source = options.map(function(item) {
						return { label: item.toString(), value: item }
					});
				} else {
					source = this.schema.options;
				}

				var $autoComplete = this.text.$el.autocomplete({
					minLength: this.minLength,
					source: source,
					select: this.onSelect,
					autoFocus: true
				});

				if (isBbCollection) {
					$autoComplete.data("autocomplete")._renderItem = function(ul, item) {
						return $("

").data("item.autocomplete", item)
							.append("" + item.label + "").appendTo(ul);
					};
				}
			},

			render: function() {
				if (this.$el.html() === "") {
					this.$el.append(this.text.el);
				}

				editors.Select.prototype.render.call(this);

				return this;
			}
		});

		editors.List.NestedModel = editors.List.NestedModel.extend({
			onModalSubmitted: function(form, modal) {
				var isNew = !this.value;

				//Stop if there are validation errors
				var error = form.validate();
				if (error) {
					return modal.preventClose();
				}
				this.modal = null;

				var idAttribute = Backbone.Model.prototype.idAttribute;
				if (this.value) {
					var id = this.value.id || this.value[idAttribute];
				}

				//If OK, render the list item
				this.value = form.getValue();

				if (id !== undefined) {
					this.value[idAttribute] = id;
				}

				this.renderSummary();

				if (isNew) {
					this.trigger('readyToAdd');
				}

				this.trigger('change', this);

				this.trigger('close', this);
				this.trigger('blur', this);
			}
		});

		editors.LocationSelect = editors.GenericModelSelect.extend({
			modelType: openhmis.Location,
			displayAttr: "name",
			allowNull: true
		});

		editors.UserSelect = editors.GenericModelSelect.extend({
			modelType: openhmis.User,
			displayAttr: "name",
			allowNull: true
		});

		editors.RoleSelect = editors.GenericModelSelect.extend({
			modelType: openhmis.Role,
			displayAttr: "name",
			allowNull: true
		});

		editors.ListSelect = editors.Base.extend({
			modalWidth: 600,
			initialize: function(options) {
				_.bindAll(this, 'updateSelected', 'clearSelection');
				options = options || {};
				editors.Base.prototype.initialize.call(this, options);
				if (!options.schema.options) {
					throw "Missing required schema.options.";
				}
			},

			getValue: function() {
				return this.value;
		    },

		    setValue: function(value) {
		    	this.value = value;
		    	this.updateSelected();
		    },

		    focus: function() {
		      if (this.hasFocus) return;

		      this.trigger("focus");
		    },

		    blur: function() {
		      if (!this.hasFocus) return;

		      this.trigger("blur");
		    },

		    initListView: function() {
		    	var options = this.schema.editorOptions || {};
		    	options.model = this.schema.options;
		    	this.listView = new openhmis.GenericListView(options);
		    },

		    updateSelected: function(view) {
		    	if (view && view.model)
		    		this.value = view.model;
		    	else if (view === null)
		    		this.value = null;
		    	this.$(".selected").text("Selected: " + (this.value || "None"));
	    		this.$(".clear_selection").css("display", this.value ? "inline" : "none");
		    },

		    clearSelection: function(event) {
		    	event.preventDefault();
		    	this.updateSelected(null);
		    	this.listView.blur();
		    },

		    render: function() {
		    	this.initListView();
		    	this.$el.html('
 Clear
');
		    	this.$el.append(this.listView.el);
		    	this.listView.fetch();
		    	this.updateSelected();
		    	this.listView.on("itemSelect", this.updateSelected);
		    	this.$(".clear_selection").click(this.clearSelection);
		    	return this;
		    }

		});

		return editors;
	}
);
<commit_msg>Updated GenericModelSelect to use max result limit<commit_after>/*
 * The contents of this file are subject to the OpenMRS Public License
 * Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://license.openmrs.org
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * Copyright (C) OpenMRS, LLC.  All Rights Reserved.
 */
define(
	[
		openhmis.url.backboneBase + 'js/lib/jquery',
		openhmis.url.backboneBase + 'js/lib/backbone',
		openhmis.url.backboneBase + 'js/lib/underscore',
		openhmis.url.backboneBase + 'js/model/generic',
		openhmis.url.backboneBase + 'js/lib/backbone-forms',
		openhmis.url.backboneBase + 'js/lib/labelOver',
		openhmis.url.backboneBase + 'js/view/list',
		openhmis.url.backboneBase + 'js/model/location',
		openhmis.url.backboneBase + 'js/model/user',
		openhmis.url.backboneBase + 'js/model/role'
	],
	function($, Backbone, _, openhmis) {
		var editors = Backbone.Form.editors;

		editors.isNumeric = function(strVal) {
			return /^-?[0-9]*\.?[0-9]*?$/.test(strVal);
		};

		editors.BasicNumber = editors.Number.extend({
			initialize: function(options) {
				this.defaultValue = null;
				editors.Text.prototype.initialize.call(this, options);
			},

			/**
			* Check value is numeric
			*/
			onKeyPress: function(event) {
				var self = this,
					delayedDetermineChange = function() {
					  setTimeout(function() {
						self.determineChange();
					  }, 0);
					}
				if (event.keyCode == 9) {
					return;
				}
				//Allow backspace && enter
				if (event.which == 8 || event.which == 13) {
					delayedDetermineChange();
					return;
				}

				//Get the whole new value so that we can prevent things like double decimals points etc.
				var newVal = this.$el.val() + String.fromCharCode(event.which);

				if (editors.isNumeric(newVal)) {
					delayedDetermineChange();
				} else {
					event.preventDefault();
				}
			},

			setValue: function(value) {
				if (value !== undefined && value !== null && this.schema.format) {
					this.$el.val(this.schema.format(value));
				} else {
					this.$el.val(value);
				}
			},

			focus: function(select) {
				editors.Number.prototype.focus.call(this);

				if (select === true) this.$el.select();
			}
		});

		editors.CustomNumber = editors.Number.extend({
			initialize: function(options) {
				this.events = _.extend(this.events, {
					'click': 'determineChange'
				});
				editors.Number.prototype.initialize.call(this, options);
				if (options && options.schema) this.minimum = options.schema.minimum;
			},

			onKeyPress: function(event) {
				var self = this,
					delayedDetermineChange = function() {
						setTimeout(function() {
							self.determineChange();
						}, 0);
					};
				if (event.keyCode == 9) {
					return;
				}
					//Allow backspace and minus character
				if (event.which == 8 || event.which == 45) {
					delayedDetermineChange();
					return;
				}

				//Get the whole new value so that we can prevent things like double decimals points etc.
				var newVal = this.$el.val() + String.fromCharCode(event.which);

				if (editors.isNumeric(newVal)) {
					delayedDetermineChange();
				} else {
					event.preventDefault();
				}
			},

			setValue: function(value) {
				this.el.defaultValue = value;
				editors.Number.prototype.setValue.call(this, value);
			},

			determineChange: function(event) {
				if (this.minimum && parseInt(this.$el.val()) < this.minimum) {
					this.$el.val(this.minimum);
					return;
				}
				editors.Number.prototype.determineChange.call(this, event);
			},

			focus: function(select) {
				editors.Number.prototype.focus.call(this);
				if (select === true) this.$el.select();
			}
		});

		editors.TrueFalseCheckbox = editors.Checkbox.extend({
			getValue: function() {
				var tmpValue = editors.Checkbox.prototype.getValue.call(this);
				return tmpValue == true ? true : false;
			}
		});

		/**
		 * "Abstract" editor class.  Extend and specify modelType and
		 * displayAttr properties.  See inventory module editors.js for examples.
		 **/
		editors.GenericModelSelect = editors.Select.extend({
			blankItem: null,

			initialize: function(options) {
				editors.Select.prototype.initialize.call(this, options);

				if (this.schema.modelType) {
					this.modelType = this.schema.modelType;
				}

				if (this.schema.displayAttr) {
					this.displayAttr = this.schema.displayAttr;
				}

				this.blankItem = new this.modelType({ name: "- Not Defined -"});
			},

			renderOptions: function(options) {
				// Add in the "Not Defined" item before rendering the options
				if (this.allowNull) {
					var item0 = options.at(0);
					if (!item0 || item0.id != this.blankItem.id) {
						options.add(this.blankItem, {
							at: 0,
							silent: true
						});
					}
				}

				editors.Select.prototype.renderOptions.call(this, options);
			},

		    getValue: function() {
				$selected = this.$('option:selected');

			    var model = new this.modelType({ uuid: $selected.val() });
			    var displayAttr = this.displayAttr || "display";
				if (model == this.blankItem) {
					model.set(displayAttr, null, { silent: true });
				} else {
			        model.set(displayAttr, $selected.text(), { silent: true });
				}

				return model;
			},

			setValue: function(value) {
				if (value === null) {
					return;
				}

				if (_.isString(value)) {
					this.$el.val(value);
				} else if (value.attributes) {
					this.$el.val(value.id); // Backbone model
				} else if (!isNaN(parseFloat(value))) {
				// This should be after Backbone model because it can evaluate
				// to a number :S
					this.$el.val(value);
				} else {
					this.$el.val(value.uuid); // bare object
				}
			},

			render: function() {
				if (this.options.options !== undefined) {
					this.setOptions(this.options.options);
				} else {
                    if (this.schema.options instanceof Backbone.Collection) {
                        if (this.schema.options.length > 0) {
                            // Collection has already been loaded so just render it
                            this.renderOptions(this.schema.options);
                        } else {
                            // Load the collection manually so that we can set the limit
                            var self = this;
                            this.schema.options.fetch({
                                success: function () {
                                    // Render the options once complete
                                    self.renderOptions(self.schema.options);
                                },
                                limit: openhmis.rest.maxResults
                            });
                        }
                    } else {
                        this.setOptions(this.schema.options);
                    }
				}

				return this;
			}
		});

		editors.Autocomplete = editors.Select.extend({
			tagName: "span",
			previousValue: "",

			initialize: function(options) {
				_.bindAll(this, "onSelect");

				editors.Select.prototype.initialize.call(this, options);
				this.text = new editors.Text();

                this.minLength = options.schema.minLength ? options.schema.minLength : 2;

                var self = this;
                this.text.on("focus", function(event) { self.trigger("focus", self); });
				this.text.on("blur", function(event) { self.trigger("blur", self); });

                this.selectedItem = null;
			},

			onSelect: function(event, ui) {
				if (ui && ui.item) {
					this.selectedItem = ui.item;
					this.trigger("select", ui.item);
				}

				this.text.trigger("change", this);
			},

			getValue: function() {
				if (this.selectedItem && this.selectedItem.label === this.text.getValue()) {
					return this.selectedItem.value;
				} else {
					return this.text.getValue();
				}
			},

			setValue: function(value) {
				this.text.setValue(value);
			},

		    focus: function() {
				if (this.hasFocus) return; {
					this.text.focus();
			    }
			},

			blur: function() {
				if (this.hasFocus) {
					this.text.blur();
				}
			},

			renderOptions: function(options) {
				var source;
				var isBbCollection = false;

                if (options instanceof Backbone.Collection) {
					isBbCollection = true;
					source = options.map(function(item) {
						return { label: item.toString(), value: item }
					});
				} else {
					source = this.schema.options;
				}

				var $autoComplete = this.text.$el.autocomplete({
					minLength: this.minLength,
					source: source,
					select: this.onSelect,
					autoFocus: true
				});

				if (isBbCollection) {
					$autoComplete.data("autocomplete")._renderItem = function(ul, item) {
						return $("

").data("item.autocomplete", item)
							.append("" + item.label + "").appendTo(ul);
					};
				}
			},

			render: function() {
				if (this.$el.html() === "") {
					this.$el.append(this.text.el);
				}

				editors.Select.prototype.render.call(this);

				return this;
			}
		});

		editors.List.NestedModel = editors.List.NestedModel.extend({
			onModalSubmitted: function(form, modal) {
				var isNew = !this.value;

				//Stop if there are validation errors
				var error = form.validate();
				if (error) {
					return modal.preventClose();
				}
				this.modal = null;

				var idAttribute = Backbone.Model.prototype.idAttribute;
				if (this.value) {
					var id = this.value.id || this.value[idAttribute];
				}

				//If OK, render the list item
				this.value = form.getValue();

				if (id !== undefined) {
					this.value[idAttribute] = id;
				}

				this.renderSummary();

				if (isNew) {
					this.trigger('readyToAdd');
				}

				this.trigger('change', this);

				this.trigger('close', this);
				this.trigger('blur', this);
			}
		});

		editors.LocationSelect = editors.GenericModelSelect.extend({
			modelType: openhmis.Location,
			displayAttr: "name",
			allowNull: true
		});

		editors.UserSelect = editors.GenericModelSelect.extend({
			modelType: openhmis.User,
			displayAttr: "name",
			allowNull: true
		});

		editors.RoleSelect = editors.GenericModelSelect.extend({
			modelType: openhmis.Role,
			displayAttr: "name",
			allowNull: true
		});

		editors.ListSelect = editors.Base.extend({
			modalWidth: 600,
			initialize: function(options) {
				_.bindAll(this, 'updateSelected', 'clearSelection');
				options = options || {};
				editors.Base.prototype.initialize.call(this, options);
				if (!options.schema.options) {
					throw "Missing required schema.options.";
				}
			},

			getValue: function() {
				return this.value;
		    },

		    setValue: function(value) {
		    	this.value = value;
		    	this.updateSelected();
		    },

		    focus: function() {
		      if (this.hasFocus) return;

		      this.trigger("focus");
		    },

		    blur: function() {
		      if (!this.hasFocus) return;

		      this.trigger("blur");
		    },

		    initListView: function() {
		    	var options = this.schema.editorOptions || {};
		    	options.model = this.schema.options;
		    	this.listView = new openhmis.GenericListView(options);
		    },

		    updateSelected: function(view) {
		    	if (view && view.model)
		    		this.value = view.model;
		    	else if (view === null)
		    		this.value = null;
		    	this.$(".selected").text("Selected: " + (this.value || "None"));
	    		this.$(".clear_selection").css("display", this.value ? "inline" : "none");
		    },

		    clearSelection: function(event) {
		    	event.preventDefault();
		    	this.updateSelected(null);
		    	this.listView.blur();
		    },

		    render: function() {
		    	this.initListView();
		    	this.$el.html('
 Clear
');
		    	this.$el.append(this.listView.el);
		    	this.listView.fetch();
		    	this.updateSelected();
		    	this.listView.on("itemSelect", this.updateSelected);
		    	this.$(".clear_selection").click(this.clearSelection);
		    	return this;
		    }

		});

		return editors;
	}
);
<|endoftext|>


<commit_before>// PiMonitor.js

var http        = require("http"),
    https       = require("https")
    url         = require("url"),
    path        = require("path"),
    fs          = require("fs"),
    os          = require("os"),
    colors      = require("colors"),
    optimist    = require("optimist").argv,
    config      = require("./config.json"),
    port        = optimist.p || config.port,
    https_pos   = config.forceSSL;

if(os.type() != "Linux")
{
    console.error("You are not running Linux. Exiting ... \n".red);
    process.exit(0);
}

if(optimist.help || optimist.h)
{
    console.log("\n--------------------------- HELP -----------------------------".red + "\n                   " + "--- PiDashboard.js ---\n".green.bold.underline + "A Monitoring server for Raspberry Pi and other Linux computers." + "\nUsage: \n".bold );
    process.exit(0);
}

if(optimist.cert || optimist.key)
{
    https_pos = true;

    var cert = "",
        key = "";

    if (optimist.cert)  cert = optimist.cert;
    if (optimist.key)   key = optimist.key;

    if (!cert.length)   cert = "./keys/cert.pem";
    if (!key.length)    key = "./keys/key.pem";

    if (!fs.existsSync(key))
    {
        console.error("File ".red+ key.red.bold + " " + "doesn't exists!".red.underline );
        console.log("Can not start https server. Exiting ...".red);
        process.exit(1);
    }
    if (!fs.existsSync(cert))
    {
        console.error("File ".red + cert.red.bold + " " +"doesn't exists!".red.underline );
        console.log("Can not start https server. Exiting ...".red);
        process.exit(1);
    }
}

/*var exec = require('child_process').exec;
    var child = exec('top -bn1',
    function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});*/

function systemOverview()
{
    return {
        "hostname":os.hostname(),
        "type": os.type(),
        "platform" : os.platform(),
        "arch": os.arch(),
        "release": os.release(),
        "uptime": os.uptime(),
        "loadavg": os.loadavg(),
        "totalmem": os.totalmem(),
        "freemem": os.freemem(),
        "cpus": os.cpus(),
        "netwok": os.networkInterfaces(),
    }
}

// Static fileserver
//@TODO change to express

if (https_pos)
{
    var httpsOptions = {
        key: fs.readFileSync(key),
        cert: fs.readFileSync(cert)
    }
    var WebServer = https.createServer(httpsOptions, httpServer).listen(port,bindingSuccess);
    WebServer.on("error",function(er)
    {
        if(er.code == "EADDRINUSE")
        {
            console.error("Unable to bind to port " + port);
            port = config.backupPort;

            var WebServer = https.createServer(httpsOptions, httpServer).listen(port,bindingSuccess);
            WebServer.on("error",function(er)
            {
                if(er.code == "EADDRINUSE")
                {
                    console.error("Unable to bing to backup port "+ port);
                    process.exit(1);
                }
            });
            console.log("Success running on port "+ port);
        }
    });
}
else
{
    var WebServer = http.createServer(httpServer).listen(port,bindingSuccess);
    WebServer.on("error",function(er)
    {
        if(err.code == "EADDRINUSE")
        {
            console.error("Unable to bind to port " + port);
            port = config.backupPort;

            var WebServer = http.createServer(httpServer).listen(port,bindingSuccess);
            Webserver.on("error",function(er)
            {
                if(er.code == "EADDRINUSE")
                {
                    console.error("Unable to bing to backup port "+ port);
                    process.exit(1);
                }
            })
            console.log("Success running on port "+ port);
        }
    });
}

function httpServer(request, response)
{
    var uri = url.parse(request.url).pathname,
        filename = path.join(process.cwd(), uri);
    fs.exists(filename, function(exists)
    {
        if(!exists)
        {
            response.writeHead(404, {"Content-Type": "text/plain"});
            response.write("404 Not Found\n");
            response.end();
            return;
        }

        if (fs.statSync(filename).isDirectory()) filename += '/index.html';

        fs.readFile(filename, "binary", function(err, file)
        {

        if(err)
        {
            response.writeHead(500, {"Content-Type": "text/plain"});
            response.write(err + "\n");
            response.end();
            return;
        }

        response.writeHead(200);
        response.write(file, "binary");
        response.end();
    });
});
}

function bindingSuccess()
{
    if(https_pos)
    {
        console_sufix = "s:/";
    }
    else
    {
        console_sufix = ":/";
    }

    console.log("Server running at => ".green + "http" + console_sufix +"/localhost:" + port);
}
<commit_msg>Reading RAM CPU<commit_after>// PiMonitor.js

var http        = require("http"),
    https       = require("https")
    url         = require("url"),
    path        = require("path"),
    fs          = require("fs"),
    os          = require("os"),
    colors      = require("colors"),
    optimist    = require("optimist").argv,
    config      = require("./config.json"),
    port        = optimist.p || config.port,
    exec        = require('child_process').exec,
    https_pos   = config.forceSSL,

    GPUtemp     = 0,
    RAMstat     = {
                    free: 0,
                    used: 0,
                    total: 0
                  }
    CPUstat     = {
                    us: 0,
                    sy: 0,
                    ni: 0,
                    id: 0,
                    wa: 0,
                    hi: 0,
                    si: 0,
                    st: 0,
                    temperature: 0
                  }

var exec = require('child_process').exec,
    child;

if(os.type() != "Linux")
{
    console.error("You are not running Linux. Exiting ... \n".red);
    process.exit(0);
}

if(optimist.help || optimist.h)
{
    console.log("\n--------------------------- HELP -----------------------------".red + "\n                   " + "--- PiDashboard.js ---\n".green.bold.underline + "A Monitoring server for Raspberry Pi and other Linux computers." + "\nUsage: \n".bold );
    process.exit(0);
}

if(optimist.cert || optimist.key)
{
    https_pos = true;

    var cert = "",
        key = "";

    if (optimist.cert)  cert = optimist.cert;
    if (optimist.key)   key = optimist.key;

    if (!cert.length)   cert = "./keys/cert.pem";
    if (!key.length)    key = "./keys/key.pem";

    if (!fs.existsSync(key))
    {
        console.error("File ".red+ key.red.bold + " " + "doesn't exists!".red.underline );
        console.log("Can not start https server. Exiting ...".red);
        process.exit(1);
    }
    if (!fs.existsSync(cert))
    {
        console.error("File ".red + cert.red.bold + " " +"doesn't exists!".red.underline );
        console.log("Can not start https server. Exiting ...".red);
        process.exit(1);
    }
}

function getStdOutput(cmd,cb)
{
    exec(cmd,function (error, stdout, stderr)
    {
        if (error !== null)
        {
            console.log('exec error: ' + error);
        }
        cb(stdout);
    });
}

setInterval(function(){

    //getStdOutput('top -bn1',function(out){console.log(out)});
    getStdOutput('cat /sys/class/thermal/thermal_zone0/temp',function(out){console.log(out)})
},1000)

function systemOverview()
{
    return {
        "hostname":os.hostname(),
        "type": os.type(),
        "platform" : os.platform(),
        "arch": os.arch(),
        "release": os.release(),
        "uptime": os.uptime(),
        "loadavg": os.loadavg(),
        "totalmem": os.totalmem(),
        "freemem": os.freemem(),
        "cpus": os.cpus(),
        "netwok": os.networkInterfaces(),
    }
}

// Static fileserver
//@TODO change to express

if (https_pos)
{
    var httpsOptions = {
        key: fs.readFileSync(key),
        cert: fs.readFileSync(cert)
    }
    var WebServer = https.createServer(httpsOptions, httpServer).listen(port,bindingSuccess);
    WebServer.on("error",function(er)
    {
        if(er.code == "EADDRINUSE")
        {
            console.error("Unable to bind to port " + port);
            port = config.backupPort;

            var WebServer = https.createServer(httpsOptions, httpServer).listen(port,bindingSuccess);
            WebServer.on("error",function(er)
            {
                if(er.code == "EADDRINUSE")
                {
                    console.error("Unable to bing to backup port "+ port);
                    process.exit(1);
                }
            });
            console.log("Success running on port "+ port);
        }
    });
}
else
{
    var WebServer = http.createServer(httpServer).listen(port,bindingSuccess);
    WebServer.on("error",function(er)
    {
        if(er.code == "EADDRINUSE")
        {
            console.error("Unable to bind to port " + port);
            port = config.backupPort;

            var WebServer = http.createServer(httpServer).listen(port,bindingSuccess);
            WebServer.on("error",function(er)
            {
                if(er.code == "EADDRINUSE")
                {
                    console.error("Unable to bing to backup port "+ port);
                    process.exit(1);
                }
            })
            console.log("Success running on port "+ port);
        }
    });
}

function httpServer(request, response)
{
    var uri = url.parse(request.url).pathname,
        filename = path.join(process.cwd(), uri);
    fs.exists(filename, function(exists)
    {
        if(!exists)
        {
            response.writeHead(404, {"Content-Type": "text/plain"});
            response.write("404 Not Found\n");
            response.end();
            return;
        }

        if (fs.statSync(filename).isDirectory()) filename += '/index.html';

        fs.readFile(filename, "binary", function(err, file)
        {

        if(err)
        {
            response.writeHead(500, {"Content-Type": "text/plain"});
            response.write(err + "\n");
            response.end();
            return;
        }

        response.writeHead(200);
        response.write(file, "binary");
        response.end();
    });
});
}

function bindingSuccess()
{
    if(https_pos)
    {
        console_sufix = "s:/";
    }
    else
    {
        console_sufix = ":/";
    }

    console.log("Server running at => ".green + "http" + console_sufix +"/localhost:" + port);
}
<|endoftext|>


<commit_before>(function(){
	/*
	Features:
		Draws a grid for the board
		Click to place a stone
		Next stone color alternates each turn
		Shadows are drawn under each stone to indicate the attack/link radius

	TODO:
		General
			Look at latest version of Raphael, my version is OLD!
			Use a package manager for Raphael and other dependencies
			Organize SVG elements into svg groups
			Manually control SVG instead of using Raphael?
		Game Logic
			track placed stones
			freedoms
			attacks
			groups / linking
		Additional Graphics
			show ghost stone. stone disapears in case of collision.
			show different shade of ghost stone in case of collision while button is held down.
			board background
			mark or visually indicate attacked stones
			use a different shadow affect to show linked stone groups
			create other board graphics as an alternative to full grid:
				dots on grid intersections
				dots for "major" intersections
		Display Game stats in additional controls

	Notes:

		Raphael has a built in bounding box (element.getBbox() ), but it is based on x, y, height, and width.
		I need top, bottom, left, and right for intersection testing, so it isn't ideal.  Have to do extra computations.

	*/

	var attackRadius = 50;

	Raphael.fn.stone = function (x, y, r, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Colored Stone. bright spot near the bottom, dark around the edges.
			this.ellipse(x, y, r, r).attr({fill: "r(.5,.9)hsb(" + hue + ", 1, .75)-hsb(" + hue + ", .5, .25)", stroke: "none"}),
			// Inner greyscale shine effect.  Bright spot near the top.
			this.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
		);
		createdSet.x = x;
		createdSet.y = y;
		createdSet.r = r;
		//createdSet.hue = hue;

		return createdSet;
	};

	Raphael.fn.stoneShadow = function (x, y, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Visualization of attack radius.
			this.ellipse(x, y, attackRadius, attackRadius)
				.attr({	stroke: "hsb(" + hue + ", 1, .75)",
						fill: "r(.5,.5)hsb(" + hue + ", .8, .75)-hsb(" + hue + ", .7, .75)",
						opacity: 0}),
			// Hack: a set with just one item will not be removed, so adding a zero size ellipse.
			// TODO: try not using a set at all.
			this.ellipse(x, y, 0, 0)
		);
		createdSet.x = x;
		createdSet.y = y;

		return createdSet;
	};

	var stones = [];
	var shadows = [];

	window.onload = function () {
		var cellSize = attackRadius;
		var halfCellSize = cellSize / 2;
		var stoneRadius = cellSize * 0.45;
		var numCells = 13;

		var boardWidth = cellSize * numCells, boardHeight = cellSize * numCells;
		var R = Raphael("holder", boardWidth, boardHeight);

		//alert("a");
		// Size the graphic playing area
		var holder = document.getElementById("holder");
		holder.style.height = boardHeight+"px";
		holder.style.width = boardWidth+"px";

		//alert("b");
		// For traditional board grid

		var gridTop = halfCellSize;
		var gridBottom = boardHeight - halfCellSize;
		var gridLeft = halfCellSize;
		var gridRight = boardWidth - halfCellSize;

		/*
		var = x, y;
		// Make a grid of stones.
		for(x = cellSize; x < boardWidth; x += cellSize){
			for(y = cellSize; y < boardHeight; y += cellSize){
				R.stone(x, y, radius, Math.random());
			}
		}
		*/

		var drawGrid = function()
		{
			var x, y;
			for(x = gridLeft; x <= gridRight; x += cellSize){
				R.path("M"+x+" "+gridTop+"L"+x+" "+gridBottom).attr({stroke: "#eee"});
			}

			for(y = gridTop; y <= gridBottom; y += cellSize){
				R.path("M"+gridLeft+" "+y+"L"+gridRight+" "+y).attr({stroke: "#eee"});
			}
		}

		drawGrid();

		//alert("3");

		var turn = 0;

		holder.onclick = function(mouseEvent){
			// in Chrome, correct mouse event co-ordinates can be found in:
			//	offsetX
			//	layerX
			// note, offestX and offsetY also worked in IE.

			x = mouseEvent.offsetX;
			y = mouseEvent.offsetY;

			var redHue = 1.0;
			var blueHue = 0.6;
			var greenHue = 0.3;
			var purpleHue = 0.75;
			var orangeHue = 0.1;
			var yellowHue = 0.2;

			var hue;

			if(turn % 2 == 0) hue = blueHue;
			else hue = redHue;

			if(gridLeft < x && x < gridRight && gridTop < y && y < gridBottom)
			{
				var newShadow =
					R.stoneShadow(x, y, hue);

				var newStone =
					R.stone(x, y, stoneRadius, hue);

				var collide = false;
				var stoneIndex = 0;

				while(stoneIndex < stones.length){
					if(stonesIntersect(newStone, stones[stoneIndex]))
					{
						collide = true;
						break;
					}
					++stoneIndex;
				}

				if(collide){
					alert("Collide with stone "+stoneIndex);
					newShadow.remove();
					newStone.remove();
				} else {
					//alert("No collision 1");
					shadows[shadows.length] = newShadow;
					stones[stones.length] = newStone;
					//alert("x: "+newStone.getBBox().x);
					++turn;
				}
			}
		};
	};

	var stonesIntersect = function(stone1, stone2)
	{
		try{
			//alert("stonesIntersect" +
			//	"\nstone1.x: " + stone1.x +
			//	"\nstone1.y: " + stone1.y +
			//	"\nstone1.r: " + stone1.r +
			//	"\nstone2.x: " + stone2.x +
			//	"\nstone2.y: " + stone2.y +
			//	"\nstone2.r: " + stone2.r);

			var intersects = false;

			// Assuming same size stones.
			var sideLength = stone1.r * 2;

			// Do a cheap bounding box intersection check.
			var bSquaresIntersect = squaresIntersect(stone1.x, stone1.y, sideLength, stone2.x, stone2.y, sideLength);
			if(bSquaresIntersect)
			{
				//alert("stonesIntersect 2");
				// Only do a more expensive check if the circles intersect when the bounding boxes intersect.
				intersects = circlesIntersect(stone1.x, stone1.y, stone1.r, stone2.x, stone2.y, stone2.r);
			}
			return intersects;
		}catch(e){
			alert(e.toString());
		}
	}

	var squaresIntersect = function(x1, y1, side1, x2, y2, side2)
	{
		try{
			//alert("squaresIntersect");

			//top1 <= bottom2
			var b1 = y1 <= y2 + side2;
			//bottom1 >= top2
			var b2 = y1 + side1 >= y2;
			//left1 <= right2
			var b3 = x1 <= x2 + side2;
			//right1 >= left2
			var b4 = x1 + side1 >= x2;

			return b1 && b2 && b3 && b4;

		} catch(e) {
			alert(e.toString());
		}
	};

	var circlesIntersect = function(x1, y1, r1, x2, y2, r2)
	{
		try{
			var dist = Math.sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
			return (dist <= r1 + r2);
		} catch(e) {
			alert(e.toString());
		}
	}
})();
<commit_msg>Cleaning up circle intersection logic.<commit_after>(function(){
	/*
	Features:
		Draws a grid for the board
		Click to place a stone
		Next stone color alternates each turn
		Shadows are drawn under each stone to indicate the attack/link radius

	TODO:
		General
			Look at latest version of Raphael, my version is OLD!
			Use a package manager for Raphael and other dependencies
			Organize SVG elements into svg groups
			Manually control SVG instead of using Raphael?
		Game Logic
			track placed stones
			freedoms
			attacks
			groups / linking
		Additional Graphics
			show ghost stone. stone disapears in case of collision.
			show different shade of ghost stone in case of collision while button is held down.
			board background
			mark or visually indicate attacked stones
			use a different shadow affect to show linked stone groups
			create other board graphics as an alternative to full grid:
				dots on grid intersections
				dots for "major" intersections
		Display Game stats in additional controls

	Notes:

		Raphael has a built in bounding box (element.getBbox() ), but it is based on x, y, height, and width.
		I need top, bottom, left, and right for intersection testing, so it isn't ideal.  Have to do extra computations.

	*/

	var ATTACK_RADIUS = 50;

	Raphael.fn.stone = function (x, y, r, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Colored Stone. bright spot near the bottom, dark around the edges.
			this.ellipse(x, y, r, r).attr({fill: "r(.5,.9)hsb(" + hue + ", 1, .75)-hsb(" + hue + ", .5, .25)", stroke: "none"}),
			// Inner greyscale shine effect.  Bright spot near the top.
			this.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
		);
		createdSet.x = x;
		createdSet.y = y;
		createdSet.r = r;
		//createdSet.hue = hue;

		return createdSet;
	};

	Raphael.fn.stoneShadow = function (x, y, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Visualization of attack radius.
			this.ellipse(x, y, ATTACK_RADIUS, ATTACK_RADIUS)
				.attr({	stroke: "hsb(" + hue + ", 1, .75)",
						fill: "r(.5,.5)hsb(" + hue + ", .8, .75)-hsb(" + hue + ", .7, .75)",
						opacity: 0}),
			// Hack: a set with just one item will not be removed, so adding a zero size ellipse.
			// TODO: try not using a set at all.
			this.ellipse(x, y, 0, 0)
		);
		createdSet.x = x;
		createdSet.y = y;

		return createdSet;
	};

	var stones = [];
	var shadows = [];

	window.onload = function () {
		var cellSize = ATTACK_RADIUS;
		var halfCellSize = cellSize / 2;
		var STONE_RADIUS = cellSize * 0.45;
		var numCells = 13;

		var boardWidth = cellSize * numCells, boardHeight = cellSize * numCells;
		var R = Raphael("holder", boardWidth, boardHeight);

		//alert("a");
		// Size the graphic playing area
		var holder = document.getElementById("holder");
		holder.style.height = boardHeight+"px";
		holder.style.width = boardWidth+"px";

		//alert("b");
		// For traditional board grid

		var gridTop = halfCellSize;
		var gridBottom = boardHeight - halfCellSize;
		var gridLeft = halfCellSize;
		var gridRight = boardWidth - halfCellSize;

		/*
		var = x, y;
		// Make a grid of stones.
		for(x = cellSize; x < boardWidth; x += cellSize){
			for(y = cellSize; y < boardHeight; y += cellSize){
				R.stone(x, y, radius, Math.random());
			}
		}
		*/

		var drawGrid = function()
		{
			var x, y;
			for(x = gridLeft; x <= gridRight; x += cellSize){
				R.path("M"+x+" "+gridTop+"L"+x+" "+gridBottom).attr({stroke: "#eee"});
			}

			for(y = gridTop; y <= gridBottom; y += cellSize){
				R.path("M"+gridLeft+" "+y+"L"+gridRight+" "+y).attr({stroke: "#eee"});
			}
		}

		drawGrid();

		//alert("3");

		var turn = 0;

		holder.onclick = function(mouseEvent){
			// in Chrome, correct mouse event co-ordinates can be found in:
			//	offsetX
			//	layerX
			// note, offestX and offsetY also worked in IE.

			x = mouseEvent.offsetX;
			y = mouseEvent.offsetY;

			var redHue = 1.0;
			var blueHue = 0.6;
			var greenHue = 0.3;
			var purpleHue = 0.75;
			var orangeHue = 0.1;
			var yellowHue = 0.2;

			var hue;

			if(turn % 2 == 0) hue = blueHue;
			else hue = redHue;

			if(gridLeft < x && x < gridRight && gridTop < y && y < gridBottom)
			{
				var newShadow =
					R.stoneShadow(x, y, hue);

				var newStone =
					R.stone(x, y, STONE_RADIUS, hue);

				var collide = false;
				var stoneIndex = 0;

				while(stoneIndex < stones.length){
					if(circlesIntersect(newStone, stones[stoneIndex]))
					{
						collide = true;
						break;
					}
					++stoneIndex;
				}

				if(collide){
					alert("Collide with stone "+stoneIndex);
					newShadow.remove();
					newStone.remove();
				} else {
					//alert("No collision 1");
					shadows[shadows.length] = newShadow;
					stones[stones.length] = newStone;
					//alert("x: "+newStone.getBBox().x);
					++turn;
				}
			}
		};
	};

	// Check if two circles OF THE SAME RADIUS
	// intersect.  Optimized with a cheap check
	// first before doing an exact check.
	var circlesIntersect = function(stone1, stone2)
	{
		try{

			var intersects = false;

			// Assuming same size stones.
			var sideLength = stone1.r * 2;

			// Do a cheap bounding box intersection check.
			var circlesMayIntersect = ;
			if(cheapCirclesMayIntersect(stone1, stone2))
			{
				// Only do a more expensive check if the circles intersect when the bounding boxes intersect.
				intersects = exactCirclesIntersect(stone1, stone2);
			}
			return intersects;
		}catch(e){
			alert(e.toString());
		}
	}

	var cheapCirclesMayIntersect = function(circle1, circle2)
	{
		try{
			//alert("cheapCirclesMayIntersect");
			diameter1 = circle1.r * 2;
			diameter2 = circle2.r + 2;

			//top1 <= bottom2
			var b1 = circle1.y <= circle2.y + diameter2;
			//bottom1 >= top2
			var b2 = circle1.y + diameter1 >= circle2.y;
			//left1 <= right2
			var b3 = circle1.x <= circle2.x + diameter2;
			//right1 >= left2
			var b4 = circle1.x + diameter1 >= circle2.x;

			return b1 && b2 && b3 && b4;

		} catch(e) {
			alert(e.toString());
		}
	};

	var exactCirclesIntersect = function(circle1, circle2)
	{
		try{
			var dist = Math.sqrt((circle2.x - circle1.x)*(circle2.x - circle1.x) + (circle2.y - circle1.y)*(circle2.y - circle1.y));
			return (dist <= circle1.r + circle2.r);
		} catch(e) {
			alert(e.toString());
		}
	}
})();
<|endoftext|>


<commit_before>(function(){
	/*
	Features:
		Draws a grid for the board
		Click to place a stone
		Next stone color alternates each turn
		Shadows are drawn under each stone to indicate the attack/link radius

	TODO:
		General
			Look at latest version of Raphael, my version is OLD!
			Use a package manager for Raphael and other dependencies
			Organize SVG elements into svg groups
			Manually control SVG instead of using Raphael?
		Game Logic
			track placed stones
			freedoms
			attacks
			groups / linking
		Additional Graphics
			show ghost stone. stone disapears in case of collision.
			show different shade of ghost stone in case of collision while button is held down.
			board background
			mark or visually indicate attacked stones
			use a different shadow affect to show linked stone groups
			create other board graphics as an alternative to full grid:
				dots on grid intersections
				dots for "major" intersections
		Display Game stats in additional controls

	Notes:

		Raphael has a built in bounding box (element.getBbox() ), but it is based on x, y, height, and width.
		I need top, bottom, left, and right for intersection testing, so it isn't ideal.  Have to do extra computations.

	*/

	var ATTACK_RADIUS = 50;

	Raphael.fn.stone = function (x, y, r, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Colored Stone. bright spot near the bottom, dark around the edges.
			this.ellipse(x, y, r, r).attr({fill: "r(.5,.9)hsb(" + hue + ", 1, .75)-hsb(" + hue + ", .5, .25)", stroke: "none"}),
			// Inner greyscale shine effect.  Bright spot near the top.
			this.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
		);
		createdSet.x = x;
		createdSet.y = y;
		createdSet.r = r;
		//createdSet.hue = hue;

		return createdSet;
	};

	Raphael.fn.stoneShadow = function (x, y, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Visualization of attack radius.
			this.ellipse(x, y, ATTACK_RADIUS, ATTACK_RADIUS)
				.attr({	stroke: "hsb(" + hue + ", 1, .75)",
						fill: "r(.5,.5)hsb(" + hue + ", .8, .75)-hsb(" + hue + ", .7, .75)",
						opacity: 0}),
			// Hack: a set with just one item will not be removed, so adding a zero size ellipse.
			// TODO: try not using a set at all.
			this.ellipse(x, y, 0, 0)
		);
		createdSet.x = x;
		createdSet.y = y;

		return createdSet;
	};

	var stones = [];
	var shadows = [];

	window.onload = function () {
		var cellSize = ATTACK_RADIUS;
		var halfCellSize = cellSize / 2;
		var STONE_RADIUS = cellSize * 0.45;
		var numCells = 13;

		var boardWidth = cellSize * numCells, boardHeight = cellSize * numCells;
		var R = Raphael("holder", boardWidth, boardHeight);

		//alert("a");
		// Size the graphic playing area
		var holder = document.getElementById("holder");
		holder.style.height = boardHeight+"px";
		holder.style.width = boardWidth+"px";

		//alert("b");
		// For traditional board grid

		var gridTop = halfCellSize;
		var gridBottom = boardHeight - halfCellSize;
		var gridLeft = halfCellSize;
		var gridRight = boardWidth - halfCellSize;

		/*
		var = x, y;
		// Make a grid of stones.
		for(x = cellSize; x < boardWidth; x += cellSize){
			for(y = cellSize; y < boardHeight; y += cellSize){
				R.stone(x, y, radius, Math.random());
			}
		}
		*/

		var drawGrid = function()
		{
			var x, y;
			for(x = gridLeft; x <= gridRight; x += cellSize){
				R.path("M"+x+" "+gridTop+"L"+x+" "+gridBottom).attr({stroke: "#eee"});
			}

			for(y = gridTop; y <= gridBottom; y += cellSize){
				R.path("M"+gridLeft+" "+y+"L"+gridRight+" "+y).attr({stroke: "#eee"});
			}
		}

		drawGrid();

		//alert("3");

		var turn = 0;

		holder.onclick = function(mouseEvent){
			// in Chrome, correct mouse event co-ordinates can be found in:
			//	offsetX
			//	layerX
			// note, offestX and offsetY also worked in IE.

			x = mouseEvent.offsetX;
			y = mouseEvent.offsetY;

			var redHue = 1.0;
			var blueHue = 0.6;
			var greenHue = 0.3;
			var purpleHue = 0.75;
			var orangeHue = 0.1;
			var yellowHue = 0.2;

			var hue;

			if(turn % 2 == 0) hue = blueHue;
			else hue = redHue;

			if(gridLeft < x && x < gridRight && gridTop < y && y < gridBottom)
			{
				var newShadow =
					R.stoneShadow(x, y, hue);

				var newStone =
					R.stone(x, y, STONE_RADIUS, hue);

				var collide = false;
				var stoneIndex = 0;

				while(stoneIndex < stones.length){
					if(circlesIntersect(newStone, stones[stoneIndex]))
					{
						collide = true;
						break;
					}
					++stoneIndex;
				}

				if(collide){
					alert("Collide with stone "+stoneIndex);
					newShadow.remove();
					newStone.remove();
				} else {
					//alert("No collision 1");
					shadows[shadows.length] = newShadow;
					stones[stones.length] = newStone;
					//alert("x: "+newStone.getBBox().x);
					++turn;
				}
			}
		};
	};

	// Check if two circles OF THE SAME RADIUS
	// intersect.  Optimized with a cheap check
	// first before doing an exact check.
	var circlesIntersect = function(stone1, stone2)
	{
		try{

			var intersects = false;

			// Assuming same size stones.
			var sideLength = stone1.r * 2;

			// Do a cheap bounding box intersection check.
			var circlesMayIntersect = ;
			if(cheapCirclesMayIntersect(stone1, stone2))
			{
				// Only do a more expensive check if the circles intersect when the bounding boxes intersect.
				intersects = exactCirclesIntersect(stone1, stone2);
			}
			return intersects;
		}catch(e){
			alert(e.toString());
		}
	}

	var cheapCirclesMayIntersect = function(circle1, circle2)
	{
		try{
			//alert("cheapCirclesMayIntersect");
			diameter1 = circle1.r * 2;
			diameter2 = circle2.r + 2;

			//top1 <= bottom2
			var b1 = circle1.y <= circle2.y + diameter2;
			//bottom1 >= top2
			var b2 = circle1.y + diameter1 >= circle2.y;
			//left1 <= right2
			var b3 = circle1.x <= circle2.x + diameter2;
			//right1 >= left2
			var b4 = circle1.x + diameter1 >= circle2.x;

			return b1 && b2 && b3 && b4;

		} catch(e) {
			alert(e.toString());
		}
	};

	var exactCirclesIntersect = function(circle1, circle2)
	{
		try{
			var dist = Math.sqrt((circle2.x - circle1.x)*(circle2.x - circle1.x) + (circle2.y - circle1.y)*(circle2.y - circle1.y));
			return (dist <= circle1.r + circle2.r);
		} catch(e) {
			alert(e.toString());
		}
	}
})();
<commit_msg>Fix incomplete line.<commit_after>(function(){
	/*
	Features:
		Draws a grid for the board
		Click to place a stone
		Next stone color alternates each turn
		Shadows are drawn under each stone to indicate the attack/link radius

	TODO:
		General
			Look at latest version of Raphael, my version is OLD!
			Use a package manager for Raphael and other dependencies
			Organize SVG elements into svg groups
			Manually control SVG instead of using Raphael?
		Game Logic
			track placed stones
			freedoms
			attacks
			groups / linking
		Additional Graphics
			show ghost stone. stone disapears in case of collision.
			show different shade of ghost stone in case of collision while button is held down.
			board background
			mark or visually indicate attacked stones
			use a different shadow affect to show linked stone groups
			create other board graphics as an alternative to full grid:
				dots on grid intersections
				dots for "major" intersections
		Display Game stats in additional controls

	Notes:

		Raphael has a built in bounding box (element.getBbox() ), but it is based on x, y, height, and width.
		I need top, bottom, left, and right for intersection testing, so it isn't ideal.  Have to do extra computations.

	*/

	var ATTACK_RADIUS = 50;

	Raphael.fn.stone = function (x, y, r, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Colored Stone. bright spot near the bottom, dark around the edges.
			this.ellipse(x, y, r, r).attr({fill: "r(.5,.9)hsb(" + hue + ", 1, .75)-hsb(" + hue + ", .5, .25)", stroke: "none"}),
			// Inner greyscale shine effect.  Bright spot near the top.
			this.ellipse(x, y, r - r / 5, r - r / 20).attr({stroke: "none", fill: "r(.5,.1)#ccc-#ccc", opacity: 0})
		);
		createdSet.x = x;
		createdSet.y = y;
		createdSet.r = r;
		//createdSet.hue = hue;

		return createdSet;
	};

	Raphael.fn.stoneShadow = function (x, y, hue) {
		hue = hue || 0;
		var createdSet = this.set(
			// Visualization of attack radius.
			this.ellipse(x, y, ATTACK_RADIUS, ATTACK_RADIUS)
				.attr({	stroke: "hsb(" + hue + ", 1, .75)",
						fill: "r(.5,.5)hsb(" + hue + ", .8, .75)-hsb(" + hue + ", .7, .75)",
						opacity: 0}),
			// Hack: a set with just one item will not be removed, so adding a zero size ellipse.
			// TODO: try not using a set at all.
			this.ellipse(x, y, 0, 0)
		);
		createdSet.x = x;
		createdSet.y = y;

		return createdSet;
	};

	var stones = [];
	var shadows = [];

	window.onload = function () {
		var cellSize = ATTACK_RADIUS;
		var halfCellSize = cellSize / 2;
		var STONE_RADIUS = cellSize * 0.45;
		var numCells = 13;

		var boardWidth = cellSize * numCells, boardHeight = cellSize * numCells;
		var R = Raphael("holder", boardWidth, boardHeight);

		//alert("a");
		// Size the graphic playing area
		var holder = document.getElementById("holder");
		holder.style.height = boardHeight+"px";
		holder.style.width = boardWidth+"px";

		//alert("b");
		// For traditional board grid

		var gridTop = halfCellSize;
		var gridBottom = boardHeight - halfCellSize;
		var gridLeft = halfCellSize;
		var gridRight = boardWidth - halfCellSize;

		/*
		var = x, y;
		// Make a grid of stones.
		for(x = cellSize; x < boardWidth; x += cellSize){
			for(y = cellSize; y < boardHeight; y += cellSize){
				R.stone(x, y, radius, Math.random());
			}
		}
		*/

		var drawGrid = function()
		{
			var x, y;
			for(x = gridLeft; x <= gridRight; x += cellSize){
				R.path("M"+x+" "+gridTop+"L"+x+" "+gridBottom).attr({stroke: "#eee"});
			}

			for(y = gridTop; y <= gridBottom; y += cellSize){
				R.path("M"+gridLeft+" "+y+"L"+gridRight+" "+y).attr({stroke: "#eee"});
			}
		}

		drawGrid();

		//alert("3");

		var turn = 0;

		holder.onclick = function(mouseEvent){
			// in Chrome, correct mouse event co-ordinates can be found in:
			//	offsetX
			//	layerX
			// note, offestX and offsetY also worked in IE.

			x = mouseEvent.offsetX;
			y = mouseEvent.offsetY;

			var redHue = 1.0;
			var blueHue = 0.6;
			var greenHue = 0.3;
			var purpleHue = 0.75;
			var orangeHue = 0.1;
			var yellowHue = 0.2;

			var hue;

			if(turn % 2 == 0) hue = blueHue;
			else hue = redHue;

			if(gridLeft < x && x < gridRight && gridTop < y && y < gridBottom)
			{
				var newShadow =
					R.stoneShadow(x, y, hue);

				var newStone =
					R.stone(x, y, STONE_RADIUS, hue);

				var collide = false;
				var stoneIndex = 0;

				while(stoneIndex < stones.length){
					if(circlesIntersect(newStone, stones[stoneIndex]))
					{
						collide = true;
						break;
					}
					++stoneIndex;
				}

				if(collide){
					alert("Collide with stone "+stoneIndex);
					newShadow.remove();
					newStone.remove();
				} else {
					//alert("No collision 1");
					shadows[shadows.length] = newShadow;
					stones[stones.length] = newStone;
					//alert("x: "+newStone.getBBox().x);
					++turn;
				}
			}
		};
	};

	// Check if two circles OF THE SAME RADIUS
	// intersect.  Optimized with a cheap check
	// first before doing an exact check.
	var circlesIntersect = function(stone1, stone2)
	{
		try{

			var intersects = false;

			// Assuming same size stones.
			var sideLength = stone1.r * 2;

			// Do a cheap bounding box intersection check.
			var circlesMayIntersect = false;
			if(cheapCirclesMayIntersect(stone1, stone2))
			{
				// Only do a more expensive check if the circles intersect when the bounding boxes intersect.
				intersects = exactCirclesIntersect(stone1, stone2);
			}
			return intersects;
		}catch(e){
			alert(e.toString());
		}
	}

	var cheapCirclesMayIntersect = function(circle1, circle2)
	{
		try{
			//alert("cheapCirclesMayIntersect");
			diameter1 = circle1.r * 2;
			diameter2 = circle2.r + 2;

			//top1 <= bottom2
			var b1 = circle1.y <= circle2.y + diameter2;
			//bottom1 >= top2
			var b2 = circle1.y + diameter1 >= circle2.y;
			//left1 <= right2
			var b3 = circle1.x <= circle2.x + diameter2;
			//right1 >= left2
			var b4 = circle1.x + diameter1 >= circle2.x;

			return b1 && b2 && b3 && b4;

		} catch(e) {
			alert(e.toString());
		}
	};

	var exactCirclesIntersect = function(circle1, circle2)
	{
		try{
			var dist = Math.sqrt((circle2.x - circle1.x)*(circle2.x - circle1.x) + (circle2.y - circle1.y)*(circle2.y - circle1.y));
			return (dist <= circle1.r + circle2.r);
		} catch(e) {
			alert(e.toString());
		}
	}
})();
<|endoftext|>


<commit_before>import {Carousel} from './Carousel';
import {Aside} from './Aside';

import {FETCH_INTERVAL, DEFAULT_INTERVAL} from './views';

export class Main extends React.Component {
    constructor(props){
      super(props);
        this.state = {
          "current" :  {
              "id": "aia_0193",
              "title": "AIA 193",
              "sensor": "AIA",
              "feed": "https://sdo.gsfc.nasa.gov/feeds/aia_0193.rss",
              "latest": {
                "image" : "images/black_square.png",
                "date" : new Date()
              },
          },
          "error" : false,
          "loading" : true
        };
        this.channels = [];
        this.currentIndex = 0;
        this.spinner = props.spinner;
    }

    componentDidMount(){
        this.fetchImages(
            () => {
                this.startCarousel();
            }
        );

        window.setInterval(this.fetchImages.bind(this), FETCH_INTERVAL);
    }

    render(){
      return

        <Carousel current={this.state.current} />

;
    }

    startCarousel(){
        if(!this.channels.length >= 1){
          //document.getElementById('error-icon').style.display = "inline-block";
          return;
        }

        console.log("Done Fetching and Parsing Images.");

        // Set to -1 so that when incremented in refreshImage() the very first image is at index 0.
        this.currentIndex = -1;
        this.refreshImage();
    }

    /**
     * Move carousel to next image.
     *
     * If this image is not yet loaded or failed to load it will try to move ahead to the following image.
     *
     */
    refreshImage(){
        this.currentIndex = (this.currentIndex + 1) % (this.channels.length);
        console.log("Switching to image " + this.currentIndex);

        let currentView = this.channels[this.currentIndex];

        this.setState(
            Object.assign({}, this.state, {"current" :  currentView})
        );

        this.spinner.reset(this.currentIndex, this.channels.length);
        setTimeout(this.refreshImage.bind(this), DEFAULT_INTERVAL);
    }

    /**
     * Contacts server and loads new images
     */
    fetchImages(callback){
        console.log("Sending update command");
        this.setLoading(true);

        fetch("/actions/update")
          .then(() => {
            fetch("/channels")
              .then(response => response.json())
              .then(
                (data) => {
                  console.log("Reading Channels");
                  this.channels = data;
                  console.log(data);

                  this.setLoading(false);

                  if(callback){
                    callback();
                  }
                }
              )
          }
        )
        .catch(error => {
            setError(true);
            console.log("Unable to do update command");
        });
    }

    setLoading(value){
        this.setState(
            Object.assign({}, this.state, {"loading" :  value})
        );
    }

    setError(value){
        this.setState(
            Object.assign({}, this.state, {"error" :  value})
        );
    }
}
<commit_msg>Skip channels without latest images<commit_after>import {Carousel} from './Carousel';
import {Aside} from './Aside';

import {FETCH_INTERVAL, DEFAULT_INTERVAL} from './views';

export class Main extends React.Component {
    constructor(props){
      super(props);
        this.state = {
          "current" :  {
              "id": "aia_0193",
              "title": "AIA 193",
              "sensor": "AIA",
              "feed": "https://sdo.gsfc.nasa.gov/feeds/aia_0193.rss",
              "latest": {
                "image" : "images/black_square.png",
                "date" : new Date()
              },
          },
          "error" : false,
          "loading" : true
        };
        this.channels = [];
        this.currentIndex = 0;
        this.spinner = props.spinner;
    }

    componentDidMount(){
        this.fetchImages(
            () => {
                this.startCarousel();
            }
        );

        window.setInterval(this.fetchImages.bind(this), FETCH_INTERVAL);
    }

    render(){
      return

        <Carousel current={this.state.current} />

;
    }

    startCarousel(){
        if(!this.channels.length >= 1){
          //document.getElementById('error-icon').style.display = "inline-block";
          return;
        }

        console.log("Done Fetching and Parsing Images.");

        // Set to -1 so that when incremented in refreshImage() the very first image is at index 0.
        this.currentIndex = -1;
        this.refreshImage();
    }

    /**
     * Move carousel to next image.
     *
     * If this image is not yet loaded or failed to load it will try to move ahead to the following image.
     *
     */
    refreshImage(){
        this.currentIndex = (this.currentIndex + 1) % (this.channels.length);
        console.log("Switching to image " + this.currentIndex);

        let currentView = this.channels[this.currentIndex];

        this.setState(
            Object.assign({}, this.state, {"current" :  currentView})
        );

        this.spinner.reset(this.currentIndex, this.channels.length);
        setTimeout(this.refreshImage.bind(this), DEFAULT_INTERVAL);
    }

    /**
     * Contacts server and loads new images
     */
    fetchImages(callback){
        console.log("Sending update command");
        this.setLoading(true);

        fetch("/actions/update")
          .then(() => {
            fetch("/channels")
              .then(response => response.json())
              .then(
                (data) => {
                  console.log("Reading Channels");

                  this.channels = data.filter(
                    // Skip channels that don't have images.
                    channel => channel.latest
                  );
                  console.log(data);

                  this.setLoading(false);

                  if(callback){
                    callback();
                  }
                }
              )
          }
        )
        .catch(error => {
            setError(true);
            console.log("Unable to do update command");
        });
    }

    setLoading(value){
        this.setState(
            Object.assign({}, this.state, {"loading" :  value})
        );
    }

    setError(value){
        this.setState(
            Object.assign({}, this.state, {"error" :  value})
        );
    }
}
<|endoftext|>


<commit_before>var APIEndPoint = "http://api.sunrise-sunset.org/json?"

http://api.sunrise-sunset.org/json?lat=36.7201600&lng=-4.4203400&date=today
//Ready
$(document).ready(function() {
	// Put your code in here!

	updateTime();
	getLocation();
});

function updateTime() {
	var time = new Date().getTime();
	time = Math.round(time / 1000);
	var dayArray = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
	$("#date_section #day_of_week").text(dayArray[moment.unix(time).format("E")-1]);
	$("#date_section #date").text(moment.unix(time).format("MMMM DD, YYYY"));
}

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(getSunPosFromAPI);
    } else {
    	displayError({ "errorTitle": "Sorry", "errorText": "Geolocation is not supported by this browser."});
    }
}

function showPosition(position) {

    var innerHTML = "Latitude: " + position.coords.latitude +
    "
Longitude: " + position.coords.longitude;

    $("#content").html("
"+innerHTML+"
");
}

function getSunPosFromAPI(position) {
    $.getJSON(APIEndPoint + "lat=" + position.coords.latitude + "&lng=" + position.coords.longitude + "&date=today" + "&callback=?")
    .done(parseData)
    .fail(getAPIError);
}

function getAPIError() {
    displayError({ "errorTitle": "Sorry", "errorText": "Refresh Me! - Service Temporarily Unavailable"});
}

function parseData(data) {
    $("#sun-rise .time").text(data["results"]["sunrise"]);
    $("#noon .time").text(data["results"]["solar_noon"]);
    $("#sun-set .time").text(data["results"]["sunset"]);
}

//helper functions
function displayError(errorInfo) {
    var item_html = $("#error-prototype").html();
    var innerHTML = Mustache.render(item_html, errorInfo);
    $("#content").html(innerHTML);
}<commit_msg>Posting<commit_after>var APIEndPoint = "http://api.sunrise-sunset.org/json?"
var time;

$(document).ready(function() {
	// Put your code in here!

	updateTime();
	getLocation();
});

function updateTime() {
	time = new Date().getTime();
	time = Math.round(time / 1000);
	var dayArray = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
	$("#date_section #day_of_week").text(dayArray[moment.unix(time).format("E")-1]);
	$("#date_section #date").text(moment.unix(time).format("MMMM DD, YYYY"));
}

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(getSunPosFromAPI);
    } else {
    	displayError({ "errorTitle": "Sorry", "errorText": "Geolocation is not supported by this browser."});
    }
}

function showPosition(position) {

    var innerHTML = "Latitude: " + position.coords.latitude +
    "
Longitude: " + position.coords.longitude;

    $("#content").html("
"+innerHTML+"
");
}

function getSunPosFromAPI(position) {
    $.getJSON(APIEndPoint + "lat=" + position.coords.latitude + "&lng=" + position.coords.longitude + "&date=today" + "&callback=?")
    .done(parseData)
    .fail(getAPIError);
}

function getAPIError() {
    displayError({ "errorTitle": "Sorry", "errorText": "Refresh Me! - Service Temporarily Unavailable"});
}

function parseData(data) {
    $("#sun-rise .time").text(data["results"]["sunrise"]);
    $("#noon .time").text(data["results"]["solar_noon"]);
    $("#sun-set .time").text(data["results"]["sunset"]);
}

//helper functions
function displayError(errorInfo) {
    var item_html = $("#error-prototype").html();
    var innerHTML = Mustache.render(item_html, errorInfo);
    $("#content").html(innerHTML);
}<|endoftext|>