<commit_before>/**
 * @fileoverview The program editor, containing a list of function editors.
 *
 * @author joseph@cs.utexas.edu (Joe Tessler)
 */

goog.provide('cn.ui.ProgramEditor');

goog.require('cn.constants');
goog.require('cn.ui.ClassComponent');
goog.require('cn.ui.FunctionEditor');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.fx.AbstractDragDrop.EventType');
goog.require('goog.fx.DragDropGroup');
goog.require('goog.object');
goog.require('goog.style');

/**
 * @param {!cn.model.Game} game The game model to render.
 * @param {!cn.ui.GameUi} ui A pointer to parent game UI.
 * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
 * @constructor
 * @extends {cn.ui.ClassComponent}
 */
cn.ui.ProgramEditor = function(game, ui, opt_domHelper) {
  goog.base(this, cn.constants.PROGRAM_EDITOR_CLASS_NAME, opt_domHelper);
  this.game_ = game;
  this.ui_ = ui;
  this.conditionDragDropGroup_ = new goog.fx.DragDropGroup();
  this.commandDragDropGroup_ = new goog.fx.DragDropGroup();

  // Wire each drag drop group to itself as a target.
  this.conditionDragDropGroup_.addTarget(this.conditionDragDropGroup_);
  this.commandDragDropGroup_.addTarget(this.commandDragDropGroup_);
};
goog.inherits(cn.ui.ProgramEditor, cn.ui.ClassComponent);

/**
 * Clears, then initializes the program editor.
 */
cn.ui.ProgramEditor.prototype.init = function() {
  this.removeChildren(true);
  goog.array.forEach(
      this.game_.program.functions,
      function(instructions, f) {
        this.addChild(
            new cn.ui.FunctionEditor(
                f, instructions,
                this.conditionDragDropGroup_, this.commandDragDropGroup_,
                this.getDomHelper()),
            true);
      },
      this);
};

/**
 * @inheritDoc
 */
cn.ui.ProgramEditor.prototype.enterDocument = function() {
  goog.base(this, 'enterDocument');
  this.conditionDragDropGroup_.init();
  this.commandDragDropGroup_.init();
  this.registerDragDropEvents(this.conditionDragDropGroup_);
  this.registerDragDropEvents(this.commandDragDropGroup_);
};

/**
 * Registers all drag drop events.
 * @param {!goog.fx.DragDropGroup} dragDropGroup The drag drop group.
 */
cn.ui.ProgramEditor.prototype.registerDragDropEvents = function(dragDropGroup) {
  var EventType = goog.fx.AbstractDragDrop.EventType;

  this.getHandler().listen(dragDropGroup, EventType.DRAGSTART,
      function(e) {
        var data = e.dragSourceItem.data;
        if (goog.object.containsKey(data, 'condition')) {
          cn.controller.removeCondition(this.game_, data.f, data.i);
        } else {
          cn.controller.removeCommand(this.game_, data.f, data.i);
        }
        goog.style.setOpacity(e.dragSourceItem.element, 0.5);
      });

  this.getHandler().listen(dragDropGroup, EventType.DRAGEND,
      function(e) {
        if (goog.object.containsKey(e.dragSourceItem.data, 'out')) {
          goog.dom.removeNode(e.dragSourceItem.element);
        } else {
          goog.style.setOpacity(e.dragSourceItem.element, 1.0);
        }
      });

  this.getHandler().listen(dragDropGroup, EventType.DRAGOVER,
      function(e) {
        goog.style.setStyle(e.dropTargetItem.element, 'background-size', '0%');
        goog.object.remove(e.dragSourceItem.data, 'out');
      });

  this.getHandler().listen(dragDropGroup, EventType.DRAGOUT,
      function(e) {
        goog.style.setStyle(
            e.dropTargetItem.element, 'background-size', '100%');
        goog.object.set(e.dragSourceItem.data, 'out', true);
      });

  this.getHandler().listen(dragDropGroup, EventType.DROP,
      function(e) {
        var source = e.dragSource;
        var element = e.dragSourceItem.element;
        var data = e.dragSourceItem.data;
        var ptr = e.dropTargetItem.data;

        // Clone the command element if coming from the toolbox.
        if (source === this.ui_.conditionToolbox.getDragDropGroup()) {
          element = e.dragSourceItem.element.cloneNode(true);
          data = goog.object.clone(data);
          this.conditionDragDropGroup_.addItem(element, data);
        } else if (source === this.ui_.commandToolbox.getDragDropGroup()) {
          element = e.dragSourceItem.element.cloneNode(true);
          data = goog.object.clone(data);
          this.commandDragDropGroup_.addItem(element, data);
        }

        // Update the style and add the element to the register's DOM.
        goog.style.setOpacity(element, 1.0);
        goog.style.setStyle(
            e.dropTargetItem.element, 'background-size', '100%');
        goog.dom.removeChildren(e.dropTargetItem.element);
        e.dropTargetItem.element.appendChild(element);

        // Update the actual program model.
        if (goog.object.containsKey(e.dragSourceItem.data, 'condition')) {
          cn.controller.setCondition(
              this.game_, ptr.f, ptr.i, e.dragSourceItem.data.condition);
        } else {
          cn.controller.setCommand(
              this.game_, ptr.f, ptr.i, e.dragSourceItem.data.command);
        }
        data.f = ptr.f;
        data.i = ptr.i;
      });
};

/** @return {!goog.fx.DragDropGroup} The condition drag drop group. */
cn.ui.ProgramEditor.prototype.getConditionDragDropGroup = function() {
  return this.conditionDragDropGroup_;
};

/** @return {!goog.fx.DragDropGroup} The command drag drop group. */
cn.ui.ProgramEditor.prototype.getCommandDragDropGroup = function() {
  return this.commandDragDropGroup_;
};

/**
 * Sets all registers to half transparency except for the register at the given
 * pointer (and it's possible caller).
 */
cn.ui.ProgramEditor.prototype.highlightExecution = function() {
  var f = this.game_.program.getCurrentFunction();
  var i = this.game_.program.getCurrentInstruction();
  var callerF = this.game_.program.getCallerFunction();
  var callerI = this.game_.program.getCallerInstruction();
  this.forEachRegister(
      function(register, regF, regI) {
        // Highlight the executing command.
        if (regF == f && regI == i) {
          goog.style.setOpacity(register.getElement(), 1.0);
        }
        // Highlight (slightly) the executing function and caller.
        else if (regF == f && regI == 0 ||
                 regF == callerF && regI == callerI) {
          goog.style.setOpacity(register.getElement(), 0.5);
        }
        // Otherwise, set the element to nearly transparent.
        else {
          goog.style.setOpacity(register.getElement(), 0.25);
        }
      });
};

/**
 * Sets all registers to fully opaque.
 */
cn.ui.ProgramEditor.prototype.unhighlightExecution = function() {
  this.forEachRegister(function(register) {
    goog.style.setOpacity(register.getElement(), 1.0);
  });
};

/**
 * Clears all registers.
 */
cn.ui.ProgramEditor.prototype.clear = function() {
  this.forEachRegister(function(register, f, i) {
    // Don't remove the function name 'fake' register.
    if (i != 0) {
      register.forEachChild(function(subRegister) {
        goog.dom.removeChildren(subRegister.getElement());
      });
    }
  });
};

/**
 * @param {function(this: S, !cn.ui.Register, number, number): ?}
 *     f The function to call for every element. This function takes 3 arguments
 *     (the register, function index, instruction index). The return value is
 *     ignored.
 * @param {S=} opt_obj The object to be used as the value of 'this' within f.
 * @template S
 */
cn.ui.ProgramEditor.prototype.forEachRegister = function(f, opt_obj) {
  this.forEachChild(function(functionEditor, r) {
    functionEditor.forEachChild(function(register, c) {
      f(register, r, c);
    }, opt_obj);
  }, opt_obj);
};

/** @type {!cn.model.Game} @private */
cn.ui.ProgramEditor.prototype.game_;

/** @type {!cn.ui.GameUi} @private */
cn.ui.ProgramEditor.prototype.ui_;

/** @type {!goog.fx.DragDropGroup} @private */
cn.ui.ProgramEditor.prototype.conditionDragDropGroup_;

/** @type {!goog.fx.DragDropGroup} @private */
cn.ui.ProgramEditor.prototype.commandDragDropGroup_;
<commit_msg>Added TODOs.<commit_after>/**
 * @fileoverview The program editor, containing a list of function editors.
 *
 * @author joseph@cs.utexas.edu (Joe Tessler)
 */

goog.provide('cn.ui.ProgramEditor');

goog.require('cn.constants');
goog.require('cn.ui.ClassComponent');
goog.require('cn.ui.FunctionEditor');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.fx.AbstractDragDrop.EventType');
goog.require('goog.fx.DragDropGroup');
goog.require('goog.object');
goog.require('goog.style');

/**
 * @param {!cn.model.Game} game The game model to render.
 * @param {!cn.ui.GameUi} ui A pointer to parent game UI.
 * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
 * @constructor
 * @extends {cn.ui.ClassComponent}
 */
cn.ui.ProgramEditor = function(game, ui, opt_domHelper) {
  goog.base(this, cn.constants.PROGRAM_EDITOR_CLASS_NAME, opt_domHelper);
  this.game_ = game;
  this.ui_ = ui;
  this.conditionDragDropGroup_ = new goog.fx.DragDropGroup();
  this.commandDragDropGroup_ = new goog.fx.DragDropGroup();

  // Wire each drag drop group to itself as a target.
  this.conditionDragDropGroup_.addTarget(this.conditionDragDropGroup_);
  this.commandDragDropGroup_.addTarget(this.commandDragDropGroup_);
};
goog.inherits(cn.ui.ProgramEditor, cn.ui.ClassComponent);

/**
 * Clears, then initializes the program editor.
 */
cn.ui.ProgramEditor.prototype.init = function() {
  this.removeChildren(true);
  goog.array.forEach(
      this.game_.program.functions,
      function(instructions, f) {
        this.addChild(
            new cn.ui.FunctionEditor(
                f, instructions,
                this.conditionDragDropGroup_, this.commandDragDropGroup_,
                this.getDomHelper()),
            true);
      },
      this);
};

/**
 * @inheritDoc
 */
cn.ui.ProgramEditor.prototype.enterDocument = function() {
  goog.base(this, 'enterDocument');
  this.conditionDragDropGroup_.init();
  this.commandDragDropGroup_.init();
  this.registerDragDropEvents(this.conditionDragDropGroup_);
  this.registerDragDropEvents(this.commandDragDropGroup_);
};

/**
 * Registers all drag drop events.
 * @param {!goog.fx.DragDropGroup} dragDropGroup The drag drop group.
 */
cn.ui.ProgramEditor.prototype.registerDragDropEvents = function(dragDropGroup) {
  var EventType = goog.fx.AbstractDragDrop.EventType;

  // TODO(joseph): Don't let user drag the actual registers.
  // TODO(joseph): Don't let user drag while the game is animating.
  this.getHandler().listen(dragDropGroup, EventType.DRAGSTART,
      function(e) {
        var data = e.dragSourceItem.data;
        if (goog.object.containsKey(data, 'condition')) {
          cn.controller.removeCondition(this.game_, data.f, data.i);
        } else {
          cn.controller.removeCommand(this.game_, data.f, data.i);
        }
        goog.style.setOpacity(e.dragSourceItem.element, 0.5);
      });

  this.getHandler().listen(dragDropGroup, EventType.DRAGEND,
      function(e) {
        if (goog.object.containsKey(e.dragSourceItem.data, 'out')) {
          goog.dom.removeNode(e.dragSourceItem.element);
        } else {
          goog.style.setOpacity(e.dragSourceItem.element, 1.0);
        }
      });

  this.getHandler().listen(dragDropGroup, EventType.DRAGOVER,
      function(e) {
        goog.style.setStyle(e.dropTargetItem.element, 'background-size', '0%');
        goog.object.remove(e.dragSourceItem.data, 'out');
      });

  this.getHandler().listen(dragDropGroup, EventType.DRAGOUT,
      function(e) {
        goog.style.setStyle(
            e.dropTargetItem.element, 'background-size', '100%');
        goog.object.set(e.dragSourceItem.data, 'out', true);
      });

  this.getHandler().listen(dragDropGroup, EventType.DROP,
      function(e) {
        var source = e.dragSource;
        var element = e.dragSourceItem.element;
        var data = e.dragSourceItem.data;
        var ptr = e.dropTargetItem.data;

        // Clone the command element if coming from the toolbox.
        if (source === this.ui_.conditionToolbox.getDragDropGroup()) {
          element = e.dragSourceItem.element.cloneNode(true);
          data = goog.object.clone(data);
          this.conditionDragDropGroup_.addItem(element, data);
        } else if (source === this.ui_.commandToolbox.getDragDropGroup()) {
          element = e.dragSourceItem.element.cloneNode(true);
          data = goog.object.clone(data);
          this.commandDragDropGroup_.addItem(element, data);
        }

        // Update the style and add the element to the register's DOM.
        goog.style.setOpacity(element, 1.0);
        goog.style.setStyle(
            e.dropTargetItem.element, 'background-size', '100%');
        goog.dom.removeChildren(e.dropTargetItem.element);
        e.dropTargetItem.element.appendChild(element);

        // Update the actual program model.
        if (goog.object.containsKey(e.dragSourceItem.data, 'condition')) {
          cn.controller.setCondition(
              this.game_, ptr.f, ptr.i, e.dragSourceItem.data.condition);
        } else {
          cn.controller.setCommand(
              this.game_, ptr.f, ptr.i, e.dragSourceItem.data.command);
        }
        data.f = ptr.f;
        data.i = ptr.i;
      });
};

/** @return {!goog.fx.DragDropGroup} The condition drag drop group. */
cn.ui.ProgramEditor.prototype.getConditionDragDropGroup = function() {
  return this.conditionDragDropGroup_;
};

/** @return {!goog.fx.DragDropGroup} The command drag drop group. */
cn.ui.ProgramEditor.prototype.getCommandDragDropGroup = function() {
  return this.commandDragDropGroup_;
};

/**
 * Sets all registers to half transparency except for the register at the given
 * pointer (and it's possible caller).
 */
cn.ui.ProgramEditor.prototype.highlightExecution = function() {
  var f = this.game_.program.getCurrentFunction();
  var i = this.game_.program.getCurrentInstruction();
  var callerF = this.game_.program.getCallerFunction();
  var callerI = this.game_.program.getCallerInstruction();
  this.forEachRegister(
      function(register, regF, regI) {
        // Highlight the executing command.
        if (regF == f && regI == i) {
          goog.style.setOpacity(register.getElement(), 1.0);
        }
        // Highlight (slightly) the executing function and caller.
        else if (regF == f && regI == 0 ||
                 regF == callerF && regI == callerI) {
          goog.style.setOpacity(register.getElement(), 0.5);
        }
        // Otherwise, set the element to nearly transparent.
        else {
          goog.style.setOpacity(register.getElement(), 0.25);
        }
      });
};

/**
 * Sets all registers to fully opaque.
 */
cn.ui.ProgramEditor.prototype.unhighlightExecution = function() {
  this.forEachRegister(function(register) {
    goog.style.setOpacity(register.getElement(), 1.0);
  });
};

/**
 * Clears all registers.
 */
cn.ui.ProgramEditor.prototype.clear = function() {
  this.forEachRegister(function(register, f, i) {
    // Don't remove the function name 'fake' register.
    if (i != 0) {
      register.forEachChild(function(subRegister) {
        goog.dom.removeChildren(subRegister.getElement());
      });
    }
  });
};

/**
 * @param {function(this: S, !cn.ui.Register, number, number): ?}
 *     f The function to call for every element. This function takes 3 arguments
 *     (the register, function index, instruction index). The return value is
 *     ignored.
 * @param {S=} opt_obj The object to be used as the value of 'this' within f.
 * @template S
 */
cn.ui.ProgramEditor.prototype.forEachRegister = function(f, opt_obj) {
  this.forEachChild(function(functionEditor, r) {
    functionEditor.forEachChild(function(register, c) {
      f(register, r, c);
    }, opt_obj);
  }, opt_obj);
};

/** @type {!cn.model.Game} @private */
cn.ui.ProgramEditor.prototype.game_;

/** @type {!cn.ui.GameUi} @private */
cn.ui.ProgramEditor.prototype.ui_;

/** @type {!goog.fx.DragDropGroup} @private */
cn.ui.ProgramEditor.prototype.conditionDragDropGroup_;

/** @type {!goog.fx.DragDropGroup} @private */
cn.ui.ProgramEditor.prototype.commandDragDropGroup_;
<|endoftext|>


<commit_before>// ** I18N
// Calendar PL language
// Author: Artur Filipiak, <imagen@poczta.fm>
// January, 2004
// Encoding: UTF-8
Calendar._DN = new Array
("Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela");

Calendar._SDN = new Array
("N", "Pn", "Wt", "Śr", "Cz", "Pt", "So", "N");

Calendar._MN = new Array
("Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień");

Calendar._SMN = new Array
("Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru");

// tooltips
Calendar._TT = {};
Calendar._TT["INFO"] = "O kalendarzu";

Calendar._TT["ABOUT"] =
"DHTML Date/Time Selector\n" +
"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
"\n\n" +
"Wybór daty:\n" +
"- aby wybrać rok użyj przycisków \xab, \xbb\n" +
"- aby wybrać miesiąc użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" +
"- aby przyspieszyć wybór przytrzymaj wciśnięty przycisk myszy nad ww. przyciskami.";
Calendar._TT["ABOUT_TIME"] = "\n\n" +
"Wybór czasu:\n" +
"- aby zwiększyć wartość kliknij na dowolnym elemencie selekcji czasu\n" +
"- aby zmniejszyć wartość użyj dodatkowo klawisza Shift\n" +
"- możesz również poruszać myszkę w lewo i prawo wraz z wciśniętym lewym klawiszem.";

Calendar._TT["PREV_YEAR"] = "Poprz. rok (przytrzymaj dla menu)";
Calendar._TT["PREV_MONTH"] = "Poprz. miesiąc (przytrzymaj dla menu)";
Calendar._TT["GO_TODAY"] = "Pokaż dziś";
Calendar._TT["NEXT_MONTH"] = "Nast. miesiąc (przytrzymaj dla menu)";
Calendar._TT["NEXT_YEAR"] = "Nast. rok (przytrzymaj dla menu)";
Calendar._TT["SEL_DATE"] = "Wybierz datę";
Calendar._TT["DRAG_TO_MOVE"] = "Przesuń okienko";
Calendar._TT["PART_TODAY"] = " (dziś)";
Calendar._TT["MON_FIRST"] = "Pokaż Poniedziałek jako pierwszy";
Calendar._TT["SUN_FIRST"] = "Pokaż Niedzielę jako pierwszą";
Calendar._TT["CLOSE"] = "Zamknij";
Calendar._TT["TODAY"] = "Dziś";
Calendar._TT["TIME_PART"] = "(Shift-)klik | drag, aby zmienić wartość";

// date formats
Calendar._TT["DEF_DATE_FORMAT"] = "%Y.%m.%d";
Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";

Calendar._TT["WK"] = "wk";<commit_msg>updated pl calendar translation (closes #531 - patch from krzychu.danek)<commit_after>// ** I18N

// Calendar PL language
// Author: Krzychu Danek, <krzychu.danek@gmail.com>
// Encoding: UTF-8
// Distributed under the same terms as the calendar itself.

// For translators: please use UTF-8 if possible.  We strongly believe that
// Unicode is the answer to a real internationalized world.  Also please
// include your contact information in the header, as can be seen above.

// full day names
Calendar._DN = new Array
("Niedziela",
 "Poniedziałek",
 "Wtorek",
 "Środa",
 "Czwartek",
 "Piątek",
 "Sobota",
 "Niedziela");

// Please note that the following array of short day names (and the same goes
// for short month names, _SMN) isn't absolutely necessary.  We give it here
// for exemplification on how one can customize the short day names, but if
// they are simply the first N letters of the full name you can simply say:
//
//   Calendar._SDN_len = N; // short day name length
//   Calendar._SMN_len = N; // short month name length
//
// If N = 3 then this is not needed either since we assume a value of 3 if not
// present, to be compatible with translation files that were written before
// this feature.

// short day names
Calendar._SDN = new Array
("N",
 "Pon",
 "Wt",
 "Śr",
 "Czw",
 "Pi",
 "So",
 "N");

// First day of the week. "0" means display Sunday first, "1" means display
// Monday first, etc.
Calendar._FD = 1;

// full month names
Calendar._MN = new Array
("Styczeń",
 "Luty",
 "Marzec",
 "Kwiecień",
 "Maj",
 "Czerwiec",
 "Lipiec",
 "Sierpień",
 "Wrzesień",
 "Październik",
 "Listopad",
 "Grudzień");

// short month names
Calendar._SMN = new Array
("Sty",
 "Lut",
 "Mar",
 "Kwi",
 "Maj",
 "Cze",
 "Lip",
 "Sie",
 "Wrz",
 "Paź",
 "Lis",
 "Gru");

// tooltips
Calendar._TT = {};
Calendar._TT["INFO"] = "O kalendarzu";

Calendar._TT["ABOUT"] =
"DHTML Date/Time Selector\n" +
"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
"Distributed under GNU LGPL.  See http://gnu.org/licenses/lgpl.html for details." +
"\n\n" +
"Wybór daty:\n" +
"- aby wybrać rok użyj przycisków \xab, \xbb\n" +
"- aby wybrać miesiąc użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" +
"- aby przyspieszyć wybór przytrzymaj wciśnięty przycisk myszy nad ww. przyciskami.";
Calendar._TT["ABOUT_TIME"] = "\n\n" +
"Wybór czasu:\n" +
"- aby zwiększyć wartość kliknij na dowolnym elemencie selekcji czasu\n" +
"- aby zmniejszyć wartość użyj dodatkowo klawisza Shift\n" +
"- możesz również poruszać myszkę w lewo i prawo wraz z wciśniętym lewym klawiszem.";

Calendar._TT["PREV_YEAR"] = "Poprz. rok (przytrzymaj dla menu)";
Calendar._TT["PREV_MONTH"] = "Poprz. miesiąc (przytrzymaj dla menu)";
Calendar._TT["GO_TODAY"] = "Pokaż dziś";
Calendar._TT["NEXT_MONTH"] = "Nast. miesiąc (przytrzymaj dla menu)";
Calendar._TT["NEXT_YEAR"] = "Nast. rok (przytrzymaj dla menu)";
Calendar._TT["SEL_DATE"] = "Wybierz datę";
Calendar._TT["DRAG_TO_MOVE"] = "Przesuń okienko";
Calendar._TT["PART_TODAY"] = " (dziś)";

// the following is to inform that "%s" is to be the first day of week
// %s will be replaced with the day name.
Calendar._TT["DAY_FIRST"] = "Pokaż dzień %s jako pierwszy";

// This may be locale-dependent.  It specifies the week-end days, as an array
// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
// means Monday, etc.
Calendar._TT["WEEKEND"] = "0,6";

Calendar._TT["CLOSE"] = "Zamknij";
Calendar._TT["TODAY"] = "Dziś";
Calendar._TT["TIME_PART"] = "(Shift-)klik | drag, aby zmienić wartość";

// date formats
Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";

Calendar._TT["WK"] = "wk";
Calendar._TT["TIME"] = "Czas:";
<|endoftext|>


<commit_before>var round = require('../round');
var partial = require('chessground').util.partial;
var crazyDrag = require('./crazyDrag');
var game = require('game').game;
var m = require('mithril');

var eventNames = ['mousedown', 'touchstart'];
var pieceRoles = ['pawn', 'knight', 'bishop', 'rook', 'queen'];

module.exports = {
  pocket: function(ctrl, color, position) {
    var step = round.plyStep(ctrl.data, ctrl.vm.ply);
    if (!step.crazy) return;
    var droppedRole = ctrl.vm.justDropped;
    var preDropRole = ctrl.vm.preDrop;
    var pocket = step.crazy.pockets[color === 'white' ? 0 : 1];
    var usablePos = position == (ctrl.vm.flip ? 'top' : 'bottom');
    var usable = usablePos && !ctrl.replaying() && game.isPlayerPlaying(ctrl.data);
    return m('div', {
        class: 'pocket is2d ' + position + (usable ? ' usable' : ''),
        config: function(el, isUpdate, ctx) {
          if (ctx.flip === ctrl.vm.flip || !usablePos) return;
          ctx.flip = ctrl.vm.flip;
          var onstart = partial(crazyDrag, ctrl);
          eventNames.forEach(function(name) {
            el.addEventListener(name, onstart);
          });
          ctx.onunload = function() {
            eventNames.forEach(function(name) {
              el.removeEventListener(name, onstart);
            });
          }
        }
      },
      pieceRoles.map(function(role) {
        var nb = pocket[role] || 0;
        if (color === ctrl.data.player.color && droppedRole === role) nb--;
        return m('piece', {
          'data-role': role,
          'data-color': color,
          'data-nb': nb,
          'data-premove': preDropRole === role,
          class: role + ' ' + color
        });
      })
    );
  }
};
<commit_msg>css cleanup<commit_after>var round = require('../round');
var partial = require('chessground').util.partial;
var crazyDrag = require('./crazyDrag');
var game = require('game').game;
var m = require('mithril');

var eventNames = ['mousedown', 'touchstart'];
var pieceRoles = ['pawn', 'knight', 'bishop', 'rook', 'queen'];

module.exports = {
  pocket: function(ctrl, color, position) {
    var step = round.plyStep(ctrl.data, ctrl.vm.ply);
    if (!step.crazy) return;
    var droppedRole = ctrl.vm.justDropped;
    var preDropRole = ctrl.vm.preDrop;
    var pocket = step.crazy.pockets[color === 'white' ? 0 : 1];
    var usablePos = position === (ctrl.vm.flip ? 'top' : 'bottom');
    var usable = usablePos && !ctrl.replaying() && game.isPlayerPlaying(ctrl.data);
    var activeColor = color === ctrl.data.player.color;
    return m('div', {
        class: 'pocket is2d ' + position + (usable ? ' usable' : ''),
        config: function(el, isUpdate, ctx) {
          if (ctx.flip === ctrl.vm.flip || !usablePos) return;
          ctx.flip = ctrl.vm.flip;
          var onstart = partial(crazyDrag, ctrl);
          eventNames.forEach(function(name) {
            el.addEventListener(name, onstart);
          });
          ctx.onunload = function() {
            eventNames.forEach(function(name) {
              el.removeEventListener(name, onstart);
            });
          }
        }
      },
      pieceRoles.map(function(role) {
        var nb = pocket[role] || 0;
        if (activeColor && droppedRole === role) nb--;
        return m('piece', {
          'data-role': role,
          'data-color': color,
          'data-nb': nb,
          'data-premove': activeColor && preDropRole === role,
          class: role + ' ' + color
        });
      })
    );
  }
};
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import {getDirection} from '@canvas/i18n/rtlHelper'
import defaultTinymceConfig from '@instructure/canvas-rce/es/defaultTinymceConfig'

export default class EditorConfig {
  /**
   * Create an editor config instance, with some internal state passed in
   *   so the object knows how to generate a dynamic hash of default
   *   configuration parameters.  May get overridden by merging
   *   with another hash of overwriting config parameters.
   *
   *  @param {tinymce} tinymce the tinymce global which we use to pull
   *    some config info off of like the BaseURL for refrencing the skin css
   *  @param {INST} inst a config hash defined in public/javascripts/INST.js,
   *    provides feature information like whether notorious is enabled for
   *    their account.  Generally you can just pass it in after requiring it.
   *  @param {int} width The width of the viewport the editor is in, this is
   *    useful for deciding how many buttons to show per toolbar line
   *  @param {string} domId the "id" attribute of the element that's going
   *    to be transformed with a tinymce editor
   *
   *  @exports
   *  @constructor
   *  @return {EditorConfig}
   */
  constructor(tinymce, inst, width, domId) {
    this.baseURL = tinymce.baseURL
    this.extraButtons = inst.editorButtons
    this.instConfig = inst
    this.viewportWidth = width
    this.idAttribute = domId
  }

  /**
   * export an appropriate config hash for this config instance.
   * This returns a simple javascript object with our default
   * configuration parameters enabled.  You can override
   * any configuration parameters you want by combining this hash
   * with an override hash at runtime using "$.extend" or similar:
   *
   *   var overrides = { resize: false };
   *   var tinyOptions = $.extend(editorConfig.defaultConfig(), overrides);
   *   tinymce.init(tinyOptions);
   *
   * @return {Hash}
   */
  defaultConfig() {
    return {
      ...defaultTinymceConfig,

      body_class:
        window.ENV.FEATURES?.canvas_k6_theme ||
        window.ENV.K5_SUBJECT_COURSE ||
        window.ENV.K5_HOMEROOM_COURSE
          ? 'elementary-theme'
          : 'default-theme',
      selector: `#${this.idAttribute}`,
      directionality: getDirection(),
      // RCEWrapper includes instructure_equation, so it shouldn't be necessary here
      // but if I leave it out equation_spec.rb and new_ui_spec selenium specs fail
      // in jenkins (but not locally) and I can't explain why. Doesn't hurt to put it here
      plugins: ['instructure_equation'],

      content_css: window.ENV.url_to_what_gets_loaded_inside_the_tinymce_editor_css,

      init_instance_callback: ed => {
        $(`#tinymce-parent-of-${ed.id}`) // eslint-disable-line no-undef
          .css('visibility', 'visible')
      },
      // if kalturaSettings is missing, we have no kaltura to upload to
      // if present, user may have chosen to hide the button anyway.
      show_media_upload: !!INST.kalturaSettings && !INST.kalturaSettings.hide_rte_button
    }
  }
}
<commit_msg>Remove ability to set H1 tags in RCE<commit_after>/*
 * Copyright (C) 2015 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation, version 3 of the License.
 *
 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import {getDirection} from '@canvas/i18n/rtlHelper'
import defaultTinymceConfig from '@instructure/canvas-rce/es/defaultTinymceConfig'

export default class EditorConfig {
  /**
   * Create an editor config instance, with some internal state passed in
   *   so the object knows how to generate a dynamic hash of default
   *   configuration parameters.  May get overridden by merging
   *   with another hash of overwriting config parameters.
   *
   *  @param {tinymce} tinymce the tinymce global which we use to pull
   *    some config info off of like the BaseURL for refrencing the skin css
   *  @param {INST} inst a config hash defined in public/javascripts/INST.js,
   *    provides feature information like whether notorious is enabled for
   *    their account.  Generally you can just pass it in after requiring it.
   *  @param {int} width The width of the viewport the editor is in, this is
   *    useful for deciding how many buttons to show per toolbar line
   *  @param {string} domId the "id" attribute of the element that's going
   *    to be transformed with a tinymce editor
   *
   *  @exports
   *  @constructor
   *  @return {EditorConfig}
   */
  constructor(tinymce, inst, width, domId) {
    this.baseURL = tinymce.baseURL
    this.extraButtons = inst.editorButtons
    this.instConfig = inst
    this.viewportWidth = width
    this.idAttribute = domId
  }

  /**
   * export an appropriate config hash for this config instance.
   * This returns a simple javascript object with our default
   * configuration parameters enabled.  You can override
   * any configuration parameters you want by combining this hash
   * with an override hash at runtime using "$.extend" or similar:
   *
   *   var overrides = { resize: false };
   *   var tinyOptions = $.extend(editorConfig.defaultConfig(), overrides);
   *   tinymce.init(tinyOptions);
   *
   * @return {Hash}
   */
  defaultConfig() {
    return {
      ...defaultTinymceConfig,

      body_class:
        window.ENV.FEATURES?.canvas_k6_theme ||
        window.ENV.K5_SUBJECT_COURSE ||
        window.ENV.K5_HOMEROOM_COURSE
          ? 'elementary-theme'
          : 'default-theme',
      selector: `#${this.idAttribute}`,
      directionality: getDirection(),
      // RCEWrapper includes instructure_equation, so it shouldn't be necessary here
      // but if I leave it out equation_spec.rb and new_ui_spec selenium specs fail
      // in jenkins (but not locally) and I can't explain why. Doesn't hurt to put it here
      plugins: ['instructure_equation'],

      content_css: window.ENV.url_to_what_gets_loaded_inside_the_tinymce_editor_css,

      style_formats: [
        {title: 'Heading 2', format: 'h2'},
        {title: 'Heading 3', format: 'h3'},
        {title: 'Heading 4', format: 'h4'},
        {title: 'Heading 5', format: 'h5'},
        {title: 'Heading 6', format: 'h6'}
      ],

      init_instance_callback: ed => {
        $(`#tinymce-parent-of-${ed.id}`) // eslint-disable-line no-undef
          .css('visibility', 'visible')
      },
      // if kalturaSettings is missing, we have no kaltura to upload to
      // if present, user may have chosen to hide the button anyway.
      show_media_upload: !!INST.kalturaSettings && !INST.kalturaSettings.hide_rte_button
    }
  }
}
<|endoftext|>


<commit_before>import React from 'react';

import PatreonIcon from 'Icons/PatreonTiny';
import GitHubMarkIcon from 'Icons/GitHubMarkLarge';

import PatreonButton from 'Main/PatreonButton';
import GithubButton from 'Main/GithubButton';

import CyclingVideo from './CyclingVideo';

const INITIAL_BACKGROUNDS = [
  '7TqE3VIAU2odkmneHU', // human salute https://giphy.com/gifs/warcraft-video-games-7TqE3VIAU2odkmneHU
  '5kFzxK6ENfjrcoMgt1', // orc salute https://giphy.com/gifs/warcraft-video-games-5kFzxK6ENfjrcoMgt1
  'PoCoePEEB1EC6buvFU', // blood elf salute https://giphy.com/gifs/warcraft-video-games-PoCoePEEB1EC6buvFU
  '8cv2DoGyUClMuCKalT', // human bow https://giphy.com/gifs/warcraft-video-games-8cv2DoGyUClMuCKalT
  'fUZW0LIJhtbDnBtqkX', // orc bow https://giphy.com/gifs/warcraft-video-games-fUZW0LIJhtbDnBtqkX
  '2erqKiXvYpXeGH9XJ5', // gnome bow https://giphy.com/gifs/warcraft-video-games-2erqKiXvYpXeGH9XJ5
].map(code => `https://media.giphy.com/media/${code}/giphy.mp4`);
// const LOGIN_SUCCESSFUL_BACKGROUNDS = [
//   '1AdZe53o36pL2ifJrW', // approve https://giphy.com/gifs/warcraft-video-games-1AdZe53o36pL2ifJrW
//   '12gdy23jcbqdvqID9D', // human cheer https://giphy.com/gifs/warcraft-video-games-12gdy23jcbqdvqID9D
//   '2fRB16C8fbWsHTogzJ', // orc cheer https://giphy.com/gifs/warcraft-video-games-2fRB16C8fbWsHTogzJ
//   '55kiNDmHdIkd2NJ9L1', // ...gnome cheer  https://giphy.com/gifs/warcraft-video-games-55kiNDmHdIkd2NJ9L1
//   'cQ29kUD2CstrP0Cyyz', // blood elf dh cheer https://giphy.com/gifs/warcraft-video-games-cQ29kUD2CstrP0Cyyz
// ];
// const LOGIN_UNSUCCESSFUL_BACKGROUNDS = [
//   '4N1IhWlgeurYEqBpbd', // no https://giphy.com/gifs/warcraft-video-games-4N1IhWlgeurYEqBpbd
//   'fdGbKBJRylAQ3Gj1f8', // please https://giphy.com/gifs/warcraft-video-games-fdGbKBJRylAQ3Gj1f8
//   '1zgvoYwvgm7LnHpYp4', // blood elf dh no https://giphy.com/gifs/warcraft-video-games-1zgvoYwvgm7LnHpYp4
//   '8h0dtWORphvPgH4O20', // orc no https://giphy.com/gifs/warcraft-video-games-8h0dtWORphvPgH4O20
//   '4a4w6CzSj1t2Hl6gYy', // orc please https://giphy.com/gifs/warcraft-video-games-4a4w6CzSj1t2Hl6gYy
// ];

class Premium extends React.PureComponent {
  render() {
    return (

                    <CyclingVideo
                      videos={INITIAL_BACKGROUNDS}
                      style={{ objectFit: 'cover', width: '100%', height: '100%' }}
                    />

Premium sign in

                      Sign in with your Patreon or GitHub account.

                      <PatreonIcon /> Patreon

                      <GitHubMarkIcon /> GitHub

WoWAnalyzer premium

                Help out development and get WoWAnalyzer premium in return! An early adopter gets the following rewards:

our thanks.

                Doesn't that sound awesome?! You too can get premium by helping out development, either by helping fund development on Patreon or by contributing code via a pull request on GitHub.

                <PatreonButton /> <GithubButton />

    );
  }
}

export default Premium;
<commit_msg>Don't exclude graphics/text<commit_after>import React from 'react';

import PatreonIcon from 'Icons/PatreonTiny';
import GitHubMarkIcon from 'Icons/GitHubMarkLarge';

import PatreonButton from 'Main/PatreonButton';
import GithubButton from 'Main/GithubButton';

import CyclingVideo from './CyclingVideo';

const INITIAL_BACKGROUNDS = [
  '7TqE3VIAU2odkmneHU', // human salute https://giphy.com/gifs/warcraft-video-games-7TqE3VIAU2odkmneHU
  '5kFzxK6ENfjrcoMgt1', // orc salute https://giphy.com/gifs/warcraft-video-games-5kFzxK6ENfjrcoMgt1
  'PoCoePEEB1EC6buvFU', // blood elf salute https://giphy.com/gifs/warcraft-video-games-PoCoePEEB1EC6buvFU
  '8cv2DoGyUClMuCKalT', // human bow https://giphy.com/gifs/warcraft-video-games-8cv2DoGyUClMuCKalT
  'fUZW0LIJhtbDnBtqkX', // orc bow https://giphy.com/gifs/warcraft-video-games-fUZW0LIJhtbDnBtqkX
  '2erqKiXvYpXeGH9XJ5', // gnome bow https://giphy.com/gifs/warcraft-video-games-2erqKiXvYpXeGH9XJ5
].map(code => `https://media.giphy.com/media/${code}/giphy.mp4`);
// const LOGIN_SUCCESSFUL_BACKGROUNDS = [
//   '1AdZe53o36pL2ifJrW', // approve https://giphy.com/gifs/warcraft-video-games-1AdZe53o36pL2ifJrW
//   '12gdy23jcbqdvqID9D', // human cheer https://giphy.com/gifs/warcraft-video-games-12gdy23jcbqdvqID9D
//   '2fRB16C8fbWsHTogzJ', // orc cheer https://giphy.com/gifs/warcraft-video-games-2fRB16C8fbWsHTogzJ
//   '55kiNDmHdIkd2NJ9L1', // ...gnome cheer  https://giphy.com/gifs/warcraft-video-games-55kiNDmHdIkd2NJ9L1
//   'cQ29kUD2CstrP0Cyyz', // blood elf dh cheer https://giphy.com/gifs/warcraft-video-games-cQ29kUD2CstrP0Cyyz
// ];
// const LOGIN_UNSUCCESSFUL_BACKGROUNDS = [
//   '4N1IhWlgeurYEqBpbd', // no https://giphy.com/gifs/warcraft-video-games-4N1IhWlgeurYEqBpbd
//   'fdGbKBJRylAQ3Gj1f8', // please https://giphy.com/gifs/warcraft-video-games-fdGbKBJRylAQ3Gj1f8
//   '1zgvoYwvgm7LnHpYp4', // blood elf dh no https://giphy.com/gifs/warcraft-video-games-1zgvoYwvgm7LnHpYp4
//   '8h0dtWORphvPgH4O20', // orc no https://giphy.com/gifs/warcraft-video-games-8h0dtWORphvPgH4O20
//   '4a4w6CzSj1t2Hl6gYy', // orc please https://giphy.com/gifs/warcraft-video-games-4a4w6CzSj1t2Hl6gYy
// ];

class Premium extends React.PureComponent {
  render() {
    return (

                    <CyclingVideo
                      videos={INITIAL_BACKGROUNDS}
                      style={{ objectFit: 'cover', width: '100%', height: '100%' }}
                    />

Premium sign in

                      Sign in with your Patreon or GitHub account.

                      <PatreonIcon /> Patreon

                      <GitHubMarkIcon /> GitHub

WoWAnalyzer premium

                Help out development and get WoWAnalyzer premium in return! An early adopter gets the following rewards:

our thanks.

                Doesn't that sound awesome?! You too can get premium by helping out development, either by helping fund development on Patreon or by contributing something via a pull request on GitHub.

                <PatreonButton /> <GithubButton />

    );
  }
}

export default Premium;
<|endoftext|>


<commit_before>/**
* Django formset helper
*/
(function($) {
    "use strict";

    var pluginName = 'formset';

    //Show dates in one format, submit in another
    var Formset = function(el, options) {
        var _this = this;

        //Defaults:
        this.defaults = {
            emptyForm: '[data-formset-empty-form]',
            body: '[data-formset-body]',
            add: '[data-formset-add]'
        };
        //Extending options:
        this.opts = $.extend({}, this.defaults, options);

        this.$formset = $(el);
        this.$emptyForm = this.$formset.find(this.opts.emptyForm);
        this.$body = this.$formset.find(this.opts.body);
        this.$add = this.$formset.find(this.opts.add);

        this.addForm = (function(addForm) {
            return function() { return addForm.apply(_this, arguments); };
        })(this.addForm);

        this.$add.click(this.addForm);

        // Store a reference to this in the elements
        this.$formset.data(pluginName, this);
    };

    Formset.prototype.addForm = function() {
        var attrs = ['name', 'id', 'for'];
        var selector = $.map(attrs, function(val) {
            return '[' + val + '*=__prefix__]';
        }).join(',');

        var count = this.formCount();
        this.formCount(count + 1);

        var $newForm = this.$emptyForm.clone();
        var $els = $newForm.find(selector);

        $els.each(function(i, el) {
            var $el = $(el);
            $.each(attrs, function(i, attrName) {
                var attr = $el.attr(attrName);
                if (!attr) return;
                $el.attr(attrName, attr.replace('__prefix__', count));
            });
        });

        this.$body.append($newForm);

        return $newForm;

    };

    Formset.prototype.managementForm = function(name) {
        return this.$formset.find('[name=' + this.$formset.data('formset-prefix') + '-' + name + ']');
    };

    Formset.prototype.formCount = function() {
        var $totalForms = this.managementForm('TOTAL_FORMS');

        if (arguments.length) {
            $totalForms.val(arguments[0]);
            return this;
        } else {
            return parseInt($totalForms.val(), 10) || 0;
        }
    };

    Formset.getOrCreate = function(el, options) {
        var rev = $(el).data(pluginName);
        if (!rev) {
            rev = new Formset(el, options);
        }

        return rev;
    };

    $.fn[pluginName] = function() {
        var options, fn, args;
        // Create a new Formset for each element
        if (arguments.length === 0 || (arguments.length === 1 && $.type(arguments[0]) != 'string')) {
            options = arguments[0];
            return this.each(function() {
                return Formset.getOrCreate(this, options);
            });
        }

        // Call a function on each Formset in the selector
        fn = arguments[0];
        args = $.makeArray(arguments).slice(1);

        if (fn in Formset) {
            // Call the Formset class method if it exists
            args.unshift(this);
            return Formset[fn].apply(Formset, args);
        } else {
            throw new Error("Unknown function call " + fn + " for $.fn.formset");
        }
    };
})(jQuery);
<commit_msg>Use <script>.innerHTML and `String.replace` to make new forms<commit_after>/**
* Django formset helper
*/
(function($) {
    "use strict";

    var pluginName = 'formset';

    /**
    * Wraps up a formset, allowing adding, and removing forms
    */
    var Formset = function(el, options) {
        var _this = this;

        //Defaults:
        this.opts = $.extend({}, Formset.defaults, options);

        this.$formset = $(el);
        this.$emptyForm = this.$formset.find(this.opts.emptyForm);
        this.$body = this.$formset.find(this.opts.body);
        this.$add = this.$formset.find(this.opts.add);

        this.formsetPrefix = $(el).data('formset-prefix');

        // Bind to the `Add form` button
        this.addForm = $.proxy(this, 'addForm');
        this.$add.click(this.addForm);

        // Set up the existing forms
        this.$body.find(this.opts.form).each(function(i, form) {
            var $form = $(form);
            _this.bindForm($(this), i);
        });

        // Store a reference to this in the formset element
        this.$formset.data(pluginName, this);
    };

    Formset.defaults = {
        form: '[data-formset-form]',
        emptyForm: 'script[type=form-template][data-formset-empty-form]',
        body: '[data-formset-body]',
        add: '[data-formset-add]',
        deleteButton: '[data-formset-delete-button]'

    };

    Formset.prototype.addForm = function() {
        var newIndex = this.formCount();
        this.formCount(newIndex + 1);

        var newFormHtml = this.$emptyForm.html()
            .replace(new RegExp('__prefix__', 'g'), newIndex)
            .replace(new RegExp('<\\\\/script>', 'g'), '</script>');

        var $newForm = $(newFormHtml);
        this.$body.append($newForm);
        this.bindForm($newForm, newIndex);
        $newForm.slideUp(0);
        $newForm.slideDown();

        return $newForm;
    };

    /**
    * Attach any events needed to a new form
    */
    Formset.prototype.bindForm = function($form, index) {
        var prefix = this.formsetPrefix + '-' + index;
        $form.data(pluginName + '__formPrefix', prefix);

        var $delete = $form.find('[name=' + prefix + '-DELETE]');
        var $deleteButton = $form.find(this.opts.deleteButton);

        if ($deleteButton.length) {
            $deleteButton.bind('click', function() {
                $form.slideUp();
                $delete.attr('checked', true);
            });

            if ($delete.is(':checked')) {
                $form.slideUp(0);
            }
        }
    };

    Formset.prototype.managementForm = function(name) {
        return this.$formset.find('[name=' + this.formsetPrefix + '-' + name + ']');
    };

    Formset.prototype.formCount = function() {
        var $totalForms = this.managementForm('TOTAL_FORMS');

        if (arguments.length) {
            $totalForms.val(arguments[0]);
            return this;
        } else {
            return parseInt($totalForms.val(), 10) || 0;
        }
    };

    Formset.getOrCreate = function(el, options) {
        var rev = $(el).data(pluginName);
        if (!rev) {
            rev = new Formset(el, options);
        }

        return rev;
    };

    $.fn[pluginName] = function() {
        var options, fn, args;
        // Create a new Formset for each element
        if (arguments.length === 0 || (arguments.length === 1 && $.type(arguments[0]) != 'string')) {
            options = arguments[0];
            return this.each(function() {
                return Formset.getOrCreate(this, options);
            });
        }

        // Call a function on each Formset in the selector
        fn = arguments[0];
        args = $.makeArray(arguments).slice(1);

        if (fn in Formset) {
            // Call the Formset class method if it exists
            args.unshift(this);
            return Formset[fn].apply(Formset, args);
        } else {
            throw new Error("Unknown function call " + fn + " for $.fn.formset");
        }
    };
})(jQuery);
<|endoftext|>


<commit_before>/* eslint-disable no-console */
const { Command } = require('discord.js-commando');

module.exports = class CleanCommand extends Command {
	constructor(client) {
		super(client, {
			name: 'clean',
			aliases: ['purge', 'prune'],
			group: 'util',
			memberName: 'clean',
			description: 'Deletes messages.',
			format: '<number> [<filter> <argument>]',
			details: `Deletes msgs. Here is a list of filters:
				__text ...:__ Messages containing the following text
				__invites:__ Messages containing an invite
				__user @user:__ Messages sent by @user
				__bots:__ Messages sent by bots
				__uploads:__ Messages containing an attachment
				__links:__ Messages containing a link
				__length #:__ Messages longer than the specified length`,
			examples: ['clean 10', 'clean 20 text test', 'clean 10 invites', 'clean 50 user @Crawl#3280', 'clean 10 bots', 'clean 20 uploads', 'clean 100 links', 'clean 50 length 10'],
			guildOnly: true,
			argsType: 'multiple',
			argsCount: 3
		});
	}

	hasPermission(msg) {
		return msg.author.id === this.client.options.owner;
	}

	async run(msg, args) {
		if (msg.author.id !== '81440962496172032') {
			return msg.say(`${msg.author}, don't set me up on stuff you can't even do yourself!`);
		}
		if (!args[0] || isNaN(args[0])) {
			return msg.say(`${msg.author}, atleast provide me with a number!`);
		}

		let limit = 100;
		let filter = null;
		if (/^[1-9]+/.test(args[0])) {
			limit = parseInt(args[0]) + 1;
			if (limit > 100) {
				limit = 100;
			}
		}

		if (args[1]) {
			if (/^text/.test(args[1])) {
				filter = message => message.content.includes(args[2]);
			} else if (args[1] === 'invite') {
				filter = message => message.content.search(/(discord\.gg\/.+|discordapp\.com\/invite\/.+)/i) !== -1;
			} else if (args[1] === 'user') {
				if (args[2]) {
					filter = message => message.author.id === args[2].replace(/<|!|>|@/g, '');
				} else {
					return msg.say(`${msg.author}, you have to mention someone.`);
				}
			} else if (args[1] === 'bots') {
				filter = message => message.author.bot === true;
			} else if (args[1] === 'you') {
				filter = message => message.author.id === message.client.user.id;
			} else if (args[1] === 'upload') {
				filter = message => message.attachments.size !== 0;
			} else if (args[1] === 'links') {
				filter = message => message.content.search(/https?:\/\/[^ \/\.]+\.[^ \/\.]+/) !== -1;
			} else if (args[1] === 'length' && /\d+/.test(args[2])) {
				let max = parseInt(args[2]);
				filter = message => message.content.length > max;
			} else {
				return msg.say(`${msg.author}, that is not a valid filter. Do \`help clean\` for all available filters.`);
			}
		}

		if (!args[1]) {
			return msg.channel.fetchMessages({ limit: limit })
			.then(messagesToDelete => {
				msg.channel.bulkDelete(messagesToDelete);
			})
			.then(() => {
				msg.say(`I cleaned up the number of messages you requested, ${msg.author}.`)
				.then(sentMessage => {
					sentMessage.delete(4000);
				});
			})
			.catch(error => {
				console.log(error);
				msg.say(`${msg.author}, I got an error over here: ${error}`);
			});
		}
		return msg.channel.fetchMessages({ limit: limit })
			.then(messages => {
				let messageFilter = messages.filter(filter);
				msg.channel.bulkDelete(messageFilter);
			})
			.then(() => {
				msg.say(`I cleaned up the number of messages you requested, ${msg.author}.`)
					.then(sentMessage => {
						sentMessage.delete(4000);
					});
			})
			.catch(error => {
				console.log(error);
				msg.say(`${msg.author}, I got an error over here: ${error}`);
			});
	}
};
<commit_msg>cba to search<commit_after>/* eslint-disable no-console */
const { Command } = require('discord.js-commando');

module.exports = class CleanCommand extends Command {
	constructor(client) {
		super(client, {
			name: 'clean',
			aliases: ['purge', 'prune'],
			group: 'util',
			memberName: 'clean',
			description: 'Deletes messages.',
			format: '<number> [<filter> <argument>]',
			details: `Deletes msgs. Here is a list of filters:
				__text ...:__ Messages containing the following text
				__invites:__ Messages containing an invite
				__user @user:__ Messages sent by @user
				__bots:__ Messages sent by bots
				__uploads:__ Messages containing an attachment
				__links:__ Messages containing a link
				__length #:__ Messages longer than the specified length`,
			examples: ['clean 10', 'clean 20 text test', 'clean 10 invites', 'clean 50 user @Crawl#3280', 'clean 10 bots', 'clean 20 uploads', 'clean 100 links', 'clean 50 length 10'],
			guildOnly: true,
			argsType: 'multiple',
			argsCount: 3
		});
	}

	hasPermission(msg) {
		return msg.author.id === this.client.options.owner;
	}

	async run(msg, args) {
		if (msg.author.id !== '81440962496172032') {
			return msg.say(`${msg.author}, don't set me up on stuff you can't even do yourself!`);
		}
		if (!args[0] || isNaN(args[0])) {
			return msg.say(`${msg.author}, atleast provide me with a number!`);
		}

		let limit = 100;
		let filter = null;
		if (/^[1-9]+/.test(args[0])) {
			limit = parseInt(args[0]) + 1;
			if (limit > 100) {
				limit = 100;
			}
		}

		if (args[1]) {
			if (/^text/.test(args[1])) {
				filter = message => message.content.includes(args[2]);
			} else if (args[1] === 'invite') {
				filter = message => message.content.search(/(discord\.gg\/.+|discordapp\.com\/invite\/.+)/i) !== -1;
			} else if (args[1] === 'user') {
				if (args[2]) {
					filter = message => message.author.id === args[2].replace(/<|!|>|@/g, '');
				} else {
					return msg.say(`${msg.author}, you have to mention someone.`);
				}
			} else if (args[1] === 'bots') {
				filter = message => message.author.bot === true;
			} else if (args[1] === 'you') {
				filter = message => message.author.id === message.client.user.id;
			} else if (args[1] === 'upload') {
				filter = message => message.attachments.size !== 0;
			} else if (args[1] === 'links') {
				filter = message => message.content.search(/https?:\/\/[^ \/\.]+\.[^ \/\.]+/) !== -1;
			} else if (args[1] === 'length' && /\d+/.test(args[2])) {
				let max = parseInt(args[2]);
				filter = message => message.content.length > max;
			} else {
				return msg.say(`${msg.author}, that is not a valid filter. Do \`help clean\` for all available filters.`);
			}
		}

		if (!args[1]) {
			return msg.channel.fetchMessages({ limit: limit })
			.then(messagesToDelete => {
				msg.channel.bulkDelete(messagesToDelete);
			})
			.then(() => {
				msg.say(`I cleaned up the number of messages you requested, ${msg.author}.`)
				.then(sentMessage => {
					sentMessage.delete(4000);
				});
			})
			.catch(error => {
				console.log(error);
			});
		}
		return msg.channel.fetchMessages({ limit: limit })
			.then(messages => {
				let messageFilter = messages.filter(filter);
				msg.channel.bulkDelete(messageFilter);
			})
			.then(() => {
				msg.say(`I cleaned up the number of messages you requested, ${msg.author}.`)
					.then(sentMessage => {
						sentMessage.delete(4000);
					});
			})
			.catch(error => {
				console.log(error);
			});
	}
};

process.on("unhandledRejection", err => {
	console.error("Uncaught Promise Error: \n" + err.stack);
});
<|endoftext|>


<commit_before>if(typeof environment == 'undefined') environment = 'default'; // Override me!

// The scope when none is set.
nullScope = (function(){ return this; }).call();

var results;
var currentTest;
var moduleName;
var moduleSetupMethod;
var moduleTeardownMethod;

var syncTestsRunning = true;

// Capturing the timers here b/c Mootools (and maybe other frameworks) may clear a timeout that
// it kicked off after this script is loaded, which would throw off a simple incrementing mechanism.
var capturedTimers = [];

// This declaration has the effect of pulling setTimeout/clearTimeout off the window's prototype
// object and setting it directly on the window itself. From here it can be globally reset while
// retaining the reference to the native setTimeout method. More about this here:
//
// http://www.adequatelygood.com/2011/4/Replacing-setTimeout-Globally

nullScope.setTimeout = nullScope.setTimeout;
nullScope.clearTimeout = nullScope.clearTimeout;

var nativeSetTimeout = nullScope.setTimeout;
var nativeClearTimeout = nullScope.clearTimeout;

var testStartTime;
var runtime;

// Arrays and objects must be treated separately here because in IE arrays with undefined
// elements will not pass the .hasOwnProperty check. For example [undefined].hasOwnProperty('0')
// will report false.
var arrayEqual = function(one, two) {
  var i, result = true;
  testArrayEach(one, function(a, i) {
    if(!testIsEqual(one[i], two[i])) {
      result = false;
    }
  });
  return result && one.length === two.length;
}

var sortOnStringValue = function(arr) {
  return arr.sort(function(a, b) {
    var aType = typeof a;
    var bType = typeof b;
    var aVal = String(a);
    var bVal = String(b);
    if(aType != bType) {
      return aType < bType;
    }
    if(aVal === bVal) return 0;
    return a < b ? -1 : 1;
  });
}

var testArrayIndexOf = function(arr, obj) {
  for(var i = 0; i < arr.length; i++) {
    if(arr[i] === obj) {
      return i;
    }
  }
  return -1;
}

testCloneObject = function(obj) {
  var result = {}, key;
  for(key in obj) {
    if(!obj.hasOwnProperty(key)) continue;
    result[key] = obj[key];
  }
  return result;
}

testArrayEach = function(arr, fn, sparse) {
  var length = arr.length, i = 0;
  while(i < length) {
    if(!(i in arr)) {
      return testIterateOverSparseArray(arr, fn, i);
    } else if(fn.call(arr, arr[i], i, arr) === false) {
      break;
    }
    i++;
  }
}

testIterateOverSparseArray = function(arr, fn, fromIndex) {
  var indexes = [], i;
  for(i in arr) {
    if(testIsArrayIndex(arr, i) && i >= fromIndex) {
      indexes.push(parseInt(i));
    }
  }
  testArrayEach(indexes.sort(), function(index) {
    return fn.call(arr, arr[index], index, arr);
  });
  return arr;
}

testIsArrayIndex = function(arr, i) {
  return i in arr && (i >>> 0) == i && i != 0xffffffff;
}

testIsArray = function(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}

testPadNumber = function(val, place, sign) {
  var num = Math.abs(val);
  var len = Math.abs(num).toString().replace(/\.\d+/, '').length;
  var str =  new Array(Math.max(0, place - len) + 1).join('0') + num;
  if(val < 0 || sign) {
    str = (val < 0 ? '-' : '+') + str;
  }
  return str;
}

testCapitalize = function(str) {
  return str.slice(0,1).toUpperCase() + str.slice(1);
}

var objectEqual = function(one, two) {
  var onep = 0, twop = 0, key;
  if(one && two) {
    for(key in one) {
      if(!one.hasOwnProperty(key)) continue;
      onep++;
      if(!testIsEqual(one[key], two[key])) {
        return false;
      }
    }
    for(key in two) {
      if(!two.hasOwnProperty(key)) continue;
      twop++;
    }
  }
  return onep === twop && String(one) === String(two);
}

var testIsEqual = function(one, two) {

  var type, klass;

  type = typeof one;

  if(type === 'string' || type === 'boolean' || one == null) {
    return one === two;
  } else if(type === 'number') {
    return (isNaN(one) && isNaN(two)) || one === two;
  }

  klass = Object.prototype.toString.call(one);

  if(klass === '[object Date]') {
    return one.getTime() === two.getTime();
  } else if(klass === '[object RegExp]') {
    return String(one) === String(two);
  } else if(klass === '[object Array]') {
    return arrayEqual(one, two);
  } else if((klass === '[object Object]' || klass === '[object Arguments]') && ('hasOwnProperty' in one) && type === 'object') {
    return objectEqual(one, two);
  } else if(isNaN(one) && isNaN(two)) {
    return true;
  }

  return one === two;
}

var testIsClass = function(obj, klass) {
  return Object.prototype.toString.call(obj) === '[object ' + klass + ']';
}

var addFailure = function(actual, expected, message, stack, warning) {
  var meta = getMeta(stack);
  currentTest.failures.push({ actual: actual, expected: expected, message: message, file: meta.file, line: meta.line, col: meta.col, warning: !!warning });
}

var getMeta = function(stack) {
  var level = 4;
  if(stack !== undefined) {
    level += stack;
  }
  var e = new Error();
  if(!e.stack) {
    return {};
  }
  var s = e.stack.split(/@|^\s+at/m);
  var match = s[level].match(/(.+\.js):(\d+)(?::(\d+))?/);
  if(!match) match = [];
  return { file: match[1], line: match[2], col: match[3] };
}

var checkCanFinish = function() {
  if(!syncTestsRunning && capturedTimers.length == 0) {
    testsFinished();
    restoreNativeTimeout();
  }
}

var testsStarted = function() {
  if(typeof testsStartedCallback != 'undefined') {
    testsStartedCallback(results);
  }
  if(environment == 'node') {
    console.info('\n----------------------- STARTING TESTS ----------------------------\n');
  }
  testStartTime = new Date();
}

var testsFinished = function() {
  runtime = new Date() - testStartTime;
  if(typeof testsFinishedCallback != 'undefined') {
    testsFinishedCallback(results, runtime);
  }
  if(environment == 'node') {
    this.totalFailures = 0
    // displayResults will increment totalFailures by 1 for each failed test encountered
    displayResults();
    // will exit now setting the status to the number of failed tests
    process.exit(this.totalFailures);
  }
  results = [];
}

var displayResults = function() {
  var i, j, failure, totalAssertions = 0, totalFailures = 0;
  for (i = 0; i < results.length; i += 1) {
    totalAssertions += results[i].assertions;
    this.totalFailures += results[i].failures.length;
    for(j = 0; j < results[i].failures.length; j++) {
      failure = results[i].failures[j];
      console.info('\n'+ (j + 1) + ') Failure:');
      console.info(failure.message);
      console.info('Expected: ' + JSON.stringify(failure.expected) + ' but was: ' + JSON.stringify(failure.actual));
      console.info('File: ' + failure.file + ', Line: ' + failure.line, ' Col: ' + failure.col + '\n');
    }
  };
  var time = (runtime / 1000);
  console.info(results.length + ' tests, ' + totalAssertions + ' assertions, ' + this.totalFailures + ' failures, ' + time + 's\n');
}

test = function(name, fn) {
  if(moduleSetupMethod) {
    moduleSetupMethod();
  }
  if(!results) {
    results = [];
    testsStarted();
  }
  currentTest = {
    name: name,
    assertions: 0,
    failures: []
  };
  try {
    fn.call();
  } catch(e) {
    console.info(e);
  }
  results.push(currentTest);
  if(moduleTeardownMethod) {
    moduleTeardownMethod();
  }
}

setTimeout = function(fn, delay) {
  var timer = nativeSetTimeout(function() {
    fn.apply(this, arguments);
    removeCapturedTimer(timer);
    checkCanFinish();
  }, delay);
  capturedTimers.push(timer);
  return timer;
}

clearTimeout = function(timer) {
  removeCapturedTimer(timer);
  return nativeClearTimeout(timer);
}

restoreNativeTimeout = function() {
  setTimeout = nativeSetTimeout;
}

var removeCapturedTimer = function(timer) {
  var index = testArrayIndexOf(capturedTimers, timer);
  if(index !== -1) {
    capturedTimers.splice(index, 1);
  }
};

testModule = function(name, options) {
  moduleName = name;
  moduleSetupMethod = options.setup;
  moduleTeardownMethod = options.teardown;
}

equal = function(actual, expected, message, exceptions, stack) {
  exceptions = exceptions || {};
  if(environment in exceptions) {
    expected = exceptions[environment];
  }
  currentTest.assertions++;
  if(!testIsEqual(actual, expected)) {
    addFailure(actual, expected, message, stack);
  }
}

notEqual = function(actual, expected, message, exceptions) {
  equal(actual !== expected, true, message + ' | strict equality', exceptions, 1);
}

equalWithWarning = function(expected, actual, message) {
  if(expected != actual) {
    addFailure(actual, expected, message, null, true);
  }
}

equalWithMargin = function(actual, expected, margin, message) {
  equal((actual > expected - margin) && (actual < expected + margin), true, message, null, 1);
}

// Array content is equal, but order may differ
arrayEquivalent = function(a, b, message) {
  equal(sortOnStringValue(a), sortOnStringValue(b), message);
}

raisesError = function(fn, message, exceptions) {
  var raised = false;
  try {
    fn.call();
  } catch(e) {
    raised = true;
  }
  equal(raised, true, message, exceptions, 1);
}

skipEnvironments = function(environments, test) {
  if(testArrayIndexOf(environments, environment) === -1) {
    test.call();
  }
}

syncTestsFinished = function() {
  syncTestsRunning = false;
  checkCanFinish();
}

// This method has 2 benefits:
// 1. It gives asynchronous functions their own scope so vars can't be overwritten later by other asynchronous functions
// 2. It runs the tests after the CPU is free decreasing the chance of timing based errors.
async = function(fn) {
  setTimeout(fn, 200);
}

<commit_msg>fix for problem with unit test suite<commit_after>if(typeof environment == 'undefined') environment = 'default'; // Override me!

// The scope when none is set.
nullScope = (function(){ return this; }).call();

var results;
var currentTest;
var moduleName;
var moduleSetupMethod;
var moduleTeardownMethod;

var syncTestsRunning = true;

// Capturing the timers here b/c Mootools (and maybe other frameworks) may clear a timeout that
// it kicked off after this script is loaded, which would throw off a simple incrementing mechanism.
var capturedTimers = [];

// This declaration has the effect of pulling setTimeout/clearTimeout off the window's prototype
// object and setting it directly on the window itself. From here it can be globally reset while
// retaining the reference to the native setTimeout method. More about this here:
//
// http://www.adequatelygood.com/2011/4/Replacing-setTimeout-Globally

nullScope.setTimeout = nullScope.setTimeout;
nullScope.clearTimeout = nullScope.clearTimeout;

var nativeSetTimeout = nullScope.setTimeout;
var nativeClearTimeout = nullScope.clearTimeout;

var testStartTime;
var runtime;

// Arrays and objects must be treated separately here because in IE arrays with undefined
// elements will not pass the .hasOwnProperty check. For example [undefined].hasOwnProperty('0')
// will report false.
var arrayEqual = function(one, two) {
  var i, result = true;
  if(!one || !two) {
    return false;
  }
  testArrayEach(one, function(a, i) {
    if(!testIsEqual(one[i], two[i])) {
      result = false;
    }
  });
  return result && one.length === two.length;
}

var sortOnStringValue = function(arr) {
  return arr.sort(function(a, b) {
    var aType = typeof a;
    var bType = typeof b;
    var aVal = String(a);
    var bVal = String(b);
    if(aType != bType) {
      return aType < bType;
    }
    if(aVal === bVal) return 0;
    return a < b ? -1 : 1;
  });
}

var testArrayIndexOf = function(arr, obj) {
  for(var i = 0; i < arr.length; i++) {
    if(arr[i] === obj) {
      return i;
    }
  }
  return -1;
}

testCloneObject = function(obj) {
  var result = {}, key;
  for(key in obj) {
    if(!obj.hasOwnProperty(key)) continue;
    result[key] = obj[key];
  }
  return result;
}

testArrayEach = function(arr, fn, sparse) {
  var length = arr.length, i = 0;
  while(i < length) {
    if(!(i in arr)) {
      return testIterateOverSparseArray(arr, fn, i);
    } else if(fn.call(arr, arr[i], i, arr) === false) {
      break;
    }
    i++;
  }
}

testIterateOverSparseArray = function(arr, fn, fromIndex) {
  var indexes = [], i;
  for(i in arr) {
    if(testIsArrayIndex(arr, i) && i >= fromIndex) {
      indexes.push(parseInt(i));
    }
  }
  testArrayEach(indexes.sort(), function(index) {
    return fn.call(arr, arr[index], index, arr);
  });
  return arr;
}

testIsArrayIndex = function(arr, i) {
  return i in arr && (i >>> 0) == i && i != 0xffffffff;
}

testIsArray = function(obj) {
  return Object.prototype.toString.call(obj) === '[object Array]';
}

testPadNumber = function(val, place, sign) {
  var num = Math.abs(val);
  var len = Math.abs(num).toString().replace(/\.\d+/, '').length;
  var str =  new Array(Math.max(0, place - len) + 1).join('0') + num;
  if(val < 0 || sign) {
    str = (val < 0 ? '-' : '+') + str;
  }
  return str;
}

testCapitalize = function(str) {
  return str.slice(0,1).toUpperCase() + str.slice(1);
}

var objectEqual = function(one, two) {
  var onep = 0, twop = 0, key;
  if(one && two) {
    for(key in one) {
      if(!one.hasOwnProperty(key)) continue;
      onep++;
      if(!testIsEqual(one[key], two[key])) {
        return false;
      }
    }
    for(key in two) {
      if(!two.hasOwnProperty(key)) continue;
      twop++;
    }
  }
  return onep === twop && String(one) === String(two);
}

var testIsEqual = function(one, two) {

  var type, klass;

  type = typeof one;

  if(type === 'string' || type === 'boolean' || one == null) {
    return one === two;
  } else if(type === 'number') {
    return (isNaN(one) && isNaN(two)) || one === two;
  }

  klass = Object.prototype.toString.call(one);

  if(klass === '[object Date]') {
    return one.getTime() === two.getTime();
  } else if(klass === '[object RegExp]') {
    return String(one) === String(two);
  } else if(klass === '[object Array]') {
    return arrayEqual(one, two);
  } else if((klass === '[object Object]' || klass === '[object Arguments]') && ('hasOwnProperty' in one) && type === 'object') {
    return objectEqual(one, two);
  } else if(isNaN(one) && isNaN(two)) {
    return true;
  }

  return one === two;
}

var testIsClass = function(obj, klass) {
  return Object.prototype.toString.call(obj) === '[object ' + klass + ']';
}

var addFailure = function(actual, expected, message, stack, warning) {
  var meta = getMeta(stack);
  currentTest.failures.push({ actual: actual, expected: expected, message: message, file: meta.file, line: meta.line, col: meta.col, warning: !!warning });
}

var getMeta = function(stack) {
  var level = 4;
  if(stack !== undefined) {
    level += stack;
  }
  var e = new Error();
  if(!e.stack) {
    return {};
  }
  var s = e.stack.split(/@|^\s+at/m);
  var match = s[level].match(/(.+\.js):(\d+)(?::(\d+))?/);
  if(!match) match = [];
  return { file: match[1], line: match[2], col: match[3] };
}

var checkCanFinish = function() {
  if(!syncTestsRunning && capturedTimers.length == 0) {
    testsFinished();
    restoreNativeTimeout();
  }
}

var testsStarted = function() {
  if(typeof testsStartedCallback != 'undefined') {
    testsStartedCallback(results);
  }
  if(environment == 'node') {
    console.info('\n----------------------- STARTING TESTS ----------------------------\n');
  }
  testStartTime = new Date();
}

var testsFinished = function() {
  runtime = new Date() - testStartTime;
  if(typeof testsFinishedCallback != 'undefined') {
    testsFinishedCallback(results, runtime);
  }
  if(environment == 'node') {
    this.totalFailures = 0
    // displayResults will increment totalFailures by 1 for each failed test encountered
    displayResults();
    // will exit now setting the status to the number of failed tests
    process.exit(this.totalFailures);
  }
  results = [];
}

var displayResults = function() {
  var i, j, failure, totalAssertions = 0, totalFailures = 0;
  for (i = 0; i < results.length; i += 1) {
    totalAssertions += results[i].assertions;
    this.totalFailures += results[i].failures.length;
    for(j = 0; j < results[i].failures.length; j++) {
      failure = results[i].failures[j];
      console.info('\n'+ (j + 1) + ') Failure:');
      console.info(failure.message);
      console.info('Expected: ' + JSON.stringify(failure.expected) + ' but was: ' + JSON.stringify(failure.actual));
      console.info('File: ' + failure.file + ', Line: ' + failure.line, ' Col: ' + failure.col + '\n');
    }
  };
  var time = (runtime / 1000);
  console.info(results.length + ' tests, ' + totalAssertions + ' assertions, ' + this.totalFailures + ' failures, ' + time + 's\n');
}

test = function(name, fn) {
  if(moduleSetupMethod) {
    moduleSetupMethod();
  }
  if(!results) {
    results = [];
    testsStarted();
  }
  currentTest = {
    name: name,
    assertions: 0,
    failures: []
  };
  try {
    fn.call();
  } catch(e) {
    console.info(e);
  }
  results.push(currentTest);
  if(moduleTeardownMethod) {
    moduleTeardownMethod();
  }
}

setTimeout = function(fn, delay) {
  var timer = nativeSetTimeout(function() {
    fn.apply(this, arguments);
    removeCapturedTimer(timer);
    checkCanFinish();
  }, delay);
  capturedTimers.push(timer);
  return timer;
}

clearTimeout = function(timer) {
  removeCapturedTimer(timer);
  return nativeClearTimeout(timer);
}

restoreNativeTimeout = function() {
  setTimeout = nativeSetTimeout;
}

var removeCapturedTimer = function(timer) {
  var index = testArrayIndexOf(capturedTimers, timer);
  if(index !== -1) {
    capturedTimers.splice(index, 1);
  }
};

testModule = function(name, options) {
  moduleName = name;
  moduleSetupMethod = options.setup;
  moduleTeardownMethod = options.teardown;
}

equal = function(actual, expected, message, exceptions, stack) {
  exceptions = exceptions || {};
  if(environment in exceptions) {
    expected = exceptions[environment];
  }
  currentTest.assertions++;
  if(!testIsEqual(actual, expected)) {
    addFailure(actual, expected, message, stack);
  }
}

notEqual = function(actual, expected, message, exceptions) {
  equal(actual !== expected, true, message + ' | strict equality', exceptions, 1);
}

equalWithWarning = function(expected, actual, message) {
  if(expected != actual) {
    addFailure(actual, expected, message, null, true);
  }
}

equalWithMargin = function(actual, expected, margin, message) {
  equal((actual > expected - margin) && (actual < expected + margin), true, message, null, 1);
}

// Array content is equal, but order may differ
arrayEquivalent = function(a, b, message) {
  equal(sortOnStringValue(a), sortOnStringValue(b), message);
}

raisesError = function(fn, message, exceptions) {
  var raised = false;
  try {
    fn.call();
  } catch(e) {
    raised = true;
  }
  equal(raised, true, message, exceptions, 1);
}

skipEnvironments = function(environments, test) {
  if(testArrayIndexOf(environments, environment) === -1) {
    test.call();
  }
}

syncTestsFinished = function() {
  syncTestsRunning = false;
  checkCanFinish();
}

// This method has 2 benefits:
// 1. It gives asynchronous functions their own scope so vars can't be overwritten later by other asynchronous functions
// 2. It runs the tests after the CPU is free decreasing the chance of timing based errors.
async = function(fn) {
  setTimeout(fn, 200);
}

<|endoftext|>


<commit_before>/*
 *
 *  ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary),
 *  Bangalore, India. All Rights Reserved.
 *
 */

const nameResolutionOrder = ['kwargs', 'context', 'decisionMap', 'plugin'];

const resolveName = (name, args, isResult = true) => new Promise((resolve, reject) => {
  nameResolutionOrder.some((key, index) => {
    const value = args[key] && args[key][name];
    if (typeof value !== 'undefined') {
      if (key === 'kwargs' || key === 'context') {
        resolve(value);
      } else if (key === 'decisionMap') {
        if (!isResult) {
          value.build(Object.assign({}, args.context, args.kwargs), { decisionMap: args.decisionMap, plugin: args.plugin }).then((result) => {
            const decisionValue = typeof result === 'object' && Object.keys(result).map(key => result[key])[0];
            resolve(decisionValue);
          });
        } else {
          const decision = {
            expr: value,
            isDecision: true,
          };
          resolve(decision);
        }
      } else if (key === 'plugin') {
        value((err, result) => {
          if (err) {
            reject(err);
          } else {
            resolve(result);
          }
        });
      }
      return true;
    }
    if (index === nameResolutionOrder.length - 1) {
      console.log(`${name} : ${value}`);
      resolve(value);
    }
    return false;
  });
});

module.exports = resolveName;

<commit_msg>added decision service execution<commit_after>/*
 *
 *  ©2016-2017 EdgeVerve Systems Limited (a fully owned Infosys subsidiary),
 *  Bangalore, India. All Rights Reserved.
 *
 */

const nameResolutionOrder = ['kwargs', 'context', 'decisionMap', 'plugin'];

const resolveName = (name, args, isResult = true) => new Promise((resolve, reject) => {
  nameResolutionOrder.some((key, index) => {
    const value = args[key] && args[key][name];
    if (typeof value !== 'undefined') {
      if (key === 'kwargs' || key === 'context') {
        resolve(value);
      } else if (key === 'decisionMap') {
        if (!isResult) {
          value.build(Object.assign({}, args.context, args.kwargs), { decisionMap: args.decisionMap, plugin: args.plugin }).then((result) => {
            const decisionValue = typeof result === 'object' && Object.keys(result).map(key => result[key])[0];
            resolve(decisionValue);
          });
        } else {
          const decision = {
            expr: value,
            isDecision: true,
          };
          resolve(decision);
        }
      } else if (key === 'plugin') {
        value((err, result) => {
          if (err) {
            reject(err);
          } else {
            resolve(result);
          }
        });
      }
      return true;
    }
    if (index === nameResolutionOrder.length - 1) {
      resolve(value);
    }
    return false;
  });
});

module.exports = resolveName;

<|endoftext|>


<commit_before><commit_msg>[finishes #105937964] stop creating duplicate element ids<commit_after><|endoftext|>