<commit_before>var callbacks = {};
var callbackId = 1;

var bitcoinWalletApp = angular.module('bitcoinWalletApp', []);

var postMessageWithCallback = function(message, callback) {
  message.id = callbackId++;
  callbacks[message.id] = callback;
  common.naclModule.postMessage(JSON.stringify(message));
};

function handleMessage(message) {
  var message_object = JSON.parse(message.data);
  console.log(message_object);
  var id = message_object.id;
  if (callbacks[id]) {
    callbacks[id].call(this, message_object);
    delete callbacks[id];
  }
}

function MasterKey() {
  this.showXprv = false;
  this.xprv = "";
  this.xpub = "";
  this.fingerprint = "";

  var mk = this;
  this.setFingerprint = function(fingerprint) {
    mk.fingerprint = fingerprint;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://robohash.org/' + fingerprint +
             '.png?set=set3&bgset=any&size=64x64', true);
    xhr.responseType = 'blob';
    xhr.onload = function(e) {
      $("#fingerprint-img").attr(
        "src",
        window.webkitURL.createObjectURL(this.response));
      $("#fingerprint-img-big").attr(
        "src",
        window.webkitURL.createObjectURL(this.response));
    };
    xhr.send();
  };
}

function Account(number) {
  this.number = number;
  this.balance = 9999.12345678;
  this.addresses = [
  { 'address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'balance': '123.45', 'tx_count': 3 },
  { 'address': '1JKMcZibd5MBn3sn4u3WVnFvHWMFiny59', 'balance': '3.50', 'tx_count': 1 },
  { 'address': '1ADc4zojfRp9794ZX3ozDSGF4W2meSfkzr', 'balance': '0.0001', 'tx_count': 2 },
  { 'address': '18gaduiJeXLcLJVcdhRAiMLge6YmCyAnQz', 'balance': '5.55', 'tx_count': 3 },
  { 'address': '1CSWk7EioDwpqUDr4gftsjnzewPUSRPs9p', 'balance': '0.00', 'tx_count': 0 },
];

  this.transactions = [
  { 'date': '3 Jan 2009', 'address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'amount': '2.34' },
  { 'date': '4 Jan 2009', 'address': '1JKMcZibd5MBn3sn4u3WVnFvHWMFiny59', 'amount': '50.00' },
  { 'date': '5 Jan 2009', 'address': '17sz256snXYak5VMX8EdE4p4Pab8X8iMGn', 'amount': '(50.00)' }
];

  this.hasTransactions = function() {
    return this.transactions.length > 0;
  }
}

function Settings() {
  this.units = "mBTC";
}

function WalletController($scope) {
  $scope.masterKey = null;
  $scope.account = null;
  $scope.settings = new Settings();

  $scope.newMasterKey = function() {
    var message = {
      'command': 'create-random-node'
    };
    postMessageWithCallback(message, function(response) {
      var masterKey = new MasterKey();
      masterKey.xprv = response.ext_prv_b58;
      masterKey.showXprv = false;
      masterKey.xpub = response.ext_pub_b58;
      masterKey.setFingerprint(response.fingerprint);

      $scope.masterKey = masterKey;
      $scope.account = new Account(7);
      $scope.$apply();
    });
  };

  $scope.removeMasterKey = function() {
    // TODO(miket): ideally we'll track whether this key was backed
    // up, and make this button available only if yes. Then we'll
    // confirm up the wazoo before actually deleting.
    //
    // Less of a big deal if the master key is public.
    $scope.masterKey = null;
    $scope.$apply();
  };
}

function moduleDidLoad() {
  common.hideModule();
  hideLoading();
}

function hideLoading() {
  $("#loading-container").fadeOut(250, function() {
    $("#main-container").fadeIn(500, function() {
      $('#main-tabs a:first').tab('show');
    });
  });
}

function showLoading() {
  $("#loading-container").show();
  $("#main-container").hide();
}

var onTabClick = function(e) {
  e.preventDefault()
  $(this).tab('show')
};

var setAccount = function(account) {
  if (!account || account == 0) {
    $("#account").text("Default Account");
  } else {
    $("#account").text("Account " + account);
  }
};

window.onload = function() {
  // Add click handlers.
  $('#main-tabs a').click(onTabClick);

  // For development in a normal browser tab.
  if (chrome && chrome.runtime)
    showLoading();
  else
    hideLoading();
};
<commit_msg>The inprog error was because it was inprog.<commit_after>var callbacks = {};
var callbackId = 1;

var bitcoinWalletApp = angular.module('bitcoinWalletApp', []);

var postMessageWithCallback = function(message, callback) {
  message.id = callbackId++;
  callbacks[message.id] = callback;
  common.naclModule.postMessage(JSON.stringify(message));
};

function handleMessage(message) {
  var message_object = JSON.parse(message.data);
  console.log(message_object);
  var id = message_object.id;
  if (callbacks[id]) {
    callbacks[id].call(this, message_object);
    delete callbacks[id];
  }
}

function MasterKey() {
  this.showXprv = false;
  this.xprv = "";
  this.xpub = "";
  this.fingerprint = "";

  var mk = this;
  this.setFingerprint = function(fingerprint) {
    mk.fingerprint = fingerprint;
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://robohash.org/' + fingerprint +
             '.png?set=set3&bgset=any&size=64x64', true);
    xhr.responseType = 'blob';
    xhr.onload = function(e) {
      $("#fingerprint-img").attr(
        "src",
        window.webkitURL.createObjectURL(this.response));
      $("#fingerprint-img-big").attr(
        "src",
        window.webkitURL.createObjectURL(this.response));
    };
    xhr.send();
  };
}

function Account(number) {
  this.number = number;
  this.balance = 9999.12345678;
  this.addresses = [
  { 'address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'balance': '123.45', 'tx_count': 3 },
  { 'address': '1JKMcZibd5MBn3sn4u3WVnFvHWMFiny59', 'balance': '3.50', 'tx_count': 1 },
  { 'address': '1ADc4zojfRp9794ZX3ozDSGF4W2meSfkzr', 'balance': '0.0001', 'tx_count': 2 },
  { 'address': '18gaduiJeXLcLJVcdhRAiMLge6YmCyAnQz', 'balance': '5.55', 'tx_count': 3 },
  { 'address': '1CSWk7EioDwpqUDr4gftsjnzewPUSRPs9p', 'balance': '0.00', 'tx_count': 0 },
];

  this.transactions = [
  { 'date': '3 Jan 2009', 'address': '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 'amount': '2.34' },
  { 'date': '4 Jan 2009', 'address': '1JKMcZibd5MBn3sn4u3WVnFvHWMFiny59', 'amount': '50.00' },
  { 'date': '5 Jan 2009', 'address': '17sz256snXYak5VMX8EdE4p4Pab8X8iMGn', 'amount': '(50.00)' }
];

  this.hasTransactions = function() {
    return this.transactions.length > 0;
  }
}

function Settings() {
  this.units = "mBTC";
}

function WalletController($scope) {
  $scope.masterKey = null;
  $scope.account = null;
  $scope.settings = new Settings();

  $scope.newMasterKey = function() {
    var message = {
      'command': 'create-random-node'
    };
    postMessageWithCallback(message, function(response) {
      var masterKey = new MasterKey();
      masterKey.xprv = response.ext_prv_b58;
      masterKey.showXprv = false;
      masterKey.xpub = response.ext_pub_b58;
      masterKey.setFingerprint(response.fingerprint);

      $scope.masterKey = masterKey;
      $scope.account = new Account(7);
      $scope.$apply();
    });
  };

  $scope.removeMasterKey = function() {
    // TODO(miket): ideally we'll track whether this key was backed
    // up, and make this button available only if yes. Then we'll
    // confirm up the wazoo before actually deleting.
    //
    // Less of a big deal if the master key is public.
    $scope.masterKey = null;
  };
}

function moduleDidLoad() {
  common.hideModule();
  hideLoading();
}

function hideLoading() {
  $("#loading-container").fadeOut(250, function() {
    $("#main-container").fadeIn(500, function() {
      $('#main-tabs a:first').tab('show');
    });
  });
}

function showLoading() {
  $("#loading-container").show();
  $("#main-container").hide();
}

var onTabClick = function(e) {
  e.preventDefault()
  $(this).tab('show')
};

var setAccount = function(account) {
  if (!account || account == 0) {
    $("#account").text("Default Account");
  } else {
    $("#account").text("Account " + account);
  }
};

window.onload = function() {
  // Add click handlers.
  $('#main-tabs a').click(onTabClick);

  // For development in a normal browser tab.
  if (chrome && chrome.runtime)
    showLoading();
  else
    hideLoading();
};
<|endoftext|>


<commit_before>module.exports = setup;

function setup(app) {
	var models = app.get('models');
	var sql = 'SELECT * FROM tags t JOIN issue_tags it ON it.tagId = t.id JOIN issues i ON it.issueId = i.id';

	setInterval(function () {

		models._sequelize.query(sql, models.Tag)
			.success(function (tags) {
				ingest(app, tags);
			});
	}, 30 * 1000);
}

function ingest(app, tags) {
	console.log('ingesting for ' + tags.length + ' tags');

	getInstagramMedia(app, tags, function (err, media) {
		if (err) {
			console.log('error getting instagram media');
			console.log(err);
			return;
		}

		console.log('retrieved ' + media.length + ' media');

		importInstagramMedia(app, media, function (err, media) {
			if (err) {
				console.log('error importing media');
				console.log(err);
				return;
			}

			console.log('created ' + media.length + ' new media items');
		});
	});
}

function getInstagramMedia(app, tags, callback) {
	var inst = app.get('instagram');

	var results = [];
	var errors = [];
	var count = 0;

	for (var i = 0; i < tags.length; i++) {
		inst.tags.recent({
			name: tags[i].name,

			error: function (errorMessage, errorObject, caller) {
				errors.push(errorMessage);
				check();
			},

			complete: function (media, pagination) {
				results.push(media);
				check();
			}
		});
	}

	function check() {
		count++;

		if (count !== tags.length)
			return;

		if (errors.length) {
			var err = new Error('Failed to retrieve media');
			err.innerErrors = errors;
			callback(err);
			return;
		}

		var media = [];
		for (var i = 0; i < results.length; i++)
			media = media.concat(results[i]);

		callback(null, media);
	}
}

function importInstagramMedia(app, media, callback) {
	var tagsNeeded = [];
	for (var i = 0; i < media.length; i++)
		tagsNeeded = tagsNeeded.concat(media[i].tags);

	getTags(app, tagsNeeded, function (err, tags) {
		if (err) {
			callback(err);
			return;
		}

		var results = [];
		var errors = [];
		var count = 0;

		for (var i = 0; i < media.length; i++) {
			createMedium(app, tags, media[i], function (err, medium) {
				count++;

				if (err) {
					if (err.code !== 'ER_DUP_ENTRY')
						errors.push(err);
				} else {
					results.push(medium);
				}

				if (count === media.length) {
					if (errors.length) {
						var err = new Error('Failed to import media');
						err.innerErrors = errors;
						callback(err);
						return;
					}

					callback(null, results);
				}
			});
		}
	});
}

function getTags(app, tags, callback) {
	var models = app.get('models');

	models.Tag.findAll()
		.error(callback)
		.success(function (existingTags) {
			// remove non-ascii chars
			for (var i = 0; i < tags.length; i++)
				tags[i] = tags[i].replace(/[^\x00-\x7F]/g, '');

			// deduplicate
			tags = tags.filter(function (obj, pos, arr) {
				return arr.indexOf(obj) == pos;
			});

			// remove existing
			for (var i = 0; i < existingTags.length; i++) {
				var j = tags.indexOf(existingTags[i].name);
				if (j > -1) tags[j] = null;
			}

			var cleanedTags = [];
			for (var i = 0; i < tags.length; i++)
				if (tags[i])
					cleanedTags.push(tags[i]);
			tags = cleanedTags;
			delete cleanedTags;

			// create new tags
			tags = tags.map(function (t) { return { name: t }; });

			models.Tag.bulkCreate(tags)
				.error(callback)
				.success(function (newTags) {
					tags = existingTags.concat(newTags);

					// array<Tag> -> map<string, Tag>
					var tagMap = {};
					for (var i = 0; i < tags.length; i++)
						tagMap[tags[i].name] = tags[i];
					tags = tagMap;
					delete tagMap;

					callback(null, tags);
				});
		});
}

function createMedium(app, tags, medium, callback) {
	var models = app.get('models');

	var thumb = medium.images.thumbnail.url;
	var standard = medium.images.standard_resolution.url;

	var obj = {
		instagramId: medium.id,
		date: new Date(medium.created_time * 1000),
		thumbnailUrl: thumb,
		imageUrl: standard
	};

	models.Media.create(obj)
		.error(callback)
		.success(function (medium, created) {
			// remove non-ascii chars
			for (var i = 0; i < medium.tags.length; i++)
				medium.tags[i] = medium.tags[i].replace(/[^\x00-\x7F]/g, '');

			// deduplicate
			medium.tags = medium.tags.filter(function (obj, pos, arr) {
				return arr.indexOf(obj) == pos;
			});

			var mediumTags = [];
			for (var i = 0; i < medium.tags.length; i++)
			 	mediumTags.push(tags[medium.tags[i]]);

			medium.setTags(medium)
				.error(callback)
				.success(function () {
					callback(null, medium);
				});
		});
}
<commit_msg>no message<commit_after>module.exports = setup;

function setup(app) {
	var models = app.get('models');
	var sql = 'SELECT * FROM tags t JOIN issue_tags it ON it.tagId = t.id JOIN issues i ON it.issueId = i.id';

	setInterval(function () {

		models._sequelize.query(sql, models.Tag)
			.success(function (tags) {
				ingest(app, tags);
			});
	}, 30 * 1000);
}

function ingest(app, tags) {
	console.log('ingesting for ' + tags.length + ' tags');

	getInstagramMedia(app, tags, function (err, media) {
		if (err) {
			console.log('error getting instagram media');
			console.log(err);
			return;
		}

		console.log('retrieved ' + media.length + ' media');

		importInstagramMedia(app, media, function (err, media) {
			if (err) {
				console.log('error importing media');
				console.log(err);
				return;
			}

			console.log('created ' + media.length + ' new media items');
		});
	});
}

function getInstagramMedia(app, tags, callback) {
	var inst = app.get('instagram');

	var results = [];
	var errors = [];
	var count = 0;

	for (var i = 0; i < tags.length; i++) {
		inst.tags.recent({
			name: tags[i].name,

			error: function (errorMessage, errorObject, caller) {
				errors.push(errorMessage);
				check();
			},

			complete: function (media, pagination) {
				results.push(media);
				check();
			}
		});
	}

	function check() {
		count++;

		if (count !== tags.length)
			return;

		if (errors.length) {
			var err = new Error('Failed to retrieve media');
			err.innerErrors = errors;
			callback(err);
			return;
		}

		var media = [];
		for (var i = 0; i < results.length; i++)
			media = media.concat(results[i]);

		callback(null, media);
	}
}

function importInstagramMedia(app, media, callback) {
	var tagsNeeded = [];
	for (var i = 0; i < media.length; i++)
		tagsNeeded = tagsNeeded.concat(media[i].tags);

	getTags(app, tagsNeeded, function (err, tags) {
		if (err) {
			callback(err);
			return;
		}

		var results = [];
		var errors = [];
		var count = 0;

		for (var i = 0; i < media.length; i++) {
			createMedium(app, tags, media[i], function (err, medium) {
				count++;

				if (err) {
					if (err.code !== 'ER_DUP_ENTRY')
						errors.push(err);
				} else {
					results.push(medium);
				}

				if (count === media.length) {
					if (errors.length) {
						var err = new Error('Failed to import media');
						err.innerErrors = errors;
						callback(err);
						return;
					}

					callback(null, results);
				}
			});
		}
	});
}

function getTags(app, tags, callback) {
	var models = app.get('models');

	models.Tag.findAll()
		.error(callback)
		.success(function (existingTags) {
			// remove non-ascii chars
			for (var i = 0; i < tags.length; i++)
				tags[i] = tags[i].replace(/[^\x00-\x7F]/g, '');

			// deduplicate
			tags = tags.filter(function (obj, pos, arr) {
				return arr.indexOf(obj) == pos;
			});

			// remove existing
			for (var i = 0; i < existingTags.length; i++) {
				var j = tags.indexOf(existingTags[i].name);
				if (j > -1) tags[j] = null;
			}

			var cleanedTags = [];
			for (var i = 0; i < tags.length; i++)
				if (tags[i])
					cleanedTags.push(tags[i]);
			tags = cleanedTags;
			delete cleanedTags;

			// create new tags
			tags = tags.map(function (t) { return { name: t }; });

			models.Tag.bulkCreate(tags)
				.error(callback)
				.success(function (newTags) {
					tags = existingTags.concat(newTags);

					// array<Tag> -> map<string, Tag>
					var tagMap = {};
					for (var i = 0; i < tags.length; i++)
						tagMap[tags[i].name] = tags[i];
					tags = tagMap;
					delete tagMap;

					callback(null, tags);
				});
		});
}

function createMedium(app, tags, medium, callback) {
	var models = app.get('models');

	var thumb = medium.images.thumbnail.url;
	var standard = medium.images.standard_resolution.url;

	var obj = {
		instagramId: medium.id,
		date: new Date(medium.created_time * 1000),
		thumbnailUrl: thumb,
		imageUrl: standard
	};

	models.Media.create(obj)
		.error(callback)
		.success(function (medium) {
			// remove non-ascii chars
			for (var i = 0; i < medium.tags.length; i++)
				medium.tags[i] = medium.tags[i].replace(/[^\x00-\x7F]/g, '');

			// deduplicate
			medium.tags = medium.tags.filter(function (obj, pos, arr) {
				return arr.indexOf(obj) == pos;
			});

			var mediumTags = [];
			for (var i = 0; i < medium.tags.length; i++)
			 	mediumTags.push(tags[medium.tags[i]]);

			medium.setTags(medium)
				.error(callback)
				.success(function () {
					callback(null, medium);
				});
		});
}
<|endoftext|>


<commit_before>'use strict';

// parse the data of documents
// only used by DAO

var parser = module.exports = {};

var glob        = require('glob');
var marked      = require('marked');
var highlight   = require('highlight.js');
var node_path   = require('path');
var sep         = node_path.sep;
var node_fs     = require('fs');
var lang        = require('./lang');
var async       = require('async');

// parse the tree structure of the document
// basic infomations
// @param {path} dir absolute dir of the document root

// tree:
// {
//     index: 'README.md',
//     // relative depth
//     rel_depth: 0,
//     pages: {
//         '1_a.md': {
//             name: '1_a.md',
//             parent: <recursive>,
//             rel_depth: 1,
//             // empty array indicates there're no sub pages
//             pages: {}
//         }
//     }
// }
parser.raw_tree = function (dir, callback) {
    glob('**/*.md', {
        cwd: dir,
        strict: true

    }, function (err, files) {
        if ( err ) {
            return callback(err);
        }

        var tree = {
            // rel_depth: 0,
            pages: {},
            type: 'dir'
        };

        files.forEach(function (file) {
            parser._save_item(tree, file, dir);
        });

        callback(null, tree);
    });
};

parser._save_item = function (tree, path, root) {
    var parent = tree;
    var abs = root;

    path.split(sep).some(function (slice, i) {
        abs = node_path.join(abs, slice);

        if ( slice === 'README.md' ) {
            parent.path = abs;
            return true;
        }

        var current = parent.pages[slice];

        if ( !current ) {
            current = parent.pages[slice] = {
                // duplicate data for more easily parsing
                name: slice,
                // recursive data
                parent: parent,
                // rel_depth: i + 1,
                path: abs
            };

            if ( node_fs.statSync(abs).isDirectory() ) {
                if ( !current.pages ) {
                    current.pages = {};
                }

                current.type = 'folder';
                parent = current;

            } else {
                current.type = 'file';
                // if file occurs, skip parsing
                return true;
            }
        }

        parent = current;
    });
};

// TODO
var REGEX_NAME_SPLITTER = /_/g;
var REGEX_INT = /^\d+$/;

parser.cook_name = function (name) {
    var split = name.split(REGEX_NAME_SPLITTER).filter(Boolean);

    var first = split[0];

    // number string
    if ( REGEX_INT.test(first) ) {
        split.shift();
    }

    return {
        // '01_abc_def' -> 'Abc Def'
        display_name: split.map(function (part) {
            return lang.capitalize(part);
        }).join(' '),

        // '01_abc_def' -> 'abc-def'
        uri_name    : split.map(function (part) {
            return part.toLowerCase();
        }).join('-')
    }
};

// @param {Object=} languages
// {
//     "zh-CN": {
//     }
// }
parser.language_tree = function (raw_tree, languages) {
    if ( lang.isEmptyObject(languages) ) {
        languages = null;
    }

    var ret = {};

    if ( languages ) {
        var root = raw_tree.pages || {};

        lang.each(languages, function (name, language) {
            var root_tree = root[language] || {};
            delete root_tree.parent;

            // it's hard to detect the closest match if user had a wrong configuration
            // convert to lowercase to make it easier
            ret[language.toLowerCase()] = {
                name: name,
                tree: root_tree
            };
        });

        return ret;

    } else {
        return {
            default: {
                tree: raw_tree
            }
        };
    }
};

var SUPPORTED_LANG = Object.keys(highlight.LANGUAGES);

var marked_opt = {
    breaks: false,
    gfm: true,
    langPrefix: 'language-',
    pedantic: false,
    sanitize: false,
    silent: false,
    smartLists: false,
    smartypants: false,
    tables: true,
    highlight: function (code, lang) {
        if ( ~ SUPPORTED_LANG.indexOf(lang) ) {
            return highlight.highlight(lang, code).value;
        } else {
            return highlight.highlightAuto(code).value;
        }
    }
};

// options.
parser.markdown = function (code, callback) {
    marked(code, marked_opt, callback);
};

var REGEX_MATCH_H1 = /<h1>(.*?)<\/h1>/i;

parser.get_title = function (html) {
    html = html || '';

    var match = html.match(REGEX_MATCH_H1);

    return match ? match[1] : undefined;
};

// @param {Object} options
// - define
parser.sort_tree = function (tree, options, callback) {

};

// create a cache
parser.create_data = function (language_tree, callback) {
    var counter = Object.keys(language_tree).length;
    var error;
    var nodes = [];

    function iterator (data, done) {
        var node = data.node;
        var descend = data.descend;

        nodes.push(node);

        if ( node.type === 'file' ) {
            var file = node.path;

            node_fs.readFile(file, function (err, content) {
                if ( err ) {
                    return done(err);
                }

                parser.markdown(content.toString(), function (err, html) {
                    if ( err ) {
                        return done(err);
                    }

                    node.html = html;

                    var title = parser.get_title(html);

                    parser._generate_url(node, title);
                    done(null);
                });
            });

        } else {
            parser._generate_url(node);

            var pages = node.pages;

            if ( pages ) {
                // `pages` from object to array
                node.pages = Object.keys(pages).map(function (name) {
                    return pages[name];
                });
            }

            descend();
            done(null);
        }
    };

    lang.each(language_tree, function (l, language) {
        parser.walk(l.tree, iterator, function (err) {
            nodes.forEach(function (node) {
                if ( node ) {
                    delete node.parent;
                }
            });

            // free
            nodes.length = 0;

            if ( err ) {
                error = err;
                return callback(err);

            } else if (error) {
                return;

            } else if ( -- counter === 0 ) {
                return callback(null, language_tree);
            }
        });
    });
};

// TODO: #7
parser._generate_url = function (node, name) {
    if ( !node.parent ) {
        node.url = '';
    } else {
        name = name || node.name;

        var cooked = parser.cook_name(name);
        node.display_name = cooked.display_name;
        node.uri_name = cooked.uri_name;

        node.url = node.parent.url + '/' + node.uri_name;
    }
};

// walk and traverse a tree
parser.walk = function (tree, iterator, callback) {
    var q = async.queue(iterator);
    var errors = [];

    q.drain = function () {
        callback( errors.length ? errors : null );
    };

    function walk (node, depth) {
        node.depth = depth;

        q.push({
            node: node,

            // descend a specific node or descend all
            descend: function (sub_node) {
                if ( sub_node ) {
                    walk(sub_node, depth + 1);

                } else if ( node.pages ) {
                    node.pages.forEach(function (sub_node, name) {
                        walk(sub_node, depth + 1);
                    });
                }
            }

        }, function (err){
            if ( err ) {
                errors.push(err);
            }
        });
    }

    walk(tree, 0);
};

<commit_msg>#4: sort pages<commit_after>'use strict';

// parse the data of documents
// only used by DAO

var parser = module.exports = {};

var glob        = require('glob');
var marked      = require('marked');
var highlight   = require('highlight.js');
var node_path   = require('path');
var sep         = node_path.sep;
var node_fs     = require('fs');
var lang        = require('./lang');
var async       = require('async');

// parse the tree structure of the document
// basic infomations
// @param {path} dir absolute dir of the document root

// tree:
// {
//     index: 'README.md',
//     // relative depth
//     rel_depth: 0,
//     pages: {
//         '1_a.md': {
//             name: '1_a.md',
//             parent: <recursive>,
//             rel_depth: 1,
//             // empty array indicates there're no sub pages
//             pages: {}
//         }
//     }
// }
parser.raw_tree = function (dir, callback) {
    glob('**/*.md', {
        cwd: dir,
        strict: true

    }, function (err, files) {
        if ( err ) {
            return callback(err);
        }

        var tree = {
            // rel_depth: 0,
            pages: {},
            type: 'dir'
        };

        files.forEach(function (file) {
            parser._save_item(tree, file, dir);
        });

        callback(null, tree);
    });
};

parser._save_item = function (tree, path, root) {
    var parent = tree;
    var abs = root;

    path.split(sep).some(function (slice, i) {
        abs = node_path.join(abs, slice);

        if ( slice === 'README.md' ) {
            parent.path = abs;
            return true;
        }

        var current = parent.pages[slice];

        if ( !current ) {
            current = parent.pages[slice] = {
                // duplicate data for more easily parsing
                name: slice,
                // recursive data
                parent: parent,
                // rel_depth: i + 1,
                path: abs
            };

            if ( node_fs.statSync(abs).isDirectory() ) {
                if ( !current.pages ) {
                    current.pages = {};
                }

                current.type = 'folder';
                parent = current;

            } else {
                current.type = 'file';
                // if file occurs, skip parsing
                return true;
            }
        }

        parent = current;
    });
};

// TODO
var REGEX_NAME_SPLITTER = /_/g;
var REGEX_INT = /^\d+$/;

parser.cook_name = function (name) {
    var split = name.split(REGEX_NAME_SPLITTER).filter(Boolean);

    var first = split[0];

    // number string
    if ( REGEX_INT.test(first) ) {
        split.shift();
    }

    return {
        // '01_abc_def' -> 'Abc Def'
        display_name: split.map(function (part) {
            return lang.capitalize(part);
        }).join(' '),

        // '01_abc_def' -> 'abc-def'
        uri_name    : split.map(function (part) {
            return part.toLowerCase();
        }).join('-')
    }
};

// @param {Object=} languages
// {
//     "zh-CN": {
//     }
// }
parser.language_tree = function (raw_tree, languages) {
    if ( lang.isEmptyObject(languages) ) {
        languages = null;
    }

    var ret = {};

    if ( languages ) {
        var root = raw_tree.pages || {};

        lang.each(languages, function (name, language) {
            var root_tree = root[language] || {};
            delete root_tree.parent;

            // it's hard to detect the closest match if user had a wrong configuration
            // convert to lowercase to make it easier
            ret[language.toLowerCase()] = {
                name: name,
                tree: root_tree
            };
        });

        return ret;

    } else {
        return {
            default: {
                tree: raw_tree
            }
        };
    }
};

var SUPPORTED_LANG = Object.keys(highlight.LANGUAGES);

var marked_opt = {
    breaks: false,
    gfm: true,
    langPrefix: 'language-',
    pedantic: false,
    sanitize: false,
    silent: false,
    smartLists: false,
    smartypants: false,
    tables: true,
    highlight: function (code, lang) {
        if ( ~ SUPPORTED_LANG.indexOf(lang) ) {
            return highlight.highlight(lang, code).value;
        } else {
            return highlight.highlightAuto(code).value;
        }
    }
};

// options.
parser.markdown = function (code, callback) {
    marked(code, marked_opt, callback);
};

var REGEX_MATCH_H1 = /<h1>(.*?)<\/h1>/i;

parser.get_title = function (html) {
    html = html || '';

    var match = html.match(REGEX_MATCH_H1);

    return match ? match[1] : undefined;
};

// @param {Object} options
// - define
parser.sort_pages = function (pages) {
    pages.sort(function (a, b) {
        return a.name < b.name ? - 1 : 1;
    });
};

// create a cache
parser.create_data = function (language_tree, callback) {
    var counter = Object.keys(language_tree).length;
    var error;
    var nodes = [];

    function iterator (data, done) {
        var node = data.node;
        var descend = data.descend;

        nodes.push(node);

        if ( node.type === 'file' ) {
            var file = node.path;

            node_fs.readFile(file, function (err, content) {
                if ( err ) {
                    return done(err);
                }

                parser.markdown(content.toString(), function (err, html) {
                    if ( err ) {
                        return done(err);
                    }

                    node.html = html;

                    var title = parser.get_title(html);

                    parser._generate_url(node, title);
                    done(null);
                });
            });

        } else {
            parser._generate_url(node);

            var pages = node.pages;

            if ( pages ) {
                // `pages` from object to array
                node.pages = Object.keys(pages).map(function (name) {
                    return pages[name];
                });

                parser.sort_pages(node.pages);
            }

            descend();
            done(null);
        }
    };

    lang.each(language_tree, function (l, language) {
        parser.walk(l.tree, iterator, function (err) {
            nodes.forEach(function (node) {
                if ( node ) {
                    delete node.parent;
                }
            });

            // free
            nodes.length = 0;

            if ( err ) {
                error = err;
                return callback(err);

            } else if (error) {
                return;

            } else if ( -- counter === 0 ) {
                return callback(null, language_tree);
            }
        });
    });
};

// TODO: #7
parser._generate_url = function (node, name) {
    if ( !node.parent ) {
        node.url = '';
    } else {
        name = name || node.name;

        var cooked = parser.cook_name(name);
        node.display_name = cooked.display_name;
        node.uri_name = cooked.uri_name;

        node.url = node.parent.url + '/' + node.uri_name;
    }
};

// walk and traverse a tree
parser.walk = function (tree, iterator, callback) {
    var q = async.queue(iterator);
    var errors = [];

    q.drain = function () {
        callback( errors.length ? errors : null );
    };

    function walk (node, depth) {
        node.depth = depth;

        q.push({
            node: node,

            // descend a specific node or descend all
            descend: function (sub_node) {
                if ( sub_node ) {
                    walk(sub_node, depth + 1);

                } else if ( node.pages ) {
                    node.pages.forEach(function (sub_node, name) {
                        walk(sub_node, depth + 1);
                    });
                }
            }

        }, function (err){
            if ( err ) {
                errors.push(err);
            }
        });
    }

    walk(tree, 0);
};

<|endoftext|>


<commit_before>var config = {
	"web_service_base": "http://maps.co.mecklenburg.nc.us/rest/",
	"geoserver_base": "http://jimserver.net/geoserver",
	//TD
	"default_map_center": [35.853, -78.746],
	"default_map_zoom": 12,
	"default_map_min_zoom": 10,
	"default_map_max_zoom": 18,
	"base_map_layers": [{
		"id": "osm",
		"name": "Open Street Map",
		"attribution": "Provided by Tiles@Home",
		"wmsurl": "http://tile.openstreetmap.org/{z}/{x}/{y}.png",
		"maxZoom": 20,
		"minZoom": 9,
		"isVisible": false,
		"isBaseLayer": true
	}, {
		"id": "google_sat",
		"name": "Google Satellite",
		"type": google.maps.MapTypeId.SATELLITE,
		"wmsurl": "",
		"isVisible": false,
		"isBaseLayer": true,
		"numZoomLevels": 20
	}, {
		"id": "google_ter",
		"name": "Google Terrain",
		"type": google.maps.MapTypeId.TERRAIN,
		"wmsurl": "",
		"isVisible": false,
		"isBaseLayer": true,
		"numZoomLevels": 16
	},{
		"id": "nconemap",
		"name": "NC OneMap",
		"wmsurl": "http://imagery.nconemap.com/arcgis/services/2010_Orthoimagery/ImageServer/WMSServer",
		"layers": "",
		"format": "image/png",
		"transparent": false,
		"maxZoom": 20,
		"minZoom": 9,
		"isVisible": false,
		"isBaseLayer": true,
                "projection": "EPSG:3857"
	}],
	"overlay_map_layers": [{
		"id": "trails",
		"name": "Named Trails",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "umstead_named_trails",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	}, {
		"id": "footpaths",
		"name": "Footpaths",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "footpaths",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	}, {
		"id": "unpaved_roads",
		"name": "Unpaved Roads",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "unpaved_roads",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	},{
		"id": "paved_roads",
		"name": "Paved Roads, Powerlines",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "paved_roads,powerline",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	},{
		"id": "parks",
		"name": "Parks and Managed Areas",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "umstead_line",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": true,
		"isBaseLayer": false
	}, {
		"id": "nexrad",
		"name": "Nexrad Weather Radar",
		"attribution": "Provided by Iowa State University",
		"wmsurl": "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
		"layers": "nexrad-n0r-900913",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.5,
		"maxZoom": 20,
		"minZoom": 9,
		"isVisible": false,
		"isBaseLayer": false
	}],
        //currently only supports one vector layer
	"vector_map_layer": {
		"id": "facilities",
		"name": "Facilities",
		"wfsurl": "http://localhost/geoserver/wfs",
		"layers": "facilities",
		"switchColumn": "switch_val",
		"switchVals": [{
			"title": "All Facilities",
			"val": "allfac"
		}, {
			"title": "Toilets",
			"val": "toilets"
		}, {
			"title": "Cabins",
			"val": "cabins"
		}, {
			"title": "Campsites",
			"val": "campsites"
		}, {
			"title": "Parking Lots",
			"val": "prklots"
		},  {
			"title": "Park Administration and Maintenance",
			"val": "admin"
		}, {
			"title": "Visitor Facilities",
			"val": "visitor"
		}]
	}
};

<commit_msg>edit config for server<commit_after>var config = {
	"web_service_base": "http://maps.co.mecklenburg.nc.us/rest/",
	"geoserver_base": "http://jimserver.net/geoserver",
	//TD
	"default_map_center": [35.853, -78.746],
	"default_map_zoom": 12,
	"default_map_min_zoom": 10,
	"default_map_max_zoom": 18,
	"base_map_layers": [{
		"id": "osm",
		"name": "Open Street Map",
		"attribution": "Provided by Tiles@Home",
		"wmsurl": "http://tile.openstreetmap.org/{z}/{x}/{y}.png",
		"maxZoom": 20,
		"minZoom": 9,
		"isVisible": false,
		"isBaseLayer": true
	}, {
		"id": "google_sat",
		"name": "Google Satellite",
		"type": google.maps.MapTypeId.SATELLITE,
		"wmsurl": "",
		"isVisible": false,
		"isBaseLayer": true,
		"numZoomLevels": 20
	}, {
		"id": "google_ter",
		"name": "Google Terrain",
		"type": google.maps.MapTypeId.TERRAIN,
		"wmsurl": "",
		"isVisible": false,
		"isBaseLayer": true,
		"numZoomLevels": 16
	},{
		"id": "nconemap",
		"name": "NC OneMap",
		"wmsurl": "http://imagery.nconemap.com/arcgis/services/2010_Orthoimagery/ImageServer/WMSServer",
		"layers": "",
		"format": "image/png",
		"transparent": false,
		"maxZoom": 20,
		"minZoom": 9,
		"isVisible": false,
		"isBaseLayer": true,
                "projection": "EPSG:3857"
	}],
	"overlay_map_layers": [{
		"id": "trails",
		"name": "Named Trails",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "umstead_named_trails",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	}, {
		"id": "footpaths",
		"name": "Footpaths",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "footpaths",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	}, {
		"id": "unpaved_roads",
		"name": "Unpaved Roads",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "unpaved_roads",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	},{
		"id": "paved_roads",
		"name": "Paved Roads, Powerlines",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "paved_roads,powerline",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": false,
		"isBaseLayer": false
	},{
		"id": "parks",
		"name": "Parks and Managed Areas",
		"wmsurl": "http://jimserver.net/geoserver/wms",
		"layers": "umstead_line",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.8,
		"maxZoom": 20,
		"minZoom": 10,
		"isVisible": true,
		"isBaseLayer": false
	}, {
		"id": "nexrad",
		"name": "Nexrad Weather Radar",
		"attribution": "Provided by Iowa State University",
		"wmsurl": "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi",
		"layers": "nexrad-n0r-900913",
		"format": "image/png",
		"transparent": true,
		"opacity": 0.5,
		"maxZoom": 20,
		"minZoom": 9,
		"isVisible": false,
		"isBaseLayer": false
	}],
        //currently only supports one vector layer
	"vector_map_layer": {
		"id": "facilities",
		"name": "Facilities",
		"wfsurl": "http://jimserver.net/geoserver/wfs",
		"layers": "facilities",
		"switchColumn": "switch_val",
		"switchVals": [{
			"title": "All Facilities",
			"val": "allfac"
		}, {
			"title": "Toilets",
			"val": "toilets"
		}, {
			"title": "Cabins",
			"val": "cabins"
		}, {
			"title": "Campsites",
			"val": "campsites"
		}, {
			"title": "Parking Lots",
			"val": "prklots"
		},  {
			"title": "Park Administration and Maintenance",
			"val": "admin"
		}, {
			"title": "Visitor Facilities",
			"val": "visitor"
		}]
	}
};

<|endoftext|>


<commit_before>/**
 * @ngdoc service
 * @name  core.service:WsService
 * @requires ng.$interval
 * @requires ng.$q
 * @requires core.service:AlertService
 *
 * @description
 *  An angular service wrapper for stop communication over websockets.
 *
 */
core.service("WsService", function($interval, $q, AlertService) {

	var WsService = this;

	/**
	 * @ngdoc property
	 * @name  core.service:WsService#WsService.pendingReqCounter
	 * @propertyOf core.service:WsService
	 *
	 * @description
	 *  A count of all unresolved requests.
	 *
	 */
	WsService.pendingReqCounter = 0;

	/**
	 * @ngdoc property
	 * @name  core.service:WsService#WsService.pendingReq
	 * @propertyOf core.service:WsService
	 *
	 * @description
	 *  An object store for pending requests.
	 *
	 */
	WsService.pendingReq = {};

	/**
	 * @ngdoc property
	 * @name  core.service:WsService#WsService.subscriptions
	 * @propertyOf core.service:WsService
	 *
	 * @description
	 *  An object store for subscriptions.
	 *
	 */
	WsService.subscriptions = {};

	/**
	 * @ngdoc method
	 * @name  core.service:WsService#WsService.subscribe
	 * @methodOf core.service:WsService
	 * @param {string} channel
	 *  The channel which will be subscribed to.
	 * @param {boolean=} persist
	 *  Indicates that the subscribe channel should not be removed on view change.
	 *
	 * @description
	 *  Registers a subscription to a stomp channel.
	 *
	 */
	WsService.subscribe = function(channel, persist) {
		var id = "sub-" + window.stompClient.counter;
		var defer;

		if(!persist) persist = false;

		var subObj;

		if((subObj = WsService.subExist(channel))) {
			defer = subObj.defer;
		} else {

			defer = $q.defer();
			subObj = {
				channel: channel,
				defer: defer
			};

			window.stompClient.subscribe(channel, function(data) {

				var meta = JSON.parse(data.body).meta

				var requestId = meta.id ? meta.id : null;
				var response = meta.type;

				if(WsService.pendingReq[requestId]) {

					//logger.info("");
					//logger.debug(channel);
					//logger.info("Resolving Request " + requestId + ": " + WsService.pendingReq[requestId].request);
					//logger.log(JSON.parse(data.body));

					if(response == "REFRESH") {
						WsService.pendingReq[requestId].defer.notify(data);
					} else {
						// We should always resolve to handle alternative notifications.
						WsService.pendingReq[requestId].defer.resolve(data);
						AlertService.add(meta, channel);
						delete WsService.pendingReq[requestId];
					}

				}

				defer.notify(data);

			});

			WsService.subscriptions[id] = subObj;
		}

		return defer.promise;
	};

	/**
	 * @ngdoc method
	 * @name  core.service:WsService#WsService.send
	 * @methodOf core.service:WsService
	 * @param {string} request
	 *  The destination of this request.
	 * @param {object} headers
	 *  An object containing desired stomp headers
	 * @param {object} payload
	 *  An objecct containing any data that should be communicated
	 *  with the request
	 * @param {string} channel
	 *  The chennel which the reseponse will be communicated over.
	 *
	 * @description
	 *  Sends a websocket message.
	 *
	 */
	WsService.send = function(request, headers, payload, channel) {

		if(!WsService.subExist(channel)) {
			var endpoint = channel;
			var controller = channel.substr(0, channel.lastIndexOf("/"));
			AlertService.create(endpoint);
			AlertService.create(controller);
			WsService.subscribe(channel);
		}

		headers.id = WsService.pendingReqCounter++;

		window.stompClient.send(request, headers, payload);

		WsService.pendingReq[headers.id] = {
			defer: $q.defer(),
			timestamp: new Date().getTime(),
			request: request,
			resend: function() {
				headers.jwt = sessionStorage.token;
				window.stompClient.send(request, headers, payload);
			}
		};

		return WsService.pendingReq[headers.id].defer.promise;

	};

	/**
	 * @ngdoc method
	 * @name  core.service:WsService#WsService.subExist
	 * @methodOf core.service:WsService
	 * @param {string} channel
	 *  The channel which is being confirmed.
	 * @returns {boolean|object}
	 *  Returns either false, or the subscription object
	 *  associated with the indicated channel.
	 * @description
	 *  Both requests and confirms the existense of a specific
	 *  subscription.
	 *
	 */
	WsService.subExist = function(channel) {
		for(var key in WsService.subscriptions) {
			var subObj = WsService.subscriptions[key];
			if(subObj.channel == channel) return subObj;
		}
		return false;
	};

	/**
	 * @ngdoc method
	 * @name  core.service:WsService#WsService.unsubscribe
	 * @methodOf core.service:WsService
	 * @param {object} sub
	 *  The subscription which will be unsubscribed to.
	 * @returns {void} returns void
	 *
	 *  @description
	 *   Unsubscribes from the indicated subscription.
	 *
	 */
	WsService.unsubscribe = function(sub) {
		window.stompClient.unsubscribe(sub);
		delete WsService.subscriptions[sub];
	};

	/**
	 * @ngdoc method
	 * @name  core.service:WsService#WsService.unsubscribeAll
	 * @methodOf core.service:WsService
	 * @returns {void} returns void
	 *
	 *  @description
	 *   Unsubscribes from all subscriptions.
	 *
	 */
	WsService.unsubscribeAll = function() {
		for(var key in WsService.subscriptions){
			var sub = WsService.subscriptions[key];
			if(!sub.persist) WsService.unsubscribe(key);
		}
	};

	$interval(function() {

		var now = new Date().getTime();

		for(var req in WsService.pendingReq) {
			if(now - WsService.pendingReq[req].timestamp > 60000) {
				console.log(WsService.pendingReq);
				AlertService.add({type: "WARNING", message: "Web service is taking too long to respond. Please refresh. If this continues to appear you can email helpdesk@library.tamu.edu."}, "/app/warnings");
			}
		}

	}, 10000);

});<commit_msg>Show alert only once and after 2 minutes without response.<commit_after>/**
 * @ngdoc service
 * @name  core.service:WsService
 * @requires ng.$interval
 * @requires ng.$q
 * @requires core.service:AlertService
 *
 * @description
 *  An angular service wrapper for stop communication over websockets.
 *
 */
core.service("WsService", function($interval, $q, AlertService) {

  var WsService = this;

  /**
   * @ngdoc property
   * @name  core.service:WsService#WsService.requestCount
   * @propertyOf core.service:WsService
   *
   * @description
   *  A count of all requests.
   *
   */
  WsService.requestCount = 0;

  /**
   * @ngdoc property
   * @name  core.service:WsService#WsService.pendingReq
   * @propertyOf core.service:WsService
   *
   * @description
   *  An object store for pending requests.
   *
   */
  WsService.pendingReq = {};

  /**
   * @ngdoc property
   * @name  core.service:WsService#WsService.delinquentReq
   * @propertyOf core.service:WsService
   *
   * @description
   *  An object store for delinquent requests.
   *
   */
  WsService.delinquentReq = {};

  /**
   * @ngdoc property
   * @name  core.service:WsService#WsService.subscriptions
   * @propertyOf core.service:WsService
   *
   * @description
   *  An object store for subscriptions.
   *
   */
  WsService.subscriptions = {};

  /**
   * @ngdoc method
   * @name  core.service:WsService#WsService.subscribe
   * @methodOf core.service:WsService
   * @param {string} channel
   *  The channel which will be subscribed to.
   * @param {boolean=} persist
   *  Indicates that the subscribe channel should not be removed on view change.
   *
   * @description
   *  Registers a subscription to a stomp channel.
   *
   */
  WsService.subscribe = function(channel, persist) {
    var id = "sub-" + window.stompClient.counter;
    var defer;

    if (!persist) persist = false;

    var subObj;

    if ((subObj = WsService.subExist(channel))) {
      defer = subObj.defer;
    } else {

      defer = $q.defer();
      subObj = {
        channel: channel,
        defer: defer
      };

      window.stompClient.subscribe(channel, function(data) {

        var meta = JSON.parse(data.body).meta

        var requestId = meta.id ? meta.id : null;
        var response = meta.type;

        if (WsService.pendingReq[requestId]) {

          //logger.info("");
          //logger.debug(channel);
          //logger.info("Resolving Request " + requestId + ": " + WsService.pendingReq[requestId].request);
          //logger.log(JSON.parse(data.body));

          if (response == "REFRESH") {
            WsService.pendingReq[requestId].defer.notify(data);
          } else {
            // We should always resolve to handle alternative notifications.
            WsService.pendingReq[requestId].defer.resolve(data);
            AlertService.add(meta, channel);
            delete WsService.pendingReq[requestId];
          }

        }

        defer.notify(data);

      });

      WsService.subscriptions[id] = subObj;
    }

    return defer.promise;
  };

  /**
   * @ngdoc method
   * @name  core.service:WsService#WsService.send
   * @methodOf core.service:WsService
   * @param {string} request
   *  The destination of this request.
   * @param {object} headers
   *  An object containing desired stomp headers
   * @param {object} payload
   *  An objecct containing any data that should be communicated
   *  with the request
   * @param {string} channel
   *  The chennel which the reseponse will be communicated over.
   *
   * @description
   *  Sends a websocket message.
   *
   */
  WsService.send = function(request, headers, payload, channel) {

    if (!WsService.subExist(channel)) {
      var endpoint = channel;
      var controller = channel.substr(0, channel.lastIndexOf("/"));
      AlertService.create(endpoint);
      AlertService.create(controller);
      WsService.subscribe(channel);
    }

    headers.id = WsService.requestCount++;

    window.stompClient.send(request, headers, payload);

    WsService.pendingReq[headers.id] = {
      defer: $q.defer(),
      timestamp: new Date().getTime(),
      request: request,
      resend: function() {
        headers.jwt = sessionStorage.token;
        window.stompClient.send(request, headers, payload);
      }
    };

    return WsService.pendingReq[headers.id].defer.promise;

  };

  /**
   * @ngdoc method
   * @name  core.service:WsService#WsService.subExist
   * @methodOf core.service:WsService
   * @param {string} channel
   *  The channel which is being confirmed.
   * @returns {boolean|object}
   *  Returns either false, or the subscription object
   *  associated with the indicated channel.
   * @description
   *  Both requests and confirms the existense of a specific
   *  subscription.
   *
   */
  WsService.subExist = function(channel) {
    for (var key in WsService.subscriptions) {
      var subObj = WsService.subscriptions[key];
      if (subObj.channel == channel) return subObj;
    }
    return false;
  };

  /**
   * @ngdoc method
   * @name  core.service:WsService#WsService.unsubscribe
   * @methodOf core.service:WsService
   * @param {object} sub
   *  The subscription which will be unsubscribed to.
   * @returns {void} returns void
   *
   *  @description
   *   Unsubscribes from the indicated subscription.
   *
   */
  WsService.unsubscribe = function(sub) {
    window.stompClient.unsubscribe(sub);
    delete WsService.subscriptions[sub];
  };

  /**
   * @ngdoc method
   * @name  core.service:WsService#WsService.unsubscribeAll
   * @methodOf core.service:WsService
   * @returns {void} returns void
   *
   *  @description
   *   Unsubscribes from all subscriptions.
   *
   */
  WsService.unsubscribeAll = function() {
    for (var key in WsService.subscriptions) {
      var sub = WsService.subscriptions[key];
      if (!sub.persist) WsService.unsubscribe(key);
    }
  };

  $interval(function() {

    var now = new Date().getTime();

    for (var req in WsService.pendingReq) {
      if (now - WsService.pendingReq[req].timestamp > 120000) {
        if (WsService.delinquentReq[req] === undefined) {
          WsService.delinquentReq[req] = WsService.pendingReq[req];
          AlertService.add({
            type: "WARNING",
            message: "Web service is taking too long to respond. Please refresh. If this continues to appear you can email helpdesk@library.tamu.edu."
          }, "/app/warnings");
        }
      }
    }

  }, 10000);

});
<|endoftext|>


<commit_before>/*!
 * Sitemap
 * Copyright(c) 2011 Eugene Kalinin
 * MIT Licensed
 */

var Rule = require('./rule').Rule
  , Entry = require('./entry').Entry
  , urlparser = require('url')
  , http = require('http')
  , ut = require('./utils');

exports.RobotsParser = RobotsParser;

/**
 * Provides a set of methods to read, parse and answer
 * questions about a single robots.txt file.
 *
 * @param {String} url
 * @param {String} userAgent User-Agent for fetching robots.txt
 */
function RobotsParser (url, userAgent) {
  this.entries = [];
  this.defaultEntry = '';
  this.disallowAll = false;
  this.allowAll = false;
  this.setUrl(url);
  this.userAgent = userAgent || 'User-Agent: Mozilla/5.0 '+
                                '(X11; Linux i686; rv:5.0) '+
                                'Gecko/20100101 Firefox/5.0';
}

/**
 * Sets the URL referring to a robots.txt file
 *
 * @param {String} url
 * @param {String} read   Optional, default=true. Immediate read robots.txt
 *
 */
RobotsParser.prototype.setUrl = function(url, read) {
  this.url = url;
  if( url && (read === undefined || read === null || read === true)) {
    this.read();
  }
};

/**
 * Reads the robots.txt URL and feeds it to the parser
 *
 */
RobotsParser.prototype.read = function() {
  var self = this
    , url = urlparser.parse(this.url)
    , client = http.createClient(url.port || 80, url.host)
    , request = client.request("GET", url.pathname, {
        'host'        : url.host,
        "User-Agent"  : self.userAgent,
      });

  ut.d('RobotsParser.read: start ...');

  request.on('response', function(resp) {
    ut.d('RobotsParser.read: get response, code: '+resp.statusCode);

    if ( [401, 403].indexOf(resp.statusCode) > -1 ) {
      ut.d('RobotsParser.read: set disallowAll');
      self.disallowAll = true;
    }
    else if (resp.statusCode >= 400) {
      ut.d('RobotsParser.read: set allowAll');
      self.allowAll = true;
    }
    else {
      resp.setEncoding('utf8');
      resp.on('data', function (chunk) {
        ut.d('RobotsParser.read: reads robots.txt');
        self.parse(chunk.split(/\r\n|\r|\n/));
      });
    }
  });
  request.end();
};

/**
 * Adds entry
 *
 * @private
 * @param {Entry} entry
 */
RobotsParser.prototype._addEntry = function(entry) {
  ut.d('Parser._addEntry, entry: '+entry);
  if( entry.userAgents.indexOf('*') > -1 ) {
    // the default entry is considered last
    // the first default entry wins
    if ( !this.defaultEntry ) {
      this.defaultEntry = entry;
    }
  }
  else {
    this.entries.push(entry);
  }
};

/**
 * Parse the input lines from a robots.txt file.
 *
 * We allow that a user-agent: line is not preceded by
 * one or more blank lines.
 *
 * @param {Array} lines Array of rows from robots.txt
 */
RobotsParser.prototype.parse = function(lines) {
  // states:
  //    0: start state
  //    1: saw user-agent line
  //    2: saw an allow or disallow line
  var STATE_START = 0
    , STATE_SAW_AGENT = 1
    , STATE_SAW_ALLOW_OR_DISALLOW = 2
    , state = STATE_START
    , entry = new Entry()
    , line
    , comment
    , field
    , value;

  for (var i = 0; i < lines.length; i++) {
    line = lines[i];

    if (!line) {
      if (state === STATE_SAW_AGENT) {
        entry = new Entry();
        state = STATE_START;
      }
      else if (state === STATE_SAW_ALLOW_OR_DISALLOW) {
        this._addEntry(entry);
        entry = new Entry();
        state = STATE_START;
      }
    }

    // remove optional comment and strip line
    comment = line.indexOf('#')
    if (comment > -1) {
      line = line.substring(0, comment);
    }

    // strip line
    line = line.replace(/^\s+|\s+$/g, '');
    // find 'field:value'
    line = line.split(':');
    if (line.length !== 2) {
      continue;
    }

    field = line[0].replace(/^\s+|\s+$/g, '').toLowerCase();
    value = line[1].replace(/^\s+|\s+$/g, '');

    switch(field) {
      case 'user-agent':
        if (state === STATE_SAW_ALLOW_OR_DISALLOW) {
          this._addEntry(entry);
          entry = new Entry();
        }
        entry.userAgents.push(value);
        state = STATE_SAW_AGENT;
        break;

      case 'disallow':
        if (state !== STATE_START) {
          entry.rules.push(new Rule(value, false));
          state = STATE_SAW_ALLOW_OR_DISALLOW;
        }
        break;

      case 'allow':
        if (state !== STATE_START) {
          entry.rules.push(new Rule(value, true));
          state = STATE_SAW_ALLOW_OR_DISALLOW;
        }
        break;
    }
  };

  if (state === STATE_SAW_ALLOW_OR_DISALLOW) {
    this._addEntry(entry);
  }
};

/**
 * Using the parsed robots.txt decide if userAgent can fetch url.
 *
 * @param {String} userAgent
 * @param {String} url
 * @return {Boolean}
 *
 */
RobotsParser.prototype.canFetch = function(userAgent, url) {
  var url = url || '/'
    , entry;

  ut.d('Parser.canFetch: url:'+url);

  if (this.disallowAll) {
    return false;
  }
  if (this.allowAll) {
    return true;
  }

  // search for given user agent matches
  // the first match counts
  for (var i = 0; i < this.entries.length; i++) {
    entry = this.entries[i];
    if (entry.appliesTo(userAgent)) {
      return entry.allowance(url);
    }
  };

  // try the default entry last
  if (this.defaultEntry) {
    return this.defaultEntry.allowance(url);
  }

  // agent not found ==> access granted
  return true;
};
<commit_msg>immediate parse used actual user-agent<commit_after>/*!
 * Sitemap
 * Copyright(c) 2011 Eugene Kalinin
 * MIT Licensed
 */

var Rule = require('./rule').Rule
  , Entry = require('./entry').Entry
  , urlparser = require('url')
  , http = require('http')
  , ut = require('./utils');

exports.RobotsParser = RobotsParser;

/**
 * Provides a set of methods to read, parse and answer
 * questions about a single robots.txt file.
 *
 * @constructor
 * @param {String} url
 * @param {String} userAgent User-Agent for fetching robots.txt
 */
function RobotsParser (url, userAgent) {
  this.entries = [];
  this.defaultEntry = '';
  this.disallowAll = false;
  this.allowAll = false;
  this.userAgent = userAgent || 'User-Agent: Mozilla/5.0 '+
                                '(X11; Linux i686; rv:5.0) '+
                                'Gecko/20100101 Firefox/5.0';
  this.setUrl(url);
}

/**
 * Sets the URL referring to a robots.txt file
 *
 * @param {String} url
 * @param {String} read   Optional, default=true. Immediate read robots.txt
 *
 */
RobotsParser.prototype.setUrl = function(url, read) {
  this.url = url;
  if( url && (read === undefined || read === null || read === true)) {
    this.read();
  }
};

/**
 * Reads the robots.txt URL and feeds it to the parser
 *
 */
RobotsParser.prototype.read = function() {
  var self = this
    , url = urlparser.parse(this.url)
    , client = http.createClient(url.port || 80, url.host)
    , request = client.request("GET", url.pathname, {
        'host'        : url.host,
        "User-Agent"  : self.userAgent,
      });

  ut.d('RobotsParser.read: start ...');

  request.on('response', function(resp) {
    ut.d('RobotsParser.read: get response, code: '+resp.statusCode);

    if ( [401, 403].indexOf(resp.statusCode) > -1 ) {
      ut.d('RobotsParser.read: set disallowAll');
      self.disallowAll = true;
    }
    else if (resp.statusCode >= 400) {
      ut.d('RobotsParser.read: set allowAll');
      self.allowAll = true;
    }
    else {
      resp.setEncoding('utf8');
      resp.on('data', function (chunk) {
        ut.d('RobotsParser.read: reads robots.txt');
        self.parse(chunk.split(/\r\n|\r|\n/));
      });
    }
  });
  request.end();
};

/**
 * Adds entry
 *
 * @private
 * @param {Entry} entry
 */
RobotsParser.prototype._addEntry = function(entry) {
  ut.d('Parser._addEntry, entry: '+entry);
  if( entry.userAgents.indexOf('*') > -1 ) {
    // the default entry is considered last
    // the first default entry wins
    if ( !this.defaultEntry ) {
      this.defaultEntry = entry;
    }
  }
  else {
    this.entries.push(entry);
  }
};

/**
 * Parse the input lines from a robots.txt file.
 *
 * We allow that a user-agent: line is not preceded by
 * one or more blank lines.
 *
 * @param {Array} lines Array of rows from robots.txt
 */
RobotsParser.prototype.parse = function(lines) {
  // states:
  //    0: start state
  //    1: saw user-agent line
  //    2: saw an allow or disallow line
  var STATE_START = 0
    , STATE_SAW_AGENT = 1
    , STATE_SAW_ALLOW_OR_DISALLOW = 2
    , state = STATE_START
    , entry = new Entry()
    , line
    , comment
    , field
    , value;

  for (var i = 0; i < lines.length; i++) {
    line = lines[i];

    if (!line) {
      if (state === STATE_SAW_AGENT) {
        entry = new Entry();
        state = STATE_START;
      }
      else if (state === STATE_SAW_ALLOW_OR_DISALLOW) {
        this._addEntry(entry);
        entry = new Entry();
        state = STATE_START;
      }
    }

    // remove optional comment and strip line
    comment = line.indexOf('#')
    if (comment > -1) {
      line = line.substring(0, comment);
    }

    // strip line
    line = line.replace(/^\s+|\s+$/g, '');
    // find 'field:value'
    line = line.split(':');
    if (line.length !== 2) {
      continue;
    }

    field = line[0].replace(/^\s+|\s+$/g, '').toLowerCase();
    value = line[1].replace(/^\s+|\s+$/g, '');

    switch(field) {
      case 'user-agent':
        if (state === STATE_SAW_ALLOW_OR_DISALLOW) {
          this._addEntry(entry);
          entry = new Entry();
        }
        entry.userAgents.push(value);
        state = STATE_SAW_AGENT;
        break;

      case 'disallow':
        if (state !== STATE_START) {
          entry.rules.push(new Rule(value, false));
          state = STATE_SAW_ALLOW_OR_DISALLOW;
        }
        break;

      case 'allow':
        if (state !== STATE_START) {
          entry.rules.push(new Rule(value, true));
          state = STATE_SAW_ALLOW_OR_DISALLOW;
        }
        break;
    }
  };

  if (state === STATE_SAW_ALLOW_OR_DISALLOW) {
    this._addEntry(entry);
  }
};

/**
 * Using the parsed robots.txt decide if userAgent can fetch url.
 *
 * @param {String} userAgent
 * @param {String} url
 * @return {Boolean}
 *
 */
RobotsParser.prototype.canFetch = function(userAgent, url) {
  var url = url || '/'
    , entry;

  ut.d('Parser.canFetch: url:'+url);

  if (this.disallowAll) {
    return false;
  }
  if (this.allowAll) {
    return true;
  }

  // search for given user agent matches
  // the first match counts
  for (var i = 0; i < this.entries.length; i++) {
    entry = this.entries[i];
    if (entry.appliesTo(userAgent)) {
      return entry.allowance(url);
    }
  };

  // try the default entry last
  if (this.defaultEntry) {
    return this.defaultEntry.allowance(url);
  }

  // agent not found ==> access granted
  return true;
};
<|endoftext|>


<commit_before>/* global app */
app.config = {};

app.config.platform = 'ios';
app.config.codeType = 'javascript';
app.config.cdn = 'https://unpkg.com/';
app.config.ci = 'https://circleci.com/api/v1/project/OnsenUI/OnsenUI/latest/artifacts/0/$CIRCLE_ARTIFACTS/';
app.config.nightly = window.sessionStorage.getItem('nightly') === 'true';

// Enables local lib versions
if ((window.location.hostname === 'localhost' || window.location.hostname.match(/[0-9.]+/)) && window.location.pathname.indexOf('/tutorial/') === 0) {
  app.config.local = true;
}

app.config.getCdnUrl = function(lib, path, forceRemote, skipNightly) {
  // Fetch from local disk
  if (app.config.local === true && !forceRemote) {
    let directory = '../../OnsenUI/';
    if (lib === 'onsenui') {
      directory += 'build/';
    } else {
      directory += `bindings/${lib.split('-')[0]}/`;
    }

    return directory + path;
  }

  // Fetch from remote CDN

  // CORS browser issue with fonts from the same server
  if (skipNightly) {
    return `${app.config.cdn}${lib}${!app.config.versions.onsenui || app.config.nightly ? '' : ('@' + app.config.versions.onsenui)}/${path}`;
  }

  var url = app.config.nightly ? app.config.ci : app.config.cdn;
  url += `${lib}${(app.config.versions[lib] && !app.config.nightly ? ('@' + app.config.versions[lib]) : '')}/${path}`;

  if (app.config.nightly) {
    url += '?branch=master&filter=successful';
  }
  return url;
};

app.config.ownLibs = ['onsenui', 'react-onsenui', 'angular2-onsenui', 'vue-onsenui'];
app.config.extLibs = ['react', 'angular1', 'angular2', 'vue'];
app.config.defaultVersions = {
  react: '15.4.2',
  angular1: '1.5.5',
  angular2: '2.0.0',
  vue: '2.3.0'
};

app.config.versions = {};
(app.config.ownLibs.concat(app.config.extLibs)).forEach(function(key) {
  app.config.versions[key] = window.sessionStorage.getItem(key + '-version') || app.config.defaultVersions[key];
});

app.config.ownLibs.forEach(function (libName) {
  if (app.config.local) {
    console.info(`Using local version of ${libName}.js`);
  } else if (app.config.nightly) {
    console.info(`Using ${libName}.js nightly build`);
  } else if (app.config.versions[libName]) {
    console.info(`Using ${libName}.js ${app.config.versions[libName]}`);
  } else {
    console.info(`Using latest release of ${libName}.js`);
  }
});

app.config.lib = function(forceRemote) {
  return {
    js: {
      // Vanilla
      onsenui: app.config.getCdnUrl('onsenui', 'js/onsenui.js', forceRemote),
      // AngularJS
      angular1: `https://cdnjs.cloudflare.com/ajax/libs/angular.js/${app.config.versions.angular1}/angular.min.js`,
      angularOnsenui: app.config.getCdnUrl('onsenui', 'js/angular-onsenui.js', forceRemote),
      // React
      react: `https://cdnjs.cloudflare.com/ajax/libs/react/${app.config.versions.react}/react.min.js`,
      reactDom: `https://cdnjs.cloudflare.com/ajax/libs/react/${app.config.versions.react}/react-dom.min.js`,
      reactOnsenui: app.config.getCdnUrl('react-onsenui', 'dist/react-onsenui.js', forceRemote),
      // Vue
      vue: `https://cdnjs.cloudflare.com/ajax/libs/vue/${app.config.versions.vue}/vue.js`,
      vueOnsenui: app.config.getCdnUrl('vue-onsenui', 'dist/vue-onsenui.js', forceRemote),
      // Angular 2
      zone: `https://unpkg.com/zone.js@0.6.21/dist/zone.min.js`,
      corejs: `https://unpkg.com/core-js@2.4.1/client/core.min.js`,
      systemjs: `https://unpkg.com/systemjs@0.19.37/dist/system.js`
    },
    css: {
      onsenui: app.config.getCdnUrl('onsenui', 'css/onsenui.css', forceRemote, true),
      onsenuiCssComponents: app.config.getCdnUrl('onsenui', 'css/onsen-css-components.css', forceRemote)
    }
  };
};

app.config.transpilerLib = {
  'babel': "https://unpkg.com/babel-standalone/babel.min.js",
  'typescript': "https://cdnjs.cloudflare.com/ajax/libs/typescript/2.2.0/typescript.min.js"
};

<commit_msg>Fix babel version.<commit_after>/* global app */
app.config = {};

app.config.platform = 'ios';
app.config.codeType = 'javascript';
app.config.cdn = 'https://unpkg.com/';
app.config.ci = 'https://circleci.com/api/v1/project/OnsenUI/OnsenUI/latest/artifacts/0/$CIRCLE_ARTIFACTS/';
app.config.nightly = window.sessionStorage.getItem('nightly') === 'true';

// Enables local lib versions
if ((window.location.hostname === 'localhost' || window.location.hostname.match(/[0-9.]+/)) && window.location.pathname.indexOf('/tutorial/') === 0) {
  app.config.local = true;
}

app.config.getCdnUrl = function(lib, path, forceRemote, skipNightly) {
  // Fetch from local disk
  if (app.config.local === true && !forceRemote) {
    let directory = '../../OnsenUI/';
    if (lib === 'onsenui') {
      directory += 'build/';
    } else {
      directory += `bindings/${lib.split('-')[0]}/`;
    }

    return directory + path;
  }

  // Fetch from remote CDN

  // CORS browser issue with fonts from the same server
  if (skipNightly) {
    return `${app.config.cdn}${lib}${!app.config.versions.onsenui || app.config.nightly ? '' : ('@' + app.config.versions.onsenui)}/${path}`;
  }

  var url = app.config.nightly ? app.config.ci : app.config.cdn;
  url += `${lib}${(app.config.versions[lib] && !app.config.nightly ? ('@' + app.config.versions[lib]) : '')}/${path}`;

  if (app.config.nightly) {
    url += '?branch=master&filter=successful';
  }
  return url;
};

app.config.ownLibs = ['onsenui', 'react-onsenui', 'angular2-onsenui', 'vue-onsenui'];
app.config.extLibs = ['react', 'angular1', 'angular2', 'vue'];
app.config.defaultVersions = {
  react: '15.4.2',
  angular1: '1.5.5',
  angular2: '2.0.0',
  vue: '2.3.0'
};

app.config.versions = {};
(app.config.ownLibs.concat(app.config.extLibs)).forEach(function(key) {
  app.config.versions[key] = window.sessionStorage.getItem(key + '-version') || app.config.defaultVersions[key];
});

app.config.ownLibs.forEach(function (libName) {
  if (app.config.local) {
    console.info(`Using local version of ${libName}.js`);
  } else if (app.config.nightly) {
    console.info(`Using ${libName}.js nightly build`);
  } else if (app.config.versions[libName]) {
    console.info(`Using ${libName}.js ${app.config.versions[libName]}`);
  } else {
    console.info(`Using latest release of ${libName}.js`);
  }
});

app.config.lib = function(forceRemote) {
  return {
    js: {
      // Vanilla
      onsenui: app.config.getCdnUrl('onsenui', 'js/onsenui.js', forceRemote),
      // AngularJS
      angular1: `https://cdnjs.cloudflare.com/ajax/libs/angular.js/${app.config.versions.angular1}/angular.min.js`,
      angularOnsenui: app.config.getCdnUrl('onsenui', 'js/angular-onsenui.js', forceRemote),
      // React
      react: `https://cdnjs.cloudflare.com/ajax/libs/react/${app.config.versions.react}/react.min.js`,
      reactDom: `https://cdnjs.cloudflare.com/ajax/libs/react/${app.config.versions.react}/react-dom.min.js`,
      reactOnsenui: app.config.getCdnUrl('react-onsenui', 'dist/react-onsenui.js', forceRemote),
      // Vue
      vue: `https://cdnjs.cloudflare.com/ajax/libs/vue/${app.config.versions.vue}/vue.js`,
      vueOnsenui: app.config.getCdnUrl('vue-onsenui', 'dist/vue-onsenui.js', forceRemote),
      // Angular 2
      zone: `https://unpkg.com/zone.js@0.6.21/dist/zone.min.js`,
      corejs: `https://unpkg.com/core-js@2.4.1/client/core.min.js`,
      systemjs: `https://unpkg.com/systemjs@0.19.37/dist/system.js`
    },
    css: {
      onsenui: app.config.getCdnUrl('onsenui', 'css/onsenui.css', forceRemote, true),
      onsenuiCssComponents: app.config.getCdnUrl('onsenui', 'css/onsen-css-components.css', forceRemote)
    }
  };
};

app.config.transpilerLib = {
  'babel': "https://unpkg.com/babel-standalone@6.24.0/babel.min.js",
  'typescript': "https://cdnjs.cloudflare.com/ajax/libs/typescript/2.2.0/typescript.min.js"
};

<|endoftext|>


<commit_before>/**
 * Created by helge on 24.08.16.
 */
import React from 'react';
import { createStructuredSelector } from 'reselect';
import { connect } from 'react-redux';
import Grid from 'grid-styled';

import * as LocalStorage from '../../services/localStorage';
import { makeSelectPrivKey } from '../AccountProvider/selectors';
import {
  makeHandStateSelector,
  makePotSizeSelector,
  makeMyMaxBetSelector,
  makeAmountSelector,
  makeMyStackSelector,
  makeMyPosSelector,
  makeMinSelector,
  makeMaxSelector,
  makeIsMyTurnSelector,
} from '../Table/selectors';

import { setCards } from '../Table/actions';
import Button from '../../components/Button';
import Slider from '../../components/Slider';
import ActionBarComponent from '../../components/ActionBar';
import TableService from '../../services/tableService';

class ActionBar extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function

  constructor(props) {
    super(props);
    this.handleBet = this.handleBet.bind(this);
    this.handleCheck = this.handleCheck.bind(this);
    this.handleShow = this.handleShow.bind(this);
    this.handleFold = this.handleFold.bind(this);
    this.table = new TableService(props.params.tableAddr, this.props.privKey);
  }

  componentWillReceiveProps(nextProps) {
    // use this function to dispatch auto actions
    const key = `${nextProps.params.tableAddr}-${nextProps.params.handId}-${nextProps.myPos}`;
    this.cards = LocalStorage.getItem(key);
  }

  setActive(active) {
    this.setState({ active });
  }

  updateValue(e) {
    const amount = (e.target.value > this.props.stackSize) ? this.props.stackSize : e.target.value;
    this.setState({ amount });
  }

  handleBet() {
    this.setActive(false);
    const amount = (this.state) ? parseInt(this.state.amount, 10) : this.props.stepAndMin;
    const handId = parseInt(this.props.params.handId, 10);
    return this.table.bet(handId, amount).catch((err) => {
      console.log(err);
      this.setActive(true);
    }).then((data) => {
      this.props.setCards(this.props.params.tableAddr, handId, data.cards);
    });
  }

  handleCheck() {
    this.setActive(false);
    const amount = this.props.myMaxBet;
    const state = this.props.state;
    const handId = parseInt(this.props.params.handId, 10);
    let call;
    switch (state) {
      case 'turn': {
        call = this.table.checkTurn(handId, amount);
        break;
      }
      case 'river': {
        call = this.table.checkRiver(handId, amount);
        break;
      }
      default: {
        call = this.table.checkFlop(handId, amount);
      }
    }
    return call.catch((err) => {
      console.log(err);
      this.setActive(true);
    });
  }

  handleShow() {
    this.setActive(false);
    const amount = this.props.myMaxBet;
    const cards = this.props.me.cards;
    const handId = parseInt(this.props.params.handId, 10);
    return this.table.show(handId, amount, cards).catch((err) => {
      console.log(err);
      this.setActive(true);
    });
  }

  handleFold() {
    this.setActive(false);
    const amount = this.props.myMaxBet;
    const handId = parseInt(this.props.params.handId, 10);
    return this.table.fold(handId, amount).catch((err) => {
      console.log(err);
      this.setActive(true);
    });
  }

  render() {
    // const state = this.props.state;
    const active = (this.state) ? this.state.active : true;
    if (active) {
      return (
        <ActionBarComponent>
          <Grid xs={1 / 2}>{this.props.stepAndMin}</Grid>
          <Grid xs={1 / 2}>{(this.state) ? this.state.amount : ''}</Grid>
          <Grid xs={1 / 1}>
            <Slider
              max={this.props.max}
              min={this.props.stepAndMin}
              step={this.props.stepAndMin}
              onChange={(e) => this.updateValue(e)}
            >
            </Slider>
          </Grid>
          <Grid xs={1 / 3}>
            <Button size="large" onClick={this.handleBet}>Bet</Button>
          </Grid>
          <Grid xs={1 / 3}>
            <Button size="large" onClick={this.handleCheck}>Check</Button>
          </Grid>
          <Grid xs={1 / 3}>
            <Button size="large" onClick={this.handleFold}>Fold</Button>
          </Grid>
        </ActionBarComponent>
      );
    }
    return null;
  }
}

export function mapDispatchToProps() {
  return {
    setCards: (tableAddr, handId, cards) => setCards(tableAddr, handId, cards),
  };
}

const mapStateToProps = createStructuredSelector({
  privKey: makeSelectPrivKey(),
  amount: makeAmountSelector(),
  potSize: makePotSizeSelector(),
  myMaxBet: makeMyMaxBetSelector(),
  stackSize: makeMyStackSelector(),
  myPos: makeMyPosSelector(),
  isMyTurn: makeIsMyTurnSelector(),
  stepAndMin: makeMinSelector(),
  max: makeMaxSelector(),
  state: makeHandStateSelector(),
});

ActionBar.propTypes = {
  params: React.PropTypes.object,
  privKey: React.PropTypes.string,
  cards: React.PropTypes.array,
  myMaxBet: React.PropTypes.number,
  stepAndMin: React.PropTypes.number,
  max: React.PropTypes.number,
  // isMyTurn: React.PropTypes.bool,
  state: React.PropTypes.string,
  stackSize: React.PropTypes.number,
  me: React.PropTypes.object,
  setCards: React.PropTypes.func,
};

export default connect(mapStateToProps, mapDispatchToProps)(ActionBar);
<commit_msg>action bar not disappaering on sliding<commit_after>/**
 * Created by helge on 24.08.16.
 */
import React from 'react';
import { createStructuredSelector } from 'reselect';
import { connect } from 'react-redux';
import Grid from 'grid-styled';

import * as LocalStorage from '../../services/localStorage';
import { makeSelectPrivKey } from '../AccountProvider/selectors';
import {
  makeHandStateSelector,
  makePotSizeSelector,
  makeMyMaxBetSelector,
  makeAmountSelector,
  makeMyStackSelector,
  makeMyPosSelector,
  makeMinSelector,
  makeMaxSelector,
  makeIsMyTurnSelector,
} from '../Table/selectors';

import { setCards } from '../Table/actions';
import Button from '../../components/Button';
import Slider from '../../components/Slider';
import ActionBarComponent from '../../components/ActionBar';
import TableService from '../../services/tableService';

class ActionBar extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function

  constructor(props) {
    super(props);
    this.handleBet = this.handleBet.bind(this);
    this.handleCheck = this.handleCheck.bind(this);
    this.handleShow = this.handleShow.bind(this);
    this.handleFold = this.handleFold.bind(this);
    this.table = new TableService(props.params.tableAddr, this.props.privKey);
  }

  componentWillReceiveProps(nextProps) {
    // use this function to dispatch auto actions
    const key = `${nextProps.params.tableAddr}-${nextProps.params.handId}-${nextProps.myPos}`;
    this.cards = LocalStorage.getItem(key);
  }

  setActive(active) {
    this.setState({ active });
  }

  updateValue(e) {
    const amount = (e.target.value > this.props.stackSize) ? this.props.stackSize : e.target.value;
    this.setState({ amount });
  }

  handleBet() {
    this.setActive(false);
    const amount = (this.state) ? parseInt(this.state.amount, 10) : this.props.stepAndMin;
    const handId = parseInt(this.props.params.handId, 10);
    return this.table.bet(handId, amount).catch((err) => {
      console.log(err);
      this.setActive(true);
    }).then((data) => {
      this.props.setCards(this.props.params.tableAddr, handId, data.cards);
    });
  }

  handleCheck() {
    this.setActive(false);
    const amount = this.props.myMaxBet;
    const state = this.props.state;
    const handId = parseInt(this.props.params.handId, 10);
    let call;
    switch (state) {
      case 'turn': {
        call = this.table.checkTurn(handId, amount);
        break;
      }
      case 'river': {
        call = this.table.checkRiver(handId, amount);
        break;
      }
      default: {
        call = this.table.checkFlop(handId, amount);
      }
    }
    return call.catch((err) => {
      console.log(err);
      this.setActive(true);
    });
  }

  handleShow() {
    this.setActive(false);
    const amount = this.props.myMaxBet;
    const cards = this.props.me.cards;
    const handId = parseInt(this.props.params.handId, 10);
    return this.table.show(handId, amount, cards).catch((err) => {
      console.log(err);
      this.setActive(true);
    });
  }

  handleFold() {
    this.setActive(false);
    const amount = this.props.myMaxBet;
    const handId = parseInt(this.props.params.handId, 10);
    return this.table.fold(handId, amount).catch((err) => {
      console.log(err);
      this.setActive(true);
    });
  }

  render() {
    // const state = this.props.state;
    const active = (this.state && this.state.active !== undefined) ? this.state.active : true;
    if (active) {
      return (
        <ActionBarComponent>
          <Grid xs={1 / 2}>{this.props.stepAndMin}</Grid>
          <Grid xs={1 / 2}>{(this.state) ? this.state.amount : ''}</Grid>
          <Grid xs={1 / 1}>
            <Slider
              max={this.props.max}
              min={this.props.stepAndMin}
              step={this.props.stepAndMin}
              onChange={(e) => this.updateValue(e)}
            >
            </Slider>
          </Grid>
          <Grid xs={1 / 3}>
            <Button size="large" onClick={this.handleBet}>Bet</Button>
          </Grid>
          <Grid xs={1 / 3}>
            <Button size="large" onClick={this.handleCheck}>Check</Button>
          </Grid>
          <Grid xs={1 / 3}>
            <Button size="large" onClick={this.handleFold}>Fold</Button>
          </Grid>
        </ActionBarComponent>
      );
    }
    return null;
  }
}

export function mapDispatchToProps() {
  return {
    setCards: (tableAddr, handId, cards) => setCards(tableAddr, handId, cards),
  };
}

const mapStateToProps = createStructuredSelector({
  privKey: makeSelectPrivKey(),
  amount: makeAmountSelector(),
  potSize: makePotSizeSelector(),
  myMaxBet: makeMyMaxBetSelector(),
  stackSize: makeMyStackSelector(),
  myPos: makeMyPosSelector(),
  isMyTurn: makeIsMyTurnSelector(),
  stepAndMin: makeMinSelector(),
  max: makeMaxSelector(),
  state: makeHandStateSelector(),
});

ActionBar.propTypes = {
  params: React.PropTypes.object,
  privKey: React.PropTypes.string,
  cards: React.PropTypes.array,
  myMaxBet: React.PropTypes.number,
  stepAndMin: React.PropTypes.number,
  max: React.PropTypes.number,
  // isMyTurn: React.PropTypes.bool,
  state: React.PropTypes.string,
  stackSize: React.PropTypes.number,
  me: React.PropTypes.object,
  setCards: React.PropTypes.func,
};

export default connect(mapStateToProps, mapDispatchToProps)(ActionBar);
<|endoftext|>


<commit_before>// for navigator language
var lang = window.navigator.language;
// you can change the language
// var lang = 'en';

//change weather params here:
//units: metric or imperial
var weatherParams = {
    'q':'Baarn,Netherlands',
    'units':'metric',
    'lang':lang
};

var feed = 'http://feeds.nos.nl/nosjournaal?format=rss';
//var feed = 'http://www.nu.nl/feeds/rss/achterklap.rss';
//var feed = 'http://www.nu.nl/feeds/rss/opmerkelijk.rss';
//var feed = 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml';

// compliments:
var morning = [
            'Good morning, handsome!',
            'Enjoy your day!',
            'How was your sleep?'
        ];

var afternoon = [
            'Hello, beauty!',
            'You look sexy!',
            'Looking good today!'
        ];

var evening = [
            'Wow, you look hot!',
            'You look nice!',
            'Hi, sexy!'
        ];<commit_msg>fix openweather api requirement<commit_after>// for navigator language
// var lang = window.navigator.language;
// you can change the language
var lang = 'nl';

//change weather params here:
//units: metric or imperial
var weatherParams = {
    'q':'Baarn,Netherlands',
    'units':'metric',
    'lang':lang,
    'APPID':'YOUR_FREE_OPENWEATHER_API_KEY'
};

var feed = 'http://feeds.nos.nl/nosjournaal?format=rss';
//var feed = 'http://www.nu.nl/feeds/rss/achterklap.rss';
//var feed = 'http://www.nu.nl/feeds/rss/opmerkelijk.rss';
//var feed = 'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml';

// compliments:
var morning = [
            'Good morning, handsome!',
            'Enjoy your day!',
            'How was your sleep?'
        ];

var afternoon = [
            'Hello, beauty!',
            'You look sexy!',
            'Looking good today!'
        ];

var evening = [
            'Wow, you look hot!',
            'You look nice!',
            'Hi, sexy!'
        ];
<|endoftext|>


<commit_before>import React from 'react';
import Helmet from 'react-helmet';
import styled from 'styled-components';
import Icons from 'components/Icons';

const Content = styled.div`
  margin: 0 0 120px;

  p {
    font-size: 16px;
    text-align: center;
    margin: 30px 0 60px;
  }
`;

const Stamp = styled.div`
  text-align: center;

  .svg-icon {
    color: #2d2d2d;
    width: 60px;
    height: 60px;
    display: block;
    margin: 0 auto;
  }

  a {
    color: #2d2d2d;
    display: inline-block;

    &:hover {
      svg {
        color: rgba(95, 40, 141, 1);
      }
    }
  }
`;

const Legal = styled.blockquote`
  margin: 0;
  border-left: 5px solid rgba(95, 40, 141, 0.6);
  padding: 0 0 0 20px;

  p {
    font-size: 14px;
    margin: 20px 0;
    text-align: left;
  }
`;

export default class DespreNoi extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
  render() {
    return (

            <Helmet
              title="Despre noi - Monitorizare Vot"
              meta={[
                { name: 'description', content: 'Despre noi' },
              ]}
            />

Află mai multe
 despre noi

            <Content>
              <Stamp>
                <Icons icon="mvCircle" />
              </Stamp>

Monitorizare Vot este un proiect Code for Romania, realizat în parteneriat cu EFOR, Geeks for Democracy, Funky Citizens, Observatorul Electoral, Centrul pentru Resurse Civice și Centrul pentru Studiul Democratiei. Scopul nostru este dezvoltarea unui instrument IT  prin care observatorii electorali i   să poată transmite simplu și rapid sesizările lor către ONG-ul care i-a acreditat. În plus,oferim cetățenilor o platformă foarte ușor de folosit unde se pot face auziți atunci când au de semnalat o neregulă în desfășurarea  alegerilor. Ne dorim astfel să-i încurajăm pe oameni să se implice în procesul electoral, pentru alegeri corecte în toată țara.

              <Stamp>
                <Icons icon="code4" />
              </Stamp>

Code for Romania este o organizație neguvernamentală, neafiliată politic și apolitică, înființată în 2016. Code for Romania își propune să formeze o comunitate de profesioniști în IT care să creeze soluții digitale ce rezolvă probleme ale societății. Misiunea noastră este să dăm oamenilor informaţiile, mijloacele şi curajul să se implice mai mult în rezolvarea problemelor societăţii. Proiectele Code for Romania sunt dezvoltate pe bază de voluntariat și în format open-source.

              <Legal>

Notă:

Toate informațiile prezentate pe acest website sunt bazate pe sesizările primite de la utilizatori. Echipa de administrare a website-ului face o minimă verificare a sesizărilor înainte de publicare, pentru a se asigura ca acestea au legatura cu subiectului alegerilor, dar nu își asumă responsabilitatea pentru conținutul și veridicitatea sesizărilor transmise de către utilizatori. Scopul platformei este acela de a informa cetățenii și de a oferi un spațiu de exprimare celor care doresc să sesizeze eventuale tentative de fraudă electorală. Platforma și statisticile aferente vor fi promovate către mass-media. Echipa Code for Romania nu își asumă responsabilitatea pentru transmiterea acestor sesizări mai departe către autoritățile competente și nici pentru oferirea de răspunsuri la sesizarile utilizatorilor. Pentru aceasta vă rugăm să va adresati Biroul Electoral de Circumscriptie sau Biroul Electoral Central.

              </Legal>
            </Content>

    );
  }
}
<commit_msg>Content replacement 12<commit_after>import React from 'react';
import Helmet from 'react-helmet';
import styled from 'styled-components';
import Icons from 'components/Icons';

const Content = styled.div`
  margin: 0 0 120px;

  p {
    font-size: 16px;
    text-align: center;
    margin: 30px 0 60px;
  }
`;

const Stamp = styled.div`
  text-align: center;

  .svg-icon {
    color: #2d2d2d;
    width: 60px;
    height: 60px;
    display: block;
    margin: 0 auto;
  }

  a {
    color: #2d2d2d;
    display: inline-block;

    &:hover {
      svg {
        color: rgba(95, 40, 141, 1);
      }
    }
  }
`;

const Legal = styled.blockquote`
  margin: 0;
  border-left: 5px solid rgba(95, 40, 141, 0.6);
  padding: 0 0 0 20px;

  p {
    font-size: 14px;
    margin: 20px 0;
    text-align: left;
  }
`;

export default class DespreNoi extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
  render() {
    return (

            <Helmet
              title="Despre noi - Monitorizare Vot"
              meta={[
                { name: 'description', content: 'Despre noi' },
              ]}
            />

Află mai multe
 despre noi

            <Content>
              <Stamp>
                <Icons icon="mvCircle" />
              </Stamp>

                Monitorizare Vot este un proiect Code for Romania. Scopul nostru este dezvoltarea unui instrument IT prin care observatorii electorali i să poată transmite simplu și rapid sesizările lor către ONG-ul care i-a acreditat. În plus ,oferim cetățenilor o platformă foarte ușor de folosit unde se pot face auziți atunci când au de semnalat o neregulă în desfășurarea alegerilor. Ne dorim astfel să-i încurajăm pe oameni să se implice în procesul electoral, pentru alegeri corecte în toată țara. Partenerii proiectului: EFOR, Geeks for Democracy, Funky Citizens, Observatorul Electoral, Centrul pentru Resurse Civice și Centrul pentru Studiul Democratiei

                Monitorizare Vot a câștigat premiul I pentru Participare Civică în 2017 la Gala Societății Civile. Aplicația de observare a alegerilor va fi utilizată în Polonia, în cadrul alegerilor din octombrie 2018. Informații despre versiunea internațională a aplicației sunt disponibile aici.

              <Stamp>
                <Icons icon="code4" />
              </Stamp>

Code for Romania este o organizație neguvernamentală, neafiliată politic și apolitică, înființată în 2016. Code for Romania își propune să formeze o comunitate de profesioniști în IT care să creeze soluții digitale ce rezolvă probleme ale societății. Misiunea noastră este să dăm oamenilor informaţiile, mijloacele şi curajul să se implice mai mult în rezolvarea problemelor societăţii. Proiectele Code for Romania sunt dezvoltate pe bază de voluntariat și în format open-source.

              <Legal>

Notă:

Toate informațiile prezentate pe acest website sunt bazate pe sesizările primite de la utilizatori. Echipa de administrare a website-ului face o minimă verificare a sesizărilor înainte de publicare, pentru a se asigura ca acestea au legatura cu subiectului alegerilor, dar nu își asumă responsabilitatea pentru conținutul și veridicitatea sesizărilor transmise de către utilizatori. Scopul platformei este acela de a informa cetățenii și de a oferi un spațiu de exprimare celor care doresc să sesizeze eventuale tentative de fraudă electorală. Platforma și statisticile aferente vor fi promovate către mass-media. Echipa Code for Romania nu își asumă responsabilitatea pentru transmiterea acestor sesizări mai departe către autoritățile competente și nici pentru oferirea de răspunsuri la sesizarile utilizatorilor. Pentru aceasta vă rugăm să va adresati Biroul Electoral de Circumscriptie sau Biroul Electoral Central.

              </Legal>
            </Content>

    );
  }
}
<|endoftext|>


<commit_before>//Stack Overflow
// http://stackoverflow.com/questions/10122291/loading-mustache-using-requirejs

// Req docs
requirejs.config({
  baseUrl: "/js",

  deps: ["menu","form", "search"],

  paths: {
    jquery: "vendor/jquery",
    val: "vendor/validate",
    lunr: "vendor/lunr.min",
    mustache: "../mustache/",
    uri: "vendor/URI.min",
    lunrSearch: "vendor/jquery.lunr.search"
  },

  shim: {
    jquery: {
      exports: 'jquery'
    },
    val: {
      deps: ['jquery'],
      exports: 'jquery'
    },
    lunr: {
      deps: ['jquery'],
      exports: 'jquery'
    },
    'mustache': {
      exports: 'Mustache'
    },
    uri: {
      deps: ['jquery'],
      exports: 'jquery'
    },
    lunrSearch: {
      deps: ['jquery'],
      exports: 'jquery'
    }
  },

  waitSeconds: 20
});<commit_msg>removed search functionality and its dependencies<commit_after>requirejs.config({
  baseUrl: "../js",

  deps: ["menu","form"],

  paths: {
    jquery: "../js/vendor/jquery",
    val: "../js/vendor/validate"
  },

  shim: {
    jquery: {
      exports: 'jquery'
    },
    val: {
      deps: ['jquery'],
      exports: 'jquery'
    }
  },

  waitSeconds: 20
});<|endoftext|>