<commit_before>const ProxyAgent = require('proxy-agent');
const http = require('http');
const https = require('https');

const Path = require('path');
const ContentDisposition = require('content-disposition');
const ContentType = require('content-type');
const MediaTyper = require('media-typer');
const iconv = require('iconv-lite');
const Cookie = require('tough-cookie').Cookie;
const mime = require('mime');
const fs = require('fs');
const debug = require('debug')('url-inspector');

const inspectSax = require('./sax');
const inspectEmbed = require('./embed');
const inspectStreat = require('./streat');

// maximum bytes to download for each type of data
const inspectors = {
	embed: [inspectEmbed.embed, 10000],
	svg: [inspectSax.svg, 30000],
	image: [inspectStreat.media, 128000, 0.1],
	audio: [inspectStreat.media, 200000, 0.1],
	video: [inspectStreat.media, 512000, 0.1],
	link: [inspectSax.html, 512000],
	file: [inspectStreat.file, 32000],
	archive: [(obj, res, cb) => {
		cb(null, obj);
	}, 0]
};

exports.exists = function (urlObj, cb) {
	setOrigin(urlObj);
	const opts = { headers: urlObj.headers };
	opts.method = 'HEAD';
	const secure = /^https:?$/.test(urlObj.protocol);
	const req = (secure ? https : http).request(urlObj, opts, (res) => {
		const status = res.statusCode;
		debug("remote", urlObj, "returns", status);
		req.destroy();
		if (status == 204 || res.headers['Content-Length'] == 0) {
			return cb(false);
		} else if (status >= 200 && status < 400) {
			return cb(parseType(res.headers['Content-Type']));
		} else {
			return cb(false);
		}
	});
	req.end();
};

exports.request = function (urlObj, obj, cb) {
	debug("request url", urlObj.href);

	doRequest(urlObj, (err, req, res) => {
		if (err) return cb(err);
		const status = res.statusCode;
		res.pause();
		debug("got response status %d", status);

		if (status < 200 || (status >= 400 && status < 600)) {
			// definitely an error - status above 600 could be an anti-bot system
			return cb(status);
		}
		if (status >= 300 && status < 400 && res.headers.location) {
			req.abort();
			const redirObj = new URL(res.headers.location, urlObj.href);
			debug("to location", redirObj);
			redirObj.headers = Object.assign({}, urlObj.headers);
			const cookies = replyCookies(res.headers['set-cookie'], redirObj.headers.Cookie);
			if (cookies) {
				debug("replying with cookie", cookies);
				redirObj.headers.Cookie = cookies;
			}
			redirObj.redirects = (urlObj.redirects || 0) + 1;
			if (redirObj.redirects >= 5) return cb("Too many http redirects");
			obj.location = redirObj;
			return exports.request(redirObj, obj, cb);
		}

		let contentType = res.headers['content-type'];

		if (!contentType) contentType = mime.getType(Path.basename(urlObj.pathname));
		const mimeObj = parseType(contentType);
		if (obj.type == "embed") {
			obj.mime = "text/html";
		} else {
			obj.mime = MediaTyper.format(mimeObj);
			obj.type = mime2type(mimeObj);
		}
		obj.ext = mime.getExtension(obj.mime);

		const contentLength = res.headers['content-length'];
		if (contentLength != null) {
			obj.size = parseInt(contentLength);
		}
		let disposition = res.headers['content-disposition'];
		if (disposition != null) {
			debug("got content disposition", disposition);
			if (disposition.startsWith('filename=')) disposition = 'attachment; ' + disposition;
			try {
				disposition = ContentDisposition.parse(disposition);
			} catch (ex) {
				debug("Unknown Content-Disposition format", ex);
			}
			if (disposition && disposition.parameters.filename) {
				urlObj = new URL(disposition.parameters.filename, urlObj);
			}
		}

		debug("(mime, type, length) is (%s, %s, %d)", obj.mime, obj.type, obj.size);
		let charset = mimeObj.parameters && mimeObj.parameters.charset;
		if (charset) {
			charset = charset.toLowerCase();
			if (charset != "utf-8") {
				res = res.pipe(iconv.decodeStream(charset));
			} else {
				res.setEncoding(charset);
			}
		} else if (mimeObj.type == "text" || mimeObj.subtype == "svg" || mimeObj.suffix == "xml") {
			res.setEncoding("utf-8");
		}
		const fun = inspectors[obj.type];
		if (urlObj.protocol != "file:") pipeLimit(req, res, fun[1], fun[2]);
		fun[0](obj, res, (err, tags) => {
			if (err) {
				// eslint-disable-next-line no-console
				console.error(err);
			}
			req.abort();
			// request oembed when
			// - not blacklisted (noembed)
			// - has already or has found a oembed url
			// - does not have a thumbnail or does not have an html embed code,
			const fetchEmbed = !obj.noembed && obj.oembed && (!obj.thumbnail || !obj.html);
			delete obj.noembed;
			let canon = obj.canonical;
			if (canon && urlObj.protocol != "file:" && canon != obj.source && obj.nocanonical !== true) {
				canon = new URL(canon);
				canon.redirects = (urlObj.redirects || 0) + 1;
			}
			delete obj.canonical;
			delete obj.nocanonical;
			if (fetchEmbed) {
				obj.type = "embed";
				// prevent loops
				obj.noembed = true;
				debug("fetch embed", obj.oembed);
				const urlObjEmbed = new URL(obj.oembed);
				urlObjEmbed.headers = Object.assign({}, urlObj.headers);
				if (urlObj.protocol) urlObjEmbed.protocol = urlObj.protocol;
				exports.request(urlObjEmbed, obj, (err, cobj, ctags) => {
					if (err) return cb(null, obj, tags);
					else return cb(null, cobj, ctags);
				});
			} else if (canon && canon.redirects < 5 && canon.pathname != urlObj.pathname && canon.pathname + '/' != urlObj.pathname && canon.pathname != urlObj.pathname + '/') {
				debug("fetch canonical url", canon.href);
				canon.headers = Object.assign({}, urlObj.headers);
				exports.request(canon, obj, (err, cobj, ctags) => {
					if (err) {
						return cb(null, obj, tags);
					} else {
						cobj.location = canon;
						return cb(null, cobj, ctags);
					}
				});
			} else {
				cb(null, obj, tags);
			}
		});
	});
};

function doRequest(urlObj, cb) {
	let req;
	if (urlObj.protocol == "file:") {
		fs.stat(urlObj.pathname, (err, stat) => {
			if (err) return cb(err);
			try {
				req = fs.createReadStream(urlObj.pathname).on('error', cb);
			} catch(err) {
				cb(err);
				return;
			}
			if (!req.abort) req.abort = req.destroy;
			req.headers = {
				'content-length': stat.size.toString()
			};
			req.local = true;
			cb(null, req, req);
		});
	} else {
		setOrigin(urlObj);
		const opts = {
			headers: urlObj.headers,
			agent: new ProxyAgent()
		};
		const secure = /^https:?$/.test(urlObj.protocol);
		if (secure) opts.rejectUnauthorized = false;

		try {
			req = (secure ? https : http).request(urlObj, opts, (res) => {
				cb(null, req, res);
			}).on('error', (err) => {
				if (err.code == "ECONNRESET" && opts.headers['User-Agent'].includes("Googlebot")) {
					// suspicion of User-Agent sniffing
					debug("ECONNRESET, trying bot-less ua");
					urlObj.headers["User-Agent"] = "Mozilla/5.0 (compatible)";
					doRequest(opts, cb);
				} else {
					cb(err);
				}
			});
			req.end();
		} catch(err) {
			cb(err);
			return;
		}
	}
}

function setOrigin(urlObj) {
	const origin = new URL(urlObj);
	origin.pathname = "";
	origin.search = "";
	urlObj.headers.Origin = origin.href;
}

function mime2type(obj) {
	let type = 'file';
	if (obj.subtype == "html") {
		type = 'link';
	} else if (obj.subtype == 'svg') {
		type = 'svg';
	} else if (['image', 'audio', 'video'].indexOf(obj.type) >= 0) {
		type = obj.type;
	} else if (['x-xz', 'x-gtar', 'x-gtar-compressed', 'x-tar', 'gzip', 'zip'].indexOf(obj.subtype) >= 0) {
		type = 'archive';
	} else if (obj.subtype == "json") {
		type = 'embed';
	}
	return type;
}

function pipeLimit(req, res, length, percent) {
	if (!length) return req.abort();
	if (percent) {
		const contentLength = parseInt(res.headers['content-length']);
		if (!Number.isNaN(contentLength)) {
			length = Math.max(length, contentLength * percent);
		}
	}
	let curLength = 0;
	res.on('data', (buf) => {
		if (res.nolimit) return;
		curLength += buf.length;
		if (curLength >= length) {
			debug("got %d bytes, aborting", curLength);
			req.abort();
		}
	});
}

function replyCookies(setCookies, prev) {
	if (!setCookies) return prev;
	let cookies;
	if (Array.isArray(setCookies)) cookies = setCookies.map(Cookie.parse);
	else cookies = [Cookie.parse(setCookies)];
	cookies = cookies.map((cookie) => {
		return cookie.cookieString();
	});
	if (prev) prev.split('; ').forEach((str) => {
		if (cookies.indexOf(str) < 0) cookies.unshift(str);
	});
	return cookies.join('; ');
}

function parseType(str) {
	if (!str) return str;
	try {
		const ct = ContentType.parse(str);
		const mt = MediaTyper.parse(ct.type);
		return Object.assign(ct, mt);
	} catch (e) {
		return {};
	}
}
<commit_msg>Use a single proxyAgent instance and also add it to exists<commit_after>const ProxyAgent = require('proxy-agent');
const http = require('http');
const https = require('https');

const Path = require('path');
const ContentDisposition = require('content-disposition');
const ContentType = require('content-type');
const MediaTyper = require('media-typer');
const iconv = require('iconv-lite');
const Cookie = require('tough-cookie').Cookie;
const mime = require('mime');
const fs = require('fs');
const debug = require('debug')('url-inspector');

const inspectSax = require('./sax');
const inspectEmbed = require('./embed');
const inspectStreat = require('./streat');

// maximum bytes to download for each type of data
const inspectors = {
	embed: [inspectEmbed.embed, 10000],
	svg: [inspectSax.svg, 30000],
	image: [inspectStreat.media, 128000, 0.1],
	audio: [inspectStreat.media, 200000, 0.1],
	video: [inspectStreat.media, 512000, 0.1],
	link: [inspectSax.html, 512000],
	file: [inspectStreat.file, 32000],
	archive: [(obj, res, cb) => {
		cb(null, obj);
	}, 0]
};

const proxy = new ProxyAgent();

exports.exists = function (urlObj, cb) {
	setOrigin(urlObj);
	const opts = {
		headers: urlObj.headers,
		agent: proxy
	};
	opts.method = 'HEAD';
	const secure = /^https:?$/.test(urlObj.protocol);
	const req = (secure ? https : http).request(urlObj, opts, (res) => {
		const status = res.statusCode;
		debug("remote", urlObj, "returns", status);
		req.destroy();
		if (status == 204 || res.headers['Content-Length'] == 0) {
			return cb(false);
		} else if (status >= 200 && status < 400) {
			return cb(parseType(res.headers['Content-Type']));
		} else {
			return cb(false);
		}
	});
	req.end();
};

exports.request = function (urlObj, obj, cb) {
	debug("request url", urlObj.href);

	doRequest(urlObj, (err, req, res) => {
		if (err) return cb(err);
		const status = res.statusCode;
		res.pause();
		debug("got response status %d", status);

		if (status < 200 || (status >= 400 && status < 600)) {
			// definitely an error - status above 600 could be an anti-bot system
			return cb(status);
		}
		if (status >= 300 && status < 400 && res.headers.location) {
			req.abort();
			const redirObj = new URL(res.headers.location, urlObj.href);
			debug("to location", redirObj);
			redirObj.headers = Object.assign({}, urlObj.headers);
			const cookies = replyCookies(res.headers['set-cookie'], redirObj.headers.Cookie);
			if (cookies) {
				debug("replying with cookie", cookies);
				redirObj.headers.Cookie = cookies;
			}
			redirObj.redirects = (urlObj.redirects || 0) + 1;
			if (redirObj.redirects >= 5) return cb("Too many http redirects");
			obj.location = redirObj;
			return exports.request(redirObj, obj, cb);
		}

		let contentType = res.headers['content-type'];

		if (!contentType) contentType = mime.getType(Path.basename(urlObj.pathname));
		const mimeObj = parseType(contentType);
		if (obj.type == "embed") {
			obj.mime = "text/html";
		} else {
			obj.mime = MediaTyper.format(mimeObj);
			obj.type = mime2type(mimeObj);
		}
		obj.ext = mime.getExtension(obj.mime);

		const contentLength = res.headers['content-length'];
		if (contentLength != null) {
			obj.size = parseInt(contentLength);
		}
		let disposition = res.headers['content-disposition'];
		if (disposition != null) {
			debug("got content disposition", disposition);
			if (disposition.startsWith('filename=')) disposition = 'attachment; ' + disposition;
			try {
				disposition = ContentDisposition.parse(disposition);
			} catch (ex) {
				debug("Unknown Content-Disposition format", ex);
			}
			if (disposition && disposition.parameters.filename) {
				urlObj = new URL(disposition.parameters.filename, urlObj);
			}
		}

		debug("(mime, type, length) is (%s, %s, %d)", obj.mime, obj.type, obj.size);
		let charset = mimeObj.parameters && mimeObj.parameters.charset;
		if (charset) {
			charset = charset.toLowerCase();
			if (charset != "utf-8") {
				res = res.pipe(iconv.decodeStream(charset));
			} else {
				res.setEncoding(charset);
			}
		} else if (mimeObj.type == "text" || mimeObj.subtype == "svg" || mimeObj.suffix == "xml") {
			res.setEncoding("utf-8");
		}
		const fun = inspectors[obj.type];
		if (urlObj.protocol != "file:") pipeLimit(req, res, fun[1], fun[2]);
		fun[0](obj, res, (err, tags) => {
			if (err) {
				// eslint-disable-next-line no-console
				console.error(err);
			}
			req.abort();
			// request oembed when
			// - not blacklisted (noembed)
			// - has already or has found a oembed url
			// - does not have a thumbnail or does not have an html embed code,
			const fetchEmbed = !obj.noembed && obj.oembed && (!obj.thumbnail || !obj.html);
			delete obj.noembed;
			let canon = obj.canonical;
			if (canon && urlObj.protocol != "file:" && canon != obj.source && obj.nocanonical !== true) {
				canon = new URL(canon);
				canon.redirects = (urlObj.redirects || 0) + 1;
			}
			delete obj.canonical;
			delete obj.nocanonical;
			if (fetchEmbed) {
				obj.type = "embed";
				// prevent loops
				obj.noembed = true;
				debug("fetch embed", obj.oembed);
				const urlObjEmbed = new URL(obj.oembed);
				urlObjEmbed.headers = Object.assign({}, urlObj.headers);
				if (urlObj.protocol) urlObjEmbed.protocol = urlObj.protocol;
				exports.request(urlObjEmbed, obj, (err, cobj, ctags) => {
					if (err) return cb(null, obj, tags);
					else return cb(null, cobj, ctags);
				});
			} else if (canon && canon.redirects < 5 && canon.pathname != urlObj.pathname && canon.pathname + '/' != urlObj.pathname && canon.pathname != urlObj.pathname + '/') {
				debug("fetch canonical url", canon.href);
				canon.headers = Object.assign({}, urlObj.headers);
				exports.request(canon, obj, (err, cobj, ctags) => {
					if (err) {
						return cb(null, obj, tags);
					} else {
						cobj.location = canon;
						return cb(null, cobj, ctags);
					}
				});
			} else {
				cb(null, obj, tags);
			}
		});
	});
};

function doRequest(urlObj, cb) {
	let req;
	if (urlObj.protocol == "file:") {
		fs.stat(urlObj.pathname, (err, stat) => {
			if (err) return cb(err);
			try {
				req = fs.createReadStream(urlObj.pathname).on('error', cb);
			} catch(err) {
				cb(err);
				return;
			}
			if (!req.abort) req.abort = req.destroy;
			req.headers = {
				'content-length': stat.size.toString()
			};
			req.local = true;
			cb(null, req, req);
		});
	} else {
		setOrigin(urlObj);
		const opts = {
			headers: urlObj.headers,
			agent: proxy
		};
		const secure = /^https:?$/.test(urlObj.protocol);
		if (secure) opts.rejectUnauthorized = false;

		try {
			req = (secure ? https : http).request(urlObj, opts, (res) => {
				cb(null, req, res);
			}).on('error', (err) => {
				if (err.code == "ECONNRESET" && opts.headers['User-Agent'].includes("Googlebot")) {
					// suspicion of User-Agent sniffing
					debug("ECONNRESET, trying bot-less ua");
					urlObj.headers["User-Agent"] = "Mozilla/5.0 (compatible)";
					doRequest(opts, cb);
				} else {
					cb(err);
				}
			});
			req.end();
		} catch(err) {
			cb(err);
			return;
		}
	}
}

function setOrigin(urlObj) {
	const origin = new URL(urlObj);
	origin.pathname = "";
	origin.search = "";
	urlObj.headers.Origin = origin.href;
}

function mime2type(obj) {
	let type = 'file';
	if (obj.subtype == "html") {
		type = 'link';
	} else if (obj.subtype == 'svg') {
		type = 'svg';
	} else if (['image', 'audio', 'video'].indexOf(obj.type) >= 0) {
		type = obj.type;
	} else if (['x-xz', 'x-gtar', 'x-gtar-compressed', 'x-tar', 'gzip', 'zip'].indexOf(obj.subtype) >= 0) {
		type = 'archive';
	} else if (obj.subtype == "json") {
		type = 'embed';
	}
	return type;
}

function pipeLimit(req, res, length, percent) {
	if (!length) return req.abort();
	if (percent) {
		const contentLength = parseInt(res.headers['content-length']);
		if (!Number.isNaN(contentLength)) {
			length = Math.max(length, contentLength * percent);
		}
	}
	let curLength = 0;
	res.on('data', (buf) => {
		if (res.nolimit) return;
		curLength += buf.length;
		if (curLength >= length) {
			debug("got %d bytes, aborting", curLength);
			req.abort();
		}
	});
}

function replyCookies(setCookies, prev) {
	if (!setCookies) return prev;
	let cookies;
	if (Array.isArray(setCookies)) cookies = setCookies.map(Cookie.parse);
	else cookies = [Cookie.parse(setCookies)];
	cookies = cookies.map((cookie) => {
		return cookie.cookieString();
	});
	if (prev) prev.split('; ').forEach((str) => {
		if (cookies.indexOf(str) < 0) cookies.unshift(str);
	});
	return cookies.join('; ');
}

function parseType(str) {
	if (!str) return str;
	try {
		const ct = ContentType.parse(str);
		const mt = MediaTyper.parse(ct.type);
		return Object.assign(ct, mt);
	} catch (e) {
		return {};
	}
}
<|endoftext|>


<commit_before>import {FLEX} from './defaults';

function alignProps(position, top, right, bottom, left, trans) {
  return {
    position,
    top,
    right,
    bottom,
    left,
    trans
  };
}

export default function align(alignment, flex=FLEX) {
  var style = {};

  if (flex !== 'flex') {
    if (alignment === 'reset') {
      style.position = 'static';

      style['& > *'] = alignProps(
        'static',
        'auto',
        'auto',
        'auto',
        'translate(0, 0)'
      );
    } else {
      style.position = 'relative';

      if (alignment === 'horizontal') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          'auto',
          'auto',
          '50%',
          'translate(-50%, 0)'
        );
      } else if (alignment === 'vertical') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          'auto',
          'auto',
          'auto',
          'translate(0, -50%)'
        );
      } else if (alignment === 'top-left') {
        style['& > *'] = alignProps(
          'absolute',
          '0',
          'auto',
          'auto',
          '0',
          'translate(0, 0)'
        );
      } else if (alignment === 'top-center' || alignment === 'top') {
        style['& > *'] = alignProps(
          'absolute',
          '0',
          'auto',
          'auto',
          '50%',
          'translate(-50%, 0)'
        );
      } else if (alignment === 'top-right') {
        style['& > *'] = alignProps(
          'absolute',
          '0',
          '0',
          'auto',
          'auto',
          'translate(0, 0)'
        );
      } else if (alignment === 'middle-left' || alignment === 'left') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          'auto',
          'auto',
          '0',
          'translate(0, -50%)'
        );
      } else if (alignment === 'middle-center' || alignment === 'center') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          'auto',
          'auto',
          '50%',
          'translate(-50%, -50%)'
        );
      } else if (alignment === 'middle-right' || alignment === 'right') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          '0',
          'auto',
          'auto',
          'translate(0, -50%)'
        );
      } else if (alignment === 'bottom-left') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          'auto',
          '0',
          '0',
          'translate(0, 0)'
        );
      } else if (alignment === 'bottom-center' || alignment === 'bottom') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          'auto',
          '0',
          '50%',
          'translate(-50%, 0)'
        );
      } else if (alignment === 'bottom-right') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          '0',
          '0',
          'auto',
          'translate(0, 0)'
        );
      }
    }
  } else {
    if (alignment === 'reset') {
     style.display = 'initial';

     style['& > *'] = {
      justifyContent: 'inherit',
      alignItems: 'inherit'
     };
    } else {
      style.display = 'flex';

      if (alignment === 'horizontal') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'inherit'
        };
      } else if (alignment === 'vertical') {
        style['& > *'] = {
          justifyContent: 'inherit',
          alignItems: 'center'
        };
      } else if (alignment === 'top-left') {
        style['& > *'] = {
          justifyContent: 'flex-start',
          alignItems: 'flex-start'
        };
      } else if (alignment === 'top-center' || alignment === 'top') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'flex-start'
        };
      } else if (alignment === 'top-right') {
        style['& > *'] = {
          justifyContent: 'flex-end',
          alignItems: 'flex-start'
        };
      } else if (alignment === 'middle-left' || alignment === 'left') {
        style['& > *'] = {
          justifyContent: 'flex-start',
          alignItems: 'center'
        };
      } else if (alignment === 'middle-center' || alignment === 'center') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'center'
        };
      } else if (alignment === 'middle-right' || alignment === 'right') {
        style['& > *'] = {
          justifyContent: 'flex-end',
          alignItems: 'center'
        };
      } else if (alignment === 'bottom-left') {
        style['& > *'] = {
          justifyContent: 'flex-start',
          alignItems: 'flex-end'
        };
      } else if (alignment === 'bottom-center' || alignment === 'bottom') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'flex-end'
        };
      } else if (alignment === 'bottom-right') {
        style['& > *'] = {
          justifyContent: 'flex-end',
          alignItems: 'flex-end'
        };
      }
    }
  }

  return style;
}
<commit_msg>Fix bug in align.<commit_after>import {FLEX} from './defaults';

function alignProps(position, top, right, bottom, left, transform) {
  return {
    position,
    top,
    right,
    bottom,
    left,
    transform
  };
}

export default function align(alignment, flex=FLEX) {
  var style = {};

  if (flex !== 'flex') {
    if (alignment === 'reset') {
      style.position = 'static';

      style['& > *'] = alignProps(
        'static',
        'auto',
        'auto',
        'auto',
        'translate(0, 0)'
      );
    } else {
      style.position = 'relative';

      if (alignment === 'horizontal') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          'auto',
          'auto',
          '50%',
          'translate(-50%, 0)'
        );
      } else if (alignment === 'vertical') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          'auto',
          'auto',
          'auto',
          'translate(0, -50%)'
        );
      } else if (alignment === 'top-left') {
        style['& > *'] = alignProps(
          'absolute',
          '0',
          'auto',
          'auto',
          '0',
          'translate(0, 0)'
        );
      } else if (alignment === 'top-center' || alignment === 'top') {
        style['& > *'] = alignProps(
          'absolute',
          '0',
          'auto',
          'auto',
          '50%',
          'translate(-50%, 0)'
        );
      } else if (alignment === 'top-right') {
        style['& > *'] = alignProps(
          'absolute',
          '0',
          '0',
          'auto',
          'auto',
          'translate(0, 0)'
        );
      } else if (alignment === 'middle-left' || alignment === 'left') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          'auto',
          'auto',
          '0',
          'translate(0, -50%)'
        );
      } else if (alignment === 'middle-center' || alignment === 'center') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          'auto',
          'auto',
          '50%',
          'translate(-50%, -50%)'
        );
      } else if (alignment === 'middle-right' || alignment === 'right') {
        style['& > *'] = alignProps(
          'absolute',
          '50%',
          '0',
          'auto',
          'auto',
          'translate(0, -50%)'
        );
      } else if (alignment === 'bottom-left') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          'auto',
          '0',
          '0',
          'translate(0, 0)'
        );
      } else if (alignment === 'bottom-center' || alignment === 'bottom') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          'auto',
          '0',
          '50%',
          'translate(-50%, 0)'
        );
      } else if (alignment === 'bottom-right') {
        style['& > *'] = alignProps(
          'absolute',
          'auto',
          '0',
          '0',
          'auto',
          'translate(0, 0)'
        );
      }
    }
  } else {
    if (alignment === 'reset') {
     style.display = 'initial';

     style['& > *'] = {
      justifyContent: 'inherit',
      alignItems: 'inherit'
     };
    } else {
      style.display = 'flex';

      if (alignment === 'horizontal') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'inherit'
        };
      } else if (alignment === 'vertical') {
        style['& > *'] = {
          justifyContent: 'inherit',
          alignItems: 'center'
        };
      } else if (alignment === 'top-left') {
        style['& > *'] = {
          justifyContent: 'flex-start',
          alignItems: 'flex-start'
        };
      } else if (alignment === 'top-center' || alignment === 'top') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'flex-start'
        };
      } else if (alignment === 'top-right') {
        style['& > *'] = {
          justifyContent: 'flex-end',
          alignItems: 'flex-start'
        };
      } else if (alignment === 'middle-left' || alignment === 'left') {
        style['& > *'] = {
          justifyContent: 'flex-start',
          alignItems: 'center'
        };
      } else if (alignment === 'middle-center' || alignment === 'center') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'center'
        };
      } else if (alignment === 'middle-right' || alignment === 'right') {
        style['& > *'] = {
          justifyContent: 'flex-end',
          alignItems: 'center'
        };
      } else if (alignment === 'bottom-left') {
        style['& > *'] = {
          justifyContent: 'flex-start',
          alignItems: 'flex-end'
        };
      } else if (alignment === 'bottom-center' || alignment === 'bottom') {
        style['& > *'] = {
          justifyContent: 'center',
          alignItems: 'flex-end'
        };
      } else if (alignment === 'bottom-right') {
        style['& > *'] = {
          justifyContent: 'flex-end',
          alignItems: 'flex-end'
        };
      }
    }
  }

  return style;
}
<|endoftext|>


<commit_before>/* by Oratio.io */

//Modules
var vm = require('vm');
var assert = require('assert');

//Global Variables
var _handlers = {};

global.process.handle = function(message, callback){
  _handlers[message] = callback;
}

process.on('message', function(message){
  if(message.type === 'code'){
    vm.runInThisContext(message.code, {timeout: message.timeout});
  }
})
<commit_msg>Update child.js<commit_after>/* Check LICENSE for details. Developed by Oratio.io */

//Node.js Standard Modules
var vm = require('vm');

//Global Variables
var _handlers = {};

global.process.handle = function(message, callback){
  _handlers[message] = callback;
}

process.on('message', function(message){
  if(message.type === 'code'){
    vm.runInThisContext(message.code, {timeout: message.timeout});
  }
})
<|endoftext|>


<commit_before>/* Check LICENSE for details. Developed by Oratio.io */

//Node.js Standard Modules
var vm = require('vm');

//Global Variables
var _handlers = {};

global.process.handle = function(message, callback){
  _handlers[message] = callback;
}

process.on('message', function(message){
  if(message.type === 'code'){
    vm.runInThisContext(message.code, {timeout: message.timeout, displayErrors: true});
    return;
  }

  if(message.type === 'message'){
    function callbackHandler(returnedMessage){
      process.send({type: 'callback', event: message.event, id: message.id, message: returnedMessage});
    }

    return _handlers[message.event](param, callbackHandler);
  }

  throw new Error('This kind of message isn\'t currently accepted.')
})
<commit_msg>API changes.<commit_after>/* Check LICENSE for details. Developed by Oratio.io */

//Node.js Standard Modules
var vm = require('vm');

//Global Variables
var _handlers = {};

global.process.handle = function(message, callback){
  _handlers[message] = callback;
}

process.on('message', function(message){
  if(message.type === 'code'){
    vm.runInThisContext(message.code, {timeout: message.timeout, displayErrors: true});
    return;
  }

  if(message.type === 'contact'){
    function callbackHandler(returnedMessage){
      process.send({type: 'callback', event: message.event, id: message.id, message: returnedMessage});
    }

    return _handlers[message.event](param, callbackHandler);
  }

  throw new Error('This kind of message isn\'t currently accepted.')
})
<|endoftext|>


<commit_before>import { isObject, isDate, isArray, isFunction } from './types.js';
import { get, reconstruct } from './proto.js';

/**
 * Useless callback function.
 * @private
 *
 * @param {*} scope The current object.
 * @param {string} key The current key.
 * @param {*} prop The current value.
 */
function noop(scope, key, prop) { return prop; }

/**
 * Clone an object.
 *
 * @method clone
 * @param {*} obj The instance to clone.
 * @param {Function} [callback] A modifier function for each property.
 * @param {WeakMap} [cache] The cache for circular references.
 * @return {*} The clone of the object.
 */
export default function clone(obj, callback = noop, cache = new WeakMap()) {
    if (isObject(obj) || isArray(obj)) {
        if (cache.has(obj)) {
            return cache.get(obj);
        }
        let res = reconstruct(get(obj));
        cache.set(obj, res);
        const descriptors = Object.getOwnPropertyDescriptors(obj);
        if (isArray(obj)) {
            // do not redefine `length` property.
            delete descriptors['length'];
        }
        for (let key in descriptors) {
            const desc = descriptors[key];
            let newDescriptor = {
                configurable: true,
                enumerable: desc.enumerable,
            };
            if (desc.get || desc.set) {
                newDescriptor['get'] = desc.get;
                newDescriptor['set'] = desc.set;
            } else {
                // `value` and `writable` are allowed in a descriptor only when there isn't a getter/setter.
                let clonedVal = clone(desc.value, callback, cache);
                newDescriptor['value'] = callback(obj, key, clonedVal);
                newDescriptor['writable'] = desc.writable;
            }
            Object.defineProperty(res, key, newDescriptor);
        }
        return res;
    } else if (isDate(obj)) {
        return new Date(obj.getTime());
    } else if (isFunction(obj)) {
        return obj;
    }
    return obj;
}
<commit_msg>refactor [minor]: changed property access<commit_after>import { isObject, isDate, isArray, isFunction } from './types.js';
import { get, reconstruct } from './proto.js';

/**
 * Useless callback function.
 * @private
 *
 * @param {*} scope The current object.
 * @param {string} key The current key.
 * @param {*} prop The current value.
 */
function noop(scope, key, prop) { return prop; }

/**
 * Clone an object.
 *
 * @method clone
 * @param {*} obj The instance to clone.
 * @param {Function} [callback] A modifier function for each property.
 * @param {WeakMap} [cache] The cache for circular references.
 * @return {*} The clone of the object.
 */
export default function clone(obj, callback = noop, cache = new WeakMap()) {
    if (isObject(obj) || isArray(obj)) {
        if (cache.has(obj)) {
            return cache.get(obj);
        }
        let res = reconstruct(get(obj));
        cache.set(obj, res);
        const descriptors = Object.getOwnPropertyDescriptors(obj);
        if (isArray(obj)) {
            // do not redefine `length` property.
            delete descriptors.length;
        }
        for (let key in descriptors) {
            const desc = descriptors[key];
            let newDescriptor = {
                configurable: true,
                enumerable: desc.enumerable,
            };
            if (desc.get || desc.set) {
                newDescriptor.get = desc.get;
                newDescriptor.set = desc.set;
            } else {
                // `value` and `writable` are allowed in a descriptor only when there isn't a getter/setter.
                let clonedVal = clone(desc.value, callback, cache);
                newDescriptor.value = callback(obj, key, clonedVal);
                newDescriptor.writable = desc.writable;
            }
            Object.defineProperty(res, key, newDescriptor);
        }
        return res;
    } else if (isDate(obj)) {
        return new Date(obj.getTime());
    } else if (isFunction(obj)) {
        return obj;
    }
    return obj;
}
<|endoftext|>


<commit_before>/**
 * Cycle - a dependency free javascript plugin
 *
 * Created by <brian at briancruddy dot com> on 4/12/15.
 * License: MIT (https://github.com/packofbadgers/Cycle/blob/master/LICENSE)
 * URL: https://github.com/packofbadgers/Cycle/
 */

/**
 * Cycle
 *
 * @param selector
 * @returns {Cycle}
 * @constructor
 */
function Cycle (selector) {

    function _data(selector, attr) {
        return document.querySelector(selector).dataset[attr];
    }

    this.selector = selector || '.cycle';
    this.target = _data(selector, 'target') || 'li';
    this.interval = _data(selector, 'interval') || '2500';
    this.width = _data(selector, 'width') || '300';
    this.speed = _data(selector, 'speed') || '1000';
    this.images = document.querySelectorAll(selector + ' ' + this.target);

    this.style();
    this.render();

    return this;
}

/**
 * Render Cycle elements
 *
 * @event cycle:change - fires on each iteration/image change
 */
Cycle.prototype.render = function () {
    var _this = this,
        i = 1; // item at index 0 already active on init

    setInterval(function () {
        if (i === _this.images.length) { i = 0; }

        for (var j = 0; j < _this.images.length; j++) {
            _this.images[j].classList.remove('active');
        }

        _this.images[i].classList.add('active');
        i++;

        _this.fire('element:change');
    }, this.interval);
};

/**
 * Set initial Cycle style with params from constructor
 *
 * {width} - width of Cycle parent
 * {speed} - transition speed
 */
Cycle.prototype.style = function () {
    var styleSheet = (function() {
        var style = document.createElement('style');

        // webkit hack
        style.appendChild(document.createTextNode(''));

        document.head.appendChild(style);

        return style.sheet;
    })();

    styleSheet.insertRule(this.selector + ' { max-width: 100%; position: relative; width: ' + this.width + 'px; }', 0);
    styleSheet.insertRule(this.selector + ' > * { position: absolute; top: 0; left: 0; z-index: 0; opacity: 0; transition: opacity 300ms }', 0);
    styleSheet.insertRule(this.selector + ' > .active { z-index: 1; opacity: 1; transition: opacity ' + this.speed + 'ms; }', 0);
    styleSheet.insertRule(this.selector + ' img { width: 100%; }', 0);
};

/**
 * Set Cycle property
 *
 * @param property
 * @param value
 */
Cycle.prototype.set = function (property, value) {
    this[property] = value;
    this.fire('cycle:set');
};

/**
 * Get Cycle property
 *
 * @param property
 * @returns {*}
 */
Cycle.prototype.get = function (property) {
    return this[property];
};

/**
 * Fire Cycle event
 *
 * @param name
 */
Cycle.prototype.fire = function (name) {
    var event = new CustomEvent(name, {
        detail: {
            settings: this
        }
    });

    if (this.selector === event.detail.settings.selector) {
        document.dispatchEvent(event);
    }
};

/**
 * Listen for Cycle event
 *
 * @param event
 * @param callback
 */
Cycle.prototype.on = function (event, callback) {
    document.addEventListener(event, callback, false);
};

<commit_msg>formatting<commit_after>/**
 * Cycle - a dependency free javascript plugin
 *
 * Created by <brian at briancruddy dot com> on 4/12/15.
 * License: MIT (https://github.com/packofbadgers/Cycle/blob/master/LICENSE)
 * URL: https://github.com/packofbadgers/Cycle/
 *
 */

/**
 * Cycle
 *
 * @param selector
 * @returns {Cycle}
 * @constructor
 */
function Cycle (selector) {

    function _data(selector, attr) {
        return document.querySelector(selector).dataset[attr];
    }

    this.selector = selector || '.cycle';
    this.target = _data(selector, 'target') || 'li';
    this.interval = _data(selector, 'interval') || '2500';
    this.width = _data(selector, 'width') || '300';
    this.speed = _data(selector, 'speed') || '1000';
    this.images = document.querySelectorAll(selector + ' ' + this.target);

    this.style();
    this.render();

    return this;
}

/**
 * Render Cycle elements
 *
 * @event cycle:change - fires on each iteration/image change
 */
Cycle.prototype.render = function () {
    var _this = this,
        i = 1; // item at index 0 already active on init

    setInterval(function () {
        if (i === _this.images.length) { i = 0; }

        for (var j = 0; j < _this.images.length; j++) {
            _this.images[j].classList.remove('active');
        }

        _this.images[i].classList.add('active');
        i++;

        _this.fire('element:change');
    }, this.interval);
};

/**
 * Set initial Cycle style with params from constructor
 *
 * {width} - width of Cycle parent
 * {speed} - transition speed
 */
Cycle.prototype.style = function () {
    var styleSheet = (function() {
        var style = document.createElement('style');

        // webkit hack
        style.appendChild(document.createTextNode(''));

        document.head.appendChild(style);

        return style.sheet;
    })();

    styleSheet.insertRule(this.selector + ' { max-width: 100%; position: relative; width: ' + this.width + 'px; }', 0);
    styleSheet.insertRule(this.selector + ' > * { position: absolute; top: 0; left: 0; z-index: 0; opacity: 0; transition: opacity 300ms }', 0);
    styleSheet.insertRule(this.selector + ' > .active { z-index: 1; opacity: 1; transition: opacity ' + this.speed + 'ms; }', 0);
    styleSheet.insertRule(this.selector + ' img { width: 100%; }', 0);
};

/**
 * Set Cycle property
 *
 * @param property
 * @param value
 */
Cycle.prototype.set = function (property, value) {
    this[property] = value;
    this.fire('cycle:set');
};

/**
 * Get Cycle property
 *
 * @param property
 * @returns {*}
 */
Cycle.prototype.get = function (property) {
    return this[property];
};

/**
 * Fire Cycle event
 *
 * @param name
 */
Cycle.prototype.fire = function (name) {
    var event = new CustomEvent(name, {
        detail: {
            settings: this
        }
    });

    if (this.selector === event.detail.settings.selector) {
        document.dispatchEvent(event);
    }
};

/**
 * Listen for Cycle event
 *
 * @param event
 * @param callback
 */
Cycle.prototype.on = function (event, callback) {
    document.addEventListener(event, callback, false);
};
<|endoftext|>


<commit_before>$.select = qwery;<commit_msg>ender changes<commit_after>$._select = qwery.noConflict();<|endoftext|>


<commit_before>'use strict';
var site = require( './site' );

/*
    A simple union with JS-standard Error with our site information.
*/

module.exports = class ParsingError extends Error {

    constructor ( site, message ) {
        super( message );
        this.site = site;
        this.stack = (new Error()).stack;
    }

    getReport () {
        return `${this.message} at position ${this.site.getBegin()}`;
    };

    getSite () {
        return this.site;
    }

};

<commit_msg>Fix: error.js/site.js circular dep.<commit_after>'use strict';

/*
    A simple union with JS-standard Error with our site information.
*/

module.exports = class ParsingError extends Error {

    constructor ( site, message ) {
        super( message );
        this.site = site;
        this.stack = (new Error()).stack;
    }

    getReport () {
        return `${this.message} at position ${this.site.getBegin()}`;
    };

    getSite () {
        return this.site;
    }

};

<|endoftext|>


<commit_before>/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code orignated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {

	// Bind an event to an element
	// Original by Dean Edwards
	add: function(element, type, handler, data) {
		if ( element.nodeType == 3 || element.nodeType == 8 )
			return;

		// For whatever reason, IE has trouble passing the window object
		// around, causing it to be cloned in the process
		if ( jQuery.browser.msie && element.setInterval != undefined )
			element = window;

		// Make sure that the function being executed has a unique ID
		if ( !handler.guid )
			handler.guid = this.guid++;

		// if data is passed, bind to handler
		if( data != undefined ) {
			// Create temporary function pointer to original handler
			var fn = handler;

			// Create unique handler function, wrapped around original handler
			handler = function() {
				// Pass arguments and context to original handler
				return fn.apply(this, arguments);
			};

			// Store data in unique handler
			handler.data = data;

			// Set the guid of unique handler to the same of original handler, so it can be removed
			handler.guid = fn.guid;
		}

		// Namespaced event handlers
		var parts = type.split(".");
		type = parts[0];
		handler.type = parts[1];

		// Init the element's event structure
		var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});

		var handle = jQuery.data(element, "handle") || jQuery.data(element, "handle", function(){
			// returned undefined or false
			var val;

			// Handle the second event of a trigger and when
			// an event is called after a page has unloaded
			if ( typeof jQuery == "undefined" || jQuery.event.triggered )
				return val;

			val = jQuery.event.handle.apply(element, arguments);

			return val;
		});

		// Get the current list of functions bound to this event
		var handlers = events[type];

		// Init the event handler queue
		if (!handlers) {
			handlers = events[type] = {};

			// And bind the global event handler to the element
			if (element.addEventListener)
				element.addEventListener(type, handle, false);
			else
				element.attachEvent("on" + type, handle);
		}

		// Add the function to the element's handler list
		handlers[handler.guid] = handler;

		// Keep track of which events have been used, for global triggering
		this.global[type] = true;
	},

	guid: 1,
	global: {},

	// Detach an event or set of events from an element
	remove: function(element, type, handler) {
		// don't do events on text and comment nodes
		if ( element.nodeType == 3 || element.nodeType == 8 )
			return;

		var events = jQuery.data(element, "events"), ret, index;

		// Namespaced event handlers
		if ( typeof type == "string" ) {
			var parts = type.split(".");
			type = parts[0];
		}

		if ( events ) {
			// type is actually an event object here
			if ( type && type.type ) {
				handler = type.handler;
				type = type.type;
			}

			if ( !type ) {
				for ( type in events )
					this.remove( element, type );

			} else if ( events[type] ) {
				// remove the given handler for the given type
				if ( handler )
					delete events[type][handler.guid];

				// remove all handlers for the given type
				else
					for ( handler in events[type] )
						// Handle the removal of namespaced events
						if ( !parts[1] || events[type][handler].type == parts[1] )
							delete events[type][handler];

				// remove generic event handler if no more handlers exist
				for ( ret in events[type] ) break;
				if ( !ret ) {
					if (element.removeEventListener)
						element.removeEventListener(type, jQuery.data(element, "handle"), false);
					else
						element.detachEvent("on" + type, jQuery.data(element, "handle"));
					ret = null;
					delete events[type];
				}
			}

			// Remove the expando if it's no longer used
			for ( ret in events ) break;
			if ( !ret ) {
				jQuery.removeData( element, "events" );
				jQuery.removeData( element, "handle" );
			}
		}
	},

	trigger: function(type, data, element, donative, extra) {
		// Clone the incoming data, if any
		data = jQuery.makeArray(data || []);

		// Handle a global trigger
		if ( !element ) {
			// Only trigger if we've ever bound an event for it
			if ( this.global[type] )
				jQuery("*").add([window, document]).trigger(type, data);

		// Handle triggering a single element
		} else {
			// don't do events on text and comment nodes
			if ( element.nodeType == 3 || element.nodeType == 8 )
				return;

			var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
				// Check to see if we need to provide a fake event, or not
				event = !data[0] || !data[0].preventDefault;

			// Pass along a fake event
			if ( event )
				data.unshift( this.fix({ type: type, target: element }) );

			// Enforce the right trigger type
			data[0].type = type;

			// Trigger the event
			if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
				val = jQuery.data(element, "handle").apply( element, data );

			// Handle triggering native .onfoo handlers
			if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
				val = false;

			// Extra functions don't get the custom event object
			if ( event )
				data.shift();

			// Handle triggering of extra function
			if ( extra ) {
				// call the extra function and tack the current return value on the end for possible inspection
				var ret = extra.apply( element, data.concat( val ) );
				// if anything is returned, give it precedence and have it overwrite the previous value
				if (ret !== undefined)
					val = ret;
			}

			// Trigger the native events (except for clicks on links)
			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
				this.triggered = true;
				try {
					element[ type ]();
				// prevent IE from throwing an error for some hidden elements
				} catch (e) {}
			}

			this.triggered = false;
		}

		return val;
	},

	handle: function(event) {
		// returned undefined or false
		var val;

		// Empty object is for triggered events with no data
		event = jQuery.event.fix( event || window.event || {} );

		// Namespaced event handlers
		var parts = event.type.split(".");
		event.type = parts[0];

		var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
		args.unshift( event );

		for ( var j in handlers ) {
			var handler = handlers[j];
			// Pass in a reference to the handler function itself
			// So that we can later remove it
			args[0].handler = handler;
			args[0].data = handler.data;

			// Filter the functions by class
			if ( !parts[1] || handler.type == parts[1] ) {
				var ret = handler.apply( this, args );

				if ( val !== false )
					val = ret;

				if ( ret === false ) {
					event.preventDefault();
					event.stopPropagation();
				}
			}
		}

		// Clean up added properties in IE to prevent memory leak
		if (jQuery.browser.msie)
			event.target = event.preventDefault = event.stopPropagation =
				event.handler = event.data = null;

		return val;
	},

	fix: function(event) {
		// store a copy of the original event object
		// and clone to set read-only properties
		var originalEvent = event;
		event = jQuery.extend({}, originalEvent);

		// add preventDefault and stopPropagation since
		// they will not work on the clone
		event.preventDefault = function() {
			// if preventDefault exists run it on the original event
			if (originalEvent.preventDefault)
				originalEvent.preventDefault();
			// otherwise set the returnValue property of the original event to false (IE)
			originalEvent.returnValue = false;
		};
		event.stopPropagation = function() {
			// if stopPropagation exists run it on the original event
			if (originalEvent.stopPropagation)
				originalEvent.stopPropagation();
			// otherwise set the cancelBubble property of the original event to true (IE)
			originalEvent.cancelBubble = true;
		};

		// Fix target property, if necessary
		if ( !event.target )
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either

		// check if target is a textnode (safari)
		if ( event.target.nodeType == 3 )
			event.target = originalEvent.target.parentNode;

		// Add relatedTarget, if necessary
		if ( !event.relatedTarget && event.fromElement )
			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;

		// Calculate pageX/Y if missing and clientX/Y available
		if ( event.pageX == null && event.clientX != null ) {
			var doc = document.documentElement, body = document.body;
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientLeft || 0);
		}

		// Add which for key events
		if ( !event.which && (event.charCode || event.keyCode) )
			event.which = event.charCode || event.keyCode;

		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
		if ( !event.metaKey && event.ctrlKey )
			event.metaKey = event.ctrlKey;

		// Add which for click: 1 == left; 2 == middle; 3 == right
		// Note: button is not normalized, so don't use it
		if ( !event.which && event.button )
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

		return event;
	}
};

jQuery.fn.extend({
	bind: function( type, data, fn ) {
		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
			jQuery.event.add( this, type, fn || data, fn && data );
		});
	},

	one: function( type, data, fn ) {
		return this.each(function(){
			jQuery.event.add( this, type, function(event) {
				jQuery(this).unbind(event);
				return (fn || data).apply( this, arguments);
			}, fn && data);
		});
	},

	unbind: function( type, fn ) {
		return this.each(function(){
			jQuery.event.remove( this, type, fn );
		});
	},

	trigger: function( type, data, fn ) {
		return this.each(function(){
			jQuery.event.trigger( type, data, this, true, fn );
		});
	},

	triggerHandler: function( type, data, fn ) {
		if ( this[0] )
			return jQuery.event.trigger( type, data, this[0], false, fn );
	},

	toggle: function() {
		// Save reference to arguments for access in closure
		var args = arguments;

		return this.click(function(event) {
			// Figure out which function to execute
			this.lastToggle = 0 == this.lastToggle ? 1 : 0;

			// Make sure that clicks stop
			event.preventDefault();

			// and execute the function
			return args[this.lastToggle].apply( this, arguments ) || false;
		});
	},

	hover: function(fnOver, fnOut) {

		// A private function for handling mouse 'hovering'
		function handleHover(event) {
			// Check if mouse(over|out) are still within the same parent element
			var parent = event.relatedTarget;

			// Traverse up the tree
			while ( parent && parent != this ) try { parent = parent.parentNode; } catch(error) { parent = this; };

			// If we actually just moused on to a sub-element, ignore it
			if ( parent == this )
				return true;

			// Execute the right function
			return (event.type == "mouseover" ? fnOver : fnOut).apply(this, [event]);
		}

		// Bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	},

	ready: function(fn) {
		// Attach the listeners
		bindReady();

		// If the DOM is already ready
		if ( jQuery.isReady )
			// Execute the function immediately
			fn.apply( document, [jQuery] );

		// Otherwise, remember the function for later
		else
			// Add the function to the wait list
			jQuery.readyList.push( function() { return fn.apply(this, [jQuery]); } );

		return this;
	}
});

jQuery.extend({
	/*
	 * All the code that makes DOM Ready work nicely.
	 */
	isReady: false,
	readyList: [],

	// Handle when the DOM is ready
	ready: function() {
		// Make sure that the DOM is not already loaded
		if ( !jQuery.isReady ) {
			// Remember that the DOM is ready
			jQuery.isReady = true;

			// If there are functions bound, to execute
			if ( jQuery.readyList ) {
				// Execute all of them
				jQuery.each( jQuery.readyList, function(){
					this.apply( document );
				});

				// Reset the list of functions
				jQuery.readyList = null;
			}
			// Remove event listener to avoid memory leak
			if ( document.removeEventListener )
				document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
		}
	}
});

jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
	"submit,keydown,keypress,keyup,error").split(","), function(i, name){

	// Handle event binding
	jQuery.fn[name] = function(fn){
		return fn ? this.bind(name, fn) : this.trigger(name);
	};
});

var readyBound = false;

function bindReady(){
	if ( readyBound ) return;
	readyBound = true;

	// Mozilla, Opera and webkit nightlies currently support this event
	if ( document.addEventListener )
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );

	// If Safari or IE is used
	// Continually check to see if the document is ready
	if (jQuery.browser.msie || jQuery.browser.safari ) (function(){
		try {
			// If IE is used, use the trick by Diego Perini
			// http://javascript.nwbox.com/IEContentLoaded/
			if ( jQuery.browser.msie || document.readyState != "loaded" && document.readyState != "complete" )
				document.documentElement.doScroll("left");
		} catch( error ) {
			return setTimeout( arguments.callee, 0 );
		}

		// and execute any waiting functions
		jQuery.ready();
	})();

	// A fallback to window.onload, that will always work
	jQuery.event.add( window, "load", jQuery.ready );
}

// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover
// Window isn't included so as not to unbind existing unload events
jQuery(window).bind("unload", function() {
	jQuery("*").add(document).unbind();
});
<commit_msg>Fix for #2032<commit_after>/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code orignated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {

	// Bind an event to an element
	// Original by Dean Edwards
	add: function(element, type, handler, data) {
		if ( element.nodeType == 3 || element.nodeType == 8 )
			return;

		// For whatever reason, IE has trouble passing the window object
		// around, causing it to be cloned in the process
		if ( jQuery.browser.msie && element.setInterval != undefined )
			element = window;

		// Make sure that the function being executed has a unique ID
		if ( !handler.guid )
			handler.guid = this.guid++;

		// if data is passed, bind to handler
		if( data != undefined ) {
			// Create temporary function pointer to original handler
			var fn = handler;

			// Create unique handler function, wrapped around original handler
			handler = function() {
				// Pass arguments and context to original handler
				return fn.apply(this, arguments);
			};

			// Store data in unique handler
			handler.data = data;

			// Set the guid of unique handler to the same of original handler, so it can be removed
			handler.guid = fn.guid;
		}

		// Namespaced event handlers
		var parts = type.split(".");
		type = parts[0];
		handler.type = parts[1];

		// Init the element's event structure
		var events = jQuery.data(element, "events") || jQuery.data(element, "events", {});

		var handle = jQuery.data(element, "handle") || jQuery.data(element, "handle", function(){
			// returned undefined or false
			var val;

			// Handle the second event of a trigger and when
			// an event is called after a page has unloaded
			if ( typeof jQuery == "undefined" || jQuery.event.triggered )
				return val;

			val = jQuery.event.handle.apply(element, arguments);

			return val;
		});

		// Get the current list of functions bound to this event
		var handlers = events[type];

		// Init the event handler queue
		if (!handlers) {
			handlers = events[type] = {};

			// And bind the global event handler to the element
			if (element.addEventListener)
				element.addEventListener(type, handle, false);
			else
				element.attachEvent("on" + type, handle);
		}

		// Add the function to the element's handler list
		handlers[handler.guid] = handler;

		// Keep track of which events have been used, for global triggering
		this.global[type] = true;
	},

	guid: 1,
	global: {},

	// Detach an event or set of events from an element
	remove: function(element, type, handler) {
		// don't do events on text and comment nodes
		if ( element.nodeType == 3 || element.nodeType == 8 )
			return;

		var events = jQuery.data(element, "events"), ret, index;

		// Namespaced event handlers
		if ( typeof type == "string" ) {
			var parts = type.split(".");
			type = parts[0];
		}

		if ( events ) {
			// type is actually an event object here
			if ( type && type.type ) {
				handler = type.handler;
				type = type.type;
			}

			if ( !type ) {
				for ( type in events )
					this.remove( element, type );

			} else if ( events[type] ) {
				// remove the given handler for the given type
				if ( handler )
					delete events[type][handler.guid];

				// remove all handlers for the given type
				else
					for ( handler in events[type] )
						// Handle the removal of namespaced events
						if ( !parts[1] || events[type][handler].type == parts[1] )
							delete events[type][handler];

				// remove generic event handler if no more handlers exist
				for ( ret in events[type] ) break;
				if ( !ret ) {
					if (element.removeEventListener)
						element.removeEventListener(type, jQuery.data(element, "handle"), false);
					else
						element.detachEvent("on" + type, jQuery.data(element, "handle"));
					ret = null;
					delete events[type];
				}
			}

			// Remove the expando if it's no longer used
			for ( ret in events ) break;
			if ( !ret ) {
				jQuery.removeData( element, "events" );
				jQuery.removeData( element, "handle" );
			}
		}
	},

	trigger: function(type, data, element, donative, extra) {
		// Clone the incoming data, if any
		data = jQuery.makeArray(data || []);

		// Handle a global trigger
		if ( !element ) {
			// Only trigger if we've ever bound an event for it
			if ( this.global[type] )
				jQuery("*").add([window, document]).trigger(type, data);

		// Handle triggering a single element
		} else {
			// don't do events on text and comment nodes
			if ( element.nodeType == 3 || element.nodeType == 8 )
				return;

			var val, ret, fn = jQuery.isFunction( element[ type ] || null ),
				// Check to see if we need to provide a fake event, or not
				event = !data[0] || !data[0].preventDefault;

			// Pass along a fake event
			if ( event )
				data.unshift( this.fix({ type: type, target: element }) );

			// Enforce the right trigger type
			data[0].type = type;

			// Trigger the event
			if ( jQuery.isFunction( jQuery.data(element, "handle") ) )
				val = jQuery.data(element, "handle").apply( element, data );

			// Handle triggering native .onfoo handlers
			if ( !fn && element["on"+type] && element["on"+type].apply( element, data ) === false )
				val = false;

			// Extra functions don't get the custom event object
			if ( event )
				data.shift();

			// Handle triggering of extra function
			if ( extra ) {
				// call the extra function and tack the current return value on the end for possible inspection
				var ret = extra.apply( element, data.concat( val ) );
				// if anything is returned, give it precedence and have it overwrite the previous value
				if (ret !== undefined)
					val = ret;
			}

			// Trigger the native events (except for clicks on links)
			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(element, 'a') && type == "click") ) {
				this.triggered = true;
				try {
					element[ type ]();
				// prevent IE from throwing an error for some hidden elements
				} catch (e) {}
			}

			this.triggered = false;
		}

		return val;
	},

	handle: function(event) {
		// returned undefined or false
		var val;

		// Empty object is for triggered events with no data
		event = jQuery.event.fix( event || window.event || {} );

		// Namespaced event handlers
		var parts = event.type.split(".");
		event.type = parts[0];

		var handlers = jQuery.data(this, "events") && jQuery.data(this, "events")[event.type], args = Array.prototype.slice.call( arguments, 1 );
		args.unshift( event );

		for ( var j in handlers ) {
			var handler = handlers[j];
			// Pass in a reference to the handler function itself
			// So that we can later remove it
			args[0].handler = handler;
			args[0].data = handler.data;

			// Filter the functions by class
			if ( !parts[1] || handler.type == parts[1] ) {
				var ret = handler.apply( this, args );

				if ( val !== false )
					val = ret;

				if ( ret === false ) {
					event.preventDefault();
					event.stopPropagation();
				}
			}
		}

		// Clean up added properties in IE to prevent memory leak
		if (jQuery.browser.msie)
			event.target = event.preventDefault = event.stopPropagation =
				event.handler = event.data = null;

		return val;
	},

	fix: function(event) {
		// store a copy of the original event object
		// and clone to set read-only properties
		var originalEvent = event;
		event = jQuery.extend({}, originalEvent);

		// add preventDefault and stopPropagation since
		// they will not work on the clone
		event.preventDefault = function() {
			// if preventDefault exists run it on the original event
			if (originalEvent.preventDefault)
				originalEvent.preventDefault();
			// otherwise set the returnValue property of the original event to false (IE)
			originalEvent.returnValue = false;
		};
		event.stopPropagation = function() {
			// if stopPropagation exists run it on the original event
			if (originalEvent.stopPropagation)
				originalEvent.stopPropagation();
			// otherwise set the cancelBubble property of the original event to true (IE)
			originalEvent.cancelBubble = true;
		};

		// Fix target property, if necessary
		if ( !event.target )
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either

		// check if target is a textnode (safari)
		if ( event.target.nodeType == 3 )
			event.target = originalEvent.target.parentNode;

		// Add relatedTarget, if necessary
		if ( !event.relatedTarget && event.fromElement )
			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;

		// Calculate pageX/Y if missing and clientX/Y available
		if ( event.pageX == null && event.clientX != null ) {
			var doc = document.documentElement, body = document.body;
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
		}

		// Add which for key events
		if ( !event.which && (event.charCode || event.keyCode) )
			event.which = event.charCode || event.keyCode;

		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
		if ( !event.metaKey && event.ctrlKey )
			event.metaKey = event.ctrlKey;

		// Add which for click: 1 == left; 2 == middle; 3 == right
		// Note: button is not normalized, so don't use it
		if ( !event.which && event.button )
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));

		return event;
	}
};

jQuery.fn.extend({
	bind: function( type, data, fn ) {
		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
			jQuery.event.add( this, type, fn || data, fn && data );
		});
	},

	one: function( type, data, fn ) {
		return this.each(function(){
			jQuery.event.add( this, type, function(event) {
				jQuery(this).unbind(event);
				return (fn || data).apply( this, arguments);
			}, fn && data);
		});
	},

	unbind: function( type, fn ) {
		return this.each(function(){
			jQuery.event.remove( this, type, fn );
		});
	},

	trigger: function( type, data, fn ) {
		return this.each(function(){
			jQuery.event.trigger( type, data, this, true, fn );
		});
	},

	triggerHandler: function( type, data, fn ) {
		if ( this[0] )
			return jQuery.event.trigger( type, data, this[0], false, fn );
	},

	toggle: function() {
		// Save reference to arguments for access in closure
		var args = arguments;

		return this.click(function(event) {
			// Figure out which function to execute
			this.lastToggle = 0 == this.lastToggle ? 1 : 0;

			// Make sure that clicks stop
			event.preventDefault();

			// and execute the function
			return args[this.lastToggle].apply( this, arguments ) || false;
		});
	},

	hover: function(fnOver, fnOut) {

		// A private function for handling mouse 'hovering'
		function handleHover(event) {
			// Check if mouse(over|out) are still within the same parent element
			var parent = event.relatedTarget;

			// Traverse up the tree
			while ( parent && parent != this ) try { parent = parent.parentNode; } catch(error) { parent = this; };

			// If we actually just moused on to a sub-element, ignore it
			if ( parent == this )
				return true;

			// Execute the right function
			return (event.type == "mouseover" ? fnOver : fnOut).apply(this, [event]);
		}

		// Bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	},

	ready: function(fn) {
		// Attach the listeners
		bindReady();

		// If the DOM is already ready
		if ( jQuery.isReady )
			// Execute the function immediately
			fn.apply( document, [jQuery] );

		// Otherwise, remember the function for later
		else
			// Add the function to the wait list
			jQuery.readyList.push( function() { return fn.apply(this, [jQuery]); } );

		return this;
	}
});

jQuery.extend({
	/*
	 * All the code that makes DOM Ready work nicely.
	 */
	isReady: false,
	readyList: [],

	// Handle when the DOM is ready
	ready: function() {
		// Make sure that the DOM is not already loaded
		if ( !jQuery.isReady ) {
			// Remember that the DOM is ready
			jQuery.isReady = true;

			// If there are functions bound, to execute
			if ( jQuery.readyList ) {
				// Execute all of them
				jQuery.each( jQuery.readyList, function(){
					this.apply( document );
				});

				// Reset the list of functions
				jQuery.readyList = null;
			}
			// Remove event listener to avoid memory leak
			if ( document.removeEventListener )
				document.removeEventListener( "DOMContentLoaded", jQuery.ready, false );
		}
	}
});

jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
	"submit,keydown,keypress,keyup,error").split(","), function(i, name){

	// Handle event binding
	jQuery.fn[name] = function(fn){
		return fn ? this.bind(name, fn) : this.trigger(name);
	};
});

var readyBound = false;

function bindReady(){
	if ( readyBound ) return;
	readyBound = true;

	// Mozilla, Opera and webkit nightlies currently support this event
	if ( document.addEventListener )
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );

	// If Safari or IE is used
	// Continually check to see if the document is ready
	if (jQuery.browser.msie || jQuery.browser.safari ) (function(){
		try {
			// If IE is used, use the trick by Diego Perini
			// http://javascript.nwbox.com/IEContentLoaded/
			if ( jQuery.browser.msie || document.readyState != "loaded" && document.readyState != "complete" )
				document.documentElement.doScroll("left");
		} catch( error ) {
			return setTimeout( arguments.callee, 0 );
		}

		// and execute any waiting functions
		jQuery.ready();
	})();

	// A fallback to window.onload, that will always work
	jQuery.event.add( window, "load", jQuery.ready );
}

// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover
// Window isn't included so as not to unbind existing unload events
jQuery(window).bind("unload", function() {
	jQuery("*").add(document).unbind();
});
<|endoftext|>


<commit_before>require('es6-promise').polyfill();

var _ = require('lodash');
var Schema = require('./schema');

/**
@namespace
*/
var Field = module.exports = exports = {};

/**
A helper to produce middleware functions.
@param {Function} modifierFunc - The function used to modify the values coming from
 the underlying schema, and return values.
@return {Function} a middleware function for modifying schema functionality.

@example
```javascript
Field.optional = Field.createMiddleware(function(value, options, object, schema){
  if(value === undefined){
    return null;
  }
  return schema.validate(value, options, object);
});
```
*/
Field.createMiddleware = function(modifierFunc){
  var extraArgLength = modifierFunc.length - 4; // amount of extra args that should have been passed
  return function(){
    var initialArgs = Array.prototype.slice.call(arguments, 0);
    var schema = initialArgs.pop();
    var compiled = Schema(schema);

    if(initialArgs.length != extraArgLength){
      var extraParamNames = getParamNames(modifierFunc).slice(0, extraArgLength);
      throw Error('Middleware function missing extra argument(s): ' + extraParamNames);
    }

    var validator = function(value, options, object){

      var args = initialArgs.slice(0);
      args.push(value);
      args.push(options || {});
      args.push(object || {});
      args.push(compiled);

      return Promise.resolve(modifierFunc.apply(null, args));
    };

    return Schema({validate: validator});
  };
};

var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;

function getParamNames(func) {
  var fnStr = func.toString().replace(STRIP_COMMENTS, '');
  var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
  if(result === null){
    result = [];
  }
  return result;
}

/**
Makes a schema optional.  If the value undefined is passed in, no errors are returned,
if anything else is passed in, regular schema validation is run.

@method
@param {Schema|Object} schema - the schema (or raw schema).
@return {Schema} A schema that can be used to validate optional values.

@example
```javascript
var maybeSchema = Schema({
  maybe: Field.optional({
    'error message': validatorFunction
  })
});
```
*/
Field.optional = Field.createMiddleware(function(value, options, object, schema){
  var ignoreValueIfOptional = options.ignoreValueIfOptional;

  if((ignoreValueIfOptional && ignoreValueIfOptional(value)) || value === undefined){
    return null;
  }
  return schema.validate(value, options, object);
});

/**
Give a field an explicit required message.  If the field is undefined the given
message is added as an error.

@method
@param {String} message - The message to add as an error when the value
 of the field is undefined.
@param {Schema|Object} schema - the schema (or raw schema).
@return {Schema} A schema that will handle undefined values with the given
 message.

@example
```javascript
var definitelySchema = Schema({
  definitely: Field.required('The definitely field is required', {
    'error message': validatorFunction
  })
});
```
*/
Field.required = Field.createMiddleware(function(message, value, options, object, schema){
  if(value !== undefined){
    return schema.validate(value, options, object);
  }
  return [message];
});
<commit_msg>added short documentation for ignoreValueIfOptional<commit_after>require('es6-promise').polyfill();

var _ = require('lodash');
var Schema = require('./schema');

/**
@namespace
*/
var Field = module.exports = exports = {};

/**
A helper to produce middleware functions.
@param {Function} modifierFunc - The function used to modify the values coming from
 the underlying schema, and return values.
@return {Function} a middleware function for modifying schema functionality.

@example
```javascript
Field.optional = Field.createMiddleware(function(value, options, object, schema){
  if(value === undefined){
    return null;
  }
  return schema.validate(value, options, object);
});
```
*/
Field.createMiddleware = function(modifierFunc){
  var extraArgLength = modifierFunc.length - 4; // amount of extra args that should have been passed
  return function(){
    var initialArgs = Array.prototype.slice.call(arguments, 0);
    var schema = initialArgs.pop();
    var compiled = Schema(schema);

    if(initialArgs.length != extraArgLength){
      var extraParamNames = getParamNames(modifierFunc).slice(0, extraArgLength);
      throw Error('Middleware function missing extra argument(s): ' + extraParamNames);
    }

    var validator = function(value, options, object){

      var args = initialArgs.slice(0);
      args.push(value);
      args.push(options || {});
      args.push(object || {});
      args.push(compiled);

      return Promise.resolve(modifierFunc.apply(null, args));
    };

    return Schema({validate: validator});
  };
};

var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
var ARGUMENT_NAMES = /([^\s,]+)/g;

function getParamNames(func) {
  var fnStr = func.toString().replace(STRIP_COMMENTS, '');
  var result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
  if(result === null){
    result = [];
  }
  return result;
}

/**
Makes a schema optional.  If the value undefined is passed in, no errors are returned,
if anything else is passed in, regular schema validation is run.

@method
@param {Schema|Object} schema - the schema (or raw schema).
@return {Schema} A schema that can be used to validate optional values.

@example
```javascript
var maybeSchema = Schema({
  maybe: Field.optional({
    'error message': validatorFunction
  })
});

maybeSchema.validate(fieldValues, {
  // do not validate empty string values if field is optional:
  ignoreValueIfOptional: function(value) { return value === ''; }
});
```
*/
Field.optional = Field.createMiddleware(function(value, options, object, schema){
  var ignoreValueIfOptional = options.ignoreValueIfOptional;

  if((ignoreValueIfOptional && ignoreValueIfOptional(value)) || value === undefined){
    return null;
  }
  return schema.validate(value, options, object);
});

/**
Give a field an explicit required message.  If the field is undefined the given
message is added as an error.

@method
@param {String} message - The message to add as an error when the value
 of the field is undefined.
@param {Schema|Object} schema - the schema (or raw schema).
@return {Schema} A schema that will handle undefined values with the given
 message.

@example
```javascript
var definitelySchema = Schema({
  definitely: Field.required('The definitely field is required', {
    'error message': validatorFunction
  })
});
```
*/
Field.required = Field.createMiddleware(function(message, value, options, object, schema){
  if(value !== undefined){
    return schema.validate(value, options, object);
  }
  return [message];
});
<|endoftext|>


<commit_before>import fs, { lstatSync, readdirSync } from 'fs-extra'
import { join } from 'path'
import glob from 'glob'
import Logger from './logger'
import {
  generateComponentTemplate,
  generateStyleFile,
  generateIndexFile,
  generateTestTemplate,
  generateStorybookTemplate,
} from './defaultTemplates'
import defaultOptions from './config.json'
import { getConfig } from './utils'
/**
 * fetch a list of dirs inside a dir
 *
 * @param {any} source path of a dir
 * @returns {array} list of the dirs inside
 */
function getDirectories(source) {
  const isDirectory = sourcePath => lstatSync(sourcePath).isDirectory()
  return readdirSync(source)
    .map(name => join(source, name))
    .filter(isDirectory)
}

/**
 * readFile fs promise wrapped
 * @param {string} path
 * @param {string} fileName
 */
function readFile(path, fileName) {
  return new Promise((resolve, reject) => {
    fs.readFile(`${path}/${fileName}`, 'utf8', (err, content) => {
      if (err) {
        return reject(err)
      }

      return resolve(content)
    })
  })
}

/**
 * generate the file name
 * @param {string} newFileName
 * @param {string} templateFileName
 */
function generateFileName(newFileName, templateFileName) {
  if (templateFileName.includes('COMPONENT_NAME')) {
    return templateFileName.replace(/COMPONENT_NAME/g, newFileName)
  }
  return templateFileName
}

/**
 * Generate component files from custom templates folder
 * Get every single file in the folder
 * @param {string} the name of the component used to create folder and file
 * @param {string} where the component folder is created
 * @param {string} where the custom templates are
 */
async function generateFilesFromTemplate({ name, path, templatesPath }) {
  try {
    const files = glob.sync('**/*', { cwd: templatesPath, nodir: true })
    const config = getConfig(null, templatesPath, templatesPath)
    const outputPath = config.noMkdir ? `${path}` : `${path}/${name}`
    files.map(async (templateFileName) => {
      // Get the template content
      const content = await readFile(templatesPath, templateFileName)
      const replaced = content.replace(/COMPONENT_NAME/g, name)
      // Exist ?
      const newFileName = generateFileName(name, templateFileName)
      // Write the new file with the new content
      fs.outputFile(`${outputPath}/${newFileName}`, replaced)
    })
  } catch (e) {
    Logger.error(e.message)
  }
}

/**
 * Return the default names replace from user filenames
 * @param {object} fileNames object with the user selected filenames
 * @param {string} componentName
 * @return {object} with the correct filenames
 */
function getFileNames(fileNames, componentName) {
  const defaultFileNames = {
    testFileName: `${defaultOptions.testFileName}.${componentName}`,
    componentFileName: componentName,
    styleFileName: componentName,
  }

  const formattedFileNames = Object.keys(fileNames).reduce(
    (acc, curr) => {
      acc[curr] = fileNames[curr].replace(/COMPONENT_NAME/g, componentName)

      return acc
    },
    { ...defaultFileNames }
  )

  return formattedFileNames
}

/**
 * Generate component files
 *
 * @param {object} params object with:
 * @param {string} type: the type of component template
 * @param {object} fileNames: object that contains the filenames to replace
 * @param {string} name: the name of the component used to create folder and file
 * @param {string} path: where the component folder is created
 * @param {string} cssExtension: the extension of the css file
 * @param {string} jsExtension: the extension of the component file
 * @param {array} componentMethods: Array of strings of methods to include in a class component
 * @param {boolean} indexFile: include or not an index file
 * @param {boolean} connected: include or not the connect function of redux
 * @param {boolean} includeStories: include or not the storybook file
 * @param {boolean} includeTests: include or not the test file
 */
function generateFiles(params) {
  const {
    type,
    name,
    fileNames,
    path,
    indexFile,
    cssExtension,
    componentMethods,
    jsExtension,
    connected,
    includeStories,
    includeTests,
  } = params
  const destination = `${path}/${name}`

  const { testFileName, componentFileName, styleFileName } = getFileNames(fileNames, name)

  if (indexFile || connected) {
    fs.outputFile(`${destination}/index.js`, generateIndexFile(componentFileName, connected))
  }

  if (includeStories) {
    fs.outputFile(`${destination}/${name}.stories.${jsExtension}`, generateStorybookTemplate(name))
  }

  if (includeTests) {
    fs.outputFile(`${destination}/${testFileName}.${jsExtension}`, generateTestTemplate(name))
  }

  // Create js file
  fs.outputFile(
    `${destination}/${componentFileName}.${jsExtension}`,
    generateComponentTemplate(type, componentFileName, {
      cssExtension,
      componentMethods,
      styleFileName,
    })
  )

  // Create css file
  if (cssExtension) {
    fs.outputFile(
      `${destination}/${styleFileName}.${cssExtension}`,
      generateStyleFile(styleFileName)
    )
  }
}

const generateFilesFromCustom = generateFilesFromTemplate

export { generateFiles, generateFilesFromTemplate, generateFilesFromCustom, getDirectories }
<commit_msg>Add default empty array when filenames is undefined or null<commit_after>import fs, { lstatSync, readdirSync } from 'fs-extra'
import { join } from 'path'
import glob from 'glob'
import Logger from './logger'
import {
  generateComponentTemplate,
  generateStyleFile,
  generateIndexFile,
  generateTestTemplate,
  generateStorybookTemplate,
} from './defaultTemplates'
import defaultOptions from './config.json'
import { getConfig } from './utils'
/**
 * fetch a list of dirs inside a dir
 *
 * @param {any} source path of a dir
 * @returns {array} list of the dirs inside
 */
function getDirectories(source) {
  const isDirectory = sourcePath => lstatSync(sourcePath).isDirectory()
  return readdirSync(source)
    .map(name => join(source, name))
    .filter(isDirectory)
}

/**
 * readFile fs promise wrapped
 * @param {string} path
 * @param {string} fileName
 */
function readFile(path, fileName) {
  return new Promise((resolve, reject) => {
    fs.readFile(`${path}/${fileName}`, 'utf8', (err, content) => {
      if (err) {
        return reject(err)
      }

      return resolve(content)
    })
  })
}

/**
 * generate the file name
 * @param {string} newFileName
 * @param {string} templateFileName
 */
function generateFileName(newFileName, templateFileName) {
  if (templateFileName.includes('COMPONENT_NAME')) {
    return templateFileName.replace(/COMPONENT_NAME/g, newFileName)
  }
  return templateFileName
}

/**
 * Generate component files from custom templates folder
 * Get every single file in the folder
 * @param {string} the name of the component used to create folder and file
 * @param {string} where the component folder is created
 * @param {string} where the custom templates are
 */
async function generateFilesFromTemplate({ name, path, templatesPath }) {
  try {
    const files = glob.sync('**/*', { cwd: templatesPath, nodir: true })
    const config = getConfig(null, templatesPath, templatesPath)
    const outputPath = config.noMkdir ? `${path}` : `${path}/${name}`
    files.map(async (templateFileName) => {
      // Get the template content
      const content = await readFile(templatesPath, templateFileName)
      const replaced = content.replace(/COMPONENT_NAME/g, name)
      // Exist ?
      const newFileName = generateFileName(name, templateFileName)
      // Write the new file with the new content
      fs.outputFile(`${outputPath}/${newFileName}`, replaced)
    })
  } catch (e) {
    Logger.error(e.message)
  }
}

/**
 * Return the default names replace from user filenames
 * @param {object} fileNames object with the user selected filenames
 * @param {string} componentName
 * @return {object} with the correct filenames
 */
function getFileNames(fileNames = [], componentName) {
  const defaultFileNames = {
    testFileName: `${defaultOptions.testFileName}.${componentName}`,
    componentFileName: componentName,
    styleFileName: componentName,
  }

  const formattedFileNames = Object.keys(fileNames).reduce(
    (acc, curr) => {
      acc[curr] = fileNames[curr].replace(/COMPONENT_NAME/g, componentName)

      return acc
    },
    { ...defaultFileNames }
  )

  return formattedFileNames
}

/**
 * Generate component files
 *
 * @param {object} params object with:
 * @param {string} type: the type of component template
 * @param {object} fileNames: object that contains the filenames to replace
 * @param {string} name: the name of the component used to create folder and file
 * @param {string} path: where the component folder is created
 * @param {string} cssExtension: the extension of the css file
 * @param {string} jsExtension: the extension of the component file
 * @param {array} componentMethods: Array of strings of methods to include in a class component
 * @param {boolean} indexFile: include or not an index file
 * @param {boolean} connected: include or not the connect function of redux
 * @param {boolean} includeStories: include or not the storybook file
 * @param {boolean} includeTests: include or not the test file
 */
function generateFiles(params) {
  const {
    type,
    name,
    fileNames,
    path,
    indexFile,
    cssExtension,
    componentMethods,
    jsExtension,
    connected,
    includeStories,
    includeTests,
  } = params
  const destination = `${path}/${name}`

  const { testFileName, componentFileName, styleFileName } = getFileNames(fileNames, name)

  if (indexFile || connected) {
    fs.outputFile(`${destination}/index.js`, generateIndexFile(componentFileName, connected))
  }

  if (includeStories) {
    fs.outputFile(`${destination}/${name}.stories.${jsExtension}`, generateStorybookTemplate(name))
  }

  if (includeTests) {
    fs.outputFile(`${destination}/${testFileName}.${jsExtension}`, generateTestTemplate(name))
  }

  // Create js file
  fs.outputFile(
    `${destination}/${componentFileName}.${jsExtension}`,
    generateComponentTemplate(type, componentFileName, {
      cssExtension,
      componentMethods,
      styleFileName,
    })
  )

  // Create css file
  if (cssExtension) {
    fs.outputFile(
      `${destination}/${styleFileName}.${cssExtension}`,
      generateStyleFile(styleFileName)
    )
  }
}

const generateFilesFromCustom = generateFilesFromTemplate

export { generateFiles, generateFilesFromTemplate, generateFilesFromCustom, getDirectories }
<|endoftext|>


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

/**
 * This module produces pointerflick events from pointerup and pointerdown
 * Events fired:
 *  - flick: a pointer is placed down, moves rapidly, and is then
 *  removed.
 *    - Additional Properties:
 *      - xVelocity: signed velocity of the flick in the x direction
 *      - yVelocity: signed velocity of the flick in the y direction
 *      - velocity: unsigned total velocity of the flick
 *      - angle: angle of the flick in degress, where 0 is along the positive
 *        x axis
 *      - majorAxis: Axis with the greatest absolute velocity. Denoted with
 *        'x' or 'y'
 */

(function(scope) {
  var dispatcher = scope.dispatcher;
  var flick = {
    // TODO(dfreedman): value should be low enough for low speed flicks, but
    // high enough to remove accidental flicks
    MIN_VELOCITY: 0.5 /* px/ms */,
    MAX_QUEUE: 4,
    moveQueue: [],
    target: null,
    pointerId: null,
    events: [
      'pointerdown',
      'pointermove',
      'pointerup',
      'pointercancel'
    ],
    pointerdown: function(inEvent) {
      if (inEvent.isPrimary && !this.pointerId) {
        this.pointerId = inEvent.pointerId;
        this.target = inEvent.target;
        this.addMove(inEvent);
      }
    },
    pointermove: function(inEvent) {
      if (inEvent.pointerId === this.pointerId) {
        this.addMove(inEvent);
      }
    },
    pointerup: function(inEvent) {
      if (inEvent.pointerId === this.pointerId) {
        this.fireFlick(inEvent);
      }
      this.cleanup();
    },
    pointercancel: function(inEvent) {
      this.cleanup();
    },
    cleanup: function() {
      this.moveQueue = [];
      this.target = null;
      this.pointerId = null;
    },
    addMove: function(inEvent) {
      if (this.moveQueue.length >= this.MAX_QUEUE) {
        this.moveQueue.unshift();
      }
      this.moveQueue.push(inEvent);
    },
    fireFlick: function(inEvent) {
      var e = inEvent;
      var l = this.moveQueue.length;
      var dt, dx, dy, tx, ty, tv, x = 0, y = 0, v = 0;
      // flick based off the fastest segment of movement
      for (var i = 0, m; i < l && (m = this.moveQueue[i]); i++) {
        dt = e.timeStamp - m.timeStamp;
        dx = e.clientX - m.clientX, dy = e.clientY - m.clientY;
        tx = dx / dt, ty = dy / dt, tv = Math.sqrt(tx * tx + ty * ty);
        if (tv > v) {
          x = tx, y = ty, v = tv;
        }
      }
      var ma = Math.abs(x) > Math.abs(y) ? 'x' : 'y';
      var a = this.calcAngle(x, y);
      if (Math.abs(v) >= this.MIN_VELOCITY) {
        var ev = dispatcher.makeEvent('flick', {
          xVelocity: x,
          yVelocity: y,
          velocity: v,
          angle: a,
          majorAxis: ma
        });
        dispatcher.asyncDispatchEvent(ev, this.target);
        // prevent a tap if a flick is detected
        inEvent.preventTap();
      }
    },
    calcAngle: function(inX, inY) {
      return (Math.atan2(inY, inX) * 180 / Math.PI);
    }
  };
  dispatcher.registerRecognizer(flick);
})(window.__PointerGestureShim__);
<commit_msg>fix copyright year to 2013<commit_after>/*
 * Copyright 2013 The Toolkitchen Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */

/**
 * This module produces pointerflick events from pointerup and pointerdown
 * Events fired:
 *  - flick: a pointer is placed down, moves rapidly, and is then
 *  removed.
 *    - Additional Properties:
 *      - xVelocity: signed velocity of the flick in the x direction
 *      - yVelocity: signed velocity of the flick in the y direction
 *      - velocity: unsigned total velocity of the flick
 *      - angle: angle of the flick in degress, where 0 is along the positive
 *        x axis
 *      - majorAxis: Axis with the greatest absolute velocity. Denoted with
 *        'x' or 'y'
 */

(function(scope) {
  var dispatcher = scope.dispatcher;
  var flick = {
    // TODO(dfreedman): value should be low enough for low speed flicks, but
    // high enough to remove accidental flicks
    MIN_VELOCITY: 0.5 /* px/ms */,
    MAX_QUEUE: 4,
    moveQueue: [],
    target: null,
    pointerId: null,
    events: [
      'pointerdown',
      'pointermove',
      'pointerup',
      'pointercancel'
    ],
    pointerdown: function(inEvent) {
      if (inEvent.isPrimary && !this.pointerId) {
        this.pointerId = inEvent.pointerId;
        this.target = inEvent.target;
        this.addMove(inEvent);
      }
    },
    pointermove: function(inEvent) {
      if (inEvent.pointerId === this.pointerId) {
        this.addMove(inEvent);
      }
    },
    pointerup: function(inEvent) {
      if (inEvent.pointerId === this.pointerId) {
        this.fireFlick(inEvent);
      }
      this.cleanup();
    },
    pointercancel: function(inEvent) {
      this.cleanup();
    },
    cleanup: function() {
      this.moveQueue = [];
      this.target = null;
      this.pointerId = null;
    },
    addMove: function(inEvent) {
      if (this.moveQueue.length >= this.MAX_QUEUE) {
        this.moveQueue.unshift();
      }
      this.moveQueue.push(inEvent);
    },
    fireFlick: function(inEvent) {
      var e = inEvent;
      var l = this.moveQueue.length;
      var dt, dx, dy, tx, ty, tv, x = 0, y = 0, v = 0;
      // flick based off the fastest segment of movement
      for (var i = 0, m; i < l && (m = this.moveQueue[i]); i++) {
        dt = e.timeStamp - m.timeStamp;
        dx = e.clientX - m.clientX, dy = e.clientY - m.clientY;
        tx = dx / dt, ty = dy / dt, tv = Math.sqrt(tx * tx + ty * ty);
        if (tv > v) {
          x = tx, y = ty, v = tv;
        }
      }
      var ma = Math.abs(x) > Math.abs(y) ? 'x' : 'y';
      var a = this.calcAngle(x, y);
      if (Math.abs(v) >= this.MIN_VELOCITY) {
        var ev = dispatcher.makeEvent('flick', {
          xVelocity: x,
          yVelocity: y,
          velocity: v,
          angle: a,
          majorAxis: ma
        });
        dispatcher.asyncDispatchEvent(ev, this.target);
        // prevent a tap if a flick is detected
        inEvent.preventTap();
      }
    },
    calcAngle: function(inX, inY) {
      return (Math.atan2(inY, inX) * 180 / Math.PI);
    }
  };
  dispatcher.registerRecognizer(flick);
})(window.__PointerGestureShim__);
<|endoftext|>