<commit_before>'use strict';
var turf = require('turf');
var _ = require('underscore');
var rbush = require('rbush');
var knn = require('rbush-knn');
var flatten = require('geojson-flatten');

module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var highways = {};
  var bboxes = [];
  var bboxLayer = turf.bboxPolygon(turf.extent(layer));
  bboxLayer.geometry.type = 'LineString';
  bboxLayer.geometry.coordinates = bboxLayer.geometry.coordinates[0];
  var bufferLayer = turf.buffer(bboxLayer, 0.01, 'miles').features[0];
  var majorRoads = {
    'motorway': true,
    'trunk': true,
    'primary': true,
    'secondary': true,
    'tertiary': true,
    'motorway_link': true,
    'trunk_link': true,
    'primary_link': true,
    'secondary_link': true,
    'tertiary_link': true
  };
  var minorRoads = {
    'unclassified': true,
    'residential': true,
    'living_street': true,
    'service': true,
    'road': true
  };
  var pathRoads = {
    'pedestrian': true,
    'track': true,
    'footway': true,
    'path': true,
    'cycleway': true,
    'steps': true
  };
  var preserveType = {};
  preserveType = _.extend(preserveType, majorRoads);
  preserveType = _.extend(preserveType, minorRoads);
  // preserveType = _.extend(preserveType, pathRoads);
  var osmlint = 'impossibleoneways';
  for (var i = 0; i < layer.features.length; i++) {
    var val = layer.features[i];
    var id = val.properties._osm_way_id;
    //Value LineString highways
    if (val.geometry.type === 'LineString' && preserveType[val.properties.highway]) {
      var coordsWayL = val.geometry.coordinates;
      var isClippedL = false;
      if (turf.inside(turf.point(coordsWayL[0]), bufferLayer) || turf.inside(turf.point(coordsWayL[coordsWayL.length - 1]), bufferLayer)) {
        isClippedL = true;
      }
      var idWayL = id + 'L';
      for (var j = 0; j < coordsWayL.length; j++) {
        var positionL;
        if (j === 0) {
          positionL = 'first';
        } else if (j === (coordsWayL.length - 1)) {
          positionL = 'end';
        } else {
          positionL = 'midle';
        }
        var propsL = {
          id: idWayL,
          position: positionL,
          isClipped: isClippedL
        };
        var itemL = coordsWayL[j].reverse().concat(coordsWayL[j].reverse());
        itemL.push(propsL);
        bboxes.push(itemL);
      }
      highways[idWayL] = val;
    } else if (val.geometry.type === 'MultiLineString' && preserveType[val.properties.highway]) { //MultiLineString evaluation
      var arrayWays = flatten(val);
      for (var f = 0; f < arrayWays.length; f++) {
        if (arrayWays[f].geometry.type === 'LineString') {
          var coordsWayM = arrayWays[f].geometry.coordinates;
          var isClippedM = false;
          if (turf.inside(turf.point(coordsWayM[0]), bufferLayer) || turf.inside(turf.point(coordsWayM[coordsWayM.length - 1]), bufferLayer)) {
            isClippedM = true;
          }
          var idWayM = id + 'M' + f;
          for (var t = 0; t < coordsWayM.length; t++) {
            var positionM;
            if (t === 0) {
              positionM = 'first';
            } else if (t === (coordsWayM.length - 1)) {
              positionM = 'end';
            } else {
              positionM = 'midle';
            }
            var propsM = {
              id: idWayM,
              position: positionM,
              isClipped: isClippedM
            };
            var itemM = coordsWayM[t].reverse().concat(coordsWayM[t].reverse());
            itemM.push(propsM);
            bboxes.push(itemM);
            highways[idWayM] = arrayWays[f];
          }
        }
      }
    }
  }

  var highwaysTree = rbush(bboxes.length);
  highwaysTree.load(bboxes);

  var features = {};
  for (var m = 0; m < bboxes.length; m++) {
    var valueBbox = bboxes[m];
    var valueHighway = highways[valueBbox[4].id];
    var fCoor = valueHighway.geometry.coordinates[0];
    var eCoor = valueHighway.geometry.coordinates[valueHighway.geometry.coordinates.length - 1];
    if (!valueBbox[4].isClipped && valueHighway.properties.oneway && valueHighway.properties.oneway !== 'no' && _.intersection(fCoor, eCoor).length !== 2 && valueHighway.properties.highway !== 'construction') {
      // var bufferedFCoor = turf.extent(turf.buffer(turf.point(fCoor), 2, 'meters'));
      var bufferedFCoor = fCoor.reverse().concat(fCoor.reverse());
      var overlapsFcoor = highwaysTree.search(bufferedFCoor);
      if (overlapsFcoor.length === 1) {
        features[valueBbox[4].id] = valueHighway;
        features[valueBbox[4].id + 'P'] = turf.point(fCoor);
      } else {
        // var flag = [];
        // for (var u = 0; u < overlapsFcoor.length; u++) {
        //   var connectRoadFirst = highways[overlapsFcoor[u][4].id];
        //   if (valueHighway.properties._osm_way_id !== connectRoadFirst.properties._osm_way_id) { //different roads
        //     if (overlapsFcoor[u][4].position === 'midle') {
        //       flag.push('connection');
        //       // break;
        //     } else {
        //       if (typeof connectRoadFirst.properties.oneway === 'undefined' || connectRoadFirst.properties.oneway === 'no') {
        //         flag.push('connection');
        //         // break;
        //       } else {
        //         //when the road's oneway is = yes or 1
        //         if ((valueHighway.properties.oneway === 'yes' || valueHighway.properties.oneway === 1) && overlapsFcoor[u][4].position === 'end' && (connectRoadFirst.properties.oneway === 'yes' || connectRoadFirst.properties.oneway === 1)) {
        //           flag.push('connection');
        //           // break;
        //         } else if ((valueHighway.properties.oneway === 'yes' || valueHighway.properties.oneway === 1) && overlapsFcoor[u][4].position === 'first' && connectRoadFirst.properties.oneway === -1) {
        //           flag.push('connection');
        //           // break;
        //         } else if (valueHighway.properties.oneway === -1 && overlapsFcoor[u][4].position === 'first' && (connectRoadFirst.properties.oneway === 'yes' || connectRoadFirst.properties.oneway === 1)) {
        //           //When the road's oneway is = -1
        //           flag.push('connection');
        //           // break;
        //         } else if (valueHighway.properties.oneway === -1 && overlapsFcoor[u][4].position === 'end' && connectRoadFirst.properties.oneway === -1) {
        //           flag.push('connection');
        //           // break;
        //         } else {
        //           flag.push('noconnection');
        //           // continue;
        //         }
        //       }
        //     }
        //   }
        // }
        // if (overlapsFcoor.length === (flag.length + 1) && flag.indexOf('connection') === -1) {
        //   features[valueBbox[4].id] = valueHighway;
        //   features[valueBbox[4].id + 'P'] = turf.point(valueHighway.geometry.coordinates[0]);
        // }
      }

      // var bufferedECoor = turf.extent(turf.buffer(turf.point(eCoor), 5, 'meters'));
      var bufferedECoor = eCoor.reverse().concat(eCoor.reverse());

      var overlapsEcoor = highwaysTree.search(bufferedECoor);
      if (overlapsEcoor.length === 1) {
        features[valueBbox[4].id] = valueHighway;
        features[valueBbox[4].id + 'P'] = turf.point(eCoor);
      } else {
        // var flag = [];
        // for (var u = 0; u < overlapsEcoor.length; u++) {
        //   var connectRoadEnd = highways[overlapsEcoor[u][4].id];
        //   if (valueHighway.properties._osm_way_id !== connectRoadEnd.properties._osm_way_id) { //different roads
        //     if (overlapsEcoor[u][4].position === 'midle') {
        //       flag.push('connection');
        //       // break;
        //     } else {
        //       if (typeof connectRoadEnd.properties.oneway === 'undefined' || connectRoadEnd.properties.oneway === 'no') {
        //         flag.push('connection');
        //         // break;
        //       } else {
        //         //when the road's oneway is = yes or 1
        //         if ((valueHighway.properties.oneway === 'yes' || valueHighway.properties.oneway === 1) && overlapsEcoor[u][4].position === 'end' && connectRoadEnd.properties.oneway === -1) {
        //           flag.push('connection');
        //           // break;
        //         } else if ((valueHighway.properties.oneway === 'yes' || valueHighway.properties.oneway === 1) && overlapsEcoor[u][4].position === 'first' && (connectRoadEnd.properties.oneway === 'yes' || connectRoadEnd.properties.oneway === 1)) {
        //           flag.push('connection');
        //           // break;
        //         } else if (valueHighway.properties.oneway === -1 && overlapsEcoor[u][4].position === 'first' && connectRoadEnd.properties.oneway === -1) {
        //           //When the road's oneway is = -1
        //           flag.push('connection');
        //           // break;
        //         } else if (valueHighway.properties.oneway === -1 && overlapsEcoor[u][4].position === 'end' && (connectRoadEnd.properties.oneway === 'yes' || connectRoadEnd.properties.oneway === 1)) {
        //           flag.push('connection');
        //           // break;
        //         } else {
        //           flag.push('noconnection');
        //           // continue;
        //         }
        //       }
        //     }
        //   }
        // }
        // if (overlapsFcoor.length === (flag.length + 1) && flag.indexOf('connection') === -1) {
        //   features[valueBbox[4].id] = valueHighway;
        //   features[valueBbox[4].id + 'P'] = turf.point(valueHighway.geometry.coordinates[0]);
        // }
      }

    }
  }

  var result = _.values(features);
  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }

  done(null, null);

};<commit_msg>imposible oneway ok<commit_after>'use strict';
var turf = require('turf');
var _ = require('underscore');
var rbush = require('rbush');
var knn = require('rbush-knn');
var flatten = require('geojson-flatten');

module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var highways = {};
  var bboxes = [];
  var bboxLayer = turf.bboxPolygon(turf.extent(layer));
  bboxLayer.geometry.type = 'LineString';
  bboxLayer.geometry.coordinates = bboxLayer.geometry.coordinates[0];
  var bufferLayer = turf.buffer(bboxLayer, 0.01, 'miles').features[0];
  var majorRoads = {
    'motorway': true,
    'trunk': true,
    'primary': true,
    'secondary': true,
    'tertiary': true,
    'motorway_link': true,
    'trunk_link': true,
    'primary_link': true,
    'secondary_link': true,
    'tertiary_link': true
  };
  var minorRoads = {
    'unclassified': true,
    'residential': true,
    'living_street': true,
    'service': true,
    'road': true
  };
  var pathRoads = {
    'pedestrian': true,
    'track': true,
    'footway': true,
    'path': true,
    'cycleway': true,
    'steps': true
  };
  var preserveType = {};
  preserveType = _.extend(preserveType, majorRoads);
  preserveType = _.extend(preserveType, minorRoads);
  preserveType = _.extend(preserveType, pathRoads);
  var osmlint = 'impossibleoneways';
  for (var i = 0; i < layer.features.length; i++) {
    var val = layer.features[i];
    var id = val.properties._osm_way_id;
    //Value LineString highways
    if (val.geometry.type === 'LineString' && preserveType[val.properties.highway]) {
      var coordsWayL = val.geometry.coordinates;
      var isClippedL = false;
      if (turf.inside(turf.point(coordsWayL[0]), bufferLayer) || turf.inside(turf.point(coordsWayL[coordsWayL.length - 1]), bufferLayer)) {
        isClippedL = true;
      }
      var idWayL = id + 'L';
      for (var j = 0; j < coordsWayL.length; j++) {
        var positionL;
        if (j === 0) {
          positionL = 'first';
        } else if (j === (coordsWayL.length - 1)) {
          positionL = 'end';
        } else {
          positionL = 'midle';
        }
        var propsL = {
          id: idWayL,
          position: positionL,
          isClipped: isClippedL
        };
        var itemL = coordsWayL[j].reverse().concat(coordsWayL[j].reverse());
        itemL.push(propsL);
        bboxes.push(itemL);
      }
      highways[idWayL] = val;
    } else if (val.geometry.type === 'MultiLineString' && preserveType[val.properties.highway]) { //MultiLineString evaluation
      var arrayWays = flatten(val);
      for (var f = 0; f < arrayWays.length; f++) {
        if (arrayWays[f].geometry.type === 'LineString') {
          var coordsWayM = arrayWays[f].geometry.coordinates;
          var isClippedM = false;
          if (turf.inside(turf.point(coordsWayM[0]), bufferLayer) || turf.inside(turf.point(coordsWayM[coordsWayM.length - 1]), bufferLayer)) {
            isClippedM = true;
          }
          var idWayM = id + 'M' + f;
          for (var t = 0; t < coordsWayM.length; t++) {
            var positionM;
            if (t === 0) {
              positionM = 'first';
            } else if (t === (coordsWayM.length - 1)) {
              positionM = 'end';
            } else {
              positionM = 'midle';
            }
            var propsM = {
              id: idWayM,
              position: positionM,
              isClipped: isClippedM
            };
            var itemM = coordsWayM[t].reverse().concat(coordsWayM[t].reverse());
            itemM.push(propsM);
            bboxes.push(itemM);
            highways[idWayM] = arrayWays[f];
          }
        }
      }
    }
  }

  var highwaysTree = rbush(bboxes.length);
  highwaysTree.load(bboxes);
  var features = {};
  for (var key in highways) {
    var valueHighway = highways[key];
    var firstCoor = valueHighway.geometry.coordinates[0];
    var endCoor = valueHighway.geometry.coordinates[valueHighway.geometry.coordinates.length - 1];

    if (valueHighway.properties.oneway && valueHighway.properties.oneway !== 'no' && _.intersection(firstCoor, endCoor).length !== 2) {
      var overlapsFirstcoor = highwaysTree.search(firstCoor.reverse().concat(firstCoor.reverse()));
      if (overlapsFirstcoor.length === 1 && !overlapsFirstcoor[0][4].isClipped) {
        // features[valueHighway.properties._osm_way_id] = valueHighway;
        // features[valueHighway.properties._osm_way_id + 'P'] = turf.point(firstCoor);
      } else {
        var isExitFirst = false;
        var flagFirst = [];
        for (var u = 0; u < overlapsFirstcoor.length; u++) {
          var connectRoad = highways[overlapsFirstcoor[u][4].id];
          flagFirst.push(connection(overlapsFirstcoor[u][4].position, connectRoad.properties.oneway));
          if (valueHighway.properties._osm_way_id === connectRoad.properties._osm_way_id && overlapsFirstcoor[u][4].isClipped) {
            isExitFirst = true;
          }
          if (overlapsFirstcoor[u][4].position === 'midle' || connectRoad.properties.oneway === 'no' || typeof connectRoad.properties.oneway === 'undefined') { //
            isExitFirst = true;
          }
        }
        var connectionFirst = _.uniq(flagFirst);
        if (!isExitFirst && (connectionFirst[0] === 'salida' || connectionFirst[0] === 'entrada') && connectionFirst.length === 1) {
          features[valueHighway.properties._osm_way_id] = valueHighway;
          features[valueHighway.properties._osm_way_id + 'P'] = turf.point(firstCoor);
        }
      }
      var overlapsEndcoor = highwaysTree.search(endCoor.reverse().concat(endCoor.reverse()));
      if (overlapsEndcoor.length === 1 && !overlapsEndcoor[0][4].isClipped) {
        // features[valueHighway.properties._osm_way_id] = valueHighway;
        // features[valueHighway.properties._osm_way_id + 'P'] = turf.point(endCoor);
      } else {
        var isExitEnd = false;
        var flagEnd = [];
        for (var m = 0; m < overlapsEndcoor.length; m++) {
          var connectRoadEnd = highways[overlapsEndcoor[m][4].id];
          flagEnd.push(connection(overlapsEndcoor[m][4].position, connectRoadEnd.properties.oneway));
          if (valueHighway.properties._osm_way_id === connectRoadEnd.properties._osm_way_id && overlapsEndcoor[m][4].isClipped) {
            isExitEnd = true;
          }
          if (overlapsEndcoor[m][4].position === 'midle' || connectRoadEnd.properties.oneway === 'no' || typeof connectRoadEnd.properties.oneway === 'undefined') { //
            isExitEnd = true;
          }
        }
        var connectionEnd = _.uniq(flagEnd);
        if (!isExitEnd && (connectionEnd[0] === 'salida' || connectionEnd[0] === 'entrada') && connectionEnd.length === 1) {
          features[valueHighway.properties._osm_way_id] = valueHighway;
          features[valueHighway.properties._osm_way_id + 'P'] = turf.point(firstCoor);
        }
      }
    }
  }

  var result = _.values(features);
  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }
  done(null, null);

};

function connection(position, oneway) {
  if (position === 'first' && oneway === -1) {
    return 'entrada';
  } else if (position === 'first' && (oneway === 'yes' || oneway === 1)) {
    return 'salida';
  } else if (position === 'end' && (oneway === 'yes' || oneway === 1)) {
    return 'entrada';
  } else if (position === 'end' && oneway === -1) {
    return 'salida';
  } else {
    return 'connecion';
  }
}<|endoftext|>


<commit_before>import {
  GPS_FAVORITE,
  GPS_FAVORITE_REMOVE,
  GPS_AVOID,
  GPS_AVOID_REMOVE,
  GPS_SEARCH,
  CREATE_ROUTE,
  DELETE_ROUTE,
  CLEAR_ROUTE_HISTORY,
} from '../actions'

export const initialState = {
  favorites: [{
    id: 30000142,
    name: 'Jita',
    sec: 0.945913117
  //}, {
  //  id: 30002053,
  //  name: "Hek",
  //  sec: 0.549668267
  //}, {
  //  id: 30002659,
  //  name: "Dodixie",
  //  sec: 0.868406702
  //}, {
  //  id: 30002187,
  //  name: "Amarr",
  //  sec: 1
  }],
  avoidance: [],
  routes: [],
  search: {
    origin: '',
    destination: '',
  }
}

export const createRoute = (state, action) => {
  const { systems } = action
  const [origin, jumps, destination] = [
    systems[0],
    systems.length,
    systems.slice().pop()
  ]
  const avgSec = systems.reduce((m, s) => m + s.sec, 0) / jumps
  const safetyScore = avgSec //* systems.reduce((m, s) => m + (-1+s.sec), 0) // higher = more dangerous
  const bestSec = systems.reduce((memo, {sec}) => Math.max(sec, memo), -1)
  const worstSec = systems.reduce((memo, {sec}) => Math.min(sec, memo), 1)
  const routes = [{
    origin,
    jumps,
    destination,
    systems,
    safetyScore,
    bestSec,
    worstSec,
  }, ...state.routes]
  return Object.assign({}, state, { routes })
}

export const search = (state, action) => {
  const { origin, destination } = action
  const search = {
    origin: origin || state.origin,
    destination: destination || state.destination,
  }

  return Object.assign({}, state, { search })
}

export const addFavorite = (state, {system}) => {
  const favorites = state.favorites.find(fav => fav.id === system.id)
  ? state.favorites
  : [...state.favorites, system]
  return Object.assign({}, state, { favorites })
}

export const removeFavorite = (state, {system}) => {
  const favorites = state.favorites.filter(fav => fav.id !== system.id)
  return Object.assign({}, state, { favorites })
}

export const deleteRouteByOrigin = (state, {origin}) => {
  const route = state.routes.filter(r => route.origin.id !== origin.id)
  return Object.assign({}, state, { routes })
}

export const gps = (state=initialState, action) => {
  switch(action.type) {

    case CREATE_ROUTE:
      return createRoute(state, action)
    case DELETE_ROUTE:
      return deleteRouteByOrigin(state, action)
    case CLEAR_ROUTE_HISTORY:
      return Object.assign(state, {routes: []})
    case GPS_SEARCH:
      return search(state, action)
    case GPS_FAVORITE:
      return addFavorite(state, action)
    case GPS_FAVORITE_REMOVE:
      return removeFavorite(state, action)
  }

  return state
}
<commit_msg>added deleteRoute to gps reducer<commit_after>import {
  GPS_FAVORITE,
  GPS_FAVORITE_REMOVE,
  GPS_AVOID,
  GPS_AVOID_REMOVE,
  GPS_SEARCH,
  CREATE_ROUTE,
  DELETE_ROUTE,
  CLEAR_ROUTE_HISTORY,
} from '../actions'

export const initialState = {
  favorites: [{
    id: 30000142,
    name: 'Jita',
    sec: 0.945913117
  //}, {
  //  id: 30002053,
  //  name: "Hek",
  //  sec: 0.549668267
  //}, {
  //  id: 30002659,
  //  name: "Dodixie",
  //  sec: 0.868406702
  //}, {
  //  id: 30002187,
  //  name: "Amarr",
  //  sec: 1
  }],
  avoidance: [],
  routes: [],
  search: {
    origin: '',
    destination: '',
  }
}

export const createRoute = (state, action) => {
  const { systems } = action
  const [origin, jumps, destination] = [
    systems[0],
    systems.length,
    systems.slice().pop()
  ]
  const avgSec = systems.reduce((m, s) => m + s.sec, 0) / jumps
  const safetyScore = avgSec //* systems.reduce((m, s) => m + (-1+s.sec), 0) // higher = more dangerous
  const bestSec = systems.reduce((memo, {sec}) => Math.max(sec, memo), -1)
  const worstSec = systems.reduce((memo, {sec}) => Math.min(sec, memo), 1)
  const routes = [{
    origin,
    jumps,
    destination,
    systems,
    safetyScore,
    bestSec,
    worstSec,
  }, ...state.routes]
  return Object.assign({}, state, { routes })
}

export const search = (state, action) => {
  const { origin, destination } = action
  const search = {
    origin: origin || state.origin,
    destination: destination || state.destination,
  }

  return Object.assign({}, state, { search })
}

export const addFavorite = (state, {system}) => {
  const favorites = state.favorites.find(fav => fav.id === system.id)
  ? state.favorites
  : [...state.favorites, system]
  return Object.assign({}, state, { favorites })
}

export const removeFavorite = (state, {system}) => {
  const favorites = state.favorites.filter(fav => fav.id !== system.id)
  return Object.assign({}, state, { favorites })
}

export const deleteRouteByOrigin = (state, {origin}) => {
  const route = state.routes.filter(r => route.origin.id !== origin.id)
  return Object.assign({}, state, { routes })
}

export const deleteRoute = (state, {origin, destination}) => {
  const routes = state.routes.filter(route => {
    return !((origin.id === route.origin.id) && (destination.id === route.destination.id))
  })
  return Object.assign({}, state, { routes })
}

export const gps = (state=initialState, action) => {
  switch(action.type) {

    case CREATE_ROUTE:
      return createRoute(state, action)
    case DELETE_ROUTE:
      return deleteRoute(state, action)
    case CLEAR_ROUTE_HISTORY:
      return Object.assign(state, {routes: []})
    case GPS_SEARCH:
      return search(state, action)
    case GPS_FAVORITE:
      return addFavorite(state, action)
    case GPS_FAVORITE_REMOVE:
      return removeFavorite(state, action)
  }

  return state
}
<|endoftext|>


<commit_before>import React from 'react';
import cx from 'classnames';
import omit from 'lodash/object/omit';

const propTypes = {
  children: React.PropTypes.node.isRequired,
  component: React.PropTypes.any,
  transitionStyles: React.PropTypes.shape({
    enter: React.PropTypes.object,
    enterActive: React.PropTypes.object,
    default: React.PropTypes.object,
    leave: React.PropTypes.object,
    leaveActive: React.PropTypes.object
  }).isRequired,
  transitionEnterTimeout: React.PropTypes.number.isRequired,
  transitionLeaveTimeout: React.PropTypes.number.isRequired,
  className: React.PropTypes.string,
  style: React.PropTypes.object.isRequired
};

const TransitionWrapper = React.createClass({

  propTypes: propTypes,

  getDefaultProps() {
    return {
      component: 'div'
    };
  },

  startAnimation(anim, timeout, callback) {
    const { transitionStyles } = this.props;
    const animationStart = transitionStyles[anim];
    const animationEnd = transitionStyles[`${anim}Active`];

    const initState = { animationStart, transitionClassName: anim };
    const activeState = { animationEnd, transitionClassName: cx(anim, `${anim}-active`) };

    this.replaceState(initState);
    setTimeout(() => {
      this.setState(activeState);
      setTimeout(callback, timeout);
    }, 30); // if the render is too fast the animation fails... 30ms is an empiric value.
  },

  componentWillAppear(callback) {
    this.componentWillEnter(callback);
  },

  componentDidAppear(callback) {
    this.componentDidEnter(callback);
  },

  componentWillEnter(callback) {
    this.startAnimation('enter', this.props.transitionEnterTimeout, callback);
  },

  componentDidEnter() {
    this.replaceState({ defaultStyle: this.props.transitionStyles.default});
  },

  componentWillLeave(callback) {
    this.leaving = true;
    this.startAnimation('leave', this.props.transitionLeaveTimeout, callback);
  },

  getStyle() {
    const { style } = this.props;
    const { animationStart, animationEnd, defaultStyle } = this.state;
    const userTransform = (animationEnd || animationStart || defaultStyle || {}).transform;

    return {
      ...style,
      ...defaultStyle,
      ...animationStart,
      ...animationEnd,
      transform: cx(userTransform, style.transform)
    };
  },

  render() {
    if (!this.state) {
      return null;
    }
    const { children, className, component } = this.props;
    const { transitionClassName } = this.state;

    const props = {
      className: cx(className, transitionClassName),
      style: this.getStyle(),
      ...omit(this.props, Object.keys(propTypes))
    };

    return React.createElement(
      component,
      props,
      children
    );
  }

});

export default TransitionWrapper;
<commit_msg>style and transitionStyles shouldn't be required<commit_after>import React from 'react';
import cx from 'classnames';
import omit from 'lodash/object/omit';

const propTypes = {
  children: React.PropTypes.node.isRequired,
  component: React.PropTypes.any,
  transitionStyles: React.PropTypes.shape({
    enter: React.PropTypes.object,
    enterActive: React.PropTypes.object,
    default: React.PropTypes.object,
    leave: React.PropTypes.object,
    leaveActive: React.PropTypes.object
  }),
  transitionEnterTimeout: React.PropTypes.number.isRequired,
  transitionLeaveTimeout: React.PropTypes.number.isRequired,
  className: React.PropTypes.string,
  style: React.PropTypes.object
};

const TransitionWrapper = React.createClass({

  propTypes: propTypes,

  getDefaultProps() {
    return {
      transitionStyles: {},
      style: {},
      component: 'div'
    };
  },

  startAnimation(anim, timeout, callback) {
    const { transitionStyles } = this.props;
    const animationStart = transitionStyles[anim];
    const animationEnd = transitionStyles[`${anim}Active`];

    const initState = { animationStart, transitionClassName: anim };
    const activeState = { animationEnd, transitionClassName: cx(anim, `${anim}-active`) };

    this.replaceState(initState);
    setTimeout(() => {
      this.setState(activeState);
      setTimeout(callback, timeout);
    }, 30); // if the render is too fast the animation fails... 30ms is an empiric value.
  },

  componentWillAppear(callback) {
    this.componentWillEnter(callback);
  },

  componentDidAppear(callback) {
    this.componentDidEnter(callback);
  },

  componentWillEnter(callback) {
    this.startAnimation('enter', this.props.transitionEnterTimeout, callback);
  },

  componentDidEnter() {
    this.replaceState({ defaultStyle: this.props.transitionStyles.default });
  },

  componentWillLeave(callback) {
    this.leaving = true;
    this.startAnimation('leave', this.props.transitionLeaveTimeout, callback);
  },

  getStyle() {
    const { style } = this.props;
    const { animationStart, animationEnd, defaultStyle } = this.state;
    const userTransform = (animationEnd || animationStart || defaultStyle || {}).transform;

    return {
      ...style,
      ...defaultStyle,
      ...animationStart,
      ...animationEnd,
      transform: cx(userTransform, style.transform)
    };
  },

  render() {
    if (!this.state) {
      return null;
    }
    const { children, className, component } = this.props;
    const { transitionClassName } = this.state;

    const props = {
      className: cx(className, transitionClassName),
      style: this.getStyle(),
      ...omit(this.props, Object.keys(propTypes))
    };

    return React.createElement(
      component,
      props,
      children
    );
  }

});

export default TransitionWrapper;
<|endoftext|>


<commit_before>const qs = require('querystring');
const syn = require('syn');
const { waitFor, waitForElement } = require('../../utils/ui');

describe('Opening a Runtime', () => {
  let iframe;
  let rtIframe;
  const runtimeDefinition = {
    id: '7695e97e-79a5-4a22-879d-847ec9592136',
    protocol: 'iframe',
    type: 'noflo-nodejs',
    address: '/base/spec/mockruntime.html',
    secret: 'foo',
  };
  const capabilities = [
    'protocol:graph',
    'protocol:component',
    'protocol:network',
    'protocol:runtime',
    'component:getsource',
  ];
  const graphDefinition = {
    caseSensitive: false,
    properties: {
      name: 'main',
      environment: {
        type: runtimeDefinition.type,
      },
    },
    inports: {},
    outports: {},
    groups: [],
    processes: {
      one: {
        component: 'core/Repeat',
        metadata: {
          label: 'One',
          x: 324,
          y: 108,
        },
      },
      two: {
        component: 'core/Repeat',
        metadata: {
          label: 'Two',
          x: 504,
          y: 108,
        },
      },
    },
    connections: [
      {
        src: {
          process: 'one',
          port: 'out',
        },
        tgt: {
          process: 'two',
          port: 'in',
        },
        metadata: {
          route: 4,
        },
      },
    ],
  };

  before('get the app iframe', () => {
    iframe = document.getElementById('app');
  });

  describe('when app receives a runtime URL', () => {
    it('should connect to runtime', () => {
      const endpointUrl = qs.stringify({
        protocol: runtimeDefinition.protocol,
        address: runtimeDefinition.address,
        id: runtimeDefinition.id,
        secret: runtimeDefinition.secret,
      });
      iframe.src = `/base/index.html#runtime/endpoint?${endpointUrl}`;
      return waitForElement(`iframe.iframe-runtime[data-runtime='${runtimeDefinition.id}']`)
        .then(element => new Promise((resolve) => {
          rtIframe = element;
          rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
            chai.expect(msg.protocol).to.equal('runtime');
            chai.expect(msg.command).to.equal('getruntime');
            send('runtime', 'runtime', {
              id: runtimeDefinition.id,
              type: runtimeDefinition.type,
              capabilities,
              version: '0.7',
              graph: 'foo/bar',
              namespace: 'foo',
            });
            resolve();
          });
        }));
    }).timeout(30000);
    it('should request sources for the main graph', (done) => {
      rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('getsource');
        chai.expect(msg.payload.name).to.equal('foo/bar');
        send('component', 'source', {
          code: JSON.stringify(graphDefinition),
          language: 'json',
          library: 'foo',
          name: 'bar',
        });
        done();
      });
    });
    it('should request a list of components', (done) => {
      const sendComponents = (msg, send, callback) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('list');
        send('component', 'component', {
          name: 'core/Repeat',
          description: 'Repeat a packet',
          icon: 'forward',
          subgraph: false,
          inPorts: [
            {
              addressable: false,
              id: 'in',
              type: 'all',
            },
          ],
          outPorts: [
            {
              addressable: false,
              id: 'in',
              type: 'all',
            },
          ],
        });
        send('component', 'componentsready', 1);
        callback();
      };
      // FIXME: Right now live mode requests component list twice (once in OpenLiveMode
      // and once in ListenRuntime). Should be made to request once and reuse
      rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
        sendComponents(msg, send, () => {
          rtIframe.contentWindow.handleProtocolMessage((msg2, send2) => {
            sendComponents(msg2, send2, done);
          });
        });
      });
    });
    it('should request the network status', (done) => {
      rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('network');
        chai.expect(msg.command).to.equal('getstatus');
        chai.expect(msg.payload.graph).to.equal('foo/bar');
        send('network', 'status', {
          graph: 'foo/bar',
          running: true,
          started: true,
        });
        done();
      });
    });
    it('should have opened the graph editor', () => waitForElement('noflo-ui the-graph-editor the-graph g.graph')
      .then(graphNode => graphNode.querySelectorAll('g.nodes g.node'))
      .then((nodes) => {
        const nodesArray = Array.prototype.slice.call(nodes);
        chai.expect(nodesArray.length).to.equal(2);
        const titles = nodesArray.map(n => n.getAttribute('name'));
        chai.expect(titles).to.eql(['one', 'two']);
      }));
    it('should show the graph name in the search bar', () => waitForElement('noflo-ui noflo-search h1 span')
      .then((searchTitle) => {
        chai.expect(searchTitle.innerHTML).to.equal('foo/bar');
      }));
    it('should show the graph as "running"', () => waitFor(1000) // Seems this one takes sometimes a while to update
      .then(() => waitForElement('noflo-ui noflo-runtime #runcontrol h2'))
      .then((runtimestatus) => {
        chai.expect(runtimestatus.innerHTML).to.equal('running');
      }));
    describe('packet inspection', () => {
      let edgeInspector;
      before('send a packet', () => {
        rtIframe.contentWindow.sendProtocolMessage('network', 'data', {
          data: 'packet one',
          graph: 'foo/bar',
          id: 'one() OUT -> IN two()',
          src: {
            node: 'one',
            port: 'out',
          },
          tgt: {
            node: 'two',
            port: 'in',
          },
        });
      });
      it('should show edge inspector when clicking on a wire', () => waitForElement('noflo-ui the-graph-editor the-graph g.edges g.edge')
        .then((edge) => {
          syn.click(edge);
        })
        .then(() => waitForElement('noflo-ui noflo-context section#contextsection the-card noflo-edge-inspector'))
        .then((element) => {
          edgeInspector = element;
        }));
      it('should send the selected edges to the runtime', (done) => {
        rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
          chai.expect(msg.protocol).to.equal('network');
          chai.expect(msg.command).to.equal('edges');
          chai.expect(msg.payload.graph).to.equal('foo/bar');
          chai.expect(msg.payload.edges.length).to.equal(1);
          send('network', 'edges', {
            edges: msg.payload.edges,
            graph: msg.payload.graph,
          });
          done();
        });
      });
      it('should show the edge title in the inspector', () => waitForElement('header h1', edgeInspector)
        .then((edgeTitle) => {
          chai.expect(edgeTitle.innerText).to.contain('one OUT');
          chai.expect(edgeTitle.innerText).to.contain('IN two');
        }));
      it('should show the first packet in the inspector', () => waitForElement('ul#events', edgeInspector)
        .then((eventsList) => {
          const packets = Array.prototype.slice.call(eventsList.querySelectorAll('li.data'));
          const packetValues = packets.map(p => p.innerText);
          chai.expect(packetValues).to.eql(['packet one']);
        }));
      it('closing the edge inspector', () => waitForElement('noflo-ui the-graph-editor the-graph svg.app-svg')
        .then((edge) => {
          syn.click(edge);
        }));
      it('should send the selected edges to the runtime', (done) => {
        rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
          chai.expect(msg.protocol).to.equal('network');
          chai.expect(msg.command).to.equal('edges');
          chai.expect(msg.payload.graph).to.equal('foo/bar');
          chai.expect(msg.payload.edges).to.eql([]);
          send('network', 'edges', {
            edges: msg.payload.edges,
            graph: msg.payload.graph,
          });
          done();
        });
      });
    });
    describe('opening a node', () => {
      let nodeMenuOption;
      it('should show a menu on right click on a node', () => waitForElement('noflo-ui the-graph-editor the-graph g.nodes g.node')
        .then((node) => {
          syn.rightClick(node);
        })
        .then(() => waitForElement('noflo-ui the-graph-editor the-graph g.context g.context-slice'))
        .then((element) => {
          nodeMenuOption = element;
        }));
      it('should contain a clickable "open" option', () => {
        const elementText = nodeMenuOption.querySelector('text.context-arc-icon-label');
        chai.expect(elementText.innerHTML).to.equal('open');
        syn.click(nodeMenuOption);
      });
      it('should trigger the "loading" indicator', () => waitForElement('noflo-ui noflo-alert.show span')
        .then((loader) => {
          chai.expect(loader.innerText).to.equal('loading');
        }));
      it('should request source code for the component', (done) => {
        rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
          chai.expect(msg.protocol).to.equal('component');
          chai.expect(msg.command).to.equal('getsource');
          chai.expect(msg.payload.name).to.equal('foo/bar');
          send('component', 'source', {
            code: JSON.stringify(graphDefinition),
            language: 'json',
            library: 'foo',
            name: 'bar',
          });
          rtIframe.contentWindow.handleProtocolMessage((msg2, send2) => {
            chai.expect(msg2.protocol).to.equal('component');
            chai.expect(msg2.command).to.equal('getsource');
            chai.expect(msg2.payload.name).to.equal('core/Repeat');
            send2('component', 'source', {
              code: 'hello, world',
              language: 'javascript',
              library: 'core',
              name: 'Repeat',
            });
            done();
          });
        });
      });
      it('should show the source code in the editor', () => waitForElement('noflo-ui noflo-component-editor #code .CodeMirror-lines')
        .then((element) => {
          chai.expect(element.innerText).to.contain('hello, world');
        }));
    });
  });
});
<commit_msg>Scope edge inspector selector correctly<commit_after>const qs = require('querystring');
const syn = require('syn');
const { waitFor, waitForElement } = require('../../utils/ui');

describe('Opening a Runtime', () => {
  let iframe;
  let rtIframe;
  const runtimeDefinition = {
    id: '7695e97e-79a5-4a22-879d-847ec9592136',
    protocol: 'iframe',
    type: 'noflo-nodejs',
    address: '/base/spec/mockruntime.html',
    secret: 'foo',
  };
  const capabilities = [
    'protocol:graph',
    'protocol:component',
    'protocol:network',
    'protocol:runtime',
    'component:getsource',
  ];
  const graphDefinition = {
    caseSensitive: false,
    properties: {
      name: 'main',
      environment: {
        type: runtimeDefinition.type,
      },
    },
    inports: {},
    outports: {},
    groups: [],
    processes: {
      one: {
        component: 'core/Repeat',
        metadata: {
          label: 'One',
          x: 324,
          y: 108,
        },
      },
      two: {
        component: 'core/Repeat',
        metadata: {
          label: 'Two',
          x: 504,
          y: 108,
        },
      },
    },
    connections: [
      {
        src: {
          process: 'one',
          port: 'out',
        },
        tgt: {
          process: 'two',
          port: 'in',
        },
        metadata: {
          route: 4,
        },
      },
    ],
  };

  before('get the app iframe', () => {
    iframe = document.getElementById('app');
  });

  describe('when app receives a runtime URL', () => {
    it('should connect to runtime', () => {
      const endpointUrl = qs.stringify({
        protocol: runtimeDefinition.protocol,
        address: runtimeDefinition.address,
        id: runtimeDefinition.id,
        secret: runtimeDefinition.secret,
      });
      iframe.src = `/base/index.html#runtime/endpoint?${endpointUrl}`;
      return waitForElement(`iframe.iframe-runtime[data-runtime='${runtimeDefinition.id}']`)
        .then(element => new Promise((resolve) => {
          rtIframe = element;
          rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
            chai.expect(msg.protocol).to.equal('runtime');
            chai.expect(msg.command).to.equal('getruntime');
            send('runtime', 'runtime', {
              id: runtimeDefinition.id,
              type: runtimeDefinition.type,
              capabilities,
              version: '0.7',
              graph: 'foo/bar',
              namespace: 'foo',
            });
            resolve();
          });
        }));
    }).timeout(30000);
    it('should request sources for the main graph', (done) => {
      rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('getsource');
        chai.expect(msg.payload.name).to.equal('foo/bar');
        send('component', 'source', {
          code: JSON.stringify(graphDefinition),
          language: 'json',
          library: 'foo',
          name: 'bar',
        });
        done();
      });
    });
    it('should request a list of components', (done) => {
      const sendComponents = (msg, send, callback) => {
        chai.expect(msg.protocol).to.equal('component');
        chai.expect(msg.command).to.equal('list');
        send('component', 'component', {
          name: 'core/Repeat',
          description: 'Repeat a packet',
          icon: 'forward',
          subgraph: false,
          inPorts: [
            {
              addressable: false,
              id: 'in',
              type: 'all',
            },
          ],
          outPorts: [
            {
              addressable: false,
              id: 'in',
              type: 'all',
            },
          ],
        });
        send('component', 'componentsready', 1);
        callback();
      };
      // FIXME: Right now live mode requests component list twice (once in OpenLiveMode
      // and once in ListenRuntime). Should be made to request once and reuse
      rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
        sendComponents(msg, send, () => {
          rtIframe.contentWindow.handleProtocolMessage((msg2, send2) => {
            sendComponents(msg2, send2, done);
          });
        });
      });
    });
    it('should request the network status', (done) => {
      rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
        chai.expect(msg.protocol).to.equal('network');
        chai.expect(msg.command).to.equal('getstatus');
        chai.expect(msg.payload.graph).to.equal('foo/bar');
        send('network', 'status', {
          graph: 'foo/bar',
          running: true,
          started: true,
        });
        done();
      });
    });
    it('should have opened the graph editor', () => waitForElement('noflo-ui the-graph-editor the-graph g.graph')
      .then(graphNode => graphNode.querySelectorAll('g.nodes g.node'))
      .then((nodes) => {
        const nodesArray = Array.prototype.slice.call(nodes);
        chai.expect(nodesArray.length).to.equal(2);
        const titles = nodesArray.map(n => n.getAttribute('name'));
        chai.expect(titles).to.eql(['one', 'two']);
      }));
    it('should show the graph name in the search bar', () => waitForElement('noflo-ui noflo-search h1 span')
      .then((searchTitle) => {
        chai.expect(searchTitle.innerHTML).to.equal('foo/bar');
      }));
    it('should show the graph as "running"', () => waitFor(1000) // Seems this one takes sometimes a while to update
      .then(() => waitForElement('noflo-ui noflo-runtime #runcontrol h2'))
      .then((runtimestatus) => {
        chai.expect(runtimestatus.innerHTML).to.equal('running');
      }));
    describe('packet inspection', () => {
      let edgeInspector;
      before('send a packet', () => {
        rtIframe.contentWindow.sendProtocolMessage('network', 'data', {
          data: 'packet one',
          graph: 'foo/bar',
          id: 'one() OUT -> IN two()',
          src: {
            node: 'one',
            port: 'out',
          },
          tgt: {
            node: 'two',
            port: 'in',
          },
        });
      });
      it('should show edge inspector when clicking on a wire', () => waitForElement('noflo-ui the-graph-editor the-graph g.edges g.edge')
        .then((edge) => {
          syn.click(edge);
        })
        .then(() => waitForElement('noflo-ui noflo-context section#contextsection the-card noflo-edge-inspector'))
        .then((element) => {
          edgeInspector = element;
        }));
      it('should send the selected edges to the runtime', (done) => {
        rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
          chai.expect(msg.protocol).to.equal('network');
          chai.expect(msg.command).to.equal('edges');
          chai.expect(msg.payload.graph).to.equal('foo/bar');
          chai.expect(msg.payload.edges.length).to.equal(1);
          send('network', 'edges', {
            edges: msg.payload.edges,
            graph: msg.payload.graph,
          });
          done();
        });
      });
      it('should show the edge title in the inspector', () => waitForElement('header h1', true, edgeInspector)
        .then((edgeTitle) => {
          chai.expect(edgeTitle.innerText).to.contain('one OUT');
          chai.expect(edgeTitle.innerText).to.contain('IN two');
        }));
      it('should show the first packet in the inspector', () => waitForElement('ul#events', true, edgeInspector)
        .then((eventsList) => {
          const packets = Array.prototype.slice.call(eventsList.querySelectorAll('li.data'));
          const packetValues = packets.map(p => p.innerText);
          chai.expect(packetValues).to.eql(['packet one']);
        }));
      it('closing the edge inspector', () => waitForElement('noflo-ui the-graph-editor the-graph svg.app-svg')
        .then((edge) => {
          syn.click(edge);
        }));
      it('should send the selected edges to the runtime', (done) => {
        rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
          chai.expect(msg.protocol).to.equal('network');
          chai.expect(msg.command).to.equal('edges');
          chai.expect(msg.payload.graph).to.equal('foo/bar');
          chai.expect(msg.payload.edges).to.eql([]);
          send('network', 'edges', {
            edges: msg.payload.edges,
            graph: msg.payload.graph,
          });
          done();
        });
      });
    });
    describe('opening a node', () => {
      let nodeMenuOption;
      it('should show a menu on right click on a node', () => waitForElement('noflo-ui the-graph-editor the-graph g.nodes g.node')
        .then((node) => {
          syn.rightClick(node);
        })
        .then(() => waitForElement('noflo-ui the-graph-editor the-graph g.context g.context-slice'))
        .then((element) => {
          nodeMenuOption = element;
        }));
      it('should contain a clickable "open" option', () => {
        const elementText = nodeMenuOption.querySelector('text.context-arc-icon-label');
        chai.expect(elementText.innerHTML).to.equal('open');
        syn.click(nodeMenuOption);
      });
      it('should trigger the "loading" indicator', () => waitForElement('noflo-ui noflo-alert.show span')
        .then((loader) => {
          chai.expect(loader.innerText).to.equal('loading');
        }));
      it('should request source code for the component', (done) => {
        rtIframe.contentWindow.handleProtocolMessage((msg, send) => {
          chai.expect(msg.protocol).to.equal('component');
          chai.expect(msg.command).to.equal('getsource');
          chai.expect(msg.payload.name).to.equal('foo/bar');
          send('component', 'source', {
            code: JSON.stringify(graphDefinition),
            language: 'json',
            library: 'foo',
            name: 'bar',
          });
          rtIframe.contentWindow.handleProtocolMessage((msg2, send2) => {
            chai.expect(msg2.protocol).to.equal('component');
            chai.expect(msg2.command).to.equal('getsource');
            chai.expect(msg2.payload.name).to.equal('core/Repeat');
            send2('component', 'source', {
              code: 'hello, world',
              language: 'javascript',
              library: 'core',
              name: 'Repeat',
            });
            done();
          });
        });
      });
      it('should show the source code in the editor', () => waitForElement('noflo-ui noflo-component-editor #code .CodeMirror-lines')
        .then((element) => {
          chai.expect(element.innerText).to.contain('hello, world');
        }));
    });
  });
});
<|endoftext|>


<commit_before>/* eslint-disable no-console */

import 'whatwg-fetch';

/**
 * Fetch the branches info for given repo directly per 'REST' from GitHub.
 *
 * @param repo <userName>/<repoName>, like lowsky/dashboard
 */
let fetchRepoBranches = repo => {
    let url = `https://api.github.com/repos/${repo}/branches`; // eslint-disable-line quotes
    return fetch(url).then(response => response.json());
};

/**
 * Fetch the user info for a given login directly per 'REST' from GitHub.
 *
 * @param login user's login name, e.g lowsky
 */
let fetchUser = login => {
    let url = `https://api.github.com/users/${login}`; // eslint-disable-line quotes
    return fetch(url).then(response => response.json());
};

export default {
    fetchUser,
    fetchRepoBranches,
};
<commit_msg>use async/await<commit_after>/* eslint-disable no-console */

import 'whatwg-fetch';

/**
 * Fetch the branches info for given repo directly per 'REST' from GitHub.
 *
 * @param repo <userName>/<repoName>, like lowsky/dashboard
 */
let fetchRepoBranches = async repo => {
    let url = `https://api.github.com/repos/${repo}/branches`; // eslint-disable-line quotes
    let response = await fetch(url);
    return await response.json();
};

/**
 * Fetch the user info for a given login directly per 'REST' from GitHub.
 *
 * @param login user's login name, e.g lowsky
 */
let fetchUser = async login => {
    let url = `https://api.github.com/users/${login}`; // eslint-disable-line quotes
    let response = await fetch(url);
    return await response.json();
};

export default {
    fetchUser,
    fetchRepoBranches,
};
<|endoftext|>


<commit_before>const choo = require('choo');
const html = require('choo/html');
const download = require('./download');
const header = require('../templates/header');
const footer = require('../templates/footer');
const fxPromo = require('../templates/fxPromo');

const app = choo();

function body(template) {
  return function(state, emit) {
    const b = html`
      ${state.promo ? fxPromo(state, emit) : ''}
      ${header(state)}

Firefox Send requires JavaScript

Why does Firefox Send require JavaScript?

Please enable JavaScript and try again.

        ${template(state, emit)}

      ${footer(state)}
    `;
    if (state.layout) {
      return state.layout(state, b);
    }
    return b;
  };
}

app.route('/', body(require('./home')));
app.route('/share/:id', body(require('../templates/share')));
app.route('/download/:id', body(download));
app.route('/download/:id/:key', body(download));
app.route('/completed', body(require('../templates/completed')));
app.route('/unsupported/:reason', body(require('../templates/unsupported')));
app.route('/legal', body(require('../templates/legal')));
app.route('/error', body(require('../templates/error')));
app.route('/blank', body(require('../templates/blank')));
app.route('*', body(require('../templates/notFound')));

module.exports = app;
<commit_msg>Restricted the banner from showing on unsupported browsers<commit_after>const choo = require('choo');
const html = require('choo/html');
const download = require('./download');
const header = require('../templates/header');
const footer = require('../templates/footer');
const fxPromo = require('../templates/fxPromo');

const app = choo();

function showBanner(state) {
  return state.promo && !state.route.startsWith('/unsupported/');
}

function body(template) {
  return function(state, emit) {
    const b = html`
      ${showBanner(state) ? fxPromo(state, emit) : ''}
      ${header(state)}

Firefox Send requires JavaScript

Why does Firefox Send require JavaScript?

Please enable JavaScript and try again.

        ${template(state, emit)}

      ${footer(state)}
    `;
    if (state.layout) {
      return state.layout(state, b);
    }
    return b;
  };
}

app.route('/', body(require('./home')));
app.route('/share/:id', body(require('../templates/share')));
app.route('/download/:id', body(download));
app.route('/download/:id/:key', body(download));
app.route('/completed', body(require('../templates/completed')));
app.route('/unsupported/:reason', body(require('../templates/unsupported')));
app.route('/legal', body(require('../templates/legal')));
app.route('/error', body(require('../templates/error')));
app.route('/blank', body(require('../templates/blank')));
app.route('*', body(require('../templates/notFound')));

module.exports = app;
<|endoftext|>


<commit_before>$(document).ready(function() {
    $('#surname').blur(function() {
        matchVolunteerPerson();
    });

    $(".datepicker").datepicker({
        dateFormat: "dd/mm/yy"
    });

    $("input[name=congregationName]").typeahead({
        source: function (query, process) {
            $.ajax({
                url: '../congregations/search',
                contentType: "application/json",
                dataType: 'json',
                data:  {
                    name: query
                },
                success: function(data) {
                    var results = [];
                    if(data.results) {
                        $.each(data.results, function() {
                            results.push(this.name);
                        });
                    }
                    return process(results);
                }
            });
        },
        minLength: 2
    });

    $("#volunteer").validate({
        rules: {
            forename: {
                minlength: 2,
                required: true
            },
            surname: {
                minlength: 2,
                required: true
            },
            gender: {
                required: true
            },
            birthDate: {
                required: true
            },
            baptismDate: {
                required: true
            },
            street: {
                minlength: 2,
                required: true
            },
            town: {
                minlength: 2,
                required: true
            },
            postcode: {
                minlength: 2,
                required: true
            },
            email: {
                required: true,
                email: true
            },
            maritalStatusId: {
                required: true
            },
            congregationName: {
                required: true,
                remote: {
                    // check for an exact match. Populate the congregation id
                    url: '../congregations/search',
                    contentType: "application/json",
                    dataType: 'json',
                    data: {
                        name: function() {
                            return $('input[name=congregationName]').val();
                        }
                    },
                    dataFilter: function(rawData) {
                        var data = JSON.parse(rawData)
                        if (data.results && data.results[0].name == $('input[name=congregationName]').val()) {
                            $('input[name=congregationId]').val(data.results[0].id);
                            return true;

                        }
                        return false;
                    }
                }
            },
            congregationId: {
                required: true
            },
            formDate: {
                required: true
            }
        },
        highlight: function(element) {
            $(element).closest('.control-group').removeClass('success').addClass('error');
        },
        success: function(element) {
            element.addClass('valid').closest('.control-group').removeClass('error').addClass('success');
        }

    });

});

function matchVolunteerPerson() {
    var forename = $('#forename').val();
    var surname = $('#surname').val();

    if(!forename || !surname) {
        return;
    }

    var $personId = $("input[name='personId']");

    var existingPersonName = $personId.data("full-name");
    if (existingPersonName == forename + " " + surname) {
        // no change in value
        return;
    }
    var existingPersonId = $personId.val();
    findVolunteerPerson(forename, surname, existingPersonId, existingPersonName);

    $personId.data("full-name", forename + " " + surname);
}

function findVolunteerPerson(forename, surname, existingPersonId, existingPersonName) {
    $.ajax({
        url: '../persons/search',
        contentType: "application/json",
        dataType: 'json',
        data:  {
            forename: forename,
            surname: surname,
            checkVolunteer: true
        },
        success: function(data) {
            // no match, and no person linked. We don't show anything
            if (!data.results && !existingPersonId) {
                return;
            }

            // enrich the results, splitting out the volunters from the persons.
            // if we are matching an existing volunteer we don't want to create a new one
            var volunteers = new Array();
            var persons = new Array();
            if (data.results) {
                for (var i = 0; i < data.results.length; i++) {
                    var result = data.results[i];

                    if (result.personId != existingPersonId) {
                        if (result.volunteer) {
                            volunteers.push(result);
                        } else {
                            persons.push(result);
                        }
                    }
                }
            }

            data.existingPersonId = existingPersonId;
            data.existingPersonName = existingPersonName;
            if (volunteers.length > 0) {
                data.matchedVolunteers = true;
                data.volunteers = volunteers;
            }

            if (persons.length > 0) {
                data.matchedPersons = true;
                data.persons = persons;
            }

            var template = $("#person-search-form").html();
            var html = Mustache.to_html(template, data);

            $("#volunteer-person-modal .modal-body").html(html)
            var modalElement = $("#volunteer-person-modal")

            modalElement.modal('show')

            // if they select the person id, set it to the hidden volunteer person id field
            $("a.matched-person").on("click", function(event){
                populateVolunteerFromPerson($(this).data("person-id"));
                modalElement.modal('hide')
            });
        }
    });
}

function populateVolunteerFromPerson(personId) {
    $personId = $("input[name='personId']");
    if (!personId) {
        $personId.val(personId);
        return;
    }
    var existingPersonId = $personId.val();

    if (existingPersonId == personId) {
        return;
    }

    // new person - pull the person data and populate the form.
    $.ajax({
        url: '../persons/' + personId,
        contentType: "application/json",
        dataType: 'json',
        success: function(data) {
            $("input[name='birthDate']").val(data.birthDate);
            $("input[name='middleName']").val(data.middleName);
            $("input[name='telephone']").val(data.telephone);
            $("input[name='mobile']").val(data.mobile);
            $("input[name='workPhone']").val(data.workPhone);
            $("input[name='email']").val(data.email);
            if(data.congregation) {
                $("input[name='congregationId']").val(data.congregation.congregationId);
            }
            if (data.address) {
                $("input[name='street']").val(data.address.street);
                $("input[name='town']").val(data.address.town);
                $("input[name='county']").val(data.address.county);
                $("input[name='postcode']").val(data.address.postcode);
            }
        }
    });
    $personId.val(personId);
}
<commit_msg>[#42842865] improve the error message positioning, especially for errors linked to radio button options<commit_after>$(document).ready(function() {
    $('#surname').blur(function() {
        matchVolunteerPerson();
    });

    $(".datepicker").datepicker({
        dateFormat: "dd/mm/yy"
    });

    $("input[name=congregationName]").typeahead({
        source: function (query, process) {
            $.ajax({
                url: '../congregations/search',
                contentType: "application/json",
                dataType: 'json',
                data:  {
                    name: query
                },
                success: function(data) {
                    var results = [];
                    if(data.results) {
                        $.each(data.results, function() {
                            results.push(this.name);
                        });
                    }
                    return process(results);
                }
            });
        },
        minLength: 2
    });

    $("#volunteer").validate({
        rules: {
            forename: {
                minlength: 2,
                required: true
            },
            surname: {
                minlength: 2,
                required: true
            },
            gender: {
                required: true
            },
            birthDate: {
                required: true
            },
            baptismDate: {
                required: true
            },
            street: {
                minlength: 2,
                required: true
            },
            town: {
                minlength: 2,
                required: true
            },
            postcode: {
                minlength: 2,
                required: true
            },
            email: {
                required: true,
                email: true
            },
            maritalStatusId: {
                required: true
            },
            congregationName: {
                required: true,
                remote: {
                    // check for an exact match. Populate the congregation id
                    url: '../congregations/search',
                    contentType: "application/json",
                    dataType: 'json',
                    data: {
                        name: function() {
                            return $('input[name=congregationName]').val();
                        }
                    },
                    dataFilter: function(rawData) {
                        var data = JSON.parse(rawData)
                        if (data.results && data.results[0].name == $('input[name=congregationName]').val()) {
                            $('input[name=congregationId]').val(data.results[0].id);
                            return true;

                        }
                        return false;
                    }
                }
            },
            congregationId: {
                required: true
            },
            formDate: {
                required: true
            }
        },
        highlight: function(element) {
            $(element).closest('.control-group').removeClass('success').addClass('error');
        },
        success: function(element) {
            element.addClass('valid').closest('.control-group').removeClass('error').addClass('success');
        }
        ,
        errorPlacement: function(error, element) {
            //error.appendTo(element.closest('.control-group').children("controls").last());
            var $controls = element.closest(".controls");
            if ($controls.length > 0) {
                error.appendTo($controls);
            } else {
                error.appendTo(element.closest(".control-group"));
            }
        }

    });

});

function matchVolunteerPerson() {
    var forename = $('#forename').val();
    var surname = $('#surname').val();

    if(!forename || !surname) {
        return;
    }

    var $personId = $("input[name='personId']");

    var existingPersonName = $personId.data("full-name");
    if (existingPersonName == forename + " " + surname) {
        // no change in value
        return;
    }
    var existingPersonId = $personId.val();
    findVolunteerPerson(forename, surname, existingPersonId, existingPersonName);

    $personId.data("full-name", forename + " " + surname);
}

function findVolunteerPerson(forename, surname, existingPersonId, existingPersonName) {
    $.ajax({
        url: '../persons/search',
        contentType: "application/json",
        dataType: 'json',
        data:  {
            forename: forename,
            surname: surname,
            checkVolunteer: true
        },
        success: function(data) {
            // no match, and no person linked. We don't show anything
            if (!data.results && !existingPersonId) {
                return;
            }

            // enrich the results, splitting out the volunters from the persons.
            // if we are matching an existing volunteer we don't want to create a new one
            var volunteers = new Array();
            var persons = new Array();
            if (data.results) {
                for (var i = 0; i < data.results.length; i++) {
                    var result = data.results[i];

                    if (result.personId != existingPersonId) {
                        if (result.volunteer) {
                            volunteers.push(result);
                        } else {
                            persons.push(result);
                        }
                    }
                }
            }

            data.existingPersonId = existingPersonId;
            data.existingPersonName = existingPersonName;
            if (volunteers.length > 0) {
                data.matchedVolunteers = true;
                data.volunteers = volunteers;
            }

            if (persons.length > 0) {
                data.matchedPersons = true;
                data.persons = persons;
            }

            var template = $("#person-search-form").html();
            var html = Mustache.to_html(template, data);

            $("#volunteer-person-modal .modal-body").html(html)
            var modalElement = $("#volunteer-person-modal")

            modalElement.modal('show')

            // if they select the person id, set it to the hidden volunteer person id field
            $("a.matched-person").on("click", function(event){
                populateVolunteerFromPerson($(this).data("person-id"));
                modalElement.modal('hide')
            });
        }
    });
}

function populateVolunteerFromPerson(personId) {
    $personId = $("input[name='personId']");
    if (!personId) {
        $personId.val(personId);
        return;
    }
    var existingPersonId = $personId.val();

    if (existingPersonId == personId) {
        return;
    }

    // new person - pull the person data and populate the form.
    $.ajax({
        url: '../persons/' + personId,
        contentType: "application/json",
        dataType: 'json',
        success: function(data) {
            $("input[name='birthDate']").val(data.birthDate);
            $("input[name='middleName']").val(data.middleName);
            $("input[name='telephone']").val(data.telephone);
            $("input[name='mobile']").val(data.mobile);
            $("input[name='workPhone']").val(data.workPhone);
            $("input[name='email']").val(data.email);
            if(data.congregation) {
                $("input[name='congregationId']").val(data.congregation.congregationId);
            }
            if (data.address) {
                $("input[name='street']").val(data.address.street);
                $("input[name='town']").val(data.address.town);
                $("input[name='county']").val(data.address.county);
                $("input[name='postcode']").val(data.address.postcode);
            }
        }
    });
    $personId.val(personId);
}
<|endoftext|>


<commit_before>import {
  hiddenFromAT
, devices
} from '../util'

export default ctx => function (tagName, props, children) {
  const hidden   = hiddenFromAT(props)
  const tabIndex = props.tabIndex === -1

  if ( hidden && !tabIndex ) {
    ctx.report({
      msg: 'You have `aria-hidden="true"` applied to an interactive element but have not '
         + 'removed it from the tab flow. This could result in a hidden tab stop for '
         + 'users of screen readers.'
    , url: 'http://john.foliot.ca/aria-hidden'
    , affects: [
        devices.screenReaders
      ]
    })
  }
}
<commit_msg>correct devices in hidden-uses-tabindex<commit_after>import {
  hiddenFromAT
, devices
} from '../util'

export default ctx => function (tagName, props, children) {
  const hidden   = hiddenFromAT(props)
  const tabIndex = props.tabIndex === -1

  if ( hidden && !tabIndex ) {
    ctx.report({
      msg: 'You have `aria-hidden="true"` applied to an interactive element but have not '
         + 'removed it from the tab flow. This could result in a hidden tab stop for '
         + 'users of screen readers.'
    , url: 'http://john.foliot.ca/aria-hidden'
    , affects: [
        devices.keyboardOnly
      , devices.screenReaders
      ]
    })
  }
}
<|endoftext|>


<commit_before>const path = require('path')
const assert = require('assert')
const _ = require('lodash')
const readGraph = require('../helpers/readGraph')
const countGraph = require('../helpers/countGraph')

const graph = readGraph('./graph')
const { nodeLabels, nodes, relationships, relationshipTypes, locales } = graph

describe('Graph', () => {

    it(`read (${countGraph(graph)})`, () => {

    })

    it('filenames should match assigned IDs', () => {
        const assertIdsMatch = (type, graphObject) => {
            const id = graphObject.content.id
            const filenameWithoutExt = path.basename(graphObject.absoluteFilePath, path.extname(graphObject.absoluteFilePath))
            assert.strictEqual(
                id,
                filenameWithoutExt,
                `${type}(${id}) does not match filename "${graphObject.absoluteFilePath}"`
            )
        }

        _.forEach(graph, (objects, type) => {
            objects.forEach(obj => assertIdsMatch(type, obj))
        })
    })

    it('IDs should be unique', () => {
        const dupes = _(nodes)
            .groupBy('content.id')
            .mapValues(group => group.length)
            .pickBy(length => length > 1)
            .keys()
            .value()

        assert.deepStrictEqual(dupes, [])
    })

    it('labels assigned to nodes should be defined', () => {
        nodes.forEach(node => {
            node.content.labels.forEach(labelId => {
                const labelExists = nodeLabels.some(nodeLabel => nodeLabel.content.id === labelId)
                assert.ok(labelExists, `Node(${node.content.id}) has unknown Label(${labelId})`)
            })
        })
    })

    it('nodes assigned to relationships should be defined', () => {
        relationships.forEach(relationship => {
            const nodesExist = _(nodes)
                .map(node => node.content.id)
                .includes(relationship.content.start, relationship.content.end)

            assert.ok(nodesExist, `Relationship(${relationship.content.id}) has unknown nodes`)
        })
    })

    describe('locale', () => {

        it('codes should match locale defined in graph', () => {
            _(nodes)
                .map('content')
                .filter('locale')
                .forEach(node => {
                    _.forEach(node.locale, (localeData, code) => {
                        assert.ok(
                            locales.some(locale => locale.content.id === code),
                            `Unknown language code "${code}" found in Node(${node.id})`
                        )
                    })
                })
        })

        it('field names should match base data field names', () => {
            _(nodes)
                .map('content')
                .filter('locale')
                .forEach(node => {
                    _.forEach(node.locale, (localeData, code) => {
                        const unknownFieldNames = _(localeData)
                            .keys()
                            .filter(fieldName => !node.data[fieldName])
                            .value()

                        assert.deepStrictEqual(unknownFieldNames, [], `Unknown fields found in Node(${node.id})'s "${code}" locale.`)
                    })
                })
        })
    })
})
<commit_msg>Stop iterating through nodes on every relationship to make test faster.<commit_after>const path = require('path')
const assert = require('assert')
const _ = require('lodash')
const readGraph = require('../helpers/readGraph')
const countGraph = require('../helpers/countGraph')

const graph = readGraph('./graph')
const { nodeLabels, nodes, relationships, relationshipTypes, locales } = graph

describe('Graph', () => {

    it(`read (${countGraph(graph)})`, () => {

    })

    it('filenames should match assigned IDs', () => {
        const assertIdsMatch = (type, graphObject) => {
            const id = graphObject.content.id
            const filenameWithoutExt = path.basename(graphObject.absoluteFilePath, path.extname(graphObject.absoluteFilePath))
            assert.strictEqual(
                id,
                filenameWithoutExt,
                `${type}(${id}) does not match filename "${graphObject.absoluteFilePath}"`
            )
        }

        _.forEach(graph, (objects, type) => {
            objects.forEach(obj => assertIdsMatch(type, obj))
        })
    })

    it('IDs should be unique', () => {
        const dupes = _(nodes)
            .groupBy('content.id')
            .mapValues(group => group.length)
            .pickBy(length => length > 1)
            .keys()
            .value()

        assert.deepStrictEqual(dupes, [])
    })

    it('labels assigned to nodes should be defined', () => {
        nodes.forEach(node => {
            node.content.labels.forEach(labelId => {
                const labelExists = nodeLabels.some(nodeLabel => nodeLabel.content.id === labelId)
                assert.ok(labelExists, `Node(${node.content.id}) has unknown Label(${labelId})`)
            })
        })
    })

    it('nodes assigned to relationships should be defined', () => {
        const nodesById = _(nodes).keyBy('content.id').value()
        relationships.forEach(relationship => {
            const nodesExist = nodesById[relationship.content.start] && nodesById[relationship.content.end]
            assert.ok(nodesExist, `Relationship(${relationship.content.id}) has unknown nodes`)
        })
    })

    describe('locale', () => {

        it('codes should match locale defined in graph', () => {
            _(nodes)
                .map('content')
                .filter('locale')
                .forEach(node => {
                    _.forEach(node.locale, (localeData, code) => {
                        assert.ok(
                            locales.some(locale => locale.content.id === code),
                            `Unknown language code "${code}" found in Node(${node.id})`
                        )
                    })
                })
        })

        it('field names should match base data field names', () => {
            _(nodes)
                .map('content')
                .filter('locale')
                .forEach(node => {
                    _.forEach(node.locale, (localeData, code) => {
                        const unknownFieldNames = _(localeData)
                            .keys()
                            .filter(fieldName => !node.data[fieldName])
                            .value()

                        assert.deepStrictEqual(unknownFieldNames, [], `Unknown fields found in Node(${node.id})'s "${code}" locale.`)
                    })
                })
        })
    })
})
<|endoftext|>


<commit_before>/* eslint-env mocha */

import chai from 'chai';
import { assoc } from '../src/index';
import 'babel-polyfill';
import { Map } from 'immutable';
chai.should();

describe('assoc', () => {
  it('should set a value onto a given key for either an Immutable data structure or a JS Object', () => {
    assoc('a', 'test', {}).should.deep.equal({ a: 'test' });
    assoc('a', 'test', new Map()).toJS().should.deep.equal({ a: 'test' });
  });
});
<commit_msg>Adds composability test case for assoc<commit_after>/* eslint-env mocha */

import chai from 'chai';
import { assoc, prop } from '../src/index';
import { compose } from 'ramda';
import 'babel-polyfill';
import { Map } from 'immutable';
chai.should();

describe('assoc', () => {
  it('should set a value onto a given key for either an Immutable data structure or a JS Object', () => {
    assoc('a', 'test', {}).should.deep.equal({ a: 'test' });
    assoc('a', 'test', new Map()).toJS().should.deep.equal({ a: 'test' });
  });

  it('should be composable', () => {
    const tester = compose(
      prop('b'),
      assoc('b', 'b'),
      assoc('a', 'a')
    );
    tester(new Map()).should.equal('b');
  });
});
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var java = require("java");

java.classpath.push('java/commons-math3-3.3.jar');
java.classpath.push('java/guava-18.0.jar');
java.classpath.push('java/mahout-core-0.9.jar');
java.classpath.push('java/mahout-integration-0.9.jar');
java.classpath.push('java/mahout-math-0.9.jar');
java.classpath.push('java/mysql-connector-java-5.0.8-bin.jar');
java.classpath.push('java/slf4j-api-1.7.7.jar');
java.classpath.push('java/slf4j-nop-1.7.7.jar');
java.classpath.push('java/aurora_recommender.jar');

var activity_recommender = java.newInstanceSync("com.aurora.recommender.RecommendActivity");
java.callMethodSync(activity_recommender, "getRecommendation",10000,3);

/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Aurora' });
});
router.get('/question1', function(req, res) {
  res.render('16_survey.jade', { title: 'Aurora' });
});
router.get('/submit_q1', function(req,res) {
    var code = req.query.code;
    console.log(code);
    res.redirect('/question2');
});
router.get('/question2', function(req, res) {
  res.render('hangout.jade', { title: 'Aurora' });
});
router.get('/privacy_policy', function(req, res) {
  res.render('privacy_policy', { title: 'Aurora' });
});

module.exports = router;
<commit_msg>Added npm java<commit_after>var express = require('express');
var router = express.Router();
var java = require("java");

java.classpath.push('java/commons-math3-3.3.jar');
java.classpath.push('java/guava-18.0.jar');
java.classpath.push('java/mahout-core-0.9.jar');
java.classpath.push('java/mahout-integration-0.9.jar');
java.classpath.push('java/mahout-math-0.9.jar');
java.classpath.push('java/mysql-connector-java-5.0.8-bin.jar');
java.classpath.push('java/slf4j-api-1.7.7.jar');
java.classpath.push('java/slf4j-nop-1.7.7.jar');
java.classpath.push('java/aurora_recommender.jar');

var activity_recommender = java.newInstanceSync("com.aurora.recommender.RecommendActivity");
var result = java.callMethodSync(activity_recommender, "getRecommendation",10000,3);
console.log(result);

/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Aurora' });
});
router.get('/question1', function(req, res) {
  res.render('16_survey.jade', { title: 'Aurora' });
});
router.get('/submit_q1', function(req,res) {
    var code = req.query.code;
    console.log(code);
    res.redirect('/question2');
});
router.get('/question2', function(req, res) {
  res.render('hangout.jade', { title: 'Aurora' });
});
router.get('/privacy_policy', function(req, res) {
  res.render('privacy_policy', { title: 'Aurora' });
});

module.exports = router;
<|endoftext|>


<commit_before><SCRIPT type="text/javascript">
<!-- Hide script contents from old browsers

    var IE4 = (document.all && !document.getElementById) ? true : false;
    var NS4 = (document.layers) ? true : false;
    var IE5 = (document.all && document.getElementById) ? true : false;
    var NS6 = (document.getElementById && !document.all) ? true : false;
    var IE  = IE4 || IE5;
    var NS  = NS4 || NS6;
    var Mac = (navigator.platform.indexOf("Mac") == -1) ? false : true;

    var sheet;

    if( NS4 )
    {
        sheet = "jspwiki_ns.css";
    }
    else if( Mac )
    {
        sheet = "jspwiki_mac.css";
    }
    else
    {
        // Let's assume all the rest of the browsers are sane
        // and standard's compliant.
        sheet = "jspwiki_ie.css";
    }

    document.write("<link rel=\"stylesheet\" href=\""+sheet+"\">");

// end hiding contents from old browsers -->
</SCRIPT>
<NOSCRIPT>
    <!-- User has no JavaScript support.  Thus, it is unlikely that
         his stylesheets would work either.  So, no stylesheets. -->
</NOSCRIPT>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=<%=wiki.getContentEncoding()%>">
<LINK REL="search" HREF="<%=wiki.getBaseURL()%>Search.jsp" TITLE="Search <%=wiki.getApplicationName()%>">
<LINK REL="help"   HREF="<%=wiki.getBaseURL()%>Wiki.jsp?page=TextFormattingRules" TITLE="Help"
<LINK REL="start"  HREF="<%=wiki.getBaseURL()%>Wiki.jsp?page=Main" TITLE="Front page">

<commit_msg>Now uses wiki link tags instead of scriptlets.<commit_after><SCRIPT type="text/javascript">
<!-- Hide script contents from old browsers

    var IE4 = (document.all && !document.getElementById) ? true : false;
    var NS4 = (document.layers) ? true : false;
    var IE5 = (document.all && document.getElementById) ? true : false;
    var NS6 = (document.getElementById && !document.all) ? true : false;
    var IE  = IE4 || IE5;
    var NS  = NS4 || NS6;
    var Mac = (navigator.platform.indexOf("Mac") == -1) ? false : true;

    var sheet;

    if( NS4 )
    {
        sheet = "jspwiki_ns.css";
    }
    else if( Mac )
    {
        sheet = "jspwiki_mac.css";
    }
    else
    {
        // Let's assume all the rest of the browsers are sane
        // and standard's compliant.
        sheet = "jspwiki_ie.css";
    }

    document.write("<link rel=\"stylesheet\" href=\"templates/default/"+sheet+"\">");

// end hiding contents from old browsers -->
</SCRIPT>
<NOSCRIPT>
    <!-- User has no JavaScript support.  Thus, it is unlikely that
         his stylesheets would work either.  So, no stylesheets. -->
</NOSCRIPT>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=<wiki:ContentEncoding />">
<LINK REL="search" HREF="<wiki:LinkTo format="url" page="FindPage"/>"            TITLE="Search <wiki:ApplicationName />">
<LINK REL="help"   HREF="<wiki:LinkTo format="url" page="TextFormattingRules"/>" TITLE="Help">
<LINK REL="start"  HREF="<wiki:LinkTo format="url" page="Main"/>"                TITLE="Front page">

<|endoftext|>


<commit_before>/**
 * @fileOverview Image
 * @import base.js, runtime/html5/runtime.js, runtime/html5/util.js, runtime/html5/imagemeta.js, lib/blob.js
 */
define( 'webuploader/runtime/html5/imagepreview', [ 'webuploader/base',
        'webuploader/runtime/html5/runtime',
        'webuploader/runtime/html5/util',
        'webuploader/runtime/html5/imagemeta',
        'webuploader/lib/blob'
        ], function( Base, Html5Runtime, Util, ImageMeta, Blob ) {

    var $ = Base.$,
        BLANK_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D',
        throttle;

    // 根据要处理的文件大小来节流，一次不能处理太多，会卡。
    throttle = (function( max ) {
        var occupied = 0,
            waiting = [],
            tick = function() {
                var item;

                while( waiting.length && occupied < max ) {
                    item = waiting.shift();
                    occupied += item[ 0 ];
                    item[ 1 ]();
                }
            };

        return function( emiter, size, cb ) {
            waiting.push( [ size, cb ] );
            emiter.once( 'destroy', function() {
                occupied -= size;
                setTimeout( tick, 1 );
            } );
            setTimeout( tick, 1 );
        }
    })( 5 * 1024 * 1024 );

    return Html5Runtime.register( 'ImagePreview', {

        // flag: 标记是否被修改过。
        modified: false,

        init: function( options ) {
            var me = this,
                img = new Image(),
                opts = this.options;

            img.onload = function() {
                // 读取meta信息。
                if ( me.type === 'image/jpeg' ) {
                    ImageMeta.parse( me._blob , function( error, ret ) {
                        me.metas = ret;
                        me.owner.trigger( 'load' );
                    } );
                } else {
                    me.owner.trigger( 'load' );
                }
            };

            img.onerror = function() {
                me.owner.trigger( 'error' );
            }

            me._img = img;
        },

        preview: function( blob, width, height ) {
            var me = this,
                img = me._img;

            throttle( me.owner, blob.size, function() {
                me._blob = blob;
                me.type = blob.type;
                img.src = Util.createObjectURL( blob.getSource() );
                me.owner.once( 'load', function() {
                    Util.revokeObjectURL( img.src );
                    me.resize( width, height );
                    me.owner.trigger( 'complete' );
                } );
            });
        },

        getMetas: function() {
            return this.metas;
        },

        /**
         * 创建缩略图，但是不会修改原始图片大小。
         */
        resize: function( width, height ) {
            var canvas = this.canvas = document.createElement( 'canvas' );

            // if ( this.metas && this.metas.exif && (result =
            //         this.metas.exif.get( 'Thumbnail' )) ) {
            //     return result;
            // }

            this._resize( this._img, canvas, width, height, true );
        },

        getAsDataURL: function() {
            var canvas = this.canvas,
                opts = this.options,
                result;

            if ( this.type === 'image/jpeg' ) {
                result = canvas.toDataURL( 'image/jpeg', opts.quality / 100 );
            } else {
                result = canvas.toDataURL( this.type );
            }

            canvas.getContext( '2d' )
                    .clearRect( 0, 0, canvas.width, canvas.height );
            canvas.width = canvas.height = 0;
            canvas = null;
            return result;
        },

        getOrientation: function() {
            return this.metas && this.metas.exif &&
                    this.metas.exif.get( 'Orientation' ) || 1;
        },

        getMetas: function() {
            return this.metas;
        },

        setMetas: function( val ) {
            this.metas = val;
        },

        destroy: function() {
            this._img.onload = null;

            // 释放内存。非常重要，否则释放不了image的内存。
            this._img.src = BLANK_IMAGE;
            this._img = this._blob = null;
        },

        _resize: function( img, cvs, width, height ) {
            var opts = this.options,
                naturalWidth = img.width,
                naturalHeight = img.height,
                orientation = this.getOrientation(),
                scale, w, h, x, y;

            // values that require 90 degree rotation
            if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) {

                // 交换width, height的值。
                width ^= height;
                height ^= width;
                width ^= height;
            }

            scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth,
                    height / naturalHeight );

            // 不允许放大。
            scale = opts.allowMagnify ? Math.min( 1, scale ) : scale;

            w = naturalWidth * scale;
            h = naturalHeight * scale;

            if ( opts.crop ) {
                cvs.width = width;
                cvs.height = height;
            } else {
                cvs.width = w;
                cvs.height = h;
            }

            x = (cvs.width - w) / 2;
            y = (cvs.height - h) / 2;

            this._rotateToOrientaion( cvs, orientation );

            this._renderImageToCanvas( cvs, img, x, y, w, h );
        },

        _rotateToOrientaion: function( canvas, orientation ) {
            var width = canvas.width,
                height = canvas.height,
                ctx = canvas.getContext( '2d' );

            switch ( orientation ) {
                case 5:
                case 6:
                case 7:
                case 8:
                    canvas.width = height;
                    canvas.height = width;
                    break;
            }

            switch ( orientation ) {
                case 2:    // horizontal flip
                    ctx.translate( width, 0 );
                    ctx.scale( -1, 1 );
                    break;

                case 3:    // 180 rotate left
                    ctx.translate( width, height );
                    ctx.rotate( Math.PI );
                    break;

                case 4:    // vertical flip
                    ctx.translate( 0, height );
                    ctx.scale( 1, -1 );
                    break;

                case 5:    // vertical flip + 90 rotate right
                    ctx.rotate( 0.5 * Math.PI );
                    ctx.scale( 1, -1 );
                    break;

                case 6:    // 90 rotate right
                    ctx.rotate( 0.5 * Math.PI );
                    ctx.translate( 0, -height );
                    break;

                case 7:    // horizontal flip + 90 rotate right
                    ctx.rotate( 0.5 * Math.PI );
                    ctx.translate( width, -height );
                    ctx.scale( -1, 1 );
                    break;

                case 8:    // 90 rotate left
                    ctx.rotate( -0.5 * Math.PI );
                    ctx.translate( -width, 0 );
                    break;
            }
        },

        _renderImageToCanvas: function( canvas, img, x, y, w, h ) {
            canvas.getContext( '2d' ).drawImage( img, x, y, w, h );
        }
    } );
} );<commit_msg>fix a preview issue<commit_after>/**
 * @fileOverview Image
 * @import base.js, runtime/html5/runtime.js, runtime/html5/util.js, runtime/html5/imagemeta.js, lib/blob.js
 */
define( 'webuploader/runtime/html5/imagepreview', [ 'webuploader/base',
        'webuploader/runtime/html5/runtime',
        'webuploader/runtime/html5/util',
        'webuploader/runtime/html5/imagemeta',
        'webuploader/lib/blob'
        ], function( Base, Html5Runtime, Util, ImageMeta, Blob ) {

    var $ = Base.$,
        BLANK_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D',
        throttle;

    // 根据要处理的文件大小来节流，一次不能处理太多，会卡。
    throttle = (function( max ) {
        var occupied = 0,
            waiting = [],
            tick = function() {
                var item;

                while( waiting.length && occupied < max ) {
                    item = waiting.shift();
                    occupied += item[ 0 ];
                    item[ 1 ]();
                }
            };

        return function( emiter, size, cb ) {
            waiting.push( [ size, cb ] );
            emiter.once( 'destroy', function() {
                occupied -= size;
                setTimeout( tick, 1 );
            } );
            setTimeout( tick, 1 );
        }
    })( 5 * 1024 * 1024 );

    return Html5Runtime.register( 'ImagePreview', {

        // flag: 标记是否被修改过。
        modified: false,

        init: function( options ) {
            var me = this,
                img = new Image(),
                opts = this.options;

            img.onload = function() {
                // 读取meta信息。
                if ( me.type === 'image/jpeg' ) {
                    ImageMeta.parse( me._blob , function( error, ret ) {
                        me.metas = ret;
                        me.owner.trigger( 'load' );
                    } );
                } else {
                    me.owner.trigger( 'load' );
                }
            };

            img.onerror = function() {
                me.owner.trigger( 'error' );
            }

            me._img = img;
        },

        preview: function( blob, width, height ) {
            var me = this,
                img = me._img;

            throttle( me.owner, blob.size, function() {
                me._blob = blob;
                me.type = blob.type;
                img.src = Util.createObjectURL( blob.getSource() );
                me.owner.once( 'load', function() {
                    Util.revokeObjectURL( img.src );
                    me.resize( width, height );
                    me.owner.trigger( 'complete' );
                } );
            });
        },

        getMetas: function() {
            return this.metas;
        },

        /**
         * 创建缩略图，但是不会修改原始图片大小。
         */
        resize: function( width, height ) {
            var canvas = this.canvas = document.createElement( 'canvas' );

            // if ( this.metas && this.metas.exif && (result =
            //         this.metas.exif.get( 'Thumbnail' )) ) {
            //     return result;
            // }

            this._resize( this._img, canvas, width, height, true );
        },

        getAsDataURL: function() {
            var canvas = this.canvas,
                opts = this.options,
                result;

            if ( this.type === 'image/jpeg' ) {
                result = canvas.toDataURL( 'image/jpeg', opts.quality / 100 );
            } else {
                result = canvas.toDataURL( this.type );
            }

            canvas.getContext( '2d' )
                    .clearRect( 0, 0, canvas.width, canvas.height );
            canvas.width = canvas.height = 0;
            canvas = null;
            return result;
        },

        getOrientation: function() {
            return this.metas && this.metas.exif &&
                    this.metas.exif.get( 'Orientation' ) || 1;
        },

        getMetas: function() {
            return this.metas;
        },

        setMetas: function( val ) {
            this.metas = val;
        },

        destroy: function() {
            this._img.onload = null;

            // 释放内存。非常重要，否则释放不了image的内存。
            this._img.src = BLANK_IMAGE;
            this._img = this._blob = null;
        },

        _resize: function( img, cvs, width, height ) {
            var opts = this.options,
                naturalWidth = img.width,
                naturalHeight = img.height,
                orientation = this.getOrientation(),
                scale, w, h, x, y;

            // values that require 90 degree rotation
            if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) {

                // 交换width, height的值。
                width ^= height;
                height ^= width;
                width ^= height;
            }

            scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth,
                    height / naturalHeight );

            // 不允许放大。
            scale = !opts.allowMagnify ? Math.min( 1, scale ) : scale;

            w = naturalWidth * scale;
            h = naturalHeight * scale;

            if ( opts.crop ) {
                cvs.width = width;
                cvs.height = height;
            } else {
                cvs.width = w;
                cvs.height = h;
            }

            x = (cvs.width - w) / 2;
            y = (cvs.height - h) / 2;

            this._rotateToOrientaion( cvs, orientation );

            this._renderImageToCanvas( cvs, img, x, y, w, h );
        },

        _rotateToOrientaion: function( canvas, orientation ) {
            var width = canvas.width,
                height = canvas.height,
                ctx = canvas.getContext( '2d' );

            switch ( orientation ) {
                case 5:
                case 6:
                case 7:
                case 8:
                    canvas.width = height;
                    canvas.height = width;
                    break;
            }

            switch ( orientation ) {
                case 2:    // horizontal flip
                    ctx.translate( width, 0 );
                    ctx.scale( -1, 1 );
                    break;

                case 3:    // 180 rotate left
                    ctx.translate( width, height );
                    ctx.rotate( Math.PI );
                    break;

                case 4:    // vertical flip
                    ctx.translate( 0, height );
                    ctx.scale( 1, -1 );
                    break;

                case 5:    // vertical flip + 90 rotate right
                    ctx.rotate( 0.5 * Math.PI );
                    ctx.scale( 1, -1 );
                    break;

                case 6:    // 90 rotate right
                    ctx.rotate( 0.5 * Math.PI );
                    ctx.translate( 0, -height );
                    break;

                case 7:    // horizontal flip + 90 rotate right
                    ctx.rotate( 0.5 * Math.PI );
                    ctx.translate( width, -height );
                    ctx.scale( -1, 1 );
                    break;

                case 8:    // 90 rotate left
                    ctx.rotate( -0.5 * Math.PI );
                    ctx.translate( -width, 0 );
                    break;
            }
        },

        _renderImageToCanvas: function( canvas, img, x, y, w, h ) {
            canvas.getContext( '2d' ).drawImage( img, x, y, w, h );
        }
    } );
} );<|endoftext|>