<commit_before>'use strict';

var Benchmark = require('benchmark');

var jcampBench = require('./jcamp');

var suite = new Benchmark.Suite();

suite
    .add('NMR 1H', jcampBench('indometacin/1h.dx'))
    .add('NMR 1H XY', jcampBench('indometacin/1h.dx', {xy:true}))
    .add('NMR 2D HMBC', jcampBench('indometacin/hmbc.dx',{fastParse:false}))
    .add('NMR 2D HMBC XY', jcampBench('indometacin/hmbc.dx', {xy:true}))
    .on('cycle', function (event) {
        console.log(String(event.target));
    })
    .run();
<commit_msg>fix benchmark<commit_after>'use strict';

var Benchmark = require('benchmark');

var jcampBench = require('./jcamp');

var suite = new Benchmark.Suite();

suite
    .add('NMR 1H', jcampBench('indometacin/1h.dx'))
    .add('NMR 1H XY', jcampBench('indometacin/1h.dx', {xy:true}))
    .add('NMR 2D HMBC', jcampBench('indometacin/hmbc.dx'))
    .add('NMR 2D HMBC XY', jcampBench('indometacin/hmbc.dx', {xy:true}))
    .on('cycle', function (event) {
        console.log(String(event.target));
    })
    .run();
<|endoftext|>


<commit_before>function Words(sentence){
    "use strict";
    var idx;
    sentence = sentence.toLowerCase();
    var wordMatches = sentence.match(/\w+/g);
    var result = {};
    for(idx = 0 ; idx < wordMatches.length ; idx++) {
        result[wordMatches[idx]] = (result[wordMatches[idx]] || 0) + 1;
    }
    return { count: result };
};

module.exports = Words;<commit_msg>Move declaration of idx<commit_after>function Words(sentence){
    "use strict";
    sentence = sentence.toLowerCase();
    var wordMatches = sentence.match(/\w+/g);
    var result = {};
    for(var idx = 0 ; idx < wordMatches.length ; idx++) {
        result[wordMatches[idx]] = (result[wordMatches[idx]] || 0) + 1;
    }
    return { count: result };
};

module.exports = Words;<|endoftext|>


<commit_before>'use strict';

var traverse = require('./')

  , hasOwnProperty = Object.prototype.hasOwnProperty

  , $common = traverse.$common
  , collectNest = traverse.collectNest
  , wsSet = traverse.wsSet
  , move = traverse.move;

module.exports = function (name) {
	var l, multi;
	name = String(name);
	l = name.length;
	multi = l > 1;
	return function (code) {
		code = String(code);
		return traverse(code, function (char, i, previous) {
			var j = 0;
			if (char !== name[j]) return $common;
			if (previous === '.') return $common;
			if (multi) {
				if (code[i] !== name[++j]) return $common;
				++i;
				while (++j !== l) {
					if (code[i] !== name[j]) return $common;
					++i;
				}
			}
			while (hasOwnProperty.call(wsSet, code[i])) ++i;
			if (code[i] !== '(') return $common;
			move(i + 1);
			return collectNest();
		});
	};
};
<commit_msg>Simplify algorithm<commit_after>'use strict';

var traverse = require('./')

  , hasOwnProperty = Object.prototype.hasOwnProperty

  , $common = traverse.$common
  , collectNest = traverse.collectNest
  , wsSet = traverse.wsSet
  , move = traverse.move;

module.exports = function (name) {
	var l;
	name = String(name);
	l = name.length;
	return function (code) {
		code = String(code);
		return traverse(code, function (char, i, previous) {
			var j = 0;
			if (char !== name[j]) return $common;
			if (previous === '.') return $common;
			while (++j !== l) {
				if (code[i] !== name[j]) return $common;
				++i;
			}
			while (hasOwnProperty.call(wsSet, code[i])) ++i;
			if (code[i] !== '(') return $common;
			move(i + 1);
			return collectNest();
		});
	};
};
<|endoftext|>


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

const chai = require("chai");
const assert = chai.assert;
const proxyquire = require("proxyquire");
const _ = require("underscore");
const Q = require("q");

describe("/lib/attribute-manager/user-attrubute-manager", function () {
	//setTimeout(15000);
	console.log("Loading user-attribute-manager-test.js");

	var UserAttributeManager;

	before(function () {
		UserAttributeManager = proxyquire("../lib/attribute-manager/user-attribute-manager", {
			"request": requestMock
		});
	});

	describe("#UserAttributeManager.init", function () {
		it("Should not be able to init without options and VCAP_SERVICS", function () {
			UserAttributeManager.init();
			// TODO: add validation that errors are printed to console
		});

		it("Should be able to init with options", function () {
			UserAttributeManager.init({
				serverUrl: "dummyurl"
			});
		});

		it("Should be able to init with VCAP_SERVICES (AdvancedMobileAccess)", function () {
			process.env.VCAP_SERVICES = JSON.stringify({
				AdvancedMobileAccess: [
					{
						credentials: {
							serverUrl: "http://abcd"
						}
					}
				]
			});
			UserAttributeManager.init();
		});

		it("Should be able to init with VCAP_SERVICES (appid)", function () {
			process.env.VCAP_SERVICES = JSON.stringify({
				AppID: [
					{
						credentials: {
							serverUrl: "http://abcd"
						}
					}
				]
			});
			UserAttributeManager.init();
		});
	});
	describe("#UserAttributeManager.setAttribute", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.setAttribute();
			var p2 = UserAttributeManager.setAttribute("accessToken");
			var p3 = UserAttributeManager.setAttribute("accessToken", "name");

			Q.allSettled([p1, p2, p3]).spread(function (r1, r2, r3) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.setAttribute("return_error", "name", "value");
			var p2 = UserAttributeManager.setAttribute("return_code_401", "name", "value");
			var p3 = UserAttributeManager.setAttribute("return_code_403", "name", "value");
			var p4 = UserAttributeManager.setAttribute("return_code_404", "name", "value");
			var p5 = UserAttributeManager.setAttribute("return_code_500", "name", "value");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {

			UserAttributeManager.setAttribute("access_token", "name", "value").then(function (result) {
				assert.equal(result.url, "http://abcd/name");
				assert.equal(result.method, "PUT");
				assert.equal(result.body, "value");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			}).catch(done);
		});
	});

	describe("#UserAttributeManager.getAttribute", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.getAttribute();
			var p2 = UserAttributeManager.getAttribute("accessToken");

			Q.allSettled([p1, p2]).spread(function (r1, r2) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.getAttribute("return_error", "name");
			var p2 = UserAttributeManager.getAttribute("return_code_401", "name");
			var p3 = UserAttributeManager.getAttribute("return_code_403", "name");
			var p4 = UserAttributeManager.getAttribute("return_code_404", "name");
			var p5 = UserAttributeManager.getAttribute("return_code_500", "name");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.getAttribute("access_token", "name").then(function (result) {
				assert.equal(result.url, "http://abcd/name");
				assert.equal(result.method, "GET");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			}).catch(done);

		});
	});

	describe("#UserAttributeManager.deleteAttribute", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.deleteAttribute();
			var p2 = UserAttributeManager.deleteAttribute("accessToken");

			Q.allSettled([p1, p2]).spread(function (r1, r2) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.deleteAttribute("return_error", "name", "value");
			var p2 = UserAttributeManager.deleteAttribute("return_code_401", "name", "value");
			var p3 = UserAttributeManager.deleteAttribute("return_code_403", "name", "value");
			var p4 = UserAttributeManager.deleteAttribute("return_code_404", "name", "value");
			var p5 = UserAttributeManager.deleteAttribute("return_code_500", "name", "value");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.deleteAttribute("access_token", "name").then(function (result) {
				assert.equal(result.url, "http://abcd/name");
				assert.equal(result.method, "DELETE");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			});
		});
	});

	describe("#UserAttributeManager.getAllAttributes", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.getAllAttributes();

			Q.allSettled([p1]).spread(function (r1) {
				assert.equal(r1.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.getAllAttributes("return_error");
			var p2 = UserAttributeManager.getAllAttributes("return_code_401");
			var p3 = UserAttributeManager.getAllAttributes("return_code_403");
			var p4 = UserAttributeManager.getAllAttributes("return_code_404");
			var p5 = UserAttributeManager.getAllAttributes("return_code_500");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.getAllAttributes("access_token").then(function (result) {
				assert.equal(result.url, "http://abcd");
				assert.equal(result.method, "GET");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			});
		});
	});

});

function requestMock(options, callback) {
	var authHeader = options.headers["Authorization"];
	console.log(authHeader);
	if (authHeader.indexOf("return_error") > 0) {
		return callback(new Error("EXPECTED FAILURE"));
	} else if (authHeader.indexOf("return_code") > 0) {
		var statusCode = parseInt(authHeader.split("_")[2]);
		return callback(null, {
			statusCode: parseInt(statusCode)
		});
	} else {
		return callback(null, {
			statusCode: 200
		}, JSON.stringify(options));
	}
}
<commit_msg>remove comments and empty lines<commit_after>/*
 Copyright 2017 IBM Corp.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

const chai = require("chai");
const assert = chai.assert;
const proxyquire = require("proxyquire");
const _ = require("underscore");
const Q = require("q");

describe("/lib/attribute-manager/user-attrubute-manager", function () {
	console.log("Loading user-attribute-manager-test.js");

	var UserAttributeManager;

	before(function () {
		UserAttributeManager = proxyquire("../lib/attribute-manager/user-attribute-manager", {
			"request": requestMock
		});
	});

	describe("#UserAttributeManager.init", function () {
		it("Should not be able to init without options and VCAP_SERVICS", function () {
			UserAttributeManager.init();
			// TODO: add validation that errors are printed to console
		});

		it("Should be able to init with options", function () {
			UserAttributeManager.init({
				serverUrl: "dummyurl"
			});
		});

		it("Should be able to init with VCAP_SERVICES (AdvancedMobileAccess)", function () {
			process.env.VCAP_SERVICES = JSON.stringify({
				AdvancedMobileAccess: [
					{
						credentials: {
							serverUrl: "http://abcd"
						}
					}
				]
			});
			UserAttributeManager.init();
		});

		it("Should be able to init with VCAP_SERVICES (appid)", function () {
			process.env.VCAP_SERVICES = JSON.stringify({
				AppID: [
					{
						credentials: {
							serverUrl: "http://abcd"
						}
					}
				]
			});
			UserAttributeManager.init();
		});
	});
	describe("#UserAttributeManager.setAttribute", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.setAttribute();
			var p2 = UserAttributeManager.setAttribute("accessToken");
			var p3 = UserAttributeManager.setAttribute("accessToken", "name");

			Q.allSettled([p1, p2, p3]).spread(function (r1, r2, r3) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.setAttribute("return_error", "name", "value");
			var p2 = UserAttributeManager.setAttribute("return_code_401", "name", "value");
			var p3 = UserAttributeManager.setAttribute("return_code_403", "name", "value");
			var p4 = UserAttributeManager.setAttribute("return_code_404", "name", "value");
			var p5 = UserAttributeManager.setAttribute("return_code_500", "name", "value");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.setAttribute("access_token", "name", "value").then(function (result) {
				assert.equal(result.url, "http://abcd/name");
				assert.equal(result.method, "PUT");
				assert.equal(result.body, "value");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			}).catch(done);
		});
	});

	describe("#UserAttributeManager.getAttribute", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.getAttribute();
			var p2 = UserAttributeManager.getAttribute("accessToken");

			Q.allSettled([p1, p2]).spread(function (r1, r2) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.getAttribute("return_error", "name");
			var p2 = UserAttributeManager.getAttribute("return_code_401", "name");
			var p3 = UserAttributeManager.getAttribute("return_code_403", "name");
			var p4 = UserAttributeManager.getAttribute("return_code_404", "name");
			var p5 = UserAttributeManager.getAttribute("return_code_500", "name");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.getAttribute("access_token", "name").then(function (result) {
				assert.equal(result.url, "http://abcd/name");
				assert.equal(result.method, "GET");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			}).catch(done);

		});
	});

	describe("#UserAttributeManager.deleteAttribute", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.deleteAttribute();
			var p2 = UserAttributeManager.deleteAttribute("accessToken");

			Q.allSettled([p1, p2]).spread(function (r1, r2) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.deleteAttribute("return_error", "name", "value");
			var p2 = UserAttributeManager.deleteAttribute("return_code_401", "name", "value");
			var p3 = UserAttributeManager.deleteAttribute("return_code_403", "name", "value");
			var p4 = UserAttributeManager.deleteAttribute("return_code_404", "name", "value");
			var p5 = UserAttributeManager.deleteAttribute("return_code_500", "name", "value");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.deleteAttribute("access_token", "name").then(function (result) {
				assert.equal(result.url, "http://abcd/name");
				assert.equal(result.method, "DELETE");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			});
		});
	});

	describe("#UserAttributeManager.getAllAttributes", function () {
		it("Should validate all parameters are present", function (done) {

			var p1 = UserAttributeManager.getAllAttributes();

			Q.allSettled([p1]).spread(function (r1) {
				assert.equal(r1.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should fail if there's an error", function (done) {
			var p1 = UserAttributeManager.getAllAttributes("return_error");
			var p2 = UserAttributeManager.getAllAttributes("return_code_401");
			var p3 = UserAttributeManager.getAllAttributes("return_code_403");
			var p4 = UserAttributeManager.getAllAttributes("return_code_404");
			var p5 = UserAttributeManager.getAllAttributes("return_code_500");
			Q.allSettled([p1, p2, p3, p4, p5]).spread(function (r1, r2, r3, r4, r5) {
				assert.equal(r1.state, "rejected");
				assert.equal(r2.state, "rejected");
				assert.equal(r3.state, "rejected");
				assert.equal(r4.state, "rejected");
				assert.equal(r5.state, "rejected");
				done();
			}).catch(function (e) {
				done(new Error(e));
			});
		});

		it("Should send proper access token, url and value", function (done) {
			UserAttributeManager.getAllAttributes("access_token").then(function (result) {
				assert.equal(result.url, "http://abcd");
				assert.equal(result.method, "GET");
				assert.equal(result.headers["Authorization"], "Bearer access_token");
				done();
			});
		});
	});

});

function requestMock(options, callback) {
	var authHeader = options.headers["Authorization"];
	console.log(authHeader);
	if (authHeader.indexOf("return_error") > 0) {
		return callback(new Error("EXPECTED FAILURE"));
	} else if (authHeader.indexOf("return_code") > 0) {
		var statusCode = parseInt(authHeader.split("_")[2]);
		return callback(null, {
			statusCode: parseInt(statusCode)
		});
	} else {
		return callback(null, {
			statusCode: 200
		}, JSON.stringify(options));
	}
}
<|endoftext|>


<commit_before>import cookie from 'cookie';
/**
 * A module for middleware that would like to make external calls through `fetch`
 * @module fetchUtils
 */

/**
 * Wrapper around `fetch` to send an array of queries to the server. It ensures
 * that the request will have the required Oauth access token and constructs
 * the `fetch` call arguments based on the request method
 * @param {String} apiUrl the general-purpose endpoint for API calls to the
 *   application server
 * @param {Object} options {
 *     method: "get", "post", "delete", or "patch",
 *   }
 * @return {Promise} resolves with a `{queries, responses}` object
 */
export const fetchQueries = (apiUrl, options) => (queries, meta) => {
	options.method = options.method || 'GET';
	const {
		method,
		headers,
	} = options;

	const isPost = method.toLowerCase() === 'post';
	const isDelete = method.toLowerCase() === 'delete';

	const fetchUrl = new URL(apiUrl);
	fetchUrl.searchParams.append('queries', JSON.stringify(queries));
	if (meta) {
		fetchUrl.searchParams.append('metadata', JSON.stringify(meta));
		if (meta.logout) {
			fetchUrl.searchParams.append('logout', true);
		}
	}
	const fetchConfig = {
		method,
		headers: {
			...(headers || {}),
			'content-type': isPost ? 'application/x-www-form-urlencoded' : 'text/plain',
			'x-csrf-jwt': (isPost || isDelete) ? options.csrf : '',
		},
		credentials: 'same-origin'  // allow response to set-cookies
	};
	if (isPost) {
		// assume client side
		fetchConfig.body = fetchUrl.searchParams.toString();
	}
	return fetch(
		isPost ? apiUrl : fetchUrl.toString(),
		fetchConfig
	)
	.then(queryResponse =>
		queryResponse.json().then(({ responses, error, message }) => {
			if (error) {
				throw new Error(message);  // treat like an API error
			}
			return {
				queries,
				responses: responses || [],
				csrf: queryResponse.headers.get('x-csrf-jwt'),
			};
		}),
		err => {
			console.error(JSON.stringify({
				err: err.stack,
				message: 'App server API fetch error',
				context: fetchConfig,
			}));
			throw err;
		}
	);
};

export const tryJSON = reqUrl => response => {
	const { status, statusText } = response;
	if (status >= 400) {  // status always 200: bugzilla #52128
		return Promise.reject(
			new Error(`Request to ${reqUrl} responded with error code ${status}: ${statusText}`)
		);
	}
	return response.text().then(text => JSON.parse(text));
};

export const stringifyCookies = cookies =>
	Object.keys(cookies)
			.map(name => `${name}=${cookies[name]}`)
			.join('; ');
/**
 * @param {String} rawCookieHeader a 'cookie' header string
 * @param {Object} newCookies an object of name-value cookies to inject
 */
export const mergeCookies = (rawCookieHeader, newCookies) => {
	// request.state has _parsed_ cookies, but we need to send raw cookies
	// _except_ when the incoming request has been back-populated with new 'raw' cookies
	const oldCookies = cookie.parse(rawCookieHeader);
	const mergedCookies = {
		...oldCookies,
		...newCookies,
	};
	return stringifyCookies(mergedCookies);
};

export const BAD_COOKIES = [
	'click-track'
];

export const cleanBadCookies = (cookieHeader) => {
	const cookies = cookie.parse(cookieHeader);
	BAD_COOKIES.forEach(badCookie => delete cookies[badCookie]);

	return stringifyCookies(cookies);
};

<commit_msg>jsdocs<commit_after>import cookie from 'cookie';
/**
 * A module for middleware that would like to make external calls through `fetch`
 * @module fetchUtils
 */

/**
 * Wrapper around `fetch` to send an array of queries to the server. It ensures
 * that the request will have the required Oauth access token and constructs
 * the `fetch` call arguments based on the request method
 * @param {String} apiUrl the general-purpose endpoint for API calls to the
 *   application server
 * @param {Object} options {
 *     method: "get", "post", "delete", or "patch",
 *   }
 * @return {Promise} resolves with a `{queries, responses}` object
 */
export const fetchQueries = (apiUrl, options) => (queries, meta) => {
	options.method = options.method || 'GET';
	const {
		method,
		headers,
	} = options;

	const isPost = method.toLowerCase() === 'post';
	const isDelete = method.toLowerCase() === 'delete';

	const fetchUrl = new URL(apiUrl);
	fetchUrl.searchParams.append('queries', JSON.stringify(queries));
	if (meta) {
		fetchUrl.searchParams.append('metadata', JSON.stringify(meta));
		if (meta.logout) {
			fetchUrl.searchParams.append('logout', true);
		}
	}
	const fetchConfig = {
		method,
		headers: {
			...(headers || {}),
			'content-type': isPost ? 'application/x-www-form-urlencoded' : 'text/plain',
			'x-csrf-jwt': (isPost || isDelete) ? options.csrf : '',
		},
		credentials: 'same-origin'  // allow response to set-cookies
	};
	if (isPost) {
		// assume client side
		fetchConfig.body = fetchUrl.searchParams.toString();
	}
	return fetch(
		isPost ? apiUrl : fetchUrl.toString(),
		fetchConfig
	)
	.then(queryResponse =>
		queryResponse.json().then(({ responses, error, message }) => {
			if (error) {
				throw new Error(message);  // treat like an API error
			}
			return {
				queries,
				responses: responses || [],
				csrf: queryResponse.headers.get('x-csrf-jwt'),
			};
		}),
		err => {
			console.error(JSON.stringify({
				err: err.stack,
				message: 'App server API fetch error',
				context: fetchConfig,
			}));
			throw err;
		}
	);
};

/**
 * Attempt to JSON parse a Response object from a fetch call
 *
 * @param {String} reqUrl the URL that was requested
 * @param {Response} response the fetch Response object
 * @return {Promise} a Promise that resolves with the JSON-parsed text
 */
export const tryJSON = reqUrl => response => {
	const { status, statusText } = response;
	if (status >= 400) {  // status always 200: bugzilla #52128
		return Promise.reject(
			new Error(`Request to ${reqUrl} responded with error code ${status}: ${statusText}`)
		);
	}
	return response.text().then(text => JSON.parse(text));
};

/**
 * Convert an object of cookie name-value pairs into a 'Cookie' header. This
 * is different than the serialization offered by the 'cookie' and
 * 'tough-cookie' packages, which write cookie values in the form of a
 * 'Set-Cookie' header, which contains more info
 *
 * @param {Object} cookies a name-value mapping of cookies, e.g. from
 *   `cookie.parse`
 * @return {String} a 'Cookie' header string
 */
export const stringifyCookies = cookies =>
	Object.keys(cookies)
		.map(name => `${name}=${cookies[name]}`)
		.join('; ');

/**
 * @param {String} rawCookieHeader a 'cookie' header string
 * @param {Object} newCookies an object of name-value cookies to inject
 */
export const mergeCookies = (rawCookieHeader, newCookies) => {
	// request.state has _parsed_ cookies, but we need to send raw cookies
	// _except_ when the incoming request has been back-populated with new 'raw' cookies
	const oldCookies = cookie.parse(rawCookieHeader);
	const mergedCookies = {
		...oldCookies,
		...newCookies,
	};
	return stringifyCookies(mergedCookies);
};

export const BAD_COOKIES = [
	'click-track'
];

/**
 * Remove cookies that are known to have values that are invalid for `fetch`
 * calls
 *
 * @param {String} cookieHeader a cookie header
 * @return {String} a cleaned cookie header string
 */
export const cleanBadCookies = (cookieHeader) => {
	const cookies = cookie.parse(cookieHeader);
	BAD_COOKIES.forEach(badCookie => delete cookies[badCookie]);

	return stringifyCookies(cookies);
};

<|endoftext|>


<commit_before>#!/usr/bin/env node
const child_process = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
const chalk = require('chalk');
const testCases = require('./cases');

const IPERF_PATH = path.join(__dirname, 'iperf.sh');
const SEC_PER_CASE = 5;

function makeConfs(presets) {
  const common = {
    "log_path": "/dev/null",
    "log_level": "error"
  };
  const server = {
    "host": "localhost",
    "port": 1082,
    "key": "JJ9,$!.!sRG==v7$",
    "presets": presets,
    // "transport": {
    //   "name": "tls",
    //   "params": {
    //     "key": "key.pem",
    //     "cert": "cert.pem"
    //   }
    // }
  };
  const clientConf = Object.assign({
    "host": "127.0.0.1",
    "port": 1081,
    "servers": [
      Object.assign({}, server, {
        "enabled": true,
        "presets": [{
          "name": "tunnel",
          "params": {
            "host": "127.0.0.1",
            "port": 1083
          }
        }].concat(server.presets)
      })
    ]
  }, common);
  const serverConf = Object.assign({}, server, common);
  return [clientConf, serverConf];
}

function writeConfs(caseId, presets) {
  const [clientConf, serverConf] = makeConfs(presets);
  const clientJson = path.join(__dirname, `jsons/case-${caseId}-client.json`);
  const serverJson = path.join(__dirname, `jsons/case-${caseId}-server.json`);
  fs.writeFileSync(clientJson, JSON.stringify(clientConf, null, '  '));
  fs.writeFileSync(serverJson, JSON.stringify(serverConf, null, '  '));
  return [clientJson, serverJson];
}

function parseStdout(stdout) {
  const matches = stdout.match(/\[SUM].*sec/g);
  if (matches === null) {
    console.error(stdout);
  }
  return matches.slice(-2).map((line) => {
    const [interval, transfer, bitrate] = line.match(/\d+[.\d\-\s]+\w+[\/\w]+/g);
    return {interval, transfer, bitrate};
  });
}

function convertTransferToKBytes(transfer) {
  const [num, unit] = transfer.split(' ');
  const factor = {
    'GBytes': 1024 * 1024,
    'MBytes': 1024,
    'KBytes': 1
  }[unit];
  return num * factor;
}

function printSystemConf() {
  console.log(chalk.bold.underline('Operating System:'));
  const osParams = [
    ['cpu', os.cpus()[0].model],
    ['cores', os.cpus().length],
    ['memory', os.totalmem()],
    ['type', os.type()],
    ['platform', os.platform()],
    ['arch', os.arch()],
    ['release', os.release()]
  ];
  for (const [key, value] of osParams) {
    console.log('%s %s', key.padEnd(15), value);
  }
  console.log('');
  console.log(chalk.bold.underline('Node.js Versions:'));
  for (const [key, value] of Object.entries(process.versions)) {
    console.log('%s %s', key.padEnd(15), value);
  }
  console.log('');
}

function run(cases) {
  const results = [];
  for (let i = 0; i < cases.length; ++i) {
    const presets = cases[i];
    const [clientJson, serverJson] = writeConfs(i, presets);
    try {
      const stdout = child_process.execFileSync(
        IPERF_PATH, [clientJson, serverJson, SEC_PER_CASE.toString()], {encoding: 'utf-8'}
      );
      const [a, b] = parseStdout(stdout);
      console.log(`------------ ${chalk.green(`Test Case ${i}`)} ----------------`);
      console.log(JSON.stringify(presets));
      console.log('Interval         Transfer     Bitrate');
      console.log(`${a.interval}  ${a.transfer}  ${a.bitrate}  sender`);
      console.log(`${b.interval}  ${b.transfer}  ${b.bitrate}  receiver`);
      console.log('-----------------------------------------');
      console.log('');
      const conv = convertTransferToKBytes;
      results.push({
        id: i,
        transfers: [a.transfer, b.transfer],
        recvTransfer: conv(b.transfer),
        conf: JSON.stringify(presets)
      });
    } catch (err) {
      console.error(err);
    }
  }
  return results;
}

function summary(results) {
  const sorted = [].concat(results).sort((a, b) => b.recvTransfer - a.recvTransfer);
  console.log('(ranking):');
  console.log('');
  for (let i = 0; i < sorted.length; ++i) {
    const {id, transfers, conf} = sorted[i];
    console.log(`${(i + 1).toString().padStart(2)}: Test Case ${id}, Transfer=[${transfers.join(', ')}], ${conf}`);
  }
  console.log('');
}

printSystemConf();

console.log('running tests...');
console.log('');

summary(run(testCases));
<commit_msg>benchmark: remove "log_path"<commit_after>#!/usr/bin/env node
const child_process = require('child_process');
const fs = require('fs');
const path = require('path');
const os = require('os');
const chalk = require('chalk');
const testCases = require('./cases');

const IPERF_PATH = path.join(__dirname, 'iperf.sh');
const SEC_PER_CASE = 5;

function makeConfs(presets) {
  const common = {
    "log_level": "error"
  };
  const server = {
    "host": "localhost",
    "port": 1082,
    "key": "JJ9,$!.!sRG==v7$",
    "presets": presets,
    // "transport": {
    //   "name": "tls",
    //   "params": {
    //     "key": "key.pem",
    //     "cert": "cert.pem"
    //   }
    // }
  };
  const clientConf = Object.assign({
    "host": "127.0.0.1",
    "port": 1081,
    "servers": [
      Object.assign({}, server, {
        "enabled": true,
        "presets": [{
          "name": "tunnel",
          "params": {
            "host": "127.0.0.1",
            "port": 1083
          }
        }].concat(server.presets)
      })
    ]
  }, common);
  const serverConf = Object.assign({}, server, common);
  return [clientConf, serverConf];
}

function writeConfs(caseId, presets) {
  const [clientConf, serverConf] = makeConfs(presets);
  const clientJson = path.join(__dirname, `jsons/case-${caseId}-client.json`);
  const serverJson = path.join(__dirname, `jsons/case-${caseId}-server.json`);
  fs.writeFileSync(clientJson, JSON.stringify(clientConf, null, '  '));
  fs.writeFileSync(serverJson, JSON.stringify(serverConf, null, '  '));
  return [clientJson, serverJson];
}

function parseStdout(stdout) {
  const matches = stdout.match(/\[SUM].*sec/g);
  if (matches === null) {
    console.error(stdout);
  }
  return matches.slice(-2).map((line) => {
    const [interval, transfer, bitrate] = line.match(/\d+[.\d\-\s]+\w+[\/\w]+/g);
    return {interval, transfer, bitrate};
  });
}

function convertTransferToKBytes(transfer) {
  const [num, unit] = transfer.split(' ');
  const factor = {
    'GBytes': 1024 * 1024,
    'MBytes': 1024,
    'KBytes': 1
  }[unit];
  return num * factor;
}

function printSystemConf() {
  console.log(chalk.bold.underline('Operating System:'));
  const osParams = [
    ['cpu', os.cpus()[0].model],
    ['cores', os.cpus().length],
    ['memory', os.totalmem()],
    ['type', os.type()],
    ['platform', os.platform()],
    ['arch', os.arch()],
    ['release', os.release()]
  ];
  for (const [key, value] of osParams) {
    console.log('%s %s', key.padEnd(15), value);
  }
  console.log('');
  console.log(chalk.bold.underline('Node.js Versions:'));
  for (const [key, value] of Object.entries(process.versions)) {
    console.log('%s %s', key.padEnd(15), value);
  }
  console.log('');
}

function run(cases) {
  const results = [];
  for (let i = 0; i < cases.length; ++i) {
    const presets = cases[i];
    const [clientJson, serverJson] = writeConfs(i, presets);
    try {
      const stdout = child_process.execFileSync(
        IPERF_PATH, [clientJson, serverJson, SEC_PER_CASE.toString()], {encoding: 'utf-8'}
      );
      const [a, b] = parseStdout(stdout);
      console.log(`------------ ${chalk.green(`Test Case ${i}`)} ----------------`);
      console.log(JSON.stringify(presets));
      console.log('Interval         Transfer     Bitrate');
      console.log(`${a.interval}  ${a.transfer}  ${a.bitrate}  sender`);
      console.log(`${b.interval}  ${b.transfer}  ${b.bitrate}  receiver`);
      console.log('-----------------------------------------');
      console.log('');
      const conv = convertTransferToKBytes;
      results.push({
        id: i,
        transfers: [a.transfer, b.transfer],
        recvTransfer: conv(b.transfer),
        conf: JSON.stringify(presets)
      });
    } catch (err) {
      console.error(err);
    }
  }
  return results;
}

function summary(results) {
  const sorted = [].concat(results).sort((a, b) => b.recvTransfer - a.recvTransfer);
  console.log('(ranking):');
  console.log('');
  for (let i = 0; i < sorted.length; ++i) {
    const {id, transfers, conf} = sorted[i];
    console.log(`${(i + 1).toString().padStart(2)}: Test Case ${id}, Transfer=[${transfers.join(', ')}], ${conf}`);
  }
  console.log('');
}

printSystemConf();

console.log('running tests...');
console.log('');

summary(run(testCases));
<|endoftext|>


<commit_before>
  var MERCATOR_RANGE = 256;
  var hash = {};

  function CoordMapType(tileSize) {
    this.tileSize = tileSize;
    this.json_tile_url = "/bubbles/";
    this.loading_tiles = 0;
  }

  CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
    var me = this;

    // Create the div tile
    var div = ownerDocument.createElement('div');
    div.setAttribute('class','tile');
    //div.innerHTML= coord.x+"_"+coord.y+"_"+zoom;
    //div.style.border = "1px solid yellow";
    div.style.zIndex = 0;
    div.style.width = this.tileSize.width + 'px';
    div.style.height = this.tileSize.height + 'px';
    div.setAttribute('id',coord.x+'_'+coord.y+'_'+zoom);

    // Remove hash key
    hash[coord.x+'_'+coord.y+'_'+zoom] = [];

    //Select query/json to take data from this tile
    var x,y;

    if (zoom>9) {
      if (zoom==12) {
        x = coord.x/2;
        y = coord.y/2;
      } else {
        x = coord.x;
        y = coord.y;
      }
      z = 11;
    } else if (zoom>6 && zoom<=9) {
      if (zoom>7) {
        var difference = (zoom - 7)*2;
        x = coord.x/difference;
        y = coord.y/difference;
      } else {
        x = coord.x;
        y = coord.y;
      }
      z = 7;
    } else {
      x = coord.x;
      y = coord.y;
      z = 6;
    }

    if (x==undefined || ((x%1==0) && (y%1==0))) {
      // Call service

      // Loading tiles spinner
      this.loading_tiles++;
      showLoader();

      $.ajax({
        method: "GET",
        dataType: 'json',
        url: global_url + me.json_tile_url + bubbles_version +"/" +z+'_'+x+'_'+y+'.json',
        success: function(points) {
          me.loading_tiles--;
          if (me.loading_tiles == 0) {
            hideLoader();
          }

          // Normalize latlng of the tile to transform it to point(x,y)
          var pixelcoord = {x:coord.x*256,y:coord.y*256,z:zoom} ;
          var worldcoord = new google.maps.Point(pixelcoord.x/Math.pow(2,zoom),pixelcoord.y/Math.pow(2,zoom));
          var projection = peninsula.getProjection();
          var ne = projection.fromPointToLatLng(worldcoord);
          var normalizedPoint = peninsula.getProjection().fromLatLngToPoint(ne);
          var scale = Math.pow(2, zoom);
          var tileCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale);

          // Remove previous data of this tile
          delete hash[coord.x+'_'+coord.y+'_'+zoom];
          hash[coord.x+'_'+coord.y+'_'+zoom] = {};

          //Loop data points
          _.each(points,function(point,i){
            me.createBubble(div,point,tileCoordinate,scale,coord,zoom,ownerDocument);
          });

          return div;
        },
        error: function(e) {
          me.loading_tiles--;
          if (me.loading_tiles == 0) {
            hideLoader();
          }
          return div;
        }
      });
    } else {
      div.style.display = "none";
    }

    return div;
  };

  CoordMapType.prototype.releaseTile = function(tile) {
    var id = tile.getAttribute('id');
    delete hash[id];
  };

  CoordMapType.prototype.createBubble = function(div,point,tileCoordinate,scale,coord,zoom,ownerDocument) {
    hash[coord.x+'_'+coord.y+'_'+zoom][point.id] = point;

    var latlng          = new google.maps.LatLng(point.center_latitude,point.center_longitude);
    var normalizedPoint = peninsula.getProjection().fromLatLngToPoint(latlng); // returns x,y normalized to 0~255
    var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale);

    var left = pixelCoordinate.x - tileCoordinate.x;
    var top = pixelCoordinate.y - tileCoordinate.y;

    var radius;
    if (point['data'][year]!=undefined) {

      var region_type = getDeepLevelFromZoomLevel(peninsula.getZoom());
      var max = max_min[region_type][normalization[compare]+'_'+year+'_max'];
      var min = max_min[region_type][normalization[compare]+'_'+year+'_min'];

      var desv = Math.max(Math.ceil(Math.abs(min)),Math.ceil(Math.abs(max)))/5;

      var value = Math.round(Math.abs(point['data'][year][normalization[compare]]));
      var actual_zoom = peninsula.getZoom();

      if ((desv*0)>=value && value<(desv*1)) {
        radius=12;
      } else if ((desv*1)>=value && value<(desv*2)) {
        radius=19 * (actual_zoom==12?1.5:1);
      } else if ((desv*2)>=value && value<(desv*3)) {
        radius=23 * (actual_zoom==12?1.5:1);
      } else if ((desv*3)>=value && value<(desv*4)) {
        radius=28 * (actual_zoom==12?1.5:1);
      } else {
        radius=32 * (actual_zoom==12?1.5:1);
      }
    } else {
      radius = 12;
    }

    var data,className;
    if (point['data'][year]==undefined || point['data'][year][normalization[compare]]==undefined) {
      data = '';
      className = "red";
    } else {
      data = ((point['data'][year][normalization[compare]]>0.5)?('+'+Math.round(point['data'][year][normalization[compare]])):(Math.round(point['data'][year][normalization[compare]])));
      className = (point['data'][year][normalization[compare]]>0)?'yellow':'grey';
    }

    var bubble =  '
'+
                    '
'+point.name+'
'+
                    ''+
                    '
'+data+'
'+
                  '
';
    $(div).append(bubble);

    if (radius < 14) {
      $('div.bubble[id="'+point.id+'"]').find('p.stat').css('display',"none");
    }

    var height_stat = $('div.bubble[id="'+point.id+'"] p.region_name').height();
    $('div.bubble[id="'+point.id+'"] p.region_name').css({top:'-'+(height_stat+2)+'px'});

    return div;
  };

  function refreshBubbles() {
    var flat = _.reduceRight(hash,function(a,b){ return a.concat(b); },[]);
    flat = _.select(flat, function(ele){ return ele!=undefined;});

    _.each(flat,function(occ,key){
      _.each(occ,function(ele,i){

        //change data of the ball
        var data,className;
        if (ele['data'][year]==undefined || ele['data'][year][normalization[compare]]==undefined) {
          data = '';
          className = "red";
        } else {
          data = ((ele['data'][year][normalization[compare]]>0)?('+'+Math.round(ele['data'][year][normalization[compare]])):(Math.round(ele['data'][year][normalization[compare]])));
          className = (ele['data'][year][normalization[compare]]>0)?'yellow':'grey';
        }

        //change color of the ball
        $('div#'+ele.id+' img').attr('src','images/'+className+'_marker.png');

        //change heigth-width of the ball
        var radius;
        if (ele['data'][year]!=undefined) {
          var region_type = getDeepLevelFromZoomLevel(peninsula.getZoom());
          var max = max_min[region_type][normalization[compare]+'_'+year+'_max'];
          var min = max_min[region_type][normalization[compare]+'_'+year+'_min'];

          var desv = Math.max(Math.ceil(Math.abs(min)),Math.ceil(Math.abs(max)))/5;
          var value = Math.round(Math.abs(ele['data'][year][normalization[compare]]));
          var actual_zoom = peninsula.getZoom();

          if ((desv*0)>=value && value<(desv*1)) {
            radius=12;
          } else if ((desv*1)>=value && value<(desv*2)) {
            radius=19 * (actual_zoom==12?1.5:1);
          } else if ((desv*2)>=value && value<(desv*3)) {
            radius=23 * (actual_zoom==12?1.5:1);
          } else if ((desv*3)>=value && value<(desv*4)) {
            radius=28 * (actual_zoom==12?1.5:1);
          } else {
            radius=32 * (actual_zoom==12?1.5:1);
          }
        } else {
          radius = 12;
        }

        $('div#'+ele.id+' p.stat').removeClass('yellow red').addClass(className);
        $('div#'+ele.id+' p.stat').text(data);

        if (radius<14) {
          $('div#'+ele.id+' p.stat').hide();
        } else {
          $('div#'+ele.id+' p.stat').show();
        }

        if ($('div#'+ele.id).length) {
          var old_radius = ($('div#'+ele.id).width()/2);
          var top = old_radius + parseFloat(($('div#'+ele.id).css('top')).replace('px',''));
          var left = old_radius + parseFloat(($('div#'+ele.id).css('left')).replace('px',''));

          $('div#'+ele.id).animate({width:radius*2+'px',height:radius*2+'px',top:top-radius+'px',left:left-radius+'px'},{duration:500,queue:true});
        }
      });
    });
  }

  function showLoader() {
    $('div#map span.loader').fadeIn();
  }

  function hideLoader() {
    $('div#map span.loader').fadeOut();
  }

<commit_msg>pib solvedgit add .<commit_after>
  var MERCATOR_RANGE = 256;
  var hash = {};

  function CoordMapType(tileSize) {
    this.tileSize = tileSize;
    this.json_tile_url = "/bubbles/";
    this.loading_tiles = 0;
  }

  CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
    var me = this;

    // Create the div tile
    var div = ownerDocument.createElement('div');
    div.setAttribute('class','tile');
    //div.innerHTML= coord.x+"_"+coord.y+"_"+zoom;
    //div.style.border = "1px solid yellow";
    div.style.zIndex = 0;
    div.style.width = this.tileSize.width + 'px';
    div.style.height = this.tileSize.height + 'px';
    div.setAttribute('id',coord.x+'_'+coord.y+'_'+zoom);

    // Remove hash key
    hash[coord.x+'_'+coord.y+'_'+zoom] = [];

    //Select query/json to take data from this tile
    var x,y;

    if (zoom>9) {
      if (zoom==12) {
        x = coord.x/2;
        y = coord.y/2;
      } else {
        x = coord.x;
        y = coord.y;
      }
      z = 11;
    } else if (zoom>6 && zoom<=9) {
      if (zoom>7) {
        var difference = (zoom - 7)*2;
        x = coord.x/difference;
        y = coord.y/difference;
      } else {
        x = coord.x;
        y = coord.y;
      }
      z = 7;
    } else {
      x = coord.x;
      y = coord.y;
      z = 6;
    }

    if (x==undefined || ((x%1==0) && (y%1==0))) {
      // Call service

      // Loading tiles spinner
      this.loading_tiles++;
      showLoader();

      $.ajax({
        method: "GET",
        dataType: 'json',
        url: global_url + me.json_tile_url + bubbles_version +"/" +z+'_'+x+'_'+y+'.json',
        success: function(points) {
          me.loading_tiles--;
          if (me.loading_tiles == 0) {
            hideLoader();
          }

          // Normalize latlng of the tile to transform it to point(x,y)
          var pixelcoord = {x:coord.x*256,y:coord.y*256,z:zoom} ;
          var worldcoord = new google.maps.Point(pixelcoord.x/Math.pow(2,zoom),pixelcoord.y/Math.pow(2,zoom));
          var projection = peninsula.getProjection();
          var ne = projection.fromPointToLatLng(worldcoord);
          var normalizedPoint = peninsula.getProjection().fromLatLngToPoint(ne);
          var scale = Math.pow(2, zoom);
          var tileCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale);

          // Remove previous data of this tile
          delete hash[coord.x+'_'+coord.y+'_'+zoom];
          hash[coord.x+'_'+coord.y+'_'+zoom] = {};

          //Loop data points
          _.each(points,function(point,i){
            me.createBubble(div,point,tileCoordinate,scale,coord,zoom,ownerDocument);
          });

          return div;
        },
        error: function(e) {
          me.loading_tiles--;
          if (me.loading_tiles == 0) {
            hideLoader();
          }
          return div;
        }
      });
    } else {
      div.style.display = "none";
    }

    return div;
  };

  CoordMapType.prototype.releaseTile = function(tile) {
    var id = tile.getAttribute('id');
    delete hash[id];
  };

  CoordMapType.prototype.createBubble = function(div,point,tileCoordinate,scale,coord,zoom,ownerDocument) {
    hash[coord.x+'_'+coord.y+'_'+zoom][point.id] = point;

    var latlng          = new google.maps.LatLng(point.center_latitude,point.center_longitude);
    var normalizedPoint = peninsula.getProjection().fromLatLngToPoint(latlng); // returns x,y normalized to 0~255
    var pixelCoordinate = new google.maps.Point(normalizedPoint.x * scale, normalizedPoint.y * scale);

    var left = pixelCoordinate.x - tileCoordinate.x;
    var top = pixelCoordinate.y - tileCoordinate.y;

    var radius;
    if (point['data'][year]!=undefined) {
      if (normalization[compare]!=undefined) {
        var region_type = getDeepLevelFromZoomLevel(peninsula.getZoom());
        var max = max_min[region_type][normalization[compare]+'_'+year+'_max'];
        var min = max_min[region_type][normalization[compare]+'_'+year+'_min'];

        var desv = Math.max(Math.ceil(Math.abs(min)),Math.ceil(Math.abs(max)))/5;

        var value = Math.round(Math.abs(point['data'][year][normalization[compare]]));
        var actual_zoom = peninsula.getZoom();

        if ((desv*0)>=value && value<(desv*1)) {
          radius=12;
        } else if ((desv*1)>=value && value<(desv*2)) {
          radius=19 * (actual_zoom==12?1.5:1);
        } else if ((desv*2)>=value && value<(desv*3)) {
          radius=23 * (actual_zoom==12?1.5:1);
        } else if ((desv*3)>=value && value<(desv*4)) {
          radius=28 * (actual_zoom==12?1.5:1);
        } else {
          radius=32 * (actual_zoom==12?1.5:1);
        }
      } else {
        radius = 13;
      }
    } else {
      radius = 12;
    }

    var data,className;
    if (point['data'][year]==undefined || point['data'][year][normalization[compare]]==undefined) {
      data = '';
      className = "red";
    } else {
      data = ((point['data'][year][normalization[compare]]>0.5)?('+'+Math.round(point['data'][year][normalization[compare]])):(Math.round(point['data'][year][normalization[compare]])));
      className = (point['data'][year][normalization[compare]]>0)?'yellow':'grey';
    }

    var bubble =  '
'+
                    '
'+point.name+'
'+
                    ''+
                    '
'+data+'
'+
                  '
';
    $(div).append(bubble);

    if (radius < 14) {
      $('div.bubble[id="'+point.id+'"]').find('p.stat').css('display',"none");
    }

    var height_stat = $('div.bubble[id="'+point.id+'"] p.region_name').height();
    $('div.bubble[id="'+point.id+'"] p.region_name').css({top:'-'+(height_stat+2)+'px'});

    return div;
  };

  function refreshBubbles() {
    var flat = _.reduceRight(hash,function(a,b){ return a.concat(b); },[]);
    flat = _.select(flat, function(ele){ return ele!=undefined;});

    _.each(flat,function(occ,key){
      _.each(occ,function(ele,i){

        //change data of the ball
        var data,className;
        if (ele['data'][year]==undefined || ele['data'][year][normalization[compare]]==undefined) {
          data = '';
          className = "red";
        } else {
          data = ((ele['data'][year][normalization[compare]]>0)?('+'+Math.round(ele['data'][year][normalization[compare]])):(Math.round(ele['data'][year][normalization[compare]])));
          className = (ele['data'][year][normalization[compare]]>0)?'yellow':'grey';
        }

        //change color of the ball
        $('div#'+ele.id+' img').attr('src','images/'+className+'_marker.png');

        //change heigth-width of the ball
        var radius;
        if (ele['data'][year]!=undefined) {
          if (normalization[compare]!=undefined) {
            var region_type = getDeepLevelFromZoomLevel(peninsula.getZoom());
            var max = max_min[region_type][normalization[compare]+'_'+year+'_max'];
            var min = max_min[region_type][normalization[compare]+'_'+year+'_min'];

            var desv = Math.max(Math.ceil(Math.abs(min)),Math.ceil(Math.abs(max)))/5;
            var value = Math.round(Math.abs(ele['data'][year][normalization[compare]]));
            var actual_zoom = peninsula.getZoom();

            if ((desv*0)>=value && value<(desv*1)) {
              radius=12;
            } else if ((desv*1)>=value && value<(desv*2)) {
              radius=19 * (actual_zoom==12?1.5:1);
            } else if ((desv*2)>=value && value<(desv*3)) {
              radius=23 * (actual_zoom==12?1.5:1);
            } else if ((desv*3)>=value && value<(desv*4)) {
              radius=28 * (actual_zoom==12?1.5:1);
            } else {
              radius=32 * (actual_zoom==12?1.5:1);
            }
          } else {
            radius = 13;
          }
        } else {
          radius = 12;
        }

        $('div#'+ele.id+' p.stat').removeClass('yellow red').addClass(className);
        $('div#'+ele.id+' p.stat').text(data);

        if (radius<14) {
          $('div#'+ele.id+' p.stat').hide();
        } else {
          $('div#'+ele.id+' p.stat').show();
        }

        if ($('div#'+ele.id).length) {
          var old_radius = ($('div#'+ele.id).width()/2);
          var top = old_radius + parseFloat(($('div#'+ele.id).css('top')).replace('px',''));
          var left = old_radius + parseFloat(($('div#'+ele.id).css('left')).replace('px',''));

          $('div#'+ele.id).animate({width:radius*2+'px',height:radius*2+'px',top:top-radius+'px',left:left-radius+'px'},{duration:500,queue:true});
        }
      });
    });
  }

  function showLoader() {
    $('div#map span.loader').fadeIn();
  }

  function hideLoader() {
    $('div#map span.loader').fadeOut();
  }

<|endoftext|>


<commit_before>import assert from 'power-assert';
import {find} from 'hoardom';
import test from '../../helper/test';
import hasLabel from '../../../lib/utility/html/has-label';

describe('hasLabel', () => {
  it('should return true if an element has an explicitly associated label', async () => {
    await test(
      `
      Lorem ipsum
      <input id="input" type="text">
      `,
      body => assert(hasLabel(find(body, 'input')) === true)
    );
  });

  it('should return true if an element has an implicitly associated label', async () => {
    await test(
      `

        Lorem ipsum
        <input type="text">

      `,
      body => assert(hasLabel(find(body, 'input')) === true)
    );
  });

  it('should return false if an element has no associated label', async () => {
    await test(
      `
      <input id="input" type="text">
      `,
      input => assert(hasLabel(input) === false)
    );

    await test(
      `
      Lorem ipsum
      <input type="text">
      `,
      body => assert(hasLabel(find(body, 'input')) === false)
    );
    await test(
      `

        Lorem ipsum
        <button>Lorem ipsum</button>
        <input type="text">

      `,
      body => assert(hasLabel(find(body, 'input')) === false)
    );
  });
});
<commit_msg>Adjust `hasLabel()` spec<commit_after>import assert from 'power-assert';
import {find} from 'hoardom';
import test from '../../helper/test';
import hasLabel from '../../../lib/utility/html/has-label';

describe('hasLabel', () => {
  it('should return true if an element has an explicitly associated label', async () => {
    await test(
      `
      Lorem ipsum
      <input id="input" type="text">
      `,
      body => assert(hasLabel(find(body, 'input')) === true)
    );
  });

  it('should return true if an element has an implicitly associated label', async () => {
    await test(
      `

        Lorem ipsum
        <input type="text">

      `,
      body => assert(hasLabel(find(body, 'input')) === true)
    );

    await test(
      `

        Lorem ipsum
        <input type="text">
        <button>Lorem ipsum</button>

      `,
      body => assert(hasLabel(find(body, 'input')) === true)
    );
  });

  it('should return false if an element has no associated label', async () => {
    await test(
      `
      <input id="input" type="text">
      `,
      input => assert(hasLabel(input) === false)
    );

    await test(
      `
      Lorem ipsum
      <input type="text">
      `,
      body => assert(hasLabel(find(body, 'input')) === false)
    );

    await test(
      `

        Lorem ipsum
        <button>Lorem ipsum</button>
        <input type="text">

      `,
      body => assert(hasLabel(find(body, 'input')) === false)
    );
  });
});
<|endoftext|>


<commit_before>const isInt = (v) => {
  return (typeof v) === "number" && (isFinite(v)) && (Math.floor(v)) === v;
};

const entryForm = (data) => {
  var errors, h, l, ref;
  errors = {};
  if (data == null) {
    errors._error = "Ungültige Daten";
    return errors;
  }
  if (data.title == null) {
    errors.title = 'Pflichtangabe';
  } else {
    if (!((l = data.title.length) <= 40)) {
      if (errors.title == null) {
        errors.title = "Zu langer Titel: " + l + " statt max. 40 Zeichen";
      }
    }
    if (!((l = data.title.length) >= 3)) {
      if (errors.title == null) {
        errors.title = "Zu kurzer Titel: " + l + " von mind. 3 Zeichen";
      }
    }
  }
  if (data.description == null) {
    errors.description = 'Pflichtangabe';
  } else {
    if (!((l = data.description.length) <= 250)) {
      if (errors.description == null) {
        errors.description = "Zu lange Beschreibung: " + l + " statt max. 250 Zeichen";
      }
    }
    if (!((l = data.description.length) >= 10)) {
      if (errors.description == null) {
        errors.description = "Zu wenig Text: " + l + " von mind. 10 Zeichen";
      }
    }
  }
  if (data.lat == null) {
    errors.lat = 'Pflichtangabe';
  } else {
    if (!(data.lat * 1)) {
      errors.lat = 'Ungültiger Breitengrad';
    }
  }
  if (data.lng == null) {
    errors.lng = 'Pflichtangabe';
  } else {
    if (!(data.lng * 1)) {
      errors.lng = 'Ungültiger Längengrad';
    }
  }
  if (data.category == null) {
    errors.category = 'Pflichtangabe';
  } else {
    if ((typeof data.category) !== "string") {
      errors.category = 'Ungültige Kategorie';
    }
  }
  if (data.license == null) {
    errors.license = 'Lizenzzustimmung ist nötig';
  } else {
    if ((typeof data.license) !== "boolean") {
      errors.license = 'Ungültige Zustimmung';
    } else if (data.license === false) {
      errors.license = 'Lizenzzustimmung ist nötig';
    }
  }
  if ((h = data.homepage) != null) {
    if (!((h.indexOf("http://") === 0) || (h.indexOf("https://") === 0))) {
      errors.homepage = 'Ungültige URL ("http://" oder "https://" fehlt)';
    }
    if (((ref = (h = data.homepage)) != null ? ref.length : void 0) < 9) {
      errors.homepage = 'Ungültige URL';
    }
  }
  return errors;
};

const ratingForm = (data) => {
  var h, l, ref;
  var errors = {};
  if (data == null) {
    errors._error = "Ungültige Daten";
    return errors;
  }
  if (data.title == null) {
    errors.title = 'Pflichtangabe';
  } else {
    if (!((l = data.title.length) <= 40)) {
      if (errors.title == null) {
        errors.title = "Zu langer Titel: " + l + " statt max. 40 Zeichen";
      }
    }
    if (!((l = data.title.length) >= 3)) {
      if (errors.title == null) {
        errors.title = "Zu kurzer Titel: " + l + " von mind. 3 Zeichen";
      }
    }
  }
  if (data.context == null) {
    errors.context = 'Pflichtangabe';
  } else {
    if ((typeof data.context) !== "string") {
      errors.context = 'Ungültiger Bewertungskontext';
    }
  }
  if (data.value == null) {
    errors.value = 'Pflichtangabe';
  } else {
    if (data.value < -1 || data.value > 2) {
      errors.value = 'Ungültige Bewertung';
    }
  }
  if (data.comment == null) {
    errors.comment = 'Pflichtangabe';
  } else {
    if (!((l = data.comment.length) <= 160)) {
      if (errors.comment == null) {
        errors.comment = "Zu langer Kommentar: " + l + " statt max. 160 Zeichen";
      }
    }
    if (!((l = data.comment.length) >= 10)) {
      if (errors.comment == null) {
        errors.comment = "Zu wenig Text: " + l + " von mind. 10 Zeichen";
      }
    }
  }
  return errors;
}

module.exports = { entryForm, ratingForm };
<commit_msg>fix(RatingForm): allow comments with up to 500 chars<commit_after>const isInt = (v) => {
  return (typeof v) === "number" && (isFinite(v)) && (Math.floor(v)) === v;
};

const entryForm = (data) => {
  var errors, h, l, ref;
  errors = {};
  if (data == null) {
    errors._error = "Ungültige Daten";
    return errors;
  }
  if (data.title == null) {
    errors.title = 'Pflichtangabe';
  } else {
    if (!((l = data.title.length) <= 40)) {
      if (errors.title == null) {
        errors.title = "Zu langer Titel: " + l + " statt max. 40 Zeichen";
      }
    }
    if (!((l = data.title.length) >= 3)) {
      if (errors.title == null) {
        errors.title = "Zu kurzer Titel: " + l + " von mind. 3 Zeichen";
      }
    }
  }
  if (data.description == null) {
    errors.description = 'Pflichtangabe';
  } else {
    if (!((l = data.description.length) <= 250)) {
      if (errors.description == null) {
        errors.description = "Zu lange Beschreibung: " + l + " statt max. 250 Zeichen";
      }
    }
    if (!((l = data.description.length) >= 10)) {
      if (errors.description == null) {
        errors.description = "Zu wenig Text: " + l + " von mind. 10 Zeichen";
      }
    }
  }
  if (data.lat == null) {
    errors.lat = 'Pflichtangabe';
  } else {
    if (!(data.lat * 1)) {
      errors.lat = 'Ungültiger Breitengrad';
    }
  }
  if (data.lng == null) {
    errors.lng = 'Pflichtangabe';
  } else {
    if (!(data.lng * 1)) {
      errors.lng = 'Ungültiger Längengrad';
    }
  }
  if (data.category == null) {
    errors.category = 'Pflichtangabe';
  } else {
    if ((typeof data.category) !== "string") {
      errors.category = 'Ungültige Kategorie';
    }
  }
  if (data.license == null) {
    errors.license = 'Lizenzzustimmung ist nötig';
  } else {
    if ((typeof data.license) !== "boolean") {
      errors.license = 'Ungültige Zustimmung';
    } else if (data.license === false) {
      errors.license = 'Lizenzzustimmung ist nötig';
    }
  }
  if ((h = data.homepage) != null) {
    if (!((h.indexOf("http://") === 0) || (h.indexOf("https://") === 0))) {
      errors.homepage = 'Ungültige URL ("http://" oder "https://" fehlt)';
    }
    if (((ref = (h = data.homepage)) != null ? ref.length : void 0) < 9) {
      errors.homepage = 'Ungültige URL';
    }
  }
  return errors;
};

const ratingForm = (data) => {
  var h, l, ref;
  var errors = {};
  if (data == null) {
    errors._error = "Ungültige Daten";
    return errors;
  }
  if (data.title == null) {
    errors.title = 'Pflichtangabe';
  } else {
    if (!((l = data.title.length) <= 40)) {
      if (errors.title == null) {
        errors.title = "Zu langer Titel: " + l + " statt max. 40 Zeichen";
      }
    }
    if (!((l = data.title.length) >= 3)) {
      if (errors.title == null) {
        errors.title = "Zu kurzer Titel: " + l + " von mind. 3 Zeichen";
      }
    }
  }
  if (data.context == null) {
    errors.context = 'Pflichtangabe';
  } else {
    if ((typeof data.context) !== "string") {
      errors.context = 'Ungültiger Bewertungskontext';
    }
  }
  if (data.value == null) {
    errors.value = 'Pflichtangabe';
  } else {
    if (data.value < -1 || data.value > 2) {
      errors.value = 'Ungültige Bewertung';
    }
  }
  if (data.comment == null) {
    errors.comment = 'Pflichtangabe';
  } else {
    if (!((l = data.comment.length) <= 500)) {
      if (errors.comment == null) {
        errors.comment = "Zu langer Kommentar: " + l + " statt max. 500 Zeichen";
      }
    }
    if (!((l = data.comment.length) >= 10)) {
      if (errors.comment == null) {
        errors.comment = "Zu wenig Text: " + l + " von mind. 10 Zeichen";
      }
    }
  }
  return errors;
}

module.exports = { entryForm, ratingForm };
<|endoftext|>


<commit_before>//
// BASE Carousel
// --------------------------------------------------

// An ultra-light, customisable, 'just-works' carousel script

(function($) {

    "use strict";

    $.carousel = function (element, options) {

        var defaults = {
            slide: 'img',
            speed: 5000,

            transition: 'fade',
            transitionSpeed: 2000,
            easing: 'ease',

            firstSlide: 1,

            pauseOnHover: true,
            cssAnimations: true,
            fallback: true,

            allowJump: true,

            // callbacks
            onSlide: function () {},
            onNext: function () {},
            onPrev: function () {},
            onJump: function () {},
            onStart: function () {},
            onPause: function () {},
        },
            plugin = this,
            $element = $(element),
            interval;

        // add the basic css classes
        plugin.create = function () {

            // basic css structure
            $element.addClass('carousel');
            $element.addClass('transition-' + plugin.settings.transition); // transition class
            $element.find(plugin.settings.slide).addClass('slide'); // slide class

            // set first slide
            plugin.slide(plugin.settings.firstSlide);
            if (plugin.settings.speed) { plugin.run(); }

        };

        // take slider to a specific slide number
        plugin.slide = function (e, s, m) {

            s = typeof s !== 'undefined' ? s : plugin.settings.transitionSpeed; // speed default
            m = typeof m !== 'undefined' ? m : plugin.settings.easing; // transition default

            var i = $element.find('.active').index('.slide') + 1,
                n = $element.find('.slide').length,
                $to = $element.find(plugin.settings.slide + ':nth-child(' + e + ')'),
                $prev = ($to.prev('.slide').length === 0) ? $element.find('.slide:last') : $to.prev('.slide'),
                $next = ($to.next('.slide').length === 0) ? $element.find('.slide:first') : $to.next('.slide'),
                animate = (plugin.settings.transition === 'slide') ? 'left' : 'opacity';

            if (e > n) { return false; } // prevent going to non-existant slide

            if (plugin.settings.cssAnimations) {
                $element.find('.slide').css('transition', animate + ' ' + (s / 1000) + 's ' + m);
            }

            if (i > e && !(e === 1 && i === n) ) {
                $element.addClass('backwards');
            } else {
                $element.removeClass('backwards');
            }

            $element.find('.slide').removeClass('left active right');
            $to.addClass('active');
            $prev.addClass('left');
            $next.addClass('right');

            if ( $('a[data-carousel="jump"]').length > 0 ) { // check if paged nav exits

                $('a[data-carousel="jump"]').each( function() {
                    if (parseInt($(this).attr('href').replace('#','')) === e) {
                        $(this).addClass('active');
                    } else {
                        $(this).removeClass('active');
                    }
                });

            }

            if (plugin.settings.fallback) { carouselAnimate(e, s); } // fallback animation
            plugin.settings.onSlide(e, s); // callback

        };

        // call next slide from current slide
        plugin.next = function () {

            var next = $element.find('.active').next('.slide').length,
                e = (next === 0) ? 0 : $element.find('.active').index('.slide') + 1;

            plugin.slide(e + 1);
            plugin.settings.onNext(e); // callback

        };

        // call previous slide from current slide
        plugin.prev = function () {

            var prev = $element.find('.active').prev('.slide').length,
                e = (prev === 0) ? $element.find('.slide:last').index('.slide') + 1 : $element.find('.active').index('.slide');

            plugin.slide(e);
            plugin.settings.onPrev(e); // callback

        };

        // move to a non-sequential slide
        plugin.jump = function (e) {

            plugin.pause();

            if (plugin.settings.transition === 'slide') {

                var index = $element.find('.active').index('.slide') + 1, // current position
                    d = (e >= index), // direction
                    steps = (d) ? (e - index) : (index - e), // slides to travel
                    speed = plugin.settings.transitionSpeed / steps, // speed fraction
                    step = 1,
                    first = true;

                (function change() {

                    var next = (d) ? (index + step) : (index - step),
                        easing = (first) ? 'ease-in' : (steps === 1) ? 'ease-out' : 'linear';

                    plugin.slide(next, speed, easing);
                    steps--;
                    step++;
                    first = false;

                    interval = setTimeout(change, speed);
                    if (steps <= 0) { clearTimeout(interval); }

                })();

            } else { plugin.slide(e); }

            plugin.settings.onJump(e); // callback

        };

        plugin.run = function () {

            // run carousel
            interval = setInterval(function () {
                plugin.next();
            }, plugin.settings.speed);
            plugin.settings.onStart(); // callback

        };

        plugin.pause = function () {

            clearInterval(interval);
            plugin.settings.onPause(); // callback

        };

        var pauseOnHover = function() {

            if (!plugin.settings.pauseOnHover) { return false; }

            $element.hover(function () {
                plugin.pause();
            }, function() {
                plugin.run();
            });

        };

        var navigation = function() {

            $('a[data-carousel!=""]').click( function(e) {

                plugin.pause();

                var action = $(this).attr('data-carousel'),
                to = $(this).attr('href').replace('#','');

                if (action === 'jump') {

                    if (plugin.settings.allowJump) {
                        $('a[data-carousel="jump"]').removeClass('active');
                        $(this).addClass('active');
                        plugin.jump(to);
                    }

                } else { plugin[action](); }

                e.preventDefault();

            });

        };

        // javascript animation fallbacks

        var carouselAnimate = function (e, s) {

            if ((!Modernizr.cssanimations || !plugin.settings.cssAnimations) && plugin.settings.transition === 'slide') {
                slideAnimation(s);
            } else if ((!Modernizr.cssanimations || !plugin.settings.cssAnimations) && plugin.settings.transition === 'fade') {
                fadeAnimation(s);
            }

        };

        var slideAnimation = function (speed) {

            $element.find('.slide').stop(true, true); // stop any running animations
            $element.find('.active').animate({ left: '0%' }, speed);
            $element.find('.left').animate({ left: '-100%' }, speed);
            $element.find('.right').animate({ left: '100%' }, speed);

        };

        var fadeAnimation = function (speed) {

            $element.find('.slide').stop(true, true); // stop any running animations
            $element.find('.active').animate({ opacity: '1' }, speed);
            $element.find('.left').animate({ opacity: '0' }, speed);
            $element.find('.right').animate({ opacity: '0' }, speed);

        };

        // external access: element.data('carousel').settings.propertyName
        plugin.settings = {};

        plugin.init = function() {

            plugin.settings = $.extend({}, defaults, options);
            plugin.create();

            // private methods
            pauseOnHover();
            navigation();

        };
        plugin.init();

    };

    // add to the jQuery object
    $.fn.carousel = function (options) {

        return this.each(function () {
            if (undefined === $(this).data('carousel')) {

                var plugin = new $.carousel(this, options);

                // element.data('carousel').publicMethod(arg1, arg2, ... argn)
                // element.data('carousel').settings.propertyName
                $(this).data('carousel', plugin);

            }
        });

    };

})(jQuery);<commit_msg>Stop link events misfiring, better selector.<commit_after>//
// BASE Carousel
// --------------------------------------------------

// An ultra-light, customisable, 'just-works' carousel script

(function($) {

    "use strict";

    $.carousel = function (element, options) {

        var defaults = {
            slide: 'img',
            speed: 5000,

            transition: 'fade',
            transitionSpeed: 2000,
            easing: 'ease',

            firstSlide: 1,

            pauseOnHover: true,
            cssAnimations: true,
            fallback: true,

            allowJump: true,

            // callbacks
            onSlide: function () {},
            onNext: function () {},
            onPrev: function () {},
            onJump: function () {},
            onStart: function () {},
            onPause: function () {},
        },
            plugin = this,
            $element = $(element),
            interval;

        // add the basic css classes
        plugin.create = function () {

            // basic css structure
            $element.addClass('carousel');
            $element.addClass('transition-' + plugin.settings.transition); // transition class
            $element.find(plugin.settings.slide).addClass('slide'); // slide class

            // set first slide
            plugin.slide(plugin.settings.firstSlide);
            if (plugin.settings.speed) { plugin.run(); }

        };

        // take slider to a specific slide number
        plugin.slide = function (e, s, m) {

            s = typeof s !== 'undefined' ? s : plugin.settings.transitionSpeed; // speed default
            m = typeof m !== 'undefined' ? m : plugin.settings.easing; // transition default

            var i = $element.find('.active').index('.slide') + 1,
                n = $element.find('.slide').length,
                $to = $element.find(plugin.settings.slide + ':nth-child(' + e + ')'),
                $prev = ($to.prev('.slide').length === 0) ? $element.find('.slide:last') : $to.prev('.slide'),
                $next = ($to.next('.slide').length === 0) ? $element.find('.slide:first') : $to.next('.slide'),
                animate = (plugin.settings.transition === 'slide') ? 'left' : 'opacity';

            if (e > n) { return false; } // prevent going to non-existant slide

            if (plugin.settings.cssAnimations) {
                $element.find('.slide').css('transition', animate + ' ' + (s / 1000) + 's ' + m);
            }

            if (i > e && !(e === 1 && i === n) ) {
                $element.addClass('backwards');
            } else {
                $element.removeClass('backwards');
            }

            $element.find('.slide').removeClass('left active right');
            $to.addClass('active');
            $prev.addClass('left');
            $next.addClass('right');

            if ( $('a[data-carousel="jump"]').length > 0 ) { // check if paged nav exits

                $('a[data-carousel="jump"]').each( function() {
                    if (parseInt($(this).attr('href').replace('#','')) === e) {
                        $(this).addClass('active');
                    } else {
                        $(this).removeClass('active');
                    }
                });

            }

            if (plugin.settings.fallback) { carouselAnimate(e, s); } // fallback animation
            plugin.settings.onSlide(e, s); // callback

        };

        // call next slide from current slide
        plugin.next = function () {

            var next = $element.find('.active').next('.slide').length,
                e = (next === 0) ? 0 : $element.find('.active').index('.slide') + 1;

            plugin.slide(e + 1);
            plugin.settings.onNext(e); // callback

        };

        // call previous slide from current slide
        plugin.prev = function () {

            var prev = $element.find('.active').prev('.slide').length,
                e = (prev === 0) ? $element.find('.slide:last').index('.slide') + 1 : $element.find('.active').index('.slide');

            plugin.slide(e);
            plugin.settings.onPrev(e); // callback

        };

        // move to a non-sequential slide
        plugin.jump = function (e) {

            plugin.pause();

            if (plugin.settings.transition === 'slide') {

                var index = $element.find('.active').index('.slide') + 1, // current position
                    d = (e >= index), // direction
                    steps = (d) ? (e - index) : (index - e), // slides to travel
                    speed = plugin.settings.transitionSpeed / steps, // speed fraction
                    step = 1,
                    first = true;

                (function change() {

                    var next = (d) ? (index + step) : (index - step),
                        easing = (first) ? 'ease-in' : (steps === 1) ? 'ease-out' : 'linear';

                    plugin.slide(next, speed, easing);
                    steps--;
                    step++;
                    first = false;

                    interval = setTimeout(change, speed);
                    if (steps <= 0) { clearTimeout(interval); }

                })();

            } else { plugin.slide(e); }

            plugin.settings.onJump(e); // callback

        };

        plugin.run = function () {

            // run carousel
            interval = setInterval(function () {
                plugin.next();
            }, plugin.settings.speed);
            plugin.settings.onStart(); // callback

        };

        plugin.pause = function () {

            clearInterval(interval);
            plugin.settings.onPause(); // callback

        };

        var pauseOnHover = function() {

            if (!plugin.settings.pauseOnHover) { return false; }

            $element.hover(function () {
                plugin.pause();
            }, function() {
                plugin.run();
            });

        };

        var navigation = function() {

            $('a[data-carousel]').click( function(e) {

                plugin.pause();

                var action = $(this).attr('data-carousel'),
                to = $(this).attr('href').replace('#','');

                if (action === 'jump') {

                    if (plugin.settings.allowJump) {
                        $('a[data-carousel="jump"]').removeClass('active');
                        $(this).addClass('active');
                        plugin.jump(to);
                    }

                } else { plugin[action](); }

                e.preventDefault();

            });

        };

        // javascript animation fallbacks

        var carouselAnimate = function (e, s) {

            if ((!Modernizr.cssanimations || !plugin.settings.cssAnimations) && plugin.settings.transition === 'slide') {
                slideAnimation(s);
            } else if ((!Modernizr.cssanimations || !plugin.settings.cssAnimations) && plugin.settings.transition === 'fade') {
                fadeAnimation(s);
            }

        };

        var slideAnimation = function (speed) {

            $element.find('.slide').stop(true, true); // stop any running animations
            $element.find('.active').animate({ left: '0%' }, speed);
            $element.find('.left').animate({ left: '-100%' }, speed);
            $element.find('.right').animate({ left: '100%' }, speed);

        };

        var fadeAnimation = function (speed) {

            $element.find('.slide').stop(true, true); // stop any running animations
            $element.find('.active').animate({ opacity: '1' }, speed);
            $element.find('.left').animate({ opacity: '0' }, speed);
            $element.find('.right').animate({ opacity: '0' }, speed);

        };

        // external access: element.data('carousel').settings.propertyName
        plugin.settings = {};

        plugin.init = function() {

            plugin.settings = $.extend({}, defaults, options);
            plugin.create();

            // private methods
            pauseOnHover();
            navigation();

        };
        plugin.init();

    };

    // add to the jQuery object
    $.fn.carousel = function (options) {

        return this.each(function () {
            if (undefined === $(this).data('carousel')) {

                var plugin = new $.carousel(this, options);

                // element.data('carousel').publicMethod(arg1, arg2, ... argn)
                // element.data('carousel').settings.propertyName
                $(this).data('carousel', plugin);

            }
        });

    };

})(jQuery);
<|endoftext|>