<commit_before>'use strict';

angular.module('service-testing-tool').controller('TeststepsController', ['$scope', 'Teststeps',
  '$location', '$stateParams', '$state', '$http', '_', '$timeout', 'PageNavigation',
  function($scope, Teststeps, $location, $stateParams, $state, $http, _, $timeout, PageNavigation) {
    var timer;
    $scope.teststep = {};
    //  use object instead of primitives, so that child scope can update the values
    $scope.savingStatus = {
      saveSuccessful: null,
      savingErrorMessage: null
    };
    $scope.tempData = {};
    $scope.showAssertionsArea = false;

    $scope.update = function(isValid) {
      if (isValid) {
        $scope.teststep.$update(function(response) {
          $scope.savingStatus.saveSuccessful = true;
          $scope.teststep = response;
        }, function(error) {
          $scope.savingStatus.savingErrorMessage = error.data.message;
          $scope.savingStatus.saveSuccessful = false;
        });
      } else {
        $scope.savingStatus.submitted = true;
      }
    };

    $scope.autoSave = function(isValid) {
      if (timer) $timeout.cancel(timer);
      timer = $timeout(function() {
        $scope.update(isValid);
      }, 2000);
    };

    $scope.loadWsdl = function() {
      $http
        .get('api/wsdls/anywsdl/operations', {
          params: {
            wsdlUrl: $scope.teststep.wsdlUrl
          }
        })
        .success(function(data, status) {
          $scope.teststep.wsdlBindings = data;
          $scope.teststep.wsdlBinding = $scope.teststep.wsdlBindings[0];
          $scope.teststep.wsdlOperations = $scope.teststep.wsdlBindings[0].operations;
          $scope.teststep.wsdlOperation = $scope.teststep.wsdlOperations[0];
        })
        .error(function(data, status) {
          alert('Error');
        });
    };

    $scope.refreshOperations = function() {
      $scope.wsdlOperations = _.findWhere($scope.wsdlBindings, { name: $scope.wsdlBinding.name }).operations;
      $scope.wsdlOperation = $scope.wsdlOperations[0];
    };

    $scope.create = function(isValid) {
      if (isValid) {
        var teststep = new Teststeps({
          testcaseId: $stateParams.testcaseId,
          name: this.teststep.name,
          description: this.teststep.description,
          wsdlUrl: this.teststep.wsdlUrl,
          wsdlBindingName: this.teststep.wsdlBinding.name,
          wsdlOperationName: this.teststep.wsdlOperation
        });
        teststep.$save(function(response) {
          $state.go('teststep_edit', {testcaseId: response.testcaseId, teststepId: response.id});
        }, function(error) {
          alert('Error');
        });
      } else {
        $scope.submitted = true;
      }
    };

    $scope.goto = function(state, params, expect) {
      var context = {
        model: $scope.teststep,
        url: $location.path(),
        expect: expect
      };

      PageNavigation.contexts.push(context);

      $state.go(state, params);
    };

    $scope.findOne = function() {
      // entry returned from other pages
      var model = PageNavigation.returns.pop();
      if (model) {
        $scope.teststep = model;
      } else {
        if ($stateParams.teststepId) {
          // edit an existing entry
          Teststeps.get({
            testcaseId: $stateParams.testcaseId,
            teststepId: $stateParams.teststepId
          }, function (response) {
            $scope.teststep = response;
          });
        } else {
          // create a new enventry
          $scope.teststep.testcaseId = $stateParams.testcaseId;
        }
      }
    };

    $scope.invoke = function(teststep) {
       var url = 'api/testcases/' + $stateParams.testcaseId + '/teststeps/' + $stateParams.teststepId + '/invoke';
       $http
        .post(url, {
          soapAddress: $scope.teststep.soapAddress,
          request: $scope.teststep.request
        })
        .success(function(data, status) {
          $scope.tempData.response = data.response;
        })
        .error(function(data, status) {
          alert('Error');
        });
    };

    $scope.toggleAssertionsArea = function() {
      document.getElementById('request-response-textareas').style.height =
        (document.getElementById('request-response-textareas').offsetHeight +
        document.getElementById('assertionsArea').offsetHeight) + 'px';

      $scope.showAssertionsArea = !($scope.showAssertionsArea);
    };

    $scope.assertionsAreaVisibleCallback = function() {
      document.getElementById('request-response-textareas').style.height =
          (document.getElementById('request-response-textareas').offsetHeight -
          document.getElementById('assertionsArea').offsetHeight) + 'px';
    };
  }
]);
<commit_msg>change UI for creating teststep with new model<commit_after>'use strict';

angular.module('service-testing-tool').controller('TeststepsController', ['$scope', 'Teststeps',
  '$location', '$stateParams', '$state', '$http', '_', '$timeout', 'PageNavigation',
  function($scope, Teststeps, $location, $stateParams, $state, $http, _, $timeout, PageNavigation) {
    var timer;
    $scope.teststep = {};
    //  use object instead of primitives, so that child scope can update the values
    $scope.savingStatus = {
      saveSuccessful: null,
      savingErrorMessage: null
    };
    $scope.tempData = {};
    $scope.showAssertionsArea = false;

    $scope.update = function(isValid) {
      if (isValid) {
        $scope.teststep.$update(function(response) {
          $scope.savingStatus.saveSuccessful = true;
          $scope.teststep = response;
        }, function(error) {
          $scope.savingStatus.savingErrorMessage = error.data.message;
          $scope.savingStatus.saveSuccessful = false;
        });
      } else {
        $scope.savingStatus.submitted = true;
      }
    };

    $scope.autoSave = function(isValid) {
      if (timer) $timeout.cancel(timer);
      timer = $timeout(function() {
        $scope.update(isValid);
      }, 2000);
    };

    $scope.loadWsdl = function() {
      $http
        .get('api/wsdls/anywsdl/operations', {
          params: {
            wsdlUrl: $scope.teststep.wsdlUrl
          }
        })
        .success(function(data, status) {
          $scope.teststep.wsdlBindings = data;
          $scope.teststep.wsdlBinding = $scope.teststep.wsdlBindings[0];
          $scope.teststep.wsdlOperations = $scope.teststep.wsdlBindings[0].operations;
          $scope.teststep.wsdlOperation = $scope.teststep.wsdlOperations[0];
        })
        .error(function(data, status) {
          alert('Error');
        });
    };

    $scope.refreshOperations = function() {
      $scope.wsdlOperations = _.findWhere($scope.wsdlBindings, { name: $scope.wsdlBinding.name }).operations;
      $scope.wsdlOperation = $scope.wsdlOperations[0];
    };

    $scope.create = function(isValid) {
      if (isValid) {
        var teststep = new Teststeps({
          testcaseId: $stateParams.testcaseId,
          name: this.teststep.name,
          description: this.teststep.description,
          type: 'SOAP',
          properties: {
            wsdlUrl: this.teststep.wsdlUrl,
            wsdlBindingName: this.teststep.wsdlBinding.name,
            wsdlOperationName: this.teststep.wsdlOperation
          }
        });
        teststep.$save(function(response) {
          $state.go('teststep_edit', {testcaseId: response.testcaseId, teststepId: response.id});
        }, function(error) {
          alert('Error');
        });
      } else {
        $scope.submitted = true;
      }
    };

    $scope.goto = function(state, params, expect) {
      var context = {
        model: $scope.teststep,
        url: $location.path(),
        expect: expect
      };

      PageNavigation.contexts.push(context);

      $state.go(state, params);
    };

    $scope.findOne = function() {
      // entry returned from other pages
      var model = PageNavigation.returns.pop();
      if (model) {
        $scope.teststep = model;
      } else {
        if ($stateParams.teststepId) {
          // edit an existing entry
          Teststeps.get({
            testcaseId: $stateParams.testcaseId,
            teststepId: $stateParams.teststepId
          }, function (response) {
            $scope.teststep = response;
          });
        } else {
          // create a new enventry
          $scope.teststep.testcaseId = $stateParams.testcaseId;
        }
      }
    };

    $scope.invoke = function(teststep) {
       var url = 'api/testcases/' + $stateParams.testcaseId + '/teststeps/' + $stateParams.teststepId + '/invoke';
       $http
        .post(url, {
          soapAddress: $scope.teststep.soapAddress,
          request: $scope.teststep.request
        })
        .success(function(data, status) {
          $scope.tempData.response = data.response;
        })
        .error(function(data, status) {
          alert('Error');
        });
    };

    $scope.toggleAssertionsArea = function() {
      document.getElementById('request-response-textareas').style.height =
        (document.getElementById('request-response-textareas').offsetHeight +
        document.getElementById('assertionsArea').offsetHeight) + 'px';

      $scope.showAssertionsArea = !($scope.showAssertionsArea);
    };

    $scope.assertionsAreaVisibleCallback = function() {
      document.getElementById('request-response-textareas').style.height =
          (document.getElementById('request-response-textareas').offsetHeight -
          document.getElementById('assertionsArea').offsetHeight) + 'px';
    };
  }
]);
<|endoftext|>


<commit_before>// This file is part of the Shapy project.
// Licensing information can be found in the LICENSE file.
// (C) 2015 The Shapy Team. All rights reserved.
goog.provide('shapy.editor.Viewport.Edit');

goog.require('shapy.editor.Viewport');

/**
 * Viewport for the 3D editor.
 *
 * @constructor
 * @extends {shapy.editor.Viewport}
 *
 * @param {!shapy.editor.Editor} editor Editor service.
 * @param {string}               name   Name of the viewport.
 */
shapy.editor.Viewport.Edit = function(editor, name) {
  shapy.editor.Viewport.call(
      this,
      editor,
      name,
      shapy.editor.Viewport.Type.EDIT
  );

  /**
   * The camera attached to the viewport.
   * @public {!shapy.editor.Camera}
   * @const
   */
  this.camera = new shapy.editor.Camera.Persp();

  /**
   * Control cube attached to the viewport.
   * @public {!shapy.editor.CamCube}
   * @const
   */
  this.camCube = new shapy.editor.CamCube(this, this.camera);

  /**
   * Flag indicating if the camera is rotating.
   * @private {boolean}
   */
   this.isRotating_ = false;

  /**
   * Flag indicating if the camera is panning.
   * @private {boolean}
   */
   this.isPanning_ = false;

  /**
   * Active rig.
   * @public {shapy.editor.Rig}
   */
  this.rig = null;
};
goog.inherits(shapy.editor.Viewport.Edit, shapy.editor.Viewport);

/**
 * Returns the ray that corresponds to the current mouse position.
 *
 * @param {number} x Mouse X position.
 * @param {number} y Mouse Y position.
 *
 * @return {!goog.vec.Ray.Type} Ray passing through point.
 */
shapy.editor.Viewport.Edit.prototype.raycast = function(x, y) {
  return this.camera.raycast(2 * x / this.rect.w - 1, 2 * y / this.rect.h - 1);
};

/**
 * Returns the frustum that corresponds to a group selection.
 *
 * @param {!goog.math.Rect} rect Selection rectangle.
 *
 * @return {!goog.vec.Ray.Type} Ray passing through point.
 */
shapy.editor.Viewport.Edit.prototype.groupcast = function(rect) {
  return this.camera.groupcast(
      2 * rect.left / this.rect.w - 1,
      2 * rect.top / this.rect.h - 1,
      2 * (rect.left + rect.width) / this.rect.w - 1,
      2 * (rect.top + rect.height) / this.rect.h - 1);
};

/**
 * Resizes the viewport, specifying a new position and size.
 *
 * @param {number} x
 * @param {number} y
 * @param {number} w
 * @param {number} h
 */
shapy.editor.Viewport.Edit.prototype.resize = function(x, y, w, h) {
  shapy.editor.Viewport.prototype.resize.call(this, x, y, w, h);
  this.camCube.resize(w, h);
  this.camera.resize(w, h);
};

/**
 * Handles a mouse motion event.
 *
 * @param {number} x Mouse X coordinate.
 * @param {number} y Mouse Y coordinate.
 * @param {number} button
 *
 * @return {!Array<!shapy.editor.Editable>}
 */
shapy.editor.Viewport.Edit.prototype.mouseMove = function(x, y, button) {
  shapy.editor.Viewport.prototype.mouseMove.call(this, x, y);
  var pick, hits = [], hit, ray, frustum, uv, object, texture;
  var hasGroup = this.group && this.group.width > 3 && this.group.height > 3;

  // Check if camcube requires the event.
  this.currMousePos.x = x;
  this.currMousePos.y = y;
  if (this.camCube.mouseMove(x, y)) {
    return [];
  }

  // Check if camera controls require the event.
  if (this.isRotating_) {
    this.rotate();
    return [];
  }
  if (this.isPanning_) {
    this.pan();
    return [];
  }

  // Check if the rig requires the event.
  ray = this.raycast(x, y);
  if (!hasGroup && this.rig && this.rig.mouseMove(ray)) {
    this.group = null;
    return [];
  }

  if (hasGroup) {
    frustum = this.groupcast(this.group);
    hits = this.editor.scene_.pickFrustum(frustum, this.editor.mode);
  } else if (ray) {
    hit = this.editor.scene_.pickRay(ray, this.editor.mode);
    hits = hit ? [hit] : [];
  }

  // Check if the object can be painted.
  if (this.editor.mode.paint && hit && hit.selected && button == 1) {
    this.editor.hover = [];
    if (!(texture = this.editor.textures_[hit.object.texture])) {
      return [];
    }

    // Paint the texture only if the user has the permission.
    if (texture.write) {
      uv = hit.pickUV(ray);

      // Paint the texture.
      this.paint_(texture, uv.u, uv.v);
    }

    return [];
  }
  return hits;
};

/**
 * Handles a mouse enter event.
 *
 * @param {number} x Mouse X coordinate.
 * @param {number} y Mouse Y coordinate.
 */
shapy.editor.Viewport.Edit.prototype.mouseEnter = function(x, y) {
  shapy.editor.Viewport.prototype.mouseEnter.call(this, x, y);
  if (this.rig) {
    this.rig.mouseEnter(this.raycast(x, y));
  }
};

/**
 * Handles a mouse leave event.
 */
shapy.editor.Viewport.Edit.prototype.mouseLeave = function() {
  shapy.editor.Viewport.prototype.mouseEnter.call(this);
  if (!this.isRotating_ && !this.isPanning_ && this.rig) {
    this.rig.mouseLeave();
  }
  this.isRotating_ = false;
  this.isPanning_ = false;
};

/**
 * Handles a mouse press event.
 *
 * @param {number} x      Mouse X coordinate.
 * @param {number} y      Mouse Y coordinate.
 * @param {number} button Mouse button that was clicked.
 *
 * @return {goog.vec.Ray}
 */
shapy.editor.Viewport.Edit.prototype.mouseDown = function(x, y, button) {
  shapy.editor.Viewport.prototype.mouseDown.call(this, x, y, button);

  var ray = this.raycast(x, y);

  if (this.camCube.mouseDown(x, y)) {
    return null;
  }

  switch (button) {
    case 1: {
      if (this.rig && this.rig.mouseDown(ray)) {
        return null;
      }
      break;
    }
    case 2: this.isPanning_ = true; return null;
    case 3: this.isRotating_ = true; return null;
  }

  return this.raycast(x, y);
};

/**
 * Handles a mouse release event.
 *
 * @param {number} x Mouse X coordinate.
 * @param {number} y Mouse Y coordinate.
 *
 * @return {goog.vec.Ray}
 */
shapy.editor.Viewport.Edit.prototype.mouseUp = function(x, y) {
  shapy.editor.Viewport.prototype.mouseUp.call(this, x, y);

  var ray = this.raycast(x, y);

  if (this.camCube.mouseUp(x, y)) {
    return null;
  }

  if (!this.isRotating_ && !this.isPanning_ && this.rig) {
    if (this.rig.mouseUp(ray)) {
      return null;
    }
  }
  this.isRotating_ = false;
  this.isPanning_ = false;
  return ray;
};

/**
 * Handles a mouse wheel event.
 *
 * @param {number} delta Mouse wheel delta value.
 */
shapy.editor.Viewport.Edit.prototype.mouseWheel = function(delta) {
  var diff = goog.vec.Vec3.createFloat32();
  goog.vec.Vec3.subtract(this.camera.eye, this.camera.center, diff);
  var zoomLevel = goog.vec.Vec3.magnitude(diff);

  // Determine if zooming in or out and update accordingly.
  if (delta < 0) {
    zoomLevel /= shapy.editor.Camera.ZOOM_SPEED;
  } else {
    zoomLevel *= shapy.editor.Camera.ZOOM_SPEED;
  }

  // Clip to MIN_ZOOM.
  if (zoomLevel < shapy.editor.Camera.MIN_ZOOM) {
    zoomLevel = shapy.editor.Camera.MIN_ZOOM;
  }

  // Clip to MAX_ZOOM.
  if (zoomLevel > shapy.editor.Camera.MAX_ZOOM) {
    zoomLevel = shapy.editor.Camera.MAX_ZOOM;
  }

  // Update the position of the camera.
  goog.vec.Vec3.normalize(diff, diff);
  goog.vec.Vec3.scale(diff, zoomLevel, diff);
  goog.vec.Vec3.add(this.camera.center, diff, this.camera.eye);
};

/**
 * Recomputes the positions & sizes of all viewport.Edits.
 *
 * @param {number} kc Keycode
 */
shapy.editor.Viewport.Edit.prototype.keyDown = function(kc) {
};

/**
 * Computes a normalised vector from the center of the virtual ball to
 * the point on the virtual ball surface that is aligned with the point (x, y)
 * on the screen.
 *
 * @private
 *
 * @param {!goog.math.Vec2} pos Position of the mouse.
 *
 * @return {!goog.vec.Vec3.Type} Arcball vector.
 */
shapy.editor.Viewport.Edit.prototype.getArcballVector_ = function(pos) {
  // Convert pos to camera coordinates [-1, 1].
  var p = goog.vec.Vec3.createFloat32FromValues(
      2 * pos.x / this.rect.w - 1.0,
      2 * pos.y / this.rect.h - 1.0,
      0);

  // Compute the square of the l2 norm of p.
  var l2Squared = p[0] * p[0] + p[1] * p[1];

  // Compute the z coordinate.
  if (l2Squared < 1.0) {
    p[2] = Math.sqrt(1 - l2Squared);
  } else {
    goog.vec.Vec3.normalize(p, p);
  }

  return p;
};

/**
 * Computes the angle and axis of the camera rotation.
 */
shapy.editor.Viewport.Edit.prototype.rotate = function() {
  if (this.currMousePos.equals(this.lastMousePos)) {
    return;
  }

  // Compute the points at the ball surface that match the click.
  var va = this.getArcballVector_(this.lastMousePos);
  var vb = this.getArcballVector_(this.currMousePos);
  this.lastMousePos.x = this.currMousePos.x;
  this.lastMousePos.y = this.currMousePos.y;

  // Compute the angle.
  var angle = Math.acos(Math.min(1.0, goog.vec.Vec3.dot(va, vb)));

  // Compute the axis.
  var axis = goog.vec.Vec3.createFloat32();
  goog.vec.Vec3.cross(va, vb, axis);
  goog.vec.Mat4.multVec3NoTranslate(this.camera.invView, axis, axis);

  // Compute the rotation quaternion from the angle and the axis.
  var rotationQuater = goog.vec.Quaternion.createFloat32();
  goog.vec.Quaternion.fromAngleAxis(-angle, axis, rotationQuater);
  goog.vec.Quaternion.normalize(rotationQuater, rotationQuater);

  // Calculate the view vector.
  var viewVector = goog.vec.Vec3.createFloat32();
  goog.vec.Vec3.subtract(this.camera.eye, this.camera.center, viewVector);

  // Compute the quternion from the view vector.
  var viewQuater = goog.vec.Quaternion.createFloat32FromValues(
      viewVector[0],
      viewVector[1],
      viewVector[2],
      0);

  // Compute the new quaternion representing the rotation.
  var temp = goog.vec.Quaternion.createFloat32();
  goog.vec.Quaternion.conjugate(rotationQuater, temp);
  goog.vec.Quaternion.concat(rotationQuater, viewQuater, viewQuater);
  goog.vec.Quaternion.concat(viewQuater, temp, viewQuater);

  // Compute the updated view vector.
  goog.vec.Vec3.setFromValues(
      viewVector,
      viewQuater[0],
      viewQuater[1],
      viewQuater[2]);

  // Compute the new up vector.
  //goog.vec.Vec3.cross(viewVector, this.camera.up, this.camera.up);
  //goog.vec.Vec3.cross(this.camera.up, viewVector, this.camera.up);
  //goog.vec.Vec3.normalize(this.camera.up, this.camera.up);

  // Update the eye.
  goog.vec.Vec3.add(this.camera.center, viewVector, this.camera.eye);
};

/**
 * Performs the paning.
 */
shapy.editor.Viewport.Edit.prototype.pan = function() {
  var left = goog.vec.Vec3.createFloat32();
  var up = goog.vec.Vec3.createFloat32();
  var v = goog.vec.Vec3.createFloat32();

  // Get the normal to the plane along which to rotate.
  goog.vec.Vec3.subtract(this.camera.eye, this.camera.center, v);
  goog.vec.Vec3.cross(v, this.camera.up, left);
  goog.vec.Vec3.normalize(left, left);
  goog.vec.Vec3.cross(left, v, up);
  goog.vec.Vec3.normalize(up, up);

  // Get movement.
  var dx =
      (this.currMousePos.x - this.lastMousePos.x) / this.rect.w *
      shapy.editor.Camera.PAN_SPEED;
  var dy =
      (this.currMousePos.y - this.lastMousePos.y) / this.rect.h *
      shapy.editor.Camera.PAN_SPEED;

  // Move along x.
  goog.vec.Vec3.scale(left, dx, left);
  goog.vec.Vec3.add(this.camera.center, left, this.camera.center);
  goog.vec.Vec3.add(this.camera.eye, left, this.camera.eye);

  // Move along y.
  goog.vec.Vec3.scale(up, dy, v);
  goog.vec.Vec3.negate(v, v);
  goog.vec.Vec3.add(this.camera.center, v, this.camera.center);
  goog.vec.Vec3.add(this.camera.eye, v, this.camera.eye);

  this.lastMousePos.x = this.currMousePos.x;
  this.lastMousePos.y = this.currMousePos.y;
};

/**
 * Destroys the viewport.
 */
shapy.editor.Viewport.Edit.prototype.destroy = function() {
  shapy.editor.Viewport.prototype.destroy.call(this);
  this.camCube.destroy();
};
<commit_msg>Check if hit object is selected, rather than hit.<commit_after>// This file is part of the Shapy project.
// Licensing information can be found in the LICENSE file.
// (C) 2015 The Shapy Team. All rights reserved.
goog.provide('shapy.editor.Viewport.Edit');

goog.require('shapy.editor.Viewport');

/**
 * Viewport for the 3D editor.
 *
 * @constructor
 * @extends {shapy.editor.Viewport}
 *
 * @param {!shapy.editor.Editor} editor Editor service.
 * @param {string}               name   Name of the viewport.
 */
shapy.editor.Viewport.Edit = function(editor, name) {
  shapy.editor.Viewport.call(
      this,
      editor,
      name,
      shapy.editor.Viewport.Type.EDIT
  );

  /**
   * The camera attached to the viewport.
   * @public {!shapy.editor.Camera}
   * @const
   */
  this.camera = new shapy.editor.Camera.Persp();

  /**
   * Control cube attached to the viewport.
   * @public {!shapy.editor.CamCube}
   * @const
   */
  this.camCube = new shapy.editor.CamCube(this, this.camera);

  /**
   * Flag indicating if the camera is rotating.
   * @private {boolean}
   */
   this.isRotating_ = false;

  /**
   * Flag indicating if the camera is panning.
   * @private {boolean}
   */
   this.isPanning_ = false;

  /**
   * Active rig.
   * @public {shapy.editor.Rig}
   */
  this.rig = null;
};
goog.inherits(shapy.editor.Viewport.Edit, shapy.editor.Viewport);

/**
 * Returns the ray that corresponds to the current mouse position.
 *
 * @param {number} x Mouse X position.
 * @param {number} y Mouse Y position.
 *
 * @return {!goog.vec.Ray.Type} Ray passing through point.
 */
shapy.editor.Viewport.Edit.prototype.raycast = function(x, y) {
  return this.camera.raycast(2 * x / this.rect.w - 1, 2 * y / this.rect.h - 1);
};

/**
 * Returns the frustum that corresponds to a group selection.
 *
 * @param {!goog.math.Rect} rect Selection rectangle.
 *
 * @return {!goog.vec.Ray.Type} Ray passing through point.
 */
shapy.editor.Viewport.Edit.prototype.groupcast = function(rect) {
  return this.camera.groupcast(
      2 * rect.left / this.rect.w - 1,
      2 * rect.top / this.rect.h - 1,
      2 * (rect.left + rect.width) / this.rect.w - 1,
      2 * (rect.top + rect.height) / this.rect.h - 1);
};

/**
 * Resizes the viewport, specifying a new position and size.
 *
 * @param {number} x
 * @param {number} y
 * @param {number} w
 * @param {number} h
 */
shapy.editor.Viewport.Edit.prototype.resize = function(x, y, w, h) {
  shapy.editor.Viewport.prototype.resize.call(this, x, y, w, h);
  this.camCube.resize(w, h);
  this.camera.resize(w, h);
};

/**
 * Handles a mouse motion event.
 *
 * @param {number} x Mouse X coordinate.
 * @param {number} y Mouse Y coordinate.
 * @param {number} button
 *
 * @return {!Array<!shapy.editor.Editable>}
 */
shapy.editor.Viewport.Edit.prototype.mouseMove = function(x, y, button) {
  shapy.editor.Viewport.prototype.mouseMove.call(this, x, y);
  var pick, hits = [], hit, ray, frustum, uv, object, texture;
  var hasGroup = this.group && this.group.width > 3 && this.group.height > 3;

  // Check if camcube requires the event.
  this.currMousePos.x = x;
  this.currMousePos.y = y;
  if (this.camCube.mouseMove(x, y)) {
    return [];
  }

  // Check if camera controls require the event.
  if (this.isRotating_) {
    this.rotate();
    return [];
  }
  if (this.isPanning_) {
    this.pan();
    return [];
  }

  // Check if the rig requires the event.
  ray = this.raycast(x, y);
  if (!hasGroup && this.rig && this.rig.mouseMove(ray)) {
    this.group = null;
    return [];
  }

  if (hasGroup) {
    frustum = this.groupcast(this.group);
    hits = this.editor.scene_.pickFrustum(frustum, this.editor.mode);
  } else if (ray) {
    hit = this.editor.scene_.pickRay(ray, this.editor.mode);
    hits = hit ? [hit] : [];
  }

  // Check if the object can be painted.
  if (this.editor.mode.paint && hit && hit.object.selected && button == 1) {
    this.editor.hover = [];
    if (!(texture = this.editor.textures_[hit.object.texture])) {
      return [];
    }

    // Paint the texture only if the user has the permission.
    if (texture.write) {
      uv = hit.pickUV(ray);

      // Paint the texture.
      this.paint_(texture, uv.u, uv.v);
    }

    return [];
  }
  return hits;
};

/**
 * Handles a mouse enter event.
 *
 * @param {number} x Mouse X coordinate.
 * @param {number} y Mouse Y coordinate.
 */
shapy.editor.Viewport.Edit.prototype.mouseEnter = function(x, y) {
  shapy.editor.Viewport.prototype.mouseEnter.call(this, x, y);
  if (this.rig) {
    this.rig.mouseEnter(this.raycast(x, y));
  }
};

/**
 * Handles a mouse leave event.
 */
shapy.editor.Viewport.Edit.prototype.mouseLeave = function() {
  shapy.editor.Viewport.prototype.mouseEnter.call(this);
  if (!this.isRotating_ && !this.isPanning_ && this.rig) {
    this.rig.mouseLeave();
  }
  this.isRotating_ = false;
  this.isPanning_ = false;
};

/**
 * Handles a mouse press event.
 *
 * @param {number} x      Mouse X coordinate.
 * @param {number} y      Mouse Y coordinate.
 * @param {number} button Mouse button that was clicked.
 *
 * @return {goog.vec.Ray}
 */
shapy.editor.Viewport.Edit.prototype.mouseDown = function(x, y, button) {
  shapy.editor.Viewport.prototype.mouseDown.call(this, x, y, button);

  var ray = this.raycast(x, y);

  if (this.camCube.mouseDown(x, y)) {
    return null;
  }

  switch (button) {
    case 1: {
      if (this.rig && this.rig.mouseDown(ray)) {
        return null;
      }
      break;
    }
    case 2: this.isPanning_ = true; return null;
    case 3: this.isRotating_ = true; return null;
  }

  return this.raycast(x, y);
};

/**
 * Handles a mouse release event.
 *
 * @param {number} x Mouse X coordinate.
 * @param {number} y Mouse Y coordinate.
 *
 * @return {goog.vec.Ray}
 */
shapy.editor.Viewport.Edit.prototype.mouseUp = function(x, y) {
  shapy.editor.Viewport.prototype.mouseUp.call(this, x, y);

  var ray = this.raycast(x, y);

  if (this.camCube.mouseUp(x, y)) {
    return null;
  }

  if (!this.isRotating_ && !this.isPanning_ && this.rig) {
    if (this.rig.mouseUp(ray)) {
      return null;
    }
  }
  this.isRotating_ = false;
  this.isPanning_ = false;
  return ray;
};

/**
 * Handles a mouse wheel event.
 *
 * @param {number} delta Mouse wheel delta value.
 */
shapy.editor.Viewport.Edit.prototype.mouseWheel = function(delta) {
  var diff = goog.vec.Vec3.createFloat32();
  goog.vec.Vec3.subtract(this.camera.eye, this.camera.center, diff);
  var zoomLevel = goog.vec.Vec3.magnitude(diff);

  // Determine if zooming in or out and update accordingly.
  if (delta < 0) {
    zoomLevel /= shapy.editor.Camera.ZOOM_SPEED;
  } else {
    zoomLevel *= shapy.editor.Camera.ZOOM_SPEED;
  }

  // Clip to MIN_ZOOM.
  if (zoomLevel < shapy.editor.Camera.MIN_ZOOM) {
    zoomLevel = shapy.editor.Camera.MIN_ZOOM;
  }

  // Clip to MAX_ZOOM.
  if (zoomLevel > shapy.editor.Camera.MAX_ZOOM) {
    zoomLevel = shapy.editor.Camera.MAX_ZOOM;
  }

  // Update the position of the camera.
  goog.vec.Vec3.normalize(diff, diff);
  goog.vec.Vec3.scale(diff, zoomLevel, diff);
  goog.vec.Vec3.add(this.camera.center, diff, this.camera.eye);
};

/**
 * Recomputes the positions & sizes of all viewport.Edits.
 *
 * @param {number} kc Keycode
 */
shapy.editor.Viewport.Edit.prototype.keyDown = function(kc) {
};

/**
 * Computes a normalised vector from the center of the virtual ball to
 * the point on the virtual ball surface that is aligned with the point (x, y)
 * on the screen.
 *
 * @private
 *
 * @param {!goog.math.Vec2} pos Position of the mouse.
 *
 * @return {!goog.vec.Vec3.Type} Arcball vector.
 */
shapy.editor.Viewport.Edit.prototype.getArcballVector_ = function(pos) {
  // Convert pos to camera coordinates [-1, 1].
  var p = goog.vec.Vec3.createFloat32FromValues(
      2 * pos.x / this.rect.w - 1.0,
      2 * pos.y / this.rect.h - 1.0,
      0);

  // Compute the square of the l2 norm of p.
  var l2Squared = p[0] * p[0] + p[1] * p[1];

  // Compute the z coordinate.
  if (l2Squared < 1.0) {
    p[2] = Math.sqrt(1 - l2Squared);
  } else {
    goog.vec.Vec3.normalize(p, p);
  }

  return p;
};

/**
 * Computes the angle and axis of the camera rotation.
 */
shapy.editor.Viewport.Edit.prototype.rotate = function() {
  if (this.currMousePos.equals(this.lastMousePos)) {
    return;
  }

  // Compute the points at the ball surface that match the click.
  var va = this.getArcballVector_(this.lastMousePos);
  var vb = this.getArcballVector_(this.currMousePos);
  this.lastMousePos.x = this.currMousePos.x;
  this.lastMousePos.y = this.currMousePos.y;

  // Compute the angle.
  var angle = Math.acos(Math.min(1.0, goog.vec.Vec3.dot(va, vb)));

  // Compute the axis.
  var axis = goog.vec.Vec3.createFloat32();
  goog.vec.Vec3.cross(va, vb, axis);
  goog.vec.Mat4.multVec3NoTranslate(this.camera.invView, axis, axis);

  // Compute the rotation quaternion from the angle and the axis.
  var rotationQuater = goog.vec.Quaternion.createFloat32();
  goog.vec.Quaternion.fromAngleAxis(-angle, axis, rotationQuater);
  goog.vec.Quaternion.normalize(rotationQuater, rotationQuater);

  // Calculate the view vector.
  var viewVector = goog.vec.Vec3.createFloat32();
  goog.vec.Vec3.subtract(this.camera.eye, this.camera.center, viewVector);

  // Compute the quternion from the view vector.
  var viewQuater = goog.vec.Quaternion.createFloat32FromValues(
      viewVector[0],
      viewVector[1],
      viewVector[2],
      0);

  // Compute the new quaternion representing the rotation.
  var temp = goog.vec.Quaternion.createFloat32();
  goog.vec.Quaternion.conjugate(rotationQuater, temp);
  goog.vec.Quaternion.concat(rotationQuater, viewQuater, viewQuater);
  goog.vec.Quaternion.concat(viewQuater, temp, viewQuater);

  // Compute the updated view vector.
  goog.vec.Vec3.setFromValues(
      viewVector,
      viewQuater[0],
      viewQuater[1],
      viewQuater[2]);

  // Compute the new up vector.
  //goog.vec.Vec3.cross(viewVector, this.camera.up, this.camera.up);
  //goog.vec.Vec3.cross(this.camera.up, viewVector, this.camera.up);
  //goog.vec.Vec3.normalize(this.camera.up, this.camera.up);

  // Update the eye.
  goog.vec.Vec3.add(this.camera.center, viewVector, this.camera.eye);
};

/**
 * Performs the paning.
 */
shapy.editor.Viewport.Edit.prototype.pan = function() {
  var left = goog.vec.Vec3.createFloat32();
  var up = goog.vec.Vec3.createFloat32();
  var v = goog.vec.Vec3.createFloat32();

  // Get the normal to the plane along which to rotate.
  goog.vec.Vec3.subtract(this.camera.eye, this.camera.center, v);
  goog.vec.Vec3.cross(v, this.camera.up, left);
  goog.vec.Vec3.normalize(left, left);
  goog.vec.Vec3.cross(left, v, up);
  goog.vec.Vec3.normalize(up, up);

  // Get movement.
  var dx =
      (this.currMousePos.x - this.lastMousePos.x) / this.rect.w *
      shapy.editor.Camera.PAN_SPEED;
  var dy =
      (this.currMousePos.y - this.lastMousePos.y) / this.rect.h *
      shapy.editor.Camera.PAN_SPEED;

  // Move along x.
  goog.vec.Vec3.scale(left, dx, left);
  goog.vec.Vec3.add(this.camera.center, left, this.camera.center);
  goog.vec.Vec3.add(this.camera.eye, left, this.camera.eye);

  // Move along y.
  goog.vec.Vec3.scale(up, dy, v);
  goog.vec.Vec3.negate(v, v);
  goog.vec.Vec3.add(this.camera.center, v, this.camera.center);
  goog.vec.Vec3.add(this.camera.eye, v, this.camera.eye);

  this.lastMousePos.x = this.currMousePos.x;
  this.lastMousePos.y = this.currMousePos.y;
};

/**
 * Destroys the viewport.
 */
shapy.editor.Viewport.Edit.prototype.destroy = function() {
  shapy.editor.Viewport.prototype.destroy.call(this);
  this.camCube.destroy();
};
<|endoftext|>


<commit_before>var amaticBold, amaticRegular, jinky, trashHand;
var fr = 30;

// Preload all fonts.
function preload() {
  amaticBold = loadFont("assets/amatic/Amatic-Bold.ttf");
  amaticRegular = loadFont("assets/amatic/AmaticSC-Regular.ttf");
  jinky = loadFont("assets/Jinky/JINKY.ttf");
  trashHand = loadFont("assets/TrashHand/TrashHand.ttf");
}

function setup() {
  createCanvas(720, 400);
  frameRate(fr);
  stroke(255);
  noFill();
}

/*
Define parts of figure
*/

var head = {
  x1: 290,
  y1: 80,
  x2: 350,
  y2: 80,
  x3: 350,
  y3: 130,
  x4: 300,
  y4: 140,
  draw: function() {
    noFill();
    quad(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3, this.x4, this.y4);
  }
};

var eyes = {
  x: (head.x1 + head.x2)/2,
  y: head.y1 + 20,
  radiusX: (head.x2-head.x1)/6,
  radiusY: (head.y3-head.y4)*2,
  draw: function() {
    ellipse(this.x-10, this.y, this.radiusX, this.radiusY);
    ellipse(this.x+10, this.y, this.radiusX, this.radiusY);
  }
};

var pupils = {
  x: eyes.x,
  y: eyes.y+3,
  radiusX: eyes.radiusX/3,
  radiusY: eyes.radiusY/3,
  draw: function() {
    fill(255);
    ellipse(this.x-10, this.y, this.radiusX, this.radiusY);
    ellipse(this.x+10, this.y, this.radiusX, this.radiusY);
  }
};

var hairs = {
  x1: (head.x1 + head.x2)/2,
  y1: head.y1,
  x2: head.x1,
  y2: head.y1 - 20,
  x3: head.x2,
  y3: head.y1 - 25,
  x4: head.x1,
  y4: head.y1 - 20,
  draw: function() {
    noFill();
    for (var i = 0; i < 200; i += 20) {
      bezier(this.x1, this.y1, this.x2 + (i/2), this.y2 - (i/2), this.x3, this.y3, this.x4 + (mouseX/2), this.y4 - (mouseY/10));
    }
  }
};

var torso = {
  x1: (head.x3 + head.x4)/2,
  y1: head.y4,
  x2: head.x3,
  y2: head.y4 + 90,
  x3: head.x4,
  y3: head.y4 + 80,
  draw: function() {
    noFill();
    triangle(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3);
  }
};

var legs = {
  x1: (torso.x2 + torso.x3)/2,
  y1: torso.y3,
  x2: torso.x2,
  y2: torso.y2 + 40,
  x3: (torso.x2 + torso.x3)/2 - 10,
  y3: torso.y3,
  x4: torso.x3,
  y4: torso.y2 + 40,
  draw: function() {
    noFill();
    line(this.x1, this.y1, this.x2, this.y2);
    line(this.x3, this.y3, this.x4, this.y4);
  }
};

var arms = {
  x1: torso.x1 + 10,
  y1: torso.y1 + 40,
  x2: torso.x1 + 40,
  y2: torso.y1 + 30,
  x3: torso.x1 - 10,
  y3: torso.y1 + 40,
  x4: torso.x1 - 40,
  y4: torso.y1 + 30,
  draw: function() {
    noFill();
    line(this.x1, this.y1, this.x2, this.y2);
    line(this.x3, this.y3, this.x4, this.y4);
  }
};

var hands = {
  x1: arms.x2,
  y1: arms.y2,
  x2: arms.x4,
  y2: arms.y4,
  draw: function() {
    quad(this.x1, this.y1, this.x1 + 5, this.y1, this.x1 + 5, this.y1 + 5, this.x1, this.y1 + 5);
    quad(this.x2, this.y2, this.x2 - 5, this.y2, this.x2 - 5, this.y2 + 5, this.x2, this.y2 + 5);
  }
};

/* Main draw function */
function draw() {
  background(0);

  // Draw each part
  eyes.draw();
  pupils.draw();
  head.draw();
  hairs.draw();
  torso.draw();
  arms.draw();
  legs.draw();
  hands.draw();

  // Render text
  s = "Imagine you're reading a really really cool and funny caption.";
  fill(255);
  textFont(amaticRegular);
  textSize(30);
  textLeading(25);
  text(s, 20, 10, 200, 300); // Text wraps within text box
}

<commit_msg>added feet<commit_after>var amaticBold, amaticRegular, jinky, trashHand;
var fr = 30;

// Preload all fonts.
function preload() {
  amaticBold = loadFont("assets/amatic/Amatic-Bold.ttf");
  amaticRegular = loadFont("assets/amatic/AmaticSC-Regular.ttf");
  jinky = loadFont("assets/Jinky/JINKY.ttf");
  trashHand = loadFont("assets/TrashHand/TrashHand.ttf");
}

function setup() {
  createCanvas(720, 400);
  frameRate(fr);
  stroke(255);
  noFill();
}

/*
Define parts of figure
*/

var head = {
  x1: 290,
  y1: 80,
  x2: 350,
  y2: 80,
  x3: 350,
  y3: 130,
  x4: 300,
  y4: 140,
  draw: function() {
    noFill();
    quad(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3, this.x4, this.y4);
  }
};

var eyes = {
  x: (head.x1 + head.x2)/2,
  y: head.y1 + 20,
  radiusX: (head.x2-head.x1)/6,
  radiusY: (head.y3-head.y4)*2,
  draw: function() {
    ellipse(this.x-10, this.y, this.radiusX, this.radiusY);
    ellipse(this.x+10, this.y, this.radiusX, this.radiusY);
  }
};

var pupils = {
  x: eyes.x,
  y: eyes.y+3,
  radiusX: eyes.radiusX/3,
  radiusY: eyes.radiusY/3,
  draw: function() {
    fill(255);
    ellipse(this.x-10, this.y, this.radiusX, this.radiusY);
    ellipse(this.x+10, this.y, this.radiusX, this.radiusY);
  }
};

var hairs = {
  x1: (head.x1 + head.x2)/2,
  y1: head.y1,
  x2: head.x1,
  y2: head.y1 - 20,
  x3: head.x2,
  y3: head.y1 - 25,
  x4: head.x1,
  y4: head.y1 - 20,
  draw: function() {
    noFill();
    for (var i = 0; i < 200; i += 20) {
      bezier(this.x1, this.y1, this.x2 + (i/2), this.y2 - (i/2), this.x3, this.y3, this.x4 + (mouseX/2), this.y4 - (mouseY/10));
    }
  }
};

var torso = {
  x1: (head.x3 + head.x4)/2,
  y1: head.y4,
  x2: head.x3,
  y2: head.y4 + 90,
  x3: head.x4,
  y3: head.y4 + 80,
  draw: function() {
    noFill();
    triangle(this.x1, this.y1, this.x2, this.y2, this.x3, this.y3);
  }
};

var legs = {
  x1: (torso.x2 + torso.x3)/2,
  y1: torso.y3,
  x2: torso.x2,
  y2: torso.y2 + 40,
  x3: (torso.x2 + torso.x3)/2 - 10,
  y3: torso.y3,
  x4: torso.x3,
  y4: torso.y2 + 40,
  draw: function() {
    noFill();
    line(this.x1, this.y1, this.x2, this.y2);
    line(this.x3, this.y3, this.x4, this.y4);
  }
};

var feet = {
  x1: legs.x2,
  y1: legs.y2,
  x2: legs.x4,
  y2: legs.y4,
  draw: function() {
    noFill();
    quad(this.x1, this.y1, this.x1 + 5, this.y1, this.x1 + 5, this.y1 + 5, this.x1, this.y1 + 5);
    quad(this.x2, this.y2, this.x2 - 5, this.y2, this.x2 - 5, this.y2 + 5, this.x2, this.y2 + 5);
  }
};

var arms = {
  x1: torso.x1 + 10,
  y1: torso.y1 + 40,
  x2: torso.x1 + 40,
  y2: torso.y1 + 30,
  x3: torso.x1 - 10,
  y3: torso.y1 + 40,
  x4: torso.x1 - 40,
  y4: torso.y1 + 30,
  draw: function() {
    noFill();
    line(this.x1, this.y1, this.x2, this.y2);
    line(this.x3, this.y3, this.x4, this.y4);
  }
};

var hands = {
  x1: arms.x2,
  y1: arms.y2,
  x2: arms.x4,
  y2: arms.y4,
  draw: function() {
    quad(this.x1, this.y1, this.x1 + 5, this.y1, this.x1 + 5, this.y1 + 5, this.x1, this.y1 + 5);
    quad(this.x2, this.y2, this.x2 - 5, this.y2, this.x2 - 5, this.y2 + 5, this.x2, this.y2 + 5);
  }
};

/* Main draw function */
function draw() {
  background(0);

  // Draw each part
  eyes.draw();
  pupils.draw();
  head.draw();
  hairs.draw();
  torso.draw();
  arms.draw();
  legs.draw();
  hands.draw();
  feet.draw();

  // Render text
  s = "Imagine you're reading a really really cool and funny caption.";
  fill(255);
  textFont(trashHand);
  textSize(30);
  textLeading(25);
  text(s, 20, 10, 200, 300); // Text wraps within text box
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2013 André Bargull
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */

(function Assert(global) {
"use strict";

const Object = global.Object,
      Function = global.Function,
      SyntaxError = global.SyntaxError;

const Object_is = Object.is,
      Object_prototype_toString = Object.prototype.toString;

const $CallFunction = Function.prototype.call.bind(Function.prototype.call);

function safeToString(o) {
  try {
    return "" + o;
  } catch (e) {
    try {
      return $CallFunction(Object_prototype_toString, o);
    } catch (e) {
      return "???";
    }
  }
}

function fmt(callSite, ...substitutions) {
  let cooked = Object(callSite);
  let literalSegments = cooked.length >>> 0;
  if (literalSegments === 0) {
    return "";
  }
  let r = "";
  for (let nextIndex = 0;; ++nextIndex) {
    r += cooked[nextIndex];
    if (nextIndex + 1 === literalSegments) {
      return r;
    }
    r += safeToString(substitutions[nextIndex]);
  }
}

class AssertionError extends Error {
  get name() {
    return "AssertionError";
  }
}

function fail(format = "", ...args) {
  let message = typeof format === "string" ? format : fmt(format, ...args);
  throw new AssertionError(message);
}

function assertSame(expected, actual) {
  if (!Object_is(expected, actual)) {
    fail `Expected «${expected}», but got «${actual}»`;
  }
}

function assertThrows(f, expected) {
  try {
    f();
  } catch (e) {
    if (e instanceof expected) {
      return;
    }
    fail `Expected error «${expected.name}», but got «${e}»`;
  }
  fail `Expected error «${expected.name}»`;
}

function assertTrue(actual) {
  return assertSame(true, actual);
}

function assertFalse(actual) {
  return assertSame(false, actual);
}

function assertSyntaxError(code) {
  return assertThrows(() => Function(code), SyntaxError);
}

// export...
Object.defineProperty(global, "Assert", {value: {
  fail, assertSame, assertThrows, assertTrue, assertFalse, assertSyntaxError
}});

})(this);
<commit_msg>Add more features to assert.js script<commit_after>/*
 * Copyright (c) 2012-2013 André Bargull
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */

(function Assert(global) {
"use strict";

const {
  Object, Function, Proxy, String, SyntaxError
} = global;

const {
  getOwnPropertyDescriptor: Object_getOwnPropertyDescriptor,
  getPrototypeOf: Object_getPrototypeOf,
  is: Object_is,
} = Object;

const {
  toString: Object_prototype_toString,
} = Object.prototype;

const $CallFunction = Function.prototype.call.bind(Function.prototype.call);

const ThrowTypeError = Object.getOwnPropertyDescriptor(function(){"use strict"}, "caller").get;

function IsCallable(o) {
  try{
    (new Proxy(o, {apply: () => {}}))();
    return true;
  } catch(e) {
    return false;
  }
}

function IsConstructor(o) {
  try{
    new (new Proxy(o, {construct: () => ({})}));
    return true;
  } catch(e) {
    return false;
  }
}

function PropertyKeyToString(pk) {
  switch(typeof pk) {
    case 'symbol':
      return String(Object(pk));
    case 'string':
    default:
      return String(pk);
  }
}

function safeToString(o) {
  try {
    return String(o);
  } catch (e) {
    try {
      return $CallFunction(Object_prototype_toString, o);
    } catch (e) {
      return "???";
    }
  }
}

function fmt(callSite, ...substitutions) {
  let cooked = Object(callSite);
  let literalSegments = cooked.length >>> 0;
  if (literalSegments === 0) {
    return "";
  }
  let r = "";
  for (let nextIndex = 0;; ++nextIndex) {
    r += cooked[nextIndex];
    if (nextIndex + 1 === literalSegments) {
      return r;
    }
    r += safeToString(substitutions[nextIndex]);
  }
}

function label(s) {
  return s !== "" ? s + ": " : "";
}

class AssertionError extends Error {
  get name() {
    return "AssertionError";
  }
}

function fail(format = "", ...args) {
  let message = typeof format === "string" ? format : fmt(format, ...args);
  throw new AssertionError(message);
}

function assertSame(expected, actual, message = "") {
  if (!Object_is(expected, actual)) {
    fail `${label(message)}Expected «${expected}», but got «${actual}»`;
  }
}

function assertNotSame(expected, actual, message = "") {
  if (Object_is(expected, actual)) {
    fail `${label(message)}Expected not «${expected}»`;
  }
}

function assertThrows(f, expected, message = "") {
  try {
    f();
  } catch (e) {
    if (e instanceof expected) {
      return;
    }
    fail `${label(message)}Expected error «${expected.name}», but got «${e}»`;
  }
  fail `${label(message)}Expected error «${expected.name}»`;
}

function assertSyntaxError(code, message = "") {
  return assertThrows(() => Function(code), SyntaxError, message);
}

function assertTrue(actual, message = "") {
  return assertSame(true, actual, message);
}

function assertFalse(actual, message = "") {
  return assertSame(false, actual, message);
}

function assertUndefined(actual, message = "") {
  return assertSame(void 0, actual, message);
}

function assertNotUndefined(actual, message = "") {
  return assertNotSame(void 0, actual, message);
}

function assertNull(actual, message = "") {
  return assertSame(null, actual, message);
}

function assertNotNull(actual, message = "") {
  return assertNotSame(null, actual, message);
}

function assertInstanceOf(constructor, value, message = `Is an instance of ${constructor.name}`) {
  return assertTrue(value instanceof constructor, message);
}

function assertCallable(o, message = "Is a [[Callable]] object") {
  return assertTrue(IsCallable(o), message);
}

function assertNotCallable(o, message = "Is not a [[Callable]] object") {
  return assertFalse(IsCallable(o), message);
}

function assertConstructor(o, message = "Is a [[Constructor]] object") {
  return assertTrue(IsConstructor(o), message);
}

function assertNotConstructor(o, message = "Is not a [[Constructor]] object") {
  return assertFalse(IsConstructor(o), message);
}

function assertDataProperty(object, propertyKey, {value, writable, enumerable, configurable}) {
  let desc = Object_getOwnPropertyDescriptor(object, propertyKey);
  assertNotUndefined(desc, `${PropertyKeyToString(propertyKey)} not found`);
  assertTrue('value' in desc);
  assertSame(value, desc.value, `${PropertyKeyToString(propertyKey)}.[[Value]]`);
  assertSame(writable, desc.writable, `${PropertyKeyToString(propertyKey)}.[[Writable]]`);
  assertSame(enumerable, desc.enumerable, `${PropertyKeyToString(propertyKey)}.[[Enumerable]]`);
  assertSame(configurable, desc.configurable, `${PropertyKeyToString(propertyKey)}.[[Configurable]]`);
}

function assertAccessorProperty(object, propertyKey, {get, set, enumerable, configurable}) {
  let desc = Object_getOwnPropertyDescriptor(object, propertyKey);
  assertNotUndefined(desc, `${PropertyKeyToString(propertyKey)} not found`);
  assertTrue('get' in desc);
  assertSame(get, desc.get, `${PropertyKeyToString(propertyKey)}.[[Get]]`);
  assertSame(set, desc.set, `${PropertyKeyToString(propertyKey)}.[[Set]]`);
  assertSame(enumerable, desc.enumerable, `${PropertyKeyToString(propertyKey)}.[[Enumerable]]`);
  assertSame(configurable, desc.configurable, `${PropertyKeyToString(propertyKey)}.[[Configurable]]`);
}

function assertBuiltinFunction(fun, name, arity) {
  assertSame("function", typeof fun);
  assertCallable(fun);
  assertNotConstructor(fun);
  assertSame(Function.prototype, Object_getPrototypeOf(fun), `${name}.[[Prototype]]`);
  assertDataProperty(fun, "length", {value: arity, writable: false, enumerable: false, configurable: true});
  assertDataProperty(fun, "name", {value: name, writable: false, enumerable: false, configurable: false});
  assertAccessorProperty(fun, "arguments", {get: ThrowTypeError, set: ThrowTypeError, enumerable: false, configurable: false});
  assertAccessorProperty(fun, "caller", {get: ThrowTypeError, set: ThrowTypeError, enumerable: false, configurable: false});
}

function assertBuiltinConstructor(fun, name, arity) {
  assertSame("function", typeof fun);
  assertCallable(fun);
  assertConstructor(fun);
  assertSame(Function.prototype, Object_getPrototypeOf(fun), `${name}.[[Prototype]]`);
  assertDataProperty(fun, "length", {value: arity, writable: false, enumerable: false, configurable: true});
  assertDataProperty(fun, "name", {value: name, writable: false, enumerable: false, configurable: false});
  assertAccessorProperty(fun, "arguments", {get: ThrowTypeError, set: ThrowTypeError, enumerable: false, configurable: false});
  assertAccessorProperty(fun, "caller", {get: ThrowTypeError, set: ThrowTypeError, enumerable: false, configurable: false});
}

function assertBuiltinPrototype(o, proto = Object.prototype) {
  if (o === Function.prototype) {
    assertSame("function", typeof o);
    assertCallable(o);
  } else {
    assertSame("object", typeof o);
    assertNotCallable(o);
  }
  assertNotConstructor(o);
  assertSame(proto, Object_getPrototypeOf(o), `[[Prototype]]`);
}

// export...
Object.defineProperty(global, "Assert", {value: {
  AssertionError, fail,
  assertSame, assertNotSame,
  assertThrows, assertSyntaxError,
  assertTrue, assertFalse,
  assertUndefined, assertNotUndefined,
  assertNull, assertNotNull,
  assertInstanceOf,
  assertCallable, assertNotCallable,
  assertConstructor, assertNotConstructor,
  assertDataProperty, assertAccessorProperty,
  assertBuiltinFunction, assertBuiltinConstructor, assertBuiltinPrototype,
}});

})(this);
<|endoftext|>


<commit_before>/*
 * Swipe 2.0
 *
 * Brad Birdsall, Prime
 * Copyright 2012, Licensed GPL & MIT
 *
*/

window.Swipe = function(element, options) {

  var _this = this;

  // return immediately if element doesn't exist
  if (!element) return;

  // reference dom elements
  this.container = element;
  this.element = this.container.children[0];

  // simple feature detection
  this.browser = {
    touch: (function() {
      return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
    })(),
    transitions: (function() {
      var temp = document.createElement('swipe'),
          props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
      for ( var i in props ) {
        if (temp.style[ props[i] ] !== undefined) return true;
      }
      return false;
    })()
  };

  // retreive options
  options = options || {};
  this.index = options.startSlide || 0;
  this.speed = options.speed || 300;
  this.callback = options.callback || function() {};
  this.transitionEnd = options.transitionEnd || function() {};
  this.delay = options.auto || 0;
  this.cont = (options.continuous != undefined) ? !!options.continuous : true;
  this.disableScroll = !!options.disableScroll;

  // verify index is a number not string
  this.index = parseInt(this.index,10);

  // trigger slider initialization
  this.setup();

  // begin auto slideshow
  this.begin();

  // add event listeners
  if (this.element.addEventListener) {
    if (!!this.browser.touch) {
      this.element.addEventListener('touchstart', this, false);
      this.element.addEventListener('touchmove', this, false);
      this.element.addEventListener('touchend', this, false);
    }
    if (!!this.browser.transitions) {
      this.element.addEventListener('webkitTransitionEnd', this, false);
      this.element.addEventListener('msTransitionEnd', this, false);
      this.element.addEventListener('oTransitionEnd', this, false);
      this.element.addEventListener('transitionend', this, false);
    }
    window.addEventListener('resize', this, false);
  }

  // to play nice with old IE
  else {
    window.onresize = function () {
      _this.setup();
    };
  }

};

Swipe.prototype = {

  setup: function() {

    // get and measure amt of slides
    this.slides = this.element.children;
    this.length = this.slides.length;
    this.cache = new Array(this.length);

    // return immediately if their are less than two slides
    if (this.length < 2) return;

    // determine width of each slide
    this.width = this.container.getBoundingClientRect().width || this.container.offsetWidth;

    // return immediately if measurement fails
    if (!this.width) return;

    // store array of slides before, current, and after
    var refArray = [[],[],[]];

    this.element.style.width = (this.slides.length * this.width) + 'px';

    // stack elements
    for (var index = this.length - 1; index > -1; index--) {

      var elem = this.slides[index];

      elem.style.width = this.width + 'px';
      elem.setAttribute('data-index', index);

      if (this.browser.transitions) {
        elem.style.left = (index * -this.width) + 'px';
      }

      // add this index to the reference array    0:before 1:equal 2:after
      refArray[this.index > index ? 0 : (this.index < index ? 2 : 1)].push(index);

    }

    if (this.browser.transitions) {
      // stack left, current, and right slides
      this._slide(refArray[0],-this.width,0,1);
      this._slide(refArray[1],0,0,1);
      this._slide(refArray[2],this.width,0,1);
    }

    this.container.style.visibility = 'visible';

  },

  kill: function() {

    // cancel slideshow
    this.delay = 0;
    clearTimeout(this.interval);

    // clear all translations
    var slideArray = [];
    for (var i = this.slides.length - 1; i >= 0; i--) {
      this.slides[i].style.width = '';
      slideArray.push(i);
    }
    this._slide(slideArray,0,0,1);

    var elem = this.element;
    elem.className = elem.className.replace('swipe-active','');

    // remove event listeners
    if (this.element.removeEventListener) {
      if (!!this.browser.touch) {
        this.element.removeEventListener('touchstart', this, false);
        this.element.removeEventListener('touchmove', this, false);
        this.element.removeEventListener('touchend', this, false);
      }
      if (!!this.browser.transitions) {
        this.element.removeEventListener('webkitTransitionEnd', this, false);
        this.element.removeEventListener('msTransitionEnd', this, false);
        this.element.removeEventListener('oTransitionEnd', this, false);
        this.element.removeEventListener('transitionend', this, false);
      }
      window.removeEventListener('resize', this.resize, false);
    }

    // kill old IE! you can quote me on that ;)
    else {
      window.onresize = null;
    }

  },

  getPos: function() {

    // return current index position
    return this.index;

  },

  prev: function(delay) {

    // cancel slideshow
    this.delay = delay || 0;
    clearTimeout(this.interval);

    // if not at first slide
    if (this.index) this.slide(this.index-1, this.speed);
    else if (this.cont) this.slide(this.length-1, this.speed);

  },

  next: function(delay) {

    // cancel slideshow
    this.delay = delay || 0;
    clearTimeout(this.interval);

    if (this.index < this.length - 1) this.slide(this.index+1, this.speed); // if not last slide
    else if (this.cont) this.slide(0, this.speed); //if last slide return to start

  },

  begin: function() {

    var _this = this;

    this.interval = (this.delay)
      ? setTimeout(function() {
        _this.next(_this.delay);
      }, this.delay)
      : 0;

  },

  handleEvent: function(e) {
    switch (e.type) {
      case 'touchstart': this.onTouchStart(e); break;
      case 'touchmove': this.onTouchMove(e); break;
      case 'touchend': this.onTouchEnd(e); break;
      case 'webkitTransitionEnd':
      case 'msTransitionEnd':
      case 'oTransitionEnd':
      case 'transitionend': this.onTransitionEnd(e); break;
      case 'resize': this.setup(); break;
    }
  },

  onTouchStart: function(e) {

    var _this = this;

    _this.start = {

      // get touch coordinates for delta calculations in onTouchMove
      pageX: e.touches[0].pageX,
      pageY: e.touches[0].pageY,

      // set initial timestamp of touch sequence
      time: Number( new Date() )

    };

    // used for testing first onTouchMove event
    _this.isScrolling = undefined;

    // reset deltaX
    _this.deltaX = 0;

  },

  onTouchMove: function(e) {

    var _this = this;

    // ensure swiping with one touch and not pinching
    if(e.touches.length > 1 || e.scale && e.scale !== 1) return;

    _this.deltaX = e.touches[0].pageX - _this.start.pageX;

    // determine if scrolling test has run - one time test
    if ( typeof _this.isScrolling == 'undefined') {
      _this.isScrolling = !!( _this.isScrolling || Math.abs(_this.deltaX) < Math.abs(e.touches[0].pageY - _this.start.pageY) );
    }

    // if user is not trying to scroll vertically
    if (!_this.isScrolling) {

      // prevent native scrolling
      e.preventDefault();

      // cancel slideshow
      _this.delay = 0;
      clearTimeout(_this.interval);

      // increase resistance if first or last slide
      _this.deltaX =
        _this.deltaX /
          ( (!_this.index && _this.deltaX > 0               // if first slide and sliding left
            || _this.index == _this.length - 1              // or if last slide and sliding right
            && _this.deltaX < 0                            // and if sliding at all
          ) ?
          ( Math.abs(_this.deltaX) / _this.width + 1 )      // determine resistance level
          : 1 );                                          // no resistance if false

      // translate immediately 1:1
      _this._slide([_this.index-1,_this.index,_this.index+1],_this.deltaX,0,-1);

    } else if (_this.disableScroll) {

      // prevent native scrolling
      e.preventDefault();

    }

  },

  onTouchEnd: function(e) {

    var _this = this;

    // determine if slide attempt triggers next/prev slide
    var isValidSlide =
          Number(new Date()) - _this.start.time < 250      // if slide duration is less than 250ms
          && Math.abs(_this.deltaX) > 20                   // and if slide amt is greater than 20px
          || Math.abs(_this.deltaX) > _this.width/2,        // or if slide amt is greater than half the width

    // determine if slide attempt is past start and end
        isPastBounds =
          !_this.index && _this.deltaX > 0                          // if first slide and slide amt is greater than 0
          || _this.index == _this.length - 1 && _this.deltaX < 0,    // or if last slide and slide amt is less than 0

        direction = _this.deltaX < 0; // true:right false:left

    // if not scrolling vertically
    if (!_this.isScrolling) {

      if (isValidSlide && !isPastBounds) {
        if (direction) {
          _this._slide([_this.index-1],-_this.width,0,1);
          _this._slide([_this.index,_this.index+1],-_this.width,_this.speed,0);
          _this.index += 1;
        } else {
          _this._slide([_this.index+1],_this.width,0,1);
          _this._slide([_this.index-1,_this.index],_this.width,_this.speed,0);
          _this.index += -1;
        }
        _this.callback(_this.index, _this.slides[_this.index]);
      } else {
        _this._slide([_this.index-1,_this.index,_this.index+1],0,_this.speed,0);
      }

    }

  },

  onTransitionEnd: function(e) {

    if (this._getElemIndex(e.target) == this.index) { // only call transition end on the main slide item

      if (this.delay) this.begin();

      this.transitionEnd(this.index, this.slides[this.index]);

    }

  },

  slide: function(to, speed) {

    var from = this.index;

    if (from == to) return; // do nothing if already on requested slide

    if (this.browser.transitions) {
      var toStack = Math.abs(from-to) - 1,
          direction = Math.abs(from-to) / (from-to), // 1:right -1:left
          inBetween = [];

      while (toStack--) inBetween.push( (to > from ? to : from) - toStack - 1 );

      // stack em
      this._slide(inBetween,this.width * direction,0,1);

      // now slide from and to in the proper direction
      this._slide([from,to],this.width * direction,this.speed,0);
    }
    else {
      this._animate(from*-this.width, to * -this.width, this.speed)
    }

    this.index = to;

    this.callback(this.index, this.slides[this.index]);

  },

  _slide: function(nums, dist, speed, _setting) { // _setting => -1:temp, 0:full, 1:absolute

    var _slides = this.slides,
        l = nums.length;

    while(l--) {

      var elem = _slides[nums[l]];

      if (elem) { // if the element at slide number exists

        var style = elem.style,
            xval = (dist + ( _setting != 1 ? this.cache[nums[l]] : 0) );

        // set duration speed (0 represents 1-to-1 scrolling)
        style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = (speed ? speed : 0) + 'ms';

        // translate to given index position
        style.webkitTransform = 'translate3d(' + xval + 'px,0,0)';
        style.msTransform = style.MozTransform = style.OTransform = 'translateX(' + xval + 'px)';

        if (_setting == 1) this.cache[nums[l]] = dist;
        else if (_setting == 0) this.cache[nums[l]] += dist;

      }

    }

  },

  _animate: function(from, to, speed) {

    var elem = this.element;

    if (!speed) { // if not an animation, just reposition

      elem.style.left = to + 'px';

      return;

    }

    var _this = this,
        start = new Date(),
        timer = setInterval(function() {

          var timeElap = new Date() - start;

          if (timeElap > speed) {

            elem.style.left = to + 'px';  // callback after this line

            if (_this._getElemIndex(elem) == _this.index) { // only call transition end on the main slide item

              if (_this.delay) _this.begin();

              _this.transitionEnd(_this.index, _this.slides[_this.index]);

            }

            clearInterval(timer);

            return;

          }

          elem.style.left = (( (to - from) * (Math.floor((timeElap / speed) * 100) / 100) ) + from) + 'px';

        }, 4);

  },

  _getElemIndex: function(elem) {

    return parseInt(elem.getAttribute('data-index'),10);

  }

};

if ( window.jQuery || window.Zepto ) {
  (function($) {
    $.fn.Swipe = function(params) {
      return this.each(function() {
        var _this = $(this);
        _this.data('Swipe', new Swipe(_this[0], params));
      });
    }
  })( window.jQuery || window.Zepto )
}<commit_msg>added _stack, _move, and _translate functions to separate some logic<commit_after>/*
 * Swipe 2.0
 *
 * Brad Birdsall
 * Copyright 2012, Licensed GPL & MIT
 *
*/

window.Swipe = function(element, options) {

  var _this = this;

  // return immediately if element doesn't exist
  if (!element) return;

  // reference dom elements
  this.container = element;
  this.element = this.container.children[0];

  // simple feature detection
  this.browser = {
    touch: (function() {
      return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
    })(),
    transitions: (function() {
      var temp = document.createElement('swipe'),
          props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
      for ( var i in props ) {
        if (temp.style[ props[i] ] !== undefined) return true;
      }
      return false;
    })()
  };

  // retreive options
  options = options || {};
  this.index = options.startSlide || 0;
  this.speed = options.speed || 300;
  this.callback = options.callback || function() {};
  this.transitionEnd = options.transitionEnd || function() {};
  this.delay = options.auto || 0;
  this.cont = (options.continuous != undefined) ? !!options.continuous : true;
  this.disableScroll = !!options.disableScroll;

  // verify index is a number not string
  this.index = parseInt(this.index,10);

  // trigger slider initialization
  this.setup();

  // begin auto slideshow
  this.begin();

  // add event listeners
  if (this.element.addEventListener) {
    if (!!this.browser.touch) {
      this.element.addEventListener('touchstart', this, false);
      this.element.addEventListener('touchmove', this, false);
      this.element.addEventListener('touchend', this, false);
    }
    if (!!this.browser.transitions) {
      this.element.addEventListener('webkitTransitionEnd', this, false);
      this.element.addEventListener('msTransitionEnd', this, false);
      this.element.addEventListener('oTransitionEnd', this, false);
      this.element.addEventListener('transitionend', this, false);
    }
    window.addEventListener('resize', this, false);
  }

  // to play nice with old IE
  else {
    window.onresize = function () {
      _this.setup();
    };
  }

};

Swipe.prototype = {

  setup: function() {

    // get and measure amt of slides
    this.slides = this.element.children;
    this.length = this.slides.length;
    this.cache = new Array(this.length);

    // return immediately if their are less than two slides
    if (this.length < 2) return;

    // determine width of each slide
    this.width = this.container.getBoundingClientRect().width || this.container.offsetWidth;

    // return immediately if measurement fails
    if (!this.width) return;

    // store array of slides before, current, and after
    var refArray = [[],[],[]];

    this.element.style.width = (this.slides.length * this.width) + 'px';

    // stack elements
    for (var index = this.length - 1; index > -1; index--) {

      var elem = this.slides[index];

      elem.style.width = this.width + 'px';
      elem.setAttribute('data-index', index);

      if (this.browser.transitions) {
        elem.style.left = (index * -this.width) + 'px';
      }

      // add this index to the reference array    0:before 1:equal 2:after
      refArray[this.index > index ? 0 : (this.index < index ? 2 : 1)].push(index);

    }

    if (this.browser.transitions) {

      // stack left, current, and right slides
      this._stack(refArray[0],-1);
      this._stack(refArray[1],0);
      this._stack(refArray[2],1);

    }

    this.container.style.visibility = 'visible';

  },

  kill: function() {

    // cancel slideshow
    this.delay = 0;
    clearTimeout(this.interval);

    // clear all translations
    var slideArray = [];
    for (var i = this.slides.length - 1; i >= 0; i--) {
      this.slides[i].style.width = '';
      slideArray.push(i);
    }
    this._stack(slideArray,0);

    var elem = this.element;
    elem.className = elem.className.replace('swipe-active','');

    // remove event listeners
    if (this.element.removeEventListener) {
      if (!!this.browser.touch) {
        this.element.removeEventListener('touchstart', this, false);
        this.element.removeEventListener('touchmove', this, false);
        this.element.removeEventListener('touchend', this, false);
      }
      if (!!this.browser.transitions) {
        this.element.removeEventListener('webkitTransitionEnd', this, false);
        this.element.removeEventListener('msTransitionEnd', this, false);
        this.element.removeEventListener('oTransitionEnd', this, false);
        this.element.removeEventListener('transitionend', this, false);
      }
      window.removeEventListener('resize', this.resize, false);
    }

    // kill old IE! you can quote me on that ;)
    else {
      window.onresize = null;
    }

  },

  getPos: function() {

    // return current index position
    return this.index;

  },

  prev: function(delay) {

    // cancel slideshow
    this.delay = delay || 0;
    clearTimeout(this.interval);

    // if not at first slide
    if (this.index) this.slide(this.index-1, this.speed);
    else if (this.cont) this.slide(this.length-1, this.speed);

  },

  next: function(delay) {

    // cancel slideshow
    this.delay = delay || 0;
    clearTimeout(this.interval);

    if (this.index < this.length - 1) this.slide(this.index+1, this.speed); // if not last slide
    else if (this.cont) this.slide(0, this.speed); //if last slide return to start

  },

  begin: function() {

    var _this = this;

    this.interval = (this.delay)
      ? setTimeout(function() {
        _this.next(_this.delay);
      }, this.delay)
      : 0;

  },

  handleEvent: function(e) {
    switch (e.type) {
      case 'touchstart': this.onTouchStart(e); break;
      case 'touchmove': this.onTouchMove(e); break;
      case 'touchend': this.onTouchEnd(e); break;
      case 'webkitTransitionEnd':
      case 'msTransitionEnd':
      case 'oTransitionEnd':
      case 'transitionend': this.onTransitionEnd(e); break;
      case 'resize': this.setup(); break;
    }
  },

  onTouchStart: function(e) {

    var _this = this;

    _this.start = {

      // get touch coordinates for delta calculations in onTouchMove
      pageX: e.touches[0].pageX,
      pageY: e.touches[0].pageY,

      // set initial timestamp of touch sequence
      time: Number( new Date() )

    };

    // used for testing first onTouchMove event
    _this.isScrolling = undefined;

    // reset deltaX
    _this.deltaX = 0;

  },

  onTouchMove: function(e) {

    var _this = this;

    // ensure swiping with one touch and not pinching
    if(e.touches.length > 1 || e.scale && e.scale !== 1) return;

    _this.deltaX = e.touches[0].pageX - _this.start.pageX;

    // determine if scrolling test has run - one time test
    if ( typeof _this.isScrolling == 'undefined') {
      _this.isScrolling = !!( _this.isScrolling || Math.abs(_this.deltaX) < Math.abs(e.touches[0].pageY - _this.start.pageY) );
    }

    // if user is not trying to scroll vertically
    if (!_this.isScrolling) {

      // prevent native scrolling
      e.preventDefault();

      // cancel slideshow
      _this.delay = 0;
      clearTimeout(_this.interval);

      // increase resistance if first or last slide
      _this.deltaX =
        _this.deltaX /
          ( (!_this.index && _this.deltaX > 0               // if first slide and sliding left
            || _this.index == _this.length - 1              // or if last slide and sliding right
            && _this.deltaX < 0                            // and if sliding at all
          ) ?
          ( Math.abs(_this.deltaX) / _this.width + 1 )      // determine resistance level
          : 1 );                                          // no resistance if false

      // translate immediately 1:1
      _this._move([_this.index-1,_this.index,_this.index+1],_this.deltaX);

    } else if (_this.disableScroll) {

      // prevent native scrolling
      e.preventDefault();

    }

  },

  onTouchEnd: function(e) {

    var _this = this;

    // determine if slide attempt triggers next/prev slide
    var isValidSlide =
          Number(new Date()) - _this.start.time < 250      // if slide duration is less than 250ms
          && Math.abs(_this.deltaX) > 20                   // and if slide amt is greater than 20px
          || Math.abs(_this.deltaX) > _this.width/2,        // or if slide amt is greater than half the width

    // determine if slide attempt is past start and end
        isPastBounds =
          !_this.index && _this.deltaX > 0                          // if first slide and slide amt is greater than 0
          || _this.index == _this.length - 1 && _this.deltaX < 0,    // or if last slide and slide amt is less than 0

        direction = _this.deltaX < 0; // true:right false:left

    // if not scrolling vertically
    if (!_this.isScrolling) {

      if (isValidSlide && !isPastBounds) {
        if (direction) {
          _this._stack([_this.index-1],-1);
          _this._slide([_this.index,_this.index+1],-_this.width,_this.speed);
          _this.index += 1;
        } else {
          _this._stack([_this.index+1],1);
          _this._slide([_this.index-1,_this.index],_this.width,_this.speed);
          _this.index += -1;
        }
        _this.callback(_this.index, _this.slides[_this.index]);
      } else {
        _this._slide([_this.index-1,_this.index,_this.index+1],0,_this.speed);
      }

    }

  },

  onTransitionEnd: function(e) {

    if (this._getElemIndex(e.target) == this.index) { // only call transition end on the main slide item

      if (this.delay) this.begin();

      this.transitionEnd(this.index, this.slides[this.index]);

    }

  },

  slide: function(to, speed) {

    var from = this.index;

    if (from == to) return; // do nothing if already on requested slide

    if (this.browser.transitions) {
      var toStack = Math.abs(from-to) - 1,
          direction = Math.abs(from-to) / (from-to), // 1:right -1:left
          inBetween = [];

      while (toStack--) inBetween.push( (to > from ? to : from) - toStack - 1 );

      // stack em
      this._stack(inBetween,direction);

      // now slide from and to in the proper direction
      this._slide([from,to],this.width * direction,this.speed);
    }
    else {
      this._animate(from*-this.width, to * -this.width, this.speed)
    }

    this.index = to;

    this.callback(this.index, this.slides[this.index]);

  },

  _slide: function(nums, dist, speed) {

    if (nums.length) console.log('Slide:', nums)

    var _slides = this.slides,
        l = nums.length;

    while(l--) {

      this._translate(_slides[nums[l]], dist + this.cache[nums[l]], speed ? speed : 0);

      this.cache[nums[l]] += dist;

    }

  },

  _stack: function(nums, pos) {  // pos: -1:left 0:center 1:right

    if (nums.length) console.log('Stack:', nums, pos)

    var _slides = this.slides,
        l = nums.length,
        dist = this.width * pos;

    while(l--) {

      this._translate(_slides[nums[l]], dist, 0);

      this.cache[nums[l]] = dist;

    }

  },

  _move: function(nums, dist) { // 1:1 scrolling

    if (nums.length) console.log('Move:', nums, dist)

    var _slides = this.slides,
        l = nums.length;

    while(l--) this._translate(_slides[nums[l]], dist + this.cache[nums[l]], 0);

  },

  _translate: function(elem, xval, speed) {

    if (!elem) return;

    var style = elem.style;

    // set duration speed to 0
    style.webkitTransitionDuration =
    style.MozTransitionDuration =
    style.msTransitionDuration =
    style.OTransitionDuration =
    style.transitionDuration = speed + 'ms';

    // translate to given position
    style.webkitTransform = 'translate3d(' + xval + 'px,0,0)';
    style.msTransform =
    style.MozTransform =
    style.OTransform = 'translateX(' + xval + 'px)';

  },

  _animate: function(from, to, speed) {

    var elem = this.element;

    if (!speed) { // if not an animation, just reposition

      elem.style.left = to + 'px';

      return;

    }

    var _this = this,
        start = new Date(),
        timer = setInterval(function() {

          var timeElap = new Date() - start;

          if (timeElap > speed) {

            elem.style.left = to + 'px';  // callback after this line

            if (_this._getElemIndex(elem) == _this.index) { // only call transition end on the main slide item

              if (_this.delay) _this.begin();

              _this.transitionEnd(_this.index, _this.slides[_this.index]);

            }

            clearInterval(timer);

            return;

          }

          elem.style.left = (( (to - from) * (Math.floor((timeElap / speed) * 100) / 100) ) + from) + 'px';

        }, 4);

  },

  _getElemIndex: function(elem) {

    return parseInt(elem.getAttribute('data-index'),10);

  }

};

if ( window.jQuery || window.Zepto ) {
  (function($) {
    $.fn.Swipe = function(params) {
      return this.each(function() {
        var _this = $(this);
        _this.data('Swipe', new Swipe(_this[0], params));
      });
    }
  })( window.jQuery || window.Zepto )
}<|endoftext|>


<commit_before>/*
 * Copyright 2016 EPAM Systems
 *
 *
 * This file is part of EPAM Report Portal.
 * https://github.com/epam/ReportPortal
 *
 * Report Portal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Report Portal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Report Portal.  If not, see <http://www.gnu.org/licenses/>.
 */
define(function (require) {
    'use strict';

    var Epoxy = require('backbone-epoxy');
    var Util = require('util');
    var Urls = require('dataUrlResolver');
    var App = require('app');

    var config = App.getInstance();

    var LogItemModel = Epoxy.Model.extend({
        defaults: {
            id: '',
            binary_content: null,
            message: '',
            test_item: '',
            time: 0,
            active: false,
            empty: false,
            level: null // INFO, ERROR,
        },
        computeds: {
            timeString: {
                deps: ['time'],
                get: function (time) {
                    return Util.dateFormat(time);
                }
            },
            imagePath: {
                deps: ['binary_content'],
                get: function (binary_content) {
                    if (!binary_content || config.userModel.get('token') === config.userModel.defaults.token) { return ''; }
                    if (!~binary_content.content_type.search('image/')) {
                        var type = binary_content.content_type.split('/')[1];
                        switch (type) {
                            case 'CSS':
                            case 'css': return 'img/launch/attachments/css.svg';
                            case 'HTML':
                            case 'html': return 'img/launch/attachments/html.svg';
                            case 'JAVASCRIPT':
                            case 'javascript': return 'img/launch/attachments/js.svg';
                            case 'CSV':
                            case 'csv': return 'img/launch/attachments/csv.svg';
                            case 'JSON':
                            case 'json': return 'img/launch/attachments/json.svg';
                            case 'PHP':
                            case 'php': return 'img/launch/attachments/php.svg';
                            case 'XML':
                            case 'xml': return 'img/launch/attachments/xml.svg';
                            case 'PLAIN':
                            case 'plain': return 'img/launch/attachments/txt.svg';
                            case 'RAR':
                            case 'rar':
                            case 'TAZ':
                            case 'taz':
                            case 'TAR':
                            case 'tar':
                            case 'GZIP':
                            case 'gzip':
                            case 'ZIP':
                            case 'zip': return 'img/launch/attachments/archive.svg';
                            default: return 'img/launch/attachment.png';
                        }
                    }
                    return Urls.getFileById(binary_content.thumbnail_id);
                }
            },
            mainImagePath: {
                deps: ['binary_content'],
                get: function (binaryContent) {
                    if (binaryContent && binaryContent.id) {
                        if (!~binaryContent.content_type.search('image/')) {
                            return this.get('imagePath');
                        }
                        return Urls.getFileById(binaryContent.id);
                    }
                    return '';
                }
            },
            shortId: {
                deps: ['id'],
                get: function (id) {
                    return id.substr(20);
                }
            }
        }
    });

    return LogItemModel;
});
<commit_msg>fix 401 query after logout<commit_after>/*
 * Copyright 2016 EPAM Systems
 *
 *
 * This file is part of EPAM Report Portal.
 * https://github.com/epam/ReportPortal
 *
 * Report Portal is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Report Portal is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Report Portal.  If not, see <http://www.gnu.org/licenses/>.
 */
define(function (require) {
    'use strict';

    var Epoxy = require('backbone-epoxy');
    var Util = require('util');
    var Urls = require('dataUrlResolver');
    var App = require('app');

    var config = App.getInstance();

    var LogItemModel = Epoxy.Model.extend({
        defaults: {
            id: '',
            binary_content: null,
            message: '',
            test_item: '',
            time: 0,
            active: false,
            empty: false,
            level: null // INFO, ERROR,
        },
        computeds: {
            timeString: {
                deps: ['time'],
                get: function (time) {
                    return Util.dateFormat(time);
                }
            },
            imagePath: {
                deps: ['binary_content'],
                get: function (binary_content) {
                    if (!binary_content || config.userModel.get('token') === config.userModel.defaults.token) { return ''; }
                    if (!~binary_content.content_type.search('image/')) {
                        var type = binary_content.content_type.split('/')[1];
                        switch (type) {
                            case 'CSS':
                            case 'css': return 'img/launch/attachments/css.svg';
                            case 'HTML':
                            case 'html': return 'img/launch/attachments/html.svg';
                            case 'JAVASCRIPT':
                            case 'javascript': return 'img/launch/attachments/js.svg';
                            case 'CSV':
                            case 'csv': return 'img/launch/attachments/csv.svg';
                            case 'JSON':
                            case 'json': return 'img/launch/attachments/json.svg';
                            case 'PHP':
                            case 'php': return 'img/launch/attachments/php.svg';
                            case 'XML':
                            case 'xml': return 'img/launch/attachments/xml.svg';
                            case 'PLAIN':
                            case 'plain': return 'img/launch/attachments/txt.svg';
                            case 'RAR':
                            case 'rar':
                            case 'TAZ':
                            case 'taz':
                            case 'TAR':
                            case 'tar':
                            case 'GZIP':
                            case 'gzip':
                            case 'ZIP':
                            case 'zip': return 'img/launch/attachments/archive.svg';
                            default: return 'img/launch/attachment.png';
                        }
                    }
                    return Urls.getFileById(binary_content.thumbnail_id);
                }
            },
            mainImagePath: {
                deps: ['binary_content'],
                get: function (binaryContent) {
                    if (binaryContent && binaryContent.id && config.userModel.get('token') !== config.userModel.defaults.token) {
                        if (!~binaryContent.content_type.search('image/')) {
                            return this.get('imagePath');
                        }
                        return Urls.getFileById(binaryContent.id);
                    }
                    return '';
                }
            },
            shortId: {
                deps: ['id'],
                get: function (id) {
                    return id.substr(20);
                }
            }
        }
    });

    return LogItemModel;
});
<|endoftext|>


<commit_before>var log = require('bows')('companies');
var PageView = require('client/js/pages/base');
var templates = require('client/js/templates');
var CompanyView = require('client/js/views/company');
var Company = require('client/js/models/company');
var AmpersandCollection = require('ampersand-collection');

module.exports = PageView.extend({
  pageTitle: 'Companies',
  template: templates.pages.companies.list,
  events: {
    'click [data-hook~=shuffle]': 'shuffle',
    'click [data-hook~=fetch]': 'fetchCollection',
    'click [data-hook~=reset]': 'resetCollection',

    'click [data-hook~=selected]': 'selected',
    'click [data-hook~=contacted]': 'contacted',
    'click [data-hook~=inconversations]': 'inconversations',
    'click [data-hook~=innegotiations]': 'innegotiations',
    'click [data-hook~=showall]': 'showall',
    'click [data-hook~=closeddeal]': 'closeddeal',
    'click [data-hook~=rejected]': 'rejected',
    'click [data-hook~=giveup]': 'giveup',

  },
  render: function () {
    this.renderWithTemplate();
    this.renderCollection(this.collection, CompanyView, this.queryByHook('companies-list'));
    if (!this.collection.length) {
      this.fetchCollection();
    }
  },
  fetchCollection: function () {
    log('Fetching companies');
    this.collection.fetch();

    return false;
  },
  resetCollection: function () {
    this.collection.reset();
  },
  shuffle: function () {
    this.collection.comparator = function () {
      return !Math.round(Math.random());
    };
    this.collection.sort();
    delete this.collection.comparator;
    return false;
  },
  contacted: function () {
    log('Fetching  contacted Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'Contacted';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  selected: function () {
    log('Fetching  Selected Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'Selected';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  closeddeal: function () {
    log('Fetching  Closed Deal Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'Closed Deal';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  rejected: function () {
    log('Fetching  Rejected Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'Rejected';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  giveup: function () {
    log('Fetching  Gave up Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'Give Up';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  inconversations: function () {
    log('Fetching  Selected Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'In Conversations';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  innegotiations: function () {
    log('Fetching  Selected Companies')
    var aux = this.collection.filter(function(company){
      return company.participation && company.participation.status == 'In Negotiations';
    });

    aux = new AmpersandCollection(aux, {model: Company});
    this.renderWithTemplate();
    this.renderCollection(aux, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
  showall: function () {
    this.renderWithTemplate();
    this.renderCollection(this.collection, CompanyView, this.queryByHook('companies-list'));
    return false;
  },
});
<commit_msg>Refactored a few things on list companies page... rerender function sucessfully :D<commit_after>var log = require('bows')('companies');
var PageView = require('client/js/pages/base');
var templates = require('client/js/templates');
var CompanyView = require('client/js/views/company');
var Company = require('client/js/models/company');
var AmpersandCollection = require('ampersand-collection');

function filtering(collection,filter){
    return collection.filter(function(company){
      return company.participation && company.participation.status == filter;
    });
  }
function rerender(page,collection){
    page.renderWithTemplate();
    page.renderCollection(collection, CompanyView, page.queryByHook('companies-list'));
    return false;
  }

module.exports = PageView.extend({
  pageTitle: 'Companies',
  template: templates.pages.companies.list,
  events: {
    'click [data-hook~=shuffle]': 'shuffle',
    'click [data-hook~=fetch]': 'fetchCollection',
    'click [data-hook~=reset]': 'resetCollection',

    'click [data-hook~=selected]': 'selected',
    'click [data-hook~=contacted]': 'contacted',
    'click [data-hook~=inconversations]': 'inconversations',
    'click [data-hook~=innegotiations]': 'innegotiations',
    'click [data-hook~=showall]': 'showall',
    'click [data-hook~=closeddeal]': 'closeddeal',
    'click [data-hook~=rejected]': 'rejected',
    'click [data-hook~=giveup]': 'giveup',

  },
  render: function () {
    this.renderWithTemplate();
    this.renderCollection(this.collection, CompanyView, this.queryByHook('companies-list'));
    if (!this.collection.length) {
      this.fetchCollection();
    }
  },
  fetchCollection: function () {
    log('Fetching companies');
    this.collection.fetch();

    return false;
  },
  resetCollection: function () {
    this.collection.reset();
  },
  shuffle: function () {
    this.collection.comparator = function () {
      return !Math.round(Math.random());
    };
    this.collection.sort();
    delete this.collection.comparator;
    return false;
  },
  contacted: function () {
    log('Fetching  contacted Companies')
    var aux =  filtering(this.collection,'Contacted');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  selected: function () {
    log('Fetching  Selected Companies')
    var aux = filtering(this.collection,'Selected');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  closeddeal: function () {
    log('Fetching  Closed Deal Companies')
    var aux = filtering(this.collection,'Closed Deal');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  rejected: function () {
    log('Fetching  Rejected Companies')
    var aux = filtering(this.collection,'Rejected');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  giveup: function () {
    log('Fetching  Gave up Companies')
    var aux = filtering(this.collection,'Give Up');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  inconversations: function () {
    log('Fetching  Selected Companies')
    var aux = filtering(this.collection,'In Conversations');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  innegotiations: function () {
    log('Fetching  Selected Companies')
    var aux = filtering(this.collection,'In Negotiations');

    aux = new AmpersandCollection(aux, {model: Company});
    rerender(this,aux);
    return false;
  },
  showall: function () {
    rerender(this,this.collection);
    return false;
  },
});
<|endoftext|>


<commit_before>// ==UserScript==
// @author      Robert Slifka (github @rslifka)
// @connect     docs.google.com
// @connect     rslifka.github.io
// @copyright   2017-2018, Robert Slifka (https://github.com/rslifka/fate_of_all_fools)
// @description Enhancements to the Destiny Item Manager
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getValue
// @grant       GM_log
// @grant       GM_setValue
// @grant       GM_xmlhttpRequest
// @homepage    https://github.com/rslifka/fate_of_all_fools
// @license     MIT; https://raw.githubusercontent.com/rslifka/fate_of_all_fools/master/LICENSE.txt
// @match       https://*.destinyitemmanager.com/*
// @name        Fate of All Fools
// @require     https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.js
// @resource    fateOfAllFoolsCSS https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.css
// @run-at      document-start
// @supportURL  https://github.com/rslifka/fate_of_all_fools/issues
// @version     57
// ==/UserScript==
<commit_msg>AUTO-CREATED Release Artifact v58 c/o Travis<commit_after>// ==UserScript==
// @author      Robert Slifka (github @rslifka)
// @connect     docs.google.com
// @connect     rslifka.github.io
// @copyright   2017-2018, Robert Slifka (https://github.com/rslifka/fate_of_all_fools)
// @description Enhancements to the Destiny Item Manager
// @grant       GM_addStyle
// @grant       GM_getResourceText
// @grant       GM_getValue
// @grant       GM_log
// @grant       GM_setValue
// @grant       GM_xmlhttpRequest
// @homepage    https://github.com/rslifka/fate_of_all_fools
// @license     MIT; https://raw.githubusercontent.com/rslifka/fate_of_all_fools/master/LICENSE.txt
// @match       https://*.destinyitemmanager.com/*
// @name        Fate of All Fools
// @require     https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.js
// @resource    fateOfAllFoolsCSS https://rslifka.github.io/fate_of_all_fools/fateOfAllFools.css
// @run-at      document-start
// @supportURL  https://github.com/rslifka/fate_of_all_fools/issues
// @version     58
// ==/UserScript==
<|endoftext|>