<commit_before>'use strict';

var fs = require('fs'),
    path = require('path'),
    expat = require('node-expat')

var RenameHandler = function (dir, encoding) {
    this.dir = dir
    this.encoding = encoding
    this.errorHandler = function (error) {
        console.error(error)
    }
}

RenameHandler.prototype.parsePackageName = function (filename) {
    var self = this
    var filepath = path.join(this.dir, filename)

    // sax parse xml file
    var parser = new expat.Parser(this.encoding)
    parser.on('startElement', function (name, attrs) {
        if (name.match(/manifest/i)) {
            console.log('found oldPackageName => ' + attrs.package)
            self.oldPackageName = attrs.package
        }
    })

    parser.on('error', this.errorHandler)
    parser.write(fs.readFileSync(filepath))
}

RenameHandler.prototype.parseResource = function (filename) {
    // cache file to memory
    var filepath = path.join(this.dir, filename)
    var content = fs.readFileSync(filepath)

    // sax parse xml file
    var parser = new expat.Parser(this.encoding)
    parser.on('startElement', function (name, attrs) {
        for(var attrName in attrs) {
            if (attrName.match(/^xmlns:/i)) {
                console.log('found xml define: ' + attrName + " => " + attrs[attrName])
            }
        }
    })

    parser.on('error', this.errorHandler)
    parser.write(content)
}

RenameHandler.prototype.parseAndroidManifest = function (filename) {
    // cache file to memory
    var filepath = path.join(this.dir, filename)
    var content = fs.readFileSync(filepath)

    // sax parse xml file
    var parser = new expat.Parser(this.encoding)
    parser.on('startElement', function (name, attrs) {
        for(var attrName in attrs) {
            if (attrName.match(/^xmlns:/i)) {
                console.log('found xml define: ' + attrName + " => " + attrs[attrName])
            }
        }
    })

    parser.on('error', this.errorHandler)
    parser.write(content)
}

RenameHandler.prototype.parseJava = function(filename) {

}

module.exports = RenameHandler
<commit_msg>add comment and parseAndroidManifest and parseJava<commit_after>'use strict';

var fs = require('fs'),
    path = require('path'),
    expat = require('node-expat')

var RenameHandler = function (dir, encoding) {
    this.dir = dir
    this.encoding = encoding
    this.errorHandler = function (error) {
        console.error(error)
    }
}

// parse package name from android manifest file
// then set the value to `this.oldPackageName`
RenameHandler.prototype.parsePackageName = function (filename) {
    var self = this
    var filepath = path.join(this.dir, filename)

    // sax parse xml file
    var parser = new expat.Parser(this.encoding)
    parser.on('startElement', function (name, attrs) {
        if (name.match(/manifest/i)) {
            console.log('found oldPackageName => ' + attrs.package)
            self.oldPackageName = attrs.package
        }
    })

    parser.on('error', this.errorHandler)
    parser.write(fs.readFileSync(filepath))
}

// parse resource to list all the modify point about custom xmlns defines
// almost it's a layout resource file
RenameHandler.prototype.parseResource = function (filename) {
    // cache file to memory
    var filepath = path.join(this.dir, filename)
    var content = fs.readFileSync(filepath)

    // sax parse xml file
    var parser = new expat.Parser(this.encoding)
    parser.on('startElement', function (name, attrs) {
        for(var attrName in attrs) {
            if (attrName.match(/^xmlns:/i)) {
                console.log('found xml define: ' + attrName + " => " + attrs[attrName])
            }
        }
    })

    parser.on('error', this.errorHandler)
    parser.write(content)
}

// parse android manifest to list all the modify point about authorities of provider and action
RenameHandler.prototype.parseAndroidManifest = function (filename) {
    // cache file to memory
    var filepath = path.join(this.dir, filename)
    var content = fs.readFileSync(filepath)

    // sax parse xml file
    var parser = new expat.Parser(this.encoding)
    parser.on('startElement', function (name, attrs) {
        for(var attrName in attrs) {
            if (attrName.match(/provider/i)) {
                if (attrs['android:authorities'] !== undefined) {
                    console.log('found provider authorities need to modify => ' + attrs['android:authorities'])
                } else {
                    console.log('found provider need to add a special authorities => ' + attrs['android:name'])
                }
            } else if (attrName.match(/action/i)) {
                if (attrs['android:name'] !== undefined) {
                    // this action is not a system action
                    if (attrs['android:name'].match(/^com\.android\.intent\.action\./)) {
                        console.log('found action need to change => ' + attrs['android:name'])
                    }
                }
            }
        }
    })

    parser.on('error', this.errorHandler)
    parser.write(content)
}

// parse java file to list all the modify point about import line which is .R and .BuildConfig
RenameHandler.prototype.parseJava = function(filename) {
    // cache file to memory
    var filepath = path.join(this.dir, filename)
    var content = fs.readFileSync(filepath)
    var lines = content.split('\n')

    // read each line
    for(var i = 0; i < lines.count; i++) {
        // filter import define line
        var importClass = lines[i].match(/^\s*import (.*);/)
        if (importClass) {
            if (importClass[1].match(this.oldPackageName + '.R')) {
                console.log('found import line need to change => ' + this.oldPackageName + '.R')
            } else if (importClass[1].match(this.oldPackageName + '.BuildConfig')) {
                console.log('found import line need to change => ' + this.oldPackageName + '.BuildConfig')
            }
        }
    }
}

module.exports = RenameHandler
<|endoftext|>


<commit_before>#!/usr/bin/env node
var
  captains = require('captains-log'),
  rc = require('rc'),
  Kuzzle = require('../lib');

module.exports = function () {
  var log = captains();
  log.info('Starting Kuzzle');

  Kuzzle.start(rc('kuzzle'));
};<commit_msg>report same logic to bin/kuzzle-start.js<commit_after>#!/usr/bin/env node
var
  captains = require('captains-log'),
  rc = require('rc'),
  Kuzzle = require('../lib');

module.exports = function () {
  var log = captains();
  log.info('Starting Kuzzle');

  Kuzzle.start(rc('kuzzle'));
  // is a reset has been asked and we are launching a server ?
  if (process.env.LIKE_A_VIRGIN == 1 && process.argv.indexOf('--server') > -1) {

    kuzzle.services.list.writeEngine.reset()
      .then(function(){
        kuzzle.log.info('Reset done: Kuzzle is now like a virgin, touched for the very first time !');
      })
      .catch(function(){
        kuzzle.log.error('Oops... something really bad happened during reset...');
      })
    ;
  }
};<|endoftext|>


<commit_before>$('#calendar').fullCalendar({
  editable: true,
  header: {
    left: 'prev,next today',
    center: 'title',
    right: 'month,agendaWeek,agendaDay'
  },
  defaultView: 'month',
  height: 500,
  slotMinutes: 15,

  loading: function(bool){
    if (bool)
      showSpinner();
    else
      hideSpinner();
  },

  eventRender: function(event) {
    removeUnread("event", [event.id]);
  },

  buttonText: {
    today:    'Heute',
    month:    'Monat',
    week:     'Woche',
    day:      'Tag'
  },

  monthNames: [
    'Januar',
    'Februar',
    'März',
    'April',
    'Mai',
    'Juni',
    'Juli',
    'August',
    'September',
    'Oktober',
    'November',
    'Dezember'
  ],

  monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sept','Okt','Nov','Dez'],

  dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],

  dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],

  allDayText: "ganztägig",

  weekNumberTitle: "KW",

  axisFormat: 'HH:mm',

  weekNumbers: true,

  firstDay: 1,

  lang: "de",

  // a future calendar might have many sources.
  eventSources: [{
    url: '/events',
    ignoreTimezone: false
  }],

  //http://arshaw.com/fullcalendar/docs/event_ui/eventDrop/
  eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc){
    updateEvent(event);
  },

  // http://arshaw.com/fullcalendar/docs/event_ui/eventResize/
  eventResize: function(event, dayDelta, minuteDelta, revertFunc){
    updateEvent(event);
  },

  // http://arshaw.com/fullcalendar/docs/mouse/dayClick/
  dayClick: function(date, allDay, jsEvent, view){
    window.location = "/events/new?start=" + date / 1000;
  },
});

var updateEvent = function(the_event) {
  $.ajax({
    url:  "/events/" + the_event.id,
    type: 'PUT',
    contentType: 'application/json',
    data: JSON.stringify({
      event: {
        starts_at: "" + the_event.start.toISOString(),
        ends_at: "" + the_event.end.toISOString()
      }
    }),
    dataType: 'json'
  });
};<commit_msg>Interpret timezones in calendar correctly<commit_after>$('#calendar').fullCalendar({
  editable: true,
  header: {
    left: 'prev,next today',
    center: 'title',
    right: 'month,agendaWeek,agendaDay'
  },
  defaultView: 'month',
  height: 500,
  slotMinutes: 15,

  loading: function(bool){
    if (bool)
      showSpinner();
    else
      hideSpinner();
  },

  eventRender: function(event) {
    removeUnread("event", [event.id]);
  },

  buttonText: {
    today:    'Heute',
    month:    'Monat',
    week:     'Woche',
    day:      'Tag'
  },

  monthNames: [
    'Januar',
    'Februar',
    'März',
    'April',
    'Mai',
    'Juni',
    'Juli',
    'August',
    'September',
    'Oktober',
    'November',
    'Dezember'
  ],

  monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sept','Okt','Nov','Dez'],

  dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],

  dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],

  allDayText: "ganztägig",

  weekNumberTitle: "KW",

  axisFormat: 'HH:mm',

  weekNumbers: true,

  firstDay: 1,

  lang: "de",

  timezone: 'UTC',

  // a future calendar might have many sources.
  eventSources: [{
    url: '/events'
  }],

  //http://arshaw.com/fullcalendar/docs/event_ui/eventDrop/
  eventDrop: function(event, dayDelta, minuteDelta, allDay, revertFunc){
    updateEvent(event);
  },

  // http://arshaw.com/fullcalendar/docs/event_ui/eventResize/
  eventResize: function(event, dayDelta, minuteDelta, revertFunc){
    updateEvent(event);
  },

  // http://arshaw.com/fullcalendar/docs/mouse/dayClick/
  dayClick: function(date, allDay, jsEvent, view){
    window.location = "/events/new?start=" + date / 1000;
  },
});

var updateEvent = function(the_event) {
  $.ajax({
    url:  "/events/" + the_event.id,
    type: 'PUT',
    contentType: 'application/json',
    data: JSON.stringify({
      event: {
        starts_at: "" + the_event.start.toISOString(),
        ends_at: "" + the_event.end.toISOString()
      }
    }),
    dataType: 'json'
  });
};<|endoftext|>


<commit_before>(function() {
  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  this.FilesCommentButton = (function() {
    var COMMENT_BUTTON_CLASS, COMMENT_BUTTON_TEMPLATE, DEBOUNCE_TIMEOUT_DURATION, EMPTY_CELL_CLASS, LINE_COLUMN_CLASSES, LINE_CONTENT_CLASS, LINE_HOLDER_CLASS, LINE_NUMBER_CLASS, OLD_LINE_CLASS, TEXT_FILE_SELECTOR, UNFOLDABLE_LINE_CLASS;

    COMMENT_BUTTON_CLASS = '.add-diff-note';

    COMMENT_BUTTON_TEMPLATE = _.template('<button name="button" type="submit" class="btn <%- COMMENT_BUTTON_CLASS %> js-add-diff-note-button" title="Add a comment to this line"></button>');

    LINE_HOLDER_CLASS = '.line_holder';

    LINE_NUMBER_CLASS = 'diff-line-num';

    LINE_CONTENT_CLASS = 'line_content';

    UNFOLDABLE_LINE_CLASS = 'js-unfold';

    EMPTY_CELL_CLASS = 'empty-cell';

    OLD_LINE_CLASS = 'old_line';

    LINE_COLUMN_CLASSES = "." + LINE_NUMBER_CLASS + ", .line_content";

    TEXT_FILE_SELECTOR = '.text-file';

    DEBOUNCE_TIMEOUT_DURATION = 100;

    function FilesCommentButton(filesContainerElement) {
      var debounce;
      this.filesContainerElement = filesContainerElement;
      this.destroy = bind(this.destroy, this);
      this.render = bind(this.render, this);
      this.VIEW_TYPE = $('input#view[type=hidden]').val();
      debounce = _.debounce(this.render, DEBOUNCE_TIMEOUT_DURATION);
      $(document).off('mouseover', LINE_COLUMN_CLASSES).off('mouseleave', LINE_COLUMN_CLASSES).on('mouseover', LINE_COLUMN_CLASSES, debounce).on('mouseleave', LINE_COLUMN_CLASSES, this.destroy);
    }

    FilesCommentButton.prototype.render = function(e) {
      var $currentTarget, buttonParentElement, lineContentElement, textFileElement;
      $currentTarget = $(e.currentTarget);
      buttonParentElement = this.getButtonParent($currentTarget);
      if (!this.shouldRender(e, buttonParentElement)) {
        return;
      }
      textFileElement = this.getTextFileElement($currentTarget);
      lineContentElement = this.getLineContent($currentTarget);
      buttonParentElement.append(this.buildButton({
        noteableType: textFileElement.attr('data-noteable-type'),
        noteableID: textFileElement.attr('data-noteable-id'),
        commitID: textFileElement.attr('data-commit-id'),
        noteType: lineContentElement.attr('data-note-type'),
        position: lineContentElement.attr('data-position'),
        lineType: lineContentElement.attr('data-line-type'),
        discussionID: lineContentElement.attr('data-discussion-id'),
        lineCode: lineContentElement.attr('data-line-code')
      }));
    };

    FilesCommentButton.prototype.destroy = function(e) {
      if (this.isMovingToSameType(e)) {
        return;
      }
      $(COMMENT_BUTTON_CLASS, this.getButtonParent($(e.currentTarget))).remove();
    };

    FilesCommentButton.prototype.buildButton = function(buttonAttributes) {
      var initializedButtonTemplate;
      initializedButtonTemplate = COMMENT_BUTTON_TEMPLATE({
        COMMENT_BUTTON_CLASS: COMMENT_BUTTON_CLASS.substr(1)
      });
      return $(initializedButtonTemplate).attr({
        'data-noteable-type': buttonAttributes.noteableType,
        'data-noteable-id': buttonAttributes.noteableID,
        'data-commit-id': buttonAttributes.commitID,
        'data-note-type': buttonAttributes.noteType,
        'data-line-code': buttonAttributes.lineCode,
        'data-position': buttonAttributes.position,
        'data-discussion-id': buttonAttributes.discussionID,
        'data-line-type': buttonAttributes.lineType
      });
    };

    FilesCommentButton.prototype.getTextFileElement = function(hoveredElement) {
      return $(hoveredElement.closest(TEXT_FILE_SELECTOR));
    };

    FilesCommentButton.prototype.getLineContent = function(hoveredElement) {
      if (hoveredElement.hasClass(LINE_CONTENT_CLASS)) {
        return hoveredElement;
      }
      if (this.VIEW_TYPE === 'inline') {
        return $(hoveredElement).closest(LINE_HOLDER_CLASS).find("." + LINE_CONTENT_CLASS);
      } else {
        return $(hoveredElement).next("." + LINE_CONTENT_CLASS);
      }
    };

    FilesCommentButton.prototype.getButtonParent = function(hoveredElement) {
      if (this.VIEW_TYPE === 'inline') {
        if (hoveredElement.hasClass(OLD_LINE_CLASS)) {
          return hoveredElement;
        }
        return hoveredElement.parent().find("." + OLD_LINE_CLASS);
      } else {
        if (hoveredElement.hasClass(LINE_NUMBER_CLASS)) {
          return hoveredElement;
        }
        return $(hoveredElement).prev("." + LINE_NUMBER_CLASS);
      }
    };

    FilesCommentButton.prototype.isMovingToSameType = function(e) {
      var newButtonParent;
      newButtonParent = this.getButtonParent($(e.toElement));
      if (!newButtonParent) {
        return false;
      }
      return newButtonParent.is(this.getButtonParent($(e.currentTarget)));
    };

    FilesCommentButton.prototype.shouldRender = function(e, buttonParentElement) {
      return !buttonParentElement.hasClass(EMPTY_CELL_CLASS) && !buttonParentElement.hasClass(UNFOLDABLE_LINE_CLASS) && $(COMMENT_BUTTON_CLASS, buttonParentElement).length === 0;
    };

    return FilesCommentButton;

  })();

  $.fn.filesCommentButton = function() {
    if (!(this && (this.parent().data('can-create-note') != null))) {
      return;
    }
    return this.each(function() {
      if (!$.data(this, 'filesCommentButton')) {
        return $.data(this, 'filesCommentButton', new FilesCommentButton($(this)));
      }
    });
  };

}).call(this);
<commit_msg>Don't show comment button in gutter of diffs on MR discussion tab<commit_after>(function() {
  var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  this.FilesCommentButton = (function() {
    var COMMENT_BUTTON_CLASS, COMMENT_BUTTON_TEMPLATE, DEBOUNCE_TIMEOUT_DURATION, EMPTY_CELL_CLASS, LINE_COLUMN_CLASSES, LINE_CONTENT_CLASS, LINE_HOLDER_CLASS, LINE_NUMBER_CLASS, OLD_LINE_CLASS, TEXT_FILE_SELECTOR, UNFOLDABLE_LINE_CLASS;

    COMMENT_BUTTON_CLASS = '.add-diff-note';

    COMMENT_BUTTON_TEMPLATE = _.template('<button name="button" type="submit" class="btn <%- COMMENT_BUTTON_CLASS %> js-add-diff-note-button" title="Add a comment to this line"></button>');

    LINE_HOLDER_CLASS = '.line_holder';

    LINE_NUMBER_CLASS = 'diff-line-num';

    LINE_CONTENT_CLASS = 'line_content';

    UNFOLDABLE_LINE_CLASS = 'js-unfold';

    EMPTY_CELL_CLASS = 'empty-cell';

    OLD_LINE_CLASS = 'old_line';

    LINE_COLUMN_CLASSES = "." + LINE_NUMBER_CLASS + ", .line_content";

    TEXT_FILE_SELECTOR = '.text-file';

    DEBOUNCE_TIMEOUT_DURATION = 100;

    function FilesCommentButton(filesContainerElement) {
      var debounce;
      this.filesContainerElement = filesContainerElement;
      this.destroy = bind(this.destroy, this);
      this.render = bind(this.render, this);
      this.VIEW_TYPE = $('input#view[type=hidden]').val();
      debounce = _.debounce(this.render, DEBOUNCE_TIMEOUT_DURATION);
      $(this.filesContainerElement).off('mouseover', LINE_COLUMN_CLASSES).off('mouseleave', LINE_COLUMN_CLASSES).on('mouseover', LINE_COLUMN_CLASSES, debounce).on('mouseleave', LINE_COLUMN_CLASSES, this.destroy);
    }

    FilesCommentButton.prototype.render = function(e) {
      var $currentTarget, buttonParentElement, lineContentElement, textFileElement;
      $currentTarget = $(e.currentTarget);
      buttonParentElement = this.getButtonParent($currentTarget);
      if (!this.shouldRender(e, buttonParentElement)) {
        return;
      }
      textFileElement = this.getTextFileElement($currentTarget);
      lineContentElement = this.getLineContent($currentTarget);
      buttonParentElement.append(this.buildButton({
        noteableType: textFileElement.attr('data-noteable-type'),
        noteableID: textFileElement.attr('data-noteable-id'),
        commitID: textFileElement.attr('data-commit-id'),
        noteType: lineContentElement.attr('data-note-type'),
        position: lineContentElement.attr('data-position'),
        lineType: lineContentElement.attr('data-line-type'),
        discussionID: lineContentElement.attr('data-discussion-id'),
        lineCode: lineContentElement.attr('data-line-code')
      }));
    };

    FilesCommentButton.prototype.destroy = function(e) {
      if (this.isMovingToSameType(e)) {
        return;
      }
      $(COMMENT_BUTTON_CLASS, this.getButtonParent($(e.currentTarget))).remove();
    };

    FilesCommentButton.prototype.buildButton = function(buttonAttributes) {
      var initializedButtonTemplate;
      initializedButtonTemplate = COMMENT_BUTTON_TEMPLATE({
        COMMENT_BUTTON_CLASS: COMMENT_BUTTON_CLASS.substr(1)
      });
      return $(initializedButtonTemplate).attr({
        'data-noteable-type': buttonAttributes.noteableType,
        'data-noteable-id': buttonAttributes.noteableID,
        'data-commit-id': buttonAttributes.commitID,
        'data-note-type': buttonAttributes.noteType,
        'data-line-code': buttonAttributes.lineCode,
        'data-position': buttonAttributes.position,
        'data-discussion-id': buttonAttributes.discussionID,
        'data-line-type': buttonAttributes.lineType
      });
    };

    FilesCommentButton.prototype.getTextFileElement = function(hoveredElement) {
      return $(hoveredElement.closest(TEXT_FILE_SELECTOR));
    };

    FilesCommentButton.prototype.getLineContent = function(hoveredElement) {
      if (hoveredElement.hasClass(LINE_CONTENT_CLASS)) {
        return hoveredElement;
      }
      if (this.VIEW_TYPE === 'inline') {
        return $(hoveredElement).closest(LINE_HOLDER_CLASS).find("." + LINE_CONTENT_CLASS);
      } else {
        return $(hoveredElement).next("." + LINE_CONTENT_CLASS);
      }
    };

    FilesCommentButton.prototype.getButtonParent = function(hoveredElement) {
      if (this.VIEW_TYPE === 'inline') {
        if (hoveredElement.hasClass(OLD_LINE_CLASS)) {
          return hoveredElement;
        }
        return hoveredElement.parent().find("." + OLD_LINE_CLASS);
      } else {
        if (hoveredElement.hasClass(LINE_NUMBER_CLASS)) {
          return hoveredElement;
        }
        return $(hoveredElement).prev("." + LINE_NUMBER_CLASS);
      }
    };

    FilesCommentButton.prototype.isMovingToSameType = function(e) {
      var newButtonParent;
      newButtonParent = this.getButtonParent($(e.toElement));
      if (!newButtonParent) {
        return false;
      }
      return newButtonParent.is(this.getButtonParent($(e.currentTarget)));
    };

    FilesCommentButton.prototype.shouldRender = function(e, buttonParentElement) {
      return !buttonParentElement.hasClass(EMPTY_CELL_CLASS) && !buttonParentElement.hasClass(UNFOLDABLE_LINE_CLASS) && $(COMMENT_BUTTON_CLASS, buttonParentElement).length === 0;
    };

    return FilesCommentButton;

  })();

  $.fn.filesCommentButton = function() {
    if (!(this && (this.parent().data('can-create-note') != null))) {
      return;
    }
    return this.each(function() {
      if (!$.data(this, 'filesCommentButton')) {
        return $.data(this, 'filesCommentButton', new FilesCommentButton($(this)));
      }
    });
  };

}).call(this);
<|endoftext|>


<commit_before>
// If the user hits a button while we are waiting for an update
// we get a data discrepancy, because he will submit it with an
// old value of the time. So we disable the buttons while doing an
// autosave. Because Javascript doesn't have a sleep, we can't
// just delay the submit.
//    This array is a list of the buttons we have disabled.
// It doesn't include anything that was already disabled.

var disabledButtons = [];

// confirm box needs to disable autosave temporarily

var doautosave = true;

//    Links are more difficult, as there isn't a disabled
// attribute for them. Currently I clear onmouseup and onclick.
//    I've tried to make this script generic, but if it is
// used with other jsp's, you may need to save and restore additional
// attributes of the links. If it's used on a page where they don't
// have id's you'll need another way to identify them.
//    disabledLinks is a list of triples, [id, onmouseup, onclick]

var disabledLinks = [];

function GetFormContent(formId, buttonName) {
    var theForm = document.getElementById(formId);
    var elements = theForm.elements;
    var pairs = [];
    disabledButtons = [];
    for (var i=0; i<elements.length; i++) {
        var elt = elements[i]
        var name = elt.name;
        var type = typeof(elt.type)=='string' ? elt.type.toLowerCase() : '';
        var value = elt.value;
        var encoded = encodeURIComponent(name)+"="+encodeURIComponent(value);
	if (type == "submit" && !elt.disabled) {
	    // save name of buttons we are disabling, and disable
	    disabledButtons.push(name);
	    elt.disabled = true;
        }
        if (type != "submit" &&
	    !((type == "radio" || type == "checkbox") && !elt.checked)){
	    pairs.push(encoded);
  	}
    }
    // save attributes and disable links
    disabledLinks = [];
    for (var i=0; i < document.links.length; i++){
	var link = document.links[i];
	if (link.id != null && link.id != "" && link.onclick != null) {
	    disabledLinks.push([link.id, link.onmouseup, link.onclick]);
	    link.onmouseup = null;
	    link.onclick = null;
	}
    }
    pairs.push(encodeURIComponent(buttonName)+"="+encodeURIComponent("true"));
    //    alert(pairs.join("&"));
    return pairs.join("&");
}

var counter = 0

function SaveFormContentAsync(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds, ok ) {
    if (!ok) {
		return;
    }

	if (repeatMilliseconds == -1) {
		return;
	}

    // asyncronously send form content to toUrl, wait for response, sleep, repeat
    //    var theStatus = document.getElementById(statusId);
    counter += 1;
    //    theStatus.innerHTML = "count "+counter+" saving form at "+Date();
    var request = initXMLHTTPRequest();
    var method = "POST";
    var async = true;
    var payload;
    function onready_callback() {
	var state = request.readyState;
	if (state!=4) {
	    // ignore intermediate states
	    return;
	}
	    // This is an Ajax response. It isn't normally processed.
	// So if we need anything from it we have to get it.
	// Get new date from response and update the form variable

	var saveok = true;
	var text = request.responseText;
        var i = text.indexOf('"' + updateVar);
	if (i < 0) {
	    i = text.indexOf('"' + updateVar2);
	}
	var j = -1;
        if (i >= 0) {
	    i = text.indexOf("value=", i);
	}
	if (i >= 0) {
	    j = text.indexOf('"', i+7);
	}
	if (j >= 0) {
	    var d = text.substring(i+7, j);
	    if (document.forms[0].elements[updateVar] != null) {
		document.forms[0].elements[updateVar].value = d;
	    } else if (document.forms[0].elements[updateVar2] != null) {
		document.forms[0].elements[updateVar2].value = d;
	    } else {
		saveok = false;
	    }
	} else {
	    saveok = false;
	}
	// Now that we have the updated date, it's safe for the user to do submits.
	// Reenable any buttons we disabled.

	for (var i=0; i<disabledButtons.length; i++) {
	    document.forms[0].elements[disabledButtons[i]].disabled=false;
	}

	// And links

	for (var i=0; i<disabledLinks.length; i++) {
	    var item = disabledLinks[i];
	    var link = document.getElementById(item[0]);
	    link.onmouseup = item[1];
	    link.onclick = item[2];
	}
	//	theStatus.innerHTML = "count "+counter+" save complete at "+Date();
        // wait and then call save form again
	if (saveok) {
	    var onTimeout = TimeOutAction(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds);
	    setTimeout(onTimeout, repeatMilliseconds);
	} else {
	    //alert("Attempt to save your work automatically failed. One common cause is that you have a second window open on Tests and Quizes. We strongly suggest that you not continue working in this window. If you go to the top level of Tests and Quizes, you can restart this test or quiz.");
	}
	window.status = "";

        // when the request is done the scope of the function can be garbage collected...
    }
    if (doautosave && counter > 1) {
	payload = GetFormContent(formId, buttonName);
	request.open(method, toUrl, async);
	request.onreadystatechange = onready_callback;
	request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	//alert("about to send");
	window.status = "Saving...";
	request.send(payload);
    } else {
	//alert("first time" + 	    document.forms[0].elements['takeAssessmentForm:lastSubmittedDate1'].value);
        var onTimeout = TimeOutAction(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds);
        setTimeout(onTimeout, repeatMilliseconds);
    }

    // onready_callback called on request response.
}

function TimeOutAction(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds) {
    function ActionResult() {
	SaveFormContentAsync(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds, true);
    }
    return ActionResult;
}

function initXMLHTTPRequest() {
        var result = null;
        if (window.XMLHttpRequest) {
                ////al("xmlhttp");
                result = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
                ////al("microsoft");
                result = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
                throw new Error("failed to create XMLHTTPRequest");
        }
        return result;
}

<commit_msg>SAM-2481<commit_after>
// If the user hits a button while we are waiting for an update
// we get a data discrepancy, because he will submit it with an
// old value of the time. So we disable the buttons while doing an
// autosave. Because Javascript doesn't have a sleep, we can't
// just delay the submit.
//    This array is a list of the buttons we have disabled.
// It doesn't include anything that was already disabled.

var disabledButtons = [];

// confirm box needs to disable autosave temporarily

var doautosave = true;

//    Links are more difficult, as there isn't a disabled
// attribute for them. Currently I clear onmouseup and onclick.
//    I've tried to make this script generic, but if it is
// used with other jsp's, you may need to save and restore additional
// attributes of the links. If it's used on a page where they don't
// have id's you'll need another way to identify them.
//    disabledLinks is a list of triples, [id, onmouseup, onclick]

var disabledLinks = [];

function GetFormContent(formId, buttonName) {
    var theForm = document.getElementById(formId);
    var elements = theForm.elements;
    var pairs = [];
    disabledButtons = [];
    //autosave for ckeditor
    for(var i in CKEDITOR.instances) {
        var encoded = encodeURIComponent(CKEDITOR.instances[i].name)+"="+encodeURIComponent(CKEDITOR.instances[i].getSnapshot());
        pairs.push(encoded);
    }
    for (var i=0; i<elements.length; i++) {
        var elt = elements[i]
        var name = elt.name;
        var type = typeof(elt.type)=='string' ? elt.type.toLowerCase() : '';
        var value = elt.value;
        var encoded = encodeURIComponent(name)+"="+encodeURIComponent(value);
	if (type == "submit" && !elt.disabled) {
	    // save name of buttons we are disabling, and disable
	    disabledButtons.push(name);
	    elt.disabled = true;
        }
        if (type != "submit" &&
	    !((type == "radio" || type == "checkbox") && !elt.checked)){
	    pairs.push(encoded);
  	}
    }
    // save attributes and disable links
    disabledLinks = [];
    for (var i=0; i < document.links.length; i++){
	var link = document.links[i];
	if (link.id != null && link.id != "" && link.onclick != null) {
	    disabledLinks.push([link.id, link.onmouseup, link.onclick]);
	    link.onmouseup = null;
	    link.onclick = null;
	}
    }
    pairs.push(encodeURIComponent(buttonName)+"="+encodeURIComponent("true"));
    //    alert(pairs.join("&"));
    return pairs.join("&");
}

var counter = 0

function SaveFormContentAsync(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds, ok ) {
    if (!ok) {
		return;
    }

	if (repeatMilliseconds == -1) {
		return;
	}

    // asyncronously send form content to toUrl, wait for response, sleep, repeat
    //    var theStatus = document.getElementById(statusId);
    counter += 1;
    //    theStatus.innerHTML = "count "+counter+" saving form at "+Date();
    var request = initXMLHTTPRequest();
    var method = "POST";
    var async = true;
    var payload;
    function onready_callback() {
	var state = request.readyState;
	if (state!=4) {
	    // ignore intermediate states
	    return;
	}
	    // This is an Ajax response. It isn't normally processed.
	// So if we need anything from it we have to get it.
	// Get new date from response and update the form variable

	var saveok = true;
	var text = request.responseText;
        var i = text.indexOf('"' + updateVar);
	if (i < 0) {
	    i = text.indexOf('"' + updateVar2);
	}
	var j = -1;
        if (i >= 0) {
	    i = text.indexOf("value=", i);
	}
	if (i >= 0) {
	    j = text.indexOf('"', i+7);
	}
	if (j >= 0) {
	    var d = text.substring(i+7, j);
	    if (document.forms[0].elements[updateVar] != null) {
		document.forms[0].elements[updateVar].value = d;
	    } else if (document.forms[0].elements[updateVar2] != null) {
		document.forms[0].elements[updateVar2].value = d;
	    } else {
		saveok = false;
	    }
	} else {
	    saveok = false;
	}
	// Now that we have the updated date, it's safe for the user to do submits.
	// Reenable any buttons we disabled.

	for (var i=0; i<disabledButtons.length; i++) {
	    document.forms[0].elements[disabledButtons[i]].disabled=false;
	}

	// And links

	for (var i=0; i<disabledLinks.length; i++) {
	    var item = disabledLinks[i];
	    var link = document.getElementById(item[0]);
	    link.onmouseup = item[1];
	    link.onclick = item[2];
	}
	//	theStatus.innerHTML = "count "+counter+" save complete at "+Date();
        // wait and then call save form again
	if (saveok) {
	    var onTimeout = TimeOutAction(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds);
	    setTimeout(onTimeout, repeatMilliseconds);
	} else {
	    //alert("Attempt to save your work automatically failed. One common cause is that you have a second window open on Tests and Quizes. We strongly suggest that you not continue working in this window. If you go to the top level of Tests and Quizes, you can restart this test or quiz.");
	}
	window.status = "";

        // when the request is done the scope of the function can be garbage collected...
    }
    if (doautosave && counter > 1) {
	payload = GetFormContent(formId, buttonName);
	request.open(method, toUrl, async);
	request.onreadystatechange = onready_callback;
	request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	//alert("about to send");
	window.status = "Saving...";
	request.send(payload);
    } else {
	//alert("first time" + 	    document.forms[0].elements['takeAssessmentForm:lastSubmittedDate1'].value);
        var onTimeout = TimeOutAction(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds);
        setTimeout(onTimeout, repeatMilliseconds);
    }

    // onready_callback called on request response.
}

function TimeOutAction(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds) {
    function ActionResult() {
	SaveFormContentAsync(toUrl, formId, buttonName, updateVar, updateVar2, repeatMilliseconds, true);
    }
    return ActionResult;
}

function initXMLHTTPRequest() {
        var result = null;
        if (window.XMLHttpRequest) {
                ////al("xmlhttp");
                result = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
                ////al("microsoft");
                result = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
                throw new Error("failed to create XMLHTTPRequest");
        }
        return result;
}

<|endoftext|>


<commit_before>/* global SETTINGS:false */
import React from 'react';
import Dialog from 'material-ui/Dialog';
import { connect } from 'react-redux';
import R from 'ramda';
import TextField from 'material-ui/TextField';
import Checkbox from 'react-mdl/lib/Checkbox';
import Select from 'react-select';
import _ from 'lodash';

import { FETCH_PROCESSING } from '../actions';
import {
  updateCalculatorEdit,
  clearCalculatorEdit,
  addFinancialAid,
  updateCalculatorValidation,
} from '../actions/financial_aid';
import {
  setConfirmSkipDialogVisibility,
  showDialog,
  hideDialog,
} from '../actions/ui';
import { createSimpleActionHelpers } from '../lib/redux';
import { currencyOptions } from '../lib/currency';
import { validateFinancialAid } from '../lib/validation/profile';
import type { AvailableProgram } from '../flow/enrollmentTypes';
import type {
  FinancialAidState,
  FinancialAidValidation,
  FetchError,
} from '../reducers/financial_aid';
import type { Program } from '../flow/programTypes';
import { formatPrice } from '../util/util';
import { dialogActions } from '../components/inputs/util';
import { getOwnDashboard } from '../reducers/util';

export const CALCULATOR_DIALOG = 'CALCULATOR_DIALOG';

export const INCOME_DIALOG = 'INCOME_DIALOG';

const updateCurrency = R.curry((update, financialAid, selection) => {
  let _financialAid = R.clone(financialAid);
  _financialAid.currency = selection ? selection.value : null;
  update(_financialAid);
});

const currencySelect = (update, current) => (
  <Select
    options={currencyOptions}
    clearable={false}
    value={current.currency}
    onChange={updateCurrency(update, current)}
    name="currency"
    id="currency-select"
    inputProps={{
      'aria-required': "true",
      'aria-invalid': _.has(current, ['validation', 'currency'])
    }}
  />
);

const salaryUpdate = R.curry((update, current, e) => {
  let newEdit = R.clone(current);
  newEdit.income = e.target.value;
  update(newEdit);
});

const salaryField = (update, current) => (
  <TextField
    name="salary"
    aria-required="true"
    aria-invalid={_.has(current, ['validation', 'income'])}
    label="income (yearly)"
    id="user-salary-input"
    className="salary-field"
    value={current.income}
    fullWidth={true}
    onChange={salaryUpdate(update, current)}
  />
);

const checkboxText = `I testify that the income I reported is true and accurate.
I am aware that I may be asked to verify the reported income with documentation.`;

const checkboxUpdate = (update, current, bool) => {
  let newEdit = R.clone(current);
  newEdit.checkBox = bool;
  update(newEdit);
};

const checkBox = (update, current) => (
  <Checkbox
    checked={current.checkBox}
    required="true"
    aria-invalid={_.has(current, ['validation', 'checkBox'])}
    label={checkboxText}
    onChange={() => checkboxUpdate(update, current, !current.checkBox)}
  />
);

const calculatorActions = (openSkipDialog, cancel, save, fetchAddStatus, fetchSkipStatus) => {
  return

    <button className="mm-minor-action full-price" onClick={openSkipDialog}>
      Skip this and Pay Full Price
    </button>

      { dialogActions(
        cancel,
        save,
        fetchAddStatus === FETCH_PROCESSING,
        'Submit',
        'calculate-cost-button',
        fetchSkipStatus === FETCH_PROCESSING
      ) }

;
};

const validationMessage = (key, errors) => {
  if (errors === undefined || R.isNil(errors[key])) {
    return null;
  }
  return

    { errors[key] }

;
};

const apiError = ({ message, code }: FetchError) => (

    {`There was an error (Error ${code}: ${message}). Please contact `}
    <a href={`mailto:${SETTINGS.support_email}`}>
      {`${SETTINGS.support_email}`}

    {" if you continue to have problems."}

);

type CalculatorProps = {
  calculatorDialogVisibility:    boolean,
  confirmIncomeDialogVisibility: boolean,
  closeDialogAndCancel:          () => void,
  closeConfirmDialogAndCancel:   () => void,
  financialAid:                  FinancialAidState,
  validation:                    FinancialAidValidation,
  saveFinancialAid:              (f: FinancialAidState) => void,
  submitFinancialAid:            (f: FinancialAidState) => void,
  updateCalculatorEdit:          (f: FinancialAidState) => void,
  currentProgramEnrollment:      AvailableProgram,
  openConfirmSkipDialog:         () => void,
  programs:                      Array<Program>,
};

const FinancialAidCalculator = ({
  calculatorDialogVisibility,
  confirmIncomeDialogVisibility,
  closeDialogAndCancel,
  closeConfirmDialogAndCancel,
  financialAid,
  financialAid: {
    validation, fetchError, income, currency, fetchAddStatus, fetchSkipStatus
  },
  saveFinancialAid,
  submitFinancialAid,
  updateCalculatorEdit,
  currentProgramEnrollment: { title, id },
  openConfirmSkipDialog,
  programs,
}: CalculatorProps) => {
  let program = programs.find(prog => prog.id === id);
  if (!program) {
    return null;
  }

  let minPossibleCost, maxPossibleCost;
  if (program.financial_aid_availability) {
    minPossibleCost = formatPrice(program.financial_aid_user_info.min_possible_cost);
    maxPossibleCost = formatPrice(program.financial_aid_user_info.max_possible_cost);
  }
  let confirmDialog = <Dialog
    key="confirm"
    title="Confirm Your Income"
    titleClassName="dialog-title"
    contentClassName="dialog confirm-dialog"
    className="financial-aid-calculator-wrapper"
    open={confirmIncomeDialogVisibility}
    bodyClassName="financial-aid-calculator-body"
    onRequestClose={closeConfirmDialogAndCancel}
    actions={dialogActions(
      closeConfirmDialogAndCancel,
      () => submitFinancialAid(financialAid),
      fetchSkipStatus === FETCH_PROCESSING,
      'Submit',
      'confirm-income-button',
      fetchAddStatus === FETCH_PROCESSING
    )}
  >

Household Income: {currency} {income}

    Please make sure that your household income is accurate and that
    you can provide documentation (if necessary). If you can't provide
    an accurate income at this time, click cancel.
    { fetchError ? apiError(fetchError) : null }
  </Dialog>;

  return

    <Dialog
      title="Personal Course Pricing"
      titleClassName="dialog-title"
      contentClassName="dialog financial-aid-calculator"
      className="financial-aid-calculator-wrapper"
      open={calculatorDialogVisibility}
      bodyClassName="financial-aid-calculator-body"
      autoScrollBodyContent={true}
      onRequestClose={closeDialogAndCancel}
      actions={calculatorActions(
        openConfirmSkipDialog,
        closeDialogAndCancel,
        () => saveFinancialAid(financialAid),
        fetchAddStatus,
        fetchSkipStatus,
      )}
    >

        { `The cost of courses in the ${title} MicroMasters varies between ${minPossibleCost} and ${maxPossibleCost},
        depending on your income and ability to pay.`}

            Income (yearly)
            { salaryField(updateCalculatorEdit, financialAid) }

          { validationMessage('income', validation) }

            Currency

          { currencySelect(updateCalculatorEdit, financialAid) }
          { validationMessage('currency', validation) }

        { checkBox(updateCalculatorEdit, financialAid) }

        { validationMessage('checkBox', validation) }

      { fetchError ? apiError(fetchError) : null }
    </Dialog>
    {confirmDialog}

;
};

const closeDialogAndCancel = dispatch => (
  () => {
    dispatch(hideDialog(CALCULATOR_DIALOG));
    dispatch(clearCalculatorEdit());
  }
);

const closeConfirmDialogAndCancel = dispatch => (
  () => {
    dispatch(hideDialog(INCOME_DIALOG));
    dispatch(clearCalculatorEdit());
  }
);

const updateFinancialAidValidation = (dispatch, current) => {
  let errors = validateFinancialAid(current);
  if (! R.equals(errors, current.validation)) {
    dispatch(updateCalculatorValidation(errors));
  }
  return R.isEmpty(errors);
};

const saveFinancialAid = R.curry((dispatch, current) => {
  let valid = updateFinancialAidValidation(dispatch, current);
  let clone = _.cloneDeep(current);
  delete clone.validation;
  if (valid) {
    dispatch(hideDialog(CALCULATOR_DIALOG));
    dispatch(showDialog(INCOME_DIALOG));
  }
});

const submitFinancialAid = R.curry((dispatch, current) => {
  const { income, currency, programId } = current;
  dispatch(addFinancialAid(income, currency, programId)).then(() => {
    dispatch(hideDialog(INCOME_DIALOG));
    dispatch(clearCalculatorEdit());
  });
});

const updateFinancialAidEdit = R.curry((dispatch, current) => {
  updateFinancialAidValidation(dispatch, current);
  let clone = _.cloneDeep(current);
  delete clone.validation;
  dispatch(updateCalculatorEdit(clone));
});

const openConfirmSkipDialogHelper = dispatch => () => {
  closeDialogAndCancel(dispatch)();
  dispatch(setConfirmSkipDialogVisibility(true));
};

const mapStateToProps = state => {
  const {
    ui,
    financialAid,
    currentProgramEnrollment,
  } = state;
  const { programs } = getOwnDashboard(state);

  return {
    calculatorDialogVisibility: ui.dialogVisibility[CALCULATOR_DIALOG] || false,
    confirmIncomeDialogVisibility: ui.dialogVisibility[INCOME_DIALOG] || false,
    financialAid,
    currentProgramEnrollment,
    programs,
  };
};

const mapDispatchToProps = dispatch => {
  return {
    closeDialogAndCancel: closeDialogAndCancel(dispatch),
    closeConfirmDialogAndCancel: closeConfirmDialogAndCancel(dispatch),
    saveFinancialAid: saveFinancialAid(dispatch),
    submitFinancialAid: submitFinancialAid(dispatch),
    openConfirmSkipDialog: openConfirmSkipDialogHelper(dispatch),
    updateCalculatorEdit: updateFinancialAidEdit(dispatch),
    ...createSimpleActionHelpers(dispatch, [
      ['clearCalculatorEdit', clearCalculatorEdit],
    ]),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(FinancialAidCalculator);
<commit_msg>Fix occasional null reference error when running snapshot_dashboard_states (#3458)<commit_after>/* global SETTINGS:false */
import React from 'react';
import Dialog from 'material-ui/Dialog';
import { connect } from 'react-redux';
import R from 'ramda';
import TextField from 'material-ui/TextField';
import Checkbox from 'react-mdl/lib/Checkbox';
import Select from 'react-select';
import _ from 'lodash';

import { FETCH_PROCESSING } from '../actions';
import {
  updateCalculatorEdit,
  clearCalculatorEdit,
  addFinancialAid,
  updateCalculatorValidation,
} from '../actions/financial_aid';
import {
  setConfirmSkipDialogVisibility,
  showDialog,
  hideDialog,
} from '../actions/ui';
import { createSimpleActionHelpers } from '../lib/redux';
import { currencyOptions } from '../lib/currency';
import { validateFinancialAid } from '../lib/validation/profile';
import type { AvailableProgram } from '../flow/enrollmentTypes';
import type {
  FinancialAidState,
  FinancialAidValidation,
  FetchError,
} from '../reducers/financial_aid';
import type { Program } from '../flow/programTypes';
import { formatPrice } from '../util/util';
import { dialogActions } from '../components/inputs/util';
import { getOwnDashboard } from '../reducers/util';

export const CALCULATOR_DIALOG = 'CALCULATOR_DIALOG';

export const INCOME_DIALOG = 'INCOME_DIALOG';

const updateCurrency = R.curry((update, financialAid, selection) => {
  let _financialAid = R.clone(financialAid);
  _financialAid.currency = selection ? selection.value : null;
  update(_financialAid);
});

const currencySelect = (update, current) => (
  <Select
    options={currencyOptions}
    clearable={false}
    value={current.currency}
    onChange={updateCurrency(update, current)}
    name="currency"
    id="currency-select"
    inputProps={{
      'aria-required': "true",
      'aria-invalid': _.has(current, ['validation', 'currency'])
    }}
  />
);

const salaryUpdate = R.curry((update, current, e) => {
  let newEdit = R.clone(current);
  newEdit.income = e.target.value;
  update(newEdit);
});

const salaryField = (update, current) => (
  <TextField
    name="salary"
    aria-required="true"
    aria-invalid={_.has(current, ['validation', 'income'])}
    label="income (yearly)"
    id="user-salary-input"
    className="salary-field"
    value={current.income}
    fullWidth={true}
    onChange={salaryUpdate(update, current)}
  />
);

const checkboxText = `I testify that the income I reported is true and accurate.
I am aware that I may be asked to verify the reported income with documentation.`;

const checkboxUpdate = (update, current, bool) => {
  let newEdit = R.clone(current);
  newEdit.checkBox = bool;
  update(newEdit);
};

const checkBox = (update, current) => (
  <Checkbox
    checked={current.checkBox}
    required="true"
    aria-invalid={_.has(current, ['validation', 'checkBox'])}
    label={checkboxText}
    onChange={() => checkboxUpdate(update, current, !current.checkBox)}
  />
);

const calculatorActions = (openSkipDialog, cancel, save, fetchAddStatus, fetchSkipStatus) => {
  return

    <button className="mm-minor-action full-price" onClick={openSkipDialog}>
      Skip this and Pay Full Price
    </button>

      { dialogActions(
        cancel,
        save,
        fetchAddStatus === FETCH_PROCESSING,
        'Submit',
        'calculate-cost-button',
        fetchSkipStatus === FETCH_PROCESSING
      ) }

;
};

const validationMessage = (key, errors) => {
  if (errors === undefined || R.isNil(errors[key])) {
    return null;
  }
  return

    { errors[key] }

;
};

const apiError = ({ message, code }: FetchError) => (

    {`There was an error (Error ${code}: ${message}). Please contact `}
    <a href={`mailto:${SETTINGS.support_email}`}>
      {`${SETTINGS.support_email}`}

    {" if you continue to have problems."}

);

type CalculatorProps = {
  calculatorDialogVisibility:    boolean,
  confirmIncomeDialogVisibility: boolean,
  closeDialogAndCancel:          () => void,
  closeConfirmDialogAndCancel:   () => void,
  financialAid:                  FinancialAidState,
  validation:                    FinancialAidValidation,
  saveFinancialAid:              (f: FinancialAidState) => void,
  submitFinancialAid:            (f: FinancialAidState) => void,
  updateCalculatorEdit:          (f: FinancialAidState) => void,
  currentProgramEnrollment:      AvailableProgram,
  openConfirmSkipDialog:         () => void,
  programs:                      Array<Program>,
};

const FinancialAidCalculator = ({
  calculatorDialogVisibility,
  confirmIncomeDialogVisibility,
  closeDialogAndCancel,
  closeConfirmDialogAndCancel,
  financialAid,
  financialAid: {
    validation, fetchError, income, currency, fetchAddStatus, fetchSkipStatus
  },
  saveFinancialAid,
  submitFinancialAid,
  updateCalculatorEdit,
  currentProgramEnrollment,
  openConfirmSkipDialog,
  programs,
}: CalculatorProps) => {
  if (!currentProgramEnrollment) {
    return null;
  }
  const { title, id } = currentProgramEnrollment;

  let program = programs.find(prog => prog.id === id);
  if (!program) {
    return null;
  }

  let minPossibleCost, maxPossibleCost;
  if (program.financial_aid_availability) {
    minPossibleCost = formatPrice(program.financial_aid_user_info.min_possible_cost);
    maxPossibleCost = formatPrice(program.financial_aid_user_info.max_possible_cost);
  }
  let confirmDialog = <Dialog
    key="confirm"
    title="Confirm Your Income"
    titleClassName="dialog-title"
    contentClassName="dialog confirm-dialog"
    className="financial-aid-calculator-wrapper"
    open={confirmIncomeDialogVisibility}
    bodyClassName="financial-aid-calculator-body"
    onRequestClose={closeConfirmDialogAndCancel}
    actions={dialogActions(
      closeConfirmDialogAndCancel,
      () => submitFinancialAid(financialAid),
      fetchSkipStatus === FETCH_PROCESSING,
      'Submit',
      'confirm-income-button',
      fetchAddStatus === FETCH_PROCESSING
    )}
  >

Household Income: {currency} {income}

    Please make sure that your household income is accurate and that
    you can provide documentation (if necessary). If you can't provide
    an accurate income at this time, click cancel.
    { fetchError ? apiError(fetchError) : null }
  </Dialog>;

  return

    <Dialog
      title="Personal Course Pricing"
      titleClassName="dialog-title"
      contentClassName="dialog financial-aid-calculator"
      className="financial-aid-calculator-wrapper"
      open={calculatorDialogVisibility}
      bodyClassName="financial-aid-calculator-body"
      autoScrollBodyContent={true}
      onRequestClose={closeDialogAndCancel}
      actions={calculatorActions(
        openConfirmSkipDialog,
        closeDialogAndCancel,
        () => saveFinancialAid(financialAid),
        fetchAddStatus,
        fetchSkipStatus,
      )}
    >

        { `The cost of courses in the ${title} MicroMasters varies between ${minPossibleCost} and ${maxPossibleCost},
        depending on your income and ability to pay.`}

            Income (yearly)
            { salaryField(updateCalculatorEdit, financialAid) }

          { validationMessage('income', validation) }

            Currency

          { currencySelect(updateCalculatorEdit, financialAid) }
          { validationMessage('currency', validation) }

        { checkBox(updateCalculatorEdit, financialAid) }

        { validationMessage('checkBox', validation) }

      { fetchError ? apiError(fetchError) : null }
    </Dialog>
    {confirmDialog}

;
};

const closeDialogAndCancel = dispatch => (
  () => {
    dispatch(hideDialog(CALCULATOR_DIALOG));
    dispatch(clearCalculatorEdit());
  }
);

const closeConfirmDialogAndCancel = dispatch => (
  () => {
    dispatch(hideDialog(INCOME_DIALOG));
    dispatch(clearCalculatorEdit());
  }
);

const updateFinancialAidValidation = (dispatch, current) => {
  let errors = validateFinancialAid(current);
  if (! R.equals(errors, current.validation)) {
    dispatch(updateCalculatorValidation(errors));
  }
  return R.isEmpty(errors);
};

const saveFinancialAid = R.curry((dispatch, current) => {
  let valid = updateFinancialAidValidation(dispatch, current);
  let clone = _.cloneDeep(current);
  delete clone.validation;
  if (valid) {
    dispatch(hideDialog(CALCULATOR_DIALOG));
    dispatch(showDialog(INCOME_DIALOG));
  }
});

const submitFinancialAid = R.curry((dispatch, current) => {
  const { income, currency, programId } = current;
  dispatch(addFinancialAid(income, currency, programId)).then(() => {
    dispatch(hideDialog(INCOME_DIALOG));
    dispatch(clearCalculatorEdit());
  });
});

const updateFinancialAidEdit = R.curry((dispatch, current) => {
  updateFinancialAidValidation(dispatch, current);
  let clone = _.cloneDeep(current);
  delete clone.validation;
  dispatch(updateCalculatorEdit(clone));
});

const openConfirmSkipDialogHelper = dispatch => () => {
  closeDialogAndCancel(dispatch)();
  dispatch(setConfirmSkipDialogVisibility(true));
};

const mapStateToProps = state => {
  const {
    ui,
    financialAid,
    currentProgramEnrollment,
  } = state;
  const { programs } = getOwnDashboard(state);

  return {
    calculatorDialogVisibility: ui.dialogVisibility[CALCULATOR_DIALOG] || false,
    confirmIncomeDialogVisibility: ui.dialogVisibility[INCOME_DIALOG] || false,
    financialAid,
    currentProgramEnrollment,
    programs,
  };
};

const mapDispatchToProps = dispatch => {
  return {
    closeDialogAndCancel: closeDialogAndCancel(dispatch),
    closeConfirmDialogAndCancel: closeConfirmDialogAndCancel(dispatch),
    saveFinancialAid: saveFinancialAid(dispatch),
    submitFinancialAid: submitFinancialAid(dispatch),
    openConfirmSkipDialog: openConfirmSkipDialogHelper(dispatch),
    updateCalculatorEdit: updateFinancialAidEdit(dispatch),
    ...createSimpleActionHelpers(dispatch, [
      ['clearCalculatorEdit', clearCalculatorEdit],
    ]),
  };
};

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


<commit_before>require('coffee-script/register');
require('../../../vendor/vast-client-js');

var vastClient = require('../../../vendor/vast-client-js/client');

KalturaVastParser = {
	parse: function(vastUrl, headers, callback){
		vastClient.get(vastUrl, callback);
	}
};

module.exports = KalturaVastParser;<commit_msg>add ip to vast request<commit_after>require('coffee-script/register');
require('../../../vendor/vast-client-js');

var vastClient = require('../../../vendor/vast-client-js/client');

KalturaVastParser = {
	parse: function(vastUrl, headers, callback){
		vastClient.get(vastUrl, headers, callback);
	}
};

module.exports = KalturaVastParser;<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2016 Berkeley Model United Nations. All rights reserved.
 * Use of this source code is governed by a BSD License (see LICENSE).
 */

'use strict';

var Modal = require('react-modal');
var React = require('react');
var ReactRouter = require('react-router');

var Button = require('components/core/Button');
var CurrentUserStore = require('stores/CurrentUserStore');
var DelegateActions = require('actions/DelegateActions');
var DelegateStore = require('stores/DelegateStore');
var CurrentUserActions = require('actions/CurrentUserActions');
var InnerView = require('components/InnerView');
var ServerAPI = require('lib/ServerAPI');
var StatusLabel = require('components/core/StatusLabel');
var Table = require('components/core/Table');
var TextInput = require('components/core/TextInput');
var TextTemplate = require('components/core/TextTemplate');
var _handleChange = require('utils/_handleChange');

require('css/Modal.less');
var AdvisorRosterViewText = require('text/AdvisorRosterViewText.md');

var AdvisorRosterView = React.createClass({
  mixins: [ReactRouter.History],

  getInitialState: function() {
    var schoolID = CurrentUserStore.getCurrentUser().school.id;
    return {
      delegates: DelegateStore.getSchoolDelegates(schoolID),
      loading: false,
      modal_open: false,
      modal_name: '',
      modal_email: '',
      modal_onClick: null,
      errors: {},
    };
  },

  componentWillMount: function() {
    Modal.setAppElement('body');
  },

  componentDidMount: function() {
    this._delegatesToken = DelegateStore.addListener(() => {
      var schoolID = CurrentUserStore.getCurrentUser().school.id;
      this.setState({
        delegates: DelegateStore.getSchoolDelegates(schoolID),
        modal_open: false,
        loading: false,
      });
    });
  },

  componentWillUnmount: function() {
    this._delegatesToken && this._delegatesToken.remove();
  },

  render: function() {
    return (
      <InnerView>
        <TextTemplate>
          {AdvisorRosterViewText}
        </TextTemplate>

              Delegate
              Email
              Edit
              Delete

            {this.renderRosterRows()}

        <Button
          color="green"
          onClick={this.openModal.bind(this, '', '', this._handleAddDelegate)}
          loading={this.state.loading}>
          Add Delegate
        </Button>
        <Modal
          isOpen={this.state.modal_open}
          className="content content-outer transparent ie-layout rounded"
          overlayClassName="modal-overlay">
          <form>

Enter your delegate's information here

            <TextInput
              placeholder="Name"
              onChange={_handleChange.bind(this, 'modal_name')}
              defaultValue={this.state.modal_name}
              value={this.state.modal_name}
            />
            {this.renderError('name')}
            <TextInput
              placeholder="Email (Optional)"
              onChange={_handleChange.bind(this, 'modal_email')}
              defaultValue={this.state.modal_email}
              value={this.state.modal_email}
            />
            {this.renderError('email')}

              <Button
                onClick={this.state.modal_onClick}
                color="green"
                loading={this.state.loading}>
                Save
              </Button>
              <Button onClick={this.closeModal} color="red">
                Cancel
              </Button>

          </form>
        </Modal>
      </InnerView>
    );
  },

  renderRosterRows: function() {
    var committees = this.state.committees;
    var countries = this.state.countries;
    return this.state.delegates.map(
      function(delegate) {
        return (

              {delegate.name}

              {delegate.email}

              <Button
                color="blue"
                size="small"
                onClick={this.openModal.bind(
                  this,
                  delegate.name,
                  delegate.email,
                  this._handleEditDelegate.bind(this, delegate),
                )}>
                Edit
              </Button>

              <Button
                color="red"
                size="small"
                onClick={this._handleDeleteDelegate.bind(this, delegate)}>
                Delete
              </Button>

        );
      }.bind(this),
    );
  },

  openModal: function(name, email, fn, event) {
    this.setState({
      modal_open: true,
      modal_name: name,
      modal_email: email,
      modal_onClick: fn,
      errors: {},
    });
    event.preventDefault();
  },

  closeModal: function(event) {
    this.setState({modal_open: false});
    event.preventDefault();
  },

  renderError: function(field) {
    if (this.state.errors[field]) {
      return (
        <StatusLabel status="error">
          {this.state.errors[field]}
        </StatusLabel>
      );
    }

    return null;
  },

  _handleDeleteDelegate: function(delegate) {
    const confirmed = window.confirm(
      `Are you sure you want to delete this delegate (${delegate.name})?`,
    );
    if (confirmed) {
      DelegateActions.deleteDelegate(delegate.id, this._handleDeleteError);
    }
  },

  _handleAddDelegate: function(data) {
    this.setState({loading: true});
    var user = CurrentUserStore.getCurrentUser();
    ServerAPI.createDelegate(
      this.state.modal_name,
      this.state.modal_email,
      user.school.id,
    ).then(this._handleAddDelegateSuccess, this._handleError);
    event.preventDefault();
  },

  _handleEditDelegate: function(delegate) {
    var user = CurrentUserStore.getCurrentUser();
    this.setState({loading: true});
    var delta = {name: this.state.modal_name, email: this.state.modal_email};
    DelegateActions.updateDelegate(delegate.id, delta, this._handleError);
    event.preventDefault();
  },

  _handleAddDelegateSuccess: function(response) {
    DelegateActions.addDelegate(response);
    this.setState({
      loading: false,
      modal_open: false,
    });
  },

  _handleDeleteError: function(response) {
    window.alert(
      `There was an issue processing your request. Please refresh you page and try again.`,
    );
  },

  _handleError: function(response) {
    this.setState({
      errors: response,
      loading: false,
      modal_open: true,
    });
  },
});

module.exports = AdvisorRosterView;
<commit_msg>Removed optional from delegate email input (#633)<commit_after>/**
 * Copyright (c) 2011-2016 Berkeley Model United Nations. All rights reserved.
 * Use of this source code is governed by a BSD License (see LICENSE).
 */

'use strict';

var Modal = require('react-modal');
var React = require('react');
var ReactRouter = require('react-router');

var Button = require('components/core/Button');
var CurrentUserStore = require('stores/CurrentUserStore');
var DelegateActions = require('actions/DelegateActions');
var DelegateStore = require('stores/DelegateStore');
var CurrentUserActions = require('actions/CurrentUserActions');
var InnerView = require('components/InnerView');
var ServerAPI = require('lib/ServerAPI');
var StatusLabel = require('components/core/StatusLabel');
var Table = require('components/core/Table');
var TextInput = require('components/core/TextInput');
var TextTemplate = require('components/core/TextTemplate');
var _handleChange = require('utils/_handleChange');

require('css/Modal.less');
var AdvisorRosterViewText = require('text/AdvisorRosterViewText.md');

var AdvisorRosterView = React.createClass({
  mixins: [ReactRouter.History],

  getInitialState: function() {
    var schoolID = CurrentUserStore.getCurrentUser().school.id;
    return {
      delegates: DelegateStore.getSchoolDelegates(schoolID),
      loading: false,
      modal_open: false,
      modal_name: '',
      modal_email: '',
      modal_onClick: null,
      errors: {},
    };
  },

  componentWillMount: function() {
    Modal.setAppElement('body');
  },

  componentDidMount: function() {
    this._delegatesToken = DelegateStore.addListener(() => {
      var schoolID = CurrentUserStore.getCurrentUser().school.id;
      this.setState({
        delegates: DelegateStore.getSchoolDelegates(schoolID),
        modal_open: false,
        loading: false,
      });
    });
  },

  componentWillUnmount: function() {
    this._delegatesToken && this._delegatesToken.remove();
  },

  render: function() {
    return (
      <InnerView>
        <TextTemplate>
          {AdvisorRosterViewText}
        </TextTemplate>

              Delegate
              Email
              Edit
              Delete

            {this.renderRosterRows()}

        <Button
          color="green"
          onClick={this.openModal.bind(this, '', '', this._handleAddDelegate)}
          loading={this.state.loading}>
          Add Delegate
        </Button>
        <Modal
          isOpen={this.state.modal_open}
          className="content content-outer transparent ie-layout rounded"
          overlayClassName="modal-overlay">
          <form>

Enter your delegate's information here

            <TextInput
              placeholder="Name"
              onChange={_handleChange.bind(this, 'modal_name')}
              defaultValue={this.state.modal_name}
              value={this.state.modal_name}
            />
            {this.renderError('name')}
            <TextInput
              placeholder="Email"
              onChange={_handleChange.bind(this, 'modal_email')}
              defaultValue={this.state.modal_email}
              value={this.state.modal_email}
            />
            {this.renderError('email')}

              <Button
                onClick={this.state.modal_onClick}
                color="green"
                loading={this.state.loading}>
                Save
              </Button>
              <Button onClick={this.closeModal} color="red">
                Cancel
              </Button>

          </form>
        </Modal>
      </InnerView>
    );
  },

  renderRosterRows: function() {
    var committees = this.state.committees;
    var countries = this.state.countries;
    return this.state.delegates.map(
      function(delegate) {
        return (

              {delegate.name}

              {delegate.email}

              <Button
                color="blue"
                size="small"
                onClick={this.openModal.bind(
                  this,
                  delegate.name,
                  delegate.email,
                  this._handleEditDelegate.bind(this, delegate),
                )}>
                Edit
              </Button>

              <Button
                color="red"
                size="small"
                onClick={this._handleDeleteDelegate.bind(this, delegate)}>
                Delete
              </Button>

        );
      }.bind(this),
    );
  },

  openModal: function(name, email, fn, event) {
    this.setState({
      modal_open: true,
      modal_name: name,
      modal_email: email,
      modal_onClick: fn,
      errors: {},
    });
    event.preventDefault();
  },

  closeModal: function(event) {
    this.setState({modal_open: false});
    event.preventDefault();
  },

  renderError: function(field) {
    if (this.state.errors[field]) {
      return (
        <StatusLabel status="error">
          {this.state.errors[field]}
        </StatusLabel>
      );
    }

    return null;
  },

  _handleDeleteDelegate: function(delegate) {
    const confirmed = window.confirm(
      `Are you sure you want to delete this delegate (${delegate.name})?`,
    );
    if (confirmed) {
      DelegateActions.deleteDelegate(delegate.id, this._handleDeleteError);
    }
  },

  _handleAddDelegate: function(data) {
    this.setState({loading: true});
    var user = CurrentUserStore.getCurrentUser();
    ServerAPI.createDelegate(
      this.state.modal_name,
      this.state.modal_email,
      user.school.id,
    ).then(this._handleAddDelegateSuccess, this._handleError);
    event.preventDefault();
  },

  _handleEditDelegate: function(delegate) {
    var user = CurrentUserStore.getCurrentUser();
    this.setState({loading: true});
    var delta = {name: this.state.modal_name, email: this.state.modal_email};
    DelegateActions.updateDelegate(delegate.id, delta, this._handleError);
    event.preventDefault();
  },

  _handleAddDelegateSuccess: function(response) {
    DelegateActions.addDelegate(response);
    this.setState({
      loading: false,
      modal_open: false,
    });
  },

  _handleDeleteError: function(response) {
    window.alert(
      `There was an issue processing your request. Please refresh you page and try again.`,
    );
  },

  _handleError: function(response) {
    this.setState({
      errors: response,
      loading: false,
      modal_open: true,
    });
  },
});

module.exports = AdvisorRosterView;
<|endoftext|>


<commit_before>if (process.env.NODE_ENV === 'development') {
  Error.stackTraceLimit = Infinity;
  require('trace');
  require('clarify');
}

const bb = require('bluebird');

require('babel-runtime/core-js/promise').default = bb;
global.Promise = bb;

require("babel-register")({
  ignore: /\/(public|node_modules)\//
});

const { server } = require('universal-webpack');

const settings = require('../server-uwsettings');
const configuration = require('../webpack.config.server.babel').default;

server(configuration, settings);
<commit_msg>⚡Disable unlimited stacktrace<commit_after>if (process.env.NODE_ENV === 'development') {
  // Error.stackTraceLimit = Infinity;
  require('trace');
  require('clarify');
}

const bb = require('bluebird');

require('babel-runtime/core-js/promise').default = bb;
global.Promise = bb;

require("babel-register")({
  ignore: /\/(public|node_modules)\//
});

const { server } = require('universal-webpack');

const settings = require('../server-uwsettings');
const configuration = require('../webpack.config.server.babel').default;

server(configuration, settings);
<|endoftext|>


<commit_before>$(document).ready(function(){

    //initiate event for discussion
    set_show_hide_discussion();

    $('#submit-btn, #test-next-btn').click(function(evt){
        $(this).addClass('disabled');
        var form = $("#training-step-form");
        var update_url = form.children("input[name=update_url]").val();
        var qid = form.children("input[name=qid]").val();
        var checkboxes = form.find("input.choices");
        var choices = [];
        var aids = [];
        var step = form.children("input[name=step]").val();
        var btn_id = $(this).attr('id');
        var sq_id = $('#session_question_id').val();
        var submission_id = $('#submission_id').val();

        $.each(checkboxes, function(i, cb) {
            choices.push($(cb).val());
            if ($(cb).is(":checked")) {
                aids.push($(cb).val());
            }
        });

        if (aids.length > 0) {
            var data = {
                'step':step,
                'qid': qid,
                'aid': aids,
                'choices': choices,
                'sq_id' : sq_id,
                'sid' :submission_id
            };
            // send ajax request to get result
            // update result form
            // change submit to continue if the answer is correct
            $.get(update_url, data, function(resp) {
                //#new code for normal training
                $('#submit-btn, #test-next-btn').removeClass('disabled');

                $('#explanation .result').html(resp.result);
                $('#explanation .reason').html(resp.explanation);
                $('#explanation').removeClass('hidden');
                $('#explanation').removeClass('mcq-ans-incorrect');
                $('#explanation').removeClass('mcq-ans-correct');

                var el = document.getElementById("explanation");
                MathJax.Hub.Queue(["Typeset", MathJax.Hub, el]);

                if (resp.is_test || resp.is_correct) {
                    $('#continue-btn').removeClass('disabled');
                    $('#continue-btn').addClass('btn-primary');
                    $('#submit-btn').removeClass('btn-primary');
                    if (resp.is_test){
                        $('#explanation').addClass('alert-info');
                    }else {
                        $('#explanation').addClass('mcq-ans-correct');
                    }
                } else {
                    $('#continue-btn').removeClass('disabled');
                    $('#explanation').addClass('mcq-ans-incorrect');
                }
                //To next question right after answering pre one
                if(btn_id=='test-next-btn') {
                    window.location.href = $('#test-next-btn').attr('href');
                }
            }, 'json');
        }
        if(btn_id=='submit-btn') {
            return false; // prevent default
        }
    });

    $('#continue-btn').click(function(evt) {
        if ($(this).hasClass('disabled')) {
            evt.preventDefault();
        }
    });

    $("#pathrun").bind("click",submitCode);
    $(document).keydown(function(evt){
        if(evt.altKey && evt.which == 82){
            submitCode();
        }
    });

    var running = false;
    function submitCode(){
        if(running) return;
        running = true;
        $("#pathrun").attr("disabled",true);
        var form = $("#training-step-form");
        var update_url = form.children("input[name=update_url]").val();
        var qid = form.children("input[name=qid]").val();
        var step = form.children("input[name=step]").val();

        var failcolor = {backgroundColor: "#e1c1b1"}
        var animateOpt = {duration: 1000, queue: false};
        var passcolor = {backgroundColor: "#008000"};
        $.get(update_url,
            {
                code: $("#ans").val(),
                step: step,
                qid: qid
            },
            function(resp){
                var $er = $("#eval_result");
                $(document.body).scrollTop(($er.offset().top + $er.height()) - $("#ruler").show().height() + 100);
                $("#ruler").hide();
                if(resp.errors.length > 0){
//                $er.text(resp.errors).animate({backgroundColor: "#3C2502",color:"#FF0000"}, animateOpt);
//                console.log("error")
                    $er.html(escapeHtml(resp.errors)).animate({backgroundColor: "#e1c1b1"}, animateOpt);
                }else{
                    var publicTestFlag = true;
                    $("#publicTestTable tbody tr").each(function(index, e){
//                    console.log("change table")
                        if(resp.public[index]){
                            var temp = $("td:last",e);
                            if(temp.hasClass("pathTestFail")){
                                temp.switchClass("pathTestFail","pathTestPass").animate(passcolor,animateOpt);
                            }else if(!temp.hasClass("pathTestPass")){
                                temp.addClass("pathTestPass").animate(passcolor,animateOpt);;
                            }
                        }else{
                            publicTestFlag = false;
                            var temp = $("td:last",e);
                            if(temp.hasClass("pathTestPass")){

                                temp.switchClass("pathTestPass", "pathTestFail").animate(failcolor, animateOpt);
                            }else if(!temp.hasClass("pathTestFail")){
                                temp.addClass("pathTestFail", 1000).animate(failcolor,animateOpt);
                            }
                        }
                    });
                    var privateTestFlag = resp.private.length == 0 ? true : resp.private.reduce(function(a,b){return a && b});
                    if(publicTestFlag){
                        if(resp.private == null || !privateTestFlag){
                            $er.html("Your answer failed to pass one or more of the private test cases."  + (resp.hint ? "
Hint: " + resp.hint : "")).animate(failcolor, animateOpt);
                        }else{
                            $er.html("You have successfully completed this step!").animate(passcolor, animateOpt);
                            $('#continue-btn').removeClass('disabled');
                            $("#pathrun").attr("disabled",true);
                            return; // we do not undisable the run
                        }
                    }else{
                        $er.html("Your answer failed to pass one or more of the public test cases.").animate(failcolor,animateOpt);
                    }
                }

                running = false;
                $("#pathrun").attr("disabled",false);
            }, 'json')
    }
});

<commit_msg>fixed show continue button when choosing wrong<commit_after>$(document).ready(function(){

    //initiate event for discussion
    set_show_hide_discussion();

    $('#submit-btn, #test-next-btn').click(function(evt){
        $(this).addClass('disabled');
        var form = $("#training-step-form");
        var update_url = form.children("input[name=update_url]").val();
        var qid = form.children("input[name=qid]").val();
        var checkboxes = form.find("input.choices");
        var choices = [];
        var aids = [];
        var step = form.children("input[name=step]").val();
        var btn_id = $(this).attr('id');
        var sq_id = $('#session_question_id').val();
        var submission_id = $('#submission_id').val();

        $.each(checkboxes, function(i, cb) {
            choices.push($(cb).val());
            if ($(cb).is(":checked")) {
                aids.push($(cb).val());
            }
        });

        if (aids.length > 0) {
            var data = {
                'step':step,
                'qid': qid,
                'aid': aids,
                'choices': choices,
                'sq_id' : sq_id,
                'sid' :submission_id
            };
            // send ajax request to get result
            // update result form
            // change submit to continue if the answer is correct
            $.get(update_url, data, function(resp) {
                //#new code for normal training
                $('#submit-btn, #test-next-btn').removeClass('disabled');

                $('#explanation .result').html(resp.result);
                $('#explanation .reason').html(resp.explanation);
                $('#explanation').removeClass('hidden');
                $('#explanation').removeClass('mcq-ans-incorrect');
                $('#explanation').removeClass('mcq-ans-correct');

                var el = document.getElementById("explanation");
                MathJax.Hub.Queue(["Typeset", MathJax.Hub, el]);

                if (resp.is_test || resp.is_correct) {
                    $('#continue-btn').removeClass('disabled');
                    $('#continue-btn').addClass('btn-primary');
                    $('#submit-btn').removeClass('btn-primary');
                    if (resp.is_test){
                        $('#explanation').addClass('alert-info');
                    }else {
                        $('#explanation').addClass('mcq-ans-correct');
                    }
                } else {
                    //$('#continue-btn').removeClass('disabled');
                    $('#explanation').addClass('mcq-ans-incorrect');
                }
                //To next question right after answering pre one
                if(btn_id=='test-next-btn') {
                    window.location.href = $('#test-next-btn').attr('href');
                }
            }, 'json');
        }
        if(btn_id=='submit-btn') {
            return false; // prevent default
        }
    });

    $('#continue-btn').click(function(evt) {
        if ($(this).hasClass('disabled')) {
            evt.preventDefault();
        }
    });

    $("#pathrun").bind("click",submitCode);
    $(document).keydown(function(evt){
        if(evt.altKey && evt.which == 82){
            submitCode();
        }
    });

    var running = false;
    function submitCode(){
        if(running) return;
        running = true;
        $("#pathrun").attr("disabled",true);
        var form = $("#training-step-form");
        var update_url = form.children("input[name=update_url]").val();
        var qid = form.children("input[name=qid]").val();
        var step = form.children("input[name=step]").val();

        var failcolor = {backgroundColor: "#e1c1b1"}
        var animateOpt = {duration: 1000, queue: false};
        var passcolor = {backgroundColor: "#008000"};
        $.get(update_url,
            {
                code: $("#ans").val(),
                step: step,
                qid: qid
            },
            function(resp){
                var $er = $("#eval_result");
                $(document.body).scrollTop(($er.offset().top + $er.height()) - $("#ruler").show().height() + 100);
                $("#ruler").hide();
                if(resp.errors.length > 0){
//                $er.text(resp.errors).animate({backgroundColor: "#3C2502",color:"#FF0000"}, animateOpt);
//                console.log("error")
                    $er.html(escapeHtml(resp.errors)).animate({backgroundColor: "#e1c1b1"}, animateOpt);
                }else{
                    var publicTestFlag = true;
                    $("#publicTestTable tbody tr").each(function(index, e){
//                    console.log("change table")
                        if(resp.public[index]){
                            var temp = $("td:last",e);
                            if(temp.hasClass("pathTestFail")){
                                temp.switchClass("pathTestFail","pathTestPass").animate(passcolor,animateOpt);
                            }else if(!temp.hasClass("pathTestPass")){
                                temp.addClass("pathTestPass").animate(passcolor,animateOpt);;
                            }
                        }else{
                            publicTestFlag = false;
                            var temp = $("td:last",e);
                            if(temp.hasClass("pathTestPass")){

                                temp.switchClass("pathTestPass", "pathTestFail").animate(failcolor, animateOpt);
                            }else if(!temp.hasClass("pathTestFail")){
                                temp.addClass("pathTestFail", 1000).animate(failcolor,animateOpt);
                            }
                        }
                    });
                    var privateTestFlag = resp.private.length == 0 ? true : resp.private.reduce(function(a,b){return a && b});
                    if(publicTestFlag){
                        if(resp.private == null || !privateTestFlag){
                            $er.html("Your answer failed to pass one or more of the private test cases."  + (resp.hint ? "
Hint: " + resp.hint : "")).animate(failcolor, animateOpt);
                        }else{
                            $er.html("You have successfully completed this step!").animate(passcolor, animateOpt);
                            $('#continue-btn').removeClass('disabled');
                            $("#pathrun").attr("disabled",true);
                            return; // we do not undisable the run
                        }
                    }else{
                        $er.html("Your answer failed to pass one or more of the public test cases.").animate(failcolor,animateOpt);
                    }
                }

                running = false;
                $("#pathrun").attr("disabled",false);
            }, 'json')
    }
});

<|endoftext|>


<commit_before>// Uncomment this to get the 'app.address is not a function' error
// Requiring express instead of expressive removes the error
const request = require('superagent');
const express = require('./../expressive.js');
//const express = require('express');
const app = express();

app.get('/user', function(req, res) {
  res.status(200).json({ name: 'tobi' });
});

app.listen(3000, () => {
  describe('GET /user', function() {
    it('respond with json', function(done) {
      request('localhost:3000/user')
        .get('/user')
        .set('Accept', 'application/json')
        .expect('Content-Type', /json/)
        .expect(200, done);
    });
  });

});

// Comment out above and uncomment below to run tests with npm test

// const request = require('supertest');
// app = require('./../test-servers/mary-server.js')
// const should = require('should')

// // app.get('/user', function(req, res) {
// //   res.status(800).json({ name: 'tobi' });
// // });

// //TESTS BASIC GET FUNCTIONALITY
// describe('GET /user', function() {
//   it('respond with json', function(done) {
//     request(app)
//       .get('/')
//       // .set('Accept', 'application/json')
//       .expect('Content-Type', /json/)
//       .expect(200, done);
//   });
// });

// describe("GET/redirect", function () {
//   it('gets status code 302', function (done) {
//     request(app)
//       .get('/redirect')
//       .expect(function(res){
//         res.body.methodRoute =  res.body.methodRoute.toLowerCase();
//       })
//       .expect(302, {
//         methodRoute: 'redirect2'
//       },done);
//   });
// });

// describe("Get /", function(){
//   it('home name should be a match to "venogram"', function(done){
//     request(app)
//       .get('/')
//       .expect(function(res){
//         res.body.name = res.body.name.toLowerCase();
//       })
//       .expect(200, {
//         name: 'venogram'
//       }, done)
//   })
// })

// // const request = require('supertest');
// // const path = require('path');
// // //  const express = require('./../expressive.js');
// // const express = require('express')
// // // console.log(express)
// // const app = express();
// // // const app = require('./mary-server.js')
// //   // const PORT = process.env.PORT || 3000;
// //  const HOST = `http://localhost:8080`
// // const expect = require('expect')

// // app.get('/', function(req, res){
// //   res.send(200)
// //   res.json({name: 'mary'})
// // })
// // describe('Get/', function () {
// //   it('should respond with status code 400', function (done) {
// //     request(app)
// //       .get('/')
// //       .expect('Content-Type', /json/)
// //       .expect(400, done)
// //       done();
// //   });
// // });

// // describe('GET/redirect', function () {
// //   it('should keep redirecting until res.body.name = "venogram"', function (done) {
// //     request(HOST)
// //       .get('/redirect')
// //       .expect(function (res) {
// //         res.body.name = 'venogram';
// //       })
// //       done();
// //   });
// // });
<commit_msg>supertest now works for expressive<commit_after>const usingExpressive = true;

// const request = require('supertest');
// const express = usingExpressive ? require('./../expressive.js') : require('express');

// const app = express();

// Comment out above and uncomment below to run tests with npm test

const request = require('supertest');
// app = require('./../test-servers/mary-server.js')

// app.get('/user', function(req, res) {
//   res.status(800).json({ name: 'tobi' });
// });

// app.get('/user', function(req, res) {
//   res.status(800).json({ name: 'tobi' });
// });

// request(app)
//   .get('/user')
//   .expect('Content-Type', /json/)
//   .expect('Content-Length', '15')
//   .expect(200)
//   .end(function(err, res) {
//     if (err) throw err;
//   });

// //TESTS BASIC GET FUNCTIONALITY
// describe('GET /user', function () {
//   it('respond with json', function (done) {
//     request(app)
//       .get('/')
//       // .set('Accept', 'application/json')
//       .expect('Content-Type', /json/)
//       .expect(200, done);
//   });
// });

// describe("GET/redirect", function () {
//   it('gets status code 302', function (done) {
//     request(app)
//       .get('/redirect')
//       .expect(function (res) {
//         res.body.methodRoute = res.body.methodRoute.toLowerCase();
//       })
//       .expect(302, {
//         methodRoute: 'redirect2'
//       }, done);
//   });
// });

// describe("Get /", function () {
//   it('home name should be a match to "venogram"', function (done) {
//     request(app)
//       .get('/')
//       .expect(function (res) {
//         res.body.name = res.body.name.toLowerCase();
//       })
//       .expect(200, {
//         name: 'venogram'
//       }, done)
//   })
// })

// const request = require('supertest');
const path = require('path');
//  const express = require('./../expressive.js');
const express = usingExpressive ? require('./../expressive.js') : require('express');
// console.log(express)
const app = express();
// const app = require('./mary-server.js')
// const PORT = process.env.PORT || 3000;
const HOST = `http://localhost:8080`
const expect = require('expect')

app.get('/', function (req, res) {
  // res.send(200)
  res.json({ name: 'mary' })
})
describe('Get/', function () {
  it('should respond with status code 200', function (done) {
    request(app)
      .get('/')
      .expect('Content-Type', /json/)
      // .expect(200, done)
    done();
  });
});

describe('GET/redirect', function () {
  it('should keep redirecting until res.body.name = "venogram"', function (done) {
    request(HOST)
      .get('/redirect')
      .expect(function (res) {
        res.body.name = 'venogram';
      })
    done();
  });
});
<|endoftext|>


<commit_before>import fs from 'fs-extra'

import syncGlob from '../src/index'
import { setup, compare, compareDir } from './helpers'

const watch = true

setup()

describe('node-sync-glob', () => {
  it('should sync a file', (done) => {
    let hasChanged = false

    const close = syncGlob('tmp/mock/a.txt', 'tmp/sync', { watch }, compare(() => {
      if (!hasChanged) {
        hasChanged = true
        fs.appendFileSync('tmp/mock/a.txt', 'foobarbaz')
      } else {
        close()
        done()
      }
    }))
  })
})
<commit_msg>continue adding async tests<commit_after>import fs from 'fs-extra'

import syncGlob from '../src/index'
import { setup, compare, compareDir } from './helpers'

const watch = true

setup()

describe('node-sync-glob', () => {
  it('should sync a file', (done) => {
    let hasChanged = false

    const close = syncGlob('tmp/mock/a.txt', 'tmp/sync/', { watch }, compare(() => {
      if (!hasChanged) {
        hasChanged = true

        setImmediate(() => {
          fs.appendFileSync('tmp/mock/a.txt', 'foobarbaz')
        })
      } else {
        close()
        done()
      }
    }))
  }, 10000)

  it('should sync an array of files', (done) => {
    let hasChanged = 0

    const close = syncGlob(['tmp/mock/a.txt', 'tmp/mock/b.txt'], 'tmp/sync', { watch }, compare(() => {
      if (hasChanged++ === 1) {
        setImmediate(() => {
          fs.appendFileSync('tmp/mock/b.txt', 'foobarbaz')
        })
      } else if (hasChanged > 1) {
        close()
        done()
      }
    }))
  }, 10000)
})
<|endoftext|>


<commit_before>var assert = require('chai').assert,
    sync_cmd = require('../lib/sync'),
    exec = require('child_process').exec,
    config = require('../lib/config'),
    fs = require('fs'),
    setup = require('./setup');

var testUrl = 'git@github.com:tmlbl/sbm-test';

describe.only('Sync command', function () {

  before(function (done) {
    setup.config({
      dependencies: [
        {
          url: testUrl,
          path: 'somepath'
        }
      ]
    }, function () {
      config.load(done);
    });
  });

  afterEach(function (done) {
    exec('rm -rf somepath/ sbm.json', done);
  });

  it('should pull code when there is none', function (done) {
    sync_cmd(null, null, function (err) {
      assert.equal(err, null, 'Err should equal null');
      exec('ls somepath', function (err, stdout, stderr) {
        assert.isNull(err);
        done();
      });
    });
  });

  describe('When given a branch', function () {

    before(function (done) {
      setup.config({
        dependencies: [
          {
            url: testUrl,
            path: 'somepath',
            branch: 'other'
          }
        ]
      }, function () {
        config.load(done);
      })
    });

    after(function (done) {
      exec('rm -rf somepath', done);
    });

    it('Should sync to a branch in config', function (done) {
      sync_cmd(null, null, function (err) {
        assert.equal(err, null, 'Err should equal null');
        exec('cd somepath && git branch', function (err, stdout, stderr) {
          assert.isNull(err);
          assert.notEqual(-1, stdout.indexOf('other'));
          done();
        });
      });
    });

  })

});
<commit_msg>removed bad describe.only<commit_after>var assert = require('chai').assert,
    sync_cmd = require('../lib/sync'),
    exec = require('child_process').exec,
    config = require('../lib/config'),
    fs = require('fs'),
    setup = require('./setup');

var testUrl = 'git@github.com:tmlbl/sbm-test';

describe('Sync command', function () {

  before(function (done) {
    setup.config({
      dependencies: [
        {
          url: testUrl,
          path: 'somepath'
        }
      ]
    }, function () {
      config.load(done);
    });
  });

  afterEach(function (done) {
    exec('rm -rf somepath/ sbm.json', done);
  });

  it('should pull code when there is none', function (done) {
    sync_cmd(null, null, function (err) {
      assert.equal(err, null, 'Err should equal null');
      exec('ls somepath', function (err, stdout, stderr) {
        assert.isNull(err);
        done();
      });
    });
  });

  describe('When given a branch', function () {

    before(function (done) {
      setup.config({
        dependencies: [
          {
            url: testUrl,
            path: 'somepath',
            branch: 'other'
          }
        ]
      }, function () {
        config.load(done);
      })
    });

    after(function (done) {
      exec('rm -rf somepath', done);
    });

    it('Should sync to a branch in config', function (done) {
      sync_cmd(null, null, function (err) {
        assert.equal(err, null, 'Err should equal null');
        exec('cd somepath && git branch', function (err, stdout, stderr) {
          assert.isNull(err);
          assert.notEqual(-1, stdout.indexOf('other'));
          done();
        });
      });
    });

  })

});
<|endoftext|>