<commit_before>/*
Language: Gherkin
Author: Sam Pikesley (@pikesley) <sam.pikesley@theodi.org>
Description: Gherkin (Cucumber etc)
*/

function(hljs) {
  return {
      contains: [
        {
          className: 'keyword',
          begin: '^\\s*(But |And |Then |When |Given |\\* |Scenarios|Examples|Scenario Template|Scenario Outline|Scenario|Background|Ability|Business Need|Feature)',
          relevance: 0
        },
        {
          className: 'string',
          begin: '\\|',
          relevance: 0
        },
        hljs.HASH_COMMENT_MODE,
        {
          className: 'string',
          begin: '"""', end: '"""',
          relevance: 10
        },
        hljs.APOS_STRING_MODE,
        hljs.QUOTE_STRING_MODE,
        hljs.C_NUMBER_MODE,
        {
          className: 'annotation', begin: '@[^@\r\n\t ]+'
        }
      ]
  };
}
<commit_msg>Capture do, end, /^step def text$/<commit_after>/*
 Language: Gherkin
 Author: Sam Pikesley (@pikesley) <sam.pikesley@theodi.org>
 Description: Gherkin (Cucumber etc)
 */

function (hljs) {
    return {
        contains: [
            {
                className: 'keyword',
                begin: '^\\s*(But |And |Then |When |Given |\\* |Scenarios|Examples|Scenario Template|Scenario Outline|Scenario|Background|Ability|Business Need|Feature)',
                relevance: 10
            },
            {
                className: 'keyword',
                begin: '( do$|^end$)',
                relevance: 0
            },
            {
                className: 'string',
                begin: '\\|',
                relevance: 0
            },
            {
                className: 'literal',
                begin: '/\\^', end: '\\$/',
                relevance: 0
            },
            hljs.HASH_COMMENT_MODE,
            {
                className: 'string',
                begin: '"""', end: '"""',
                relevance: 10
            },
            hljs.APOS_STRING_MODE,
            hljs.QUOTE_STRING_MODE,
            hljs.C_NUMBER_MODE,
            {
                className: 'annotation', begin: '@[^@\r\n\t ]+'
            }
        ]
    };
}
<|endoftext|>


<commit_before>VER = "0.4";

function Risibot() {

  this.room = room;
  this.currentTurn = 0;

  this.movesParsed = false;
  this.parsingMoves = false;
  this.moves = undefined;
  this.buttonsMoves = undefined;

  this.ennemyParsed = false;
  this.ennemy = undefined;

  this.pokemonParsed = false;
  this.pokemon = undefined;

  this.havePlayed = false;

  this.AI = new PokeyI(this);
	this.stopSignal = false;

	console.log(this);

  this.firstMessages(0);
};

Risibot.prototype.say = function(msg) {
	this.room.send("[Risibot]: La chancla channel: " + msg);
};

Risibot.prototype.firstMessages = function(i) {
	switch (i) {
		case 0:
			this.say("Risibot initialized. V." + VER);
			break;
		case 1:
			this.say("Here is my code : https://github.com/Risitop/Risibot/");
			break;
		case 2:
			this.say("Good luck human.");
			return;
	}
	var that = this;
	console.log(this);
	setTimeout( function() { that.firstMessages(i + 1); }, 1000 );
};

// Gets a formatted moves object
Risibot.prototype.parseMoves = function() {
  this.movesParsed = false;
  this.moves = {
    'traps': [], // Entry hazards
    'status': [], // Thunder wave
    'special': [], // Hydro pump
    'physical': [], // Earthquake
    'boost': [], // Swords dance
    'specialS': [], // Scald
    'physicalS': [], // Dynamic punch
    'specialB': [], // Power up punch
    'physicalB': [], // ?
    'protect': [],
    'seeds': [],
    'defog': [],
    'spin': [],
    'taunt': [],
    'heal': [],
    'cure': [],
    'roar': [],
    'uTurn': [],
    'voltSwitch': [],
    'trick': [],
    'fakeOut': [],
		'painSplit': []
  };

  movesTab = [];
  this.buttonsMoves = document.getElementsByName("chooseMove");
  if (this.buttonsMoves.length == 0) {
    console.log("Risibot: parseMoves: " + this.buttonsMoves.length + " moves parsed. Retrying...");
    var that = this;
    this.parsingMoves = true;
    setTimeout(function() {
      that.parseMoves();
    }, 1000);
    return;
  }

  for (var i = 0; i < this.buttonsMoves.length; i++) {
    movesTab.push(Tools.getMove(this.buttonsMoves[i].attributes['data-move'].nodeValue));
  }

  for (i = 0; i < movesTab.length; i++) {
    m = movesTab[i];
    k = parseInt(this.buttonsMoves[i].value);

    // Particular moves
    if (m.id == 'leechseed')
      this.moves.seeds.push([m, k]);
    else if (m.id == 'rapidspin')
      this.moves.spin.push([m, k]);
    else if (m.id == 'defog')
      this.moves.defog.push([m, k]);
    else if (m.id == 'taunt')
      this.moves.taunt.push([m, k]);
    else if (m.priority == -6)
      this.moves.roar.push([m, k]);
    else if (m.heal)
      this.moves.heal.push([m, k]);
    else if (m.target == 'allyTeam')
      this.moves.cure.push([m, k]);
    else if (m.selfSwitch)
      if (m.baseType == 'bug')
        this.moves.uTurn.push([m, k]);
      else
        this.moves.voltSwitch.push([m, k]);
    else if (m.id == 'trick' || m.id == 'switcheroo')
      this.moves.trick.push([m, k]);
    else if (m.id == 'fakeout')
      this.moves.fakeOut.push([m, k]);
		else if (m.id == 'painsplit')
      this.moves.spin.push([m, k]);

    else if (m.category == 'Status') {
      if (m.target == 'foeSide')
        this.moves.traps.push([m, k]);
      else if (m.status)
        this.moves.status.push([m, k]);
      else if (m.target == 'self')
        if (m.volatileStatus == 'protect')
          this.moves.protect.push([m, k]);
        else
          this.moves.boost.push([m, k]);
    } else if (m.category == 'Special') {
      if (m.secondaries)
        if (m.boosts)
          this.moves.specialB.push([m, k]);
        else
          this.moves.specialS.push([m, k]);
      else
        this.moves.special.push([m, k]);
    } else if (m.category == 'Physical') {
      if (m.secondaries)
        if (m.boosts)
          this.moves.physicalB.push([m, k]);
        else
          this.moves.physicalS.push([m, k]);
      else
        this.moves.physical.push([m, k]);
    }
  }

  console.log("Risibot: parseMoves: " + this.buttonsMoves.length + " moves parsed.");
	e = document.getElementsByName("megaevo");
	if (e.length)
		e[0].setAttribute("checked", true);
  this.movesParsed = true;
};

Risibot.prototype.getPokemon = function() {
  this.pokemon = undefined;
  pokemonPerso = undefined;
  for (i = 0; i < this.room.myPokemon.length; i++) {
    if (this.room.myPokemon[i].active)
      pokemonPerso = this.room.myPokemon[i];
  }
  pokemonGeneral = this.room.battle.mySide.active[0];
  if (pokemonPerso && pokemonGeneral) {
    this.pokemonParsed = true;
    this.pokemon = new FullPokemon(pokemonPerso, pokemonGeneral);
    console.log("Risibot: getPokemon: " + this.pokemon.name + " parsed.");
  }
};

Risibot.prototype.getEnnemyPokemon = function() {
  this.ennemy = new EnnemyPokemon(this.room.battle.yourSide.active[0]);
  if (this.ennemy) {
    this.ennemyParsed = true;
    console.log("Risibot: getPokemon: Ennemy " + this.ennemy.name + " parsed.");
  }
};

Risibot.prototype.waitingForMe = function() {
  if (!this.room)
    return false;
  else if (!this.room.choice)
    return false;
  else if (!this.room.choice.waiting)
    return true;
  return false;
};

Risibot.prototype.attack = function(id) {

  if (!this.buttonsMoves[0])
    return;

  console.log("Risibot: attack: Trying to execute move " + id + ".");

  var k = 0;
  while (parseInt(this.buttonsMoves[k].value) != id)
    k++;
  this.room.chooseMove(id, this.buttonsMoves[k]);
  return true;
};
Risibot.prototype.routine = function() {

  if (this.currentTurn < this.room.battle.turn) {
    this.movesParsed = false;
    this.parsingMoves = false;
    this.getEnnemyPokemon();
    this.getPokemon();
    this.currentTurn = this.room.battle.turn;
		console.log("Maximum damage taken: " + this.AI.getMaxDamageTaken(this.pokemon));
  }

  if (!this.movesParsed && !this.parsingMoves) {
    this.parseMoves();
  }

  if (this.waitingForMe()) {
    if (this.pokemon && this.room.battle.mySide.active && !this.pokemon.fainted && this.movesParsed) {
      m = this.choseMove();
			if (m != -1)
				this.attack(m + 1);
    } else { //Chose another
      placeholder = 1;
    }
  }

	if (this.stopSignal)
		return;

  var that = this;
  setTimeout(function() {
    that.routine();
  }, 500);
};

Risibot.prototype.getField = function() { // Get the current status of the field DONE
    var f = new Field();

    f.isLightScreen[0] = (typeof this.room.battle.mySide.sideConditions.lightScreen !== 'undefined');
    f.isLightScreen[1] = (typeof this.room.battle.yourSide.sideConditions.lightScreen !== 'undefined');
    f.isReflect[0] = (typeof this.room.battle.mySide.sideConditions.reflect !== 'undefined');
    f.isReflect[1] = (typeof this.room.battle.yourSide.sideConditions.reflect !== 'undefined');

    f.weather = (this.room.battle.weather == 'sunnyday') ? "Sun" : (this.room.battle.weather == 'raindance') ? "Rain" : (this.room.battle.weather == 'hail') ? "Hail" : "";

    f.isGravity = (this.room.battle.weather == "pseudo");

}
<commit_msg>Update Risibot.js<commit_after>VER = "0.4.1";

function Risibot() {

  this.room = room;
  this.currentTurn = 0;

  this.movesParsed = false;
  this.parsingMoves = false;
  this.moves = undefined;
  this.buttonsMoves = undefined;

  this.ennemyParsed = false;
  this.ennemy = undefined;

  this.pokemonParsed = false;
  this.pokemon = undefined;

  this.havePlayed = false;

  this.AI = new PokeyI(this);
	this.stopSignal = false;

	console.log(this);

  this.firstMessages(0);
};

Risibot.prototype.say = function(msg) {
	this.room.send("[Risibot]: La chancla channel: " + msg);
};

Risibot.prototype.firstMessages = function(i) {
	switch (i) {
		case 0:
			this.say("Risibot initialized. V." + VER);
			break;
		case 1:
			this.say("Here is my code : https://github.com/Risitop/Risibot/");
			break;
		case 2:
			this.say("Good luck human.");
			return;
	}
	var that = this;
	console.log(this);
	setTimeout( function() { that.firstMessages(i + 1); }, 1000 );
};

// Gets a formatted moves object
Risibot.prototype.parseMoves = function() {
  this.movesParsed = false;
  this.moves = {
    'traps': [], // Entry hazards
    'status': [], // Thunder wave
    'special': [], // Hydro pump
    'physical': [], // Earthquake
    'boost': [], // Swords dance
    'specialS': [], // Scald
    'physicalS': [], // Dynamic punch
    'specialB': [], // Power up punch
    'physicalB': [], // ?
    'protect': [],
    'seeds': [],
    'defog': [],
    'spin': [],
    'taunt': [],
    'heal': [],
    'cure': [],
    'roar': [],
    'uTurn': [],
    'voltSwitch': [],
    'trick': [],
    'fakeOut': [],
		'painSplit': []
  };

  movesTab = [];
  this.buttonsMoves = document.getElementsByName("chooseMove");
  if (this.buttonsMoves.length == 0) {
    console.log("Risibot: parseMoves: " + this.buttonsMoves.length + " moves parsed. Retrying...");
    var that = this;
    this.parsingMoves = true;
    setTimeout(function() {
      that.parseMoves();
    }, 1000);
    return;
  }

  for (var i = 0; i < this.buttonsMoves.length; i++) {
    movesTab.push(Tools.getMove(this.buttonsMoves[i].attributes['data-move'].nodeValue));
  }

  for (i = 0; i < movesTab.length; i++) {
    m = movesTab[i];
    k = parseInt(this.buttonsMoves[i].value);

    // Particular moves
    if (m.id == 'leechseed')
      this.moves.seeds.push([m, k]);
    else if (m.id == 'rapidspin')
      this.moves.spin.push([m, k]);
    else if (m.id == 'defog')
      this.moves.defog.push([m, k]);
    else if (m.id == 'taunt')
      this.moves.taunt.push([m, k]);
    else if (m.priority == -6)
      this.moves.roar.push([m, k]);
    else if (m.heal)
      this.moves.heal.push([m, k]);
    else if (m.target == 'allyTeam')
      this.moves.cure.push([m, k]);
    else if (m.selfSwitch)
      if (m.baseType == 'bug')
        this.moves.uTurn.push([m, k]);
      else
        this.moves.voltSwitch.push([m, k]);
    else if (m.id == 'trick' || m.id == 'switcheroo')
      this.moves.trick.push([m, k]);
    else if (m.id == 'fakeout')
      this.moves.fakeOut.push([m, k]);
		else if (m.id == 'painsplit')
      this.moves.spin.push([m, k]);

    else if (m.category == 'Status') {
      if (m.target == 'foeSide')
        this.moves.traps.push([m, k]);
      else if (m.status)
        this.moves.status.push([m, k]);
      else if (m.target == 'self')
        if (m.volatileStatus == 'protect')
          this.moves.protect.push([m, k]);
        else
          this.moves.boost.push([m, k]);
    } else if (m.category == 'Special') {
      if (m.secondaries)
        if (m.boosts)
          this.moves.specialB.push([m, k]);
        else
          this.moves.specialS.push([m, k]);
      else
        this.moves.special.push([m, k]);
    } else if (m.category == 'Physical') {
      if (m.secondaries)
        if (m.boosts)
          this.moves.physicalB.push([m, k]);
        else
          this.moves.physicalS.push([m, k]);
      else
        this.moves.physical.push([m, k]);
    }
  }

  console.log("Risibot: parseMoves: " + this.buttonsMoves.length + " moves parsed.");
	e = document.getElementsByName("megaevo");
	if (e.length)
		e[0].setAttribute("checked", true);
  this.movesParsed = true;
};

Risibot.prototype.getPokemon = function() {
  this.pokemon = undefined;
  pokemonPerso = undefined;
  for (i = 0; i < this.room.myPokemon.length; i++) {
    if (this.room.myPokemon[i].active)
      pokemonPerso = this.room.myPokemon[i];
  }
  pokemonGeneral = this.room.battle.mySide.active[0];
  if (pokemonPerso && pokemonGeneral) {
    this.pokemonParsed = true;
    this.pokemon = new FullPokemon(pokemonPerso, pokemonGeneral);
    console.log("Risibot: getPokemon: " + this.pokemon.name + " parsed.");
  }
};

Risibot.prototype.getEnnemyPokemon = function() {
  this.ennemy = new EnnemyPokemon(this.room.battle.yourSide.active[0]);
  if (this.ennemy) {
    this.ennemyParsed = true;
    console.log("Risibot: getPokemon: Ennemy " + this.ennemy.name + " parsed.");
  }
};

Risibot.prototype.waitingForMe = function() {
  if (!this.room)
    return false;
  else if (!this.room.choice)
    return false;
  else if (!this.room.choice.waiting)
    return true;
  return false;
};

Risibot.prototype.attack = function(id) {

  if (!this.buttonsMoves[0])
    return;

  console.log("Risibot: attack: Trying to execute move " + id + ".");

  var k = 0;
  while (parseInt(this.buttonsMoves[k].value) != id)
    k++;
  this.room.chooseMove(id, this.buttonsMoves[k]);
  return true;
};
Risibot.prototype.routine = function() {

  if (this.currentTurn < this.room.battle.turn) {
    this.movesParsed = false;
    this.parsingMoves = false;
    this.getEnnemyPokemon();
    this.getPokemon();
    this.currentTurn = this.room.battle.turn;
		console.log("Maximum damage taken: " + this.AI.getMaxDamageTaken(this.pokemon));
  }

  if (!this.movesParsed && !this.parsingMoves) {
    this.parseMoves();
  }

  if (this.waitingForMe()) {
    if (this.pokemon && this.room.battle.mySide.active && !this.pokemon.fainted && this.movesParsed) {
      m = this.choseMove();
			if (m != -1)
				this.attack(m + 1);
    } else { //Chose another
      placeholder = 1;
    }
  }

	if (this.stopSignal)
		return;

  var that = this;
  setTimeout(function() {
    that.routine();
  }, 500);
};

Risibot.prototype.getField = function() { // Get the current status of the field DONE
    var f = new Field();

    f.isLightScreen[0] = (typeof this.room.battle.mySide.sideConditions.lightScreen !== 'undefined');
    f.isLightScreen[1] = (typeof this.room.battle.yourSide.sideConditions.lightScreen !== 'undefined');
    f.isReflect[0] = (typeof this.room.battle.mySide.sideConditions.reflect !== 'undefined');
    f.isReflect[1] = (typeof this.room.battle.yourSide.sideConditions.reflect !== 'undefined');

    f.weather = (this.room.battle.weather == 'sunnyday') ? "Sun" : (this.room.battle.weather == 'raindance') ? "Rain" : (this.room.battle.weather == 'hail') ? "Hail" : "";

    f.isGravity = (this.room.battle.weather == "pseudo");

}
<|endoftext|>


<commit_before>var layer = new maptalks.TileLayer('light', {
  urlTemplate: '$(urlTemplate)',
  subdomains: $(subdomains),
  attribution: '$(attribution)',
  // force layer to render when map is zooming and moving
  'forceRenderOnMoving' : true,
  'forceRenderOnZooming' : true
});

var map = new maptalks.Map('map', {
  center: [121.4,37.5],
  zoom: 13,
  baseLayer : new maptalks.TileLayer('base',{
    'urlTemplate': 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
    'subdomains'  : ['a','b','c','d']
  }),
  layers : [layer]
});

var swipe = document.getElementById('swipe');

var renderer = layer.getRenderer();
var canvasGetter = renderer.getCanvasImage;
//override renderer's default method to get layer canvas image
renderer.getCanvasImage = function () {
  //original layer canvas image
  var layerImage = canvasGetter.call(renderer);
  if (!layerImage || !layerImage.image) {
    return layerImage;
  }
  //drawn width after layer is erased by swipper
  var width = renderer.canvas.width * (swipe.value / 100);
  var ctx = renderer.context;

  //copy drawn rect of original layer canvas
  var drawnRect = document.createElement('canvas');
  drawnRect.width = width;
  drawnRect.height = ctx.canvas.height;
  drawnRect.getContext('2d').drawImage(ctx.canvas, 0, 0);

  //clear the erased part
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

  //draw a white background to cover the bottom layers when zooming
  ctx.beginPath();
  ctx.rect(0, 0, drawnRect.width, ctx.canvas.height);
  ctx.fillStyle = '#fff';
  ctx.fill();

  //draw the drawn part on layer's canvas
  ctx.drawImage(drawnRect, 0, 0);
  return layerImage;
};

swipe.addEventListener('input', function () {
  //let layer redraw self in the next frame
  layer.getRenderer().setToRedraw();
});
<commit_msg>fix swipe when tilting<commit_after>var layer = new maptalks.TileLayer('light', {
  urlTemplate: '$(urlTemplate)',
  subdomains: $(subdomains),
  attribution: '$(attribution)',
  // force layer to render when map is zooming and moving
  'forceRenderOnMoving' : true,
  'forceRenderOnZooming' : true
});

var map = new maptalks.Map('map', {
  center: [121.4,37.5],
  zoom: 13,
  baseLayer : new maptalks.TileLayer('base',{
    'urlTemplate': 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
    'subdomains'  : ['a','b','c','d']
  }),
  layers : [layer]
});

var swipe = document.getElementById('swipe');

var renderer = layer.getRenderer();
var canvasGetter = renderer.getCanvasImage;
//override renderer's default method to get layer canvas image
renderer.getCanvasImage = function () {
  //original layer canvas image
  var layerImage = canvasGetter.call(renderer);
  if (!layerImage || !layerImage.image) {
    return layerImage;
  }
  //drawn width after layer is erased by swipper
  var width = renderer.canvas.width * (swipe.value / 100);
  var ctx = renderer.context;

  //copy drawn rect of original layer canvas
  var drawnRect = document.createElement('canvas');
  drawnRect.width = width;
  drawnRect.height = ctx.canvas.height;
  drawnRect.getContext('2d').drawImage(layerImage.image, 0, 0);

  //clear the erased part
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

  //draw a white background to cover the bottom layers when zooming
  ctx.beginPath();
  ctx.rect(0, 0, drawnRect.width, ctx.canvas.height);
  ctx.fillStyle = '#fff';
  ctx.fill();

  //draw the drawn part on layer's canvas
  ctx.drawImage(drawnRect, 0, 0);
  layerImage.image = ctx.canvas;
  return layerImage;
};

swipe.addEventListener('input', function () {
  //let layer redraw self in the next frame
  layer.getRenderer().setToRedraw();
});
<|endoftext|>


<commit_before>/**
 * Sigma.js Display Data Classes
 * ==============================
 *
 * Classes representing nodes & edges display data aiming at facilitating
 * the engine's memory representation and keep them in a pool to avoid
 * requiring to allocate memory too often.
 *
 * NOTE: it's possible to optimize this further by maintaining display data
 * in byte arrays but this would prove more tedious for the rendering logic
 * afterwards.
 */
export class NodeDisplayData {
  constructor(index, settings) {
    this.index = index;
    this.x = 0;
    this.y = 0;
    this.size = 2;
    this.color = settings.defaultNodeColor;
    this.hidden = false;
    this.label = '';
  }

  assign(data) {
    if ('x' in data)
      this.x = data.x;

    if ('y' in data)
      this.y = data.y;

    if ('size' in data)
      this.size = data.size;

    if ('color' in data)
      this.color = data.color;

    if ('hidden' in data)
      this.hidden = data.hidden;

    if ('label' in data)
      this.label = data.label;
  }
}

export class EdgeDisplayData {
  constructor(index, settings) {
    this.index = index;
    this.size = 1;
    this.color = settings.defaultEdgeColor;
    this.hidden = false;
    this.label = '';
  }

  assign(data) {
    if ('size' in data)
      this.size = data.size;

    if ('color' in data)
      this.color = data.color;

    if ('hidden' in data)
      this.hidden = data.hidden;

    if ('label' in data)
      this.label = data.label;
  }
}
<commit_msg>WebGL: Accept arbitrary data from reducers<commit_after>/**
 * Sigma.js Display Data Classes
 * ==============================
 *
 * Classes representing nodes & edges display data aiming at facilitating
 * the engine's memory representation and keep them in a pool to avoid
 * requiring to allocate memory too often.
 *
 * NOTE: it's possible to optimize this further by maintaining display data
 * in byte arrays but this would prove more tedious for the rendering logic
 * afterwards.
 */
export class NodeDisplayData {
  constructor(index, settings) {
    this.index = index;
    this.x = 0;
    this.y = 0;
    this.size = 2;
    this.color = settings.defaultNodeColor;
    this.hidden = false;
    this.label = '';
  }

  assign(data) {
    for (const key in data)
      this[key] = data[key];
  }
}

export class EdgeDisplayData {
  constructor(index, settings) {
    this.index = index;
    this.size = 1;
    this.color = settings.defaultEdgeColor;
    this.hidden = false;
    this.label = '';
  }

  assign(data) {
    for (const key in data)
      this[key] = data[key];
  }
}
<|endoftext|>


<commit_before>$.fn.extend({

  dmWidgetNavigationMenuForm: function(widget)
  {
    var self = this,

    formName = self.metadata().form_name,

    $form = self.find('form:first'),

    $tabs = $form.find('div.dm_tabbed_form').dmCoreTabForm(),

    $items = $form.find('.items_list'),
    itemIndex = 0,

    metadata = $items.metadata(),

    createItemElement = function(item)
    {
      item = $.extend({
        position: 0,
        link: '',
        text: '',
        secure: false,
        nofollow: false,
        target: ''
      }, item);

      alert(item.target);

      var $li = $('
')
      .html('\
'+item.text+' \

 \

'+metadata.text_message+':<input class="text" type="text" name="'+formName+'[text]['+itemIndex+']" />
 \

'+metadata.link_message+':<input class="link" type="text" name="'+formName+'[link]['+itemIndex+']" />
 \

 \
'+metadata.delete_message+' \
'+metadata.extended_show_message+' \

 \

 \

'+metadata.secure_message+':<input class="secure" type="checkbox" name="'+formName+'[secure]['+itemIndex+']" value="1" />
 \

'+metadata.nofollow_message+':<input class="nofollow" type="checkbox" name="'+formName+'[nofollow]['+itemIndex+']" value="1" />
 \

'+metadata.depth_message+':<select class="depth" name="'+formName+'[depth]['+itemIndex+']">'+self.getDepthOptions(item.depth)+'</select>
\

'+metadata.target_message+':<input class="target" type="text" name="'+formName+'[target]['+itemIndex+']" />
 \

 \

 \

 \

'
        );

      $li.find('div.extended').hide().end()
        .find('input.text').val(item.text).end()
        .find('input.link').val(item.link).end()
        .find('input.secure').attr('checked', item.secure).end()
        .find('input.nofollow').attr('checked', item.nofollow).end()
        .find('input.target').val(item.target);

      $items.append($li);
      itemIndex++;

      var $itemText = $li.find('a.item_text');

      $itemText.click(function()
      {
        if (!$li.hasClass('dm_dragging'))
        {
          $li.find('ul.item_form').toggle(200);
        }
      })
      .end()
      .find('a.extend').click(function() {
         var extended = $('.extended', $(this).parent());
         $(this).text(extended.is(":hidden") ? metadata.extended_hide_message:metadata.extended_show_message);
         extended.toggle();
       })
      .end()
      .find('a.remove').click(function() {
        if (confirm($(this).text()+' ?'))
        {
          $li.remove();
        }
      })
      .end()
      .find('input.text').bind('keyup', function() {
        $itemText.text($(this).val());
      })
      .end()
      .find('input.link').bind('keyup', function() {
        $li.find('li.for_depth')[$(this).val().substr(0, 5) == 'page:' ? 'show' : 'hide']();
      }).trigger('keyup');

      self.dmFrontForm('linkDroppable');

      if ($items.hasClass('ui-sortable'))
      {
        $items.sortable('refresh');
      }
    };

    $.each($items.metadata().items, function() {
      createItemElement(this);
    });

    $items.droppable({
      accept:       '#dm_page_bar li > a',
      activeClass:  'droppable_active',
      hoverClass:   'droppable_hover',
      tolerance:    'touch',
      drop:         function(event, ui)
      {
        createItemElement({
          link: 'page:'+ui.draggable.attr('data-page-id'),
          text: ui.draggable.text()
        });

        $items.attr('scrollTop', 999999);
      }
    }).sortable({
      opacity:                0.5,
      distance:               5,
      revert:                 false,
      scroll:                 true,
      tolerance:              'pointer',
      start:                  function(e, ui) {
        ui.item.addClass('dm_dragging');
      },
      stop:                   function(e, ui) {
        setTimeout(function() {
          ui.item.removeClass('dm_dragging');
        }, 200);
        $(this).trigger('resort');
      }
    });

    $form.find('a.external_link').click(function() {
      createItemElement({
        link: '',
        text: '',
        target: ''
      });

      $items.attr('scrollTop', 999999).find('li.item_element:last a.item_text').trigger('click');
    });
  },

  // show/hide for_depth

  getDepthOptions: function(value)
  {
    value = value || 0;
    html = '';
    for(i=0; i<10; i++)
    {
      text = 0 == i ? '-' : i;
      html += (value == i
        ? '<option value="'+i+'" selected="selected">'+text+'</option>'
        : '<option value="'+i+'">'+text+'</option>');
    }
    return html;
  }
});
<commit_msg>remove debug output<commit_after>$.fn.extend({

  dmWidgetNavigationMenuForm: function(widget)
  {
    var self = this,

    formName = self.metadata().form_name,

    $form = self.find('form:first'),

    $tabs = $form.find('div.dm_tabbed_form').dmCoreTabForm(),

    $items = $form.find('.items_list'),
    itemIndex = 0,

    metadata = $items.metadata(),

    createItemElement = function(item)
    {
      item = $.extend({
        position: 0,
        link: '',
        text: '',
        secure: false,
        nofollow: false,
        target: ''
      }, item);

      var $li = $('
')
      .html('\
'+item.text+' \

 \

'+metadata.text_message+':<input class="text" type="text" name="'+formName+'[text]['+itemIndex+']" />
 \

'+metadata.link_message+':<input class="link" type="text" name="'+formName+'[link]['+itemIndex+']" />
 \

 \
'+metadata.delete_message+' \
'+metadata.extended_show_message+' \

 \

 \

'+metadata.secure_message+':<input class="secure" type="checkbox" name="'+formName+'[secure]['+itemIndex+']" value="1" />
 \

'+metadata.nofollow_message+':<input class="nofollow" type="checkbox" name="'+formName+'[nofollow]['+itemIndex+']" value="1" />
 \

'+metadata.depth_message+':<select class="depth" name="'+formName+'[depth]['+itemIndex+']">'+self.getDepthOptions(item.depth)+'</select>
\

'+metadata.target_message+':<input class="target" type="text" name="'+formName+'[target]['+itemIndex+']" />
 \

 \

 \

 \

'
        );

      $li.find('div.extended').hide().end()
        .find('input.text').val(item.text).end()
        .find('input.link').val(item.link).end()
        .find('input.secure').attr('checked', item.secure).end()
        .find('input.nofollow').attr('checked', item.nofollow).end()
        .find('input.target').val(item.target);

      $items.append($li);
      itemIndex++;

      var $itemText = $li.find('a.item_text');

      $itemText.click(function()
      {
        if (!$li.hasClass('dm_dragging'))
        {
          $li.find('ul.item_form').toggle(200);
        }
      })
      .end()
      .find('a.extend').click(function() {
         var extended = $('.extended', $(this).parent());
         $(this).text(extended.is(":hidden") ? metadata.extended_hide_message:metadata.extended_show_message);
         extended.toggle();
       })
      .end()
      .find('a.remove').click(function() {
        if (confirm($(this).text()+' ?'))
        {
          $li.remove();
        }
      })
      .end()
      .find('input.text').bind('keyup', function() {
        $itemText.text($(this).val());
      })
      .end()
      .find('input.link').bind('keyup', function() {
        $li.find('li.for_depth')[$(this).val().substr(0, 5) == 'page:' ? 'show' : 'hide']();
      }).trigger('keyup');

      self.dmFrontForm('linkDroppable');

      if ($items.hasClass('ui-sortable'))
      {
        $items.sortable('refresh');
      }
    };

    $.each($items.metadata().items, function() {
      createItemElement(this);
    });

    $items.droppable({
      accept:       '#dm_page_bar li > a',
      activeClass:  'droppable_active',
      hoverClass:   'droppable_hover',
      tolerance:    'touch',
      drop:         function(event, ui)
      {
        createItemElement({
          link: 'page:'+ui.draggable.attr('data-page-id'),
          text: ui.draggable.text()
        });

        $items.attr('scrollTop', 999999);
      }
    }).sortable({
      opacity:                0.5,
      distance:               5,
      revert:                 false,
      scroll:                 true,
      tolerance:              'pointer',
      start:                  function(e, ui) {
        ui.item.addClass('dm_dragging');
      },
      stop:                   function(e, ui) {
        setTimeout(function() {
          ui.item.removeClass('dm_dragging');
        }, 200);
        $(this).trigger('resort');
      }
    });

    $form.find('a.external_link').click(function() {
      createItemElement({
        link: '',
        text: '',
        target: ''
      });

      $items.attr('scrollTop', 999999).find('li.item_element:last a.item_text').trigger('click');
    });
  },

  // show/hide for_depth

  getDepthOptions: function(value)
  {
    value = value || 0;
    html = '';
    for(i=0; i<10; i++)
    {
      text = 0 == i ? '-' : i;
      html += (value == i
        ? '<option value="'+i+'" selected="selected">'+text+'</option>'
        : '<option value="'+i+'">'+text+'</option>');
    }
    return html;
  }
});
<|endoftext|>


<commit_before>/**
 * Created by Zsolt on 5/16/2014.
 *
 * http://localhost:8888/rest/external/executor/
 * http://localhost:8888/rest/external/executor/create/[validhash]
 *
 */

define(['logManager',
    'blob/BlobRunPluginClient',
    'blob/BlobFSBackend',
    'blob/BlobMetadata',
    'fs',
    'path',
    'unzip',
    'child_process'], function(logManager, BlobRunPluginClient, BlobFSBackend, BlobMetadata, fs, path, unzip, child_process) {

    var walk = function(dir, done) {
        var results = [];
        fs.readdir(dir, function(err, list) {
            if (err) return done(err);
            var i = 0;
            (function next() {
                var file = list[i++];
                if (!file) return done(null, results);
                file = dir + '/' + file;
                fs.stat(file, function(err, stat) {
                    if (stat && stat.isDirectory()) {
                        walk(file, function(err, res) {
                            results = results.concat(res);
                            next();
                        });
                    } else {
                        results.push(file);
                        next();
                    }
                });
            })();
        });
    };

    var deleteFolderRecursive = function(path) {
        if( fs.existsSync(path) ) {
            fs.readdirSync(path).forEach(function(file,index){
                var curPath = path + "/" + file;
                if(fs.lstatSync(curPath).isDirectory()) { // recurse
                    deleteFolderRecursive(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    };

    //here you can define global variables for your middleware
    var logger = logManager.create('REST-External-Executor'); //how to define your own logger which will use the global settings

    var executorBackend = null;

    var ExecutorBackend = function (parameters) {
        this.jobList = {};

        // FIXME: should we use HTTP here?
        var blobBackend = new BlobFSBackend();
        this.blobClient = new BlobRunPluginClient(blobBackend);

        this.sourceFilename = 'source.zip';
        this.resultFilename = 'execution_results';
        this.executorConfigFilename = 'executor_config.json';

        this.workingDirectory = 'executor-temp';

        if (!fs.existsSync(this.workingDirectory)) {
            fs.mkdirSync(this.workingDirectory);
        }
    };

    ExecutorBackend.prototype.startJob = function (jobInfo) {
        // FIXME: This is the server side implementation of a dumb executor.

        var self = this;

        // TODO: create job
        // TODO: what if job is already running?

        this.jobList[jobInfo.hash] = jobInfo;

        // get metadata for hash
        self.blobClient.getMetadata(jobInfo.hash, function (err, metadata) {
            if (err) {
                logger.error(err);
                jobInfo.status = 'FAILED_TO_GET_SOURCE';
                return;
            }

            if (metadata.contentType !== BlobMetadata.CONTENT_TYPES.COMPLEX) {
                jobInfo.status = 'FAILED_SOURCE_IS_NOT_COMPLEX';
                return;
            }

//            if (metadata.content.hasOwnProperty(self.executorConfigFilename)) {
//
//            } else {
//                jobInfo.status = 'FAILED_EXECUTOR_CONFIG_DOES_NOT_EXIST';
//                return;
//            }

            // download artifacts
            self.blobClient.getObject(jobInfo.hash, function (err, content) {
                if (err) {
                    // TODO: handle errors
                    return;
                }

                var jobDir = path.normalize(path.join(self.workingDirectory, jobInfo.hash));

                if (!fs.existsSync(jobDir)) {
                    fs.mkdirSync(jobDir);
                }

                var zipPath = path.join(jobDir, self.sourceFilename);

                fs.writeFile(zipPath, content, function (err) {
                    // TODO: handle errors

                    // unzip downloaded file

                    var extract = unzip.Extract({ path: jobDir });
                    fs.createReadStream(zipPath).pipe(extract);

                    extract.on('close', function(err) {
                        if (err) {
                            logger.error(err);
                            jobInfo.status = 'FAILED_UNZIP';
                            return;
                        }

                        // delete downloaded file
                        fs.unlinkSync(zipPath);

                        // TODO: start job
                        var exec = child_process.exec;

                        jobInfo.startTime = new Date().toISOString();

                        // get cmd file dynamically from the this.executorConfigFilename file
                        fs.readFile(path.join(jobDir, self.executorConfigFilename), 'utf8', function (err, data) {
                            if (err) {
                                logger.error(err);
                                jobInfo.status = 'FAILED_EXECUTOR_CONFIG';
                                //return;
                            }

//                            var executorConfig = JSON.parse(data);
                            var cmd = 'run_jmodelica_model_exchange.cmd'; //executorConfig.cmd;

                            logger.debug('working directory: ' + jobDir + ' executing: ' + cmd);

                            var child = exec(cmd, {cwd: jobDir},
                                function (error, stdout, stderr) {

                                    jobInfo.finishTime = new Date().toISOString();

                                    logger.debug('stdout: ' + stdout);

                                    if (stderr) {
                                        logger.error('stderr: ' + stderr);
                                    }

                                    if (error !== null) {
                                        logger.error('exec error: ' + error);
                                        jobInfo.status = 'FAILED';
                                    } else {
                                        jobInfo.status = 'SUCCESS';
                                    }

                                    // TODO: save stderr and stdout to files.

                                    self.saveJobResults(jobInfo, jobDir);
                                });
                        });
                    });
                });
            });
        });
    };

    ExecutorBackend.prototype.saveJobResults = function (jobInfo, directory) {
        // TODO: list all files and subdirectories

        var self = this;

        var resultArtifact = self.blobClient.createArtifact(self.resultFilename);

        walk(directory, function (err, results) {
            var i,
                remaining = results.length;

            for (i = 0; i < results.length; i++) {
                resultArtifact.addFile(path.relative(directory, results[i]).replace(/\\/g,'/'), fs.createReadStream(results[i]), function(err, hash) {
                    remaining -= 1;

                    if (err) {
                        logger.error('Failed to add to blob ' + results[i]);
                        logger.error(err);
                    } else {

                    }

                    if (remaining === 0) {
                        resultArtifact.save(function(err, resultHash) {
                            if (err) {
                                logger.error(err);
                                jobInfo.status = 'FAILED_TO_SAVE_ARTIFACT';
                                return;
                            } else {
                                // FIXME: This is synchronous
                                deleteFolderRecursive(directory);
                            }

                            jobInfo.resultHash = resultHash;
                        });
                    }

                });
            }
        });

        // TODO: create a result artifact

        // TODO: delete directory

    };

    ExecutorBackend.prototype.cancelJob = function () {

    };

    // this should be in a database
    var jobList = {};

    var JobInfo = function (parameters) {
        this.hash = parameters.hash;
        this.resultHash = null;
        this.userId = [];
        this.status = 'CREATED'; // TODO: define a constant for this
        this.startTime = null;
        this.finishTime = null;
    };

    var ExecutorREST = function(req,res,next){
        //global config is accessible via webGMEGlobal.getConfig()
        var config = webGMEGlobal.getConfig();
        logger.debug('Executor request');

        var url = req.url.split('/');

        if (url.length === 2) {
            //next should be always called / the response should be sent otherwise this thread will stop without and end

            // TODO: send status
            res.send(jobList);
        } else {

            switch (url[1]) {
                case "create":
                    ExecutorRESTCreate(req, res, next);
                    break;
                case "cancel":
                    ExecutorRESTCancel(req, res, next);
                    break;
                case "info":
                    ExecutorRESTInfo(req, res, next);
                    break;
                default:
                    res.send(500);
            }

        }

    };

    var ExecutorRESTCreate = function(req, res, next) {
        // TODO: accept only POST

        var url = req.url.split('/');

        if (url.length < 3 || !url[2]) {
            res.send(500);
        }

        var hash = url[2];
        var jobInfo = new JobInfo({hash:hash});

        // TODO: check if hash ok
        jobList[hash] = jobInfo;

        // TODO: get job description

        // TODO: schedule job

        if (!executorBackend) {
            executorBackend = new ExecutorBackend();
        }

        executorBackend.startJob(jobInfo);

        res.send(jobInfo);
    };

    var ExecutorRESTCancel = function(req, res, next) {
        // TODO: accept only POST
        var url = req.url.split('/');

        if (url.length < 3 || !url[2]) {
            res.send(500);
        }

        var hash = url[2];

        if (!executorBackend) {
            res.send(500);
        } else {

            executorBackend.cancelJob(hash);

            res.send(200);
        }
    };

    var ExecutorRESTInfo = function(req, res, next) {
        // TODO: accept only GET

        var url = req.url.split('/');

        if (url.length < 3 || !url[2]) {
            res.send(500);
        }

        var hash = url[2];

        if (jobList.hasOwnProperty(hash)) {
            res.send(jobList[hash]);
        } else {
            res.send(500);
        }
    };

    var setup = function() { //it has to be done this way, but this is probably a placeholder for later option parameters...
        return ExecutorREST;
    };
    return setup();
});<commit_msg>Send the full job list (info) if no hash defined.<commit_after>/**
 * Created by Zsolt on 5/16/2014.
 *
 * http://localhost:8888/rest/external/executor/
 * http://localhost:8888/rest/external/executor/create/[validhash]
 *
 * THIS IS A THROW AWAY CODE AND IMPLEMENTATION.
 *
 * TEMPORARY CODE AND IMPLEMENTATION.
 *
 */

define(['logManager',
    'blob/BlobRunPluginClient',
    'blob/BlobFSBackend',
    'blob/BlobMetadata',
    'fs',
    'path',
    'unzip',
    'child_process'], function(logManager, BlobRunPluginClient, BlobFSBackend, BlobMetadata, fs, path, unzip, child_process) {

    var walk = function(dir, done) {
        var results = [];
        fs.readdir(dir, function(err, list) {
            if (err) return done(err);
            var i = 0;
            (function next() {
                var file = list[i++];
                if (!file) return done(null, results);
                file = dir + '/' + file;
                fs.stat(file, function(err, stat) {
                    if (stat && stat.isDirectory()) {
                        walk(file, function(err, res) {
                            results = results.concat(res);
                            next();
                        });
                    } else {
                        results.push(file);
                        next();
                    }
                });
            })();
        });
    };

    var deleteFolderRecursive = function(path) {
        if( fs.existsSync(path) ) {
            fs.readdirSync(path).forEach(function(file,index){
                var curPath = path + "/" + file;
                if(fs.lstatSync(curPath).isDirectory()) { // recurse
                    deleteFolderRecursive(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    };

    //here you can define global variables for your middleware
    var logger = logManager.create('REST-External-Executor'); //how to define your own logger which will use the global settings

    var executorBackend = null;

    var ExecutorBackend = function (parameters) {
        this.jobList = {};

        // FIXME: should we use HTTP here?
        var blobBackend = new BlobFSBackend();
        this.blobClient = new BlobRunPluginClient(blobBackend);

        this.sourceFilename = 'source.zip';
        this.resultFilename = 'execution_results';
        this.executorConfigFilename = 'executor_config.json';

        this.workingDirectory = 'executor-temp';

        if (!fs.existsSync(this.workingDirectory)) {
            fs.mkdirSync(this.workingDirectory);
        }
    };

    ExecutorBackend.prototype.startJob = function (jobInfo) {
        // FIXME: This is the server side implementation of a dumb executor.

        var self = this;

        // TODO: create job
        // TODO: what if job is already running?

        this.jobList[jobInfo.hash] = jobInfo;

        // get metadata for hash
        self.blobClient.getMetadata(jobInfo.hash, function (err, metadata) {
            if (err) {
                logger.error(err);
                jobInfo.status = 'FAILED_TO_GET_SOURCE';
                return;
            }

            if (metadata.contentType !== BlobMetadata.CONTENT_TYPES.COMPLEX) {
                jobInfo.status = 'FAILED_SOURCE_IS_NOT_COMPLEX';
                return;
            }

//            if (metadata.content.hasOwnProperty(self.executorConfigFilename)) {
//
//            } else {
//                jobInfo.status = 'FAILED_EXECUTOR_CONFIG_DOES_NOT_EXIST';
//                return;
//            }

            // download artifacts
            self.blobClient.getObject(jobInfo.hash, function (err, content) {
                if (err) {
                    // TODO: handle errors
                    return;
                }

                var jobDir = path.normalize(path.join(self.workingDirectory, jobInfo.hash));

                if (!fs.existsSync(jobDir)) {
                    fs.mkdirSync(jobDir);
                }

                var zipPath = path.join(jobDir, self.sourceFilename);

                fs.writeFile(zipPath, content, function (err) {
                    // TODO: handle errors

                    // unzip downloaded file

                    var extract = unzip.Extract({ path: jobDir });
                    fs.createReadStream(zipPath).pipe(extract);

                    extract.on('close', function(err) {
                        if (err) {
                            logger.error(err);
                            jobInfo.status = 'FAILED_UNZIP';
                            return;
                        }

                        // delete downloaded file
                        fs.unlinkSync(zipPath);

                        // TODO: start job
                        var exec = child_process.exec;

                        jobInfo.startTime = new Date().toISOString();

                        // get cmd file dynamically from the this.executorConfigFilename file
                        fs.readFile(path.join(jobDir, self.executorConfigFilename), 'utf8', function (err, data) {
                            if (err) {
                                logger.error(err);
                                jobInfo.status = 'FAILED_EXECUTOR_CONFIG';
                                //return;
                            }

//                            var executorConfig = JSON.parse(data);
                            var cmd = 'run_jmodelica_model_exchange.cmd'; //executorConfig.cmd;

                            logger.debug('working directory: ' + jobDir + ' executing: ' + cmd);

                            var child = exec(cmd, {cwd: jobDir},
                                function (error, stdout, stderr) {

                                    jobInfo.finishTime = new Date().toISOString();

                                    logger.debug('stdout: ' + stdout);

                                    if (stderr) {
                                        logger.error('stderr: ' + stderr);
                                    }

                                    if (error !== null) {
                                        logger.error('exec error: ' + error);
                                        jobInfo.status = 'FAILED';
                                    } else {
                                        jobInfo.status = 'SUCCESS';
                                    }

                                    // TODO: save stderr and stdout to files.

                                    self.saveJobResults(jobInfo, jobDir);
                                });
                        });
                    });
                });
            });
        });
    };

    ExecutorBackend.prototype.saveJobResults = function (jobInfo, directory) {
        // TODO: list all files and subdirectories

        var self = this;

        var resultArtifact = self.blobClient.createArtifact(self.resultFilename);

        walk(directory, function (err, results) {
            var i,
                remaining = results.length;

            for (i = 0; i < results.length; i++) {
                resultArtifact.addFile(path.relative(directory, results[i]).replace(/\\/g,'/'), fs.createReadStream(results[i]), function(err, hash) {
                    remaining -= 1;

                    if (err) {
                        logger.error('Failed to add to blob ' + results[i]);
                        logger.error(err);
                    } else {

                    }

                    if (remaining === 0) {
                        resultArtifact.save(function(err, resultHash) {
                            if (err) {
                                logger.error(err);
                                jobInfo.status = 'FAILED_TO_SAVE_ARTIFACT';
                                return;
                            } else {
                                // FIXME: This is synchronous
                                deleteFolderRecursive(directory);
                            }

                            jobInfo.resultHash = resultHash;
                        });
                    }

                });
            }
        });

        // TODO: create a result artifact

        // TODO: delete directory

    };

    ExecutorBackend.prototype.cancelJob = function () {

    };

    // this should be in a database
    var jobList = {};

    var JobInfo = function (parameters) {
        this.hash = parameters.hash;
        this.resultHash = null;
        this.userId = [];
        this.status = 'CREATED'; // TODO: define a constant for this
        this.startTime = null;
        this.finishTime = null;
    };

    var ExecutorREST = function(req,res,next){
        //global config is accessible via webGMEGlobal.getConfig()
        var config = webGMEGlobal.getConfig();
        logger.debug('Executor request');

        var url = req.url.split('/');

        if (url.length === 2) {
            //next should be always called / the response should be sent otherwise this thread will stop without and end

            res.send(jobList);

            // TODO: send status
            // FIXME: this path will not be safe
//            res.sendfile(path.join('src', 'rest', 'executor', 'index2.html'), function (err) {
//                if (err) {
//                    logger.error(err);
//                    res.send(500);
//                }
//            });

        } else {

            switch (url[1]) {
                case "create":
                    ExecutorRESTCreate(req, res, next);
                    break;
                case "cancel":
                    ExecutorRESTCancel(req, res, next);
                    break;
                case "info":
                    ExecutorRESTInfo(req, res, next);
                    break;
                default:
                    res.send(500);
            }

        }

    };

    var ExecutorRESTCreate = function(req, res, next) {
        // TODO: accept only POST

        var url = req.url.split('/');

        if (url.length < 3 || !url[2]) {
            res.send(500);
        }

        var hash = url[2];
        var jobInfo = new JobInfo({hash:hash});

        // TODO: check if hash ok
        jobList[hash] = jobInfo;

        // TODO: get job description

        // TODO: schedule job

        if (!executorBackend) {
            executorBackend = new ExecutorBackend();
        }

        executorBackend.startJob(jobInfo);

        res.send(jobInfo);
    };

    var ExecutorRESTCancel = function(req, res, next) {
        // TODO: accept only POST
        var url = req.url.split('/');

        if (url.length < 3 || !url[2]) {
            res.send(500);
        }

        var hash = url[2];

        if (!executorBackend) {
            res.send(500);
        } else {

            executorBackend.cancelJob(hash);

            res.send(200);
        }
    };

    var ExecutorRESTInfo = function(req, res, next) {
        // TODO: accept only GET

        var url = req.url.split('/');

        if (url.length < 3 || !url[2]) {
            res.send(500);
        }

        var hash = url[2];

        if (hash) {
            if (jobList.hasOwnProperty(hash)) {
                res.send(jobList[hash]);
            } else {
                res.send(500);
            }
        } else {
            res.send(jobList);
        }
    };

    var setup = function() { //it has to be done this way, but this is probably a placeholder for later option parameters...
        return ExecutorREST;
    };
    return setup();
});<|endoftext|>


<commit_before>/**
 * A table view row that can add an arbitrary number of data entry rows
 *
 * @package   Swat
 * @copyright 2004-2007 silverorange
 * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
 */

/**
 * A table view row that can add an arbitrary number of data entry rows
 *
 * @param String id the identifier of this row.
 * @param String row_string the XML string to use when inserting a new row. The
 *                           XML string can contain '%s' placeholders. Before
 *                           a new row is added, the placeholders are replaced
 *                           with the new row index.
 */
function SwatTableViewInputRow(id, row_string)
{
	this.id = id;

	// decode string
	row_string = row_string.replace(/</g, '<').replace(/>/g, '>');
	row_string = row_string.replace(/"/g, '"').replace(/&/g, '&');

	/*
	 * Pack row string in an XHTML document
	 *
	 * We purposly do not specify a DTD here as Internet Explorer is too slow
	 * when given a DTD. The XML string is encoded in UTF-8 with no special
	 * entities at this point.
	 */
	this.row_string = "<?xml version='1.0' encoding='UTF-8'?>\n" +
		'' +
		'<title>row</title>
' +
		row_string +
		'
';

	this.enter_row = document.getElementById(this.id + '_enter_row');

	// get table node belonging to the enter row
	this.table = this.enter_row;
	while (this.table.nodeName.toLowerCase() != 'table')
		this.table = this.table.parentNode;

	this.replicators = null;
	this.replicators_input = null;
}

/**
 * Check if the browser is Safari
 *
 * Safari's DOM importNode() method is broken so we use the IE table object
 * model hack for it as well.
 *
 * @var boolean
 */
SwatTableViewInputRow.is_webkit =
	(/AppleWebKit|Konqueror|KHTML/gi).test(navigator.userAgent);

/**
 * Gets an XML parser with a loadXML() method
 */
function SwatTableViewInputRow_getXMLParser()
{
	var parser = null;
	var is_ie = true;

	try {
		var dom = new ActiveXObject('Msxml2.XMLDOM');
	} catch (err1) {
		try {
			var dom = new ActiveXObject('Microsoft.XMLDOM');
		} catch (err2) {
			is_ie = false;
		}
	}

	if (is_ie) {
		/*
		 * Internet Explorer's XMLDOM object has a proprietary loadXML()
		 * method. Our method returns the document.
		 */
		parser = function() {}
		parser.loadXML = function(document_string)
		{
			if (!dom.loadXML(document_string))
				alert(dom.parseError.reason);

			return dom;
		}
	}

	if (parser === null && typeof DOMParser != 'undefined') {
		/*
		 * Mozilla, Safari and Opera have a proprietary DOMParser()
		 * class.
		 */
		dom_parser = new DOMParser();

		// Cannot add loadXML method to a newly created DOMParser because it
		// crashes Safari
		parser = function() {}
		parser.loadXML = function(document_string)
		{
			return dom_parser.parseFromString(document_string, 'text/xml');
		}
	}

	return parser;
}

/**
 * The XML parser used by this widget
 *
 * @var Object
 */
SwatTableViewInputRow.parser = SwatTableViewInputRow_getXMLParser();

/*
 * If the browser does not support the importNode() method then we need to
 * manually copy nodes from one document to the current document. These methods
 * parse a HTMLTableRowNode in one document into a table row in this document.
 */
if (!document.importNode || SwatTableViewInputRow.is_webkit) {

	/**
	 * Parses a table row from one document into another
	 *
	 * Internet Explorer does not allow writing to the innerHTML property for
	 * table row nodes so the table cells are individually inserted and cloned.
	 *
	 * @param HTMLTableRowNode source_tr the table row from the source document.
	 * @param HTMLTableRowNode dest_tr the table row in the destination
	 *                                  document.
	 */
	function SwatTableViewInputRow_parseTableRow(source_tr, dest_tr)
	{
		var child_node;
		var dest_td;
		var source_attributes;
		for (var i = 0; i < source_tr.childNodes.length; i++) {
			child_node = source_tr.childNodes[i];
			if (child_node.nodeType == 1 && child_node.nodeName == 'td') {
				dest_td = dest_tr.insertCell(-1);
				source_attributes = child_node.attributes;
				for (var j = 0; j < source_attributes.length; j++) {
					if (source_attributes[j].name == 'class') {
						dest_td.className = source_attributes[j].value;
					} else {
						dest_td.setAttribute(source_attributes[j].name,
							source_attributes[j].value);
					}
				}
				SwatTableViewInputRow_parseTableCell(child_node, dest_td);
			}
		}
	}

	/**
	 * Parses a table cell from one document into another
	 *
	 * @param HTMLTableRowNode source_td the table cell from the source
	 *                                    document.
	 * @param HTMLTableRowNode dest_td the table cell in the destination
	 *                                  document.
	 */
	function SwatTableViewInputRow_parseTableCell(source_td, dest_td)
	{
		// Internet Explorer does not have an innerHTML property set on
		// imported DOM nodes even if the imported document is XHTML.
		if (source_td.innerHTML)
			dest_td.innerHTML = source_td.innerHTML;
		else
			dest_td.innerHTML = source_td.xml;
	}
}

/**
 * Initializes the replicator array
 *
 * @return boolean true if the replicators were successfully initialized and
 *          false if they were not.
 */
SwatTableViewInputRow.prototype.initReplicators = function()
{
	if (this.replicators === null) {
		this.replicators_input = document.getElementsByName(this.id +
			'_replicators')[0];

		if (this.replicators_input === null)
			return false;

		if (this.replicators_input.value == '')
			this.replicators = [];
		else
			this.replicators = this.replicators_input.value.split(',');
	}
	return true;
}

/**
 * Adds a new data row to the table
 */
SwatTableViewInputRow.prototype.addRow = function()
{
	if (!this.initReplicators())
		return;

	var replicator_id;
	if (this.replicators.length > 0)
		replicator_id = (parseInt(
			this.replicators[this.replicators.length - 1]) + 1).toString();
	else
		replicator_id = '0';

	this.replicators.push(replicator_id);
	this.replicators_input.value = this.replicators.join(',');

	var document_string = this.row_string.replace(/%s/g, replicator_id);
	var dom = SwatTableViewInputRow.parser.loadXML(document_string);
	var source_tr = dom.documentElement.getElementsByTagName('tr')[0];

	if (document.importNode && !SwatTableViewInputRow.is_webkit) {
		var dest_tr = document.importNode(source_tr, true);
		this.enter_row.parentNode.insertBefore(dest_tr, this.enter_row);
	} else {
		/*
		 * Internet Explorer and Safari specific code
		 *
		 * Uses the table object model instead of the DOM. IE does not
		 * implement importNode() and Safari's importNode() implementation is
		 * broken.
		 */
		var dest_tr = this.table.insertRow(this.enter_row.rowIndex);
		SwatTableViewInputRow_parseTableRow(source_tr, dest_tr);
	}

	dest_tr.className = 'swat-table-view-input-row';
	dest_tr.id = this.id + '_row_' + replicator_id;

	var node = dest_tr;
	var dest_color = 'transparent';
	while (dest_color == 'transparent' && node) {
		dest_color = YAHOO.util.Dom.getStyle(node, 'background-color');
		node = node.parentNode;
	}
	if (dest_color == 'transparent') {
		dest_color = '#ffffff';
	}

	var animation = new YAHOO.util.ColorAnim(dest_tr,
		{ backgroundColor: { from: '#fffbc9', to: dest_color } }, 1,
		YAHOO.util.Easing.easeOut);

	animation.animate();

	/*
	 * Run scripts
	 *
	 * A better way to do this might be to remove the script nodes from the
	 * document and then run the scripts. This way we can ensure the scripts
	 * are only run once.
	 */
	var scripts = dom.documentElement.getElementsByTagName('script');
	for (var i = 0; i < scripts.length; i++)
		if (scripts[0].getAttribute('type') == 'text/javascript' &&
			scripts[0].childNodes.length > 0)
				eval(scripts[i].firstChild.nodeValue);
}

/**
 * Removes a data row from the table
 */
SwatTableViewInputRow.prototype.removeRow = function(replicator_id)
{
	if (!this.initReplicators())
		return;

	// remove replicator_id from replicators array
	var replicator_index = -1;
	for (var i = 0; i < this.replicators.length; i++) {
		if (this.replicators[i] == replicator_id) {
			replicator_index = i;
			break;
		}
	}
	if (replicator_index != -1) {
		this.replicators.splice(replicator_index, 1);
		this.replicators_input.value = this.replicators.join(',');
	}

	// remove row from document
	var row_id = this.id + '_row_' + replicator_id;
	var row = document.getElementById(row_id);
	if (row && row.parentNode !== null) {
		var removed_row = row.parentNode.removeChild(row);
		delete removed_row;
	}
}
<commit_msg>Make table-view-input-row work in IE9.<commit_after>/**
 * A table view row that can add an arbitrary number of data entry rows
 *
 * @package   Swat
 * @copyright 2004-2007 silverorange
 * @license   http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
 */

/**
 * A table view row that can add an arbitrary number of data entry rows
 *
 * @param String id the identifier of this row.
 * @param String row_string the XML string to use when inserting a new row. The
 *                           XML string can contain '%s' placeholders. Before
 *                           a new row is added, the placeholders are replaced
 *                           with the new row index.
 */
function SwatTableViewInputRow(id, row_string)
{
	this.id = id;

	// decode string
	row_string = row_string.replace(/</g, '<').replace(/>/g, '>');
	row_string = row_string.replace(/"/g, '"').replace(/&/g, '&');

	/*
	 * Pack row string in an XHTML document
	 *
	 * We purposly do not specify a DTD here as Internet Explorer is too slow
	 * when given a DTD. The XML string is encoded in UTF-8 with no special
	 * entities at this point.
	 */
	this.row_string = "<?xml version='1.0' encoding='UTF-8'?>\n" +
		'' +
		'<title>row</title>
' +
		row_string +
		'
';

	this.enter_row = document.getElementById(this.id + '_enter_row');

	// get table node belonging to the enter row
	this.table = this.enter_row;
	while (this.table.nodeName.toLowerCase() != 'table')
		this.table = this.table.parentNode;

	this.replicators = null;
	this.replicators_input = null;
}

/**
 * Check if the browser is Safari
 *
 * Safari's DOM importNode() method is broken so we use the IE table object
 * model hack for it as well.
 *
 * @var boolean
 */
SwatTableViewInputRow.is_webkit =
	(/AppleWebKit|Konqueror|KHTML/gi).test(navigator.userAgent);

/**
 * Gets an XML parser with a loadXML() method
 */
function SwatTableViewInputRow_getXMLParser()
{
	var parser = null;
	var is_ie = true;

	try {
		var dom = new ActiveXObject('Msxml2.XMLDOM');
	} catch (err1) {
		try {
			var dom = new ActiveXObject('Microsoft.XMLDOM');
		} catch (err2) {
			is_ie = false;
		}
	}

	if (is_ie) {
		/*
		 * Internet Explorer's XMLDOM object has a proprietary loadXML()
		 * method. Our method returns the document.
		 */
		parser = function() {}
		parser.loadXML = function(document_string)
		{
			if (!dom.loadXML(document_string))
				alert(dom.parseError.reason);

			return dom;
		}
	}

	if (parser === null && typeof DOMParser != 'undefined') {
		/*
		 * Mozilla, Safari and Opera have a proprietary DOMParser()
		 * class.
		 */
		dom_parser = new DOMParser();

		// Cannot add loadXML method to a newly created DOMParser because it
		// crashes Safari
		parser = function() {}
		parser.loadXML = function(document_string)
		{
			return dom_parser.parseFromString(document_string, 'text/xml');
		}
	}

	return parser;
}

/**
 * The XML parser used by this widget
 *
 * @var Object
 */
SwatTableViewInputRow.parser = SwatTableViewInputRow_getXMLParser();

/*
 * If the browser does not support the importNode() method then we need to
 * manually copy nodes from one document to the current document. These methods
 * parse a HTMLTableRowNode in one document into a table row in this document.
 */
if (!document.importNode || SwatTableViewInputRow.is_webkit) {

	/**
	 * Parses a table row from one document into another
	 *
	 * Internet Explorer does not allow writing to the innerHTML property for
	 * table row nodes so the table cells are individually inserted and cloned.
	 *
	 * @param HTMLTableRowNode source_tr the table row from the source document.
	 * @param HTMLTableRowNode dest_tr the table row in the destination
	 *                                  document.
	 */
	function SwatTableViewInputRow_parseTableRow(source_tr, dest_tr)
	{
		var child_node;
		var dest_td;
		var source_attributes;
		for (var i = 0; i < source_tr.childNodes.length; i++) {
			child_node = source_tr.childNodes[i];
			if (child_node.nodeType == 1 && child_node.nodeName == 'td') {
				dest_td = dest_tr.insertCell(-1);
				source_attributes = child_node.attributes;
				for (var j = 0; j < source_attributes.length; j++) {
					if (source_attributes[j].name == 'class') {
						dest_td.className = source_attributes[j].value;
					} else {
						dest_td.setAttribute(source_attributes[j].name,
							source_attributes[j].value);
					}
				}
				SwatTableViewInputRow_parseTableCell(child_node, dest_td);
			}
		}
	}

	/**
	 * Parses a table cell from one document into another
	 *
	 * @param HTMLTableRowNode source_td the table cell from the source
	 *                                    document.
	 * @param HTMLTableRowNode dest_td the table cell in the destination
	 *                                  document.
	 */
	function SwatTableViewInputRow_parseTableCell(source_td, dest_td)
	{
		// Internet Explorer does not have an innerHTML property set on
		// imported DOM nodes even if the imported document is XHTML.
		if (source_td.innerHTML)
			dest_td.innerHTML = source_td.innerHTML;
		else
			dest_td.innerHTML = source_td.xml;
	}
}

/**
 * Initializes the replicator array
 *
 * @return boolean true if the replicators were successfully initialized and
 *          false if they were not.
 */
SwatTableViewInputRow.prototype.initReplicators = function()
{
	if (this.replicators === null) {
		this.replicators_input = document.getElementsByName(this.id +
			'_replicators')[0];

		if (this.replicators_input === null)
			return false;

		if (this.replicators_input.value == '')
			this.replicators = [];
		else
			this.replicators = this.replicators_input.value.split(',');
	}
	return true;
}

/**
 * Adds a new data row to the table
 */
SwatTableViewInputRow.prototype.addRow = function()
{
	if (!this.initReplicators())
		return;

	var replicator_id;
	if (this.replicators.length > 0)
		replicator_id = (parseInt(
			this.replicators[this.replicators.length - 1]) + 1).toString();
	else
		replicator_id = '0';

	this.replicators.push(replicator_id);
	this.replicators_input.value = this.replicators.join(',');

	var document_string = this.row_string.replace(/%s/g, replicator_id);
	var dom = SwatTableViewInputRow.parser.loadXML(document_string);
	var source_tr = dom.documentElement.getElementsByTagName('tr')[0];

	if (document.importNode && !SwatTableViewInputRow.is_webkit) {
		try {
			var dest_tr = document.importNode(source_tr, true);
			this.enter_row.parentNode.insertBefore(dest_tr, this.enter_row);
		} catch (ex) {
			/*
			 * IE9 specific code. IE9 claims to support importNode, but fails
			 * when it is called.
			 */
			var dest_tr = this.table.insertRow(this.enter_row.rowIndex);
			SwatTableViewInputRow_parseTableRow(source_tr, dest_tr);
		}
	} else {
		/*
		 * Internet Explorer and Safari specific code
		 *
		 * Uses the table object model instead of the DOM. IE does not
		 * implement importNode() and Safari's importNode() implementation is
		 * broken.
		 */
		var dest_tr = this.table.insertRow(this.enter_row.rowIndex);
		SwatTableViewInputRow_parseTableRow(source_tr, dest_tr);
	}

	dest_tr.className = 'swat-table-view-input-row';
	dest_tr.id = this.id + '_row_' + replicator_id;

	var node = dest_tr;
	var dest_color = 'transparent';
	while (dest_color == 'transparent' && node) {
		dest_color = YAHOO.util.Dom.getStyle(node, 'background-color');
		node = node.parentNode;
	}
	if (dest_color == 'transparent') {
		dest_color = '#ffffff';
	}

	var animation = new YAHOO.util.ColorAnim(dest_tr,
		{ backgroundColor: { from: '#fffbc9', to: dest_color } }, 1,
		YAHOO.util.Easing.easeOut);

	animation.animate();

	/*
	 * Run scripts
	 *
	 * A better way to do this might be to remove the script nodes from the
	 * document and then run the scripts. This way we can ensure the scripts
	 * are only run once.
	 */
	var scripts = dom.documentElement.getElementsByTagName('script');
	for (var i = 0; i < scripts.length; i++)
		if (scripts[0].getAttribute('type') == 'text/javascript' &&
			scripts[0].childNodes.length > 0)
				eval(scripts[i].firstChild.nodeValue);
}

/**
 * Removes a data row from the table
 */
SwatTableViewInputRow.prototype.removeRow = function(replicator_id)
{
	if (!this.initReplicators())
		return;

	// remove replicator_id from replicators array
	var replicator_index = -1;
	for (var i = 0; i < this.replicators.length; i++) {
		if (this.replicators[i] == replicator_id) {
			replicator_index = i;
			break;
		}
	}
	if (replicator_index != -1) {
		this.replicators.splice(replicator_index, 1);
		this.replicators_input.value = this.replicators.join(',');
	}

	// remove row from document
	var row_id = this.id + '_row_' + replicator_id;
	var row = document.getElementById(row_id);
	if (row && row.parentNode !== null) {
		var removed_row = row.parentNode.removeChild(row);
		delete removed_row;
	}
}
<|endoftext|>


<commit_before>var Main;
define(['utils','profile','publicKeys','certificates','server','users','classes','nodes'],
/**
 * @lends MainPage
 */
function(Utils,Profile,PublicKeys,Certificates,Server,Users,Classes,Nodes){

	 /**
	 * The FITeagle main page class contains functions required for initialization of the
	 * main page forms and elements located on the page.
     * @class
     * @constructor
     * @return Main Object
     */
	Main = {};

	/**
	* Initializes change of the icon sign for all of the headers with the class with  the ".collapseHeader" selector after clicking on it.
	* @private
	* @memberOf Main#
	*/
	initCollapseHeaders = function(){
		$('.collapseHeader').click(function(event){
			var header = event.currentTarget;
			var icon = $(header).find("i")[0];
			window.setTimeout(function(){
				switchCollapseSignFor($(icon));
			},100);
		});
	};

	/**
	* Initializes the icon sign replacement within the given container according to the current section state.
	* Icon chevron right from the font awesome icons is shown if the section is collapsed and icon chevron right is section is opened.
 	* @param {Object} icon_object is a container object to change the icon sign after the section is opened or collapsed.
	* @private
	* @memberOf Main#
	*/
	switchCollapseSignFor = function(icon_object){
		var selector = $(icon_object[0].parentNode.parentNode).attr("data-target");
		var isOpen  = $(selector).hasClass('in');
			if(isOpen){
				icon_object.attr('class','');
				icon_object.addClass('collapseSign fa fa-caret-down fa-li');
			}else{
				icon_object.attr('class','');
				icon_object.addClass('collapseSign fa fa-caret-right fa-li');
		}
	};

	/**
	* Defines the behavior for clicking on "back" or "next" browser buttons aka browser history.
	* The function opens the appropriate form views.
	* @private
	* @memberOf Main#
	*/
	initHashtagChange = function(){
		$(window).unbind();
		openDesktopTab(window.location.hash.split("_page")[0], true);
		$(window).on('popstate hashchange',function(){
			var hash = window.location.hash.split("_page")[0];
			openDesktopTab(hash, false);
		});
	};

	/**
	* Triggers functions for main Page initialization such as: screen adjustments by resizing, initialization of user panel, profile form,
	* public keys form, manage certificates form, and showing of the last opened tab.
    * @private
	* @memberOf Main#
	*/
	initMainPage = function(){
		$("#unifiLogo").attr("href",home);
		Classes.init();
		Nodes.init();
		initNavigationTabs();
		Utils.updateUserInfoPanel();
		initSignOutBtn();
		initHashtagChange();
		Profile.initForm();
		PublicKeys.initForm();
		Certificates.initForm();
		initCollapseHeaders();
	};

	initNavigationTabs = function(){
		var navLinks = $(".navigationLink a");
		navLinks.not('#signOut, #tasksToggle').on('click',function(e){
			e.preventDefault();
			var hash = $(this).attr('href');
			openDesktopTab(hash, true);
		});
	};

	var welcome_message = "Manage your personal data, public keys and certificates from the dropdown-menu in the upper right corner.";
	var welcome_message_user = "Manage your personal data, public keys and certificates from the dropdown-menu in the upper right corner. " +
			"Classes, lectures and	virtualized testbeds from each partner university can be reached through the links on the map";

	/**
	* Loads HTML for the FITeagle main page dynamically and triggers the page initialization after the loading is successfully completed.
	* @public
	* @name Main#load
	* @function
	**/
	Main.load = function(){
		$("#mainPage").load("main.html #navigation,#main",
			function(){
				switch(Utils.getCurrentUser().role){
				case "FEDERATION_ADMIN":
					$("#welcome_content").append(welcome_message);
					Users.init();
					initMainPage();
					break;

				case "NODE_ADMIN":
					$("#welcome_content").append(welcome_message);
					Users.init();
					initMainPage();
					break;

				case "CLASSOWNER":
					$("#welcome_content").append(welcome_message);
					initMainPage();
					break;

				default:
					var img = $("<img>").attr("id", "unifiMap").attr("src", "img/map_unifi.png").attr("usemap", "#unifimap");

					var tubAreaClasses = $("<area>").attr("shape", "rect").attr("coords", "374,73,452,94").attr("id", "tubClassesMapLink").attr("href","#classes1");
					var tubAreaLectures = $("<area>").attr("shape", "rect").attr("coords", "374,95,452,118").attr("href","#tublectures").attr("onclick", "return false;");
					var tubAreaTestbeds = $("<area>").attr("shape", "rect").attr("coords", "374,119,452,142").attr("href","#tubtestbeds").attr("onclick", "return false;");

					var uctAreaClasses = $("<area>").attr("shape", "rect").attr("coords", "415,328,492,349").attr("id", "uctClassesMapLink").attr("href","#classes2");
					var uctAreaLectures = $("<area>").attr("shape", "rect").attr("coords", "415,350,492,374").attr("href","#uctlectures").attr("onclick", "return false;");
					var uctAreaTestbeds = $("<area>").attr("shape", "rect").attr("coords", "415,375,492,398").attr("href","#ucttestbeds").attr("onclick", "return false;");
					var map = $("<map>").attr("name", "unifimap").append(tubAreaClasses, tubAreaLectures, tubAreaTestbeds, uctAreaClasses, uctAreaLectures, uctAreaTestbeds);
					$("#welcome_content").append(welcome_message_user, img, map);
					initMainPage();
				}
			}
		);
	};

	var home = "#home";

	openDesktopTab = function(hash, pushToHistory){
		if(hash != null){
			var navLinks = $(".navigationLink li");
			navLinks.removeClass("active");

			var a = $('.navigationLink [href$='+hash+']');
			if(a.length != 0){
				if(pushToHistory){
					history.pushState(hash, "page "+hash, hash+"_page");
				}
				a.tab('show');
				window.scrollTo(0,0);
			}
			else{
				if(pushToHistory){
					history.pushState(home, "page "+home, home+"_page");
				}
				$('[href$='+home+']').tab('show');
				window.scrollTo(0,0);
			}
		}
	};

	/**
     * Defines the behaviour after clicking on the singOut button: Cookie invalidation on the server and singing out of the current user.
	  * @private
	  * @memberOf Main#
    */
	initSignOutBtn = function(){
		$("#signOut").on('click',function(e){
			e.preventDefault();
			Main.signOut();
		});
	};

	/**
	* Signs out the current user. Resets its data in the session storage and loads the login page.
	* @public
	* @name Main#signOut
	* @function
	**/
	Main.signOut = function(){
		Server.invalidateCookie();
		Server.invalidateSession();
		Utils.clearSessionStorage();
		history.pushState('', "page ", "/unifi/");
		require('loginPage').load();
	};

	return Main;

});
<commit_msg>refactoring<commit_after>var Main;
define(['utils','profile','publicKeys','certificates','server','users','classes','nodes'],
/**
 * @lends MainPage
 */
function(Utils,Profile,PublicKeys,Certificates,Server,Users,Classes,Nodes){

	 /**
	 * The FITeagle main page class contains functions required for initialization of the
	 * main page forms and elements located on the page.
     * @class
     * @constructor
     * @return Main Object
     */
	Main = {};

	/**
	* Initializes change of the icon sign for all of the headers with the class with  the ".collapseHeader" selector after clicking on it.
	* @private
	* @memberOf Main#
	*/
	initCollapseHeaders = function(){
		$('.collapseHeader').click(function(event){
			var header = event.currentTarget;
			var icon = $(header).find("i")[0];
			window.setTimeout(function(){
				switchCollapseSignFor($(icon));
			},100);
		});
	};

	/**
	* Initializes the icon sign replacement within the given container according to the current section state.
	* Icon chevron right from the font awesome icons is shown if the section is collapsed and icon chevron right is section is opened.
 	* @param {Object} icon_object is a container object to change the icon sign after the section is opened or collapsed.
	* @private
	* @memberOf Main#
	*/
	switchCollapseSignFor = function(icon_object){
		var selector = $(icon_object[0].parentNode.parentNode).attr("data-target");
		var isOpen  = $(selector).hasClass('in');
			if(isOpen){
				icon_object.attr('class','');
				icon_object.addClass('collapseSign fa fa-caret-down fa-li');
			}else{
				icon_object.attr('class','');
				icon_object.addClass('collapseSign fa fa-caret-right fa-li');
		}
	};

	/**
	* Defines the behavior for clicking on "back" or "next" browser buttons aka browser history.
	* The function opens the appropriate form views.
	* @private
	* @memberOf Main#
	*/
	initHashtagChange = function(){
		$(window).unbind();
		openDesktopTab(window.location.hash.split("_page")[0], true);
		$(window).on('popstate hashchange',function(){
			var hash = window.location.hash.split("_page")[0];
			openDesktopTab(hash, false);
		});
	};

	/**
	* Triggers functions for main Page initialization such as: screen adjustments by resizing, initialization of user panel, profile form,
	* public keys form, manage certificates form, and showing of the last opened tab.
    * @private
	* @memberOf Main#
	*/
	initMainPage = function(){
		$("#welcome_content").append(welcome_message);
		$("#unifiLogo").attr("href",home);
		Users.init();
		Classes.init();
		Nodes.init();
		initNavigationTabs();
		Utils.updateUserInfoPanel();
		initSignOutBtn();
		initHashtagChange();
		Profile.initForm();
		PublicKeys.initForm();
		Certificates.initForm();
		initCollapseHeaders();
	};

	initNavigationTabs = function(){
		var navLinks = $(".navigationLink a");
		navLinks.not('#signOut, #tasksToggle').on('click',function(e){
			e.preventDefault();
			var hash = $(this).attr('href');
			openDesktopTab(hash, true);
		});
	};

	var welcome_message = "Manage your personal data, public keys and certificates from the dropdown-menu in the upper right corner.";
	/**
	* Loads HTML for the FITeagle main page dynamically and triggers the page initialization after the loading is successfully completed.
	* @public
	* @name Main#load
	* @function
	**/
	Main.load = function(){
		$("#mainPage").load("main.html #navigation,#main",
			function(){
				switch(Utils.getCurrentUser().role){
				case "FEDERATION_ADMIN":
					initMainPage();
					break;

				case "NODE_ADMIN":
					initMainPage();
					break;

				case "CLASSOWNER":
					initMainPage();
					break;

				default:
					welcome_message = "Manage your personal data, public keys and certificates from the dropdown-menu in the upper right corner. " +
					"Classes, lectures and	virtualized testbeds from each partner university can be reached through the links on the map";
					initMainPage();
					addMap();
				}
			}
		);
	};

	addMap = function(){
		var img = $("<img>").attr("id", "unifiMap").attr("src", "img/map_unifi.png").attr("usemap", "#unifimap");

		var tubAreaClasses = $("<area>").attr("shape", "rect").attr("coords", "374,73,452,94").attr("id", "tubClassesMapLink").attr("href","#classes1");
		var tubAreaLectures = $("<area>").attr("shape", "rect").attr("coords", "374,95,452,118").attr("href","#tublectures").attr("onclick", "return false;");
		var tubAreaTestbeds = $("<area>").attr("shape", "rect").attr("coords", "374,119,452,142").attr("href","#tubtestbeds").attr("onclick", "return false;");

		var uctAreaClasses = $("<area>").attr("shape", "rect").attr("coords", "415,328,492,349").attr("id", "uctClassesMapLink").attr("href","#classes2");
		var uctAreaLectures = $("<area>").attr("shape", "rect").attr("coords", "415,350,492,374").attr("href","#uctlectures").attr("onclick", "return false;");
		var uctAreaTestbeds = $("<area>").attr("shape", "rect").attr("coords", "415,375,492,398").attr("href","#ucttestbeds").attr("onclick", "return false;");
		var map = $("<map>").attr("name", "unifimap").append(tubAreaClasses, tubAreaLectures, tubAreaTestbeds, uctAreaClasses, uctAreaLectures, uctAreaTestbeds);
		$("#welcome_content").append(img, map);
	}

	var home = "#home";

	openDesktopTab = function(hash, pushToHistory){
		if(hash != null){
			var navLinks = $(".navigationLink li");
			navLinks.removeClass("active");

			var a = $('.navigationLink [href$='+hash+']');
			if(a.length != 0){
				if(pushToHistory){
					history.pushState(hash, "page "+hash, hash+"_page");
				}
				a.tab('show');
				window.scrollTo(0,0);
			}
			else{
				if(pushToHistory){
					history.pushState(home, "page "+home, home+"_page");
				}
				$('[href$='+home+']').tab('show');
				window.scrollTo(0,0);
			}
		}
	};

	/**
     * Defines the behaviour after clicking on the singOut button: Cookie invalidation on the server and singing out of the current user.
	  * @private
	  * @memberOf Main#
    */
	initSignOutBtn = function(){
		$("#signOut").on('click',function(e){
			e.preventDefault();
			Main.signOut();
		});
	};

	/**
	* Signs out the current user. Resets its data in the session storage and loads the login page.
	* @public
	* @name Main#signOut
	* @function
	**/
	Main.signOut = function(){
		Server.invalidateCookie();
		Server.invalidateSession();
		Utils.clearSessionStorage();
		history.pushState('', "page ", "/unifi/");
		require('loginPage').load();
	};

	return Main;

});
<|endoftext|>


<commit_before>/**
 * parsePartialString.js
 * Written by: Connor Taylor
 */
import fumanchu from 'fu-manchu';

/**
 * Given a string, validates that it is a valid partial string and parses it.
 * Passes the string inside of the partial tag through the fumanchu renderer
 * to allow for dynamic setting of the template or the template id.
 */
const parsePartialString = async (partialString, context) => {
  try {
    const renderedString = await fumanchu.render(partialString, context);
    const tokens = renderedString.split(' ').filter((s) => s.trim());
    if (!tokens.length || tokens.length > 2) {
      throw new Error(`Invalid partial string ${partialString}`);
    } else if (tokens.length === 1) {
      if (context.id) {
        tokens.push(context.id);
      } else {
        throw new Error(`${partialString} has no id.
  Either set one explicity or make sure that the partial's rendering context has an id`);
      }
    }

    const [rawId, id] = tokens;
    const templateId = await fumanchu.render(rawId, context);

    return [templateId, id];
  } catch (e) {
    throw new Error(e);
  }
};

export default parsePartialString;
<commit_msg>revert changes to parsePartialString<commit_after>/**
 * parsePartialString.js
 * Written by: Connor Taylor
 */
import fumanchu from 'fu-manchu';

/**
 * Given a string, validates that it is a valid partial string and parses it.
 * Passes the string inside of the partial tag through the fumanchu renderer
 * to allow for dynamic setting of the template or the template id.
 */
const parsePartialString = async (partialString, context) => {
  const renderedString = await fumanchu.render(partialString, context);
  const tokens = renderedString.split(' ').filter((s) => s.trim());
  if (!tokens.length || tokens.length > 2) {
    throw new Error(`Invalid partial string ${partialString}`);
  } else if (tokens.length === 1) {
    if (context.id) {
      tokens.push(context.id);
    } else {
      throw new Error(`${partialString} has no id.
Either set one explicity or make sure that the partial's rendering context has an id`);
    }
  }

  const [rawId, id] = tokens;
  const templateId = await fumanchu.render(rawId, context);

  return [templateId, id];
};

export default parsePartialString;
<|endoftext|>


<commit_before>// A function for modhistory table
<commit_msg>JSDOCS and variables<commit_after>// A function for modhistory table
let table = r.table('ModHistory');
/**
* @param {String} column - What column to update
* @param {String} guild - guild would be the ID of the guild
* @param {String} user - user would be the ID of the user
*/
async function updateModHistory(column, guild, user) {
  try {
      let exists = await table.filter({userID : user}).run()[0];
  } catch (e) {

  }
}
<|endoftext|>