<commit_before>dojo.provide("dojox.form.manager._NodeMixin");

dojo.require("dojox.form.manager._Mixin");

(function(){
	var fm = dojox.form.manager,
		aa = fm.actionAdapter,
		keys = fm._keys,

		ce = fm.changeEvent = function(node){
			// summary:
			//		Function that returns a valid "onchange" event for a given form node.
			// node: Node:
			//		Form node.

			var eventName = "onclick";
			switch(node.tagName.toLowerCase()){
				case "textarea":
					eventName = "onkeyup";
					break;
				case "select":
					eventName = "onchange";
					break;
				case "input":
					switch(node.type.toLowerCase()){
						case "text":
						case "password":
							eventName = "onkeyup";
							break;
					}
					break;
				// button, input/button, input/checkbox, input/radio,
				// input/file, input/image, input/submit, input/reset
				// use "onclick" (the default)
			}
			return eventName;	// String
		},

		registerNode = function(node, groupNode){
			var name = dojo.attr(node, "name");
			groupNode = groupNode || this.domNode;
			if(name && !(name in this.formWidgets)){
				// verify that it is not part of any widget
				for(var n = node; n && n !== groupNode; n = n.parentNode){
					if(dojo.attr(n, "widgetId") && dijit.byNode(n) instanceof dijit.form._FormWidget){
						// this is a child of some widget --- bail out
						return null;
					}
				}
				// register the node
				if(node.tagName.toLowerCase() == "input" && node.type.toLowerCase() == "radio"){
					var a = this.formNodes[name];
					a = a && a.node;
					if(a && dojo.isArray(a)){
						a.push(node);
					}else{
						this.formNodes[name] = {node: [node], connections: []};
					}
				}else{
					this.formNodes[name] = {node: node, connections: []};
				}
			}else{
				name = null;
			}
			return name;
		},

		getObserversFromNode = function(name){
			var observers = {};
			aa(function(_, n){
				var o = dojo.attr(n, "observer");
				if(o && typeof o == "string"){
					dojo.forEach(o.split(","), function(o){
						o = dojo.trim(o);
						if(o && dojo.isFunction(this[o])){
							observers[o] = 1;
						}
					}, this);
				}
			}).call(this, null, this.formNodes[name].node);
			return keys(observers);
		},

		connectNode = function(name, observers){
			var t = this.formNodes[name], c = t.connections;
			if(c.length){
				dojo.forEach(c, dojo.disconnect);
				c = t.connections = [];
			}
			aa(function(_, n){
				// the next line is a crude workaround for dijit.form.Button that fires onClick instead of onChange
				var eventName = ce(n);
				dojo.forEach(observers, function(o){
					c.push(dojo.connect(n, eventName, this, function(evt){
						if(this.watch){
							this[o](this.formNodeValue(name), name, n, evt);
						}
					}));
				}, this);
			}).call(this, null, t.node);
		};
	dojo.declare("dojox.form.manager._NodeMixin", null, {
		// summary:
		//		Mixin to orchestrate dynamic forms (works with DOM nodes).
		// description:
		//		This mixin provideas a foundation for an enhanced form
		//		functionality: unified access to individual form elements,
		//		unified "onchange" event processing, and general event
		//		processing. It complements dojox.form.manager._Mixin
		//		extending the functionality to DOM nodes.

		destroy: function(){
			// summary:
			//		Called when the widget is being destroyed

			for(var name in this.formNodes){
				dojo.forEach(this.formNodes[name].connections, dojo.disconnect);
			}
			this.formNodes = {};

			this.inherited(arguments);
		},

		// register/unregister widgets and nodes

		registerNode: function(node){
			// summary:
			//		Register a node with the form manager
			// node: String|Node:
			//		A node, or its id
			// returns: Object:
			//		Returns self
			if(typeof node == "string"){
				node = dojo.byId(node);
			}
			var name = registerNode.call(this, node);
			if(name){
				connectNode.call(this, name, getObserversFromNode.call(this, name));
			}
			return this;
		},

		unregisterNode: function(name){
			// summary:
			//		Removes the node by name from internal tables unregistering
			//		connected observers
			// name: String:
			//		Name of the to unregister
			// returns: Object:
			//		Returns self
			if(name in this.formNodes){
				dojo.forEach(this.formNodes[name].connections, this.disconnect, this);
				delete this.formNodes[name];
			}
			return this;
		},

		registerNodeDescendants: function(node){
			// summary:
			//		Register node's descendants (form nodes) with the form manager
			// node: String|Node:
			//		A widget, or its widgetId, or its DOM node
			// returns: Object:
			//		Returns self

			if(typeof node == "string"){
				node = dojo.byId(node);
			}

			dojo.query("input, select, textarea, button", node).
				map(function(n){
					return registerNode.call(this, n, node);
				}, this).
				forEach(function(name){
					if(name){
						connectNode.call(this, name, getObserversFromNode.call(this, name));
					}
				}, this);

			return this;
		},

		unregisterNodeDescendants: function(node){
			// summary:
			//		Unregister node's descendants (form nodes) with the form manager
			// node: String|Node:
			//		A widget, or its widgetId, or its DOM node
			// returns: Object:
			//		Returns self

			if(typeof node == "string"){
				node = dojo.byId(node);
			}

			dojo.query("input, select, textarea, button", node).
				map(function(n){ return dojo.attr(node, "name") || null; }).
				forEach(function(name){
					if(name){
						this.unregisterNode(name);
					}
				}, this);

			return this;
		},

		// value accessors

		formNodeValue: function(elem, value){
			// summary:
			//		Set or get a form element by name.
			// elem: String|Node|Array:
			//		Form element's name, DOM node, or array or radio nodes.
			// value: Object?:
			//		Optional. The value to set.
			// returns: Object:
			//		For a getter it returns the value, for a setter it returns
			//		self. If the elem is not valid, null will be returned.

			var isSetter = arguments.length == 2 && value !== undefined, result;

			if(typeof elem == "string"){
				elem = this.formNodes[elem];
				if(elem){
					elem = elem.node;
				}
			}

			if(!elem){
				return null;	// Object
			}

			if(dojo.isArray(elem)){
				// input/radio array
				if(isSetter){
					dojo.forEach(elem, function(node){
						node.checked = "";
					});
					dojo.forEach(elem, function(node){
						node.checked = node.value === value ? "checked" : "";
					});
					return this;	// self
				}
				// getter
				dojo.some(elem, function(node){
					if(node.checked){
						result = node;
						return true;
					}
					return false;
				});
				return result ? result.value : "";	// String
			}
			// all other elements
			switch(elem.tagName.toLowerCase()){
				case "select":
					if(elem.multiple){
						// multiple is allowed
						if(isSetter){
							if(dojo.isArray(value)){
								var dict = {};
								dojo.forEach(value, function(v){
									dict[v] = 1;
								});
								dojo.query("> option", elem).forEach(function(opt){
									opt.selected = opt.value in dict;
								});
								return this;	// self
							}
							// singular property
							dojo.query("> option", elem).forEach(function(opt){
								opt.selected = opt.value === value;
							});
							return this;	// self
						}
						// getter
						var result = dojo.query("> option", elem).filter(function(opt){
							return opt.selected;
						}).map(function(opt){
							return opt.value;
						});
						return result.length == 1 ? result[0] : result;	// Object
					}
					// singular
					if(isSetter){
						dojo.query("> option", elem).forEach(function(opt){
							opt.selected = opt.value === value;
						});
						return this;	// self
					}
					// getter
					var result = dojo.query("> option", elem).filter(function(opt){
						return opt.selected;
					}).map(function(opt){
						return opt.value;
					});
					return result.length == 1 ? result[0] : "";	// String
				case "textarea":
					if(isSetter){
						elem.value = "" + value;
						return this;
					}
					// getter
					return elem.value;
				case "button":
					if(isSetter){
						elem.innerHTML = "" + value;
						return this;
					}
					// getter
					return elem.innerHTML;
				case "input":
					if(elem.type.toLowerCase() == "checkbox"){
						// input/checkbox element
						if(isSetter){
							elem.checked = value ? "checked" : "";
							return this;
						}
						// getter
						return Boolean(elem.checked);
					}
			}
			// the rest of inputs
			if(isSetter){
				elem.value = "" + value;
				return this;
			}
			// getter
			return elem.value;
		},

		// inspectors

		inspectFormNodes: function(inspector, state, defaultValue){
			// summary:
			//		Run an inspector function on controlled form elements returning a result object.
			// inspector: Function:
			//		A function to be called on a form element. Takes three arguments: a name, a node or
			//		an array of nodes, and a supplied value. Runs in the context of the form manager.
			//		Returns a value that will be collected and returned as a state.
			// state: Object?:
			//		Optional. If a name-value dictionary --- only listed names will be processed.
			//		If an array, all names in the array will be processed with defaultValue.
			//		If omitted or null, all form elements will be processed with defaultValue.
			// defaultValue: Object?:
			//		Optional. The default state (true, if omitted).

			var name, result = {};

			if(state){
				if(dojo.isArray(state)){
					dojo.forEach(state, function(name){
						if(name in this.formNodes){
							result[name] = inspector.call(this, name, this.formNodes[name].node, defaultValue);
						}
					}, this);
				}else{
					for(name in state){
						if(name in this.formNodes){
							result[name] = inspector.call(this, name, this.formNodes[name].node, state[name]);
						}
					}
				}
			}else{
				for(name in this.formNodes){
					result[name] = inspector.call(this, name, this.formNodes[name].node, defaultValue);
				}
			}

			return result;	// Object
		}
	});
})();
<commit_msg>dojox.form.manager: simplifying the node value getter/setter code for text areas (the generic code works just fine) and selects, !strict.<commit_after>dojo.provide("dojox.form.manager._NodeMixin");

dojo.require("dojox.form.manager._Mixin");

(function(){
	var fm = dojox.form.manager,
		aa = fm.actionAdapter,
		keys = fm._keys,

		ce = fm.changeEvent = function(node){
			// summary:
			//		Function that returns a valid "onchange" event for a given form node.
			// node: Node:
			//		Form node.

			var eventName = "onclick";
			switch(node.tagName.toLowerCase()){
				case "textarea":
					eventName = "onkeyup";
					break;
				case "select":
					eventName = "onchange";
					break;
				case "input":
					switch(node.type.toLowerCase()){
						case "text":
						case "password":
							eventName = "onkeyup";
							break;
					}
					break;
				// button, input/button, input/checkbox, input/radio,
				// input/file, input/image, input/submit, input/reset
				// use "onclick" (the default)
			}
			return eventName;	// String
		},

		registerNode = function(node, groupNode){
			var name = dojo.attr(node, "name");
			groupNode = groupNode || this.domNode;
			if(name && !(name in this.formWidgets)){
				// verify that it is not part of any widget
				for(var n = node; n && n !== groupNode; n = n.parentNode){
					if(dojo.attr(n, "widgetId") && dijit.byNode(n) instanceof dijit.form._FormWidget){
						// this is a child of some widget --- bail out
						return null;
					}
				}
				// register the node
				if(node.tagName.toLowerCase() == "input" && node.type.toLowerCase() == "radio"){
					var a = this.formNodes[name];
					a = a && a.node;
					if(a && dojo.isArray(a)){
						a.push(node);
					}else{
						this.formNodes[name] = {node: [node], connections: []};
					}
				}else{
					this.formNodes[name] = {node: node, connections: []};
				}
			}else{
				name = null;
			}
			return name;
		},

		getObserversFromNode = function(name){
			var observers = {};
			aa(function(_, n){
				var o = dojo.attr(n, "observer");
				if(o && typeof o == "string"){
					dojo.forEach(o.split(","), function(o){
						o = dojo.trim(o);
						if(o && dojo.isFunction(this[o])){
							observers[o] = 1;
						}
					}, this);
				}
			}).call(this, null, this.formNodes[name].node);
			return keys(observers);
		},

		connectNode = function(name, observers){
			var t = this.formNodes[name], c = t.connections;
			if(c.length){
				dojo.forEach(c, dojo.disconnect);
				c = t.connections = [];
			}
			aa(function(_, n){
				// the next line is a crude workaround for dijit.form.Button that fires onClick instead of onChange
				var eventName = ce(n);
				dojo.forEach(observers, function(o){
					c.push(dojo.connect(n, eventName, this, function(evt){
						if(this.watch){
							this[o](this.formNodeValue(name), name, n, evt);
						}
					}));
				}, this);
			}).call(this, null, t.node);
		};
	dojo.declare("dojox.form.manager._NodeMixin", null, {
		// summary:
		//		Mixin to orchestrate dynamic forms (works with DOM nodes).
		// description:
		//		This mixin provideas a foundation for an enhanced form
		//		functionality: unified access to individual form elements,
		//		unified "onchange" event processing, and general event
		//		processing. It complements dojox.form.manager._Mixin
		//		extending the functionality to DOM nodes.

		destroy: function(){
			// summary:
			//		Called when the widget is being destroyed

			for(var name in this.formNodes){
				dojo.forEach(this.formNodes[name].connections, dojo.disconnect);
			}
			this.formNodes = {};

			this.inherited(arguments);
		},

		// register/unregister widgets and nodes

		registerNode: function(node){
			// summary:
			//		Register a node with the form manager
			// node: String|Node:
			//		A node, or its id
			// returns: Object:
			//		Returns self
			if(typeof node == "string"){
				node = dojo.byId(node);
			}
			var name = registerNode.call(this, node);
			if(name){
				connectNode.call(this, name, getObserversFromNode.call(this, name));
			}
			return this;
		},

		unregisterNode: function(name){
			// summary:
			//		Removes the node by name from internal tables unregistering
			//		connected observers
			// name: String:
			//		Name of the to unregister
			// returns: Object:
			//		Returns self
			if(name in this.formNodes){
				dojo.forEach(this.formNodes[name].connections, this.disconnect, this);
				delete this.formNodes[name];
			}
			return this;
		},

		registerNodeDescendants: function(node){
			// summary:
			//		Register node's descendants (form nodes) with the form manager
			// node: String|Node:
			//		A widget, or its widgetId, or its DOM node
			// returns: Object:
			//		Returns self

			if(typeof node == "string"){
				node = dojo.byId(node);
			}

			dojo.query("input, select, textarea, button", node).
				map(function(n){
					return registerNode.call(this, n, node);
				}, this).
				forEach(function(name){
					if(name){
						connectNode.call(this, name, getObserversFromNode.call(this, name));
					}
				}, this);

			return this;
		},

		unregisterNodeDescendants: function(node){
			// summary:
			//		Unregister node's descendants (form nodes) with the form manager
			// node: String|Node:
			//		A widget, or its widgetId, or its DOM node
			// returns: Object:
			//		Returns self

			if(typeof node == "string"){
				node = dojo.byId(node);
			}

			dojo.query("input, select, textarea, button", node).
				map(function(n){ return dojo.attr(node, "name") || null; }).
				forEach(function(name){
					if(name){
						this.unregisterNode(name);
					}
				}, this);

			return this;
		},

		// value accessors

		formNodeValue: function(elem, value){
			// summary:
			//		Set or get a form element by name.
			// elem: String|Node|Array:
			//		Form element's name, DOM node, or array or radio nodes.
			// value: Object?:
			//		Optional. The value to set.
			// returns: Object:
			//		For a getter it returns the value, for a setter it returns
			//		self. If the elem is not valid, null will be returned.

			var isSetter = arguments.length == 2 && value !== undefined, result;

			if(typeof elem == "string"){
				elem = this.formNodes[elem];
				if(elem){
					elem = elem.node;
				}
			}

			if(!elem){
				return null;	// Object
			}

			if(dojo.isArray(elem)){
				// input/radio array
				if(isSetter){
					dojo.forEach(elem, function(node){
						node.checked = "";
					});
					dojo.forEach(elem, function(node){
						node.checked = node.value === value ? "checked" : "";
					});
					return this;	// self
				}
				// getter
				dojo.some(elem, function(node){
					if(node.checked){
						result = node;
						return true;
					}
					return false;
				});
				return result ? result.value : "";	// String
			}
			// all other elements
			switch(elem.tagName.toLowerCase()){
				case "select":
					if(elem.multiple){
						// multiple is allowed
						if(isSetter){
							if(dojo.isArray(value)){
								var dict = {};
								dojo.forEach(value, function(v){
									dict[v] = 1;
								});
								dojo.query("> option", elem).forEach(function(opt){
									opt.selected = opt.value in dict;
								});
								return this;	// self
							}
							// singular property
							dojo.query("> option", elem).forEach(function(opt){
								opt.selected = opt.value === value;
							});
							return this;	// self
						}
						// getter
						var result = dojo.query("> option", elem).filter(function(opt){
							return opt.selected;
						}).map(function(opt){
							return opt.value;
						});
						return result.length == 1 ? result[0] : result;	// Object
					}
					// singular
					if(isSetter){
						dojo.query("> option", elem).forEach(function(opt){
							opt.selected = opt.value === value;
						});
						return this;	// self
					}
					// getter
					return elem.value || ""; // String
				case "button":
					if(isSetter){
						elem.innerHTML = "" + value;
						return this;
					}
					// getter
					return elem.innerHTML;
				case "input":
					if(elem.type.toLowerCase() == "checkbox"){
						// input/checkbox element
						if(isSetter){
							elem.checked = value ? "checked" : "";
							return this;
						}
						// getter
						return Boolean(elem.checked);
					}
			}
			// the rest of inputs
			if(isSetter){
				elem.value = "" + value;
				return this;
			}
			// getter
			return elem.value;
		},

		// inspectors

		inspectFormNodes: function(inspector, state, defaultValue){
			// summary:
			//		Run an inspector function on controlled form elements returning a result object.
			// inspector: Function:
			//		A function to be called on a form element. Takes three arguments: a name, a node or
			//		an array of nodes, and a supplied value. Runs in the context of the form manager.
			//		Returns a value that will be collected and returned as a state.
			// state: Object?:
			//		Optional. If a name-value dictionary --- only listed names will be processed.
			//		If an array, all names in the array will be processed with defaultValue.
			//		If omitted or null, all form elements will be processed with defaultValue.
			// defaultValue: Object?:
			//		Optional. The default state (true, if omitted).

			var name, result = {};

			if(state){
				if(dojo.isArray(state)){
					dojo.forEach(state, function(name){
						if(name in this.formNodes){
							result[name] = inspector.call(this, name, this.formNodes[name].node, defaultValue);
						}
					}, this);
				}else{
					for(name in state){
						if(name in this.formNodes){
							result[name] = inspector.call(this, name, this.formNodes[name].node, state[name]);
						}
					}
				}
			}else{
				for(name in this.formNodes){
					result[name] = inspector.call(this, name, this.formNodes[name].node, defaultValue);
				}
			}

			return result;	// Object
		}
	});
})();
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Resin.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const yargs = require('yargs');
const utils = require('./utils');
const EXIT_CODES = require('../src/exit-codes');
const packageJSON = require('../../package.json');

/**
 * @summary Parsed CLI options and arguments
 * @type Object
 * @public
 */
module.exports = yargs
  .demand(1, 'Missing image')

  // Usage help
  .usage('Usage: $0 <image>')
  .epilogue([
    'Exit codes:',
    _.map(EXIT_CODES, (value, key) => {
      const reason = _.map(_.split(key, '_'), _.capitalize).join(' ');
      return '  ' + value + ' - ' + reason;
    }).join('\n'),
    '',
    'If you need help, don\'t hesitate in contacting us at:',
    '',
    '  GitHub: https://github.com/resin-io/etcher-cli/issues/new',
    '  Gitter: https://gitter.im/resin-io/etcher'
  ].join('\n'))

  // Examples
  .example('$0 raspberry-pi.img')
  .example('$0 --no-check raspberry-pi.img')
  .example('$0 -d /dev/disk2 ubuntu.iso')
  .example('$0 -d /dev/disk2 -y rpi.img')

  // Help option
  .help()

  // Version option
  .version(_.constant(packageJSON.version))

  // Error reporting
  .fail((message, error) => {
    yargs.showHelp();
    utils.printError(error || message);
    process.exit(1);
  })

  // Assert that image exists
  .check((argv) => {
    fs.accessSync(argv._[0]);
    return true;
  })

  .check((argv) => {
    if (argv.robot && !argv.drive) {
      throw new Error('Missing drive');
    }

    return true;
  })

  .options({
    help: {
      describe: 'show help',
      boolean: true,
      alias: 'h'
    },
    version: {
      describe: 'show version number',
      boolean: true,
      alias: 'v'
    },
    drive: {
      describe: 'drive',
      string: true,
      alias: 'd'
    },
    check: {
      describe: 'validate write',
      boolean: true,
      alias: 'c',
      default: true
    },
    robot: {
      describe: 'parse-able output without interactivity',
      boolean: true,
      alias: 'r'
    },
    yes: {
      describe: 'confirm non-interactively',
      boolean: true,
      alias: 'y'
    },
    unmount: {
      describe: 'unmount on success',
      boolean: true,
      alias: 'u',
      default: true
    }
  })

  // Make sure arguments are parsed correctly when running
  // in development mode (or NPM) and in a final package.
  //
  // We rely on the following heuristics to determine if the
  // Etcher CLI is being run as a final packaged executable
  // or by a tool passing the script as an argument:
  .parse(_.attempt((argv) => {

    // Excluding the extension makes sure we cover cases
    // like *.exe and *.cmd in Windows systems.
    const executable = path.basename(argv[0], path.extname(argv[0])).toLowerCase();

    if (_.includes([
      'node',
      'electron',
      'electron helper'
    ], executable)) {

      // In this case, the second argument (e.g: index 1)
      // equals `lib/cli/etcher.js`, so the real arguments
      // start from the third one.
      return argv.slice(2);

    }

    // Handle the case where the CLI is executed by pointing
    // the packaged electron `Etcher` binary to the application
    // asar archive by using `ELECTRON_RUN_AS_NODE`.
    if (argv[1] && path.basename(argv[1]) === 'app.asar') {
      return argv.slice(2);
    }

    return argv.slice(1);
  }, process.argv));
<commit_msg>style(CLI): don't wrap CLI help outputdrives (#813)<commit_after>/*
 * Copyright 2016 Resin.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const _ = require('lodash');
const fs = require('fs');
const path = require('path');
const yargs = require('yargs');
const utils = require('./utils');
const EXIT_CODES = require('../src/exit-codes');
const packageJSON = require('../../package.json');

/**
 * @summary Parsed CLI options and arguments
 * @type Object
 * @public
 */
module.exports = yargs

  // Don't wrap at all
  .wrap(null)

  .demand(1, 'Missing image')

  // Usage help
  .usage('Usage: $0 <image>')
  .epilogue([
    'Exit codes:',
    _.map(EXIT_CODES, (value, key) => {
      const reason = _.map(_.split(key, '_'), _.capitalize).join(' ');
      return '  ' + value + ' - ' + reason;
    }).join('\n'),
    '',
    'If you need help, don\'t hesitate in contacting us at:',
    '',
    '  GitHub: https://github.com/resin-io/etcher-cli/issues/new',
    '  Gitter: https://gitter.im/resin-io/etcher'
  ].join('\n'))

  // Examples
  .example('$0 raspberry-pi.img')
  .example('$0 --no-check raspberry-pi.img')
  .example('$0 -d /dev/disk2 ubuntu.iso')
  .example('$0 -d /dev/disk2 -y rpi.img')

  // Help option
  .help()

  // Version option
  .version(_.constant(packageJSON.version))

  // Error reporting
  .fail((message, error) => {
    yargs.showHelp();
    utils.printError(error || message);
    process.exit(1);
  })

  // Assert that image exists
  .check((argv) => {
    fs.accessSync(argv._[0]);
    return true;
  })

  .check((argv) => {
    if (argv.robot && !argv.drive) {
      throw new Error('Missing drive');
    }

    return true;
  })

  .options({
    help: {
      describe: 'show help',
      boolean: true,
      alias: 'h'
    },
    version: {
      describe: 'show version number',
      boolean: true,
      alias: 'v'
    },
    drive: {
      describe: 'drive',
      string: true,
      alias: 'd'
    },
    check: {
      describe: 'validate write',
      boolean: true,
      alias: 'c',
      default: true
    },
    robot: {
      describe: 'parse-able output without interactivity',
      boolean: true,
      alias: 'r'
    },
    yes: {
      describe: 'confirm non-interactively',
      boolean: true,
      alias: 'y'
    },
    unmount: {
      describe: 'unmount on success',
      boolean: true,
      alias: 'u',
      default: true
    }
  })

  // Make sure arguments are parsed correctly when running
  // in development mode (or NPM) and in a final package.
  //
  // We rely on the following heuristics to determine if the
  // Etcher CLI is being run as a final packaged executable
  // or by a tool passing the script as an argument:
  .parse(_.attempt((argv) => {

    // Excluding the extension makes sure we cover cases
    // like *.exe and *.cmd in Windows systems.
    const executable = path.basename(argv[0], path.extname(argv[0])).toLowerCase();

    if (_.includes([
      'node',
      'electron',
      'electron helper'
    ], executable)) {

      // In this case, the second argument (e.g: index 1)
      // equals `lib/cli/etcher.js`, so the real arguments
      // start from the third one.
      return argv.slice(2);

    }

    // Handle the case where the CLI is executed by pointing
    // the packaged electron `Etcher` binary to the application
    // asar archive by using `ELECTRON_RUN_AS_NODE`.
    if (argv[1] && path.basename(argv[1]) === 'app.asar') {
      return argv.slice(2);
    }

    return argv.slice(1);
  }, process.argv));
<|endoftext|>


<commit_before>'use strict';

const lookupCommand = require('./lookup-command');
const getOptionArgs = require('../utilities/get-option-args');
const hash = require('promise.hash.helper');
const logger = require('heimdalljs-logger')('ember-cli:cli');
const loggerTesting = require('heimdalljs-logger')('ember-cli:testing');
const Instrumentation = require('../models/instrumentation');
const PackageInfoCache = require('../models/package-info-cache');
const heimdall = require('heimdalljs');

const onProcessInterrupt = require('../utilities/will-interrupt-process');

class CLI {
  /**
   * @private
   * @class CLI
   * @constructor
   * @param options
   */
  constructor(options) {
    /**
     * @private
     * @property name
     */
    this.name = options.name;

    /**
     * @private
     * @property ui
     * @type UI
     */
    this.ui = options.ui;

    /**
     * @private
     * @property analytics
     */
    this.analytics = options.analytics;

    /**
     * @private
     * @property testing
     * @type Boolean
     */
    this.testing = options.testing;

    /**
     * @private
     * @property disableDependencyChecker
     * @type Boolean
     */
    this.disableDependencyChecker = options.disableDependencyChecker;

    /**
     * @private
     * @property root
     */
    this.root = options.root;

    /**
     * @private
     * @property npmPackage
     */
    this.npmPackage = options.npmPackage;

    /**
     * @private
     * @property instrumentation
     */
    this.instrumentation =
      options.instrumentation ||
      new Instrumentation({
        ui: options.ui,
        initInstrumentation: options.initInstrumentation,
      });

    this.packageInfoCache = new PackageInfoCache(this.ui);

    logger.info('testing %o', !!this.testing);
  }

  /**
   * @private
   * @method maybeMakeCommand
   * @param commandName
   * @param commandArgs
   * @return {null|CurrentCommand}
   */
  maybeMakeCommand(commandName, commandArgs) {
    if (this._environment === undefined) {
      throw new Error('Unable to make command without environment, you have to execute "run" method first.');
    }
    let CurrentCommand = lookupCommand(this._environment.commands, commandName, commandArgs, {
      project: this._environment.project,
      ui: this.ui,
    });

    /*
     * XXX Need to decide what to do here about showing errors. For
     * a non-CLI project the cache is local and probably should. For
     * a CLI project the cache is there, but not sure when we'll know
     * about all the errors, because there may be multiple projects.
     *   if (this.packageInfoCache.hasErrors()) {
     *     this.packageInfoCache.showErrors();
     *   }
     */
    let command = new CurrentCommand({
      ui: this.ui,
      analytics: this.analytics,
      commands: this._environment.commands,
      tasks: this._environment.tasks,
      project: this._environment.project,
      settings: this._environment.settings,
      testing: this.testing,
      cli: this,
    });

    return command;
  }

  /**
   * @private
   * @method run
   * @param {Promise<object>} environmentPromiseHash
   * @return {Promise}
   */
  async run(environmentPromiseHash) {
    if (environmentPromiseHash === undefined) {
      return Promise.reject(new Error('Unable to execute "run" command without environment argument'));
    }
    let shutdownOnExit = null;

    let environment = (this._environment = await hash(environmentPromiseHash));

    try {
      let args = environment.cliArgs.slice();
      let commandName = args.shift();
      let commandArgs = args;
      let helpOptions;

      let commandLookupCreationToken = heimdall.start('lookup-command');

      let command = this.maybeMakeCommand(commandName, commandArgs);

      commandLookupCreationToken.stop();

      getOptionArgs('--verbose', commandArgs).forEach((arg) => {
        process.env[`EMBER_VERBOSE_${arg.toUpperCase()}`] = 'true';
      });

      let platformCheckerToken = heimdall.start('platform-checker');

      const PlatformChecker = require('../utilities/platform-checker');
      let platform = new PlatformChecker(process.version);
      let recommendation =
        ' We recommend that you use the most-recent "Active LTS" version of Node.js.' +
        ' See https://github.com/ember-cli/ember-cli/blob/master/docs/node-support.md for details.';

      if (!this.testing) {
        if (platform.isDeprecated) {
          this.ui.writeDeprecateLine(`Node ${process.version} is no longer supported by Ember CLI.${recommendation}`);
        }

        if (!platform.isTested) {
          this.ui.writeWarnLine(
            `Node ${process.version} is not tested against Ember CLI on your platform.${recommendation}`
          );
        }
      }

      platformCheckerToken.stop();

      logger.info('command: %s', commandName);

      if (!this.testing) {
        process.chdir(environment.project.root);
        let skipInstallationCheck = commandArgs.indexOf('--skip-installation-check') !== -1;
        if (environment.project.isEmberCLIProject() && !skipInstallationCheck) {
          const InstallationChecker = require('../models/installation-checker');
          new InstallationChecker({ project: environment.project }).checkInstallations();
        }
      }

      let instrumentation = this.instrumentation;
      let onCommandInterrupt;

      let runPromise = Promise.resolve().then(async () => {
        let resultOrExitCode;

        try {
          instrumentation.stopAndReport('init');

          try {
            instrumentation.start('command');

            loggerTesting.info('cli: command.beforeRun');
            onProcessInterrupt.addHandler(onCommandInterrupt);

            await command.beforeRun(commandArgs);

            loggerTesting.info('cli: command.validateAndRun');

            resultOrExitCode = await command.validateAndRun(commandArgs);
          } finally {
            instrumentation.stopAndReport('command', commandName, commandArgs);

            onProcessInterrupt.removeHandler(onCommandInterrupt);
          }
        } finally {
          instrumentation.start('shutdown');
          shutdownOnExit = function () {
            instrumentation.stopAndReport('shutdown');
          };
        }

        // if the help option was passed, call the help command
        if (resultOrExitCode === 'callHelp') {
          helpOptions = {
            environment,
            commandName,
            commandArgs,
          };

          resultOrExitCode = await this.callHelp(helpOptions);
        }

        let exitCode = resultOrExitCode;

        loggerTesting.info(`cli: command run complete. exitCode: ${exitCode}`);
        // TODO: fix this
        // Possibly this issue: https://github.com/joyent/node/issues/8329
        // Wait to resolve promise when running on windows.
        // This ensures that stdout is flushed so acceptance tests get full output

        if (process.platform === 'win32') {
          return new Promise((resolve) => {
            setTimeout(resolve, 250, exitCode);
          });
        } else {
          return exitCode;
        }
      });

      onCommandInterrupt = async () => {
        await command.onInterrupt();

        return await runPromise;
      };

      return await runPromise;
    } catch (error) {
      this.logError(error);
      return 1;
    } finally {
      if (shutdownOnExit) {
        shutdownOnExit();
      }
    }
  }

  /**
   * @private
   * @method callHelp
   * @param options
   * @return {Promise}
   */
  callHelp(options) {
    let environment = options.environment;
    let commandName = options.commandName;
    let commandArgs = options.commandArgs;
    let helpIndex = commandArgs.indexOf('--help');
    let hIndex = commandArgs.indexOf('-h');

    let HelpCommand = lookupCommand(environment.commands, 'help', commandArgs, {
      project: environment.project,
      ui: this.ui,
    });

    let help = new HelpCommand({
      ui: this.ui,
      analytics: this.analytics,
      commands: environment.commands,
      tasks: environment.tasks,
      project: environment.project,
      settings: environment.settings,
      testing: this.testing,
    });

    if (helpIndex > -1) {
      commandArgs.splice(helpIndex, 1);
    }

    if (hIndex > -1) {
      commandArgs.splice(hIndex, 1);
    }

    commandArgs.unshift(commandName);

    return help.validateAndRun(commandArgs);
  }

  /**
   * @private
   * @method logError
   * @param error
   * @return {number}
   */
  logError(error) {
    if (this.testing && error) {
      console.error(error.message);
      if (error.stack) {
        console.error(error.stack);
      }
      throw error;
    }
    this.ui.errorLog.push(error);
    this.ui.writeError(error);
    return 1;
  }
}

module.exports = CLI;
<commit_msg>Update Node compatibility warning<commit_after>'use strict';

const lookupCommand = require('./lookup-command');
const getOptionArgs = require('../utilities/get-option-args');
const hash = require('promise.hash.helper');
const logger = require('heimdalljs-logger')('ember-cli:cli');
const loggerTesting = require('heimdalljs-logger')('ember-cli:testing');
const Instrumentation = require('../models/instrumentation');
const PackageInfoCache = require('../models/package-info-cache');
const heimdall = require('heimdalljs');

const onProcessInterrupt = require('../utilities/will-interrupt-process');

class CLI {
  /**
   * @private
   * @class CLI
   * @constructor
   * @param options
   */
  constructor(options) {
    /**
     * @private
     * @property name
     */
    this.name = options.name;

    /**
     * @private
     * @property ui
     * @type UI
     */
    this.ui = options.ui;

    /**
     * @private
     * @property analytics
     */
    this.analytics = options.analytics;

    /**
     * @private
     * @property testing
     * @type Boolean
     */
    this.testing = options.testing;

    /**
     * @private
     * @property disableDependencyChecker
     * @type Boolean
     */
    this.disableDependencyChecker = options.disableDependencyChecker;

    /**
     * @private
     * @property root
     */
    this.root = options.root;

    /**
     * @private
     * @property npmPackage
     */
    this.npmPackage = options.npmPackage;

    /**
     * @private
     * @property instrumentation
     */
    this.instrumentation =
      options.instrumentation ||
      new Instrumentation({
        ui: options.ui,
        initInstrumentation: options.initInstrumentation,
      });

    this.packageInfoCache = new PackageInfoCache(this.ui);

    logger.info('testing %o', !!this.testing);
  }

  /**
   * @private
   * @method maybeMakeCommand
   * @param commandName
   * @param commandArgs
   * @return {null|CurrentCommand}
   */
  maybeMakeCommand(commandName, commandArgs) {
    if (this._environment === undefined) {
      throw new Error('Unable to make command without environment, you have to execute "run" method first.');
    }
    let CurrentCommand = lookupCommand(this._environment.commands, commandName, commandArgs, {
      project: this._environment.project,
      ui: this.ui,
    });

    /*
     * XXX Need to decide what to do here about showing errors. For
     * a non-CLI project the cache is local and probably should. For
     * a CLI project the cache is there, but not sure when we'll know
     * about all the errors, because there may be multiple projects.
     *   if (this.packageInfoCache.hasErrors()) {
     *     this.packageInfoCache.showErrors();
     *   }
     */
    let command = new CurrentCommand({
      ui: this.ui,
      analytics: this.analytics,
      commands: this._environment.commands,
      tasks: this._environment.tasks,
      project: this._environment.project,
      settings: this._environment.settings,
      testing: this.testing,
      cli: this,
    });

    return command;
  }

  /**
   * @private
   * @method run
   * @param {Promise<object>} environmentPromiseHash
   * @return {Promise}
   */
  async run(environmentPromiseHash) {
    if (environmentPromiseHash === undefined) {
      return Promise.reject(new Error('Unable to execute "run" command without environment argument'));
    }
    let shutdownOnExit = null;

    let environment = (this._environment = await hash(environmentPromiseHash));

    try {
      let args = environment.cliArgs.slice();
      let commandName = args.shift();
      let commandArgs = args;
      let helpOptions;

      let commandLookupCreationToken = heimdall.start('lookup-command');

      let command = this.maybeMakeCommand(commandName, commandArgs);

      commandLookupCreationToken.stop();

      getOptionArgs('--verbose', commandArgs).forEach((arg) => {
        process.env[`EMBER_VERBOSE_${arg.toUpperCase()}`] = 'true';
      });

      let platformCheckerToken = heimdall.start('platform-checker');

      const emberCLIVersion = require('../../package.json').version;
      const PlatformChecker = require('../utilities/platform-checker');
      let platform = new PlatformChecker(process.version);
      let recommendation =
        ' See "https://github.com/ember-cli/ember-cli/blob/master/docs/node-support.md" to find out which version of Node is best to use.';

      if (!this.testing) {
        if (platform.isDeprecated) {
          this.ui.writeDeprecateLine(
            `Node ${process.version} is no longer supported by Ember CLI v${emberCLIVersion}.${recommendation}`
          );
        }

        if (!platform.isTested) {
          this.ui.writeWarnLine(
            `Ember CLI v${emberCLIVersion} is not tested against Node ${process.version}.${recommendation}`
          );
        }
      }

      platformCheckerToken.stop();

      logger.info('command: %s', commandName);

      if (!this.testing) {
        process.chdir(environment.project.root);
        let skipInstallationCheck = commandArgs.indexOf('--skip-installation-check') !== -1;
        if (environment.project.isEmberCLIProject() && !skipInstallationCheck) {
          const InstallationChecker = require('../models/installation-checker');
          new InstallationChecker({ project: environment.project }).checkInstallations();
        }
      }

      let instrumentation = this.instrumentation;
      let onCommandInterrupt;

      let runPromise = Promise.resolve().then(async () => {
        let resultOrExitCode;

        try {
          instrumentation.stopAndReport('init');

          try {
            instrumentation.start('command');

            loggerTesting.info('cli: command.beforeRun');
            onProcessInterrupt.addHandler(onCommandInterrupt);

            await command.beforeRun(commandArgs);

            loggerTesting.info('cli: command.validateAndRun');

            resultOrExitCode = await command.validateAndRun(commandArgs);
          } finally {
            instrumentation.stopAndReport('command', commandName, commandArgs);

            onProcessInterrupt.removeHandler(onCommandInterrupt);
          }
        } finally {
          instrumentation.start('shutdown');
          shutdownOnExit = function () {
            instrumentation.stopAndReport('shutdown');
          };
        }

        // if the help option was passed, call the help command
        if (resultOrExitCode === 'callHelp') {
          helpOptions = {
            environment,
            commandName,
            commandArgs,
          };

          resultOrExitCode = await this.callHelp(helpOptions);
        }

        let exitCode = resultOrExitCode;

        loggerTesting.info(`cli: command run complete. exitCode: ${exitCode}`);
        // TODO: fix this
        // Possibly this issue: https://github.com/joyent/node/issues/8329
        // Wait to resolve promise when running on windows.
        // This ensures that stdout is flushed so acceptance tests get full output

        if (process.platform === 'win32') {
          return new Promise((resolve) => {
            setTimeout(resolve, 250, exitCode);
          });
        } else {
          return exitCode;
        }
      });

      onCommandInterrupt = async () => {
        await command.onInterrupt();

        return await runPromise;
      };

      return await runPromise;
    } catch (error) {
      this.logError(error);
      return 1;
    } finally {
      if (shutdownOnExit) {
        shutdownOnExit();
      }
    }
  }

  /**
   * @private
   * @method callHelp
   * @param options
   * @return {Promise}
   */
  callHelp(options) {
    let environment = options.environment;
    let commandName = options.commandName;
    let commandArgs = options.commandArgs;
    let helpIndex = commandArgs.indexOf('--help');
    let hIndex = commandArgs.indexOf('-h');

    let HelpCommand = lookupCommand(environment.commands, 'help', commandArgs, {
      project: environment.project,
      ui: this.ui,
    });

    let help = new HelpCommand({
      ui: this.ui,
      analytics: this.analytics,
      commands: environment.commands,
      tasks: environment.tasks,
      project: environment.project,
      settings: environment.settings,
      testing: this.testing,
    });

    if (helpIndex > -1) {
      commandArgs.splice(helpIndex, 1);
    }

    if (hIndex > -1) {
      commandArgs.splice(hIndex, 1);
    }

    commandArgs.unshift(commandName);

    return help.validateAndRun(commandArgs);
  }

  /**
   * @private
   * @method logError
   * @param error
   * @return {number}
   */
  logError(error) {
    if (this.testing && error) {
      console.error(error.message);
      if (error.stack) {
        console.error(error.stack);
      }
      throw error;
    }
    this.ui.errorLog.push(error);
    this.ui.writeError(error);
    return 1;
  }
}

module.exports = CLI;
<|endoftext|>


<commit_before>/////////////////////////////////
// Controller for tickets list //
/////////////////////////////////

'use strict';

pay.controller('Login', [
    '$scope',
    '$timeout',
    'PayAuth',
    function ($scope, $timeout, PayAuth) {
        // Account already connected, hide the login form and auto show the connecter header
        if (!!PayAuth.etu) {
            $('.loginForm').hide();
            $('#logged').show();
            var $loginPanel = $('.loginPanel');

            var fixedHeight = {
                height: 75,
                maxHeight: 75,
                minHeight: 75
            };

            $loginPanel.css(fixedHeight);
            $loginPanel.children().css(fixedHeight);
            $loginPanel.children().children().css(fixedHeight);
        }

        /**
          * Animate the circles to a given size
          * @param {int} to - The size to give to the circle
          * @param {function} callback - Called when the animation is done
          */
        function animLoad (to, callback) {
            $('#loginLoader').animate({
                height: to,
                width: to,
                top: '-' + (to / 2) + 'px',
                left: '-' + (to / 2) + 'px'
            }, {
                done: function () {
                    setTimeout(function () {
                        callback();
                    }, 100);
                },
                duration: 300
            }, 'easeInOutExpo');
        }

        /**
          * Triggered when the login has been done or not
          * @param {bool} fail - True when the login has failed
          * @param {bool} wrongAuth - True when the login has failed because of the username/password
          */
        function animEnd (fail, wrongAuth) {
            $('.logging').fadeOut();
            $('#okayIcon').animate({
                fontSize: 0
            }, function () {
                if (fail) {
                    if (wrongAuth) {
                        $('#password').val('');
                        $('#loginControllerWrapper').css('backgroundColor', '#e74c3c');
                        setTimeout(function () {
                            $('#loginControllerWrapper').removeAttr('style');
                            $('.loginForm').fadeIn();
                            $('#password').focus();
                        }, 600);
                        return;
                    }
                    $('.loginForm').fadeIn();
                } else {
                    $('#logged').fadeIn();
                }
            });

            $('.loginPanel').height(75);
            $('#loginControllerWrapper').css('minHeight', 0);
        }

        /**
          * Shows the modal related to the ticket lost
          * @param {object} e - The click event
          */
        this.showModal = function (e) {
            e.preventDefault();
            $timeout(function () {
                $('#modalLost').modal();
            });
        };

        /**
          * Authenticates the user via site etu
          * @param {object} e - The click event
          */
        this.authUser = function (e) {
            e.preventDefault();
            PayAuth.auth($('#username').val(), $('#password').val()).then(function (etu) {
                $scope.etu = etu;
            }, function (wrongAuth) {
                animEnd(true, wrongAuth);
            });

            $('.loginForm').fadeOut();
            $('.logging').fadeIn();

            var callbackIn = function () {
                animLoad(0, callbackOut);
            };

            var callbackOut = function () {
                if (!$scope.etu) {
                    animLoad(65, callbackIn);
                } else {
                    $('#okayIcon').animate({
                        fontSize: 60
                    }, function () {
                        setTimeout(animEnd, 400);
                    });
                }
            };

            animLoad(65, callbackIn);
        };

        /**
          * Logs out the user
          * @param {object} e - The click event
          */
        this.logout = function (e) {
            e.preventDefault();
            window.location.reload();
        };
    }
]);
<commit_msg>Avoid two login form submit by blurring the password field<commit_after>/////////////////////////////////
// Controller for tickets list //
/////////////////////////////////

'use strict';

pay.controller('Login', [
    '$scope',
    '$timeout',
    'PayAuth',
    function ($scope, $timeout, PayAuth) {
        // Account already connected, hide the login form and auto show the connecter header
        if (!!PayAuth.etu) {
            $('.loginForm').hide();
            $('#logged').show();
            var $loginPanel = $('.loginPanel');

            var fixedHeight = {
                height: 75,
                maxHeight: 75,
                minHeight: 75
            };

            $loginPanel.css(fixedHeight);
            $loginPanel.children().css(fixedHeight);
            $loginPanel.children().children().css(fixedHeight);
        }

        /**
          * Animate the circles to a given size
          * @param {int} to - The size to give to the circle
          * @param {function} callback - Called when the animation is done
          */
        function animLoad (to, callback) {
            $('#loginLoader').animate({
                height: to,
                width: to,
                top: '-' + (to / 2) + 'px',
                left: '-' + (to / 2) + 'px'
            }, {
                done: function () {
                    setTimeout(function () {
                        callback();
                    }, 100);
                },
                duration: 300
            }, 'easeInOutExpo');
        }

        /**
          * Triggered when the login has been done or not
          * @param {bool} fail - True when the login has failed
          * @param {bool} wrongAuth - True when the login has failed because of the username/password
          */
        function animEnd (fail, wrongAuth) {
            $('.logging').fadeOut();
            $('#okayIcon').animate({
                fontSize: 0
            }, function () {
                if (fail) {
                    if (wrongAuth) {
                        $('#password').val('');
                        $('#loginControllerWrapper').css('backgroundColor', '#e74c3c');
                        setTimeout(function () {
                            $('#loginControllerWrapper').removeAttr('style');
                            $('.loginForm').fadeIn();
                            $('#password').focus();
                        }, 600);
                        return;
                    }
                    $('.loginForm').fadeIn();
                } else {
                    $('#logged').fadeIn();
                }
            });

            $('.loginPanel').height(75);
            $('#loginControllerWrapper').css('minHeight', 0);
        }

        /**
          * Shows the modal related to the ticket lost
          * @param {object} e - The click event
          */
        this.showModal = function (e) {
            e.preventDefault();
            $timeout(function () {
                $('#modalLost').modal();
            });
        };

        /**
          * Authenticates the user via site etu
          * @param {object} e - The click event
          */
        this.authUser = function (e) {
            e.preventDefault();
            $('#password').blur();
            PayAuth.auth($('#username').val(), $('#password').val()).then(function (etu) {
                $scope.etu = etu;
            }, function (wrongAuth) {
                animEnd(true, wrongAuth);
            });

            $('.loginForm').fadeOut();
            $('.logging').fadeIn();

            var callbackIn = function () {
                animLoad(0, callbackOut);
            };

            var callbackOut = function () {
                if (!$scope.etu) {
                    animLoad(65, callbackIn);
                } else {
                    $('#okayIcon').animate({
                        fontSize: 60
                    }, function () {
                        setTimeout(animEnd, 400);
                    });
                }
            };

            animLoad(65, callbackIn);
        };

        /**
          * Logs out the user
          * @param {object} e - The click event
          */
        this.logout = function (e) {
            e.preventDefault();
            window.location.reload();
        };
    }
]);
<|endoftext|>


<commit_before>// Load options
var options = {
  dontScrollPosts: false,
  dontPlayGifs: false,
};

if (window.vkManagerOptions) {
  options = window.vkManagerOptions;
}

var renderer = new marked.Renderer();

/*
 * Override marked default heading code
 * This will purge the "id" attr from the heading avoiding problems with
 * existing vk code that uses document.getElementById
 */
renderer.heading = function (text, level) {
  var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

  return '<h' + level + '>' + text + '</h' + level + '>';
};

marked.setOptions({
  renderer: renderer,
  gfm: true,
  breaks: true,
});

// Override nav.setLoc, this is called on every page change
nav.setLoc = (function() {
  var cached_function = nav.setLoc;

  return function() {

    var result = cached_function.apply(this, arguments);

    handleRouteChange();

    return result;
  };
})();

// Override Board.checkedUpdates, this is called after every board update
//
// NOTE:
// Board might be undefined on some pages, try to override on every page changes
var overrideBoardUpdates = function() {
  if (typeof Board !== 'undefined'
   && typeof Board.checkedUpdates !== 'undefined'
   && !window.boardOverrided
  ) {
    window.boardOverrided = true;

    Board.checkedUpdates = (function() {
      var cached_function = Board.checkedUpdates;

      return function() {

        var result = cached_function.apply(this, arguments);

        if (arguments && arguments.length >= 1) {
          handleBoardUpdate(arguments[1]);
        }

        return result;
      };
    })();
  }

  if (typeof wall !== 'undefined'
   && typeof wall.sendReply !== 'undefined'
   && !window.wallOverrided
  ) {
    window.wallOverrided = true;

    wall.sendReply = (function() {
      var cached_function = wall.sendReply;

      return function() {

        var result = cached_function.apply(this, arguments);

        handleBoardUpdate();

        return result;
      };
    })();
  }
};
overrideBoardUpdates();

// Play all gifs available on screen
var playGifs = function() {
  if (options.dontPlayGifs) {
    return 1;
  }

  var $gifs = document.querySelectorAll('.media_desc.media_desc_soft:not([data-playing])');
  [].forEach.call($gifs, function($gif) {
    var $link = $gif.querySelector('a.photo.page_doc_photo_href');
    if ($link) {
      var $size = $link.querySelector('.doc_size');
      var $ext = $link.querySelector('.doc_ext');

      if (!$ext || $ext.textContent.toUpperCase() !== 'GIF') {
        return;
      }

      if ($size && $size.textContent.match(/MB/)) {
        var size = parseInt($size.textContent, 10);

        if (typeof size === 'number' && size <= 4) {
          $link.click();
        } else {
          // TODO: report error
        }
      } else {
        $link.click();
      }
    }
  });
};

var convertToMarkdown = function() {
  var $allTexts = document.querySelectorAll('.bp_text:not(.markdown-body)');
  if ($allTexts) {
    [].forEach.call($allTexts, function($text) {
      $text.innerHTML = marked($text.innerHTML.replace(/(<br\ ?\/?>)+/g, "\n"));
      $text.classList.add('markdown-body');
    });
  }
};

var discussionBoardRoute = function() {
  // Update the "Discussion Board" to reload on click
  var $discussionBoard = document.querySelector('.ui_crumb:last-child');

  if ($discussionBoard) {
    var $link = document.createElement('a');
    $link.setAttribute('class', 'ui_crumb');
    $link.textContent = $discussionBoard.firstChild.textContent;
    $link.setAttribute('href', document.location.pathname);
    $link.setAttribute('onclick', 'return nav.go(this, event);');

    if ($discussionBoard.childNodes.length >= 1) {
      var $spanEl = document.createElement('span');
      $spanEl.setAttribute('class', 'ui_crumb_count');

      var $span = $discussionBoard.childNodes[1];

      $spanEl.textContent = $span.textContent;
      $link.appendChild($spanEl);
    }

    $discussionBoard.parentNode.replaceChild($link, $discussionBoard);
  }
};

var boardTopicRoute = function() {

  playGifs();
  convertToMarkdown();

  // Update the "Discussion Board" crumb to reload the page on returning
  var $allCrumbs = document.querySelectorAll('.ui_crumb');

  if ($allCrumbs && $allCrumbs.length >= 2) {
    var $discussionBoard = $allCrumbs[1];

    if ($discussionBoard) {
      $discussionBoard.setAttribute('onclick', 'return nav.go(this, event);');
    }
  }
};

var handleRouteChange = function() {

  // See NOTE above
  overrideBoardUpdates();

  var currentLocation = document.location.pathname;
  var currentQueryString = document.location.search;

  if (/board/.test(currentLocation) && !/\?act=search/.test(currentQueryString)) {
    discussionBoardRoute();
  } else if (/topic/.test(currentLocation)) {
    boardTopicRoute();
  }
};

var handleBoardUpdate = function(e) {

  playGifs();
  convertToMarkdown();

  if (options.dontScrollPosts) {
    return 1;
  }

  if (!e || !e.events || typeof e.events.forEach !== 'function') {
    return 1;
  }

  e.events.forEach(function (event) {
    var ev = event.split('<!>');
    var evType = ev[1];

    // new post event
    if (evType === 'new_post') {
      // comment area is focused
      if (document.querySelector('.submit_post_field') === document.activeElement) {
        // scroll to last post
        document.querySelector('.bp_post:last-child').scrollIntoView();
      }
    }
  });
};

handleRouteChange();
<commit_msg>Fix self post event<commit_after>// Load options
var options = {
  dontScrollPosts: false,
  dontPlayGifs: false,
};

if (window.vkManagerOptions) {
  options = window.vkManagerOptions;
}

var renderer = new marked.Renderer();

/*
 * Override marked default heading code
 * This will purge the "id" attr from the heading avoiding problems with
 * existing vk code that uses document.getElementById
 */
renderer.heading = function (text, level) {
  var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

  return '<h' + level + '>' + text + '</h' + level + '>';
};

marked.setOptions({
  renderer: renderer,
  gfm: true,
  breaks: true,
});

// Override nav.setLoc, this is called on every page change
nav.setLoc = (function() {
  var cached_function = nav.setLoc;

  return function() {

    var result = cached_function.apply(this, arguments);

    handleRouteChange();

    return result;
  };
})();

// Override Board.checkedUpdates, this is called after every board update
//
// NOTE:
// Board might be undefined on some pages, try to override on every page changes
var overrideBoardUpdates = function() {
  if (typeof Board !== 'undefined'
   && typeof Board.checkedUpdates !== 'undefined'
   && !window.boardOverrided
  ) {
    window.boardOverrided = true;

    Board.checkedUpdates = (function() {
      var cached_function = Board.checkedUpdates;

      return function() {

        var result = cached_function.apply(this, arguments);

        if (arguments && arguments.length >= 1) {
          handleBoardUpdate(arguments[1]);
        }

        return result;
      };
    })();
  }

  if (typeof Pagination !== 'undefined'
   && typeof Pagination.loaded !== 'undefined'
   && !window.paginationOverrided
  ) {
    window.paginationOverrided = true;

    Pagination.loaded = (function() {
      var cached_function = Pagination.loaded;

      return function() {

        var result = cached_function.apply(this, arguments);

        handleBoardUpdate();

        return result;
      };
    })();
  }
};
overrideBoardUpdates();

// Play all gifs available on screen
var playGifs = function() {
  if (options.dontPlayGifs) {
    return 1;
  }

  var $gifs = document.querySelectorAll('.media_desc.media_desc_soft:not([data-playing])');
  [].forEach.call($gifs, function($gif) {
    var $link = $gif.querySelector('a.photo.page_doc_photo_href');
    if ($link) {
      var $size = $link.querySelector('.doc_size');
      var $ext = $link.querySelector('.doc_ext');

      if (!$ext || $ext.textContent.toUpperCase() !== 'GIF') {
        return;
      }

      if ($size && $size.textContent.match(/MB/)) {
        var size = parseInt($size.textContent, 10);

        if (typeof size === 'number' && size <= 4) {
          $link.click();
        } else {
          // TODO: report error
        }
      } else {
        $link.click();
      }
    }
  });
};

var convertToMarkdown = function() {
  var $allTexts = document.querySelectorAll('.bp_text:not(.markdown-body)');
  if ($allTexts) {
    [].forEach.call($allTexts, function($text) {
      $text.innerHTML = marked($text.innerHTML.replace(/(<br\ ?\/?>)+/g, "\n"));
      $text.classList.add('markdown-body');
    });
  }
};

var discussionBoardRoute = function() {
  // Update the "Discussion Board" to reload on click
  var $discussionBoard = document.querySelector('.ui_crumb:last-child');

  if ($discussionBoard) {
    var $link = document.createElement('a');
    $link.setAttribute('class', 'ui_crumb');
    $link.textContent = $discussionBoard.firstChild.textContent;
    $link.setAttribute('href', document.location.pathname);
    $link.setAttribute('onclick', 'return nav.go(this, event);');

    if ($discussionBoard.childNodes.length >= 1) {
      var $spanEl = document.createElement('span');
      $spanEl.setAttribute('class', 'ui_crumb_count');

      var $span = $discussionBoard.childNodes[1];

      $spanEl.textContent = $span.textContent;
      $link.appendChild($spanEl);
    }

    $discussionBoard.parentNode.replaceChild($link, $discussionBoard);
  }
};

var boardTopicRoute = function() {

  playGifs();
  convertToMarkdown();

  // Update the "Discussion Board" crumb to reload the page on returning
  var $allCrumbs = document.querySelectorAll('.ui_crumb');

  if ($allCrumbs && $allCrumbs.length >= 2) {
    var $discussionBoard = $allCrumbs[1];

    if ($discussionBoard) {
      $discussionBoard.setAttribute('onclick', 'return nav.go(this, event);');
    }
  }
};

var handleRouteChange = function() {

  // See NOTE above
  overrideBoardUpdates();

  var currentLocation = document.location.pathname;
  var currentQueryString = document.location.search;

  if (/board/.test(currentLocation) && !/\?act=search/.test(currentQueryString)) {
    discussionBoardRoute();
  } else if (/topic/.test(currentLocation)) {
    boardTopicRoute();
  }
};

var handleBoardUpdate = function(e) {

  playGifs();
  convertToMarkdown();

  if (options.dontScrollPosts) {
    return 1;
  }

  if (!e || !e.events || typeof e.events.forEach !== 'function') {
    return 1;
  }

  e.events.forEach(function (event) {
    var ev = event.split('<!>');
    var evType = ev[1];

    // new post event
    if (evType === 'new_post') {
      // comment area is focused
      if (document.querySelector('.submit_post_field') === document.activeElement) {
        // scroll to last post
        document.querySelector('.bp_post:last-child').scrollIntoView();
      }
    }
  });
};

handleRouteChange();
<|endoftext|>


<commit_before>import React from 'react'
import styled from 'styled-components'
import {
  Box,
  Flex,
  Container,
  Text,
  Heading,
  LargeButton as Button,
  Link as A,
  Image,
  theme
} from '@hackclub/design-system'
import Helmet from 'react-helmet'
import Nav from 'components/Nav'
import Footer from 'components/Footer'
import Module from 'components/Module'
import Sheet from 'components/Sheet'
import { Lead } from 'components/Content'
import BankStats from 'components/bank/BankStats'

const styles = `
  body {
    width: 100%;
    max-width: 100vw;
    background-color: ${theme.colors.dark};
    color: ${theme.colors.gray[3]};
    background-image: radial-gradient(circle, ${theme.colors.black}, ${
  theme.colors.black
} 1px,
      ${theme.colors.dark} 1px, ${theme.colors.dark});
    background-size: 2rem 2rem;
  }
`

const CTA = styled(Button).attrs({
  target: '_blank',
  scale: true,
  chevronRight: true,
  bg: 'teal.6'
})`
  background: ${theme.gradient('teal.6', 'teal.7', 'teal.8')};
`

const Modules = styled(Container)`
  display: grid;
  grid-gap: ${theme.space[3]}px;
  h3,
  svg {
    color: ${theme.colors.white};
  }
  ${theme.mediaQueries.md} {
    grid-template-columns: repeat(3, 1fr);
    grid-gap: ${theme.space[4]}px;
    > div {
      align-items: center;
    }
  }
`
Modules.defaultProps = {
  px: 3,
  mt: [4, null, 3],
  mb: 3,
  mx: 'auto',
  maxWidth: 72,
  align: ['left', null, 'center']
}

const Megaline = styled(Heading.h1).attrs({
  fontSize: [6, 7, 8],
  color: 'white'
})`
  line-height: 1.125;
`
const Headline = styled(Heading.h2).attrs({
  fontSize: [5, 6],
  mb: 3,
  color: 'snow',
  bold: true
})`
  line-height: 1.125;
`
const subhline = { fontSize: [3, 4], style: { lineHeight: '1.375' } }

const Banner = styled(Container).attrs({
  maxWidth: 48,
  mt: [5, 6],
  mb: [3, 4],
  mx: 'auto',
  px: 3,
  align: ['left', 'center']
})``

const Join = styled(Sheet)`
  display: grid;
  grid-gap: ${theme.space[3]}px;
  align-items: flex-start;
  ${theme.mediaQueries.md} {
    grid-template-columns: 32rem auto;
  }
`

const title = 'Hack Club Bank – The Bank For Student Hackers'
const desc =
  'Get a bank account for your high school coding event or hackathon with the backing of a 501(c)(3) non-profit. Student organizers can invoice sponsors, issue physical debit cards, and get access to their event’s financials through a real-time dashboard.'
const img = 'https://hackclub.com/cards/bank.png'

export default () => (
  <Box align="center">
    <Helmet
      title={title}
      meta={[
        { name: 'description', content: desc },
        { name: 'twitter:title', content: title },
        { name: 'twitter:description', content: desc },
        { name: 'twitter:image', content: img },
        { property: 'og:title', content: title },
        { property: 'og:description', content: desc },
        { property: 'og:image', content: img },
        { property: 'og:url', content: 'https://hackclub.com/bank' }
      ]}
    />
    <style children={styles} />
    <Nav dark />
    <Box pt={[6, 7]}>
      <Image
        src={require('../../static/bank/logo.svg')}
        alt="Hack Club Bank logo"
        width={128}
        mx="auto"
        mb={3}
      />
      <Megaline>The bank for student hackers.</Megaline>
      <Lead color="inherit" px={3} maxWidth={48} my={[3, 4]}>
        Hack Club Bank is the best place for high school hackers to store money
        for hackathons. Student organizers can invoice sponsors, issue physical
        debit cards, and get access to their event’s financials through a live
        dashboard all with the benefits of the backing of a 501(c)(3) nonprofit.
      </Lead>
    </Box>
    <Flex justify="center" mb={[3, 4]}>
      <CTA href="https://medium.com/hackclub/a-bank-for-student-hackers-e5d894ea5375">
        Read the announcement
      </CTA>
    </Flex>
    <Banner>
      <Headline>Finances, done right.</Headline>
      <Lead maxWidth={36}>
        No waiting days for an email reply about your balance. Everything is
        immediately available and easy to see.
      </Lead>
    </Banner>
    <Modules>
      <Module
        icon="bank-account"
        name="Bank account"
        body="Get a 501(c)(3) non-profit bank account (contributions will be tax-deductible)."
      />
      <Module
        icon="analytics"
        name="Balance + history"
        body="Check real-time account balance and transaction history on the site at any time."
      />
      <Module
        icon="settings"
        name="Manage your finances"
        body="Add notes to transactions, export data, issue reimbursements. Easy."
      />
    </Modules>
    <Container maxWidth={48} mt={[5, 6]} mb={4}>
      <Image
        width={1}
        src="/bank-screenshot.png"
        alt="Screenshot of Bank on an iPad Pro"
      />
    </Container>
    <BankStats />
    <Banner maxWidth={36}>
      <Headline>A powerful toolbox for organizing your event.</Headline>
      <Lead>
        We’ve got all the tools to start planning your event, from emails with
        custom domains to legal forms.
      </Lead>
    </Banner>
    <Modules>
      <Module
        icon="docs"
        name="Pre-written forms"
        body="Download free consent and photo release forms for your event. No lawyers needed."
      />
      <Module
        icon="card"
        name="Debit cards"
        body="Issue physical debit cards to all your team members—no need for reimbursements."
      />
      <Module
        icon="google"
        name="G Suite"
        body="Get free G Suite + email addresses (like megan@hackchicago.io) for everyone."
      />
    </Modules>
    <Banner>
      <Headline>We’re here to help out.</Headline>
      <Lead maxWidth={36}>
        Planning your event is enough work. Let us answer questions and do the
        background work.
      </Lead>
    </Banner>
    <Modules>
      <Module
        icon="payment"
        name="Taxes + accounting"
        body="We’ll handle end-of-year taxes and accounting in the background."
      />
      <Module
        icon="support"
        name="Support anytime"
        body="Questions? We’ll never leave you in the dark. Best-effort 12hr response time."
      />
      <Module
        icon="message"
        name="Community"
        body="Talk to our community of experienced event organizers anytime."
      />
    </Modules>
    <Container maxWidth={48} py={[4, 5]} px={3}>
      <Join align="left" bg="black">
        <Container maxWidth={32} mx={0}>
          <Heading.h2 {...subhline} color="white">
            Ready to join Hack Club Bank?
          </Heading.h2>
          <Text color="smoke">
            You can join immediately with an invitation from an existing Bank
            user or a member of the Hack Club community. Otherwise, tell us
            about your event and we’ll get back to you within two weeks.
          </Text>
        </Container>
        <CTA href="https://goo.gl/forms/1UzFR4zkljL7dHQ32">Apply</CTA>
      </Join>
      <Lead maxWidth={32} color="slate" fontSize={1} mt={3}>
        Hack Club does not directly provide banking services. Banking services
        provided by Silicon Valley Bank, an FDIC-certified institution.
      </Lead>
    </Container>
    <Container maxWidth={48} py={[4, 5]} px={3} color="snow">
      <Headline align={['left', 'center']}>More organizer resources</Headline>
      <Flex flexDirection={['column', 'row']} align="left" mt={4}>
        <Container maxWidth={24} mb={3}>
          <Heading.h3 {...subhline}>Hackathons Directory</Heading.h3>
          <Text color="smoke" fontSize={2} mt={2} mb={3}>
            We maintain an up-to-date directory of high school hackathons
            happening all around the world. Attend some and add yours!
          </Text>
          <A
            href="https://hackathons.hackclub.com"
            chevronRight
            hoverline
            color="primary"
          >
            See the list
          </A>
        </Container>
        <Container maxWidth={24} mb={3}>
          <Heading.h3 {...subhline}>#organizers channel on Slack</Heading.h3>
          <Text color="smoke" fontSize={2} mt={2} mb={3}>
            On our Slack, we have a worldwide community of hundreds of event
            organizers. Get advice and connect with fellow organizers.
          </Text>
          <A
            href="https://slack.hackclub.com"
            chevronRight
            hoverline
            color="primary"
          >
            Join our Slack
          </A>
        </Container>
      </Flex>
    </Container>
    <Footer dark />
  </Box>
)
<commit_msg>Use emdash in Bank description<commit_after>import React from 'react'
import styled from 'styled-components'
import {
  Box,
  Flex,
  Container,
  Text,
  Heading,
  LargeButton as Button,
  Link as A,
  Image,
  theme
} from '@hackclub/design-system'
import Helmet from 'react-helmet'
import Nav from 'components/Nav'
import Footer from 'components/Footer'
import Module from 'components/Module'
import Sheet from 'components/Sheet'
import { Lead } from 'components/Content'
import BankStats from 'components/bank/BankStats'

const styles = `
  body {
    width: 100%;
    max-width: 100vw;
    background-color: ${theme.colors.dark};
    color: ${theme.colors.gray[3]};
    background-image: radial-gradient(circle, ${theme.colors.black}, ${
  theme.colors.black
} 1px,
      ${theme.colors.dark} 1px, ${theme.colors.dark});
    background-size: 2rem 2rem;
  }
`

const CTA = styled(Button).attrs({
  target: '_blank',
  scale: true,
  chevronRight: true,
  bg: 'teal.6'
})`
  background: ${theme.gradient('teal.6', 'teal.7', 'teal.8')};
`

const Modules = styled(Container)`
  display: grid;
  grid-gap: ${theme.space[3]}px;
  h3,
  svg {
    color: ${theme.colors.white};
  }
  ${theme.mediaQueries.md} {
    grid-template-columns: repeat(3, 1fr);
    grid-gap: ${theme.space[4]}px;
    > div {
      align-items: center;
    }
  }
`
Modules.defaultProps = {
  px: 3,
  mt: [4, null, 3],
  mb: 3,
  mx: 'auto',
  maxWidth: 72,
  align: ['left', null, 'center']
}

const Megaline = styled(Heading.h1).attrs({
  fontSize: [6, 7, 8],
  color: 'white'
})`
  line-height: 1.125;
`
const Headline = styled(Heading.h2).attrs({
  fontSize: [5, 6],
  mb: 3,
  color: 'snow',
  bold: true
})`
  line-height: 1.125;
`
const subhline = { fontSize: [3, 4], style: { lineHeight: '1.375' } }

const Banner = styled(Container).attrs({
  maxWidth: 48,
  mt: [5, 6],
  mb: [3, 4],
  mx: 'auto',
  px: 3,
  align: ['left', 'center']
})``

const Join = styled(Sheet)`
  display: grid;
  grid-gap: ${theme.space[3]}px;
  align-items: flex-start;
  ${theme.mediaQueries.md} {
    grid-template-columns: 32rem auto;
  }
`

const title = 'Hack Club Bank – The Bank For Student Hackers'
const desc =
  'Get a bank account for your high school coding event or hackathon with the backing of a 501(c)(3) non-profit. Student organizers can invoice sponsors, issue physical debit cards, and get access to their event’s financials through a real-time dashboard.'
const img = 'https://hackclub.com/cards/bank.png'

export default () => (
  <Box align="center">
    <Helmet
      title={title}
      meta={[
        { name: 'description', content: desc },
        { name: 'twitter:title', content: title },
        { name: 'twitter:description', content: desc },
        { name: 'twitter:image', content: img },
        { property: 'og:title', content: title },
        { property: 'og:description', content: desc },
        { property: 'og:image', content: img },
        { property: 'og:url', content: 'https://hackclub.com/bank' }
      ]}
    />
    <style children={styles} />
    <Nav dark />
    <Box pt={[6, 7]}>
      <Image
        src={require('../../static/bank/logo.svg')}
        alt="Hack Club Bank logo"
        width={128}
        mx="auto"
        mb={3}
      />
      <Megaline>The bank for student hackers.</Megaline>
      <Lead color="inherit" px={3} maxWidth={48} my={[3, 4]}>
        Hack Club Bank is the best place for high school hackers to store money
        for hackathons. Student organizers can invoice sponsors, issue physical
        debit cards, and get access to their event’s financials through a live
        dashboard—all with the benefits of the backing of a 501(c)(3) nonprofit.
      </Lead>
    </Box>
    <Flex justify="center" mb={[3, 4]}>
      <CTA href="https://medium.com/hackclub/a-bank-for-student-hackers-e5d894ea5375">
        Read the announcement
      </CTA>
    </Flex>
    <Banner>
      <Headline>Finances, done right.</Headline>
      <Lead maxWidth={36}>
        No waiting days for an email reply about your balance. Everything is
        immediately available and easy to see.
      </Lead>
    </Banner>
    <Modules>
      <Module
        icon="bank-account"
        name="Bank account"
        body="Get a 501(c)(3) non-profit bank account (contributions will be tax-deductible)."
      />
      <Module
        icon="analytics"
        name="Balance + history"
        body="Check real-time account balance and transaction history on the site at any time."
      />
      <Module
        icon="settings"
        name="Manage your finances"
        body="Add notes to transactions, export data, issue reimbursements. Easy."
      />
    </Modules>
    <Container maxWidth={48} mt={[5, 6]} mb={4}>
      <Image
        width={1}
        src="/bank-screenshot.png"
        alt="Screenshot of Bank on an iPad Pro"
      />
    </Container>
    <BankStats />
    <Banner maxWidth={36}>
      <Headline>A powerful toolbox for organizing your event.</Headline>
      <Lead>
        We’ve got all the tools to start planning your event, from emails with
        custom domains to legal forms.
      </Lead>
    </Banner>
    <Modules>
      <Module
        icon="docs"
        name="Pre-written forms"
        body="Download free consent and photo release forms for your event. No lawyers needed."
      />
      <Module
        icon="card"
        name="Debit cards"
        body="Issue physical debit cards to all your team members—no need for reimbursements."
      />
      <Module
        icon="google"
        name="G Suite"
        body="Get free G Suite + email addresses (like megan@hackchicago.io) for everyone."
      />
    </Modules>
    <Banner>
      <Headline>We’re here to help out.</Headline>
      <Lead maxWidth={36}>
        Planning your event is enough work. Let us answer questions and do the
        background work.
      </Lead>
    </Banner>
    <Modules>
      <Module
        icon="payment"
        name="Taxes + accounting"
        body="We’ll handle end-of-year taxes and accounting in the background."
      />
      <Module
        icon="support"
        name="Support anytime"
        body="Questions? We’ll never leave you in the dark. Best-effort 12hr response time."
      />
      <Module
        icon="message"
        name="Community"
        body="Talk to our community of experienced event organizers anytime."
      />
    </Modules>
    <Container maxWidth={48} py={[4, 5]} px={3}>
      <Join align="left" bg="black">
        <Container maxWidth={32} mx={0}>
          <Heading.h2 {...subhline} color="white">
            Ready to join Hack Club Bank?
          </Heading.h2>
          <Text color="smoke">
            You can join immediately with an invitation from an existing Bank
            user or a member of the Hack Club community. Otherwise, tell us
            about your event and we’ll get back to you within two weeks.
          </Text>
        </Container>
        <CTA href="https://goo.gl/forms/1UzFR4zkljL7dHQ32">Apply</CTA>
      </Join>
      <Lead maxWidth={32} color="slate" fontSize={1} mt={3}>
        Hack Club does not directly provide banking services. Banking services
        provided by Silicon Valley Bank, an FDIC-certified institution.
      </Lead>
    </Container>
    <Container maxWidth={48} py={[4, 5]} px={3} color="snow">
      <Headline align={['left', 'center']}>More organizer resources</Headline>
      <Flex flexDirection={['column', 'row']} align="left" mt={4}>
        <Container maxWidth={24} mb={3}>
          <Heading.h3 {...subhline}>Hackathons Directory</Heading.h3>
          <Text color="smoke" fontSize={2} mt={2} mb={3}>
            We maintain an up-to-date directory of high school hackathons
            happening all around the world. Attend some and add yours!
          </Text>
          <A
            href="https://hackathons.hackclub.com"
            chevronRight
            hoverline
            color="primary"
          >
            See the list
          </A>
        </Container>
        <Container maxWidth={24} mb={3}>
          <Heading.h3 {...subhline}>#organizers channel on Slack</Heading.h3>
          <Text color="smoke" fontSize={2} mt={2} mb={3}>
            On our Slack, we have a worldwide community of hundreds of event
            organizers. Get advice and connect with fellow organizers.
          </Text>
          <A
            href="https://slack.hackclub.com"
            chevronRight
            hoverline
            color="primary"
          >
            Join our Slack
          </A>
        </Container>
      </Flex>
    </Container>
    <Footer dark />
  </Box>
)
<|endoftext|>


<commit_before>'use strict';

var ig     = require('instagram-node').instagram()
  , config = require('../config')
  , logger = require('../lib').logger
  , Image  = require('../models').Image
  , async  = require('async')
  , _      = require('lodash')
  ;

(function() {

  logger.info('Beginning Instagram Import');

  ig.use({
    client_id: config.instagram.key,
    client_secret: config.instagram.secret
  });

  ig.user_media_recent(config.instagram.userid, function(err, medias, pagination, limit) {
    if (medias && medias.length > 0) {

      async.each(medias, function(media, done) {
        var image = {
          instid: media.id,
          href: media.link,
          src: media.images.low_resolution.url,
          postDate: new Date(0).setUTCSeconds(media.created_time)
        }

        new Image(image).save(function(err) {

          // prevent db errors from stopping the script
          done(null);
        });
      }, function(err) {
        if (err) {
          logger.error(err);
        }

        logger.info('Instagram Import Complete');
        process.exit();
      });
    } else {
      if (err) {
        logger.error(err);
      }

      logger.info('Instagram Import Complete');
      process.exit();
    }
  });
})();
<commit_msg>continue using access token for instagram<commit_after>'use strict';

var ig     = require('instagram-node').instagram()
  , config = require('../config')
  , logger = require('../lib').logger
  , Image  = require('../models').Image
  , async  = require('async')
  , _      = require('lodash')
  ;

(function() {

  logger.info('Beginning Instagram Import');

  ig.use({
    // client_id: config.instagram.key,
    // client_secret: config.instagram.secret,
    access_token: config.instagram.token
  });

  ig.user_media_recent(config.instagram.userid, function(err, medias, pagination, limit) {
    if (medias && medias.length > 0) {

      async.each(medias, function(media, done) {
        var image = {
          instid: media.id,
          href: media.link,
          src: media.images.low_resolution.url,
          postDate: new Date(0).setUTCSeconds(media.created_time)
        }

        new Image(image).save(function(err) {

          // prevent db errors from stopping the script
          done(null);
        });
      }, function(err) {
        if (err) {
          logger.error(err);
        }

        logger.info('Instagram Import Complete');
        process.exit();
      });
    } else {
      if (err) {
        logger.error(err);
      }

      logger.info('Instagram Import Complete');
      process.exit();
    }
  });
})();
<|endoftext|>


<commit_before>'use strict';

var presidents = `George Washington, Feb 22 1732, Westmoreland Co. Va., Dec 14 1799, Mount Vernon Va.
			John Adams, Oct 30 1735, Quincy Mass., Jul 04 1826, Quincy Mass.
			Thomas Jefferson, Apr 13 1743, Albemarle Co. Va., Jul 04 1826, Albemarle Co. Va.
			James Madison, Mar 16 1751, Port Conway Va., Jun 28 1836, Orange Co. Va.
			James Monroe, Apr 28 1758, Westmoreland Co. Va., Jul 04 1831, New York New York
			John Quincy Adams, Jul 11 1767, Quincy Mass., Feb 23 1848, Washington D.C.
			Andrew Jackson, Mar 15 1767, Lancaster Co. S.C., Jun 08 1845, Nashville Tennessee
			Martin Van Buren, Dec 05 1782, Kinderhook New York, Jul 24 1862, Kinderhook New York
			William Henry Harrison, Feb 09 1773, Charles City Co. Va., Apr 04 1841, Washington D.C.
			John Tyler, Mar 29 1790, Charles City Co. Va., Jan 18 1862, Richmond Va.
			James K. Polk, Nov 02 1795, Mecklenburg Co. N.C., Jun 15 1849, Nashville Tennessee
			Zachary Taylor, Nov 24 1784, Orange County Va., Jul 09 1850, Washington D.C
			Millard Fillmore, Jan 07 1800, Cayuga Co. New York, Mar 08 1874, Buffalo New York
			Franklin Pierce, Nov 23 1804, Hillsborough N.H., Oct 08 1869, Concord New Hamp.
			James Buchanan, Apr 23 1791, Cove Gap Pa., Jun 01 1868, Lancaster Pa.
			Abraham Lincoln, Feb 12 1809, LaRue Co. Kentucky, Apr 15 1865, Washington D.C.
			Andrew Johnson, Dec 29 1808, Raleigh North Carolina, Jul 31 1875, Elizabethton Tenn.
			Ulysses S. Grant, Apr 27 1822, Point Pleasant Ohio, Jul 23 1885, Wilton New York
			Rutherford B. Hayes, Oct 04 1822, Delaware Ohio, Jan 17 1893, Fremont Ohio
			James A. Garfield, Nov 19 1831, Cuyahoga Co. Ohio, Sep 19 1881, Elberon New Jersey
			Chester Arthur, Oct 05 1829, Fairfield Vermont, Nov 18 1886, New York New York
			Grover Cleveland, Mar 18 1837, Caldwell New Jersey, Jun 24 1908, Princeton New Jersey
			Benjamin Harrison, Aug 20 1833, North Bend Ohio, Mar 13 1901, Indianapolis Indiana
			William McKinley, Jan 29 1843, Niles Ohio, Sep 14 1901, Buffalo New York
			Theodore Roosevelt, Oct 27 1858, New York New York, Jan 06 1919, Oyster Bay New York
			William Howard Taft, Sep 15 1857, Cincinnati Ohio, Mar 08 1930, Washington D.C.
			Woodrow Wilson, Dec 28 1856, Staunton Virginia, Feb 03 1924, Washington D.C.
			Warren G. Harding, Nov 02 1865, Morrow County Ohio, Aug 02 1923, San Francisco Cal.
			Calvin Coolidge, Jul 04 1872, Plymouth Vermont, Jan 05 1933, Northampton Mass.
			Herbert Hoover, Aug 10 1874, West Branch Iowa, Oct 20 1964, New York New York
			Franklin Roosevelt, Jan 30 1882, Hyde Park New York, Apr 12 1945, Warm Springs Georgia
			Harry S. Truman, May 08 1884, Lamar Missouri, Dec 26 1972, Kansas City Missouri
			Dwight Eisenhower, Oct 14 1890, Denison Texas, Mar 28 1969, Washington D.C.
			John F. Kennedy, May 29 1917, Brookline Mass., Nov 22 1963, Dallas Texas
			Lyndon B. Johnson, Aug 27 1908, Gillespie Co. Texas, Jan 22 1973, Gillespie Co. Texas
			Richard Nixon, Jan 09 1913, Yorba Linda Cal., Apr 22 1994, New York New York
			Gerald Ford, Jul 14 1913, Omaha Nebraska, Dec 26 2006, Rancho Mirage Cal.
			Jimmy Carter, Oct 01 1924, Plains Georgia, ,
			Ronald Reagan, Feb 06 1911, Tampico Illinois, Jun 05 2004, Los Angeles Cal.
			George Bush, Jun 12 1924, Milton Mass., ,
			Bill Clinton, Aug 19 1946, Hope Arkansas, ,
			George W. Bush, Jul 06 1946, New Haven Conn., , ,
			Barack Obama, Aug 04 1961, Honolulu Hawaii, , `;

var lines = presidents.split('\n');

var presidentsArray = [];
for (var i = 0; i < lines.length; i++) {
	presidentsArray[i] = lines[i].split(',');
}

function checkAlive(date) {
	for (var i = 0; i < presidentsArray.length; i++) {
		if ((date <= parseInt(presidentsArray[i][3].substring(7, 12)) && date > parseInt(presidentsArray[i][1].substring(7, 12))) || (presidentsArray[i][3] == " " && date > parseInt(presidentsArray[i][1].substring(7, 12)))) {
			document.getElementById("superInfo").innerHTML += presidentsArray[i][0] + "
";
		}
	}
}

function whoIsAlive() {
	document.getElementById("superInfo").innerHTML = "";
	checkAlive(document.getElementById("textbox").value);
	if (document.getElementById("superInfo").innerHTML === "") {
		document.getElementById("superInfo").innerHTML = "No presidents alive in year: " + document.getElementById("textbox").value
	}
}<commit_msg>account for fringe cases<commit_after>'use strict';

var presidents = `George Washington, Feb 22 1732, Westmoreland Co. Va., Dec 14 1799, Mount Vernon Va.
			John Adams, Oct 30 1735, Quincy Mass., Jul 04 1826, Quincy Mass.
			Thomas Jefferson, Apr 13 1743, Albemarle Co. Va., Jul 04 1826, Albemarle Co. Va.
			James Madison, Mar 16 1751, Port Conway Va., Jun 28 1836, Orange Co. Va.
			James Monroe, Apr 28 1758, Westmoreland Co. Va., Jul 04 1831, New York New York
			John Quincy Adams, Jul 11 1767, Quincy Mass., Feb 23 1848, Washington D.C.
			Andrew Jackson, Mar 15 1767, Lancaster Co. S.C., Jun 08 1845, Nashville Tennessee
			Martin Van Buren, Dec 05 1782, Kinderhook New York, Jul 24 1862, Kinderhook New York
			William Henry Harrison, Feb 09 1773, Charles City Co. Va., Apr 04 1841, Washington D.C.
			John Tyler, Mar 29 1790, Charles City Co. Va., Jan 18 1862, Richmond Va.
			James K. Polk, Nov 02 1795, Mecklenburg Co. N.C., Jun 15 1849, Nashville Tennessee
			Zachary Taylor, Nov 24 1784, Orange County Va., Jul 09 1850, Washington D.C
			Millard Fillmore, Jan 07 1800, Cayuga Co. New York, Mar 08 1874, Buffalo New York
			Franklin Pierce, Nov 23 1804, Hillsborough N.H., Oct 08 1869, Concord New Hamp.
			James Buchanan, Apr 23 1791, Cove Gap Pa., Jun 01 1868, Lancaster Pa.
			Abraham Lincoln, Feb 12 1809, LaRue Co. Kentucky, Apr 15 1865, Washington D.C.
			Andrew Johnson, Dec 29 1808, Raleigh North Carolina, Jul 31 1875, Elizabethton Tenn.
			Ulysses S. Grant, Apr 27 1822, Point Pleasant Ohio, Jul 23 1885, Wilton New York
			Rutherford B. Hayes, Oct 04 1822, Delaware Ohio, Jan 17 1893, Fremont Ohio
			James A. Garfield, Nov 19 1831, Cuyahoga Co. Ohio, Sep 19 1881, Elberon New Jersey
			Chester Arthur, Oct 05 1829, Fairfield Vermont, Nov 18 1886, New York New York
			Grover Cleveland, Mar 18 1837, Caldwell New Jersey, Jun 24 1908, Princeton New Jersey
			Benjamin Harrison, Aug 20 1833, North Bend Ohio, Mar 13 1901, Indianapolis Indiana
			William McKinley, Jan 29 1843, Niles Ohio, Sep 14 1901, Buffalo New York
			Theodore Roosevelt, Oct 27 1858, New York New York, Jan 06 1919, Oyster Bay New York
			William Howard Taft, Sep 15 1857, Cincinnati Ohio, Mar 08 1930, Washington D.C.
			Woodrow Wilson, Dec 28 1856, Staunton Virginia, Feb 03 1924, Washington D.C.
			Warren G. Harding, Nov 02 1865, Morrow County Ohio, Aug 02 1923, San Francisco Cal.
			Calvin Coolidge, Jul 04 1872, Plymouth Vermont, Jan 05 1933, Northampton Mass.
			Herbert Hoover, Aug 10 1874, West Branch Iowa, Oct 20 1964, New York New York
			Franklin Roosevelt, Jan 30 1882, Hyde Park New York, Apr 12 1945, Warm Springs Georgia
			Harry S. Truman, May 08 1884, Lamar Missouri, Dec 26 1972, Kansas City Missouri
			Dwight Eisenhower, Oct 14 1890, Denison Texas, Mar 28 1969, Washington D.C.
			John F. Kennedy, May 29 1917, Brookline Mass., Nov 22 1963, Dallas Texas
			Lyndon B. Johnson, Aug 27 1908, Gillespie Co. Texas, Jan 22 1973, Gillespie Co. Texas
			Richard Nixon, Jan 09 1913, Yorba Linda Cal., Apr 22 1994, New York New York
			Gerald Ford, Jul 14 1913, Omaha Nebraska, Dec 26 2006, Rancho Mirage Cal.
			Jimmy Carter, Oct 01 1924, Plains Georgia, ,
			Ronald Reagan, Feb 06 1911, Tampico Illinois, Jun 05 2004, Los Angeles Cal.
			George Bush, Jun 12 1924, Milton Mass., ,
			Bill Clinton, Aug 19 1946, Hope Arkansas, ,
			George W. Bush, Jul 06 1946, New Haven Conn., , ,
			Barack Obama, Aug 04 1961, Honolulu Hawaii, , `;

var lines = presidents.split('\n');

var presidentsArray = [];
for (var i = 0; i < lines.length; i++) {
	presidentsArray[i] = lines[i].split(',');
}

function checkAlive(date) {
	for (var i = 0; i < presidentsArray.length; i++) {
		if ((date <= parseInt(presidentsArray[i][3].substring(7, 12)) && date > parseInt(presidentsArray[i][1].substring(7, 12))) || (presidentsArray[i][3] == " " && date > parseInt(presidentsArray[i][1].substring(7, 12)))) {
			document.getElementById("superInfo").innerHTML += presidentsArray[i][0] + "
";
		}
	}
}

function whoIsAlive() {
	document.getElementById("superInfo").innerHTML = "";
	checkAlive(document.getElementById("textbox").value);
	if (document.getElementById("superInfo").innerHTML === "" && document.getElementById("textbox").value !== "") {
		document.getElementById("superInfo").innerHTML = "No presidents alive in year: " + document.getElementById("textbox").value
	}
	if (document.getElementById("textbox").value === "") {
		document.getElementById("superInfo").innerHTML = "No year entered"
	}
}<|endoftext|>