<commit_before>/**
 * Clientside page builder
 * Gets extended by the page builder controllers to provide specific functionality
 * @param {jQuery} canvas
 * @param {Status} status
 */
function PageBuilder(canvas, status){
  this.services = new Services;
  this.deletedPages = [];
  this.pages = {};
  this.pageTypes = [];
  this.elementTypes = [];
  this.paymentTypes = [];
  this.isModified = false;
  this.canvas = canvas;
  this.status = status;
  //make sure we don't have any collisions with new page and element Ids
  this.IdCounter = 0;
  this.controllerPath = '';
  this.currentPage = false;

  //are we editing global pages or application pages
  this.editGlobal = false;
  var pageBuilder = this;
  $(window).bind('beforeunload', function(){
    if(pageBuilder.isModified){
      return 'Are you sure you want to leave?  If you do all of your changes will be lost.';
    }
  });
};

/**
 * Setup the workspace layout
 */
PageBuilder.prototype.setup = function(){
  var pageBuilder = this;
  $.ajax({
    type: 'GET',
    url: this.controllerPath + '/listPageTypes',
    async: false,
    success: function(json){
      pageBuilder.pageTypes = [];
      $(json.data.result).each(function(i){
        pageBuilder.pageTypes.push(this);
      });
    }
  });
  $.ajax({
    type: 'GET',
    url: this.controllerPath + '/listElementTypes',
    async: false,
    success: function(json){
      pageBuilder.elementTypes = [];
      $(json.data.result).each(function(i){
        pageBuilder.elementTypes.push(this);
      });
    }
  });
  $.ajax({
    type: 'GET',
    url: this.controllerPath + '/listPaymentTypes',
    async: false,
    success: function(json){
      pageBuilder.paymentTypes = [];
      $(json.data.result).each(function(i){
        pageBuilder.paymentTypes.push(this);
      });
    }
  });
  var button = $('<button>').html('Save Changes');
  button.button({'disabled': true});
  button.bind('click', function(){
    if(pageBuilder.checkNames()){
      var toSave = [];
      for(var i in pageBuilder.pages){
        if(pageBuilder.pages[i].checkIsModified()){
          toSave.push(pageBuilder.pages[i].getDataObject());
        }
      }
      for(var i = 0; i < pageBuilder.deletedPages.length; i++){
        toSave.push(pageBuilder.deletedPages[i].getDataObject());
      }
      pageBuilder.deletedPages = [];
      for(var i = 0; i < toSave.length; i++){
        $.post(pageBuilder.controllerPath + '/savePage/' + toSave[i].id,{data: $.toJSON(toSave[i])});
      }
      pageBuilder.setup();
    }
    return false;
  });
  $('#save', this.canvas).empty().append(button);
};

/**
 * Create an JazzeePage object
 * Calls itself recursivly for child pages
 * @param {Object} obj
 * @returns {JazzeePage}
 */
PageBuilder.prototype.createPageObject = function(obj){
  var pageBuilder = this;
  var page = new window[obj.typeClass]();
  page.init(obj, pageBuilder);
  $(obj.elements).each(function(i,element){
    var Element = new window[element.typeClass]();
    Element.init(element, page);
    $(element.list).each(function(){
      Element.addListItem(this);
    });
    page.addElement(Element);
  });
  $(obj.variables).each(function(){
    page.variables[this.name] = {name : this.name, value: this.value};
  });
  $(obj.children).each(function(){
    page.addChild(pageBuilder.createPageObject(this));
  });
  page.isModified = false; //reset isModified now that we have added cildren and varialbes
  return page;
};

/**
 * Refresh the pages
 */
PageBuilder.prototype.refreshPages = function(){
  var pageBuilder = this;
  $.get(this.controllerPath + '/listPages',function(json){
    pageBuilder.pages = {};
    $(json.data.result).each(function(i){
      var page = pageBuilder.createPageObject(this);
      pageBuilder.pages[page.id] = page;
    });
    pageBuilder.synchronizePageList();
    var currentPageLi = $('#'+pageBuilder.currentPage);
    if(currentPageLi.length){
      currentPageLi.click();
    } else {
      $('#pages li', this.canvas).first().click();
    }
    pageBuilder.isModified = false;
  });
};

/**
 * Get an ordered list object of all the pages in the list
 * @param integer kind
 * @return {jQuery} ol
 */
PageBuilder.prototype.getPagesList = function(kind){
  var pageBuilder = this;
  var ol = $('<ol>');
  for(var i in this.pages){
    var page = this.pages[i];
    if(page.kind == kind){
      var li = $('<li>');
      li.html(page.title).attr('id', 'page-' + page.id);
      li.data('page', page);
      li.unbind('click');
      li.bind('click', function(e){
        $(this).parent().children('li').removeClass('active');
        $(this).addClass('active');
        $(this).data('page').workspace();
        pageBuilder.currentPage = $(this).attr('id');
      });
      if(page.isGlobal && !this.editGlobal){
        li.addClass('global');
      }
      $(ol).append(li);
    }
  }
  return ol;
};

/**
 * Add a page to the store
 * @param {JazzeePage} page
 */
PageBuilder.prototype.addPage = function(page){
  this.pages[page.id] = page;
  this.synchronizePageList();
  this.markModified();
};

/**
 * Get the unique ID and incirement the counter
 * @returns {Integer}
 */
PageBuilder.prototype.getUniqueId = function(){
  return this.IdCounter++;
};

/**
 * Mark the modified
 */
PageBuilder.prototype.markModified = function(){
  this.isModified = true;
  $('#save button', this.canvas).button( "option", "disabled", false );
};

/**
 * Copy a page
 * @param {Object} obj
 */
PageBuilder.prototype.copyPage = function(obj){
  this.addPage(this.pageFromObject(obj, 'Copy of '+ obj.title, 'copy'));
};

/**
 * Import a page
 * @param {Object} obj
 */
PageBuilder.prototype.importPage = function(obj){
  var error = false;
  for(var i in this.pages){
    var page = this.pages[i];
    if(obj.uuid == page.uuid){
      error = true;
      alert('That page cannot be imported, it has the same UUID as ' + page.title + '.  It should be copied instead.');
    }
  }
  if(!error){
    this.addPage(this.pageFromObject(obj, obj.title, 'import'));
  }
};

/**
 * Import a page
 * @param {Object} obj
 * @param String title
 * @param String status
 * @return {JazzeePage}
 */
PageBuilder.prototype.pageFromObject = function(obj, title, status){
  if(window[obj.typeClass] == undefined){
    alert('Canot create this page becuase ' + obj.typeName + ' is not a recognized page type.');
  }
  var id = 'newpage' + this.getUniqueId();
  obj.id = id;
  obj.title = title;
  var page = new window[obj.typeClass]();
  page.init(obj, this);
  page.status = status;
  page.isModified = true;
  for(var i=0; i<obj.elements.length; i++){
    var e = obj.elements[i];
    e.id = 'newelement' + this.getUniqueId();
    var Element = new window[e.typeClass]();
    Element.init(e, page);
    Element.status = 'new';
    Element.isModified = true;
    for(var j = 0; j < e.list.length; j++){
      var item = Element.newListItem(e.list[j].value);
      item.isActive = e.list[j].isActive;
      item.weight = e.list[j].weight;
      item.name = e.list[j].name;
      item.status = 'new';
    }
    page.addElement(Element);
  }
  for(var property in obj.variables){
    page.setVariable(property, obj.variables[property].value);
  }
  for(var i=0; i<obj.children.length; i++){
    page.addChild(this.pageFromObject(obj.children[i], obj.children[i].title, status));
  }
  return page;
};

/**
 * Delete a page from the store
 * @param {ApplyPage} page
 */
PageBuilder.prototype.deletePage = function(page){
  this.deletedPages.push(page);
  delete this.pages[page.id];
  $('#page-' + page.id).remove();
  this.markModified();
};

/**
 * Get a preview of the page
 * @param {ApplyPage} page
 * @returns {jQuery}
 */
PageBuilder.prototype.getPagePreview = function(page){
  var div = $('<div>');
  $.ajax({
    type: 'POST',
    url: this.controllerPath + '/previewPage',
    data: {data: $.toJSON(page.getDataObject())},
    async: false,
    success: function(html){
      div.html(html);
    }
  });
  return div;
};

/**
 * Get a preview of the page
 * @param {String} type
 * @returns {}
 */
PageBuilder.prototype.getElementType = function(typeName){
  for(var i = 0; i < this.elementTypes.length; i++){
    if(this.elementTypes[i].typeName == typeName ) {
      return this.elementTypes[i];
    }
  }
  return false;
};

/**
 * Test an element to ensure it is a valid name
 * @param {jQuery}
 */
PageBuilder.prototype.addNameTest = function(element){
    $(element).filter_input({
      regex:'[a-zA-Z0-9_]',
      feedback: function(wrongChar) {
        var div = $(this).parent();
        var message = $('<p>').addClass('message').appendTo(div);
        message.html('"' + wrongChar + '" is not allowed.');
        message.delay(1000).fadeOut(2000);
      }
  });
};

/**
 * Complete a special page action
 * @param String pageId
 * @param String actionName
 * @param {} data
 * @return {}
 */
PageBuilder.prototype.specialPageAction = function(pageClass, actionName, data){
  var result = null;
  $.ajax({
    type: 'POST',
    url: this.controllerPath + '/specialPageAction',
    data: {
      data: $.toJSON(data),
      actionName: actionName,
      className: pageClass},
    async: false,
    success: function(json){
      result = json.data.result;
    }
  });
  return result;
};

/**
 * Complete a special element action
 * @param String elementClass
 * @param String actionName
 * @param {} data
 * @return {}
 */
PageBuilder.prototype.specialElementAction = function(elementClass, actionName, data){
  var result = null;
  $.ajax({
    type: 'POST',
    url: this.controllerPath + '/specialElementAction',
    data: {
      data: $.toJSON(data),
      className: elementClass,
      actionName: actionName},
    async: false,
    success: function(json){
      result = json.data.result;
    }
  });
  return result;
};<commit_msg>Prevent duplicate name conflicts in the page builder among pages, elements, and list items.<commit_after>/**
 * Clientside page builder
 * Gets extended by the page builder controllers to provide specific functionality
 * @param {jQuery} canvas
 * @param {Status} status
 */
function PageBuilder(canvas, status){
  this.services = new Services;
  this.deletedPages = [];
  this.pages = {};
  this.pageTypes = [];
  this.elementTypes = [];
  this.paymentTypes = [];
  this.isModified = false;
  this.canvas = canvas;
  this.status = status;
  //make sure we don't have any collisions with new page and element Ids
  this.IdCounter = 0;
  this.controllerPath = '';
  this.currentPage = false;

  //are we editing global pages or application pages
  this.editGlobal = false;
  var pageBuilder = this;
  $(window).bind('beforeunload', function(){
    if(pageBuilder.isModified){
      return 'Are you sure you want to leave?  If you do all of your changes will be lost.';
    }
  });
};

/**
 * Setup the workspace layout
 */
PageBuilder.prototype.setup = function(){
  var pageBuilder = this;
  $.ajax({
    type: 'GET',
    url: this.controllerPath + '/listPageTypes',
    async: false,
    success: function(json){
      pageBuilder.pageTypes = [];
      $(json.data.result).each(function(i){
        pageBuilder.pageTypes.push(this);
      });
    }
  });
  $.ajax({
    type: 'GET',
    url: this.controllerPath + '/listElementTypes',
    async: false,
    success: function(json){
      pageBuilder.elementTypes = [];
      $(json.data.result).each(function(i){
        pageBuilder.elementTypes.push(this);
      });
    }
  });
  $.ajax({
    type: 'GET',
    url: this.controllerPath + '/listPaymentTypes',
    async: false,
    success: function(json){
      pageBuilder.paymentTypes = [];
      $(json.data.result).each(function(i){
        pageBuilder.paymentTypes.push(this);
      });
    }
  });
  var button = $('<button>').html('Save Changes');
  button.button({'disabled': true});
  button.bind('click', function(){
    if(pageBuilder.checkNames()){
      var toSave = [];
      for(var i in pageBuilder.pages){
        if(pageBuilder.pages[i].checkIsModified()){
          toSave.push(pageBuilder.pages[i].getDataObject());
        }
      }
      for(var i = 0; i < pageBuilder.deletedPages.length; i++){
        toSave.push(pageBuilder.deletedPages[i].getDataObject());
      }
      pageBuilder.deletedPages = [];
      for(var i = 0; i < toSave.length; i++){
        $.post(pageBuilder.controllerPath + '/savePage/' + toSave[i].id,{data: $.toJSON(toSave[i])});
      }
      pageBuilder.setup();
    }
    return false;
  });
  $('#save', this.canvas).empty().append(button);
};

/**
 * Create an JazzeePage object
 * Calls itself recursivly for child pages
 * @param {Object} obj
 * @returns {JazzeePage}
 */
PageBuilder.prototype.createPageObject = function(obj){
  var pageBuilder = this;
  var page = new window[obj.typeClass]();
  page.init(obj, pageBuilder);
  $(obj.elements).each(function(i,element){
    var Element = new window[element.typeClass]();
    Element.init(element, page);
    $(element.list).each(function(){
      Element.addListItem(this);
    });
    page.addElement(Element);
  });
  $(obj.variables).each(function(){
    page.variables[this.name] = {name : this.name, value: this.value};
  });
  $(obj.children).each(function(){
    page.addChild(pageBuilder.createPageObject(this));
  });
  page.isModified = false; //reset isModified now that we have added cildren and varialbes
  return page;
};

/**
 * Refresh the pages
 */
PageBuilder.prototype.refreshPages = function(){
  var pageBuilder = this;
  $.get(this.controllerPath + '/listPages',function(json){
    pageBuilder.pages = {};
    $(json.data.result).each(function(i){
      var page = pageBuilder.createPageObject(this);
      pageBuilder.pages[page.id] = page;
    });
    pageBuilder.synchronizePageList();
    var currentPageLi = $('#'+pageBuilder.currentPage);
    if(currentPageLi.length){
      currentPageLi.click();
    } else {
      $('#pages li', this.canvas).first().click();
    }
    pageBuilder.isModified = false;
  });
};

/**
 * Get an ordered list object of all the pages in the list
 * @param integer kind
 * @return {jQuery} ol
 */
PageBuilder.prototype.getPagesList = function(kind){
  var pageBuilder = this;
  var ol = $('<ol>');
  for(var i in this.pages){
    var page = this.pages[i];
    if(page.kind == kind){
      var li = $('<li>');
      li.html(page.title).attr('id', 'page-' + page.id);
      li.data('page', page);
      li.unbind('click');
      li.bind('click', function(e){
        $(this).parent().children('li').removeClass('active');
        $(this).addClass('active');
        $(this).data('page').workspace();
        pageBuilder.currentPage = $(this).attr('id');
      });
      if(page.isGlobal && !this.editGlobal){
        li.addClass('global');
      }
      $(ol).append(li);
    }
  }
  return ol;
};

/**
 * Add a page to the store
 * @param {JazzeePage} page
 */
PageBuilder.prototype.addPage = function(page){
  this.pages[page.id] = page;
  this.synchronizePageList();
  this.markModified();
};

/**
 * Get the unique ID and incirement the counter
 * @returns {Integer}
 */
PageBuilder.prototype.getUniqueId = function(){
  return this.IdCounter++;
};

/**
 * Mark the modified
 */
PageBuilder.prototype.markModified = function(){
  this.isModified = true;
  $('#save button', this.canvas).button( "option", "disabled", false );
};

/**
 * Copy a page
 * @param {Object} obj
 */
PageBuilder.prototype.copyPage = function(obj){
  this.addPage(this.pageFromObject(obj, 'Copy of '+ obj.title, 'copy'));
};

/**
 * Import a page
 * @param {Object} obj
 */
PageBuilder.prototype.importPage = function(obj){
  var error = false;
  for(var i in this.pages){
    var page = this.pages[i];
    if(obj.uuid == page.uuid){
      error = true;
      alert('That page cannot be imported, it has the same UUID as ' + page.title + '.  It should be copied instead.');
    }
  }
  if(!error){
    this.addPage(this.pageFromObject(obj, obj.title, 'import'));
  }
};

/**
 * Import a page
 * @param {Object} obj
 * @param String title
 * @param String status
 * @return {JazzeePage}
 */
PageBuilder.prototype.pageFromObject = function(obj, title, status){
  if(window[obj.typeClass] == undefined){
    alert('Canot create this page becuase ' + obj.typeName + ' is not a recognized page type.');
  }
  var id = 'newpage' + this.getUniqueId();
  obj.id = id;
  obj.title = title;
  var page = new window[obj.typeClass]();
  page.init(obj, this);
  page.status = status;
  page.isModified = true;
  for(var i=0; i<obj.elements.length; i++){
    var e = obj.elements[i];
    e.id = 'newelement' + this.getUniqueId();
    var Element = new window[e.typeClass]();
    Element.init(e, page);
    Element.status = 'new';
    Element.isModified = true;
    for(var j = 0; j < e.list.length; j++){
      var item = Element.newListItem(e.list[j].value);
      item.isActive = e.list[j].isActive;
      item.weight = e.list[j].weight;
      item.name = e.list[j].name;
      item.status = 'new';
    }
    page.addElement(Element);
  }
  for(var property in obj.variables){
    page.setVariable(property, obj.variables[property].value);
  }
  for(var i=0; i<obj.children.length; i++){
    page.addChild(this.pageFromObject(obj.children[i], obj.children[i].title, status));
  }
  return page;
};

/**
 * Delete a page from the store
 * @param {ApplyPage} page
 */
PageBuilder.prototype.deletePage = function(page){
  this.deletedPages.push(page);
  delete this.pages[page.id];
  $('#page-' + page.id).remove();
  this.markModified();
};

/**
 * Get a preview of the page
 * @param {ApplyPage} page
 * @returns {jQuery}
 */
PageBuilder.prototype.getPagePreview = function(page){
  var div = $('<div>');
  $.ajax({
    type: 'POST',
    url: this.controllerPath + '/previewPage',
    data: {data: $.toJSON(page.getDataObject())},
    async: false,
    success: function(html){
      div.html(html);
    }
  });
  return div;
};

/**
 * Get a preview of the page
 * @param {String} type
 * @returns {}
 */
PageBuilder.prototype.getElementType = function(typeName){
  for(var i = 0; i < this.elementTypes.length; i++){
    if(this.elementTypes[i].typeName == typeName ) {
      return this.elementTypes[i];
    }
  }
  return false;
};

/**
 * Test an element to ensure it is a valid name
 * @param {jQuery}
 */
PageBuilder.prototype.addNameTest = function(element){
    $(element).filter_input({
      regex:'[a-zA-Z0-9_]',
      feedback: function(wrongChar) {
        var div = $(this).parent();
        var message = $('<p>').addClass('message').appendTo(div);
        message.html('"' + wrongChar + '" is not allowed.');
        message.delay(1000).fadeOut(2000);
      }
  });
};

/**
 * Check all pages elements and lists to ensure there are no name collisions
 * @return boolean
 */
PageBuilder.prototype.checkNames = function(){
  var pageNames = [];
  var messages = [];
  var conflict = false;
  for(var i in this.pages){
    var page = this.pages[i];

    if(page.name != null){
      if($.inArray(page.name, pageNames) > -1 ){
        conflict = true;
        messages.push('The name "' + page.name + '" is used for more than one page.');
      }
      pageNames.push(page.name);
    }
    var elementNames = [];
    for(var j in page.elements){
      var element = page.elements[j];
      if(element.name != null){
        if($.inArray(element.name, elementNames) > -1 ){
          conflict = true;
          messages.push('The name "' + element.name + '" is used in more than once on the ' + page.title + ' page.');
        }
        elementNames.push(element.name);
      }
      var itemNames = [];
      for(var k in element.listItems){
        var item = element.listItems[k];
        if(item.name != null){
          if($.inArray(item.name, itemNames) > -1 ){
            conflict = true;
            messages.push('The name "' + item.name + '" is used more than once in the ' + element.title + ' element on the ' + page.title + ' page.');
          }
          itemNames.push(item.name);
        }
      }
    }
  }

  if(conflict){
    var unique = [];
    for(var i = 0; i < messages.length; ++i){
      if($.inArray(messages[i], unique) == -1 ){
        unique.push(messages[i]);
        this.status.addMessage('error', 'There was an error saving: ' + messages[i]);
      }
    }
    return false;
  }
  return true;
};

/**
 * Complete a special page action
 * @param String pageId
 * @param String actionName
 * @param {} data
 * @return {}
 */
PageBuilder.prototype.specialPageAction = function(pageClass, actionName, data){
  var result = null;
  $.ajax({
    type: 'POST',
    url: this.controllerPath + '/specialPageAction',
    data: {
      data: $.toJSON(data),
      actionName: actionName,
      className: pageClass},
    async: false,
    success: function(json){
      result = json.data.result;
    }
  });
  return result;
};

/**
 * Complete a special element action
 * @param String elementClass
 * @param String actionName
 * @param {} data
 * @return {}
 */
PageBuilder.prototype.specialElementAction = function(elementClass, actionName, data){
  var result = null;
  $.ajax({
    type: 'POST',
    url: this.controllerPath + '/specialElementAction',
    data: {
      data: $.toJSON(data),
      className: elementClass,
      actionName: actionName},
    async: false,
    success: function(json){
      result = json.data.result;
    }
  });
  return result;
};
<|endoftext|>


<commit_before>
function PPTournamentLoader() {
  this.tournamentTypes = new Array();
}

PPTournamentLoader.prototype.registerTournamentType = function (type) {
  this.tournamentTypes.push(type);
}

PPTournamentLoader.prototype.registerTournamentTypes = function (typeArray) {
  for (var i = 0; i < typeArray.length; i++) {
    this.registerTournamentType(typeArray[i]);
  }
}

PPTournamentLoader.prototype.printTournamentTypes = function () {
  for( var i = 0; i < this.tournamentTypes.length; i++) {
    var tType = this.tournamentTypes[i];
    console.log(tType.typeName());
  }
}

PPTournamentLoader.prototype.getSelectedTournamentType = function () {
  for( var i = 0; i < this.tournamentTypes.length; i ++ ) {
   if ( $("tTypeRadio" + i).checked == true ) {
     return new this.tournamentTypes[i]();
   }
  }
  throw new Error("No tournament type selected");
}

PPTournamentLoader.prototype.process = function(data) {
  var jsonData = JSON.parse(data);
  theApp.setTournament(new PPTennisTournament()); // TODO -- temporary  -- Tournament object type should be stored in file
  theApp.tournament.name = jsonData.name;
  $("tournamentNameTextField").value = theApp.tournament.name; // TODO -- this could be a bound configuration.
  theApp.tournament.loadRoundsFromJSON(jsonData.rounds);

  stateManager.startTournament();   // TODO -- global variable

  //selectMatch(theApp.tournament.getSelectedMatch()); // TODO -- global method.
  theApp.redraw();
}<commit_msg>Fix loading of file<commit_after>
function PPTournamentLoader() {
  this.tournamentTypes = new Array();
}

PPTournamentLoader.prototype.registerTournamentType = function (type) {
  this.tournamentTypes.push(type);
}

PPTournamentLoader.prototype.registerTournamentTypes = function (typeArray) {
  for (var i = 0; i < typeArray.length; i++) {
    this.registerTournamentType(typeArray[i]);
  }
}

PPTournamentLoader.prototype.printTournamentTypes = function () {
  for( var i = 0; i < this.tournamentTypes.length; i++) {
    var tType = this.tournamentTypes[i];
    console.log(tType.typeName());
  }
}

PPTournamentLoader.prototype.getSelectedTournamentType = function () {
  for( var i = 0; i < this.tournamentTypes.length; i ++ ) {
   if ( $("tTypeRadio" + i).checked == true ) {
     return new this.tournamentTypes[i]();
   }
  }
  throw new Error("No tournament type selected");
}

PPTournamentLoader.prototype.process = function(data) {
  var jsonData = JSON.parse(data);

  // reload tournament object
  var tournament = new PPTennisTournament(); // TODO -- temporary  -- Tournament object type should be stored in file
  tournament.name = jsonData.name;
  $("tournamentNameTextField").value = tournament.name; // TODO -- this could be a bound configuration.
  tournament.loadRoundsFromJSON(jsonData.rounds);

  theApp.setTournament(tournament);
  stateManager.startTournament();   // TODO -- global variable

  theApp.redraw();
}<|endoftext|>


<commit_before>var editor = ace.edit("editor");
editor.renderer.setScrollMargin(10, 0, 10, 0);
var modelist = ace.require("ace/ext/modelist");
editor.renderer.setShowGutter(false);
editor.setHighlightActiveLine(false);
editor.getSession().setMode("ace/mode/asciidoc");
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(false);
editor.setBehavioursEnabled(true);
editor.session.setFoldStyle("manual");
editor.setOptions({
    enableSnippets: true,
    dragEnabled: true
});
editor.setScrollSpeed("0.1");
editor.setTheme("ace/theme/xcode");

var lastEditorRow = 0;
var afterFirstChange = false;
var renderTimeout;
var refreshTimeout;
var updateDelay = 100;

//var maxTop = editor.renderer.layerConfig.maxHeight - editor.renderer.$size.scrollerHeight + editor.renderer.scrollMargin.bottom;
//afx.onscroll(editor.getSession().getScrollTop(), maxTop);

function updateHtmlScroll(){
    var row = editor.renderer.getFirstFullyVisibleRow();
    afx.scrollByLine(row + "");
}

function updateMarkupScroll() {

    var row = editor.renderer.getFirstFullyVisibleRow();

    if (lastEditorRow == row)
        return;

    for (var i = 0; i < 10; i++) { // try ten times
        var trimmed = editor.session.getLine(row).trim();
        if ((trimmed == "") || (trimmed.match(/\(\(\(.*?\)\)\)/)) || (trimmed.match(/'''/)) || (trimmed.match(/\[\[.*?\]\]/))) {
            row++;
        }
        else {
            break;
        }
    }

    var range = sketch.searchBlockPosition(row);
    if (range) {

        if (lastEditorRow == range.start.row)
            return;
        lastEditorRow = range.start.row;

        var blockText = editor.session.getTextRange(range);
        afx.scrollByPosition(blockText);
    }
    else {
        lastEditorRow = row;

        var lineText = editor.session.getLine(row);

        if (lineText.trim() == "")
            return;

        afx.scrollByPosition(lineText);
    }
};

editor.getSession().on('changeScrollTop', function (scroll) {

    var maxTop = editor.renderer.layerConfig.maxHeight - editor.renderer.$size.scrollerHeight + editor.renderer.scrollMargin.bottom;
    var scrollTop = editor.getSession().getScrollTop();

    if (Math.abs(maxTop - scrollTop) < 10 || scrollTop < 10) {
        afx.onscroll(scrollTop, maxTop);
        return;
    }

    var mode = editorMode();

    var firstly = editor.getFirstVisibleRow();

    var interval = setInterval(function () {
        if (firstly == editor.getFirstVisibleRow())
            return;
        clearInterval(interval);

        if (mode == "asciidoc" || mode == "markdown") {
            updateMarkupScroll();
        }
        else if (mode == "html") {
            updateHtmlScroll();
        }
    }, 50);
});

var updateStatusAction = new BufferedAction();
function updateStatusBox() {

    updateStatusAction.buff(function () {
        var cursorPosition = editor.getCursorPosition();
        var row = cursorPosition.row;
        var column = cursorPosition.column;

        var lineCount = editor.session.getLength();
        var wordCount = editor.session.getValue().length;

        afx.updateStatusBox(row, column, lineCount, wordCount);
    }, 1000);

}

editor.getSession().selection.on('changeCursor', function (e) {

    var cursorPosition = editor.getCursorPosition();
    var row = cursorPosition.row;

    updateStatusBox();

    if (lastEditorRow == row)
        return;

    var range = sketch.searchBlockPosition(row);
    if (range) {

        if (lastEditorRow == range.start.row)
            return;
        lastEditorRow = range.start.row;

        var blockText = editor.session.getTextRange(range);
        afx.scrollByLine(blockText);
    }
    else {
        lastEditorRow = row;

        var lineText = editor.session.getLine(row);

        if (lineText.trim() == "")
            return;

        afx.scrollByLine(lineText);
    }
});

var constructListAction = new BufferedAction();
var renderAction = new BufferedAction();
var editorChangeListener = function (obj) {

    if (afterFirstChange)
        afx.appendWildcard();

    renderAction.buff(function () {
        afx.textListener(editor.getValue(), editorMode());
    }, 100);

    constructListAction.buff(function () {
        sketch.refreshConstructList();
    }, 1000);
};

function updateOptions() {
    var editorConfigBean = afx.getEditorConfigBean();
    editor.setOptions({
        fontFamily: editorConfigBean.getFontFamily(),
        fontSize: editorConfigBean.getFontSize()
    });
    var themes = editorConfigBean.getEditorTheme();
    if (themes.size() > 0) {
        changeTheme(themes.get(0));
    }

    changeScrollSpeed(editorConfigBean.getScrollSpeed());
    setShowGutter(editorConfigBean.getShowGutter());
    setWrapLimitRange(editorConfigBean.getWrapLimit());
    setUseWrapMode(editorConfigBean.getUseWrapMode());

    editor.focus();
}

function changeTheme(theme) {
    editor.setTheme("ace/theme/" + theme);
}

function changeFontSize(fontSize) {
    editor.setFontSize(fontSize);
}

function changeScrollSpeed(value) {
    editor.setScrollSpeed(value);
}

function setShowGutter(showGutter) {
    editor.renderer.setShowGutter(showGutter);
}

function setUseWrapMode(useWrapMode) {
    editor.getSession().setUseWrapMode(useWrapMode);
}

function setWrapLimitRange(wrapLimitRange) {
    editor.getSession().setWrapLimitRange(wrapLimitRange, wrapLimitRange);
}

function setEditorValue(content) {
    var pos;
    if (afterFirstChange)
        pos = editor.session.selection.toJSON();
    editor.setValue(content, 1);
    editor.session.setScrollTop(-100);
    if (afterFirstChange)
        editor.session.selection.fromJSON(pos);
    editor.focus();
    afterFirstChange = true;
}

var emmetRegex = /^ace\/mode\/(css|less|scss|sass|stylus|html|php|twig|ejs|handlebars)$/;
function switchMode(mode) {
    if (mode) {
        editor.getSession().setMode(mode);
        if (emmetRegex.test(mode)) {
            initializeEmmet(mode);
        }
    }
}

function changeEditorMode(filePath) {
    var mode = modelist.getModeForPath(filePath).mode;
    editor.getSession().setMode(mode);

    if (emmetRegex.test(mode))
        initializeEmmet(mode);

    return mode;
}

function addAnnotation(row, column, text, type) {
    editor.renderer.setShowGutter(true);
    editor.session.setOption("useWorker", false);
    editor.getSession().setAnnotations([{row: row, column: column, text: text, type: type}]);
    editor.scrollToLine(row, false, false, function () {
    });
}

function initializeEmmet(mode) {

    ace.require("ace/ext/emmet");

    ["js/emmet.js", "ace/src/ext-emmet.js"].forEach(function (path, index) {
        var script = document.createElement("script");
        script.src = path;
        document.querySelector("body").appendChild(script);

        if (index == 1) {
            script.onload = function () {
                editor.setOption("enableEmmet", true);
            }
        }
    });

}

var rerenderAction = new BufferedAction();
function rerender() {
    rerenderAction.buff(function () {
        afx.textListener(editor.getValue(), editorMode());
        updateStatusBox();
    }, 100);
}

function editorMode() {
    var mode = editor.session.$modeId;
    return mode.replace("ace/mode/", "");
}

function setInitialized() {
    editor.getSession().on('change', editorChangeListener);
    updateStatusBox();
}<commit_msg>setValue over session for UndoManager empty issue<commit_after>var editor = ace.edit("editor");
editor.renderer.setScrollMargin(10, 0, 10, 0);
var modelist = ace.require("ace/ext/modelist");
editor.renderer.setShowGutter(false);
editor.setHighlightActiveLine(false);
editor.getSession().setMode("ace/mode/asciidoc");
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(false);
editor.setBehavioursEnabled(true);
editor.session.setFoldStyle("manual");
editor.setOptions({
    enableSnippets: true,
    dragEnabled: true
});
editor.setScrollSpeed("0.1");
editor.setTheme("ace/theme/xcode");

var lastEditorRow = 0;
var afterFirstChange = false;
var renderTimeout;
var refreshTimeout;
var updateDelay = 100;

//var maxTop = editor.renderer.layerConfig.maxHeight - editor.renderer.$size.scrollerHeight + editor.renderer.scrollMargin.bottom;
//afx.onscroll(editor.getSession().getScrollTop(), maxTop);

function updateHtmlScroll(){
    var row = editor.renderer.getFirstFullyVisibleRow();
    afx.scrollByLine(row + "");
}

function updateMarkupScroll() {

    var row = editor.renderer.getFirstFullyVisibleRow();

    if (lastEditorRow == row)
        return;

    for (var i = 0; i < 10; i++) { // try ten times
        var trimmed = editor.session.getLine(row).trim();
        if ((trimmed == "") || (trimmed.match(/\(\(\(.*?\)\)\)/)) || (trimmed.match(/'''/)) || (trimmed.match(/\[\[.*?\]\]/))) {
            row++;
        }
        else {
            break;
        }
    }

    var range = sketch.searchBlockPosition(row);
    if (range) {

        if (lastEditorRow == range.start.row)
            return;
        lastEditorRow = range.start.row;

        var blockText = editor.session.getTextRange(range);
        afx.scrollByPosition(blockText);
    }
    else {
        lastEditorRow = row;

        var lineText = editor.session.getLine(row);

        if (lineText.trim() == "")
            return;

        afx.scrollByPosition(lineText);
    }
};

editor.getSession().on('changeScrollTop', function (scroll) {

    var maxTop = editor.renderer.layerConfig.maxHeight - editor.renderer.$size.scrollerHeight + editor.renderer.scrollMargin.bottom;
    var scrollTop = editor.getSession().getScrollTop();

    if (Math.abs(maxTop - scrollTop) < 10 || scrollTop < 10) {
        afx.onscroll(scrollTop, maxTop);
        return;
    }

    var mode = editorMode();

    var firstly = editor.getFirstVisibleRow();

    var interval = setInterval(function () {
        if (firstly == editor.getFirstVisibleRow())
            return;
        clearInterval(interval);

        if (mode == "asciidoc" || mode == "markdown") {
            updateMarkupScroll();
        }
        else if (mode == "html") {
            updateHtmlScroll();
        }
    }, 50);
});

var updateStatusAction = new BufferedAction();
function updateStatusBox() {

    updateStatusAction.buff(function () {
        var cursorPosition = editor.getCursorPosition();
        var row = cursorPosition.row;
        var column = cursorPosition.column;

        var lineCount = editor.session.getLength();
        var wordCount = editor.session.getValue().length;

        afx.updateStatusBox(row, column, lineCount, wordCount);
    }, 1000);

}

editor.getSession().selection.on('changeCursor', function (e) {

    var cursorPosition = editor.getCursorPosition();
    var row = cursorPosition.row;

    updateStatusBox();

    if (lastEditorRow == row)
        return;

    var range = sketch.searchBlockPosition(row);
    if (range) {

        if (lastEditorRow == range.start.row)
            return;
        lastEditorRow = range.start.row;

        var blockText = editor.session.getTextRange(range);
        afx.scrollByLine(blockText);
    }
    else {
        lastEditorRow = row;

        var lineText = editor.session.getLine(row);

        if (lineText.trim() == "")
            return;

        afx.scrollByLine(lineText);
    }
});

var constructListAction = new BufferedAction();
var renderAction = new BufferedAction();
var editorChangeListener = function (obj) {

    if (afterFirstChange)
        afx.appendWildcard();

    renderAction.buff(function () {
        afx.textListener(editor.getValue(), editorMode());
    }, 100);

    constructListAction.buff(function () {
        sketch.refreshConstructList();
    }, 1000);
};

function updateOptions() {
    var editorConfigBean = afx.getEditorConfigBean();
    editor.setOptions({
        fontFamily: editorConfigBean.getFontFamily(),
        fontSize: editorConfigBean.getFontSize()
    });
    var themes = editorConfigBean.getEditorTheme();
    if (themes.size() > 0) {
        changeTheme(themes.get(0));
    }

    changeScrollSpeed(editorConfigBean.getScrollSpeed());
    setShowGutter(editorConfigBean.getShowGutter());
    setWrapLimitRange(editorConfigBean.getWrapLimit());
    setUseWrapMode(editorConfigBean.getUseWrapMode());

    editor.focus();
}

function changeTheme(theme) {
    editor.setTheme("ace/theme/" + theme);
}

function changeFontSize(fontSize) {
    editor.setFontSize(fontSize);
}

function changeScrollSpeed(value) {
    editor.setScrollSpeed(value);
}

function setShowGutter(showGutter) {
    editor.renderer.setShowGutter(showGutter);
}

function setUseWrapMode(useWrapMode) {
    editor.getSession().setUseWrapMode(useWrapMode);
}

function setWrapLimitRange(wrapLimitRange) {
    editor.getSession().setWrapLimitRange(wrapLimitRange, wrapLimitRange);
}

function setEditorValue(content) {
    var pos;
    if (afterFirstChange)
        pos = editor.session.selection.toJSON();
    editor.session.setValue(content, 1);
    editor.session.setScrollTop(-100);
    if (afterFirstChange)
        editor.session.selection.fromJSON(pos);
    editor.focus();
    afterFirstChange = true;
}

var emmetRegex = /^ace\/mode\/(css|less|scss|sass|stylus|html|php|twig|ejs|handlebars)$/;
function switchMode(mode) {
    if (mode) {
        editor.getSession().setMode(mode);
        if (emmetRegex.test(mode)) {
            initializeEmmet(mode);
        }
    }
}

function changeEditorMode(filePath) {
    var mode = modelist.getModeForPath(filePath).mode;
    editor.getSession().setMode(mode);

    if (emmetRegex.test(mode))
        initializeEmmet(mode);

    return mode;
}

function addAnnotation(row, column, text, type) {
    editor.renderer.setShowGutter(true);
    editor.session.setOption("useWorker", false);
    editor.getSession().setAnnotations([{row: row, column: column, text: text, type: type}]);
    editor.scrollToLine(row, false, false, function () {
    });
}

function initializeEmmet(mode) {

    ace.require("ace/ext/emmet");

    ["js/emmet.js", "ace/src/ext-emmet.js"].forEach(function (path, index) {
        var script = document.createElement("script");
        script.src = path;
        document.querySelector("body").appendChild(script);

        if (index == 1) {
            script.onload = function () {
                editor.setOption("enableEmmet", true);
            }
        }
    });

}

var rerenderAction = new BufferedAction();
function rerender() {
    rerenderAction.buff(function () {
        afx.textListener(editor.getValue(), editorMode());
        updateStatusBox();
    }, 100);
}

function editorMode() {
    var mode = editor.session.$modeId;
    return mode.replace("ace/mode/", "");
}

function setInitialized() {
    editor.getSession().on('change', editorChangeListener);
    updateStatusBox();
}<|endoftext|>


<commit_before>import React from "react"

function Foot(props) {
    return (

                    Click to select a point

                    Ctrl + Click or Command + Click (on Mac) to add a point

                Made by Anthony Dugois (@a_dugois)

    )
}

export default Foot
<commit_msg>update foot<commit_after>import React from "react"

function Foot(props) {
    return (

                    Click to select a point

                    Ctrl + Click or Cmd + Click (on Mac) to add a point

                Made by Anthony Dugois (@a_dugois)

    )
}

export default Foot
<|endoftext|>


<commit_before>var creep_upSupplier = {

    /** @param {Creep} creep **/
    run: function(creep) {
        if (creep.ticksToLive <= creep.memory.deathWarn && creep.memory.priority != 'upSupplierNearDeath') {
            creep.memory.priority = 'upSupplierNearDeath';
        }

        if (_.sum(creep.carry) == 0) {
            //Get from storage
            //Get power if available and powerSpawn is empty
            var storageTarget = creep.room.storage;
            if (storageTarget) {
                var getPower = false;
                var powerAmount = 100;
                if (Memory.powerSpawnList[creep.room.name].length && creep.room.storage.store[RESOURCE_POWER] > 0) {
                    var pSpawn = Game.getObjectById(Memory.powerSpawnList[creep.room.name][0]);
                    if (pSpawn && pSpawn.power == 0) {
                        getPower = true;
                        if (creep.room.storage.store[RESOURCE_POWER] < 100) {
                            powerAmount = creep.room.storage.store[RESOURCE_POWER];
                        }
                    }
                }
                if (getPower) {
                    var withdrawResult = creep.withdraw(storageTarget, RESOURCE_POWER, powerAmount);
                    if (withdrawResult == ERR_NOT_IN_RANGE) {
                        creep.travelTo(storageTarget, {
                            ignoreRoads: true,
                            maxRooms: 1
                        });
                    } else if (withdrawResult == OK) {
                        locateSupplierTarget("POWER", creep);
                    }
                } else {
                    if (creep.room.terminal && storageTarget.store[RESOURCE_ENERGY] < 300000 && creep.room.terminal.store[RESOURCE_ENERGY] > 31000) {
                        var withdrawResult = creep.withdraw(creep.room.terminal, RESOURCE_ENERGY);
                        if (withdrawResult == ERR_NOT_IN_RANGE) {
                            creep.travelTo(creep.room.terminal, {
                                ignoreRoads: true,
                                maxRooms: 1
                            });
                        } else if (withdrawResult == OK) {
                            locateSupplierTarget("ENERGY", creep);
                        }
                    } else {
                        if (withdrawResult == ERR_NOT_IN_RANGE) {
                            creep.travelTo(storageTarget, {
                                ignoreRoads: true,
                                maxRooms: 1
                            });
                        } else if (withdrawResult == OK) {
                            locateSupplierTarget("ENERGY", creep);
                        }
                    }
                }
            }
        } else {
            if (creep.carry[RESOURCE_POWER] > 0) {
                //Drop off in power Spawn
                var pSpawn = Game.getObjectById(Memory.powerSpawnList[creep.room.name][0]);
                if (pSpawn) {
                    var transferResult = creep.transfer(pSpawn, RESOURCE_POWER);
                    if (transferResult == ERR_NOT_IN_RANGE) {
                        creep.travelTo(pSpawn, {
                            maxRooms: 1
                        });
                    } else if (transferResult == OK) {
                        determineIfEmptyPower(pSpawn, creep);
                    }
                }
            } else {
                //Drop off in upgrader link
                var upLink = Game.getObjectById(creep.memory.linkTarget);
                if (upLink) {
                    var transferResult = creep.transfer(upLink, RESOURCE_ENERGY);
                    if (transferResult == ERR_NOT_IN_RANGE) {
                        creep.travelTo(upLink, {
                            maxRooms: 1
                        });
                    } else if (transferResult == OK){
                        determineIfEmptyEnergy(upLink, creep);
                    }
                }
            }
        }
    }
};

function locateSupplierTarget(targetType, creep) {
    if (targetType == "POWER") {
        var pSpawn = Game.getObjectById(Memory.powerSpawnList[creep.room.name][0]);
        if (pSpawn) {
            creep.travelTo(pSpawn, {
                maxRooms: 1
            });
        }
    } else {
        //Energy
        var upLink = Game.getObjectById(creep.memory.linkTarget);
        if (upLink) {
            creep.travelTo(upLink, {
                maxRooms: 1
            });
        }
    }
}

//Below functions are only fired when OK is returned
function determineIfEmptyPower(thisSpawn, creep) {
    if (_.sum(creep.carry) <= thisSpawn.powerCapacity - thisSpawn.power) {
        var storageTarget = creep.room.storage;
        if (storageTarget) {
            creep.travelTo(storageTarget, {
                ignoreRoads: true,
                maxRooms: 1
            });
        }
    }
}

function determineIfEmptyEnergy(thisLink, creep) {
    if (_.sum(creep.carry) <= thisLink.energyCapacity - thisLink.energy) {
        var storageTarget = creep.room.storage;
        if (storageTarget) {
            creep.travelTo(storageTarget, {
                ignoreRoads: true,
                maxRooms: 1
            });
        }
    }
}

module.exports = creep_upSupplier;<commit_msg>WHOOPS<commit_after>var creep_upSupplier = {

    /** @param {Creep} creep **/
    run: function(creep) {
        if (creep.ticksToLive <= creep.memory.deathWarn && creep.memory.priority != 'upSupplierNearDeath') {
            creep.memory.priority = 'upSupplierNearDeath';
        }

        if (_.sum(creep.carry) == 0) {
            //Get from storage
            //Get power if available and powerSpawn is empty
            var storageTarget = creep.room.storage;
            if (storageTarget) {
                var getPower = false;
                var powerAmount = 100;
                if (Memory.powerSpawnList[creep.room.name].length && creep.room.storage.store[RESOURCE_POWER] > 0) {
                    var pSpawn = Game.getObjectById(Memory.powerSpawnList[creep.room.name][0]);
                    if (pSpawn && pSpawn.power == 0) {
                        getPower = true;
                        if (creep.room.storage.store[RESOURCE_POWER] < 100) {
                            powerAmount = creep.room.storage.store[RESOURCE_POWER];
                        }
                    }
                }
                if (getPower) {
                    var withdrawResult = creep.withdraw(storageTarget, RESOURCE_POWER, powerAmount);
                    if (withdrawResult == ERR_NOT_IN_RANGE) {
                        creep.travelTo(storageTarget, {
                            ignoreRoads: true,
                            maxRooms: 1
                        });
                    } else if (withdrawResult == OK) {
                        locateSupplierTarget("POWER", creep);
                    }
                } else {
                    if (creep.room.terminal && storageTarget.store[RESOURCE_ENERGY] < 300000 && creep.room.terminal.store[RESOURCE_ENERGY] > 31000) {
                        var withdrawResult = creep.withdraw(creep.room.terminal, RESOURCE_ENERGY);
                        if (withdrawResult == ERR_NOT_IN_RANGE) {
                            creep.travelTo(creep.room.terminal, {
                                ignoreRoads: true,
                                maxRooms: 1
                            });
                        } else if (withdrawResult == OK) {
                            locateSupplierTarget("ENERGY", creep);
                        }
                    } else {
                        var withdrawResult = creep.withdraw(storageTarget, RESOURCE_ENERGY);
                        if (withdrawResult == ERR_NOT_IN_RANGE) {
                            creep.travelTo(storageTarget, {
                                ignoreRoads: true,
                                maxRooms: 1
                            });
                        } else if (withdrawResult == OK) {
                            locateSupplierTarget("ENERGY", creep);
                        }
                    }
                }
            }
        } else {
            if (creep.carry[RESOURCE_POWER] > 0) {
                //Drop off in power Spawn
                var pSpawn = Game.getObjectById(Memory.powerSpawnList[creep.room.name][0]);
                if (pSpawn) {
                    var transferResult = creep.transfer(pSpawn, RESOURCE_POWER);
                    if (transferResult == ERR_NOT_IN_RANGE) {
                        creep.travelTo(pSpawn, {
                            maxRooms: 1
                        });
                    } else if (transferResult == OK) {
                        determineIfEmptyPower(pSpawn, creep);
                    }
                }
            } else {
                //Drop off in upgrader link
                var upLink = Game.getObjectById(creep.memory.linkTarget);
                if (upLink) {
                    var transferResult = creep.transfer(upLink, RESOURCE_ENERGY);
                    if (transferResult == ERR_NOT_IN_RANGE) {
                        creep.travelTo(upLink, {
                            maxRooms: 1
                        });
                    } else if (transferResult == OK){
                        determineIfEmptyEnergy(upLink, creep);
                    }
                }
            }
        }
    }
};

function locateSupplierTarget(targetType, creep) {
    if (targetType == "POWER") {
        var pSpawn = Game.getObjectById(Memory.powerSpawnList[creep.room.name][0]);
        if (pSpawn) {
            creep.travelTo(pSpawn, {
                maxRooms: 1
            });
        }
    } else {
        //Energy
        var upLink = Game.getObjectById(creep.memory.linkTarget);
        if (upLink) {
            creep.travelTo(upLink, {
                maxRooms: 1
            });
        }
    }
}

//Below functions are only fired when OK is returned
function determineIfEmptyPower(thisSpawn, creep) {
    if (_.sum(creep.carry) <= thisSpawn.powerCapacity - thisSpawn.power) {
        var storageTarget = creep.room.storage;
        if (storageTarget) {
            creep.travelTo(storageTarget, {
                ignoreRoads: true,
                maxRooms: 1
            });
        }
    }
}

function determineIfEmptyEnergy(thisLink, creep) {
    if (_.sum(creep.carry) <= thisLink.energyCapacity - thisLink.energy) {
        var storageTarget = creep.room.storage;
        if (storageTarget) {
            creep.travelTo(storageTarget, {
                ignoreRoads: true,
                maxRooms: 1
            });
        }
    }
}

module.exports = creep_upSupplier;<|endoftext|>


<commit_before>var walk = require('acorn/util/walk');
var monitoredTags = new Array('input');
//working in testing.js
//inefficient, but will do for now.
function contains(a, obj) {
  for (var i = 0; i < a.length; i++) {
    if (a[i] === obj) {
      return true;
    }
  }
  return false;
}

//Tests our inputs Array for a specific Name
function containsName(a, obj) {
  for (var i = 0; i < a.length; i++) {
    if (a[i][0] === obj) {
      return true;
    }
  }
  return false;
}

//Tests our inputs Array for a specific Type
function containsType(a, obj) {
  for (var i = 0; i < a.length; i++) {
    if (a[i][1] === obj) {
      return true;
    }
  }
  return false;
}

//gets the latest object of a List by the Name
function getLastName(a, obj){
	for(var i = a.length-1; i >= 0; i--){
		if (a[i][0] === obj) {
			return a;
		}
	}
	return [];
}

//Tests whether or not a node poses a risk
function dangerousNode(node){
  return node.callee.name === 'prompt' ||
         (node.callee.property.name === 'createElement' ||
         node.callee.property.name === 'getElementsByTagName')
         && contains(monitoredTags,node.arguments[0].value);
}

module.exports = function (tree) {
  var inputs = new Array(); //saving all the names of our inputs in the Form {Name, Type}
  var assignments = new Array(); //Contains all new assigned monitored values {Name, dangerous (boolean), ending symbol}
  walk.recursive(tree.data.cfg, {}, {
    //We will have to go to the VariableDeclarators over the VariableDeclarations for some reason.
    VariableDeclaration: function (node, state, c) {
      var declarator = node.declarations;
      for(var i = 0; i < declarator.length; i++){
        var subnode = declarator[i].init;
        //prompts,created Elements and Elements gotten are monitored
        if(subnode.type === 'CallExpression'
          && (subnode.callee.name === 'prompt' ||
          dangerousNode(subnode)))
          {
            var name = declarator[i].id.name; //Variable Name
            var type = subnode.arguments[0].value; //Variable type (e.g. 'input', 'span', 'button' etc.)
            var nameType = new Array(name, type);
            //If we get Elements by Tag Name, then we only need to monitor the value,
            //if it actually returns something.
            if(subnode.callee.name !== 'prompt'
              &&subnode.callee.property.name === 'getElementsByTagName'
              && !contains(inputs, nameType)
              && containsType(inputs,type)){
              //Push element into List if not already existant.
              inputs.push(nameType);
              assignments.push(new Array(name, true, node.end));
            }
            else if(!contains(inputs, nameType)){
              inputs.push(nameType);
              assignments.push(new Array(name, true, node.end));
            }
        }
      }
    }
	});

	walk.recursive(tree.data.cfg, {}, {
    //We test all assigned values for changes
    AssignmentExpression: function (node, state, c){
			//Continue with inner stuff if function is declared;
      if(node.operator === '='){
        //Is new assignment a risk?
        var dangerous;
        //Does Assignment use functions?
        if(node.right.type === 'CallExpression'){
          dangerous = dangerousNode(node.right);
        }
        else{
          dangerous = false;
        }
        //Is monitored Value newly assigned?
        var name = node.left.name;
        var endSign = node.end;
        if (containsName(inputs,name)){
          assignments.push(new Array(name, dangerous, endSign));
        }
				//Variable takes value of another dangerous one
				else if(node.right.type == 'Identifier' && containsName(inputs, node.right.name)){
					assignments.push(new Array(name, getLastName(assignments, node.right.name[1]), endSign));
				}
        //Defined variable gets dangerous value
        else if(dangerous){
          inputs.push(new Array(name, node.right.callee.name));
          assignments.push(new Array(name, true, endSign));
        }
      }
			if(node.right.type === 'FunctionExpression'){
				c(node.right.body,state);
			}
    }
  });

  walk.recursive(tree.data.cfg, {}, {
    CallExpression: function (node, state, c) {
      //Every appended Object will (for now) throw an error, even if the container isn't added to the body.
      if(node.arguments[0].callee !== undefined
        && node.callee.property.name === 'appendChild'){
        //Go into lowest CallExpression in chain
        var subNode = node;
        while(subNode.arguments[0].type === 'CallExpression'){
          subNode = subNode.arguments[0];
        }
        //Go through the different chain design to find variable name.
        if(subNode.callee.object.name === 'document'){
          var name;
          //Name is very early within chain.
          if(subNode.arguments[0].type === 'Identifier'){
            name = subNode.arguments[0].name;
          }
          //Name comes very late and is within a chain of CallExpressions and MemberExpressions.
          else if(subNode.arguments[0].type === 'MemberExpression'){
            var memNode =  subNode.arguments[0];
            while(memNode.object.type == 'MemberExpression'){
              memNode = memNode.object;
            }
            name = memNode.object.name;
          }
          //Last assignment will be used.
          var nowDangerous = false;
          for(var i = 0; i < assignments.length; i++){
            if(assignments[i][0] === name){
              //Assignment before the appending?
              if(assignments[i][2] < node.end){
                nowDangerous = assignments[i][1];
              }
            }
          }
          //Push warning if dangerous value is appended
          if(nowDangerous){
            tree.data.problems.push({
              'type': 'warning',
              'message': 'To put the user defined variable ' + name + ' into the DOM tree is a risk',
              'weight': 5,
              'position': {
              'start': node.start,
              'end': node.end
              }
            });
          }
        }
      }
    }
  });    //graph.domio = 'success';
};<commit_msg>Now test for assignment of evil functions.<commit_after>var walk = require('acorn/util/walk');
var monitoredTags = new Array('input');
//working in testing.js
//inefficient, but will do for now.
function contains(a, obj) {
  for (var i = 0; i < a.length; i++) {
    if (a[i] === obj) {
      return true;
    }
  }
  return false;
}

//Tests our inputs Array for a specific Name
function containsName(a, obj) {
  for (var i = 0; i < a.length; i++) {
    if (a[i][0] === obj) {
      return true;
    }
  }
  return false;
}

//Tests our inputs Array for a specific Type
function containsType(a, obj) {
  for (var i = 0; i < a.length; i++) {
    if (a[i][1] === obj) {
      return true;
    }
  }
  return false;
}

//gets the latest object of a List by the Name
function getLastName(a, obj){
	for(var i = a.length-1; i >= 0; i--){
		if (a[i][0] === obj) {
			return a;
		}
	}
	return [];
}

//Gets the assigned value for an assignment
function getAssignedValue(node){
	console.log(node.type);
	if(node.type === 'CallExpression'){
		if(node.callee.name === undefined){
			return node.callee.name;
		}
		else if(node.callee.property !== undefined){
			return node.callee.property.name;
		}
	}
	else if(node.type === 'Literal'){
		return node.right.value;
	}
	else if(node.type === 'BinaryExpression'){
		return getAssignedValue(node.left)
		+ node.right.operator
		+ getAssignedValue(node.right);
	}
	else{
		return [];
	}
}

//Tests whether or not a node poses a risk
function dangerousNode(node){
  return node.callee.name === 'prompt' ||
         (node.callee.property.name === 'createElement' ||
         (node.callee.property.name === 'getElementsByTagName')
         && contains(monitoredTags,node.arguments[0].value));
}

module.exports = function (tree) {
  var inputs = new Array(); //saving all the names of our inputs in the Form {Name, Type}
  var assignments = new Array(); //Contains all new assigned monitored values {Name, dangerous (boolean), value, starting symbol, ending symbol}
	var evilFunctions = new Array();

	//called when a warning happens
	function pushWarning(name, start, end){
		tree.data.problems.push({
			'type': 'warning',
			'message': 'To put the user defined variable ' + name + ' into the DOM tree is a risk',
			'weight': 5,
			'position': {
			'start': start,
			'end': end
			}
		});
	}

  walk.recursive(tree.data.cfg, {}, {
    //We will have to go to the VariableDeclarators over the VariableDeclarations for some reason.
    VariableDeclaration: function (node, state, c) {
      var declarator = node.declarations;
      for(var i = 0; i < declarator.length; i++){
        var subnode = declarator[i].init;
        //prompts,created Elements and Elements gotten are monitored
        if(subnode.type === 'CallExpression'
          && dangerousNode(subnode))
          {
            var name = declarator[i].id.name; //Variable Name
            var type = subnode.arguments[0].value; //Variable type (e.g. 'input', 'span', 'button' etc.)
            var nameType = new Array(name, type);
            //If we get Elements by Tag Name, then we only need to monitor the value,
            //if it actually returns something.
            if(subnode.callee.name !== 'prompt'
              && subnode.callee.property.name === 'getElementsByTagName'
              && !contains(inputs, nameType)
              && containsType(inputs,type)){
              //Push element into List if not already existant.
              inputs.push(nameType);
              assignments.push(new Array(name, true, getAssignedValue(subnode), node.start, node.end));
            }
            else if(!contains(inputs, nameType)){
              inputs.push(nameType);
              assignments.push(new Array(name, true, getAssignedValue(subnode), node.start, node.end));
            }
        }
      }
    }
	});

	walk.recursive(tree.data.cfg, {}, {
    //We test all assigned values for changes
    AssignmentExpression: function (node, state, c){
			//Continue with inner stuff if function is declared;
      if(node.operator === '='){
        //Is new assignment a risk?
        var dangerous;
        //Does Assignment use functions?
        if(node.right.type === 'CallExpression'){
          dangerous = dangerousNode(node.right);
        }
        else{
          dangerous = false;
        }
        //Is monitored Value newly assigned?
        if (containsName(inputs,node.left.name)){
          assignments.push(new Array(node.left.name, dangerous, getAssignedValue(node.right) ,node.start, node.end));
        }
				//Variable takes value of another dangerous one
				else if(node.right.type == 'Identifier'
				&& containsName(inputs, node.right.value)){
					assignments.push(new Array(node.left.name, getLastName(assignments, node.right.value)[1], node.right.value ,node.start, node.end));
				}
        //Defined variable gets dangerous value
        else if(dangerous){
          inputs.push(new Array(node.left.name, node.right.callee.name));
          assignments.push(new Array(node.left.name, true, getAssignedValue(node.right) ,node.start, node.end));
        }
      }
			//Continue search if in FunctionExpression
			if(node.right.type === 'FunctionExpression'){
				c(node.right.body,state);
			}
    }
  });

	//Walk all Functions to look if evil values are behind Functions.
	walk.recursive(tree.data.cfg, {}, {
    FunctionDeclaration: function (node, state, c) {
			for(var i = 0; i < assignments.length; i++){
				if(assignments[i][3] >= node.start
				&& assignments[i][4] <= node.end
				&& assignments[i][1]){
					evilFunctions.push(node.id.name);
				}
			}
		}
	});

  walk.recursive(tree.data.cfg, {}, {
    CallExpression: function (node, state, c) {
      //Every appended Object will (for now) throw an error, even if the container isn't added to the body.
      if(node.arguments[0].callee !== undefined
        && node.callee.property.name === 'appendChild'){
        //Go into lowest CallExpression in chain until you reach a document call
        var subNode = node;
        while(subNode.arguments[0] !== undefined &&
				subNode.arguments[0].type === 'CallExpression' &&
				!(subNode.callee.object !== undefined &&
				subNode.callee.object.name === 'document')){
          subNode = subNode.arguments[0];
        }
        //Go through the different chain design to find variable name.
        if(subNode.callee.object !== undefined &&
				subNode.callee.object.name === 'document'){
          var name;
          //Name is very early within chain.
          if(subNode.arguments[0].type === 'Identifier'){
            name = subNode.arguments[0].name;
          }
          //Name comes very late and is within a chain of CallExpressions and MemberExpressions.
          else if(subNode.arguments[0].type === 'MemberExpression'){
            var memNode =  subNode.arguments[0];
            while(memNode.object.type == 'MemberExpression'){
              memNode = memNode.object;
            }
            name = memNode.object.name;
          }
					else if(subNode.arguments[0].type === 'CallExpression'){
						name = subNode.arguments[0].callee.name;
					}
          //Last assignment will be used.
          var nowDangerous = false;
          for(var i = 0; i < assignments.length; i++){
            if(assignments[i][0] === name){
              //Assignment before the appending?
              if(assignments[i][4] <= node.end){
                nowDangerous = assignments[i][1];
              }
            }
          }
          //Push warning if dangerous value is appended
          if(nowDangerous
					|| contains(evilFunctions,name)){
						pushWarning(name, node.start, node.end)
          }
        }
      }
    }
  });    //graph.domio = 'success';
};<|endoftext|>


<commit_before>import React, {PropTypes, Component} from 'react'
import {Link} from 'react-router'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'

import Dygraph from 'src/external/dygraph'

import OverlayTechnologies from 'shared/components/OverlayTechnologies'
import CellEditorOverlay from 'src/dashboards/components/CellEditorOverlay'
import DashboardHeader from 'src/dashboards/components/DashboardHeader'
import DashboardHeaderEdit from 'src/dashboards/components/DashboardHeaderEdit'
import Dashboard from 'src/dashboards/components/Dashboard'
import TemplateVariableManager from 'src/dashboards/components/TemplateVariableManager'

import {errorThrown as errorThrownAction} from 'shared/actions/errors'

import * as dashboardActionCreators from 'src/dashboards/actions'

import {
  setAutoRefresh,
  templateControlBarVisibilityToggled as templateControlBarVisibilityToggledAction,
} from 'shared/actions/app'
import {presentationButtonDispatcher} from 'shared/dispatchers'

class DashboardPage extends Component {
  constructor(props) {
    super(props)

    this.state = {
      selectedCell: null,
      isEditMode: false,
      isTemplating: false,
      dygraphs: [],
    }

    this.handleAddCell = ::this.handleAddCell
    this.handleEditDashboard = ::this.handleEditDashboard
    this.handleSaveEditedCell = ::this.handleSaveEditedCell
    this.handleDismissOverlay = ::this.handleDismissOverlay
    this.handleUpdatePosition = ::this.handleUpdatePosition
    this.handleChooseTimeRange = ::this.handleChooseTimeRange
    this.handleRenameDashboard = ::this.handleRenameDashboard
    this.handleEditDashboardCell = ::this.handleEditDashboardCell
    this.handleCancelEditDashboard = ::this.handleCancelEditDashboard
    this.handleDeleteDashboardCell = ::this.handleDeleteDashboardCell
    this.handleOpenTemplateManager = ::this.handleOpenTemplateManager
    this.handleRenameDashboardCell = ::this.handleRenameDashboardCell
    this.handleUpdateDashboardCell = ::this.handleUpdateDashboardCell
    this.handleCloseTemplateManager = ::this.handleCloseTemplateManager
    this.handleSummonOverlayTechnologies = ::this
      .handleSummonOverlayTechnologies
    this.handleRunTemplateVariableQuery = ::this.handleRunTemplateVariableQuery
    this.handleSelectTemplate = ::this.handleSelectTemplate
    this.handleEditTemplateVariables = ::this.handleEditTemplateVariables
    this.handleRunQueryFailure = ::this.handleRunQueryFailure
    this.handleToggleTempVarControls = ::this.handleToggleTempVarControls
    this.synchronizer = ::this.synchronizer
  }

  async componentDidMount() {
    const {
      params: {dashboardID},
      dashboardActions: {
        getDashboardsAsync,
        updateTempVarValues,
        putDashboardByID,
      },
      source,
    } = this.props

    const dashboards = await getDashboardsAsync()
    const dashboard = dashboards.find(d => d.id === +dashboardID)

    // Refresh and persists influxql generated template variable values
    await updateTempVarValues(source, dashboard)
    await putDashboardByID(dashboardID)
  }

  handleOpenTemplateManager() {
    this.setState({isTemplating: true})
  }

  handleCloseTemplateManager(isEdited) {
    if (
      !isEdited ||
      (isEdited && confirm('Do you want to close without saving?')) // eslint-disable-line no-alert
    ) {
      this.setState({isTemplating: false})
    }
  }

  handleDismissOverlay() {
    this.setState({selectedCell: null})
  }

  handleSaveEditedCell(newCell) {
    this.props.dashboardActions
      .updateDashboardCell(this.getActiveDashboard(), newCell)
      .then(this.handleDismissOverlay)
  }

  handleSummonOverlayTechnologies(cell) {
    this.setState({selectedCell: cell})
  }

  handleChooseTimeRange(timeRange) {
    this.props.dashboardActions.setTimeRange(timeRange)
  }

  handleUpdatePosition(cells) {
    const newDashboard = {...this.getActiveDashboard(), cells}
    this.props.dashboardActions.updateDashboard(newDashboard)
    this.props.dashboardActions.putDashboard(newDashboard)
  }

  handleAddCell() {
    this.props.dashboardActions.addDashboardCellAsync(this.getActiveDashboard())
  }

  handleEditDashboard() {
    this.setState({isEditMode: true})
  }

  handleCancelEditDashboard() {
    this.setState({isEditMode: false})
  }

  handleRenameDashboard(name) {
    this.setState({isEditMode: false})
    const newDashboard = {...this.getActiveDashboard(), name}
    this.props.dashboardActions.updateDashboard(newDashboard)
    this.props.dashboardActions.putDashboard(newDashboard)
  }

  // Places cell into editing mode.
  handleEditDashboardCell(x, y, isEditing) {
    return () => {
      this.props.dashboardActions.editDashboardCell(
        this.getActiveDashboard(),
        x,
        y,
        !isEditing
      ) /* eslint-disable no-negated-condition */
    }
  }

  handleRenameDashboardCell(x, y) {
    return evt => {
      this.props.dashboardActions.renameDashboardCell(
        this.getActiveDashboard(),
        x,
        y,
        evt.target.value
      )
    }
  }

  handleUpdateDashboardCell(newCell) {
    return () => {
      this.props.dashboardActions.editDashboardCell(
        this.getActiveDashboard(),
        newCell.x,
        newCell.y,
        false
      )
      this.props.dashboardActions.putDashboard(this.getActiveDashboard())
    }
  }

  handleDeleteDashboardCell(cell) {
    const dashboard = this.getActiveDashboard()
    this.props.dashboardActions.deleteDashboardCellAsync(dashboard, cell)
  }

  handleSelectTemplate(templateID, values) {
    const {params: {dashboardID}} = this.props
    this.props.dashboardActions.templateVariableSelected(
      +dashboardID,
      templateID,
      values
    )
  }

  handleRunTemplateVariableQuery(
    templateVariable,
    {query, db, tempVars, type, tagKey, measurement}
  ) {
    const {source} = this.props
    this.props.dashboardActions.runTemplateVariableQueryAsync(
      templateVariable,
      {
        source,
        query,
        db,
        // rp, TODO
        tempVars,
        type,
        tagKey,
        measurement,
      }
    )
  }

  handleEditTemplateVariables(templates, onSaveTemplatesSuccess) {
    return async () => {
      try {
        await this.props.dashboardActions.putDashboard({
          ...this.getActiveDashboard(),
          templates,
        })
        onSaveTemplatesSuccess()
      } catch (error) {
        console.error(error)
      }
    }
  }

  handleRunQueryFailure(error) {
    console.error(error)
    this.props.errorThrown(error)
  }

  synchronizer(dygraph) {
    const dygraphs = [...this.state.dygraphs, dygraph]
    const {dashboards, params} = this.props
    const dashboard = dashboards.find(d => d.id === +params.dashboardID)
    if (dashboard && dygraphs.length === dashboard.cells.length) {
      Dygraph.synchronize(dygraphs, {
        selection: true,
        zoom: false,
        range: false,
      })
    }
    this.setState({dygraphs})
  }

  handleToggleTempVarControls() {
    this.props.templateControlBarVisibilityToggled()
  }

  getActiveDashboard() {
    const {params: {dashboardID}, dashboards} = this.props
    return dashboards.find(d => d.id === +dashboardID)
  }

  render() {
    const {
      source,
      timeRange,
      showTemplateControlBar,
      dashboards,
      autoRefresh,
      cellQueryStatus,
      dashboardActions,
      inPresentationMode,
      handleChooseAutoRefresh,
      handleClickPresentationButton,
      params: {sourceID},
    } = this.props

    const dashboard = this.getActiveDashboard()
    const dashboardTime = {
      id: 'dashtime',
      tempVar: ':dashboardTime:',
      type: 'constant',
      values: [
        {
          value: timeRange.lower,
          type: 'constant',
          selected: true,
        },
      ],
    }

    // this controls the auto group by behavior
    const interval = {
      id: 'interval',
      type: 'constant',
      tempVar: ':interval:',
      resolution: 1000,
      reportingInterval: 10000000000,
      values: [],
    }

    const templatesIncludingDashTime =
      (dashboard &&
        dashboard.templates.concat(dashboardTime).concat(interval)) ||
      []

    const {selectedCell, isEditMode, isTemplating} = this.state

    return (

        {isTemplating
          ? <OverlayTechnologies>
              <TemplateVariableManager
                onClose={this.handleCloseTemplateManager}
                onEditTemplateVariables={this.handleEditTemplateVariables}
                source={source}
                templates={dashboard.templates}
                onRunQueryFailure={this.handleRunQueryFailure}
              />
            </OverlayTechnologies>
          : null}
        {selectedCell
          ? <CellEditorOverlay
              source={source}
              templates={templatesIncludingDashTime}
              cell={selectedCell}
              timeRange={timeRange}
              autoRefresh={autoRefresh}
              queryStatus={cellQueryStatus}
              onSave={this.handleSaveEditedCell}
              onCancel={this.handleDismissOverlay}
              editQueryStatus={dashboardActions.editCellQueryStatus}
            />
          : null}
        {isEditMode
          ? <DashboardHeaderEdit
              dashboard={dashboard}
              onCancel={this.handleCancelEditDashboard}
              onSave={this.handleRenameDashboard}
            />
          : <DashboardHeader
              buttonText={dashboard ? dashboard.name : ''}
              handleChooseAutoRefresh={handleChooseAutoRefresh}
              autoRefresh={autoRefresh}
              timeRange={timeRange}
              handleChooseTimeRange={this.handleChooseTimeRange}
              isHidden={inPresentationMode}
              handleClickPresentationButton={handleClickPresentationButton}
              dashboard={dashboard}
              sourceID={sourceID}
              source={source}
              onAddCell={this.handleAddCell}
              onEditDashboard={this.handleEditDashboard}
              onToggleTempVarControls={this.handleToggleTempVarControls}
              showTemplateControlBar={showTemplateControlBar}
            >
              {dashboards
                ? dashboards.map((d, i) =>

                      <Link to={`/sources/${sourceID}/dashboards/${d.id}`}>
                        {d.name}
                      </Link>

                  )
                : null}
            </DashboardHeader>}
        {dashboard
          ? <Dashboard
              source={source}
              dashboard={dashboard}
              timeRange={timeRange}
              autoRefresh={autoRefresh}
              synchronizer={this.synchronizer}
              onAddCell={this.handleAddCell}
              inPresentationMode={inPresentationMode}
              onEditCell={this.handleEditDashboardCell}
              onPositionChange={this.handleUpdatePosition}
              onDeleteCell={this.handleDeleteDashboardCell}
              onRenameCell={this.handleRenameDashboardCell}
              onUpdateCell={this.handleUpdateDashboardCell}
              onOpenTemplateManager={this.handleOpenTemplateManager}
              templatesIncludingDashTime={templatesIncludingDashTime}
              onSummonOverlayTechnologies={this.handleSummonOverlayTechnologies}
              onSelectTemplate={this.handleSelectTemplate}
              showTemplateControlBar={showTemplateControlBar}
            />
          : null}

    )
  }
}

const {arrayOf, bool, func, number, shape, string} = PropTypes

DashboardPage.propTypes = {
  source: shape({
    links: shape({
      proxy: string,
      self: string,
    }),
  }).isRequired,
  params: shape({
    sourceID: string.isRequired,
    dashboardID: string.isRequired,
  }).isRequired,
  location: shape({
    pathname: string.isRequired,
  }).isRequired,
  dashboardActions: shape({
    putDashboard: func.isRequired,
    getDashboardsAsync: func.isRequired,
    setTimeRange: func.isRequired,
    addDashboardCellAsync: func.isRequired,
    editDashboardCell: func.isRequired,
    renameDashboardCell: func.isRequired,
  }).isRequired,
  dashboards: arrayOf(
    shape({
      id: number.isRequired,
      cells: arrayOf(shape({})).isRequired,
      templates: arrayOf(
        shape({
          type: string.isRequired,
          tempVar: string.isRequired,
          query: shape({
            db: string,
            rp: string,
            influxql: string,
          }),
          values: arrayOf(
            shape({
              value: string.isRequired,
              selected: bool.isRequired,
              type: string.isRequired,
            })
          ),
        })
      ),
    })
  ),
  handleChooseAutoRefresh: func.isRequired,
  autoRefresh: number.isRequired,
  templateControlBarVisibilityToggled: func.isRequired,
  timeRange: shape({}).isRequired,
  showTemplateControlBar: bool.isRequired,
  inPresentationMode: bool.isRequired,
  handleClickPresentationButton: func,
  cellQueryStatus: shape({
    queryID: string,
    status: shape(),
  }).isRequired,
  errorThrown: func,
}

const mapStateToProps = state => {
  const {
    app: {
      ephemeral: {inPresentationMode},
      persisted: {autoRefresh, showTemplateControlBar},
    },
    dashboardUI: {dashboards, timeRange, cellQueryStatus},
  } = state

  return {
    dashboards,
    autoRefresh,
    timeRange,
    showTemplateControlBar,
    inPresentationMode,
    cellQueryStatus,
  }
}

const mapDispatchToProps = dispatch => ({
  handleChooseAutoRefresh: bindActionCreators(setAutoRefresh, dispatch),
  templateControlBarVisibilityToggled: bindActionCreators(
    templateControlBarVisibilityToggledAction,
    dispatch
  ),
  handleClickPresentationButton: presentationButtonDispatcher(dispatch),
  dashboardActions: bindActionCreators(dashboardActionCreators, dispatch),
  errorThrown: bindActionCreators(errorThrownAction, dispatch),
})

export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage)
<commit_msg>Fix for dashboardTime on Dashboards.<commit_after>import React, {PropTypes, Component} from 'react'
import {Link} from 'react-router'
import {connect} from 'react-redux'
import {bindActionCreators} from 'redux'

import Dygraph from 'src/external/dygraph'

import OverlayTechnologies from 'shared/components/OverlayTechnologies'
import CellEditorOverlay from 'src/dashboards/components/CellEditorOverlay'
import DashboardHeader from 'src/dashboards/components/DashboardHeader'
import DashboardHeaderEdit from 'src/dashboards/components/DashboardHeaderEdit'
import Dashboard from 'src/dashboards/components/Dashboard'
import TemplateVariableManager from 'src/dashboards/components/TemplateVariableManager'

import {errorThrown as errorThrownAction} from 'shared/actions/errors'

import * as dashboardActionCreators from 'src/dashboards/actions'

import {
  setAutoRefresh,
  templateControlBarVisibilityToggled as templateControlBarVisibilityToggledAction,
} from 'shared/actions/app'
import {presentationButtonDispatcher} from 'shared/dispatchers'

class DashboardPage extends Component {
  constructor(props) {
    super(props)

    this.state = {
      selectedCell: null,
      isEditMode: false,
      isTemplating: false,
      dygraphs: [],
    }

    this.handleAddCell = ::this.handleAddCell
    this.handleEditDashboard = ::this.handleEditDashboard
    this.handleSaveEditedCell = ::this.handleSaveEditedCell
    this.handleDismissOverlay = ::this.handleDismissOverlay
    this.handleUpdatePosition = ::this.handleUpdatePosition
    this.handleChooseTimeRange = ::this.handleChooseTimeRange
    this.handleRenameDashboard = ::this.handleRenameDashboard
    this.handleEditDashboardCell = ::this.handleEditDashboardCell
    this.handleCancelEditDashboard = ::this.handleCancelEditDashboard
    this.handleDeleteDashboardCell = ::this.handleDeleteDashboardCell
    this.handleOpenTemplateManager = ::this.handleOpenTemplateManager
    this.handleRenameDashboardCell = ::this.handleRenameDashboardCell
    this.handleUpdateDashboardCell = ::this.handleUpdateDashboardCell
    this.handleCloseTemplateManager = ::this.handleCloseTemplateManager
    this.handleSummonOverlayTechnologies = ::this
      .handleSummonOverlayTechnologies
    this.handleRunTemplateVariableQuery = ::this.handleRunTemplateVariableQuery
    this.handleSelectTemplate = ::this.handleSelectTemplate
    this.handleEditTemplateVariables = ::this.handleEditTemplateVariables
    this.handleRunQueryFailure = ::this.handleRunQueryFailure
    this.handleToggleTempVarControls = ::this.handleToggleTempVarControls
    this.synchronizer = ::this.synchronizer
  }

  async componentDidMount() {
    const {
      params: {dashboardID},
      dashboardActions: {
        getDashboardsAsync,
        updateTempVarValues,
        putDashboardByID,
      },
      source,
    } = this.props

    const dashboards = await getDashboardsAsync()
    const dashboard = dashboards.find(d => d.id === +dashboardID)

    // Refresh and persists influxql generated template variable values
    await updateTempVarValues(source, dashboard)
    await putDashboardByID(dashboardID)
  }

  handleOpenTemplateManager() {
    this.setState({isTemplating: true})
  }

  handleCloseTemplateManager(isEdited) {
    if (
      !isEdited ||
      (isEdited && confirm('Do you want to close without saving?')) // eslint-disable-line no-alert
    ) {
      this.setState({isTemplating: false})
    }
  }

  handleDismissOverlay() {
    this.setState({selectedCell: null})
  }

  handleSaveEditedCell(newCell) {
    this.props.dashboardActions
      .updateDashboardCell(this.getActiveDashboard(), newCell)
      .then(this.handleDismissOverlay)
  }

  handleSummonOverlayTechnologies(cell) {
    this.setState({selectedCell: cell})
  }

  handleChooseTimeRange(timeRange) {
    this.props.dashboardActions.setTimeRange(timeRange)
  }

  handleUpdatePosition(cells) {
    const newDashboard = {...this.getActiveDashboard(), cells}
    this.props.dashboardActions.updateDashboard(newDashboard)
    this.props.dashboardActions.putDashboard(newDashboard)
  }

  handleAddCell() {
    this.props.dashboardActions.addDashboardCellAsync(this.getActiveDashboard())
  }

  handleEditDashboard() {
    this.setState({isEditMode: true})
  }

  handleCancelEditDashboard() {
    this.setState({isEditMode: false})
  }

  handleRenameDashboard(name) {
    this.setState({isEditMode: false})
    const newDashboard = {...this.getActiveDashboard(), name}
    this.props.dashboardActions.updateDashboard(newDashboard)
    this.props.dashboardActions.putDashboard(newDashboard)
  }

  // Places cell into editing mode.
  handleEditDashboardCell(x, y, isEditing) {
    return () => {
      this.props.dashboardActions.editDashboardCell(
        this.getActiveDashboard(),
        x,
        y,
        !isEditing
      ) /* eslint-disable no-negated-condition */
    }
  }

  handleRenameDashboardCell(x, y) {
    return evt => {
      this.props.dashboardActions.renameDashboardCell(
        this.getActiveDashboard(),
        x,
        y,
        evt.target.value
      )
    }
  }

  handleUpdateDashboardCell(newCell) {
    return () => {
      this.props.dashboardActions.editDashboardCell(
        this.getActiveDashboard(),
        newCell.x,
        newCell.y,
        false
      )
      this.props.dashboardActions.putDashboard(this.getActiveDashboard())
    }
  }

  handleDeleteDashboardCell(cell) {
    const dashboard = this.getActiveDashboard()
    this.props.dashboardActions.deleteDashboardCellAsync(dashboard, cell)
  }

  handleSelectTemplate(templateID, values) {
    const {params: {dashboardID}} = this.props
    this.props.dashboardActions.templateVariableSelected(
      +dashboardID,
      templateID,
      values
    )
  }

  handleRunTemplateVariableQuery(
    templateVariable,
    {query, db, tempVars, type, tagKey, measurement}
  ) {
    const {source} = this.props
    this.props.dashboardActions.runTemplateVariableQueryAsync(
      templateVariable,
      {
        source,
        query,
        db,
        // rp, TODO
        tempVars,
        type,
        tagKey,
        measurement,
      }
    )
  }

  handleEditTemplateVariables(templates, onSaveTemplatesSuccess) {
    return async () => {
      try {
        await this.props.dashboardActions.putDashboard({
          ...this.getActiveDashboard(),
          templates,
        })
        onSaveTemplatesSuccess()
      } catch (error) {
        console.error(error)
      }
    }
  }

  handleRunQueryFailure(error) {
    console.error(error)
    this.props.errorThrown(error)
  }

  synchronizer(dygraph) {
    const dygraphs = [...this.state.dygraphs, dygraph]
    const {dashboards, params} = this.props
    const dashboard = dashboards.find(d => d.id === +params.dashboardID)
    if (dashboard && dygraphs.length === dashboard.cells.length) {
      Dygraph.synchronize(dygraphs, {
        selection: true,
        zoom: false,
        range: false,
      })
    }
    this.setState({dygraphs})
  }

  handleToggleTempVarControls() {
    this.props.templateControlBarVisibilityToggled()
  }

  getActiveDashboard() {
    const {params: {dashboardID}, dashboards} = this.props
    return dashboards.find(d => d.id === +dashboardID)
  }

  render() {
    const {
      source,
      timeRange: {lower, upper},
      timeRange,
      showTemplateControlBar,
      dashboards,
      autoRefresh,
      cellQueryStatus,
      dashboardActions,
      inPresentationMode,
      handleChooseAutoRefresh,
      handleClickPresentationButton,
      params: {sourceID},
    } = this.props

    const value = upper ? `'${lower}' AND time < '${upper}'` : lower

    const dashboard = this.getActiveDashboard()
    const dashboardTime = {
      id: 'dashtime',
      tempVar: ':dashboardTime:',
      type: 'constant',
      values: [
        {
          value,
          type: 'constant',
          selected: true,
        },
      ],
    }

    // this controls the auto group by behavior
    const interval = {
      id: 'interval',
      type: 'constant',
      tempVar: ':interval:',
      resolution: 1000,
      reportingInterval: 10000000000,
      values: [],
    }

    const templatesIncludingDashTime =
      (dashboard &&
        dashboard.templates.concat(dashboardTime).concat(interval)) ||
      []

    const {selectedCell, isEditMode, isTemplating} = this.state

    return (

        {isTemplating
          ? <OverlayTechnologies>
              <TemplateVariableManager
                onClose={this.handleCloseTemplateManager}
                onEditTemplateVariables={this.handleEditTemplateVariables}
                source={source}
                templates={dashboard.templates}
                onRunQueryFailure={this.handleRunQueryFailure}
              />
            </OverlayTechnologies>
          : null}
        {selectedCell
          ? <CellEditorOverlay
              source={source}
              templates={templatesIncludingDashTime}
              cell={selectedCell}
              timeRange={timeRange}
              autoRefresh={autoRefresh}
              queryStatus={cellQueryStatus}
              onSave={this.handleSaveEditedCell}
              onCancel={this.handleDismissOverlay}
              editQueryStatus={dashboardActions.editCellQueryStatus}
            />
          : null}
        {isEditMode
          ? <DashboardHeaderEdit
              dashboard={dashboard}
              onCancel={this.handleCancelEditDashboard}
              onSave={this.handleRenameDashboard}
            />
          : <DashboardHeader
              buttonText={dashboard ? dashboard.name : ''}
              handleChooseAutoRefresh={handleChooseAutoRefresh}
              autoRefresh={autoRefresh}
              timeRange={timeRange}
              handleChooseTimeRange={this.handleChooseTimeRange}
              isHidden={inPresentationMode}
              handleClickPresentationButton={handleClickPresentationButton}
              dashboard={dashboard}
              sourceID={sourceID}
              source={source}
              onAddCell={this.handleAddCell}
              onEditDashboard={this.handleEditDashboard}
              onToggleTempVarControls={this.handleToggleTempVarControls}
              showTemplateControlBar={showTemplateControlBar}
            >
              {dashboards
                ? dashboards.map((d, i) =>

                      <Link to={`/sources/${sourceID}/dashboards/${d.id}`}>
                        {d.name}
                      </Link>

                  )
                : null}
            </DashboardHeader>}
        {dashboard
          ? <Dashboard
              source={source}
              dashboard={dashboard}
              timeRange={timeRange}
              autoRefresh={autoRefresh}
              synchronizer={this.synchronizer}
              onAddCell={this.handleAddCell}
              inPresentationMode={inPresentationMode}
              onEditCell={this.handleEditDashboardCell}
              onPositionChange={this.handleUpdatePosition}
              onDeleteCell={this.handleDeleteDashboardCell}
              onRenameCell={this.handleRenameDashboardCell}
              onUpdateCell={this.handleUpdateDashboardCell}
              onOpenTemplateManager={this.handleOpenTemplateManager}
              templatesIncludingDashTime={templatesIncludingDashTime}
              onSummonOverlayTechnologies={this.handleSummonOverlayTechnologies}
              onSelectTemplate={this.handleSelectTemplate}
              showTemplateControlBar={showTemplateControlBar}
            />
          : null}

    )
  }
}

const {arrayOf, bool, func, number, shape, string} = PropTypes

DashboardPage.propTypes = {
  source: shape({
    links: shape({
      proxy: string,
      self: string,
    }),
  }).isRequired,
  params: shape({
    sourceID: string.isRequired,
    dashboardID: string.isRequired,
  }).isRequired,
  location: shape({
    pathname: string.isRequired,
  }).isRequired,
  dashboardActions: shape({
    putDashboard: func.isRequired,
    getDashboardsAsync: func.isRequired,
    setTimeRange: func.isRequired,
    addDashboardCellAsync: func.isRequired,
    editDashboardCell: func.isRequired,
    renameDashboardCell: func.isRequired,
  }).isRequired,
  dashboards: arrayOf(
    shape({
      id: number.isRequired,
      cells: arrayOf(shape({})).isRequired,
      templates: arrayOf(
        shape({
          type: string.isRequired,
          tempVar: string.isRequired,
          query: shape({
            db: string,
            rp: string,
            influxql: string,
          }),
          values: arrayOf(
            shape({
              value: string.isRequired,
              selected: bool.isRequired,
              type: string.isRequired,
            })
          ),
        })
      ),
    })
  ),
  handleChooseAutoRefresh: func.isRequired,
  autoRefresh: number.isRequired,
  templateControlBarVisibilityToggled: func.isRequired,
  timeRange: shape({}).isRequired,
  showTemplateControlBar: bool.isRequired,
  inPresentationMode: bool.isRequired,
  handleClickPresentationButton: func,
  cellQueryStatus: shape({
    queryID: string,
    status: shape(),
  }).isRequired,
  errorThrown: func,
}

const mapStateToProps = state => {
  const {
    app: {
      ephemeral: {inPresentationMode},
      persisted: {autoRefresh, showTemplateControlBar},
    },
    dashboardUI: {dashboards, timeRange, cellQueryStatus},
  } = state

  return {
    dashboards,
    autoRefresh,
    timeRange,
    showTemplateControlBar,
    inPresentationMode,
    cellQueryStatus,
  }
}

const mapDispatchToProps = dispatch => ({
  handleChooseAutoRefresh: bindActionCreators(setAutoRefresh, dispatch),
  templateControlBarVisibilityToggled: bindActionCreators(
    templateControlBarVisibilityToggledAction,
    dispatch
  ),
  handleClickPresentationButton: presentationButtonDispatcher(dispatch),
  dashboardActions: bindActionCreators(dashboardActionCreators, dispatch),
  errorThrown: bindActionCreators(errorThrownAction, dispatch),
})

export default connect(mapStateToProps, mapDispatchToProps)(DashboardPage)
<|endoftext|>


<commit_before>$.register({
  rule: {
    host: /^(www\.)?safelinkconverter2\.com$/,
    path: /^\/decrypt-\d\/$/,
    query: /id=(\w+==)/,
  },
  ready: function (m) {
    'use strict';

    $.openLink(window.atob(m.query[1]));
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<commit_msg>safelinkconverter2.com<commit_after>$.register({
  rule: {
    host: /^(www\.)?safelinkconverter2\.com$/,
    path: /^\/decrypt-\d\/$/,
    query: /id=(\w+=+)/,
  },
  start: function (m) {
    'use strict';

    $.get('https://decrypt.safelinkconverter.com/index.php' + window.location.search, {}, function (html) {
      var m = html.match(/3;URL=([^"]+)/);
      if (!m) {
        _.warn('pattern changed');
        return;
      }
      $.openLink(m[1]);
    });
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<|endoftext|>