<commit_before>var _ = require('underscore');
var MBTiles = require('mbtiles');
var iconv = new require('iconv').Iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE');

module.exports = MBTiles;

// Implements carmen#search method.
MBTiles.prototype.search = function(query, id, callback) {
    var arg = query ? query : id;
    var sql = query
        ? 'SELECT c.id, c.text, c.zxy FROM carmen c WHERE c.text MATCH(?) LIMIT 1000'
        : 'SELECT c.id, c.text, c.zxy FROM carmen c WHERE c.id MATCH(?) LIMIT 1000';
    this._db.all(sql, arg, function(err, rows) {
        if (err) return callback(err);
        rows = rows.map(function(row) {
            row.zxy = row.zxy.split(',');
            return row;
        });
        callback(null, rows);
    });
};

// Implements carmen#feature method.
MBTiles.prototype.feature = function(id, callback) {
    this._db.get('SELECT key_name AS id, key_json AS data FROM keymap WHERE key_name = ?', id, function(err, row) {
        if (err) return callback(err);
        try { return callback(null, JSON.parse(row.data)); }
        catch(err) { return callback(err); }
    });
};

// Implements carmen#index method.
MBTiles.prototype.index = function(id, text, doc, zxy, callback) {
    try { text = iconv.convert(text).toString(); }
    catch(err) { return callback(err); }

    var remaining = 2;
    var done = function(err) {
        if (err) {
            remaining = -1;
            callback(err);
        } else if (!--remaining) {
            callback(null);
        }
    };
    this._db.run('REPLACE INTO carmen (id, text, zxy) VALUES (?, ?, ?)', id, text, zxy.join(','), done);
    this._db.run('REPLACE INTO keymap (key_name, key_json) VALUES (?, ?)', id, JSON.stringify(doc), done);
};

// Implements carmen#indexable method.
MBTiles.prototype.indexable = function(pointer, callback) {
    pointer = pointer || 0;
    this.getInfo(function(err, info) {
        this._db.all("SELECT k.key_name, k.key_json, GROUP_CONCAT(zoom_level||'/'||tile_column ||'/'||tile_row,',') AS zxy FROM keymap k JOIN grid_key g ON k.key_name = g.key_name JOIN map m ON g.grid_id = m.grid_id WHERE m.zoom_level=? GROUP BY k.key_name LIMIT 10000 OFFSET ?;", info.maxzoom, pointer, function(err, rows) {
            if (err) return callback(err);
            var docs = rows.map(function(row) {
                var doc = {};
                doc.id = row.key_name;
                doc.doc = JSON.parse(row.key_json);
                // @TODO the doc field name for searching probably (?) belongs
                // in `metadata` and should be un-hardcoded in the future.
                doc.text = doc.doc.search || '';
                doc.zxy = row.zxy.split(',');
                return doc;
            });
            pointer += 10000;
            return callback(null, docs, pointer);
        }.bind(this));
    }.bind(this));
};

// Adds carmen schema to startWriting.
MBTiles.prototype.startWriting = _(MBTiles.prototype.startWriting).wrap(function(parent, callback) {
    parent.call(this, function(err) {
        if (err) return callback(err);
        var sql = '\
        CREATE INDEX IF NOT EXISTS map_grid_id ON map (grid_id);\
        CREATE VIRTUAL TABLE carmen USING fts4(id,text,zxy,tokenize=simple);'
        this._db.exec(sql, function(err) {
            if (err && !/table carmen already exists/.test(err.message)) {
                return callback(err);
            } else {
                return callback();
            }
        });
    }.bind(this));
});

<commit_msg>Allow carmen index to be used as source of indexable docs.<commit_after>var _ = require('underscore');
var MBTiles = require('mbtiles');
var iconv = new require('iconv').Iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE');

module.exports = MBTiles;

// Implements carmen#search method.
MBTiles.prototype.search = function(query, id, callback) {
    var arg = query ? query : id;
    var sql = query
        ? 'SELECT c.id, c.text, c.zxy FROM carmen c WHERE c.text MATCH(?) LIMIT 1000'
        : 'SELECT c.id, c.text, c.zxy FROM carmen c WHERE c.id MATCH(?) LIMIT 1000';
    this._db.all(sql, arg, function(err, rows) {
        if (err) return callback(err);
        rows = rows.map(function(row) {
            row.zxy = row.zxy.split(',');
            return row;
        });
        callback(null, rows);
    });
};

// Implements carmen#feature method.
MBTiles.prototype.feature = function(id, callback) {
    this._db.get('SELECT key_name AS id, key_json AS data FROM keymap WHERE key_name = ?', id, function(err, row) {
        if (err) return callback(err);
        try { return callback(null, JSON.parse(row.data)); }
        catch(err) { return callback(err); }
    });
};

// Implements carmen#index method.
MBTiles.prototype.index = function(id, text, doc, zxy, callback) {
    try { text = iconv.convert(text).toString(); }
    catch(err) { return callback(err); }

    var remaining = 2;
    var done = function(err) {
        if (err) {
            remaining = -1;
            callback(err);
        } else if (!--remaining) {
            callback(null);
        }
    };
    this._db.run('REPLACE INTO carmen (id, text, zxy) VALUES (?, ?, ?)', id, text, zxy.join(','), done);
    this._db.run('REPLACE INTO keymap (key_name, key_json) VALUES (?, ?)', id, JSON.stringify(doc), done);
};

// Implements carmen#indexable method.
MBTiles.prototype.indexable = function(pointer, callback) {
    pointer = pointer || {};
    pointer.offset = pointer.offset || 0;

    // If 'carmen' option is passed in initial pointer, retrieve indexables from
    // carmen table. This option can be used to access the previously indexed
    // documents from an MBTiles database without having to know what search
    // field was used in the past (see comment below).
    if (pointer.table === 'carmen') return this._db.all("SELECT c.id, c.text, c.zxy, k.key_json FROM carmen c JOIN keymap k ON c.id = k.key_name LIMIT 10000 OFFSET ?", pointer.offset, function(err, rows) {
        if (err) return callback(err);
        var docs = rows.map(function(row) {
            var doc = {};
            doc.id = row.id;
            doc.doc = JSON.parse(row.key_json);
            doc.text = row.text;
            doc.zxy = row.zxy.split(',');
            return doc;
        });
        pointer.offset += 10000;
        return callback(null, docs, pointer);
    }.bind(this));

    // By default the keymap table contains all indexable documents.
    this.getInfo(function(err, info) {
        this._db.all("SELECT k.key_name, k.key_json, GROUP_CONCAT(zoom_level||'/'||tile_column ||'/'||tile_row,',') AS zxy FROM keymap k JOIN grid_key g ON k.key_name = g.key_name JOIN map m ON g.grid_id = m.grid_id WHERE m.zoom_level=? GROUP BY k.key_name LIMIT 10000 OFFSET ?;", info.maxzoom, pointer.offset, function(err, rows) {
            if (err) return callback(err);
            var docs = rows.map(function(row) {
                var doc = {};
                doc.id = row.key_name;
                doc.doc = JSON.parse(row.key_json);
                // @TODO the doc field name for searching probably (?) belongs
                // in `metadata` and should be un-hardcoded in the future.
                doc.text = doc.doc.search || '';
                doc.zxy = row.zxy.split(',');
                return doc;
            });
            pointer.offset += 10000;
            return callback(null, docs, pointer);
        }.bind(this));
    }.bind(this));
};

// Adds carmen schema to startWriting.
MBTiles.prototype.startWriting = _(MBTiles.prototype.startWriting).wrap(function(parent, callback) {
    parent.call(this, function(err) {
        if (err) return callback(err);
        var sql = '\
        CREATE INDEX IF NOT EXISTS map_grid_id ON map (grid_id);\
        CREATE VIRTUAL TABLE carmen USING fts4(id,text,zxy,tokenize=simple);'
        this._db.exec(sql, function(err) {
            if (err && !/table carmen already exists/.test(err.message)) {
                return callback(err);
            } else {
                return callback();
            }
        });
    }.bind(this));
});

<|endoftext|>


<commit_before>//By Rajeshwar Patlolla
//https://github.com/rajeshwarpatlolla

"use strict";
angular.module('ionic-datepicker', ['ionic', 'ionic-datepicker.templates'])

  .directive('ionicDatepicker', ['$ionicPopup', function ($ionicPopup) {
    return {
      restrict: 'AE',
      replace: true,
      scope: {
        value: '=value'
      },
      link: function (scope, element, attrs) {
        var now = new Date();
        var currentDate = angular.copy(scope.value) || now; // Date for the UI calendar display
        scope.selectedDate = currentDate; // Temporary selected date before the 'Set' or 'Today' is pressed

        scope.dayInitials = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];

        scope.calendarRows = new Array(6);
        scope.calendarCols = new Array(7);

        var refreshCalendar = function (currentDate) {

          var firstDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDate();
          var lastDay = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate();

          scope.dayList = [];

          for (var i = firstDay; i <= lastDay; i++) {
            var tempDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), i);
            scope.dayList.push({
              date: tempDate,
              day: tempDate.getDate()
            });
          }

          // Offset the first of the month
          firstDay = scope.dayList[0].date.getDay();
          for (var j = 0; j < firstDay; j++) {
            scope.dayList.unshift(undefined);
          }

          scope.currentMonth = currentDate.getMonth();
          scope.currentYear = currentDate.getFullYear();
        };

        // Go to previous month
        scope.prevMonth = function () {
          currentDate.setMonth(currentDate.getMonth() - 1);
          scope.currentMonth = currentDate.getMonth();
          scope.currentYear = currentDate.getFullYear();
          refreshCalendar(currentDate)
        };

        // Go to next month
        scope.nextMonth = function () {
          currentDate.setMonth(currentDate.getMonth() + 1);
          scope.currentMonth = currentDate.getMonth();
          scope.currentYear = currentDate.getFullYear();
          refreshCalendar(currentDate)
        };

        scope.setDate = function (date) {
          if (typeof date !== 'undefined') {
            scope.selectedDate = date.date;
          }
        };

        // Check if the day is valid
        scope.isValidDay = function(rowIndex, colIndex) {
          var day = scope.dayList[rowIndex * 7 + colIndex];
          return (typeof day !== 'undefined');
        };
        // Check if the day should be selected
        scope.isSelected = function(rowIndex, colIndex) {
          if (scope.isValidDay(rowIndex, colIndex)) {
            var day = scope.dayList[rowIndex * 7 + colIndex]
            return (day.date.toDateString() === scope.selectedDate.toDateString());
          }
          return false;
        };
        // Check if the day is today
        scope.isToday = function(rowIndex, colIndex) {
          if (scope.isValidDay(rowIndex, colIndex)) {
            return (scope.dayList[rowIndex * 7 + colIndex].date.toDateString() === new Date().toDateString());
          }
          return false;
        }

        element.on("click", function () {
          var now = new Date();
          if (!scope.value) {
            refreshCalendar(now);
          } else {
            refreshCalendar(scope.value);
          }

          $ionicPopup.show({
            templateUrl: 'date-picker-modal.html',
            title: 'Select Date',
            subTitle: '',
            scope: scope,
            buttons: [
              {text: 'Close'},
              {
                text: 'Today',
                onTap: function () {
                  var now = new Date();
                  scope.setDate({ date: now });
                  scope.value = now;
                }
              },
              {
                text: 'Set',
                type: 'button-positive',
                onTap: function () {
                  scope.value = scope.selectedDate;
                }
              }
            ]
          })
        })
      }
    }
  }]);
<commit_msg>Eliminate some 'var now's<commit_after>//By Rajeshwar Patlolla
//https://github.com/rajeshwarpatlolla

"use strict";
angular.module('ionic-datepicker', ['ionic', 'ionic-datepicker.templates'])

  .directive('ionicDatepicker', ['$ionicPopup', function ($ionicPopup) {
    return {
      restrict: 'AE',
      replace: true,
      scope: {
        value: '=value'
      },
      link: function (scope, element, attrs) {
        var currentDate = angular.copy(scope.value) || new Date(); // Date for the UI calendar display
        scope.selectedDate = currentDate; // Temporary selected date before the 'Set' or 'Today' is pressed

        scope.dayInitials = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];

        scope.calendarRows = new Array(6);
        scope.calendarCols = new Array(7);

        var refreshCalendar = function (currentDate) {

          var firstDay = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1).getDate();
          var lastDay = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 0).getDate();

          scope.dayList = [];

          for (var i = firstDay; i <= lastDay; i++) {
            var tempDate = new Date(currentDate.getFullYear(), currentDate.getMonth(), i);
            scope.dayList.push({
              date: tempDate,
              day: tempDate.getDate()
            });
          }

          // Offset the first of the month
          firstDay = scope.dayList[0].date.getDay();
          for (var j = 0; j < firstDay; j++) {
            scope.dayList.unshift(undefined);
          }

          scope.currentMonth = currentDate.getMonth();
          scope.currentYear = currentDate.getFullYear();
        };

        // Go to previous month
        scope.prevMonth = function () {
          currentDate.setMonth(currentDate.getMonth() - 1);
          scope.currentMonth = currentDate.getMonth();
          scope.currentYear = currentDate.getFullYear();
          refreshCalendar(currentDate)
        };

        // Go to next month
        scope.nextMonth = function () {
          currentDate.setMonth(currentDate.getMonth() + 1);
          scope.currentMonth = currentDate.getMonth();
          scope.currentYear = currentDate.getFullYear();
          refreshCalendar(currentDate)
        };

        scope.setDate = function (date) {
          if (typeof date !== 'undefined') {
            scope.selectedDate = date.date;
          }
        };

        // Check if the day is valid
        scope.isValidDay = function(rowIndex, colIndex) {
          var day = scope.dayList[rowIndex * 7 + colIndex];
          return (typeof day !== 'undefined');
        };
        // Check if the day should be selected
        scope.isSelected = function(rowIndex, colIndex) {
          if (scope.isValidDay(rowIndex, colIndex)) {
            var day = scope.dayList[rowIndex * 7 + colIndex]
            return (day.date.toDateString() === scope.selectedDate.toDateString());
          }
          return false;
        };
        // Check if the day is today
        scope.isToday = function(rowIndex, colIndex) {
          if (scope.isValidDay(rowIndex, colIndex)) {
            return (scope.dayList[rowIndex * 7 + colIndex].date.toDateString() === new Date().toDateString());
          }
          return false;
        }

        element.on("click", function () {
          refreshCalendar(currentDate);
          $ionicPopup.show({
            templateUrl: 'date-picker-modal.html',
            title: 'Select Date',
            subTitle: '',
            scope: scope,
            buttons: [
              {text: 'Close'},
              {
                text: 'Today',
                onTap: function () {
                  var now = new Date();
                  scope.setDate({ date: now });
                  scope.value = now;
                }
              },
              {
                text: 'Set',
                type: 'button-positive',
                onTap: function () {
                  scope.value = scope.selectedDate;
                }
              }
            ]
          })
        })
      }
    }
  }]);
<|endoftext|>


<commit_before>angular.module('PropLookupRE.controllers.Main', [])

.controller('MainController', function($scope){

        $scope.address = "315 S. Garfield St, Arlington, VA 22204"

});<commit_msg>add content template<commit_after>angular.module('PropLookupRE.controllers.Main', [])

.controller('MainController', function($scope){
		$scope.currentAddress = "1111 19th St NW, Washington, DC 20036";
        $scope.address = "315 S. Garfield St, Arlington, VA 22204"

});<|endoftext|>


<commit_before>app.controller("MessageController", ["$scope", "uibModal", "MessageService", function($scope, MessageService){
	//add as needed
	$scope.messages = [];
	$scope.alerts = [];

	//get messages frmo API
	//come back for the other gets
	//make docblocks better
	$scope.getMessages = function() {
		MessageService.all()
			.then(function(result){
				if(result.data.status === 200) {
					$scope.messages =result.data.data;
				} else {
					$scope.alerts[0] = {type: "danger", msg: result.data.message};
				}
			});
	};

	$scope.getMessagesById = function(messageid, validated) {
		if(validate === true){
			MessageServices.fetch(messageId)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else{
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	$scope.getMessagesByListingId = function(listingId, validated){
		if(validated === true){
			MessageService.fetch()(listingId)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else{
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	$scope.getMessageByOrgId = function(orgId, validated){
		if(validated === true){
			MessageService. fetch()(ordId)
				.then(function(result){
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else{
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	$scope.getMessageByMessageText = function(messageText, validated) {
		if(validated === true){
			MessageService. fetch()(messageText)
				.then(function(result){
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else {
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	// create new organazation
$scope.createMessage = function(message, validated) {
	if(validated === true) {
		MessageService.create(organization)
			.then(function(result) {
				if(result.data.status === 200) {
					$scope.alerts[0] = {type: "success", msg: result.data.message};
				} else {
					$scope.alerts[0] = {type: "danger", msg: result.data.message};
				}
			});
	}
};

//update the organization
	$scope.updateMessage = function(message, validate) {
		if(validate === true && $scope.isEditing === true) {
			MessageService.update(organization.messageId, message)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.alerts[0] = {type: "success", msg: result.data.message};
					}else {
						$scope.alerts[0] = {type: "danger", msg: result.data.message};
					}
				});
		}
	};

	//delete the message
	$scope.deleteMessage = function(messageId) {
		//create a modal to ask for confirmation
		var message = "do you really want to delete this message?";
		var modalHtml = '
' + message + '

<button class="btn btn-primary" ng-click="yes()">Yes</button><button class="btn-warning" ng-click"no()">No</button>
;
		var modalInstance = $uibModal.open({
			template: modalHtml,
			controller: ModalInstanceCtrl
		});

		//if yes is selceted, delet the message
		modalInstance.result.then(function() {
			MessageService.destroy(messageId)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.alerts[0] = {type:"success", msg: result.data.message};
					} else {
						$scope.alerts[0] = {type: "danger", msg: result.data.message};
					}
				})
		});
	};

}]);

<commit_msg>added delete instance controller (message-controller.js)---->https://app.asana.com/0/60990639151493/70724622878576<commit_after>app.controller("MessageController", ["$scope", "uibModal", "MessageService", function($scope, MessageService){
	//add as needed
	$scope.messages = [];
	$scope.alerts = [];

	//get messages frmo API
	//come back for the other gets
	//make docblocks better
	$scope.getMessages = function() {
		MessageService.all()
			.then(function(result){
				if(result.data.status === 200) {
					$scope.messages =result.data.data;
				} else {
					$scope.alerts[0] = {type: "danger", msg: result.data.message};
				}
			});
	};

	$scope.getMessagesById = function(messageid, validated) {
		if(validate === true){
			MessageServices.fetch(messageId)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else{
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	$scope.getMessagesByListingId = function(listingId, validated){
		if(validated === true){
			MessageService.fetch()(listingId)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else{
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	$scope.getMessageByOrgId = function(orgId, validated){
		if(validated === true){
			MessageService. fetch()(ordId)
				.then(function(result){
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else{
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	$scope.getMessageByMessageText = function(messageText, validated) {
		if(validated === true){
			MessageService. fetch()(messageText)
				.then(function(result){
					if(result.data.status === 200) {
						$scope.messages = result.data.data;
					} else {
						$scope.alerts[0] = {type: "danger", msg:result.data.message}
					}
				});
		}
	};

	// create new organazation
$scope.createMessage = function(message, validated) {
	if(validated === true) {
		MessageService.create(organization)
			.then(function(result) {
				if(result.data.status === 200) {
					$scope.alerts[0] = {type: "success", msg: result.data.message};
				} else {
					$scope.alerts[0] = {type: "danger", msg: result.data.message};
				}
			});
	}
};

//update the organization
	$scope.updateMessage = function(message, validate) {
		if(validate === true && $scope.isEditing === true) {
			MessageService.update(organization.messageId, message)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.alerts[0] = {type: "success", msg: result.data.message};
					}else {
						$scope.alerts[0] = {type: "danger", msg: result.data.message};
					}
				});
		}
	};

	//delete the message
	$scope.deleteMessage = function(messageId) {
		//create a modal to ask for confirmation
		var message = "do you really want to delete this message?";
		var modalHtml = '
' + message + '

<button class="btn btn-primary" ng-click="yes()">Yes</button><button class="btn-warning" ng-click"no()">No</button>
;
		var modalInstance = $uibModal.open({
			template: modalHtml,
			controller: ModalInstanceCtrl
		});

		//if yes is selceted, delet the message
		modalInstance.result.then(function() {
			MessageService.destroy(messageId)
				.then(function(result) {
					if(result.data.status === 200) {
						$scope.alerts[0] = {type:"success", msg: result.data.message};
					} else {
						$scope.alerts[0] = {type: "danger", msg: result.data.message};
					}
				})
		});
	};

}]);

//modal instance controller for deleting prompt
var modalInstanceCtrl = function($scope, $ubiModalInstance) {
	$scope.yes =function() {
		$ubiModalInstance.dismiss('cancel');
	};
	$scope.no = function() {
		$ubiModalInstance.dismiss('cancel');
	};
};

<|endoftext|>


<commit_before>import GraphicsHelper from 'helpers/GraphicsHelper';
import {analysisPanelText} from 'js/config';
import registry from 'dijit/registry';
import Request from 'utils/request';
import alt from 'js/alt';

class AnalysisActions {

  findWatershed (pointGeometry) {
    app.debug('AnalysisActions >>> findWatershed');
    Request.getWatershedByGeometry(pointGeometry).then(feature => {
      this.actions.analyzeFeature(feature.attributes.objectid);
      app.map.setExtent(feature.geometry.getExtent(), true);
      //- Add Highlight polygon
      GraphicsHelper.addActiveWatershed(feature);
    }, console.error);
  }

  analyzeFeature (featureId) {
    app.debug('AnalysisActions >>> analyzeFeature');
    this.dispatch(featureId);
  }

  clearAnalysis () {
    app.debug('AnalysisActions >>> clearAnalysis');
    this.dispatch();
    //- Clear Highlight Polygons
    GraphicsHelper.clearFeatures();
    registry.byId(analysisPanelText.searchWidgetId).clear();
  }

  setAnalysisType (tabId) {
    this.dispatch(tabId);
  }

  addPoint (geometry) {
    GraphicsHelper.addPointFromDraw(geometry);
  }

  /**
  * GraphicsHelper.addPointFromLatLng returns a point object
  * This enables the callee of this function to pass that point on to other methods
  * without having to explicitly create a point and use other methods
  */
  addPointFromLatLng (lat, lon) {
    return GraphicsHelper.addPointFromLatLng(lat, lon);
  }

}

export const analysisActions = alt.createActions(AnalysisActions);
<commit_msg>fixed bug in analysis actions<commit_after>import GraphicsHelper from 'helpers/GraphicsHelper';
import {analysisPanelText} from 'js/config';
import registry from 'dijit/registry';
import Request from 'utils/request';
import alt from 'js/alt';

class AnalysisActions {

  findWatershed (pointGeometry) {
    app.debug('AnalysisActions >>> findWatershed');
    Request.getWatershedByGeometry(pointGeometry).then(feature => {
      this.actions.analyzeFeature(feature.attributes.objectid);
      app.map.setExtent(feature.geometry.getExtent(), true);
      //- Add Highlight polygon
      GraphicsHelper.addActiveWatershed(feature);
    }, console.error);
  }

  analyzeFeature (featureId) {
    app.debug('AnalysisActions >>> analyzeFeature');
    this.dispatch(featureId);
  }

  clearAnalysis () {
    app.debug('AnalysisActions >>> clearAnalysis');
    this.dispatch();
    //- Clear Highlight Polygons
    GraphicsHelper.clearFeatures();
    registry.byId(analysisPanelText.searchWidgetId).clear();
  }

  setAnalysisType (tabId) {
    this.dispatch(tabId);
  }

  addPointFromDraw (geometry) {
    GraphicsHelper.addPoint(geometry);
  }

  /**
  * GraphicsHelper.addPointFromLatLng returns a point object
  * This enables the callee of this function to pass that point on to other methods
  * without having to explicitly create a point and use other methods
  */
  addPointFromLatLng (lat, lon) {
    return GraphicsHelper.addPointFromLatLng(lat, lon);
  }

}

export const analysisActions = alt.createActions(AnalysisActions);
<|endoftext|>


<commit_before>var views = exports;

views.index = function(req,res,matches){
	var file
	if(!matches || !matches[2] || (file = this.files[matches[2]])){

		res.writeHead(200,{'Content-Type': 'text/html; charset=utf-8'});
		res.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n \n \
\n \
\n \
<title>8080 - Dateien</title>\n \
<meta name="keywords" content="" />\n \
<meta name="description" content="" />\n \
<link rel="stylesheet" type="text/css" href="/style.css">
OTR-Mirror
\
\n \
\n \

\n \

 \n \
\n \

\n \
\n \

8080
\n \

 free and open otr-mirror system
\n \

\n \

\n \

\n \

\n \

\n \

Dateien
\n \
\n \

FAQ
\n \

Impressum
			\n \

\n \

\n \

\n \
\n \
\n \
\n \

\n \
	\n \

\n \
')
		if(file){
			res.end('\t
Deine Anfrage

'+ file.filename +'

');
		}
		else{

			for(var i in this.files)
				res.write('
\n \

[TODO:]Tatort vom 31.01.2011 um 22:45 (rbb) mpg
\n \

'+i+'\n \

\n \

                    Datei herunterladen ([TODO:]999 MB ~ 99 Minuten)
\n \

\n \

\n \
');
		}
res.end('\n \

\n \

\n \
\n \

\n \
\n \

\n \

 8080 is open software. You are free to use and edit it as you like. Source can be found at github.com
\n \

\n \
\n \
\n \
\n \
');
	}
	else{
		console.log('x: '+matches[2]);
		this.views.send404(req,res);
	}
}

views.linklist = function(req,res){
	res.writeHead(200,{'Content-Type':'text/plain; charset=utf-8'});
	for(fname in this.files)
		res.write('http://' + this.options.servername + '/index/'+fname+"\n");
	res.end();
}

views.send404 = function(req,res){
	res.writeHead(404, {'Content-Type': 'text/plain; charset=utf-8'});
	res.end('file not found. we cannot satisfy your request');
}
<commit_msg>removed
<commit_after>var views = exports;

views.index = function(req,res,matches){
	var file
	if(!matches || !matches[2] || (file = this.files[matches[2]])){

		res.writeHead(200,{'Content-Type': 'text/html; charset=utf-8'});
		res.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n \n \
\n \
\n \
<title>8080 - Dateien</title>\n \
<meta name="keywords" content="" />\n \
<meta name="description" content="" />\n \
<link rel="stylesheet" type="text/css" href="/style.css">\
\n \
\n \

\n \

 \n \
\n \

\n \
\n \

8080
\n \

 free and open otr-mirror system
\n \

\n \

\n \

\n \

\n \

\n \

Dateien
\n \
\n \

FAQ
\n \

Impressum
			\n \

\n \

\n \

\n \
\n \
\n \
\n \

\n \
	\n \

\n \
')
		if(file){
			res.end('\t
Deine Anfrage

'+ file.filename +'

');
		}
		else{

			for(var i in this.files)
				res.write('
\n \

[TODO:]Tatort vom 31.01.2011 um 22:45 (rbb) mpg
\n \

'+i+'\n \

\n \

                    Datei herunterladen ([TODO:]999 MB ~ 99 Minuten)
\n \

\n \

\n \
');
		}
res.end('\n \

\n \

\n \
\n \

\n \
\n \

\n \

 8080 is open software. You are free to use and edit it as you like. Source can be found at github.com
\n \

\n \
\n \
\n \
\n \
');
	}
	else{
		console.log('x: '+matches[2]);
		this.views.send404(req,res);
	}
}

views.linklist = function(req,res){
	res.writeHead(200,{'Content-Type':'text/plain; charset=utf-8'});
	for(fname in this.files)
		res.write('http://' + this.options.servername + '/index/'+fname+"\n");
	res.end();
}

views.send404 = function(req,res){
	res.writeHead(404, {'Content-Type': 'text/plain; charset=utf-8'});
	res.end('file not found. we cannot satisfy your request');
}
<|endoftext|>


<commit_before>/*jslint nomen: true */
/*globals define: true */

define(function(require, exports, module) {
  'use strict';

  // Libs
  var _ = require('lib/lodash');
  var util = require('./project-utils');

  // https://app.localdata.com/api/surveys/8a340df0-87af-11e2-9485-c3fff44e7c8e/forms
  var gary = {
    name: 'Gary Parcel Survey',
    description: '',
    baselayer: '//a.tiles.mapbox.com/v3/matth.kmf6l3h1/{z}/{x}/{y}.png',
    location: 'Gary, IN',
    center: [-87.346427, 41.59337],
    zoom: 13,
    scrollWheelZoom: false,
    surveys: [{
      layerName: 'Parcels surveyed',
      layerId: '2012edd0-b17c-11e4-b2e2-af76412575df',
      color: '#45403e',
      options: {
        anonymous: true,
        exploreButton: true,
        hideCollectorNames: true,
        explorationControlsItem: true
      },
      countPath: 'survey.responseCount',
      query: {},
      select: {},
      filters: {
        question: 'Property condition'
      },
      styles: util.simpleStyles({color: '#45403e'}),
      exploration: [
        util.makeBasicExploration({
          name: 'Is there a structure?',
          question: 'structure',
          values: [
            'yes',
            'no'
          ],
          valueNames: [
            'Yes',
            'No structure'
          ],
          colors: ['#0571b0', '#05b04c']
        }),
        util.makeBasicExploration({
          name: 'Occupancy',
          question: 'vacant-abandoned',
          values: [
            'occupied-structure',
            'vacant-abandoned-structure'
          ],
          valueNames: [
            'Occupied',
            'Vacant'
          ],
          colors: ['#0571b0', '#f46d31']
        }),
        util.makeBasicExploration({
          name: 'Property condition',
          question: 'structure-grade',
          values: [
            'excellent',
            'good',
            'fair',
            'poor',
            'dangerous'
          ],
          valueNames: [
            'Excellent',
            "Good",
            'Fair',
            'Poor',
            'Dangerous'
          ],
          colors: ['#0571b0', '#92c5de', '#d3d3d3', '#f46d31', '#ca0020']
          // purples:
          // colors: ['#05b04c', '#a5e76b', '#d3d3d3', '#d791da', '#85048a']
        }),
        util.makeBasicExploration({
          name: 'Fire damage on blighted buildings',
          question: 'structural-damage',
          values: [
            'none',
            'some-damage',
            'significant-damage',
            'no response'
          ],
          valueNames: [
            'No damage',
            "Some fire damage",
            'Significant fire damage',
            'Not applicable'
          ],
          colors: ['#0571b0', '#f46d31', '#ca0020', '#d3d3d3'],
          showNoResponse: true
        }),
        // util.makeBasicExploration({
        //   name: 'Enclosed buildings',
        //   question: 'enclosed-secure',
        //   values: [
        //     'yes',
        //     'no'
        //   ],
        //   valueNames: [
        //     'Building Enclosed/Secure',
        //     "Building Not Enclosed/Secure"
        //   ],
        //   colors: ['#0571b0', '#ca0020']
        // }),
        // util.makeBasicExploration({
        //   name: 'Parking lot',
        //   question: 'parking-lot',
        //   values: [
        //     'yes',
        //     'no'
        //   ],
        //   valueNames: [
        //     'Yes',
        //     'No'
        //   ],
        //   colors: ['#0571b0', '#535353']
        // }),

        util.makeBasicExploration({
          name: 'Residential use structures',
          question: 'residential',
          values: [
            'yes'
          ],
          valueNames: [
            'Yes'
          ],
          colors: ['#0571b0']
        }),

        util.makeBasicExploration({
          name: 'Commercial use structures',
          question: 'commercial',
          values: [
            'yes'
          ],
          valueNames: [
            "Yes"
          ],
          colors: ['#0571b0']
        }),

        util.makeBasicExploration({
          name: 'Public use structures',
          question: 'public-gov',
          values: [
            'yes'
          ],
          valueNames: [
            'Yes'
          ],
          colors: ['#0571b0']
        }),

        // Public building info
        util.makeBasicExploration({
          name: 'Public owner',
          question: 'deeded-own',
          values: [
            'City of Gary',
            'GUEA',
            'Department of Redevelopment',
            'Public Works',
            'Parks Department'
          ],
          valueNames: [
            'City of Gary',
            'GUEA',
            'Department of Redevelopment',
            'Public Works',
            'Parks Department'
          ],
          colors: ['#f46d31', '#d3d3d3', '#92c5de', '#ca0020', '#0571b0']
        }),
        util.makeTextExploration({
          name: 'Assessed value',
          question: 'assessed'
        }),
        util.makeTextExploration({
          name: 'Lot square feet',
          question: 'lot_sf'
        }),
        util.makeTextExploration({
          name: 'Building square feet',
          question: 'bldg_sf'
        })
      ]
    }]
  };

  return gary;

});
<commit_msg>Add Gary public works & community development<commit_after>/*jslint nomen: true */
/*globals define: true */

define(function(require, exports, module) {
  'use strict';

  // Libs
  var _ = require('lib/lodash');
  var util = require('./project-utils');

  // https://app.localdata.com/api/surveys/8a340df0-87af-11e2-9485-c3fff44e7c8e/forms
  var gary = {
    name: 'Gary Parcel Survey',
    description: '',
    baselayer: '//a.tiles.mapbox.com/v3/matth.kmf6l3h1/{z}/{x}/{y}.png',
    location: 'Gary, IN',
    center: [-87.346427, 41.59337],
    zoom: 13,
    scrollWheelZoom: false,
    surveys: [{
      layerName: 'Parcels surveyed',
      layerId: '2012edd0-b17c-11e4-b2e2-af76412575df',
      color: '#45403e',
      options: {
        anonymous: true,
        exploreButton: true,
        hideCollectorNames: true,
        explorationControlsItem: true
      },
      countPath: 'survey.responseCount',
      query: {},
      select: {},
      filters: {
        question: 'Property condition'
      },
      styles: util.simpleStyles({color: '#45403e'}),
      exploration: [
        util.makeBasicExploration({
          name: 'Is there a structure?',
          question: 'structure',
          values: [
            'yes',
            'no'
          ],
          valueNames: [
            'Yes',
            'No structure'
          ],
          colors: ['#0571b0', '#05b04c']
        }),
        util.makeBasicExploration({
          name: 'Occupancy',
          question: 'vacant-abandoned',
          values: [
            'occupied-structure',
            'vacant-abandoned-structure'
          ],
          valueNames: [
            'Occupied',
            'Vacant'
          ],
          colors: ['#0571b0', '#f46d31']
        }),
        util.makeBasicExploration({
          name: 'Property condition',
          question: 'structure-grade',
          values: [
            'excellent',
            'good',
            'fair',
            'poor',
            'dangerous'
          ],
          valueNames: [
            'Excellent',
            "Good",
            'Fair',
            'Poor',
            'Dangerous'
          ],
          colors: ['#0571b0', '#92c5de', '#d3d3d3', '#f46d31', '#ca0020']
          // purples:
          // colors: ['#05b04c', '#a5e76b', '#d3d3d3', '#d791da', '#85048a']
        }),
        util.makeBasicExploration({
          name: 'Fire damage on blighted buildings',
          question: 'structural-damage',
          values: [
            'none',
            'some-damage',
            'significant-damage',
            'no response'
          ],
          valueNames: [
            'No damage',
            "Some fire damage",
            'Significant fire damage',
            'Not applicable'
          ],
          colors: ['#0571b0', '#f46d31', '#ca0020', '#d3d3d3'],
          showNoResponse: true
        }),
        // util.makeBasicExploration({
        //   name: 'Enclosed buildings',
        //   question: 'enclosed-secure',
        //   values: [
        //     'yes',
        //     'no'
        //   ],
        //   valueNames: [
        //     'Building Enclosed/Secure',
        //     "Building Not Enclosed/Secure"
        //   ],
        //   colors: ['#0571b0', '#ca0020']
        // }),
        // util.makeBasicExploration({
        //   name: 'Parking lot',
        //   question: 'parking-lot',
        //   values: [
        //     'yes',
        //     'no'
        //   ],
        //   valueNames: [
        //     'Yes',
        //     'No'
        //   ],
        //   colors: ['#0571b0', '#535353']
        // }),

        util.makeBasicExploration({
          name: 'Residential use structures',
          question: 'residential',
          values: [
            'yes'
          ],
          valueNames: [
            'Yes'
          ],
          colors: ['#0571b0']
        }),

        util.makeBasicExploration({
          name: 'Commercial use structures',
          question: 'commercial',
          values: [
            'yes'
          ],
          valueNames: [
            "Yes"
          ],
          colors: ['#0571b0']
        }),

        util.makeBasicExploration({
          name: 'Public use structures',
          question: 'public-gov',
          values: [
            'yes'
          ],
          valueNames: [
            'Yes'
          ],
          colors: ['#0571b0']
        }),

        // Public building info
        util.makeBasicExploration({
          name: 'Public owner',
          question: 'deeded-own',
          values: [
            'City of Gary',
            'GUEA',
            'Department of Redevelopment',
            'Public Works Department',
            'Community Development Department',
            'Parks Department'
          ],
          valueNames: [
            'City of Gary',
            'GUEA',
            'Department of Redevelopment',
            'Public Works',
            'Parks Department'
          ],
          colors: ['#f46d31', '#d3d3d3', '#92c5de', '#ca0020', '#0571b0']
        }),
        util.makeTextExploration({
          name: 'Assessed value',
          question: 'assessed'
        }),
        util.makeTextExploration({
          name: 'Lot square feet',
          question: 'lot_sf'
        }),
        util.makeTextExploration({
          name: 'Building square feet',
          question: 'bldg_sf'
        })
      ]
    }]
  };

  return gary;

});
<|endoftext|>


<commit_before>import autosize from "autosize";
import ClipboardJS from "clipboard";
import {add} from "date-fns";
import $ from "jquery";

import copy_invite_link from "../templates/copy_invite_link.hbs";
import render_invitation_failed_error from "../templates/invitation_failed_error.hbs";
import render_invite_subscription from "../templates/invite_subscription.hbs";
import render_invite_user from "../templates/invite_user.hbs";
import render_settings_dev_env_email_access from "../templates/settings/dev_env_email_access.hbs";

import * as browser_history from "./browser_history";
import * as channel from "./channel";
import * as common from "./common";
import {$t, $t_html} from "./i18n";
import * as overlays from "./overlays";
import {page_params} from "./page_params";
import * as settings_config from "./settings_config";
import * as stream_data from "./stream_data";
import * as ui from "./ui";
import * as ui_report from "./ui_report";
import {user_settings} from "./user_settings";
import * as util from "./util";

let custom_expiration_time_input = 10;
let custom_expiration_time_unit = "days";

function reset_error_messages() {
    $("#invite_status").hide().text("").removeClass(common.status_classes);
    $("#multiuse_invite_status").hide().text("").removeClass(common.status_classes);

    $("#invitee_emails").closest(".control-group").removeClass("warning error");

    if (page_params.development_environment) {
        $("#dev_env_msg").hide().text("").removeClass(common.status_classes);
    }
}

function get_common_invitation_data() {
    const invite_as = Number.parseInt($("#invite_as").val(), 10);
    let expires_in = $("#expires_in").val();
    // See settings_config.expires_in_values for why we do this conversion.
    if (expires_in === "null") {
        expires_in = JSON.stringify(null);
    } else if (expires_in === "custom") {
        expires_in = Number.parseFloat(get_expiration_time_in_minutes());
    } else {
        expires_in = Number.parseFloat($("#expires_in").val());
    }

    const stream_ids = [];
    $("#invite-stream-checkboxes input:checked").each(function () {
        const stream_id = Number.parseInt($(this).val(), 10);
        stream_ids.push(stream_id);
    });
    const data = {
        csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').attr("value"),
        invite_as,
        stream_ids: JSON.stringify(stream_ids),
        invite_expires_in_minutes: expires_in,
    };
    return data;
}

function beforeSend() {
    reset_error_messages();
    // TODO: You could alternatively parse the textarea here, and return errors to
    // the user if they don't match certain constraints (i.e. not real email addresses,
    // aren't in the right domain, etc.)
    //
    // OR, you could just let the server do it. Probably my temptation.
    const loading_text = $("#submit-invitation").data("loading-text");
    $("#submit-invitation").text(loading_text);
    $("#submit-invitation").prop("disabled", true);
    return true;
}

function submit_invitation_form() {
    const $invite_status = $("#invite_status");
    const $invitee_emails = $("#invitee_emails");
    const $invitee_emails_group = $invitee_emails.closest(".control-group");
    const data = get_common_invitation_data();
    data.invitee_emails = $("#invitee_emails").val();

    channel.post({
        url: "/json/invites",
        data,
        beforeSend,
        success() {
            ui_report.success(
                $t_html({defaultMessage: "User(s) invited successfully."}),
                $invite_status,
            );
            $invitee_emails_group.removeClass("warning");
            $invitee_emails.val("");

            if (page_params.development_environment) {
                const rendered_email_msg = render_settings_dev_env_email_access();
                $("#dev_env_msg").html(rendered_email_msg).addClass("alert-info").show();
            }

            if ($("#expires_in").val() === "custom") {
                // Hide the custom inputs if the custom input is set
                // to one of the dropdown's standard options.
                const time_in_minutes = get_expiration_time_in_minutes();
                for (const option of Object.values(settings_config.expires_in_values)) {
                    if (option.value === time_in_minutes) {
                        $("#custom-invite-expiration-time").hide();
                        $("#expires_in").val(time_in_minutes);
                        return;
                    }
                }
            }
        },
        error(xhr) {
            const arr = JSON.parse(xhr.responseText);
            if (arr.errors === undefined) {
                // There was a fatal error, no partial processing occurred.
                ui_report.error("", xhr, $invite_status);
            } else {
                // Some users were not invited.
                const invitee_emails_errored = [];
                const error_list = [];
                let is_invitee_deactivated = false;
                for (const value of arr.errors) {
                    const [email, error_message, deactivated] = value;
                    error_list.push(`${email}: ${error_message}`);
                    if (deactivated) {
                        is_invitee_deactivated = true;
                    }
                    invitee_emails_errored.push(email);
                }

                const error_response = render_invitation_failed_error({
                    error_message: arr.msg,
                    error_list,
                    is_admin: page_params.is_admin,
                    is_invitee_deactivated,
                    license_limit_reached: arr.license_limit_reached,
                    has_billing_access: page_params.is_owner || page_params.is_billing_admin,
                    daily_limit_reached: arr.daily_limit_reached,
                });
                ui_report.message(error_response, $invite_status, "alert-warning");
                $invitee_emails_group.addClass("warning");

                if (arr.sent_invitations) {
                    $invitee_emails.val(invitee_emails_errored.join("\n"));
                }
            }
        },
        complete() {
            $("#submit-invitation").text($t({defaultMessage: "Invite"}));
            $("#submit-invitation").prop("disabled", false);
            $("#invitee_emails").trigger("focus");
            ui.get_scroll_element($("#invite_user_form .modal-body"))[0].scrollTop = 0;
        },
    });
}

function generate_multiuse_invite() {
    const $invite_status = $("#multiuse_invite_status");
    const data = get_common_invitation_data();
    channel.post({
        url: "/json/invites/multiuse",
        data,
        beforeSend,
        success(data) {
            const copy_link_html = copy_invite_link(data);
            ui_report.success(copy_link_html, $invite_status);
            new ClipboardJS("#copy_generated_invite_link");
        },
        error(xhr) {
            ui_report.error("", xhr, $invite_status);
        },
        complete() {
            $("#submit-invitation").text($t({defaultMessage: "Generate invite link"}));
            $("#submit-invitation").prop("disabled", false);
        },
    });
}

export function get_invite_streams() {
    const streams = stream_data.get_invite_stream_data();
    streams.sort((a, b) => util.strcmp(a.name, b.name));
    return streams;
}

function update_subscription_checkboxes() {
    const data = {
        streams: get_invite_streams(),
        notifications_stream: stream_data.get_notifications_stream(),
    };
    const html = render_invite_subscription(data);
    $("#streams_to_add").html(html);
}

function prepare_form_to_be_shown() {
    update_subscription_checkboxes();
    reset_error_messages();
}

export function launch() {
    $("#submit-invitation").button();
    prepare_form_to_be_shown();

    overlays.open_overlay({
        name: "invite",
        $overlay: $("#invite-user"),
        on_close() {
            browser_history.exit_overlay();
        },
    });

    autosize($("#invitee_emails").trigger("focus"));

    // Ctrl + Enter key to submit form
    $("#invite-user").on("keydown", (e) => {
        if (e.key === "Enter" && e.ctrlKey) {
            submit_invitation_form();
        }
    });
}

function valid_to(expires_in) {
    const time_valid = Number.parseFloat(expires_in);
    if (!time_valid) {
        return $t({defaultMessage: "Never expires"});
    }
    const valid_to = add(new Date(), {minutes: time_valid});
    const options = {
        year: "numeric",
        month: "numeric",
        day: "numeric",
        hour: "2-digit",
        minute: "2-digit",
        hour12: !user_settings.twenty_four_hour_time,
    };
    return $t(
        {defaultMessage: "Expires on {date}"},
        {date: valid_to.toLocaleTimeString([], options)},
    );
}

function get_expiration_time_in_minutes() {
    switch (custom_expiration_time_unit) {
        case "hours":
            return custom_expiration_time_input * 60;
        case "days":
            return custom_expiration_time_input * 24 * 60;
        case "weeks":
            return custom_expiration_time_input * 7 * 24 * 60;
        default:
            return custom_expiration_time_input;
    }
}

function set_expires_on_text() {
    if ($("#expires_in").val() === "custom") {
        $("#expires_on").hide();
        $("#custom_expires_on").text(valid_to(get_expiration_time_in_minutes()));
    } else {
        $("#expires_on").show();
        $("#expires_on").text(valid_to($("#expires_in").val()));
    }
}

function set_custom_time_inputs_visibility() {
    if ($("#expires_in").val() === "custom") {
        $("#custom-expiration-time-input").val(custom_expiration_time_input);
        $("#custom-expiration-time-unit").val(custom_expiration_time_unit);
        $("#custom-invite-expiration-time").show();
    } else {
        $("#custom-invite-expiration-time").hide();
    }
}

export function initialize() {
    const time_unit_choices = ["minutes", "hours", "days", "weeks"];
    const rendered = render_invite_user({
        is_admin: page_params.is_admin,
        is_owner: page_params.is_owner,
        development_environment: page_params.development_environment,
        invite_as_options: settings_config.user_role_values,
        expires_in_options: settings_config.expires_in_values,
        time_choices: time_unit_choices,
    });

    $(".app").append(rendered);
    set_custom_time_inputs_visibility();
    set_expires_on_text();

    $(document).on("click", "#invite_check_all_button", () => {
        $("#streams_to_add :checkbox").prop("checked", true);
    });

    $(document).on("click", "#invite_uncheck_all_button", () => {
        $("#streams_to_add :checkbox").prop("checked", false);
    });

    $("#submit-invitation").on("click", () => {
        const is_generate_invite_link = $("#generate_multiuse_invite_radio").prop("checked");
        if (is_generate_invite_link) {
            generate_multiuse_invite();
        } else {
            submit_invitation_form();
        }
    });

    $("#generate_multiuse_invite_button").on("click", () => {
        $("#generate_multiuse_invite_radio").prop("checked", true);
        $("#multiuse_radio_section").show();
        $("#invite-method-choice").hide();
        $("#invitee_emails").prop("disabled", true);
        $("#submit-invitation").text($t({defaultMessage: "Generate invite link"}));
        $("#submit-invitation").data("loading-text", $t({defaultMessage: "Generating link..."}));
        reset_error_messages();
    });

    $("#invite-user").on("change", "#generate_multiuse_invite_radio", () => {
        $("#invitee_emails").prop("disabled", false);
        $("#submit-invitation").text($t({defaultMessage: "Invite"}));
        $("#submit-invitation").data("loading-text", $t({defaultMessage: "Inviting..."}));
        $("#multiuse_radio_section").hide();
        $("#invite-method-choice").show();
        reset_error_messages();
    });

    $("#expires_on").text(valid_to($("#expires_in").val()));
    $("#expires_in").on("change", () => {
        set_custom_time_inputs_visibility();
        set_expires_on_text();
    });

    $(".custom-expiration-time").on("change", () => {
        custom_expiration_time_input = $("#custom-expiration-time-input").val();
        custom_expiration_time_unit = $("#custom-expiration-time-unit").val();
        $("#custom_expires_on").text(valid_to(get_expiration_time_in_minutes()));
    });

    $("#custom-expiration-time-input").on("keydown", (e) => {
        if (e.key === "Enter") {
            e.preventDefault();
            return;
        }
    });
}
<commit_msg>invites: Remove stale use of `control-group` class.<commit_after>import autosize from "autosize";
import ClipboardJS from "clipboard";
import {add} from "date-fns";
import $ from "jquery";

import copy_invite_link from "../templates/copy_invite_link.hbs";
import render_invitation_failed_error from "../templates/invitation_failed_error.hbs";
import render_invite_subscription from "../templates/invite_subscription.hbs";
import render_invite_user from "../templates/invite_user.hbs";
import render_settings_dev_env_email_access from "../templates/settings/dev_env_email_access.hbs";

import * as browser_history from "./browser_history";
import * as channel from "./channel";
import * as common from "./common";
import {$t, $t_html} from "./i18n";
import * as overlays from "./overlays";
import {page_params} from "./page_params";
import * as settings_config from "./settings_config";
import * as stream_data from "./stream_data";
import * as ui from "./ui";
import * as ui_report from "./ui_report";
import {user_settings} from "./user_settings";
import * as util from "./util";

let custom_expiration_time_input = 10;
let custom_expiration_time_unit = "days";

function reset_error_messages() {
    $("#invite_status").hide().text("").removeClass(common.status_classes);
    $("#multiuse_invite_status").hide().text("").removeClass(common.status_classes);

    if (page_params.development_environment) {
        $("#dev_env_msg").hide().text("").removeClass(common.status_classes);
    }
}

function get_common_invitation_data() {
    const invite_as = Number.parseInt($("#invite_as").val(), 10);
    let expires_in = $("#expires_in").val();
    // See settings_config.expires_in_values for why we do this conversion.
    if (expires_in === "null") {
        expires_in = JSON.stringify(null);
    } else if (expires_in === "custom") {
        expires_in = Number.parseFloat(get_expiration_time_in_minutes());
    } else {
        expires_in = Number.parseFloat($("#expires_in").val());
    }

    const stream_ids = [];
    $("#invite-stream-checkboxes input:checked").each(function () {
        const stream_id = Number.parseInt($(this).val(), 10);
        stream_ids.push(stream_id);
    });
    const data = {
        csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').attr("value"),
        invite_as,
        stream_ids: JSON.stringify(stream_ids),
        invite_expires_in_minutes: expires_in,
    };
    return data;
}

function beforeSend() {
    reset_error_messages();
    // TODO: You could alternatively parse the textarea here, and return errors to
    // the user if they don't match certain constraints (i.e. not real email addresses,
    // aren't in the right domain, etc.)
    //
    // OR, you could just let the server do it. Probably my temptation.
    const loading_text = $("#submit-invitation").data("loading-text");
    $("#submit-invitation").text(loading_text);
    $("#submit-invitation").prop("disabled", true);
    return true;
}

function submit_invitation_form() {
    const $invite_status = $("#invite_status");
    const $invitee_emails = $("#invitee_emails");
    const data = get_common_invitation_data();
    data.invitee_emails = $("#invitee_emails").val();

    channel.post({
        url: "/json/invites",
        data,
        beforeSend,
        success() {
            ui_report.success(
                $t_html({defaultMessage: "User(s) invited successfully."}),
                $invite_status,
            );
            $invitee_emails.val("");

            if (page_params.development_environment) {
                const rendered_email_msg = render_settings_dev_env_email_access();
                $("#dev_env_msg").html(rendered_email_msg).addClass("alert-info").show();
            }

            if ($("#expires_in").val() === "custom") {
                // Hide the custom inputs if the custom input is set
                // to one of the dropdown's standard options.
                const time_in_minutes = get_expiration_time_in_minutes();
                for (const option of Object.values(settings_config.expires_in_values)) {
                    if (option.value === time_in_minutes) {
                        $("#custom-invite-expiration-time").hide();
                        $("#expires_in").val(time_in_minutes);
                        return;
                    }
                }
            }
        },
        error(xhr) {
            const arr = JSON.parse(xhr.responseText);
            if (arr.errors === undefined) {
                // There was a fatal error, no partial processing occurred.
                ui_report.error("", xhr, $invite_status);
            } else {
                // Some users were not invited.
                const invitee_emails_errored = [];
                const error_list = [];
                let is_invitee_deactivated = false;
                for (const value of arr.errors) {
                    const [email, error_message, deactivated] = value;
                    error_list.push(`${email}: ${error_message}`);
                    if (deactivated) {
                        is_invitee_deactivated = true;
                    }
                    invitee_emails_errored.push(email);
                }

                const error_response = render_invitation_failed_error({
                    error_message: arr.msg,
                    error_list,
                    is_admin: page_params.is_admin,
                    is_invitee_deactivated,
                    license_limit_reached: arr.license_limit_reached,
                    has_billing_access: page_params.is_owner || page_params.is_billing_admin,
                    daily_limit_reached: arr.daily_limit_reached,
                });
                ui_report.message(error_response, $invite_status, "alert-warning");

                if (arr.sent_invitations) {
                    $invitee_emails.val(invitee_emails_errored.join("\n"));
                }
            }
        },
        complete() {
            $("#submit-invitation").text($t({defaultMessage: "Invite"}));
            $("#submit-invitation").prop("disabled", false);
            $("#invitee_emails").trigger("focus");
            ui.get_scroll_element($("#invite_user_form .modal-body"))[0].scrollTop = 0;
        },
    });
}

function generate_multiuse_invite() {
    const $invite_status = $("#multiuse_invite_status");
    const data = get_common_invitation_data();
    channel.post({
        url: "/json/invites/multiuse",
        data,
        beforeSend,
        success(data) {
            const copy_link_html = copy_invite_link(data);
            ui_report.success(copy_link_html, $invite_status);
            new ClipboardJS("#copy_generated_invite_link");
        },
        error(xhr) {
            ui_report.error("", xhr, $invite_status);
        },
        complete() {
            $("#submit-invitation").text($t({defaultMessage: "Generate invite link"}));
            $("#submit-invitation").prop("disabled", false);
        },
    });
}

export function get_invite_streams() {
    const streams = stream_data.get_invite_stream_data();
    streams.sort((a, b) => util.strcmp(a.name, b.name));
    return streams;
}

function update_subscription_checkboxes() {
    const data = {
        streams: get_invite_streams(),
        notifications_stream: stream_data.get_notifications_stream(),
    };
    const html = render_invite_subscription(data);
    $("#streams_to_add").html(html);
}

function prepare_form_to_be_shown() {
    update_subscription_checkboxes();
    reset_error_messages();
}

export function launch() {
    $("#submit-invitation").button();
    prepare_form_to_be_shown();

    overlays.open_overlay({
        name: "invite",
        $overlay: $("#invite-user"),
        on_close() {
            browser_history.exit_overlay();
        },
    });

    autosize($("#invitee_emails").trigger("focus"));

    // Ctrl + Enter key to submit form
    $("#invite-user").on("keydown", (e) => {
        if (e.key === "Enter" && e.ctrlKey) {
            submit_invitation_form();
        }
    });
}

function valid_to(expires_in) {
    const time_valid = Number.parseFloat(expires_in);
    if (!time_valid) {
        return $t({defaultMessage: "Never expires"});
    }
    const valid_to = add(new Date(), {minutes: time_valid});
    const options = {
        year: "numeric",
        month: "numeric",
        day: "numeric",
        hour: "2-digit",
        minute: "2-digit",
        hour12: !user_settings.twenty_four_hour_time,
    };
    return $t(
        {defaultMessage: "Expires on {date}"},
        {date: valid_to.toLocaleTimeString([], options)},
    );
}

function get_expiration_time_in_minutes() {
    switch (custom_expiration_time_unit) {
        case "hours":
            return custom_expiration_time_input * 60;
        case "days":
            return custom_expiration_time_input * 24 * 60;
        case "weeks":
            return custom_expiration_time_input * 7 * 24 * 60;
        default:
            return custom_expiration_time_input;
    }
}

function set_expires_on_text() {
    if ($("#expires_in").val() === "custom") {
        $("#expires_on").hide();
        $("#custom_expires_on").text(valid_to(get_expiration_time_in_minutes()));
    } else {
        $("#expires_on").show();
        $("#expires_on").text(valid_to($("#expires_in").val()));
    }
}

function set_custom_time_inputs_visibility() {
    if ($("#expires_in").val() === "custom") {
        $("#custom-expiration-time-input").val(custom_expiration_time_input);
        $("#custom-expiration-time-unit").val(custom_expiration_time_unit);
        $("#custom-invite-expiration-time").show();
    } else {
        $("#custom-invite-expiration-time").hide();
    }
}

export function initialize() {
    const time_unit_choices = ["minutes", "hours", "days", "weeks"];
    const rendered = render_invite_user({
        is_admin: page_params.is_admin,
        is_owner: page_params.is_owner,
        development_environment: page_params.development_environment,
        invite_as_options: settings_config.user_role_values,
        expires_in_options: settings_config.expires_in_values,
        time_choices: time_unit_choices,
    });

    $(".app").append(rendered);
    set_custom_time_inputs_visibility();
    set_expires_on_text();

    $(document).on("click", "#invite_check_all_button", () => {
        $("#streams_to_add :checkbox").prop("checked", true);
    });

    $(document).on("click", "#invite_uncheck_all_button", () => {
        $("#streams_to_add :checkbox").prop("checked", false);
    });

    $("#submit-invitation").on("click", () => {
        const is_generate_invite_link = $("#generate_multiuse_invite_radio").prop("checked");
        if (is_generate_invite_link) {
            generate_multiuse_invite();
        } else {
            submit_invitation_form();
        }
    });

    $("#generate_multiuse_invite_button").on("click", () => {
        $("#generate_multiuse_invite_radio").prop("checked", true);
        $("#multiuse_radio_section").show();
        $("#invite-method-choice").hide();
        $("#invitee_emails").prop("disabled", true);
        $("#submit-invitation").text($t({defaultMessage: "Generate invite link"}));
        $("#submit-invitation").data("loading-text", $t({defaultMessage: "Generating link..."}));
        reset_error_messages();
    });

    $("#invite-user").on("change", "#generate_multiuse_invite_radio", () => {
        $("#invitee_emails").prop("disabled", false);
        $("#submit-invitation").text($t({defaultMessage: "Invite"}));
        $("#submit-invitation").data("loading-text", $t({defaultMessage: "Inviting..."}));
        $("#multiuse_radio_section").hide();
        $("#invite-method-choice").show();
        reset_error_messages();
    });

    $("#expires_on").text(valid_to($("#expires_in").val()));
    $("#expires_in").on("change", () => {
        set_custom_time_inputs_visibility();
        set_expires_on_text();
    });

    $(".custom-expiration-time").on("change", () => {
        custom_expiration_time_input = $("#custom-expiration-time-input").val();
        custom_expiration_time_unit = $("#custom-expiration-time-unit").val();
        $("#custom_expires_on").text(valid_to(get_expiration_time_in_minutes()));
    });

    $("#custom-expiration-time-input").on("keydown", (e) => {
        if (e.key === "Enter") {
            e.preventDefault();
            return;
        }
    });
}
<|endoftext|>


<commit_before>
var primitives = require('./primitives');
var Symbol = primitives.Symbol, HashSymbol = primitives.HashSymbol;

function Reader (stream) {
    this.stream = stream;
}
exports.Reader = Reader;

Reader.prototype.read = function () {
    this.stream.skipWhitespace();

    if (!this.stream.eof()) {
	switch (this.stream.peekChar()) {
	case ';':
	    this.stream.skipLine();
	    return this.read();
	case '"':
	    return this.readString();
	case '(':
	    return this.readList();
	default:
	    return this.readAtom();
	}
    }
}

var hexNumberExpression = /0x[0-9a-fA-F]+/;
var octalNumberExpression = /0[0-7]+/;
var decimalNumberExpression = /\d*\.?\d*(?:[eE]-?\d*(?:\d\.?|\.?\d)\d*)?/;

Reader.prototype.readAtom = function () {
    var c = this.stream.peekChar();
    var rest = this.stream.rest()
    if ([hexNumberExpression,
	 octalNumberExpression,
	 decimalNumberExpression]
	.some(function (expression) {
	    var match = expression.exec(rest);
	    return match && match[0] != '';
	}))
    {
	return this.readNumber();
    } else
	return this.readSymbol();
}

Reader.prototype.readList = function () {
    var result = new Array();
    this.stream.readChar();
    this.stream.skipWhitespace();

    while (this.stream.peekChar() != ')') {
	if (this.stream.eof())
	    throw new Error('Unbalanced parens');
	var next = this.read();
	result.push(next);
	this.stream.skipWhitespace();
    }

    this.stream.readChar();
    return result;
}

Reader.prototype.readSymbol = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    var name = match[0];
    this.stream.index += name.length;
    // TODO: keywords
    if (name[0] == '#' && HashSymbol.names.indexOf(name.substring(1)) >= 0)
	return HashSymbol[name.substring(1)];
    else
	return new Symbol(match[0]);
}

// TODO: escapes in strings: \t, \r, \n

Reader.prototype.readString = function () {
    this.stream.readChar();
    var c, result = "";
    while ((c = this.stream.readChar()) != '"') {
	if (c == '\\')
	    result += this.stream.readChar();
	else
	    result += c;
    }
    return result;
}

Reader.prototype.readNumber = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    this.stream.index += match[0].length;
    return new Number(match[0]);
}<commit_msg>fix reading of comments<commit_after>
var primitives = require('./primitives');
var Symbol = primitives.Symbol, HashSymbol = primitives.HashSymbol;

function Reader (stream) {
    this.stream = stream;
}
exports.Reader = Reader;

Reader.prototype.read = function () {
    this.stream.skipWhitespace();
    if (!this.stream.eof()) {
	switch (this.stream.peekChar()) {
	case ';':
	    this.stream.skipLine();
	    return this.read();
	case '"':
	    return this.readString();
	case '(':
	    return this.readList();
	default:
	    return this.readAtom();
	}
    }
}

var hexNumberExpression = /0x[0-9a-fA-F]+/;
var octalNumberExpression = /0[0-7]+/;
var decimalNumberExpression = /\d*\.?\d*(?:[eE]-?\d*(?:\d\.?|\.?\d)\d*)?/;

Reader.prototype.readAtom = function () {
    var c = this.stream.peekChar();
    var rest = this.stream.rest()
    if ([hexNumberExpression,
	 octalNumberExpression,
	 decimalNumberExpression]
	.some(function (expression) {
	    var match = expression.exec(rest);
	    return match && match[0] != '';
	}))
    {
	return this.readNumber();
    } else
	return this.readSymbol();
}

Reader.prototype.readList = function () {
    var result = new Array();
    this.stream.readChar();
    this.stream.skipWhitespace();

    while (this.stream.peekChar() != ')') {
	if (this.stream.eof())
	    throw new Error('Unbalanced parens');
	if (this.stream.peekChar() == ';')
	    this.stream.skipLine();
	else {
	    var next = this.read();
	    result.push(next);
	}
	this.stream.skipWhitespace();
    }

    this.stream.readChar();
    return result;
}

Reader.prototype.readSymbol = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    var name = match[0];
    this.stream.index += name.length;
    // TODO: keywords
    if (name[0] == '#' && HashSymbol.names.indexOf(name.substring(1)) >= 0)
	return HashSymbol[name.substring(1)];
    else
	return new Symbol(match[0]);
}

// TODO: escapes in strings: \t, \r, \n

Reader.prototype.readString = function () {
    this.stream.readChar();
    var c, result = "";
    while ((c = this.stream.readChar()) != '"') {
	if (c == '\\')
	    result += this.stream.readChar();
	else
	    result += c;
    }
    return result;
}

Reader.prototype.readNumber = function () {
    var match = /[^()\n\t ]+/.exec(this.stream.rest());
    this.stream.index += match[0].length;
    return new Number(match[0]);
}<|endoftext|>


<commit_before>import React from 'react';
import { props, t } from '../../utils';
import LoadingSpinner from '../../loading-spinner';
import ExampleCard from './ExampleCard';
import Markdown from 'react-remarkable';

@props({
  iso: t.maybe(t.Boolean),
  scope: t.Object,
  component: t.maybe(t.Object),
  header: t.maybe(t.ReactChildren),
  footer: t.maybe(t.ReactChildren)
})
export default class Component extends React.Component {

  getLoadingSpinner() {
    return (

        <LoadingSpinner />

    );
  }

  getExamples = (examples) => {
    const { scope, iso } = this.props;
    return [].concat(examples).map((example, key) =>

        <Markdown source={example.description} options={{ html: true }} />
        <ExampleCard {...{ codeText: example.code, iso, scope, key }} />

);
  };

  render() {
    const { component, header, footer } = this.props;
    const { examples } = component || {};
    return (

          {header}

          {examples ? this.getExamples(examples) : this.getLoadingSpinner()}

          {footer}

    );
  }

}
<commit_msg>minor fix (add "key" prop to examples div)<commit_after>import React from 'react';
import { props, t } from '../../utils';
import LoadingSpinner from '../../loading-spinner';
import ExampleCard from './ExampleCard';
import Markdown from 'react-remarkable';

@props({
  iso: t.maybe(t.Boolean),
  scope: t.Object,
  component: t.maybe(t.Object),
  header: t.maybe(t.ReactChildren),
  footer: t.maybe(t.ReactChildren)
})
export default class Component extends React.Component {

  getLoadingSpinner() {
    return (

        <LoadingSpinner />

    );
  }

  getExamples = (examples) => {
    const { scope, iso } = this.props;
    return [].concat(examples).map((example, key) =>

        <Markdown source={example.description} options={{ html: true }} />
        <ExampleCard {...{ codeText: example.code, iso, scope }} />

);
  };

  render() {
    const { component, header, footer } = this.props;
    const { examples } = component || {};
    return (

          {header}

          {examples ? this.getExamples(examples) : this.getLoadingSpinner()}

          {footer}

    );
  }

}
<|endoftext|>


<commit_before>var program = require('commander')
    , WebSocket = require('ws')
    , debug = require('debug')('wsclient');

program
    .version('0.0.1')
    .option('-c, --clients <clients>', 'Number of clients', Number, 1)
    .option('-s, --server <server>', 'websocket server', 'localhost:4000')
    .parse(process.argv);

const THROTTLE = 50;
var toConnect = 0;
var connected= 0, lastConnected=0;
setTimeout(function connect() {
    var ws = new WebSocket('ws://' + program.server + '/');
    ws.on('open', function(e) {
        connected+=1

    });

    ws.on('close', function() {
        debug('close');
    });

    ws.on('error', function(e) {
        debug('ERROR %s', e);
    });

    if (++toConnect < program.clients) {
        setTimeout(connect, THROTTLE);
    }
}, THROTTLE);

setInterval(function() {
    if (lastConnected == connected) {
        return;
    }

    debug('connected: %d', connected);
    lastConnected = connected;
}, 100);

<commit_msg>add an id number to dumb client test<commit_after>var program = require('commander')
    , WebSocket = require('ws')
    , debug = require('debug')('wsclient');

program
    .version('0.0.1')
    .option('-c, --clients <clients>', 'Number of clients', Number, 1)
    .option('-s, --server <server>', 'websocket server', 'localhost:4000')
    .parse(process.argv);

const THROTTLE = 50;
var toConnect = 0;
var connected= 0, lastConnected=0;
setTimeout(function connect() {
    var ws = new WebSocket('ws://' + program.server + '/');
    var myid = 0;
    ws.on('open', function(e) {
        connected+=1
        myid = connected;
    });

    ws.on('close', function() {
        debug('close id: %d', myid);
    });

    ws.on('error', function(e) {
        debug('ERROR (%d) %s', myid, e);
    });

    if (++toConnect < program.clients) {
        setTimeout(connect, THROTTLE);
    }
}, THROTTLE);

setInterval(function() {
    if (lastConnected == connected) {
        return;
    }

    debug('connected: %d', connected);
    lastConnected = connected;
}, 100);

<|endoftext|>


<commit_before>// A jQuery plugin to detect magnetic card swipes.  Requires a card reader that simulates a keyboard.
// This expects a card that encodes data on track 1, though it also reads tracks 2 and 3.  Most cards
// use track 1.  This won't recognize cards that don't use track 1, or work with a reader that
// doesn't read track 1.
//
// See http://en.wikipedia.org/wiki/Magnetic_card to understand the format of the data on a card.
//
// Uses pattern at https://github.com/umdjs/umd/blob/master/jqueryPlugin.js to declare
// the plugin so that it works with or without an AMD-compatible module loader, like RequireJS.
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {

	// State definitions:
	var IDLE = 0; // Waiting for track 1 start character, %
	var PENDING = 1; // Saw track 1 start character and waiting for B
	var READING = 2; // Saw %B and capturing until a carriage return, or until the timer times out
	var DISCARD = 3; // Eating all characters until a carriage return, or until the timer lapses

	// Holds current state
	var state = IDLE;

	// Array holding scanned characters
	var scanbuffer;

	// Interdigit timer
	var timerHandle = 0;

	// Keypress listener
	var listener = function (e) {
		switch (state) {
			case IDLE:
				// Look for '%'
				if (e.which == 37) {
					state = PENDING;
					scanbuffer = new Array();
					processCode(e.which);
					e.preventDefault();
					e.stopPropagation();
					startTimer();
				}

				break;

			case PENDING:
				// Look for format code character, A-Z. Almost always B for cards
				// used by the general public.
				if (e.which >= 65 && e.which <= 90) {
					state = READING;

					// Leaving focus on a form element wreaks browser-dependent
					// havoc because of keyup and keydown events.  This is a
					// cross-browser way to prevent trouble.
					$("input").blur();

					processCode(e.which);
					e.preventDefault();
					e.stopPropagation();
					startTimer();
				}
				else {
					clearTimer();
					scanbuffer = null;
					state = IDLE;
				}
				break;

			case READING:
				processCode(e.which);
				startTimer();
				e.preventDefault();
				e.stopPropagation();

				// Carriage return indicates end of scan
				if (e.which == 13) {
					clearTimer();
					state = IDLE;
					processScan();
				}

				if (settings.firstLineOnly && e.which == 63) {
					// End of line 1.  Return early, and eat remaining characters.
					state = DISCARD;
					processScan();
				}
				break;

			case DISCARD:
				e.preventDefault();
				e.stopPropagation();
				if (e.which == 13) {
					clearTimer();
					state = IDLE;
					return;
				}

				startTimer();
				break;
		}
	};

	// Converts a scancode to a character and appends it to the buffer.
	var processCode = function (code) {
		scanbuffer.push(String.fromCharCode(code));
		//console.log(code);
	}

	var startTimer = function () {
		clearTimeout(timerHandle);
		timerHandle = setTimeout(onTimeout, settings.interdigitTimeout);
	};

	var clearTimer = function () {
		clearTimeout(timerHandle);
		timerHandle = 0;
	};

	// Invoked when the timer lapses.
	var onTimeout = function () {
		if (state == READING) {
			processScan();
		}
		scanbuffer = null;
		state = IDLE;
	};

	// Processes the scanned card
	var processScan = function () {

		var rawData = scanbuffer.join('');

		// Invoke client parser and callbacks
		var parsedData = settings.parser.call(this, rawData);
		if (parsedData) {
			settings.success && settings.success.call(this, parsedData);
		}
		else {
			settings.error && settings.error.call(this, rawData);
		}
	};

	// Binds the event listener
	var bindListener = function () {
		$(document).bind("keypress.cardswipe", listener);
	};

	// Unbinds the event listener
	var unbindListener = function () {
		$(document).unbind(".cardswipe");
	};

	// Default parser. Separates raw data into up to three lines
	var defaultParser = function (rawData) {
		var pattern = new RegExp("^(%[^%;\\?]+\\?)(;[0-9\\:<>\\=]+\\?)?(;[0-9\\:<>\\=]+\\?)?");

		var match = pattern.exec(rawData);
		if (!match) return null;

		// Extract the three lines
		var cardData = {
			line1: match[1],
			line2: match[2],
			line3: match[3]
		};

		return cardData;
	};

	// Default callback used if no other specified. Works with default parser.
	var defaultSuccessCallback = function (cardData) {
		var text = ['Success!\nFirst name: ', cardData.firstName, '\nLast name: ', cardData.lastName, '\nID number: ', cardData.idNumber].join('');
		alert(text);
	};

	// Defaults for settings
	var defaults = {
		enabled: true,
		interdigitTimeout: 250,
		success: defaultSuccessCallback,
		error: null,
		parser: defaultCardParser,
		firstLineOnly: false
	};

	// Plugin actual settings
	var settings;

	// Callable plugin methods
	var methods = {
		init: function (options) {
			settings = $.extend(defaults, options || {});

			if (settings.enabled)
				methods.enable();
		},

		disable: function (options) {
			unbindListener();
		},

		enable: function (options) {
			bindListener();
		}
	};

	// The extension proper.  Dispatches methods using the usual jQuery pattern.
	$.cardswipe = function (method) {
		// Method calling logic
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.cardswipe');
		}
	}

}));
<commit_msg>Bugfix.<commit_after>// A jQuery plugin to detect magnetic card swipes.  Requires a card reader that simulates a keyboard.
// This expects a card that encodes data on track 1, though it also reads tracks 2 and 3.  Most cards
// use track 1.  This won't recognize cards that don't use track 1, or work with a reader that
// doesn't read track 1.
//
// See http://en.wikipedia.org/wiki/Magnetic_card to understand the format of the data on a card.
//
// Uses pattern at https://github.com/umdjs/umd/blob/master/jqueryPlugin.js to declare
// the plugin so that it works with or without an AMD-compatible module loader, like RequireJS.
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {

	// State definitions:
	var IDLE = 0; // Waiting for track 1 start character, %
	var PENDING = 1; // Saw track 1 start character and waiting for B
	var READING = 2; // Saw %B and capturing until a carriage return, or until the timer times out
	var DISCARD = 3; // Eating all characters until a carriage return, or until the timer lapses

	// Holds current state
	var state = IDLE;

	// Array holding scanned characters
	var scanbuffer;

	// Interdigit timer
	var timerHandle = 0;

	// Keypress listener
	var listener = function (e) {
		switch (state) {
			case IDLE:
				// Look for '%'
				if (e.which == 37) {
					state = PENDING;
					scanbuffer = new Array();
					processCode(e.which);
					e.preventDefault();
					e.stopPropagation();
					startTimer();
				}

				break;

			case PENDING:
				// Look for format code character, A-Z. Almost always B for cards
				// used by the general public.
				if (e.which >= 65 && e.which <= 90) {
					state = READING;

					// Leaving focus on a form element wreaks browser-dependent
					// havoc because of keyup and keydown events.  This is a
					// cross-browser way to prevent trouble.
					$("input").blur();

					processCode(e.which);
					e.preventDefault();
					e.stopPropagation();
					startTimer();
				}
				else {
					clearTimer();
					scanbuffer = null;
					state = IDLE;
				}
				break;

			case READING:
				processCode(e.which);
				startTimer();
				e.preventDefault();
				e.stopPropagation();

				// Carriage return indicates end of scan
				if (e.which == 13) {
					clearTimer();
					state = IDLE;
					processScan();
				}

				if (settings.firstLineOnly && e.which == 63) {
					// End of line 1.  Return early, and eat remaining characters.
					state = DISCARD;
					processScan();
				}
				break;

			case DISCARD:
				e.preventDefault();
				e.stopPropagation();
				if (e.which == 13) {
					clearTimer();
					state = IDLE;
					return;
				}

				startTimer();
				break;
		}
	};

	// Converts a scancode to a character and appends it to the buffer.
	var processCode = function (code) {
		scanbuffer.push(String.fromCharCode(code));
		//console.log(code);
	}

	var startTimer = function () {
		clearTimeout(timerHandle);
		timerHandle = setTimeout(onTimeout, settings.interdigitTimeout);
	};

	var clearTimer = function () {
		clearTimeout(timerHandle);
		timerHandle = 0;
	};

	// Invoked when the timer lapses.
	var onTimeout = function () {
		if (state == READING) {
			processScan();
		}
		scanbuffer = null;
		state = IDLE;
	};

	// Processes the scanned card
	var processScan = function () {

		var rawData = scanbuffer.join('');

		// Invoke client parser and callbacks
		var parsedData = settings.parser.call(this, rawData);
		if (parsedData) {
			settings.success && settings.success.call(this, parsedData);
		}
		else {
			settings.error && settings.error.call(this, rawData);
		}
	};

	// Binds the event listener
	var bindListener = function () {
		$(document).bind("keypress.cardswipe", listener);
	};

	// Unbinds the event listener
	var unbindListener = function () {
		$(document).unbind(".cardswipe");
	};

	// Default parser. Separates raw data into up to three lines
	var defaultParser = function (rawData) {
		var pattern = new RegExp("^(%[^%;\\?]+\\?)(;[0-9\\:<>\\=]+\\?)?(;[0-9\\:<>\\=]+\\?)?");

		var match = pattern.exec(rawData);
		if (!match) return null;

		// Extract the three lines
		var cardData = {
			line1: match[1],
			line2: match[2],
			line3: match[3]
		};

		return cardData;
	};

	// Default callback used if no other specified. Works with default parser.
	var defaultSuccessCallback = function (cardData) {
		var text = ['Success!\nFirst name: ', cardData.firstName, '\nLast name: ', cardData.lastName, '\nID number: ', cardData.idNumber].join('');
		alert(text);
	};

	// Defaults for settings
	var defaults = {
		enabled: true,
		interdigitTimeout: 250,
		success: defaultSuccessCallback,
		error: null,
		parser: defaultParser,
		firstLineOnly: false
	};

	// Plugin actual settings
	var settings;

	// Callable plugin methods
	var methods = {
		init: function (options) {
			settings = $.extend(defaults, options || {});

			if (settings.enabled)
				methods.enable();
		},

		disable: function (options) {
			unbindListener();
		},

		enable: function (options) {
			bindListener();
		}
	};

	// The extension proper.  Dispatches methods using the usual jQuery pattern.
	$.cardswipe = function (method) {
		// Method calling logic
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		}
		else {
			$.error('Method ' + method + ' does not exist on jQuery.cardswipe');
		}
	}

}));
<|endoftext|>


<commit_before>'use strict';

var db           = require('magic-db')
  , express      = require('express')
  , stylus       = require('stylus')
  , bodyParser   = require('body-parser')
  , cookieParser = require('cookie-parser')
  , compression  = require('compression')
  , favicon      = require('serve-favicon')
  , fs           = require('fs')
  , morgan       = require('morgan')
  , errorHandler = require('magic-errorHandler')
  , headers      = require('magic-headers')
  , log          = require('magic-log')
  , menu         = require('magic-menu')
  , path         = require('path')
  , R            = require('magic-router')
  , sslRedirect  = require('magic-ssl')
;

module.exports = function(S, dir) {
  var css         = ( S.get('css') || stylus )
    , faviconPath = path.join(dir, 'public', 'favicon.ico')
    , env         = S.get('env') || 'development'
    , routes      = S.get('routes')
    , dbConf      = S.get('db') || false
    , dirs        = S.get('dirs') || {
        public: path.join(dir, 'public')
      , views : path.join(dir, 'views')
    }
  ;
  if ( dbConf ) {
    S.set('schema', db.init(dbConf) );
  }

  if ( ! S.get('allowHttp') && S.get('env') === 'production' ) {
   // S.use(sslRedirect);
  }

  S.use(headers);

  if ( fs.existsSync(faviconPath) ) {
    S.use( favicon(faviconPath) );
  }

  S.set('views', dirs.views);
  S.set('view engine', S.get('view engine') || 'jade');

  S.use(compression({
    threshold: 128
  }));

  S.use( css.middleware(dirs.public, {maxAge: '1d'}) );
  S.use( express.static(dirs.public, {maxAge: '1d'}) );

  if ( S.get('useMenu') ) {
    S.use(function(req, res, next) {
      menu(S, req, res , next);
    } );
  }

  S.use(morgan('combined'));

  if ( routes ) {
    if ( typeof routes === 'array' || typeof routes === 'object' ) {
      for (var route in routes ) {
        S.use(route);
      }
    } else if ( typeof routes === 'function' ) {
      S.use( routes );
    }
  }

  if ( S.get('bodyParser') ) {
    S.use(bodyParser.json());
    S.use(bodyParser.urlencoded({ extended: false }));
  }
  if ( S.get('cookieParser') ) {
    S.use(cookieParser());
  }

  S.route('*').get(R);
  S.route('/:page').get(R);

  S.use(errorHandler);

  return S;
}
<commit_msg>added auth module, added "caching" to favicon"<commit_after>'use strict';

var db           = require('magic-db')
  , express      = require('express')
  , stylus       = require('stylus')
  , bodyParser   = require('body-parser')
  , cookieParser = require('cookie-parser')
  , compression  = require('compression')
  , favicon      = require('serve-favicon')
  , fs           = require('fs')
  , morgan       = require('morgan')
  , errorHandler = require('magic-errorHandler')
  , headers      = require('magic-headers')
  , log          = require('magic-log')
  , menu         = require('magic-menu')
  , auth         = require('magic-auth')
  , path         = require('path')
  , R            = require('magic-router')
  , sslRedirect  = require('magic-ssl')
;

module.exports = function(S, dir) {
  var css         = ( S.get('css') || stylus )
    , env         = S.get('env') || 'production'
    , dbConf      = S.get('db') || false
    , faviconPath = path.join(dir, 'public', 'favicon.ico')
    , dirs        = S.get('dirs') || {
        public: path.join(dir, 'public')
      , views : path.join(dir, 'views')
    }
  ;

  if ( ! S.get('allowHttp') && S.get('env') === 'production' ) {
   // S.use(sslRedirect);
  }

  //set expiry headers
  S.use(headers);

  //fs.existsSync only gets called once
  if ( S.get('faviconExists') || fs.existsSync(faviconPath) ) {
    S.set('faviconExists', true);
    S.use( favicon(faviconPath) );
  }

  S.set('views', dirs.views);
  S.set('view engine', S.get('view engine') || 'jade');

  S.use(compression({ threshold: 128 }));

  S.use( css.middleware(dirs.public, {maxAge: '1d'}) );
  S.use( express.static(dirs.public, {maxAge: '1d'}) );

  //load the menu for the current host
  S.use(function(req, res, next) {
    menu(S, req, res , next);
  } );

  //logging
  S.use(morgan('combined'));

  //if host sets bodyparser to true, init it
  if ( S.get('bodyParser') ) {
    S.use(bodyParser.json());
    S.use(bodyParser.urlencoded({ extended: false }));
  }

  //if host sets cookieparser to true, init it:
  if ( S.get('cookieParser') ) {
    S.use(cookieParser());
  }

  if ( S.get('useAuth') ) {
    S.use(function (req, res, next) {
       auth.routes(S, req, res, next);
    });
  }

  //load host specific routes
  if ( S.get('routes') ) {
    let routes = S.get('routes');

    if ( typeof routes === 'array' || typeof routes === 'object' ) {
      for (var route in routes ) {
        S.use(route);
      }
    } else if ( typeof routes === 'function' ) {
      S.use( routes );
    }
  }

  S.route('*').get(R);
  S.route('/:page').get(R);

  S.use(errorHandler);

  return S;
}
<|endoftext|>