<commit_before>'use strict';
const path = require('path');
const chalk = require('chalk');

/**
 * @typedef {import('../types').Identifier} Identifier
 */

/** @type {Record<string, string[]>} */
const browsers = {
  desktop: [
    'chrome',
    'edge',
    'firefox',
    'ie',
    'opera',
    'safari',
  ],
  mobile: [
    'chrome_android',
    'firefox_android',
    'opera_android',
    'qq_android',
    'safari_ios',
    'samsunginternet_android',
    'uc_android',
    'uc_chinese_android',
    'webview_android',
  ],
  server: [
    'nodejs',
  ],
  'webextensions-desktop': [
    'chrome',
    'edge',
    'firefox',
    'opera',
  ],
  'webextensions-mobile': [
    'firefox_android',
  ],
};

/**
 * @param {Identifier} data
 * @param {string[]} displayBrowsers
 * @param {string[]} requiredBrowsers
 * @param {string} category
 * @param {{error:function(...unknown):void}} logger
 * @param {string} [path]
 * @returns {boolean}
 */
function processData(data, displayBrowsers, requiredBrowsers, category, logger, path = '') {
  let hasErrors = false;
  if (data.__compat && data.__compat.support) {
    const invalidEntries = Object.keys(data.__compat.support).filter(value => !displayBrowsers.includes(value));
    if (invalidEntries.length > 0) {
      logger.error(chalk`{red.bold ${path}}{red  has the following browsers, which are invalid for }{red.bold ${category}}{red  compat data: }{red.bold ${invalidEntries.join(', ')}}`);
      hasErrors = true;
    }
    const missingEntries = requiredBrowsers.filter(value => !(value in data.__compat.support));
    if (missingEntries.length > 0) {
      logger.error(chalk`{red.bold ${path}}{red  is missing the following browsers, which are required for }{red.bold ${category}}{red  compat data: }{red.bold ${missingEntries.join(', ')}}`);
      hasErrors = true;
    }
  }
  for (const key in data) {
    if (key === "__compat") continue;
    // Note that doing `hasErrors |= processData(…)` would convert
    // `hasErrors` into a number, which could potentially lead
    // to unexpected issues down the line.

    // We can't use the ESNext `hasErrors ||= processData(…)` here either,
    // as that would prevent printing nested browser issues, making testing
    // and fixing issues longer, as nested issues wouldn't be logged.
    hasErrors = processData(
      data[key],
      displayBrowsers,
      requiredBrowsers,
      category,
      logger,
      (path && path.length > 0)
        ? `${path}.${key}`
        : key,
    ) || hasErrors;
  }
  return hasErrors;
}

/**
 * @param {string} filename
 * @returns {boolean} If the file contains errors
 */
function testBrowsers(filename) {
  const relativePath = path.relative(path.resolve(__dirname, '..'), filename);
  const category = relativePath.includes(path.sep) && relativePath.split(path.sep)[0];
  /** @type {Identifier} */
  const data = require(filename);

  if (!category) {
    console.warn(chalk.blackBright('  Browsers – Unknown category'));
    return false;
  }

  let displayBrowsers = [...browsers['desktop'], ...browsers['mobile']];
  let requiredBrowsers = browsers['desktop'];
  if (category === 'api') {
    displayBrowsers.push('nodejs');
  }
  if (category === 'javascript') {
    displayBrowsers.push(...browsers['server']);
  }
  if (category === 'webextensions') {
    displayBrowsers = [...browsers['webextensions-desktop'], ...browsers['webextensions-mobile']];
    requiredBrowsers = browsers['webextensions-desktop'];
  }
  displayBrowsers.sort();
  requiredBrowsers.sort();

  /** @type {string[]} */
  const errors = [];
  const logger = {
    /** @param {...unknown} message */
    error: (...message) => {
      errors.push(message.join(' '));
    },
  };

  processData(data, displayBrowsers, requiredBrowsers, category, logger);

  if (errors.length) {
    console.error(chalk`{red   Browsers – }{red.bold ${errors.length}}{red  ${errors.length === 1 ? 'error' : 'errors'}:}`);
    for (const error of errors) {
      console.error(`    ${error}`);
    }
    return true;
  }
  return false;
}

module.exports = testBrowsers;
<commit_msg>Lint for multiple support statements with only `version_added` (#3526)<commit_after>'use strict';
const path = require('path');
const chalk = require('chalk');

/**
 * @typedef {import('../types').Identifier} Identifier
 */

/** @type {Record<string, string[]>} */
const browsers = {
  desktop: [
    'chrome',
    'edge',
    'firefox',
    'ie',
    'opera',
    'safari',
  ],
  mobile: [
    'chrome_android',
    'firefox_android',
    'opera_android',
    'qq_android',
    'safari_ios',
    'samsunginternet_android',
    'uc_android',
    'uc_chinese_android',
    'webview_android',
  ],
  server: [
    'nodejs',
  ],
  'webextensions-desktop': [
    'chrome',
    'edge',
    'firefox',
    'opera',
  ],
  'webextensions-mobile': [
    'firefox_android',
  ],
};

/**
 * @param {Identifier} data
 * @param {string[]} displayBrowsers
 * @param {string[]} requiredBrowsers
 * @param {string} category
 * @param {{error:function(...unknown):void}} logger
 * @param {string} [path]
 * @returns {boolean}
 */
function processData(data, displayBrowsers, requiredBrowsers, category, logger, path = '') {
  let hasErrors = false;
  if (data.__compat && data.__compat.support) {
    const support = data.__compat.support;

    const invalidEntries = Object.keys(support).filter(value => !displayBrowsers.includes(value));
    if (invalidEntries.length > 0) {
      logger.error(chalk`{red.bold ${path}}{red  has the following browsers, which are invalid for }{red.bold ${category}}{red  compat data: }{red.bold ${invalidEntries.join(', ')}}`);
      hasErrors = true;
    }

    const missingEntries = requiredBrowsers.filter(value => !(value in support));
    if (missingEntries.length > 0) {
      logger.error(chalk`{red.bold ${path}}{red  is missing the following browsers, which are required for }{red.bold ${category}}{red  compat data: }{red.bold ${missingEntries.join(', ')}}`);
      hasErrors = true;
    }

    for (const [browser, supportStatement] of Object.entries(support)) {
      let statementList = Array.isArray(supportStatement) ? supportStatement : [supportStatement];
      function hasVersionAddedOnly(statement) {
        const keys = Object.keys(statement);
        return keys.length === 1 && keys[0] === 'version_added';
      }
      let sawVersionAddedOnly = false;
      for (const statement of statementList) {
        if (hasVersionAddedOnly(statement)) {
          if (sawVersionAddedOnly) {
           logger.error(`'${path}' has multiple support statement with only \`version_added\` for ${browser}`);
            hasErrors = true;
            break;
          } else {
            sawVersionAddedOnly = true;
          }
        }
      }
    }
  }
  for (const key in data) {
    if (key === "__compat") continue;
    // Note that doing `hasErrors |= processData(…)` would convert
    // `hasErrors` into a number, which could potentially lead
    // to unexpected issues down the line.

    // We can't use the ESNext `hasErrors ||= processData(…)` here either,
    // as that would prevent printing nested browser issues, making testing
    // and fixing issues longer, as nested issues wouldn't be logged.
    hasErrors = processData(
      data[key],
      displayBrowsers,
      requiredBrowsers,
      category,
      logger,
      (path && path.length > 0)
        ? `${path}.${key}`
        : key,
    ) || hasErrors;
  }
  return hasErrors;
}

/**
 * @param {string} filename
 * @returns {boolean} If the file contains errors
 */
function testBrowsers(filename) {
  const relativePath = path.relative(path.resolve(__dirname, '..'), filename);
  const category = relativePath.includes(path.sep) && relativePath.split(path.sep)[0];
  /** @type {Identifier} */
  const data = require(filename);

  if (!category) {
    console.warn(chalk.blackBright('  Browsers – Unknown category'));
    return false;
  }

  let displayBrowsers = [...browsers['desktop'], ...browsers['mobile']];
  let requiredBrowsers = browsers['desktop'];
  if (category === 'api') {
    displayBrowsers.push('nodejs');
  }
  if (category === 'javascript') {
    displayBrowsers.push(...browsers['server']);
  }
  if (category === 'webextensions') {
    displayBrowsers = [...browsers['webextensions-desktop'], ...browsers['webextensions-mobile']];
    requiredBrowsers = browsers['webextensions-desktop'];
  }
  displayBrowsers.sort();
  requiredBrowsers.sort();

  /** @type {string[]} */
  const errors = [];
  const logger = {
    /** @param {...unknown} message */
    error: (...message) => {
      errors.push(message.join(' '));
    },
  };

  processData(data, displayBrowsers, requiredBrowsers, category, logger);

  if (errors.length) {
    console.error(chalk`{red   Browsers – }{red.bold ${errors.length}}{red  ${errors.length === 1 ? 'error' : 'errors'}:}`);
    for (const error of errors) {
      console.error(`    ${error}`);
    }
    return true;
  }
  return false;
}

module.exports = testBrowsers;
<|endoftext|>


<commit_before>/*global describe, beforeEach, it */
'use strict';
var path = require('path');
var helpers = require('yeoman-generator').test;

describe('poojan-html generator', function () {
  beforeEach(function (done) {
    helpers.testDirectory(path.join(__dirname, 'temp'), function (err) {
      if (err) {
        return done(err);
      }

      this.app = helpers.createGenerator('poojan-html:app', [
        '../../app'
      ]);
      done();
    }.bind(this));
  });

  it('creates expected files', function (done) {
    var expected = [
      // add files you expect to exist here.
      '.jshintrc',
      '.editorconfig'
    ];

    helpers.mockPrompt(this.app, {
      'someOption': true
    });
    this.app.options['skip-install'] = true;
    this.app.run({}, function () {
      helpers.assertFile(expected);
      done();
    });
  });
});
<commit_msg>Added expected files to test.<commit_after>/*global describe, beforeEach, it */
'use strict';
var path = require('path');
var helpers = require('yeoman-generator').test;

describe('poojan-html generator', function () {
  beforeEach(function (done) {
    helpers.testDirectory(path.join(__dirname, 'temp'), function (err) {
      if (err) {
        return done(err);
      }

      this.app = helpers.createGenerator('poojan-html:app', [
        '../../app'
      ]);
      done();
    }.bind(this));
  });

  it('creates expected files', function (done) {
    var expected = [
      // add files you expect to exist here.
      '.jshintrc',
      '.editorconfig',
      'bower.json',
      'package.json'
    ];

    helpers.mockPrompt(this.app, {
      'someOption': true
    });
    this.app.options['skip-install'] = true;
    this.app.run({}, function () {
      helpers.assertFile(expected);
      done();
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var EventEmitter = require('events');
var assign = require('react/lib/Object.assign');

var NOOP = function () {};

function Img (src) {
  this._originalSrc = src;
  this._img = new Image();
  this._img.onload = this.emit.bind(this, 'load');
  this._img.onerror = this.emit.bind(this, 'error');
  this._img.src = src;

  // The default impl of events emitter will throw on any 'error' event unless
  // there is at least 1 handler. Logging anything in this case is unnecessary
  // since the browser console will log it too.
  this.on('error', NOOP);

  // Default is just 10.
  this.setMaxListeners(100);
}

assign(Img.prototype, EventEmitter.prototype, {

  /**
   * Pooling owner looks for this
   */
  destructor: function () {
    // Make sure we aren't leaking callbacks.
    this.removeAllListeners();
  },

  /**
   * Retrieve the original image URL before browser normalization
   *
   * @return {String}
   */
  getOriginalSrc: function () {
    return this._originalSrc;
  },

  /**
   * Retrieve a reference to the underyling <img> node.
   *
   * @return {HTMLImageElement}
   */
  getRawImage: function () {
    return this._img;
  },

  /**
   * Retrieve the loaded image width
   *
   * @return {Number}
   */
  getWidth: function () {
    return this._img.naturalWidth;
  },

  /**
   * Retrieve the loaded image height
   *
   * @return {Number}
   */
  getHeight: function () {
    return this._img.naturalHeight;
  },

  /**
   * @return {Bool}
   */
  isLoaded: function () {
    return this._img.naturalHeight > 0;
  }

});

var kInstancePoolLength = 300;

var _instancePool = {
  length: 0,
  // Keep all the nodes in memory.
  elements: {

  },

  // Push with 0 frequency
  push: function (hash, data) {
    this.length++;
    this.elements[hash] = {
      hash: hash, // Helps identifying
      freq: 0,
      data: data
    };
  },

  get: function (path) {
    var element = this.elements[path];

    if( element ){
      element.freq++;
      return element.data;
    }

    return null;
  },

  // used to explicitely remove the path
  removeElement: function (path) {
    // Now almighty GC can claim this soul
    var element = this.elements[path];
    delete this.elements[path];
    this.length--;
    return element;
  },

  _reduceLeastUsed: function (least, currentHash) {
    var current = _instancePool.elements[currentHash];

    if( least.freq > current.freq ){
      return current;
    }

    return least;
  },

  popLeastUsed: function () {
    var reducer = _instancePool._reduceLeastUsed;
    var minUsed = Object.keys(this.elements).reduce(reducer, { freq: Infinity });

    if( minUsed.hash ){
      return this.removeElement(minUsed.hash);
    }

    return null;
  }
};

var ImageCache = {

  /**
   * Retrieve an image from the cache
   *
   * @return {Img}
   */
  get: function (src) {
    var image = _instancePool.get(src);
    if (!image) {
      // Awesome LRU
      image = new Img(src);
      if (_instancePool.length >= kInstancePoolLength) {
        _instancePool.popLeastUsed().destructor();
      }
      _instancePool.push(image.getOriginalSrc(), image);
    }
    return image;
  }

};

module.exports = ImageCache;<commit_msg>Removed White Space<commit_after>'use strict';

var EventEmitter = require('events');
var assign = require('react/lib/Object.assign');

var NOOP = function () {};

function Img (src) {
  this._originalSrc = src;
  this._img = new Image();
  this._img.onload = this.emit.bind(this, 'load');
  this._img.onerror = this.emit.bind(this, 'error');
  this._img.src = src;

  // The default impl of events emitter will throw on any 'error' event unless
  // there is at least 1 handler. Logging anything in this case is unnecessary
  // since the browser console will log it too.
  this.on('error', NOOP);

  // Default is just 10.
  this.setMaxListeners(100);
}

assign(Img.prototype, EventEmitter.prototype, {

  /**
   * Pooling owner looks for this
   */
  destructor: function () {
    // Make sure we aren't leaking callbacks.
    this.removeAllListeners();
  },

  /**
   * Retrieve the original image URL before browser normalization
   *
   * @return {String}
   */
  getOriginalSrc: function () {
    return this._originalSrc;
  },

  /**
   * Retrieve a reference to the underyling <img> node.
   *
   * @return {HTMLImageElement}
   */
  getRawImage: function () {
    return this._img;
  },

  /**
   * Retrieve the loaded image width
   *
   * @return {Number}
   */
  getWidth: function () {
    return this._img.naturalWidth;
  },

  /**
   * Retrieve the loaded image height
   *
   * @return {Number}
   */
  getHeight: function () {
    return this._img.naturalHeight;
  },

  /**
   * @return {Bool}
   */
  isLoaded: function () {
    return this._img.naturalHeight > 0;
  }

});

var kInstancePoolLength = 300;

var _instancePool = {
  length: 0,
  // Keep all the nodes in memory.
  elements: {

  },

  // Push with 0 frequency
  push: function (hash, data) {
    this.length++;
    this.elements[hash] = {
      hash: hash, // Helps identifying
      freq: 0,
      data: data
    };
  },

  get: function (path) {
    var element = this.elements[path];

    if( element ){
      element.freq++;
      return element.data;
    }

    return null;
  },

  // used to explicitely remove the path
  removeElement: function (path) {
    // Now almighty GC can claim this soul
    var element = this.elements[path];
    delete this.elements[path];
    this.length--;
    return element;
  },

  _reduceLeastUsed: function (least, currentHash) {
    var current = _instancePool.elements[currentHash];

    if( least.freq > current.freq ){
      return current;
    }

    return least;
  },

  popLeastUsed: function () {
    var reducer = _instancePool._reduceLeastUsed;
    var minUsed = Object.keys(this.elements).reduce(reducer, { freq: Infinity });

    if( minUsed.hash ){
      return this.removeElement(minUsed.hash);
    }

    return null;
  }
};

var ImageCache = {

  /**
   * Retrieve an image from the cache
   *
   * @return {Img}
   */
  get: function (src) {
    var image = _instancePool.get(src);
    if (!image) {
      // Awesome LRU
      image = new Img(src);
      if (_instancePool.length >= kInstancePoolLength) {
        _instancePool.popLeastUsed().destructor();
      }
      _instancePool.push(image.getOriginalSrc(), image);
    }
    return image;
  }

};

module.exports = ImageCache;
<|endoftext|>


<commit_before>/*
 * moleculer
 * Copyright (c) 2019 MoleculerJS (https://github.com/moleculerjs/moleculer)
 * MIT Licensed
 */

"use strict";

const crypto = require("crypto");

/**
 * This is a AES encryption middleware to protect the whole
 * Moleculer transporter communication with AES.
 *
 * @param {String|Buffer} password
 * @param {String?} algorithm
 * @param {String|Buffer?} iv
 */
module.exports = function EncryptionMiddleware(password, algorithm = "aes-256-cbc", iv) {
	if (!password || password.length == 0) {
		/* istanbul ignore next */
		throw new Error("Must be set a password for encryption");
	}

	return {
		name: "Encryption",

		created() {
			/* istanbul ignore next */
			this.logger.info(`The transmission is ENCRYPTED by '${algorithm}'.`);
		},

		transporterSend(next) {
			return (topic, data, meta) => {
				const encrypter = iv ? crypto.createCipheriv(algorithm, password, iv) : crypto.createCipher(algorithm, password);
				const res = Buffer.concat([encrypter.update(data), encrypter.final()]);
				return next(topic, res, meta);
			};
		},

		transporterReceive(next) {
			return (cmd, data, s) => {
				try {
					const decrypter = iv ? crypto.createDecipheriv(algorithm, password, iv) : crypto.createDecipher(algorithm, password);
					const res = Buffer.concat([decrypter.update(data), decrypter.final()]);
					return next(cmd, res, s);
				} catch(e) {

				}
			};
		}
	};
};
<commit_msg>log the error if decryption fails<commit_after>/*
 * moleculer
 * Copyright (c) 2019 MoleculerJS (https://github.com/moleculerjs/moleculer)
 * MIT Licensed
 */

"use strict";

const crypto = require("crypto");

/**
 * This is a AES encryption middleware to protect the whole
 * Moleculer transporter communication with AES.
 *
 * @param {String|Buffer} password
 * @param {String?} algorithm
 * @param {String|Buffer?} iv
 */
module.exports = function EncryptionMiddleware(password, algorithm = "aes-256-cbc", iv) {
	if (!password || password.length == 0) {
		/* istanbul ignore next */
		throw new Error("Must be set a password for encryption");
	}

	return {
		name: "Encryption",

		created() {
			/* istanbul ignore next */
			this.logger.info(`The transmission is ENCRYPTED by '${algorithm}'.`);
		},

		transporterSend(next) {
			return (topic, data, meta) => {
				const encrypter = iv ? crypto.createCipheriv(algorithm, password, iv) : crypto.createCipher(algorithm, password);
				const res = Buffer.concat([encrypter.update(data), encrypter.final()]);
				return next(topic, res, meta);
			};
		},

		transporterReceive(next) {
			return (cmd, data, s) => {
				try {
					const decrypter = iv ? crypto.createDecipheriv(algorithm, password, iv) : crypto.createDecipher(algorithm, password);
					const res = Buffer.concat([decrypter.update(data), decrypter.final()]);
					return next(cmd, res, s);
				} catch(e) {
					this.logger.error(e);
				}
			};
		}
	};
};
<|endoftext|>


<commit_before>alienship.prototype = new SpaceObject();
function alienship(canvas){
	this.canvas = canvas;

	var turnDelay = 0; //ms
	this.angle = Math.PI / 2; //constant, straight up
	var lastTurn = (new Date()).getTime();
	var lastShot = (new Date()).getTime();
	var shotDelay = 0; //milliseconds

	this.getLastTurn = function(){
		return lastTurn;
	}

	function init(){
		this.canvas = canvas;
		alienship.prototype.init.call(this);
		this.x, this.y;
		this.x = randomInt(0, this.canvas.width);
		this.y = randomInt(0, this.canvas.height);
		this.paint;
		var level = game.getLevel();
		if (level < 7) {
			this.setVelocity(	randomFloat(-level - 1, level + 1),
						randomFloat(-level - 1, level + 1));
		} else {
			this.setVelocity(	randomFloat(-7, 7),
						randomFloat(-7, 7));
		}
		window.alien = this;
		//set initial shot delay
		this.shotDelay = randomInt(2000 - (10 * level), 5000 - (10 * level));
		this.turnDelay = randomInt(1000, 3500);
	}

	this.canCollideWith = function(item){
		var can =
			(//(item instanceof asteroid ||
			item instanceof missile ||
			item instanceof spaceship);
		return can;
	}

	this.getBoundingBox = function getBoundingBox(){
		var shipPoints = this.getShipPoints();
		var points = shipPoints;
		var maxX = points[0].x;
		var minX = points[0].x;
		var maxY = points[0].y;
		var minY = points[0].y;
		for (var i = 1; i < 6; i++) {
			maxX = Math.max(maxX, points[i].x);
			minX = Math.min(minX, points[i].x);
			maxY = Math.max(maxY, points[i].y);
			minY = Math.min(minY, points[i].y);
		}

		return [{x: minX, y: minY}, {x: maxX, y: minY}, {x: maxX, y: maxY}, {x: minX, y: maxY}];
	}

	this.getShipPoints = function(){
		var degAngle = toDegrees(this.angle);
		return [getArcCoordinates(this.x, this.y, normalizeAngle(0), 20),
				getArcCoordinates(this.x, this.y, normalizeAngle(60), 20),
				getArcCoordinates(this.x, this.y, normalizeAngle(120), 20),
				getArcCoordinates(this.x, this.y, normalizeAngle(180), 20),
				getArcCoordinates(this.x, this.y, normalizeAngle(240), 20),
				getArcCoordinates(this.x, this.y, normalizeAngle(300), 20)];
	}

	this.paint = function(){
		var ctx = this.canvas.getContext("2d");
		var shipPoints = this.getShipPoints();
		ctx.strokeStyle = 'rgb(255, 255, 255)';
		connectTheDots(ctx, shipPoints);
		ctx.beginPath();
		ctx.moveTo(shipPoints[0].x, shipPoints[0].y);
		ctx.lineTo(shipPoints[3].x, shipPoints[3].y);
		ctx.stroke();
	}

	this.shoot = function(){
		lastShot = (new Date()).getTime();
		var level = game.getLevel();
		this.shotDelay = randomInt(2000 - (10 * level), 5000 - (10 * level));
		var p = game.getPlayer().getCoordinates();
		var a = this.getCoordinates();
		//set fuzz to be +/- 6 degrees for this guy (seems to be about the right balance)
		//bumped fuzz up to +- 11, seemed too accurate to me
		var fuzz = toRadians(randomFloat(-11, 11));
		var vector = {x: p.x - a.x, y: p.y - a.y};
		var angle = Math.atan(vector.y/vector.x);
		var origin = vectorAdd(this.getCoordinates(), scaleVector(angle, 23));
		if (a.x <= p.x) {
			game.addItem(new alien_missile(this.canvas, origin.x, origin.y, angle + fuzz, this.velocity.x, this.velocity.y, 3));
		} else {
			game.addItem(new alien_missile(this.canvas, origin.x, origin.y, angle - Math.PI + fuzz, this.velocity.x, this.velocity.y, 3));
		}
	}

	this.changeDirection = function() {
		var max = game.getLevel() + 3;
		if (max > 7) {
			max = 7;
		}
		var xVel = this.getVelocity().x;
		var yVel = this.getVelocity().y;
		this.setVelocity(	xVel + randomFloat(-2, 2),
					yVel + randomFloat(-2, 2));
		if (this.getVelocity().x > max) {
			this.setVelocity( 7, this.getVelocity().y);
		}
		if (this.getVelocity().x < -max) {
			this.setVelocity( -max, this.getVelocity().y);
		}
		if (this.getVelocity().y > max) {
			this.setVelocity( this.getVelocity().x, max);
		}
		if (this.getVelocity().y < -max) {
			this.setVelocity( this.getVelocity().x, -max);
		}
		console.log(this.getVelocity());
		this.turnDelay = randomInt(1000, 3500);
		lastTurn = (new Date()).getTime();
	}

	this.update = function(){
		var now = (new Date()).getTime();
		if(now - lastShot > this.shotDelay){
			this.shoot();
		}
		if(now - lastTurn > this.turnDelay){
			this.changeDirection();
		}
		alienship.prototype.update.call(this);
	}

	this.init = init;

	this.init();
	return this;
}
<commit_msg>refined speed and changes of direction<commit_after>alienship.prototype = new SpaceObject();
function alienship(canvas){
	this.canvas = canvas;

	var turnDelay = 0; //ms
	this.angle = Math.PI / 2; //constant, straight up
	var lastTurn = (new Date()).getTime();
	var lastShot = (new Date()).getTime();
	var shotDelay = 0; //milliseconds
	var radius = 20;
	this.points = radius * 10;

	this.getLastTurn = function(){
		return lastTurn;
	}

	function init(){
		this.canvas = canvas;
		alienship.prototype.init.call(this);
		this.x, this.y;
		this.x = randomInt(0, this.canvas.width);
		this.y = randomInt(0, this.canvas.height);
		this.paint;
		var level = game.getLevel();
		if (level < 7) {
			this.setVelocity(	randomFloat(-level - 1, level + 1),
						randomFloat(-level - 1, level + 1));
		} else {
			this.setVelocity(	randomFloat(-7, 7),
						randomFloat(-7, 7));
		}
		window.alien = this;
		//set initial shot delay
		this.shotDelay = randomInt(2000 - (10 * level), 5000 - (10 * level));
		this.turnDelay = randomInt(1000, 3500);
	}

	this.canCollideWith = function(item){
		var can =
			(item instanceof asteroid ||
			item instanceof missile ||
			item instanceof spaceship);
		return can;
	}

	this.getBoundingBox = function getBoundingBox(){
		var shipPoints = this.getShipPoints();
		var points = shipPoints;
		var maxX = points[0].x;
		var minX = points[0].x;
		var maxY = points[0].y;
		var minY = points[0].y;
		for (var i = 1; i < 6; i++) {
			maxX = Math.max(maxX, points[i].x);
			minX = Math.min(minX, points[i].x);
			maxY = Math.max(maxY, points[i].y);
			minY = Math.min(minY, points[i].y);
		}

		return [{x: minX, y: minY}, {x: maxX, y: minY}, {x: maxX, y: maxY}, {x: minX, y: maxY}];
	}

	this.getShipPoints = function(){
		var degAngle = toDegrees(this.angle);
		return [getArcCoordinates(this.x, this.y, normalizeAngle(0), radius),
				getArcCoordinates(this.x, this.y, normalizeAngle(60), radius),
				getArcCoordinates(this.x, this.y, normalizeAngle(120), radius),
				getArcCoordinates(this.x, this.y, normalizeAngle(180), radius),
				getArcCoordinates(this.x, this.y, normalizeAngle(240), radius),
				getArcCoordinates(this.x, this.y, normalizeAngle(300), radius)];
	}

	this.paint = function(){
		var ctx = this.canvas.getContext("2d");
		var shipPoints = this.getShipPoints();
		ctx.strokeStyle = 'rgb(255, 255, 255)';
		connectTheDots(ctx, shipPoints);
		ctx.beginPath();
		ctx.moveTo(shipPoints[0].x, shipPoints[0].y);
		ctx.lineTo(shipPoints[3].x, shipPoints[3].y);
		ctx.stroke();
	}

	this.shoot = function(){
		lastShot = (new Date()).getTime();
		var level = game.getLevel();
		this.shotDelay = randomInt(2000 - (10 * level), 5000 - (10 * level));
		var p = game.getPlayer().getCoordinates();
		var a = this.getCoordinates();
		//set fuzz to be +/- 6 degrees for this guy (seems to be about the right balance)
		//bumped fuzz up to +- 11, seemed too accurate to me
		var fuzz = toRadians(randomFloat(-11, 11));
		var vector = {x: p.x - a.x, y: p.y - a.y};
		var angle = Math.atan(vector.y/vector.x);
		var origin = vectorAdd(this.getCoordinates(), scaleVector(angle, 23));
		if (a.x <= p.x) {
			game.addItem(new alien_missile(this.canvas, origin.x, origin.y, angle + fuzz, this.velocity.x, this.velocity.y, 3));
		} else {
			game.addItem(new alien_missile(this.canvas, origin.x, origin.y, angle - Math.PI + fuzz, this.velocity.x, this.velocity.y, 3));
		}
	}

	this.changeDirection = function() {
		var max = game.getLevel() + 3;
		if (max > 7) {
			max = 7;
		}
		var xVel = this.getVelocity().x;
		var yVel = this.getVelocity().y;
		this.setVelocity(	xVel + randomFloat(-2, 2),
					yVel + randomFloat(-2, 2));
		if (this.getVelocity().x > max) {
			this.setVelocity( 7, this.getVelocity().y);
		}
		if (this.getVelocity().x < -max) {
			this.setVelocity( -max, this.getVelocity().y);
		}
		if (this.getVelocity().y > max) {
			this.setVelocity( this.getVelocity().x, max);
		}
		if (this.getVelocity().y < -max) {
			this.setVelocity( this.getVelocity().x, -max);
		}
		//console.log(this.getVelocity());
		this.turnDelay = randomInt(1000, 3500);
		lastTurn = (new Date()).getTime();
	}

	this.update = function(){
		var now = (new Date()).getTime();
		if(now - lastShot > this.shotDelay){
			this.shoot();
		}
		if(now - lastTurn > this.turnDelay){
			this.changeDirection();
		}
		alienship.prototype.update.call(this);
	}

	this.init = init;

	this.init();
	return this;
}
<|endoftext|>


<commit_before>
describe ('git test', function(){
var git     = require('gift');
var  _      = require('lodash');
var  Q      = require('q');
var path    = require('path');
var assert  = require('assert');
var repos = [
  "https://github.com/Codefresh-Examples/lets-chat.git",
  "https://github.com/Codefresh-Examples/socket-io.git",
  "https://github.com/Codefresh-Examples/jsbeautify.git",
  "https://github.com/Codefresh-Examples/express-angular.git",
  "https://github.com/zwij/wap_zaverecna.git",
  "https://github.com/yaronr/dockerfile.git",
  "https://github.com/codefresh-io/spigo.git"
];
var docker = 5;
var js = 1;
function only(index)
{
  repos = repos.slice(index, index + 1);
}
it.skip('set docker repo' , function(){
    only(js);
    console.log(JSON.stringify(docker));
});

it('just git clone', function(done){
  this.timeout(20000);
  var index = 0;
  var promises =  _.map(repos, function(repo){

      console.log('cloing repo :' + JSON.stringify(repo));
      index++;
      var defer = Q.defer();
      var localDir = path.resolve(__dirname, "./test/repo", index.toString());
      console.log('local folder:' + localDir);
      git.clone(repo, localDir, function (err, _repo){
      console.log('repo created err:' + err);

      if (err) return defer.reject(err);
        defer.resolve(_repo);
      });

      return defer.promise;
    });

    Q.all(promises).then(function(result){
      console.log('cloned with result : ' + JSON.stringify(result));
      done();},
      function(err){
        done(err);});
});
it('run on spigo repo' , function(done){
  this.timeout(10000);

  index = 0;
  var promises = [];
  var Runner = require('../analyzer');
  assert(Runner);

  var localDir = path.resolve(__dirname, "./test/repo", index.toString());

  var r = new Runner(localDir);
  var p = r.start();
  r.on('packageJson', function(data){
    console.log('package json found :'  + data);
  });

});

it('using git clone [node]' , function(done){
     console.log('git clone use case');

     var repoUrl = "https://github.com/codefresh-io/codefresh-io.git";
     var git = require('gift');
     var localDir = path.resolve(__dirname, "./test/repo");
     this.timeout(2000000);

     console.log('clonning repo to ' + localDir);
     git.clone(repoUrl, localDir, function (err, _repo){
     console.log('repo created');

      if (err)
        done(err);

      var r = new Runner(localDir);
      r.on('docker:dockefiles', function(p){
         console.log('docker file was detected:' + p);
       });
       r.start();
       r.done(function(err, data){
         done(err);});
     });
 });

 it('using git clone php' , function(done){
      console.log('git clone use case');
      var Runner = require('../analyzer');
      assert(Runner);

      var repoUrl = "https://github.com/zwij/wap_zaverecna.git";
      var git = require('gift');
      var localDir = path.resolve(__dirname, "./test/repo");
      this.timeout(2000000);

      console.log('clonning repo to ' + localDir);
      git.clone(repoUrl, localDir, function (err, _repo){
      console.log('repo created');

       if (err)
         done(err);

       var r = new Runner(localDir);
       r.on('docker:dockefiles', function(p){
          console.log('docker file was detected:' + p);
        });
        r.start();
        r.done(function(err, data){
          done(err);});
      });
  });

it('run on multiple repos' , function(done){
  this.timeout(10000);

  index = 0;
  var promises = [];
  var Runner = require('../analyzer');
  assert(Runner);
  _.forEach(repos, function(r){
  index++;
  var defer = Q.defer();
  var localDir = path.resolve(__dirname, "./test/repo", index.toString());
  done();
  var r = new Runner(localDir);
  var p = r.start();
  r.on('packageJson', function(data){
    console.log('repo name is :' + r);
    console.log('package json found :'  + data);
  });
  promises.push(p);
});

  Q.all(promises).then(function(result){
    _.forEach(result, function(r){
        console.log('cloned with result : ' + JSON.stringify(r));
    });

    done();},
    function(err){
      done(err);});

});
});
<commit_msg>add test_folder env<commit_after>
describe ('git test', function(){
var git     = require('gift');
var  _      = require('lodash');
var  Q      = require('q');
var path    = require('path');
var assert  = require('assert');
var repos = [
  "https://github.com/Codefresh-Examples/lets-chat.git",
  "https://github.com/Codefresh-Examples/socket-io.git",
  "https://github.com/Codefresh-Examples/jsbeautify.git",
  "https://github.com/Codefresh-Examples/express-angular.git",
  "https://github.com/zwij/wap_zaverecna.git",
  "https://github.com/yaronr/dockerfile.git",
  "https://github.com/codefresh-io/spigo.git"
];
var docker = 5;
var js = 1;
var testFolder = process.env.TEST_FOLDER || './test/repo';

function only(index)
{
  repos = repos.slice(index, index + 1);
}
it.skip('set docker repo' , function(){
    only(js);
    console.log(JSON.stringify(docker));
});

it('just git clone', function(done){
  this.timeout(20000);
  var index = 0;
  var promises =  _.map(repos, function(repo){

      console.log('cloing repo :' + JSON.stringify(repo));
      index++;
      var defer = Q.defer();
      var localDir = path.resolve(__dirname, testFolder, index.toString());
      console.log('local folder:' + localDir);
      git.clone(repo, localDir, function (err, _repo){
      console.log('repo created err:' + err);

      if (err) return defer.reject(err);
        defer.resolve(_repo);
      });

      return defer.promise;
    });

    Q.all(promises).then(function(result){
      console.log('cloned with result : ' + JSON.stringify(result));
      done();},
      function(err){
        done(err);});
});
it('run on spigo repo' , function(done){
  this.timeout(10000);

  index = 0;
  var promises = [];
  var Runner = require('../analyzer');
  assert(Runner);

  var localDir = path.resolve(__dirname, testFolder, index.toString());

  var r = new Runner(localDir);
  var p = r.start();
  r.on('packageJson', function(data){
    console.log('package json found :'  + data);
  });

});

it('using git clone [node]' , function(done){
     console.log('git clone use case');

     var repoUrl = "https://github.com/codefresh-io/codefresh-io.git";
     var git = require('gift');
     var localDir = path.resolve(__dirname, testFolder);
     this.timeout(2000000);

     console.log('clonning repo to ' + localDir);
     git.clone(repoUrl, localDir, function (err, _repo){
     console.log('repo created');

      if (err)
        done(err);

      var r = new Runner(localDir);
      r.on('docker:dockefiles', function(p){
         console.log('docker file was detected:' + p);
       });
       r.start();
       r.done(function(err, data){
         done(err);});
     });
 });

 it('using git clone php' , function(done){
      console.log('git clone use case');
      var Runner = require('../analyzer');
      assert(Runner);

      var repoUrl = "https://github.com/zwij/wap_zaverecna.git";
      var git = require('gift');
      var localDir = path.resolve(__dirname, testFolder);
      this.timeout(2000000);

      console.log('clonning repo to ' + localDir);
      git.clone(repoUrl, localDir, function (err, _repo){
      console.log('repo created');

       if (err)
         done(err);

       var r = new Runner(localDir);
       r.on('docker:dockefiles', function(p){
          console.log('docker file was detected:' + p);
        });
        r.start();
        r.done(function(err, data){
          done(err);});
      });
  });

it('run on multiple repos' , function(done){
  this.timeout(10000);

  index = 0;
  var promises = [];
  var Runner = require('../analyzer');
  assert(Runner);
  _.forEach(repos, function(r){
  index++;
  var defer = Q.defer();
  var localDir = path.resolve(__dirname, testFolder, index.toString());
  done();
  var r = new Runner(localDir);
  var p = r.start();
  r.on('packageJson', function(data){
    console.log('repo name is :' + r);
    console.log('package json found :'  + data);
  });
  promises.push(p);
});

  Q.all(promises).then(function(result){
    _.forEach(result, function(r){
        console.log('cloned with result : ' + JSON.stringify(r));
    });

    done();},
    function(err){
      done(err);});

});
});
<|endoftext|>


<commit_before>/**
 * Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * An audience action flow will show a dialog prompt to a reader, asking them
 * to complete an action for potentially free, additional metered entitlements.
 *
 * An action flow can potentially assign a new user token so if we complete one,
 * we should:
 * 1) Store the new user token
 * 2) Clear any existing entitlements stored on the page
 * 3) Re-fetch entitlements which may potentially provide access to the page
 * 4) Close the prompt that initiated the flow.
 */

import {ActivityIframeView} from '../ui/activity-iframe-view';
import {
  AlreadySubscribedResponse,
  CompleteAudienceActionResponse,
  EntitlementsResponse,
  SurveyDataTransferRequest,
  SurveyDataTransferResponse,
} from '../proto/api_messages';
import {AutoPromptType} from '../api/basic-subscriptions';
import {Constants} from '../utils/constants';
import {ProductType} from '../api/subscriptions';
import {SWG_I18N_STRINGS} from '../i18n/swg-strings';
import {Toast} from '../ui/toast';
import {feArgs, feUrl} from './services';
import {msg} from '../utils/i18n';
import {parseUrl} from '../utils/url';

/**
 * @typedef {{
 *  action: (string|undefined),
 *  onCancel: (function()|undefined),
 *  autoPromptType: (AutoPromptType|undefined)
 * }}
 */
export let AudienceActionParams;

const actionToIframeMapping = {
  'TYPE_REGISTRATION_WALL': '/regwalliframe',
  'TYPE_NEWSLETTER_SIGNUP': '/newsletteriframe',
  'TYPE_REWARDED_SURVEY': '/surveyiframe',
};

const autopromptTypeToProductTypeMapping = {
  [AutoPromptType.SUBSCRIPTION]: ProductType.SUBSCRIPTION,
  [AutoPromptType.SUBSCRIPTION_LARGE]: ProductType.SUBSCRIPTION,
  [AutoPromptType.CONTRIBUTION]: ProductType.UI_CONTRIBUTION,
  [AutoPromptType.CONTRIBUTION_LARGE]: ProductType.UI_CONTRIBUTION,
};

const DEFAULT_PRODUCT_TYPE = ProductType.SUBSCRIPTION;

const placeholderPatternForEmail = /<ph name="EMAIL".+?\/ph>/g;

/**
 * The flow to initiate and manage handling an audience action.
 */
export class AudienceActionFlow {
  /**
   * @param {!./deps.DepsDef} deps
   * @param {!AudienceActionParams} params
   */
  constructor(deps, params) {
    /** @private @const {!./deps.DepsDef} */
    this.deps_ = deps;

    /** @private @const {!AudienceActionParams} */
    this.params_ = params;

    /** @private @const {!ProductType} */
    this.productType_ = params.autoPromptType
      ? autopromptTypeToProductTypeMapping[params.autoPromptType]
      : DEFAULT_PRODUCT_TYPE;

    /** @private @const {!../components/dialog-manager.DialogManager} */
    this.dialogManager_ = deps.dialogManager();

    /** @private @const {!./entitlements-manager.EntitlementsManager} */
    this.entitlementsManager_ = deps.entitlementsManager();

    /** @private @const {?./client-config-manager.ClientConfigManager} */
    this.clientConfigManager_ = deps.clientConfigManager();

    /** @private {?ActivityIframeView} */
    this.activityIframeView_ = new ActivityIframeView(
      deps.win(),
      deps.activities(),
      feUrl(actionToIframeMapping[this.params_.action], {
        'origin': parseUrl(deps.win().location.href).origin,
      }),
      feArgs({
        'supportsEventManager': true,
        'productType': this.productType_,
      }),
      /* shouldFadeBody */ true
    );
  }

  /**
   * Starts the flow for the suggested audience action.
   * @public
   * @return {!Promise}
   */
  start() {
    if (!this.activityIframeView_) {
      return Promise.resolve();
    }

    this.activityIframeView_.on(CompleteAudienceActionResponse, (response) =>
      this.handleCompleteAudienceActionResponse_(response)
    );

    this.activityIframeView_.on(SurveyDataTransferRequest, (request) =>
      this.handleSurveyDataTransferRequest_(request)
    );

    this.activityIframeView_.on(
      AlreadySubscribedResponse,
      this.handleLinkRequest_.bind(this)
    );

    const {onCancel} = this.params_;
    if (onCancel) {
      this.activityIframeView_.onCancel(onCancel);
    }

    return this.dialogManager_.openView(
      this.activityIframeView_,
      /* hidden */ false,
      /* dialogConfig */ {
        shouldDisableBodyScrolling: true,
      }
    );
  }

  /**
   * On a successful response from the dialog, we should:
   * 1) Store the updated user token
   * 2) Clear existing entitlements from the page
   * 3) Update READ_TIME in local storage to indicate that entitlements may have changed recently
   * 4) Re-fetch entitlements which may potentially provide access to the page
   * @param {CompleteAudienceActionResponse} response
   * @private
   */
  handleCompleteAudienceActionResponse_(response) {
    this.dialogManager_.completeView(this.activityIframeView_);
    this.entitlementsManager_.clear();
    const userToken = response.getSwgUserToken();
    if (userToken) {
      this.deps_.storage().set(Constants.USER_TOKEN, userToken, true);
    }
    if (response.getActionCompleted()) {
      this.showSignedInToast_(response.getUserEmail() ?? '');
    } else if (response.getAlreadyCompleted()) {
      this.showAlreadyOptedInToast_();
    } else {
      this.showFailedOptedInToast_();
    }
    const now = Date.now().toString();
    this.deps_
      .storage()
      .set(Constants.READ_TIME, now, /*useLocalStorage=*/ false);
    this.entitlementsManager_.getEntitlements();
  }

  /**
   * @param {string} userEmail
   * @private
   */
  showSignedInToast_(userEmail) {
    const lang = this.clientConfigManager_.getLanguage();
    let customText = '';
    if (this.params_.action === 'TYPE_REGISTRATION_WALL') {
      customText = msg(
        SWG_I18N_STRINGS.REGWALL_ACCOUNT_CREATED_LANG_MAP,
        lang
      ).replace(placeholderPatternForEmail, userEmail);
    } else if (this.params_.action === 'TYPE_NEWSLETTER_SIGNUP') {
      customText = msg(
        SWG_I18N_STRINGS.NEWSLETTER_SIGNED_UP_LANG_MAP,
        lang
      ).replace(placeholderPatternForEmail, userEmail);
    }
    new Toast(
      this.deps_,
      feUrl('/toastiframe', {
        flavor: 'custom',
        customText,
      })
    ).open();
  }

  /** @private */
  showAlreadyOptedInToast_() {
    if (this.params_.action === 'TYPE_REGISTRATION_WALL') {
      // Show 'Signed in as abc@gmail.com' toast on the pub page.
      new Toast(
        this.deps_,
        feUrl('/toastiframe', {
          flavor: 'basic',
        })
      ).open();
    } else if (this.params_.action === 'TYPE_NEWSLETTER_SIGNUP') {
      const lang = this.clientConfigManager_.getLanguage();
      const customText = msg(
        SWG_I18N_STRINGS.NEWSLETTER_ALREADY_SIGNED_UP_LANG_MAP,
        lang
      );
      new Toast(
        this.deps_,
        feUrl('/toastiframe', {
          flavor: 'custom',
          customText,
        })
      ).open();
    }
  }

  /** @private */
  showFailedOptedInToast_() {
    const lang = this.clientConfigManager_.getLanguage();
    const customText = msg(
      this.params_.action === 'TYPE_REGISTRATION_WALL'
        ? SWG_I18N_STRINGS.REGWALL_REGISTER_FAILED_LANG_MAP
        : SWG_I18N_STRINGS.NEWSLETTER_SIGN_UP_FAILED_LANG_MAP,
      lang
    );
    new Toast(
      this.deps_,
      feUrl('/toastiframe', {
        flavor: 'custom',
        customText,
      })
    ).open();
  }

  /**
   * @param {AlreadySubscribedResponse} response
   * @private
   */
  handleLinkRequest_(response) {
    if (response.getSubscriberOrMember()) {
      this.deps_.callbacks().triggerLoginRequest({linkRequested: false});
    }
  }

  /**
   * @param {SurveyDataTransferRequest} request
   * @private
   */
  // eslint-disable-next-line no-unused-vars
  handleSurveyDataTransferRequest_(request) {
    // @TODO(justinchou): execute callback with setOnInterventionComplete
    // then check for success
    const gaLoggingSuccess = this.logSurveyDataToGoogleAnalytics(request);
    const surveyDataTransferResponse = new SurveyDataTransferResponse();
    surveyDataTransferResponse.setSuccess(gaLoggingSuccess);
    this.activityIframeView_.execute(surveyDataTransferResponse);
  }

  /**
   * Logs SurveyDataTransferRequest to Google Analytics. Returns boolean
   * for whether or not logging was successful.
   * @param {SurveyDataTransferRequest} request
   * @return {boolean}
   * @private
   */
  logSurveyDataToGoogleAnalytics(request) {
    const gtag = this.deps_.win().gtag;
    if (typeof gtag !== 'function') {
      return false;
    }
    request.getSurveyQuestionsList().map((question) => {
      const answer = question.getSurveyAnswersList()[0];
      gtag('event', 'survey submission', {
        'event_category': 'survey',
        'survey_question_category': question.getQuestionCategory(),
        'survey_question': question.getQuestionText(),
        'survey_answer_category': answer.getAnswerCategory() || null,
        'survey_answer': answer.getAnswerText() || null,
      });
    });
    return true;
  }

  /**
   * Shows the toast of 'no entitlement found' on activity iFrame view.
   * @public
   */
  showNoEntitlementFoundToast() {
    if (this.activityIframeView_) {
      this.activityIframeView_.execute(new EntitlementsResponse());
    }
  }
}
<commit_msg>add null check<commit_after>/**
 * Copyright 2018 The Subscribe with Google Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS-IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * An audience action flow will show a dialog prompt to a reader, asking them
 * to complete an action for potentially free, additional metered entitlements.
 *
 * An action flow can potentially assign a new user token so if we complete one,
 * we should:
 * 1) Store the new user token
 * 2) Clear any existing entitlements stored on the page
 * 3) Re-fetch entitlements which may potentially provide access to the page
 * 4) Close the prompt that initiated the flow.
 */

import {ActivityIframeView} from '../ui/activity-iframe-view';
import {
  AlreadySubscribedResponse,
  CompleteAudienceActionResponse,
  EntitlementsResponse,
  SurveyDataTransferRequest,
  SurveyDataTransferResponse,
} from '../proto/api_messages';
import {AutoPromptType} from '../api/basic-subscriptions';
import {Constants} from '../utils/constants';
import {ProductType} from '../api/subscriptions';
import {SWG_I18N_STRINGS} from '../i18n/swg-strings';
import {Toast} from '../ui/toast';
import {feArgs, feUrl} from './services';
import {msg} from '../utils/i18n';
import {parseUrl} from '../utils/url';

/**
 * @typedef {{
 *  action: (string|undefined),
 *  onCancel: (function()|undefined),
 *  autoPromptType: (AutoPromptType|undefined)
 * }}
 */
export let AudienceActionParams;

const actionToIframeMapping = {
  'TYPE_REGISTRATION_WALL': '/regwalliframe',
  'TYPE_NEWSLETTER_SIGNUP': '/newsletteriframe',
  'TYPE_REWARDED_SURVEY': '/surveyiframe',
};

const autopromptTypeToProductTypeMapping = {
  [AutoPromptType.SUBSCRIPTION]: ProductType.SUBSCRIPTION,
  [AutoPromptType.SUBSCRIPTION_LARGE]: ProductType.SUBSCRIPTION,
  [AutoPromptType.CONTRIBUTION]: ProductType.UI_CONTRIBUTION,
  [AutoPromptType.CONTRIBUTION_LARGE]: ProductType.UI_CONTRIBUTION,
};

const DEFAULT_PRODUCT_TYPE = ProductType.SUBSCRIPTION;

const placeholderPatternForEmail = /<ph name="EMAIL".+?\/ph>/g;

/**
 * The flow to initiate and manage handling an audience action.
 */
export class AudienceActionFlow {
  /**
   * @param {!./deps.DepsDef} deps
   * @param {!AudienceActionParams} params
   */
  constructor(deps, params) {
    /** @private @const {!./deps.DepsDef} */
    this.deps_ = deps;

    /** @private @const {!AudienceActionParams} */
    this.params_ = params;

    /** @private @const {!ProductType} */
    this.productType_ = params.autoPromptType
      ? autopromptTypeToProductTypeMapping[params.autoPromptType]
      : DEFAULT_PRODUCT_TYPE;

    /** @private @const {!../components/dialog-manager.DialogManager} */
    this.dialogManager_ = deps.dialogManager();

    /** @private @const {!./entitlements-manager.EntitlementsManager} */
    this.entitlementsManager_ = deps.entitlementsManager();

    /** @private @const {?./client-config-manager.ClientConfigManager} */
    this.clientConfigManager_ = deps.clientConfigManager();

    /** @private {?ActivityIframeView} */
    this.activityIframeView_ = new ActivityIframeView(
      deps.win(),
      deps.activities(),
      feUrl(actionToIframeMapping[this.params_.action], {
        'origin': parseUrl(deps.win().location.href).origin,
      }),
      feArgs({
        'supportsEventManager': true,
        'productType': this.productType_,
      }),
      /* shouldFadeBody */ true
    );
  }

  /**
   * Starts the flow for the suggested audience action.
   * @public
   * @return {!Promise}
   */
  start() {
    if (!this.activityIframeView_) {
      return Promise.resolve();
    }

    this.activityIframeView_.on(CompleteAudienceActionResponse, (response) =>
      this.handleCompleteAudienceActionResponse_(response)
    );

    this.activityIframeView_.on(SurveyDataTransferRequest, (request) =>
      this.handleSurveyDataTransferRequest_(request)
    );

    this.activityIframeView_.on(
      AlreadySubscribedResponse,
      this.handleLinkRequest_.bind(this)
    );

    const {onCancel} = this.params_;
    if (onCancel) {
      this.activityIframeView_.onCancel(onCancel);
    }

    return this.dialogManager_.openView(
      this.activityIframeView_,
      /* hidden */ false,
      /* dialogConfig */ {
        shouldDisableBodyScrolling: true,
      }
    );
  }

  /**
   * On a successful response from the dialog, we should:
   * 1) Store the updated user token
   * 2) Clear existing entitlements from the page
   * 3) Update READ_TIME in local storage to indicate that entitlements may have changed recently
   * 4) Re-fetch entitlements which may potentially provide access to the page
   * @param {CompleteAudienceActionResponse} response
   * @private
   */
  handleCompleteAudienceActionResponse_(response) {
    this.dialogManager_.completeView(this.activityIframeView_);
    this.entitlementsManager_.clear();
    const userToken = response.getSwgUserToken();
    if (userToken) {
      this.deps_.storage().set(Constants.USER_TOKEN, userToken, true);
    }
    if (response.getActionCompleted()) {
      this.showSignedInToast_(response.getUserEmail() ?? '');
    } else if (response.getAlreadyCompleted()) {
      this.showAlreadyOptedInToast_();
    } else {
      this.showFailedOptedInToast_();
    }
    const now = Date.now().toString();
    this.deps_
      .storage()
      .set(Constants.READ_TIME, now, /*useLocalStorage=*/ false);
    this.entitlementsManager_.getEntitlements();
  }

  /**
   * @param {string} userEmail
   * @private
   */
  showSignedInToast_(userEmail) {
    const lang = this.clientConfigManager_.getLanguage();
    let customText = '';
    if (this.params_.action === 'TYPE_REGISTRATION_WALL') {
      customText = msg(
        SWG_I18N_STRINGS.REGWALL_ACCOUNT_CREATED_LANG_MAP,
        lang
      ).replace(placeholderPatternForEmail, userEmail);
    } else if (this.params_.action === 'TYPE_NEWSLETTER_SIGNUP') {
      customText = msg(
        SWG_I18N_STRINGS.NEWSLETTER_SIGNED_UP_LANG_MAP,
        lang
      ).replace(placeholderPatternForEmail, userEmail);
    }
    new Toast(
      this.deps_,
      feUrl('/toastiframe', {
        flavor: 'custom',
        customText,
      })
    ).open();
  }

  /** @private */
  showAlreadyOptedInToast_() {
    if (this.params_.action === 'TYPE_REGISTRATION_WALL') {
      // Show 'Signed in as abc@gmail.com' toast on the pub page.
      new Toast(
        this.deps_,
        feUrl('/toastiframe', {
          flavor: 'basic',
        })
      ).open();
    } else if (this.params_.action === 'TYPE_NEWSLETTER_SIGNUP') {
      const lang = this.clientConfigManager_.getLanguage();
      const customText = msg(
        SWG_I18N_STRINGS.NEWSLETTER_ALREADY_SIGNED_UP_LANG_MAP,
        lang
      );
      new Toast(
        this.deps_,
        feUrl('/toastiframe', {
          flavor: 'custom',
          customText,
        })
      ).open();
    }
  }

  /** @private */
  showFailedOptedInToast_() {
    const lang = this.clientConfigManager_.getLanguage();
    const customText = msg(
      this.params_.action === 'TYPE_REGISTRATION_WALL'
        ? SWG_I18N_STRINGS.REGWALL_REGISTER_FAILED_LANG_MAP
        : SWG_I18N_STRINGS.NEWSLETTER_SIGN_UP_FAILED_LANG_MAP,
      lang
    );
    new Toast(
      this.deps_,
      feUrl('/toastiframe', {
        flavor: 'custom',
        customText,
      })
    ).open();
  }

  /**
   * @param {AlreadySubscribedResponse} response
   * @private
   */
  handleLinkRequest_(response) {
    if (response.getSubscriberOrMember()) {
      this.deps_.callbacks().triggerLoginRequest({linkRequested: false});
    }
  }

  /**
   * @param {SurveyDataTransferRequest} request
   * @private
   */
  // eslint-disable-next-line no-unused-vars
  handleSurveyDataTransferRequest_(request) {
    // @TODO(justinchou): execute callback with setOnInterventionComplete
    // then check for success
    const gaLoggingSuccess = this.logSurveyDataToGoogleAnalytics(request);
    const surveyDataTransferResponse = new SurveyDataTransferResponse();
    surveyDataTransferResponse.setSuccess(gaLoggingSuccess);
    this.activityIframeView_.execute(surveyDataTransferResponse);
  }

  /**
   * Logs SurveyDataTransferRequest to Google Analytics. Returns boolean
   * for whether or not logging was successful.
   * @param {SurveyDataTransferRequest} request
   * @return {boolean}
   * @private
   */
  logSurveyDataToGoogleAnalytics(request) {
    const gtag = this.deps_.win().gtag || null;
    if (gtag && typeof gtag !== 'function') {
      return false;
    }
    request.getSurveyQuestionsList().map((question) => {
      const answer = question.getSurveyAnswersList()[0];
      gtag('event', 'survey submission', {
        'event_category': 'survey',
        'survey_question_category': question.getQuestionCategory(),
        'survey_question': question.getQuestionText(),
        'survey_answer_category': answer.getAnswerCategory() || null,
        'survey_answer': answer.getAnswerText() || null,
      });
    });
    return true;
  }

  /**
   * Shows the toast of 'no entitlement found' on activity iFrame view.
   * @public
   */
  showNoEntitlementFoundToast() {
    if (this.activityIframeView_) {
      this.activityIframeView_.execute(new EntitlementsResponse());
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

var EventEmitter = require('events');
var assign = require('react/lib/Object.assign');

var NOOP = function () {};

function Img (src) {
  this._originalSrc = src;
  this._img = new Image();
  this._img.onload = this.emit.bind(this, 'load');
  this._img.onerror = this.emit.bind(this, 'error');
  this._img.src = src;

  // The default impl of events emitter will throw on any 'error' event unless
  // there is at least 1 handler. Logging anything in this case is unnecessary
  // since the browser console will log it too.
  this.on('error', NOOP);

  // Default is just 10.
  this.setMaxListeners(100);
}

assign(Img.prototype, EventEmitter.prototype, {

  /**
   * Pooling owner looks for this
   */
  destructor: function () {
    // Make sure we aren't leaking callbacks.
    this.removeAllListeners();
  },

  /**
   * Retrieve the original image URL before browser normalization
   *
   * @return {String}
   */
  getOriginalSrc: function () {
    return this._originalSrc;
  },

  /**
   * Retrieve a reference to the underyling <img> node.
   *
   * @return {HTMLImageElement}
   */
  getRawImage: function () {
    return this._img;
  },

  /**
   * Retrieve the loaded image width
   *
   * @return {Number}
   */
  getWidth: function () {
    return this._img.naturalWidth;
  },

  /**
   * Retrieve the loaded image height
   *
   * @return {Number}
   */
  getHeight: function () {
    return this._img.naturalHeight;
  },

  /**
   * @return {Bool}
   */
  isLoaded: function () {
    return this._img.naturalHeight > 0;
  }

});

var kInstancePoolLength = 300;
var _instancePool = {
  length: 0,
  // Keep all the nodes in memory.
  elements: {

  },

  // Push with 0 frequency
  push: function (hash, data) {
    this.length++;
    this.elements[hash] = {
      hash: hash, // Helps identifying
      freq: 0,
      data: data
    };
  },

  get: function (path) {
    var element = this.elements[path];

    if( element ){
      element.freq++;
      return element.data;
    }

    return null;
  },

  // used to explicitely remove the path
  removeElement: function (path) {
    // Now almighty GC can claim this soul
    var element = this.elements[path];
    delete this.elements[path];
    this.length--;
    return element;
  },

  _reduceLeastUsed: function (least, currentHash) {
      var current = this.elements[currentHash];

      if( least.freq > current.freq ){
        return current;
      }

      return least;
  },

  popLeastUsed: function () {
    // there is a much faster way using self
    var reducer = this._reduceLeastUsed.bind(this);
    var minUsed = Object.keys(this.elements).reduce(reducer, { freq: Infinity });

    if( minUsed.hash ){
      return this.removeElement(minUsed.hash);
    }

    return null;
  }
};

var ImageCache = {

  /**
   * Retrieve an image from the cache
   *
   * @return {Img}
   */
  get: function (src) {
    var image = _instancePool.get(src);
    if (!image) {
      // Simple FIFO queue
      image = new Img(src);
      if (_instancePool.length >= kInstancePoolLength) {
        _instancePool.popLeastUsed().destructor();
      }
      _instancePool.push(image.getOriginalSrc(), image);
    }
    return image;
  }

};

module.exports = ImageCache;
<commit_msg>Changes made as asked<commit_after>'use strict';

var EventEmitter = require('events');
var assign = require('react/lib/Object.assign');

var NOOP = function () {};

function Img (src) {
  this._originalSrc = src;
  this._img = new Image();
  this._img.onload = this.emit.bind(this, 'load');
  this._img.onerror = this.emit.bind(this, 'error');
  this._img.src = src;

  // The default impl of events emitter will throw on any 'error' event unless
  // there is at least 1 handler. Logging anything in this case is unnecessary
  // since the browser console will log it too.
  this.on('error', NOOP);

  // Default is just 10.
  this.setMaxListeners(100);
}

assign(Img.prototype, EventEmitter.prototype, {

  /**
   * Pooling owner looks for this
   */
  destructor: function () {
    // Make sure we aren't leaking callbacks.
    this.removeAllListeners();
  },

  /**
   * Retrieve the original image URL before browser normalization
   *
   * @return {String}
   */
  getOriginalSrc: function () {
    return this._originalSrc;
  },

  /**
   * Retrieve a reference to the underyling <img> node.
   *
   * @return {HTMLImageElement}
   */
  getRawImage: function () {
    return this._img;
  },

  /**
   * Retrieve the loaded image width
   *
   * @return {Number}
   */
  getWidth: function () {
    return this._img.naturalWidth;
  },

  /**
   * Retrieve the loaded image height
   *
   * @return {Number}
   */
  getHeight: function () {
    return this._img.naturalHeight;
  },

  /**
   * @return {Bool}
   */
  isLoaded: function () {
    return this._img.naturalHeight > 0;
  }

});

var kInstancePoolLength = 300;

var _instancePool = {
  length: 0,
  // Keep all the nodes in memory.
  elements: {

  },

  // Push with 0 frequency
  push: function (hash, data) {
    this.length++;
    this.elements[hash] = {
      hash: hash, // Helps identifying
      freq: 0,
      data: data
    };
  },

  get: function (path) {
    var element = this.elements[path];

    if( element ){
      element.freq++;
      return element.data;
    }

    return null;
  },

  // used to explicitely remove the path
  removeElement: function (path) {
    // Now almighty GC can claim this soul
    var element = this.elements[path];
    delete this.elements[path];
    this.length--;
    return element;
  },

  _reduceLeastUsed: function (least, currentHash) {
    var current = _instancePool.elements[currentHash];

    if( least.freq > current.freq ){
      return current;
    }

    return least;
  },

  popLeastUsed: function () {
    var reducer = _instancePool._reduceLeastUsed;
    var minUsed = Object.keys(this.elements).reduce(reducer, { freq: Infinity });

    if( minUsed.hash ){
      return this.removeElement(minUsed.hash);
    }

    return null;
  }
};

var ImageCache = {

  /**
   * Retrieve an image from the cache
   *
   * @return {Img}
   */
  get: function (src) {
    var image = _instancePool.get(src);
    if (!image) {
      // Awesome LRU
      image = new Img(src);
      if (_instancePool.length >= kInstancePoolLength) {
        _instancePool.popLeastUsed().destructor();
      }
      _instancePool.push(image.getOriginalSrc(), image);
    }
    return image;
  }

};

module.exports = ImageCache;<|endoftext|>


<commit_before>var generators = require('yeoman-generator');
var git = require('nodegit');
var fse = require('fs-extra');
var mysql = require('mysql');
var exec = require('child_process').exec;

// Vars
var repo = null;
var cwd = process.cwd();

module.exports = generators.Base.extend({

  // ## Clone odddrupal

  // Clone https://github.com/oddhill/odddrupal.git.
  // And rename origin to odddrupal.
  clone: function () {
    var done = this.async();
    // Check if cwd is empty or not.
    var files = fse.readdirSync(cwd);
    if (files.length > 0) {
      // quit
      console.error('Current dir not empty! Emergency, quits.');
      return;
    }

    console.log('Cloning odddrupal to ' + cwd + '...');

    // Clone odddrupal to cwd
    var options = {
      remoteCallbacks: {
        certificateCheck: function() {
          return 1;
        }
      }
    };

    git.Clone.clone('https://github.com/oddhill/odddrupal.git', cwd, options).then(function(repository) {
      // Make sure we can use it later.
      repo = repository;

      // @TODO
      // The removal sohuld probably be done through nodegit, instead.

      // Remove origin remote ref
      var command = 'cd ' + cwd + ' && git remote rm origin';
      exec(command, function(err, stdout, stderr) {
        if (!err) {
          console.log('Done');
        }
        else {
          console.error('Unable to remove origin remote reference.');
        }

        // Continue
        done();
      });
    });
  },

  // Rename current branch to master
  createMaster: function () {
    var done = this.async();
    console.log('Renaming the 7.x branch to master...');
    // Rename current local branch to master
    git.Branch.lookup(repo, '7.x', git.Branch.BRANCH.LOCAL).then(function(branchRef) {
      var signature = git.Signature.default(repo);
      git.Branch.move(branchRef, 'master', 0, signature, 'Renamed 7.x to master').then(function(reference) {
        console.log('Done');
        done();
      });
    });
  },

  // ## Install odddrupal

  // Copy .htaccess.default to .htaccess.
  htaccess: function () {
    var done = this.async();
    fse.copy(cwd + '/.htaccess.default', cwd + '/.htaccess', function(err) {
      if (!err) {
        console.log('Copied .htaccess.default to .htaccess');
        done();
      }
    });
  },

  // Create a new mysql db.
  createDb: function () {
    // Connect to mysql
    var connection = mysql.createConnection({
      host: '127.0.0.1',
      user: 'root',
      password: ''
    });

    connection.connect();

    var db_name = cwd.split('/');
    db_name = db_name[db_name.length-1];

    connection.query('CREATE DATABASE ' + db_name, function (err) {
      if (!err) {
        console.log('Added a new database named ' + db_name + '.');
      }
      else if (err.code == 'ER_DB_CREATE_EXISTS') {
        console.error('Db already exists');
      }
    });

    connection.end();
  },

  // Copy sites/default/settings.local.php.default to settings.local.php.
  dbSettings: function () {
    var done = this.async();
    fse.copy(cwd + '/sites/default/settings.local.php.default', cwd + '/sites/default/settings.local.php', function(err) {
      if (!err) {
        console.log('Copied settings.local.php.default to settings.local.php');

        done();

        // @TODO:
        // Add db settings to file.
      }
    });
  },

  // Make sure the files folder (sites/all/files) is 777.
  filesChmod: function () {
    var done = this.async();
    fse.ensureDirSync(cwd + '/sites/all/files', function(err) {
      if (!err) {
        fse.chmodSync(cwd + '/sites/all/files', 777);
        console.log('Created files dir');

        // Continue
        done();
      }
    });
  }

});
<commit_msg>Use async<commit_after>var generators = require('yeoman-generator');
var git = require('nodegit');
var fse = require('fs-extra');
var mysql = require('mysql');
var exec = require('child_process').exec;

// Vars
var repo = null;
var cwd = process.cwd();

module.exports = generators.Base.extend({

  // ## Clone odddrupal

  // Clone https://github.com/oddhill/odddrupal.git.
  // And rename origin to odddrupal.
  clone: function () {
    var done = this.async();
    // Check if cwd is empty or not.
    var files = fse.readdirSync(cwd);
    if (files.length > 0) {
      // quit
      console.error('Current dir not empty! Emergency, quits.');
      return;
    }

    console.log('Cloning odddrupal to ' + cwd + '...');

    // Clone odddrupal to cwd
    var options = {
      remoteCallbacks: {
        certificateCheck: function() {
          return 1;
        }
      }
    };

    git.Clone.clone('https://github.com/oddhill/odddrupal.git', cwd, options).then(function(repository) {
      // Make sure we can use it later.
      repo = repository;

      // @TODO
      // The removal sohuld probably be done through nodegit, instead.

      // Remove origin remote ref
      var command = 'cd ' + cwd + ' && git remote rm origin';
      exec(command, function(err, stdout, stderr) {
        if (!err) {
          console.log('Done');
        }
        else {
          console.error('Unable to remove origin remote reference.');
        }

        // Continue
        done();
      });
    });
  },

  // Rename current branch to master
  createMaster: function () {
    var done = this.async();
    console.log('Renaming the 7.x branch to master...');
    // Rename current local branch to master
    git.Branch.lookup(repo, '7.x', git.Branch.BRANCH.LOCAL).then(function(branchRef) {
      var signature = git.Signature.default(repo);
      git.Branch.move(branchRef, 'master', 0, signature, 'Renamed 7.x to master').then(function(reference) {
        console.log('Done');
        done();
      });
    });
  },

  // ## Install odddrupal

  // Copy .htaccess.default to .htaccess.
  htaccess: function () {
    var done = this.async();
    fse.copy(cwd + '/.htaccess.default', cwd + '/.htaccess', function(err) {
      if (!err) {
        console.log('Copied .htaccess.default to .htaccess');
        done();
      }
    });
  },

  // Create a new mysql db.
  createDb: function () {
    // Connect to mysql
    var connection = mysql.createConnection({
      host: '127.0.0.1',
      user: 'root',
      password: ''
    });

    connection.connect();

    var db_name = cwd.split('/');
    db_name = db_name[db_name.length-1];

    connection.query('CREATE DATABASE ' + db_name, function (err) {
      if (!err) {
        console.log('Added a new database named ' + db_name + '.');
      }
      else if (err.code == 'ER_DB_CREATE_EXISTS') {
        console.error('Db already exists');
      }
    });

    connection.end();
  },

  // Copy sites/default/settings.local.php.default to settings.local.php.
  dbSettings: function () {
    var done = this.async();
    fse.copy(cwd + '/sites/default/settings.local.php.default', cwd + '/sites/default/settings.local.php', function(err) {
      if (!err) {
        console.log('Copied settings.local.php.default to settings.local.php');

        done();

        // @TODO:
        // Add db settings to file.
      }
    });
  },

  // Make sure the files folder (sites/all/files) is 777.
  filesChmod: function () {
    var done = this.async();
    fse.ensureDir(cwd + '/sites/all/files', function(err) {
      if (!err) {
        fse.chmodSync(cwd + '/sites/all/files', 777);
        console.log('Created files dir');

        // Continue
        done();
      }
    });
  }

});
<|endoftext|>


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

// Provides element sap.m.FlexItemData
sap.ui.define(['jquery.sap.global', './FlexBoxStylingHelper', './library', 'sap/ui/core/LayoutData'],
	function(jQuery, FlexBoxStylingHelper, library, LayoutData) {
	"use strict";

	/**
	 * Constructor for a new sap.m.FlexItemData.
	 *
	 * @param {string} [sId] id for the new element, generated automatically if no id is given
	 * @param {object} [mSettings] initial settings for the new element
	 *
	 * @class
	 * Holds layout data for a FlexBox / HBox / VBox.
	 * @extends sap.ui.core.LayoutData
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @alias sap.m.FlexItemData
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var FlexItemData = LayoutData.extend("sap.m.FlexItemData", /** @lends sap.m.FlexItemData.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * Determines cross-axis alignment of individual element (not currently supported in Internet Explorer)
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#align-items-property
			 */
			alignSelf : {type : "sap.m.FlexAlignSelf", group : "Misc", defaultValue : sap.m.FlexAlignSelf.Auto},

			/**
			 * Determines the display order of flex items independent of their source code order.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#order-property
			 */
			order : {type : "int", group : "Misc", defaultValue : 0},

			/**
			 * Determines the flexibility of the flex item when allocatable space is remaining.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#flex-grow-property
			 */
			growFactor : {type : "float", group : "Misc", defaultValue : 0},

			/**
			 * The shrink factor determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#flex-shrink-property
			 *
			 * Note: This property is not supported in Internet Explorer 9, Android Native Browser/Webview <4.4, and Safari <7.
			 * @since 1.24.0
			 */
			shrinkFactor : {type : "float", group : "Misc", defaultValue : 1},

			/**
			 * The base size is the initial main size of the item for the flex algorithm. If set to "auto", this will be the computed size of the item.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#flex-basis-property
			 *
			 * @since 1.32.0
			 */
			baseSize : {type : "sap.ui.core.CSSSize", group : "Misc", defaultValue : "auto"},

			/**
			 * The minimum height of the flex item.
			 * @since 1.36.0
			 */
			minHeight : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : 'auto'},

			/**
			 * The maximum height of the flex item.
			 * @since 1.36.0
			 */
			maxHeight : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : ''},

			/**
			 * The minimum height of the flex item.
			 * @since 1.36.0
			 */
			minWidth : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : 'auto'},

			/**
			 * The maximum height of the flex item.
			 * @since 1.36.0
			 */
			maxWidth : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : ''},

			/**
			 * The style class will be applied to the flex item and can be used for CSS selectors
			 */
			styleClass : {type : "string", group : "Misc", defaultValue : ''},

			/**
			 * Defines the background style of the flex item.
			 *
			 * @since 1.38.5
			 */
			backgroundDesign: {type: "sap.m.BackgroundDesign", group: "Appearance", defaultValue: sap.m.BackgroundDesign.Transparent}
		}
	}});

	FlexItemData.prototype.setAlignSelf = function(sValue) {
		var sOldValue = this.getAlignSelf();
		this.setProperty("alignSelf", sValue, true);
		this.$().removeClass("sapMFlexItemAlign" + sOldValue).addClass("sapMFlexItemAlign" + this.getAlignSelf());

		return this;
	};

	FlexItemData.prototype.setOrder = function(sValue) {
		this.setProperty("order", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "order", this.getOrder());

		return this;
	};

	FlexItemData.prototype.setGrowFactor = function(sValue) {
		this.setProperty("growFactor", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "flex-grow", this.getGrowFactor());

		return this;
	};

	FlexItemData.prototype.setShrinkFactor = function(sValue) {
		this.setProperty("shrinkFactor", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "flex-shrink", this.getShrinkFactor());

		return this;
	};

	FlexItemData.prototype.setBaseSize = function(sValue) {
		this.setProperty("baseSize", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "flex-basis", this.getBaseSize());

		return this;
	};

	FlexItemData.prototype.setMinHeight = function(sValue) {
		this.setProperty("minHeight", sValue, true);
		this.$().css("min-height", this.getMinHeight());

		return this;
	};

	FlexItemData.prototype.setMaxHeight = function(sValue) {
		this.setProperty("maxHeight", sValue, true);
		this.$().css("max-height", this.getMaxHeight());

		return this;
	};

	FlexItemData.prototype.setMinWidth = function(sValue) {
		this.setProperty("minWidth", sValue, true);
		this.$().css("min-width", this.getMinWidth());

		return this;
	};

	FlexItemData.prototype.setMaxWidth = function(sValue) {
		this.setProperty("maxWidth", sValue, true);
		this.$().css("max-width", this.getMaxWidth());

		return this;
	};

	FlexItemData.prototype.setBackgroundDesign = function(sValue) {
		var sOldValue = this.getBackgroundDesign();
		this.setProperty("backgroundDesign", sValue, true);
		this.$().removeClass("sapMFlexBoxBG" + sOldValue).addClass("sapMFlexBoxBG" + this.getBackgroundDesign());

		return this;
	};

	FlexItemData.prototype.setStyleClass = function(sValue) {
		var sOldValue = this.getStyleClass();
		this.setProperty("styleClass", sValue, true);
		this.$().removeClass(sOldValue).addClass(this.getStyleClass());

		return this;
	};

	return FlexItemData;

}, /* bExport= */ true);
<commit_msg>[INTERNAL] sap.m.FlexItemData: JSDoc has been added<commit_after>/*!
 * ${copyright}
 */

// Provides element sap.m.FlexItemData
sap.ui.define(['jquery.sap.global', './FlexBoxStylingHelper', './library', 'sap/ui/core/LayoutData'],
	function(jQuery, FlexBoxStylingHelper, library, LayoutData) {
	"use strict";

	/**
	 * Constructor for a new sap.m.FlexItemData.
	 *
	 * @param {string} [sId] ID for the new element, generated automatically if no ID is given
	 * @param {object} [mSettings] Initial settings for the new element.
	 *
	 * @class
	 * Holds layout data for a FlexBox / HBox / VBox.
	 * @extends sap.ui.core.LayoutData
	 * @version ${version}
	 *
	 * @constructor
	 * @public
	 * @alias sap.m.FlexItemData
	 * @ui5-metamodel This control/element also will be described in the UI5 (legacy) designtime metamodel
	 */
	var FlexItemData = LayoutData.extend("sap.m.FlexItemData", /** @lends sap.m.FlexItemData.prototype */ { metadata : {

		library : "sap.m",
		properties : {

			/**
			 * Determines cross-axis alignment of individual element (not currently supported in Internet Explorer).
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#align-items-property
			 */
			alignSelf : {type : "sap.m.FlexAlignSelf", group : "Misc", defaultValue : sap.m.FlexAlignSelf.Auto},

			/**
			 * Determines the display order of flex items independent of their source code order.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#order-property
			 */
			order : {type : "int", group : "Misc", defaultValue : 0},

			/**
			 * Determines the flexibility of the flex item when allocatable space is remaining.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#flex-grow-property
			 */
			growFactor : {type : "float", group : "Misc", defaultValue : 0},

			/**
			 * The shrink factor determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#flex-shrink-property
			 *
			 * Note: This property is not supported in Internet Explorer 9, Android Native Browser/Webview <4.4, and Safari <7.
			 * @since 1.24.0
			 */
			shrinkFactor : {type : "float", group : "Misc", defaultValue : 1},

			/**
			 * The base size is the initial main size of the item for the flex algorithm. If set to "auto", this will be the computed size of the item.
			 *
			 * @see http://www.w3.org/TR/css-flexbox-1/#flex-basis-property
			 *
			 * @since 1.32.0
			 */
			baseSize : {type : "sap.ui.core.CSSSize", group : "Misc", defaultValue : "auto"},

			/**
			 * The minimum height of the flex item.
			 * @since 1.36.0
			 */
			minHeight : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : 'auto'},

			/**
			 * The maximum height of the flex item.
			 * @since 1.36.0
			 */
			maxHeight : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : ''},

			/**
			 * The minimum height of the flex item.
			 * @since 1.36.0
			 */
			minWidth : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : 'auto'},

			/**
			 * The maximum height of the flex item.
			 * @since 1.36.0
			 */
			maxWidth : {type : "sap.ui.core.CSSSize", group : "Dimension", defaultValue : ''},

			/**
			 * The style class will be applied to the flex item and can be used for CSS selectors.
			 */
			styleClass : {type : "string", group : "Misc", defaultValue : ''},

			/**
			 * Defines the background style of the flex item.
			 *
			 * @since 1.38.5
			 */
			backgroundDesign: {type: "sap.m.BackgroundDesign", group: "Appearance", defaultValue: sap.m.BackgroundDesign.Transparent}
		}
	}});

	/**
	 * Sets the alignSelf property.
	 *
	 * @name sap.m.FlexItemData.setAlignSelf
	 * @method
	 * @public
	 * @param {string} sValue Align option.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setAlignSelf = function(sValue) {
		var sOldValue = this.getAlignSelf();
		this.setProperty("alignSelf", sValue, true);
		this.$().removeClass("sapMFlexItemAlign" + sOldValue).addClass("sapMFlexItemAlign" + this.getAlignSelf());

		return this;
	};

	/**
	 * Sets the order.
	 *
	 * @name sap.m.FlexItemData.setOrder
	 * @method
	 * @public
	 * @param {string} sValue Order in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setOrder = function(sValue) {
		this.setProperty("order", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "order", this.getOrder());

		return this;
	};

	/**
	 * Sets the growFactor property.
	 *
	 * @name sap.m.FlexItemData.setGrowFactor
	 * @method
	 * @public
	 * @param {string} sValue Grow factor in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setGrowFactor = function(sValue) {
		this.setProperty("growFactor", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "flex-grow", this.getGrowFactor());

		return this;
	};

	/**
	 * Sets the shrinkFactor property.
	 *
	 * @name sap.m.FlexItemData.setShrinkFactor
	 * @method
	 * @public
	 * @param {string} sValue Shrink factor in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setShrinkFactor = function(sValue) {
		this.setProperty("shrinkFactor", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "flex-shrink", this.getShrinkFactor());

		return this;
	};

	/**
	 * Sets the base size for flex items.
	 *
	 * @name sap.m.FlexItemData.setBaseSize
	 * @method
	 * @public
	 * @param {string} sValue Base size in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setBaseSize = function(sValue) {
		this.setProperty("baseSize", sValue, true);
		FlexBoxStylingHelper.setStyle(null, this, "flex-basis", this.getBaseSize());

		return this;
	};

	/**
	 * Sets minimum height.
	 *
	 * @name sap.m.FlexItemData.setMinHeight
	 * @method
	 * @public
	 * @param {string} sValue Minimum height in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setMinHeight = function(sValue) {
		this.setProperty("minHeight", sValue, true);
		this.$().css("min-height", this.getMinHeight());

		return this;
	};

	/**
	 * Sets maximum height.
	 *
	 * @name sap.m.FlexItemData.setMaxHeight
	 * @method
	 * @public
	 * @param {string} sValue Maximum height in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setMaxHeight = function(sValue) {
		this.setProperty("maxHeight", sValue, true);
		this.$().css("max-height", this.getMaxHeight());

		return this;
	};

	/**
	 * Sets minimum width.
	 *
	 * @name sap.m.FlexItemData.setMinWidth
	 * @method
	 * @public
	 * @param {string} sValue Minimum width in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setMinWidth = function(sValue) {
		this.setProperty("minWidth", sValue, true);
		this.$().css("min-width", this.getMinWidth());

		return this;
	};

	/**
	 * Sets maximum width.
	 *
	 * @name sap.m.FlexItemData.setMaxWidth
	 * @method
	 * @public
	 * @param {string} sValue Maximum width in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setMaxWidth = function(sValue) {
		this.setProperty("maxWidth", sValue, true);
		this.$().css("max-width", this.getMaxWidth());

		return this;
	};

	/**
	 * Sets background design for flex items.
	 *
	 * @name sap.m.FlexItemData.setBackgroundDesign
	 * @method
	 * @public
	 * @param {string} sValue Background design in string format.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setBackgroundDesign = function(sValue) {
		var sOldValue = this.getBackgroundDesign();
		this.setProperty("backgroundDesign", sValue, true);
		this.$().removeClass("sapMFlexBoxBG" + sOldValue).addClass("sapMFlexBoxBG" + this.getBackgroundDesign());

		return this;
	};

	/**
	 * Sets style class.
	 *
	 * @name sap.m.FlexItemData.setStyleClass
	 * @method
	 * @public
	 * @param {string} sValue Style class.
	 * @returns {sap.m.FlexItemData} this FlexItemData reference for chaining.
	 */
	FlexItemData.prototype.setStyleClass = function(sValue) {
		var sOldValue = this.getStyleClass();
		this.setProperty("styleClass", sValue, true);
		this.$().removeClass(sOldValue).addClass(this.getStyleClass());

		return this;
	};

	return FlexItemData;

}, /* bExport= */ true);
<|endoftext|>