<commit_before>/*global defineSuite*/
defineSuite([
        'Scene/SceneTransforms',
        'Core/Cartesian2',
        'Core/Cartesian3',
        'Core/Cartographic',
        'Core/Ellipsoid',
        'Core/Math',
        'Scene/SceneMode',
        'Specs/createScene',
        'Specs/destroyScene'
    ], function(
        SceneTransforms,
        Cartesian2,
        Cartesian3,
        Cartographic,
        Ellipsoid,
        CesiumMath,
        SceneMode,
        createScene,
        destroyScene) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    var scene;

    beforeAll(function() {
        scene = createScene();
    });

    afterAll(function() {
        destroyScene(scene);
    });

    it('throws an exception without scene', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var position = ellipsoid.cartographicToCartesian(new Cartographic(0.0, 0.0));
        expect(function() {
            SceneTransforms.wgs84ToWindowCoordinates(undefined, position);
        }).toThrowDeveloperError();
    });

    it('throws an exception without position', function() {
        expect(function() {
            SceneTransforms.wgs84ToWindowCoordinates(scene);
        }).toThrowDeveloperError();
    });

    it('returns correct window position in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height = 0.0;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(windowCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });

    it('returns correct drawing buffer position in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height = 0.0;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(drawingBufferCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });

    it('returns undefined for window position behind camera in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height *= 1.1;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates).not.toBeDefined();
    });

    it('returns undefined for drawing buffer position behind camera in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height *= 1.1;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates).not.toBeDefined();
    });

    it('returns correct window position in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var actualWindowCoordinates = new Cartesian2(0.5, 0.5);
        var position = scene.camera.pickEllipsoid(actualWindowCoordinates);

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates).toEqualEpsilon(actualWindowCoordinates, CesiumMath.EPSILON2);
    });

    it('returns correct drawing buffer position in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var actualDrawingBufferCoordinates = new Cartesian2(0.5, 0.5);
        var position = scene.camera.pickEllipsoid(actualDrawingBufferCoordinates);

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates).toEqualEpsilon(actualDrawingBufferCoordinates, CesiumMath.EPSILON2);
    });

    it('returns undefined for window position behind camera in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var position = new Cartesian3();
        Cartesian3.normalize(scene.camera.position, position);
        Cartesian3.add(position, scene.camera.direction, position);
        Cartesian3.multiplyByScalar(scene.camera.direction, -1, scene.camera.direction);

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates).not.toBeDefined();
    });

    it('returns undefined for drawing buffer position behind camera in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var position = new Cartesian3();
        Cartesian3.normalize(scene.camera.position, position);
        Cartesian3.add(position, scene.camera.direction, position);
        Cartesian3.multiplyByScalar(scene.camera.direction, -1, scene.camera.direction);

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates).not.toBeDefined();
    });

    it('returns correct window position in 2D', function() {
        // Update scene state
        scene.morphTo2D(0);
        scene.initializeFrame();

        var ellipsoid = Ellipsoid.WGS84;
        var position = ellipsoid.cartographicToCartesian(new Cartographic());

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(windowCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });

    it('returns correct drawing buffer position in 2D', function() {
        // Update scene state
        scene.morphTo2D(0);
        scene.initializeFrame();
        scene.render();

        var ellipsoid = Ellipsoid.WGS84;
        var position = ellipsoid.cartographicToCartesian(new Cartographic());

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(drawingBufferCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });
}, 'WebGL');
<commit_msg>Since all SceneTransforms tests share state, we need to reset the camera before each tests.<commit_after>/*global defineSuite*/
defineSuite([
        'Scene/SceneTransforms',
        'Core/Cartesian2',
        'Core/Cartesian3',
        'Core/Cartographic',
        'Core/Ellipsoid',
        'Core/Math',
        'Scene/SceneMode',
        'Specs/createScene',
        'Specs/destroyScene'
    ], function(
        SceneTransforms,
        Cartesian2,
        Cartesian3,
        Cartographic,
        Ellipsoid,
        CesiumMath,
        SceneMode,
        createScene,
        destroyScene) {
    "use strict";
    /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

    var scene;
    var defaultCamera;

    beforeAll(function() {
        scene = createScene();
        defaultCamera = scene.camera.clone();
    });

    afterAll(function() {
        destroyScene(scene);
    });

    beforeEach(function() {
        scene.camera.position = defaultCamera.position.clone();
        scene.camera.direction = defaultCamera.direction.clone();
        scene.camera.up = defaultCamera.up.clone();
        scene.camera.right = defaultCamera.right.clone();
        scene.camera.transform = defaultCamera.transform.clone();
        scene.camera.frustum = defaultCamera.frustum.clone();
    });

    it('throws an exception without scene', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var position = ellipsoid.cartographicToCartesian(new Cartographic(0.0, 0.0));
        expect(function() {
            SceneTransforms.wgs84ToWindowCoordinates(undefined, position);
        }).toThrowDeveloperError();
    });

    it('throws an exception without position', function() {
        expect(function() {
            SceneTransforms.wgs84ToWindowCoordinates(scene);
        }).toThrowDeveloperError();
    });

    it('returns correct window position in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height = 0.0;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(windowCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });

    it('returns correct drawing buffer position in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height = 0.0;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(drawingBufferCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });

    it('returns undefined for window position behind camera in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height *= 1.1;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates).not.toBeDefined();
    });

    it('returns undefined for drawing buffer position behind camera in 3D', function() {
        var ellipsoid = Ellipsoid.WGS84;
        var positionCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);
        positionCartographic.height *= 1.1;
        var position = ellipsoid.cartographicToCartesian(positionCartographic);

        // Update scene state
        scene.initializeFrame();
        scene.render();

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates).not.toBeDefined();
    });

    it('returns correct window position in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var actualWindowCoordinates = new Cartesian2(0.5, 0.5);
        var position = scene.camera.pickEllipsoid(actualWindowCoordinates);

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates).toEqualEpsilon(actualWindowCoordinates, CesiumMath.EPSILON2);
    });

    it('returns correct drawing buffer position in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var actualDrawingBufferCoordinates = new Cartesian2(0.5, 0.5);
        var position = scene.camera.pickEllipsoid(actualDrawingBufferCoordinates);

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates).toEqualEpsilon(actualDrawingBufferCoordinates, CesiumMath.EPSILON2);
    });

    it('returns undefined for window position behind camera in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var position = new Cartesian3();
        Cartesian3.normalize(scene.camera.position, position);
        Cartesian3.add(position, scene.camera.direction, position);
        Cartesian3.multiplyByScalar(scene.camera.direction, -1, scene.camera.direction);

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates).not.toBeDefined();
    });

    it('returns undefined for drawing buffer position behind camera in ColumbusView', function() {
        // Update scene state
        scene.morphToColumbusView(0);
        scene.initializeFrame();
        scene.render();

        var position = new Cartesian3();
        Cartesian3.normalize(scene.camera.position, position);
        Cartesian3.add(position, scene.camera.direction, position);
        Cartesian3.multiplyByScalar(scene.camera.direction, -1, scene.camera.direction);

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates).not.toBeDefined();
    });

    it('returns correct window position in 2D', function() {
        // Update scene state
        scene.morphTo2D(0);
        scene.initializeFrame();

        var ellipsoid = Ellipsoid.WGS84;
        var position = ellipsoid.cartographicToCartesian(new Cartographic());

        var windowCoordinates = SceneTransforms.wgs84ToWindowCoordinates(scene, position);
        expect(windowCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(windowCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });

    it('returns correct drawing buffer position in 2D', function() {
        // Update scene state
        scene.morphTo2D(0);
        scene.initializeFrame();
        scene.render();

        var ellipsoid = Ellipsoid.WGS84;
        var position = ellipsoid.cartographicToCartesian(new Cartographic());

        var drawingBufferCoordinates = SceneTransforms.wgs84ToDrawingBufferCoordinates(scene, position);
        expect(drawingBufferCoordinates.x).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
        expect(drawingBufferCoordinates.y).toEqualEpsilon(0.5, CesiumMath.EPSILON2);
    });
}, 'WebGL');
<|endoftext|>


<commit_before>import { hooks as auth } from 'feathers-authentication';
import { associateCurrentUser, queryWithCurrentUser } from 'feathers-authentication-hooks';
import { iff, isProvider } from 'feathers-hooks-common';
import { hooks } from 'mostly-feathers-mongoose';

module.exports = function(options = {}) {
  return {
    before: {
      all: [
        auth.authenticate('jwt'),
        iff(isProvider('external'),
          queryWithCurrentUser({ idField: 'id', as: 'creator' }))
      ]
    },
    after: {
      all: [
        hooks.responder()
      ]
    }
  };
};<commit_msg>add HiddenInNavigation facets to workspace<commit_after>import { hooks as auth } from 'feathers-authentication';
import { associateCurrentUser, queryWithCurrentUser } from 'feathers-authentication-hooks';
import { iff, isProvider } from 'feathers-hooks-common';
import { hooks } from 'mostly-feathers-mongoose';
import * as content from '~/hooks';

module.exports = function(options = {}) {
  return {
    before: {
      all: [
        auth.authenticate('jwt'),
        iff(isProvider('external'),
          queryWithCurrentUser({ idField: 'id', as: 'creator' }))
      ]
    },
    after: {
      all: [
        content.addMetadata('facets', ['HiddenInNavigation']),
        hooks.responder()
      ]
    }
  };
};<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular.module('permission')
    .provider('Permission', function () {
      var permissionStore = {};
      var self = this;

      /**
       * Allows to define permission on application configuration
       * @deprecated
       *
       * @param permission {String} Name of defined permission
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      this.defineRole = function (permission, validationFunction) {
        console.warn('Function "defineRole" will be deprecated. Use "definePermission" instead');
        self.definePermission(permission, validationFunction);
        return this;
      };

      /**
       * Allows to define permission on application configuration
       *
       * @param permission {String} Name of defined permission
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      this.definePermission = function (permission, validationFunction) {
        validatePermission(permission, validationFunction);
        permissionStore[permission] = validationFunction;
        return this;
      };

      /**
       * Allows to define set of permissions with shared validation function on application configuration
       *
       * @param permissions {Array} Set of permission names
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      this.defineManyPermissions = function (permissions, validationFunction) {
        if (!angular.isArray(permissions)) {
          throw new TypeError('Parameter "permissions" name must be Array');
        }

        angular.forEach(permissions, function (permissionName) {
          self.definePermission(permissionName, validationFunction);
        });

        return this;
      };

      /**
       * Checks if provided permission has accepted parameter types
       * @private
       *
       * @param permission {String} Name of defined permission
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      function validatePermission(permission, validationFunction) {
        if (!angular.isString(permission)) {
          throw new TypeError('Parameter "permission" name must be String');
        }
        if (!angular.isFunction(validationFunction)) {
          throw new TypeError('Parameter "validationFunction" must be Function');
        }
      }

      /**
       * Checks if provided permission map has accepted parameter types
       * @private
       *
       * @param permissionMap {Object}
       */
      function validatePermissionMap(permissionMap) {
        if (!angular.isObject(permissionMap)) {
          throw new TypeError('Parameter "permissionMap" has to be Object');
        }

        if (angular.isUndefined(permissionMap.only) && angular.isUndefined(permissionMap.except)) {
          throw new ReferenceError('Either "only" or "except" keys must me defined');
        }

        if (!(angular.isArray(permissionMap.only) || angular.isArray(permissionMap.except))) {
          throw new TypeError('Parameter "permissionMap" properties must be Array');
        }
      }

      this.$get = ['$q', function ($q) {

        /**
         * Converts a value into a promise, if the value is truthy it resolves it, otherwise it rejects it
         * @private
         *
         * @param func {Function} Function to be wrapped into promise
         * @return {promise} $q.promise object
         */
        function wrapInPromise(func) {
          var dfd = $q.defer();

          if (func) {
            dfd.resolve();
          } else {
            dfd.reject();
          }

          return dfd.promise;
        }

        /**
         * Performs iteration over list of defined permissions looking for matching roles
         * @private
         *
         * @param permissions {Array} Set of permission names
         * @param toParams {Object} UI-Router params object
         * @returns {promise} $q.promise object
         */
        function findMatchingRole(permissions, toParams) {
          var deferred = $q.defer();
          var currentPermission = permissions.shift();

          if (angular.isDefined(currentPermission) && angular.isFunction(permissionStore[currentPermission])) {
            var validationResult = permissionStore[currentPermission].call(self, toParams, currentPermission);

            if (!angular.isFunction(validationResult.then)) {
              validationResult = wrapInPromise(validationResult);
            }

            $q.when(validationResult)
              .then(function () {
                deferred.resolve();
              })
              .catch(function () {
                findMatchingRole(permissions, toParams)
                  .then(function () {
                    deferred.resolve();
                  })
                  .catch(function () {
                    deferred.reject();
                  });
              });
          } else {
            // If no roles left to validate reject promise
            deferred.reject();
          }

          return deferred.promise;
        }

        /**
         * Resolves promise if search permission is found
         * @private
         *
         * @param permissions {Array} Set of permission names
         * @param toParams {Object} UI-Router params object
         * @returns {promise} $q.promise object
         */
        function resolveIfMatch(permissions, toParams) {
          var deferred = $q.defer();

          findMatchingRole(permissions, toParams)
            .then(function () {
              deferred.resolve();
            })
            .catch(function () {
              deferred.reject();
            });

          return deferred.promise;
        }

        /**
         * Resolves promise if search permission is missing
         * @private
         *
         * @param permissions {Array} Set of permission names
         * @param toParams {Object} UI-Router params object
         * @returns {promise} $q.promise object
         */
        function rejectIfMatch(permissions, toParams) {
          var deferred = $q.defer();

          findMatchingRole(permissions, toParams)
            .then(function () {
              deferred.reject();
            })
            .catch(function () {
              deferred.resolve();
            });

          return deferred.promise;
        }

        var Permission = {
          /**
           * Allows to define permission in runtime
           * @deprecated
           *
           * @param permission {String} Name of defined permission
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          defineRole: function (permission, validationFunction) {
            console.warn('Function "defineRole" will be deprecated. Use "definePermission" instead');
            self.definePermission(permission, validationFunction);
            return Permission;
          },

          /**
           * Allows to define permission in runtime
           *
           * @param permission {String} Name of defined permission
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          definePermission: function (permission, validationFunction) {
            self.definePermission(permission, validationFunction);
            return Permission;
          },

          /**
           * Allows to define set of permissions with shared validation function in runtime
           * @deprecated
           *
           * @param permissions {Array} Set of permission names
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          defineManyRoles: function (permissions, validationFunction) {
            console.warn('Function "defineManyRoles" will be deprecated. Use "defineManyPermissions" instead');
            self.defineManyPermissions(permissions, validationFunction);
            return Permission;
          },

          /**
           * Allows to define set of permissions with shared validation function in runtime
           *
           * @param permissions {Array} Set of permission names
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          defineManyPermissions: function (permissions, validationFunction) {
            self.defineManyPermissions(permissions, validationFunction);
            return Permission;
          },

          /**
           * Deletes permission
           *
           * @param permission {String} Name of defined permission
           */
          removePermission: function (permission) {
            delete permissionStore[permission];
          },

          /**
           * Deletes set of permissions
           *
           * @param permissions {Array} Set of permission names
           */
          removeManyPermissions: function (permissions) {
            angular.forEach(permissions, function (permission) {
              delete permissionStore[permission];
            });
          },

          /**
           * Checks if permission exists
           *
           * @param permission {String} Name of defined permission
           * @returns {Boolean}
           */
          hasPermission: function (permission) {
            return angular.isDefined(permissionStore[permission]);
          },

          /**
           * Returns all permissions
           *
           * @returns {Object} Permissions collection
           */
          getPermissions: function () {
            return permissionStore;
          },

          /**
           * Removes all permissions
           */
          clearPermissions: function () {
            permissionStore = [];
          },

          /**
           * Checks if provided permissions are acceptable
           *
           * @param permissionsMap {Object} Map of "only" or "except" permission names
           * @param toParams {Object} UI-Router params object
           * @returns {promise} $q.promise object
           */
          authorize: function (permissionsMap, toParams) {
            var result;

            validatePermissionMap(permissionsMap);

            if (angular.isDefined(permissionsMap.only)) {
              result = resolveIfMatch(angular.copy(permissionsMap.only), toParams);
            } else {
              result = rejectIfMatch(angular.copy(permissionsMap.except), toParams);
            }

            return result;
          }
        };

        return Permission;
      }];
    });
})();<commit_msg>Remove wrapInPromise method.<commit_after>(function () {
  'use strict';

  angular.module('permission')
    .provider('Permission', function () {
      var permissionStore = {};
      var self = this;

      /**
       * Allows to define permission on application configuration
       * @deprecated
       *
       * @param permission {String} Name of defined permission
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      this.defineRole = function (permission, validationFunction) {
        console.warn('Function "defineRole" will be deprecated. Use "definePermission" instead');
        self.definePermission(permission, validationFunction);
        return this;
      };

      /**
       * Allows to define permission on application configuration
       *
       * @param permission {String} Name of defined permission
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      this.definePermission = function (permission, validationFunction) {
        validatePermission(permission, validationFunction);
        permissionStore[permission] = validationFunction;
        return this;
      };

      /**
       * Allows to define set of permissions with shared validation function on application configuration
       *
       * @param permissions {Array} Set of permission names
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      this.defineManyPermissions = function (permissions, validationFunction) {
        if (!angular.isArray(permissions)) {
          throw new TypeError('Parameter "permissions" name must be Array');
        }

        angular.forEach(permissions, function (permissionName) {
          self.definePermission(permissionName, validationFunction);
        });

        return this;
      };

      /**
       * Checks if provided permission has accepted parameter types
       * @private
       *
       * @param permission {String} Name of defined permission
       * @param validationFunction {Function} Function used to validate if permission is valid
       */
      function validatePermission(permission, validationFunction) {
        if (!angular.isString(permission)) {
          throw new TypeError('Parameter "permission" name must be String');
        }
        if (!angular.isFunction(validationFunction)) {
          throw new TypeError('Parameter "validationFunction" must be Function');
        }
      }

      /**
       * Checks if provided permission map has accepted parameter types
       * @private
       *
       * @param permissionMap {Object}
       */
      function validatePermissionMap(permissionMap) {
        if (!angular.isObject(permissionMap)) {
          throw new TypeError('Parameter "permissionMap" has to be Object');
        }

        if (angular.isUndefined(permissionMap.only) && angular.isUndefined(permissionMap.except)) {
          throw new ReferenceError('Either "only" or "except" keys must me defined');
        }

        if (!(angular.isArray(permissionMap.only) || angular.isArray(permissionMap.except))) {
          throw new TypeError('Parameter "permissionMap" properties must be Array');
        }
      }

      this.$get = ['$q', function ($q) {
        /**
         * Performs iteration over list of defined permissions looking for matching roles
         * @private
         *
         * @param permissions {Array} Set of permission names
         * @param toParams {Object} UI-Router params object
         * @returns {promise} $q.promise object
         */
        function findMatchingRole(permissions, toParams) {
          var dfd = $q.defer();
          var currentPermission = permissions.shift();

          if (angular.isDefined(currentPermission) && angular.isFunction(permissionStore[currentPermission])) {
            var validationResult = permissionStore[currentPermission].call(self, toParams, currentPermission);

            $q.when(validationResult)
              .then(function (value) {
                // If is promise wrapped true-falsely function resolve it based on value
                if (value) {
                  dfd.resolve();
                } else {
                  dfd.reject();
                }

                dfd.resolve();
              })
              .catch(function () {
                findMatchingRole(permissions, toParams)
                  .then(function () {
                    dfd.resolve();
                  })
                  .catch(function () {
                    dfd.reject();
                  });
              });
          } else {
            // If no roles left to validate reject promise
            dfd.reject();
          }

          return dfd.promise;
        }

        /**
         * Resolves promise if search permission is found
         * @private
         *
         * @param permissions {Array} Set of permission names
         * @param toParams {Object} UI-Router params object
         * @returns {promise} $q.promise object
         */
        function resolveIfMatch(permissions, toParams) {
          var deferred = $q.defer();

          findMatchingRole(permissions, toParams)
            .then(function () {
              deferred.resolve();
            })
            .catch(function () {
              deferred.reject();
            });

          return deferred.promise;
        }

        /**
         * Resolves promise if search permission is missing
         * @private
         *
         * @param permissions {Array} Set of permission names
         * @param toParams {Object} UI-Router params object
         * @returns {promise} $q.promise object
         */
        function rejectIfMatch(permissions, toParams) {
          var deferred = $q.defer();

          findMatchingRole(permissions, toParams)
            .then(function () {
              deferred.reject();
            })
            .catch(function () {
              deferred.resolve();
            });

          return deferred.promise;
        }

        var Permission = {
          /**
           * Allows to define permission in runtime
           * @deprecated
           *
           * @param permission {String} Name of defined permission
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          defineRole: function (permission, validationFunction) {
            console.warn('Function "defineRole" will be deprecated. Use "definePermission" instead');
            self.definePermission(permission, validationFunction);
            return Permission;
          },

          /**
           * Allows to define permission in runtime
           *
           * @param permission {String} Name of defined permission
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          definePermission: function (permission, validationFunction) {
            self.definePermission(permission, validationFunction);
            return Permission;
          },

          /**
           * Allows to define set of permissions with shared validation function in runtime
           * @deprecated
           *
           * @param permissions {Array} Set of permission names
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          defineManyRoles: function (permissions, validationFunction) {
            console.warn('Function "defineManyRoles" will be deprecated. Use "defineManyPermissions" instead');
            self.defineManyPermissions(permissions, validationFunction);
            return Permission;
          },

          /**
           * Allows to define set of permissions with shared validation function in runtime
           *
           * @param permissions {Array} Set of permission names
           * @param validationFunction {Function} Function used to validate if permission is valid
           */
          defineManyPermissions: function (permissions, validationFunction) {
            self.defineManyPermissions(permissions, validationFunction);
            return Permission;
          },

          /**
           * Deletes permission
           *
           * @param permission {String} Name of defined permission
           */
          removePermission: function (permission) {
            delete permissionStore[permission];
          },

          /**
           * Deletes set of permissions
           *
           * @param permissions {Array} Set of permission names
           */
          removeManyPermissions: function (permissions) {
            angular.forEach(permissions, function (permission) {
              delete permissionStore[permission];
            });
          },

          /**
           * Checks if permission exists
           *
           * @param permission {String} Name of defined permission
           * @returns {Boolean}
           */
          hasPermission: function (permission) {
            return angular.isDefined(permissionStore[permission]);
          },

          /**
           * Returns all permissions
           *
           * @returns {Object} Permissions collection
           */
          getPermissions: function () {
            return permissionStore;
          },

          /**
           * Removes all permissions
           */
          clearPermissions: function () {
            permissionStore = [];
          },

          /**
           * Checks if provided permissions are acceptable
           *
           * @param permissionsMap {Object} Map of "only" or "except" permission names
           * @param toParams {Object} UI-Router params object
           * @returns {promise} $q.promise object
           */
          authorize: function (permissionsMap, toParams) {
            var result;

            validatePermissionMap(permissionsMap);

            if (angular.isDefined(permissionsMap.only)) {
              result = resolveIfMatch(angular.copy(permissionsMap.only), toParams);
            } else {
              result = rejectIfMatch(angular.copy(permissionsMap.except), toParams);
            }

            return result;
          }
        };

        return Permission;
      }];
    });
})();<|endoftext|>


<commit_before>// @flow

import typeOf from 'ramda/src/type';
import isPlainObject from 'lodash/lang/isPlainObject';
import createValidator from '../createValidator';
import type {Validator} from './Validator';
import type {ValidationResult} from './ValidationResult';

export default class RecordValidator {
	shape: {[key: mixed]: Validator};

	constructor(desc: mixed) {
		if (!(typeof desc === 'object' && desc && isPlainObject(desc)))
			throw Error(`A record must be defined by an object.`);

		this.shape = {};
		for (let propName of Object.getOwnPropertyNames(desc)) {
			try {
				this.shape[propName] = createValidator(desc[propName]);
			} catch (e) {
				let propertyName = propName;
				let stack = e.stack;
				if (e.originalStack) {
					stack = e.originalStack;
					propertyName += '.' + e.propertyName;
					e.propertyName = propertyName;
				} else {
					e.originalStack = e.stack;
				}
				e.stack = `Error defining prop \'${propertyName}': ${e.originalStack}`
				throw e;
			}
		}
	}

	isValid(val: mixed): boolean {
		if (!(typeof val === 'object' && val))
			return false;

		for (let key of Object.keys(this.shape)) {
			let validator = this.shape[key];
			if (validator.isValid(val[key]) === false)
				return false;
		}

		return true;
	}

	getValidationResult(val: mixed): ValidationResult {
		if (!(typeof val === 'object' && val))
			return {
				isValid: 'false',
				message: `Object expected, ${typeOf(val)} given.`,
				score: 0
			}

		var numberOfPropsCounted = 0
		for (let key of Object.keys(this.shape)) {
			let validator = this.shape[key];
			let result = validator.getValidationResult(val[key]);
			if (result.isValid == 'false') {
				return {
					isValid: 'false',
					message: `Error validating prop ${key}:\n ${result.message}`,
					score: 1 + numberOfPropsCounted
				}
			}
			numberOfPropsCounted++;
		}

		return {
			isValid: 'true'
		}
	}
}<commit_msg>Fix the type error in Record<commit_after>// @flow

import typeOf from 'ramda/src/type';
import isPlainObject from 'lodash/lang/isPlainObject';
import createValidator from '../createValidator';
import type {Validator} from './Validator';
import type {ValidationResult} from './ValidationResult';

export default class RecordValidator {
	shape: {[key: mixed]: Validator};

	constructor(desc: mixed) {
		if (!(typeof desc === 'object' && desc && isPlainObject(desc)))
			throw Error(`A record must be defined by an object.`);

		this.shape = {};
		for (let propName of Object.getOwnPropertyNames(desc)) {
			try {
				this.shape[propName] = createValidator(desc[propName]);
			} catch (e) {
				let propertyName = propName;
				let stack = e.stack;
				if (e.originalStack) {
					stack = e.originalStack;
					propertyName += '.' + e.propertyName;
					e.propertyName = propertyName;
				} else {
					e.originalStack = e.stack;
				}
				e.stack = `Error defining prop \'${propertyName}': ${e.originalStack}`
				throw e;
			}
		}
	}

	isValid(val: mixed): boolean {
		if (!(typeof val === 'object' && val))
			return false;

		for (let key of Object.keys(this.shape)) {
			let validator = this.shape[key];
			if (validator.isValid(val[key]) === false)
				return false;
		}

		return true;
	}

	getValidationResult(val: mixed): ValidationResult {
		if (!(typeof val === 'object' && val))
			return {
				isValid: 'false',
				message: `Object expected, ${typeOf(val)} given.`,
				score: 0
			}

		var numberOfPropsCounted = 0
		for (let key of Object.keys(this.shape)) {
			let validator = this.shape[key];
			let result = validator.getValidationResult(val[key]);
			if (result.isValid === 'false') {
				return {
					isValid: 'false',
					message: `Error validating prop ${key}:\n ${result.message}`,
					score: 1 + numberOfPropsCounted
				}
			}
			numberOfPropsCounted++;
		}

		return {
			isValid: 'true'
		}
	}
}<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const Wechat = require('../../../service/Wechat');
const async = require('async');

exports.sync = function(req, res, next) {
  let Subscriber = req.app.db.models.Subscriber;
  Subscriber.update({}, { subscribe: false }, { multi: true }).exec((err) => {
    if (err) return callback(err);
    Wechat.getCompleteOpenIdList().then((remoteList) => {
      async.eachSeries(remoteList, function(openId, callback) {
        Wechat.getSubscriberInfo(openId).then((info) => {
          let newData = {
            openId: info.openid,
            groupId: info.groupid,
            unionId: info.unionid,
            subscribe: info.subscribe ? true : false,
            subscribeTime: new Date(info.subscribe_time * 1000),
            nickname: info.nickname,
            remark: info.remark,
            gender: info.sex,
            headImgUrl: info.headimgurl,
            city: info.city,
            province: info.province,
            country: info.country,
            language: info.language
          };
          Subscriber.findOneAndUpdate({ openId }, newData, { upsert: true }, function(err, doc){
            if (err) return callback(err);
            return callback();
          });
        }).catch((err) => {
          callback(err);
        });
      }, function(err) {
        if(err) return next(err);
        res.send({ remoteList });
      });
    });
  });
};

<commit_msg>fix(subscriber): 同步过程不被异常中断<commit_after>'use strict';

const _ = require('lodash');
const Wechat = require('../../../service/Wechat');
const async = require('async');

exports.sync = function(req, res, next) {
  let Subscriber = req.app.db.models.Subscriber;
  Subscriber.update({}, { subscribe: false }, { multi: true }).exec((err) => {
    if (err) return callback(err);
    Wechat.getCompleteOpenIdList().then((remoteList) => {
      async.eachOfSeries(remoteList, function(openId, index, callback) {
        Wechat.getSubscriberInfo(openId).then((info) => {
          let newData = {
            openId: info.openid,
            groupId: info.groupid,
            unionId: info.unionid,
            subscribe: info.subscribe ? true : false,
            subscribeTime: new Date(info.subscribe_time * 1000),
            nickname: info.nickname,
            remark: info.remark,
            gender: info.sex,
            headImgUrl: info.headimgurl,
            city: info.city,
            province: info.province,
            country: info.country,
            language: info.language
          };
          Subscriber.findOneAndUpdate({ openId }, newData, { upsert: true }, function(err, doc){
            if (err) return callback(err);
            console.log('Sync: ' + info.openid + ` (${index}/${remoteList.length})`);
            return callback();
          });
        }).catch((err) => {
          console.error('Sync error:', err);
          callback();
        });
      }, function(err) {
        if(err) return next(err);
        res.send({ remoteList });
      });
    });
  });
};

<|endoftext|>


<commit_before>define(['pex/utils/Log'], function(Log) {
  var Time = {
    now: 0,
    prev: 0,
    delta: 0,
    seconds: 0,
    frameNumber: 0,
    fpsFrames: 0,
    fpsTime: 0,
    fps: 0,
    fpsFrequency: 3,
    paused: false,
    verbose: false
  }

  Time.update = function(delta) {
    if (Time.paused) return;

    if (Time.prev == 0) {
      Time.prev = Date.now();
    }
    Time.now = Date.now();
    Time.delta = (delta !== undefined) ? delta : (Time.now - Time.prev)/1000;
    Time.prev = Time.now;
    Time.seconds += Time.delta;
    Time.fpsTime += Time.delta;
    Time.frameNumber++;
    Time.fpsFrames++;
    if (Time.fpsTime > Time.fpsFrequency) {
      Time.fps = Time.fpsFrames / Time.fpsTime;
      Time.fpsTime = 0;
      Time.fpsFrames = 0;
      if (this.verbose) Log.message('FPS: ' + Time.fps);
    }
    return Time.seconds;
  }

  var startOfMeasuredTime = 0;
  Time.startMeasuringTime = function() {
    startOfMeasuredTime = Date.now();
  }

  Time.stopMeasuringTime = function(msg) {
    var now = Date.now();

    var seconds = (now - startOfMeasuredTime)/1000;

    if (msg) {
      Log.message(msg + seconds)
    }
    return seconds;
  }

  Time.pause = function() {
    Time.paused = true;
  }

  Time.togglePause = function() {
    Time.paused = !Time.paused;
  }

  return Time;
});
<commit_msg>Added check to avoid big Time update jumps<commit_after>define(['pex/utils/Log'], function(Log) {
  var Time = {
    now: 0,
    prev: 0,
    delta: 0,
    seconds: 0,
    frameNumber: 0,
    fpsFrames: 0,
    fpsTime: 0,
    fps: 0,
    fpsFrequency: 3,
    paused: false,
    verbose: false
  }

  Time.update = function(delta) {
    if (Time.paused) return;

    if (Time.prev == 0) {
      Time.prev = Date.now();
    }
    Time.now = Date.now();
    Time.delta = (delta !== undefined) ? delta : (Time.now - Time.prev)/1000;
    //More than 1s = probably switched back from another window so we have big jump now
    if (Time.delta > 1) {
      Time.delta = 0;
    }
    Time.prev = Time.now;
    Time.seconds += Time.delta;
    Time.fpsTime += Time.delta;
    Time.frameNumber++;
    Time.fpsFrames++;
    if (Time.fpsTime > Time.fpsFrequency) {
      Time.fps = Time.fpsFrames / Time.fpsTime;
      Time.fpsTime = 0;
      Time.fpsFrames = 0;
      if (this.verbose) Log.message('FPS: ' + Time.fps);
    }
    return Time.seconds;
  }

  var startOfMeasuredTime = 0;
  Time.startMeasuringTime = function() {
    startOfMeasuredTime = Date.now();
  }

  Time.stopMeasuringTime = function(msg) {
    var now = Date.now();

    var seconds = (now - startOfMeasuredTime)/1000;

    if (msg) {
      Log.message(msg + seconds)
    }
    return seconds;
  }

  Time.pause = function() {
    Time.paused = true;
  }

  Time.togglePause = function() {
    Time.paused = !Time.paused;
  }

  return Time;
});
<|endoftext|>


<commit_before>var Post = require('./model');
var router = require('express').Router();

function validatePost(req, res, next) {
  // Sanitize Input
  req.sanitizeBody('title').escape();
  req.sanitizeBody('description').escape();
  req.sanitizeBody('slug').escape();
  req.sanitizeBody('published').toBoolean();

  // Validate Input
  req.checkBody('title', 'Invalid title').notEmpty().isLength({min : 0, max : 120});
  req.checkBody('description', 'Invalid description').notEmpty().isLength({min : 0, max : 160});
  req.checkBody('body', 'Invalid content').notEmpty();
  req.checkBody('slug', 'Invalid slug').notEmpty().matches(/^[a-z0-9-]+$/).isLength({min : 0, max : 150});
  req.checkBody('published', 'Invalid published option').notEmpty().isBoolean();

  next(req.validationErrors(true));
}

function validatePostParam(req, res, next) {
  // Sanitize param
  req.sanitizeParams('post').escape();

  // Validate params
  req.checkParams('post').isAlphanumeric();

  next(req.validationErrors(true));
}

router.get('/', function(req, res, next){
  Post.find({}).then(function(posts) {
    res.json({
      meta : {},
      data : posts
    });
  }).catch(next);
});

router.get('/:post', validatePostParam, function(req, res, next){
  Post.findOne({_id : req.params.post}).then(function(post){
    if (post != null) {
      res.json({
        meta : {},
        data : post
      });
    } else {
      next('Unable to find resource');
    }
  }).catch(next);
});

router.post('/', validatePost, function(req, res, next){
  var post = Post.create({
    title : req.body.title,
    description : req.body.description,
    body  : req.body.body,
    slug  : req.body.slug,
    published : req.body.published
  });

  post.save().then(function(post){
    res.json({
      meta : {},
      data : post
    });
  }).catch(next);
});

router.put('/:post', validatePostParam, validatePost, function(req, res, next){
  Post.findOneAndUpdate({'_id' : req.params.post}, {
    title : req.body.title,
    description : req.body.description,
    body  : req.body.body,
    slug  : req.body.slug,
    published : req.body.published
  }).then(function(post){
    if (post != null) {
      res.json({
        meta : {},
        data : post
      });
    } else {
      next('Unable to find resource');
    }
  }).catch(next);
});

router.delete('/:post', validatePostParam, function(req, res, next){
  Post.findOneAndDelete({'_id' : req.params.post}).then(function(rows){
    res.json({
      meta : {},
      data : {
        rows : rows
      }
    });
  }).catch(next);
});

module.exports = router;
<commit_msg>Fixed #32 : Slugs automatically converted to lower case<commit_after>var Post = require('./model');
var router = require('express').Router();

function validatePost(req, res, next) {
  // Sanitize Input
  req.sanitizeBody('title').escape();
  req.sanitizeBody('description').escape();
  req.sanitizeBody('slug').escape();
  req.sanitizeBody('published').toBoolean();

  // Make the slug lower case
  req.body.slug = req.body.slug.toLowerCase();

  // Validate Input
  req.checkBody('title', 'Invalid title').notEmpty().isLength({min : 0, max : 120});
  req.checkBody('description', 'Invalid description').notEmpty().isLength({min : 0, max : 160});
  req.checkBody('body', 'Invalid content').notEmpty();
  req.checkBody('slug', 'Invalid slug').notEmpty().matches(/^[a-z0-9-]+$/).isLength({min : 0, max : 150});
  req.checkBody('published', 'Invalid published option').notEmpty().isBoolean();

  next(req.validationErrors(true));
}

function validatePostParam(req, res, next) {
  // Sanitize param
  req.sanitizeParams('post').escape();

  // Validate params
  req.checkParams('post').isAlphanumeric();

  next(req.validationErrors(true));
}

router.get('/', function(req, res, next){
  Post.find({}).then(function(posts) {
    res.json({
      meta : {},
      data : posts
    });
  }).catch(next);
});

router.get('/:post', validatePostParam, function(req, res, next){
  Post.findOne({_id : req.params.post}).then(function(post){
    if (post != null) {
      res.json({
        meta : {},
        data : post
      });
    } else {
      next('Unable to find resource');
    }
  }).catch(next);
});

router.post('/', validatePost, function(req, res, next){
  var post = Post.create({
    title : req.body.title,
    description : req.body.description,
    body  : req.body.body,
    slug  : req.body.slug,
    published : req.body.published
  });

  post.save().then(function(post){
    res.json({
      meta : {},
      data : post
    });
  }).catch(next);
});

router.put('/:post', validatePostParam, validatePost, function(req, res, next){
  Post.findOneAndUpdate({'_id' : req.params.post}, {
    title : req.body.title,
    description : req.body.description,
    body  : req.body.body,
    slug  : req.body.slug,
    published : req.body.published
  }).then(function(post){
    if (post != null) {
      res.json({
        meta : {},
        data : post
      });
    } else {
      next('Unable to find resource');
    }
  }).catch(next);
});

router.delete('/:post', validatePostParam, function(req, res, next){
  Post.findOneAndDelete({'_id' : req.params.post}).then(function(rows){
    res.json({
      meta : {},
      data : {
        rows : rows
      }
    });
  }).catch(next);
});

module.exports = router;
<|endoftext|>


<commit_before>var promises = require('q'),
	assert = require('assert');

/**@class	A Feature models a sequence of actions to be executed through Widgets.
*
* A feature description file contains a simple descriptive array listing widget methods to execute and widget state descriptors to assert.
* More formally, such an array is ordered and its members may be:
* - a closure;
* - an object whose keys are some widgets' attributes identifiers (ex: "MyWidget.myAttr"), pointing at a string that contains the expected text content of the HTML element represented by the `myAttr` hook in `MyWidget`.
*
* Upon instanciation, a Feature translates this array into an array of promises:
* - closures are executed directly, either as promises if they are so themselves, or as basic functions;
* - a widget state descripting hash maps each of its members to an assertion inside a promise, evaluating all of them completely asynchronously.
* All those promises are then evaluated sequentially upon calling the `test` method of a Feature.
*/
var Feature = new Class({
	/** A sequence of promises to be executed in order, constructed after the scenario for this feature.
	*/
	steps: [],

	/**
	*@param	description	A plaintext description of the feature, advised to be written in a BDD fashion.
	*@param	scenario	An array that describes states and transitions.
	*/
	initialize: function init(description, scenario) {
		this.description = description;

		this.loadScenario(scenario);
	},

	loadScenario: function loadScenario(scenario) {
		scenario.forEach(function(step) {
			this.steps.push(this.promiseStep(step));
		}, this);
	},

	promiseStep: function promiseStep(step) {
		switch (typeOf(step)) {
			case 'function':
				return step;
			case 'object':
				return this.constructMatchAssertion(step);
			default:
				throw 'Unknown description step in feature "' + this.description + '": ' + step;
		}
	},

	/**
	*@param	hooksVals	A hash whose keys match some widgets' attributes, pointing at values that are expected values for those attributes.
	*/
	constructMatchAssertion: function constructMatchAssertion(hooksVals) {
		return function() {
			var evaluator = promises.defer(),
				matchesLeft = Object.getLength(hooksVals);

			Object.each(hooksVals, function(expected, attribute) {
				eval(attribute).getText().then(function(actual) { //TODO: replace eval with an object walker
					if (expected != actual)
						evaluator.reject(attribute + ' was "' + actual + '" instead of "' + expected + '"');

					if (--matchesLeft == 0)
						evaluator.resolve();
				});
			});

			return evaluator.promise;
		}
	},

	/** Evaluate this feature.
	*/
	test: function evaluate() {
		var deferred = promises.defer(),
			stepIndex = 0;

		var evaluateNext,
			failureReasons = [];

		var handleFailure = function handleFailure(message) {
			failureReasons.push(message);
			evaluateNext();
		}

		evaluateNext = (function(value) {
			if (stepIndex == this.steps.length) {
				if (failureReasons.length == 0)
					return deferred.resolve();
				else
					return deferred.reject(failureReasons.join('\n'));
			}

			try {
				promises.when(this.steps[stepIndex](),
							  evaluateNext,
							  handleFailure);
			} catch (error) {
				handleFailure(error);
			}

			stepIndex++;
		}).bind(this);

		evaluateNext();

		return deferred.promise;
	}
});

module.exports = Feature;	// CommonJS export
<commit_msg>Documented Feature class.<commit_after>var promises = require('q'),
	assert = require('assert');

/**@class	A Feature models a sequence of actions to be executed through Widgets.
*
* A feature description file contains a simple descriptive array listing widget methods to execute and widget state descriptors to assert.
* More formally, such an array is ordered and its members may be:
* - a closure;
* - an object whose keys are some widgets' attributes identifiers (ex: "MyWidget.myAttr"), pointing at a string that contains the expected text content of the HTML element represented by the `myAttr` hook in `MyWidget`.
*
* Upon instanciation, a Feature translates this array into an array of promises:
* - closures are executed directly, either as promises if they are so themselves, or as basic functions;
* - a widget state descripting hash maps each of its members to an assertion inside a promise, evaluating all of them completely asynchronously.
* All those promises are then evaluated sequentially upon calling the `test` method of a Feature.
*/
var Feature = new Class({
	/** A sequence of promises to be executed in order, constructed after the scenario for this feature.
	*
	*@private
	*/
	steps: [],

	/**
	*
	*@param	{String}	description	A plaintext description of the feature, advised to be written in a BDD fashion.
	*@param	{Array}		scenario	An array that describes states and transitions. See class documentation for formatting.
	*/
	initialize: function init(description, scenario) {
		this.description = description;

		this.steps = this.loadScenario(scenario);
	},

	/** Parses an array that describes states and transitions and transforms it into a sequence of promises to be evaluated.
	*
	*@private
	*@param		{Array}	scenario	An array that describes states and transitions. See class documentation for formatting.
	*@returns	{Array.<function>}	An array of promises representing the given scenario.
	*/
	loadScenario: function loadScenario(scenario) {
		var result = [];

		scenario.forEach(function(step) {
			result.push(this.promiseStep(step));
		}, this);

		return result;
	},

	/** Parses a scenario step and returns the corresponding promise.
	*
	*@private
	*@param		{function|object}	step	Either a widget method or an object describing a widget state.
	*@returns	{function}	A closure returing an evaluatable promise for an asynchronous action.
	*/
	promiseStep: function promiseStep(step) {
		switch (typeOf(step)) {
			case 'function':
				return step;
			case 'object':
				return this.constructMatchAssertion(step);
			default:
				throw 'Unknown description step in feature "' + this.description + '": ' + step;
		}
	},

	/** Parses a widget state description and creates an assertive closure returning the promise for assertions results upon evaluation.
	*
	*@private
	*@param		{Object}	hooksVals	A hash whose keys match some widgets' attributes, pointing at values that are expected values for those attributes.
	*@returns	{function}	A parameter-less closure asserting the described state and returning a promise that will be either:
	*	- rejected if any assertion fails, passing a string parameter that describes the first failed match;
	*	- resolved if all assertions pass, with no parameter.
	*/
	constructMatchAssertion: function constructMatchAssertion(hooksVals) {
		return function() {
			var evaluator = promises.defer(),
				matchesLeft = Object.getLength(hooksVals);

			Object.each(hooksVals, function(expected, attribute) {
				eval(attribute).getText().then(function(actual) { //TODO: replace eval with an object walker
					if (expected != actual)
						evaluator.reject(attribute + ' was "' + actual + '" instead of "' + expected + '"');

					if (--matchesLeft == 0)
						evaluator.resolve();
				});
			});

			return evaluator.promise;
		}
	},

	/** Asynchronously evaluates the scenario given to this feature.
	*
	*@returns	{Promise}	A promise that will be either:
	*	- rejected if any assertion or action fails, passing an array of strings that describe reason(s) for failure(s) (one reason per item in the array);
	*	- resolved if all assertions pass, with no parameter.
	*/
	test: function evaluate() {
		var deferred = promises.defer(),
			stepIndex = 0;

		var evaluateNext,
			failureReasons = [];

		var handleFailure = function handleFailure(message) {
			failureReasons.push(message);
			evaluateNext();
		}

		evaluateNext = (function(value) {
			if (stepIndex == this.steps.length) {
				if (failureReasons.length == 0)
					return deferred.resolve();
				else
					return deferred.reject(failureReasons);
			}

			try {
				promises.when(this.steps[stepIndex](),
							  evaluateNext,
							  handleFailure);
			} catch (error) {
				handleFailure(error);
			}

			stepIndex++;
		}).bind(this);

		evaluateNext();

		return deferred.promise;
	}
});

module.exports = Feature;	// CommonJS export
<|endoftext|>


<commit_before><commit_msg>grunt file: gave isSplit and usedIn default states<commit_after><|endoftext|>


<commit_before>const smash = require('../../../../../smash');
const errorUtil = smash.errorUtil();
const { isObject, typeError, validateSiblings, validateChild, getLatestFromNames, saveCurrentValue } = require("../../util/ruleUtil");
const Queue = require("../../util/queue");
const { BODY, PARAMETERS, PROPERTIES, OPTIONAL, OBJECT, CLEAN, ERRORS } = require("../../constant");
const { extend } = require("../../../js/extend");

const depth = 1;
const config = {
	none: {
		siblings: [
			{ name: PARAMETERS },
		],
		children: [
			{ name: PROPERTIES, mandatory: true },
			{ name: OPTIONAL },
			{ name: CLEAN },
		],
	},
};

module.exports = {
	name: BODY,
	priority: 50,
	validate,
	execute,
	config,
};

function defaultProperties({ current, parents, rule }) {
	if (current.value.clean === undefined) {
		current.value.clean = true;
		saveCurrentValue({ current, parents, initialData: rule });
	}
}

function execute({ rule, data }) {
	return new Promise((resolve, reject) => {
		const { current, parents, processor } = rule;
		if (data.current.value) {
			const queue = new Queue();
			extend(current.value).forEach((value, name) => {
				const action = processor.getModuleByName(name);
				queue.add(action, {
					rule: {
						...rule,
						current: { name, value },
						parents: [...parents, current],
					},
					data,
				});
			});
			queue.start().then(resolve).catch(reject);
		} else {
			reject(errorUtil.badRequestError("Invalid body", { type: ERRORS.TYPE, reason: ERRORS.REASON_TYPE, name: data.current.name, expected: OBJECT, given: data.current.value }));
		}
	});
}

function validate({ current, parents, rule, processor, ruleConfig }) {
	defaultProperties({ current, parents, rule, processor, ruleConfig });
	const { siblings, children } = getLatestFromNames(config, parents, depth, BODY);
	validateSiblings({ siblings, current, parents, ruleConfig });
	if (isObject(current)) {
		extend(current.value).forEach((value, name) => {
			const child = { name, value };
			validateChild({ child, children, parents, current, ruleConfig });
			const newParents = [...parents, current];
			const newCurrent = { name, value };
			const action = processor.getModuleByName(name);
			action.validate({ current: newCurrent, parents: newParents, rule, processor, ruleConfig });
		});
		return true;
	}
	throw typeError({ current, ruleConfig, expected: OBJECT });
}
<commit_msg>Improve nothing given<commit_after>const smash = require('../../../../../smash');
const errorUtil = smash.errorUtil();
const { isObject, typeError, validateSiblings, validateChild, getLatestFromNames, saveCurrentValue } = require("../../util/ruleUtil");
const Queue = require("../../util/queue");
const { BODY, PARAMETERS, PROPERTIES, OPTIONAL, OBJECT, CLEAN, ERRORS } = require("../../constant");
const { extend } = require("../../../js/extend");

const depth = 1;
const config = {
	none: {
		siblings: [
			{ name: PARAMETERS },
		],
		children: [
			{ name: PROPERTIES, mandatory: true },
			{ name: OPTIONAL },
			{ name: CLEAN },
		],
	},
};

module.exports = {
	name: BODY,
	priority: 50,
	validate,
	execute,
	config,
};

function defaultProperties({ current, parents, rule }) {
	if (current.value.clean === undefined) {
		current.value.clean = true;
		saveCurrentValue({ current, parents, initialData: rule });
	}
}

function execute({ rule, data }) {
	return new Promise((resolve, reject) => {
		const { current, parents, processor } = rule;
		if (data.current.value) {
			const queue = new Queue();
			extend(current.value).forEach((value, name) => {
				const action = processor.getModuleByName(name);
				queue.add(action, {
					rule: {
						...rule,
						current: { name, value },
						parents: [...parents, current],
					},
					data,
				});
			});
			queue.start().then(resolve).catch(reject);
		} else {
			const given = data.current.value === undefined ? "undefined" : "null";
			reject(errorUtil.badRequestError("Invalid body", { type: ERRORS.TYPE, reason: ERRORS.REASON_TYPE, name: data.current.name, expected: OBJECT, given }));
		}
	});
}

function validate({ current, parents, rule, processor, ruleConfig }) {
	defaultProperties({ current, parents, rule, processor, ruleConfig });
	const { siblings, children } = getLatestFromNames(config, parents, depth, BODY);
	validateSiblings({ siblings, current, parents, ruleConfig });
	if (isObject(current)) {
		extend(current.value).forEach((value, name) => {
			const child = { name, value };
			validateChild({ child, children, parents, current, ruleConfig });
			const newParents = [...parents, current];
			const newCurrent = { name, value };
			const action = processor.getModuleByName(name);
			action.validate({ current: newCurrent, parents: newParents, rule, processor, ruleConfig });
		});
		return true;
	}
	throw typeError({ current, ruleConfig, expected: OBJECT });
}
<|endoftext|>


<commit_before>'use strict';

var CoreObject = require('core-object');
var fs = require('fs-extra');
var RSVP = require('rsvp');
var path = require('path');
var extend = require('extend');
var debug = require('debug')('ember-try:dependency-manager-adapter:npm');
var rimraf = RSVP.denodeify(require('rimraf'));

module.exports = CoreObject.extend({
  init: function() {
    this._super.apply(this, arguments);
    this.run = this.run || require('../utils/run');
  },
  useYarnCommand: false,
  yarnLock: 'yarn.lock',
  configKey: 'npm',
  packageJSON: 'package.json',
  packageJSONBackupFileName: 'package.json.ember-try',
  nodeModules: 'node_modules',
  nodeModulesBackupLocation: '.node_modules.ember-try',
  setup: function({ ui }) {
    this._runYarnCheck(ui);
    return this._backupOriginalDependencies();
  },
  changeToDependencySet: function(depSet) {
    var adapter = this;
    depSet = depSet[adapter.configKey];

    debug('Changing to dependency set: %s', JSON.stringify(depSet));

    if (!depSet) { return RSVP.resolve([]); }
    var backupPackageJSON = path.join(adapter.cwd, adapter.packageJSONBackupFileName);
    var packageJSONFile = path.join(adapter.cwd, adapter.packageJSON);
    var packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON));
    var newPackageJSON = adapter._packageJSONForDependencySet(packageJSON, depSet);

    debug('Write package.json with: \n', JSON.stringify(newPackageJSON));

    fs.writeFileSync(packageJSONFile, JSON.stringify(newPackageJSON, null, 2));
    return adapter._install().then(function() {
      var deps = extend({}, depSet.dependencies || {}, depSet.devDependencies || {});
      var currentDeps = Object.keys(deps).map(function(dep) {
        return {
          name: dep,
          versionExpected: deps[dep],
          versionSeen: adapter._findCurrentVersionOf(dep),
          packageManager: adapter.useYarnCommand ? 'yarn' : 'npm'
        };
      });

      debug('Switched to dependencies: \n', currentDeps);

      return RSVP.Promise.resolve(currentDeps);
    });
  },
  cleanup: function() {
    var adapter = this;

    return this._restoreOriginalDependencies().then(function() {
      debug('Remove backup package.json and node_modules');

      var cleanupTasks = [rimraf(path.join(adapter.cwd, adapter.packageJSONBackupFileName)),
        rimraf(path.join(adapter.cwd, adapter.nodeModulesBackupLocation))];

      return RSVP.all(cleanupTasks);
    }).catch(function(e) {
      console.log('Error cleaning up npm scenario:', e);
    });
  },
  _runYarnCheck: function(ui) {
    if (!this.useYarnCommand) {
      try {
        if (fs.statSync(path.join(this.cwd, this.yarnLock)).isFile()) {
          ui.writeLine('Detected a yarn.lock file, add useYarn: true to your configuration if you want to use Yarn to install npm dependencies.');
        }
      } catch (e) {
        // If no yarn.lock is found, no need to warn.
      }
    }
  },
  _findCurrentVersionOf: function(packageName) {
    var filename = path.join(this.cwd, this.nodeModules, packageName, this.packageJSON);
    if (fs.existsSync(filename)) {
      return JSON.parse(fs.readFileSync(filename)).version;
    } else {
      return null;
    }
  },
  _install: function() {
    var adapter = this;
    var mgrOptions = this.managerOptions || [];

    debug('Run npm install with options %s', mgrOptions);

    var cmd = this.useYarnCommand ? 'yarn' : 'npm';
    if (this.useYarnCommand) {
      if (mgrOptions.indexOf('--no-lockfile') === -1) {
        mgrOptions = mgrOptions.concat(['--no-lockfile']);
      }
      // npm warns on incompatible engines
      // yarn errors, not a good experience
      if (mgrOptions.indexOf('--ignore-engines') === -1) {
        mgrOptions = mgrOptions.concat(['--ignore-engines']);
      }
    }

    return this.run(cmd, [].concat(['install'], mgrOptions), { cwd: this.cwd }).then(function() {
      if (!adapter.useYarnCommand) {
        debug('Run npm prune');
        return adapter.run(adapter.configKey, [].concat(['prune'], mgrOptions), { cwd: adapter.cwd });
      }
    });
  },
  _packageJSONForDependencySet: function(packageJSON, depSet) {

    this._overridePackageJSONDependencies(packageJSON, depSet, 'dependencies');
    this._overridePackageJSONDependencies(packageJSON, depSet, 'devDependencies');
    this._overridePackageJSONDependencies(packageJSON, depSet, 'peerDependencies');

    return packageJSON;
  },
  _overridePackageJSONDependencies: function(packageJSON, depSet, kindOfDependency) {
    if (!depSet[kindOfDependency]) { return; }
    var pkgs = Object.keys(depSet[kindOfDependency]);

    pkgs.forEach(function(pkg) {
      if (!packageJSON[kindOfDependency]) {
        packageJSON[kindOfDependency] = {};
      }

      var version = depSet[kindOfDependency][pkg];
      if (version === null) {
        delete packageJSON[kindOfDependency][pkg];
      } else {
        packageJSON[kindOfDependency][pkg] = version;
      }
    });
  },
  _restoreOriginalDependencies: function() {
    var copy = RSVP.denodeify(fs.copy);

    debug('Restoring original package.json and node_modules');

    var restoreTasks = [
      copy(path.join(this.cwd, this.packageJSONBackupFileName),
           path.join(this.cwd, this.packageJSON)),
      copy(path.join(this.cwd, this.nodeModulesBackupLocation),
           path.join(this.cwd, this.nodeModules), { clobber: true })
    ];

    return RSVP.all(restoreTasks);
  },
  _backupOriginalDependencies: function() {
    var copy = RSVP.denodeify(fs.copy);

    debug('Backing up package.json and node_modules');

    var backupTasks = [
      copy(path.join(this.cwd, this.packageJSON),
           path.join(this.cwd, this.packageJSONBackupFileName)),
      copy(path.join(this.cwd, this.nodeModules),
           path.join(this.cwd, this.nodeModulesBackupLocation), { clobber: true })];

    return RSVP.all(backupTasks);
  }
});
<commit_msg>Change Yarn warning to be in yellow<commit_after>'use strict';

var CoreObject = require('core-object');
var fs = require('fs-extra');
var RSVP = require('rsvp');
var path = require('path');
var extend = require('extend');
var debug = require('debug')('ember-try:dependency-manager-adapter:npm');
var rimraf = RSVP.denodeify(require('rimraf'));
var chalk = require('chalk');

module.exports = CoreObject.extend({
  init: function() {
    this._super.apply(this, arguments);
    this.run = this.run || require('../utils/run');
  },
  useYarnCommand: false,
  yarnLock: 'yarn.lock',
  configKey: 'npm',
  packageJSON: 'package.json',
  packageJSONBackupFileName: 'package.json.ember-try',
  nodeModules: 'node_modules',
  nodeModulesBackupLocation: '.node_modules.ember-try',
  setup: function({ ui }) {
    this._runYarnCheck(ui);
    return this._backupOriginalDependencies();
  },
  changeToDependencySet: function(depSet) {
    var adapter = this;
    depSet = depSet[adapter.configKey];

    debug('Changing to dependency set: %s', JSON.stringify(depSet));

    if (!depSet) { return RSVP.resolve([]); }
    var backupPackageJSON = path.join(adapter.cwd, adapter.packageJSONBackupFileName);
    var packageJSONFile = path.join(adapter.cwd, adapter.packageJSON);
    var packageJSON = JSON.parse(fs.readFileSync(backupPackageJSON));
    var newPackageJSON = adapter._packageJSONForDependencySet(packageJSON, depSet);

    debug('Write package.json with: \n', JSON.stringify(newPackageJSON));

    fs.writeFileSync(packageJSONFile, JSON.stringify(newPackageJSON, null, 2));
    return adapter._install().then(function() {
      var deps = extend({}, depSet.dependencies || {}, depSet.devDependencies || {});
      var currentDeps = Object.keys(deps).map(function(dep) {
        return {
          name: dep,
          versionExpected: deps[dep],
          versionSeen: adapter._findCurrentVersionOf(dep),
          packageManager: adapter.useYarnCommand ? 'yarn' : 'npm'
        };
      });

      debug('Switched to dependencies: \n', currentDeps);

      return RSVP.Promise.resolve(currentDeps);
    });
  },
  cleanup: function() {
    var adapter = this;

    return this._restoreOriginalDependencies().then(function() {
      debug('Remove backup package.json and node_modules');

      var cleanupTasks = [rimraf(path.join(adapter.cwd, adapter.packageJSONBackupFileName)),
        rimraf(path.join(adapter.cwd, adapter.nodeModulesBackupLocation))];

      return RSVP.all(cleanupTasks);
    }).catch(function(e) {
      console.log('Error cleaning up npm scenario:', e);
    });
  },
  _runYarnCheck: function(ui) {
    if (!this.useYarnCommand) {
      try {
        if (fs.statSync(path.join(this.cwd, this.yarnLock)).isFile()) {
          ui.writeLine(chalk.yellow('Detected a yarn.lock file, add useYarn: true to your configuration if you want to use Yarn to install npm dependencies.'));
        }
      } catch (e) {
        // If no yarn.lock is found, no need to warn.
      }
    }
  },
  _findCurrentVersionOf: function(packageName) {
    var filename = path.join(this.cwd, this.nodeModules, packageName, this.packageJSON);
    if (fs.existsSync(filename)) {
      return JSON.parse(fs.readFileSync(filename)).version;
    } else {
      return null;
    }
  },
  _install: function() {
    var adapter = this;
    var mgrOptions = this.managerOptions || [];

    debug('Run npm install with options %s', mgrOptions);

    var cmd = this.useYarnCommand ? 'yarn' : 'npm';
    if (this.useYarnCommand) {
      if (mgrOptions.indexOf('--no-lockfile') === -1) {
        mgrOptions = mgrOptions.concat(['--no-lockfile']);
      }
      // npm warns on incompatible engines
      // yarn errors, not a good experience
      if (mgrOptions.indexOf('--ignore-engines') === -1) {
        mgrOptions = mgrOptions.concat(['--ignore-engines']);
      }
    }

    return this.run(cmd, [].concat(['install'], mgrOptions), { cwd: this.cwd }).then(function() {
      if (!adapter.useYarnCommand) {
        debug('Run npm prune');
        return adapter.run(adapter.configKey, [].concat(['prune'], mgrOptions), { cwd: adapter.cwd });
      }
    });
  },
  _packageJSONForDependencySet: function(packageJSON, depSet) {

    this._overridePackageJSONDependencies(packageJSON, depSet, 'dependencies');
    this._overridePackageJSONDependencies(packageJSON, depSet, 'devDependencies');
    this._overridePackageJSONDependencies(packageJSON, depSet, 'peerDependencies');

    return packageJSON;
  },
  _overridePackageJSONDependencies: function(packageJSON, depSet, kindOfDependency) {
    if (!depSet[kindOfDependency]) { return; }
    var pkgs = Object.keys(depSet[kindOfDependency]);

    pkgs.forEach(function(pkg) {
      if (!packageJSON[kindOfDependency]) {
        packageJSON[kindOfDependency] = {};
      }

      var version = depSet[kindOfDependency][pkg];
      if (version === null) {
        delete packageJSON[kindOfDependency][pkg];
      } else {
        packageJSON[kindOfDependency][pkg] = version;
      }
    });
  },
  _restoreOriginalDependencies: function() {
    var copy = RSVP.denodeify(fs.copy);

    debug('Restoring original package.json and node_modules');

    var restoreTasks = [
      copy(path.join(this.cwd, this.packageJSONBackupFileName),
           path.join(this.cwd, this.packageJSON)),
      copy(path.join(this.cwd, this.nodeModulesBackupLocation),
           path.join(this.cwd, this.nodeModules), { clobber: true })
    ];

    return RSVP.all(restoreTasks);
  },
  _backupOriginalDependencies: function() {
    var copy = RSVP.denodeify(fs.copy);

    debug('Backing up package.json and node_modules');

    var backupTasks = [
      copy(path.join(this.cwd, this.packageJSON),
           path.join(this.cwd, this.packageJSONBackupFileName)),
      copy(path.join(this.cwd, this.nodeModules),
           path.join(this.cwd, this.nodeModulesBackupLocation), { clobber: true })];

    return RSVP.all(backupTasks);
  }
});
<|endoftext|>


<commit_before>import Victor from 'victor'
import Shape, { shapeOptions } from './Shape'

const options = {
  ...shapeOptions,
  ...{
    circleLobes: {
      title: 'Number of lobes',
      min: 1
    }
  }
}

export default class Circle extends Shape {
  constructor() {
    super('Circle')
  }

  getInitialState() {
    return {
      ...super.getInitialState(),
      ...{
        type: 'circle',
        circleLobes: 1
      }
    }
  }

  getVertices(state) {
    let points = []
    for (let i=0; i<=128; i++) {
      let angle = Math.PI * 2.0 / 128.0 * i
      points.push(new Victor(Math.cos(angle), Math.sin(state.shape.circleLobes * angle)/state.shape.circleLobes))
    }
    return points
  }

  getOptions() {
    return options
  }
}
<commit_msg>support counterclockwise circle rendering<commit_after>import Victor from 'victor'
import Shape, { shapeOptions } from './Shape'

const options = {
  ...shapeOptions,
  ...{
    circleLobes: {
      title: 'Number of lobes',
      min: 1
    },
    circleDirection: {
      title: 'Direction',
      type: 'dropdown',
      choices: ['clockwise', 'counterclockwise']
    }
  }
}

export default class Circle extends Shape {
  constructor() {
    super('Circle')
  }

  getInitialState() {
    return {
      ...super.getInitialState(),
      ...{
        type: 'circle',
        circleLobes: 1,
        circleDirection: 'clockwise'
      },
    }
  }

  getVertices(state) {
    let points = []

    if (state.shape.circleDirection === 'counterclockwise') {
      for (let i=128; i>=0; i--) {
        let angle = Math.PI * 2.0 / 128.0 * i
        points.push(new Victor(Math.cos(angle), Math.sin(state.shape.circleLobes * angle)/state.shape.circleLobes))
      }
    } else {
      for (let i=0; i<=128; i++) {
        let angle = Math.PI * 2.0 / 128.0 * i
        points.push(new Victor(Math.cos(angle), Math.sin(state.shape.circleLobes * angle)/state.shape.circleLobes))
      }
    }

    return points
  }

  getOptions() {
    return options
  }
}
<|endoftext|>


<commit_before>var utils = require('../lib/utils.js');

var enemies = {}

module.exports = {
    info: {
        name: 'Ψ',
        style: 3
    },
    ai: (playerState, enemiesStates, gameEnvironment) => { /* Siegfried */
        var directionToAmmo;

        if (utils.canKill(playerState, enemiesStates) && playerState.ammo) {
            return 'shoot';
        }

        if (gameEnvironment.ammoPosition.length) {

            var closestAmmo = findClosestAmmo(gameEnvironment.ammoPosition);

            // if (playerState.ammo < 1) {
                directionToAmmo = utils.fastGetDirection(playerState.position, closestAmmo);
                if (directionToAmmo !== playerState.direction) return directionToAmmo;
                return 'move';
            // } else {
            //     directionToAmmo = utils.fastGetDirection(playerState.position, closestAmmo);
            //     if (closestAmmo[0] === playerState.position[0] || closestAmmo[1] === playerState.position[1]) {
            //         if (directionToAmmo !== playerState.direction) return directionToAmmo;
            //     }
            // }
            //
            // if (playerState.ammo > 2) {
            //
            // }
        }

        return utils.safeRandomMove();

        function findClosestAmmo(ammos) {
            var min = 0;
            ammos.forEach((a, i) => {
                if (utils.getDistance(playerState.position, a) < utils.getDistance(playerState.position, ammos[min])) {
                    min = i;
                }
            });
            return ammos[min];
        }
    }
};
<commit_msg>next iteration<commit_after>var utils = require('../lib/utils.js');

var enemies = {};

module.exports = {
    info: {
        name: 'Ψ',
        style: 3
    },
    ai: (playerState, enemiesStates, gameEnvironment) => { /* Siegfried */
        var directionToAmmo;

        if (utils.canKill(playerState, enemiesStates) && playerState.ammo) {
            return 'shoot';
        }

        if (gameEnvironment.ammoPosition.length) {

            var closestAmmo = findClosestAmmo(gameEnvironment.ammoPosition);

            if (playerState.ammo === 0) {
                directionToAmmo = utils.fastGetDirection(playerState.position, closestAmmo);
                if (directionToAmmo !== playerState.direction) return directionToAmmo;
                return 'move';
            }
            //     directionToAmmo = utils.fastGetDirection(playerState.position, closestAmmo);
            //     if (closestAmmo[0] === playerState.position[0] || closestAmmo[1] === playerState.position[1]) {
            //         if (directionToAmmo !== playerState.direction) return directionToAmmo;
            //     }
            // }
            //
            var dir = utils.fastGetDirection(playerState.position, fx());
            if (dir !== playerState.direction) return dir;
            return 'move';

        }

        return utils.safeRandomMove();

        function findClosestAmmo(ammos) {
            var min = 0;
            ammos.forEach((a, i) => {
                if (utils.getDistance(playerState.position, a) < utils.getDistance(playerState.position, ammos[min])) {
                    min = i;
                }
            });
            return ammos[min];
        }

        function fx() {
            var min = 0;
            enemiesStates.forEach((e, i) => {
                if (utils.getDistance(playerState.position, e.position) < utils.getDistance(playerState.position, enemiesStates[min].position)) {
                    min = i;
                }
            });
            return enemiesStates[min].position;
        }
    }
};
<|endoftext|>