<commit_before>/*
Copyright 2010 University of Toronto

Licensed under the Educational Community License (ECL), Version 2.0.
You may not use this file except in compliance with this License.

You may obtain a copy of the ECL 2.0 License at
https://source.collectionspace.org/collection-space/LICENSE.txt
*/

/*global jQuery, fluid, cspace:true*/
"use strict";

cspace = cspace || {};

(function ($, fluid) {
    fluid.log("RelatedRecordsTab.js loaded");

    fluid.registerNamespace("cspace.relatedRecordsTab");

    var bindEventHandlers = function (that) {
        var elPath = "relations." + that.related;
        that.applier.modelChanged.addListener(elPath, that.listEditor.updateList);
        that.relationManager.events.onCreateNewRecord.addListener(that.listEditor.addNewListRow);
        that.listEditor.detailsDC.events.afterCreate.addListener(function (data) {
            var newRelation = [{
                source: {
                    csid: that.model.csid,
                    recordtype: that.primary
                },
                target: {
                    csid: data.csid,
                    recordtype: that.related
                },
                type: "affects",
                "one-way": false
            }];
            that.relationManager.addRelations({items: newRelation});
        });

        that.options.globalNavigator.events.onPerformNavigation.addListener(function (callback) {
            if (that.listEditor.details.unsavedChanges) {
                that.confirmation.open("cspace.confirmation.saveDialog", undefined, {
                    listeners: {
                        onClose: function (userAction) {
                            if (userAction === "act") {
                                that.listEditor.events.afterListUpdate.addListener(function () {
                                    callback();
                                }, undefined, undefined, "last");
                                that.listEditor.details.requestSave();
                            } else if (userAction === "proceed") {
                                callback();
                            }
                        }
                    }
                });
                return false;
            }
        }, null, null, "first");

        that.listEditor.details.events.afterRender.addListener(function () {
            var csid = that.listEditor.details.model.csid;
            if (csid) {
                var gotoLink = that.locate("goToRecord");
                gotoLink.attr("href", fluid.stringTemplate(that.options.urls.goTo, {related: that.related, csid: csid}));
                gotoLink.show();
            }
        });
    };

    /**
     *
     * @param {Object} container
     * @param {Object} uispec
     * @param {Object} applier  The applier holding the data model of the primary record
     * @param {Object} options
     */
    cspace.relatedRecordsTab = function (container, options) {
        var that = fluid.initRendererComponent("cspace.relatedRecordsTab", container, options);
        that.primary = that.options.primary;
        that.related = that.options.related;

        that.renderer.refreshView();
        fluid.initDependents(that);

        bindEventHandlers(that);

        return that;
    };

    cspace.relatedRecordsTab.provideData = function (relations, related) {
        return {
            items: relations[related]
        };
    };

    cspace.relatedRecordsTab.deleteRelation = function (that, recordEditor) {
        recordEditor.confirmation.open("cspace.confirmation.deleteDialog", undefined, {
            listeners: {
                onClose: function (userAction) {
                    if (userAction === "act") {
                        that.relationManager.dataContext.removeRelations({
                            source: {
                                csid: that.model.csid,
                                recordtype: that.primary
                            },
                            target: {
                                csid: recordEditor.model.csid,
                                recordtype: that.related
                            },
                            "one-way": false,
                            type: "affects"
                        });
                    }
                }
            },
            strings: {
                primaryMessage: recordEditor.options.strings.deletePrimaryMessage
            }
        });
    };

    cspace.relatedRecordsTab.produceTree = function (that) {
        return {
            recordHeader: {
                messagekey: "editRecord"
            },
            listHeader: {
                messagekey: "recordList"
            },
            goToRecord: {
                messagekey: "goToRecord"
            }
        };
    };

    fluid.defaults("cspace.relatedRecordsTab", {
        gradeNames: "fluid.rendererComponent",
        globalNavigator: "{globalNavigator}",
        components: {
            confirmation: {
                type: "cspace.confirmation"
            },
            relationManager: {
                type: "cspace.relationManager",
                options: {
                    relationsElPath: "relations",
                    primary: "{relatedRecordsTab}.primary",
                    related: "{relatedRecordsTab}.related",
                    model: "{relatedRecordsTab}.model",
                    applier: "{relatedRecordsTab}.applier",
                    strings: {
                        addButton: "Add record"
                    }
                }
            },
            togglable: {
                type: "cspace.util.togglable",
                options: {
                    selectors: {
                        header: "{relatedRecordsTab}.options.selectors.header",
                        togglable: "{relatedRecordsTab}.options.selectors.togglable"
                    }
                }
            },
            listEditor: {
                type: "cspace.listEditor",
                options: {
                    recordType: "{relatedRecordsTab}.related",
                    listModel: {
                        expander: {
                            type: "fluid.deferredInvokeCall",
                            func: "cspace.relatedRecordsTab.provideData",
                            args: [
                                "{relatedRecordsTab}.model.relations",
                                "{relatedRecordsTab}.related"
                            ]
                        }
                    },
                    listeners: {
                        pageReady: "{relatedRecordsTab}.events.afterRender.fire"
                    }
                }
            }
        },
        produceTree: cspace.relatedRecordsTab.produceTree,
        selectors: {
            goToRecord: ".csc-goto",
            recordHeader: ".csc-relatedRecordsTab-recordHeader",
            togglable: ".csc-relatedRecordsTab-togglable",
            listHeader: ".csc-relatedRecordsTab-listHeader",
            header: ".csc-relatedRecordsTab-header"
        },
        selectorsToIgnore: ["togglable", "header"],
        events: {
            afterRender: null
        },
        parentBundle: "{globalBundle}",
        strings: {
            goToRecord: "Go To Record"
        },
        urls: cspace.componentUrlBuilder({
            "goTo": "%webapp/html/%related.html?csid=%csid"
        })
    });

})(jQuery, fluid);
<commit_msg>CSPACE-4295: Fixed the tab navigation away (listener has to be fired only once when the user saves on confirmation).<commit_after>/*
Copyright 2010 University of Toronto

Licensed under the Educational Community License (ECL), Version 2.0.
You may not use this file except in compliance with this License.

You may obtain a copy of the ECL 2.0 License at
https://source.collectionspace.org/collection-space/LICENSE.txt
*/

/*global jQuery, fluid, cspace:true*/
"use strict";

cspace = cspace || {};

(function ($, fluid) {
    fluid.log("RelatedRecordsTab.js loaded");

    fluid.registerNamespace("cspace.relatedRecordsTab");

    var bindEventHandlers = function (that) {
        var elPath = "relations." + that.related;
        that.applier.modelChanged.addListener(elPath, that.listEditor.updateList);
        that.relationManager.events.onCreateNewRecord.addListener(that.listEditor.addNewListRow);
        that.listEditor.detailsDC.events.afterCreate.addListener(function (data) {
            var newRelation = [{
                source: {
                    csid: that.model.csid,
                    recordtype: that.primary
                },
                target: {
                    csid: data.csid,
                    recordtype: that.related
                },
                type: "affects",
                "one-way": false
            }];
            that.relationManager.addRelations({items: newRelation});
        });

        that.options.globalNavigator.events.onPerformNavigation.addListener(function (callback) {
            if (that.listEditor.details.unsavedChanges) {
                that.confirmation.open("cspace.confirmation.saveDialog", undefined, {
                    listeners: {
                        onClose: function (userAction) {
                            if (userAction === "act") {
                                that.listEditor.events.afterListUpdate.addListener(function () {
                                    that.listEditor.events.afterListUpdate.removeListener("afterListUpdate");
                                    callback();
                                }, "afterListUpdate", undefined, "last");
                                that.listEditor.details.requestSave();
                            } else if (userAction === "proceed") {
                                callback();
                            }
                        }
                    }
                });
                return false;
            }
        }, null, null, "first");

        that.listEditor.details.events.afterRender.addListener(function () {
            var csid = that.listEditor.details.model.csid;
            if (csid) {
                var gotoLink = that.locate("goToRecord");
                gotoLink.attr("href", fluid.stringTemplate(that.options.urls.goTo, {related: that.related, csid: csid}));
                gotoLink.show();
            }
        });
    };

    /**
     *
     * @param {Object} container
     * @param {Object} uispec
     * @param {Object} applier  The applier holding the data model of the primary record
     * @param {Object} options
     */
    cspace.relatedRecordsTab = function (container, options) {
        var that = fluid.initRendererComponent("cspace.relatedRecordsTab", container, options);
        that.primary = that.options.primary;
        that.related = that.options.related;

        that.renderer.refreshView();
        fluid.initDependents(that);

        bindEventHandlers(that);

        return that;
    };

    cspace.relatedRecordsTab.provideData = function (relations, related) {
        return {
            items: relations[related]
        };
    };

    cspace.relatedRecordsTab.deleteRelation = function (that, recordEditor) {
        recordEditor.confirmation.open("cspace.confirmation.deleteDialog", undefined, {
            listeners: {
                onClose: function (userAction) {
                    if (userAction === "act") {
                        that.relationManager.dataContext.removeRelations({
                            source: {
                                csid: that.model.csid,
                                recordtype: that.primary
                            },
                            target: {
                                csid: recordEditor.model.csid,
                                recordtype: that.related
                            },
                            "one-way": false,
                            type: "affects"
                        });
                    }
                }
            },
            strings: {
                primaryMessage: recordEditor.options.strings.deletePrimaryMessage
            }
        });
    };

    cspace.relatedRecordsTab.produceTree = function (that) {
        return {
            recordHeader: {
                messagekey: "editRecord"
            },
            listHeader: {
                messagekey: "recordList"
            },
            goToRecord: {
                messagekey: "goToRecord"
            }
        };
    };

    fluid.defaults("cspace.relatedRecordsTab", {
        gradeNames: "fluid.rendererComponent",
        globalNavigator: "{globalNavigator}",
        components: {
            confirmation: {
                type: "cspace.confirmation"
            },
            relationManager: {
                type: "cspace.relationManager",
                options: {
                    relationsElPath: "relations",
                    primary: "{relatedRecordsTab}.primary",
                    related: "{relatedRecordsTab}.related",
                    model: "{relatedRecordsTab}.model",
                    applier: "{relatedRecordsTab}.applier",
                    strings: {
                        addButton: "Add record"
                    }
                }
            },
            togglable: {
                type: "cspace.util.togglable",
                options: {
                    selectors: {
                        header: "{relatedRecordsTab}.options.selectors.header",
                        togglable: "{relatedRecordsTab}.options.selectors.togglable"
                    }
                }
            },
            listEditor: {
                type: "cspace.listEditor",
                options: {
                    recordType: "{relatedRecordsTab}.related",
                    listModel: {
                        expander: {
                            type: "fluid.deferredInvokeCall",
                            func: "cspace.relatedRecordsTab.provideData",
                            args: [
                                "{relatedRecordsTab}.model.relations",
                                "{relatedRecordsTab}.related"
                            ]
                        }
                    },
                    listeners: {
                        pageReady: "{relatedRecordsTab}.events.afterRender.fire"
                    }
                }
            }
        },
        produceTree: cspace.relatedRecordsTab.produceTree,
        selectors: {
            goToRecord: ".csc-goto",
            recordHeader: ".csc-relatedRecordsTab-recordHeader",
            togglable: ".csc-relatedRecordsTab-togglable",
            listHeader: ".csc-relatedRecordsTab-listHeader",
            header: ".csc-relatedRecordsTab-header"
        },
        selectorsToIgnore: ["togglable", "header"],
        events: {
            afterRender: null
        },
        parentBundle: "{globalBundle}",
        strings: {
            goToRecord: "Go To Record"
        },
        urls: cspace.componentUrlBuilder({
            "goTo": "%webapp/html/%related.html?csid=%csid"
        })
    });

})(jQuery, fluid);
<|endoftext|>


<commit_before>(function(module) {

	var _MIN_HORIZONTAL_WIDTH = 950;

	var _pageContent = jQuery("#page-content");
	var _container = jQuery("div.sl-container");
	var _pane = jQuery("div.sl-pane");

	var _object = {}

	_object.vertical = true;

	_object.init = function() {
		_object.updateLayout();
    jQuery(window).resize(function() {
    	_object.updateLayout();
		});
	};

	_object.updateLayout = function() {
		if (_container.width() < _MIN_HORIZONTAL_WIDTH) {
			_object.setVerticalLayout();
		}
		else {
			_object.setHorizontalLayout();
		}
	};

	_object.setVerticalLayout = function() {
		if (!_object.vertical) {
			_object.vertical = true;
			_pageContent.toggleClass("sl-horizontal", false);
			jQuery("body").css("overflow", "auto");
			_pane.css("width", "auto");
		}
	};

	_object.setHorizontalLayout = function() {
		if (_object.vertical) {
			_object.vertical = false
			_pageContent.toggleClass("sl-horizontal", true);
			jQuery("body").css("overflow", "hidden");
		}
		_pane.css("width", (_container.width() / 2) - 25);
	};

	module.SmartLayout = _object;

})(piggydb.widget);
<commit_msg>#smart_layout: fixed improper container positioning after switching from scrolled vertical layout<commit_after>(function(module) {

	var _MIN_HORIZONTAL_WIDTH = 950;

	var _pageContent = jQuery("#page-content");
	var _container = jQuery("div.sl-container");
	var _pane = jQuery("div.sl-pane");

	var _object = {}

	_object.vertical = true;

	_object.init = function() {
		_object.updateLayout();
    jQuery(window).resize(function() {
    	_object.updateLayout();
		});
	};

	_object.updateLayout = function() {
		if (_container.width() < _MIN_HORIZONTAL_WIDTH) {
			_object.setVerticalLayout();
		}
		else {
			_object.setHorizontalLayout();
		}
	};

	_object.setVerticalLayout = function() {
		if (!_object.vertical) {
			_object.vertical = true;
			_pageContent.toggleClass("sl-horizontal", false);
			jQuery("body").css("overflow", "auto");
			_pane.css("width", "auto");
		}
	};

	_object.setHorizontalLayout = function() {
		if (_object.vertical) {
			// to make sure that the layout switching will be done with the scrollTop zero
			jQuery('html,body').animate({ scrollTop: 0 }, 0, 'linear', function() {
				_object.vertical = false
				_pageContent.toggleClass("sl-horizontal", true);
				jQuery("body").css("overflow", "hidden");
			});
		}
		_pane.css("width", (_container.width() / 2) - 25);
	};

	module.SmartLayout = _object;

})(piggydb.widget);
<|endoftext|>


<commit_before>import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { getStore } from "../../redux/getStore";
import {
  getDetailsForSample,
  sampleDetailsReducer
} from "../../components/SampleDetails";
import { actions } from "../../redux/reducers/app";
import { reducer as galaxyReducer } from "../../components/galaxy/reducer";
import {
  empty,
  removeProjectFromCart,
  removeSampleFromCart,
  loadFullCart
} from "../../redux/sagas/cart";
import { Cart } from "./components/Cart";

const store = getStore(
  { sampleDetailsReducer },
  {
    empty,
    getDetailsForSample,
    removeSampleFromCart,
    removeProjectFromCart,
    loadFullCart
  }
);

render(
  <Provider store={store}>
    <Cart />
  </Provider>,
  document.querySelector("#root")
);

store.dispatch(actions.initialize({}));
<commit_msg>Tell webpack where the resources are located.<commit_after>import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { getStore } from "../../redux/getStore";
import {
  getDetailsForSample,
  sampleDetailsReducer
} from "../../components/SampleDetails";
import { actions } from "../../redux/reducers/app";
import {
  empty,
  loadFullCart,
  removeProjectFromCart,
  removeSampleFromCart
} from "../../redux/sagas/cart";
import { Cart } from "./components/Cart";

/*
WEBPACK PUBLIC PATH:
Webpack does not now what the servlet context path is.  To fix this, webpack exposed
the variable `__webpack_public_path__`
See: https://webpack.js.org/guides/public-path/#on-the-fly
 */
window.__webpack_public_path__ = `${window.TL.BASE_URL}resources/dist/`;

const store = getStore(
  { sampleDetailsReducer },
  {
    empty,
    getDetailsForSample,
    removeSampleFromCart,
    removeProjectFromCart,
    loadFullCart
  }
);

render(
  <Provider store={store}>
    <Cart />
  </Provider>,
  document.querySelector("#root")
);

store.dispatch(actions.initialize({}));
<|endoftext|>


<commit_before>/**
 * @classdesc Adapter layer between Common Map Widget API v. 1.1 javascript
 * 		implementation and ESRI map implementations
 * @constructor
 * @version 1.1
 * @param map {object} ESRI map object for which this adapter should apply
 */
var EsriAdapter = function(map) {

	/**
     * The container for ESRI Adapter status methods
     * @memberof EsriAdapter
     * @alias status
     */
	this.status = new (function() {
		var me = this;

		/**
		 * Handler for an incomming map status request.
		 * @method status.handleRequest
		 * @param caller {String} optional; the widget making the status request
		 * @param types {String[]} optional; the types of status being requested. Array of strings;
		 *		1.1 only supports "about", "format", and "view"
		 * @memberof! EsriAdapter#
		 */
		me.handleRequest = function(caller, types) {
			if(!types || types.contains("view")) {
				me.sendView(caller);
			}

			if(!types || types.contains("about")) {
				me.sendAbout(caller);
			}

			if(!types || types.contains("format")) {
				me.sendFormat(caller);
			}
		};

		/**
		 * Calculate the view details of the map and announce via the CMW-API
		 * @private
		 * @method status.sendView
		 * @param caller {String} The Id of the widget which requested the map view status
		 * @memberof! EsriAdapter#
		 */
		var sendView = function(caller) {
			var bounds = {
				southWest: {
					lat: map.geographicExtent.ymin,
					lon: map.geographicExtent.xmin
				},
				northEast: {
					lat: map.geographicExtent.ymax,
					lon: map.geographicExtent.xmax
				}
			};

			var center = {
				lat: map.geographicExtent.getCenter().y,
				lon: map.geographicExtent.getCenter().x,
			};

			var range = map.getScale();

			Map.status.view(caller, bounds, center, range);
		};

		/**
		 * Compile the map about details and announce via the CMW-API
		 * @private
		 * @method status.sendAbout
		 * @param caller {object} The Id of the widget which requested the map view status
		 * @memberof! EsriAdapter#
		 */
		var sendAbout = function(caller) {
			var version = esri.version;
			var type = "2-D";
			var widgetName = ""; //FIXME

			Map.status.about(version, type, widgetName);
		};

		/**
		 * Announce the accepted formats via the CMW-API
		 * @private
		 * @method status.sendFormat
		 * @param caller {object} The Id of the widget which requested the map view status
		 * @memberof! EsriAdapter#
		 */
		var sendFormat = function(caller) {
			var formats = ["kml"/*, "geojson", "wms"*/];

			Map.status.format(formats);
		};
	})();
	//bind the functions to the CMW API
	Map.status.handleRequest(this.status.handleRequest);

	/**
	 * The container for EsriAdapter error methods
	 * @alias error
	 * @memberof EsriAdapter
	 */
	this.error = (function() {
		var me = this;

		/**
		 * Build and send an error
		 * @method error.error
		 * @param caller {String} The id of the widget which sent a call triggering the event causing this error
		 * @param message {String} The readable message for the error
		 * @param err {object} The object representing the error details data
		 * @memberof! EsriAdapter#
		 */
		me.error = function(caller, message, err) {
			var sender = caller;
			var type = err.type;
			var msg = message;
			var error = err;

			Map.error.error(sender, type, msg, error);
		};

		/**
		 * handle an error
		 * @method error.handleError
		 * @param sender {String} The id of the widget which send the error message
		 * @param type {String} The type of error for which the message corresponds
		 * @param message {String} The readable error message
		 * @param error {object} The object representing the error details data
		 * @memberof! EsriAdapter#
		 */
		me.handleError = function(sender, type, message, error) {
			//TODO
		};
	})();
	//Bind error functions to CMW API
	Map.error.handleError(this.error.handleError);
};<commit_msg>Cleanup of adapter<commit_after>/**
 * @classdesc Adapter layer between Common Map Widget API v. 1.1 javascript
 * 		implementation and ESRI map implementations
 * @constructor
 * @version 1.1
 * @param map {object} ESRI map object for which this adapter should apply
 */
EsriAdapter = function(map) {

	/**
     * The container for ESRI Adapter status methods
     * @memberof EsriAdapter
     * @alias status
     */
	this.status = (function() {
		var me = this;

		/**
		 * Handler for an incomming map status request.
		 * @method status.handleRequest
		 * @param caller {String} optional; the widget making the status request
		 * @param types {String[]} optional; the types of status being requested. Array of strings;
		 *		1.1 only supports "about", "format", and "view"
		 * @memberof! EsriAdapter#
		 */
		me.handleRequest = function(caller, types) {
			if(!types || types.contains("view")) {
				sendView(caller);
			}

			if(!types || types.contains("about")) {
				sendAbout(caller);
			}

			if(!types || types.contains("format")) {
				sendFormat(caller);
			}
		};

		/**
		 * Calculate the view details of the map and announce via the CMW-API
		 * @private
		 * @method status.sendView
		 * @param caller {String} The Id of the widget which requested the map view status
		 * @memberof! EsriAdapter#
		 */
		var sendView = function(caller) {
			var bounds = {
				southWest: {
					lat: map.geographicExtent.ymin,
					lon: map.geographicExtent.xmin
				},
				northEast: {
					lat: map.geographicExtent.ymax,
					lon: map.geographicExtent.xmax
				}
			};

			var center = {
				lat: map.geographicExtent.getCenter().y,
				lon: map.geographicExtent.getCenter().x,
			};

			var range = map.getScale();

			Map.status.view(caller, bounds, center, range);
		};

		/**
		 * Compile the map about details and announce via the CMW-API
		 * @private
		 * @method status.sendAbout
		 * @param caller {object} The Id of the widget which requested the map view status
		 * @memberof! EsriAdapter#
		 */
		var sendAbout = function(caller) {
			var version = esri.version;
			var type = "2-D";
			var widgetName = ""; //FIXME

			Map.status.about(version, type, widgetName);
		};

		/**
		 * Announce the accepted formats via the CMW-API
		 * @private
		 * @method status.sendFormat
		 * @param caller {object} The Id of the widget which requested the map view status
		 * @memberof! EsriAdapter#
		 */
		var sendFormat = function(caller) {
			var formats = ["kml"/*, "geojson", "wms"*/];

			Map.status.format(formats);
		};
	})();
	//bind the functions to the CMW API
	Map.status.handleRequest(this.status.handleRequest);

	/**
	 * The container for EsriAdapter error methods
	 * @alias error
	 * @memberof EsriAdapter
	 */
	this.error = (function() {
		var me = this;

		/**
		 * Build and send an error
		 * @method error.error
		 * @param caller {String} The id of the widget which sent a call triggering the event causing this error
		 * @param message {String} The readable message for the error
		 * @param err {object} The object representing the error details data
		 * @memberof! EsriAdapter#
		 */
		me.error = function(caller, message, err) {
			var sender = caller;
			var type = err.type;
			var msg = message;
			var error = err;

			Map.error.error(sender, type, msg, error);
		};

		/**
		 * handle an error
		 * @method error.handleError
		 * @param sender {String} The id of the widget which send the error message
		 * @param type {String} The type of error for which the message corresponds
		 * @param message {String} The readable error message
		 * @param error {object} The object representing the error details data
		 * @memberof! EsriAdapter#
		 */
		me.handleError = function(sender, type, message, error) {
			//TODO
		};
	})();
	//Bind error functions to CMW API
	Map.error.handleError(this.error.handleError);
};<|endoftext|>


<commit_before>import Article from '../models/article';
import personalization from '../utils/personalization';

exports.list = async (req, res) => {
	const query = req.query || {};
	let articles = [];
	if (query.type === 'recommended') {
		let articleIds = await personalization({
			endpoint: '/winds_article_recommendations',
			userId: req.user.sub,
		});
		articles = await Article.find({ _id: {$in: articleIds}});
	} else {
		articles = await Article.apiQuery(req.query);
	}
	res.json(articles.filter(a => a.valid));
};

exports.get = async (req, res) => {
	let articleID = req.params.articleId

	if (!mongoose.Types.ObjectId.isValid(articleID)) {
		return res.sendStatus(404);
	}

	let article = await Article.findById(articleID);
	if (!article) {
		return res.sendStatus(404);
	}

	if (req.query && req.query.type === 'parsed') {
		let parsed = await article.getParsedArticle();
		res.json(parsed);
	} else {
		res.json(article);
	}
};
<commit_msg>happy tests<commit_after>import Article from '../models/article';
import personalization from '../utils/personalization';
import mongoose from 'mongoose';

exports.list = async (req, res) => {
	const query = req.query || {};
	let articles = [];
	if (query.type === 'recommended') {
		let articleIds = await personalization({
			endpoint: '/winds_article_recommendations',
			userId: req.user.sub,
		});
		articles = await Article.find({ _id: {$in: articleIds}});
	} else {
		articles = await Article.apiQuery(req.query);
	}
	res.json(articles.filter(a => a.valid));
};

exports.get = async (req, res) => {
	let articleID = req.params.articleId

	if (!mongoose.Types.ObjectId.isValid(articleID)) {
		return res.sendStatus(404);
	}

	let article = await Article.findById(articleID);
	if (!article) {
		return res.sendStatus(404);
	}

	if (req.query && req.query.type === 'parsed') {
		let parsed = await article.getParsedArticle();
		res.json(parsed);
	} else {
		res.json(article);
	}
};
<|endoftext|>


<commit_before>import CoreCombatLogParser from 'parser/core/CombatLogParser';
import DamageDone from 'parser/shared/modules/DamageDone';
import Abilities from './modules/Abilities';

import CooldownThroughputTracker from './modules/features/CooldownThroughputTracker';
import AlwaysBeCasting from './modules/features/AlwaysBeCasting';
import Checklist from './modules/features/Checklist/Module';
import Flametongue from './modules/core/Flametongue';
import FlametongueRefresh from './modules/core/FlametongueRefresh';
import Rockbiter from './modules/core/Rockbiter';

import CrashingStorm from './modules/talents/CrashingStorm';
import EarthenSpike from './modules/talents/EarthenSpike';
import FuryOfAir from './modules/talents/FuryOfAir';
import ForcefulWinds from './modules/talents/ForcefulWinds';
import Hailstorm from './modules/talents/Hailstorm';
import HotHand from './modules/talents/HotHand';
import Landslide from './modules/talents/Landslide';
import SearingAssault from './modules/talents/SearingAssault';
import Sundering from './modules/talents/Sundering';

import SpiritWolf from '../shared/talents/SpiritWolf';
import StaticCharge from '../shared/talents/StaticCharge';
import AnkhNormalizer from '../shared/normalizers/AnkhNormalizer';
import AstralShift from '../shared/spells/AstralShift';
import PackSpirit from '../shared/azerite/PackSpirit';
import SereneSpirit from '../shared/azerite/SereneSpirit';

//Resources
import MaelstromDetails from '../shared/maelstromchart/MaelstromDetails';
import MaelstromTracker from '../shared/maelstromchart/MaelstromTracker';

class CombatLogParser extends CoreCombatLogParser {
  static specModules = {
    // ShamanCore
    damageDone: [DamageDone, { showStatistic: true }],
    flametongue: Flametongue,
    rockbiter: Rockbiter,
    flametongueRefresh: FlametongueRefresh,

    // Features
    alwaysBeCasting: AlwaysBeCasting,
    abilities: Abilities,
    checklist: Checklist,
    cooldownThroughputTracker: CooldownThroughputTracker,

    //Talents
    crashingStorm: CrashingStorm,
    earthenSpike: EarthenSpike,
    forcefulWinds: ForcefulWinds,
    furyOfAir: FuryOfAir,
    hailstorm: Hailstorm,
    hotHand: HotHand,
    landslide: Landslide,
    searingAssault: SearingAssault,
    sundering: Sundering,

    spiritWolf: SpiritWolf,
    staticCharge: StaticCharge,
    ankhNormalizer: AnkhNormalizer,
    astralShift: AstralShift,
    packSpirit: PackSpirit,
    sereneSpirit: SereneSpirit,

    maelstromTracker: MaelstromTracker,
    maelstromDetails: MaelstromDetails,

  };
}

export default CombatLogParser;
<commit_msg>Actually use the module as well<commit_after>import CoreCombatLogParser from 'parser/core/CombatLogParser';
import DamageDone from 'parser/shared/modules/DamageDone';
import Abilities from './modules/Abilities';
import Stormbringer from './modules/core/Stormbringer';

import CooldownThroughputTracker from './modules/features/CooldownThroughputTracker';
import AlwaysBeCasting from './modules/features/AlwaysBeCasting';
import Checklist from './modules/features/Checklist/Module';
import Flametongue from './modules/core/Flametongue';
import FlametongueRefresh from './modules/core/FlametongueRefresh';
import Rockbiter from './modules/core/Rockbiter';

import CrashingStorm from './modules/talents/CrashingStorm';
import EarthenSpike from './modules/talents/EarthenSpike';
import FuryOfAir from './modules/talents/FuryOfAir';
import ForcefulWinds from './modules/talents/ForcefulWinds';
import Hailstorm from './modules/talents/Hailstorm';
import HotHand from './modules/talents/HotHand';
import Landslide from './modules/talents/Landslide';
import SearingAssault from './modules/talents/SearingAssault';
import Sundering from './modules/talents/Sundering';

import SpiritWolf from '../shared/talents/SpiritWolf';
import StaticCharge from '../shared/talents/StaticCharge';
import AnkhNormalizer from '../shared/normalizers/AnkhNormalizer';
import AstralShift from '../shared/spells/AstralShift';
import PackSpirit from '../shared/azerite/PackSpirit';
import SereneSpirit from '../shared/azerite/SereneSpirit';

//Resources
import MaelstromDetails from '../shared/maelstromchart/MaelstromDetails';
import MaelstromTracker from '../shared/maelstromchart/MaelstromTracker';

class CombatLogParser extends CoreCombatLogParser {
  static specModules = {
    // ShamanCore
    damageDone: [DamageDone, { showStatistic: true }],
    flametongue: Flametongue,
    rockbiter: Rockbiter,
    flametongueRefresh: FlametongueRefresh,
    stormbringer: Stormbringer,

    // Features
    alwaysBeCasting: AlwaysBeCasting,
    abilities: Abilities,
    checklist: Checklist,
    cooldownThroughputTracker: CooldownThroughputTracker,

    //Talents
    crashingStorm: CrashingStorm,
    earthenSpike: EarthenSpike,
    forcefulWinds: ForcefulWinds,
    furyOfAir: FuryOfAir,
    hailstorm: Hailstorm,
    hotHand: HotHand,
    landslide: Landslide,
    searingAssault: SearingAssault,
    sundering: Sundering,

    spiritWolf: SpiritWolf,
    staticCharge: StaticCharge,
    ankhNormalizer: AnkhNormalizer,
    astralShift: AstralShift,
    packSpirit: PackSpirit,
    sereneSpirit: SereneSpirit,

    maelstromTracker: MaelstromTracker,
    maelstromDetails: MaelstromDetails,

  };
}

export default CombatLogParser;
<|endoftext|>


<commit_before>app.service("eventService", function($window, config) {
  this.recordSearchEvent = function(query, type, status, latency) {
    this.recordEvent_("search", type, status, latency);
    if (status != "200") {
      this.recordEvent_("search_error", type, query);
    }
  };

  this.recordException = function(name, message) {
    this.recordEvent_("exception", name, message, 1);
  };

  this.recordGenerateDeckEvent = function(status, latency) {
    this.recordEvent_("generate_deck", status, null, latency);
  };

  this.recordEvent_ = function(category, action, label, value) {
    if (config.ENVIRONMENT == "PROD") {
      $window.ga("send", "event", category, action, label, value);
    } else {
      $window.console.log("Skipped recording event. Category: " + category +
          ". Action: " + action + ". Label: " + label + ". Value: " + value);
    }
  }
});
<commit_msg>Record status in label for consistency<commit_after>app.service("eventService", function($window, config) {
  this.recordSearchEvent = function(query, type, status, latency) {
    this.recordEvent_("search", type, status, latency);
    if (status != "200") {
      this.recordEvent_("search_error", type, query);
    }
  };

  this.recordException = function(name, message) {
    this.recordEvent_("exception", name, message, 1);
  };

  this.recordGenerateDeckEvent = function(status, latency) {
    this.recordEvent_("generate_deck", null, status, latency);
  };

  this.recordEvent_ = function(category, action, label, value) {
    if (config.ENVIRONMENT == "PROD") {
      $window.ga("send", "event", category, action, label, value);
    } else {
      $window.console.log("Skipped recording event. Category: " + category +
          ". Action: " + action + ". Label: " + label + ". Value: " + value);
    }
  }
});
<|endoftext|>


<commit_before>var cards = {};
var bankPartners = {};

function Card(attributes){
	this.id = attributes.id;
    this.name = attributes.name;
    this.c_type = attributes.c_type;
    this.bonus = attributes.bonus;
    this.apr = attributes.apr;
    this.anual_fee = attributes.anual_fee;
    this.credit_needed = attributes.credit_needed;
    this.balance_transfer_apr = attributes.balance_transfer_apr;
    this.category = attributes.category.title;
    this.bank_partners = attributes.bank_partners;
    this.balance_transfer_period = attributes.balance_transfer_period;
    this.corp_url = attributes.corp_url;
};

function BankPartner(attributes){
	this.id = attributes.id;
	this.name = attributes.name;
	this.cards = attributes.cards;
};

BankPartner.getCards = function(bankNode){
    $.ajax({
    	url: bankNode.href,
    	dataType: "json",
    	method: "GET"
    })
    .success(function(data){
    })
};

BankPartner.prototype.renderModal = function(){
    return BankPartner.modalTemplate(this)
};

Card.getCard = function(cardNode){
    $.ajax({
    	url: cardNode.href,
    	dataType: "json",
    	method: 'GET'
    })
    .success(function(data){
    	var newCard = Card.makeCard(data)
    	var cardModal = newCard.renderModal()
    	$('div.cards_list').append(cardModal);
    	Card.showCard(newCard.id)
    })
};

Card.showCard = function(cardId){
   $(`#modalCard${cardId}`)[0].style.display = "block";
};

Card.makeCard = function(json){
    var card = new Card(json);
    cards[card.id] = card;
    return card;
};

Card.prototype.renderModal = function(){
    return Card.modalTemplate(this)
};

function closeCard(card){
	card.parentElement.parentElement.style.display = "none"
};

$(function(){

    Card.modalTemplateSource = $('#cardModalTemplate').html();
    Card.modalTemplate = Handlebars.compile(Card.modalTemplateSource);

    BankPartner.modalTemplateSource = $('#bankPartnerModalTemplate').html();
    BankPartner.modalTemplate = Handlebars.compile(BankPartner.modalTemplateSource);

	$('a.card_name').on("click", function(event){
		event.preventDefault();
	    if(cards[this.dataset.id]){
		    Card.showCard(this.dataset.id)
		}else{
			Card.getCard(this)
		}
	});

	$('li div strong a.bank_link').on("click", function(event){
        event.preventDefault();
        if (bankPartners[this.dataset.id]){
            // BankPartner.showCards();
        }else{
            BankPartner.getCards(this);
        }
	});

})

<commit_msg>added makeCards function to BankPartner object. Edited success for get BankPartner.getCards<commit_after>var cards = {};
var bankPartners = {};

function Card(attributes){
	this.id = attributes.id;
    this.name = attributes.name;
    this.c_type = attributes.c_type;
    this.bonus = attributes.bonus;
    this.apr = attributes.apr;
    this.anual_fee = attributes.anual_fee;
    this.credit_needed = attributes.credit_needed;
    this.balance_transfer_apr = attributes.balance_transfer_apr;
    this.category = attributes.category.title;
    this.bank_partners = attributes.bank_partners;
    this.balance_transfer_period = attributes.balance_transfer_period;
    this.corp_url = attributes.corp_url;
};

function BankPartner(attributes){
	this.id = attributes.id;
	this.name = attributes.name;
	this.cards = attributes.cards;
};

BankPartner.getCards = function(bankNode){
    $.ajax({
    	url: bankNode.href,
    	dataType: "json",
    	method: "GET"
    })
    .success(function(data){
    	var newBankPartner = BankPartner.makeCards(data);
    	var cardsList = newBankPartner.renderModal();
    	$(`div.banks_list ul li div#bank_partner_cards_list_${data.id}`).append(cardsList);
    })
};

BankPartner.prototype.renderModal = function(){
    return BankPartner.modalTemplate(this)
};

BankPartner.makeCards = function(json){
  var bankPartner = new BankPartner(json);
  bankPartners[bankPartner.id] = bankPartner;
  return bankPartner;
};

Card.getCard = function(cardNode){
    $.ajax({
    	url: cardNode.href,
    	dataType: "json",
    	method: 'GET'
    })
    .success(function(data){
    	var newCard = Card.makeCard(data)
    	var cardModal = newCard.renderModal()
    	$('div.cards_list').append(cardModal);
    	Card.showCard(newCard.id)
    })
};

Card.showCard = function(cardId){
   $(`#modalCard${cardId}`)[0].style.display = "block";
};

Card.makeCard = function(json){
    var card = new Card(json);
    cards[card.id] = card;
    return card;
};

Card.prototype.renderModal = function(){
    return Card.modalTemplate(this)
};

function closeCard(card){
	card.parentElement.parentElement.style.display = "none"
};

$(function(){

    Card.modalTemplateSource = $('#cardModalTemplate').html();
    Card.modalTemplate = Handlebars.compile(Card.modalTemplateSource);

    BankPartner.modalTemplateSource = $('#bankPartnerModalTemplate').html();
    BankPartner.modalTemplate = Handlebars.compile(BankPartner.modalTemplateSource);

	$('a.card_name').on("click", function(event){
		event.preventDefault();
	    if(cards[this.dataset.id]){
		    Card.showCard(this.dataset.id)
		}else{
			Card.getCard(this)
		}
	});

	$('li div strong a.bank_link').on("click", function(event){
        event.preventDefault();
        if (bankPartners[this.dataset.id]){
            // BankPartner.showCards();
        }else{
            BankPartner.getCards(this);
        }
	});

})

<|endoftext|>


<commit_before>var Game = function() {
  this.lives = 5;
  this.score = 0;
  // change speed back to 1
  this.speed = 3;
  this.words = [];
  this.activeWords = [];
  this.correctWords = [];
  this.startTime = 0;
  this.keystrokes = 0;
  this.textVisible = false;
};

Game.prototype.getWords = function() {
  return $.ajax({
    url: "/game-words",
    method: "get",
    data: {level: localStorage.level}
  }).done(function(response) {
    this.words = response;
  }.bind(this));
};

Game.prototype.drawStart = function() {
  this.ctx.beginPath();
  this.ctx.rect(175, 275, 150, 60);
  this.ctx.strokeStyle = "#0095DD";
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.font = "30px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.ctx.fillText("START", 200, 315);

  this.startGame();
};

Game.prototype.startGame = function() {
  this.canvas.addEventListener('click', function(event) {
    var x = event.pageX - this.canvas.offsetLeft;
    var y = event.pageY - this.canvas.offsetTop;

    if (y > 275 && y < 335 && x > 175 && x < 325) {
      this.input.focus();
      this.addWord();
      this.startTime = new Date().getTime();
      // change this back to 1000
      setInterval(this.addWord.bind(this), 100);
      this.drawGame();
    }
  }.bind(this));
};

Game.prototype.drawGame = function() {
  this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
  this.drawLives();
  this.drawScore();

  if (this.lives === 0) {
    this.drawGameOver();
    this.drawRestart();
  } else if (this.activeWords.length === 0 && this.words.length === 0) {
    this.drawWin();
    this.drawContinue();
    this.drawRestart();
  } else {
    this.drawWord();
    this.collisionTest();

    for (var i in this.activeWords) this.activeWords[i].y += this.speed;

    requestAnimationFrame(this.drawGame.bind(this));
  }
};

Game.prototype.collisionTest = function() {
  for (var i in this.activeWords) {
    if (this.activeWords[i].y > this.canvas.height - 110) {
      this.activeWords.splice(i, 1);
      this.lives -= 1;
    }
  }
};

Game.prototype.checkSpelling = function() {
  var inputValue = $("#inputText").val();
  for (var i in this.activeWords) {
    if (this.activeWords[i].text === inputValue.trim()) {
      this.score += this.activeWords[i].points;
      var correctWord = this.activeWords.splice(i, 1)[0];
      this.correctWords.push(correctWord);
      return $("#inputText").val("");
    }
  }
};

Game.prototype.addWord = function() {
  if (this.words.length > 0) {
    var word = this.words.shift();
    this.activeWords.push(word);
  }
};

Game.prototype.drawLives = function() {
  this.ctx.font = "20px Arial";
  this.ctx.fillStyle = "black";
  this.ctx.fillText("LIVES: " + this.lives, 400, 570);
};

Game.prototype.drawScore = function() {
  this.ctx.font = "20px Arial";
  this.ctx.fillStyle = "black";
  this.ctx.fillText("SCORE: " + this.score, 20, 570);
};

Game.prototype.drawWord = function() {
  this.ctx.font = "20px Arial";
  this.ctx.fillStyle = "#0095DD";
  var words = this.activeWords;
  for (var i in words) {
    this.ctx.fillText(words[i].text, words[i].x, words[i].y);
  }
};

Game.prototype.drawWin = function() {
  this.ctx.font = "30px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.activeWords = [];
  this.ctx.fillText("LEVEL COMPLETE", 120, 200);

  this.saveGame();
};

Game.prototype.drawGameOver = function() {
  var that = this;
  this.ctx.font = "30px 'Press Start 2P'";
  this.ctx.fillStyle = "#0095DD";
  this.activeWords = [];
  // change this back to 160, 300
  // this.ctx.fillText("GAME OVER", 115, 300);
  this.interval = setInterval(function() { that.doBlink(); }, 800);
  this.saveGame();
};

Game.prototype.doBlink = function() {
  if(this.textVisible) {
    this.ctx.clearRect(0,0, 500, 300);
    this.textVisible = false;
  }
  else {
    this.ctx.font = "30px 'Press Start 2P'";
    this.ctx.fillText("GAME OVER", 115, 299);
    this.textVisible = true;
  }
};

Game.prototype.drawRestart = function() {
  this.ctx.beginPath();
  this.ctx.rect(200, 325, 100, 40);
  this.ctx.strokeStyle = "#0095DD";
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.font = "16px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.ctx.fillText("RESTART", 214, 350);

  this.canvas.addEventListener('click', function(event) {
    var x = event.pageX - this.canvas.offsetLeft;
    var y = event.pageY - this.canvas.offsetTop;

    if (y > 325 && y < 365 && x > 200 && x < 300) {
      // create new game instead of reloading everything
      document.location.reload();
    }
  }.bind(this));
};

Game.prototype.drawContinue = function() {
  this.ctx.beginPath();
  this.ctx.rect(200, 250, 100, 40);
  this.ctx.strokeStyle = "#0095DD";
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.font = "16px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.ctx.fillText("CONTINUE", 208, 275);

  this.nextLevel();
};

Game.prototype.nextLevel = function() {
  this.canvas.addEventListener('click', function(event) {
    var x = event.pageX - this.canvas.offsetLeft;
    var y = event.pageY - this.canvas.offsetTop;
    if (y > 250 && y < 290 && x > 200 && x < 300) {
      if (parseInt(localStorage.level) < 6) {
        localStorage.setItem("level", parseInt(localStorage.level) + 1);
      }
      document.location.reload();
    }
  }.bind(this));
};

Game.prototype.saveGame = function() {
  var endTime = new Date().getTime();
  var totalTime = (endTime - this.startTime) / 60000;
  var totalLetters = this.correctWords.reduce(function(total, word) {
    return total + word.text.length;
  }, 0);
  var normalizeWords = totalLetters / 5;
  var wpm = normalizeWords / totalTime;
  var accuracy = (totalLetters / this.keystrokes) * 100;
  var score = this.score;
  var level = localStorage.level;

  if (wpm > 0) {
    $.ajax({
      url: "/games",
      method: "post",
      data: {game: {score: score, wpm: wpm, accuracy: accuracy, time: totalTime, level: level}}
    });
  }
};
<commit_msg>Revert changes back to default<commit_after>var Game = function() {
  this.lives = 5;
  this.score = 0;
  this.speed = 1;
  this.words = [];
  this.activeWords = [];
  this.correctWords = [];
  this.startTime = 0;
  this.keystrokes = 0;
  this.textVisible = false;
};

Game.prototype.getWords = function() {
  return $.ajax({
    url: "/game-words",
    method: "get",
    data: {level: localStorage.level}
  }).done(function(response) {
    this.words = response;
  }.bind(this));
};

Game.prototype.drawStart = function() {
  this.ctx.beginPath();
  this.ctx.rect(175, 275, 150, 60);
  this.ctx.strokeStyle = "#0095DD";
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.font = "30px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.ctx.fillText("START", 200, 315);

  this.startGame();
};

Game.prototype.startGame = function() {
  this.canvas.addEventListener('click', function(event) {
    var x = event.pageX - this.canvas.offsetLeft;
    var y = event.pageY - this.canvas.offsetTop;

    if (y > 275 && y < 335 && x > 175 && x < 325) {
      this.input.focus();
      this.addWord();
      this.startTime = new Date().getTime();
      setInterval(this.addWord.bind(this), 1000);
      this.drawGame();
    }
  }.bind(this));
};

Game.prototype.drawGame = function() {
  this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
  this.drawLives();
  this.drawScore();

  if (this.lives === 0) {
    this.drawGameOver();
    this.drawRestart();
  } else if (this.activeWords.length === 0 && this.words.length === 0) {
    this.drawWin();
    this.drawContinue();
    this.drawRestart();
  } else {
    this.drawWord();
    this.collisionTest();

    for (var i in this.activeWords) this.activeWords[i].y += this.speed;

    requestAnimationFrame(this.drawGame.bind(this));
  }
};

Game.prototype.collisionTest = function() {
  for (var i in this.activeWords) {
    if (this.activeWords[i].y > this.canvas.height - 110) {
      this.activeWords.splice(i, 1);
      this.lives -= 1;
    }
  }
};

Game.prototype.checkSpelling = function() {
  var inputValue = $("#inputText").val();
  for (var i in this.activeWords) {
    if (this.activeWords[i].text === inputValue.trim()) {
      this.score += this.activeWords[i].points;
      var correctWord = this.activeWords.splice(i, 1)[0];
      this.correctWords.push(correctWord);
      return $("#inputText").val("");
    }
  }
};

Game.prototype.addWord = function() {
  if (this.words.length > 0) {
    var word = this.words.shift();
    this.activeWords.push(word);
  }
};

Game.prototype.drawLives = function() {
  this.ctx.font = "20px Arial";
  this.ctx.fillStyle = "black";
  this.ctx.fillText("LIVES: " + this.lives, 400, 570);
};

Game.prototype.drawScore = function() {
  this.ctx.font = "20px Arial";
  this.ctx.fillStyle = "black";
  this.ctx.fillText("SCORE: " + this.score, 20, 570);
};

Game.prototype.drawWord = function() {
  this.ctx.font = "20px Arial";
  this.ctx.fillStyle = "#0095DD";
  var words = this.activeWords;
  for (var i in words) {
    this.ctx.fillText(words[i].text, words[i].x, words[i].y);
  }
};

Game.prototype.drawWin = function() {
  this.ctx.font = "30px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.activeWords = [];
  this.ctx.fillText("LEVEL COMPLETE", 120, 200);

  this.saveGame();
};

Game.prototype.drawGameOver = function() {
  var that = this;
  this.ctx.font = "30px 'Press Start 2P'";
  this.ctx.fillStyle = "#0095DD";
  this.activeWords = [];
  this.interval = setInterval(function() { that.doBlink(); }, 800);
  this.saveGame();
};

Game.prototype.doBlink = function() {
  if(this.textVisible) {
    this.ctx.clearRect(0,0, 500, 300);
    this.textVisible = false;
  }
  else {
    this.ctx.font = "30px 'Press Start 2P'";
    this.ctx.fillText("GAME OVER", 115, 299);
    this.textVisible = true;
  }
};

Game.prototype.drawRestart = function() {
  this.ctx.beginPath();
  this.ctx.rect(200, 325, 100, 40);
  this.ctx.strokeStyle = "#0095DD";
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.font = "16px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.ctx.fillText("RESTART", 214, 350);

  this.canvas.addEventListener('click', function(event) {
    var x = event.pageX - this.canvas.offsetLeft;
    var y = event.pageY - this.canvas.offsetTop;

    if (y > 325 && y < 365 && x > 200 && x < 300) {
      // create new game instead of reloading everything
      document.location.reload();
    }
  }.bind(this));
};

Game.prototype.drawContinue = function() {
  this.ctx.beginPath();
  this.ctx.rect(200, 250, 100, 40);
  this.ctx.strokeStyle = "#0095DD";
  this.ctx.stroke();
  this.ctx.closePath();
  this.ctx.font = "16px Arial";
  this.ctx.fillStyle = "#0095DD";
  this.ctx.fillText("CONTINUE", 208, 275);

  this.nextLevel();
};

Game.prototype.nextLevel = function() {
  this.canvas.addEventListener('click', function(event) {
    var x = event.pageX - this.canvas.offsetLeft;
    var y = event.pageY - this.canvas.offsetTop;
    if (y > 250 && y < 290 && x > 200 && x < 300) {
      if (parseInt(localStorage.level) < 6) {
        localStorage.setItem("level", parseInt(localStorage.level) + 1);
      }
      document.location.reload();
    }
  }.bind(this));
};

Game.prototype.saveGame = function() {
  var endTime = new Date().getTime();
  var totalTime = (endTime - this.startTime) / 60000;
  var totalLetters = this.correctWords.reduce(function(total, word) {
    return total + word.text.length;
  }, 0);
  var normalizeWords = totalLetters / 5;
  var wpm = normalizeWords / totalTime;
  var accuracy = (totalLetters / this.keystrokes) * 100;
  var score = this.score;
  var level = localStorage.level;

  if (wpm > 0) {
    $.ajax({
      url: "/games",
      method: "post",
      data: {game: {score: score, wpm: wpm, accuracy: accuracy, time: totalTime, level: level}}
    });
  }
};
<|endoftext|>


<commit_before>var jobsworth = jobsworth || {}

jobsworth.Grid = (function($){

  var columns = [
    {id: 'read', name: "", field: 'read', resizable: false, sortable: true, formatter: UnreadMarkFormatter, width:16},
    {id: 'id', name: 'id', field: 'id', sortable: true},
    {id: 'summary', name: 'summary', field: 'summary', formatter: HtmlFormatter, width:300},
    {id: 'client', name: 'client', field: 'client', sortable: true, formatter: HtmlFormatter},
    {id: 'milestone', name: 'milestone', field: 'milestone', sortable: true, formatter: HtmlFormatter},
    {id: 'due', name: 'target date', field: 'due', sortable: true, formatter: HtmlFormatter},
    {id: 'time', name: 'time', field: 'time', sortable: true, formatter: DurationFormatter},
    {id: 'assigned', name: 'assigned', field: 'assigned', sortable: true},
    {id: 'resolution', name: 'resolution', field: 'resolution', sortable: true},
    {id: 'estimate_date', name: 'Forecast date', field: 'estimate_date', sortable: true, formatter: TimeFormatter},
    {id: 'updated_at', name: 'last comment date', field: 'updated_at', sortable: true, formatter: TimeFormatter}
  ];

  function Grid(options) {
    this.options = options;
    this.init();
  }

  /* formatters for SlickGrid */
  function UnreadMarkFormatter(row, cell, value, columnDef, dataContext) {
    return value == "f" ? "" : "";
  }
  // fix slickgrid displaying html in cell
  function HtmlFormatter(row, cell, value, columnDef, dataContext) {
    return value;
  }
  function DurationFormatter(row, cell, value, columnDef, dataContext) {
    if (value == 0) {
      return "";
    } else {
      if (dataContext.is_default) {
        return "" + Math.round(value/6)/10 + "hr (default)";
      } else {
        return Math.round(value/6)/10 + "hr";
      }
    }
  }
  function HtmlFormatter(row, cell, value, columnDef, dataContext) {
    return value;
  }
  function TimeFormatter(row, cell, value, columnDef, dataContext) {
    return $.timeago(value);
  }
  /* end of formatters */

  Grid.prototype.init = function() {
    var self = this;

    $.getJSON("/companies/properties", function(data) {
      for(var index in data) {
        var property = data[index]["property"]
        columns.push({
          id: property.name.toLowerCase(),
          name: property.name.toLowerCase(),
          field: property.name.toLowerCase(),
          sortable: true,
          formatter: HtmlFormatter
        });
      }
      $.getJSON("/tasks?format=json", function(rows) {
        self.createGrid(rows);
      })
    })
  }

  Grid.prototype.reload = function() {
    var self = this;
    $.getJSON("/tasks?format=json", function(rows) {
      self.dataView.setItems(rows);
      self.grid.invalidate();
      self.grid.render();
    })
  }

  Grid.prototype.bind = function() {
    var self = this;

    $("#groupBy select").change(function() {
      var value = $(this).val();
      store.set("grid.groupBy", value)
      for(var index in columns) {
        if(columns[index].id == value) {
          self.groupBy(columns[index]);
          return;
        }
      }
      self.groupBy(null);
    })

    this.grid.onClick.subscribe(function (e) {
      var cell = self.grid.getCellFromEvent(e);
      var task = self.grid.getDataItem(cell.row);

      // mark task as read
      if (task.read == "f") {
        task.read = "t";
        self.dataView.updateItem(task.id, task);
      }

      new jobsworth.Task(task.id);
    });

    this.grid.onSort.subscribe(function(e, args) {
      self.onSort(e, args);
    });

    this.dataView.onRowCountChanged.subscribe(function (e, args) {
      self.grid.updateRowCount();
      self.grid.render();
    });

    this.dataView.onRowsChanged.subscribe(function (e, args) {
      self.grid.invalidateRows(args.rows);
      self.grid.render();
    });

    this.grid.onColumnsReordered.subscribe(function (e, args) {
      store.set('grid.Columns', self.grid.getColumns());
    });

    this.grid.onColumnsResized.subscribe(function (e, args) {
      store.set('grid.Columns', self.grid.getColumns());
    });

    $(window).resize(function () {
      self.grid.resizeCanvas();
    });
  }

  Grid.prototype.createGrid = function(rows) {
    var self = this;

    var options = {
      enableCellNavigation: true,
      enableColumnReorder: true,
      multiColumnSort: true,
      forceFitColumns:true
    };

    var groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider();
    this.dataView = new Slick.Data.DataView({
      groupItemMetadataProvider: groupItemMetadataProvider,
      inlineFilters: true
    });

    // highlight unread line
    this.dataView.getItemMetadata = (function(original_provider){
      return function(row) {
        var item = this.getItem(row),
            ret  = original_provider(row);

        if (item){
          ret = ret || {}
          if (item.read == "f") {
            ret.cssClasses = (ret.cssClasses || '') + ' unread';
          } else {
            ret.cssClasses = (ret.cssClasses || '') + ' read';
          }

          // highlight the top next task
          if (item.is_top_next_task) {
            ret.cssClasses = (ret.cssClasses || '') + ' top-next-task';
          }
        }

        return ret;
      }
    })(this.dataView.getItemMetadata)

    this.grid = new Slick.Grid(this.options.el, this.dataView, columns, options);
    this.grid.setSelectionModel(new Slick.RowSelectionModel());
    this.grid.registerPlugin(groupItemMetadataProvider);

    var columnpicker = new jobsworth.grids.ColumnPicker(columns, this.grid, options);

    // this line must be called before the lines below
    this.bind();

    // resize grid
    if (store.get('grid.height')) {
      $(this.options.el).height(store.get('grid.height'));
    }
    $(this.options.el).resizable({
      handles: 's',
      stop: function(event, ui) {
        store.set("grid.height", ui.size.height);
      }
    });

    this.dataView.beginUpdate();
    this.dataView.setItems(rows);
    this.dataView.endUpdate();
    this.grid.autosizeColumns();

    // group rows
    if (store.get('grid.groupBy')) {
      $("#groupBy select").val(store.get('grid.groupBy'));
    }
    $("#groupBy select").trigger("change");

    // select columns
    if (store.get('grid.Columns')) {
      var visibleColumns = [];
      var cols = store.get('grid.Columns');
      for(var i in cols) {
        for(var j in columns) {
          if (cols[i].name == columns[j].name) {
            columns[j].width = cols[i].width;
            visibleColumns.push(columns[j]);
          }
        }
      }
      this.grid.setColumns(visibleColumns);
    }
  }

  Grid.prototype.groupBy = function(column) {
    if (!column) {
      this.dataView.groupBy(null);
      return;
    }

    this.dataView.groupBy(
      column.field,
      function (g) {
        var total = 0;
        for(var i in g.rows){ total = total + g.rows[i].time; };
        var hours = Math.round(total/6)/10 + "hr";
        var text = column.name + ":  " + g.value + "  (" + g.count + " items, "+ hours + ")";
        return text;
      },
      function (a, b) {
        return a.value > b.value;
      }
    );
  }

  Grid.prototype.onSort = function (e, args) {
    var cols = args.sortCols;

    this.grid.getData().sort(function (dataRow1, dataRow2) {
      for (var i = 0, l = cols.length; i < l; i++) {
        var field = cols[i].sortCol.field;
        var sign = cols[i].sortAsc ? 1 : -1;
        var value1 = dataRow1[field], value2 = dataRow2[field];
        var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
        if (result != 0) {
          return result;
        }
      }
      return 0;
    });
    this.grid.invalidate();
    this.grid.render();
  };

  return Grid;
})(jQuery);
<commit_msg>Fix the JavaScript error on tasks page if estimate_date is null. Fixes https://squish.ish.com.au/tasks/17933<commit_after>var jobsworth = jobsworth || {}

jobsworth.Grid = (function($){

  var columns = [
    {id: 'read', name: "", field: 'read', resizable: false, sortable: true, formatter: UnreadMarkFormatter, width:16},
    {id: 'id', name: 'id', field: 'id', sortable: true},
    {id: 'summary', name: 'summary', field: 'summary', formatter: HtmlFormatter, width:300},
    {id: 'client', name: 'client', field: 'client', sortable: true, formatter: HtmlFormatter},
    {id: 'milestone', name: 'milestone', field: 'milestone', sortable: true, formatter: HtmlFormatter},
    {id: 'due', name: 'target date', field: 'due', sortable: true, formatter: HtmlFormatter},
    {id: 'time', name: 'time', field: 'time', sortable: true, formatter: DurationFormatter},
    {id: 'assigned', name: 'assigned', field: 'assigned', sortable: true},
    {id: 'resolution', name: 'resolution', field: 'resolution', sortable: true},
    {id: 'estimate_date', name: 'Forecast date', field: 'estimate_date', sortable: true, formatter: TimeFormatter},
    {id: 'updated_at', name: 'last comment date', field: 'updated_at', sortable: true, formatter: TimeFormatter}
  ];

  function Grid(options) {
    this.options = options;
    this.init();
  }

  /* formatters for SlickGrid */
  function UnreadMarkFormatter(row, cell, value, columnDef, dataContext) {
    return value == "f" ? "" : "";
  }
  // fix slickgrid displaying html in cell
  function HtmlFormatter(row, cell, value, columnDef, dataContext) {
    return value;
  }
  function DurationFormatter(row, cell, value, columnDef, dataContext) {
    if (value == 0) {
      return "";
    } else {
      if (dataContext.is_default) {
        return "" + Math.round(value/6)/10 + "hr (default)";
      } else {
        return Math.round(value/6)/10 + "hr";
      }
    }
  }
  function HtmlFormatter(row, cell, value, columnDef, dataContext) {
    return value;
  }
  function TimeFormatter(row, cell, value, columnDef, dataContext) {
    if(value) {
      return $.timeago(value);
    }
  }
  /* end of formatters */

  Grid.prototype.init = function() {
    var self = this;

    $.getJSON("/companies/properties", function(data) {
      for(var index in data) {
        var property = data[index]["property"]
        columns.push({
          id: property.name.toLowerCase(),
          name: property.name.toLowerCase(),
          field: property.name.toLowerCase(),
          sortable: true,
          formatter: HtmlFormatter
        });
      }
      $.getJSON("/tasks?format=json", function(rows) {
        self.createGrid(rows);
      })
    })
  }

  Grid.prototype.reload = function() {
    var self = this;
    $.getJSON("/tasks?format=json", function(rows) {
      self.dataView.setItems(rows);
      self.grid.invalidate();
      self.grid.render();
    })
  }

  Grid.prototype.bind = function() {
    var self = this;

    $("#groupBy select").change(function() {
      var value = $(this).val();
      store.set("grid.groupBy", value)
      for(var index in columns) {
        if(columns[index].id == value) {
          self.groupBy(columns[index]);
          return;
        }
      }
      self.groupBy(null);
    })

    this.grid.onClick.subscribe(function (e) {
      var cell = self.grid.getCellFromEvent(e);
      var task = self.grid.getDataItem(cell.row);

      // mark task as read
      if (task.read == "f") {
        task.read = "t";
        self.dataView.updateItem(task.id, task);
      }

      new jobsworth.Task(task.id);
    });

    this.grid.onSort.subscribe(function(e, args) {
      self.onSort(e, args);
    });

    this.dataView.onRowCountChanged.subscribe(function (e, args) {
      self.grid.updateRowCount();
      self.grid.render();
    });

    this.dataView.onRowsChanged.subscribe(function (e, args) {
      self.grid.invalidateRows(args.rows);
      self.grid.render();
    });

    this.grid.onColumnsReordered.subscribe(function (e, args) {
      store.set('grid.Columns', self.grid.getColumns());
    });

    this.grid.onColumnsResized.subscribe(function (e, args) {
      store.set('grid.Columns', self.grid.getColumns());
    });

    $(window).resize(function () {
      self.grid.resizeCanvas();
    });
  }

  Grid.prototype.createGrid = function(rows) {
    var self = this;

    var options = {
      enableCellNavigation: true,
      enableColumnReorder: true,
      multiColumnSort: true,
      forceFitColumns:true
    };

    var groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider();
    this.dataView = new Slick.Data.DataView({
      groupItemMetadataProvider: groupItemMetadataProvider,
      inlineFilters: true
    });

    // highlight unread line
    this.dataView.getItemMetadata = (function(original_provider){
      return function(row) {
        var item = this.getItem(row),
            ret  = original_provider(row);

        if (item){
          ret = ret || {}
          if (item.read == "f") {
            ret.cssClasses = (ret.cssClasses || '') + ' unread';
          } else {
            ret.cssClasses = (ret.cssClasses || '') + ' read';
          }

          // highlight the top next task
          if (item.is_top_next_task) {
            ret.cssClasses = (ret.cssClasses || '') + ' top-next-task';
          }
        }

        return ret;
      }
    })(this.dataView.getItemMetadata)

    this.grid = new Slick.Grid(this.options.el, this.dataView, columns, options);
    this.grid.setSelectionModel(new Slick.RowSelectionModel());
    this.grid.registerPlugin(groupItemMetadataProvider);

    var columnpicker = new jobsworth.grids.ColumnPicker(columns, this.grid, options);

    // this line must be called before the lines below
    this.bind();

    // resize grid
    if (store.get('grid.height')) {
      $(this.options.el).height(store.get('grid.height'));
    }
    $(this.options.el).resizable({
      handles: 's',
      stop: function(event, ui) {
        store.set("grid.height", ui.size.height);
      }
    });

    this.dataView.beginUpdate();
    this.dataView.setItems(rows);
    this.dataView.endUpdate();
    this.grid.autosizeColumns();

    // group rows
    if (store.get('grid.groupBy')) {
      $("#groupBy select").val(store.get('grid.groupBy'));
    }
    $("#groupBy select").trigger("change");

    // select columns
    if (store.get('grid.Columns')) {
      var visibleColumns = [];
      var cols = store.get('grid.Columns');
      for(var i in cols) {
        for(var j in columns) {
          if (cols[i].name == columns[j].name) {
            columns[j].width = cols[i].width;
            visibleColumns.push(columns[j]);
          }
        }
      }
      this.grid.setColumns(visibleColumns);
    }
  }

  Grid.prototype.groupBy = function(column) {
    if (!column) {
      this.dataView.groupBy(null);
      return;
    }

    this.dataView.groupBy(
      column.field,
      function (g) {
        var total = 0;
        for(var i in g.rows){ total = total + g.rows[i].time; };
        var hours = Math.round(total/6)/10 + "hr";
        var text = column.name + ":  " + g.value + "  (" + g.count + " items, "+ hours + ")";
        return text;
      },
      function (a, b) {
        return a.value > b.value;
      }
    );
  }

  Grid.prototype.onSort = function (e, args) {
    var cols = args.sortCols;

    this.grid.getData().sort(function (dataRow1, dataRow2) {
      for (var i = 0, l = cols.length; i < l; i++) {
        var field = cols[i].sortCol.field;
        var sign = cols[i].sortAsc ? 1 : -1;
        var value1 = dataRow1[field], value2 = dataRow2[field];
        var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;
        if (result != 0) {
          return result;
        }
      }
      return 0;
    });
    this.grid.invalidate();
    this.grid.render();
  };

  return Grid;
})(jQuery);
<|endoftext|>


<commit_before>$(function(){

    // hide original labels and inputs
    $('.charity input[type=radio], .charity span').hide();

    // replace with charity images
    $('.charity img').click(function(){

        var $radio = $(this).prev('input:radio');

        $('.charity').removeClass('checked', false);
        $(this).parents('.charity').addClass('checked');

        // uncheck all charities
        $('.charities input[type=radio]').attr('checked', false);

        // check charity
        $radio.attr('checked', true);
    });

    // select a random charity
    var rand = Math.floor(Math.random()*5);
    $('.charity img').eq(rand).click();
});
<commit_msg>Respect array bounds when randomly selecting an index<commit_after>$(function(){
    // hide original labels and inputs
    $('.charity input[type=radio], .charity span').hide();

    // replace with charity images
    $('.charity img').click(function(){
        var $radio = $(this).prev('input:radio');

        $('.charity').removeClass('checked', false);
        $(this).parents('.charity').addClass('checked');

        // uncheck all charities
        $('.charities input[type=radio]').attr('checked', false);

        // check charity
        $radio.attr('checked', true);
    });

    // select a random charity
    var $charities = $('.charity img');
    var rand = Math.floor(Math.random()* $charities.length);
    $charities.eq(rand).click();
});
<|endoftext|>


<commit_before>$( document ).ready(function() {
  console.log( "ready!" );

  if(/iP(hone|ad)/.test(window.navigator.userAgent)) {
      var elements = document.querySelectorAll('button');
      var emptyFunction = function() {};
      for(var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('touchstart', emptyFunction, false);
      }
    }

  $(document).foundation();

  var noteWidget = new Note();

  google.maps.event.addDomListener(window, 'load', initialize(noteWidget));

  // google.maps.event.addDomListener(window, 'load', initialize());

  setSlickCarousel('.center');

  $('body').on('click', 'form.like', function(e){
    var note = $(this).children()[0].value
    var user = $(this).children()[1].value
    e.preventDefault();
    $.ajax({
      url: '/vote/add',
      type: 'get',
      data: {noteId: note, userId: user}
    }).done(function(data){
      $('.likesrc').attr('src', '/assets/liked.png')
      $('.like').attr('class', 'liked')
    })
  })
  $('body').on('click', 'form.liked', function(e){
    var note = $(this).children()[0].value
    var user = $(this).children()[1].value
    e.preventDefault();
    $.ajax({
      url: '/vote/remove',
      type: 'get',
      data: {noteId: note, userId: user}
    }).done(function(data){
      $('.likedsrc').attr('src', '/assets/like.png')
      $('.liked').attr('class', 'like')
    })
  })

}); // end document ready

// //CONTROLLER
// var Controller = function(model, view) {
//   this.model = model;
//   this.view = view;
// };

// Controller.prototype = {

// };
// //MODEL
// var Model = function() {

// };

// Model.prototype = {

// };

// //VIEW
// var View = function() {

// };

// View.prototype = {

// }; // VIEW PROTOTYPE END

// //INSTANTIATE
// var model = new Model();
// var view = new View();
// var controller = new Controller(model, view);
// // controller.bindEvents()

<commit_msg>fixed all hearts changing bug<commit_after>$( document ).ready(function() {
  console.log( "ready!" );

  if(/iP(hone|ad)/.test(window.navigator.userAgent)) {
      var elements = document.querySelectorAll('button');
      var emptyFunction = function() {};
      for(var i = 0; i < elements.length; i++) {
        elements[i].addEventListener('touchstart', emptyFunction, false);
      }
    }

  $(document).foundation();

  var noteWidget = new Note();

  google.maps.event.addDomListener(window, 'load', initialize(noteWidget));

  // google.maps.event.addDomListener(window, 'load', initialize());

  setSlickCarousel('.center');

  $('body').on('click', 'form.like', function(e){
    item = $(this).children()[2]
    item = $(item).children()[0]
    $(item).attr('src', '/assets/liked.png')
    var note = $(this).children()[0].value
    var user = $(this).children()[1].value
    e.preventDefault();
    $.ajax({
      url: '/vote/add',
      type: 'get',
      data: {noteId: note, userId: user}
    }).done(function(data){

    })
  })
  $('body').on('click', 'form.liked', function(e){
    item = $(this).children()[2]
    item = $(item).children()[0]
    $(item).attr('src', '/assets/like.png')
    var note = $(this).children()[0].value
    var user = $(this).children()[1].value
    e.preventDefault();
    $.ajax({
      url: '/vote/remove',
      type: 'get',
      data: {noteId: note, userId: user}
    }).done(function(data){
    })
  })

}); // end document ready

// //CONTROLLER
// var Controller = function(model, view) {
//   this.model = model;
//   this.view = view;
// };

// Controller.prototype = {

// };
// //MODEL
// var Model = function() {

// };

// Model.prototype = {

// };

// //VIEW
// var View = function() {

// };

// View.prototype = {

// }; // VIEW PROTOTYPE END

// //INSTANTIATE
// var model = new Model();
// var view = new View();
// var controller = new Controller(model, view);
// // controller.bindEvents()

<|endoftext|>


<commit_before>/**
 * Created by Luis Alonso Murillo Rojas on 11/12/16.
 */

/* Global definitions */
var map;
var route;
var fireStationMarker;
var currentFireCoordinates;
var gpsMarker;
var reportMarker;
var MODISLayer;
var fireIcon;
var fireStationIcon;
var markerIcon;
var markerArea;
var reportMarkerLocation = { 'latitude':0.0, 'longitude':0.0 }

/* Interface function with the client app */

//@function displayWildfiresDetails
//Funtion that parse the MODIS data an send it to the corresponding mobile clients
//@param {double} lat (latitude) of the fire point
//@param {double} lng (longitude) of the fire point
//@param {double} birghtness value of the fire point
//@param {double} scan value
//@param {double} track value
//@param {String} adquisitionTime from the satellite
//@param {String} satellite identification
//@param {integer} confidence value
//@param {String} version of the data
//@param {double} bright_t31 value
//@param {double} frp value
//@param {String} daynight value
function displayWildfiresDetails(lat, lng, brightness, scan, track, adquisitionTime, satellite, confidence, version, bright_t31, frp, daynight) {
    var jsonMODIS = {"LATITUDE":lat,
        "LONGITUDE":lng,
        "BRIGHTNESS":brightness,
        "SCAN":scan,
        "TRACK":track,
        "ADQUISITION_TIME":adquisitionTime,
        "SATELLITE":satellite,
        "CONFIDENCE":confidence,
        "VERSION":version,
        "BRIGHT_T31":bright_t31,
        "FRP":frp,
        "DAYNIGHT":daynight};
    try {
        mobile.getMODISData(JSON.stringify(jsonMODIS));
    } catch(err) {
        console.log("Error trying to invoke mobile method");
    }
}

//@function setUserCurrentLocation
//Funtor that centers the map to the current a given point provided by the clients
//@param {double} latitued
//@param {double} longitude
function setUserCurrentLocation(latitude, longitude) {

    // Center map on Location
    map.setView(L.latLng(latitude, longitude), 8);

    // Initialize marker if null
    if ( gpsMarker == null ){
        gpsMarker = L.marker([latitude, longitude], {icon: markerIcon});
        gpsMarker.addTo(map);
    }

    try {
        mobile.notifyCurrentLocation();
    } catch (err) {
        console.log("Error trying to invoke mobile method");
    }
}

//@function mobileShowDetails
//Function that notify the client when is the time to show the detail information of a given fire point
function mobileShowDetails() {
    try {
        mobile.showWildfireDetails();
    } catch(err) {
        console.log("Error trying to invoke mobile method");
    }
}

//@function setRouteFromTwoPoints
//Function that sets the route from a point A to a point B
//@param {double} latitudeA of the point A
//@param {double} longitudeA of the point A
//@param {double} latitudeB of the point B
//@param {double} longitudeB of the point B
function setRouteFromTwoPoints(latitudeA, longitudeA, latitudeB, longitudeB) {
    route.setWaypoints([
        L.latLng(latitudeA, longitudeA),
        L.latLng(latitudeB, longitudeB)
    ]);
}

//@function removeRoute
//Function that removes the route from the map
function removeRoute() {
    route.setWaypoints([]);
}

function addReportLocation( latitude, longitude ){

    // Center map on Location
    map.setView(L.latLng(latitude, longitude), 8);

    // Initialize marker if null
    if ( reportMarker == null ){
        reportMarker = L.marker([latitude, longitude], {icon: markerArea, draggable:'true'});
        reportMarkerLocation.latitude = latitude;
        reportMarkerLocation.longitude = longitude;
        reportMarker.addTo(map);
        console.log("latitude: " + reportMarkerLocation.latitude);
        console.log("longitude: " + reportMarkerLocation.longitude);
        reportMarker.on("dragend",function(ev){
            var position = ev.target.getLatLng();
            reportMarkerLocation.latitude = position.lat;
            reportMarkerLocation.longitude = position.lng;
            console.log("latitude: " + reportMarkerLocation.latitude);
            console.log("longitude: " + reportMarkerLocation.longitude);
        });
    }
}

function clearReportLocation(){
    map.removeLayer(reportMarker);
}

function prepareReportLocation(){
    console.log("prepareReportLocation");
    console.log(reportMarkerLocation.latitude);
    console.log(reportMarkerLocation.longitude);
    mobile.reportLocation(reportMarkerLocation.latitude, reportMarkerLocation.longitude);
}

function addFireStationMark(latitude, longitude) {
    fireStationMarker = L.marker([latitude, longitude], {icon: fireStationIcon});
    fireStationMarker.addTo(map);
}

function removeFireStationMark() {
    if (fireStationMarker == null){
        return;
    }

    fireStationMarker.removeFrom(map);
}

/* Pop up functions */

//@function addWildfireMessage
//Function that creates a popup message with some info related to the pressed fire point
//@param {double} latitude
//@param {double} longitude
//@param {double} brightness value of the wildfire
//@param {double} temperature value of the place where the fire is located
//@param {double} humidity value of the place where the fire is located
function addWildfireMessage(latitude, longitude, brightness, temperature, humidity) {
    var popup = L.popup({offset: L.point(0, -37)})
        .setLatLng(L.latLng(latitude, longitude))
        .setContent('Incendio' +
            '
Intensidad: ' + brightness +
            '
Temperatura: ' + temperature + " ℃" +
            '
Humedad: ' + humidity + "%" +
            '
Detalles')
        .openOn(map);
}

function removeWildfireMessage() {
    map.closePopup();
}

//Callback that will the called each time a fire marker is creator on the map.
//@param {Object} feature
//@param {Layer} layer where the marker are been displayed
function onEachFeature(feature, layer) {
    layer.setIcon(fireIcon);
    /* onClick event */
    layer.on('click', function (e) {
        displayWildfiresDetails(e.latlng.lat,
            e.latlng.lng,
            e.target.feature.properties.brightness,
            e.target.feature.properties.scan,
            e.target.feature.properties.track,
            e.target.feature.properties.acquisition_time,
            e.target.feature.properties.satellite,
            e.target.feature.properties.confidence,
            e.target.feature.properties.version,
            e.target.feature.properties.bright_t31,
            e.target.feature.properties.frp,
            e.target.feature.properties.daynight);
    });
}
//@function downloadMODISData
//Function that downloads the MODIS data from the backend
function downloadMODISData() {
    console.log('downloading modis data...');

    var bounds = map.getBounds();

    var data = new FormData();
    data.append("north", bounds.getNorth());
    data.append("south", bounds.getSouth());
    data.append("east", bounds.getEast());
    data.append("west", bounds.getWest());

    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;

    xhr.addEventListener("readystatechange", function () {
        if (this.readyState === 4) {
            try {
                var geoJSONData = JSON.parse(this.responseText);
                MODISLayer.clearLayers();
                console.log(this.responseText);
                MODISLayer.addData(geoJSONData);
            } catch (err) {
                console.log("Error downloading the MODIS data: " + err);
            }
        }
    });

    xhr.open("POST", "/modis_data/fires.json");
    xhr.setRequestHeader("cache-control", "no-cache");

    xhr.send(data);
}

/* Map events functions */

//@function checkZoomLevel
//Function that check the the zoom level of the map in order to decide if display or not the datailed MODIS data
function checkZoomLevel() {
    var zoomLevel = map.getZoom();
    console.log("Zoom level: " + zoomLevel);
    if (zoomLevel > 7) {
        console.log("Download the MODIS data");
        downloadMODISData();
    } else {
        console.log("MODISLayer clear layer");
        MODISLayer.clearLayers();
    }
}

$(function() {
    //Map where the data will be displayed
    map = L.map('map').setView([10.07568504578726, -84.31182861328125], 8);
    //Some setting to the general map
    L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
 	    attribution: '© OpenStreetMap © CartoDB',
 	    maxZoom: 18
    }).addTo(map);

    /* Routing */
    route = L.Routing.control({
        waypoints: [],
        routeWhileDragging: false,
        createMarker: function() { return null; },
        router: L.Routing.graphHopper('c06e05f1-cd2f-4c9d-921c-06d634c9c8e9')
    });
    route.addTo(map);

    /* Fire station mark */
    fireStationIcon = L.icon({
        iconUrl: '/assets/firemen.png',
        iconSize:     [32, 37],
        iconAnchor:   [16, 36],
        popupAnchor:  [0, -37]
    });

    markerIcon = L.icon({
        iconUrl: '/assets/marker-gps.png',
        iconSize:     [16, 16],
        iconAnchor:   [8, 8],
        popupAnchor:  [0, -37]
    });

    markerArea = L.icon({
        iconUrl: '/assets/marker-area.png',
        iconSize:     [180, 180],
        iconAnchor:   [90, 90],
        popupAnchor:  [0, 0]
    });

    /* Wildfire icon */

    fireIcon = L.icon({
        iconUrl: '/assets/fire.png',
        iconSize:     [32, 37],
        iconAnchor:   [16, 36],
        popupAnchor:  [0, -37]
    });

    //Capturing the moveend event from the map
    map.on('moveend', function() {
        checkZoomLevel();
    });

    /* MODIS data layers */

    //Data from the backend
    MODISLayer = L.geoJSON(null, {
        onEachFeature:onEachFeature
    }).addTo(map);

    //NASA's WMS service
    var wmsLayer = L.tileLayer.wms('https://firms.modaps.eosdis.nasa.gov/wms/c6?', {
        layers:'fires24',
        transparent: true,
        format: 'image/png'
    }).addTo(map);

});
<commit_msg>Fix clearReportLocation method.<commit_after>/**
 * Created by Luis Alonso Murillo Rojas on 11/12/16.
 */

/* Global definitions */
var map;
var route;
var fireStationMarker;
var currentFireCoordinates;
var gpsMarker;
var reportMarker;
var MODISLayer;
var fireIcon;
var fireStationIcon;
var markerIcon;
var markerArea;
var reportMarkerLocation = { 'latitude':0.0, 'longitude':0.0 }

/* Interface function with the client app */

//@function displayWildfiresDetails
//Funtion that parse the MODIS data an send it to the corresponding mobile clients
//@param {double} lat (latitude) of the fire point
//@param {double} lng (longitude) of the fire point
//@param {double} birghtness value of the fire point
//@param {double} scan value
//@param {double} track value
//@param {String} adquisitionTime from the satellite
//@param {String} satellite identification
//@param {integer} confidence value
//@param {String} version of the data
//@param {double} bright_t31 value
//@param {double} frp value
//@param {String} daynight value
function displayWildfiresDetails(lat, lng, brightness, scan, track, adquisitionTime, satellite, confidence, version, bright_t31, frp, daynight) {
    var jsonMODIS = {"LATITUDE":lat,
        "LONGITUDE":lng,
        "BRIGHTNESS":brightness,
        "SCAN":scan,
        "TRACK":track,
        "ADQUISITION_TIME":adquisitionTime,
        "SATELLITE":satellite,
        "CONFIDENCE":confidence,
        "VERSION":version,
        "BRIGHT_T31":bright_t31,
        "FRP":frp,
        "DAYNIGHT":daynight};
    try {
        mobile.getMODISData(JSON.stringify(jsonMODIS));
    } catch(err) {
        console.log("Error trying to invoke mobile method");
    }
}

//@function setUserCurrentLocation
//Funtor that centers the map to the current a given point provided by the clients
//@param {double} latitued
//@param {double} longitude
function setUserCurrentLocation(latitude, longitude) {

    // Center map on Location
    map.setView(L.latLng(latitude, longitude), 8);

    // Initialize marker if null
    if ( gpsMarker == null ){
        gpsMarker = L.marker([latitude, longitude], {icon: markerIcon});
        gpsMarker.addTo(map);
    }

    try {
        mobile.notifyCurrentLocation();
    } catch (err) {
        console.log("Error trying to invoke mobile method");
    }
}

//@function mobileShowDetails
//Function that notify the client when is the time to show the detail information of a given fire point
function mobileShowDetails() {
    try {
        mobile.showWildfireDetails();
    } catch(err) {
        console.log("Error trying to invoke mobile method");
    }
}

//@function setRouteFromTwoPoints
//Function that sets the route from a point A to a point B
//@param {double} latitudeA of the point A
//@param {double} longitudeA of the point A
//@param {double} latitudeB of the point B
//@param {double} longitudeB of the point B
function setRouteFromTwoPoints(latitudeA, longitudeA, latitudeB, longitudeB) {
    route.setWaypoints([
        L.latLng(latitudeA, longitudeA),
        L.latLng(latitudeB, longitudeB)
    ]);
}

//@function removeRoute
//Function that removes the route from the map
function removeRoute() {
    route.setWaypoints([]);
}

function addReportLocation( latitude, longitude ){

    // Center map on Location
    map.setView(L.latLng(latitude, longitude), 8);

    // Initialize marker if null
    if ( reportMarker == null ){
        reportMarker = L.marker([latitude, longitude], {icon: markerArea, draggable:'true'});
        reportMarkerLocation.latitude = latitude;
        reportMarkerLocation.longitude = longitude;
        reportMarker.addTo(map);
        console.log("latitude: " + reportMarkerLocation.latitude);
        console.log("longitude: " + reportMarkerLocation.longitude);
        reportMarker.on("dragend",function(ev){
            var position = ev.target.getLatLng();
            reportMarkerLocation.latitude = position.lat;
            reportMarkerLocation.longitude = position.lng;
            console.log("latitude: " + reportMarkerLocation.latitude);
            console.log("longitude: " + reportMarkerLocation.longitude);
        });
    }
}

function clearReportLocation(){
    map.removeLayer(reportMarker);
    reportMarker = null;
}

function prepareReportLocation(){
    console.log("prepareReportLocation");
    console.log(reportMarkerLocation.latitude);
    console.log(reportMarkerLocation.longitude);
    mobile.reportLocation(reportMarkerLocation.latitude, reportMarkerLocation.longitude);
}

function addFireStationMark(latitude, longitude) {
    fireStationMarker = L.marker([latitude, longitude], {icon: fireStationIcon});
    fireStationMarker.addTo(map);
}

function removeFireStationMark() {
    if (fireStationMarker == null){
        return;
    }

    fireStationMarker.removeFrom(map);
}

/* Pop up functions */

//@function addWildfireMessage
//Function that creates a popup message with some info related to the pressed fire point
//@param {double} latitude
//@param {double} longitude
//@param {double} brightness value of the wildfire
//@param {double} temperature value of the place where the fire is located
//@param {double} humidity value of the place where the fire is located
function addWildfireMessage(latitude, longitude, brightness, temperature, humidity) {
    var popup = L.popup({offset: L.point(0, -37)})
        .setLatLng(L.latLng(latitude, longitude))
        .setContent('Incendio' +
            '
Intensidad: ' + brightness +
            '
Temperatura: ' + temperature + " ℃" +
            '
Humedad: ' + humidity + "%" +
            '
Detalles')
        .openOn(map);
}

function removeWildfireMessage() {
    map.closePopup();
}

//Callback that will the called each time a fire marker is creator on the map.
//@param {Object} feature
//@param {Layer} layer where the marker are been displayed
function onEachFeature(feature, layer) {
    layer.setIcon(fireIcon);
    /* onClick event */
    layer.on('click', function (e) {
        displayWildfiresDetails(e.latlng.lat,
            e.latlng.lng,
            e.target.feature.properties.brightness,
            e.target.feature.properties.scan,
            e.target.feature.properties.track,
            e.target.feature.properties.acquisition_time,
            e.target.feature.properties.satellite,
            e.target.feature.properties.confidence,
            e.target.feature.properties.version,
            e.target.feature.properties.bright_t31,
            e.target.feature.properties.frp,
            e.target.feature.properties.daynight);
    });
}
//@function downloadMODISData
//Function that downloads the MODIS data from the backend
function downloadMODISData() {
    console.log('downloading modis data...');

    var bounds = map.getBounds();

    var data = new FormData();
    data.append("north", bounds.getNorth());
    data.append("south", bounds.getSouth());
    data.append("east", bounds.getEast());
    data.append("west", bounds.getWest());

    var xhr = new XMLHttpRequest();
    xhr.withCredentials = true;

    xhr.addEventListener("readystatechange", function () {
        if (this.readyState === 4) {
            try {
                var geoJSONData = JSON.parse(this.responseText);
                MODISLayer.clearLayers();
                console.log(this.responseText);
                MODISLayer.addData(geoJSONData);
            } catch (err) {
                console.log("Error downloading the MODIS data: " + err);
            }
        }
    });

    xhr.open("POST", "/modis_data/fires.json");
    xhr.setRequestHeader("cache-control", "no-cache");

    xhr.send(data);
}

/* Map events functions */

//@function checkZoomLevel
//Function that check the the zoom level of the map in order to decide if display or not the datailed MODIS data
function checkZoomLevel() {
    var zoomLevel = map.getZoom();
    console.log("Zoom level: " + zoomLevel);
    if (zoomLevel > 7) {
        console.log("Download the MODIS data");
        downloadMODISData();
    } else {
        console.log("MODISLayer clear layer");
        MODISLayer.clearLayers();
    }
}

$(function() {
    //Map where the data will be displayed
    map = L.map('map').setView([10.07568504578726, -84.31182861328125], 8);
    //Some setting to the general map
    L.tileLayer('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
 	    attribution: '© OpenStreetMap © CartoDB',
 	    maxZoom: 18
    }).addTo(map);

    /* Routing */
    route = L.Routing.control({
        waypoints: [],
        routeWhileDragging: false,
        createMarker: function() { return null; },
        router: L.Routing.graphHopper('c06e05f1-cd2f-4c9d-921c-06d634c9c8e9')
    });
    route.addTo(map);

    /* Fire station mark */
    fireStationIcon = L.icon({
        iconUrl: '/assets/firemen.png',
        iconSize:     [32, 37],
        iconAnchor:   [16, 36],
        popupAnchor:  [0, -37]
    });

    markerIcon = L.icon({
        iconUrl: '/assets/marker-gps.png',
        iconSize:     [16, 16],
        iconAnchor:   [8, 8],
        popupAnchor:  [0, -37]
    });

    markerArea = L.icon({
        iconUrl: '/assets/marker-area.png',
        iconSize:     [180, 180],
        iconAnchor:   [90, 90],
        popupAnchor:  [0, 0]
    });

    /* Wildfire icon */

    fireIcon = L.icon({
        iconUrl: '/assets/fire.png',
        iconSize:     [32, 37],
        iconAnchor:   [16, 36],
        popupAnchor:  [0, -37]
    });

    //Capturing the moveend event from the map
    map.on('moveend', function() {
        checkZoomLevel();
    });

    /* MODIS data layers */

    //Data from the backend
    MODISLayer = L.geoJSON(null, {
        onEachFeature:onEachFeature
    }).addTo(map);

    //NASA's WMS service
    var wmsLayer = L.tileLayer.wms('https://firms.modaps.eosdis.nasa.gov/wms/c6?', {
        layers:'fires24',
        transparent: true,
        format: 'image/png'
    }).addTo(map);

});
<|endoftext|>