<commit_before>/*
Copyright (C) 2012 Christian Perfect

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function() {

function saveSelection(containerEl) {
    var charIndex = 0, start = 0, end = 0, foundStart = false, stop = {};
    var sel = rangy.getSelection(), range;

    function traverseTextNodes(node, range) {
        if (node.nodeType == 3) {
            if (!foundStart && node == range.startContainer) {
                start = charIndex + range.startOffset;
                foundStart = true;
            }
            if (foundStart && node == range.endContainer) {
                end = charIndex + range.endOffset;
                throw stop;
            }
            charIndex += node.length;
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                traverseTextNodes(node.childNodes[i], range);
            }
        }
    }

    if (sel.rangeCount) {
        try {
            traverseTextNodes(containerEl, sel.getRangeAt(0));
        } catch (ex) {
            if (ex != stop) {
                throw ex;
            }
        }
    }

    return {
        start: start,
        end: end
    };
}

function restoreSelection(containerEl, savedSel) {
    var charIndex = 0, range = rangy.createRange(), foundStart = false, stop = {};
    range.collapseToPoint(containerEl, 0);

    function traverseTextNodes(node) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                range.setStart(node, savedSel.start - charIndex);
                foundStart = true;
            }
            if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                range.setEnd(node, savedSel.end - charIndex);
                throw stop;
            }
            charIndex = nextCharIndex;
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                traverseTextNodes(node.childNodes[i]);
            }
        }
    }

    try {
        traverseTextNodes(containerEl);
    } catch (ex) {
        if (ex == stop) {
            rangy.getSelection().setSingleRange(range);
        } else {
            throw ex;
        }
    }
}

var endDelimiters = {
    '$': /[^\\]\$/,
    '\\(': /[^\\]\\\)/,
    '$$': /[^\\]\$\$/,
    '\\[': /[^\\]\\\]/
}
var re_startMaths = /\$\$|\$|\\\(|\\\[|\\begin\{(\w+)\}/;
function findMaths(txt,target) {
    var i = 0;
    var m;
    var startDelimiter, endDelimiter;
    var start, end;
    var startChop, endChop;
    var re_end;

    while(txt.length) {
        m = re_startMaths.exec(txt);

        if(!m)     // if no maths delimiters, target is not in a maths section
            return null;

        startDelimiter = m[0];
        var start = m.index;

        if(i+start >= target)    // if target was before the starting delimiter, it's not in a maths section
            return null;

        startChop = start+startDelimiter.length;
        txt = txt.slice(startChop);

        if(startDelimiter.match(/^\\begin/)) {    //if this is an environment, construct a regexp to find the corresponding \end{} command.
            var environment = m[1];
            re_end = new RegExp('[^\\\\]\\\\end\\{'+environment+'\\}');    // don't ask if this copes with nested environments
        }
        else {
            re_end = endDelimiters[startDelimiter];    // get the delimiter for the
        }

        m = re_end.exec(txt);

        if(!m) {    // if no ending delimiter, target is in a maths section
            return {
                start: i+start,
                end: i+startChop+txt.length,
                math: txt,
                startDelimiter: startDelimiter,
                endDelimiter: endDelimiter
            };
        }

        endDelimiter = m[0];
        var end = m.index+1;    // the end delimiter regexp has a "not a backslash" character at the start because JS regexps don't do negative lookbehind
        endChop = end+endDelimiter.length-1;
        if(i+startChop+end >= target) {    // if target is before the end delimiter, it's in a maths section
            return {
                start: i+start,
                end: i+startChop+endChop,
                math: txt.slice(0,end),
                startDelimiter: startDelimiter,
                endDelimiter: endDelimiter.slice(1)
            };
        }
        else {
            txt = txt.slice(endChop);
            i += startChop+endChop;
        }
    }
}

jQuery(function() {
    jQuery("").appendTo("head");

	jQuery.fn.writemaths = function(options) {
		options = jQuery.extend({
			cleanMaths: function(m){ return m; },
			callback: function() {},
            iFrame: false,
			position: false,
			previewPosition: 'left top'
		},options);

        jQuery(this).each(function() {

            var textarea = jQuery(this).is('textarea,input');

            var root = this;
            if(options.iFrame) {
    			var iframe = jQuery(this).find('iframe')[0];
                var el = jQuery(iframe).contents().find('body');
            }
            else
            {
                el = jQuery(this);
            }
            el.addClass('writemaths tex2jax_ignore');
            var previewElement = jQuery('
');
			jQuery('body').append(previewElement);

            var queue = MathJax.Callback.Queue(MathJax.Hub.Register.StartupHook("End",{}));

			function positionPreview() {
				var of = options.iFrame ? iframe : textarea ? root : document;
				if(options.position)
					previewElement.position({my: options.previewPosition, at: options.position, of: of, collision: 'fit'})
				else
					previewElement.position({my: 'left bottom', at: 'left top', of: of, offset: pos.x+' '+pos.y, collision: 'fit'})
			}

			function updatePreview(e) {
                previewElement.hide();

                var pos, txt, sel, range;
                if(textarea) {
                    pos = jQuery(this).getCaretPosition();
                    var fontHeight = parseInt(jQuery(this).css('font-size').replace('px',''));
                    pos = {x: pos.left, y: pos.top - fontHeight};
                    sel = jQuery(this).getSelection();
                    range = {startOffset: sel.start, endOffset: sel.end};
                    txt = jQuery(this).val();
                }
                else {
                    sel = options.iFrame ? rangy.getIframeSelection(iframe) : rangy.getSelection();
                    try{
                        pos = sel.getStartDocumentPos();
                    }
                    catch(e) {
                        return;
                    }
					if(options.iFrame) {
						pos.y -= $(iframe).contents().scrollTop();
					}
                    var anchor = sel.anchorNode;

                    range = sel.getRangeAt(0);

					if(anchor.nodeType == anchor.TEXT_NODE) {
						while(anchor.previousSibling) {
							anchor = anchor.previousSibling;
							range.startOffset += anchor.textContent.length;
							range.endOffset += anchor.textContent.length;
						}
						anchor = anchor.parentNode;
					}

                    if(jQuery(anchor).add(jQuery(anchor).parents()).filter('code,pre,.wm_ignore').length)
                        return;
                    txt = jQuery(anchor).text();
                }
				if(pos.y<0)
					return;

                //only do this if the selection has zero width
                //so when you're selecting blocks of text, distracting previews don't pop up
                if(range.startOffset != range.endOffset)
                    return;

				var target = range.startOffset;

				var q = findMaths(txt,target);

				if(!q)
					return;

                var math;
				if(q.startDelimiter.match(/^\\begin/))
					math = q.startDelimiter + q.math + (q.endDelimiter ? q.endDelimiter : '');
				else
					math = q.math;

                if(!math.length)
                    return;

                previewElement.show();

				if(math==$(this).data('writemaths-lastMath'))
					return;

				var script = document.createElement('script');
				script.setAttribute('type','math/tex');
				script.textContent = options.cleanMaths(math);
				previewElement.html(script);
				$(this).data('writemaths-lastMath',math);;
                positionPreview();

                queue.Push(['Typeset',MathJax.Hub,previewElement[0]]);
                queue.Push(positionPreview);
                queue.Push(options.callback);
            }

			updatePreview = $.throttle(100,updatePreview);

            el
			.on('blur',function(e) {
				previewElement.hide();
			})
			.on('keyup click',updatePreview);
			if(options.iFrame)
				$(el[0].ownerDocument).on('scroll',updatePreview);
			else
				el.on('scroll',updatePreview);

        });
		return this;
	}
});

})();
<commit_msg>finish unfinished sentence in a comment :P<commit_after>/*
Copyright (C) 2012 Christian Perfect

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function() {

function saveSelection(containerEl) {
    var charIndex = 0, start = 0, end = 0, foundStart = false, stop = {};
    var sel = rangy.getSelection(), range;

    function traverseTextNodes(node, range) {
        if (node.nodeType == 3) {
            if (!foundStart && node == range.startContainer) {
                start = charIndex + range.startOffset;
                foundStart = true;
            }
            if (foundStart && node == range.endContainer) {
                end = charIndex + range.endOffset;
                throw stop;
            }
            charIndex += node.length;
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                traverseTextNodes(node.childNodes[i], range);
            }
        }
    }

    if (sel.rangeCount) {
        try {
            traverseTextNodes(containerEl, sel.getRangeAt(0));
        } catch (ex) {
            if (ex != stop) {
                throw ex;
            }
        }
    }

    return {
        start: start,
        end: end
    };
}

function restoreSelection(containerEl, savedSel) {
    var charIndex = 0, range = rangy.createRange(), foundStart = false, stop = {};
    range.collapseToPoint(containerEl, 0);

    function traverseTextNodes(node) {
        if (node.nodeType == 3) {
            var nextCharIndex = charIndex + node.length;
            if (!foundStart && savedSel.start >= charIndex && savedSel.start <= nextCharIndex) {
                range.setStart(node, savedSel.start - charIndex);
                foundStart = true;
            }
            if (foundStart && savedSel.end >= charIndex && savedSel.end <= nextCharIndex) {
                range.setEnd(node, savedSel.end - charIndex);
                throw stop;
            }
            charIndex = nextCharIndex;
        } else {
            for (var i = 0, len = node.childNodes.length; i < len; ++i) {
                traverseTextNodes(node.childNodes[i]);
            }
        }
    }

    try {
        traverseTextNodes(containerEl);
    } catch (ex) {
        if (ex == stop) {
            rangy.getSelection().setSingleRange(range);
        } else {
            throw ex;
        }
    }
}

var endDelimiters = {
    '$': /[^\\]\$/,
    '\\(': /[^\\]\\\)/,
    '$$': /[^\\]\$\$/,
    '\\[': /[^\\]\\\]/
}
var re_startMaths = /\$\$|\$|\\\(|\\\[|\\begin\{(\w+)\}/;
function findMaths(txt,target) {
    var i = 0;
    var m;
    var startDelimiter, endDelimiter;
    var start, end;
    var startChop, endChop;
    var re_end;

    while(txt.length) {
        m = re_startMaths.exec(txt);

        if(!m)     // if no maths delimiters, target is not in a maths section
            return null;

        startDelimiter = m[0];
        var start = m.index;

        if(i+start >= target)    // if target was before the starting delimiter, it's not in a maths section
            return null;

        startChop = start+startDelimiter.length;
        txt = txt.slice(startChop);

        if(startDelimiter.match(/^\\begin/)) {    //if this is an environment, construct a regexp to find the corresponding \end{} command.
            var environment = m[1];
            re_end = new RegExp('[^\\\\]\\\\end\\{'+environment+'\\}');    // don't ask if this copes with nested environments
        }
        else {
            re_end = endDelimiters[startDelimiter];    // get the corresponding end delimiter for the matched start delimiter
        }

        m = re_end.exec(txt);

        if(!m) {    // if no ending delimiter, target is in a maths section
            return {
                start: i+start,
                end: i+startChop+txt.length,
                math: txt,
                startDelimiter: startDelimiter,
                endDelimiter: endDelimiter
            };
        }

        endDelimiter = m[0];
        var end = m.index+1;    // the end delimiter regexp has a "not a backslash" character at the start because JS regexps don't do negative lookbehind
        endChop = end+endDelimiter.length-1;
        if(i+startChop+end >= target) {    // if target is before the end delimiter, it's in a maths section
            return {
                start: i+start,
                end: i+startChop+endChop,
                math: txt.slice(0,end),
                startDelimiter: startDelimiter,
                endDelimiter: endDelimiter.slice(1)
            };
        }
        else {
            txt = txt.slice(endChop);
            i += startChop+endChop;
        }
    }
}

jQuery(function() {
    jQuery("").appendTo("head");

	jQuery.fn.writemaths = function(options) {
		options = jQuery.extend({
			cleanMaths: function(m){ return m; },
			callback: function() {},
            iFrame: false,
			position: false,
			previewPosition: 'left top'
		},options);

        jQuery(this).each(function() {

            var textarea = jQuery(this).is('textarea,input');

            var root = this;
            if(options.iFrame) {
    			var iframe = jQuery(this).find('iframe')[0];
                var el = jQuery(iframe).contents().find('body');
            }
            else
            {
                el = jQuery(this);
            }
            el.addClass('writemaths tex2jax_ignore');
            var previewElement = jQuery('
');
			jQuery('body').append(previewElement);

            var queue = MathJax.Callback.Queue(MathJax.Hub.Register.StartupHook("End",{}));

			function positionPreview() {
				var of = options.iFrame ? iframe : textarea ? root : document;
				if(options.position)
					previewElement.position({my: options.previewPosition, at: options.position, of: of, collision: 'fit'})
				else
					previewElement.position({my: 'left bottom', at: 'left top', of: of, offset: pos.x+' '+pos.y, collision: 'fit'})
			}

			function updatePreview(e) {
                previewElement.hide();

                var pos, txt, sel, range;
                if(textarea) {
                    pos = jQuery(this).getCaretPosition();
                    var fontHeight = parseInt(jQuery(this).css('font-size').replace('px',''));
                    pos = {x: pos.left, y: pos.top - fontHeight};
                    sel = jQuery(this).getSelection();
                    range = {startOffset: sel.start, endOffset: sel.end};
                    txt = jQuery(this).val();
                }
                else {
                    sel = options.iFrame ? rangy.getIframeSelection(iframe) : rangy.getSelection();
                    try{
                        pos = sel.getStartDocumentPos();
                    }
                    catch(e) {
                        return;
                    }
					if(options.iFrame) {
						pos.y -= $(iframe).contents().scrollTop();
					}
                    var anchor = sel.anchorNode;

                    range = sel.getRangeAt(0);

					if(anchor.nodeType == anchor.TEXT_NODE) {
						while(anchor.previousSibling) {
							anchor = anchor.previousSibling;
							range.startOffset += anchor.textContent.length;
							range.endOffset += anchor.textContent.length;
						}
						anchor = anchor.parentNode;
					}

                    if(jQuery(anchor).add(jQuery(anchor).parents()).filter('code,pre,.wm_ignore').length)
                        return;
                    txt = jQuery(anchor).text();
                }
				if(pos.y<0)
					return;

                //only do this if the selection has zero width
                //so when you're selecting blocks of text, distracting previews don't pop up
                if(range.startOffset != range.endOffset)
                    return;

				var target = range.startOffset;

				var q = findMaths(txt,target);

				if(!q)
					return;

                var math;
				if(q.startDelimiter.match(/^\\begin/))
					math = q.startDelimiter + q.math + (q.endDelimiter ? q.endDelimiter : '');
				else
					math = q.math;

                if(!math.length)
                    return;

                previewElement.show();

				if(math==$(this).data('writemaths-lastMath'))
					return;

				var script = document.createElement('script');
				script.setAttribute('type','math/tex');
				script.textContent = options.cleanMaths(math);
				previewElement.html(script);
				$(this).data('writemaths-lastMath',math);;
                positionPreview();

                queue.Push(['Typeset',MathJax.Hub,previewElement[0]]);
                queue.Push(positionPreview);
                queue.Push(options.callback);
            }

			updatePreview = $.throttle(100,updatePreview);

            el
			.on('blur',function(e) {
				previewElement.hide();
			})
			.on('keyup click',updatePreview);
			if(options.iFrame)
				$(el[0].ownerDocument).on('scroll',updatePreview);
			else
				el.on('scroll',updatePreview);

        });
		return this;
	}
});

})();
<|endoftext|>


<commit_before>'use strict';

function Bowling () {
  this.FRAME_COUNT_LIMIT = 10;
  this.STRIKE = 10;
  this._frames = [];
  this._frameCounter = 1;
  this._bonusPoints = 0;
  this._bonusCounter = 0;
  this._isStrike = false;
  this._isSpare = true;
  this._spareArray = [];
}
Bowling.prototype.setFrames = function (value) {
  this._frames.push(value);
};
Bowling.prototype.getBonusCounter = function () {
  return this._bonusCounter;
};
Bowling.prototype.setBonusCounter = function (value) {
  this._bonusCounter += value;
};
Bowling.prototype.setBonusPoints = function (value) {
  this._bonusPoints += value;
};
Bowling.prototype.setIsStrike = function (value) {
  this._isStrike = value;
};
Bowling.prototype.setIsSpare = function (value) {
  this._isSpare = value;
};
Bowling.prototype.setSpareArray = function (value) {
  this._spareArray = value;
};
Bowling.prototype.calculateFrameCount = function () {
  var numberOfBowls = this._frames.length;
  var frameCount = this._frameCounter = ( numberOfBowls / 2 );
  return frameCount;
};
Bowling.prototype.randomNumberOfPins = function () {
  return Math.floor( Math.random () * ( 10 - 1 + 1)) + 1;
};
Bowling.prototype.spareChecker = function (pins) {
  this._spareArray.push(pins);
  if (this._spareArray.length === 1) {
    this.setIsSpare(false);
  } else if ((this._spareArray.length === 2) && (this._spareArray[0] + this._spareArray[1] !== 10)) {
    this.setIsSpare(false);
    this.setSpareArray([]);
  } else {
    this.setIsSpare(true);
    this.setBonusCounter(1);
    this.setSpareArray([]);
  }
};
Bowling.prototype.bowl = function (number) {
  if(this._frameCounter === this.FRAME_COUNT_LIMIT) {
    throw new Error('Game over!!');
  }

  this.setIsStrike(false);

  var pins =  number || this.randomNumberOfPins();
  if (this.getBonusCounter() >= 1) {
    this.setBonusPoints(pins);
    this.setBonusCounter(-1);
  }

  if (pins === this.STRIKE) {
    this.strike();
  }

  if (pins !== this.STRIKE) {
    this.setFrames(pins);
    this.calculateFrameCount();
    this.spareChecker(pins);
  }

  return pins;
};
Bowling.prototype.strike = function () {
  this.setIsStrike(true);
  this.setBonusCounter(2);
  this.setFrames(10);
  this.setFrames(0);
  this.calculateFrameCount();
};
<commit_msg>Refactor to remove magic numbers<commit_after>'use strict';

function Bowling () {
  this.FRAME_COUNT_LIMIT = 10;
  this.STRIKE = 10;
  this._frames = [];
  this._frameCounter = 1;
  this._bonusPoints = 0;
  this._bonusCounter = 0;
  this._isStrike = false;
  this._isSpare = true;
  this._spareArray = [];
}
Bowling.prototype.setFrames = function (value) {
  this._frames.push(value);
};
Bowling.prototype.getBonusCounter = function () {
  return this._bonusCounter;
};
Bowling.prototype.setBonusCounter = function (value) {
  this._bonusCounter += value;
};
Bowling.prototype.setBonusPoints = function (value) {
  this._bonusPoints += value;
};
Bowling.prototype.setIsStrike = function (value) {
  this._isStrike = value;
};
Bowling.prototype.setIsSpare = function (value) {
  this._isSpare = value;
};
Bowling.prototype.setSpareArray = function (value) {
  this._spareArray = value;
};
Bowling.prototype.calculateFrameCount = function () {
  var numberOfBowls = this._frames.length;
  var frameCount = this._frameCounter = ( numberOfBowls / 2 );
  return frameCount;
};
Bowling.prototype.randomNumberOfPins = function () {
  return Math.floor( Math.random () * ( this.FRAME_COUNT_LIMIT - 1 + 1)) + 1;
};
Bowling.prototype.spareChecker = function (pins) {
  this._spareArray.push(pins);
  if (this._spareArray.length === 1) {
    this.setIsSpare(false);
  } else if ((this._spareArray.length === 2) && (this._spareArray[0] + this._spareArray[1] !== this.STRIKE)) {
    this.setIsSpare(false);
    this.setSpareArray([]);
  } else {
    this.setIsSpare(true);
    this.setBonusCounter(1);
    this.setSpareArray([]);
  }
};
Bowling.prototype.bowl = function (number) {
  if(this._frameCounter === this.FRAME_COUNT_LIMIT) {
    throw new Error('Game over!!');
  }

  this.setIsStrike(false);
  var pins = number || this.randomNumberOfPins();

  if (this.getBonusCounter() >= 1) {
    this.setBonusPoints(pins);
    this.setBonusCounter(-1);
  }
  if (pins === this.STRIKE) {
    this.strike();
  }
  if (pins !== this.STRIKE) {
    this.setFrames(pins);
    this.calculateFrameCount();
    this.spareChecker(pins);
  }
  return pins;
};
Bowling.prototype.strike = function () {
  this.setIsStrike(true);
  this.setBonusCounter(2);
  this.setFrames(this.STRIKE);
  this.setFrames(0);
  this.calculateFrameCount();
};
<|endoftext|>


<commit_before>
export function selectBrush(brushName) {
    this.settings.brush = this.availableBrushes[brushName];
};

export function setBrushSize(brushSize) {
    this.settings.lineWidth = brushSize;
};

export function pen() {

    let x, y;
    let mousePosition = this.settings.mousePosition;
    let lineWidth = this.settings.lineWidth;
    let velocity = this.settings.velocity;
    let ctx = this.ctx;

    ctx.lineWidth = lineWidth / (velocity * .5);

    if (ctx.lineWidth > lineWidth) {
        ctx.lineWidth = lineWidth;
    } else if (ctx.lineWidth < lineWidth / 5) {
        ctx.lineWidth = lineWidth / 5;
    }

    ctx.beginPath();

    x = (mousePosition[0].x + mousePosition[1].x) / 2;
    y = (mousePosition[0].y + mousePosition[1].y) / 2;

    ctx.moveTo(x, y);

    x = (mousePosition[1].x + mousePosition[2].x) / 2;
    y = (mousePosition[1].y + mousePosition[2].y) / 2;

    ctx.quadraticCurveTo(mousePosition[1].x, mousePosition[1].y, x, y);
    ctx.stroke();
};

export function pencil() {

    let lineWidth = this.settings.lineWidth;
    let mousePosition = this.settings.mousePosition;
    let ctx = this.ctx;

    ctx.lineWidth = lineWidth;
    ctx.beginPath();
    ctx.moveTo(mousePosition[1].x, mousePosition[1].y);
    ctx.lineTo(mousePosition[2].x, mousePosition[2].y);
    ctx.stroke();
};
<commit_msg>Update Brushes.js<commit_after>
export function selectBrush(brushName) {
    this.settings.brush = this.availableBrushes[brushName];
};

export function setBrushSize(brushSize) {
    this.settings.lineWidth = brushSize;
};

export function pen() {

    let x, y;
    let mousePosition = this.settings.mousePosition;
    let lineWidth = this.settings.lineWidth;
    let velocity = this.settings.velocity;
    let ctx = this.ctx;

    ctx.lineWidth = lineWidth + (velocity * .5);

    ctx.beginPath();

    x = (mousePosition[0].x + mousePosition[1].x) / 2;
    y = (mousePosition[0].y + mousePosition[1].y) / 2;

    ctx.moveTo(x, y);

    x = (mousePosition[1].x + mousePosition[2].x) / 2;
    y = (mousePosition[1].y + mousePosition[2].y) / 2;

    ctx.quadraticCurveTo(mousePosition[1].x, mousePosition[1].y, x, y);
    ctx.stroke();
};

export function pencil() {

    let lineWidth = this.settings.lineWidth;
    let mousePosition = this.settings.mousePosition;
    let ctx = this.ctx;

    ctx.lineWidth = lineWidth;
    ctx.beginPath();
    ctx.moveTo(mousePosition[1].x, mousePosition[1].y);
    ctx.lineTo(mousePosition[2].x, mousePosition[2].y);
    ctx.stroke();
};
<|endoftext|>


<commit_before>export default (() => {
  "use strict";

  let Querier = (() => {
    class QueryableObject {
      constructor({name, queryableEntity, where}) {
        Object.assign(this, { name, queryableEntity, where });
      }

      match({ queryableObjectPath, constraintObjectPath }) {
        return this.where
          ? constraintObjectPath(this.queryableEntity, this.where)
          : queryableObjectPath(this.queryableEntity);
      }
    }

    class Querier {
      constructor(queryableObjects) {
        Object.defineProperty(this, 'queryableObjects', { value: queryableObjects });
      }

      append({ as, from, where }){
        let queryableObject = new QueryableObject({
          name: as,
          queryableEntity: from,
          where: where
        });

        return new Query(this.queryableObjects.concat([queryableObject]));
      }
    }

    class EmptyQuery extends Querier {
      constructor() {
        super([]);
      }
    }

    class Query extends Querier {
      constructor(queryableObjects) {
        super(queryableObjects);
      }

      select(func) {
        let $q = this.queryableObjects;

        let bind = function(item, instruction, target) {
          return (...args) => item[instruction](target.bind(item, ...args));
        };

        return $q.reduceRight((func, item, idx, orig) => {
          let entity = item.match({
            queryableObjectPath: (entity) => entity,
            constraintObjectPath: (entity, where) => entity.where(where)
          });

          return bind(entity, (idx + 1 === orig.length) ? 'select' : 'selectMany', func);
        }, func)();
      }
    }

    return new EmptyQuery();
  })();

  return { Querier };

})();<commit_msg>$q isn't really required so, removing.<commit_after>export default (() => {
  "use strict";

  let Querier = (() => {
    class QueryableObject {
      constructor({name, queryableEntity, where}) {
        Object.assign(this, { name, queryableEntity, where });
      }

      match({ queryableObjectPath, constraintObjectPath }) {
        return this.where
          ? constraintObjectPath(this.queryableEntity, this.where)
          : queryableObjectPath(this.queryableEntity);
      }
    }

    class Querier {
      constructor(queryableObjects) {
        Object.defineProperty(this, 'queryableObjects', { value: queryableObjects });
      }

      append({ as, from, where }){
        let queryableObject = new QueryableObject({
          name: as,
          queryableEntity: from,
          where: where
        });

        return new Query(this.queryableObjects.concat([queryableObject]));
      }
    }

    class EmptyQuery extends Querier {
      constructor() {
        super([]);
      }
    }

    class Query extends Querier {
      constructor(queryableObjects) {
        super(queryableObjects);
      }

      select(func) {
        let bind = function(item, instruction, target) {
          return (...args) => item[instruction](target.bind(item, ...args));
        };

        return this.queryableObjects.reduceRight((func, item, idx, orig) => {
          let entity = item.match({
            queryableObjectPath: (entity) => entity,
            constraintObjectPath: (entity, where) => entity.where(where)
          });

          return bind(entity, (idx + 1 === orig.length) ? 'select' : 'selectMany', func);
        }, func)();
      }
    }

    return new EmptyQuery();
  })();

  return { Querier };

})();<|endoftext|>


<commit_before>'use strict';
const _ = require('lodash');
module.exports = app => {
  class Hom extends app.Service {
    * text1() {
      return 'hello';
    }
    * text2() {
      const arr1 = [ 1, 2.1, 2.2, 3.2, 3.22, 4.3, 2.11 ];
      const arr2 = [ 1, 2, 3, 4, 5 ];
      return _.difference(arr1, arr2, Math.floor);
    }
    * text3() {
      const arr1 = [ 1, 2, 3, 4, 5 ];
      const arr2 = [ 'a', 'b', 'c', 'd', 'e' ];
      return _.zipObject(arr1, arr2);
    }
    * text4() {
      const arr = [ 'q', 'w', 'e', 'r' ];
      return _.tail(arr);
    }
    * text5() {
      const arr = [ 1.2, 1.3, 1.4, 2.1, 2.4, 3.1 ];
      return _.groupBy(arr, Math.floor);
    }
    * text6(a, b) {
      return a + b;
    }
    * text7() {
      const t = new Date();
      return t + 8;
    }
  }
  return Hom;
};

<commit_msg>获取当前时间<commit_after>'use strict';
const _ = require('lodash');
module.exports = app => {
  class Hom extends app.Service {
    * text1() {
      return 'hello';
    }
    * text2() {
      const arr1 = [ 1, 2.1, 2.2, 3.2, 3.22, 4.3, 2.11 ];
      const arr2 = [ 1, 2, 3, 4, 5 ];
      return _.difference(arr1, arr2, Math.floor);
    }
    * text3() {
      const arr1 = [ 1, 2, 3, 4, 5 ];
      const arr2 = [ 'a', 'b', 'c', 'd', 'e' ];
      return _.zipObject(arr1, arr2);
    }
    * text4() {
      const arr = [ 'q', 'w', 'e', 'r' ];
      return _.tail(arr);
    }
    * text5() {
      const arr = [ 1.2, 1.3, 1.4, 2.1, 2.4, 3.1 ];
      return _.groupBy(arr, Math.floor);
    }
    * text6(a, b) {
      return a + b;
    }
    * text7() {
      const t = new Date();
      const s = t.getSeconds();
      const h = t.getHours();
      const m = t.getMinutes();
      const y = t.getFullYear();
      const d = t.getDate();
      const mon = t.getMonth();
      return y + '年' + mon + '月' + d + '日' + h + ':' + m + ':' + s;
      // return `${y}年${mon}月${d}日${h}:${m}:${s}`;

    }
  }

  return Hom;
};

<|endoftext|>


<commit_before>'use strict';
const request          = require('../comum/tago_request.js');
const paramsSerializer = require('../comum/paramsSerializer.js');
const config           = require('../config.js');
const default_headers  = require('../comum/default_headers.js');
const Widgets          = require('./dashboards.widgets.js');
const share            = require('./_share.js');

class Dashboards {
  constructor(acc_token) {
    this.token = acc_token;
    this.default_options = {
      'json':    true,
      'headers': default_headers(this)
    };
  }

  /** List Dashboards
     * @param  {Number} page
     * Page of list starting from 1
     * Default: 1
     * @param  {Array} fields
     * Array of field names
     * Default: ['id', 'label']
     * Example: ['id', 'label', 'visible']
     *
     * Values allowed:
     * id, label, description, public_token, group_by,
     * account, tags, created_at, updated_at.
     * @param  {JSON} filter
     * JSON of filter
     * Without default
     * Example: {label: 'Motor'}
     * Values allowed: same of fields parameter.
     *
     * TIP: On name you can use * (asterisk) as wildcard.
     * @param {Number} amount
     * Amount of items will return
     * Default is 20
     * @param {String} orderBy
     * Order by a field
     * Examples:
     *  'name,asc'
     *  'name,desc'
     *  'name' [default: asc]
     * @return {Promise}
     * Array of dashboards in alphabetically order.
    */
  list(page = 1, fields = ['id', 'name'], filter = {}, amount = 20, orderBy = 'label,asc') {
    if (!arguments.length) return this._list(); // @deprecated
    const url = `${config.api_url}/dashboard`;
    const method = 'GET';

    let options = Object.assign({}, this.default_options, {
      url,
      method,
      paramsSerializer,
      params: {
        page,
        filter,
        fields,
        amount,
        orderBy,
      },
    });
    return request(options);
  }

  /**
     * It return old api style
     * @deprecated
     */
  _list() {
    const parameters = [
      1,
      ['account', 'created_at', 'group_by', 'id', 'label', 'tags', 'visible'],
      {},
      1000,
      'label'
    ];
    return this.list.call(this, ...parameters);
  }

  /** Create a Dashboard
    * @param  {JSON} data
    * @param  {string} data.name - Name of the dashboard
    * @return {Promise}
     */
  create(data) {
    data       = data || {};
    let url    = `${config.api_url}/dashboard`;
    let method = 'POST';

    let options = Object.assign({}, this.default_options, {url, method, data});
    return request(options);
  }

  /** Edit the Dashboard
    * @param  {String} dashboard id
    * @param  {Object} data
    * @return {Promise}
     */
  edit(dashboard_id, data) {
    data       = data || {};
    let url    = `${config.api_url}/dashboard/${dashboard_id}`;
    let method = 'PUT';

    let options = Object.assign({}, this.default_options, {url, method, data});
    return request(options);
  }

  /** Delete the Dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  delete(dashboard_id) {
    let url    = `${config.api_url}/dashboard/${dashboard_id}`;
    let method = 'DELETE';

    let options = Object.assign({}, this.default_options, {url, method});
    return request(options);
  }

  /** Get Info of the Dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  info(dashboard_id) {
    if (!dashboard_id || dashboard_id == '') {
      //If ID is send with null, it will get List instead info.
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    }
    let url    = `${config.api_url}/dashboard/${dashboard_id}`;
    let method = 'GET';

    let options = Object.assign({}, this.default_options, {url, method});
    return request(options);
  }

  /** Duplicate the dashboard to your own account
    * @param  {String} dashboard id
    * @param  {JSON} data - Name of the dashboard
    * @param  {JSON} data{}.setup - special setup for duplicate
    * @param  {boolean} data{}.new_label - optional new dashboard label
    * @return {Promise}
     */
  duplicate(dashboard_id, data) {
    data = data || {};
    if (!dashboard_id || dashboard_id === '') {
      return new Promise((resolve, reject) => reject('Dashboard ID parameter is obrigatory.'));
    }

    const url    = `${config.api_url}/dashboard/${dashboard_id}/duplicate`;
    const method = 'POST';

    const options = Object.assign({}, this.default_options, { url, method, data });
    return request(options);
  }

  /******************************************* */

  /** Get share list of the dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  shareList(dashboard_id) {
    if (!dashboard_id || dashboard_id == '') {
      //If ID is send with null, it will get List instead info.
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    }
    return share.list('dashboard', dashboard_id, this.default_options);
  }

  /** Share the dashboard with another person
    * @param  {String} dashboard id
    * @param  {JSON} data
    * @param  {String} data{}.email - Email to receive invitation
    * @param  {String} data{}.message - Scope message for the email
    * @param  {boolean} data{}.copy_me - true to send a copy to yourself
    * @return {Promise}
     */
  shareSendInvite(dashboard_id, data) {
    data = data || {};
    if (!dashboard_id || dashboard_id == '') {
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    } else if (!data.email) {
      return new Promise((resolve,reject) => reject('data.email parameter is obrigatory.'));
    }
    return share.invite('dashboard', dashboard_id, data, this.default_options);
  }

  /** Change permissions of the bucket
    * @param  {String} share id
    * @param  {JSON} data -
    * @param  {String} data{}.email - Email to change permissions
    * @param  {String} data{}.permission - New Permission to be applied
    * @return {Promise}
     */
  shareEdit(share_id, data) {
    data = data || {};
    if (!share_id || share_id == '') {
      return new Promise((resolve,reject) => reject('Share ID parameter is obrigatory.'));
    } else if (!data.email) {
      return new Promise((resolve,reject) => reject('data.email parameter is obrigatory.'));
    }
    return share.edit('dashboard', share_id, data, this.default_options);
  }

  /** Remove share of the bucket
    * @param  {String} share id
    * @return {Promise}
     */
  shareDelete(share_id) {
    if (!share_id || share_id == '') {
      return new Promise((resolve,reject) => reject('Share ID parameter is obrigatory.'));
    }
    return share.remove('dashboard', share_id, this.default_options);
  }
  /******************************************* */

  /** Generate a new public token for the dashboard
    * @param  {String} dashboard id
    * @param  {String} expire_time time when token will expire. (optional)
    * @return {Promise}
     */
  genPublicToken(dashboard_id, expire_time = 'never') {
    if (!dashboard_id || dashboard_id == '') {
      //If ID is send with null, it will get List instead info.
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    }
    const url    = `${config.api_url}/dashboard/${dashboard_id}/share/public`;
    const method = 'GET';
    const params = { expire_time };

    const options = Object.assign({}, this.default_options, {url, method, params});
    return request(options);
  }

  /** Clone the dashboard with special parameters
    * @param  {String} dashboard id
    * @param  {JSON} data - Name of the dashboard
    * @param  {String} data{}.email - Email to receive invitation
    * @param  {String} data{}.message - Scope message for the email
    * @param  {JSON} data{}.setup - special setup for clone
    * @param  {boolean} data{}.copy_me - true to send a copy to yourself
    * @return {Promise}
     */
  shareClone(dashboard_id, data) {
    data = data || {};
    if (!dashboard_id || dashboard_id == '') {
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    } else if (!data.email) {
      return new Promise((resolve,reject) => reject('data.email parameter is obrigatory.'));
    }

    let url    = `${config.api_url}/dashboard/${dashboard_id}/share/copy`;
    let method = 'POST';

    let options = Object.assign({}, this.default_options, {url, method, data});
    return request(options);
  }

  /** Get list of devices related with dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  listDevicesRelated(dashboard_id) {
    let url = `${config.api_url}/dashboard/${dashboard_id}/devices`;
    let method = 'GET';

    let options = Object.assign({}, this.default_options, { url, method });
    return request(options);
  }

  // ----------- Sub-methods -----------
  get widgets() {
    return new Widgets(this.token);
  }
}

module.exports = Dashboards;
<commit_msg>improve jsdocs from shareSendInvite<commit_after>'use strict';
const request          = require('../comum/tago_request.js');
const paramsSerializer = require('../comum/paramsSerializer.js');
const config           = require('../config.js');
const default_headers  = require('../comum/default_headers.js');
const Widgets          = require('./dashboards.widgets.js');
const share            = require('./_share.js');

class Dashboards {
  constructor(acc_token) {
    this.token = acc_token;
    this.default_options = {
      'json':    true,
      'headers': default_headers(this)
    };
  }

  /** List Dashboards
     * @param  {Number} page
     * Page of list starting from 1
     * Default: 1
     * @param  {Array} fields
     * Array of field names
     * Default: ['id', 'label']
     * Example: ['id', 'label', 'visible']
     *
     * Values allowed:
     * id, label, description, public_token, group_by,
     * account, tags, created_at, updated_at.
     * @param  {JSON} filter
     * JSON of filter
     * Without default
     * Example: {label: 'Motor'}
     * Values allowed: same of fields parameter.
     *
     * TIP: On name you can use * (asterisk) as wildcard.
     * @param {Number} amount
     * Amount of items will return
     * Default is 20
     * @param {String} orderBy
     * Order by a field
     * Examples:
     *  'name,asc'
     *  'name,desc'
     *  'name' [default: asc]
     * @return {Promise}
     * Array of dashboards in alphabetically order.
    */
  list(page = 1, fields = ['id', 'name'], filter = {}, amount = 20, orderBy = 'label,asc') {
    if (!arguments.length) return this._list(); // @deprecated
    const url = `${config.api_url}/dashboard`;
    const method = 'GET';

    let options = Object.assign({}, this.default_options, {
      url,
      method,
      paramsSerializer,
      params: {
        page,
        filter,
        fields,
        amount,
        orderBy,
      },
    });
    return request(options);
  }

  /**
     * It return old api style
     * @deprecated
     */
  _list() {
    const parameters = [
      1,
      ['account', 'created_at', 'group_by', 'id', 'label', 'tags', 'visible'],
      {},
      1000,
      'label'
    ];
    return this.list.call(this, ...parameters);
  }

  /** Create a Dashboard
    * @param  {JSON} data
    * @param  {string} data.name - Name of the dashboard
    * @return {Promise}
     */
  create(data) {
    data       = data || {};
    let url    = `${config.api_url}/dashboard`;
    let method = 'POST';

    let options = Object.assign({}, this.default_options, {url, method, data});
    return request(options);
  }

  /** Edit the Dashboard
    * @param  {String} dashboard id
    * @param  {Object} data
    * @return {Promise}
     */
  edit(dashboard_id, data) {
    data       = data || {};
    let url    = `${config.api_url}/dashboard/${dashboard_id}`;
    let method = 'PUT';

    let options = Object.assign({}, this.default_options, {url, method, data});
    return request(options);
  }

  /** Delete the Dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  delete(dashboard_id) {
    let url    = `${config.api_url}/dashboard/${dashboard_id}`;
    let method = 'DELETE';

    let options = Object.assign({}, this.default_options, {url, method});
    return request(options);
  }

  /** Get Info of the Dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  info(dashboard_id) {
    if (!dashboard_id || dashboard_id == '') {
      //If ID is send with null, it will get List instead info.
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    }
    let url    = `${config.api_url}/dashboard/${dashboard_id}`;
    let method = 'GET';

    let options = Object.assign({}, this.default_options, {url, method});
    return request(options);
  }

  /** Duplicate the dashboard to your own account
    * @param  {String} dashboard id
    * @param  {JSON} data - Name of the dashboard
    * @param  {JSON} data{}.setup - special setup for duplicate
    * @param  {boolean} data{}.new_label - optional new dashboard label
    * @return {Promise}
     */
  duplicate(dashboard_id, data) {
    data = data || {};
    if (!dashboard_id || dashboard_id === '') {
      return new Promise((resolve, reject) => reject('Dashboard ID parameter is obrigatory.'));
    }

    const url    = `${config.api_url}/dashboard/${dashboard_id}/duplicate`;
    const method = 'POST';

    const options = Object.assign({}, this.default_options, { url, method, data });
    return request(options);
  }

  /******************************************* */

  /** Get share list of the dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  shareList(dashboard_id) {
    if (!dashboard_id || dashboard_id == '') {
      //If ID is send with null, it will get List instead info.
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    }
    return share.list('dashboard', dashboard_id, this.default_options);
  }

  /** Share the dashboard with another person
    * @param  {String} dashboard id
    * @param  {JSON} data
    * @param  {String} data{}.email - Email to receive invitation
    * @param  {String} data{}.message - Scope message for the email
    * @param  {boolean} data{}.copy_me - true to send a copy to yourself
    * @param  {String} data{}.whitelabel_url - Url without https. it's send email template
    * @param  {boolean} data{}.allow_tags - Send dahsboard tags. Default false
    * @param  {boolean} data{}.allow_share - Allow user to share dashboared with another emails. Default false
    * @return {Promise}
     */
  shareSendInvite(dashboard_id, data) {
    data = data || {};
    if (!dashboard_id || dashboard_id == '') {
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    } else if (!data.email) {
      return new Promise((resolve,reject) => reject('data.email parameter is obrigatory.'));
    }
    return share.invite('dashboard', dashboard_id, data, this.default_options);
  }

  /** Change permissions of the bucket
    * @param  {String} share id
    * @param  {JSON} data -
    * @param  {String} data{}.email - Email to change permissions
    * @param  {String} data{}.permission - New Permission to be applied
    * @return {Promise}
     */
  shareEdit(share_id, data) {
    data = data || {};
    if (!share_id || share_id == '') {
      return new Promise((resolve,reject) => reject('Share ID parameter is obrigatory.'));
    } else if (!data.email) {
      return new Promise((resolve,reject) => reject('data.email parameter is obrigatory.'));
    }
    return share.edit('dashboard', share_id, data, this.default_options);
  }

  /** Remove share of the bucket
    * @param  {String} share id
    * @return {Promise}
     */
  shareDelete(share_id) {
    if (!share_id || share_id == '') {
      return new Promise((resolve,reject) => reject('Share ID parameter is obrigatory.'));
    }
    return share.remove('dashboard', share_id, this.default_options);
  }
  /******************************************* */

  /** Generate a new public token for the dashboard
    * @param  {String} dashboard id
    * @param  {String} expire_time time when token will expire. (optional)
    * @return {Promise}
     */
  genPublicToken(dashboard_id, expire_time = 'never') {
    if (!dashboard_id || dashboard_id == '') {
      //If ID is send with null, it will get List instead info.
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    }
    const url    = `${config.api_url}/dashboard/${dashboard_id}/share/public`;
    const method = 'GET';
    const params = { expire_time };

    const options = Object.assign({}, this.default_options, {url, method, params});
    return request(options);
  }

  /** Clone the dashboard with special parameters
    * @param  {String} dashboard id
    * @param  {JSON} data - Name of the dashboard
    * @param  {String} data{}.email - Email to receive invitation
    * @param  {String} data{}.message - Scope message for the email
    * @param  {JSON} data{}.setup - special setup for clone
    * @param  {boolean} data{}.copy_me - true to send a copy to yourself
    * @return {Promise}
     */
  shareClone(dashboard_id, data) {
    data = data || {};
    if (!dashboard_id || dashboard_id == '') {
      return new Promise((resolve,reject) => reject('Dashboard ID parameter is obrigatory.'));
    } else if (!data.email) {
      return new Promise((resolve,reject) => reject('data.email parameter is obrigatory.'));
    }

    let url    = `${config.api_url}/dashboard/${dashboard_id}/share/copy`;
    let method = 'POST';

    let options = Object.assign({}, this.default_options, {url, method, data});
    return request(options);
  }

  /** Get list of devices related with dashboard
    * @param  {String} dashboard id
    * @return {Promise}
     */
  listDevicesRelated(dashboard_id) {
    let url = `${config.api_url}/dashboard/${dashboard_id}/devices`;
    let method = 'GET';

    let options = Object.assign({}, this.default_options, { url, method });
    return request(options);
  }

  // ----------- Sub-methods -----------
  get widgets() {
    return new Widgets(this.token);
  }
}

module.exports = Dashboards;
<|endoftext|>


<commit_before>/*
We retrieve some exercises for structural analysis
 */

import UI from 'src/util/ui';

let html = `

      Algorithm
      Allow negative
      Scale insensitive
      Formula

      avg
      ✔
      ✘

      canberra
      ✘
      ✘

      chebyshev
      ✔
      ✘

      clark
      ✔
      ✘

      czekanowski
      ✔
      ✔

      dice
      ✔
      ✘

      divergence
      ✔
      ✘

      euclidean
      ✔
      ✘

      gower
      ✔
      ✘

      intersection
Requires normalization
      ✔
      ✘

      jaccard
      ✔
      ✔

      kulczynski
      ✘
      ✘

      lorentzian
      ✔
      ✘

      manhattan
      ✔
      ✘

      probabilisticSymmetric
      ✘
      ✘

      soergel
      ✔
      ✔

      sorensen
      ✔
      ✘

      squared
      ✘
      ✘

      squaredChord
      ✘
      ✘

      squaredEuclidean
      ✔
      ✘

      waveHedges
      ✔
      ✔

`;

module.exports = function showMfGroupsList() {
  UI.dialog(html, {
    width: 700,
    height: 700,
    title: 'List of known groups'
  });
};
<commit_msg>fix: display italic in darkred<commit_after>/*
We retrieve some exercises for structural analysis
 */

import UI from 'src/util/ui';

let html = `

      Algorithm
      Allow negative
      Scale insensitive
      Formula

      avg
      ✔
      ✘

      canberra
      ✘
      ✘

      chebyshev
      ✔
      ✘

      clark
      ✔
      ✘

      czekanowski
      ✔
      ✔

      dice
      ✔
      ✘

      divergence
      ✔
      ✘

      euclidean
      ✔
      ✘

      gower
      ✔
      ✘

      intersection
Requires normalization
      ✔
      ✘

      jaccard
      ✔
      ✔

      kulczynski
      ✘
      ✘

      lorentzian
      ✔
      ✘

      manhattan
      ✔
      ✘

      probabilisticSymmetric
      ✘
      ✘

      soergel
      ✔
      ✔

      sorensen
      ✔
      ✘

      squared
      ✘
      ✘

      squaredChord
      ✘
      ✘

      squaredEuclidean
      ✔
      ✘

      waveHedges
      ✔
      ✔

`;

module.exports = function showMfGroupsList() {
  UI.dialog(html, {
    width: 700,
    height: 700,
    title: 'List of known groups'
  });
};
<|endoftext|>


<commit_before>/** @babel */

import helpers from '../spec-helpers'
import fs from 'fs-plus'
import path from 'path'
import KnitrBuilder from '../../lib/builders/knitr'

function getRawFile (filePath) {
  return fs.readFileSync(filePath, {encoding: 'utf-8'})
}

describe('KnitrBuilder', () => {
  let builder, fixturesPath, filePath

  beforeEach(() => {
    waitsForPromise(() => {
      return helpers.activatePackages()
    })
    builder = new KnitrBuilder()
    spyOn(builder, 'logStatusCode')
    fixturesPath = helpers.cloneFixtures()
    filePath = path.join(fixturesPath, 'knitr', 'file.Rnw')
  })

  describe('constructArgs', () => {
    it('produces default arguments containing expected file path', () => {
      const expectedArgs = [
        '-e "library(knitr)"',
        '-e "opts_knit$set(concordance = TRUE)"',
        `-e "knit('${filePath.replace(/\\/g, '\\\\')}')"`
      ]

      const args = builder.constructArgs(filePath)
      expect(args).toEqual(expectedArgs)
    })
  })

  describe('run', () => {
    let exitCode

    beforeEach(() => {
      atom.config.set('latex.builder', 'latexmk')
    })

    it('successfully executes knitr when given a valid R Sweave file', () => {
      waitsForPromise(() => {
        return builder.run(filePath).then(code => { exitCode = code })
      })

      runs(() => {
        const outputFilePath = path.join(fixturesPath, 'knitr', 'file.tex')

        expect(exitCode).toBe(0)
        expect(builder.logStatusCode).not.toHaveBeenCalled()
        expect(getRawFile(outputFilePath)).toContain('$\\tau \\approx 6.2831853$')
      })
    })

    it('fails to execute knitr when given an invalid file path', () => {
      filePath = path.join(fixturesPath, 'foo.Rnw')

      waitsForPromise(() => {
        return builder.run(filePath).then(code => { exitCode = code })
      })

      runs(() => {
        expect(exitCode).toBe(1)
        expect(builder.logStatusCode).toHaveBeenCalled()
      })
    })

    it('detects missing knitr library and logs an error', () => {
      const directoryPath = path.dirname(filePath)
      const env = { 'R_LIBS_USER': '/dev/null', 'R_LIBS_SITE': '/dev/null' }
      const options = builder.constructChildProcessOptions(directoryPath)
      Object.assign(options.env, env)
      spyOn(builder, 'constructChildProcessOptions').andReturn(options)
      spyOn(latex.log, 'showMessage').andCallThrough()

      waitsForPromise(() => {
        return builder.run(filePath).then(code => { exitCode = code })
      })

      runs(() => {
        expect(exitCode).toBe(-1)
        expect(builder.logStatusCode).toHaveBeenCalled()
        expect(latex.log.showMessage).toHaveBeenCalledWith({
          type: 'error',
          text: 'The R package "knitr" could not be loaded.'
        })
      })
    })
  })

  describe('resolveOutputPath', () => {
    let sourcePath, resultPath

    beforeEach(() => {
      sourcePath = path.resolve('/var/foo.Rnw')
      resultPath = path.resolve('/var/foo.tex')
    })

    it('detects an absolute path and returns it unchanged', () => {
      const stdout = `foo\nbar\n\n[1] "${resultPath}"`
      const resolvedPath = builder.resolveOutputPath(sourcePath, stdout)

      expect(resolvedPath).toBe(resultPath)
    })

    it('detects a relative path and makes it absolute with respect to the source file', () => {
      const stdout = `foo\nbar\n\n[1] "${path.basename(resultPath)}"`
      const resolvedPath = builder.resolveOutputPath(sourcePath, stdout)

      expect(resolvedPath).toBe(resultPath)
    })
  })
})
<commit_msg>Add test for KnitrBuilder.canProcess<commit_after>/** @babel */

import helpers from '../spec-helpers'
import fs from 'fs-plus'
import path from 'path'
import KnitrBuilder from '../../lib/builders/knitr'

function getRawFile (filePath) {
  return fs.readFileSync(filePath, {encoding: 'utf-8'})
}

describe('KnitrBuilder', () => {
  let builder, fixturesPath, filePath

  beforeEach(() => {
    waitsForPromise(() => {
      return helpers.activatePackages()
    })
    builder = new KnitrBuilder()
    spyOn(builder, 'logStatusCode')
    fixturesPath = helpers.cloneFixtures()
    filePath = path.join(fixturesPath, 'knitr', 'file.Rnw')
  })

  describe('constructArgs', () => {
    it('produces default arguments containing expected file path', () => {
      const expectedArgs = [
        '-e "library(knitr)"',
        '-e "opts_knit$set(concordance = TRUE)"',
        `-e "knit('${filePath.replace(/\\/g, '\\\\')}')"`
      ]

      const args = builder.constructArgs(filePath)
      expect(args).toEqual(expectedArgs)
    })
  })

  describe('run', () => {
    let exitCode

    beforeEach(() => {
      atom.config.set('latex.builder', 'latexmk')
    })

    it('successfully executes knitr when given a valid R Sweave file', () => {
      waitsForPromise(() => {
        return builder.run(filePath).then(code => { exitCode = code })
      })

      runs(() => {
        const outputFilePath = path.join(fixturesPath, 'knitr', 'file.tex')

        expect(exitCode).toBe(0)
        expect(builder.logStatusCode).not.toHaveBeenCalled()
        expect(getRawFile(outputFilePath)).toContain('$\\tau \\approx 6.2831853$')
      })
    })

    it('fails to execute knitr when given an invalid file path', () => {
      filePath = path.join(fixturesPath, 'foo.Rnw')

      waitsForPromise(() => {
        return builder.run(filePath).then(code => { exitCode = code })
      })

      runs(() => {
        expect(exitCode).toBe(1)
        expect(builder.logStatusCode).toHaveBeenCalled()
      })
    })

    it('detects missing knitr library and logs an error', () => {
      const directoryPath = path.dirname(filePath)
      const env = { 'R_LIBS_USER': '/dev/null', 'R_LIBS_SITE': '/dev/null' }
      const options = builder.constructChildProcessOptions(directoryPath)
      Object.assign(options.env, env)
      spyOn(builder, 'constructChildProcessOptions').andReturn(options)
      spyOn(latex.log, 'showMessage').andCallThrough()

      waitsForPromise(() => {
        return builder.run(filePath).then(code => { exitCode = code })
      })

      runs(() => {
        expect(exitCode).toBe(-1)
        expect(builder.logStatusCode).toHaveBeenCalled()
        expect(latex.log.showMessage).toHaveBeenCalledWith({
          type: 'error',
          text: 'The R package "knitr" could not be loaded.'
        })
      })
    })
  })

  describe('resolveOutputPath', () => {
    let sourcePath, resultPath

    beforeEach(() => {
      sourcePath = path.resolve('/var/foo.Rnw')
      resultPath = path.resolve('/var/foo.tex')
    })

    it('detects an absolute path and returns it unchanged', () => {
      const stdout = `foo\nbar\n\n[1] "${resultPath}"`
      const resolvedPath = builder.resolveOutputPath(sourcePath, stdout)

      expect(resolvedPath).toBe(resultPath)
    })

    it('detects a relative path and makes it absolute with respect to the source file', () => {
      const stdout = `foo\nbar\n\n[1] "${path.basename(resultPath)}"`
      const resolvedPath = builder.resolveOutputPath(sourcePath, stdout)

      expect(resolvedPath).toBe(resultPath)
    })
  })

  describe('canProcess', () => {
    it('returns true when given a file path with a .Rnw extension', () => {
      const canProcess = KnitrBuilder.canProcess(filePath)
      expect(canProcess).toBe(true)
    })
  })
})
<|endoftext|>


<commit_before>var config = {};

config.api= {};

config.api.ip = "192.168.1.11";
config.api.port = "9000";
config.api.base ="http://" + config.api.ip + ":" +config.api.port + "/";
config.api.urls = {
	customerList: config.api.base + "api/customers/current" };

var constant = {};
constant.cartSlider = {"ADD_ITEM": 0, "REMOVE_ITEM": 2, "CURRENT_ITEM": 1};

/*
config.api.url + 'api/customer'*/<commit_msg>cartCtrl, cartService tamamlandı.<commit_after>var config = {};

config.api= {};

config.api.ip = "192.168.1.11";
config.api.port = "9000";
config.api.base ="http://" + config.api.ip + ":" +config.api.port + "/";
config.api.urls = {
	customerList: config.api.base + "api/customers/current",
	employeeList: config.api.base + "api/employees"
};

var constant = {};
constant.cartSlider = {"ADD_ITEM": 0, "REMOVE_ITEM": 2, "CURRENT_ITEM": 1};

/*
config.api.url + 'api/customer'*/<|endoftext|>


<commit_before>'use strict';

const ROUND_DURATION = 8 * 1000; //8 seconds

class Ambush {
	constructor(room, seconds) {
		this.players = new Map();
		this.round = 0;
		this.room = room;
		if (this.room.ambushCount) {
			this.room.ambushCount++;
		} else {
			this.room.ambushCount = 1;
		}
		this.timeLeft = Date.now() + seconds * 1000;

		this.room.add('|uhtml|ambush' + this.room.ambushCount + this.round + '|
A game of Ambush has been started!
' +
			'The game will begin in ' + seconds + ' seconds!
' +
			'<button name = "send" value = "/ambush join">Join!</button>
'
		);
		this.timer = setTimeout(() => {
			if (this.players.size < 3) {
				this.room.add('|uhtmlchange|ambush' + this.room.ambushCount + this.round + '|
This game of ambush has been ended due to the lack of players.
').update();
				return this.end();
			}
			this.nextRound();
		}, seconds * 1000);
	}
	updateJoins() {
		let msg = 'ambush' + this.room.ambushCount + this.round + '|
A game of Ambush has been started!
' +
			'The game will begin in ' + Math.round((this.timeLeft - Date.now()) / 1000) + ' seconds
' +
			'<button name = "send" value = "/ambush join">Join!</button>';
		if (this.players.size > 0) {
			msg += '' + this.players.size + ' ' + (this.players.size === 1 ? 'user has' : 'users have') + ' joined: ' + Array.from(this.players).map(player => Tools.escapeHTML(player[0].name)).join(', ') + '';
		}
		this.room.add('|uhtmlchange|' + msg + '
');
	}
	join(user, self) {
		if (!user.named) return self.errorReply("You must choose a name before joining a game of ambush.");
		if (this.players.has(user)) return self.sendReply('You have already joined this game of ambush.');
		if (this.round > 0) return self.sendReply('You cannot join a game of ambush after it has started.');

		this.players.set(user, {status:'alive', rounds:0});
		this.updateJoins();
	}
	leave(user, self) {
		if (!this.players.has(user)) return self.sendReply('You haven\'t joined this game of ambush yet.');

		this.players.delete(user);
		if (!this.round) {
			this.updateJoins();
		} else {
			this.room.add('|html|' + Tools.escapeHTML(user.name) + ' has left the game!');
		}
	}
	getSurvivors() {
		return Array.from(this.players).filter(player => player[1].status === 'alive');
	}
	nextRound() {
		clearTimeout(this.timer);
		this.canShoot = false;
		if (this.checkWinner()) return this.getWinner();
		let survivors = this.getSurvivors();
		if (this.lastRoundSurvivors === survivors.length) {
			this.room.add('|html|
This game of ambush has ended due to inactivity, with ' + survivors.length + ' survivors.
');
			return this.end();
		}
		this.lastRoundSurvivors = survivors.length;

		this.round++;
		this.loadGuns();
		let msg = 'ambush' + this.room.ambushCount + this.round + '|
Round ' + this.round + '
' +
			'Players: ' + survivors.map(player => Tools.escapeHTML(player[0].name)).join(', ') +
			'
Use /fire [player] to shoot another player!';
		this.room.add('|uhtml|' + msg + '
Wait for it...
').update();

		this.release = setTimeout(() => {
			this.room.add('|uhtmlchange|' + msg + '
FIRE!
').update();
			this.canShoot = true;
			this.resetTimer();
		}, (Math.floor(Math.random() * 12) + 3) * 1000);
	}
	fire(user, target, self) {
		let getUser = this.players.get(user);
		if (!getUser) return self.sendReply("You aren't a player in this game of Ambush.");
		this.madeMove = false;

		if (!this.canShoot) return self.sendReply("You're not allowed to open fire yet!");

		if (getUser.status === 'dead') return self.sendReply("You can't fire after you've been killed!");
		if (!getUser.rounds) return self.sendReply("You're out of rounds! You can't shoot anyone else!");

		let targetUser = Users(target);
		if (!targetUser) return self.sendReply('User ' + target + ' not found.');
		if (!this.players.has(targetUser)) return self.sendReply(targetUser.name + ' is not a player!');
		if (this.players.get(targetUser).status === 'dead') return self.sendReply(targetUser.name + ' has already been shot!');

		this.players.get(user).rounds--;
		this.madeMove = true;
		if (targetUser === user) {
			this.room.add('|html|' + user.name + ' shot themself!');
		} else if (!this.players.get(targetUser).rounds) {
			this.room.add('|html|' + Tools.escapeHTML(user.name) + ' fired at ' + Tools.escapeHTML(targetUser.name) + ', but ' + Tools.escapeHTML(targetUser.name) + ' has an active shield!');
			return;
		} else {
			this.room.add('|html|' + Tools.escapeHTML(user.name) + ' fired at ' + Tools.escapeHTML(targetUser.name) + '!');
		}
		this.players.get(targetUser).status = 'dead';

		if (this.checkWinner()) this.getWinner();
	}
	loadGuns() {
		this.players.forEach((details, user) => {
			if (this.players.get(user).status === 'alive') this.players.get(user).rounds = 1;
		});
	}
	resetTimer() {
		this.timer = setTimeout(() => {
			this.nextRound();
			this.room.update();
		}, ROUND_DURATION);
	}
	dq(target, self) {
		if (!this.round) return self.sendReply('You can only disqualify a player after the first round has begun.');
		let targetUser = Users(target);
		if (!targetUser) return self.sendReply('User ' + target + ' not found.');

		let getUser = this.players.get(targetUser);
		if (!getUser) return self.sendReply(targetUser.name + ' is not a player!');
		if (getUser.status === 'dead') return self.sendReply(targetUser.name + ' has already been killed!');

		this.players.delete(targetUser);
		this.room.add('|html|' + Tools.escapeHTML(targetUser.name) + ' has been disqualified from the game.');
		if (this.checkWinner()) this.getWinner();
	}
	checkWinner() {
		if (this.getSurvivors().length === 1) return true;
	}
	getWinner() {
		let winner = this.getSurvivors()[0][0].name;
		let msg = '|html|
The winner of this game of ambush is ' + Tools.escapeHTML(winner) + '! Congratulations!';
		if (this.room.id === 'lobby') {
			msg += '' + Tools.escapeHTML(winner) + ' has also won 5 tickets for winning!';
			Db('ticket').set(toId(user.userid), Db('ticket').get(toId(user), 0) + 5).get(toId(user.userid) () => this.room.add(msg).update());
		} else {
			this.room.add(msg).update();
		}
		this.end();
	}
	end(user) {
		if (user) {
			let msg = '
This game of ambush has been forcibly ended by ' + Tools.escapeHTML(user.name) + '
';
			if (!this.madeMove) {
				this.room.add('|uhtmlchange|ambush' + this.room.ambushCount + this.round + '|' + msg).update();
			} else {
				this.room.add('|html|' + msg).update();
			}
		}
		if (this.release) clearTimeout(this.release);
		clearTimeout(this.timer);
		delete this.room.ambush;
	}
}
let commands = {
	'': 'new',
	'start': 'new',
	'begin': 'new',
	'new': function (target, room, user) {
		if (room.ambush) return this.sendReply("There is already a game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");
		if (!user.can('broadcast', null, room)) return this.sendReply("You must be ranked + or higher in this room to start a game of ambush.");

		if (!target || !target.trim()) target = '60';
		if (isNaN(target)) return this.sendReply('\'' + target + '\' is not a valid number.');
		if (target.includes('.') || target > 180 || target < 10) return this.sendReply('The number of seconds needs to be a non-decimal number between 10 and 180.');

		room.ambush = new Ambush(room, Number(target));
	},
	join: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");

		room.ambush.join(user, this);
	},
	leave: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");

		room.ambush.leave(user, this);
	},
	proceed: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");
		if (!user.can('broadcast', null, room)) return this.sendReply("You must be ranked + or higher in this room to forcibly begin the first round of a game of ambush.");

		if (room.ambush.round) return this.sendReply('This game of ambush has already begun!');
		if (room.ambush.players.size < 3) return this.sendReply('There aren\'t enough players yet. Wait for more to join!');
		room.add('(' + user.name + ' forcibly started round 1)');
		room.ambush.nextRound();
	},
	disqualify: 'dq',
	dq: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");
		if (!user.can('mute', null, room)) return this.sendReply("You must be ranked % or higher in this room to disqualify a user from a game of ambush.");

		room.ambush.dq(target, this);
	},
	shoot: 'fire',
	fire: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");

		room.ambush.fire(user, target, this);
	},
	cancel: 'end',
	end: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (!user.can('mute', null, room)) return this.sendReply("You must be ranked % or higher in this room to end a game of ambush.");

		room.ambush.end(user);
	},
	help: function () {
		this.parse('/help ambush');
	},
};
exports.commands = {
	ambush: commands,
	shoot: commands.fire,
	ambushhelp: [
		'/ambush start [seconds] - Starts a game of ambush in the room. The first round will begin after the mentioned number of seconds (1 minute by default). Requires + or higher to use.',
		'/ambush join/leave - Joins/Leaves a game of ambush.',
		'/ambush proceed - Forcibly starts the first round of the game. Requires + or higher to use',
		'/ambush dq [user] - Disqualifies a player from a game of ambush. Requires % or higher to use',
		'/ambush shoot [user] - Shoots another player (you can shoot yourself too)',
		'/ambush end - Forcibly ends a game of ambush. Requires % or higher to use.',
		'/ambush rules - Displays the rules of the game.',
	],
};
<commit_msg>Update ambush.js<commit_after>'use strict';

const ROUND_DURATION = 8 * 1000; //8 seconds

class Ambush {
	constructor(room, seconds) {
		this.players = new Map();
		this.round = 0;
		this.room = room;
		if (this.room.ambushCount) {
			this.room.ambushCount++;
		} else {
			this.room.ambushCount = 1;
		}
		this.timeLeft = Date.now() + seconds * 1000;

		this.room.add('|uhtml|ambush' + this.room.ambushCount + this.round + '|
A game of Ambush has been started!
' +
			'The game will begin in ' + seconds + ' seconds!
' +
			'<button name = "send" value = "/ambush join">Join!</button>
'
		);
		this.timer = setTimeout(() => {
			if (this.players.size < 3) {
				this.room.add('|uhtmlchange|ambush' + this.room.ambushCount + this.round + '|
This game of ambush has been ended due to the lack of players.
').update();
				return this.end();
			}
			this.nextRound();
		}, seconds * 1000);
	}
	updateJoins() {
		let msg = 'ambush' + this.room.ambushCount + this.round + '|
A game of Ambush has been started!
' +
			'The game will begin in ' + Math.round((this.timeLeft - Date.now()) / 1000) + ' seconds
' +
			'<button name = "send" value = "/ambush join">Join!</button>';
		if (this.players.size > 0) {
			msg += '' + this.players.size + ' ' + (this.players.size === 1 ? 'user has' : 'users have') + ' joined: ' + Array.from(this.players).map(player => Tools.escapeHTML(player[0].name)).join(', ') + '';
		}
		this.room.add('|uhtmlchange|' + msg + '
');
	}
	join(user, self) {
		if (!user.named) return self.errorReply("You must choose a name before joining a game of ambush.");
		if (this.players.has(user)) return self.sendReply('You have already joined this game of ambush.');
		if (this.round > 0) return self.sendReply('You cannot join a game of ambush after it has started.');

		this.players.set(user, {status:'alive', rounds:0});
		this.updateJoins();
	}
	leave(user, self) {
		if (!this.players.has(user)) return self.sendReply('You haven\'t joined this game of ambush yet.');

		this.players.delete(user);
		if (!this.round) {
			this.updateJoins();
		} else {
			this.room.add('|html|' + Tools.escapeHTML(user.name) + ' has left the game!');
		}
	}
	getSurvivors() {
		return Array.from(this.players).filter(player => player[1].status === 'alive');
	}
	nextRound() {
		clearTimeout(this.timer);
		this.canShoot = false;
		if (this.checkWinner()) return this.getWinner();
		let survivors = this.getSurvivors();
		if (this.lastRoundSurvivors === survivors.length) {
			this.room.add('|html|
This game of ambush has ended due to inactivity, with ' + survivors.length + ' survivors.
');
			return this.end();
		}
		this.lastRoundSurvivors = survivors.length;

		this.round++;
		this.loadGuns();
		let msg = 'ambush' + this.room.ambushCount + this.round + '|
Round ' + this.round + '
' +
			'Players: ' + survivors.map(player => Tools.escapeHTML(player[0].name)).join(', ') +
			'
Use /fire [player] to shoot another player!';
		this.room.add('|uhtml|' + msg + '
Wait for it...
').update();

		this.release = setTimeout(() => {
			this.room.add('|uhtmlchange|' + msg + '
FIRE!
').update();
			this.canShoot = true;
			this.resetTimer();
		}, (Math.floor(Math.random() * 12) + 3) * 1000);
	}
	fire(user, target, self) {
		let getUser = this.players.get(user);
		if (!getUser) return self.sendReply("You aren't a player in this game of Ambush.");
		this.madeMove = false;

		if (!this.canShoot) return self.sendReply("You're not allowed to open fire yet!");

		if (getUser.status === 'dead') return self.sendReply("You can't fire after you've been killed!");
		if (!getUser.rounds) return self.sendReply("You're out of rounds! You can't shoot anyone else!");

		let targetUser = Users(target);
		if (!targetUser) return self.sendReply('User ' + target + ' not found.');
		if (!this.players.has(targetUser)) return self.sendReply(targetUser.name + ' is not a player!');
		if (this.players.get(targetUser).status === 'dead') return self.sendReply(targetUser.name + ' has already been shot!');

		this.players.get(user).rounds--;
		this.madeMove = true;
		if (targetUser === user) {
			this.room.add('|html|' + user.name + ' shot themself!');
		} else if (!this.players.get(targetUser).rounds) {
			this.room.add('|html|' + Tools.escapeHTML(user.name) + ' fired at ' + Tools.escapeHTML(targetUser.name) + ', but ' + Tools.escapeHTML(targetUser.name) + ' has an active shield!');
			return;
		} else {
			this.room.add('|html|' + Tools.escapeHTML(user.name) + ' fired at ' + Tools.escapeHTML(targetUser.name) + '!');
		}
		this.players.get(targetUser).status = 'dead';

		if (this.checkWinner()) this.getWinner();
	}
	loadGuns() {
		this.players.forEach((details, user) => {
			if (this.players.get(user).status === 'alive') this.players.get(user).rounds = 1;
		});
	}
	resetTimer() {
		this.timer = setTimeout(() => {
			this.nextRound();
			this.room.update();
		}, ROUND_DURATION);
	}
	dq(target, self) {
		if (!this.round) return self.sendReply('You can only disqualify a player after the first round has begun.');
		let targetUser = Users(target);
		if (!targetUser) return self.sendReply('User ' + target + ' not found.');

		let getUser = this.players.get(targetUser);
		if (!getUser) return self.sendReply(targetUser.name + ' is not a player!');
		if (getUser.status === 'dead') return self.sendReply(targetUser.name + ' has already been killed!');

		this.players.delete(targetUser);
		this.room.add('|html|' + Tools.escapeHTML(targetUser.name) + ' has been disqualified from the game.');
		if (this.checkWinner()) this.getWinner();
	}
	checkWinner() {
		if (this.getSurvivors().length === 1) return true;
	}
	getWinner() {
		let winner = this.getSurvivors()[0][0].name;
		let msg = '|html|
The winner of this game of ambush is ' + Tools.escapeHTML(winner) + '! Congratulations!';
		{
			this.room.add(msg).update();
		}
		this.end();
	}
	end(user) {
		if (user) {
			let msg = '
This game of ambush has been forcibly ended by ' + Tools.escapeHTML(user.name) + '
';
			if (!this.madeMove) {
				this.room.add('|uhtmlchange|ambush' + this.room.ambushCount + this.round + '|' + msg).update();
			} else {
				this.room.add('|html|' + msg).update();
			}
		}
		if (this.release) clearTimeout(this.release);
		clearTimeout(this.timer);
		delete this.room.ambush;
	}
}
let commands = {
	'': 'new',
	'start': 'new',
	'begin': 'new',
	'new': function (target, room, user) {
		if (room.ambush) return this.sendReply("There is already a game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");
		if (!user.can('broadcast', null, room)) return this.sendReply("You must be ranked + or higher in this room to start a game of ambush.");

		if (!target || !target.trim()) target = '60';
		if (isNaN(target)) return this.sendReply('\'' + target + '\' is not a valid number.');
		if (target.includes('.') || target > 180 || target < 10) return this.sendReply('The number of seconds needs to be a non-decimal number between 10 and 180.');

		room.ambush = new Ambush(room, Number(target));
	},
	join: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");

		room.ambush.join(user, this);
	},
	leave: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");

		room.ambush.leave(user, this);
	},
	proceed: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");
		if (!user.can('broadcast', null, room)) return this.sendReply("You must be ranked + or higher in this room to forcibly begin the first round of a game of ambush.");

		if (room.ambush.round) return this.sendReply('This game of ambush has already begun!');
		if (room.ambush.players.size < 3) return this.sendReply('There aren\'t enough players yet. Wait for more to join!');
		room.add('(' + user.name + ' forcibly started round 1)');
		room.ambush.nextRound();
	},
	disqualify: 'dq',
	dq: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");
		if (!user.can('mute', null, room)) return this.sendReply("You must be ranked % or higher in this room to disqualify a user from a game of ambush.");

		room.ambush.dq(target, this);
	},
	shoot: 'fire',
	fire: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (room.isMuted(user) || user.locked) return this.errorReply("You cannot use this while unable to speak.");

		room.ambush.fire(user, target, this);
	},
	cancel: 'end',
	end: function (target, room, user) {
		if (!room.ambush) return this.sendReply("There is no game of ambush going on in this room.");
		if (!user.can('mute', null, room)) return this.sendReply("You must be ranked % or higher in this room to end a game of ambush.");

		room.ambush.end(user);
	},
	help: function () {
		this.parse('/help ambush');
	},
};
exports.commands = {
	ambush: commands,
	shoot: commands.fire,
	ambushhelp: [
		'/ambush start [seconds] - Starts a game of ambush in the room. The first round will begin after the mentioned number of seconds (1 minute by default). Requires + or higher to use.',
		'/ambush join/leave - Joins/Leaves a game of ambush.',
		'/ambush proceed - Forcibly starts the first round of the game. Requires + or higher to use',
		'/ambush dq [user] - Disqualifies a player from a game of ambush. Requires % or higher to use',
		'/ambush shoot [user] - Shoots another player (you can shoot yourself too)',
		'/ambush end - Forcibly ends a game of ambush. Requires % or higher to use.',
		'/ambush rules - Displays the rules of the game.',
	],
};
<|endoftext|>


<commit_before>'use strict';

/***************
 *  Utilities  *
 ***************/

/**
 * Extends the target object with properties from the other object
 * @param {Object} target The object to extend, and the one returned
 * @param {Object} object The object to borrow properties from
 */
function extend(target, obj) {
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            target[i] = obj[i];
        }
    }

    return target;
}

/*********
 *  API  *
 *********/

/**
 * Returns the specified header property
 * @param {String} key The key associated with a header value
 * @return {String} The header value
 */
function get(key) {
    return this.getResponseHeader(key);
}

/**
 * Returns the specified header property
 * @param {String} key   The key associated with a header
 * @param {String} value The header value
 */
function set(key, value) {
    this.setRequestHeader(key, value);
}

/*****************
 *  Constructor  *
 *****************/

/**
 * Creates a new request object, appending new convenience methods as appropriate
 * @param {XMLHttpRequest} request an XHR object
 */
function Request(request, url) {
    if (request) {
        extend(request, Request.prototype);
    }

    request.path = url;

    return request;
}

/***************
 *  Prototype  *
 ***************/

Request.prototype = {
    get  : get,
    set  : set,
    path : null
};

/*************
 *  Exports  *
 *************/

module.exports = Request;
<commit_msg>Added data to request<commit_after>'use strict';

/***************
 *  Utilities  *
 ***************/

/**
 * Extends the target object with properties from the other object
 * @param {Object} target The object to extend, and the one returned
 * @param {Object} object The object to borrow properties from
 */
function extend(target, obj) {
    for (var i in obj) {
        if (obj.hasOwnProperty(i)) {
            target[i] = obj[i];
        }
    }

    return target;
}

/*********
 *  API  *
 *********/

/**
 * Returns the specified header property
 * @param {String} key The key associated with a header value
 * @return {String} The header value
 */
function get(key) {
    return this.getResponseHeader(key);
}

/**
 * Returns the specified header property
 * @param {String} key   The key associated with a header
 * @param {String} value The header value
 */
function set(key, value) {
    this.setRequestHeader(key, value);
}

/*****************
 *  Constructor  *
 *****************/

/**
 * Creates a new request object, appending new convenience methods as appropriate
 * @param {XMLHttpRequest} request an XHR object
 */
function Request(request, url) {
    if (request) {
        extend(request, Request.prototype);
    }

    request.path = url;

    return request;
}

/***************
 *  Prototype  *
 ***************/

Request.prototype = {
    get  : get,
    set  : set,
    path : null,
    data : null
};

/*************
 *  Exports  *
 *************/

module.exports = Request;
<|endoftext|>


<commit_before>import expandProperty from './expand-property';

export default function(property) {
  if (typeof property !== 'string') {
    return [property];
  }

  let atEachIndex = property.indexOf('@each.');
  if (atEachIndex === -1) {
    atEachIndex = property.indexOf('[]');
  }

  if (atEachIndex === 0) {
    return [''];
  } else if (atEachIndex > 0) {
    return [property.slice(0, atEachIndex - 1)];
  }

  return expandProperty(property);
}
<commit_msg>use a more generic var name for array keys (#122)<commit_after>import expandProperty from './expand-property';

export default function(property) {
  if (typeof property !== 'string') {
    return [property];
  }

  let arrayIndex = property.indexOf('@each.');
  if (arrayIndex === -1) {
    arrayIndex = property.indexOf('[]');
  }

  if (arrayIndex === 0) {
    return [''];
  } else if (arrayIndex > 0) {
    return [property.slice(0, arrayIndex - 1)];
  }

  return expandProperty(property);
}
<|endoftext|>


<commit_before>/**
 * @file Tab component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import FlatButton from '../FlatButton';

import ComponentUtil from '../_vendors/ComponentUtil';

class Tab extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            activatedIndex: props.activatedIndex
        };

    }

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            activatedIndex: ComponentUtil.getDerivedState(props, state, 'activatedIndex')
        };
    }

    handleTabClick = (item, activatedIndex) => {
        this.setState({
            activatedIndex
        }, () => {

            item.onActive && item.onActive(item, activatedIndex);

            const {onTabClick, onIndexChange} = this.props;
            onTabClick && onTabClick(item, activatedIndex);
            onIndexChange && onIndexChange(activatedIndex, item);

        });
    };

    getRenderer = item => {

        if (!item || !item.renderer) {
            return null;
        }

        return typeof item.renderer === 'function' ?
            item.renderer(item)
            :
            item.renderer;

    };

    render() {

        const {className, style, isTabFullWidth, tabs, isAnimated} = this.props,
            {activatedIndex} = this.state,
            tabWidthPerCent = 100 / tabs.length;

        return (

                    {
                        tabs && tabs.map((item, index) => {

                            const {

                                // not passing down these props
                                renderer, onActive,

                                ...restProps

                            } = item;

                            return (
                                <FlatButton {...restProps}
                                            key={index}
                                            className={classNames('tab-button', {
                                                activated: activatedIndex === index
                                            })}
                                            style={{
                                                width: isTabFullWidth ? `${tabWidthPerCent}%` : 'auto'
                                            }}
                                            onClick={() => this.handleTabClick(item, index)}/>
                            );

                        })
                    }

                    {
                        isTabFullWidth ?
                            <div className="ink-bar"
                                 style={{
                                     width: `${tabWidthPerCent}%`,
                                     transform: `translate(${activatedIndex * 100}%, 0)`
                                 }}>

                            :
                            null
                    }

                    {
                        isAnimated ?
                            <div className="tab-content-scroller"
                                 style={{
                                     width: `${tabs.length * 100}%`,
                                     transform: `translate(${-activatedIndex * tabWidthPerCent}%, 0)`
                                 }}>
                                {
                                    tabs && tabs.map((item, index) =>
                                        <div key={index}
                                             className="tab-content"
                                             style={{
                                                 width: `${tabWidthPerCent}%`
                                             }}>
                                            {this.getRenderer(item)}

                                    )
                                }

                            :

                                {tabs && this.getRenderer(tabs[activatedIndex])}

                    }

        );

    }
}

Tab.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Children passed into the TabsItem.
     */
    tabs: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The text value of the tab.Type can be string or number.
         */
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * If true, the tab will be disabled.
         */
        disabled: PropTypes.bool,

        /**
         * If true,the tab will be have loading effect.
         */
        isLoading: PropTypes.bool,

        /**
         * If true,the element's ripple effect will be disabled.
         */
        disableTouchRipple: PropTypes.bool,

        /**
         * Use this property to display an icon.It will display on the left.
         */
        iconCls: PropTypes.string,

        /**
         * The position of the icon.
         */
        iconPosition: PropTypes.string,

        /**
         * The render content in tab.
         */
        renderer: PropTypes.any,

        /**
         * Callback function fired when click onActive tab.
         */
        onActive: PropTypes.func

    })).isRequired,

    /**
     * Activated tab index.
     */
    activatedIndex: PropTypes.number,

    /**
     * If true,the tabs is FullWidth.
     */
    isTabFullWidth: PropTypes.bool,

    isAnimated: PropTypes.bool,

    onIndexChange: PropTypes.func,
    onTabClick: PropTypes.func

};

Tab.defaultProps = {

    tabs: [],

    activatedIndex: 0,
    isTabFullWidth: true,
    isAnimated: true

};

export default Tab;
<commit_msg>update Tab<commit_after>/**
 * @file Tab component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import FlatButton from '../FlatButton';

import ComponentUtil from '../_vendors/ComponentUtil';

class Tab extends Component {

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            activatedIndex: props.activatedIndex
        };

    }

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            activatedIndex: ComponentUtil.getDerivedState(props, state, 'activatedIndex')
        };
    }

    handleTabClick = (item, activatedIndex, e) => {
        this.setState({
            activatedIndex
        }, () => {

            item.onActive && item.onActive(item, activatedIndex, e);

            const {onTabClick, onIndexChange} = this.props;
            onTabClick && onTabClick(item, activatedIndex, e);
            onIndexChange && onIndexChange(activatedIndex, item);

        });
    };

    getRenderer = item => {

        if (!item || !item.renderer) {
            return null;
        }

        return typeof item.renderer === 'function' ?
            item.renderer(item)
            :
            item.renderer;

    };

    render() {

        const {className, style, isTabFullWidth, tabs, isAnimated} = this.props,
            {activatedIndex} = this.state,
            tabWidthPerCent = 100 / tabs.length;

        return (

                    {
                        tabs && tabs.map((item, index) => {

                            const {

                                // not passing down these props
                                renderer, onActive,

                                ...restProps

                            } = item;

                            return (
                                <FlatButton {...restProps}
                                            key={index}
                                            className={classNames('tab-button', {
                                                activated: activatedIndex === index
                                            })}
                                            style={{
                                                width: isTabFullWidth ? `${tabWidthPerCent}%` : 'auto'
                                            }}
                                            onClick={e => this.handleTabClick(item, index, e)}/>
                            );

                        })
                    }

                    {
                        isTabFullWidth ?
                            <div className="ink-bar"
                                 style={{
                                     width: `${tabWidthPerCent}%`,
                                     transform: `translate(${activatedIndex * 100}%, 0)`
                                 }}>

                            :
                            null
                    }

                    {
                        isAnimated ?
                            <div className="tab-content-scroller"
                                 style={{
                                     width: `${tabs.length * 100}%`,
                                     transform: `translate(${-activatedIndex * tabWidthPerCent}%, 0)`
                                 }}>
                                {
                                    tabs && tabs.map((item, index) =>
                                        <div key={index}
                                             className="tab-content"
                                             style={{
                                                 width: `${tabWidthPerCent}%`
                                             }}>
                                            {this.getRenderer(item)}

                                    )
                                }

                            :

                                {tabs && this.getRenderer(tabs[activatedIndex])}

                    }

        );

    }
}

Tab.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Children passed into the TabsItem.
     */
    tabs: PropTypes.arrayOf(PropTypes.shape({

        /**
         * The text value of the tab.Type can be string or number.
         */
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),

        /**
         * If true, the tab will be disabled.
         */
        disabled: PropTypes.bool,

        /**
         * If true,the tab will be have loading effect.
         */
        isLoading: PropTypes.bool,

        /**
         * If true,the element's ripple effect will be disabled.
         */
        disableTouchRipple: PropTypes.bool,

        /**
         * Use this property to display an icon.It will display on the left.
         */
        iconCls: PropTypes.string,

        /**
         * The position of the icon.
         */
        iconPosition: PropTypes.string,

        /**
         * The render content in tab.
         */
        renderer: PropTypes.any,

        /**
         * Callback function fired when click onActive tab.
         */
        onActive: PropTypes.func

    })).isRequired,

    /**
     * Activated tab index.
     */
    activatedIndex: PropTypes.number,

    /**
     * If true,the tabs is FullWidth.
     */
    isTabFullWidth: PropTypes.bool,

    isAnimated: PropTypes.bool,

    onIndexChange: PropTypes.func,
    onTabClick: PropTypes.func

};

Tab.defaultProps = {

    tabs: [],

    activatedIndex: 0,
    isTabFullWidth: true,
    isAnimated: true

};

export default Tab;
<|endoftext|>