<commit_before>// ARTIFACT ///////////////////////////////////////////////////////

// added as part of the ingress #13magnus in november 2013, artifacts
// are additional game elements overlayed on the intel map
// currently there are only jarvis-related entities
// - shards: move between portals (along links) each hour. more than one can be at a portal
// - targets: specific portals - one per team
// the artifact data includes details for the specific portals, so can be useful
// 2014-02-06: intel site updates hint at new 'amar artifacts', likely following the same system as above

window.artifact = function() {}

window.artifact.setup = function() {
  artifact.REFRESH_JITTER = 2*60;  // 2 minute random period so not all users refresh at once
  artifact.REFRESH_SUCCESS = 60*60;  // 60 minutes on success
  artifact.REFRESH_FAILURE = 2*60;  // 2 minute retry on failure

  artifact.idle = false;
  artifact.clearData();

  addResumeFunction(artifact.idleResume);

  // move the initial data request onto a very short timer. prevents thrown exceptions causing IITC boot failures
  setTimeout (artifact.requestData, 1);

  artifact._layer = new L.LayerGroup();
  addLayerGroup ('Artifacts', artifact._layer, true);

  $('#toolbox').append(' Artifacts');

}

window.artifact.requestData = function() {
  if (isIdle()) {
    artifact.idle = true;
  } else {
    window.postAjax('artifacts', {}, artifact.handleSuccess, artifact.handleError);
  }
}

window.artifact.idleResume = function() {
  if (artifact.idle) {
    artifact.idle = false;
    artifact.requestData();
  }
}

window.artifact.handleSuccess = function(data) {
  artifact.processData (data);

  // start the next refresh at a multiple of REFRESH_SUCCESS seconds, plus a random REFRESH_JITTER amount to prevent excessive server hits at one time
  var now = Date.now();
  var nextTime = Math.ceil(now/(artifact.REFRESH_SUCCESS*1000))*(artifact.REFRESH_SUCCESS*1000) + Math.floor(Math.random()*artifact.REFRESH_JITTER*1000);

  setTimeout (artifact.requestData, nextTime - now);
}

window.artifact.handleFailure = function(data) {
  // no useful data on failure - do nothing

  setTimeout (artifact.requestData, artifact.REFRESH_FAILURE*1000);
}

window.artifact.processData = function(data) {

  if (data.error || !data.artifacts) {
    console.warn('Failed to find artifacts in artifact response');
  }

  artifact.clearData();

  $.each (data.artifacts, function(i,artData) {
    // if we have no descriptions for a type, we don't know about it
    if (!artifact.getArtifactDescriptions(artData.artifactId)) {
      // jarvis and amar artifacts - fragmentInfos and targetInfos
      // (future types? completely unknown at this time!)
      console.warn('Note: unknown artifactId '+artData.artifactId+' - guessing how to handle it');
    }

    artifact.artifactTypes[artData.artifactId] = artData.artifactId;

    if (artData.fragmentInfos) {
      artifact.processFragmentInfos (artData.artifactId, artData.fragmentInfos);
    }

    if (artData.targetInfos) {
      artifact.processTargetInfos (artData.artifactId, artData.targetInfos);
    }

    // other data in future? completely unknown!
  });

  // redraw the artifact layer
  artifact.updateLayer();

}

window.artifact.clearData = function() {

  artifact.portalInfo = {};
  artifact.artifactTypes = {};
}

window.artifact.processFragmentInfos = function (id, fragments) {
  $.each(fragments, function(i, fragment) {
    if (!artifact.portalInfo[fragment.portalGuid]) {
      artifact.portalInfo[fragment.portalGuid] = { _entityData: fragment.portalInfo };
    }

    if (!artifact.portalInfo[fragment.portalGuid][id]) artifact.portalInfo[fragment.portalGuid][id] = {};

    if (!artifact.portalInfo[fragment.portalGuid][id].fragments) artifact.portalInfo[fragment.portalGuid][id].fragments = [];

    $.each(fragment.fragments, function(i,f) {
      artifact.portalInfo[fragment.portalGuid][id].fragments.push(f);
    });

  });
}

window.artifact.processTargetInfos = function (id, targets) {
  $.each(targets, function(i, target) {
    if (!artifact.portalInfo[target.portalGuid]) {
      artifact.portalInfo[target.portalGuid] = { _entityData: target.portalInfo };
    }

    if (!artifact.portalInfo[target.portalGuid][id]) artifact.portalInfo[target.portalGuid][id] = {};

    artifact.portalInfo[target.portalGuid][id].target = target.team === 'RESISTANCE' ? TEAM_RES : TEAM_ENL;
  });
}

window.artifact.getArtifactTypes = function() {
  return Object.keys(artifact.artifactTypes);
}

window.artifact.isArtifact = function(type) {
  return type in artifact.artifactTypes;
}

window.artifact.getArtifactDescriptions = function(type) {
  var descriptions = {
    'jarvis': { 'title': "Jarvis Shards", 'fragmentName': "shards" },
    'amar': { 'title': "Amar Artifacts", 'fragmentName': "artifacts" }
  };

  return descriptions[type];
}

// used to render portals that would otherwise be below the visible level
window.artifact.getArtifactEntities = function() {
  var entities = [];

  // create fake entities from the artifact data
  $.each (artifact.portalInfo, function(guid,data) {
    var timestamp = 0; // we don't have a valid timestamp - so let's use 0
    var ent = [ guid, timestamp, data._entityData ];
    entities.push(ent);
  });

  return entities;
}

window.artifact.getInterestingPortals = function() {
  return Object.keys(artifact.portalInfo);
}

// quick test for portal being relevant to artifacts - of any type
window.artifact.isInterestingPortal = function(guid) {
  return guid in artifact.portalInfo;
}

// get the artifact data for a specified artifact id (e.g. 'jarvis'), if it exists - otherwise returns something 'false'y
window.artifact.getPortalData = function(guid,artifactId) {
  return artifact.portalInfo[guid] && artifact.portalInfo[guid][artifactId];
}

window.artifact.updateLayer = function() {
  artifact._layer.clearLayers();

  $.each(artifact.portalInfo, function(guid,data) {
    var latlng = L.latLng ([data._entityData.latE6/1E6, data._entityData.lngE6/1E6]);

    // jarvis shard icon
    var iconUrl = undefined;
    var iconSize = 0;
    var opacity = 1.0;

    // redundant as of 2014-02-05 - jarvis shards removed
    if (data.jarvis) {
      if (data.jarvis.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.jarvis.fragments ? data.jarvis.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.jarvis.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }
    // 2014-02-06: a guess at whats needed for the new artifacts
    if (data.amar) {
      if (data.amar.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.amar.fragments ? data.amar.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/amar_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.amar.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/amar_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }

    if (iconUrl) {
      var icon = L.icon({
        iconUrl: iconUrl,
        iconSize: [iconSize,iconSize],
        iconAnchor: [iconSize/2,iconSize/2],
        className: 'no-pointer-events'  // the clickable: false below still blocks events going through to the svg underneath
      });

      var marker = L.marker (latlng, {icon: icon, clickable: false, keyboard: false, opacity: opacity });

      artifact._layer.addLayer(marker);
    } else {
      console.warn('Oops! no URL for artifact portal icon?!');
    }
  });

}

window.artifact.showArtifactList = function() {

  var html = '';

  var typeNames = { 'jarvis': 'Jarvis Shards', 'amar': 'Amar Artifacts' };

  if (Object.keys(artifact.artifactTypes).length == 0) {
    html += 'No artifacts at this time';
  }

  $.each(artifact.artifactTypes, function(type,type2) {
    var description = artifact.getArtifactDescriptions(type);

    var name = description ? description.title : ('unknown artifact type: '+type);

    html += '

'+name+'
';

    html += '
';
    html += '
Portal	Details
';

    var tableRows = [];

    $.each(artifact.portalInfo, function(guid, data) {
      if (type in data) {
        // this portal has data for this artifact type - add it to the table

        var sortVal = 0;

        var onclick = 'zoomToAndShowPortal(\''+guid+'\',['+data._entityData.latE6/1E6+','+data._entityData.lngE6/1E6+'])';
        var row = '
'+escapeHtmlSpecialChars(data._entityData.title)+'	';

        row += '';

        if (data[type].target) {
          row += ''+(data[type].target==TEAM_RES?'Resistance':'Enlightened')+' target ';
          sortVal = 100000+data[type].target;
        }

        if (data[type].fragments) {
          if (data[type].target) {
            row += '
';
          }
          var fragmentName = description ? description.fragmentName : 'fragment';
          row += ''+fragmentName+': #'+data[type].fragments.join(', #')+' ';
          sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key
        }

        row += '
';

        tableRows.push ( [sortVal, row] );
      }
    });

    // check for no rows, and add a note to the table instead
    if (tableRows.length == 0) {
      html += '
No portals at this time
';
    }

    // sort the rows
    tableRows.sort(function(a,b) {
      return a[0]-b[0];
    });

    // and add them to the table
    html += tableRows.map(function(a){return a[1];}).join('');

    html += '
';
  });

  dialog({
    title: 'Artifacts',
    html: html,
    width: 400,
    position: {my: 'right center', at: 'center-60 center', of: window, collision: 'fit'}
  });

}
<commit_msg>artifacts: a guess as to what's needed for the up-coming 'helios' artifacts<commit_after>// ARTIFACT ///////////////////////////////////////////////////////

// added as part of the ingress #13magnus in november 2013, artifacts
// are additional game elements overlayed on the intel map
// currently there are only jarvis-related entities
// - shards: move between portals (along links) each hour. more than one can be at a portal
// - targets: specific portals - one per team
// the artifact data includes details for the specific portals, so can be useful
// 2014-02-06: intel site updates hint at new 'amar artifacts', likely following the same system as above

window.artifact = function() {}

window.artifact.setup = function() {
  artifact.REFRESH_JITTER = 2*60;  // 2 minute random period so not all users refresh at once
  artifact.REFRESH_SUCCESS = 60*60;  // 60 minutes on success
  artifact.REFRESH_FAILURE = 2*60;  // 2 minute retry on failure

  artifact.idle = false;
  artifact.clearData();

  addResumeFunction(artifact.idleResume);

  // move the initial data request onto a very short timer. prevents thrown exceptions causing IITC boot failures
  setTimeout (artifact.requestData, 1);

  artifact._layer = new L.LayerGroup();
  addLayerGroup ('Artifacts', artifact._layer, true);

  $('#toolbox').append(' Artifacts');

}

window.artifact.requestData = function() {
  if (isIdle()) {
    artifact.idle = true;
  } else {
    window.postAjax('artifacts', {}, artifact.handleSuccess, artifact.handleError);
  }
}

window.artifact.idleResume = function() {
  if (artifact.idle) {
    artifact.idle = false;
    artifact.requestData();
  }
}

window.artifact.handleSuccess = function(data) {
  artifact.processData (data);

  // start the next refresh at a multiple of REFRESH_SUCCESS seconds, plus a random REFRESH_JITTER amount to prevent excessive server hits at one time
  var now = Date.now();
  var nextTime = Math.ceil(now/(artifact.REFRESH_SUCCESS*1000))*(artifact.REFRESH_SUCCESS*1000) + Math.floor(Math.random()*artifact.REFRESH_JITTER*1000);

  setTimeout (artifact.requestData, nextTime - now);
}

window.artifact.handleFailure = function(data) {
  // no useful data on failure - do nothing

  setTimeout (artifact.requestData, artifact.REFRESH_FAILURE*1000);
}

window.artifact.processData = function(data) {

  if (data.error || !data.artifacts) {
    console.warn('Failed to find artifacts in artifact response');
  }

  artifact.clearData();

  $.each (data.artifacts, function(i,artData) {
    // if we have no descriptions for a type, we don't know about it
    if (!artifact.getArtifactDescriptions(artData.artifactId)) {
      // jarvis and amar artifacts - fragmentInfos and targetInfos
      // (future types? completely unknown at this time!)
      console.warn('Note: unknown artifactId '+artData.artifactId+' - guessing how to handle it');
    }

    artifact.artifactTypes[artData.artifactId] = artData.artifactId;

    if (artData.fragmentInfos) {
      artifact.processFragmentInfos (artData.artifactId, artData.fragmentInfos);
    }

    if (artData.targetInfos) {
      artifact.processTargetInfos (artData.artifactId, artData.targetInfos);
    }

    // other data in future? completely unknown!
  });

  // redraw the artifact layer
  artifact.updateLayer();

}

window.artifact.clearData = function() {

  artifact.portalInfo = {};
  artifact.artifactTypes = {};
}

window.artifact.processFragmentInfos = function (id, fragments) {
  $.each(fragments, function(i, fragment) {
    if (!artifact.portalInfo[fragment.portalGuid]) {
      artifact.portalInfo[fragment.portalGuid] = { _entityData: fragment.portalInfo };
    }

    if (!artifact.portalInfo[fragment.portalGuid][id]) artifact.portalInfo[fragment.portalGuid][id] = {};

    if (!artifact.portalInfo[fragment.portalGuid][id].fragments) artifact.portalInfo[fragment.portalGuid][id].fragments = [];

    $.each(fragment.fragments, function(i,f) {
      artifact.portalInfo[fragment.portalGuid][id].fragments.push(f);
    });

  });
}

window.artifact.processTargetInfos = function (id, targets) {
  $.each(targets, function(i, target) {
    if (!artifact.portalInfo[target.portalGuid]) {
      artifact.portalInfo[target.portalGuid] = { _entityData: target.portalInfo };
    }

    if (!artifact.portalInfo[target.portalGuid][id]) artifact.portalInfo[target.portalGuid][id] = {};

    artifact.portalInfo[target.portalGuid][id].target = target.team === 'RESISTANCE' ? TEAM_RES : TEAM_ENL;
  });
}

window.artifact.getArtifactTypes = function() {
  return Object.keys(artifact.artifactTypes);
}

window.artifact.isArtifact = function(type) {
  return type in artifact.artifactTypes;
}

window.artifact.getArtifactDescriptions = function(type) {
  var descriptions = {
    'jarvis': { 'title': "Jarvis Shards", 'fragmentName': "shards" },
    'amar': { 'title': "Amar Artifacts", 'fragmentName': "artifacts" },
    'helios': { 'title': "Helios Artifacts", 'fragmentName': "artifacts" },
  };

  return descriptions[type];
}

// used to render portals that would otherwise be below the visible level
window.artifact.getArtifactEntities = function() {
  var entities = [];

  // create fake entities from the artifact data
  $.each (artifact.portalInfo, function(guid,data) {
    var timestamp = 0; // we don't have a valid timestamp - so let's use 0
    var ent = [ guid, timestamp, data._entityData ];
    entities.push(ent);
  });

  return entities;
}

window.artifact.getInterestingPortals = function() {
  return Object.keys(artifact.portalInfo);
}

// quick test for portal being relevant to artifacts - of any type
window.artifact.isInterestingPortal = function(guid) {
  return guid in artifact.portalInfo;
}

// get the artifact data for a specified artifact id (e.g. 'jarvis'), if it exists - otherwise returns something 'false'y
window.artifact.getPortalData = function(guid,artifactId) {
  return artifact.portalInfo[guid] && artifact.portalInfo[guid][artifactId];
}

window.artifact.updateLayer = function() {
  artifact._layer.clearLayers();

  $.each(artifact.portalInfo, function(guid,data) {
    var latlng = L.latLng ([data._entityData.latE6/1E6, data._entityData.lngE6/1E6]);

    // jarvis shard icon
    var iconUrl = undefined;
    var iconSize = 0;
    var opacity = 1.0;

    // redundant as of 2014-02-05 - jarvis shards removed
    if (data.jarvis) {
      if (data.jarvis.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.jarvis.fragments ? data.jarvis.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.jarvis.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/jarvis_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }
    // 2014-02-06: a guess at whats needed for the new artifacts
    if (data.amar) {
      if (data.amar.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.amar.fragments ? data.amar.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/amar_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.amar.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/amar_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }

    // 2014-07-28 - another guess, for the upcoming 'helios' artifacts
    if (data.helios) {
      if (data.helios.target) {
        // target portal - show the target marker. use the count of fragments at the target to pick the right icon - it has segments that fill up

        var count = data.helios.fragments ? data.helios.fragments.length : 0;

        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/helios_shard_target_'+count+'.png';
        iconSize = 100/2; // 100 pixels - half that size works better
      } else if (data.helios.fragments) {
        iconUrl = '//commondatastorage.googleapis.com/ingress.com/img/map_icons/marker_images/helios_shard.png';
        iconSize = 60/2; // 60 pixels - half that size works better
        opacity = 0.6; // these often hide portals - let's make them semi transparent
      }

    }

    if (iconUrl) {
      var icon = L.icon({
        iconUrl: iconUrl,
        iconSize: [iconSize,iconSize],
        iconAnchor: [iconSize/2,iconSize/2],
        className: 'no-pointer-events'  // the clickable: false below still blocks events going through to the svg underneath
      });

      var marker = L.marker (latlng, {icon: icon, clickable: false, keyboard: false, opacity: opacity });

      artifact._layer.addLayer(marker);
    } else {
      console.warn('Oops! no URL for artifact portal icon?!');
    }
  });

}

window.artifact.showArtifactList = function() {
  var html = '';

  if (Object.keys(artifact.artifactTypes).length == 0) {
    html += 'No artifacts at this time';
  }

  $.each(artifact.artifactTypes, function(type,type2) {
    var description = artifact.getArtifactDescriptions(type);

    var name = description ? description.title : ('unknown artifact type: '+type);

    html += '

'+name+'
';

    html += '
';
    html += '
Portal	Details
';

    var tableRows = [];

    $.each(artifact.portalInfo, function(guid, data) {
      if (type in data) {
        // this portal has data for this artifact type - add it to the table

        var sortVal = 0;

        var onclick = 'zoomToAndShowPortal(\''+guid+'\',['+data._entityData.latE6/1E6+','+data._entityData.lngE6/1E6+'])';
        var row = '
'+escapeHtmlSpecialChars(data._entityData.title)+'	';

        row += '';

        if (data[type].target) {
          row += ''+(data[type].target==TEAM_RES?'Resistance':'Enlightened')+' target ';
          sortVal = 100000+data[type].target;
        }

        if (data[type].fragments) {
          if (data[type].target) {
            row += '
';
          }
          var fragmentName = description ? description.fragmentName : 'fragment';
          row += ''+fragmentName+': #'+data[type].fragments.join(', #')+' ';
          sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key
        }

        row += '
';

        tableRows.push ( [sortVal, row] );
      }
    });

    // check for no rows, and add a note to the table instead
    if (tableRows.length == 0) {
      html += '
No portals at this time
';
    }

    // sort the rows
    tableRows.sort(function(a,b) {
      return a[0]-b[0];
    });

    // and add them to the table
    html += tableRows.map(function(a){return a[1];}).join('');

    html += '
';
  });

  dialog({
    title: 'Artifacts',
    html: html,
    width: 400,
    position: {my: 'right center', at: 'center-60 center', of: window, collision: 'fit'}
  });

}
<|endoftext|>


<commit_before>var express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello from express');
});

app.listen(3000, () => {
  console.log('listen on port 3000');
});
<commit_msg>update server<commit_after>var express = require('express');
const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

app.get('/data', (req, res) => {
  console.log('caught a get on /data');
  res.send({
    'name': 'light',
    'data': {
        label: 'light',
        data: [
            100,
            90,
            80,
            70,
            60,
            50,
            40
        ]
    }
  });
});

app.get('/', (req, res) => {
  res.send('Hello from express');
});

app.listen(3000, () => {
  console.log('listen on port 3000');
});
<|endoftext|>


<commit_before>var MyRobot = function(){
  Robot.apply(this, arguments);

  this.on("")
}

util.inherits(MyRobot, Robot);

MyRobot.prototype.moveForward = function(){

}

//------------------

var r = new Robot();

r.addState("moveForward",
  [["forward", 2000]]);

r.stateListener("moveForward", "colorChange", function(oldColor, newColor, currentState) {
  if newcolor == black
    r.changeState("moveBackward");

})

//-------------------------

var r = new Robot(/* ... */);

r.run(function(){
  r.on("sensor", function(type, oldValue, newValue){
    if(type != "color") return;
    if(/* out of field */){
      r.commands.back(2000).then(function(){
        r.repeatedSequence([
          ["back", 100],
          function check(break){
            if(r.sensors.color.getValue() == "black"){
              r.commands.turn(180);
              break();

            }
          }
        ])
      });
    }
  })
  r.sequence([
    ["forward", 2000],
    /* ... */
  ])
});<commit_msg>more figuring out what an ideal API would be<commit_after>var seq = scheduler.sequence(function(){
  //init phase
}).after(2000, function(){
  //do after 2000 ms
}).once(function(){ return foo == bar}, function(){
  //do something once foo == bar
})

seq.on("interrupt", function(reason){
  //handle any cleanup for the sequence
})
seq.on("cancel", function(){
  //handle if the sequence was never run
})

seq.schedule();

//alternatively

scheduler.uninterruptableSequence(/*...*/);

// then

scheduler.interrupt("myReason", function(){
  //cancels all scheduled sequences
  //gets called once the uninterruptable sequences/cleanups clear out

  //we can schedule something to be run here
});

//alternatively
scheduler.uninterruptableInterrupt(/*...*/)

//////////////////////////////

//this forces that all state tracking should be done via the main robot class or with local variables

scheduler.sequence(function(s){
  s.do(function(){

  }).after(2000, function(){

  }).once(function(){ return foo == bar }, function(){

  }).after(2000, function(){
    //at the end of a sequence we should do something else
    //so our robot isn't idle
    scheduleSomeOtherSequence();
  })

  return s;
}).whenInterrupted(function(reason, s){
  //cleanup sequence (can't be interrupted)

  return s;

  //once the returned sequence finishes the sequence passed by the interupt will run
}).schedule();

scheduler.uninterruptableSequence(function(s){
  // ...
  return s;
}).schedule();

//then

scheduler.interrupt("myReason", function(s){
  // ...
  return s;
  // this sequence will get run once all scheduled cleanup and uninterruptable sequences finish
  //this is used for when we need to do stuff like respond to sensor data
}).whenInterrupted(/*...*/); //interupt sequences can be interrupted too

//alternatively
scheduler.uninterruptableInterrupt("myReason", function(s){ /*...*/ });

/////////////////////////////

var sequence = robot.sequence(function(){
  robot.motors.set("A,B", 100);
}).after(2000, function(){
  //turn
  robot.motors.set({
    "A": 50,
    "B": -50
  })
}).once(function(){ return robot.sensors.light.value == sensors.LightSensor.colors.BLACK }, function(){
  robot.motors.set("A,B", -100);
}).finally(function(err, result){
  //if err then we got an interrupt
})

//alternatively
.then(function(done){
  robot.motors.set("*", 100); //all motors at 100%
  robot.scheduler.scheduleTimeout(done, 2000);
})

sequence.run();

///////////////////////

var MyRobot = function(){
  Robot.apply(this, arguments);

  this.on("")
}

util.inherits(MyRobot, Robot);

MyRobot.prototype.moveForward = function(){

}

//------------------

var r = new Robot();

r.addState("moveForward",
  [["forward", 2000]]);

r.stateListener("moveForward", "colorChange", function(oldColor, newColor, currentState) {
  if newcolor == black
    r.changeState("moveBackward");

})

//-------------------------

var r = new Robot(/* ... */);

r.run(function(){
  r.on("sensor", function(type, oldValue, newValue){
    if(type != "color") return;
    if(/* out of field */){
      r.commands.back(2000).then(function(){
        r.repeatedSequence([
          ["back", 100],
          function check(break){
            if(r.sensors.color.getValue() == "black"){
              r.commands.turn(180);
              break();

            }
          }
        ])
      });
    }
  })
  r.sequence([
    ["forward", 2000],
    /* ... */
  ])
});<|endoftext|>


<commit_before>Modules.set('controllers.appViewController', function() {
    // imports
    var AppComponentController = Modules.get('controllers.AppComponentController');
    var u = Modules.get('utils');
    var port = Modules.get('port');
    var appViewsInfo = Modules.get('collections.appViewsInfo');
    var appModelsInfo = Modules.get('collections.appModelsInfo');
    var appCollectionsInfo = Modules.get('collections.appCollectionsInfo');

    var appViewController = new (AppComponentController.extend({ // singleton

        // the DOM element that is placed hover another element to highlight it,
        // is created just-in-time when needed.
        highlightMask: undefined,

        initialize: function() {
            this.setupHighlightMask();
        },

        handle: function(view) {
            // on new instance

            var me = this;

            var viewInfo = appViewsInfo.register(view, {
                "component_name": null, // string
                "component_modelIndex": null, // int
                "component_collectionIndex": null, // int
                "component_status": null // can be "Created", "Rendered" or "Removed"
            });

            // based on the constructor and on the el.tagName, el.id and el.className
            var updateViewName = function() {
                var viewSelector = "";
                if (u.isObject(view.el)) {
                    if (typeof view.el.tagName == 'string' && view.el.tagName !== "") {
                        viewSelector += view.el.tagName.toLowerCase();
                    }
                    if (typeof view.el.id == 'string' && view.el.id !== "") {
                        viewSelector += "#"+view.el.id;
                    }
                    if (typeof view.el.className == 'string' && view.el.className !== "") {
                        viewSelector += "."+view.el.className.replace(/ /g, '.');
                    }
                }
                var componentName = view.constructor.name || null;
                var componentNameDetails = viewSelector || null;
                if (componentName && componentNameDetails) {
                    componentName += " - " + componentNameDetails;
                } else {
                    componentName = componentName || componentNameDetails;
                }

                viewInfo.set("component_name", componentName);
            }

            // initial attributes
            viewInfo.set("component_status", "Created");
            updateViewName(); // is based also on the constructor!

            // monitor app component properties to update attributes

            u.monitorProperty(view, "model", 0, function() {
                var componentModelInfo = appModelsInfo.getByComponent(viewInfo.component.model);
                var componentModelIndex = componentModelInfo? componentModelInfo.index : null;
                viewInfo.set("component_modelIndex", componentModelIndex);
            });

            u.monitorProperty(view, "collection", 0, function() {
                var componentCollectionInfo = appCollectionsInfo.getByComponent(viewInfo.component.collection);
                var componentCollectionIndex = componentCollectionInfo? componentCollectionInfo.index : null;
                viewInfo.set("component_collectionIndex", componentCollectionIndex);
            });

            u.monitorProperty(view, "el.tagName", 0, updateViewName, {stealth: true});
            u.monitorProperty(view, "el.id", 0, updateViewName, {stealth: true});
            u.monitorProperty(view, "el.className", 0, updateViewName, {stealth: true});

            // Patch the app component methods

            this.patchTrigger(viewInfo);
            this.patchEvents(viewInfo);

            u.patchFunctionLater(view, "delegateEvents", function(originalFunction) { return function() {
                var events = arguments[0]; // hash <selector, callback>
                if (events === undefined) {
                    // delegateEvents internally uses this.events when called without arguments,
                    // not enabling the changing of the input,
                    // hence in this case this behaviour is anticipated by using this.events as input.
                    // (this.events can also be a function that returns the hash)
                    events = (typeof this.events == "function") ? this.events() : this.events;
                }

                // the callback in events must be patched on-the-fly
                // so to be able to track when they are called
                events = u.clone(events); // avoid to change the original object
                for (var eventType in events) {
                    if (events.hasOwnProperty(eventType)) {
                        // callback can be a function or the name of a function in the view
                        var callback = events[eventType];
                        if (typeof callback != "function") {
                            callback = this[callback];
                        }
                        if (!callback) {
                            // leave the unvalid callback untouched so that the original method
                            // can warn for the error
                            continue;
                        }

                        // callback is valid, patch it on-the-fly
                        // (every function has its own closure with the event data)
                        events[eventType] = (function(eventType, callback) {
                            return function(event) {
                                // event is the jQuery event

                                viewInfo.actions.register({
                                    "type": "Page event handling",
                                    "name": eventType,
                                    "dataKind": "jQuery Event"
                                }, event);

                                var result = callback.apply(this, arguments);
                                return result;
                            }
                        })(eventType, callback);
                    }
                }

                // edit the arguments
                // (it's not enough to set arguments[0] since doesn't work in strict mode)
                var argumentsArray = Array.prototype.slice.call(arguments);
                argumentsArray[0] = events;
                var result = originalFunction.apply(this, argumentsArray);

                return result;
            }});

            u.patchFunctionLater(view, "render", function(originalFunction) { return function() {
                var result = originalFunction.apply(this, arguments);

                viewInfo.set("component_status", "Rendered");

                viewInfo.actions.register({
                    "type": "Operation",
                    "name": "render"
                });

                return result;
            }});

            u.patchFunctionLater(view, "remove", function(originalFunction) { return function() {
                var result = originalFunction.apply(this, arguments);

                viewInfo.set("component_status", "Removed");

                viewInfo.actions.register({
                    "type": "Operation",
                    "name": "remove"
                });

                return result;
            }});
        },

        setupHighlightMask: function() {
            // unhighlight when the user closes the devtools, etc.
            this.listenTo(port, 'client:disconnect', this.unhighlightViewElements);
        },

        // highlight the dom element associated with the view
        highlightViewElement: function(view) {
            this.unhighlightViewElements();

            var element = view.$el ? view.$el[0] : view.el;
            if (!element) return;

            var highlightMask = document.createElement('div');
            highlightMask.style.position = 'absolute';
            highlightMask.style.zIndex = '100000000000';
            highlightMask.style.pointerEvents = 'none';
            highlightMask.style.backgroundColor = 'rgba(55, 161, 243, 0.48)';
            highlightMask.style.webkitFilter = 'grayscale(20%)';

            // set position and size (top, right, bottom, left, width, height)
            var bounds = element.getBoundingClientRect();
            u.each(bounds, function(boundValue, boundName) {
                highlightMask.style[boundName] = boundValue+'px';
            }, this);

            document.body.appendChild(highlightMask);

            this.highlightMask = highlightMask;
        },

        unhighlightViewElements: function() {
            if (this.highlightMask) {
                this.highlightMask.parentNode.removeChild(this.highlightMask);
                this.highlightMask = undefined;
            }
        }

    }))();

    return appViewController;
});<commit_msg>Cache highlightMask #29<commit_after>Modules.set('controllers.appViewController', function() {
    // imports
    var AppComponentController = Modules.get('controllers.AppComponentController');
    var u = Modules.get('utils');
    var port = Modules.get('port');
    var appViewsInfo = Modules.get('collections.appViewsInfo');
    var appModelsInfo = Modules.get('collections.appModelsInfo');
    var appCollectionsInfo = Modules.get('collections.appCollectionsInfo');

    var appViewController = new (AppComponentController.extend({ // singleton

        // the DOM element that is placed hover another element to highlight it
        highlightMask: undefined,

        initialize: function() {
            this.setupHighlight();
        },

        handle: function(view) {
            // on new instance

            var me = this;

            var viewInfo = appViewsInfo.register(view, {
                "component_name": null, // string
                "component_modelIndex": null, // int
                "component_collectionIndex": null, // int
                "component_status": null // can be "Created", "Rendered" or "Removed"
            });

            // based on the constructor and on the el.tagName, el.id and el.className
            var updateViewName = function() {
                var viewSelector = "";
                if (u.isObject(view.el)) {
                    if (typeof view.el.tagName == 'string' && view.el.tagName !== "") {
                        viewSelector += view.el.tagName.toLowerCase();
                    }
                    if (typeof view.el.id == 'string' && view.el.id !== "") {
                        viewSelector += "#"+view.el.id;
                    }
                    if (typeof view.el.className == 'string' && view.el.className !== "") {
                        viewSelector += "."+view.el.className.replace(/ /g, '.');
                    }
                }
                var componentName = view.constructor.name || null;
                var componentNameDetails = viewSelector || null;
                if (componentName && componentNameDetails) {
                    componentName += " - " + componentNameDetails;
                } else {
                    componentName = componentName || componentNameDetails;
                }

                viewInfo.set("component_name", componentName);
            }

            // initial attributes
            viewInfo.set("component_status", "Created");
            updateViewName(); // is based also on the constructor!

            // monitor app component properties to update attributes

            u.monitorProperty(view, "model", 0, function() {
                var componentModelInfo = appModelsInfo.getByComponent(viewInfo.component.model);
                var componentModelIndex = componentModelInfo? componentModelInfo.index : null;
                viewInfo.set("component_modelIndex", componentModelIndex);
            });

            u.monitorProperty(view, "collection", 0, function() {
                var componentCollectionInfo = appCollectionsInfo.getByComponent(viewInfo.component.collection);
                var componentCollectionIndex = componentCollectionInfo? componentCollectionInfo.index : null;
                viewInfo.set("component_collectionIndex", componentCollectionIndex);
            });

            u.monitorProperty(view, "el.tagName", 0, updateViewName, {stealth: true});
            u.monitorProperty(view, "el.id", 0, updateViewName, {stealth: true});
            u.monitorProperty(view, "el.className", 0, updateViewName, {stealth: true});

            // Patch the app component methods

            this.patchTrigger(viewInfo);
            this.patchEvents(viewInfo);

            u.patchFunctionLater(view, "delegateEvents", function(originalFunction) { return function() {
                var events = arguments[0]; // hash <selector, callback>
                if (events === undefined) {
                    // delegateEvents internally uses this.events when called without arguments,
                    // not enabling the changing of the input,
                    // hence in this case this behaviour is anticipated by using this.events as input.
                    // (this.events can also be a function that returns the hash)
                    events = (typeof this.events == "function") ? this.events() : this.events;
                }

                // the callback in events must be patched on-the-fly
                // so to be able to track when they are called
                events = u.clone(events); // avoid to change the original object
                for (var eventType in events) {
                    if (events.hasOwnProperty(eventType)) {
                        // callback can be a function or the name of a function in the view
                        var callback = events[eventType];
                        if (typeof callback != "function") {
                            callback = this[callback];
                        }
                        if (!callback) {
                            // leave the unvalid callback untouched so that the original method
                            // can warn for the error
                            continue;
                        }

                        // callback is valid, patch it on-the-fly
                        // (every function has its own closure with the event data)
                        events[eventType] = (function(eventType, callback) {
                            return function(event) {
                                // event is the jQuery event

                                viewInfo.actions.register({
                                    "type": "Page event handling",
                                    "name": eventType,
                                    "dataKind": "jQuery Event"
                                }, event);

                                var result = callback.apply(this, arguments);
                                return result;
                            }
                        })(eventType, callback);
                    }
                }

                // edit the arguments
                // (it's not enough to set arguments[0] since doesn't work in strict mode)
                var argumentsArray = Array.prototype.slice.call(arguments);
                argumentsArray[0] = events;
                var result = originalFunction.apply(this, argumentsArray);

                return result;
            }});

            u.patchFunctionLater(view, "render", function(originalFunction) { return function() {
                var result = originalFunction.apply(this, arguments);

                viewInfo.set("component_status", "Rendered");

                viewInfo.actions.register({
                    "type": "Operation",
                    "name": "render"
                });

                return result;
            }});

            u.patchFunctionLater(view, "remove", function(originalFunction) { return function() {
                var result = originalFunction.apply(this, arguments);

                viewInfo.set("component_status", "Removed");

                viewInfo.actions.register({
                    "type": "Operation",
                    "name": "remove"
                });

                return result;
            }});
        },

        setupHighlight: function() {
            this.highlightMask = document.createElement('div');
            this.highlightMask.style.position = 'absolute';
            this.highlightMask.style.zIndex = '100000000000';
            this.highlightMask.style.pointerEvents = 'none';
            this.highlightMask.style.backgroundColor = 'rgba(55, 161, 243, 0.48)';
            this.highlightMask.style.webkitFilter = 'grayscale(20%)';

            // unhighlight when the user closes the devtools, etc.
            this.listenTo(port, 'client:disconnect', this.unhighlightViewElements);
        },

        // highlight the dom element associated with the view
        highlightViewElement: function(view) {
            this.unhighlightViewElements();

            var element = view.$el ? view.$el[0] : view.el;
            if (!element) return;

            // set position and size (top, right, bottom, left, width, height)
            var bounds = element.getBoundingClientRect();
            u.each(bounds, function(boundValue, boundName) {
                this.highlightMask.style[boundName] = boundValue+'px';
            }, this);

            if (!this.highlightMask.parentNode) {
                // is not in the dom yet
                document.body.appendChild(this.highlightMask);
            }

            // make visible
            this.highlightMask.style.display = '';
        },

        unhighlightViewElements: function() {
            // hide if visible
            if (this.highlightMask.style.display != 'none') {
                this.highlightMask.style.display = 'none';
            }
        }

    }))();

    return appViewController;
});<|endoftext|>


<commit_before>'use strict';

import Botkit from 'botkit';
import requestify from 'requestify';
import _ from 'lodash';
import config from '../../config';
import botkit_mongo_storage from './botkit_storage_mongoose';
import logger from './logger';
import * as messages from './messages';
import * as actions from './actions';

export const controller = Botkit.slackbot({
    storage: botkit_mongo_storage(config)
});

function save_user(scope, { access_token, user_id, team_id, user }) {
    let approved_scopes = scope.split(/\,/);

    controller.storage.users.get(user_id, (err, user) => {
        if (!user) {
            user = {
                id: user_id,
                access_token: access_token,
                scopes: approved_scopes,
                team_id: team_id,
                user: user
            };
        }

        controller.storage.users.save(user, (err, id) => {
            if (err) {
                logger.error('An error occurred while saving a user: ', err);
                controller.trigger('error', [err]);
            }
        });
    });
}

export function connect(config) {
    let bot = controller.spawn(config);
    controller.trigger('create_bot', [ bot, config ]);
}

export function save_team({ access_token, bot, scope }) {
    let url = `https://slack.com/api/auth.test?token=${access_token}`;

    return new Promise((resolve, reject) => {
        resolve(requestify.get(url).then((res) => {
            let { team_id, user_id, url, team, user } = res.getBody();

            let slack_team = {
                id: team_id,
                bot:{
                token: bot.bot_access_token,
                user_id: bot.bot_user_id,
                createdBy: user_id
                },
                createdBy: user_id,
                url: url,
                name: team
            };

            connect(slack_team);
            save_user(scope, { access_token, user_id, team_id, user });

            return slack_team;
        }));
    });
}

export function register_slack_team(incoming_webhook_url, team_id, callback) {
    controller.storage.teams.get(team_id, (err, team) => {
        team.webhooks = {
            incomingUrl: incoming_webhook_url
        };

        controller.storage.teams.save(team, (err, team) => {
            if (!err) {
                callback(messages.register_command_reply(incoming_webhook_url));
            }
        });
    });
}

export function share_channel(team_id, channel_id, channel_name, callback) {
    controller.storage.teams.get(team_id, (err, team) => {
        if (!err) {
            let shared_channel = {
                id: `${team_id}.${channel_id}`,
                team_id: team.id,
                team_name: team.name,
                channel_id: channel_id,
                channel_name: channel_name,
                joined_channels: []
            };

            controller.storage.shares.save(shared_channel, (err, shared_channel) => {
                callback(messages.share_command_reply(shared_channel.channel_name));
            });
        }
    });
}

export function get_available_channels(channel_id, filter, callback) {
    controller.storage.shares.all((err, shares) => {
        let channels = _.filter(shares, (share) => share.channel_id !== channel_id);
        if (filter !== '') {
            channels = _.filter(channels, (channel) => channel.team_name === filter);
        }

        let grouped_channels = _.groupBy(channels, 'team_name');
        let reply_message = {
            attachments: []
        }

        _.forEach(grouped_channels, (value, key) => {
            let attachment = messages.available_channels_reply(key);

            _.forEach(value, (channel) => {
                attachment.push(actions.available_channel_action(channel.channel_name, channel.channel_id, channel.team_id));
            });

            reply_message.attachments.push(attachment);
        });

        callback(reply_message);
    });
}

const _bots = {};

function trackBot(bot) {
    _bots[bot.config.token] = bot;
}

controller.on('create_bot', (bot, team) => {
    if (_bots[bot.config.token]) {
        bot.api.channels.list({ token: bot.confi.token }, (err, result) => {
            if (!err) {
                team.channels = []; // reset channel listing.
                if (result.ok) {
                    for (var i = 0; i < result.channels.length; i++) {
                        team.channels.push({
                            id: result.channels[i].id,
                            name: result.channels[i].name
                        });
                    }
                }
            }
        });

        logger.info("already online! channel listing updated.");
    } else {
        bot.startRTM((err) => {
            if (!err) {
                trackBot(bot);

                bot.api.channels.list({ token: bot.config.token }, (err, result) => {
                    if(!err) {
                        team.channels = [];
                        if (result.ok) {
                            for (var i = 0; i < result.channels.length; i++) {
                                team.channels.push({
                                    id: result.channels[i].id,
                                    name: result.channels[i].name
                                });
                            }
                        }

                        controller.saveTeam(team, function(err, id) {
                            if (err) {
                                logger.info("Error saving team");
                            }
                            else {
                                logger.info("Team " + team.name + " saved");
                            }
                        });
                    }
                });
            }

            bot.say(messages.general_help_message(team.createdBy));
        });
    }
});<commit_msg>fixing linting error<commit_after>'use strict';

import Botkit from 'botkit';
import requestify from 'requestify';
import _ from 'lodash';
import config from '../../config';
import botkit_mongo_storage from './botkit_storage_mongoose';
import logger from './logger';
import * as messages from './messages';
import * as actions from './actions';

export const controller = Botkit.slackbot({
    storage: botkit_mongo_storage(config)
});

function save_user(scope, { access_token, user_id, team_id, user }) {
    let approved_scopes = scope.split(/\,/);

    controller.storage.users.get(user_id, (err, user) => {
        if (!user) {
            user = {
                id: user_id,
                access_token: access_token,
                scopes: approved_scopes,
                team_id: team_id,
                user: user
            };
        }

        controller.storage.users.save(user, (err, id) => {
            if (err) {
                logger.error('An error occurred while saving a user: ', err);
                controller.trigger('error', [err]);
            }
        });
    });
}

export function connect(config) {
    let bot = controller.spawn(config);
    controller.trigger('create_bot', [ bot, config ]);
}

export function save_team({ access_token, bot, scope }) {
    let url = `https://slack.com/api/auth.test?token=${access_token}`;

    return new Promise((resolve, reject) => {
        resolve(requestify.get(url).then((res) => {
            let { team_id, user_id, url, team, user } = res.getBody();

            let slack_team = {
                id: team_id,
                bot:{
                token: bot.bot_access_token,
                user_id: bot.bot_user_id,
                createdBy: user_id
                },
                createdBy: user_id,
                url: url,
                name: team
            };

            connect(slack_team);
            save_user(scope, { access_token, user_id, team_id, user });

            return slack_team;
        }));
    });
}

export function register_slack_team(incoming_webhook_url, team_id, callback) {
    controller.storage.teams.get(team_id, (err, team) => {
        team.webhooks = {
            incomingUrl: incoming_webhook_url
        };

        controller.storage.teams.save(team, (err, team) => {
            if (!err) {
                callback(messages.register_command_reply(incoming_webhook_url));
            }
        });
    });
}

export function share_channel(team_id, channel_id, channel_name, callback) {
    controller.storage.teams.get(team_id, (err, team) => {
        if (!err) {
            let shared_channel = {
                id: `${team_id}.${channel_id}`,
                team_id: team.id,
                team_name: team.name,
                channel_id: channel_id,
                channel_name: channel_name,
                joined_channels: []
            };

            controller.storage.shares.save(shared_channel, (err, shared_channel) => {
                callback(messages.share_command_reply(shared_channel.channel_name));
            });
        }
    });
}

export function get_available_channels(channel_id, filter, callback) {
    controller.storage.shares.all((err, shares) => {
        let channels = _.filter(shares, (share) => share.channel_id !== channel_id);
        if (filter !== '') {
            channels = _.filter(channels, (channel) => channel.team_name === filter);
        }

        let grouped_channels = _.groupBy(channels, 'team_name');
        let reply_message = {
            attachments: []
        };

        _.forEach(grouped_channels, (value, key) => {
            let attachment = messages.available_channels_reply(key);

            _.forEach(value, (channel) => {
                attachment.push(actions.available_channel_action(channel.channel_name, channel.channel_id, channel.team_id));
            });

            reply_message.attachments.push(attachment);
        });

        callback(reply_message);
    });
}

const _bots = {};

function trackBot(bot) {
    _bots[bot.config.token] = bot;
}

controller.on('create_bot', (bot, team) => {
    if (_bots[bot.config.token]) {
        bot.api.channels.list({ token: bot.confi.token }, (err, result) => {
            if (!err) {
                team.channels = []; // reset channel listing.
                if (result.ok) {
                    for (var i = 0; i < result.channels.length; i++) {
                        team.channels.push({
                            id: result.channels[i].id,
                            name: result.channels[i].name
                        });
                    }
                }
            }
        });

        logger.info("already online! channel listing updated.");
    } else {
        bot.startRTM((err) => {
            if (!err) {
                trackBot(bot);

                bot.api.channels.list({ token: bot.config.token }, (err, result) => {
                    if(!err) {
                        team.channels = [];
                        if (result.ok) {
                            for (var i = 0; i < result.channels.length; i++) {
                                team.channels.push({
                                    id: result.channels[i].id,
                                    name: result.channels[i].name
                                });
                            }
                        }

                        controller.saveTeam(team, function(err, id) {
                            if (err) {
                                logger.info("Error saving team");
                            }
                            else {
                                logger.info("Team " + team.name + " saved");
                            }
                        });
                    }
                });
            }

            bot.say(messages.general_help_message(team.createdBy));
        });
    }
});<|endoftext|>


<commit_before>/*
* @Author: Mike Reich
* @Date:   2015-11-22 13:06:39
* @Last Modified 2015-12-15
*/

'use strict';

import Dispatcher from './Dispatcher'

export default class Module extends Dispatcher {

  constructor(app, name) {
    super()
    this._app = app;
    this._name = name;
    app.on('stop', this.removeAllListeners.bind(this));
  }

  /**
   * Provide arguments to a delayed gather() call.
   *
   * @param  {string} name The name of the gather event
   * @param  {...*}   args Arguments to provide to the gather event
   * @return {Promise} Resolves when the event is eventually handled
   */
  provide(name, ...args) {
    return this._app.onceBefore('load').then(() => {
      return this.emit(name, ...args);
    });
  }

  /**
   * Receive arguments provided to a delayed gather() call.
   *
   * @param  {string}   name The name of the gather event
   * @param  {callable} handler The handler for each provided value
   */
  gather(name, handler) {
    return this.on(name, handler);
  }

  /**
   * Request the result of processing a named event
   *
   * @param  {string}   name The name of the request event
   * @param  {...*}   args Arguments to provide to the responder
   * @return {Promise} Resolves to the result of the event's handler
   */
  request(name, ...args) {
    return this.emit(name, ...args);
  }

  /**
   * Respond to a named event
   *
   * @param  {string}   name The name of the request event
   * @param  {callable} handler The handler for the request
   */
  respond(name, handler) {
    this.after(name, (results) => {
      if (results.length == 1) {
        return results[0]
      }
      return results;
    });
    return this.on(name, handler);
  }
}
<commit_msg>Changed provide to send the emit if called after init<commit_after>/*
* @Author: Mike Reich
* @Date:   2015-11-22 13:06:39
* @Last Modified 2015-12-15
*/

'use strict';

import Dispatcher from './Dispatcher'

export default class Module extends Dispatcher {

  constructor(app, name) {
    super()
    this._app = app;
    this._name = name;
    this.loaded = false
    app.on('stop', this.removeAllListeners.bind(this));
    this._app.onceBefore('load').then(() => {
      this.loaded = true
    })
  }

  /**
   * Provide arguments to a delayed gather() call.
   *
   * @param  {string} name The name of the gather event
   * @param  {...*}   args Arguments to provide to the gather event
   * @return {Promise} Resolves when the event is eventually handled
   */
  provide(name, ...args) {
    if(!this.loaded)
      return this._app.onceBefore('load').then(() => {
        return this.emit(name, ...args);
      });
    else
      return this.emit(name, ...args);
  }

  /**
   * Receive arguments provided to a delayed gather() call.
   *
   * @param  {string}   name The name of the gather event
   * @param  {callable} handler The handler for each provided value
   */
  gather(name, handler) {
    return this.on(name, handler);
  }

  /**
   * Request the result of processing a named event
   *
   * @param  {string}   name The name of the request event
   * @param  {...*}   args Arguments to provide to the responder
   * @return {Promise} Resolves to the result of the event's handler
   */
  request(name, ...args) {
    return this.emit(name, ...args);
  }

  /**
   * Respond to a named event
   *
   * @param  {string}   name The name of the request event
   * @param  {callable} handler The handler for the request
   */
  respond(name, handler) {
    this.after(name, (results) => {
      if (results.length == 1) {
        return results[0]
      }
      return results;
    });
    return this.on(name, handler);
  }
}
<|endoftext|>


<commit_before>
function Player(data) {
	this.id = data['id'];
	this.name = data['name'];
	this.team = {
		icon: data['icon'],
		color: data['color']
	}
	this.coordinate = {
		latitude: parseFloat(data['latitude']),
		longitude: parseFloat(data['longitude'])
	}
	this.troops = JSON.parse(data['troops']);
}

Player.prototype.get = function(attribute) {
	return this[attribute];
}

Player.prototype.set = function(attribute, value) {
	this[attribute] = value;
}

Player.prototype.updateLocation = function() {
	// update location called in task object
}

console.log("Player loaded");<commit_msg>Player Class<commit_after>
function Player(data) {
	this.id = data['id'];
	this.name = data['name'];
	this.team = {
		icon: data['icon'],
		color: data['color']
	}
	this.coordinate = {
		latitude: parseFloat(data['latitude']),
		longitude: parseFloat(data['longitude'])
	}
	this.troops = JSON.parse(data['troops']);
}

Player.prototype.get = function(attribute) {
	return this[attribute];
}

Player.prototype.set = function(attribute, value) {
	this[attribute] = value;
}

Player.prototype.updateLocation = function(newLoc) {
	// update location called in task object
	this.coordinate = {
		latitude:parseFloat(newLoc['latitude']),
		longitude:parseFloat(newLoc['longitude'])
	};
}

Player.prototype.toString = function() {
	return "Player " + this.id + ": " + this.name + " Team:" + this.team.color;
}

var testPlayer = new Player({
    "id": "marcuswan",
    "name": "Marcus Wan",
    "team": {"icon": "png", "color": "Blue"},
    "coordinates": {"latitude": "10", "longitude": "20"},
    "troops": "[]"
});

console.log("Player loaded");
<|endoftext|>


<commit_before>import _ from 'lodash';
import moment from 'moment';
import chrome from 'ui/chrome';
import uiModules from 'ui/modules';
import uiRoutes from 'ui/routes';
import $ from 'jquery';

/* Elasticsearch */

import elasticsearch from 'elasticsearch-browser';

/* Ace editor */
import 'ace';

/* Timepicker */
import 'ui/timepicker';
import 'ui/courier';
import 'ui/filter_bar';

// import TableVisTypeProvider from 'ui/template_vis_type/TemplateVisType';
// import VisSchemasProvider from 'ui/vis/schemas';
// import tableVisTemplate from 'plugins/table_vis/table_vis.html';
// require('ui/registry/vis_types').register(TableVisTypeProvider);

import AggResponseTabifyTabifyProvider from 'ui/agg_response/tabify/tabify';
// import tableSpyModeTemplate from 'plugins/spy_modes/table_spy_mode.html';

import Notifier from 'ui/notify/notifier';
// import 'ui/autoload/styles';

/* Custom Template + CSS */
import './less/main.less';
import template from './templates/index.html';
import about from './templates/about.html';
import alarms from './templates/alarms.html';
import jsonHtml from './templates/json.html';

var impactLogo = require('plugins/kaae/kaae_watch.svg');
var smallLogo = require('plugins/kaae/kaae.svg');

/* Inject Tabs */
  var topNavMenu = [
  {
    key: 'watchers',
    description: 'WATCH',
    run: function () { kbnUrl.change('/'); }
  },
  {
    key: 'about',
    description: 'ABOUT',
    run: function () { kbnUrl.change('/about'); }
  }
  ];

chrome
  .setBrand({
    'logo': 'url(' + impactLogo + ') left no-repeat'
    ,'smallLogo': 'url(' + impactLogo + ') left no-repeat'
    ,'title': 'KAAE'
  })
  .setNavBackground('#222222')
  .setTabs([
  {
    id: '',
    title: 'Watchers',
    activeIndicatorColor: '#EFF0F2'
  },
  {
    id: 'alarms',
    title: 'Alarms',
    activeIndicatorColor: '#EFF0F2'
  },
  {
    id: 'about',
    title: 'About',
    activeIndicatorColor: '#EFF0F2'
  }
  ]);

uiRoutes.enable();

uiRoutes
.when('/', {
  template,
  resolve: {
    currentTime($http) {
      return $http.get('../api/kaae/example').then(function (resp) {
        return resp.data.time;
      });
    },
    currentWatchers($http) {
      return $http.get('../api/kaae/list').then(function (resp) {
	// console.log('DEBUG LIST:',resp);
        return resp;
      });
    }
  }
});

uiRoutes
.when('/alarms', {
  template: alarms,
  resolve: {
    currentTime($http) {
      return $http.get('../api/kaae/example').then(function (resp) {
        return resp.data.time;
      });
    },
    currentWatchers($http) {
      return $http.get('../api/kaae/list').then(function (resp) {
	// console.log('DEBUG LIST:',resp);
        return resp;
      });
    },
    currentAlarms($http) {
      return $http.get('../api/kaae/alarms').then(function (resp) {
	// console.log('DEBUG ALARMS:',resp);
        return resp;
      });
    },
    elasticAlarms($http) {
      return $http.get('../api/kaae/list/alarms').then(function (resp) {
	// console.log('DEBUG ALARMS:',resp);
        return resp;
      });
    }
  }
});

uiRoutes
.when('/about', {
  template: about
});

uiModules
.get('api/kaae', [])
.filter('moment', function() {
    return function(dateString) {
        return moment(dateString).format('YYYY-MM-DD HH:mm:ss.sss');;
    };
})
.controller('kaaeHelloWorld', function ($rootScope, $scope, $route, $interval, $timeout, timefilter, Private, Notifier, $window, kbnUrl, $http) {
  $scope.title = 'KaaE: Alarms';
  $scope.description = 'Kibana Alert App for Elasticsearch';
  // $scope.store = window.sessionStorage;

  $scope.notify = new Notifier();

  timefilter.enabled = true;

  /* Alarm Functions */

  var checkAlarm = function() {
	  if ($route.current.locals.currentAlarms.data) {
		   $scope.currentAlarms = $route.current.locals.currentAlarms.data.data;
	  } else { $scope.currentAlarms = [] }
  }

  var getAlarmsFromEs = function() {
	  if ($route.current.locals.elasticAlarms.data.hits) {
		   $scope.elasticAlarms = $route.current.locals.elasticAlarms.data.hits.hits;
	  } else { $scope.elasticAlarms = [] }
  }

  /* Update Time Filter */
  var updateFilter = function(){
	  return $http.get('../api/kaae/set/interval/'+JSON.stringify($scope.timeInterval)).then(function (resp) {
	        // console.log('NEW TIMEFILTER:',$scope.timeInterval);
          });
  }

  /* First Boot */

  $scope.timeInterval = timefilter.time;
  updateFilter();

  // checkAlarm();
  getAlarmsFromEs();

  /* Listen for refreshInterval changes */

   $rootScope.$watchCollection('timefilter.time', function (newvar, oldvar) {
      if (newvar == oldvar) { return; }
      let timeInterval = _.get($rootScope, 'timefilter.time');
      // console.log('Time Range Change!',timefilter.time);
      if (timeInterval) {
	 	$scope.timeInterval = timeInterval;
	  	updateFilter();
		$route.reload();
      }

    });

   $rootScope.$watchCollection('timefilter.refreshInterval', function () {
      let refreshValue = _.get($rootScope, 'timefilter.refreshInterval.value');
      let refreshPause = _.get($rootScope, 'timefilter.refreshInterval.pause');

      // Kill any existing timer immediately
      if ($scope.refreshalarms) {
	  	$timeout.cancel($scope.refreshalarms);
		$scope.refreshalarms = undefined;
      }

      // Check if Paused
      if (refreshPause) {
		// console.log('REFRESH PAUSED');
	  	if ($scope.refreshalarms) $timeout.cancel($scope.refreshalarms);
		return;
      }

      // Process New Filter
      if (refreshValue != $scope.currentRefresh && refreshValue != 0) {
	      // new refresh value
      	      if (_.isNumber(refreshValue) && !refreshPause) {
		    // console.log('TIMEFILTER REFRESH');
		    $scope.newRefresh = refreshValue;
			  // Reset Interval & Schedule Next
			  $scope.refreshalarms = $timeout(function () {
			     // console.log('Reloading data....');
			     $route.reload();
		          }, refreshValue);
  			  $scope.$watch('$destroy', $scope.refreshalarms);
	      } else {
		  // console.log('PAUSE REFRESH');
	  	  $scope.currentRefresh = 0;
		  $timeout.cancel($scope.refreshalarms);
	      }

      } else {
		// console.log('NULL CHANGE!');
  	        $timeout.cancel($scope.refreshalarms);
      }

    });

  $scope.deleteAlarm = function($index){
	 $scope.notify.warning('KAAE function not yet implemented!');
	 // $scope.currentAlarms.splice($index,1);
  }

  var currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  var utcTime = moment.utc($route.current.locals.currentTime);
  $scope.utcTime = utcTime.format('HH:mm:ss');
  var unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
    $scope.utcTime = utcTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);

});

// WATCHERS CONTROLLER
uiModules
.get('api/kaae', [])
.controller('kaaeWatchers', function ($rootScope, $scope, $route, $interval, $timeout, timefilter, Private, Notifier, $window, kbnUrl, $http) {
  $scope.title = 'KaaE: Watchers';
  $scope.description = 'Kibana Alert App for Elasticsearch';
  // $scope.store = window.sessionStorage;

  $scope.notify = new Notifier();

  $scope.topNavMenu = [
  {
    key: 'watchers',
    description: 'WATCH',
    run: function () { kbnUrl.change('/'); }
  },
  {
    key: 'about',
    description: 'ABOUT',
    run: function () { kbnUrl.change('/about'); }
  }
  ];

  timefilter.enabled = false;
  /*
	time: {
	        gt: timefilter.getBounds().min.valueOf(),
	        lte: timefilter.getBounds().max.valueOf()
	      }
  */

  // kbnUrl.change('/', {});

  const tabifyAggResponse = Private(AggResponseTabifyTabifyProvider);
  if ($route.current.locals.currentWatchers.data.hits.hits) {
	   $scope.watchers = $route.current.locals.currentWatchers.data.hits.hits;

	/*
	   $scope.spy.params.spyPerPage = 10;
	   $scope.table = tabifyAggResponse($scope.vis, $route.current.locals.currentWatchers.data.hits.hits, {
             canSplit: false,
             asAggConfigResults: true,
             partialRows: true
           });
	*/

  } else { $scope.watchers = []; }

  /* ACE Editor */
  $scope.editor;
  $scope.editor_status = { readonly: false, undo: false, new: false };
  $scope.setAce = function($index,edit) {
	  // var content = $scope.currentAlarms[$index];
	  $scope.editor = ace.edit("editor-"+$index);
	  var _session = $scope.editor.getSession();
    	  // var _renderer = $scope.editor.renderer;
	  $scope.editor.setReadOnly(edit);
	  $scope.editor_status.readonly = edit;
    	  _session.setUndoManager(new ace.UndoManager());

	  $scope.editor_status.undo = $scope.editor.session.getUndoManager().isClean();

	  if (!edit) { $scope.editor.getSession().setMode("ace/mode/json"); }
	  else { $scope.editor.getSession().setMode("ace/mode/text"); }
  }

  $scope.watcherDelete = function($index){

     if (confirm('Are you sure?')) {
	 return $http.get('../api/kaae/delete/watcher/'+$scope.watchers[$index]._id).then(function (resp) {
        	// console.log('API DELETE:',resp.data);
			 var reload = $timeout(function () {
		              $route.reload();
		 	      $scope.notify.warning('KAAE Watcher successfully deleted!');
		 	 }, 1000);
         });
      }
  }

  $scope.watcherGet = function($index){
	 // console.log('saving watcher ', $scope.watchers[$index] );
	 return $http.get('../api/kaae/get/watcher/'+$scope.watchers[$index]._id).then(function (resp) {
        	// console.log('API GET:',resp.data);
         });
  }

  $scope.watcherSave = function($index){
	 // console.log('saving watcher ', $scope.watchers[$index] );
    	 var watcher = $scope.editor ? JSON.parse($scope.editor.getValue()) : $scope.watchers[$index];
	 return $http.get('../api/kaae/save/watcher/'+JSON.stringify(watcher)).then(function (resp) {
        	// console.log('API STORE:',resp);
			 var reload = $timeout(function () {
		              $route.reload();
		 	      $scope.notify.warning('KAAE Watcher successfully saved!');
		 	 }, 1000);
         });
  }

  $scope.getWatchers = function(){
	return $scope.watchers;
  }

  /* New Entry */
  $scope.watcherNew = function(newwatcher) {
	if (!newwatcher) {
	  var newwatcher = {
		  "_index": "watcher",
		  "_type": "watch",
		  "_id": "new",
		  "_new": "true",
		  "_source": {
		    "trigger": {
		      "schedule": {
		        "interval": "60"
		      }
		    },
		    "input": {
		      "search": {
		        "request": {
		          "indices": [],
		          "body": {},
		        }
		      }
		    },
		    "condition": {
		      "script": {
		        "script": "payload.hits.total > 100"
		      }
		    },
		    "transform": {},
		    "actions": {
		      "email_admin": {
		        "throttle_period": "15m",
		        "email": {
		          "to": "alarm@localhost",
		          "subject": "KaaE Alarm",
		          "priority": "high",
		          "body": "Found {{payload.hits.total}} Events"
		        }
		      }
		    }
		  }
		};
        }

	$scope.watchers.unshift(newwatcher);

	/*
	 refreshalarms = $timeout(function () {
	      // console.log('set new watcher to edit mode...');
	      $scope.setAce(0,false);
 	 }, 200);
	*/

  }

  /* New Entry from Saved Kibana Query */
  if ($window.localStorage.getItem('kaae_saved_query')) {
	// $scope.watcherSaved = JSON.parse($window.localStorage.getItem('kaae_saved_query'));
	$scope.watcherNew(JSON.parse($window.localStorage.getItem('kaae_saved_query')));
	$window.localStorage.removeItem('kaae_saved_query');
  }

  var currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  var utcTime = moment.utc($route.current.locals.currentTime);
  $scope.utcTime = utcTime.format('HH:mm:ss');
  var unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
    $scope.utcTime = utcTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);

});

// NEW END

uiModules
.get('api/kaae', [])
.controller('kaaeAbout', function ($scope, $route, $interval, timefilter, Notifier) {
  $scope.title = 'KaaE';
  $scope.description = 'Kibana Alert App for Elasticsearch';
  timefilter.enabled = false;
  $scope.notify = new Notifier();

  if (!$scope.notified) {
	  $scope.notify.warning('KAAE is a work in progress! Use at your own risk!');
	  $scope.notified = true;
  }

  var currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  var utcTime = moment.utc($route.current.locals.currentTime);
  $scope.utcTime = utcTime.format('HH:mm:ss');
  var unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
    $scope.utcTime = utcTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);

});

<commit_msg>fix encoding at savetime<commit_after>import _ from 'lodash';
import moment from 'moment';
import chrome from 'ui/chrome';
import uiModules from 'ui/modules';
import uiRoutes from 'ui/routes';
import $ from 'jquery';

/* Elasticsearch */

import elasticsearch from 'elasticsearch-browser';

/* Ace editor */
import 'ace';

/* Timepicker */
import 'ui/timepicker';
import 'ui/courier';
import 'ui/filter_bar';

// import TableVisTypeProvider from 'ui/template_vis_type/TemplateVisType';
// import VisSchemasProvider from 'ui/vis/schemas';
// import tableVisTemplate from 'plugins/table_vis/table_vis.html';
// require('ui/registry/vis_types').register(TableVisTypeProvider);

import AggResponseTabifyTabifyProvider from 'ui/agg_response/tabify/tabify';
// import tableSpyModeTemplate from 'plugins/spy_modes/table_spy_mode.html';

import Notifier from 'ui/notify/notifier';
// import 'ui/autoload/styles';

/* Custom Template + CSS */
import './less/main.less';
import template from './templates/index.html';
import about from './templates/about.html';
import alarms from './templates/alarms.html';
import jsonHtml from './templates/json.html';

var impactLogo = require('plugins/kaae/kaae_watch.svg');
var smallLogo = require('plugins/kaae/kaae.svg');

/* Inject Tabs */
  var topNavMenu = [
  {
    key: 'watchers',
    description: 'WATCH',
    run: function () { kbnUrl.change('/'); }
  },
  {
    key: 'about',
    description: 'ABOUT',
    run: function () { kbnUrl.change('/about'); }
  }
  ];

chrome
  .setBrand({
    'logo': 'url(' + impactLogo + ') left no-repeat'
    ,'smallLogo': 'url(' + impactLogo + ') left no-repeat'
    ,'title': 'KAAE'
  })
  .setNavBackground('#222222')
  .setTabs([
  {
    id: '',
    title: 'Watchers',
    activeIndicatorColor: '#EFF0F2'
  },
  {
    id: 'alarms',
    title: 'Alarms',
    activeIndicatorColor: '#EFF0F2'
  },
  {
    id: 'about',
    title: 'About',
    activeIndicatorColor: '#EFF0F2'
  }
  ]);

uiRoutes.enable();

uiRoutes
.when('/', {
  template,
  resolve: {
    currentTime($http) {
      return $http.get('../api/kaae/example').then(function (resp) {
        return resp.data.time;
      });
    },
    currentWatchers($http) {
      return $http.get('../api/kaae/list').then(function (resp) {
	// console.log('DEBUG LIST:',resp);
        return resp;
      });
    }
  }
});

uiRoutes
.when('/alarms', {
  template: alarms,
  resolve: {
    currentTime($http) {
      return $http.get('../api/kaae/example').then(function (resp) {
        return resp.data.time;
      });
    },
    currentWatchers($http) {
      return $http.get('../api/kaae/list').then(function (resp) {
	// console.log('DEBUG LIST:',resp);
        return resp;
      });
    },
    currentAlarms($http) {
      return $http.get('../api/kaae/alarms').then(function (resp) {
	// console.log('DEBUG ALARMS:',resp);
        return resp;
      });
    },
    elasticAlarms($http) {
      return $http.get('../api/kaae/list/alarms').then(function (resp) {
	// console.log('DEBUG ALARMS:',resp);
        return resp;
      });
    }
  }
});

uiRoutes
.when('/about', {
  template: about
});

uiModules
.get('api/kaae', [])
.filter('moment', function() {
    return function(dateString) {
        return moment(dateString).format('YYYY-MM-DD HH:mm:ss.sss');;
    };
})
.controller('kaaeHelloWorld', function ($rootScope, $scope, $route, $interval, $timeout, timefilter, Private, Notifier, $window, kbnUrl, $http) {
  $scope.title = 'KaaE: Alarms';
  $scope.description = 'Kibana Alert App for Elasticsearch';
  // $scope.store = window.sessionStorage;

  $scope.notify = new Notifier();

  timefilter.enabled = true;

  /* Alarm Functions */

  var checkAlarm = function() {
	  if ($route.current.locals.currentAlarms.data) {
		   $scope.currentAlarms = $route.current.locals.currentAlarms.data.data;
	  } else { $scope.currentAlarms = [] }
  }

  var getAlarmsFromEs = function() {
	  if ($route.current.locals.elasticAlarms.data.hits) {
		   $scope.elasticAlarms = $route.current.locals.elasticAlarms.data.hits.hits;
	  } else { $scope.elasticAlarms = [] }
  }

  /* Update Time Filter */
  var updateFilter = function(){
	  return $http.get('../api/kaae/set/interval/'+JSON.stringify($scope.timeInterval)).then(function (resp) {
	        // console.log('NEW TIMEFILTER:',$scope.timeInterval);
          });
  }

  /* First Boot */

  $scope.timeInterval = timefilter.time;
  updateFilter();

  // checkAlarm();
  getAlarmsFromEs();

  /* Listen for refreshInterval changes */

   $rootScope.$watchCollection('timefilter.time', function (newvar, oldvar) {
      if (newvar == oldvar) { return; }
      let timeInterval = _.get($rootScope, 'timefilter.time');
      // console.log('Time Range Change!',timefilter.time);
      if (timeInterval) {
	 	$scope.timeInterval = timeInterval;
	  	updateFilter();
		$route.reload();
      }

    });

   $rootScope.$watchCollection('timefilter.refreshInterval', function () {
      let refreshValue = _.get($rootScope, 'timefilter.refreshInterval.value');
      let refreshPause = _.get($rootScope, 'timefilter.refreshInterval.pause');

      // Kill any existing timer immediately
      if ($scope.refreshalarms) {
	  	$timeout.cancel($scope.refreshalarms);
		$scope.refreshalarms = undefined;
      }

      // Check if Paused
      if (refreshPause) {
		// console.log('REFRESH PAUSED');
	  	if ($scope.refreshalarms) $timeout.cancel($scope.refreshalarms);
		return;
      }

      // Process New Filter
      if (refreshValue != $scope.currentRefresh && refreshValue != 0) {
	      // new refresh value
      	      if (_.isNumber(refreshValue) && !refreshPause) {
		    // console.log('TIMEFILTER REFRESH');
		    $scope.newRefresh = refreshValue;
			  // Reset Interval & Schedule Next
			  $scope.refreshalarms = $timeout(function () {
			     // console.log('Reloading data....');
			     $route.reload();
		          }, refreshValue);
  			  $scope.$watch('$destroy', $scope.refreshalarms);
	      } else {
		  // console.log('PAUSE REFRESH');
	  	  $scope.currentRefresh = 0;
		  $timeout.cancel($scope.refreshalarms);
	      }

      } else {
		// console.log('NULL CHANGE!');
  	        $timeout.cancel($scope.refreshalarms);
      }

    });

  $scope.deleteAlarm = function($index){
	 $scope.notify.warning('KAAE function not yet implemented!');
	 // $scope.currentAlarms.splice($index,1);
  }

  var currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  var utcTime = moment.utc($route.current.locals.currentTime);
  $scope.utcTime = utcTime.format('HH:mm:ss');
  var unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
    $scope.utcTime = utcTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);

});

// WATCHERS CONTROLLER
uiModules
.get('api/kaae', [])
.controller('kaaeWatchers', function ($rootScope, $scope, $route, $interval, $timeout, timefilter, Private, Notifier, $window, kbnUrl, $http) {
  $scope.title = 'KaaE: Watchers';
  $scope.description = 'Kibana Alert App for Elasticsearch';
  // $scope.store = window.sessionStorage;

  $scope.notify = new Notifier();

  $scope.topNavMenu = [
  {
    key: 'watchers',
    description: 'WATCH',
    run: function () { kbnUrl.change('/'); }
  },
  {
    key: 'about',
    description: 'ABOUT',
    run: function () { kbnUrl.change('/about'); }
  }
  ];

  timefilter.enabled = false;
  /*
	time: {
	        gt: timefilter.getBounds().min.valueOf(),
	        lte: timefilter.getBounds().max.valueOf()
	      }
  */

  // kbnUrl.change('/', {});

  const tabifyAggResponse = Private(AggResponseTabifyTabifyProvider);
  if ($route.current.locals.currentWatchers.data.hits.hits) {
	   $scope.watchers = $route.current.locals.currentWatchers.data.hits.hits;

	/*
	   $scope.spy.params.spyPerPage = 10;
	   $scope.table = tabifyAggResponse($scope.vis, $route.current.locals.currentWatchers.data.hits.hits, {
             canSplit: false,
             asAggConfigResults: true,
             partialRows: true
           });
	*/

  } else { $scope.watchers = []; }

  /* ACE Editor */
  $scope.editor;
  $scope.editor_status = { readonly: false, undo: false, new: false };
  $scope.setAce = function($index,edit) {
	  // var content = $scope.currentAlarms[$index];
	  $scope.editor = ace.edit("editor-"+$index);
	  var _session = $scope.editor.getSession();
    	  // var _renderer = $scope.editor.renderer;
	  $scope.editor.setReadOnly(edit);
	  $scope.editor_status.readonly = edit;
    	  _session.setUndoManager(new ace.UndoManager());

	  $scope.editor_status.undo = $scope.editor.session.getUndoManager().isClean();

	  if (!edit) { $scope.editor.getSession().setMode("ace/mode/json"); }
	  else { $scope.editor.getSession().setMode("ace/mode/text"); }
  }

  $scope.watcherDelete = function($index){

     if (confirm('Are you sure?')) {
	 return $http.get('../api/kaae/delete/watcher/'+$scope.watchers[$index]._id).then(function (resp) {
        	// console.log('API DELETE:',resp.data);
			 var reload = $timeout(function () {
		              $route.reload();
		 	      $scope.notify.warning('KAAE Watcher successfully deleted!');
		 	 }, 1000);
         });
      }
  }

  $scope.watcherGet = function($index){
	 // console.log('retreiving watcher ', $scope.watchers[$index] );
	 return $http.get('../api/kaae/get/watcher/'+$scope.watchers[$index]._id).then(function (resp) {
        	// console.log('API GET:',resp.data);
         });
  }

  $scope.watcherSave = function($index){
	 // console.log('saving watcher ', $scope.watchers[$index] );
    	 var watcher = $scope.editor ? JSON.parse($scope.editor.getValue()) : $scope.watchers[$index];
	 console.log('saving object:',watcher);
	 return $http.get('../api/kaae/save/watcher/'+encodeURIComponent(JSON.stringify(watcher))).then(function (resp) {
        	// console.log('API STORE:',resp);
			 var reload = $timeout(function () {
		              $route.reload();
		 	      $scope.notify.warning('KAAE Watcher successfully saved!');
		 	 }, 1000);
         });
  }

  $scope.getWatchers = function(){
	return $scope.watchers;
  }

  /* New Entry */
  $scope.watcherNew = function(newwatcher) {
	if (!newwatcher) {
	  var newwatcher = {
		  "_index": "watcher",
		  "_type": "watch",
		  "_id": "new",
		  "_new": "true",
		  "_source": {
		    "trigger": {
		      "schedule": {
		        "interval": "60"
		      }
		    },
		    "input": {
		      "search": {
		        "request": {
		          "indices": [],
		          "body": {},
		        }
		      }
		    },
		    "condition": {
		      "script": {
		        "script": "payload.hits.total > 100"
		      }
		    },
		    "transform": {},
		    "actions": {
		      "email_admin": {
		        "throttle_period": "15m",
		        "email": {
		          "to": "alarm@localhost",
		          "subject": "KaaE Alarm",
		          "priority": "high",
		          "body": "Found {{payload.hits.total}} Events"
		        }
		      }
		    }
		  }
		};
        }

	$scope.watchers.unshift(newwatcher);

	/*
	 refreshalarms = $timeout(function () {
	      // console.log('set new watcher to edit mode...');
	      $scope.setAce(0,false);
 	 }, 200);
	*/

  }

  /* New Entry from Saved Kibana Query */
  if ($window.localStorage.getItem('kaae_saved_query')) {
	// $scope.watcherSaved = JSON.parse($window.localStorage.getItem('kaae_saved_query'));
	$scope.watcherNew(JSON.parse($window.localStorage.getItem('kaae_saved_query')));
	$window.localStorage.removeItem('kaae_saved_query');
  }

  var currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  var utcTime = moment.utc($route.current.locals.currentTime);
  $scope.utcTime = utcTime.format('HH:mm:ss');
  var unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
    $scope.utcTime = utcTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);

});

// NEW END

uiModules
.get('api/kaae', [])
.controller('kaaeAbout', function ($scope, $route, $interval, timefilter, Notifier) {
  $scope.title = 'KaaE';
  $scope.description = 'Kibana Alert App for Elasticsearch';
  timefilter.enabled = false;
  $scope.notify = new Notifier();

  if (!$scope.notified) {
	  $scope.notify.warning('KAAE is a work in progress! Use at your own risk!');
	  $scope.notified = true;
  }

  var currentTime = moment($route.current.locals.currentTime);
  $scope.currentTime = currentTime.format('HH:mm:ss');
  var utcTime = moment.utc($route.current.locals.currentTime);
  $scope.utcTime = utcTime.format('HH:mm:ss');
  var unsubscribe = $interval(function () {
    $scope.currentTime = currentTime.add(1, 'second').format('HH:mm:ss');
    $scope.utcTime = utcTime.add(1, 'second').format('HH:mm:ss');
  }, 1000);
  $scope.$watch('$destroy', unsubscribe);

});

<|endoftext|>


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


<commit_before>export default [
  {
    name: 'Razvan Stoenescu',
    role: 'Creator, Lead Dev & Architect',
    avatar: 'razvan_stoenescu.jpeg',
    email: 'razvan@quasar.dev',
    twitter: 'quasarframework',
    github: 'rstoenescu',
    desc: 'Architecture and development of Quasar on all fronts.'
  },

  {
    name: 'Dan Popescu',
    role: 'Senior Core Developer',
    avatar: 'dan_popescu.jpg',
    email: 'dan@quasar.dev',
    github: 'pdanpdan',
    desc: 'Focuses on Quasar UI components, directives and plugins.'
  },

  {
    name: 'Denjell Thompson-Yvetot',
    role: 'Senior Dev & Security Engineer',
    avatar: 'daniel_thompson-yvetot.jpg',
    email: 'denjell@quasar.dev',
    twitter: 'nothingismagick',
    github: 'nothingismagick',
    desc: 'Tooling and rigging app extensions, product development, Quasar Radio Show, community manager. Also writes articles.'
  },

  {
    name: 'Jeff Galbraith',
    role: 'Senior Developer',
    avatar: 'jeff_galbraith.jpg',
    email: 'jeff@quasar.dev',
    twitter: 'jgalbraith64',
    github: 'hawkeye64',
    desc: 'UI app extensions, the Quasar Radio Show and community outreach.'
  },

  {
    name: 'Lucas Nogueira',
    role: 'Senior Developer',
    avatar: 'lucas_nogueira.jpg',
    github: 'lucasfernog',
    desc: 'Quasar CLI development, Webview Quasar mode.'
  },

  {
    name: 'Allan Gaunt',
    role: 'Senior Developer',
    avatar: 'allan_gaunt.png',
    github: 'webnoob',
    desc: 'Web products and security research.'
  },

  {
    name: 'Scott Molinari',
    role: 'DevOps / Senior Developer',
    avatar: 'scott_molinari.jpg',
    github: 'smolinari',
    desc: 'Helps with docs, bug reports, external systems, writes articles and offers community support.'
  },

  {
    name: 'Tobias Mesquita',
    role: 'Senior Developer',
    avatar: 'tobias_mesquita.jpg',
    github: 'TobyMosque',
    desc: 'Help desk'
  },

  {
    name: 'Kerry Huguet',
    role: 'Senior Developer',
    avatar: 'kerry_huguet.jpeg',
    github: 'outofmemoryagain',
    desc: 'Typescript support'
  },

  {
    name: 'Noah Klayman',
    role: 'DevOps / Community Staff',
    avatar: 'noah_klayman.jpeg',
    github: 'nklayman',
    desc: 'GraphQL, App Extensions'
  },

  {
    name: 'Aldrin Marquez',
    role: 'Community Staff',
    avatar: 'aldrin_marquez.jpg',
    github: 'metalsadman',
    desc: 'Help desk'
  },

  {
    name: 'Matyáš Racek',
    role: 'Community Staff',
    avatar: 'matyas_panstromek.jpeg',
    github: 'panstromek',
    desc: 'Help desk'
  },

  {
    name: 'James Harrington',
    role: 'Community Staff',
    avatar: 'james_harrington.jpeg',
    github: 'codenamezjames',
    desc: 'Help desk'
  },

  {
    name: 'Ross Ball',
    role: 'Designer / Community Staff',
    avatar: 'ross_ball.jpeg',
    github: 'rossity',
    desc: 'Quasar Themes'
  },

  {
    name: 'James Gilchrist',
    role: 'Community Staff',
    avatar: 'james_gilchrist.png',
    github: 'jpgilchrist',
    desc: 'Help desk'
  },

  {
    name: 'Ben Coughenour',
    role: 'Community Staff',
    avatar: 'ben_coughenour.jpg',
    github: 'sskwrl',
    desc: 'Help desk'
  },

  {
    name: 'Heitor Ribeiro',
    role: 'Community Staff',
    avatar: 'heitor_ribeiro.jpg',
    github: 'bloodf',
    desc: 'Writes articles and offers community support.'
  },

  {
    name: 'David Watson',
    role: 'Community Staff',
    avatar: 'david_watson.jpg',
    github: 'realtimeappsolutions',
    desc: 'Marketing and PR.'
  },

  {
    name: 'Stanislav Valasek',
    role: 'Community Staff',
    avatar: 'stanislav_valasek.jpg',
    github: 'valasek',
    desc: 'Marketing, Open Source Compliance, Community experience.'
  }
]
<commit_msg>chore: Fix build<commit_after>export default [
  {
    name: 'Razvan Stoenescu',
    role: 'Creator, Lead Dev & Architect',
    avatar: 'razvan_stoenescu.jpeg',
    email: 'razvan@quasar.dev',
    twitter: 'quasarframework',
    github: 'rstoenescu',
    desc: 'Architecture and development of Quasar on all fronts.'
  },

  {
    name: 'Dan Popescu',
    role: 'Senior Core Developer',
    avatar: 'dan_popescu.jpg',
    email: 'dan@quasar.dev',
    github: 'pdanpdan',
    desc: 'Focuses on Quasar UI components, directives and plugins.'
  },

  {
    name: 'Denjell Thompson-Yvetot',
    role: 'Senior Dev & Security Engineer',
    avatar: 'daniel_thompson-yvetot.jpg',
    email: 'denjell@quasar.dev',
    twitter: 'nothingismagick',
    github: 'nothingismagick',
    desc: 'Tooling and rigging app extensions, product development, Quasar Radio Show, community manager. Also writes articles.'
  },

  {
    name: 'Jeff Galbraith',
    role: 'Senior Developer',
    avatar: 'jeff_galbraith.jpg',
    email: 'jeff@quasar.dev',
    twitter: 'jgalbraith64',
    github: 'hawkeye64',
    desc: 'UI app extensions, the Quasar Radio Show and community outreach.'
  },

  {
    name: 'Lucas Nogueira',
    role: 'Senior Developer',
    avatar: 'lucas_nogueira.jpg',
    github: 'lucasfernog',
    desc: 'Quasar CLI development, Webview Quasar mode.'
  },

  {
    name: 'Allan Gaunt',
    role: 'Senior Developer',
    avatar: 'allan_gaunt.png',
    github: 'webnoob',
    desc: 'Web products and security research.'
  },

  {
    name: 'Scott Molinari',
    role: 'DevOps / Senior Developer',
    avatar: 'scott_molinari.jpg',
    github: 'smolinari',
    desc: 'Helps with docs, bug reports, external systems, writes articles and offers community support.'
  },

  {
    name: 'Tobias Mesquita',
    role: 'Senior Developer',
    avatar: 'tobias_mesquita.jpg',
    github: 'TobyMosque',
    desc: 'Help desk'
  },

  {
    name: 'Kerry Huguet',
    role: 'Senior Developer',
    avatar: 'kerry_huguet.jpeg',
    github: 'outofmemoryagain',
    desc: 'Typescript support'
  },

  {
    name: 'Noah Klayman',
    role: 'DevOps / Community Staff',
    avatar: 'noah_klayman.jpeg',
    github: 'nklayman',
    desc: 'GraphQL, App Extensions'
  },

  {
    name: 'Aldrin Marquez',
    role: 'Community Staff',
    avatar: 'aldrin_marquez.jpg',
    github: 'metalsadman',
    desc: 'Help desk'
  },

  {
    name: 'Matyáš Racek',
    role: 'Community Staff',
    avatar: 'matyas_panstromek.jpeg',
    github: 'panstromek',
    desc: 'Help desk'
  },

  {
    name: 'James Harrington',
    role: 'Community Staff',
    avatar: 'james_harrington.jpeg',
    github: 'codenamezjames',
    desc: 'Help desk'
  },

  {
    name: 'Ross Ball',
    role: 'Designer / Community Staff',
    avatar: 'ross_ball.jpeg',
    github: 'rossity',
    desc: 'Quasar Themes'
  },

  {
    name: 'James Gilchrist',
    role: 'Community Staff',
    avatar: 'james_gilchrist.png',
    github: 'jpgilchrist',
    desc: 'Help desk'
  },

  {
    name: 'Ben Coughenour',
    role: 'Community Staff',
    avatar: 'ben_coughenour.jpg',
    github: 'sskwrl',
    desc: 'Help desk'
  },

  {
    name: 'Heitor Ribeiro',
    role: 'Community Staff',
    avatar: 'heitor_ribeiro.jpg',
    github: 'bloodf',
    desc: 'Writes articles and offers community support.'
  },

  {
    name: 'David Watson',
    role: 'Community Staff',
    avatar: 'david_watson.jpg',
    github: 'realtimeappsolutions',
    desc: 'Marketing and PR.'
  },

  {
    name: 'Stanislav Valasek',
    role: 'Community Staff',
    avatar: 'stanislav_valasek.jpg',
    github: 'valasek',
    desc: 'Marketing, Open Source Compliance, Community experience.'
  }
]
<|endoftext|>