<commit_before>import emitter from 'mitt';
import Props from './props';
import viewer from './viewer';
import * as THREE from './lib/three';
import { textColor } from './theme/colors';
import deps from './deps';

//  These are empty objects -- but we'll fill them soon.
let [leftController, rightController] = viewer.controllers;
const controllerGroup = new THREE.Group();

function handleLeftPress() {
  if (leftPress) leftPress();
}
function handleRightPress() {
  if (rightPress) rightPress();
}

function addController(controller) {
  //  We're only interested in Vive or Oculus controllers right now.
  const isVive = controller.gamepadStyle !== 'vive';
  if (isVive && controller.gamepadStyle !== 'oculus') {
    return;
  }

  //  For 6DOF systems we need to add the VRControls standingMatrix
  //  otherwise your controllers will be on the floor!
  controller.standingMatrix = viewer.controls.getStandingMatrix();

  //  This is for if we do add Daydream controller support here,
  //  we'd need access to the camera (your head) position so we could
  //  guess where the 3DOF controller is in relation to your head.
  controller.head = viewer.cameras.default;

  //  Ok... Earlier efforts to outsmart the Gamepad API's (and Steam's)
  //  reporting of handedness has failed. So we're giving up and only
  //  allowing a controller to mount if it indeed contains a valid "left"
  //  or "right" in the gamepad.hand property. And note that this CAN CHANGE!
  //  So let's roll with it and store the gamepad's current handedness
  //  right on the controller. And if the gamepad's handedness changes we'll
  //  catch that through an event and swap them. But for now:
  if (controller.gamepad.hand === 'left') {
    controller.hand = 'left';
  } else {
    controller.hand = 'right';
  }

  //  Now that we've made a decision about handedness we can assign this controller
  //  to either leftController or rightController and add the appropriate mesh.
  let mesh;
  if (controller.hand === 'left') {
    viewer.controllers[0] = leftController = controller;
    mesh = lhand;
  } else {
    viewer.controllers[1] = rightController = controller;
    mesh = rhand;
  }
  controller.add(mesh);

  //  Button events!
  const handlePress = () => {
    if (controller.hand === 'left') handleLeftPress();
    else handleRightPress();
  };
  //  For Vive, it's pretty straight forward.
  if (controller.gamepadStyle === 'vive') {
    controller.addEventListener('thumbpad press began', handlePress);
    //  And we'll also listen for the Menu button because it's on the front
    //  and we're trying to be accomodating to inaccurate thumbs.
    controller.addEventListener('menu press began', handlePress);
  }
  //  For Oculus we need to add a little more flexibility...
  if (controller.gamepadStyle === 'oculus') {
    controller.addEventListener('thumbstick press began', handlePress);
    controller.addEventListener('A press began', handlePress);//  RIGHT controller.
    controller.addEventListener('B press began', handlePress);//  RIGHT controller.
    controller.addEventListener('X press began', handlePress);//  LEFT controller.
    controller.addEventListener('Y press began', handlePress);//  LEFT controller.
  }

  //  On disconnect we need to remove the mesh
  //  and destroy the controller.
  //  The mesh (lhand or rhand) should continue to exist
  //  which is good because we'll need it again if the controller reconnects.
  controller.addEventListener('disconnected', () => {
    controller.remove(mesh);
    controllerGroup.remove(controller);
    if (controller.hand === 'left') {
      viewer.controllers[0] = leftController = {};
    } else {
      viewer.controllers[1] = rightController = {};
    }
  });

  //  We're going to add this directly onto the controller which will yield
  //  no harm in production, and for dev creates the benefit of being able to
  //  directly test how this should work. We can now call things like:
  //  THREE.VRController.controllers[0].onHandChanged("left");
  //  THREE.VRController.controllers[1].onHandChanged("right");
  //  THREE.VRController.controllers[0].onHandChanged("right");
  //  THREE.VRController.controllers[1].onHandChanged("left");
  //  Notice what we're NOT doing. We're NOT SWAPPING controllers. We are
  //  relying entirely on the Gamepad API to report a "swap" by reporting a
  //  change event on both controllers independently.
  controller.onHandChanged = (forceHand) => {
    let hand;
    //  This forceHand is only for manual testing of this swap feature.
    //  If doing manual swap tests send a 'left' or 'right' string only.
    //  In "normal mode" this is just an event listener and will therefore
    //  receive a full event object and so the following string comnpare
    //  will fail and use the actual gamepad.hand value -- a good thing!
    if (forceHand === 'left' || forceHand === 'right') {
      hand = forceHand;
    } else hand = controller.gamepad.hand;
    // console.log('This controller has swapped hands!', controller, hand);
    controller.remove(mesh);
    controller.hand = hand;
    if (hand === 'left') {
      viewer.controllers[0] = leftController = controller;
      mesh = lhand;
    } else {
      viewer.controllers[1] = rightController = controller;
      mesh = rhand;
    }
    controller.add(mesh);
  };
  controller.addEventListener('hand changed', controller.onHandChanged);

  //  All our work here is done, let's add this controller to the scene!
  //  Well sort off... We’ll add it to our controllerGroup which has already
  //  been added to viewer.scene. This was we can more cleanly show and hide
  //  whatever’s connected.
  // (And yes, Jonathan -- we will remove it on disconnect and destroy it.)
  controllerGroup.add(controller);
}

window.addEventListener('vr controller connected', ({ detail: controller }) => {
  //  If .hand is an empty String, null, or undefined...
  if (!controller.gamepad.hand) {
    //  Tempted to add a setTimeOut here so if a "hand changed" event doesn't fire
    //  within a second or two we just assign a hand. HOWEVER if the controllers
    //  are already turned on and a button was pressed, then window refreshed
    //  the controllers will show up with hand === '' and event won't fire until
    //  Tutorial Mode is exited! So if you left Tutorial running for 5 minutes
    //  the "hand changed" event won't hand a chance to fire during that time.
    //  Unclear why... But if we believe this event WILL FIRE EVENTUALLY then
    //  this current setup is totally fine.
    const onHandChanged = () => {
      controller.removeEventListener(onHandChanged);
      addController(controller);
    };
    controller.addEventListener('hand changed', onHandChanged);
  } else addController(controller);
});

//  Still worried multiple VRController instances are being left in the scene
//  after a few disconnects and reconnects? Check it for yourself!
// window.kids = viewer.scene.children;

const textCreator = deps.SDFText.creator();

const rhand = Props.controller.clone();
const lhand = Props.controller.clone();
rhand.children[0].castShadow = lhand.children[0].castShadow = true;

const rText = textCreator.create('', {
  wrapWidth: 1980, //was originally 1600
  scale: 0.25,
  align: 'left',
  color: textColor.getHex(),
});
const lText = textCreator.create('', {
  wrapWidth: 1980, // was originally 1600.
  scale: 0.25,
  align: 'right',
  color: textColor.getHex(),
});
rhand.add(rText);
lhand.add(lText);

rText.rotation.x = lText.rotation.x = -Math.PI * 0.5;
rText.position.set(0.03, 0, -0.022);
//  Original left text position was:
// lText.position.set(-0.12, 0, -0.022);
//  So... x = 1980/1600*-0.12 roughly anyhow...
lText.position.set(-0.1485, 0, -0.022);

let leftPress;
let rightPress;

const rButton = rhand.getObjectByName('button');
const lButton = lhand.getObjectByName('button');

function setButtonVisibility(hand, flag) {
  const button = (hand === 'left') ? lButton : rButton;
  button.visible = flag;
}

const removeLeft = () => {
  lText.updateLabel('');
  leftPress = null;
  setButtonVisibility('left', false);
};

const removeRight = () => {
  rText.updateLabel('');
  rightPress = null;
  setButtonVisibility('right', false);
};

let currentParam;
const controllers = Object.assign(
  emitter(),
  {
    update(param) {
      if (param === currentParam) return;
      currentParam = param;
      const { left, right, removeOnPress } = param || {};
      if (left) {
        lText.updateLabel(left.text);
        if (left.onPress) {
          setButtonVisibility('left', true);
        }
        leftPress = () => {
          if (left.removeOnPress || removeOnPress) {
            removeLeft();
          }
          if (removeOnPress) {
            removeRight();
          }
          if (left.onPress) {
            left.onPress();
          }
        };
      } else {
        removeLeft();
      }

      if (right) {
        rText.updateLabel(right.text);
        if (right.onPress) {
          setButtonVisibility('right', true);
        }
        rightPress = () => {
          if (right.removeOnPress || removeOnPress) {
            removeRight();
          }
          if (removeOnPress) {
            removeLeft();
          }
          if (right.onPress) {
            right.onPress();
          }
        };
      } else {
        removeRight();
      }
    },
    add() {
      viewer.scene.add(controllerGroup);
    },
    remove() {
      rightPress = leftPress = null;
      viewer.scene.remove(controllerGroup);
    },
    setButtonVisibility,
  },
);

controllers.countActiveControllers = () => +!!leftController.gamepad + +!!rightController.gamepad;

controllers.fixToPosition = (function () {
  const MATRIX = new THREE.Matrix4();
  const POSITION = new THREE.Vector3();
  const ROTATION = new THREE.Quaternion();
  const SCALE = new THREE.Vector3();
  return (position) => {
    for (let i = 0; i < viewer.controllers.length; i++) {
      const controller = viewer.controllers[i];
      controller.matrix.decompose(POSITION, ROTATION, SCALE);
      const { x, y, z } = POSITION.add(position).sub(viewer.camera.position);
      controller.matrix.copyPosition(MATRIX.makeTranslation(x, y, z));
    }
  };
}());

export default controllers;
<commit_msg>fix errors in review when controllers are missing – closes #499<commit_after>import emitter from 'mitt';
import Props from './props';
import viewer from './viewer';
import * as THREE from './lib/three';
import { textColor } from './theme/colors';
import deps from './deps';

//  These are empty objects -- but we'll fill them soon.
let [leftController, rightController] = viewer.controllers;
const controllerGroup = new THREE.Group();

function handleLeftPress() {
  if (leftPress) leftPress();
}
function handleRightPress() {
  if (rightPress) rightPress();
}

function addController(controller) {
  //  We're only interested in Vive or Oculus controllers right now.
  const isVive = controller.gamepadStyle !== 'vive';
  if (isVive && controller.gamepadStyle !== 'oculus') {
    return;
  }

  //  For 6DOF systems we need to add the VRControls standingMatrix
  //  otherwise your controllers will be on the floor!
  controller.standingMatrix = viewer.controls.getStandingMatrix();

  //  This is for if we do add Daydream controller support here,
  //  we'd need access to the camera (your head) position so we could
  //  guess where the 3DOF controller is in relation to your head.
  controller.head = viewer.cameras.default;

  //  Ok... Earlier efforts to outsmart the Gamepad API's (and Steam's)
  //  reporting of handedness has failed. So we're giving up and only
  //  allowing a controller to mount if it indeed contains a valid "left"
  //  or "right" in the gamepad.hand property. And note that this CAN CHANGE!
  //  So let's roll with it and store the gamepad's current handedness
  //  right on the controller. And if the gamepad's handedness changes we'll
  //  catch that through an event and swap them. But for now:
  if (controller.gamepad.hand === 'left') {
    controller.hand = 'left';
  } else {
    controller.hand = 'right';
  }

  //  Now that we've made a decision about handedness we can assign this controller
  //  to either leftController or rightController and add the appropriate mesh.
  let mesh;
  if (controller.hand === 'left') {
    viewer.controllers[0] = leftController = controller;
    mesh = lhand;
  } else {
    viewer.controllers[1] = rightController = controller;
    mesh = rhand;
  }
  controller.add(mesh);

  //  Button events!
  const handlePress = () => {
    if (controller.hand === 'left') handleLeftPress();
    else handleRightPress();
  };
  //  For Vive, it's pretty straight forward.
  if (controller.gamepadStyle === 'vive') {
    controller.addEventListener('thumbpad press began', handlePress);
    //  And we'll also listen for the Menu button because it's on the front
    //  and we're trying to be accomodating to inaccurate thumbs.
    controller.addEventListener('menu press began', handlePress);
  }
  //  For Oculus we need to add a little more flexibility...
  if (controller.gamepadStyle === 'oculus') {
    controller.addEventListener('thumbstick press began', handlePress);
    controller.addEventListener('A press began', handlePress);//  RIGHT controller.
    controller.addEventListener('B press began', handlePress);//  RIGHT controller.
    controller.addEventListener('X press began', handlePress);//  LEFT controller.
    controller.addEventListener('Y press began', handlePress);//  LEFT controller.
  }

  //  On disconnect we need to remove the mesh
  //  and destroy the controller.
  //  The mesh (lhand or rhand) should continue to exist
  //  which is good because we'll need it again if the controller reconnects.
  controller.addEventListener('disconnected', () => {
    controller.remove(mesh);
    controllerGroup.remove(controller);
    if (controller.hand === 'left') {
      viewer.controllers[0] = leftController = {};
    } else {
      viewer.controllers[1] = rightController = {};
    }
  });

  //  We're going to add this directly onto the controller which will yield
  //  no harm in production, and for dev creates the benefit of being able to
  //  directly test how this should work. We can now call things like:
  //  THREE.VRController.controllers[0].onHandChanged("left");
  //  THREE.VRController.controllers[1].onHandChanged("right");
  //  THREE.VRController.controllers[0].onHandChanged("right");
  //  THREE.VRController.controllers[1].onHandChanged("left");
  //  Notice what we're NOT doing. We're NOT SWAPPING controllers. We are
  //  relying entirely on the Gamepad API to report a "swap" by reporting a
  //  change event on both controllers independently.
  controller.onHandChanged = (forceHand) => {
    let hand;
    //  This forceHand is only for manual testing of this swap feature.
    //  If doing manual swap tests send a 'left' or 'right' string only.
    //  In "normal mode" this is just an event listener and will therefore
    //  receive a full event object and so the following string comnpare
    //  will fail and use the actual gamepad.hand value -- a good thing!
    if (forceHand === 'left' || forceHand === 'right') {
      hand = forceHand;
    } else hand = controller.gamepad.hand;
    // console.log('This controller has swapped hands!', controller, hand);
    controller.remove(mesh);
    controller.hand = hand;
    if (hand === 'left') {
      viewer.controllers[0] = leftController = controller;
      mesh = lhand;
    } else {
      viewer.controllers[1] = rightController = controller;
      mesh = rhand;
    }
    controller.add(mesh);
  };
  controller.addEventListener('hand changed', controller.onHandChanged);

  //  All our work here is done, let's add this controller to the scene!
  //  Well sort off... We’ll add it to our controllerGroup which has already
  //  been added to viewer.scene. This was we can more cleanly show and hide
  //  whatever’s connected.
  // (And yes, Jonathan -- we will remove it on disconnect and destroy it.)
  controllerGroup.add(controller);
}

window.addEventListener('vr controller connected', ({ detail: controller }) => {
  //  If .hand is an empty String, null, or undefined...
  if (!controller.gamepad.hand) {
    //  Tempted to add a setTimeOut here so if a "hand changed" event doesn't fire
    //  within a second or two we just assign a hand. HOWEVER if the controllers
    //  are already turned on and a button was pressed, then window refreshed
    //  the controllers will show up with hand === '' and event won't fire until
    //  Tutorial Mode is exited! So if you left Tutorial running for 5 minutes
    //  the "hand changed" event won't hand a chance to fire during that time.
    //  Unclear why... But if we believe this event WILL FIRE EVENTUALLY then
    //  this current setup is totally fine.
    const onHandChanged = () => {
      controller.removeEventListener(onHandChanged);
      addController(controller);
    };
    controller.addEventListener('hand changed', onHandChanged);
  } else addController(controller);
});

//  Still worried multiple VRController instances are being left in the scene
//  after a few disconnects and reconnects? Check it for yourself!
// window.kids = viewer.scene.children;

const textCreator = deps.SDFText.creator();

const rhand = Props.controller.clone();
const lhand = Props.controller.clone();
rhand.children[0].castShadow = lhand.children[0].castShadow = true;

const rText = textCreator.create('', {
  wrapWidth: 1980, //was originally 1600
  scale: 0.25,
  align: 'left',
  color: textColor.getHex(),
});
const lText = textCreator.create('', {
  wrapWidth: 1980, // was originally 1600.
  scale: 0.25,
  align: 'right',
  color: textColor.getHex(),
});
rhand.add(rText);
lhand.add(lText);

rText.rotation.x = lText.rotation.x = -Math.PI * 0.5;
rText.position.set(0.03, 0, -0.022);
//  Original left text position was:
// lText.position.set(-0.12, 0, -0.022);
//  So... x = 1980/1600*-0.12 roughly anyhow...
lText.position.set(-0.1485, 0, -0.022);

let leftPress;
let rightPress;

const rButton = rhand.getObjectByName('button');
const lButton = lhand.getObjectByName('button');

function setButtonVisibility(hand, flag) {
  const button = (hand === 'left') ? lButton : rButton;
  button.visible = flag;
}

const removeLeft = () => {
  lText.updateLabel('');
  leftPress = null;
  setButtonVisibility('left', false);
};

const removeRight = () => {
  rText.updateLabel('');
  rightPress = null;
  setButtonVisibility('right', false);
};

let currentParam;
const controllers = Object.assign(
  emitter(),
  {
    update(param) {
      if (param === currentParam) return;
      currentParam = param;
      const { left, right, removeOnPress } = param || {};
      if (left) {
        lText.updateLabel(left.text);
        if (left.onPress) {
          setButtonVisibility('left', true);
        }
        leftPress = () => {
          if (left.removeOnPress || removeOnPress) {
            removeLeft();
          }
          if (removeOnPress) {
            removeRight();
          }
          if (left.onPress) {
            left.onPress();
          }
        };
      } else {
        removeLeft();
      }

      if (right) {
        rText.updateLabel(right.text);
        if (right.onPress) {
          setButtonVisibility('right', true);
        }
        rightPress = () => {
          if (right.removeOnPress || removeOnPress) {
            removeRight();
          }
          if (removeOnPress) {
            removeLeft();
          }
          if (right.onPress) {
            right.onPress();
          }
        };
      } else {
        removeRight();
      }
    },
    add() {
      viewer.scene.add(controllerGroup);
    },
    remove() {
      rightPress = leftPress = null;
      viewer.scene.remove(controllerGroup);
    },
    setButtonVisibility,
  },
);

controllers.countActiveControllers = () => +!!leftController.gamepad + +!!rightController.gamepad;

controllers.fixToPosition = (function () {
  const MATRIX = new THREE.Matrix4();
  const POSITION = new THREE.Vector3();
  const ROTATION = new THREE.Quaternion();
  const SCALE = new THREE.Vector3();
  return (position) => {
    for (let i = 0; i < viewer.controllers.length; i++) {
      const controller = viewer.controllers[i];
      if (!controller.matrix) return;
      controller.matrix.decompose(POSITION, ROTATION, SCALE);
      const { x, y, z } = POSITION.add(position).sub(viewer.camera.position);
      controller.matrix.copyPosition(MATRIX.makeTranslation(x, y, z));
    }
  };
}());

export default controllers;
<|endoftext|>


<commit_before>// Chart channels
var doughnutData = [
    {
      value: 19124,
      color:"#00ad51",
      highlight: "#66ce97",
      label: "Web"
    },
    {
      value: 7605,
      color: "#007dc3",
      highlight: "#66b1db",
      label: "010"
    },
    {
      value: 233,
      color: "#ffdc08",
      highlight: "#ffea6b",
      label: "Papel"
    },
  ];

// Chart sex
var doughnutDataSex = [
    {
      value: 16395,
      color:"#00dae0",
      highlight: "#66e9ec",
      label: "Hombres"
    },
    {
      value: 10466,
      color: "#e00094",
      highlight: "#ec66bf",
      label: "Mujeres"
    },
  ];

  window.onload = function(){
    var channels = document.getElementById("chart-channels").getContext("2d");
    window.myDoughnut = new Chart(channels).Doughnut(doughnutData, {responsive : true});

    var sex = document.getElementById("chart-sex").getContext("2d");
    window.myDoughnut = new Chart(sex).Doughnut(doughnutDataSex, {responsive : true});
  };
<commit_msg>makes survey charts work with turbolinks<commit_after>// Chart channels
var doughnutData = [
    {
      value: 19124,
      color:"#00ad51",
      highlight: "#66ce97",
      label: "Web"
    },
    {
      value: 7605,
      color: "#007dc3",
      highlight: "#66b1db",
      label: "010"
    },
    {
      value: 233,
      color: "#ffdc08",
      highlight: "#ffea6b",
      label: "Papel"
    },
  ];

// Chart sex
var doughnutDataSex = [
    {
      value: 16395,
      color:"#00dae0",
      highlight: "#66e9ec",
      label: "Hombres"
    },
    {
      value: 10466,
      color: "#e00094",
      highlight: "#ec66bf",
      label: "Mujeres"
    },
  ];

var load_charts = function(){
  var channels = document.getElementById("chart-channels").getContext("2d");
  window.myDoughnut = new Chart(channels).Doughnut(doughnutData, {responsive : true});

  var sex = document.getElementById("chart-sex").getContext("2d");
  window.myDoughnut = new Chart(sex).Doughnut(doughnutDataSex, {responsive : true});
};

$(function(){
  $(document).ready(load_charts);
  $(document).on('page:load', load_charts);
  $(document).on('ajax:complete', load_charts);
});
<|endoftext|>


<commit_before>define( ["backbone", "backbone.marionette", "communicator", "config", "polyline", "jquery",
         "tpl!plugins/routeyou/route-selector.html"],

  function( Backbone, Marionette, Communicator, Config, Polyline, $,
            RouteSelectorTemplate ) {

    return Marionette.ItemView.extend( {

      els: {},
      previewLayer: null,
      template: RouteSelectorTemplate,

      events: {
        "change #edit-route": "getGeo",
        "click .button-add-route": function(e) {
          e.preventDefault();
          if ($(e.target).hasClass('disabled')) return;
          console.log('add route');
        },
        "click .button-add-points": function(e) {
          e.preventDefault();
          if ($(e.target).hasClass('disabled')) return;
          console.log('add points');
        }
      },

      initialize: function(o) {
        var self = this;
        this.collection = o.collection;
        this.model = new Backbone.Model();
        this.model.set('routes', this.collection.toArray());

        this.collection.on("change:geo", function(model) {
          self.showPreviewRoute( model.get( 'geo' ) );
        });
      },

      onShow: function() {
        this.els.addRouteButton = $('.button-add-route', this.$el);
        this.els.addPointsButton = $('.button-add-points', this.$el);
        this.map = Communicator.reqres.request( "getMap" );
      },

      showPreviewRoute: function( route ) {
        if (route) {
          this.els.addRouteButton.removeClass( 'disabled' );
          this.els.addPointsButton.removeClass( 'disabled' );
        }
        var o = {
          color: '#000',
          dashArray: "5, 5",
          opacity: 0.4
        };
        if (this.previewLayer) this.map.removeLayer(this.previewLayer);
        this.previewLayer = L.polyline( route, o ).addTo( this.map );
        this.map.fitBounds( this.previewLayer.getBounds() );
      },

      getGeo: function(e) {
        var self = this;
        var id = $( e.target ).val();
        if ( id > 0 ) {
          $.ajax( Config.routeyou_proxy.uri + '/routeyou/api/get_route/' + id )
            .done( function( msg ) {
              msg.geo = Polyline.decode( msg.geo );
              id = parseInt(id);
              var model = self.collection.findWhere( { id: id });
              model.set(msg);
              self.collection.set( model, {remove: false} );
            } );
        } else {
          if (this.previewLayer) {
            this.map.removeLayer(this.previewLayer);
            this.previewLayer = null;
          }
          this.els.addRouteButton.addClass( 'disabled' );
          this.els.addPointsButton.addClass( 'disabled' );
        }
      },

      togglePOIs: function(e) {

        var self = this;
        var id = $( e.target ).val();

        // Do not show POIs if there is no route.
        if ( !this.layers.route || !$( e.target ).is(':checked') ) {
          if ( this.layers.pois ) this.map.removeLayer( this.layers.pois );
          return;
        }

        var pois = this.model.get('pois');
        if (pois.length > 0) {
          if ( this.layers.pois ) this.map.removeLayer( this.layers.pois );
          var markers = [];
          _.each(pois, function(poi) {
            var re = /POINT\((-?\d+\.[0-9]+)\s(-?[0-9]+\.[0-9]+)/;
            var point = poi.location.centroid.wkt.match(re);
            markers.push(
              L.marker([point[2], point[1]] ).bindPopup(poi.text.description.nl)
            );
          });
          this.layers.pois = L.layerGroup(markers ).addTo( this.map );
        }

      }

    } );

  } );<commit_msg>allow multiple routes; distinguish between preview and added<commit_after>define( ["backbone", "backbone.marionette", "communicator", "config", "polyline", "jquery",
         "tpl!plugins/routeyou/route-selector.html"],

  function( Backbone, Marionette, Communicator, Config, Polyline, $,
            RouteSelectorTemplate ) {

    return Marionette.ItemView.extend( {

      els: {},
      previewLayer: null,
      template: RouteSelectorTemplate,
      routeLayerGroup: null,
      style: {
        previewRoute: {
          color: '#000',
          dashArray: "10, 10",
          opacity: 0.4
        },
        savedRoute: {
          color: '#000',
          dashArray: false,
          opacity: 0.7
        }
      },

      events: {
        "change #edit-route": "getGeo",
        "click .button-add-route": function(e) {
          e.preventDefault();
          if ($(e.target).hasClass('disabled')) return;
          this.saveRoute();
        },
        "click .button-add-points": function(e) {
          e.preventDefault();
          if ($(e.target).hasClass('disabled')) return;
          console.log('add points');
        }
      },

      initialize: function(o) {
        var self = this;
        this.available_routes = o.available_routes;
        this.added_routes = o.added_routes;
        this.model = new Backbone.Model();
        this.model.set('routes', this.available_routes.toArray());

        this.available_routes.on("change:geo", function(model) {
          self.showPreview( model );
        });
      },

      onShow: function() {
        this.els.addRouteButton = $('.button-add-route', this.$el);
        this.els.addPointsButton = $('.button-add-points', this.$el);
        this.map = Communicator.reqres.request( "getMap" );
        this.routeLayerGroup = L.layerGroup().addTo(this.map);
        this.added_routes.add()
      },

      /* ---- end marionette functions ---- */

      getGeo: function(e) {
        var self = this;
        var id = $( e.target ).val();
        if ( id > 0 ) {
          $.ajax( Config.routeyou_proxy.uri + '/routeyou/api/get_route/' + id )
            .done( function( msg ) {
              msg.geo = Polyline.decode( msg.geo );
              id = parseInt(id);
              var model = self.available_routes.findWhere( { id: id });
              model.set(msg);
              self.available_routes.set( model, {remove: false} );
            } );
        } else {
          this.removePreview();
        }
      },

      removePreview: function(beingSaved) {
        this.previewingModel = null;
        if (this.previewLayer) {
          if (!beingSaved) this.map.removeLayer(this.previewLayer);
          this.previewLayer = null;
        }
        this.els.addRouteButton.addClass( 'disabled' );
        this.els.addPointsButton.addClass( 'disabled' );
      },

      /**
       * Redraws routes based on collection.
       */
      resetRoutes: function() {
        console.log('reset routes');
        var self = this;
        this.routeLayerGroup.clearLayers();
        this.added_routes.each(function(route) {
          console.log('add route', route);
          L.polyline( route, self.style.savedRoute ).addTo( self.routeLayerGroup );
        });
      },

      /**
       * Once user clicks "Route Toevoegen", this is called.
       */
      saveRoute: function() {
        this.previewLayer.setStyle(this.style.savedRoute);
        this.routeLayerGroup.addLayer( this.previewLayer );
        this.added_routes.add( this.previewingModel.clone() );
        this.removePreview(true);
      },

      /**
       * A route is previewed after selected from a drop down, but is not officially
       * added to the saveable map.
       */
      showPreview: function( model ) {
        this.previewingModel = model;
        var route = model.get('geo');
        if (route) {
          this.els.addRouteButton.removeClass( 'disabled' );
          this.els.addPointsButton.removeClass( 'disabled' );
        }
        if (this.previewLayer) this.map.removeLayer(this.previewLayer);
        this.previewLayer = L.polyline( route, this.style.previewRoute ).addTo( this.map );
        this.map.fitBounds( this.previewLayer.getBounds() );
      },

      togglePOIs: function(e) {

        var self = this;
        var id = $( e.target ).val();

        // Do not show POIs if there is no route.
        if ( !this.layers.route || !$( e.target ).is(':checked') ) {
          if ( this.layers.pois ) this.map.removeLayer( this.layers.pois );
          return;
        }

        var pois = this.model.get('pois');
        if (pois.length > 0) {
          if ( this.layers.pois ) this.map.removeLayer( this.layers.pois );
          var markers = [];
          _.each(pois, function(poi) {
            var re = /POINT\((-?\d+\.[0-9]+)\s(-?[0-9]+\.[0-9]+)/;
            var point = poi.location.centroid.wkt.match(re);
            markers.push(
              L.marker([point[2], point[1]] ).bindPopup(poi.text.description.nl)
            );
          });
          this.layers.pois = L.layerGroup(markers ).addTo( this.map );
        }

      }

    } );

  } );<|endoftext|>


<commit_before>import React from 'react'

export default function () {
  return (

Houston Endowment

Mapping Need for Out-of-School Time Programs in Harris County

This tool assesses the degree of need for out-of-school time programs in nine select neighborhoods across Harris County. In displaying the varying resources and socioeconomic factors across these zip codes, we hope that this map guides the Houston out-of-school time community to effectively allocate funds to support its highest-need youth.

Share

  )
}
<commit_msg>Update header.js<commit_after>import React from 'react'

export default function () {
  return (

           {/*
Houston Endowment
*/}

Mapping Need for Out-of-School Time Programs in Harris County

This tool assesses the degree of need for out-of-school time programs in nine select neighborhoods across Harris County. In displaying the varying resources and socioeconomic factors across these zip codes, we hope that this map guides the Houston out-of-school time community to effectively allocate funds to support its highest-need youth.

Share

  )
}
<|endoftext|>


<commit_before>/* --------------------------------------- *
* Guerrilla UI                             *
* @author: Garrett Haptonstall (FearDread) *
* @module: GUI Core                        *
* ---------------------------------------- */
var GUI;

/**
 * @todo - add default config that will change behavior of GUI core
 * @todo - add custom config logic to apply customization options
 * @todo - allow async dependency loading to keep framework light - loads modules / plugins only when called via dependency array
 **/

// GUI Core
GUI = (function($) {

    // Make sure we have jQuery
    if (typeof $ === 'undefined' || $ === null) {
        throw new Error('Guerrilla UI requires jQuery library.');
    }

    // GUI Constructor
    function GUI() {

        // default config
        this.config = {
            name: 'Guerrilla UI',
            /* Logging verbosity */
            logLevel: 0,
            /* Single page app or Multiple page site */
            mode: 'multi',
            /* GUI library version */
            version: '0.4.7',
            jquery: true,
            animations: false
        };

        // ability to pass optional config object
        this.configure = function(options) {

            if (options !== null && utils.isObj(options)) {
                // set custom config options
                this.config = utils.merge(this.config, options);

                // set logging verbosity
                this.debug.level = this.config.logLevel || 0;
            }
        };

        // private objects & arrays for tracking
        this._modules = {};
        this._plugins = [];
        this._instances = {};
        this._sandboxes = {};
        this._running = {};
        this._imports = [];

        // add broker to core object
        this._broker = new Broker(this);
        this.Broker = Broker;

        this.attach = function(imports) {
            console.log('dynamic asyn module loading.');
            console.log('imports = ', imports);
        }
    }

    // console log wrapper
    GUI.prototype.debug = {
        level: 0,
        history: [],
        timeout: 5000,

        /**
         * Adds a warning message to the console.
         *
         * @param {String} out the message
        **/
        warn: function(out) {
            if (this.level < 2) {

                [].unshift.call(arguments, 'WARN:');

                if (typeof window !== undefined && window.console && console.warn) {

                    this._logger("warn", [].slice.call(arguments));

                } else if (window.console && console.log) {

                    this._logger("log", [].slice.call(arguments));

                } else if (window.opera && window.opera.postError) {

                    window.opera.postError("WARNING: " + out);

                }
            }
        },

        /**
         * Adds a message to the console.
         *
         * @param {String} out the message
        **/
        log: function(out) {
            if (this.level < 1) {
                if (window.console && console.log) {

                    [].unshift.call(arguments, 'Debug:');

                    this._logger("log", [].slice.call(arguments));

                } else if (window.opera && window.opera.postError) {

                    window.opera.postError("DEBUG: " + out);

                }
            }
        },

        _logger: function(type, arr) {

            this.history.push({type:arr});

            if (console.log.apply) {

                console[type].apply(console, arr);

            } else {

                console[type](arr);
            }
        },

        _stackTrace: function() {

            this.log(this.history);
        }
    };

    /* Public Methods */
    /******************/

    /**
     * Create new GUI module
     *
     * @param id {string} - module identifier
     * @param creator {function}  logic to execute inside module namespace
     * @param options {object} - optional object of extra parameters that will be passed to load()
     * @return this {object}
    **/
    GUI.prototype.create = function(id, creator, options) {
        var error;

        if (!options || options === null) {
          options = {};
        }

        error = utils.isType("string", id, "module ID") || utils.isType("function", creator, "creator") || utils.isType("object", options, "option parameter");

        if (error) {
          this.debug.warn("could not register module '" + id + "': " + error);
          return this;
        }

        if (id in this._modules) {
          this.debug.log("module " + id + " was already registered");
          return this;
        }

        this._modules[id] = {
          id: id,
          creator: creator,
          options: options
        };

        return this;
    };

    /**
     * Starts module with new sandbox instance
     *
     * @param moduleId {string} - module name or identifier
     * @param opt {object} - optional options object
     * @param cb {function} - callback function
     * @return boot {function} - call boot method and create new sandbox instance
    **/
    GUI.prototype.start = function(moduleId, opt, cb) {
        var error, id, initInst;

        if (!opt || opt === null) {
            opt = {};
        }
        if (!cb || cb === null) {
            cb = function() {};
        }

        if (arguments.length === 0) {
            return this._startAll();
        }

        if (moduleId instanceof Array) {
            return this._startAll(moduleId, opt);
        }

        if (typeof moduleId === "function") {
            return this._startAll(null, moduleId);
        }

        if (typeof opt === "function") {
            cb = opt;
            opt = {};
        }

        error = utils.isType("string", moduleId, "module ID") || utils.isType("object", opt, "second parameter") || (!this._modules[moduleId] ? "module doesn't exist" : void 0);

        if (error) {
            return this._fail(error, cb);
        }

        id = opt.instanceId || moduleId;

        if (this._running[id] === true) {
            return this._fail(new Error("module was already started"), cb);
        }

        initInst = (function(_this) {
            return function(err, instance, opt) {
                if (err) {
                    return _this._fail(err, cb);
                }

                try {
                    if (utils.hasArgs(instance.load, 2)) {
                        return instance.load(opt, function(err) {

                            if (!err) {
                                _this._running[id] = true;
                            }

                            return cb(err);
                        });
                    } else {

                        instance.load(opt);
                        _this._running[id] = true;

                        return cb();
                    }
                } catch (_error) {
                    e = _error;
                    return _this._fail(e, cb);
                }
            };
        })(this);

        return this.boot((function(_this) {

            return function(err) {

                if (err) {
                    return _this._fail(err, cb);
                }

                return _this._createInstance(moduleId, opt, initInst);
            };
        })(this));
    };

    /**
     * Loads plugin to Sandbox or Core classes
     *
     * @param plugin {function} - method with plugin logic
     * @param opt {object} - optional options object to be accessed in plugin
     * @return this {object}
    **/
    GUI.prototype.use = function(plugin, opt) {
        var i, len, p;

        if (plugin instanceof Array) {

            for (i = 0, len = plugin.length; i < len; i++) {
                p = plugin[i];

                switch (typeof p) {
                    case "function":
                        this.use(p);
                        break;

                    case "object":
                        this.use(p.plugin, p.options);
                }
            }

      } else {
          // must be function
          if (!utils.isFunc(plugin)) {
              return this;
          }

          // add to _plugins array
          this._plugins.push({
              creator: plugin,
              options: opt
          });
      }

      return this;
    };

    /**
     * Stops all running instances
     *
     * @param id {string} - module identifier
     * @param callback {function} - optional callback to run when module stopped
     * @return this {object}
    **/
    GUI.prototype.stop = function(id, callback) {
        var instance;

        if (cb === null) {
            cb = function() {};
        }

        if (arguments.length === 0 || typeof id === "function") {
            utils.run.all((function() {
                var results = [], x;

                for (x in this._instances) {
                    results.push(x);
                }

                return results;

            }).call(this), ((function(_this) {
                return function() {
                    return _this.stop.apply(_this, arguments);
                };
            })(this)), id, true);

        } else if (instance === this._instances[id]) {

            // remove instance from instances cache
            delete this._instances[id];

            // disable any events registered by module
            this._broker.off(instance);

            // run unload method in stopped modules
            this._runSandboxPlugins('unload', this._sandboxes[id], (function(_this) {
                return function(err) {
                    if (utils.hasArgs(instance.unload)) {

                        return instance.unload(function(err2) {
                            delete _this._running[id];

                            return cb(err || err2);
                        });
                    } else {

                        if (typeof instance.unload === "function") {
                            instance.unload();
                        }

                        delete _this._running[id];

                        return cb(err);
                    }
                };
            })(this));
        }

        return this;
    };

    /**
     * Register jQuery plugins to $ nameSpace
     *
     * @param plugin {object} - plugin object with all logic
     * @param module {string} - identifier for jQuery plugin
     * @return {function} - initialized jQuery plugin
    **/
    GUI.prototype.plugin = function(plugin, module) {
        var _this = this;

        if (plugin.fn && utils.isFunc(plugin.fn)) {

            $.fn[module.toLowerCase()] = function(options) {

                return new plugin.fn(this, options);
            };
        } else {

            GUI.log('Error :: Missing ' + plugin + ' fn() method.');
        }
    };

    /**
     * Load single or all available core plugins
     *
     * @param cb {function} - callback to execute after plugins loaded
     * @return this {object} - return GUI object with tasks array
    **/
    GUI.prototype.boot = function(cb) {
        var core, p, tasks;

        core = this;

        tasks = (function() {
            var j, len, ref, results;

            ref = this._plugins;
            results = [];

            for (j = 0, len = ref.length; j < len; j++) {
                p = ref[j];

                if (p.booted !== true) {
                    results.push((function(p) {

                        if (utils.hasArgs(p.creator, 3)) {
                            return function(next) {
                                var plugin;

                                return p.creator(core, p.options, function(err) {
                                    if (!err) {
                                        p.booted = true;
                                        p.plugin = plugin;
                                    }

                                    return next();
                                });
                            };
                        } else {
                            return function(next) {
                                p.plugin = p.creator(core, p.options);
                                p.booted = true;

                                return next();
                            };
                        }
                    })(p));
                }
            }

            return results;

        }).call(this);

        utils.run.series(tasks, cb, true);

        return this;
    };

    /* Private Methods */
    /*******************/

    /**
      * Called when starting module fails
      *
      * @param ev {object} - message or error object
      * @param cb {function} - callback method to run with error string / object
      * @return this {object}
    **/
    GUI.prototype._fail = function(ev, cb) {
        this.debug.warn(ev);

        cb(new Error("could not start module: " + ev.message));

        return this;
    };

    /**
      * Called when starting module fails
      *
      * @param mods {function} - method with array of all modules to start
      * @param cb {function} - callback method to run once modules started
      * @return this {object}
    **/
    GUI.prototype._startAll = function(mods, cb) {
        var done, startAction;

        // start all stored modules
        if (!mods || mods === null) {
            mods = (function() {
                var results = [], m;

                for (m in this._modules) {
                    results.push(m);
                }

                return results;
            }).call(this);
        }

        // self executing action
        startAction = (function(_this) {
            return function(m, next) {
                return _this.start(m, _this._modules[m].options, next);
            };
        })(this);

        // optional done callback for async loading
        done = function(err) {
            var e, i, j, k, len, mdls, modErrors, x;

            if ((err !== null ? err.length : void 0) > 0) {
                modErrors = {};

                for (i = j = 0, len = err.length; j < len; i = ++j) {
                    x = err[i];

                    if (x !== null) {
                        modErrors[mods[i]] = x;
                    }
                }

                // store all available modules errors
                mdls = (function() {
                    var results = [], k;

                    for (k in modErrors) {
                        results.push("'" + k + "'");
                    }

                    return results;
                })();

                e = new Error("errors occurred in the following modules: " + mdls);
                e.moduleErrors = modErrors;
            }

            return typeof cb === "function" ? cb(e) : void 0;
        };

        // run all modules in parallel formation
        utils.run.all(mods, startAction, done, true);

        return this;
    };

    /**
      * Create new sandbox instance and attach to module
      *
      * @param moduleId {string} - the module to create sandbox instance for
      * @param o {object} - options object
      * @param cb {function} - callback method to run once instance created
      * @return {function} - run sandboxed instances
    **/
    GUI.prototype._createInstance = function(moduleId, o, cb) {
        var Sandbox, iOpts, id, j, key, len, module, obj, opt, ref, sb, val;

        opt = o.options;
        id = o.instanceId || moduleId;

        module = this._modules[moduleId];

        if (this._instances[id]) {
            return cb(this._instances[id]);
        }

        iOpts = {};
        ref = [module.options, opt];

        for (j = 0, len = ref.length; j < len; j++) {
            obj = ref[j];

            if (obj) {
                for (key in obj) {
                    val = obj[key];

                    if (!iOpts[key] || iOpts[key] === null) {
                        iOpts[key] = val;
                    }
                }
            }
        }

        // create new API Sandbox
        sb = new API().create(this, id, iOpts, moduleId);

        // add config object if avail
        if (this.config && this.config !== null) {
          sb.config = this.config;
        }

        // run sandboxed instance load method
        return this._runSandboxPlugins('load', sb, (function(_this) {
            return function(err) {
                var instance;

                instance = new module.creator(sb);

                if (typeof instance.load !== "function") {

                    // determine if module is jQuery plugin
                    if (instance.fn && typeof instance.fn === 'function') {
                        return _this.plugin(instance, id);
                    }

                    return cb(new Error("module has no 'load' or 'fn' method"));
                }

                // store instance and sandbox
                _this._instances[id] = instance;
                _this._sandboxes[id] = sb;

                return cb(null, instance, iOpts);
            };
        })(this));
    };

    /**
      * Sets up needed tasks for module initializations
      *
      * @param ev {string} - check module for load / unload methods
      * @param sb {object} - the sandbox instance
      * @param cb {function} - callback method to run once instances initialized
      * @return {function} - utils.run.seris
    **/
    GUI.prototype._runSandboxPlugins = function(ev, sb, cb) {
        var p, tasks;

        tasks = (function() {
            var j, len, ref, ref1, results;

            ref = this._plugins;
            results = [];

            for (j = 0, len = ref.length; j < len; j++) {
                p = ref[j];

                if (typeof ((ref1 = p.plugin) !== null ? ref1[ev] : void 0) === "function") {
                    results.push((function(p) {
                        var fn;
                        fn = p.plugin[ev];

                        return function(next) {
                            if (utils.hasArgs(fn, 3)) {
                                return fn(sb, p.options, next);
                            } else {
                                fn(sb, p.options);
                                return next();
                            }
                        };
                    })(p));
                }
            }

            return results;

        }).call(this);

        return utils.run.series(tasks, cb, true);
    };

    return GUI;

})(jQuery);
<commit_msg>--fix minor lint error in main GUI object class.<commit_after>/* --------------------------------------- *
* Guerrilla UI                             *
* @author: Garrett Haptonstall (FearDread) *
* @module: GUI Core                        *
* ---------------------------------------- */
var GUI;

/**
 * @todo - add default config that will change behavior of GUI core
 * @todo - add custom config logic to apply customization options
 * @todo - allow async dependency loading to keep framework light - loads modules / plugins only when called via dependency array
 **/

// GUI Core
GUI = (function($) {

    // Make sure we have jQuery
    if (typeof $ === 'undefined' || $ === null) {
        throw new Error('Guerrilla UI requires jQuery library.');
    }

    // GUI Constructor
    function GUI() {

        // default config
        this.config = {
            name: 'Guerrilla UI',
            /* Logging verbosity */
            logLevel: 0,
            /* Single page app or Multiple page site */
            mode: 'multi',
            /* GUI library version */
            version: '0.4.7',
            jquery: true,
            animations: false
        };

        // ability to pass optional config object
        this.configure = function(options) {

            if (options !== null && utils.isObj(options)) {
                // set custom config options
                this.config = utils.merge(this.config, options);

                // set logging verbosity
                this.debug.level = this.config.logLevel || 0;
            }
        };

        // private objects & arrays for tracking
        this._modules = {};
        this._plugins = [];
        this._instances = {};
        this._sandboxes = {};
        this._running = {};
        this._imports = [];

        // add broker to core object
        this._broker = new Broker(this);
        this.Broker = Broker;

        this.attach = function(imports) {
            console.log('dynamic asyn module loading.');
            console.log('imports = ', imports);
        };
    }

    // console log wrapper
    GUI.prototype.debug = {
        level: 0,
        history: [],
        timeout: 5000,

        /**
         * Adds a warning message to the console.
         *
         * @param {String} out the message
        **/
        warn: function(out) {
            if (this.level < 2) {

                [].unshift.call(arguments, 'WARN:');

                if (typeof window !== undefined && window.console && console.warn) {

                    this._logger("warn", [].slice.call(arguments));

                } else if (window.console && console.log) {

                    this._logger("log", [].slice.call(arguments));

                } else if (window.opera && window.opera.postError) {

                    window.opera.postError("WARNING: " + out);

                }
            }
        },

        /**
         * Adds a message to the console.
         *
         * @param {String} out the message
        **/
        log: function(out) {
            if (this.level < 1) {
                if (window.console && console.log) {

                    [].unshift.call(arguments, 'Debug:');

                    this._logger("log", [].slice.call(arguments));

                } else if (window.opera && window.opera.postError) {

                    window.opera.postError("DEBUG: " + out);

                }
            }
        },

        _logger: function(type, arr) {

            this.history.push({type:arr});

            if (console.log.apply) {

                console[type].apply(console, arr);

            } else {

                console[type](arr);
            }
        },

        _stackTrace: function() {

            this.log(this.history);
        }
    };

    /* Public Methods */
    /******************/

    /**
     * Create new GUI module
     *
     * @param id {string} - module identifier
     * @param creator {function}  logic to execute inside module namespace
     * @param options {object} - optional object of extra parameters that will be passed to load()
     * @return this {object}
    **/
    GUI.prototype.create = function(id, creator, options) {
        var error;

        if (!options || options === null) {
          options = {};
        }

        error = utils.isType("string", id, "module ID") || utils.isType("function", creator, "creator") || utils.isType("object", options, "option parameter");

        if (error) {
          this.debug.warn("could not register module '" + id + "': " + error);
          return this;
        }

        if (id in this._modules) {
          this.debug.log("module " + id + " was already registered");
          return this;
        }

        this._modules[id] = {
          id: id,
          creator: creator,
          options: options
        };

        return this;
    };

    /**
     * Starts module with new sandbox instance
     *
     * @param moduleId {string} - module name or identifier
     * @param opt {object} - optional options object
     * @param cb {function} - callback function
     * @return boot {function} - call boot method and create new sandbox instance
    **/
    GUI.prototype.start = function(moduleId, opt, cb) {
        var error, id, initInst;

        if (!opt || opt === null) {
            opt = {};
        }
        if (!cb || cb === null) {
            cb = function() {};
        }

        if (arguments.length === 0) {
            return this._startAll();
        }

        if (moduleId instanceof Array) {
            return this._startAll(moduleId, opt);
        }

        if (typeof moduleId === "function") {
            return this._startAll(null, moduleId);
        }

        if (typeof opt === "function") {
            cb = opt;
            opt = {};
        }

        error = utils.isType("string", moduleId, "module ID") || utils.isType("object", opt, "second parameter") || (!this._modules[moduleId] ? "module doesn't exist" : void 0);

        if (error) {
            return this._fail(error, cb);
        }

        id = opt.instanceId || moduleId;

        if (this._running[id] === true) {
            return this._fail(new Error("module was already started"), cb);
        }

        initInst = (function(_this) {
            return function(err, instance, opt) {
                if (err) {
                    return _this._fail(err, cb);
                }

                try {
                    if (utils.hasArgs(instance.load, 2)) {
                        return instance.load(opt, function(err) {

                            if (!err) {
                                _this._running[id] = true;
                            }

                            return cb(err);
                        });
                    } else {

                        instance.load(opt);
                        _this._running[id] = true;

                        return cb();
                    }
                } catch (_error) {
                    e = _error;
                    return _this._fail(e, cb);
                }
            };
        })(this);

        return this.boot((function(_this) {

            return function(err) {

                if (err) {
                    return _this._fail(err, cb);
                }

                return _this._createInstance(moduleId, opt, initInst);
            };
        })(this));
    };

    /**
     * Loads plugin to Sandbox or Core classes
     *
     * @param plugin {function} - method with plugin logic
     * @param opt {object} - optional options object to be accessed in plugin
     * @return this {object}
    **/
    GUI.prototype.use = function(plugin, opt) {
        var i, len, p;

        if (plugin instanceof Array) {

            for (i = 0, len = plugin.length; i < len; i++) {
                p = plugin[i];

                switch (typeof p) {
                    case "function":
                        this.use(p);
                        break;

                    case "object":
                        this.use(p.plugin, p.options);
                }
            }

      } else {
          // must be function
          if (!utils.isFunc(plugin)) {
              return this;
          }

          // add to _plugins array
          this._plugins.push({
              creator: plugin,
              options: opt
          });
      }

      return this;
    };

    /**
     * Stops all running instances
     *
     * @param id {string} - module identifier
     * @param callback {function} - optional callback to run when module stopped
     * @return this {object}
    **/
    GUI.prototype.stop = function(id, callback) {
        var instance;

        if (cb === null) {
            cb = function() {};
        }

        if (arguments.length === 0 || typeof id === "function") {
            utils.run.all((function() {
                var results = [], x;

                for (x in this._instances) {
                    results.push(x);
                }

                return results;

            }).call(this), ((function(_this) {
                return function() {
                    return _this.stop.apply(_this, arguments);
                };
            })(this)), id, true);

        } else if (instance === this._instances[id]) {

            // remove instance from instances cache
            delete this._instances[id];

            // disable any events registered by module
            this._broker.off(instance);

            // run unload method in stopped modules
            this._runSandboxPlugins('unload', this._sandboxes[id], (function(_this) {
                return function(err) {
                    if (utils.hasArgs(instance.unload)) {

                        return instance.unload(function(err2) {
                            delete _this._running[id];

                            return cb(err || err2);
                        });
                    } else {

                        if (typeof instance.unload === "function") {
                            instance.unload();
                        }

                        delete _this._running[id];

                        return cb(err);
                    }
                };
            })(this));
        }

        return this;
    };

    /**
     * Register jQuery plugins to $ nameSpace
     *
     * @param plugin {object} - plugin object with all logic
     * @param module {string} - identifier for jQuery plugin
     * @return {function} - initialized jQuery plugin
    **/
    GUI.prototype.plugin = function(plugin, module) {
        var _this = this;

        if (plugin.fn && utils.isFunc(plugin.fn)) {

            $.fn[module.toLowerCase()] = function(options) {

                return new plugin.fn(this, options);
            };
        } else {

            GUI.log('Error :: Missing ' + plugin + ' fn() method.');
        }
    };

    /**
     * Load single or all available core plugins
     *
     * @param cb {function} - callback to execute after plugins loaded
     * @return this {object} - return GUI object with tasks array
    **/
    GUI.prototype.boot = function(cb) {
        var core, p, tasks;

        core = this;

        tasks = (function() {
            var j, len, ref, results;

            ref = this._plugins;
            results = [];

            for (j = 0, len = ref.length; j < len; j++) {
                p = ref[j];

                if (p.booted !== true) {
                    results.push((function(p) {

                        if (utils.hasArgs(p.creator, 3)) {
                            return function(next) {
                                var plugin;

                                return p.creator(core, p.options, function(err) {
                                    if (!err) {
                                        p.booted = true;
                                        p.plugin = plugin;
                                    }

                                    return next();
                                });
                            };
                        } else {
                            return function(next) {
                                p.plugin = p.creator(core, p.options);
                                p.booted = true;

                                return next();
                            };
                        }
                    })(p));
                }
            }

            return results;

        }).call(this);

        utils.run.series(tasks, cb, true);

        return this;
    };

    /* Private Methods */
    /*******************/

    /**
      * Called when starting module fails
      *
      * @param ev {object} - message or error object
      * @param cb {function} - callback method to run with error string / object
      * @return this {object}
    **/
    GUI.prototype._fail = function(ev, cb) {
        this.debug.warn(ev);

        cb(new Error("could not start module: " + ev.message));

        return this;
    };

    /**
      * Called when starting module fails
      *
      * @param mods {function} - method with array of all modules to start
      * @param cb {function} - callback method to run once modules started
      * @return this {object}
    **/
    GUI.prototype._startAll = function(mods, cb) {
        var done, startAction;

        // start all stored modules
        if (!mods || mods === null) {
            mods = (function() {
                var results = [], m;

                for (m in this._modules) {
                    results.push(m);
                }

                return results;
            }).call(this);
        }

        // self executing action
        startAction = (function(_this) {
            return function(m, next) {
                return _this.start(m, _this._modules[m].options, next);
            };
        })(this);

        // optional done callback for async loading
        done = function(err) {
            var e, i, j, k, len, mdls, modErrors, x;

            if ((err !== null ? err.length : void 0) > 0) {
                modErrors = {};

                for (i = j = 0, len = err.length; j < len; i = ++j) {
                    x = err[i];

                    if (x !== null) {
                        modErrors[mods[i]] = x;
                    }
                }

                // store all available modules errors
                mdls = (function() {
                    var results = [], k;

                    for (k in modErrors) {
                        results.push("'" + k + "'");
                    }

                    return results;
                })();

                e = new Error("errors occurred in the following modules: " + mdls);
                e.moduleErrors = modErrors;
            }

            return typeof cb === "function" ? cb(e) : void 0;
        };

        // run all modules in parallel formation
        utils.run.all(mods, startAction, done, true);

        return this;
    };

    /**
      * Create new sandbox instance and attach to module
      *
      * @param moduleId {string} - the module to create sandbox instance for
      * @param o {object} - options object
      * @param cb {function} - callback method to run once instance created
      * @return {function} - run sandboxed instances
    **/
    GUI.prototype._createInstance = function(moduleId, o, cb) {
        var Sandbox, iOpts, id, j, key, len, module, obj, opt, ref, sb, val;

        opt = o.options;
        id = o.instanceId || moduleId;

        module = this._modules[moduleId];

        if (this._instances[id]) {
            return cb(this._instances[id]);
        }

        iOpts = {};
        ref = [module.options, opt];

        for (j = 0, len = ref.length; j < len; j++) {
            obj = ref[j];

            if (obj) {
                for (key in obj) {
                    val = obj[key];

                    if (!iOpts[key] || iOpts[key] === null) {
                        iOpts[key] = val;
                    }
                }
            }
        }

        // create new API Sandbox
        sb = new API().create(this, id, iOpts, moduleId);

        // add config object if avail
        if (this.config && this.config !== null) {
          sb.config = this.config;
        }

        // run sandboxed instance load method
        return this._runSandboxPlugins('load', sb, (function(_this) {
            return function(err) {
                var instance;

                instance = new module.creator(sb);

                if (typeof instance.load !== "function") {

                    // determine if module is jQuery plugin
                    if (instance.fn && typeof instance.fn === 'function') {
                        return _this.plugin(instance, id);
                    }

                    return cb(new Error("module has no 'load' or 'fn' method"));
                }

                // store instance and sandbox
                _this._instances[id] = instance;
                _this._sandboxes[id] = sb;

                return cb(null, instance, iOpts);
            };
        })(this));
    };

    /**
      * Sets up needed tasks for module initializations
      *
      * @param ev {string} - check module for load / unload methods
      * @param sb {object} - the sandbox instance
      * @param cb {function} - callback method to run once instances initialized
      * @return {function} - utils.run.seris
    **/
    GUI.prototype._runSandboxPlugins = function(ev, sb, cb) {
        var p, tasks;

        tasks = (function() {
            var j, len, ref, ref1, results;

            ref = this._plugins;
            results = [];

            for (j = 0, len = ref.length; j < len; j++) {
                p = ref[j];

                if (typeof ((ref1 = p.plugin) !== null ? ref1[ev] : void 0) === "function") {
                    results.push((function(p) {
                        var fn;
                        fn = p.plugin[ev];

                        return function(next) {
                            if (utils.hasArgs(fn, 3)) {
                                return fn(sb, p.options, next);
                            } else {
                                fn(sb, p.options);
                                return next();
                            }
                        };
                    })(p));
                }
            }

            return results;

        }).call(this);

        return utils.run.series(tasks, cb, true);
    };

    return GUI;

})(jQuery);
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    $ = require('gulp-load-plugins')({
        lazy: true
    }),

    // base application configuration
    del = require('del'),
    wiredep = require('wiredep').stream,
    browserSync = require('browser-sync'),
    args = require('yargs').argv,
    chalk = require('chalk'),

    // custom plugins for simple style guide
    helper = require('./libs/helper'),
    config = require('./gulp.config'),
    ssgCoreConfig = require('./libs/gen-config'),
    ssgCoreCompile = require('./libs/precomp-pattern');

// Contants
var reload = browserSync.reload;

/////////// Reused functions
// check javascript styling conventions
var checkJSStyle = function(files) {

    if (files === undefined || files === null) {
        log.Error('Files is not defined');
        return;
    }

    // pass correct file array in
    gulp.src(files)
        .pipe($.plumber())
        .pipe($.if(args.verbose, $.print()))
        .pipe($.jscs())
        .pipe($.jshint())
        .pipe($.jshint.reporter('jshint-stylish'), {
            verbose: true
        });
};

// Used for inject
var inject = function(options) {

    // pages to inject files
    var target = gulp.src(config.landingPages);

    // source that needs to be injected
    var sources = gulp.src(options.source, {
        read: false
    });

    return target
        .pipe($.plumber())
        .pipe($.inject(sources, {
            ignorePath: '.tmp'
        }))
        .pipe(gulp.dest(config.basepath));
};

// compile styles and use path
var compileStyles = function(config) {

    // base remove all except sub folder
    var cssPath = '';

    return gulp.src(config.src, {
            base: config.base
        })
        .pipe($.plumber())
        .pipe($.sourcemaps.init())
        .pipe($.sass.sync({
            outputStyle: 'expanded',
            precision: 10,
            includePaths: ['.']
        }).on('error', $.sass.logError))
        .pipe($.autoprefixer({
            browsers: ['last 1 version']
        }))
        .pipe($.sourcemaps.write())
        .pipe($.rename({
            dirname: cssPath
        }))
        .pipe(gulp.dest('.tmp/styles'))
        .pipe(browserSync.stream());

};
// Gulp taks
var log = {
    Msg: function(msg) {
        helper.logMessage(msg, helper.logType.info);
    },
    Error: function(msg) {
        helper().logMessage(msg, helper.logType.error);
    },
    Warn: function(msg) {
        helper().logMessage(msg, helper.logType.warning);
    }
};

/// Cleaning up tmp folder
// Clean forlder strucuture and temp folders
gulp.task('clean', function(done) {

    var files2delete = config.tempFiles + '*';

    del(config.tempFiles).then(function() {
        return done();
    });

});

///// Style Configuration
// Styles Sheet compilation
gulp.task('styles', function() {

    var baseStyleOptions = {
        src: 'app/styles/*.scss',
        base: './app/styles/'
    };

    // piping through sass
    return compileStyles(baseStyleOptions);

});

// Styles Sheet compilation
gulp.task('styles:core', function() {

    var baseStyleOptions = {
        src: 'app/_core/styles/*.scss',
        base: './app/_core/styles/',
    };

    // piping through sass
    return compileStyles(baseStyleOptions);

});
///// Style Configuration End

// Generate index file for all pattern
gulp.task('gen-config', function() {

    // var patternPath = config.patterns[0];
    var patternPath = './app/_patterns/**/*.hbs';

    var curConfig = {
        patterns: patternPath,
        configFile: config.patternConfig
    };

    // parse configuration and log
    gulp.src(patternPath)
        .pipe(ssgCoreConfig.createConfig(curConfig));

});

// Precompile handle bar templates
gulp.task('precompile:ssg', function() {

    return ssgCoreCompile(config.ssg);

});

// Precompile core templates
gulp.task('precompile:core', function() {

    return ssgCoreCompile(config.core);

});

gulp.task('test', function() {

    ssgCoreConfig.handleDelete();

});

gulp.task('ssgCore-update', function() {

    return gulp.src('app/_core/**/*.js')
        .pipe($.sourcemaps.init())
        .pipe($.concat('ssgCoreLib.js'))
        .pipe($.wrap('var jQuery = jQuery.noConflict();\n(function($){\n\'use strict\';\n<%= contents %>\n})(jQuery);'))
        .pipe($.sourcemaps.write('./', {
            includeContent: false,
            sourceRoot: '/_core/'
        }))
        .pipe(gulp.dest('.tmp/scripts'))
        .pipe(browserSync.stream({
            match: '**/*.js'
        }));

});

// Wire up dependencies
gulp.task('wiredep', function() {

    var options = config.getWiredepDefaultOptions();

    gulp.src('app/styles/main.scss')
        .pipe($.plumber())
        .pipe($.print())
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)+/
        }))
        .pipe(gulp.dest('app/styles'));

    gulp.src('app/*.html')
        .pipe($.plumber())
        .pipe($.print())
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)*\.\./,
            devDependencies: true
        }))
        .pipe(gulp.dest('app'));

});

// inject javascript into file
gulp.task('inject:scripts', function() {

    var options = {
        source: [config.tempFiles + '**/*.js'],
    };

    return inject(options);

});

gulp.task('inject:styles', function() {

    var options = {
        source: [config.js],
    };

    helper.log('Inject Style Sheets', helper.logType.info);

    return inject(options);

});

gulp.task('vet', function() {

    log.Msg('Analyzing source :: Style Guide Mode');

    gulp.watch(config.devjs)
        .on('change', function() {
            checkJSStyle(config.js);
        });

});

gulp.task('vet-dev', function() {

    log.Msg('Analyzing source :: Dev Mode');
    console.log(config.devjs);
    gulp.watch(config.devjs)
        .on('change', function() {
            checkJSStyle(config.devjs);
        });

});

gulp.task('wiredep', () => {
    // Inject into CSS files
    gulp.src('app/styles/*.scss')
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)+/
        }))
        .pipe(gulp.dest('app/styles'));
    // Inject into html files
    gulp.src('app/*.html')
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)*\.\./
        }))
        .pipe(gulp.dest('app'));
});

// compile handlebar patterns
gulp.task('serve', ['ssgCore-update', 'styles', 'styles:core', 'precompile:core', 'precompile:ssg', 'vet'], function() {

    gulp.watch('app/_patterns/**/*.hbs', function(event) {
        ssgCoreConfig.fsEvents(event, config);
    });

    // Recompile pattern
    gulp.watch([
        'app/*.html',
        'app/scripts/**/*.js',
        'app/images/**/*'
    ]).on('change', reload);

    gulp.watch(['app/_config/*.json'], ['precompile:ssg'], reload);

    gulp.watch('./app/styles/**/*.scss', ['styles'], reload);

    browserSync({
        notify: false,
        port: 9000,
        server: {
            baseDir: ['app', 'libs', '.tmp'],
            routes: {
                '/bower_components': 'bower_components',
                '/tmp': '/',
                '/lib': '/'
            }
        },
        https: true
    });

});<commit_msg>Updated gulpfile.js<commit_after>var gulp = require('gulp'),
    $ = require('gulp-load-plugins')({
        lazy: true
    }),

    // base application configuration
    del = require('del'),
    wiredep = require('wiredep').stream,
    browserSync = require('browser-sync'),
    args = require('yargs').argv,
    chalk = require('chalk'),

    // custom plugins for simple style guide
    helper = require('./libs/helper'),
    config = require('./gulp.config'),
    ssgCoreConfig = require('./libs/gen-config'),
    ssgCoreCompile = require('./libs/precomp-pattern');

// Contants
var reload = browserSync.reload;

/////////// Reused functions
// check javascript styling conventions
var checkJSStyle = function(files) {

    if (files === undefined || files === null) {
        log.Error('Files is not defined');
        return;
    }

    // pass correct file array in
    gulp.src(files)
        .pipe($.plumber())
        .pipe($.if(args.verbose, $.print()))
        // .pipe($.jscs())
        .pipe($.jshint())
        .pipe($.jshint.reporter('jshint-stylish'), {
            verbose: true
        });
};

// Used for inject
var inject = function(options) {

    // pages to inject files
    var target = gulp.src(config.landingPages);

    // source that needs to be injected
    var sources = gulp.src(options.source, {
        read: false
    });

    return target
        .pipe($.plumber())
        .pipe($.inject(sources, {
            ignorePath: '.tmp'
        }))
        .pipe(gulp.dest(config.basepath));
};

// compile styles and use path
var compileStyles = function(config) {

    // base remove all except sub folder
    var cssPath = '';

    return gulp.src(config.src, {
            base: config.base
        })
        .pipe($.plumber())
        .pipe($.sourcemaps.init())
        .pipe($.sass.sync({
            outputStyle: 'expanded',
            precision: 10,
            includePaths: ['.']
        }).on('error', $.sass.logError))
        .pipe($.autoprefixer({
            browsers: ['last 1 version']
        }))
        .pipe($.sourcemaps.write())
        .pipe($.rename({
            dirname: cssPath
        }))
        .pipe(gulp.dest('.tmp/styles'))
        .pipe(browserSync.stream());

};
// Gulp taks
var log = {
    Msg: function(msg) {
        helper.logMessage(msg, helper.logType.info);
    },
    Error: function(msg) {
        helper().logMessage(msg, helper.logType.error);
    },
    Warn: function(msg) {
        helper().logMessage(msg, helper.logType.warning);
    }
};

/// Cleaning up tmp folder
// Clean forlder strucuture and temp folders
gulp.task('clean', function(done) {

    var files2delete = config.tempFiles + '*';

    del(config.tempFiles).then(function() {
        return done();
    });

});

///// Style Configuration
// Styles Sheet compilation
gulp.task('styles', function() {

    var baseStyleOptions = {
        src: 'app/styles/**/*.scss',
        base: './app/styles/'
    };

    // piping through sass
    return compileStyles(baseStyleOptions);

});

// Styles Sheet compilation
gulp.task('styles:core', function() {

    var baseStyleOptions = {
        src: 'app/_core/styles/*.scss',
        base: './app/_core/styles/',
    };

    // piping through sass
    return compileStyles(baseStyleOptions);

});
///// Style Configuration End

// Generate index file for all pattern
gulp.task('gen-config', function() {

    // var patternPath = config.patterns[0];
    var patternPath = './app/_pattern/**/*.hbs';

    var curConfig = {
        patterns: patternPath,
        configFile: config.patternConfig
    };

    // parse configuration and log
    gulp.src(patternPath)
        .pipe(ssgCoreConfig.createConfig(curConfig));

});

// Precompile handle bar templates
gulp.task('precompile:ssg', function() {

    return ssgCoreCompile(config.ssg);

});

// Precompile core templates
gulp.task('precompile:core', function() {

    return ssgCoreCompile(config.core);

});

gulp.task('test', function() {

    ssgCoreConfig.handleDelete();

});

gulp.task('ssgCore-update', function() {

    return gulp.src('app/_core/**/*.js')
        .pipe($.sourcemaps.init())
        .pipe($.concat('ssgCoreLib.js'))
        .pipe($.wrap('var jQuery = jQuery.noConflict();\n(function($){\n\'use strict\';\n<%= contents %>\n})(jQuery);'))
        .pipe($.sourcemaps.write('./', {
            includeContent: false,
            sourceRoot: '/_core/'
        }))
        .pipe(gulp.dest('.tmp/scripts'))
        .pipe(browserSync.stream({
            match: '**/*.js'
        }));

});

// Wire up dependencies
gulp.task('wiredep', function() {

    var options = config.getWiredepDefaultOptions();

    gulp.src('app/styles/main.scss')
        .pipe($.plumber())
        .pipe($.print())
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)+/
        }))
        .pipe(gulp.dest('app/styles'));

    gulp.src('app/*.html')
        .pipe($.plumber())
        .pipe($.print())
        .pipe(wiredep({
            ignorePath: /^(\.\.\/)*\.\./,
            devDependencies: true
        }))
        .pipe(gulp.dest('app'));

});

// inject javascript into file
gulp.task('inject:scripts', function() {

    var options = {
        source: [config.tempFiles + '**/*.js'],
    };

    return inject(options);

});

gulp.task('inject:styles', function() {

    var options = {
        source: [config.js],
    };

    helper.log('Inject Style Sheets', helper.logType.info);

    return inject(options);

});

gulp.task('vet', function() {

    log.Msg('Analyzing source :: Style Guide Mode');

    gulp.watch(config.devjs)
        .on('change', function() {
            checkJSStyle(config.js);
        });

});

gulp.task('vet-dev', function() {

    log.Msg('Analyzing source :: Dev Mode');
    console.log(config.devjs);
    gulp.watch(config.devjs)
        .on('change', function() {
            checkJSStyle(config.devjs);
        });

});

// compile handlebar patterns
gulp.task('serve', ['ssgCore-update', 'styles', 'styles:core', 'precompile:core', 'precompile:ssg', 'vet'], function() {

    gulp.watch('app/_patterns/**/*.hbs', function(event) {

        ssgCoreConfig.fsEvents(event, config);

    });

    // Recompile pattern
    gulp.watch([
        'app/*.html',
        'app/scripts/**/*.js',
        'app/images/**/*'
    ]).on('change', reload);

    gulp.watch(['app/_config/*.json'], ['precompile:ssg'], reload);

    // gulp.watch('app/_core/**/*.js', ['ssgCore-update'], reload);

    // gulp.watch('app/_core/styles/*.scss', ['styles:core'], reload);
    gulp.watch('./app/styles/**/*.scss', ['styles'], reload);

    browserSync({
        notify: false,
        port: 9000,
        server: {
            baseDir: ['libs', '.tmp', 'app'],
            routes: {
                '/bower_components': 'bower_components',
                '/tmp': '/',
                '/lib': '/'
            }
        },
        https: true
    });

});<|endoftext|>