<commit_before>/*!
* ${copyright}
*/

// Provides control sap.m.MessageStrip.
sap.ui.define([
	"./library",
	"sap/ui/core/Control",
	"./MessageStripUtilities",
	"./Text",
	"./Link",
	"./FormattedText",
	"sap/ui/core/library",
	"./MessageStripRenderer",
	"sap/base/Log",
	"sap/m/Button",
	"sap/ui/core/Core",
	"sap/ui/core/InvisibleText"
], function(
	library,
	Control,
	MSUtils,
	Text,
	Link,
	FormattedText,
	coreLibrary,
	MessageStripRenderer,
	Log,
	Button,
	Core,
	InvisibleText
) {
	"use strict";

	// shortcut for sap.ui.core.MessageType
	var MessageType = coreLibrary.MessageType;

	// shortcut for sap.m.ButtonType
	var ButtonType = library.ButtonType;

	/**
	 * Constructor for a new MessageStrip.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * MessageStrip is a control that enables the embedding of application-related messages in the application.
	 *
Overview

	 * The message strip displays 4 types of messages, each with a corresponding semantic color and icon: Information, Success, Warning and Error.
	 *
	 * Each message can have a close button, so that it can be removed from the UI if needed.
	 *
	 * With version 1.50 you can use a limited set of formatting tags for the message text by setting enableFormattedText. The allowed tags are:
	 *

	 *
<a>

	 *
<br>

	 *
<em>

	 *
<strong>

	 *
<u>

	 *

	 *
	 *
Dynamically generated Message Strip

	 * To meet the accessibility requirements when using dynamically generated Message Strip you must implement it alongside sap.ui.core.InvisibleMessage.
	 * This will allow screen readers to announce it in real time. We suggest such dynamically generated message strips to be announced as Information Bar,
	 * as shown in our “Dynamic Message Strip Generator sample.”
	 *
	 *
Usage

	 *
When to use

	 *

	 *
You want to provide information or status update within the detail area of an object

	 *

	 *
When not to use

	 *

	 *
You want to display information within the object page header, within a control, in the master list, or above the page header.

	 *

	 * @extends sap.ui.core.Control
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.30
	 * @alias sap.m.MessageStrip
	 * @see {@link fiori:https://experience.sap.com/fiori-design-web/message-strip/ Message Strip}
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var MessageStrip = Control.extend("sap.m.MessageStrip", /** @lends sap.m.MessageStrip.prototype */ {
		metadata: {
			library: "sap.m",
			designtime: "sap/m/designtime/MessageStrip.designtime",
			properties: {

				/**
				 * Determines the text of the message.
				 */
				text: { type: "string", group: "Appearance", defaultValue: "" },

				/**
				 * Determines the type of messages that are displayed in the MessageStrip.
				 * Possible values are: Information (default), Success, Warning, Error.
				 * If None is passed, the value is set to Information and a warning is displayed in the console.
				 */
				type: { type: "sap.ui.core.MessageType", group: "Appearance", defaultValue: MessageType.Information },

				/**
				 * Determines a custom icon which is displayed.
				 * If none is set, the default icon for this message type is used.
				 */
				customIcon: { type: "sap.ui.core.URI", group: "Appearance", defaultValue: "" },

				/**
				 * Determines if an icon is displayed for the message.
				 */
				showIcon: { type: "boolean", group: "Appearance", defaultValue: false },

				/**
				 * Determines if the message has a close button in the upper right corner.
				 */
				showCloseButton: { type: "boolean", group: "Appearance", defaultValue: false },

				/**
				 * Determines the limited collection of HTML elements passed to the text property should be
				 * evaluated.
				 *
				 * Note: If this property is set to true the string passed to text property
				 * can evaluate the following list of limited HTML elements. All other HTML elements and their nested
				 * content will not be rendered by the control:
				 *

				 *
a

				 *
br

				 *
em

				 *
strong

				 *
u

				 *

				 *
				 * @since 1.50
				 */
				enableFormattedText: { type: "boolean", group: "Appearance", defaultValue: false }
			},
			defaultAggregation: "link",
			aggregations: {

				/**
				 * Adds an sap.m.Link control which will be displayed at the end of the message.
				 */
				link: { type: "sap.m.Link", multiple: false, singularName: "link" },

				/**
				 * Hidden aggregation which is used to transform the string message into sap.m.Text control.
				 * @private
				 */
				_formattedText: { type: "sap.m.FormattedText", multiple: false, visibility: "hidden" },

				/**
				 * Hidden aggregation which is used to transform the string message into sap.m.Text control.
				 */
				_text: { type: "sap.m.Text", multiple: false, visibility: "hidden" },

				/**
				 * Hidden aggregation which is used to create the close button with sap.m.Button control.
				 */
				_closeButton: { type: "sap.m.Button", multiple: false, visibility: "hidden" }
			},
			events: {

				/**
				 * This event will be fired after the container is closed.
				 */
				close: {}
			},
			dnd: { draggable: true, droppable: false }
		}
	});

	MessageStrip.prototype.init = function () {
		this.data("sap-ui-fastnavgroup", "true", true);
		this.setAggregation("_text", new Text());
		this._initCloseButton();
	};

	/**
	 * Setter for property text.
	 * Default value is empty/undefined
	 * @public
	 * @param {string} sText new value for property text
	 * @returns {this} this to allow method chaining
	 */
	MessageStrip.prototype.setText = function (sText) {
		// Update the internal FormattedText control if needed
		var oFormattedText = this.getAggregation("_formattedText");
		if (oFormattedText) {
			oFormattedText.setHtmlText(sText);
		}

		// Update the internal text control
		this.getAggregation("_text").setText(sText);

		return this.setProperty("text", sText);
	};

	/**
	 * Setter for property type.
	 * Default value is sap.ui.core.MessageType.Information
	 * @public
	 * @param {sap.ui.core.MessageType} sType The Message type
	 * @returns {this} this to allow method chaining
	 */
	MessageStrip.prototype.setType = function (sType) {
		if (!sType || sType === MessageType.None) {
			Log.warning(MSUtils.MESSAGES.TYPE_NOT_SUPPORTED);
			sType = MessageType.Information;
		}

		this.getType() !== sType && this._setButtonAriaLabelledBy(sType);

		return this.setProperty("type", sType);
	};

	/**
	 * Closes the MessageStrip.
	 * This method sets the visible property of the MessageStrip to false.
	 * The MessageStrip can be shown again by setting the visible property to true.
	 * @public
	 */
	MessageStrip.prototype.close = function () {
		var fnClosed = function () {
			this.setVisible(false);
			this.fireClose();
		}.bind(this);

		if (!Core.getConfiguration().getAnimation()) {
			fnClosed();
			return;
		}

		MSUtils.closeTransitionWithCSS.call(this, fnClosed);
	};

	MessageStrip.prototype.setEnableFormattedText = function (bEnable) {
		var oFormattedText  = this.getAggregation("_formattedText");

		if (bEnable) {
			if (!oFormattedText) {
				oFormattedText = new FormattedText();
				oFormattedText._setUseLimitedRenderingRules(true);
				this.setAggregation("_formattedText", oFormattedText);
			}
			// Aways call setHtmlText - do not use a constructor property to avoid unwanted warnings for HTML elements
			oFormattedText.setHtmlText(this.getText());
		}

		return this.setProperty("enableFormattedText", bEnable);
	};

	MessageStrip.prototype.setAggregation = function (sName, oControl, bSupressInvalidate) {
		if (sName === "link" && oControl instanceof Link) {
			oControl.addAriaDescribedBy(this.getId());
		}

		Control.prototype.setAggregation.call(this, sName, oControl, bSupressInvalidate);
		return this;
	};

	/**
	 * Retrieves the accessibility state of the control.
	 *
	 * @returns {object} The accessibility state of the control
	 */
	MessageStripRenderer.getAccessibilityState = function () {
		var mAccessibilityState = MSUtils.getAccessibilityState.call(this),
			oLink = this.getLink(),
			oResourceBundle = Core.getLibraryResourceBundle("sap.m");

		if (!oLink) {
			mAccessibilityState.labelledby = this.getId();
		}

		mAccessibilityState.roledescription = oResourceBundle.getText("MESSAGE_STRIP_ARIA_ROLE_DESCRIPTION");
		return mAccessibilityState;
	};

	/**
	 * Handles mobile touch events
	 * @param {jQuery.Event} oEvent The event object
	 * @private
	 */
	MessageStrip.prototype.ontouchmove = function (oEvent) {
		// mark the event for components that needs to know if the event was handled
		oEvent.setMarked();
	};

	/**
	 * Initialize close button.
	 */
	MessageStrip.prototype._initCloseButton = function () {
		var oRb = Core.getLibraryResourceBundle("sap.m"),
			oCloseButton = this.getAggregation("_closeButton");

			if (!oCloseButton) {

				var oButton = new Button({
					type: ButtonType.Transparent,
					tooltip: oRb.getText("MESSAGE_STRIP_TITLE"),
					icon: "sap-icon://decline",
					press: this.close.bind(this)
				}).addStyleClass(MSUtils.CLASSES.CLOSE_BUTTON).addStyleClass("sapUiSizeCompact");

				this.setAggregation("_closeButton", oButton);
				this._setButtonAriaLabelledBy(this.getType());
		}
	};

	/**
	 * Set Arialabelledby to the close button.
	 * @param {sap.ui.core.MessageType} sType The Message type
	 */
	MessageStrip.prototype._setButtonAriaLabelledBy = function (sType) {
		var oCloseButton = this.getAggregation("_closeButton"),
			oRb = Core.getLibraryResourceBundle("sap.m"),
			sText = oRb.getText("MESSAGE_STRIP_" + sType.toUpperCase() + "_CLOSE_BUTTON");

		if (!this._oInvisibleText) {
			this._oInvisibleText = new InvisibleText({
				text: sText
			}).toStatic();
		} else {
			this._oInvisibleText.setText(sText);
		}

		if (oCloseButton) {
			oCloseButton.removeAllAriaLabelledBy();
			oCloseButton.addAriaLabelledBy(this._oInvisibleText.getId());
		}
	};

	MessageStrip.prototype.exit = function () {
		if (this._oInvisibleText) {
			this._oInvisibleText.destroy();
			this._oInvisibleText = null;
		}
	};

	return MessageStrip;

});<commit_msg>[FIX] sap.m.MessageStrip: Documentation enhancement<commit_after>/*!
* ${copyright}
*/

// Provides control sap.m.MessageStrip.
sap.ui.define([
	"./library",
	"sap/ui/core/Control",
	"./MessageStripUtilities",
	"./Text",
	"./Link",
	"./FormattedText",
	"sap/ui/core/library",
	"./MessageStripRenderer",
	"sap/base/Log",
	"sap/m/Button",
	"sap/ui/core/Core",
	"sap/ui/core/InvisibleText"
], function(
	library,
	Control,
	MSUtils,
	Text,
	Link,
	FormattedText,
	coreLibrary,
	MessageStripRenderer,
	Log,
	Button,
	Core,
	InvisibleText
) {
	"use strict";

	// shortcut for sap.ui.core.MessageType
	var MessageType = coreLibrary.MessageType;

	// shortcut for sap.m.ButtonType
	var ButtonType = library.ButtonType;

	/**
	 * Constructor for a new MessageStrip.
	 *
	 * @param {string} [sId] ID for the new control, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new control
	 *
	 * @class
	 * MessageStrip is a control that enables the embedding of application-related messages in the application.
	 *
Overview

	 * The message strip displays 4 types of messages, each with a corresponding semantic color and icon: Information, Success, Warning and Error.
	 *
	 * Each message can have a close button, so that it can be removed from the UI if needed.
	 *
	 * You can use a limited set of formatting tags for the message text by setting enableFormattedText. The allowed tags are:
	 * With version 1.50
	 *

	 *
<a>

	 *
<em>

	 *
<strong>

	 *
<u>

	 *

	 * With version 1.85
	 *

	 *
<br>

	 *

	 *
	 *
Dynamically generated Message Strip

	 * To meet the accessibility requirements when using dynamically generated Message Strip you must implement it alongside sap.ui.core.InvisibleMessage.
	 * This will allow screen readers to announce it in real time. We suggest such dynamically generated message strips to be announced as Information Bar,
	 * as shown in our “Dynamic Message Strip Generator sample.”
	 *
	 *
Usage

	 *
When to use

	 *

	 *
You want to provide information or status update within the detail area of an object

	 *

	 *
When not to use

	 *

	 *
You want to display information within the object page header, within a control, in the master list, or above the page header.

	 *

	 * @extends sap.ui.core.Control
	 *
	 * @author SAP SE
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @since 1.30
	 * @alias sap.m.MessageStrip
	 * @see {@link fiori:https://experience.sap.com/fiori-design-web/message-strip/ Message Strip}
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var MessageStrip = Control.extend("sap.m.MessageStrip", /** @lends sap.m.MessageStrip.prototype */ {
		metadata: {
			library: "sap.m",
			designtime: "sap/m/designtime/MessageStrip.designtime",
			properties: {

				/**
				 * Determines the text of the message.
				 */
				text: { type: "string", group: "Appearance", defaultValue: "" },

				/**
				 * Determines the type of messages that are displayed in the MessageStrip.
				 * Possible values are: Information (default), Success, Warning, Error.
				 * If None is passed, the value is set to Information and a warning is displayed in the console.
				 */
				type: { type: "sap.ui.core.MessageType", group: "Appearance", defaultValue: MessageType.Information },

				/**
				 * Determines a custom icon which is displayed.
				 * If none is set, the default icon for this message type is used.
				 */
				customIcon: { type: "sap.ui.core.URI", group: "Appearance", defaultValue: "" },

				/**
				 * Determines if an icon is displayed for the message.
				 */
				showIcon: { type: "boolean", group: "Appearance", defaultValue: false },

				/**
				 * Determines if the message has a close button in the upper right corner.
				 */
				showCloseButton: { type: "boolean", group: "Appearance", defaultValue: false },

				/**
				 * Determines the limited collection of HTML elements passed to the text property should be
				 * evaluated.
				 *
				 * Note: If this property is set to true the string passed to text property
				 * can evaluate the following list of limited HTML elements. All other HTML elements and their nested
				 * content will not be rendered by the control:
				 *

				 *
a

				 *
br

				 *
em

				 *
strong

				 *
u

				 *

				 *
				 * @since 1.50
				 */
				enableFormattedText: { type: "boolean", group: "Appearance", defaultValue: false }
			},
			defaultAggregation: "link",
			aggregations: {

				/**
				 * Adds an sap.m.Link control which will be displayed at the end of the message.
				 */
				link: { type: "sap.m.Link", multiple: false, singularName: "link" },

				/**
				 * Hidden aggregation which is used to transform the string message into sap.m.Text control.
				 * @private
				 */
				_formattedText: { type: "sap.m.FormattedText", multiple: false, visibility: "hidden" },

				/**
				 * Hidden aggregation which is used to transform the string message into sap.m.Text control.
				 */
				_text: { type: "sap.m.Text", multiple: false, visibility: "hidden" },

				/**
				 * Hidden aggregation which is used to create the close button with sap.m.Button control.
				 */
				_closeButton: { type: "sap.m.Button", multiple: false, visibility: "hidden" }
			},
			events: {

				/**
				 * This event will be fired after the container is closed.
				 */
				close: {}
			},
			dnd: { draggable: true, droppable: false }
		}
	});

	MessageStrip.prototype.init = function () {
		this.data("sap-ui-fastnavgroup", "true", true);
		this.setAggregation("_text", new Text());
		this._initCloseButton();
	};

	/**
	 * Setter for property text.
	 * Default value is empty/undefined
	 * @public
	 * @param {string} sText new value for property text
	 * @returns {this} this to allow method chaining
	 */
	MessageStrip.prototype.setText = function (sText) {
		// Update the internal FormattedText control if needed
		var oFormattedText = this.getAggregation("_formattedText");
		if (oFormattedText) {
			oFormattedText.setHtmlText(sText);
		}

		// Update the internal text control
		this.getAggregation("_text").setText(sText);

		return this.setProperty("text", sText);
	};

	/**
	 * Setter for property type.
	 * Default value is sap.ui.core.MessageType.Information
	 * @public
	 * @param {sap.ui.core.MessageType} sType The Message type
	 * @returns {this} this to allow method chaining
	 */
	MessageStrip.prototype.setType = function (sType) {
		if (!sType || sType === MessageType.None) {
			Log.warning(MSUtils.MESSAGES.TYPE_NOT_SUPPORTED);
			sType = MessageType.Information;
		}

		this.getType() !== sType && this._setButtonAriaLabelledBy(sType);

		return this.setProperty("type", sType);
	};

	/**
	 * Closes the MessageStrip.
	 * This method sets the visible property of the MessageStrip to false.
	 * The MessageStrip can be shown again by setting the visible property to true.
	 * @public
	 */
	MessageStrip.prototype.close = function () {
		var fnClosed = function () {
			this.setVisible(false);
			this.fireClose();
		}.bind(this);

		if (!Core.getConfiguration().getAnimation()) {
			fnClosed();
			return;
		}

		MSUtils.closeTransitionWithCSS.call(this, fnClosed);
	};

	MessageStrip.prototype.setEnableFormattedText = function (bEnable) {
		var oFormattedText  = this.getAggregation("_formattedText");

		if (bEnable) {
			if (!oFormattedText) {
				oFormattedText = new FormattedText();
				oFormattedText._setUseLimitedRenderingRules(true);
				this.setAggregation("_formattedText", oFormattedText);
			}
			// Aways call setHtmlText - do not use a constructor property to avoid unwanted warnings for HTML elements
			oFormattedText.setHtmlText(this.getText());
		}

		return this.setProperty("enableFormattedText", bEnable);
	};

	MessageStrip.prototype.setAggregation = function (sName, oControl, bSupressInvalidate) {
		if (sName === "link" && oControl instanceof Link) {
			oControl.addAriaDescribedBy(this.getId());
		}

		Control.prototype.setAggregation.call(this, sName, oControl, bSupressInvalidate);
		return this;
	};

	/**
	 * Retrieves the accessibility state of the control.
	 *
	 * @returns {object} The accessibility state of the control
	 */
	MessageStripRenderer.getAccessibilityState = function () {
		var mAccessibilityState = MSUtils.getAccessibilityState.call(this),
			oLink = this.getLink(),
			oResourceBundle = Core.getLibraryResourceBundle("sap.m");

		if (!oLink) {
			mAccessibilityState.labelledby = this.getId();
		}

		mAccessibilityState.roledescription = oResourceBundle.getText("MESSAGE_STRIP_ARIA_ROLE_DESCRIPTION");
		return mAccessibilityState;
	};

	/**
	 * Handles mobile touch events
	 * @param {jQuery.Event} oEvent The event object
	 * @private
	 */
	MessageStrip.prototype.ontouchmove = function (oEvent) {
		// mark the event for components that needs to know if the event was handled
		oEvent.setMarked();
	};

	/**
	 * Initialize close button.
	 */
	MessageStrip.prototype._initCloseButton = function () {
		var oRb = Core.getLibraryResourceBundle("sap.m"),
			oCloseButton = this.getAggregation("_closeButton");

			if (!oCloseButton) {

				var oButton = new Button({
					type: ButtonType.Transparent,
					tooltip: oRb.getText("MESSAGE_STRIP_TITLE"),
					icon: "sap-icon://decline",
					press: this.close.bind(this)
				}).addStyleClass(MSUtils.CLASSES.CLOSE_BUTTON).addStyleClass("sapUiSizeCompact");

				this.setAggregation("_closeButton", oButton);
				this._setButtonAriaLabelledBy(this.getType());
		}
	};

	/**
	 * Set Arialabelledby to the close button.
	 * @param {sap.ui.core.MessageType} sType The Message type
	 */
	MessageStrip.prototype._setButtonAriaLabelledBy = function (sType) {
		var oCloseButton = this.getAggregation("_closeButton"),
			oRb = Core.getLibraryResourceBundle("sap.m"),
			sText = oRb.getText("MESSAGE_STRIP_" + sType.toUpperCase() + "_CLOSE_BUTTON");

		if (!this._oInvisibleText) {
			this._oInvisibleText = new InvisibleText({
				text: sText
			}).toStatic();
		} else {
			this._oInvisibleText.setText(sText);
		}

		if (oCloseButton) {
			oCloseButton.removeAllAriaLabelledBy();
			oCloseButton.addAriaLabelledBy(this._oInvisibleText.getId());
		}
	};

	MessageStrip.prototype.exit = function () {
		if (this._oInvisibleText) {
			this._oInvisibleText.destroy();
			this._oInvisibleText = null;
		}
	};

	return MessageStrip;

});<|endoftext|>


<commit_before>
Math.sign = function(x) {
  x = +x;
  if (x === 0 || isNaN(x)) {
    return x;
  }
  return x > 0 ? 1 : -1;
};
const BaseUtil = {
  deepMix: require('@antv/util/lib/deep-mix'),
  mix: require('@antv/util/lib/mix'),
  debounce: require('@antv/util/lib/debounce'),
  each: require('@antv/util/lib/each'),
  throttle: require('@antv/util/lib/throttle'),
  mat3: require('@antv/util/lib/matrix/mat3'),
  vec2: require('@antv/util/lib/matrix/vec2'),
  vec3: require('@antv/util/lib/matrix/vec3'),
  transform: require('@antv/util/lib/matrix/transform'),
  clone: require('@antv/util/lib/clone'),
  upperFirst: require('@antv/util/lib/string/upper-first'),
  isNil: require('@antv/util/lib/type/is-nil'),
  isArray: require('@antv/util/lib/type/is-array'),
  createDom: require('@antv/util/lib/dom/create-dom'),
  /**
   * traverse tree
   * @param  {object}      parent      parent
   * @param  {function}    callback    callback
   * @param  {function}    getChild    get child function
   * @param  {boolean}     runSelf     callback run self or not
   */
  traverseTree(parent, callback, getChild, runSelf = false) {
    const children = getChild(parent);
    runSelf && callback(parent, null, null);
    children && BaseUtil.each(children, (child, index) => {
      callback(child, parent, index);
      BaseUtil.traverseTree(child, callback, getChild);
    });
  },

  /**
   * turn padding into [top, right, bottom, right]
   * @param  {Number|Array} padding input padding
   * @return {array} output
   */
  toAllPadding(padding) {
    let top = 0;
    let left = 0;
    let right = 0;
    let bottom = 0;

    if (BaseUtil.isNumber(padding) || BaseUtil.isString(padding)) {
      top = left = right = bottom = padding;
    } else if (BaseUtil.isArray(padding)) {
      top = padding[0];
      right = !BaseUtil.isNil(padding[1]) ? padding[1] : padding[0];
      bottom = !BaseUtil.isNil(padding[2]) ? padding[2] : padding[0];
      left = !BaseUtil.isNil(padding[3]) ? padding[3] : right;
    }
    return [ top, right, bottom, left ];
  }
};

module.exports = BaseUtil;
<commit_msg>chore: remove unnecessary utils<commit_after>const BaseUtil = {
  deepMix: require('@antv/util/lib/deep-mix'),
  mix: require('@antv/util/lib/mix'),
  debounce: require('@antv/util/lib/debounce'),
  each: require('@antv/util/lib/each'),
  throttle: require('@antv/util/lib/throttle'),
  mat3: require('@antv/util/lib/matrix/mat3'),
  vec2: require('@antv/util/lib/matrix/vec2'),
  vec3: require('@antv/util/lib/matrix/vec3'),
  transform: require('@antv/util/lib/matrix/transform'),
  clone: require('@antv/util/lib/clone'),
  upperFirst: require('@antv/util/lib/string/upper-first'),
  isNil: require('@antv/util/lib/type/is-nil'),
  isArray: require('@antv/util/lib/type/is-array'),
  createDom: require('@antv/util/lib/dom/create-dom'),
  /**
   * traverse tree
   * @param  {object}      parent      parent
   * @param  {function}    callback    callback
   * @param  {function}    getChild    get child function
   * @param  {boolean}     runSelf     callback run self or not
   */
  traverseTree(parent, callback, getChild, runSelf = false) {
    const children = getChild(parent);
    runSelf && callback(parent, null, null);
    children && BaseUtil.each(children, (child, index) => {
      callback(child, parent, index);
      BaseUtil.traverseTree(child, callback, getChild);
    });
  },

  /**
   * turn padding into [top, right, bottom, right]
   * @param  {Number|Array} padding input padding
   * @return {array} output
   */
  toAllPadding(padding) {
    let top = 0;
    let left = 0;
    let right = 0;
    let bottom = 0;

    if (BaseUtil.isNumber(padding) || BaseUtil.isString(padding)) {
      top = left = right = bottom = padding;
    } else if (BaseUtil.isArray(padding)) {
      top = padding[0];
      right = !BaseUtil.isNil(padding[1]) ? padding[1] : padding[0];
      bottom = !BaseUtil.isNil(padding[2]) ? padding[2] : padding[0];
      left = !BaseUtil.isNil(padding[3]) ? padding[3] : right;
    }
    return [ top, right, bottom, left ];
  }
};

module.exports = BaseUtil;
<|endoftext|>


<commit_before>define(
        "sb/base/binding/BindingChain",
        [
                "sb/util",
                "sb/base/binding/Binding",
                "sb/base/observable/isObservableObject"
        ],
        function(util, Binding, isObservableObject){

                /**
                 * A set of bindings which provide binding functions as method chains.
                 * @class BindingChain
                 * @constructor
                 * @namespace sb.base.binding
                 * @param {sb.base.binding.Observer} observer
                 * @param {Array} observables
                 */
                function BindingChain(observer, observables) {

                        /**
                         * Create bindings.
                         * @property bindingsMaker
                         * @private
                         * @type {sb.util.expandable}
                         */
                        var bindingsMaker = sb.util.expandable();

                        /**
                         * A set of bindings.
                         * @property bindings
                         * @private
                         * @type {Array}
                         */
                        var bindings = [];

                        /**
                         * Synchronize observables which are same value each other
                         * and when an observable changes, others immediately synchronized.
                         * @method synchronize
                         * @public
                         * @chainable
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.synchronize = function() {

                                // Arguments array this function.
                                var args = util.argumentsToArray(arguments);

                                // Observables which are synchronized.
                                var syncObservables = [];

                                args.forEach(function(arg) {
                                        if (isObservableObject(arg)) {
                                                syncObservables.push(arg);
                                                if (observables.indexOf(arg) < 0) {
                                                        observables.push(arg);
                                                }
                                        }
                                });

                                // Bindings which are used for synchronize given observables.
                                var syncBindings = syncObservables.map(function(input) {
                                        var inputs = {input: input};
                                        var outputs = {};
                                        syncObservables.forEach(function(output, i) {
                                                if (input !== output) {
                                                        outputs["output"+i] = output;
                                                }
                                        });
                                        var computed = function(inputs) {
                                                var results = {};
                                                Object.keys(outputs).forEach(function(key){
                                                        results[key] = inputs.input();
                                                });
                                                return results;
                                        };
                                        var b = new Binding(observer, inputs, outputs, computed);
                                        return b;
                                });

                                // for lazy evaluation
                                bindingsMaker.expand(function() {
                                        bindings = bindings.concat(syncBindings);
                                });

                                return this;
                        };

                        /**
                         * Add computed binding.
                         * @method computed
                         * @public
                         * @chainable
                         * @param {sb.base.observable.ObservableObject} observable target observable
                         * @param {sb.base.binding.Computed} func computed function
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.computed = function(observable, func) {

                                if (!sb.base.observable.isObservableObject(observable)
                                    || typeof func !== "function") {
                                            return this;
                                    }

                                    if (observables.indexOf(observable) < 0) {
                                            observables.push(observable);
                                    }

                                    // lazy evaluation
                                    bindingsMaker.expand(function() {
                                            var inputs = {};
                                            observables.forEach(function(input, i) {
                                                    if (observable !== input) {
                                                            inputs["input"+i] = input;
                                                    }
                                            });
                                            var outputs = {output: observable};

                                            var b = new sb.base.binding.Binding(
                                                    observer,
                                                    inputs,
                                                    outputs,
                                                    function(inputs, source, e) {
                                                            return {output: func(inputs, source, e)};
                                                    }
                                            );

                                            bindings.push(b);
                                    });

                                    return this;
                        };

                        /**
                         * Add callback which call after changing a given observable value.
                         * @method onChange
                         * @public
                         * @chainable
                         * @param {sb.base.observable.ObservableObject} observable target observable.
                         * @param {function(sb.base.observable.ObservableObject, sb.base.binding.NotificationEvent)} callback callback function
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.onChange = function(observable, callback) {

                                if (!sb.base.observable.isObservableObject(observable)
                                    || typeof callback !== "function") {
                                            return this;
                                    }

                                    if (observables.indexOf(observable)) {
                                            observables.push(observable);
                                    }

                                    var b = new sb.base.binding.Binding(
                                            observer,
                                            {input: observable},
                                            {},
                                            function(inputs, source, e) {
                                                    callback(source, e);
                                                    return {};
                                            }
                                    );

                                    // for lazy evaluation
                                    bindingsMaker.expand(function() {
                                            bindings.push(b);
                                    });
                                    return this;
                        };

                        /**
                         * Enable internal all internal bindings.
                         * @method bind
                         * @public
                         * @chainable
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.bind = function() {

                                // init
                                this.unbind();
                                bindingsMaker();

                                bindings.forEach(function(b) {
                                        b.bind();
                                });

                                return this;
                        };

                        /**
                         * Disable internal all internal bindings.
                         * @method unbind
                         * @public
                         * @chainable
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.unbind = function() {

                                bindings.forEach(function(b) {
                                        b.unbind();
                                });
                                bindings = [];

                                return this;
                        };
                };
                return 	BindingChain;
        }
);

<commit_msg>pass lint<commit_after>define(
        "sb/base/binding/BindingChain",
        [
                "sb/util",
                "sb/base/binding/Binding",
                "sb/base/observable/isObservableObject"
        ],
        function(util, Binding, isObservableObject){

                /**
                 * A set of bindings which provide binding functions as method chains.
                 * @class BindingChain
                 * @constructor
                 * @namespace sb.base.binding
                 * @param {sb.base.binding.Observer} observer
                 * @param {Array} observables
                 */
                function BindingChain(observer, observables) {

                        /**
                         * Create bindings.
                         * @property bindingsMaker
                         * @private
                         * @type {sb.util.expandable}
                         */
                        var bindingsMaker = sb.util.expandable();

                        /**
                         * A set of bindings.
                         * @property bindings
                         * @private
                         * @type {Array}
                         */
                        var bindings = [];

                        /**
                         * Synchronize observables which are same value each other
                         * and when an observable changes, others immediately synchronized.
                         * @method synchronize
                         * @public
                         * @chainable
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.synchronize = function() {

                                // Arguments array this function.
                                var args = util.argumentsToArray(arguments);

                                // Observables which are synchronized.
                                var syncObservables = [];

                                args.forEach(function(arg) {
                                        if (isObservableObject(arg)) {
                                                syncObservables.push(arg);
                                                if (observables.indexOf(arg) < 0) {
                                                        observables.push(arg);
                                                }
                                        }
                                });

                                // Bindings which are used for synchronize given observables.
                                var syncBindings = syncObservables.map(function(input) {
                                        var inputs = {input: input};
                                        var outputs = {};
                                        syncObservables.forEach(function(output, i) {
                                                if (input !== output) {
                                                        outputs["output"+i] = output;
                                                }
                                        });
                                        var computed = function(inputs) {
                                                var results = {};
                                                Object.keys(outputs).forEach(function(key){
                                                        results[key] = inputs.input();
                                                });
                                                return results;
                                        };
                                        var b = new Binding(observer, inputs, outputs, computed);
                                        return b;
                                });

                                // for lazy evaluation
                                bindingsMaker.expand(function() {
                                        bindings = bindings.concat(syncBindings);
                                });

                                return this;
                        };

                        /**
                         * Add computed binding.
                         * @method computed
                         * @public
                         * @chainable
                         * @param {sb.base.observable.ObservableObject} observable target observable
                         * @param {sb.base.binding.Computed} func computed function
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.computed = function(observable, func) {

                                if (!sb.base.observable.isObservableObject(observable) ||
                                    typeof func !== "function") {
                                        return this;
                                }

                                if (observables.indexOf(observable) < 0) {
                                        observables.push(observable);
                                }

                                // lazy evaluation
                                bindingsMaker.expand(function() {
                                        var inputs = {};
                                        observables.forEach(function(input, i) {
                                                if (observable !== input) {
                                                        inputs["input"+i] = input;
                                                }
                                        });
                                        var outputs = {output: observable};

                                        var b = new sb.base.binding.Binding(
                                                observer,
                                                inputs,
                                                outputs,
                                                function(inputs, source, e) {
                                                        return {output: func(inputs, source, e)};
                                                }
                                        );

                                        bindings.push(b);
                                });

                                return this;
                        };

                        /**
                         * Add callback which call after changing a given observable value.
                         * @method onChange
                         * @public
                         * @chainable
                         * @param {sb.base.observable.ObservableObject} observable target observable.
                         * @param {function(sb.base.observable.ObservableObject, sb.base.binding.NotificationEvent)} callback callback function
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.onChange = function(observable, callback) {

                                if (!sb.base.observable.isObservableObject(observable) ||
                                    typeof callback !== "function") {
                                        return this;
                                }

                                if (observables.indexOf(observable)) {
                                        observables.push(observable);
                                }

                                var b = new sb.base.binding.Binding(
                                        observer,
                                        {input: observable},
                                        {},
                                        function(inputs, source, e) {
                                                callback(source, e);
                                                return {};
                                        }
                                );

                                // for lazy evaluation
                                bindingsMaker.expand(function() {
                                        bindings.push(b);
                                });
                                return this;
                        };

                        /**
                         * Enable internal all internal bindings.
                         * @method bind
                         * @public
                         * @chainable
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.bind = function() {

                                // init
                                this.unbind();
                                bindingsMaker();

                                bindings.forEach(function(b) {
                                        b.bind();
                                });

                                return this;
                        };

                        /**
                         * Disable internal all internal bindings.
                         * @method unbind
                         * @public
                         * @chainable
                         * @return {sb.base.binding.BindingChain} own object
                         */
                        this.unbind = function() {

                                bindings.forEach(function(b) {
                                        b.unbind();
                                });
                                bindings = [];

                                return this;
                        };
                }
                return BindingChain;
        }
);

<|endoftext|>


<commit_before>(function (context, factory) {
  if (typeof module === 'object' && typeof module.exports === 'object') {
    module.exports = function (context) {
      var core = require('./core.js');
      var ajax = require('./ajax.js');
      var $ = ajax(context);
      return factory(context, core, $);
    };
  } else {
    factory(context, context._, context.$);
  }
}(this, function (context, _, $) {
  'use strict';

  var window = context.window;
  // Violentmonkey passes unsafeWindow by closure/arguments
  // need to break the sandbox to get unsafeWindow
  var unsafeWindow = context.unsafeWindow || (0, eval)('this').window;
  var document = window.document;

  $.removeAllTimer = function () {
    var handle = window.setInterval(_.nop, 10);
    while (handle > 0) {
      window.clearInterval(handle--);
    }
    handle = window.setTimeout(_.nop, 10);
    while (handle > 0) {
      window.clearTimeout(handle--);
    }
  };

  $.generateRandomIP = function () {
    return [0,0,0,0].map(function () {
      return Math.floor(Math.random() * 256);
    }).join('.');
  };

  $.captcha = function (imgSrc, cb) {
    if (!$.config.externalServerSupport) {
      return;
    }

    var a = document.createElement('canvas');
    var b = a.getContext('2d');
    var c = new Image();
    c.src = imgSrc;
    c.onload = function () {
      a.width = c.width;
      a.height = c.height;
      b.drawImage(c, 0, 0);
      var d = a.toDataURL();
      var e = d.substr(d.indexOf(',') + 1);
      $.post('http://www.wcpan.info/cgi-bin/captcha.cgi', {
        i: e,
      }, cb);
    };
  };

  // Firefox only
  // cloneInto is too buggy
  // TODO Date, Regexp, subclasses
  function clone (safe) {
    if (safe === null || !(safe instanceof Object)) {
      return safe;
    }
    if (safe instanceof String) {
      return safe.toString();
    }
    if (safe instanceof Function) {
      return exportFunction(safe, unsafeWindow, {
        allowCrossOriginArguments: true,
      });
    }
    if (safe instanceof Array) {
      var unsafe = new unsafeWindow.Array();
      for (var i = 0; i < safe.length; ++i) {
        unsafe.push(clone(safe[i]));
      }
      return unsafe;
    }
    var unsafe = new unsafeWindow.Object();
    _.C(safe).each(function (v, k) {
      unsafe[k] = clone(v);
    });
    return unsafe;
  }

  // magic property to get the original object
  var MAGIC_KEY = '__adsbypasser_reverse_proxy__';

  $.window = (function () {
    // GreaseMonkey 1.15 won't pass this test
    var isFirefox = typeof InstallTrigger !== 'undefined';
    if (!isFirefox) {
      // other browsers does not need this
      return unsafeWindow;
    }

    var decorator = {
      set: function (target, key, value) {
        if (key === MAGIC_KEY) {
          return false;
        }
        // GreaseMonkey 2.1 has a bug
        // unsafeWindow.open will become read-only after modifying
        // so we have to explicitly assign property descriptor
        if (target === unsafeWindow && key === 'open') {
          var d = Object.getOwnPropertyDescriptor(target, key);
          d.value = clone(value);
          Object.defineProperty(target, key, d);
        } else {
          target[key] = clone(value);
        }
        return true;
      },
      get: function (target, key) {
        if (key === MAGIC_KEY) {
          return target;
        }
        var value = target[key];
        var type = typeof value;
        if (value === null || (type !== 'function' && type !== 'object')) {
          // primitive values does not need this
          return value;
        }
        return new Proxy(value, decorator);
      },
      apply: function (target, self, args) {
        args = Array.prototype.slice.call(args);

        // special hack for Object.defineProperty
        if (target === unsafeWindow.Object.defineProperty) {
          args[0] = args[0][MAGIC_KEY];
        }
        // special hack for Function.apply
        if (target === unsafeWindow.Function.apply) {
          self = self[MAGIC_KEY];
          args[1] = Array.prototype.slice.call(args[1]);
        }
        // special hack for querySelector
        if (target === unsafeWindow.document.querySelector) {
          self = self[MAGIC_KEY];
        }

        var usargs = clone(args);

        return target.apply(self, usargs);
      },
      construct: function (target, args) {
        args = Array.prototype.slice.call(args);
        // insert this argument
        args.unshift(undefined);
        var usargs = clone(args);
        var bind = unsafeWindow.Function.prototype.bind;
        return new (bind.apply(target, usargs));
      },
    };
    return new Proxy(unsafeWindow, decorator);
  })();

  return $;

}));

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<commit_msg>Add new API.<commit_after>(function (context, factory) {
  if (typeof module === 'object' && typeof module.exports === 'object') {
    module.exports = function (context) {
      var core = require('./core.js');
      var ajax = require('./ajax.js');
      var $ = ajax(context);
      return factory(context, core, $);
    };
  } else {
    factory(context, context._, context.$);
  }
}(this, function (context, _, $) {
  'use strict';

  var window = context.window;
  // Violentmonkey passes unsafeWindow by closure/arguments
  // need to break the sandbox to get unsafeWindow
  var unsafeWindow = context.unsafeWindow || (0, eval)('this').window;
  var document = window.document;

  $.removeAllTimer = function () {
    var handle = window.setInterval(_.nop, 10);
    while (handle > 0) {
      window.clearInterval(handle--);
    }
    handle = window.setTimeout(_.nop, 10);
    while (handle > 0) {
      window.clearTimeout(handle--);
    }
  };

  $.nuke = function () {
    document.write('nuked by AdsBypasser');
  };

  $.generateRandomIP = function () {
    return [0,0,0,0].map(function () {
      return Math.floor(Math.random() * 256);
    }).join('.');
  };

  $.captcha = function (imgSrc, cb) {
    if (!$.config.externalServerSupport) {
      return;
    }

    var a = document.createElement('canvas');
    var b = a.getContext('2d');
    var c = new Image();
    c.src = imgSrc;
    c.onload = function () {
      a.width = c.width;
      a.height = c.height;
      b.drawImage(c, 0, 0);
      var d = a.toDataURL();
      var e = d.substr(d.indexOf(',') + 1);
      $.post('http://www.wcpan.info/cgi-bin/captcha.cgi', {
        i: e,
      }, cb);
    };
  };

  // Firefox only
  // cloneInto is too buggy
  // TODO Date, Regexp, subclasses
  function clone (safe) {
    if (safe === null || !(safe instanceof Object)) {
      return safe;
    }
    if (safe instanceof String) {
      return safe.toString();
    }
    if (safe instanceof Function) {
      return exportFunction(safe, unsafeWindow, {
        allowCrossOriginArguments: true,
      });
    }
    if (safe instanceof Array) {
      var unsafe = new unsafeWindow.Array();
      for (var i = 0; i < safe.length; ++i) {
        unsafe.push(clone(safe[i]));
      }
      return unsafe;
    }
    var unsafe = new unsafeWindow.Object();
    _.C(safe).each(function (v, k) {
      unsafe[k] = clone(v);
    });
    return unsafe;
  }

  // magic property to get the original object
  var MAGIC_KEY = '__adsbypasser_reverse_proxy__';

  $.window = (function () {
    // GreaseMonkey 1.15 won't pass this test
    var isFirefox = typeof InstallTrigger !== 'undefined';
    if (!isFirefox) {
      // other browsers does not need this
      return unsafeWindow;
    }

    var decorator = {
      set: function (target, key, value) {
        if (key === MAGIC_KEY) {
          return false;
        }
        // GreaseMonkey 2.1 has a bug
        // unsafeWindow.open will become read-only after modifying
        // so we have to explicitly assign property descriptor
        if (target === unsafeWindow && key === 'open') {
          var d = Object.getOwnPropertyDescriptor(target, key);
          d.value = clone(value);
          Object.defineProperty(target, key, d);
        } else {
          target[key] = clone(value);
        }
        return true;
      },
      get: function (target, key) {
        if (key === MAGIC_KEY) {
          return target;
        }
        var value = target[key];
        var type = typeof value;
        if (value === null || (type !== 'function' && type !== 'object')) {
          // primitive values does not need this
          return value;
        }
        return new Proxy(value, decorator);
      },
      apply: function (target, self, args) {
        args = Array.prototype.slice.call(args);

        // special hack for Object.defineProperty
        if (target === unsafeWindow.Object.defineProperty) {
          args[0] = args[0][MAGIC_KEY];
        }
        // special hack for Function.apply
        if (target === unsafeWindow.Function.apply) {
          self = self[MAGIC_KEY];
          args[1] = Array.prototype.slice.call(args[1]);
        }
        // special hack for querySelector
        if (target === unsafeWindow.document.querySelector) {
          self = self[MAGIC_KEY];
        }

        var usargs = clone(args);

        return target.apply(self, usargs);
      },
      construct: function (target, args) {
        args = Array.prototype.slice.call(args);
        // insert this argument
        args.unshift(undefined);
        var usargs = clone(args);
        var bind = unsafeWindow.Function.prototype.bind;
        return new (bind.apply(target, usargs));
      },
    };
    return new Proxy(unsafeWindow, decorator);
  })();

  return $;

}));

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<|endoftext|>


<commit_before>(function() {

  /**
   * @namespace
   */
  fabric.util = { };

  /**
   * Removes value from an array.
   * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`
   * @static
   * @memberOf fabric.util
   * @method removeFromArray
   * @param {Array} array
   * @param {Any} value
   * @return {Array} original array
   */
  function removeFromArray(array, value) {
    var idx = array.indexOf(value);
    if (idx !== -1) {
      array.splice(idx, 1);
    }
    return array;
  };

  /**
   * Returns random number between 2 specified ones.
   * @static
   * @method getRandomInt
   * @memberOf fabric.util
   * @param {Number} min lower limit
   * @param {Number} max upper limit
   * @return {Number} random value (between min and max)
   */
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  var PiBy180 = Math.PI / 180;

  /**
   * Transforms degrees to radians.
   * @static
   * @method degreesToRadians
   * @memberOf fabric.util
   * @param {Number} degrees value in degrees
   * @return {Number} value in radians
   */
  function degreesToRadians(degrees) {
    return degrees * PiBy180;
  }

  /**
   * A wrapper around Number#toFixed, which contrary to native method returns number, not string.
   * @static
   * @method toFixed
   * @memberOf fabric.util
   * @param {Number | String} number number to operate on
   * @param {Number} fractionDigits number of fraction digits to "leave"
   * @return {Number}
   */
   function toFixed(number, fractionDigits) {
     return parseFloat(Number(number).toFixed(fractionDigits));
   }

   /**
    * Function which always returns `false`.
    * @static
    * @method falseFunction
    * @memberOf fabric.util
    * @return {Boolean}
    */
   function falseFunction() {
     return false;
   }

   /**
    * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.
    * @method animate
    * @memberOf fabric.util
    * @param {Object} [options] Animation options
    * @param {Function} [options.onChange] Callback; invoked on every value change
    * @param {Function} [options.onComplete] Callback; invoked when value change is completed
    * @param {Number} [options.startValue=0] Starting value
    * @param {Number} [options.endValue=100] Ending value
    * @param {Function} [options.easing] Easing function
    * @param {Number} [options.duration=500] Duration of change
    */
   function animate(options) {

     options || (options = { });

     var start = +new Date(),
         duration = options.duration || 500,
         finish = start + duration, time, pos,
         onChange = options.onChange || function() { },
         abort = options.abort || function() { return false; },
         easing = options.easing || function(pos) { return (-Math.cos(pos * Math.PI) / 2) + 0.5; },
         startValue = 'startValue' in options ? options.startValue : 0,
         endValue = 'endValue' in options ? options.endValue : 100,
         isReversed = startValue > endValue;

     options.onStart && options.onStart();

     var interval = setInterval(function() {
       time = +new Date();
       pos = time > finish ? 1 : (time - start) / duration;
       onChange(isReversed
         ? (startValue - (startValue - endValue) * easing(pos))
         : (startValue + (endValue - startValue) * easing(pos)));
       if (time > finish || abort()) {
         clearInterval(interval);
         options.onComplete && options.onComplete();
       }
     }, 10);

     return interval;
   }

  fabric.util.removeFromArray = removeFromArray;
  fabric.util.degreesToRadians = degreesToRadians;
  fabric.util.toFixed = toFixed;
  fabric.util.getRandomInt = getRandomInt;
  fabric.util.falseFunction = falseFunction;
  fabric.util.animate = animate;

})();<commit_msg>Remove unnecessary test in fabric.util.animate<commit_after>(function() {

  /**
   * @namespace
   */
  fabric.util = { };

  /**
   * Removes value from an array.
   * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`
   * @static
   * @memberOf fabric.util
   * @method removeFromArray
   * @param {Array} array
   * @param {Any} value
   * @return {Array} original array
   */
  function removeFromArray(array, value) {
    var idx = array.indexOf(value);
    if (idx !== -1) {
      array.splice(idx, 1);
    }
    return array;
  };

  /**
   * Returns random number between 2 specified ones.
   * @static
   * @method getRandomInt
   * @memberOf fabric.util
   * @param {Number} min lower limit
   * @param {Number} max upper limit
   * @return {Number} random value (between min and max)
   */
  function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  var PiBy180 = Math.PI / 180;

  /**
   * Transforms degrees to radians.
   * @static
   * @method degreesToRadians
   * @memberOf fabric.util
   * @param {Number} degrees value in degrees
   * @return {Number} value in radians
   */
  function degreesToRadians(degrees) {
    return degrees * PiBy180;
  }

  /**
   * A wrapper around Number#toFixed, which contrary to native method returns number, not string.
   * @static
   * @method toFixed
   * @memberOf fabric.util
   * @param {Number | String} number number to operate on
   * @param {Number} fractionDigits number of fraction digits to "leave"
   * @return {Number}
   */
   function toFixed(number, fractionDigits) {
     return parseFloat(Number(number).toFixed(fractionDigits));
   }

   /**
    * Function which always returns `false`.
    * @static
    * @method falseFunction
    * @memberOf fabric.util
    * @return {Boolean}
    */
   function falseFunction() {
     return false;
   }

   /**
    * Changes value from one to another within certain period of time, invoking callbacks as value is being changed.
    * @method animate
    * @memberOf fabric.util
    * @param {Object} [options] Animation options
    * @param {Function} [options.onChange] Callback; invoked on every value change
    * @param {Function} [options.onComplete] Callback; invoked when value change is completed
    * @param {Number} [options.startValue=0] Starting value
    * @param {Number} [options.endValue=100] Ending value
    * @param {Function} [options.easing] Easing function
    * @param {Number} [options.duration=500] Duration of change
    */
   function animate(options) {

     options || (options = { });

     var start = +new Date(),
         duration = options.duration || 500,
         finish = start + duration, time, pos,
         onChange = options.onChange || function() { },
         abort = options.abort || function() { return false; },
         easing = options.easing || function(pos) { return (-Math.cos(pos * Math.PI) / 2) + 0.5; },
         startValue = 'startValue' in options ? options.startValue : 0,
         endValue = 'endValue' in options ? options.endValue : 100;

     options.onStart && options.onStart();

     var interval = setInterval(function() {
       time = +new Date();
       pos = time > finish ? 1 : (time - start) / duration;
       onChange(startValue + (endValue - startValue) * easing(pos));
       if (time > finish || abort()) {
         clearInterval(interval);
         options.onComplete && options.onComplete();
       }
     }, 10);

     return interval;
   }

  fabric.util.removeFromArray = removeFromArray;
  fabric.util.degreesToRadians = degreesToRadians;
  fabric.util.toFixed = toFixed;
  fabric.util.getRandomInt = getRandomInt;
  fabric.util.falseFunction = falseFunction;
  fabric.util.animate = animate;

})();
<|endoftext|>


<commit_before>'use strict';
angular.module('arethusa.hist').service('history', [
  'configurator',
  'keyCapture',
  'state',
  function (configurator, keyCapture, state) {
    var self = this;

    function configure() {
      configurator.getConfAndDelegate('history', self);
      self.maxSize = self.maxSize || 20;
    }

    function doSilent(fn) {
      state.doSilent(fn);
      checkAvailability();
    }

    this.undo = function() {
      if (self.canUndo) {
        doSilent(function() {
          current().undo();
          self.position++;
        });
      }
    };

    this.redo = function() {
      if (self.canRedo) {
        doSilent(function() {
          self.position--;
          current().exec();
        });
      }
    };

    keyCapture.initCaptures(function(kC) {
      return {
        history: [
          kC.create('undo', self.undo),
          kC.create('redo', self.redo)
        ]
      };
    });

    function current() {
      return self.events[self.position];
    }

    this.saveEvent = function(event) {
      if (state.silent) return;

      var events = self.events;
      if (events.length === self.maxSize) events.pop();
      events.splice(0, self.position);
      self.position = 0;
      events.unshift(event);
      checkAvailability();
    };

    function checkAvailability() {
      var any = self.events.length > 0;
      self.canUndo = any && self.position < self.events.length;
      self.canRedo = any && self.position > 0;
    }

    state.watch('*', function(n, o, event) {
      self.saveEvent(event);
    });

    function HistEvent(token, type) {
      var id = token.id;

      this.token = token;
      this.type = type;
      this.time = new Date();

      if (type === 'add') {
        this.exec = function() {
          state.addToken(token, id);
        };
        this.undo = function() {
          state.removeToken(id);
        };
      } else { // type === removed
        this.exec = function() {
          state.removeToken(id);
        };
        this.undo = function() {
          state.addToken(token, id);
        };
      }
    }

    state.on('tokenAdded', function(event, token) {
      var histEvent = new HistEvent(token, 'add');
      self.saveEvent(histEvent);
    });

    state.on('tokenRemoved', function(event, token) {
      var histEvent = new HistEvent(token, 'remove');
      self.saveEvent(histEvent);
    });

    this.init = function() {
      configure();
      self.canRedo = false;
      self.canUndo = false;
      self.events = [];
      self.position = 0;
    };
  }
]);
<commit_msg>Make history file a little prettier<commit_after>'use strict';
angular.module('arethusa.hist').service('history', [
  'configurator',
  'keyCapture',
  'state',
  function (configurator, keyCapture, state) {
    var self = this;

    function configure() {
      configurator.getConfAndDelegate('history', self);
      self.maxSize = self.maxSize || 20;
    }

    function doSilent(fn) {
      state.doSilent(fn);
      checkAvailability();
    }

    function current() {
      return self.events[self.position];
    }

    function checkAvailability() {
      var any = self.events.length > 0;
      self.canUndo = any && self.position < self.events.length;
      self.canRedo = any && self.position > 0;
    }

    function HistEvent(token, type) {
      var id = token.id;

      this.token = token;
      this.type = type;
      this.time = new Date();

      if (type === 'add') {
        this.exec = function() {
          state.addToken(token, id);
        };
        this.undo = function() {
          state.removeToken(id);
        };
      } else { // type === removed
        this.exec = function() {
          state.removeToken(id);
        };
        this.undo = function() {
          state.addToken(token, id);
        };
      }
    }

/***************************************************************************
 *                            Public Functions                             *
 ***************************************************************************/

    this.undo = function() {
      if (self.canUndo) {
        doSilent(function() {
          current().undo();
          self.position++;
        });
      }
    };

    this.redo = function() {
      if (self.canRedo) {
        doSilent(function() {
          self.position--;
          current().exec();
        });
      }
    };

    this.saveEvent = function(event) {
      if (state.silent) return;

      var events = self.events;
      if (events.length === self.maxSize) events.pop();
      events.splice(0, self.position);
      self.position = 0;
      events.unshift(event);
      checkAvailability();
    };

/***************************************************************************
 *                          Watches and Listeners                          *
 ***************************************************************************/

    state.watch('*', function(n, o, event) {
      self.saveEvent(event);
    });

    state.on('tokenAdded', function(event, token) {
      var histEvent = new HistEvent(token, 'add');
      self.saveEvent(histEvent);
    });

    state.on('tokenRemoved', function(event, token) {
      var histEvent = new HistEvent(token, 'remove');
      self.saveEvent(histEvent);
    });

/***************************************************************************
 *                                  Init                                   *
 ***************************************************************************/

    keyCapture.initCaptures(function(kC) {
      return {
        history: [
          kC.create('undo', self.undo),
          kC.create('redo', self.redo)
        ]
      };
    });

    this.init = function() {
      configure();
      self.canRedo = false;
      self.canUndo = false;
      self.events = [];
      self.position = 0;
    };
  }
]);
<|endoftext|>


<commit_before>'use strict';

const Notification = require('atom').Notification;

const _caches = require('./caches');
const _db = require('./db');
const _utils = require('./utils');
const _gateway = require('./gateway');

const _component = require('./component');

const utilities = {
    registerComponent: function registerComponent(component) {
        return _component.register(component.definition, component.methods);
    },
    getConstructor: function getConstructor(definition) {
        return _component.getConstructor(definition);
    },
    fetchProjects: function fetchProjects () {
        return _db.views.projects.map(
            (projectId) => {
                return _db.mapper.get(
                    document.getElementById(projectId)
                );
            }
        ).filter(
            (project) => {
                if (!project) {
                    return false;
                }
                return true;
            }
        );
    },
    getItemChain: function f_getItemChain (item) {
        let parentPrototype;
        let parentProto;
        let rootPrototype;
        let chain = {};

        if (item && Object.keys(item).length > 0) {
            chain.current = item;
        }

        if (Object.getPrototypeOf(item) === Object.prototype) {
            parentPrototype = undefined;
        } else {
            parentPrototype = Object.getPrototypeOf(item);
            parentProto = Object.getPrototypeOf(parentPrototype);
            chain.parent = parentPrototype;
        }

        if (parentProto === Object.prototype) {
            rootPrototype = undefined;
        } else if (parentProto) {
            rootPrototype = parentProto;
            chain.root = rootPrototype;
        }

        return chain;
    },
    removeItem: function removeItem(original) {
        const promise = new Promise((resolve, reject) => {
            this.getDB().store();
            let currentName = original[original.type + 'Name'];

            const idx = this.getDB().views[original.type + 's'].indexOf(original[original.type + 'Id']);
            let view;
            if (idx !== -1) {
                this.getDB().views[original.type + 's'].splice(idx, 1);
                view = document.getElementById(original[original.type + 'Id']);
            }

            if (view) {
                view.remove();
            }

            this.getDB().store();

            this.updateStatusBar();

            resolve({
                type: 'success',
                message: `Removed <em>${original.type}</em> called <strong>${currentName}</strong>!`
            });
        });
        return promise;
    },
    updateItem: function updateItem(original, changes) {
        const promise = new Promise((resolve, reject) => {
            let isANewParent;
            let currentName = original.current[original.current.type + 'Name'];
            let activeModel = this.getSelectedProjectModel();
            const itemView = document.getElementById(original.current[original.current.type + 'Id']);

            if (changes.name) {
                const newName = _utils.sanitizeString(changes.name);
                original.current[original.current.type + 'Name'] = newName;
                itemView.setText(newName);
            }

            if (changes.icon) {
                original.current[original.current.type + 'Icon'] = changes.icon;
                itemView.setIcon(changes.icon, true);
            }
            else {
                original.current[original.current.type + 'Icon'] = undefined;
                itemView.setIcon('');
            }

            if (changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = changes.color;
                itemView.setColor(changes.color);
            }
            else if (!changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = undefined;
                itemView.setColor();
            }

            if (changes.sortBy) {
                original.current.sortBy = changes.sortBy;
                itemView.sortChildren();
            }

            if (changes.paths) {
                changes.paths.remove.forEach(
                    (path) => {
                        const pathIdx = original.current.projectPaths.indexOf(path);
                        if (pathIdx !== -1) {
                            original.current.projectPaths.splice(pathIdx, 1);
                        }
                        if (pathIdx !== -1 && activeModel && activeModel.projectId === original.current.projectId) {
                            atom.project.removePath(path);
                        }
                    }
                );
                changes.paths.add.forEach(
                    (path) => {
                        const pathIdx = original.current.projectPaths.indexOf(path);
                        if (pathIdx === 1) {
                            original.current.projectPaths.push(path);
                        }
                        if (pathNotInArray && activeModel && activeModel.projectId === original.current.projectId) {
                            atom.project.addPath(path);
                        }
                    }
                );
                itemView.validate();
            }

            if (changes.hasGroup) {
                Object.setPrototypeOf(original.current, changes.group);
                isANewParent = document.getElementById(changes.group.groupId);
            }
            else if (changes.hasClient) {
                Object.setPrototypeOf(original.current, changes.client);
                isANewParent = document.getElementById(changes.client.clientId);
            }
            else if (!changes.hasGroup && !original.parent && !original.root) {
                Object.setPrototypeOf(original.current, Object.prototype);
                isANewParent = document.querySelector('ul[is="pv-list-tree"].list-tree.has-collapsable-children')
            }

            if (isANewParent) {
                isANewParent.addChild(itemView, true, true);
            }

            this.getDB().store();

            this.updateStatusBar();

            resolve({
                type: 'success',
                message: `Updates to <strong>${currentName}</strong> were applied!`
            });
        });
        return promise;
    },
    createItem: function createItem(original, changes) {
        const promise = new Promise((resolve, reject) => {
            if (!original.current || !changes) {
                reject({
                    type: 'warning',
                    message: 'Please provide the minimum parameters to create a new item'
                });
            }

            if (!original.current.type) {
                reject({
                    type: 'warning',
                    message: 'Please select a type to create'
                });
            }

            if (!changes.name) {
                reject({
                    type: 'warning',
                    message: 'Please define a valid name for the ' + changes.type + ''
                });
                return;
            }

            const newName = _utils.sanitizeString(changes.name);

            this.getDB().mapper.set(changes.view, original.current);

            original.current[original.current.type + 'Id'] = _gateway.helpers.generateUUID();
            changes.view.setId(original.current[original.current.type + 'Id']);
            original.current[original.current.type + 'Name'] = changes.name;
            changes.view.setText(original.current[original.current.type + 'Name']);
            original.current[original.current.type + 'Icon'] = changes.icon || '';
            changes.view.setIcon(original.current[original.current.type + 'Icon']);

            if (original.current.type !== 'project') {
                original.current.sortBy = changes.sortBy || 'position';
                original.current[original.current.type + 'Expanded'] = false;
                changes.view.setExpanded(false);
            } else {
                original.current[original.current.type + 'Paths'] = changes.paths || [];
            }

            if (changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = changes.color;
                changes.view.setColor(changes.color);
            }
            else if (!changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = undefined;
                changes.view.setColor();
            }

            let parentView;

            if (changes.hasGroup) {
                parentView = document.getElementById(changes.group.groupId);
                parentView.addChild(changes.view);
            }
            else if (changes.hasClient) {
                parentView = document.getElementById(changes.client.clientId);
                parentView.addChild(changes.view);
            } else {
                parentView = document.querySelector('project-viewer .list-tree.has-collapsable-children');
                parentView.addNode(changes.view);
            }

            this.getDB().views[original.current.type + 's'].push(original.current[original.current.type + 'Id']);
            this.getDB().store();

            resolve({
                type: 'success',
                message: `${original.current.type} <strong>${newName}</strong> was created`
            });
        });
        return promise;
    },
    getConfig: function getConfig(config) {
        return _db.info.name.concat('.', config);
    },
    setSelectedProjectView: function setSelectedProjectView(view) {
        _caches.selectedProjectView = view;
        this.updateStatusBar();
    },
    getSelectedProjectView: function getSelectedProjectView() {
        let view = _caches.selectedProjectView;
        if (!view) {
            view = document.querySelector('project-viewer .active');
            _caches.selectedProjectView = view;
        }
        return view;
    },
    getSelectedProjectModel: function getSelectedProjectModel() {
        let selected = this.getSelectedProjectView();
        let model;

        if (selected) {
            model = _db.mapper.get(selected);
        }

        return model;
    },
    clearStatusBar: function clearStatusBar() {
        _caches.statusBar = undefined;
    },
    getStatusBar: function getStatusBar() {
        let view = _caches.statusBar;
        if (!view) {
            view = document.querySelector('pv-status-bar');
            _caches.statusBar = view;
        }
        return view;
    },
    updateStatusBar: function updateStatusBar() {
        let statusBar = this.getStatusBar();
        let model = this.getSelectedProjectModel();
        let context = '';

        if (!statusBar) {
            return;
        }

        if (!model) {
            context = 'No project selected';
            statusBar.setText(context);
            return;
        }

        if (model.clientName) {
            context += model.clientName + ' / ';
        }

        if (model.groupName) {
            context += model.groupName + ' / ';
        }

        if (model.projectName) {
            context += model.projectName;
        } else {
            context = 'No project selected';
        }

        statusBar.setText(context);
    },
    setStatusBarText: function setStatusBarText(text) {
        let statusBar = this.getStatusBar();

        if (statusBar && typeof text === 'string') {
            statusBar.setText(text);
        }
    },
    getDB: function getDB() {
        return _db;
    }
};

module.exports = utilities;
<commit_msg>Fix issue #71<commit_after>'use strict';

const Notification = require('atom').Notification;

const _caches = require('./caches');
const _db = require('./db');
const _utils = require('./utils');
const _gateway = require('./gateway');

const _component = require('./component');

const utilities = {
    registerComponent: function registerComponent(component) {
        return _component.register(component.definition, component.methods);
    },
    getConstructor: function getConstructor(definition) {
        return _component.getConstructor(definition);
    },
    fetchProjects: function fetchProjects () {
        return _db.views.projects.map(
            (projectId) => {
                return _db.mapper.get(
                    document.getElementById(projectId)
                );
            }
        ).filter(
            (project) => {
                if (!project) {
                    return false;
                }
                return true;
            }
        );
    },
    getItemChain: function f_getItemChain (item) {
        let parentPrototype;
        let parentProto;
        let rootPrototype;
        let chain = {};

        if (item && Object.keys(item).length > 0) {
            chain.current = item;
        }

        if (Object.getPrototypeOf(item) === Object.prototype) {
            parentPrototype = undefined;
        } else {
            parentPrototype = Object.getPrototypeOf(item);
            parentProto = Object.getPrototypeOf(parentPrototype);
            chain.parent = parentPrototype;
        }

        if (parentProto === Object.prototype) {
            rootPrototype = undefined;
        } else if (parentProto) {
            rootPrototype = parentProto;
            chain.root = rootPrototype;
        }

        return chain;
    },
    removeItem: function removeItem(original) {
        const promise = new Promise((resolve, reject) => {
            this.getDB().store();
            let currentName = original[original.type + 'Name'];

            const idx = this.getDB().views[original.type + 's'].indexOf(original[original.type + 'Id']);
            let view;
            if (idx !== -1) {
                this.getDB().views[original.type + 's'].splice(idx, 1);
                view = document.getElementById(original[original.type + 'Id']);
            }

            if (view) {
                view.remove();
            }

            this.getDB().store();

            this.updateStatusBar();

            resolve({
                type: 'success',
                message: `Removed <em>${original.type}</em> called <strong>${currentName}</strong>!`
            });
        });
        return promise;
    },
    updateItem: function updateItem(original, changes) {
        const promise = new Promise((resolve, reject) => {
            let isANewParent;
            let currentName = original.current[original.current.type + 'Name'];
            let activeModel = this.getSelectedProjectModel();
            const itemView = document.getElementById(original.current[original.current.type + 'Id']);

            if (changes.name) {
                const newName = _utils.sanitizeString(changes.name);
                original.current[original.current.type + 'Name'] = newName;
                itemView.setText(newName);
            }

            if (changes.icon) {
                original.current[original.current.type + 'Icon'] = changes.icon;
                itemView.setIcon(changes.icon, true);
            }
            else {
                original.current[original.current.type + 'Icon'] = undefined;
                itemView.setIcon('');
            }

            if (changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = changes.color;
                itemView.setColor(changes.color);
            }
            else if (!changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = undefined;
                itemView.setColor();
            }

            if (changes.sortBy) {
                original.current.sortBy = changes.sortBy;
                itemView.sortChildren();
            }

            if (changes.paths) {
                changes.paths.remove.forEach(
                    (path) => {
                        const pathIdx = original.current.projectPaths.indexOf(path);
                        if (pathIdx !== -1) {
                            original.current.projectPaths.splice(pathIdx, 1);
                        }
                        if (pathIdx !== -1 && activeModel && activeModel.projectId === original.current.projectId) {
                            atom.project.removePath(path);
                        }
                    }
                );
                changes.paths.add.forEach(
                    (path) => {
                        if ( path !== undefined ) {
                            original.current.projectPaths.push(path);
                        }
                    }
                );
                itemView.validate();
            }

            if (changes.hasGroup) {
                Object.setPrototypeOf(original.current, changes.group);
                isANewParent = document.getElementById(changes.group.groupId);
            }
            else if (changes.hasClient) {
                Object.setPrototypeOf(original.current, changes.client);
                isANewParent = document.getElementById(changes.client.clientId);
            }
            else if (!changes.hasGroup && !original.parent && !original.root) {
                Object.setPrototypeOf(original.current, Object.prototype);
                isANewParent = document.querySelector('ul[is="pv-list-tree"].list-tree.has-collapsable-children')
            }

            if (isANewParent) {
                isANewParent.addChild(itemView, true, true);
            }

            this.getDB().store();

            this.updateStatusBar();

            resolve({
                type: 'success',
                message: `Updates to <strong>${currentName}</strong> were applied!`
            });
        });
        return promise;
    },
    createItem: function createItem(original, changes) {
        const promise = new Promise((resolve, reject) => {
            if (!original.current || !changes) {
                reject({
                    type: 'warning',
                    message: 'Please provide the minimum parameters to create a new item'
                });
            }

            if (!original.current.type) {
                reject({
                    type: 'warning',
                    message: 'Please select a type to create'
                });
            }

            if (!changes.name) {
                reject({
                    type: 'warning',
                    message: 'Please define a valid name for the ' + changes.type + ''
                });
                return;
            }

            const newName = _utils.sanitizeString(changes.name);

            this.getDB().mapper.set(changes.view, original.current);

            original.current[original.current.type + 'Id'] = _gateway.helpers.generateUUID();
            changes.view.setId(original.current[original.current.type + 'Id']);
            original.current[original.current.type + 'Name'] = changes.name;
            changes.view.setText(original.current[original.current.type + 'Name']);
            original.current[original.current.type + 'Icon'] = changes.icon || '';
            changes.view.setIcon(original.current[original.current.type + 'Icon']);

            if (original.current.type !== 'project') {
                original.current.sortBy = changes.sortBy || 'position';
                original.current[original.current.type + 'Expanded'] = false;
                changes.view.setExpanded(false);
            } else {
                original.current[original.current.type + 'Paths'] = changes.paths || [];
            }

            if (changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = changes.color;
                changes.view.setColor(changes.color);
            }
            else if (!changes.color && original.current.type !== 'project') {
                original.current[original.current.type + 'Color'] = undefined;
                changes.view.setColor();
            }

            let parentView;

            if (changes.hasGroup) {
                parentView = document.getElementById(changes.group.groupId);
                parentView.addChild(changes.view);
            }
            else if (changes.hasClient) {
                parentView = document.getElementById(changes.client.clientId);
                parentView.addChild(changes.view);
            } else {
                parentView = document.querySelector('project-viewer .list-tree.has-collapsable-children');
                parentView.addNode(changes.view);
            }

            this.getDB().views[original.current.type + 's'].push(original.current[original.current.type + 'Id']);
            this.getDB().store();

            resolve({
                type: 'success',
                message: `${original.current.type} <strong>${newName}</strong> was created`
            });
        });
        return promise;
    },
    getConfig: function getConfig(config) {
        return _db.info.name.concat('.', config);
    },
    setSelectedProjectView: function setSelectedProjectView(view) {
        _caches.selectedProjectView = view;
        this.updateStatusBar();
    },
    getSelectedProjectView: function getSelectedProjectView() {
        let view = _caches.selectedProjectView;
        if (!view) {
            view = document.querySelector('project-viewer .active');
            _caches.selectedProjectView = view;
        }
        return view;
    },
    getSelectedProjectModel: function getSelectedProjectModel() {
        let selected = this.getSelectedProjectView();
        let model;

        if (selected) {
            model = _db.mapper.get(selected);
        }

        return model;
    },
    clearStatusBar: function clearStatusBar() {
        _caches.statusBar = undefined;
    },
    getStatusBar: function getStatusBar() {
        let view = _caches.statusBar;
        if (!view) {
            view = document.querySelector('pv-status-bar');
            _caches.statusBar = view;
        }
        return view;
    },
    updateStatusBar: function updateStatusBar() {
        let statusBar = this.getStatusBar();
        let model = this.getSelectedProjectModel();
        let context = '';

        if (!statusBar) {
            return;
        }

        if (!model) {
            context = 'No project selected';
            statusBar.setText(context);
            return;
        }

        if (model.clientName) {
            context += model.clientName + ' / ';
        }

        if (model.groupName) {
            context += model.groupName + ' / ';
        }

        if (model.projectName) {
            context += model.projectName;
        } else {
            context = 'No project selected';
        }

        statusBar.setText(context);
    },
    setStatusBarText: function setStatusBarText(text) {
        let statusBar = this.getStatusBar();

        if (statusBar && typeof text === 'string') {
            statusBar.setText(text);
        }
    },
    getDB: function getDB() {
        return _db;
    }
};

module.exports = utilities;
<|endoftext|>


<commit_before>function LevelListViewCtrl($q, LevelService, CurrentUserService, LoggerService) {

  var vm = this;
  var currentOrg = CurrentUserService.getOrganization();

  vm.levels = [];
  vm.buyLevel = buyLevel;

  init();

  /** Get levels and mark the ones already bought */
  // TODO: Should be in a service
  function init() {
    $q.all([
      LevelService.getLevels(),
      LevelService.getLevelsByOrganizationId(currentOrg._id)
    ])
    .then(function (results) {
      vm.levels = results[0];
      var boughtLevels = results[1];

      _.each(vm.levels, function(level) {
        var isAlreadyBought = _.find(boughtLevels, function(boughtLevel) {
          return level._id == boughtLevel._id;
        });

        if (isAlreadyBought)
          level.bought = true;
        else
          level.bought = false;
      });
    });
  }

  /** Buys a level and reload organization info */
  // TODO: Should be in a service
  function buyLevel(level) {

    var currentOrg = CurrentUserService.getOrganization();

    if (currentOrg.statistics.cash - level.price < 0) {
      LoggerService.error('You do not have enough cash to buy this level');
      return false;
    }

    return LevelService.buyLevelbyOrganizationId(
      level._id, currentOrg._id
    )
    .then(buyLevelSuccess)
    .catch(function(response) {
      LoggerService.errorFromResponse(response);
    });

    function buyLevelSuccess() {
      level.bought = true;

      LoggerService.error("Level "+level.name+" succesfully bought !");
      CurrentUserService.loadOrganizationStatistics();
    }
  }

}

angular
  .module('portal.levels')
  .controller('LevelListViewCtrl', LevelListViewCtrl);
<commit_msg>success instead of error<commit_after>function LevelListViewCtrl($q, LevelService, CurrentUserService, LoggerService) {

  var vm = this;
  var currentOrg = CurrentUserService.getOrganization();

  vm.levels = [];
  vm.buyLevel = buyLevel;

  init();

  /** Get levels and mark the ones already bought */
  // TODO: Should be in a service
  function init() {
    $q.all([
      LevelService.getLevels(),
      LevelService.getLevelsByOrganizationId(currentOrg._id)
    ])
    .then(function (results) {
      vm.levels = results[0];
      var boughtLevels = results[1];

      _.each(vm.levels, function(level) {
        var isAlreadyBought = _.find(boughtLevels, function(boughtLevel) {
          return level._id == boughtLevel._id;
        });

        if (isAlreadyBought)
          level.bought = true;
        else
          level.bought = false;
      });
    });
  }

  /** Buys a level and reload organization info */
  // TODO: Should be in a service
  function buyLevel(level) {

    var currentOrg = CurrentUserService.getOrganization();

    if (currentOrg.statistics.cash - level.price < 0) {
      LoggerService.error('You do not have enough cash to buy this level');
      return false;
    }

    return LevelService.buyLevelbyOrganizationId(
      level._id, currentOrg._id
    )
    .then(buyLevelSuccess)
    .catch(function(response) {
      LoggerService.errorFromResponse(response);
    });

    function buyLevelSuccess() {
      level.bought = true;

      LoggerService.success("Level "+level.name+" succesfully bought !");
      CurrentUserService.loadOrganizationStatistics();
    }
  }

}

angular
  .module('portal.levels')
  .controller('LevelListViewCtrl', LevelListViewCtrl);
<|endoftext|>