<commit_before>/*globals define*/
/*jshint node:true, browser:true*/

/**
 * Generated by PluginGenerator 0.14.0 from webgme on Thu Aug 27 2015 14:29:24 GMT-0500 (Central Daylight Time).
 */

define([
    'plugin/PluginConfig',
    'plugin/PluginBase',
    'common/core/users/serialization'
], function (PluginConfig,
             PluginBase,
             serialization) {
    'use strict';

    /**
     * Initializes a new instance of ExportImport.
     * @class
     * @augments {PluginBase}
     * @classdesc This class represents the plugin ExportImport.
     * @constructor
     */
    var ExportImport = function () {
        // Call base class' constructor.
        PluginBase.call(this);
    };

    // Prototypal inheritance from PluginBase.
    ExportImport.prototype = Object.create(PluginBase.prototype);
    ExportImport.prototype.constructor = ExportImport;

    /**
     * Gets the name of the ExportImport.
     * @returns {string} The name of the plugin.
     * @public
     */
    ExportImport.prototype.getName = function () {
        return 'Export, Import and Update Library';
    };

    /**
     * Gets the semantic version (semver.org) of the ExportImport.
     * @returns {string} The version of the plugin.
     * @public
     */
    ExportImport.prototype.getVersion = function () {
        return '0.14.0';
    };

    /**
     * Gets the description of the ExportImport.
     * @returns {string} The description of the plugin.
     * @public
     */
    ExportImport.prototype.getDescription = function () {
        return 'Example of how to export, import and update a library from and to webgme.\n' +
            'The active node (i.e. open node on the canvas) will be the starting point.';
    };

    /**
     * Gets the configuration structure for the ExportImport.
     * The ConfigurationStructure defines the configuration for the plugin
     * and will be used to populate the GUI when invoking the plugin from webGME.
     * @returns {object} The version of the plugin.
     * @public
     */
    ExportImport.prototype.getConfigStructure = function () {
        return [
            {
                name: 'type',
                displayName: 'Type',
                description: 'What library action should be taken?',
                value: 'Export',
                valueType: 'string',
                valueItems: [
                    'Export',
                    'Import',
                    'Update'
                ]
            },
            {
                name: 'file',
                displayName: 'Webgme library file.',
                description: 'Provide an export json file when importing or updating.',
                value: '',
                valueType: 'asset',
                readOnly: false
            }
        ];
    };

    /**
     * Main function for the plugin to execute. This will perform the execution.
     * Notes:
     * - Always log with the provided logger.[error,warning,info,debug].
     * - Do NOT put any user interaction logic UI, etc. inside this method.
     * - callback always has to be called even if error happened.
     *
     * @param {function(string, plugin.PluginResult)} callback - the result callback
     */
    ExportImport.prototype.main = function (callback) {
        // Use self to access core, project, result, logger etc from PluginBase.
        // These are all instantiated at this point.
        var self = this,
            currentConfig = self.getCurrentConfig();

        if (currentConfig.type === 'Export') {
            self.exportLibrary(currentConfig, callback);
        } else {
            if (!currentConfig.file) {
                self.result.setError('Add a json file when importing or updating.');
                callback(new Error('No file provided.'), self.result);
            } else if (currentConfig.type === 'Import') {
                self.importLibrary(currentConfig, callback);
            } else if (currentConfig.type === 'Update') {
                self.updateLibrary(currentConfig, callback);
            }
        }
    };

    ExportImport.prototype.exportLibrary = function (currentConfig, callback) {
        var self = this,
            artie,
            jsonStr;
        serialization.export(self.core, self.activeNode, function (err, projectJson) {
            if (err) {
                callback(err, self.result);
                return;
            }
            jsonStr = JSON.stringify(projectJson, null, 4);
            self.logger.info(projectJson);
            artie = self.blobClient.createArtifact('exported');
            artie.addFile('lib.json', jsonStr, function (err/*, hash*/) {
                if (err) {
                    callback(err, self.result);
                    return;
                }
                self.blobClient.saveAllArtifacts(function (err, hashes) {
                    if (err) {
                        callback(err, self.result);
                        return;
                    }
                    self.result.addArtifact(hashes[0]);
                    self.result.setSuccess(true);
                    callback(null, self.result);
                });
            });
        });
    };

    ExportImport.prototype.importLibrary = function (currentConfig, callback) {
        callback(new Error('Not Implemented!'));
    };

    ExportImport.prototype.updateLibrary = function (currentConfig, callback) {
        callback(new Error('Not Implemented!'));
    };

    return ExportImport;
});<commit_msg>#509 Update and Import implemented.<commit_after>/*globals define*/
/*jshint node:true, browser:true*/

/**
 * Generated by PluginGenerator 0.14.0 from webgme on Thu Aug 27 2015 14:29:24 GMT-0500 (Central Daylight Time).
 */

define([
    'plugin/PluginConfig',
    'plugin/PluginBase',
    'common/core/users/serialization'
], function (PluginConfig,
             PluginBase,
             serialization) {
    'use strict';

    /**
     * Initializes a new instance of ExportImport.
     * @class
     * @augments {PluginBase}
     * @classdesc This class represents the plugin ExportImport.
     * @constructor
     */
    var ExportImport = function () {
        // Call base class' constructor.
        PluginBase.call(this);
    };

    // Prototypal inheritance from PluginBase.
    ExportImport.prototype = Object.create(PluginBase.prototype);
    ExportImport.prototype.constructor = ExportImport;

    /**
     * Gets the name of the ExportImport.
     * @returns {string} The name of the plugin.
     * @public
     */
    ExportImport.prototype.getName = function () {
        return 'Export, Import and Update Library';
    };

    /**
     * Gets the semantic version (semver.org) of the ExportImport.
     * @returns {string} The version of the plugin.
     * @public
     */
    ExportImport.prototype.getVersion = function () {
        return '0.14.0';
    };

    /**
     * Gets the description of the ExportImport.
     * @returns {string} The description of the plugin.
     * @public
     */
    ExportImport.prototype.getDescription = function () {
        return 'Example of how to export, import and update a library from and to webgme.\n' +
            'The active node (i.e. open node on the canvas) will be the starting point.';
    };

    /**
     * Gets the configuration structure for the ExportImport.
     * The ConfigurationStructure defines the configuration for the plugin
     * and will be used to populate the GUI when invoking the plugin from webGME.
     * @returns {object} The version of the plugin.
     * @public
     */
    ExportImport.prototype.getConfigStructure = function () {
        return [
            {
                name: 'type',
                displayName: 'Type',
                description: 'What library action should be taken?',
                value: 'Export',
                valueType: 'string',
                valueItems: [
                    'Export',
                    'Import',
                    'Update'
                ]
            },
            {
                name: 'file',
                displayName: 'Webgme library file.',
                description: 'Provide an export json file when importing or updating.',
                value: '',
                valueType: 'asset',
                readOnly: false
            }
        ];
    };

    /**
     * Main function for the plugin to execute. This will perform the execution.
     * Notes:
     * - Always log with the provided logger.[error,warning,info,debug].
     * - Do NOT put any user interaction logic UI, etc. inside this method.
     * - callback always has to be called even if error happened.
     *
     * @param {function(string, plugin.PluginResult)} callback - the result callback
     */
    ExportImport.prototype.main = function (callback) {
        // Use self to access core, project, result, logger etc from PluginBase.
        // These are all instantiated at this point.
        var self = this,
            currentConfig = self.getCurrentConfig();

        if (currentConfig.type === 'Export') {
            self.exportLibrary(currentConfig, callback);
        } else if (currentConfig.type === 'Import') {
            self.importOrUpdateLibrary(currentConfig, callback);
        } else if (currentConfig.type === 'Update') {
            self.importOrUpdateLibrary(currentConfig, callback);
        }
    };

    ExportImport.prototype.exportLibrary = function (currentConfig, callback) {
        var self = this,
            artie,
            jsonStr;
        serialization.export(self.core, self.activeNode, function (err, projectJson) {
            if (err) {
                callback(err, self.result);
                return;
            }
            jsonStr = JSON.stringify(projectJson, null, 4);
            self.logger.info(projectJson);
            artie = self.blobClient.createArtifact('exported');
            artie.addFile('lib.json', jsonStr, function (err/*, hash*/) {
                if (err) {
                    callback(err, self.result);
                    return;
                }
                self.blobClient.saveAllArtifacts(function (err, hashes) {
                    if (err) {
                        callback(err, self.result);
                        return;
                    }
                    self.result.addArtifact(hashes[0]);
                    self.result.setSuccess(true);
                    callback(null, self.result);
                });
            });
        });
    };

    ExportImport.prototype.importOrUpdateLibrary = function (currentConfig, callback) {
        var self = this,
            libraryRoot;

        self.getLibObject(currentConfig, function (err, libObject) {
            if (err) {
                callback(err, self.result);
                return;
            }

            if (currentConfig.type === 'Import') {
                libraryRoot = self.core.createNode({
                    parent: self.activeNode,
                    base: null
                });
                self.core.setAttribute(libraryRoot, 'name', 'Import Library');
            } else {
                libraryRoot = self.activeNode;
            }

            serialization.import(self.core, libraryRoot, libObject, function (err) {
                if (err) {
                    callback(err, self.result);
                    return;
                }
                self.save('Imported Library to "' + self.core.getPath(self.activeNode) + '"', function (err) {
                    if (err) {
                        callback(err, self.result);
                        return;
                    }
                    self.createMessage(self.activeNode, 'Library imported');
                    self.result.setSuccess(true);
                    callback(null, self.result);
                });
            });
        });
    };

    ExportImport.prototype.getLibObject = function (currentConfig, callback) {
        var self = this;
        if (!currentConfig.file) {
            self.result.setError('Add a json file when importing or updating.');
            callback(new Error('No file provided.'));
            return;
        }

        self.blobClient.getObject(currentConfig.file, function (err, libOrBuf) {
            var libObject;
            if (err) {
                callback(err);
                return;
            }

            if (false) {
                try {
                    libOrBuf = String.fromCharCode.apply(null, new Uint8Array(libOrBuf));
                    libObject = JSON.loads(libOrBuf);
                    callback(null, libObject);
                } catch (err) {
                    callback(new Error('Failed to parse file.'));
                    return;
                }
            } else {
                callback(null, libOrBuf);
            }
        });
    };

    return ExportImport;
});<|endoftext|>


<commit_before>$(document).ready(function() {

$('#add_hike').hide();
$('#edit_hike').hide();

function get_hikes() {
	var url = "inc/call_db.inc.php?view=admin_list";
	$.ajax({
		method: "GET",
		url: url,
		dataType: 'json'
	}).done(function(data) {
		for (var i=0; i < data.rows.length; i++) {
			var lat = data.rows[i].key.lat;
			var lng = data.rows[i].key.lng;
			var hike_id = data.rows[i].id;
			var rev = data.rows[i].value.rev;

			var output = "
";
			output += "
" + data.rows[i].value.name + "
";
			output += "
 Area:
" + data.rows[i].value.area;
			output += "
 Date:
" + data.rows[i].value.date;
			output += "<button class=\"edit\">Edit</button>";
			output += "<button class=\"delete\">Delete</button>";
			output += "
";
			$('#hike_list').append(output);
			add_handlers(lat, lng, hike_id, rev);
		} //end for

		function add_handlers(lat, lng, hike_id, rev) {
			var edit_button = $('#hike_list section:last-of-type .edit');
			var delete_button = $('#hike_list section:last-of-type .delete');

			$(edit_button).click(function() {
				$('#edit_hike').show();
				edit_hike(lat, lng, hike_id);
			});

			$(delete_button).click(function() {
				delete_hike(hike_id, rev);
			});
		}
	})
}

function delete_hike(hike_id, rev) {
	var url = "inc/delete_hike.inc.php";

	$.ajax({
		method: "POST",
		url: url,
		data: {id: hike_id, rev: rev}
	}).done(function(data){
		console.log(data);
	});
}

function edit_hike(lat, lng, hike_id) {
	var url = "inc/call_db.inc.php?view=full_hike_info&lat=" + lat + "&lng=" + lng;
	$.ajax({
		method: "GET",
		url: url,
		dataType: 'json'
	}).done(function(data) {
		var hike_id = data.rows[0].id;
		var rev = data.rows[0].value.rev;
		// Populate Fields
		$('#edit_hike #edit_hike_name').val(data.rows[0].value.name);
		$('#edit_hike #edit_area').val(data.rows[0].value.area);
		$('#edit_hike #edit_type').val(data.rows[0].value.type);
		$('#edit_hike #edit_date').val(data.rows[0].value.date);
		$('#edit_hike #edit_description').val(data.rows[0].value.description);
		$('#edit_hike #edit_distance').val(data.rows[0].value.distance);
		$('#edit_hike #edit_elevation_gain').val(data.rows[0].value.elevation_gain);
		$('#edit_hike #edit_lat').val(data.rows[0].key.lat);
		$('#edit_hike #edit_lng').val(data.rows[0].key.lng);

		if(data.rows[0].value.directions.length > 1) {
			$('#edit_hike #edit_directions').val(data.rows[0].value.directions[0]);
			for (var i=1; i < data.rows[0].value.directions.length; i++) {
				var new_field = "<input type=\"text\" name=\"directions[]\">";
				$(new_field).appendTo($("#edit_directions_container"));
				$('#edit_directions_container input:last-of-type').val(data.rows[0].value.directions[i]);
			}
		} else {
			$('#edit_hike #edit_directions').val(data.rows[0].value.directions[0]);
		}

		if(data.rows[0].value.hasOwnProperty("attachments")) {
			for (var j=0; j < data.rows[0].value.attachments.length; j++) {
				var output = "";
				$('#image_container').append(output);
			} //end for
		}

		$('#edit_hike_form').submit(function(event) {
			event.preventDefault();
			submit_form("edit", hike_id, rev);
		});
	});
}

function submit_form(action, hike_id, rev) {
	switch(action) {
		case "edit":
			var form_contents = $("#edit_hike_form").serializeArray();
			var image_upload = document.getElementById('edit_image_upload');
			var url = "inc/submit_form.inc.php?action=edit&id=" + hike_id + "&rev=" + rev;

			var files = image_upload.files;

			var formData = new FormData();

			for (var i = 0; i < files.length; i++) {
				var file = files[i];

				if (!file.type.match('image.*')) {
					continue;
				}

				formData.append('image_upload', file, file.name);
			}

			for (var j=0; j < form_contents.length; j++) {
				formData.append(form_contents[j].name, form_contents[j].value);
			}

			formData.append('action', action);
			formData.append('hike_id', hike_id);
			formData.append('rev', rev);
		break;

		case "add":
			var form_contents = $('#add_hike_form').serializeArray();
			var image_upload = document.getElementById('image_upload');
			var url = "inc/submit_form.inc.php";

			var files = image_upload.files;

			var formData = new FormData();

			for (var i = 0; i < files.length; i++) {
				//Note: http://blog.teamtreehouse.com/uploading-files-ajax
				var file = files[i];

				// Check the file type.
				if (!file.type.match('image.*')) {
				    continue;
				}

				// Add the file to the request.
				formData.append('image_upload', file, file.name);
			}

			for (var j=0; j < form_contents.length; j++) {
				formData.append(form_contents[j].name, form_contents[j].value);
			}
		break;
	}

	var xhr = new XMLHttpRequest();

	xhr.open('POST', url, true);

	xhr.send(formData);
}

$('#add_hike_button').click(function() {
	$('#add_hike').show();
})

$('#add_hike_form').submit(function() {
	event.preventDefault();
	submit_form();
});

$(':file').change(function() {
	var file = this.files[0];
	name = file.name;
	size = file.size;
	type = file.type;

	if(file.name.length < 1) {

	}
	else if(file.size > 10000000) {
		alert("File is too big");
	}
	else if(file.type != 'image/jpg') {
		// alert("Invalid file type");
	}
});

$('#add_button, #edit_add_button').click(function() {
	event.preventDefault();
	var new_field = "<input type=\"text\" name=\"directions[]\">";
	if ($(this).attr("id") == "add_button") {
		$(new_field).appendTo($("#directions_container"));
	} else {
		$(new_field).appendTo($("#edit_directions_container"));
	}
});

get_hikes();

});<commit_msg>Added deletion confirmation<commit_after>$(document).ready(function() {

$('#add_hike').hide();
$('#edit_hike').hide();

function get_hikes() {
	var url = "inc/call_db.inc.php?view=admin_list";
	$.ajax({
		method: "GET",
		url: url,
		dataType: 'json'
	}).done(function(data) {
		for (var i=0; i < data.rows.length; i++) {
			var lat = data.rows[i].key.lat;
			var lng = data.rows[i].key.lng;
			var hike_id = data.rows[i].id;
			var rev = data.rows[i].value.rev;

			var output = "
";
			output += "
" + data.rows[i].value.name + "
";
			output += "
 Area:
" + data.rows[i].value.area;
			output += "
 Date:
" + data.rows[i].value.date;
			output += "<button class=\"edit\">Edit</button>";
			output += "<button class=\"delete\">Delete</button>";
			output += "
";
			$('#hike_list').append(output);
			add_handlers(lat, lng, hike_id, rev);
		} //end for

		function add_handlers(lat, lng, hike_id, rev) {
			var edit_button = $('#hike_list section:last-of-type .edit');
			var delete_button = $('#hike_list section:last-of-type .delete');

			$(edit_button).click(function() {
				$('#edit_hike').show();
				edit_hike(lat, lng, hike_id);
			});

			$(delete_button).click(function() {
				var delete_ok = confirm("Are you sure you want to delete this hike?");
				if (delete_ok == true) {
					delete_hike(hike_id, rev);
				}
			});
		}
	})
}

function delete_hike(hike_id, rev) {
	var url = "inc/delete_hike.inc.php";

	$.ajax({
		method: "POST",
		url: url,
		data: {id: hike_id, rev: rev}
	}).done(function(data){
		console.log(data);
	});
}

function edit_hike(lat, lng, hike_id) {
	var url = "inc/call_db.inc.php?view=full_hike_info&lat=" + lat + "&lng=" + lng;
	$.ajax({
		method: "GET",
		url: url,
		dataType: 'json'
	}).done(function(data) {
		var hike_id = data.rows[0].id;
		var rev = data.rows[0].value.rev;
		// Populate Fields
		$('#edit_hike #edit_hike_name').val(data.rows[0].value.name);
		$('#edit_hike #edit_area').val(data.rows[0].value.area);
		$('#edit_hike #edit_type').val(data.rows[0].value.type);
		$('#edit_hike #edit_date').val(data.rows[0].value.date);
		$('#edit_hike #edit_description').val(data.rows[0].value.description);
		$('#edit_hike #edit_distance').val(data.rows[0].value.distance);
		$('#edit_hike #edit_elevation_gain').val(data.rows[0].value.elevation_gain);
		$('#edit_hike #edit_lat').val(data.rows[0].key.lat);
		$('#edit_hike #edit_lng').val(data.rows[0].key.lng);

		if(data.rows[0].value.directions.length > 1) {
			$('#edit_hike #edit_directions').val(data.rows[0].value.directions[0]);
			for (var i=1; i < data.rows[0].value.directions.length; i++) {
				var new_field = "<input type=\"text\" name=\"directions[]\">";
				$(new_field).appendTo($("#edit_directions_container"));
				$('#edit_directions_container input:last-of-type').val(data.rows[0].value.directions[i]);
			}
		} else {
			$('#edit_hike #edit_directions').val(data.rows[0].value.directions[0]);
		}

		if(data.rows[0].value.hasOwnProperty("attachments")) {
			for (var j=0; j < data.rows[0].value.attachments.length; j++) {
				var output = "";
				$('#image_container').append(output);
			} //end for
		}

		$('#edit_hike_form').submit(function(event) {
			event.preventDefault();
			submit_form("edit", hike_id, rev);
		});
	});
}

function submit_form(action, hike_id, rev) {
	switch(action) {
		case "edit":
			var form_contents = $("#edit_hike_form").serializeArray();
			var image_upload = document.getElementById('edit_image_upload');
			var url = "inc/submit_form.inc.php?action=edit&id=" + hike_id + "&rev=" + rev;

			var files = image_upload.files;

			var formData = new FormData();

			for (var i = 0; i < files.length; i++) {
				var file = files[i];

				if (!file.type.match('image.*')) {
					continue;
				}

				formData.append('image_upload', file, file.name);
			}

			for (var j=0; j < form_contents.length; j++) {
				formData.append(form_contents[j].name, form_contents[j].value);
			}

			formData.append('action', action);
			formData.append('hike_id', hike_id);
			formData.append('rev', rev);
		break;

		case "add":
			var form_contents = $('#add_hike_form').serializeArray();
			var image_upload = document.getElementById('image_upload');
			var url = "inc/submit_form.inc.php";

			var files = image_upload.files;

			var formData = new FormData();

			for (var i = 0; i < files.length; i++) {
				//Note: http://blog.teamtreehouse.com/uploading-files-ajax
				var file = files[i];

				// Check the file type.
				if (!file.type.match('image.*')) {
				    continue;
				}

				// Add the file to the request.
				formData.append('image_upload', file, file.name);
			}

			for (var j=0; j < form_contents.length; j++) {
				formData.append(form_contents[j].name, form_contents[j].value);
			}
		break;
	}

	var xhr = new XMLHttpRequest();

	xhr.open('POST', url, true);

	xhr.send(formData);
}

$('#add_hike_button').click(function() {
	$('#add_hike').show();
})

$('#add_hike_form').submit(function() {
	event.preventDefault();
	submit_form();
});

$(':file').change(function() {
	var file = this.files[0];
	name = file.name;
	size = file.size;
	type = file.type;

	if(file.name.length < 1) {

	}
	else if(file.size > 10000000) {
		alert("File is too big");
	}
	else if(file.type != 'image/jpg') {
		// alert("Invalid file type");
	}
});

$('#add_button, #edit_add_button').click(function() {
	event.preventDefault();
	var new_field = "<input type=\"text\" name=\"directions[]\">";
	if ($(this).attr("id") == "add_button") {
		$(new_field).appendTo($("#directions_container"));
	} else {
		$(new_field).appendTo($("#edit_directions_container"));
	}
});

get_hikes();

});<|endoftext|>


<commit_before>'use strict';

/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

import $C from '../deps/collection';
import esprima from '../deps/esprima';

import Snakeskin from '../core';
import { nmeRgxp, nmsRgxp, nmssRgxp } from '../parser/name';

import { ws, r } from '../helpers/string';
import { applyDefEscape, escapeDoubleQuotes } from '../helpers/escape';
import { concatProp } from '../helpers/literals';
import { getRgxp } from '../helpers/cache';

import { symbols } from '../consts/regs';
import { G_MOD } from '../consts/literals';
import {

	$write,
	$scope,
	$templates,
	$cache,
	$args,
	$argsRes,
	$output,
	$extList,
	$extMap

} from '../consts/cache';

$C(['template', 'interface', 'placeholder']).forEach((dir) => {
	Snakeskin.addDirective(
		dir,

		{
			block: true,
			deferInit: true,
			group: [dir, 'template', 'rootTemplate', 'define'],
			notEmpty: true,
			placement: 'global'
		},

		function (command, commandLength, type, raw, jsDoc) {
			const
				nms = this.namespace;

			if (!nms) {
				return this.error(`the directive "${this.name}" can't be declared without namespace`);
			}

			if (this.namespaces[nms].id !== this.environment.id) {
				return this.error(
					`the namespace "${nms}" already used for templates in another file (${this.namespaces[nms].file})`
				);
			}

			const rank = {
				'interface': 1,
				'placeholder': 0,
				'template': 2
			};

			this.startDir(
				this.renderAs && rank[this.renderAs] < rank[type] ?
					this.renderAs : null
			);

			const
				iface = this.name === 'interface';

			this.startTemplateI = this.i + 1;
			this.startTemplateLine = this.info.line;

			const
				nameRgxp = getRgxp(`^[^${symbols}_$[]`, 'i'),
				esprimaNameHackRgxp = getRgxp(`[${r(G_MOD)}]`, 'g');

			let tplName = this.replaceFileNamePatterns(this.getFnName(command));
			tplName = nms + concatProp(tplName);

			const setTplName = () => {
				this.info.template = this.tplName = tplName;
				$write[tplName] = this.name === 'template';
			};

			let
				prfx = '',
				pos;

			if (/\*/.test(tplName)) {
				prfx = '*';
				tplName = tplName.replace(prfx, '');
				this.generator = true;
			}

			try {
				let
					tmp = this.pasteDangerBlocks(tplName);

				if (!tmp || nameRgxp.test(tmp)) {
					throw false;
				}

				esprima.parse(tmp.replace(esprimaNameHackRgxp, ''));

			} catch (ignore) {
				return this.error(`invalid "${this.name}" name`);
			}

			setTplName();
			const fnArgsKey = this.getFnArgs(command).join().replace(/=(.*?)(?:,|$)/g, '');
			this.save((pos = `/* Snakeskin template: ${tplName}; ${fnArgsKey} */`), {iface, jsDoc});

			if (jsDoc) {
				jsDoc += pos.length;
			}

			const tplNameParts = tplName
				.replace(nmssRgxp, '%')
				.replace(nmsRgxp, '.%')
				.replace(nmeRgxp, '')
				.split('.');

			const
				tplNameLength = tplNameParts.length;

			let shortcut = '';
			[tplName] = tplNameParts;

			if (tplName[0] === '%') {
				try {
					tplName = ws`['${
						applyDefEscape(
							this.returnEvalVal(
								this.out(tplName.slice(1), {unsafe: true})
							)
						)
					}']`;

				} catch (err) {
					return this.error(err.message);
				}

			} else {
				shortcut = tplName;
			}

			let lastName = '';
			for (let i = 1; i < tplNameLength; i++) {
				let el = tplNameParts[i];

				const
					custom = el[0] === '%',
					def = `exports${concatProp(tplName)}`;

				if (custom) {
					el = el.slice(1);
				}

				this.save(
					(pos = ws`
						if (${def} == null) {
							${def} = {};
						}

						${i === 1 && shortcut ? `${this.module === 'native' ? 'export ' : ''}var ${shortcut} = ${def};` : ''}
					`),

					{iface, jsDoc}
				);

				if (jsDoc) {
					jsDoc += pos.length;
				}

				if (custom) {
					try {
						tplName += ws`['${
							applyDefEscape(
								this.returnEvalVal(
									this.out(el, {unsafe: true})
								)
							)
						}']`;

					} catch (err) {
						return this.error(err.message);
					}

					continue;

				} else if (i === tplNameLength - 1) {
					lastName = el;
				}

				tplName += `.${el}`;
			}

			setTplName();
			this.vars[tplName] = {};
			this.blockTable = {};
			this.blockStructure = {
				children: [],
				name: 'root',
				parent: null
			};

			let parentTplName;
			if (/\)\s+extends\s+/.test(command)) {
				try {
					parentTplName = /\)\s+extends\s+(.*?)(?=@=|$)/.exec(command)[1];

					if (parentTplName[0] === '@') {
						parentTplName = parentTplName.slice(1);

					} else {
						parentTplName = nms + concatProp(parentTplName);
					}

					if (!parentTplName || nameRgxp.test(parentTplName)) {
						throw false;
					}

					esprima.parse(parentTplName.replace(esprimaNameHackRgxp, ''));

				} catch (ignore) {
					return this.error(`invalid template name "${this.name}" for inheritance`);
				}

				try {
					parentTplName = this.parentTplName = this.prepareNameDecl(parentTplName);

				} catch (err) {
					return this.error(err.message);
				}

				if ($cache[parentTplName] == null) {
					if (!this.renderAs || this.renderAs === 'template') {
						return this.error(`the specified template "${parentTplName}" for inheritance is not defined`);
					}

					parentTplName = this.parentTplName = undefined;
				}
			}

			const
				decorators = (parentTplName ? $output[parentTplName].decorators : []).concat(this.decorators);

			this.save(ws`
				exports${concatProp(tplName)} =
				 Snakeskin.decorate([${decorators.join()}], function ${prfx}${tplNameLength > 1 ? lastName : shortcut}(`,

				{iface}
			);

			this.decorators = [];
			this.initTemplateCache(tplName);

			if (tplName in $extMap) {
				this.clearScopeCache(tplName);
			}

			const
				scope = $scope['template'],
				parent = scope[parentTplName];

			scope[tplName] = {
				children: {},
				id: this.environment.id,
				parent
			};

			scope[tplName].root = parent ?
				parent.root : scope[tplName];

			if (parent) {
				parent.children[tplName] = scope[tplName];
			}

			$args[tplName] = {};
			$argsRes[tplName] = {};
			$output[tplName] = {decorators};
			$extMap[tplName] = parentTplName;
			delete $extList[tplName];

			const
				baseParams = {},
				flags = command.split('@=').slice(1);

			if (!parentTplName) {
				$C(this.params[this.params.length - 1]).forEach((el, key) => {
					if (key !== 'renderAs' && key[0] !== '@' && el !== undefined) {
						baseParams[key] = el;
					}
				});
			}

			if (parentTplName && !flags.length) {
				flags.push('@skip true');
			}

			$C(flags).forEach((el) => {
				el = el.trim();

				const
					[name] = el.split(' ');

				delete baseParams[name];
				Snakeskin.Directives['__set__'].call(this, el);
			});

			$C(baseParams).forEach((el, key) => {
				Snakeskin.Directives['__set__'].call(this, [key, key === 'filters' ? el[el.length - 1] : el]);
			});

			const
				args = this.prepareArgs(command, 'template', {parentTplName, tplName});

			if (args.scope) {
				this.scope.push(args.scope);
			}

			this.save(`${args.str}) {`, {iface});
			this.save(ws`
				var
					__THIS__ = this;

				var
					callee = exports${concatProp(tplName)},
					self = callee.Blocks = {};

				var
					__RESULT__ = ${this.getResultDecl()},
					__STRING_RESULT__;

				var
					__ATTR_STR__,
					__ATTR_TMP__,
					__ATTR_TYPE__,
					__ATTR_CACHE__,
					__ATTR_CONCAT_MAP__;

				var
					__INLINE_TAGS__ = Snakeskin.inlineTags,
					__INLINE_TAG__;

				var
					$0 = ${this.renderMode === 'dom' ? '__RESULT__[0]' : 'undefined'};

				function getTplResult(opt_clear) {
					var res = ${this.getReturnResultDecl()};

					if (opt_clear) {
						__RESULT__ = ${this.getResultDecl()};
					}

					return res;
				}

				function clearTplResult() {
					__RESULT__ = ${this.getResultDecl()};
				}

				var
					__RETURN__ = false,
					__RETURN_VAL__;

				var
					TPL_NAME = "${escapeDoubleQuotes(tplName)}",
					PARENT_TPL_NAME${parentTplName ? ` = "${escapeDoubleQuotes(parentTplName)}"` : ''};

				${args.defParams}
			`);

			const preDefs = this.preDefs[tplName];
			if ((!$extMap[tplName] || parentTplName) && preDefs) {
				this.source =
					this.source.slice(0, this.i + 1) +
					preDefs.text +
					this.source.slice(this.i + 1);

				delete this.preDefs[tplName];
			}
		},

		function (command, commandLength) {
			const
				tplName = String(this.tplName),
				diff = this.getDiff(commandLength);

			$cache[tplName] = this.source.slice(this.startTemplateI, this.i - diff);
			$templates[tplName] = this.blockTable;

			if (this.parentTplName) {
				this.info.line = this.startTemplateLine;
				this.lines.splice(this.startTemplateLine, this.lines.length);

				this.source =
					this.source.slice(0, this.startTemplateI) +
					this.getTplFullBody(tplName) +
					this.source.slice(this.i - diff);

				this.initTemplateCache(tplName);
				this.startDir(this.structure.name);
				this.i = this.startTemplateI - 1;
				this.parentTplName = undefined;
				this.blockTable = {};
				this.vars[tplName] = {};
				return;
			}

			const
				iface = this.structure.name === 'interface';

			if (iface) {
				this.save('};', {iface});

			} else {
				this.save(ws`
						${this.consts.join('')}
						return ${this.getReturnResultDecl()};
					});

					Snakeskin.cache["${escapeDoubleQuotes(tplName)}"] = exports${concatProp(tplName)};
				`);
			}

			this.save('/* Snakeskin template. */', {iface});
			if (this.params[this.params.length - 1]['@tplName'] === this.tplName) {
				this.popParams();
			}

			this.canWrite = true;
			this.tplName = undefined;
			delete this.info.template;

			if (this.scope.length) {
				this.scope.pop();
			}
		}

	);
});
<commit_msg>:wrench:<commit_after>'use strict';

/*!
 * Snakeskin
 * https://github.com/SnakeskinTpl/Snakeskin
 *
 * Released under the MIT license
 * https://github.com/SnakeskinTpl/Snakeskin/blob/master/LICENSE
 */

import $C from '../deps/collection';
import esprima from '../deps/esprima';

import Snakeskin from '../core';
import { nmeRgxp, nmsRgxp, nmssRgxp } from '../parser/name';

import { ws, r } from '../helpers/string';
import { applyDefEscape, escapeDoubleQuotes } from '../helpers/escape';
import { concatProp } from '../helpers/literals';
import { getRgxp } from '../helpers/cache';

import { symbols } from '../consts/regs';
import { G_MOD } from '../consts/literals';
import {

	$write,
	$scope,
	$templates,
	$cache,
	$args,
	$argsRes,
	$output,
	$extList,
	$extMap

} from '../consts/cache';

$C(['template', 'interface', 'placeholder']).forEach((dir) => {
	Snakeskin.addDirective(
		dir,

		{
			block: true,
			deferInit: true,
			group: [dir, 'template', 'rootTemplate', 'define'],
			notEmpty: true,
			placement: 'global'
		},

		function (command, commandLength, type, raw, jsDoc) {
			const
				nms = this.namespace;

			if (!nms) {
				return this.error(`the directive "${this.name}" can't be declared without namespace`);
			}

			if (this.namespaces[nms].id !== this.environment.id) {
				return this.error(
					`the namespace "${nms}" already used for templates in another file (${this.namespaces[nms].file})`
				);
			}

			const rank = {
				'interface': 1,
				'placeholder': 0,
				'template': 2
			};

			this.startDir(
				this.renderAs && rank[this.renderAs] < rank[type] ?
					this.renderAs : null
			);

			const
				iface = this.name === 'interface';

			this.startTemplateI = this.i + 1;
			this.startTemplateLine = this.info.line;

			const
				nameRgxp = getRgxp(`^[^${symbols}_$[]`, 'i'),
				esprimaNameHackRgxp = getRgxp(`[${r(G_MOD)}]`, 'g');

			let tplName = this.replaceFileNamePatterns(this.getFnName(command));
			tplName = nms + concatProp(tplName);

			const setTplName = () => {
				this.info.template = this.tplName = tplName;
				$write[tplName] = this.name === 'template';
			};

			let
				prfx = '',
				pos;

			if (/\*/.test(tplName)) {
				prfx = '*';
				tplName = tplName.replace(prfx, '');
				this.generator = true;
			}

			try {
				let
					tmp = this.pasteDangerBlocks(tplName);

				if (!tmp || nameRgxp.test(tmp)) {
					throw false;
				}

				esprima.parse(tmp.replace(esprimaNameHackRgxp, ''));

			} catch (ignore) {
				return this.error(`invalid "${this.name}" name`);
			}

			setTplName();
			const fnArgsKey = this.getFnArgs(command).join().replace(/=(.*?)(?:,|$)/g, '');
			this.save((pos = `/* Snakeskin template: ${tplName}; ${fnArgsKey} */`), {iface, jsDoc});

			if (jsDoc) {
				jsDoc += pos.length;
			}

			const tplNameParts = tplName
				.replace(nmssRgxp, '%')
				.replace(nmsRgxp, '.%')
				.replace(nmeRgxp, '')
				.split('.');

			const
				tplNameLength = tplNameParts.length;

			let shortcut = '';
			[tplName] = tplNameParts;

			if (tplName[0] === '%') {
				try {
					tplName = ws`['${
						applyDefEscape(
							this.returnEvalVal(
								this.out(tplName.slice(1), {unsafe: true})
							)
						)
					}']`;

				} catch (err) {
					return this.error(err.message);
				}

			} else {
				shortcut = tplName;
			}

			let lastName = '';
			for (let i = 1; i < tplNameLength; i++) {
				let el = tplNameParts[i];

				const
					custom = el[0] === '%',
					def = `exports${concatProp(tplName)}`;

				if (custom) {
					el = el.slice(1);
				}

				this.save(
					(pos = ws`
						if (${def} == null) {
							${def} = {};
						}

						${i === 1 && shortcut ? `${this.module === 'native' ? 'export ' : ''}var ${shortcut} = ${def};` : ''}
					`),

					{iface, jsDoc}
				);

				if (jsDoc) {
					jsDoc += pos.length;
				}

				if (custom) {
					try {
						tplName += ws`['${
							applyDefEscape(
								this.returnEvalVal(
									this.out(el, {unsafe: true})
								)
							)
						}']`;

					} catch (err) {
						return this.error(err.message);
					}

					continue;

				} else if (i === tplNameLength - 1) {
					lastName = el;
				}

				tplName += `.${el}`;
			}

			setTplName();
			this.vars[tplName] = {};
			this.blockTable = {};
			this.blockStructure = {
				children: [],
				name: 'root',
				parent: null
			};

			let parentTplName;
			if (/\)\s+extends\s+/.test(command)) {
				try {
					parentTplName = /\)\s+extends\s+(.*?)(?=@=|$)/.exec(command)[1];

					if (!parentTplName || nameRgxp.test(parentTplName)) {
						throw false;
					}

					esprima.parse(parentTplName.replace(esprimaNameHackRgxp, ''));

				} catch (ignore) {
					return this.error(`invalid template name "${this.name}" for inheritance`);
				}

				try {
					parentTplName = this.parentTplName = this.prepareNameDecl(parentTplName);

				} catch (err) {
					return this.error(err.message);
				}

				if ($cache[parentTplName] == null) {
					if (!this.renderAs || this.renderAs === 'template') {
						return this.error(`the specified template "${parentTplName}" for inheritance is not defined`);
					}

					parentTplName = this.parentTplName = undefined;
				}
			}

			const
				decorators = (parentTplName ? $output[parentTplName].decorators : []).concat(this.decorators);

			this.save(ws`
				exports${concatProp(tplName)} =
				 Snakeskin.decorate([${decorators.join()}], function ${prfx}${tplNameLength > 1 ? lastName : shortcut}(`,

				{iface}
			);

			this.decorators = [];
			this.initTemplateCache(tplName);

			if (tplName in $extMap) {
				this.clearScopeCache(tplName);
			}

			const
				scope = $scope['template'],
				parent = scope[parentTplName];

			scope[tplName] = {
				children: {},
				id: this.environment.id,
				parent
			};

			scope[tplName].root = parent ?
				parent.root : scope[tplName];

			if (parent) {
				parent.children[tplName] = scope[tplName];
			}

			$args[tplName] = {};
			$argsRes[tplName] = {};
			$output[tplName] = {decorators};
			$extMap[tplName] = parentTplName;
			delete $extList[tplName];

			const
				baseParams = {},
				flags = command.split('@=').slice(1);

			if (!parentTplName) {
				$C(this.params[this.params.length - 1]).forEach((el, key) => {
					if (key !== 'renderAs' && key[0] !== '@' && el !== undefined) {
						baseParams[key] = el;
					}
				});
			}

			if (parentTplName && !flags.length) {
				flags.push('@skip true');
			}

			$C(flags).forEach((el) => {
				el = el.trim();

				const
					[name] = el.split(' ');

				delete baseParams[name];
				Snakeskin.Directives['__set__'].call(this, el);
			});

			$C(baseParams).forEach((el, key) => {
				Snakeskin.Directives['__set__'].call(this, [key, key === 'filters' ? el[el.length - 1] : el]);
			});

			const
				args = this.prepareArgs(command, 'template', {parentTplName, tplName});

			if (args.scope) {
				this.scope.push(args.scope);
			}

			this.save(`${args.str}) {`, {iface});
			this.save(ws`
				var
					__THIS__ = this;

				var
					callee = exports${concatProp(tplName)},
					self = callee.Blocks = {};

				var
					__RESULT__ = ${this.getResultDecl()},
					__STRING_RESULT__;

				var
					__ATTR_STR__,
					__ATTR_TMP__,
					__ATTR_TYPE__,
					__ATTR_CACHE__,
					__ATTR_CONCAT_MAP__;

				var
					__INLINE_TAGS__ = Snakeskin.inlineTags,
					__INLINE_TAG__;

				var
					$0 = ${this.renderMode === 'dom' ? '__RESULT__[0]' : 'undefined'};

				function getTplResult(opt_clear) {
					var res = ${this.getReturnResultDecl()};

					if (opt_clear) {
						__RESULT__ = ${this.getResultDecl()};
					}

					return res;
				}

				function clearTplResult() {
					__RESULT__ = ${this.getResultDecl()};
				}

				var
					__RETURN__ = false,
					__RETURN_VAL__;

				var
					TPL_NAME = "${escapeDoubleQuotes(tplName)}",
					PARENT_TPL_NAME${parentTplName ? ` = "${escapeDoubleQuotes(parentTplName)}"` : ''};

				${args.defParams}
			`);

			const preDefs = this.preDefs[tplName];
			if ((!$extMap[tplName] || parentTplName) && preDefs) {
				this.source =
					this.source.slice(0, this.i + 1) +
					preDefs.text +
					this.source.slice(this.i + 1);

				delete this.preDefs[tplName];
			}
		},

		function (command, commandLength) {
			const
				tplName = String(this.tplName),
				diff = this.getDiff(commandLength);

			$cache[tplName] = this.source.slice(this.startTemplateI, this.i - diff);
			$templates[tplName] = this.blockTable;

			if (this.parentTplName) {
				this.info.line = this.startTemplateLine;
				this.lines.splice(this.startTemplateLine, this.lines.length);

				this.source =
					this.source.slice(0, this.startTemplateI) +
					this.getTplFullBody(tplName) +
					this.source.slice(this.i - diff);

				this.initTemplateCache(tplName);
				this.startDir(this.structure.name);
				this.i = this.startTemplateI - 1;
				this.parentTplName = undefined;
				this.blockTable = {};
				this.vars[tplName] = {};
				return;
			}

			const
				iface = this.structure.name === 'interface';

			if (iface) {
				this.save('};', {iface});

			} else {
				this.save(ws`
						${this.consts.join('')}
						return ${this.getReturnResultDecl()};
					});

					Snakeskin.cache["${escapeDoubleQuotes(tplName)}"] = exports${concatProp(tplName)};
				`);
			}

			this.save('/* Snakeskin template. */', {iface});
			if (this.params[this.params.length - 1]['@tplName'] === this.tplName) {
				this.popParams();
			}

			this.canWrite = true;
			this.tplName = undefined;
			delete this.info.template;

			if (this.scope.length) {
				this.scope.pop();
			}
		}

	);
});
<|endoftext|>


<commit_before>$(function() {
    function dataFromEl(el) {
        var data = {};
        var eventID = $(el).data('event');
        var groupID = $(el).data('group');
        if (eventID) { data.event = eventID; }
        if (groupID) { data.group = groupID; }
        return data;
    }
    var csrftoken = $.cookie('csrftoken');
    $('.js-upcoming-events').on('click', '.js-add-to-collection', function(ev) {
        var data = dataFromEl(ev.target.parentNode);
        $.ajax({
            type: 'POST',
            url: document.collectionConfig.saveItemDefault,
            data: JSON.stringify(data),
            headers: {
                "X-CSRFToken": csrftoken,
            },
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function(response) {
                // Hide the
                $(ev.target.parentNode).addClass('hidden');
                $('.js-your-events').append(
                    document.collectionConfig.yourTalkTemplate({event: response.item})
                );
            },
            error: function(err) {
                console.log(err);
            },
        });
    });
    $('.js-your-talks').on('click', '.js-remove-from-collection', function(ev) {
        var data = dataFromEl(ev.target.parentNode);
        $.ajax({
            type: 'POST',
            url: document.collectionConfig.removeItemDefault,
            data: JSON.stringify(data),
            headers: {
                "X-CSRFToken": csrftoken,
            },
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function(response) {
                // Remove the

                $(ev.target.parentNode.parentNode).remove();
                if (response.id) {
                    $('.js-upcoming-events [data-event="'+response.id+'"].hidden').removeClass('hidden');
                    $('.js-upcoming-events [data-group="'+response.id+'"].hidden').removeClass('hidden');
                }
            },
            error: function(err) {
                console.log(err);
            },
        });
    });
});
<commit_msg>Added case statements to handle Event/EventGroup<commit_after>$(function() {
    function dataFromEl(el) {
        var data = {};
        var eventID = $(el).data('event');
        var groupID = $(el).data('group');
        if (eventID) { data.event = eventID; }
        if (groupID) { data.group = groupID; }
        return data;
    }
    var csrftoken = $.cookie('csrftoken');
    $('.js-upcoming-events').on('click', '.js-add-to-collection', function(ev) {
        var data = dataFromEl(ev.target.parentNode);
        $.ajax({
            type: 'POST',
            url: document.collectionConfig.saveItemDefault,
            data: JSON.stringify(data),
            headers: {
                "X-CSRFToken": csrftoken,
            },
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function(response) {
                // Hide the
                $(ev.target.parentNode).addClass('hidden');
                switch (response.item.class_name) {
                    case 'Event':
                        $('.js-your-talks').append(
                            document.collectionConfig.yourTalkTemplate({event: response.item})
                        );
                        break;
                    case 'EventGroup':
                        $('.js-your-groups').append(
                            document.collectionConfig.yourGroupTemplate({group: response.item})
                        );
                        break;
                }
            },
            error: function(err) {
                console.log(err);
            },
        });
    });
    $('.js-your-collection').on('click', '.js-remove-from-collection', function(ev) {
        var data = dataFromEl(ev.target.parentNode);
        $.ajax({
            type: 'POST',
            url: document.collectionConfig.removeItemDefault,
            data: JSON.stringify(data),
            headers: {
                "X-CSRFToken": csrftoken,
            },
            contentType: "application/json; charset=utf-8",
            dataType: 'json',
            success: function(response) {
                // Remove the

                $(ev.target.parentNode.parentNode).remove();
                switch (response.class_name) {
                    case 'Event':
                        $('.js-upcoming-events [data-event="'+response.id+'"].hidden').removeClass('hidden');
                        break;
                    case 'EventGroup':
                        $('.js-upcoming-events [data-group="'+response.id+'"].hidden').removeClass('hidden');
                        break;
                }
            },
            error: function(err) {
                console.log(err);
            },
        });
    });
});
<|endoftext|>


<commit_before>var assert = require('proclaim');
var config = require('../helpers/client-config');
var Keen = require('../../../lib/browser');

describe('Auto Tracking', function() {

  beforeEach(function() {
    this.client = new Keen({
      projectId: config.projectId,
      writeKey: config.writeKey,
      requestType: 'xhr',
      host: config.host,
      protocol: config.protocol
    });
  });

  it('should capture "pageviews," "clicks," and "form submits"', function(done){
    var aNode = document.createElement('A');
    var bNode = document.createElement('BUTTON');
    var fNode = document.createElement('FORM');
    var iNode = document.createElement('INPUT');
    var pNode = document.createElement('INPUT');
    var inc = 0;

    this.client.on('recordEvent', function(stream, payload){
      if (stream === 'pageviews') {
        assert.equal(stream, 'pageviews');
        inc++;
      }
      else if (stream === 'clicks') {
        assert.equal(stream, 'clicks');
        assert.equal(payload.element.id, 'test-auto-tracker-clicks');
        assert.equal(payload.element.node_name, 'A');
        aNode.outerHTML = '';
        inc++;
      }
      else if (stream === 'form_submissions') {
        assert.equal(stream, 'form_submissions');
        assert.equal(payload.element.id, 'test-auto-tracker-submits');
        assert.equal(payload.element.node_name, 'FORM');
        assert.equal(payload.form.fields.email, 'team@keen.io');
        assert.notOk(payload.form.fields.password);
        fNode.outerHTML = '';
        inc++;
      }
      if (inc === 3) {
        done();
      }
    });
    this.client.initAutoTracking();

    /*
      Anchor Tag Listener
    */
    aNode.id = 'test-auto-tracker-clicks';
    aNode.href = 'javascript:void(0);';
    aNode.onclick = function(e){
      e.preventDefault();
      return false;
    };
    document.body.appendChild(aNode);

    /*
      Form Listener
    */
    fNode.id = 'test-auto-tracker-submits';
    fNode.action = 'javascript:void(0);';
    fNode.onsubmit = function(e) {
      e.preventDefault();
      return false;
    };
    // fNode.style.display = 'none';

    iNode.type = 'text';
    iNode.name = 'email';
    iNode.value = 'team@keen.io';

    pNode.type = 'password';
    pNode.name = 'password';
    pNode.value = '**********';

    bNode.type = 'submit';
    fNode.appendChild(iNode);
    fNode.appendChild(pNode);
    fNode.appendChild(bNode);
    document.body.appendChild(fNode);

    /*
      Init Behavior
    */
    if (aNode.click) {
      aNode.click();
      bNode.click();
    }
    else if(document.createEvent) {
      ev = document.createEvent('MouseEvent');
      ev.initMouseEvent(click,
          true /* bubble */, true /* cancelable */,
          window, null,
          0, 0, 0, 0,
          false, false, false, false,
          0, null
      );
      aNode.dispatchEvent(ev);
      bNode.dispatchEvent(ev);
    }
  });

});
<commit_msg>Fix var error in test<commit_after>var assert = require('proclaim');
var config = require('../helpers/client-config');
var Keen = require('../../../lib/browser');

describe('Auto Tracking', function() {

  beforeEach(function() {
    this.client = new Keen({
      projectId: config.projectId,
      writeKey: config.writeKey,
      requestType: 'xhr',
      host: config.host,
      protocol: config.protocol
    });
  });

  it('should capture "pageviews," "clicks," and "form submits"', function(done){
    var aNode = document.createElement('A');
    var bNode = document.createElement('BUTTON');
    var fNode = document.createElement('FORM');
    var iNode = document.createElement('INPUT');
    var pNode = document.createElement('INPUT');
    var inc = 0;

    this.client.on('recordEvent', function(stream, payload){
      if (stream === 'pageviews') {
        assert.equal(stream, 'pageviews');
        inc++;
      }
      else if (stream === 'clicks') {
        assert.equal(stream, 'clicks');
        assert.equal(payload.element.id, 'test-auto-tracker-clicks');
        assert.equal(payload.element.node_name, 'A');
        aNode.outerHTML = '';
        inc++;
      }
      else if (stream === 'form_submissions') {
        assert.equal(stream, 'form_submissions');
        assert.equal(payload.element.id, 'test-auto-tracker-submits');
        assert.equal(payload.element.node_name, 'FORM');
        assert.equal(payload.form.fields.email, 'team@keen.io');
        assert.notOk(payload.form.fields.password);
        fNode.outerHTML = '';
        inc++;
      }
      if (inc === 3) {
        done();
      }
    });
    this.client.initAutoTracking();

    /*
      Anchor Tag Listener
    */
    aNode.id = 'test-auto-tracker-clicks';
    aNode.href = 'javascript:void(0);';
    aNode.onclick = function(e){
      e.preventDefault();
      return false;
    };
    document.body.appendChild(aNode);

    /*
      Form Listener
    */
    fNode.id = 'test-auto-tracker-submits';
    fNode.action = 'javascript:void(0);';
    fNode.onsubmit = function(e) {
      e.preventDefault();
      return false;
    };
    // fNode.style.display = 'none';

    iNode.type = 'text';
    iNode.name = 'email';
    iNode.value = 'team@keen.io';

    pNode.type = 'password';
    pNode.name = 'password';
    pNode.value = '**********';

    bNode.type = 'submit';
    fNode.appendChild(iNode);
    fNode.appendChild(pNode);
    fNode.appendChild(bNode);
    document.body.appendChild(fNode);

    /*
      Init Behavior
    */
    if (aNode.click) {
      aNode.click();
      bNode.click();
    }
    else if(document.createEvent) {
      ev = document.createEvent('MouseEvent');
      ev.initMouseEvent('click',
          true /* bubble */, true /* cancelable */,
          window, null,
          0, 0, 0, 0,
          false, false, false, false,
          0, null
      );
      aNode.dispatchEvent(ev);
      bNode.dispatchEvent(ev);
    }
  });

});
<|endoftext|>


<commit_before>'use strict';

var mongoose = require('mongoose'),
    url = require('url'),
    Car = mongoose.model('Car'),
    User = mongoose.model('User'),
    constants = require('../common/constants'),
    dateExt = require('../common/date-time-extensions');

module.exports = function (carData) {
    return {
        getCarById: function (req, res, next) {
            if (!constants.objectIdPattern.test(req.params.id)) {
                res.status(400)
                    .json({
                        message: 'This is not an Id'
                    });
                return;
            }
            carData.details(req.params.id)
                .then(function (car) {
                    res.json(car);
                }, function (error) {
                    console.log(error);
                    res.status(error.status)
                        .json({message: error.message});
                });
        },
        getAllCars: function (req, res, next) {
            carData.all(req.query.skip, req.query.take, req.query.sort, req.query.by)
                .then(function (cars) {
                    res.json(cars);
                }, function (error) {
                    res.status(error.status)
                        .json({message: error.message});
                });
        },
        // TODO: Decide if we need this.
        //getAllCarModels: function (req, res, next) {
        //    console.log(req.query);
        //    carData.all(req.query.skip, req.query.take, req.query.sort, req.query.by)
        //        .then(function (cars) {
        //            var carModels = [];
        //            for (let i = 0; i < cars.count; i += 1) {
        //                carModels.push(cars[i].model);
        //            }
        //
        //            res.json(carModels);
        //        }, function (error) {
        //            res.status(error.status)
        //                .json({message: error.message});
        //        })
        //},
        buyCar: function (req, res, next) {
            var currUserId = req.user._id;
            if (!constants.objectIdPattern.test(req.params.id)) {
                res.status(400)
                    .json({
                        message: 'This is not an Id'
                    });
                return;
            }
            carData.details(req.params.id)
                .then(function (car) {
                    User.findById(currUserId)
                        .exec(function (err, user) {
                            if(err) throw err;
                            console.log(user.cars);
                            console.log(car);
                            user.cars.push(car);
                            user.save();
                        });

                    res.json(car);
                }, function (error) {
                    console.log(error);
                    res.status(error.status)
                        .json({message: error.message});
                });
        },
        addCar: function (req, res, next) {
            var car = req.body;
            var user = req.user;

            if (!req.body) {
                res.status(400)
                    .json({
                        message: 'data was not provided!'
                    });
                return;
            }

            if (user.role !== User.getRoles()[2]) {
                res.status(400)
                    .json({
                        message: 'Not authorised!'
                    });
                return;
            }

            //car.wheelsLevel = 1;
            //car.engineLevel = 1;
            //car.turbo = 1;
            //car.damage = 0;
            car.dateCreated = dateExt.getUTCDate(new Date());
            //car.price = 1;
            //car.levelRequired = 1;

            carData.save(car).then(function (readyCar) {
                res.status(201)
                    .json({
                        carId: readyCar._id
                    });
            }, function (error) {
                res.status(error.status || 500)
                    .json({
                        message: error.message
                    });
            });
        },
        removeCar: function (req, res, next) {
            if (!constants.objectIdPattern.test(req.params.id)) {
                res.status(400)
                    .json({
                        message: 'This is not an Id'
                    });
                return;
            }

            // authenticated User
            var user = req.user;
            var id = req.body.id;

            if (user.role !== User.getRoles()[2]) {
                res.status(401)
                    .json({
                        message: 'permissions required!'
                    });
                return;
            }

            carData.remove(id)
                .then(function (data) {
                    res.json(data);
                }, function (err) {
                    res.status(err.status)
                        .json({
                            message: err.message
                        });
                });
        }
    }
};<commit_msg>Removed console.log<commit_after>'use strict';

var mongoose = require('mongoose'),
    url = require('url'),
    Car = mongoose.model('Car'),
    User = mongoose.model('User'),
    constants = require('../common/constants'),
    dateExt = require('../common/date-time-extensions');

module.exports = function (carData) {
    return {
        getCarById: function (req, res, next) {
            if (!constants.objectIdPattern.test(req.params.id)) {
                res.status(400)
                    .json({
                        message: 'This is not an Id'
                    });
                return;
            }
            carData.details(req.params.id)
                .then(function (car) {
                    res.json(car);
                }, function (error) {
                    console.log(error);
                    res.status(error.status)
                        .json({message: error.message});
                });
        },
        getAllCars: function (req, res, next) {
            carData.all(req.query.skip, req.query.take, req.query.sort, req.query.by)
                .then(function (cars) {
                    res.json(cars);
                }, function (error) {
                    res.status(error.status)
                        .json({message: error.message});
                });
        },
        // TODO: Decide if we need this.
        //getAllCarModels: function (req, res, next) {
        //    console.log(req.query);
        //    carData.all(req.query.skip, req.query.take, req.query.sort, req.query.by)
        //        .then(function (cars) {
        //            var carModels = [];
        //            for (let i = 0; i < cars.count; i += 1) {
        //                carModels.push(cars[i].model);
        //            }
        //
        //            res.json(carModels);
        //        }, function (error) {
        //            res.status(error.status)
        //                .json({message: error.message});
        //        })
        //},
        buyCar: function (req, res, next) {
            var currUserId = req.user._id;
            if (!constants.objectIdPattern.test(req.params.id)) {
                res.status(400)
                    .json({
                        message: 'This is not an Id'
                    });
                return;
            }
            carData.details(req.params.id)
                .then(function (car) {
                    User.findById(currUserId)
                        .exec(function (err, user) {
                            if(err) throw err;

                            user.cars.push(car);
                            user.save();
                        });

                    res.json(car);
                }, function (error) {
                    console.log(error);
                    res.status(error.status)
                        .json({message: error.message});
                });
        },
        addCar: function (req, res, next) {
            var car = req.body;
            var user = req.user;

            if (!req.body) {
                res.status(400)
                    .json({
                        message: 'data was not provided!'
                    });
                return;
            }

            if (user.role !== User.getRoles()[2]) {
                res.status(400)
                    .json({
                        message: 'Not authorised!'
                    });
                return;
            }

            //car.wheelsLevel = 1;
            //car.engineLevel = 1;
            //car.turbo = 1;
            //car.damage = 0;
            car.dateCreated = dateExt.getUTCDate(new Date());
            //car.price = 1;
            //car.levelRequired = 1;

            carData.save(car).then(function (readyCar) {
                res.status(201)
                    .json({
                        carId: readyCar._id
                    });
            }, function (error) {
                res.status(error.status || 500)
                    .json({
                        message: error.message
                    });
            });
        },
        removeCar: function (req, res, next) {
            if (!constants.objectIdPattern.test(req.params.id)) {
                res.status(400)
                    .json({
                        message: 'This is not an Id'
                    });
                return;
            }

            // authenticated User
            var user = req.user;
            var id = req.body.id;

            if (user.role !== User.getRoles()[2]) {
                res.status(401)
                    .json({
                        message: 'permissions required!'
                    });
                return;
            }

            carData.remove(id)
                .then(function (data) {
                    res.json(data);
                }, function (err) {
                    res.status(err.status)
                        .json({
                            message: err.message
                        });
                });
        }
    }
};<|endoftext|>


<commit_before>// This just loads the shell on to the page. The fancy word for this
// is AMD ... but let's not be arrogant here.
//
// Here's some expected copy-pasta:
/*

document.body.innerHTML += '<script src="https://raw.github.com/kristopolous/js-shell/master/injecter.js"></script>';

*/

(function(){
  if(!self._Shell) {
    var script = document.body.createElement("script");
    script.src = "https://raw.github.com/kristopolous/js-shell/master/shell.js";
    document.body.appendChild(script.src);
  }

  var ival = setInterval(function() {
    if(self._Shell) {
      _Shell.init(document.body);
      clearInterval(ival);
    }
  }, 100);
});
<commit_msg>stupid mistake undone<commit_after>// This just loads the shell on to the page. The fancy word for this
// is AMD ... but let's not be arrogant here.
//
// Here's some expected copy-pasta:
/*

document.body.innerHTML += '<script src="https://raw.github.com/kristopolous/js-shell/master/injecter.js"></script>';

*/

(function(){
  if(!self._Shell) {
    var script = document.body.createElement("script");
    script.src = "https://raw.github.com/kristopolous/js-shell/master/shell.js";
    document.body.appendChild(script.src);
  }

  var ival = setInterval(function() {
    if(self._Shell) {
      _Shell.init(document.body);
      clearInterval(ival);
    }
  }, 100);
})();
<|endoftext|>


<commit_before>function editRelated (collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#'+ idField).replaceWith(html);
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function refreshRelated(collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#sortable-'+ idField).replaceWith($(html).find('#sortable-'+ idField));
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function createRelatedTemplate(idField, list) {
  var dataTemplate;
  if (idField === 'article') {
    dataTemplate = {list: list, idField: idField, idPlural: 'articles'};
  } else if (idField === 'bulletin') {
    dataTemplate = {list: list, idField: idField, idPlural: 'bulletins'};
  } else if (idField === 'dataset') {
    dataTemplate = {list: list, idField: idField, idPlural: 'datasets'};
  } else if (idField === 'document') {
    dataTemplate = {list: list, idField: idField, idPlural: 'documents'};
  } else if (idField === 'methodology') {
    dataTemplate = {list: list, idField: idField, idPlural: 'methodologies'};
  } else {
    dataTemplate = {list: list, idField: idField};
  }
  return dataTemplate;
}

function initialiseRelated(collectionId, data, templateData, field, idField) {
  // Load
  if (!data[field] || data[field].length === 0) {
    editRelated['lastIndex' + field] = 0;
  } else {
    $(data[field]).each(function (index, value) {
      editRelated['lastIndex' + field] = index + 1;

      // Delete
      $('#' + idField + '-delete_' + index).click(function () {
        var result = confirm("Are you sure you want to delete this link?");
        if (result === true) {
          var position = $(".workspace-edit").scrollTop();
          Florence.globalVars.pagePos = position;
          $(this).parent().remove();
          data[field].splice(index, 1);
          templateData[field].splice(index, 1);
          postContent(collectionId, data.uri, JSON.stringify(data),
            success = function (response) {
              Florence.Editor.isDirty = false;
              refreshPreview(data.uri);
              refreshRelated(collectionId, data, templateData, field, idField)
            },
            error = function (response) {
              if (response.status === 400) {
                alert("Cannot edit this file. It is already part of another collection.");
              }
              else if (response.status === 401) {
                alert("You are not authorised to update content.");
              }
              else {
                handleApiError(response);
              }
            }
          );
        }
      });
    });
  }

  //Add
  $('#add-' + idField).off().one('click', function () {
    var latestCheck;
    var position = $(".workspace-edit").scrollTop();
    Florence.globalVars.pagePos = position;
    var iframeEvent = document.getElementById('iframe').contentWindow;
    iframeEvent.removeEventListener('click', Florence.Handler, true);
    createWorkspace(data.uri, collectionId, '', true);

    $('#sortable-' + idField).append(
      '
' +
      '  <textarea id="' + idField + '-uri_' + editRelated['lastIndex' + field] + '" placeholder="Go to the related data and click Get"></textarea>' +
      '

' +
      '  <button class="btn-page-get" id="' + idField + '-get_' + editRelated['lastIndex' + field] + '">Get</button>' +
      '  <button class="btn-page-cancel" id="' + idField + '-cancel_' + editRelated['lastIndex' + field] + '">Cancel</button>' +
      '
').trigger('create');

    if (idField === 'article' || idField === 'bulletin' || idField === 'document') {
      $('#latest-container').append('Latest' +
        '<input id="latest" type="checkbox" value="value" checked/>');
    }

    $('#' + idField + '-cancel_' + editRelated['lastIndex' + field]).one('click', function () {
      createWorkspace(data.uri, collectionId, 'edit');
    });

    $('#latest-container input:checkbox').on('change', function () {
      latestCheck = $(this).prop('checked');
    });

    $('#' + idField  + '-get_' + editRelated['lastIndex' + field]).one('click', function () {
      var baseUrl = $('#' + idField + '-uri_'+editRelated['lastIndex' + field]).val();
      if (!baseUrl) {
        baseUrl = getPathNameTrimLast();
      }
      baseUrl = checkPathParsed(baseUrl);
      var dataUrlData = baseUrl + "/data";
      var latestUrl;
      if (latestCheck) {
        var tempUrl = baseUrl.split('/');
        tempUrl.pop();
        tempUrl.push('latest');
        latestUrl = tempUrl.join('/');
      } else {
        latestUrl = baseUrl;
      }

      $.ajax({
        url: dataUrlData,
        dataType: 'json',
        crossDomain: true,
        success: function (result) {
          if ((field === 'relatedBulletins' || field === 'statsBulletins') && result.type === 'bulletin') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedArticles' && result.type === 'article') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDocuments') && (result.type === 'article' || result.type === 'bulletin' || result.type === 'compendium_landing_page')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDatasets' || field === 'datasets') && (result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'items') && (result.type === 'timeseries')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedData') && (result.type === 'timeseries' || result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedMethodology' && result.type === 'static_methodology') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else {
            alert("This is not a valid document");
            return;
          }

          data[field].push({uri: latestUrl});
          saveRelated(collectionId, data.uri, data, field, idField);

        },
        error: function () {
          console.log('No page data returned');
        }
      });
    });
  });

  function sortable() {
    $('#sortable-' + idField).sortable();
  }
  sortable();
}
<commit_msg>Add related check on ready<commit_after>function editRelated (collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#'+ idField).replaceWith(html);
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function refreshRelated(collectionId, data, templateData, field, idField) {
  var list = templateData[field];
  var dataTemplate = createRelatedTemplate(idField, list);
  var html = templates.editorRelated(dataTemplate);
  $('#sortable-'+ idField).replaceWith($(html).find('#sortable-'+ idField));
  initialiseRelated(collectionId, data, templateData, field, idField);
}

function createRelatedTemplate(idField, list) {
  var dataTemplate;
  if (idField === 'article') {
    dataTemplate = {list: list, idField: idField, idPlural: 'articles'};
  } else if (idField === 'bulletin') {
    dataTemplate = {list: list, idField: idField, idPlural: 'bulletins'};
  } else if (idField === 'dataset') {
    dataTemplate = {list: list, idField: idField, idPlural: 'datasets'};
  } else if (idField === 'document') {
    dataTemplate = {list: list, idField: idField, idPlural: 'documents'};
  } else if (idField === 'methodology') {
    dataTemplate = {list: list, idField: idField, idPlural: 'methodologies'};
  } else {
    dataTemplate = {list: list, idField: idField};
  }
  return dataTemplate;
}

function initialiseRelated(collectionId, data, templateData, field, idField) {
  // Load
  if (!data[field] || data[field].length === 0) {
    editRelated['lastIndex' + field] = 0;
  } else {
    $(data[field]).each(function (index, value) {
      editRelated['lastIndex' + field] = index + 1;

      // Delete
      $('#' + idField + '-delete_' + index).click(function () {
        var result = confirm("Are you sure you want to delete this link?");
        if (result === true) {
          var position = $(".workspace-edit").scrollTop();
          Florence.globalVars.pagePos = position;
          $(this).parent().remove();
          data[field].splice(index, 1);
          templateData[field].splice(index, 1);
          postContent(collectionId, data.uri, JSON.stringify(data),
            success = function (response) {
              Florence.Editor.isDirty = false;
              refreshPreview(data.uri);
              refreshRelated(collectionId, data, templateData, field, idField)
            },
            error = function (response) {
              if (response.status === 400) {
                alert("Cannot edit this file. It is already part of another collection.");
              }
              else if (response.status === 401) {
                alert("You are not authorised to update content.");
              }
              else {
                handleApiError(response);
              }
            }
          );
        }
      });
    });
  }

  //Add
  $('#add-' + idField).off().one('click', function () {
    var latestCheck;
    var position = $(".workspace-edit").scrollTop();
    Florence.globalVars.pagePos = position;
    var iframeEvent = document.getElementById('iframe').contentWindow;
    iframeEvent.removeEventListener('click', Florence.Handler, true);
    createWorkspace(data.uri, collectionId, '', true);

    $('#sortable-' + idField).append(
      '
' +
      '  <textarea id="' + idField + '-uri_' + editRelated['lastIndex' + field] + '" placeholder="Go to the related data and click Get"></textarea>' +
      '

' +
      '  <button class="btn-page-get" id="' + idField + '-get_' + editRelated['lastIndex' + field] + '">Get</button>' +
      '  <button class="btn-page-cancel" id="' + idField + '-cancel_' + editRelated['lastIndex' + field] + '">Cancel</button>' +
      '
').trigger('create');

    if (idField === 'article' || idField === 'bulletin' || idField === 'document') {
      $('#latest-container').append('Link to latest' +
        '<input id="latest" type="checkbox" value="value" checked/>');
    }

    $('#' + idField + '-cancel_' + editRelated['lastIndex' + field]).one('click', function () {
      createWorkspace(data.uri, collectionId, 'edit');
    });

    $('#latest-container input:checkbox').on('ready change', function () {
      latestCheck = $(this).prop('checked');
    });

    $('#' + idField  + '-get_' + editRelated['lastIndex' + field]).one('click', function () {
      var baseUrl = $('#' + idField + '-uri_'+editRelated['lastIndex' + field]).val();
      if (!baseUrl) {
        baseUrl = getPathNameTrimLast();
      }
      baseUrl = checkPathParsed(baseUrl);
      var dataUrlData = baseUrl + "/data";
      var latestUrl;
      if (latestCheck) {
        var tempUrl = baseUrl.split('/');
        tempUrl.pop();
        tempUrl.push('latest');
        latestUrl = tempUrl.join('/');
      } else {
        latestUrl = baseUrl;
      }

      $.ajax({
        url: dataUrlData,
        dataType: 'json',
        crossDomain: true,
        success: function (result) {
          if ((field === 'relatedBulletins' || field === 'statsBulletins') && result.type === 'bulletin') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedArticles' && result.type === 'article') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDocuments') && (result.type === 'article' || result.type === 'bulletin' || result.type === 'compendium_landing_page')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedDatasets' || field === 'datasets') && (result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'items') && (result.type === 'timeseries')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if ((field === 'relatedData') && (result.type === 'timeseries' || result.type === 'dataset' || result.type === 'reference_tables')) {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else if (field === 'relatedMethodology' && result.type === 'static_methodology') {
            if (!data[field]) {
              data[field] = [];
            }
          }

          else {
            alert("This is not a valid document");
            return;
          }

          data[field].push({uri: latestUrl});
          saveRelated(collectionId, data.uri, data, field, idField);

        },
        error: function () {
          console.log('No page data returned');
        }
      });
    });
  });

  function sortable() {
    $('#sortable-' + idField).sortable();
  }
  sortable();
}
<|endoftext|>


<commit_before>$("#rg2-load-jgw-file").button().change(function(evt) {
	// read the selected file
	readJGW(evt);
});

function readJGW(evt) {

	var reader = new FileReader();

	reader.readAsText(evt.target.files[0]);

	reader.onerror = function(evt) {
		switch(evt.target.error.code) {
			case evt.target.error.NOT_FOUND_ERR:
				alert('File not found');
				break;
			case evt.target.error.NOT_READABLE_ERR:
				alert('File not readable');
				break;
			default:
				alert('An error occurred reading the file.');
		}
	};

	reader.onload = function(evt) {
		// see http://en.wikipedia.org/wiki/World_file
		// read JGW world file
		var txt = evt.target.result;
		var args = txt.split(/[\r\n]+/g);

		// image file size
		var pxWidth = 1554;
		var pxHeight = 1140;

		var xScale = parseFloat(args[0]);
		var ySkew = parseFloat(args[1]);
		var xSkew = parseFloat(args[2]);
		var yScale = parseFloat(args[3]);

		var xos = [];
		var yos = [];
		var xpx = [];
		var ypx = [];

		// x0, y0 is top left
		xos[0] = parseFloat(args[4]);
		yos[0] = parseFloat(args[5]);
		xpx[0] = 0;
		ypx[0] = 0;

		// x1, y1 is bottom right
		xpx[1] = pxWidth;
		ypx[1] = pxHeight;
		xos[1] = (xScale * xpx[1]) + (xSkew * ypx[1]) + xos[0];
		yos[1] = (yScale * ypx[1]) + (ySkew * xpx[1]) + yos[0];

		// x2, y2 is top right
		xpx[2] = pxWidth;
		ypx[2] = 0;
		xos[2] = (xScale * xpx[2]) + (xSkew * ypx[2]) + xos[0];
		yos[2] = (yScale * ypx[2]) + (ySkew * xpx[2]) + yos[0];

		// x3, y3 is bottom left
		xpx[3] = 0;
		ypx[3] = pxHeight;
		xos[3] = (xScale * xpx[3]) + (xSkew * ypx[3]) + xos[0];
		yos[3] = (yScale * ypx[3]) + (ySkew * xpx[3]) + yos[0];

		// translate OS Grid ref to WGS84 (as in GPS file)
		var o;
		var osgb36 = [];
		var ct = [];
		var WGS84 = [];
		var i;
		for (i = 0; i < 4; i++) {
			o = new OsGridRef(parseInt(xos[i] + 0.5, 10), parseInt(yos[i] + 0.5, 10));
			osgb36[i] = o.osGridToLatLong(o);
			ct[i] = CoordTransform;
			WGS84[i] = ct[i].convertOSGB36toWGS84(osgb36[i]);
		}

		var hypot = getLatLonDistance(WGS84[0]._lat, WGS84[0]._lon, WGS84[2]._lat, WGS84[2]._lon);
		var adj = getLatLonDistance(WGS84[0]._lat, WGS84[0]._lon, WGS84[0]._lat, WGS84[2]._lon);
		var angle1 = Math.acos(adj / hypot);

		var hypot2 = getLatLonDistance(WGS84[2]._lat, WGS84[2]._lon, WGS84[1]._lat, WGS84[1]._lon);
		var adj2 = getLatLonDistance(WGS84[2]._lat, WGS84[2]._lon, WGS84[1]._lat, WGS84[2]._lon);
		var angle2 = Math.acos(adj2 / hypot2);

		var angle = (angle1 + angle2) / 2;

		var pixResX = (WGS84[2]._lon - WGS84[0]._lon) / pxWidth;
		var pixResY = (WGS84[2]._lat - WGS84[1]._lat) / pxHeight;

		var A = pixResX * Math.cos(angle);
		var D = pixResY * Math.sin(angle);
		var B = pixResX * Math.sin(angle);
		var E = -1 * pixResY * Math.cos(angle);
		var C = WGS84[0]._lon;
		var F = WGS84[0]._lat;
    console.log(A, B, C, D, E, F);
		var newx = [];
		var newy = [];

		for ( i = 0; i < 4; i++) {
			newx[i] = Math.round(((E * WGS84[i]._lon) - (B * WGS84[i]._lat) + (B * F) - (E * C)) / ((A * E) - (D * B)));
			console.log("X: " + xpx[i] + " becomes " + WGS84[i]._lon + " becomes " + newx[i]);
			newy[i] = Math.round(((-1 * D * WGS84[i]._lon) + (A * WGS84[i]._lat) + (D * C) - (A * F)) / ((A * E) - (D * B)));
			console.log("Y: " + ypx[i] + " becomes " + WGS84[i]._lat + " becomes " + newy[i]);
		}

		// UK National Grid
		Proj4js.defs["EPSG:27700"] = "+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs ";
		var EPSG27700 = new Proj4js.Proj("EPSG:27700");
		// WGS84
		var EPSG4326 = new Proj4js.Proj("EPSG:4326");
		var p = [];

		for ( i = 0; i < 4; i++) {
			p[i] = new pt(xos[i], yos[i]);
			Proj4js.transform(EPSG27700, EPSG4326, p[i]);
		}

	};

}

function pt(x, y) {
	this.x = x;
	this.y = y;
}

function getLatLonDistance(lat1, lon1, lat2, lon2) {
	// Haversine formula (http://www.codecodex.com/wiki/Calculate_distance_between_two_points_on_a_globe)
	var x = lat2 - lat1;
	var dLat = x.toRad();
	var y = lon2 - lon1;
	var dLon = y.toRad();
	var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos((lat1).toRad()) * Math.cos((lat2.toRad())) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

	// multiply by IUUG earth mean radius (http://en.wikipedia.org/wiki/Earth_radius) in metres
	return 6371009 * c;
}

function getAngle(x1, y1, x2, y2) {
	var angle = Math.atan2((y2 - y1), (x2 - x1));
	if (angle < 0) {
		angle = angle + (2 * Math.PI);
	}
	return angle;
}

function OsGridRef(easting, northing) {
	this.easting = parseInt(easting, 10);
	this.northing = parseInt(northing, 10);
}

OsGridRef.prototype = {

	Constructor : OsGridRef,
	/**
	 * Convert Ordnance Survey grid reference easting/northing coordinate to (OSGB36) latitude/longitude
	 *
	 * @param {OsGridRef} easting/northing to be converted to latitude/longitude
	 * @return {LatLon} latitude/longitude (in OSGB36) of supplied grid reference
	 */
	osGridToLatLong : function(gridref) {
		var E = gridref.easting;
		var N = gridref.northing;

		var a = 6377563.396, b = 6356256.910;
		// Airy 1830 major & minor semi-axes
		var F0 = 0.9996012717;
		// NatGrid scale factor on central meridian
		var lat0 = 49 * Math.PI / 180, lon0 = -2 * Math.PI / 180;
		// NatGrid true origin
		var N0 = -100000, E0 = 400000;
		// northing & easting of true origin, metres
		var e2 = 1 - (b * b) / (a * a);
		// eccentricity squared
		var n = (a - b) / (a + b), n2 = n * n, n3 = n * n * n;

		var lat = lat0, M = 0;
		do {
			lat = (N - N0 - M) / (a * F0) + lat;

			var Ma = (1 + n + (5 / 4) * n2 + (5 / 4) * n3) * (lat - lat0);
			var Mb = (3 * n + 3 * n * n + (21 / 8) * n3) * Math.sin(lat - lat0) * Math.cos(lat + lat0);
			var Mc = ((15 / 8) * n2 + (15 / 8) * n3) * Math.sin(2 * (lat - lat0)) * Math.cos(2 * (lat + lat0));
			var Md = (35 / 24) * n3 * Math.sin(3 * (lat - lat0)) * Math.cos(3 * (lat + lat0));
			M = b * F0 * (Ma - Mb + Mc - Md);
			// meridional arc

		} while (N-N0-M >= 0.00001);// ie until < 0.01mm

		var cosLat = Math.cos(lat), sinLat = Math.sin(lat);
		var nu = a * F0 / Math.sqrt(1 - e2 * sinLat * sinLat);
		// transverse radius of curvature
		var rho = a * F0 * (1 - e2) / Math.pow(1 - e2 * sinLat * sinLat, 1.5);
		// meridional radius of curvature
		var eta2 = nu / rho - 1;

		var tanLat = Math.tan(lat);
		var tan2lat = tanLat * tanLat, tan4lat = tan2lat * tan2lat, tan6lat = tan4lat * tan2lat;
		var secLat = 1 / cosLat;
		var nu3 = nu * nu * nu, nu5 = nu3 * nu * nu, nu7 = nu5 * nu * nu;
		var VII = tanLat / (2 * rho * nu);
		var VIII = tanLat / (24 * rho * nu3) * (5 + 3 * tan2lat + eta2 - 9 * tan2lat * eta2);
		var IX = tanLat / (720 * rho * nu5) * (61 + 90 * tan2lat + 45 * tan4lat);
		var X = secLat / nu;
		var XI = secLat / (6 * nu3) * (nu / rho + 2 * tan2lat);
		var XII = secLat / (120 * nu5) * (5 + 28 * tan2lat + 24 * tan4lat);
		var XIIA = secLat / (5040 * nu7) * (61 + 662 * tan2lat + 1320 * tan4lat + 720 * tan6lat);

		var dE = (E - E0), dE2 = dE * dE, dE3 = dE2 * dE, dE4 = dE2 * dE2, dE5 = dE3 * dE2, dE6 = dE4 * dE2, dE7 = dE5 * dE2;
		lat = lat - VII * dE2 + VIII * dE4 - IX * dE6;
		var lon = lon0 + X * dE - XI * dE3 + XII * dE5 - XIIA * dE7;

		return new LatLon(lat.toDeg(), lon.toDeg());
	}
}

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  Latitude/longitude spherical geodesy formulae & scripts (c) Chris Veness 2002-2012            */
/*   - www.movable-type.co.uk/scripts/latlong.html                                                */
/*                                                                                */
/*  Sample usage:                                                                                */
/*    var p1 = new LatLon(51.5136, -0.0983);                                                      */
/*    var p2 = new LatLon(51.4778, -0.0015);                                                      */
/*    var dist = p1.distanceTo(p2);          // in km                                             */
/*    var brng = p1.bearingTo(p2);           // in degrees clockwise from north                   */
/*    ... etc                                                                                */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
/*  Note that minimal error checking is performed in this example code!                           */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

/**
 * @requires Geo
 */

/**
 * Creates a point on the earth's surface at the supplied latitude / longitude
 *
 * @constructor
 * @param {Number} lat: latitude in numeric degrees
 * @param {Number} lon: longitude in numeric degrees
 * @param {Number} [rad=6371]: radius of earth if different value is required from standard 6,371km
 */
function LatLon(lat, lon, rad) {
	if ( typeof (rad) == 'undefined')
		rad = 6371;
	// earth's mean radius in km
	// only accept numbers or valid numeric strings
	this._lat = typeof (lat) == 'number' ? lat : typeof (lat) == 'string' && lat.trim() != '' ? +lat : NaN;
	this._lon = typeof (lon) == 'number' ? lon : typeof (lon) == 'string' && lon.trim() != '' ? +lon : NaN;
	this._radius = typeof (rad) == 'number' ? rad : typeof (rad) == 'string' && trim(lon) != '' ? +rad : NaN;
}

/**
 * Returns the latitude of this point; signed numeric degrees if no format, otherwise format & dp
 * as per Geo.toLat()
 *
 * @param   {String} [format]: Return value as 'd', 'dm', 'dms'
 * @param   {Number} [dp=0|2|4]: No of decimal places to display
 * @returns {Number|String} Numeric degrees if no format specified, otherwise deg/min/sec
 */
LatLon.prototype.lat = function(format, dp) {
	if ( typeof format == 'undefined')
		return this._lat;

	return Geo.toLat(this._lat, format, dp);
}
/**
 * Returns the longitude of this point; signed numeric degrees if no format, otherwise format & dp
 * as per Geo.toLon()
 *
 * @param   {String} [format]: Return value as 'd', 'dm', 'dms'
 * @param   {Number} [dp=0|2|4]: No of decimal places to display
 * @returns {Number|String} Numeric degrees if no format specified, otherwise deg/min/sec
 */
LatLon.prototype.lon = function(format, dp) {
	if ( typeof format == 'undefined')
		return this._lon;

	return Geo.toLon(this._lon, format, dp);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */

// ---- extend Number object with methods for converting degrees/radians

/** Converts numeric degrees to radians */
if ( typeof Number.prototype.toRad == 'undefined') {
	Number.prototype.toRad = function() {
		return this * Math.PI / 180;
	}
}

/** Converts radians to numeric (signed) degrees */
if ( typeof Number.prototype.toDeg == 'undefined') {
	Number.prototype.toDeg = function() {
		return this * 180 / Math.PI;
	}
}

/**
 * Formats the significant digits of a number, using only fixed-point notation (no exponential)
 *
 * @param   {Number} precision: Number of significant digits to appear in the returned string
 * @returns {String} A string representation of number which contains precision significant digits
 */
if ( typeof Number.prototype.toPrecisionFixed == 'undefined') {
	Number.prototype.toPrecisionFixed = function(precision) {

		// use standard toPrecision method
		var n = this.toPrecision(precision);

		// ... but replace +ve exponential format with trailing zeros
		n = n.replace(/(.+)e\+(.+)/, function(n, sig, exp) {
			sig = sig.replace(/\./, '');
			// remove decimal from significand
			l = sig.length - 1;
			while (exp-- > l)
			sig = sig + '0';
			// append zeros from exponent
			return sig;
		});

		// ... and replace -ve exponential format with leading zeros
		n = n.replace(/(.+)e-(.+)/, function(n, sig, exp) {
			sig = sig.replace(/\./, '');
			// remove decimal from significand
			while (exp-- > 1)
			sig = '0' + sig;
			// prepend zeros from exponent
			return '0.' + sig;
		});

		return n;
	}
}

/** Trims whitespace from string (q.v. blog.stevenlevithan.com/archives/faster-trim-javascript) */
if ( typeof String.prototype.trim == 'undefined') {
	String.prototype.trim = function() {
		return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	}
}

var CoordTransform = {};
// CoordTransform namespace, representing static class

// ellipse parameters
CoordTransform.ellipse = {
	WGS84 : {
		a : 6378137,
		b : 6356752.3142,
		f : 1 / 298.257223563
	},
	GRS80 : {
		a : 6378137,
		b : 6356752.314140,
		f : 1 / 298.257222101
	},
	Airy1830 : {
		a : 6377563.396,
		b : 6356256.910,
		f : 1 / 299.3249646
	},
	AiryModified : {
		a : 6377340.189,
		b : 6356034.448,
		f : 1 / 299.32496
	},
	Intl1924 : {
		a : 6378388.000,
		b : 6356911.946,
		f : 1 / 297.0
	}
};

// helmert transform parameters from WGS84 to other datums
CoordTransform.datumTransform = {
	toOSGB36 : {
		tx : -446.448,
		ty : 125.157,
		tz : -542.060, // m
		rx : -0.1502,
		ry : -0.2470,
		rz : -0.8421, // sec
		s : 20.4894
	}, // ppm
	toED50 : {
		tx : 89.5,
		ty : 93.8,
		tz : 123.1, // m
		rx : 0.0,
		ry : 0.0,
		rz : 0.156, // sec
		s : -1.2
	}, // ppm
	toIrl1975 : {
		tx : -482.530,
		ty : 130.596,
		tz : -564.557, // m
		rx : -1.042,
		ry : -0.214,
		rz : -0.631, // sec
		s : -8.150
	}
};
// ppm
// ED50: og.decc.gov.uk/en/olgs/cms/pons_and_cop/pons/pon4/pon4.aspx
// strictly, Ireland 1975 is from ETRF89: qv
// www.osi.ie/OSI/media/OSI/Content/Publications/transformations_booklet.pdf
// www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/guide6.html#6.5

/**
 * Convert lat/lon point in OSGB36 to WGS84
 *
 * @param  {LatLon} pOSGB36: lat/lon in OSGB36 reference frame
 * @return {LatLon} lat/lon point in WGS84 reference frame
 */
CoordTransform.convertOSGB36toWGS84 = function(pOSGB36) {
	var eAiry1830 = CoordTransform.ellipse.Airy1830;
	var eWGS84 = CoordTransform.ellipse.WGS84;
	var txToOSGB36 = CoordTransform.datumTransform.toOSGB36;
	var txFromOSGB36 = {};
	// negate the 'to' transform to get the 'from'
	for (var param in txToOSGB36)
	txFromOSGB36[param] = -txToOSGB36[param];
	var pWGS84 = CoordTransform.convertEllipsoid(pOSGB36, eAiry1830, txFromOSGB36, eWGS84);
	return pWGS84;
}
/**
 * Convert lat/lon point in WGS84 to OSGB36
 *
 * @param  {LatLon} pWGS84: lat/lon in WGS84 reference frame
 * @return {LatLon} lat/lon point in OSGB36 reference frame
 */
CoordTransform.convertWGS84toOSGB36 = function(pWGS84) {
	var eWGS84 = CoordTransform.ellipse.WGS84;
	var eAiry1830 = CoordTransform.ellipse.Airy1830;
	var txToOSGB36 = CoordTransform.datumTransform.toOSGB36;
	var pOSGB36 = CoordTransform.convertEllipsoid(pWGS84, eWGS84, txToOSGB36, eAiry1830);
	return pOSGB36;
}
/**
 * Convert lat/lon from one ellipsoidal model to another
 *
 * q.v. Ordnance Survey 'A guide to coordinate systems in Great Britain' Section 6
 *      www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf
 *
 * @private
 * @param {LatLon}   point: lat/lon in source reference frame
 * @param {Number[]} e1:    source ellipse parameters
 * @param {Number[]} t:     Helmert transform parameters
 * @param {Number[]} e1:    target ellipse parameters
 * @return {Coord} lat/lon in target reference frame
 */
CoordTransform.convertEllipsoid = function(point, e1, t, e2) {

	// -- 1: convert polar to cartesian coordinates (using ellipse 1)

	var lat = point.lat().toRad();
	var lon = point.lon().toRad();

	var a = e1.a, b = e1.b;

	var sinPhi = Math.sin(lat);
	var cosPhi = Math.cos(lat);
	var sinLambda = Math.sin(lon);
	var cosLambda = Math.cos(lon);
	var H = 24.7;
	// for the moment

	var eSq = (a * a - b * b) / (a * a);
	var nu = a / Math.sqrt(1 - eSq * sinPhi * sinPhi);

	var x1 = (nu + H) * cosPhi * cosLambda;
	var y1 = (nu + H) * cosPhi * sinLambda;
	var z1 = ((1 - eSq) * nu + H) * sinPhi;

	// -- 2: apply helmert transform using appropriate params

	var tx = t.tx, ty = t.ty, tz = t.tz;
	var rx = (t.rx / 3600).toRad();
	// normalise seconds to radians
	var ry = (t.ry / 3600).toRad();
	var rz = (t.rz / 3600).toRad();
	var s1 = t.s / 1e6 + 1;
	// normalise ppm to (s+1)

	// apply transform
	var x2 = tx + x1 * s1 - y1 * rz + z1 * ry;
	var y2 = ty + x1 * rz + y1 * s1 - z1 * rx;
	var z2 = tz - x1 * ry + y1 * rx + z1 * s1;

	// -- 3: convert cartesian to polar coordinates (using ellipse 2)

	a = e2.a, b = e2.b;
	var precision = 4 / a;
	// results accurate to around 4 metres

	eSq = (a * a - b * b) / (a * a);
	var p = Math.sqrt(x2 * x2 + y2 * y2);
	var phi = Math.atan2(z2, p * (1 - eSq)), phiP = 2 * Math.PI;
	while (Math.abs(phi - phiP) > precision) {
		nu = a / Math.sqrt(1 - eSq * Math.sin(phi) * Math.sin(phi));
		phiP = phi;
		phi = Math.atan2(z2 + eSq * nu * Math.sin(phi), p);
	}
	var lambda = Math.atan2(y2, x2);
	H = p / Math.cos(phi) - nu;

	return new LatLon(phi.toDeg(), lambda.toDeg(), H);
}

<commit_msg>Delete coords.js<commit_after><|endoftext|>