<commit_before>/*!
 * ${copyright}
 */
/**
 * Adds support rules of the sap.ui.table library to the support infrastructure.
 */
sap.ui.define(["jquery.sap.global", "sap/ui/support/library", "sap/ui/support/supportRules/RuleSet", "./rules/TableHelper.support", 'sap/ui/Device'],
	function(jQuery, SupportLib, Ruleset, SupportHelper, Device) {
	"use strict";

	// shortcuts
	var Categories = SupportLib.Categories, // Accessibility, Performance, Memory, ...
		Severity = SupportLib.Severity;	// Hint, Warning, Error
		//Audiences = SupportLib.Audiences; // Control, Internal, Application

	var oLib = {
		name: "sap.ui.table",
		niceName: "UI5 Table library"
	};

	var oRuleset = new Ruleset(oLib);

	function createRule(oRuleDef) {
		oRuleDef.id = "gridTable" + oRuleDef.id;
		SupportHelper.addRuleToRuleset(oRuleDef, oRuleset);
	}

	//**********************************************************
	// Helpers related to sap.ui.table Controls
	//**********************************************************

	/**
	 * Loops over all columns of all visible tables and calls the given callback with the following parameters:
	 * table instance, column instance, column template instance.
	 *
	 * If the column does not have a template or a type is given and the template is not of this type the callback is not called.
	 *
	 * @param {function} fnDoCheck Callback
	 * @param {object} oScope The scope as given in the rule check function.
	 * @param {string} [sType] If given an additional type check is performed. Module syntax required!
	 */
	function checkColumnTemplate(fnDoCheck, oScope, sType) {
		var aTables = SupportHelper.find(oScope, true, "sap/ui/table/Table");
		var aColumns, oTemplate;
		for (var i = 0; i < aTables.length; i++) {
			aColumns = aTables[i].getColumns();
			for (var k = 0; k < aColumns.length; k++) {
				oTemplate = aColumns[k].getTemplate();
				if (oTemplate && (!sType || SupportHelper.isInstanceOf(oTemplate, sType))) {
					fnDoCheck(aTables[i], aColumns[k], oTemplate);
				}
			}
		}
	}

	//**********************************************************
	// Rule Definitions
	//**********************************************************

	/*
	 * Checks whether content densities are used correctly.
	 */
	createRule({
		id : "ContentDensity",
		categories: [Categories.Usage],
		title : "Content Density Usage",
		description : "Checks whether the content densities 'Cozy', 'Compact' and 'Condensed' are used correctly.",
		resolution : "Ensure that either only the 'Cozy' or 'Compact' content density is used or the 'Condensed' and 'Compact' content densities in combination are used.",
		resolutionurls : [SupportHelper.createDocuRef("Documentation: Content Densities", "#docs/guide/e54f729da8e3405fae5e4fe8ae7784c1.html")],
		check : function(oIssueManager, oCoreFacade, oScope) {
			var $Document = jQuery("html");
			var $Cozy = $Document.find(".sapUiSizeCozy");
			var $Compact = $Document.find(".sapUiSizeCompact");
			var $Condensed = $Document.find(".sapUiSizeCondensed");

			function checkDensity($Source, sTargetClass, sMessage) {
				var bFound = false;
				$Source.each(function(){
					if (jQuery(this).closest(sTargetClass).length) {
						bFound = true;
					}
				});
				if (bFound && sMessage) {
					SupportHelper.reportIssue(oIssueManager, sMessage, Severity.High);
				}
				return bFound;
			}

			checkDensity($Compact, ".sapUiSizeCozy", "'Compact' content density is used within 'Cozy' area.");
			checkDensity($Cozy, ".sapUiSizeCompact", "'Cozy' content density is used within 'Compact' area.");
			checkDensity($Condensed, ".sapUiSizeCozy", "'Condensed' content density is used within 'Cozy' area.");
			checkDensity($Cozy, ".sapUiSizeCondensed", "'Cozy' content density is used within 'Condensed' area.");

			if ($Condensed.length > 0) {
				var bFound = checkDensity($Condensed, ".sapUiSizeCompact");
				if (!bFound) {
					SupportHelper.reportIssue(oIssueManager, "'Condensed' content density must be used in combination with 'Compact'.", Severity.High);
				}
			}
		}
	});

	/*
	 * Validates whether title or aria-labelledby is correctly set
	 */
	createRule({
		id : "AccessibleLabel",
		categories: [Categories.Accessibility],
		title : "Accessible Label",
		description : "Checks whether 'sap.ui.table.Table' controls have an accessible label.",
		resolution : "Use the 'title' aggregation or the 'ariaLabelledBy' association of the 'sap.ui.table.Table' control to define a proper accessible labeling.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			var aTables = SupportHelper.find(oScope, true, "sap/ui/table/Table");
			for (var i = 0; i < aTables.length; i++) {
				if (!aTables[i].getTitle() && aTables[i].getAriaLabelledBy().length == 0) {
					SupportHelper.reportIssue(oIssueManager, "Table '" + aTables[i].getId() + "' does not have an accessible label.", Severity.High, aTables[i].getId());
				}
			}
		}
	});

	/*
	 * Validates sap.ui.core.Icon column templates.
	 */
	createRule({
		id : "ColumnTemplateIcon",
		categories: [Categories.Accessibility],
		title : "Column template validation - 'sap.ui.core.Icon'",
		description : "The 'decorative' property of control 'sap.ui.core.Icon' is set to 'true' although the control is used as column template.",
		resolution : "Set the 'decorative' property of control 'sap.ui.core.Icon' to 'false' if the control is used as column template.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			checkColumnTemplate(function(oTable, oColumn, oIconTemplate) {
				if (!oIconTemplate.isBound("decorative") && oIconTemplate.getDecorative()) {
					var sId = oColumn.getId();
					SupportHelper.reportIssue(oIssueManager, "Column '" + sId + "' of table '" + oTable.getId() + "' uses decorative 'sap.ui.core.Icon' control.", Severity.High, sId);
				}
			}, oScope, "sap/ui/core/Icon");
		}
	});

	/*
	 * Validates sap.m.Text column templates.
	 */
	createRule({
		id : "ColumnTemplateTextWrapping",
		categories: [Categories.Usage],
		title : "Column template validation - 'sap.m.Text'",
		description : "The 'wrapping' property of the control 'sap.m.Text' is set to 'true' although the control is used as a column template.",
		resolution : "Set the 'wrapping' property of the control 'sap.m.Text' to 'false' if the control is used as a column template.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			checkColumnTemplate(function(oTable, oColumn, oMTextTemplate) {
				if (!oMTextTemplate.isBound("wrapping") && oMTextTemplate.getWrapping()) {
					var sColumnId = oColumn.getId();
					SupportHelper.reportIssue(oIssueManager, "Column '" + sColumnId + "' of table '" + oTable.getId() + "' uses an 'sap.m.Text' control with wrapping enabled.", Severity.High, sColumnId);
				}
			}, oScope, "sap/m/Text");
		}
	});

	/*
	 * Checks for No Deviating units issue in AnalyticalBinding
	 */
	createRule({
		id : "AnalyticsNoDeviatingUnits",
		categories: [Categories.Bindings],
		title : "Analytical Binding reports 'No deviating units found...'",
		description : "The analytical service returns duplicate IDs. This could also lead to many requests, but the analytical service expects to receive just one record",
		resolution : "Adjust the service implementation.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			var aTables = SupportHelper.find(oScope, true, "sap/ui/table/AnalyticalTable");
			var sAnalyticalErrorId = "NO_DEVIATING_UNITS";
			var oIssues = {};

			SupportHelper.checkLogEntries(function(oLogEntry) {
				// Filter out totally irrelevant issues
				if (oLogEntry.level != jQuery.sap.log.Level.ERROR && oLogEntry.level != jQuery.sap.log.Level.FATAL) {
					return false;
				}
				var oInfo = oLogEntry.supportInfo;
				if (oInfo && oInfo.type === "sap.ui.model.analytics.AnalyticalBinding" && oInfo.analyticalError === sAnalyticalErrorId) {
					return true;
				}
				return false;
			}, function(oLogEntry){
				// Check the remaining Issues
				var sBindingId = oLogEntry.supportInfo.analyticalBindingId;
				if (sBindingId && !oIssues[sAnalyticalErrorId + "-" + sBindingId]) {
					var oBinding;
					for (var i = 0; i < aTables.length; i++) {
						oBinding = aTables[i].getBinding("rows");
						if (oBinding && oBinding.__supportUID === sBindingId) {
							oIssues[sAnalyticalErrorId + "-" + sBindingId] = true; // Ensure is only reported once
							SupportHelper.reportIssue(oIssueManager, "Analytical Binding reports 'No deviating units found...'", Severity.High, aTables[i].getId());
						}
					}
				}
			});
		}
	});

	/*
	 * Checks whether the currently visible rows have the expected height.
	 */
	createRule({
		id : "RowHeights",
		categories: [Categories.Usage],
		title : "Row heights",
		description : "Checks whether the currently visible rows have the expected height.",
		resolution : "Check whether content densities are correctly used, and only the supported controls are used as column templates, with their"
					 + " wrapping property set to \"false\"",
		resolutionurls: [
			SupportHelper.createDocuRef("Documentation: Content Densities", "#docs/guide/e54f729da8e3405fae5e4fe8ae7784c1.html"),
			SupportHelper.createDocuRef("Documentation: Supported controls", "#docs/guide/148892ff9aea4a18b912829791e38f3e.html"),
			{text: "SAP Fiori Design Guidelines: Grid Table", href: "https://experience.sap.com/fiori-design-web/grid-table/"}/*,
			SupportHelper.createDocuRef("API Reference: Column #setTemplate", "#docs/api/symbols/sap.ui.table.Column.html#setTemplate")*/
		],
		check: function(oIssueManager, oCoreFacade, oScope) {
			var aTables = SupportHelper.find(oScope, true, "sap/ui/table/Table");
			var aVisibleRows;
			var fActualRowHeight;
			var iExpectedRowHeight;
			var oRowElement;
			var bIsZoomedInChrome = Device.browser.chrome && window.devicePixelRatio != 1;
			var bUnexpectedRowHeightDetected = false;

			for (var i = 0; i < aTables.length; i++) {
				aVisibleRows = aTables[i].getRows();
				iExpectedRowHeight = aTables[i]._getDefaultRowHeight();

				for (var j = 0; j < aVisibleRows.length; j++) {
					oRowElement = aVisibleRows[j].getDomRef();

					if (oRowElement != null) {
						fActualRowHeight = oRowElement.getBoundingClientRect().height;

						if (bIsZoomedInChrome) {
							var nHeightDeviation = Math.abs(iExpectedRowHeight - fActualRowHeight);
							if (nHeightDeviation > 1) {
								// If zoomed in Chrome, the actual height may deviate from the expected height by less than 1 pixel. Any higher
								// deviation shall be considered as defective.
								bUnexpectedRowHeightDetected = true;
							}
						} else if (fActualRowHeight !== iExpectedRowHeight) {
							bUnexpectedRowHeightDetected = true;
						}

						if (bUnexpectedRowHeightDetected) {
							SupportHelper.reportIssue(oIssueManager,
								"The row height was expected to be " + iExpectedRowHeight + "px, but was " + fActualRowHeight + "px instead."
								+ " This causes issues with vertical scrolling.",
								Severity.High, aVisibleRows[j].getId());
							break;
						}
					}
				}
			}
		}
	});

	return {lib: oLib, ruleset: oRuleset};

}, true);
<commit_msg>[INTERNAL] GridTable: Updated Support Rule for Text column template<commit_after>/*!
 * ${copyright}
 */
/**
 * Adds support rules of the sap.ui.table library to the support infrastructure.
 */
sap.ui.define(["jquery.sap.global", "sap/ui/support/library", "sap/ui/support/supportRules/RuleSet", "./rules/TableHelper.support", 'sap/ui/Device'],
	function(jQuery, SupportLib, Ruleset, SupportHelper, Device) {
	"use strict";

	// shortcuts
	var Categories = SupportLib.Categories, // Accessibility, Performance, Memory, ...
		Severity = SupportLib.Severity;	// Hint, Warning, Error
		//Audiences = SupportLib.Audiences; // Control, Internal, Application

	var oLib = {
		name: "sap.ui.table",
		niceName: "UI5 Table library"
	};

	var oRuleset = new Ruleset(oLib);

	function createRule(oRuleDef) {
		oRuleDef.id = "gridTable" + oRuleDef.id;
		SupportHelper.addRuleToRuleset(oRuleDef, oRuleset);
	}

	//**********************************************************
	// Helpers related to sap.ui.table Controls
	//**********************************************************

	/**
	 * Loops over all columns of all visible tables and calls the given callback with the following parameters:
	 * table instance, column instance, column template instance.
	 *
	 * If the column does not have a template or a type is given and the template is not of this type the callback is not called.
	 *
	 * @param {function} fnDoCheck Callback
	 * @param {object} oScope The scope as given in the rule check function.
	 * @param {string} [sType] If given an additional type check is performed. Module syntax required!
	 */
	function checkColumnTemplate(fnDoCheck, oScope, sType) {
		var aTables = SupportHelper.find(oScope, true, "sap/ui/table/Table");
		var aColumns, oTemplate;
		for (var i = 0; i < aTables.length; i++) {
			aColumns = aTables[i].getColumns();
			for (var k = 0; k < aColumns.length; k++) {
				oTemplate = aColumns[k].getTemplate();
				if (oTemplate && (!sType || SupportHelper.isInstanceOf(oTemplate, sType))) {
					fnDoCheck(aTables[i], aColumns[k], oTemplate);
				}
			}
		}
	}

	//**********************************************************
	// Rule Definitions
	//**********************************************************

	/*
	 * Checks whether content densities are used correctly.
	 */
	createRule({
		id : "ContentDensity",
		categories: [Categories.Usage],
		title : "Content Density Usage",
		description : "Checks whether the content densities 'Cozy', 'Compact' and 'Condensed' are used correctly.",
		resolution : "Ensure that either only the 'Cozy' or 'Compact' content density is used or the 'Condensed' and 'Compact' content densities in combination are used.",
		resolutionurls : [SupportHelper.createDocuRef("Documentation: Content Densities", "#docs/guide/e54f729da8e3405fae5e4fe8ae7784c1.html")],
		check : function(oIssueManager, oCoreFacade, oScope) {
			var $Document = jQuery("html");
			var $Cozy = $Document.find(".sapUiSizeCozy");
			var $Compact = $Document.find(".sapUiSizeCompact");
			var $Condensed = $Document.find(".sapUiSizeCondensed");

			function checkDensity($Source, sTargetClass, sMessage) {
				var bFound = false;
				$Source.each(function(){
					if (jQuery(this).closest(sTargetClass).length) {
						bFound = true;
					}
				});
				if (bFound && sMessage) {
					SupportHelper.reportIssue(oIssueManager, sMessage, Severity.High);
				}
				return bFound;
			}

			checkDensity($Compact, ".sapUiSizeCozy", "'Compact' content density is used within 'Cozy' area.");
			checkDensity($Cozy, ".sapUiSizeCompact", "'Cozy' content density is used within 'Compact' area.");
			checkDensity($Condensed, ".sapUiSizeCozy", "'Condensed' content density is used within 'Cozy' area.");
			checkDensity($Cozy, ".sapUiSizeCondensed", "'Cozy' content density is used within 'Condensed' area.");

			if ($Condensed.length > 0) {
				var bFound = checkDensity($Condensed, ".sapUiSizeCompact");
				if (!bFound) {
					SupportHelper.reportIssue(oIssueManager, "'Condensed' content density must be used in combination with 'Compact'.", Severity.High);
				}
			}
		}
	});

	/*
	 * Validates whether title or aria-labelledby is correctly set
	 */
	createRule({
		id : "AccessibleLabel",
		categories: [Categories.Accessibility],
		title : "Accessible Label",
		description : "Checks whether 'sap.ui.table.Table' controls have an accessible label.",
		resolution : "Use the 'title' aggregation or the 'ariaLabelledBy' association of the 'sap.ui.table.Table' control to define a proper accessible labeling.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			var aTables = SupportHelper.find(oScope, true, "sap/ui/table/Table");
			for (var i = 0; i < aTables.length; i++) {
				if (!aTables[i].getTitle() && aTables[i].getAriaLabelledBy().length == 0) {
					SupportHelper.reportIssue(oIssueManager, "Table '" + aTables[i].getId() + "' does not have an accessible label.", Severity.High, aTables[i].getId());
				}
			}
		}
	});

	/*
	 * Validates sap.ui.core.Icon column templates.
	 */
	createRule({
		id : "ColumnTemplateIcon",
		categories: [Categories.Accessibility],
		title : "Column template validation - 'sap.ui.core.Icon'",
		description : "The 'decorative' property of control 'sap.ui.core.Icon' is set to 'true' although the control is used as column template.",
		resolution : "Set the 'decorative' property of control 'sap.ui.core.Icon' to 'false' if the control is used as column template.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			checkColumnTemplate(function(oTable, oColumn, oIconTemplate) {
				if (!oIconTemplate.isBound("decorative") && oIconTemplate.getDecorative()) {
					var sId = oColumn.getId();
					SupportHelper.reportIssue(oIssueManager, "Column '" + sId + "' of table '" + oTable.getId() + "' uses decorative 'sap.ui.core.Icon' control.", Severity.High, sId);
				}
			}, oScope, "sap/ui/core/Icon");
		}
	});

	/*
	 * Validates sap.m.Text column templates.
	 */
	createRule({
		id : "ColumnTemplateTextWrapping",
		categories: [Categories.Usage],
		title : "Column template validation - 'sap.m.Text'",
		description : "The 'wrapping' and/or 'renderWhitespace' property of the control 'sap.m.Text' is set to 'true' although the control is used as a column template.",
		resolution : "Set the 'wrapping' and 'renderWhitespace' property of the control 'sap.m.Text' to 'false' if the control is used as a column template.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			checkColumnTemplate(function(oTable, oColumn, oMTextTemplate) {
				if (oMTextTemplate.isBound("wrapping") || (!oMTextTemplate.isBound("wrapping") && oMTextTemplate.getWrapping())) {
					var sColumnId = oColumn.getId();
					SupportHelper.reportIssue(oIssueManager, "Column '" + sColumnId + "' of table '" + oTable.getId() + "' uses an 'sap.m.Text' control with wrapping enabled.", Severity.High, sColumnId);
				}
				if (oMTextTemplate.isBound("renderWhitespace") || (!oMTextTemplate.isBound("renderWhitespace") && oMTextTemplate.getRenderWhitespace())) {
					var sColumnId = oColumn.getId();
					SupportHelper.reportIssue(oIssueManager, "Column '" + sColumnId + "' of table '" + oTable.getId() + "' uses an 'sap.m.Text' control with renderWhitespace enabled.", Severity.High, sColumnId);
				}
			}, oScope, "sap/m/Text");
		}
	});

	/*
	 * Checks for No Deviating units issue in AnalyticalBinding
	 */
	createRule({
		id : "AnalyticsNoDeviatingUnits",
		categories: [Categories.Bindings],
		title : "Analytical Binding reports 'No deviating units found...'",
		description : "The analytical service returns duplicate IDs. This could also lead to many requests, but the analytical service expects to receive just one record",
		resolution : "Adjust the service implementation.",
		check : function(oIssueManager, oCoreFacade, oScope) {
			var aTables = SupportHelper.find(oScope, true, "sap/ui/table/AnalyticalTable");
			var sAnalyticalErrorId = "NO_DEVIATING_UNITS";
			var oIssues = {};

			SupportHelper.checkLogEntries(function(oLogEntry) {
				// Filter out totally irrelevant issues
				if (oLogEntry.level != jQuery.sap.log.Level.ERROR && oLogEntry.level != jQuery.sap.log.Level.FATAL) {
					return false;
				}
				var oInfo = oLogEntry.supportInfo;
				if (oInfo && oInfo.type === "sap.ui.model.analytics.AnalyticalBinding" && oInfo.analyticalError === sAnalyticalErrorId) {
					return true;
				}
				return false;
			}, function(oLogEntry){
				// Check the remaining Issues
				var sBindingId = oLogEntry.supportInfo.analyticalBindingId;
				if (sBindingId && !oIssues[sAnalyticalErrorId + "-" + sBindingId]) {
					var oBinding;
					for (var i = 0; i < aTables.length; i++) {
						oBinding = aTables[i].getBinding("rows");
						if (oBinding && oBinding.__supportUID === sBindingId) {
							oIssues[sAnalyticalErrorId + "-" + sBindingId] = true; // Ensure is only reported once
							SupportHelper.reportIssue(oIssueManager, "Analytical Binding reports 'No deviating units found...'", Severity.High, aTables[i].getId());
						}
					}
				}
			});
		}
	});

	/*
	 * Checks whether the currently visible rows have the expected height.
	 */
	createRule({
		id : "RowHeights",
		categories: [Categories.Usage],
		title : "Row heights",
		description : "Checks whether the currently visible rows have the expected height.",
		resolution : "Check whether content densities are correctly used, and only the supported controls are used as column templates, with their"
					 + " wrapping property set to \"false\"",
		resolutionurls: [
			SupportHelper.createDocuRef("Documentation: Content Densities", "#docs/guide/e54f729da8e3405fae5e4fe8ae7784c1.html"),
			SupportHelper.createDocuRef("Documentation: Supported controls", "#docs/guide/148892ff9aea4a18b912829791e38f3e.html"),
			{text: "SAP Fiori Design Guidelines: Grid Table", href: "https://experience.sap.com/fiori-design-web/grid-table/"}/*,
			SupportHelper.createDocuRef("API Reference: Column #setTemplate", "#docs/api/symbols/sap.ui.table.Column.html#setTemplate")*/
		],
		check: function(oIssueManager, oCoreFacade, oScope) {
			var aTables = SupportHelper.find(oScope, true, "sap/ui/table/Table");
			var aVisibleRows;
			var fActualRowHeight;
			var iExpectedRowHeight;
			var oRowElement;
			var bIsZoomedInChrome = Device.browser.chrome && window.devicePixelRatio != 1;
			var bUnexpectedRowHeightDetected = false;

			for (var i = 0; i < aTables.length; i++) {
				aVisibleRows = aTables[i].getRows();
				iExpectedRowHeight = aTables[i]._getDefaultRowHeight();

				for (var j = 0; j < aVisibleRows.length; j++) {
					oRowElement = aVisibleRows[j].getDomRef();

					if (oRowElement != null) {
						fActualRowHeight = oRowElement.getBoundingClientRect().height;

						if (bIsZoomedInChrome) {
							var nHeightDeviation = Math.abs(iExpectedRowHeight - fActualRowHeight);
							if (nHeightDeviation > 1) {
								// If zoomed in Chrome, the actual height may deviate from the expected height by less than 1 pixel. Any higher
								// deviation shall be considered as defective.
								bUnexpectedRowHeightDetected = true;
							}
						} else if (fActualRowHeight !== iExpectedRowHeight) {
							bUnexpectedRowHeightDetected = true;
						}

						if (bUnexpectedRowHeightDetected) {
							SupportHelper.reportIssue(oIssueManager,
								"The row height was expected to be " + iExpectedRowHeight + "px, but was " + fActualRowHeight + "px instead."
								+ " This causes issues with vertical scrolling.",
								Severity.High, aVisibleRows[j].getId());
							break;
						}
					}
				}
			}
		}
	});

	return {lib: oLib, ruleset: oRuleset};

}, true);
<|endoftext|>


<commit_before>angular.module("application").controller("FileGenerationScheduleController", [
    "$scope", "$modal", "FileGenerationSchedule", "EmailNotification", "$rootScope", function ($scope, $modal, FileGenerationSchedule, EmailNotification, $rootScope) {

        $scope.$on('emailClicked', function (event, mass) {
            $scope.gridContainer.notificationGrid.dataSource.read();
        });

        $scope.EmailHelpText = $rootScope.HelpTexts.EmailHelpText.text;

        $scope.gridContainer = {};

        ///
        /// Loads existing FileGenerationSchedules from backend to kendo grid datasource.
        ///
        $scope.notifications = {
            autoBind : false,
            dataSource: {
                type: "odata",
                transport: {
                    read: {
                        beforeSend: function (req) {
                            req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
                        },
                        url: "/odata/FileGenerationSchedule?$expand=MailNotificationSchedules",
                        dataType: "json",
                        cache: false
                    },
                    parameterMap: function (options, type) {
                        var d = kendo.data.transports.odata.parameterMap(options);
                        delete d.$inlinecount; // <-- remove inlinecount parameter
                        d.$count = true;
                        return d;
                    }
                },
                schema: {
                    data: function (data) {
                        return data.value;
                    },
                    total: function (data) {
                        return data['@odata.count']; // <-- The total items count is the data length, there is no .Count to unpack.
                    }
                },
                pageSize: 20,
                serverPaging: false,
                serverSorting: true
            },
            sortable: true,
            pageable: {
                messages: {
                    display: "{0} - {1} af {2} adviseringer", //{0} is the index of the first record on the page, {1} - index of the last record on the page, {2} is the total amount of records
                    empty: "Ingen adviseringer at vise",
                    page: "Side",
                    of: "af {0}", //{0} is total amount of pages
                    itemsPerPage: "adviseringer pr. side",
                    first: "Gå til første side",
                    previous: "Gå til forrige side",
                    next: "Gå til næste side",
                    last: "Gå til sidste side",
                    refresh: "Genopfrisk"
                },
                pageSizes: [5, 10, 20, 30, 40, 50, 100, 150, 200]
            },
            scrollable: false,
            columns: [
                {
                    field: "DateTimestamp",
                    title: "Lønkørsel",
                    template: function (data) {
                        var m = moment.unix(data.DateTimestamp);
                        return m._d.getDate() + "/" +
                            (m._d.getMonth() + 1) + "/" + // +1 because getMonth is zero indexed.
                            m._d.getFullYear();
                    }
                }, {
                    field: "Repeat",
                    title: "Gentag månedligt",
                    template: function (data) {
                        if (data.Repeat) {
                            return "Ja";
                        }
                        return "Nej";
                    }
                }, {
                    //field: "Notified",
                    title: "Er kørt",
                    template: function (data) {
                        if (data.DateTimestamp < moment().unix()) {
                            return "";
                        }
                        return "";
                    }
                },
                {
                    //field: "MailNotificationSchedules",
                    title: "Emailadvis sendt",
                    template: function (data) {
                        if (data.MailNotificationSchedules.length > 0){
                            console.log(moment().unix());
                            if(data.MailNotificationSchedules[0].DateTimestamp < moment().unix()) {
                                return "";
                            }
                        }
                        return "";
                    }
                },
                {
                    field: "Id",
                    template: "Redigér | Slet",
                    title: "Muligheder"
                }
            ]
        };

        $scope.updateNotificationGrid = function () {
            ///
            /// Refreshes kendo grid datasource.
            ///
            $scope.gridContainer.notificationGrid.dataSource.read();
        }

        $scope.editClick = function (id) {
            ///
            /// Opens Edit MailNotification modal
            ///
            /// <param name="id">Id of MailNotification to edit</param>
            var modalInstance = $modal.open({
                templateUrl: '/App/Admin/HTML/Email/AddEditFileGenerationScheduleTemplate.html',
                controller: 'AddEditFileGenerationScheduleController',
                backdrop: "static",
                resolve: {
                    itemId: function () {
                        return id;
                    }
                }
            });

            modalInstance.result.then(function (result) {
                FileGenerationSchedule.patch({ id: id }, {
                    "DateTimestamp": result.FileGenerationSchedule.DateTimestamp,
                    "Repeat": result.FileGenerationSchedule.Repeat
                }, function() {
                    $scope.updateNotificationGrid();
                });

                angular.forEach(result.DeletedMailsIds, function(deleteId) {
                    if(deleteId > 0) {
                        EmailNotification.delete({ id: deleteId} );
                    }
                });

                angular.forEach(result.FileGenerationSchedule.MailNotificationSchedules, function(mailnotif){
                    if(mailnotif.Id > 0) {
                        EmailNotification.patch({id: mailnotif.Id}, {
                            "DateTimestamp": mailnotif.DateTimestamp,
                            "CustomText": mailnotif.CustomText
                        });
                    }
                    else {
                        mailnotif.FileGenerationScheduleId = id;
                        EmailNotification.post(mailnotif);
                    }
                });
            });
        }

        //$scope.pageSizeChanged = function () {
        //    $scope.gridContainer.notificationGrid.dataSource.pageSize(Number($scope.gridContainer.gridPageSize));
        //}

        $scope.deleteClick = function (id) {
            ///
            /// Opens delete MailNotification modal
            ///
            /// <param name="id">Id of MailNotification to delete</param>
            var modalInstance = $modal.open({
                templateUrl: '/App/Admin/HTML/Email/ConfirmDeleteFileGenerationScheduleTemplate.html',
                controller: 'DeleteFileGenerationScheduleController',
                backdrop: "static",
                resolve: {
                    itemId: function () {
                        return id;
                    }
                }
            });

            modalInstance.result.then(function () {
                FileGenerationSchedule.delete({ id: id }, function () {
                    $scope.updateNotificationGrid();
                });
            });
        }

        $scope.addNewClick = function () {
            ///
            /// Opens add new MailNotification modal
            ///
            var modalInstance = $modal.open({
                templateUrl: '/App/Admin/HTML/Email/AddEditFileGenerationScheduleTemplate.html',
                controller: 'AddEditFileGenerationScheduleController',
                backdrop: "static",
                resolve: {
                    itemId: function () {
                        return -1;
                    }
                }
            });

            modalInstance.result.then(function (result) {
                FileGenerationSchedule.post(result.FileGenerationSchedule, function () {
                    $scope.updateNotificationGrid();
                });
            });
        }

    }
]);
<commit_msg>Removed console output from the file generation schedule<commit_after>angular.module("application").controller("FileGenerationScheduleController", [
    "$scope", "$modal", "FileGenerationSchedule", "EmailNotification", "$rootScope", function ($scope, $modal, FileGenerationSchedule, EmailNotification, $rootScope) {

        $scope.$on('emailClicked', function (event, mass) {
            $scope.gridContainer.notificationGrid.dataSource.read();
        });

        $scope.EmailHelpText = $rootScope.HelpTexts.EmailHelpText.text;

        $scope.gridContainer = {};

        ///
        /// Loads existing FileGenerationSchedules from backend to kendo grid datasource.
        ///
        $scope.notifications = {
            autoBind : false,
            dataSource: {
                type: "odata",
                transport: {
                    read: {
                        beforeSend: function (req) {
                            req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
                        },
                        url: "/odata/FileGenerationSchedule?$expand=MailNotificationSchedules",
                        dataType: "json",
                        cache: false
                    },
                    parameterMap: function (options, type) {
                        var d = kendo.data.transports.odata.parameterMap(options);
                        delete d.$inlinecount; // <-- remove inlinecount parameter
                        d.$count = true;
                        return d;
                    }
                },
                schema: {
                    data: function (data) {
                        return data.value;
                    },
                    total: function (data) {
                        return data['@odata.count']; // <-- The total items count is the data length, there is no .Count to unpack.
                    }
                },
                pageSize: 20,
                serverPaging: false,
                serverSorting: true
            },
            sortable: true,
            pageable: {
                messages: {
                    display: "{0} - {1} af {2} adviseringer", //{0} is the index of the first record on the page, {1} - index of the last record on the page, {2} is the total amount of records
                    empty: "Ingen adviseringer at vise",
                    page: "Side",
                    of: "af {0}", //{0} is total amount of pages
                    itemsPerPage: "adviseringer pr. side",
                    first: "Gå til første side",
                    previous: "Gå til forrige side",
                    next: "Gå til næste side",
                    last: "Gå til sidste side",
                    refresh: "Genopfrisk"
                },
                pageSizes: [5, 10, 20, 30, 40, 50, 100, 150, 200]
            },
            scrollable: false,
            columns: [
                {
                    field: "DateTimestamp",
                    title: "Lønkørsel",
                    template: function (data) {
                        var m = moment.unix(data.DateTimestamp);
                        return m._d.getDate() + "/" +
                            (m._d.getMonth() + 1) + "/" + // +1 because getMonth is zero indexed.
                            m._d.getFullYear();
                    }
                }, {
                    field: "Repeat",
                    title: "Gentag månedligt",
                    template: function (data) {
                        if (data.Repeat) {
                            return "Ja";
                        }
                        return "Nej";
                    }
                }, {
                    //field: "Notified",
                    title: "Er kørt",
                    template: function (data) {
                        if (data.DateTimestamp < moment().unix()) {
                            return "";
                        }
                        return "";
                    }
                },
                {
                    //field: "MailNotificationSchedules",
                    title: "Emailadvis sendt",
                    template: function (data) {
                        if (data.MailNotificationSchedules.length > 0){
                            if(data.MailNotificationSchedules[0].DateTimestamp < moment().unix()) {
                                return "";
                            }
                        }
                        return "";
                    }
                },
                {
                    field: "Id",
                    template: "Redigér | Slet",
                    title: "Muligheder"
                }
            ]
        };

        $scope.updateNotificationGrid = function () {
            ///
            /// Refreshes kendo grid datasource.
            ///
            $scope.gridContainer.notificationGrid.dataSource.read();
        }

        $scope.editClick = function (id) {
            ///
            /// Opens Edit MailNotification modal
            ///
            /// <param name="id">Id of MailNotification to edit</param>
            var modalInstance = $modal.open({
                templateUrl: '/App/Admin/HTML/Email/AddEditFileGenerationScheduleTemplate.html',
                controller: 'AddEditFileGenerationScheduleController',
                backdrop: "static",
                resolve: {
                    itemId: function () {
                        return id;
                    }
                }
            });

            modalInstance.result.then(function (result) {
                FileGenerationSchedule.patch({ id: id }, {
                    "DateTimestamp": result.FileGenerationSchedule.DateTimestamp,
                    "Repeat": result.FileGenerationSchedule.Repeat
                }, function() {
                    $scope.updateNotificationGrid();
                });

                angular.forEach(result.DeletedMailsIds, function(deleteId) {
                    if(deleteId > 0) {
                        EmailNotification.delete({ id: deleteId} );
                    }
                });

                angular.forEach(result.FileGenerationSchedule.MailNotificationSchedules, function(mailnotif){
                    if(mailnotif.Id > 0) {
                        EmailNotification.patch({id: mailnotif.Id}, {
                            "DateTimestamp": mailnotif.DateTimestamp,
                            "CustomText": mailnotif.CustomText
                        });
                    }
                    else {
                        mailnotif.FileGenerationScheduleId = id;
                        EmailNotification.post(mailnotif);
                    }
                });
            });
        }

        //$scope.pageSizeChanged = function () {
        //    $scope.gridContainer.notificationGrid.dataSource.pageSize(Number($scope.gridContainer.gridPageSize));
        //}

        $scope.deleteClick = function (id) {
            ///
            /// Opens delete MailNotification modal
            ///
            /// <param name="id">Id of MailNotification to delete</param>
            var modalInstance = $modal.open({
                templateUrl: '/App/Admin/HTML/Email/ConfirmDeleteFileGenerationScheduleTemplate.html',
                controller: 'DeleteFileGenerationScheduleController',
                backdrop: "static",
                resolve: {
                    itemId: function () {
                        return id;
                    }
                }
            });

            modalInstance.result.then(function () {
                FileGenerationSchedule.delete({ id: id }, function () {
                    $scope.updateNotificationGrid();
                });
            });
        }

        $scope.addNewClick = function () {
            ///
            /// Opens add new MailNotification modal
            ///
            var modalInstance = $modal.open({
                templateUrl: '/App/Admin/HTML/Email/AddEditFileGenerationScheduleTemplate.html',
                controller: 'AddEditFileGenerationScheduleController',
                backdrop: "static",
                resolve: {
                    itemId: function () {
                        return -1;
                    }
                }
            });

            modalInstance.result.then(function (result) {
                FileGenerationSchedule.post(result.FileGenerationSchedule, function () {
                    $scope.updateNotificationGrid();
                });
            });
        }

    }
]);
<|endoftext|>


<commit_before>// @flow
import * as KBFSGen from '../actions/kbfs-gen'
import Banner from './install/banner'
import InstallSecurityPrefs from './install/security-prefs'
import List from './list'
import React, {Component} from 'react'
import {Box, TabBar} from '../common-adapters'
import {TabBarItem, TabBarButton} from '../common-adapters/tab-bar'
import {connect, type TypedState} from '../util/container'
import {globalStyles, globalColors, globalMargins} from '../styles'
import {isLinux} from '../constants/platform'
import {type Props, type FolderType} from '.'

class FoldersRender extends Component<Props> {
  _makeItem(folderType: FolderType, isSelected: boolean) {
    let isPublic = folderType === 'public'
    const icon = isPublic ? 'iconfont-folder-public' : 'iconfont-folder-private'
    const selectedColor = isPublic ? globalColors.yellowGreen : globalColors.darkBlue2
    const iconStyle = isPublic
      ? {color: globalColors.yellowGreen2, marginBottom: isSelected ? 0 : 0, opacity: isSelected ? 1.0 : 0.6}
      : {color: globalColors.darkBlue2, marginBottom: isSelected ? 0 : 0, opacity: isSelected ? 1.0 : 0.6}
    const badgeNumber = this.props[folderType + 'Badge']
    return (
      <TabBarButton
        source={{type: 'icon', icon}}
        style={{
          ...styleItem,
          borderBottom: `solid 2px ${isSelected ? selectedColor : 'transparent'}`,
          paddingLeft: 0,
          width: 106 + 2 / 3,
        }}
        styleBadge={styleBadge}
        styleBadgeContainer={{position: 'absolute', right: -1 * globalMargins.tiny}}
        styleIcon={{...styleIcon, ...iconStyle}}
        styleLabel={{
          color: isPublic ? globalColors.yellowGreen2 : globalColors.darkBlue,
          opacity: isSelected ? 1 : 0.6,
          fontSize: 12,
        }}
        selected={isSelected}
        label={`${folderType}/`}
        badgeNumber={badgeNumber}
      />
    )
  }

  render() {
    if (this.props.showSecurityPrefs) {
      return <InstallSecurityPrefs />
    }

    const sharedListProps = {
      style: this.props.listStyle,
      smallMode: this.props.smallMode,
      onRekey: this.props.onRekey,
      onOpen: this.props.onOpen,
      onChat: this.props.onChat,
      onClick: this.props.onClick,
      installed: this.props.installed,
    }

    return (
      <Box
        style={{
          ...stylesContainer,
          backgroundColor: globalColors.white,
          paddingTop: 0,
          minHeight: 32,
        }}
      >
        {!this.props.smallMode && !isLinux && <Banner />}
        <TabBar
          styleTabBar={{
            ...tabBarStyle,
            backgroundColor: !this.props.smallMode && !this.props.installed
              ? globalColors.grey
              : globalColors.white,
            minHeight: this.props.smallMode ? 32 : 48,
          }}
        >
          {['private', 'public', 'team'].map(selected => (
            <TabBarItem
              key={selected}
              selected={this.props.selected === selected}
              styleContainer={itemContainerStyle}
              tabBarButton={this._makeItem(selected, this.props.selected === selected)}
              onClick={() => {
                this.props.onSwitchTab && this.props.onSwitchTab(selected)
              }}
            >
              <List
                {...this.props[selected]}
                {...sharedListProps}
                type={selected}
                showIgnored={this.props.showingIgnored}
                onToggleShowIgnored={this.props.onToggleShowIgnored}
              />
            </TabBarItem>
          ))}
        </TabBar>
      </Box>
    )
  }
}

const stylesContainer = {
  ...globalStyles.flexBoxColumn,
  flexGrow: 1,
}

const styleBadge = {
  marginRight: 2,
  marginLeft: 2,
}

const styleIcon = {
  marginBottom: 2,
}

const styleItem = {
  ...globalStyles.flexBoxRow,
  paddingTop: 8,
  paddingBottom: 8,
  justifyContent: 'center',
  backgroundColor: globalColors.transparent,
}

const itemContainerStyle = {
  ...globalStyles.flexBoxColumn,
  marginBottom: -1,
}

const tabBarStyle = {
  ...globalStyles.flexBoxRow,
}

const mapStateToProps = (state: TypedState) => {
  const installed = isLinux || (state.favorite.fuseStatus && state.favorite.fuseStatus.kextStarted)
  return {
    installed,
    showSecurityPrefs: !installed && state.favorite.kextPermissionError,
  }
}

const mapDispatchToProps = (dispatch: any) => ({
  fuseStatus: () => dispatch(KBFSGen.createFuseStatus()),
})

export default connect(mapStateToProps, mapDispatchToProps)(FoldersRender)
<commit_msg>Add comment<commit_after>// @flow
import * as KBFSGen from '../actions/kbfs-gen'
import Banner from './install/banner'
import InstallSecurityPrefs from './install/security-prefs'
import List from './list'
import React, {Component} from 'react'
import {Box, TabBar} from '../common-adapters'
import {TabBarItem, TabBarButton} from '../common-adapters/tab-bar'
import {connect, type TypedState} from '../util/container'
import {globalStyles, globalColors, globalMargins} from '../styles'
import {isLinux} from '../constants/platform'
import {type Props, type FolderType} from '.'

// NOTE: This component is also used in menu-bar (widget)
// Make sure to check behavior there if you're changing this
class FoldersRender extends Component<Props> {
  _makeItem(folderType: FolderType, isSelected: boolean) {
    let isPublic = folderType === 'public'
    const icon = isPublic ? 'iconfont-folder-public' : 'iconfont-folder-private'
    const selectedColor = isPublic ? globalColors.yellowGreen : globalColors.darkBlue2
    const iconStyle = isPublic
      ? {color: globalColors.yellowGreen2, marginBottom: isSelected ? 0 : 0, opacity: isSelected ? 1.0 : 0.6}
      : {color: globalColors.darkBlue2, marginBottom: isSelected ? 0 : 0, opacity: isSelected ? 1.0 : 0.6}
    const badgeNumber = this.props[folderType + 'Badge']
    return (
      <TabBarButton
        source={{type: 'icon', icon}}
        style={{
          ...styleItem,
          borderBottom: `solid 2px ${isSelected ? selectedColor : 'transparent'}`,
          paddingLeft: 0,
          width: 106 + 2 / 3,
        }}
        styleBadge={styleBadge}
        styleBadgeContainer={{position: 'absolute', right: -1 * globalMargins.tiny}}
        styleIcon={{...styleIcon, ...iconStyle}}
        styleLabel={{
          color: isPublic ? globalColors.yellowGreen2 : globalColors.darkBlue,
          opacity: isSelected ? 1 : 0.6,
          fontSize: 12,
        }}
        selected={isSelected}
        label={`${folderType}/`}
        badgeNumber={badgeNumber}
      />
    )
  }

  render() {
    if (this.props.showSecurityPrefs) {
      return <InstallSecurityPrefs />
    }

    const sharedListProps = {
      style: this.props.listStyle,
      smallMode: this.props.smallMode,
      onRekey: this.props.onRekey,
      onOpen: this.props.onOpen,
      onChat: this.props.onChat,
      onClick: this.props.onClick,
      installed: this.props.installed,
    }

    return (
      <Box
        style={{
          ...stylesContainer,
          backgroundColor: globalColors.white,
          paddingTop: 0,
          minHeight: 32,
        }}
      >
        {!this.props.smallMode && !isLinux && <Banner />}
        <TabBar
          styleTabBar={{
            ...tabBarStyle,
            backgroundColor: !this.props.smallMode && !this.props.installed
              ? globalColors.grey
              : globalColors.white,
            minHeight: this.props.smallMode ? 32 : 48,
          }}
        >
          {['private', 'public', 'team'].map(selected => (
            <TabBarItem
              key={selected}
              selected={this.props.selected === selected}
              styleContainer={itemContainerStyle}
              tabBarButton={this._makeItem(selected, this.props.selected === selected)}
              onClick={() => {
                this.props.onSwitchTab && this.props.onSwitchTab(selected)
              }}
            >
              <List
                {...this.props[selected]}
                {...sharedListProps}
                type={selected}
                showIgnored={this.props.showingIgnored}
                onToggleShowIgnored={this.props.onToggleShowIgnored}
              />
            </TabBarItem>
          ))}
        </TabBar>
      </Box>
    )
  }
}

const stylesContainer = {
  ...globalStyles.flexBoxColumn,
  flexGrow: 1,
}

const styleBadge = {
  marginRight: 2,
  marginLeft: 2,
}

const styleIcon = {
  marginBottom: 2,
}

const styleItem = {
  ...globalStyles.flexBoxRow,
  paddingTop: 8,
  paddingBottom: 8,
  justifyContent: 'center',
  backgroundColor: globalColors.transparent,
}

const itemContainerStyle = {
  ...globalStyles.flexBoxColumn,
  marginBottom: -1,
}

const tabBarStyle = {
  ...globalStyles.flexBoxRow,
}

const mapStateToProps = (state: TypedState) => {
  const installed = isLinux || (state.favorite.fuseStatus && state.favorite.fuseStatus.kextStarted)
  return {
    installed,
    showSecurityPrefs: !installed && state.favorite.kextPermissionError,
  }
}

const mapDispatchToProps = (dispatch: any) => ({
  fuseStatus: () => dispatch(KBFSGen.createFuseStatus()),
})

export default connect(mapStateToProps, mapDispatchToProps)(FoldersRender)
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import hoistStatics                    from 'hoist-non-react-statics';

const { shape, func } = PropTypes;
/**
 * Should always be a top level (outermost) decorator because
 * on the server all static `needs` properties are collected
 * to pass them to fetchComponentData.
 *
 * @param needs
 * @returns {Function}
 */
export default (needs) => {
  return WrappedComponent => {
    class FetchDataDecorator extends Component {
      static WrappedComponent = WrappedComponent;
      static needs = needs;

      static propTypes = {
        params: PropTypes.object.isRequired
      };

      static contextTypes = {
        store: shape({
          dispatch: func.isRequired
        })
      };

      componentDidMount() {
        const { dispatch } = this.context.store;

        const promises = needs.map(need => dispatch(need(this.props.params)));

        Promise.all(promises);
      }

      render() {
        return <WrappedComponent {...this.props} />;
      }
    }

    return hoistStatics(FetchDataDecorator, WrappedComponent)
  };
}
<commit_msg>Prettify<commit_after>import React, { Component, PropTypes } from 'react';
import hoistStatics                    from 'hoist-non-react-statics';

const { shape, func, object } = PropTypes;

/**
 * Should always be a top level (outermost) decorator because
 * on the server all static `needs` properties are collected
 * to pass them to fetchComponentData.
 *
 * @param needs
 * @returns {Function}
 */
export default (needs) => {
  return WrappedComponent => {
    class FetchDataDecorator extends Component {
      static WrappedComponent = WrappedComponent;
      static needs = needs;

      static propTypes = {
        params: object.isRequired
      };

      static contextTypes = {
        store: shape({
          dispatch: func.isRequired
        })
      };

      componentDidMount() {
        const { dispatch } = this.context.store;

        const promises = needs.map(need => dispatch(need(this.props.params)));

        Promise.all(promises);
      }

      render() {
        return <WrappedComponent {...this.props} />;
      }
    }

    return hoistStatics(FetchDataDecorator, WrappedComponent)
  };
}
<|endoftext|>


<commit_before>//var octSort = require('./utils/octTreeSort');

function getDistance(vertA, vertB)
{
	return Math.sqrt(
		Math.pow(vertB.x  - vertA.x, 2) +
		Math.pow(vertB.y  - vertA.y, 2) +
		Math.pow(vertB.z  - vertA.z, 2)
	);
}

function permutator(inputArr) {
  var results = [];

  function permute(arr, memo) {
    var cur, memo = memo || [];

    for (var i = 0; i < arr.length; i++) {
      cur = arr.splice(i, 1);
      if (arr.length === 0) {
        results.push(memo.concat(cur));
      }
      permute(arr.slice(), memo.concat(cur));
      arr.splice(i, 0, cur[0]);
    }
    return results;
  }

  return permute(inputArr);
}

function pairClosestPoints(vertsA, vertsB) {

	var baseArr = [];
	for (var i = 0; i < vertsA.length; i++) {
		baseArr.push(i);
	};
	var allperms = permutator(baseArr);
	var alldistances = [];

	for (var i = 0; i < allperms.length; i++)
	{
		var perm = allperms[i];

		var distance = 0;
		for (var j = 0; j < vertsA.length; j++)
		{
			distance += getDistance(vertsA[j], vertsB[perm[j]]);
		}

		alldistances.push({ dist: distance, index: i });
	}

	alldistances.sort(function(a, b) {
		return a.dist - b.dist;
	});

	var lowest = alldistances[0];
	var lowestsoln = allperms[lowest.index];

	console.log('lowest distance: ', lowest.dist);
	console.log('lowest index: ', lowest.index);
	console.log('lowest solution: ', lowestsoln);

	var newVertsB = [];
	for (var k = 0; k < lowestsoln.length; k++)
	{
		var newindex = lowestsoln[k];
		newVertsB.push(vertsB[newindex].clone());
	}

	// Copy newVertsB into vertsB
	for (var k = 0; k < vertsB.length; k++) {
		vertsB[k].copy(newVertsB[k]);
	}
}

module.exports = pairClosestPoints;<commit_msg>precomputed distances instead of computing every iteration<commit_after>//var octSort = require('./utils/octTreeSort');

function getDistance(vertA, vertB)
{
	return Math.sqrt(
		Math.pow(vertB.x  - vertA.x, 2) +
		Math.pow(vertB.y  - vertA.y, 2) +
		Math.pow(vertB.z  - vertA.z, 2)
	);
}

function permutator(inputArr) {
  var results = [];

  function permute(arr, memo) {
    var cur, memo = memo || [];

    for (var i = 0; i < arr.length; i++) {
      cur = arr.splice(i, 1);
      if (arr.length === 0) {
        results.push(memo.concat(cur));
      }
      permute(arr.slice(), memo.concat(cur));
      arr.splice(i, 0, cur[0]);
    }
    return results;
  }

  return permute(inputArr);
}

function pairClosestPoints(vertsA, vertsB) {

	var baseArr = [];
	for (var i = 0; i < vertsA.length; i++) {
		baseArr.push(i);
	};
	var allperms = permutator(baseArr);
	var alldistances = [];

	// Precompute all distance combinations from VertA to VertB first
	var precomputedDistances = [];

	for (var i = 0; i < vertsA.length; i++)
	{
		precomputedDistances.push([]);

		for (var j = 0; j < vertsB.length; j++)
		{
			precomputedDistances[i][j] = getDistance(vertsA[i], vertsB[j]);
		}
	}

	// Use precomputed distances instead of computing every iteration
	for (var i = 0; i < allperms.length; i++)
	{
		var perm = allperms[i];

		var distance = 0;
		for (var j = 0; j < vertsA.length; j++)
		{
			distance += precomputedDistances[j][perm[j]];
			//getDistance(vertsA[j], vertsB[perm[j]]);
		}

		alldistances.push({ dist: distance, index: i });
	}

	alldistances.sort(function(a, b) {
		return a.dist - b.dist;
	});

	var lowest = alldistances[0];
	var lowestsoln = allperms[lowest.index];

	console.log('lowest distance: ', lowest.dist);
	console.log('lowest index: ', lowest.index);
	console.log('lowest solution: ', lowestsoln);

	var newVertsB = [];
	for (var k = 0; k < lowestsoln.length; k++)
	{
		var newindex = lowestsoln[k];
		newVertsB.push(vertsB[newindex].clone());
	}

	// Copy newVertsB into vertsB
	for (var k = 0; k < vertsB.length; k++) {
		vertsB[k].copy(newVertsB[k]);
	}

}

module.exports = pairClosestPoints;<|endoftext|>


<commit_before>openerp.base_calendar = function(instance) {
var _t = instance.web._t;
var QWeb = instance.web.qweb;
instance.base_calendar = {}

    instance.base_calendar.invite = instance.web.Widget.extend({

        init: function(parent,db,token,action,view_type,status) {
            this._super();
            this.db = db;
            this.token = token;
            this.status = status;
            this.action = action;
            this.view_type = view_type;
            this.ds_attendee = new instance.web.DataSetSearch(this, 'calendar.attendee');
        },
        start: function() {
            var self = this;
            if (instance.session.session_is_valid(self.db)) {
                self.show_meeting();
            } else {
                self.show_login()
            }
        },
        show_login: function(action) {
            var self =  this;
            this.destroy_content();
            this.login = new instance.web.Login_extended(this,self.action);
            this.login.appendTo(this.$el);
            this.login.on('db_loaded',self,function(db,login){
                if (instance.session.session_is_valid(db)) {
                    (self.show_meeting()).done(function(){
                        self.login.off('db_loaded');
                    });
                }
                else{
                    self.show_login();
                }
            })
        },
        destroy_content: function() {
            _.each(_.clone(this.getChildren()), function(el) {
                el.destroy();
            });
            this.$el.children().remove();
        },
        show_meeting : function(){
            var db = this.db;
            var att_status = "do_decline";
            var self = this;
            if(self.status === 'accepted'){att_status = "do_accept";}
            return this.ds_attendee.call(att_status,[[parseInt(this.token)]]).done(function(res){
                location.replace(_.str.sprintf('/?db=%s#view_type=%s&model=crm.meeting&action=%s&id=%s',self.db,self.view_type,self.action,self.token));
            });
        },
    });
    instance.web.Login_extended = instance.web.Login.extend({
        do_login: function (db, login, password) {
            var self = this;
            (this._super.apply(this,arguments)).done(function(){
               self.trigger('db_loaded',db,login)
            });
        }
    });
    instance.web.form.Many2Many_invite = instance.web.form.FieldMany2ManyTags.extend({
        initialize_content: function() {
            var self = this;
            var ignore_blur = false;
            self.$text = this.$("textarea");
            if (this.get("effective_readonly"))
                return;
            self.$text.textext({
                plugins : 'tags arrow autocomplete',
                html: {
                    tag: '

'
                },
                autocomplete: {
                    render: function(suggestion) {
                        return $('').
                                 data('index', suggestion['index']).html(suggestion['label']);
                    }
                },
                ext: {
                    autocomplete: {
                        selectFromDropdown: function() {
                            this.trigger('hideDropdown');
                            var index = Number(this.selectedSuggestionElement().children().children().data('index'));
                            var data = self.search_result[index];
                            if (data.id) {
                                self.add_id(data.id);
                            } else {
                                ignore_blur = true;
                                data.action();
                            }
                            this.trigger('setSuggestions', {result : []});
                        },
                    },
                    tags: {
                        isTagAllowed: function(tag) {
                            return !!tag.name;

                        },
                        removeTag: function(tag) {
                            var id = tag.data("id");
                            self.set({"value": _.without(self.get("value"), id)});
                        },
                        renderTag: function(stuff) {
                            return $.fn.textext.TextExtTags.prototype.renderTag.
                                call(this, stuff).data("id", stuff.id);
                        },
                    },
                    itemManager: {
                        itemToString: function(item) {
                            return item.name;
                        },
                    },
                    core: {
                        onSetInputData: function(e, data) {
                            if (data == '') {
                                this._plugins.autocomplete._suggestions = null;
                            }
                            this.input().val(data);
                        },
                    },
                },
            }).bind('getSuggestions', function(e, data) {
                var _this = this;
                var str = !!data ? data.query || '' : '';
                self.get_search_result(str).done(function(result) {
                    self.search_result = result;
                    $(_this).trigger('setSuggestions', {result : _.map(result, function(el, i) {
                        return _.extend(el, {index:i});
                    })});
                });
            }).bind('hideDropdown', function() {
                self._drop_shown = false;
            }).bind('showDropdown', function() {
                self._drop_shown = true;
            });
            self.tags = self.$text.textext()[0].tags();
            self.$text
                .focusin(function () {
                    self.trigger('focused');
                    ignore_blur = false;
                })
                .focusout(function() {
                    self.$text.trigger("setInputData", "");
                    if (!ignore_blur) {
                        self.trigger('blurred');
                    }
                }).keydown(function(e) {
                    if (e.which === $.ui.keyCode.TAB && self._drop_shown) {
                        self.$text.textext()[0].autocomplete().selectFromDropdown();
                    }
                });
        },
        render_value: function() {
            var self = this;
            var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
            var values = self.get("value");
            var handle_names = function(data) {
                if (self.isDestroyed())
                    return;
                if (! self.get("effective_readonly")) {
                    self.tags.containerElement().children().remove();
                    self.$('textarea').css("padding-left", "3px");
                    self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};}));
                    var tag_element = self.tags.tagElements();
                    _.each(data,function(value, key){
                        $(tag_element[key]).find(".custom-edit").addClass(data[key][2])
                    })
                } else {
                    self.$el.html(QWeb.render("Many2Many_invite", {elements: data}));
                }
            };
            if (! values || values.length > 0) {
                if(self.getParent().datarecord.attendee_ids){
                    return new instance.web.Model("calendar.attendee").call('read',[self.getParent().datarecord.attendee_ids ,['state','cn','partner_id']]).then(function(res){
                        data = []
                        _.each(res,function(val){
                            data.push([val['partner_id'][0],val['cn'],val['state']])
                        });
                        handle_names(data)
                    });
                } else { this._display_orderer.add(dataset.name_get(values)).done(handle_names); }
            } else { handle_names([]); }
        },

    });
    instance.web.form.widgets = instance.web.form.widgets.extend({
        'Many2Many_invite' : 'instance.web.form.Many2Many_invite',
    });
    instance.base_calendar.event = function (db, token, action, view_type, status) {
        instance.session.session_bind(instance.session.origin).done(function () {
            new instance.base_calendar.invite(null,db,token,action,view_type,status).appendTo($("body").addClass('openerp'));
        });
    }
};
//vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<commit_msg>[IMP]Accept/reject must enable only single time from mail.<commit_after>openerp.base_calendar = function(instance) {
var _t = instance.web._t;
var QWeb = instance.web.qweb;
instance.base_calendar = {}

    instance.base_calendar.invite = instance.web.Widget.extend({

        init: function(parent,db,token,action,view_type,status) {
            this._super();
            this.db = db;
            this.token = token;
            this.status = status;
            this.action = action;
            this.view_type = view_type;
        },
        start: function() {
            var self = this;
            if (instance.session.session_is_valid(self.db)) {
                self.show_meeting();
            } else {
                self.show_login()
            }
        },
        show_login: function(action) {
            var self =  this;
            this.destroy_content();
            this.login = new instance.web.Login_extended(this,self.action);
            this.login.appendTo(this.$el);
            this.login.on('db_loaded',self,function(db,login){
                if (instance.session.session_is_valid(db)) {
                    (self.show_meeting()).done(function(){
                        self.login.off('db_loaded');
                    });
                }
                else{
                    self.show_login();
                }
            })
        },
        destroy_content: function() {
            _.each(_.clone(this.getChildren()), function(el) {
                el.destroy();
            });
            this.$el.children().remove();
        },
        show_meeting : function(){
            var db = this.db;
            var att_status = "do_decline";
            var self = this;
            var reload_page = function(){
                return location.replace(_.str.sprintf('/?db=%s#view_type=%s&model=crm.meeting&action=%s&id=%s',self.db,self.view_type,self.action,self.token));
            }
            if(self.status === 'accepted'){att_status = "do_accept";}
            var calender_attendee = new instance.web.Model('calendar.attendee')
            var check = calender_attendee.query(["state"]).filter([["id", "=", parseInt(this.token)]]).first();
            return check.done(function(res){
                if(res['state'] === "needs-action"){
                    return calender_attendee.call(att_status,[[parseInt(self.token)]]).done(reload_page);
                }
                reload_page();
            });
        },
    });
    instance.web.Login_extended = instance.web.Login.extend({
        do_login: function (db, login, password) {
            var self = this;
            (this._super.apply(this,arguments)).done(function(){
               self.trigger('db_loaded',db,login)
            });
        }
    });
    instance.web.form.Many2Many_invite = instance.web.form.FieldMany2ManyTags.extend({
        initialize_content: function() {
            var self = this;
            var ignore_blur = false;
            self.$text = this.$("textarea");
            if (this.get("effective_readonly"))
                return;
            self.$text.textext({
                plugins : 'tags arrow autocomplete',
                html: {
                    tag: '

'
                },
                autocomplete: {
                    render: function(suggestion) {
                        return $('').
                                 data('index', suggestion['index']).html(suggestion['label']);
                    }
                },
                ext: {
                    autocomplete: {
                        selectFromDropdown: function() {
                            this.trigger('hideDropdown');
                            var index = Number(this.selectedSuggestionElement().children().children().data('index'));
                            var data = self.search_result[index];
                            if (data.id) {
                                self.add_id(data.id);
                            } else {
                                ignore_blur = true;
                                data.action();
                            }
                            this.trigger('setSuggestions', {result : []});
                        },
                    },
                    tags: {
                        isTagAllowed: function(tag) {
                            return !!tag.name;

                        },
                        removeTag: function(tag) {
                            var id = tag.data("id");
                            self.set({"value": _.without(self.get("value"), id)});
                        },
                        renderTag: function(stuff) {
                            return $.fn.textext.TextExtTags.prototype.renderTag.
                                call(this, stuff).data("id", stuff.id);
                        },
                    },
                    itemManager: {
                        itemToString: function(item) {
                            return item.name;
                        },
                    },
                    core: {
                        onSetInputData: function(e, data) {
                            if (data == '') {
                                this._plugins.autocomplete._suggestions = null;
                            }
                            this.input().val(data);
                        },
                    },
                },
            }).bind('getSuggestions', function(e, data) {
                var _this = this;
                var str = !!data ? data.query || '' : '';
                self.get_search_result(str).done(function(result) {
                    self.search_result = result;
                    $(_this).trigger('setSuggestions', {result : _.map(result, function(el, i) {
                        return _.extend(el, {index:i});
                    })});
                });
            }).bind('hideDropdown', function() {
                self._drop_shown = false;
            }).bind('showDropdown', function() {
                self._drop_shown = true;
            });
            self.tags = self.$text.textext()[0].tags();
            self.$text
                .focusin(function () {
                    self.trigger('focused');
                    ignore_blur = false;
                })
                .focusout(function() {
                    self.$text.trigger("setInputData", "");
                    if (!ignore_blur) {
                        self.trigger('blurred');
                    }
                }).keydown(function(e) {
                    if (e.which === $.ui.keyCode.TAB && self._drop_shown) {
                        self.$text.textext()[0].autocomplete().selectFromDropdown();
                    }
                });
        },
        render_value: function() {
            var self = this;
            var dataset = new instance.web.DataSetStatic(this, this.field.relation, self.build_context());
            var values = self.get("value");
            var handle_names = function(data) {
                if (self.isDestroyed())
                    return;
                if (! self.get("effective_readonly")) {
                    self.tags.containerElement().children().remove();
                    self.$('textarea').css("padding-left", "3px");
                    self.tags.addTags(_.map(data, function(el) {return {name: el[1], id:el[0]};}));
                    var tag_element = self.tags.tagElements();
                    _.each(data,function(value, key){
                        $(tag_element[key]).find(".custom-edit").addClass(data[key][2])
                    })
                } else {
                    self.$el.html(QWeb.render("Many2Many_invite", {elements: data}));
                }
            };
            if (! values || values.length > 0) {
                if(self.getParent().datarecord.attendee_ids){
                    return new instance.web.Model("calendar.attendee").call('read',[self.getParent().datarecord.attendee_ids ,['state','cn','partner_id']]).then(function(res){
                        data = []
                        _.each(res,function(val){
                            data.push([val['partner_id'][0],val['cn'],val['state']])
                        });
                        handle_names(data)
                    });
                } else { this._display_orderer.add(dataset.name_get(values)).done(handle_names); }
            } else { handle_names([]); }
        },

    });
    instance.web.form.widgets = instance.web.form.widgets.extend({
        'Many2Many_invite' : 'instance.web.form.Many2Many_invite',
    });
    instance.base_calendar.event = function (db, token, action, view_type, status) {
        instance.session.session_bind(instance.session.origin).done(function () {
            new instance.base_calendar.invite(null,db,token,action,view_type,status).appendTo($("body").addClass('openerp'));
        });
    }
};
//vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * [description]
 *
 * @function Phaser.Actions.SetXY
 * @since 3.0.0
 *
 * @param {array} items - An array of Game Objects. The contents of this array are updated by this Action.
 * @param {number} x - [description]
 * @param {number} y - [description]
 * @param {number} [stepX=0] - [description]
 * @param {number} [stepY=0] - [description]
 *
 * @return {array} The array of Game Objects that was passed to this Action.
 */
var SetXY = function (items, x, y, stepX, stepY)
{
    if (stepX === undefined) { stepX = 0; }
    if (stepY === undefined) { stepY = 0; }

    for (var i = 0; i < items.length; i++)
    {
        items[i].x = x + (i * stepX);
        items[i].y = y + (i * stepY);
    }

    return items;
};

module.exports = SetXY;
<commit_msg>Actions.SetXY has 2 new arguments: `index` and `direction`.<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var PropertyValueSet = require('./PropertyValueSet');

/**
 * Takes an array of Game Objects, or any objects that have the public properties `x` and `y`
 * and then sets them to the given values.
 *
 * The optional `stepX` and `stepY` properties are applied incrementally, multiplied by each item in the array.
 *
 * To use this with a Group: `SetXY(group.getChildren(), x, y, stepX, stepY)`
 *
 * @function Phaser.Actions.SetXY
 * @since 3.0.0
 *
 * @param {array|Phaser.GameObjects.GameObject[]} items - The array of items to be updated by this action.
 * @param {number} x - The amount to set the `x` property to.
 * @param {number} [y] - The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value.
 * @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter.
 * @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter.
 * @param {integer} [index=0] - An optional offset to start searching from within the items array.
 * @param {integer} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning.
 *
 * @return {array} The array of objects that were passed to this Action.
 */
var SetXY = function (items, x, y, stepX, stepY, index, direction)
{
    if (y === undefined || y === null) { y = x; }

    PropertyValueSet(items, 'x', x, stepX, index, direction);

    return PropertyValueSet(items, 'y', y, stepY, index, direction);
};

module.exports = SetXY;
<|endoftext|>


<commit_before><commit_msg>add actions back in<commit_after>import axios from 'axios';

// get top twitch channels
export const GET_CHANNELS = 'GET_CHANNELS';
export function getChannels() {
  const request = axios.get('https://api.twitch.tv/kraken/streams?api_version=3&limit=10');
  return {
    type: GET_CHANNELS,
    payload: request,
  };
}

// set the currently active channel
export const SET_CHANNEL = 'SET_CHANNEL';
export function setChannel(channel) {
  return {
    type: SET_CHANNEL,
    payload: channel,
  };
}

export const GET_MESSAGE = 'GET_MESSAGE';
export function getMessage(data) {
  return {
    type: GET_MESSAGE,
    payload: data,
  };
}
<|endoftext|>


<commit_before>import { readAsText } from 'promise-file-reader';
import tinycolor from 'tinycolor2';
import axios from 'axios';

export const LESS_TO_PALETTE = 'LESS_TO_PALETTE';
export const UPDATE_LOADING = 'UPDATE_LOADING';
export const COLOUR_DETAIL = 'COLOUR_DETAIL';
export const TOAST = 'TOAST';

function constructColor(Obj) {
  const colorObj = Obj;
  const hex = colorObj.hex.substring(1);
  /* Get the RGB values to calculate the Hue. */
  const r = parseInt(hex.substring(0, 2), 16) / 255;
  const g = parseInt(hex.substring(2, 4), 16) / 255;
  const b = parseInt(hex.substring(4, 6), 16) / 255;

  /* Getting the Max and Min values for Chroma. */
  const max = Math.max.apply(Math, [r, g, b]);
  const min = Math.min.apply(Math, [r, g, b]);

  /* Variables for HSV value of hex color. */
  const chr = max - min;
  let hue = 0;
  const val = max;
  let sat = 0;

  if (val > 0) {
      /* Calculate Saturation only if Value isn't 0. */
    sat = chr / val;
    if (sat > 0) {
      if (r === max) {
        hue = 60 * (((g - min) - (b - min)) / chr);
        if (hue < 0) {
          hue += 360;
        }
      } else if (g === max) {
        hue = (120 + 60) * (((b - min) - (r - min)) / chr);
      } else if (b === max) {
        hue = (240 + 60) * (((r - min) - (g - min)) / chr);
      }
    }
  }
  colorObj.chroma = chr;
  colorObj.hue = hue;
  colorObj.satutation = sat;
  colorObj.val = val;
  colorObj.luma = 0.3 * (r + 0.59) * (g + 0.11) * b;
  colorObj.red = parseInt(hex.substring(0, 2), 16);
  colorObj.green = parseInt(hex.substring(2, 4), 16);
  colorObj.blue = parseInt(hex.substring(4, 6), 16);
  return colorObj;
}

function processFileContent(content) {
  const lines = content.split('\n');
  const colours = [];
  lines.forEach((line) => {
    if ((line.indexOf('@') > -1 || line.indexOf('$') > -1 || line.indexOf('--') > -1) && (line.indexOf(': #') > -1 || line.indexOf(': rgb') > -1)) {
      const label = line.substring(0, line.indexOf(':'));
      let value = line.substring(line.indexOf(':') + 2);
      value = value.replace(';', '');
      if (value.indexOf('rgb') > -1 || value.indexOf(',') === -1) {
        const baseColourObj = {
          name: label,
          colour: value,
          hex: tinycolor(value).toHexString()
        };
        colours.push(constructColor(baseColourObj));
      }
    }
  });
  return colours;
}

export function lessFileToPalette(file) {
  const palette = readAsText(file).then(content => processFileContent(content));
  return { type: LESS_TO_PALETTE, payload: palette };
}

export function fileUrlToPalette(url) {
  const palette = axios.get(url)
  .then(resp => resp.data).then(content => processFileContent(content));
  return { type: LESS_TO_PALETTE, payload: palette };
}

export function updateLoadingState(loading) {
  return { type: UPDATE_LOADING, payload: loading };
}

export function updateColourDetail(colour) {
  return { type: COLOUR_DETAIL, payload: colour };
}

export function updateToast(toast) {
  return { type: TOAST, payload: toast };
}
<commit_msg>added logic to exclude inline comments from extracted values<commit_after>import { readAsText } from 'promise-file-reader';
import tinycolor from 'tinycolor2';
import axios from 'axios';

export const LESS_TO_PALETTE = 'LESS_TO_PALETTE';
export const UPDATE_LOADING = 'UPDATE_LOADING';
export const COLOUR_DETAIL = 'COLOUR_DETAIL';
export const TOAST = 'TOAST';

function constructColor(Obj) {
  const colorObj = Obj;
  const hex = colorObj.hex.substring(1);
  /* Get the RGB values to calculate the Hue. */
  const r = parseInt(hex.substring(0, 2), 16) / 255;
  const g = parseInt(hex.substring(2, 4), 16) / 255;
  const b = parseInt(hex.substring(4, 6), 16) / 255;

  /* Getting the Max and Min values for Chroma. */
  const max = Math.max.apply(Math, [r, g, b]);
  const min = Math.min.apply(Math, [r, g, b]);

  /* Variables for HSV value of hex color. */
  const chr = max - min;
  let hue = 0;
  const val = max;
  let sat = 0;

  if (val > 0) {
      /* Calculate Saturation only if Value isn't 0. */
    sat = chr / val;
    if (sat > 0) {
      if (r === max) {
        hue = 60 * (((g - min) - (b - min)) / chr);
        if (hue < 0) {
          hue += 360;
        }
      } else if (g === max) {
        hue = (120 + 60) * (((b - min) - (r - min)) / chr);
      } else if (b === max) {
        hue = (240 + 60) * (((r - min) - (g - min)) / chr);
      }
    }
  }
  colorObj.chroma = chr;
  colorObj.hue = hue;
  colorObj.satutation = sat;
  colorObj.val = val;
  colorObj.luma = 0.3 * (r + 0.59) * (g + 0.11) * b;
  colorObj.red = parseInt(hex.substring(0, 2), 16);
  colorObj.green = parseInt(hex.substring(2, 4), 16);
  colorObj.blue = parseInt(hex.substring(4, 6), 16);
  return colorObj;
}

function processFileContent(content) {
  const lines = content.split('\n');
  const colours = [];
  lines.forEach((line) => {
    if ((line.indexOf('@') > -1 || line.indexOf('$') > -1 || line.indexOf('--') > -1) && (line.indexOf(': #') > -1 || line.indexOf(': rgb') > -1)) {
      const label = line.substring(0, line.indexOf(':'));
      let value = line.substring(line.indexOf(':') + 2).trim();
      if (value.indexOf('/') > 0) {
        value = value.substring(0, value.indexOf(' '));
      }
      value = value.replace(';', '');
      if (value.indexOf('rgb') > -1 || value.indexOf(',') === -1) {
        const baseColourObj = {
          name: label,
          colour: value,
          hex: tinycolor(value).toHexString()
        };
        colours.push(constructColor(baseColourObj));
      }
    }
  });
  return colours;
}

export function lessFileToPalette(file) {
  const palette = readAsText(file).then(content => processFileContent(content));
  return { type: LESS_TO_PALETTE, payload: palette };
}

export function fileUrlToPalette(url) {
  const palette = axios.get(url)
  .then(resp => resp.data).then(content => processFileContent(content));
  return { type: LESS_TO_PALETTE, payload: palette };
}

export function updateLoadingState(loading) {
  return { type: UPDATE_LOADING, payload: loading };
}

export function updateColourDetail(colour) {
  return { type: COLOUR_DETAIL, payload: colour };
}

export function updateToast(toast) {
  return { type: TOAST, payload: toast };
}
<|endoftext|>


<commit_before>(function (window, document, ajl) {
"use strict";

// ----------------------------------------------------------------------------
// GoogleMap: Google Mapsの表示
// ----------------------------------------------------------------------------
// todo: コントロールUIの変更について要検討
//       https://developers.google.com/maps/documentation/javascript/controls?hl=ja#DefaultControls
//
//       スタイルの変更について
//       変更しても見にくいだけではないか？
//       https://developers.google.com/maps/documentation/javascript/styling?hl=ja
ajl.GoogleMap = function (elem, options) {
    this.elem = elem;
    this.map = null;
    this.mapImg = null;
    this.markers = [];
    this.state = {
        openedInfoWindow: null
    };
    this.defaults = {
        dynamicOnly: false,
        sensor: false,
        className: "dynamicmap",
        mapOptions: null,
        language: "ja",
        collect: function (elem) {
            return elem.getElementsByTagName("img")[0];
        }
    };

    this.options = ajl.util.deepExtend({}, this.defaults, options);
};

ajl.GoogleMap.prototype = {
    _loadScript: function (cbName) {
        var script = document.createElement("script"),
            src;

        src = "http://maps.googleapis.com/maps/api/js?sensor=";

        if (this.options.sensor) {
            src += "true";
        } else {
            src += "false";
        }

        if (this.options.key) {
            src += "key=" + this.options.key;
        }

        if (cbName) {
            src += "&callback=" + cbName;
        }

        src += "&language=" + this.options.language;

        script.src = src;
        document.body.appendChild(script);
    },

    _getParams: function () {
        var params = {},
            paramStr = this.mapImg.src.replace(/https?:\/\/[a-zA-Z0-9\/\.]*\?/, ""),
            paramsArray = paramStr.split("&"),
            i,
            nParams = paramsArray.length,
            keyValuePair;

        for (i = 0; i < nParams; i += 1) {
            keyValuePair = paramsArray[i].split("=");
            params[keyValuePair[0]] = keyValuePair[1];
        }

        return params;
    },

    _ctrlInfoWindow: function (markerObj, obj) {
        if (obj.state.openedInfoWindow) {
            obj.state.openedInfoWindow.close();
        }
        markerObj.infoWindow.open(obj.map, markerObj);
        obj.state.openedInfoWindow = markerObj.infoWindow;
    },

    _setMarkers: function () {
        var self = this,
            latLng,
            nMarkers = this.options.markers.length,
            i,
            handler = function () {
                self._ctrlInfoWindow(this, self);
            };

        for (i = 0; i < nMarkers; i += 1) {
            latLng = new google.maps.LatLng(
                this.options.markers[i].lat,
                this.options.markers[i].lng
            );
            this.markers[i] = new google.maps.Marker({
                position: latLng,
                title: this.options.markers[i].title,
                icon: this.options.markers[i].icon ? this.options.markers[i].icon : "",
                map: this.map
            });

            if (this.options.markers[i].content) {
                this.markers[i].infoWindow = new google.maps.InfoWindow({
                    content: this.options.markers[i].content
                });
                google.maps.event.addListener(
                    this.markers[i],
                    "click",
                    handler
                );
            }
        }
    },

    replaceMap: function () {
        var div = document.createElement("div"),
            params = this._getParams(),
            latLngStr,
            latLng,
            zoom,
            map,
            marker,
            options;

        latLngStr = params.center.split(",");
        latLng = new google.maps.LatLng(latLngStr[0], latLngStr[1]);
        zoom = parseInt(params.zoom, 10);
        options = {
            zoom: zoom,
            center: latLng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        div.className = this.options.className;
        div.style.height = this.mapImg.offsetHeight + "px";
        this.mapImg.parentNode.replaceChild(div, this.mapImg);    // 先にappendしないと表示にバグ発生

        this.map = new google.maps.Map(div, options);
        latLngStr = params.markers.split(",");
        latLng = new google.maps.LatLng(latLngStr[0], latLngStr[1]);
        marker = new google.maps.Marker({
            position: latLng,
            map: this.map
        });
    },

    dispMap: function (self) {
        var div = document.createElement("div"),
            map,
            marker,
            options = {};

        div.className = self.options.className;
        options.center = new google.maps.LatLng(
            self.options.mapOptions.lat,
            self.options.mapOptions.lng
        );
        options.zoom = self.options.mapOptions.zoom;
        options.mapTypeId = self.options.mapType;
        this.map = new google.maps.Map(div, options);
        this._setMarkers();

        // div.style.height = self.mapImg.offsetHeight + "px";
        self.elem.appendChild(div);
     },

    init: function () {
        var id;

        if (this.options.dynamicOnly) {
            ajl.event.add(window, "gmaploaded", ajl.util.proxy(this, function () {
                this.dispMap(this);
            }));

            if (!ajl.cb.gmap) {
                id = "AJL_GMAP_" + Math.floor(Math.random() * 1000000);
                ajl.cb.gmap = {};
                ajl.cb.gmap[id] = ajl.util.proxy(this, function () {
                    ajl.event.trigger(window, "gmaploaded");
                });
                this._loadScript("ajl.cb.gmap." + id);
            }
        } else {
            this.mapImg = this.options.collect(this.elem);
            ajl.event.add(window, "gmaploaded", ajl.util.proxy(this, function () {
                ajl.event.add(this.mapImg, "click", ajl.util.proxy(this, this.replaceMap));
            }));

            if (!ajl.cb.gmap) {
                id = "AJL_GMAP_" + Math.floor(Math.random() * 1000000);
                ajl.cb.gmap = {};
                ajl.cb.gmap[id] = ajl.util.proxy(this, function () {
                    ajl.event.trigger(window, "gmaploaded");
                });
                this._loadScript("ajl.cb.gmap." + id);
            }
        }
    }
};

ajl.util.createRunner("GoogleMap");

}(window, document, ajl));
<commit_msg>GoogleMapのinfoWindow表示を改良<commit_after>(function (window, document, ajl) {
"use strict";

// ----------------------------------------------------------------------------
// GoogleMap: Google Mapsの表示
// ----------------------------------------------------------------------------
// todo: コントロールUIの変更について要検討
//       https://developers.google.com/maps/documentation/javascript/controls?hl=ja#DefaultControls
//
//       スタイルの変更について
//       変更しても見にくいだけではないか？
//       https://developers.google.com/maps/documentation/javascript/styling?hl=ja
ajl.GoogleMap = function (elem, options) {
    this.elem = elem;
    this.map = null;
    this.mapImg = null;
    this.markers = [];
    this.state = {
        openedInfoWindow: null
    };
    this.defaults = {
        dynamicOnly: false,
        sensor: false,
        className: "dynamicmap",
        mapOptions: null,
        language: "ja",
        collect: function (elem) {
            return elem.getElementsByTagName("img")[0];
        }
    };

    this.options = ajl.util.deepExtend({}, this.defaults, options);
};

ajl.GoogleMap.prototype = {
    _loadScript: function (cbName) {
        var script = document.createElement("script"),
            src;

        src = "http://maps.googleapis.com/maps/api/js?sensor=";

        if (this.options.sensor) {
            src += "true";
        } else {
            src += "false";
        }

        if (this.options.key) {
            src += "key=" + this.options.key;
        }

        if (cbName) {
            src += "&callback=" + cbName;
        }

        src += "&language=" + this.options.language;

        script.src = src;
        document.body.appendChild(script);
    },

    _getParams: function () {
        var params = {},
            paramStr = this.mapImg.src.replace(/https?:\/\/[a-zA-Z0-9\/\.]*\?/, ""),
            paramsArray = paramStr.split("&"),
            i,
            nParams = paramsArray.length,
            keyValuePair;

        for (i = 0; i < nParams; i += 1) {
            keyValuePair = paramsArray[i].split("=");
            params[keyValuePair[0]] = keyValuePair[1];
        }

        return params;
    },

    _ctrlInfoWindow: function (markerObj, obj) {
        if (obj.state.openedInfoWindow) {
            obj.state.openedInfoWindow.close();
        }
        markerObj.infoWindow.open(obj.map, markerObj);
        obj.state.openedInfoWindow = markerObj.infoWindow;
    },

    _setMarkers: function () {
        var self = this,
            latLng,
            nMarkers = this.options.markers.length,
            i,
            infoWindow,
            handler = function () {
                self._ctrlInfoWindow(this, self);
            };

        for (i = 0; i < nMarkers; i += 1) {
            latLng = new google.maps.LatLng(
                this.options.markers[i].lat,
                this.options.markers[i].lng
            );
            this.markers[i] = new google.maps.Marker({
                position: latLng,
                title: this.options.markers[i].title,
                icon: this.options.markers[i].icon ? this.options.markers[i].icon : "",
                map: this.map
            });

            if (this.options.markers[i].content) {
                infoWindow = this.markers[i].infoWindow = new google.maps.InfoWindow({
                    content: this.options.markers[i].content
                });
                google.maps.event.addListener(
                    this.markers[i],
                    "click",
                    handler
                );
                google.maps.event.addListener(
                    infoWindow,
                    "closeclick",
                    function () {
                        google.maps.event.addListenerOnce(this.markers[i], "click", function () {
                            infoWindow.open(this.map, this.markers[i]);
                        });
                    }
                );

                if (this.options.markers[i].openOnLoad) {
                    infoWindow.open(this.map, this.markers[i]);
                }
            }
        }
    },

    replaceMap: function () {
        var div = document.createElement("div"),
            params = this._getParams(),
            latLngStr,
            latLng,
            zoom,
            map,
            marker,
            options;

        latLngStr = params.center.split(",");
        latLng = new google.maps.LatLng(latLngStr[0], latLngStr[1]);
        zoom = parseInt(params.zoom, 10);
        options = {
            zoom: zoom,
            center: latLng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        div.className = this.options.className;
        div.style.height = this.mapImg.offsetHeight + "px";
        this.mapImg.parentNode.replaceChild(div, this.mapImg);    // 先にappendしないと表示にバグ発生

        this.map = new google.maps.Map(div, options);
        latLngStr = params.markers.split(",");
        latLng = new google.maps.LatLng(latLngStr[0], latLngStr[1]);
        marker = new google.maps.Marker({
            position: latLng,
            map: this.map
        });
    },

    dispMap: function (self) {
        var div = document.createElement("div"),
            map,
            marker,
            options = {};

        div.className = self.options.className;
        options.center = new google.maps.LatLng(
            self.options.mapOptions.lat,
            self.options.mapOptions.lng
        );
        options.zoom = self.options.mapOptions.zoom;
        options.mapTypeId = self.options.mapType;
        this.map = new google.maps.Map(div, options);
        this._setMarkers();

        // div.style.height = self.mapImg.offsetHeight + "px";
        self.elem.appendChild(div);
     },

    init: function () {
        var id;

        if (this.options.dynamicOnly) {
            ajl.event.add(window, "gmaploaded", ajl.util.proxy(this, function () {
                this.dispMap(this);
            }));

            if (!ajl.cb.gmap) {
                id = "AJL_GMAP_" + Math.floor(Math.random() * 1000000);
                ajl.cb.gmap = {};
                ajl.cb.gmap[id] = ajl.util.proxy(this, function () {
                    ajl.event.trigger(window, "gmaploaded");
                });
                this._loadScript("ajl.cb.gmap." + id);
            }
        } else {
            this.mapImg = this.options.collect(this.elem);
            ajl.event.add(window, "gmaploaded", ajl.util.proxy(this, function () {
                ajl.event.add(this.mapImg, "click", ajl.util.proxy(this, this.replaceMap));
            }));

            if (!ajl.cb.gmap) {
                id = "AJL_GMAP_" + Math.floor(Math.random() * 1000000);
                ajl.cb.gmap = {};
                ajl.cb.gmap[id] = ajl.util.proxy(this, function () {
                    ajl.event.trigger(window, "gmaploaded");
                });
                this._loadScript("ajl.cb.gmap." + id);
            }
        }
    }
};

ajl.util.createRunner("GoogleMap");

}(window, document, ajl));
<|endoftext|>


<commit_before>/*global window:false, angular:false, Gauge:false*/
/**
 * angular-gaugejs version 0.1
 * License: MIT.
 * Copyright (C) 2014, Rasmus Schlünsen
 */

(function(angular) {
    'use strict';

    angular.module('gaugejs', [])
    .directive('gaugejs', [function() {
        return {
            restrict: 'AC',
            scope: {
                'animationTime': '=',
                'value': '=',
                'options': '=',
                'maxValue': '='
            },
            controller: function($scope, $element) {
                $scope.gauge = new Gauge($element[0]);
                $scope.gauge.maxValue = $scope.maxValue;
                $scope.$watchCollection('[options, value]', function(newValues){
                    $scope.gauge.setOptions(newValues[0]);
                    $scope.gauge.set(newValues[1]);
                });
            },
        };
    }]);

})(window.angular);
<commit_msg>Fixed bug when receiving NaN as gauge value<commit_after>/*global window:false, angular:false, Gauge:false*/
/**
 * angular-gaugejs version 0.1
 * License: MIT.
 * Copyright (C) 2014, Rasmus Schlünsen
 */

(function(angular) {
    'use strict';

    angular.module('gaugejs', [])
    .directive('gaugejs', [function() {
        return {
            restrict: 'AC',
            scope: {
                'animationTime': '=',
                'value': '=',
                'options': '=',
                'maxValue': '='
            },
            controller: function($scope, $element) {
                $scope.gauge = new Gauge($element[0]);
                $scope.gauge.maxValue = $scope.maxValue;
                $scope.$watchCollection('[options, value]', function(newValues){
                    $scope.gauge.setOptions(newValues[0]);
                    if (!isNaN(newValues[1])){
                        $scope.gauge.set(newValues[1]);
                    }
                });
            },
        };
    }]);

})(window.angular);
<|endoftext|>