<commit_before>import Format from "src/base/Format.js"
import Seq from "src/base/Seq.js"
import Util from "src/base/Util.js"
import Rect from "src/math/Rect.js"
import Config from "src/Config.js"
import Point from "src/math/Point.js"
import Matrix from "src/math/Matrix.js"
import Complex from "src/math/Complex.js"
import Gate from "src/circuit/Gate.js"
import Painter from "src/ui/Painter.js"
import MathPainter from "src/ui/MathPainter.js"

export default class WidgetPainter {

    /**
     * @param {!Painter} painter
     * @param {!number} w
     * @param {!Gate} gate
     * @param {!number} time
     * @returns {!{maxX: !number, maxY: !number}}
     * @private
     */
    static paintGateTooltipHelper(painter, w, gate, time) {
        let maxX = 0;
        let maxY = 4;
        let pad = 4;
        let dispSize = 65;
        let pushRect = (rect, actualPad=pad) => {
            maxY = Math.max(maxY, rect.bottom() + actualPad);
            maxX = Math.max(maxX, rect.right() + actualPad);
        };

        pushRect(painter.printLine(gate.name, new Rect(pad, maxY, w, 18), 0, "blue", 24));
        pushRect(painter.printParagraph(gate.blurb, new Rect(pad, maxY, w, 50), new Point(0, 0), 'black', 14));

        if (Matrix.identity(2).isEqualTo(gate.matrixOrFunc)) {
            return {maxX, maxY};
        }
        pushRect(new Rect(0, maxY, 1, 0), pad*3);
        let curMatrix = gate.matrixAt(time);
        let format = gate.isTimeBased() ? Format.CONSISTENT : Format.SIMPLIFIED;

        // Matrix interpretation.
        pushRect(painter.printParagraph('As matrix:', new Rect(pad, maxY, w, 18), new Point(0, 0), 'black', 12), 0);
        let matrixRect = new Rect(pad, maxY, dispSize, dispSize);
        let matrixDescRect = new Rect(0, matrixRect.y, w - pad, dispSize).skipLeft(matrixRect.right() + pad);
        MathPainter.paintMatrix(painter, curMatrix, matrixRect, Config.DISPLAY_GATE_FORE_COLOR, 'black', undefined);
        pushRect(matrixRect);
        let n = curMatrix.height();
        let b = Math.log2(n);
        let matDescs = Seq.range(n).
            map(c => {
                let inDesc = WidgetPainter.describeKet(b, c, 1, Format.SIMPLIFIED);
                let col = curMatrix.getColumn(c);
                if (col.every(e => e.isEqualTo(0))) {
                    return "discards " + inDesc;
                }
                if (Seq.range(n).every(r => col[r].isEqualTo(r === c ? 1 : 0))) {
                    return "doesn't affect " + inDesc;
                }
                if (Seq.range(n).every(r => r === c || col[r].isEqualTo(0))) {
                    return "phases " + inDesc + " by " + col[c].toString(format);
                }
                let outDesc = new Seq(col).
                    mapWithIndex((e, c) => WidgetPainter.describeKet(b, c, e, format)).
                    filter(e => e !== "").
                    join(" + ").
                    replace(" + -", " - ").
                    replace(" + +", " + ");
                return 'transforms ' + inDesc + ' into ' + outDesc;
            }).
            toArray();
        let rowHeight = matrixDescRect.h / n;
        for (let r = 0; r < n; r++) {
            pushRect(painter.printParagraph(
                matDescs[r],
                matrixDescRect.skipTop(r * rowHeight).takeTop(rowHeight),
                new Point(0, 0.5),
                'black',
                12));
        }

        // Bloch sphere interpretation.
        if (curMatrix.width() === 2 && curMatrix.isApproximatelyUnitary(0.000000001)) {
            pushRect(painter.printParagraph(
                'As rotation:',
                new Rect(pad, maxY, w, 18),
                new Point(0, 0),
                'black',
                12), 0);
            let {angle, axis, phase} = curMatrix.qubitOperationToAngleAxisRotation();

            let blochRect = new Rect(pad, maxY, dispSize, dispSize);
            MathPainter.paintBlochSphereRotation(
                painter,
                curMatrix,
                blochRect);
            pushRect(blochRect);

            let rotDesc = new Seq([
                `rotates: ${format.formatFloat(angle * 180 / Math.PI)}°`,
                `around: ${WidgetPainter.describeAxis(axis, format)}`,
                '',
                `hidden phase: exp(${format.formatFloat(phase * 180 / Math.PI)}°i)`,
                ''
            ]).join('\n');
            pushRect(painter.printParagraph(
                rotDesc,
                new Rect(0, blochRect.y, w - pad, dispSize).skipLeft(blochRect.right() + pad),
                new Point(0, 0.5),
                'black',
                12));
        }

        return {maxX, maxY};
    }

    /**
     * @param {!Painter} painter
     * @param {!Rect} area
     * @param {!Gate} gate
     * @param {!number} time
     */
    static paintGateTooltip(painter, area, gate, time) {
        painter.ctx.save();
        painter.ctx.translate(area.x, area.y);
        area = area.withX(0).withY(0);
        let scale = Math.min(area.w/500, area.h/200);
        if (scale < 1) {
            painter.ctx.scale(scale, scale);
            area = area.withH(area.h/scale).withW(area.w/scale);
        }
        let w = area.w;

        let {maxX, maxY} = WidgetPainter.paintGateTooltipHelper(painter, w, gate, time);
        let r = new Rect(0, 0, maxX, maxY);
        painter.fillRect(r, '#F9FFF9');
        painter.strokeRect(r, 'black');
        WidgetPainter.paintGateTooltipHelper(painter, w, gate, time);

        painter.ctx.restore();
    };

    static describeKet(bitCount, bitMask, factor, format) {
        factor = Complex.from(factor);
        if (factor.isEqualTo(0)) {
            return "";
        }
        let scaleFactoDesc =
            factor.isEqualTo(1) ? "" :
            factor.isEqualTo(-1) ? "-" :
            factor.isEqualTo(Complex.I) ? "i" :
            factor.isEqualTo(Complex.I.times(-1)) ? "-i" :
            (factor.real === 0 || factor.imag === 0) && format !== Format.CONSISTENT ? factor.toString(format) :
            '(' + factor.toString(format) + ')·';

        let bitDesc = bitMask.toString(2);
        while (bitDesc.length < bitCount) {
            bitDesc = '0' + bitDesc;
        }
        return scaleFactoDesc + '|' + bitDesc + '⟩';
    }
    /**
     * @param {!Array.<!number>} unitAxis x, y, z
     * @param {!Format} format
     * @returns {!string}
     */
    static describeAxis(unitAxis, format) {
        let max = new Seq(unitAxis).map(Math.abs).max();
        return new Seq(unitAxis).
            map(e => e/max).
            zip(["X", "Y", "Z"], (val, name) => {
                if (val === 0) {
                    return "";
                }
                if (val === 1) {
                    return name;
                }
                if (val === -1) {
                    return "-" + name;
                }
                return format.formatFloat(val) + "·" + name;
            }).
            filter(e => e !== "").
            join(" + ").
            replace(" + -", " - ").
            replace(" + +", " + ");
    }

    ///**
    // *
    // * @param {!Point} firstNodePoint
    // * @param {!Point} levelDelta
    // * @param {!Point} nodeDelta
    // * @param {!Array<!String>} levelLabels
    // */
    //paintBinaryTree(firstNodePoint, levelDelta, nodeDelta, levelLabels) {
    //    let makeNodePoint = i => firstNodePoint.
    //        plus(nodeDelta.times(i)).
    //        plus(levelDelta.times(Util.powerOfTwoness(i)));
    //
    //    let n = 1 << levelLabels.length;
    //    for (let i = 1; i < n; i++) {
    //        let b = Util.powerOfTwoness(i);
    //        let p = makeNodePoint(i);
    //        if (b > 0) {
    //            let d = 1 << (b - 1);
    //            this.strokeLine(p, makeNodePoint(i + d), Config.BINARY_TREE_LABEL_EDGE_COLOR);
    //            this.strokeLine(p, makeNodePoint(i - d), Config.BINARY_TREE_LABEL_EDGE_COLOR);
    //        }
    //
    //        let levelDeltaLength = Math.sqrt(levelDelta.x * levelDelta.x + levelDelta.y * levelDelta.y);
    //        let weight = new Point(0.5, 0.5).plus(levelDelta.times(-0.5 / levelDeltaLength));
    //        this.printCenteredText(
    //            levelLabels[b],
    //            p,
    //            Config.DEFAULT_TEXT_COLOR,
    //            Config.DEFAULT_FONT_SIZE,
    //            Config.DEFAULT_FONT_FAMILY,
    //            weight);
    //    }
    //};

    ///**
    // *
    // * @param {!QuantumState} state
    // * @param {!Rect} drawArea
    // * @param {!Array<!string>} labels
    // */
    //paintQuantumStateAsLabelledGrid(state, drawArea, labels) {
    //    Util.need(state.columnVector.height() === 1 << labels.length, "columnVector.height() === labels.length");
    //
    //    let numWireRows = Math.floor(labels.length / 2);
    //    let numWireCols = labels.length - numWireRows;
    //    let numDrawRows = 1 << numWireRows;
    //    let numDrawCols = 1 << numWireCols;
    //
    //    let labelDif = 5;
    //    let labelSpace = 8;
    //    let skipLength = Math.max(numWireRows, numWireCols) * labelDif + labelSpace;
    //
    //    // Draw state grid
    //    let gridRect = drawArea.skipLeft(skipLength).skipTop(skipLength);
    //    this.paintQuantumStateAsGrid(state, gridRect);
    //
    //    // Draw row label tree
    //    this.paintBinaryTree(
    //        gridRect.topLeft().offsetBy(0, -1),
    //        new Point(-labelDif, 0),
    //        new Point(0, gridRect.h / numDrawRows),
    //        labels.slice(numWireCols));
    //
    //    // Draw column label tree
    //    this.paintBinaryTree(
    //        gridRect.topLeft().offsetBy(0, -1),
    //        new Point(0, -labelDif),
    //        new Point(gridRect.w / numDrawCols, 0),
    //        labels.slice(0, numWireCols));
    //}
}
<commit_msg>- "doesn't affect x" no longer shows in time-based gate hints<commit_after>import Format from "src/base/Format.js"
import Seq from "src/base/Seq.js"
import Util from "src/base/Util.js"
import Rect from "src/math/Rect.js"
import Config from "src/Config.js"
import Point from "src/math/Point.js"
import Matrix from "src/math/Matrix.js"
import Complex from "src/math/Complex.js"
import Gate from "src/circuit/Gate.js"
import Painter from "src/ui/Painter.js"
import MathPainter from "src/ui/MathPainter.js"

export default class WidgetPainter {

    /**
     * @param {!Painter} painter
     * @param {!number} w
     * @param {!Gate} gate
     * @param {!number} time
     * @returns {!{maxX: !number, maxY: !number}}
     * @private
     */
    static paintGateTooltipHelper(painter, w, gate, time) {
        let maxX = 0;
        let maxY = 4;
        let pad = 4;
        let dispSize = 65;
        let pushRect = (rect, actualPad=pad) => {
            maxY = Math.max(maxY, rect.bottom() + actualPad);
            maxX = Math.max(maxX, rect.right() + actualPad);
        };

        pushRect(painter.printLine(gate.name, new Rect(pad, maxY, w, 18), 0, "blue", 24));
        pushRect(painter.printParagraph(gate.blurb, new Rect(pad, maxY, w, 50), new Point(0, 0), 'black', 14));

        if (Matrix.identity(2).isEqualTo(gate.matrixOrFunc)) {
            return {maxX, maxY};
        }
        pushRect(new Rect(0, maxY, 1, 0), pad*3);
        let curMatrix = gate.matrixAt(time);
        let format = gate.isTimeBased() ? Format.CONSISTENT : Format.SIMPLIFIED;

        // Matrix interpretation.
        pushRect(painter.printParagraph('As matrix:', new Rect(pad, maxY, w, 18), new Point(0, 0), 'black', 12), 0);
        let matrixRect = new Rect(pad, maxY, dispSize, dispSize);
        let matrixDescRect = new Rect(0, matrixRect.y, w - pad, dispSize).skipLeft(matrixRect.right() + pad);
        MathPainter.paintMatrix(painter, curMatrix, matrixRect, Config.DISPLAY_GATE_FORE_COLOR, 'black', undefined);
        pushRect(matrixRect);
        let n = curMatrix.height();
        let b = Math.log2(n);
        let matDescs = Seq.range(n).
            map(c => {
                let inDesc = WidgetPainter.describeKet(b, c, 1, Format.SIMPLIFIED);
                let col = curMatrix.getColumn(c);
                if (col.every(e => e.isEqualTo(0))) {
                    return "discards " + inDesc;
                } else if (Seq.range(n).every(r => col[r].isEqualTo(r === c ? 1 : 0))) {
                    if (!gate.isTimeBased()) {
                        return "doesn't affect " + inDesc;
                    }
                } else if (Seq.range(n).every(r => r === c || col[r].isEqualTo(0))) {
                    return "phases " + inDesc + " by " + col[c].toString(format);
                }
                let outDesc = new Seq(col).
                    mapWithIndex((e, c) => WidgetPainter.describeKet(b, c, e, format)).
                    filter(e => e !== "").
                    join(" + ").
                    replace(" + -", " - ").
                    replace(" + +", " + ");
                return 'transforms ' + inDesc + ' into ' + outDesc;
            }).
            toArray();
        let rowHeight = matrixDescRect.h / n;
        for (let r = 0; r < n; r++) {
            pushRect(painter.printParagraph(
                matDescs[r],
                matrixDescRect.skipTop(r * rowHeight).takeTop(rowHeight),
                new Point(0, 0.5),
                'black',
                12));
        }

        // Bloch sphere interpretation.
        if (curMatrix.width() === 2 && curMatrix.isApproximatelyUnitary(0.000000001)) {
            pushRect(painter.printParagraph(
                'As rotation:',
                new Rect(pad, maxY, w, 18),
                new Point(0, 0),
                'black',
                12), 0);
            let {angle, axis, phase} = curMatrix.qubitOperationToAngleAxisRotation();

            let blochRect = new Rect(pad, maxY, dispSize, dispSize);
            MathPainter.paintBlochSphereRotation(
                painter,
                curMatrix,
                blochRect);
            pushRect(blochRect);

            let rotDesc = new Seq([
                `rotates: ${format.formatFloat(angle * 180 / Math.PI)}°`,
                `around: ${WidgetPainter.describeAxis(axis, format)}`,
                '',
                `hidden phase: exp(${format.formatFloat(phase * 180 / Math.PI)}°i)`,
                ''
            ]).join('\n');
            pushRect(painter.printParagraph(
                rotDesc,
                new Rect(0, blochRect.y, w - pad, dispSize).skipLeft(blochRect.right() + pad),
                new Point(0, 0.5),
                'black',
                12));
        }

        return {maxX, maxY};
    }

    /**
     * @param {!Painter} painter
     * @param {!Rect} area
     * @param {!Gate} gate
     * @param {!number} time
     */
    static paintGateTooltip(painter, area, gate, time) {
        painter.ctx.save();
        painter.ctx.translate(area.x, area.y);
        area = area.withX(0).withY(0);
        let scale = Math.min(area.w/500, area.h/200);
        if (scale < 1) {
            painter.ctx.scale(scale, scale);
            area = area.withH(area.h/scale).withW(area.w/scale);
        }
        let w = area.w;

        let {maxX, maxY} = WidgetPainter.paintGateTooltipHelper(painter, w, gate, time);
        let r = new Rect(0, 0, maxX, maxY);
        painter.fillRect(r, '#F9FFF9');
        painter.strokeRect(r, 'black');
        WidgetPainter.paintGateTooltipHelper(painter, w, gate, time);

        painter.ctx.restore();
    };

    static describeKet(bitCount, bitMask, factor, format) {
        factor = Complex.from(factor);
        if (factor.isEqualTo(0)) {
            return "";
        }
        let scaleFactoDesc =
            factor.isEqualTo(1) ? "" :
            factor.isEqualTo(-1) ? "-" :
            factor.isEqualTo(Complex.I) ? "i" :
            factor.isEqualTo(Complex.I.times(-1)) ? "-i" :
            (factor.real === 0 || factor.imag === 0) && format !== Format.CONSISTENT ? factor.toString(format) :
            '(' + factor.toString(format) + ')·';

        let bitDesc = bitMask.toString(2);
        while (bitDesc.length < bitCount) {
            bitDesc = '0' + bitDesc;
        }
        return scaleFactoDesc + '|' + bitDesc + '⟩';
    }
    /**
     * @param {!Array.<!number>} unitAxis x, y, z
     * @param {!Format} format
     * @returns {!string}
     */
    static describeAxis(unitAxis, format) {
        let max = new Seq(unitAxis).map(Math.abs).max();
        return new Seq(unitAxis).
            map(e => e/max).
            zip(["X", "Y", "Z"], (val, name) => {
                if (val === 0) {
                    return "";
                }
                if (val === 1) {
                    return name;
                }
                if (val === -1) {
                    return "-" + name;
                }
                return format.formatFloat(val) + "·" + name;
            }).
            filter(e => e !== "").
            join(" + ").
            replace(" + -", " - ").
            replace(" + +", " + ");
    }

    ///**
    // *
    // * @param {!Point} firstNodePoint
    // * @param {!Point} levelDelta
    // * @param {!Point} nodeDelta
    // * @param {!Array<!String>} levelLabels
    // */
    //paintBinaryTree(firstNodePoint, levelDelta, nodeDelta, levelLabels) {
    //    let makeNodePoint = i => firstNodePoint.
    //        plus(nodeDelta.times(i)).
    //        plus(levelDelta.times(Util.powerOfTwoness(i)));
    //
    //    let n = 1 << levelLabels.length;
    //    for (let i = 1; i < n; i++) {
    //        let b = Util.powerOfTwoness(i);
    //        let p = makeNodePoint(i);
    //        if (b > 0) {
    //            let d = 1 << (b - 1);
    //            this.strokeLine(p, makeNodePoint(i + d), Config.BINARY_TREE_LABEL_EDGE_COLOR);
    //            this.strokeLine(p, makeNodePoint(i - d), Config.BINARY_TREE_LABEL_EDGE_COLOR);
    //        }
    //
    //        let levelDeltaLength = Math.sqrt(levelDelta.x * levelDelta.x + levelDelta.y * levelDelta.y);
    //        let weight = new Point(0.5, 0.5).plus(levelDelta.times(-0.5 / levelDeltaLength));
    //        this.printCenteredText(
    //            levelLabels[b],
    //            p,
    //            Config.DEFAULT_TEXT_COLOR,
    //            Config.DEFAULT_FONT_SIZE,
    //            Config.DEFAULT_FONT_FAMILY,
    //            weight);
    //    }
    //};

    ///**
    // *
    // * @param {!QuantumState} state
    // * @param {!Rect} drawArea
    // * @param {!Array<!string>} labels
    // */
    //paintQuantumStateAsLabelledGrid(state, drawArea, labels) {
    //    Util.need(state.columnVector.height() === 1 << labels.length, "columnVector.height() === labels.length");
    //
    //    let numWireRows = Math.floor(labels.length / 2);
    //    let numWireCols = labels.length - numWireRows;
    //    let numDrawRows = 1 << numWireRows;
    //    let numDrawCols = 1 << numWireCols;
    //
    //    let labelDif = 5;
    //    let labelSpace = 8;
    //    let skipLength = Math.max(numWireRows, numWireCols) * labelDif + labelSpace;
    //
    //    // Draw state grid
    //    let gridRect = drawArea.skipLeft(skipLength).skipTop(skipLength);
    //    this.paintQuantumStateAsGrid(state, gridRect);
    //
    //    // Draw row label tree
    //    this.paintBinaryTree(
    //        gridRect.topLeft().offsetBy(0, -1),
    //        new Point(-labelDif, 0),
    //        new Point(0, gridRect.h / numDrawRows),
    //        labels.slice(numWireCols));
    //
    //    // Draw column label tree
    //    this.paintBinaryTree(
    //        gridRect.topLeft().offsetBy(0, -1),
    //        new Point(0, -labelDif),
    //        new Point(gridRect.w / numDrawCols, 0),
    //        labels.slice(0, numWireCols));
    //}
}
<|endoftext|>


<commit_before>var gitAccountsAppConfig = {
	'form': {
		'login': {
			'entries': [
				{
					'name': 'provider',
					'label': translation.accountProvider[LANG],
					'type': 'select',
					'value': [{'v': 'github', 'l': 'GitHub'}, {'v': 'bitbucket_org', 'l': 'Bitbucket'}, {'v': 'bitbucket_enterprise', 'l': 'Bitbucket Enterprise'}],
					'tooltip': translation.chooseAccountProvider[LANG],
					'required': true,
					'onAction': function (id, selected, form) {
						if (selected === 'github') {
							form.entries[1].value = 'github.com';
							form.entries[1].type = 'readonly';

							form.entries[4].label = 'Username';

							if (!form.entries[2].value[2]) {
								form.entries[2].value.push({'v': 'organization_public', 'l': 'Organization - Public'});
							}
						}
						else {
							if (form.entries[2].value[2] && form.entries[2].value[2].v === 'organization_public') {
								form.entries[2].value.splice(2, 1);
							}

							if (selected === 'bitbucket_org') {
								form.entries[1].value = 'bitbucket.org';
								form.entries[1].type = 'readonly';

								form.entries[4].label = 'Email Address';
							}
							else if (selected === 'bitbucket_enterprise') {
								form.entries[1].value = ' ';
								form.entries[1].type = 'text';

								form.entries[4].label = 'Username';
							}
						}

						form.entries = form.entries.slice(0, 5);
						form.refresh();
					}
				},
				{
					'name': 'providerDomain',
					'label': 'Provider Domain',
					'type': 'text',
					'value': '',
					'required': true
				},
				{
		            'name': 'type',
		            'label': 'Account Type',
		            'class': 'accountType',
		            'type': 'radio',
		            'value': [
						{'v': 'personal_public', 'l': 'Personal Account - Public Repositories', 'selected': true},
		                {'v': 'personal_private', 'l': 'Personal Account - Public and Private Repositories'}
					],
		            'required': true,
		            onAction: function (label, selected, formConfig) {
						if (selected.split('_')[1] === 'private') {
							if (!formConfig.entries[5] || (formConfig.entries[5] && formConfig.entries[5].name !== 'password')) {
								var password = {
			                        'name': 'password',
			                        'label': 'Password',
			                        'type': 'password',
			                        'value': '',
			                        'tooltip': 'Account Password',
			                        'placeholder': 'Your Password',
			                        'required': true
			                    };
			                    formConfig.entries.splice(5, 0, password);
							}

							var currentProvider;
							for (var i =0; i < formConfig.entries[0].value.length; i++) {
								if (formConfig.entries[0].value[i].selected) {
									currentProvider = formConfig.entries[0].value[i];
								}
							}
							if (currentProvider.v === 'bitbucket_org' && !formConfig.entries[6] && !formConfig.entries[7]) {
								var oauth = [
									{
										'name': 'oauthKey',
										'label': 'OAuth 2.0 Consumer Key',
										'type': 'text',
										'value': '',
										'placeholder': 'OAuth consumer key generated using Bitbucket account settings',
										'required': true
									},
									{
										'name': 'oauthSecret',
										'label': 'OAuth 2.0 Consumer Secret',
										'type': 'text',
										'value': '',
										'placeholder': 'OAuth consumer secret generated using Bitbucket account settings',
										'required': true
									},
									{
										"name": "bitbucketMessage",
										"type": "html",
										"value": "

In order to generate OAuth consumer key/secret, follow the following steps:

Login to your bitbucket account, go to Bitbucket Settings > OAuth

Under OAuth consumers section, click on Add consumer and fill in the required information

Make sure you grant this consumer permission to read repositories

Finally, grab the generated key and secret and use them to login to SOAJS Git app using your bitbucket account

"
									}
								];
								formConfig.entries.splice(6, 0, oauth[0], oauth[1], oauth[2]);
							}
							else if (currentProvider.v === 'github') {
								var githubMessage = {
									"name": "tokenMessage",
									"type": "html",
									"value": "

" + translation.loginMessagePermissionsPartOne[LANG] + "

" + translation.loginMessagePermissionsPartTwo[LANG] + "

" + translation.loginMessagePermissionsPartThree[LANG] + "

" + translation.loginMessagePermissionsPartFour[LANG] + "
"
								};
								formConfig.entries.splice(6, 0, githubMessage);
							}
						}
						else {

							if (formConfig.entries[8] && formConfig.entries[8].name === 'bitbucketMessage') {
								formConfig.entries.splice(8, 1);
							}
							if (formConfig.entries[7] && formConfig.entries[7].name === 'oauthSecret') {
								formConfig.entries.splice(7, 1);
							}
							if (formConfig.entries[6] && formConfig.entries[6].name === 'oauthKey') {
								formConfig.entries.splice(6, 1);
							}
							if (formConfig.entries[5] && formConfig.entries[5].name === 'password') {
								formConfig.entries.splice(5, 1);
							}
						}
		            }
		        },
				{
					'name': 'label',
					'label': translation.accountLabel[LANG],
					'type': 'text',
					'value': '',
					'tooltip': translation.chooseAccountName[LANG],
					'placeholder': translation.exampleMyAccount[LANG],
					'required': true
				},
				{
					'name': 'username',
					'label': translation.username[LANG],
					'type': 'text',
					'value': '',
					'placeholder': translation.yourUsername[LANG],
					'required': true
				}
			]
		},
		'logout': {
			'entries': [
				{
					'name': 'password',
					'label': translation.pleaseProvidePassword[LANG],
					'type': 'password',
					'value': '',
					'placeholder': translation.gitPassword[LANG],
					'required': true
				}
			]
		},
		'selectConfigBranch': {
			'entries': [
				{
					'name': 'branch',
					'label': translation.pleaseSpecifyConfigBranch[LANG],
					'type': 'select',
					'value': [],
					'required': true
				}
			]
		}
	},
	'permissions': {
		listAccounts: ['dashboard', '/gitAccounts/accounts/list', 'get'],
		login: ['dashboard', '/gitAccounts/login', 'post'],
		logout: ['dashboard', '/gitAccounts/logout', 'delete'],
		activateRepo: ['dashboard', '/gitAccounts/repo/activate', 'post'],
		deactivateRepo: ['dashboard', '/gitAccounts/repo/deactivate', 'put'],
		syncRepo: ['dashboard', '/gitAccounts/repo/sync', 'put'],
		getRepos: ['dashboard', '/gitAccounts/getRepos', 'get'],
		getBranches: ['dashboard', '/gitAccounts/getBranches', 'get']
	},

	"blacklistedRepos": [
		'soajs/connect-mongo-soajs',
		'soajs/soajs',
		'soajs/soajs.agent',
		'soajs/soajs.composer',
		'soajs/soajs.dash.example',
		'soajs/soajs.gcs',
		'soajs/soajs.mongodb.data',
		'soajs/soajs.utilities',
		'soajs/soajs.website.contactus',
		'soajs/soajs.jsconfbeirut',
		"soajs/soajs.installer",
		"soajs/soajs.sdk",
		"soajs/soajs.dashboard.ui",
		"soajs/soajs.website.ui",
		"soajs/grunt-soajs",
		"soajs/soajs.urac.driver",
		"soajs/soajs.core.drivers"
	]
};
<commit_msg>updated blacklist repos<commit_after>var gitAccountsAppConfig = {
	'form': {
		'login': {
			'entries': [
				{
					'name': 'provider',
					'label': translation.accountProvider[LANG],
					'type': 'select',
					'value': [{'v': 'github', 'l': 'GitHub'}, {'v': 'bitbucket_org', 'l': 'Bitbucket'}, {'v': 'bitbucket_enterprise', 'l': 'Bitbucket Enterprise'}],
					'tooltip': translation.chooseAccountProvider[LANG],
					'required': true,
					'onAction': function (id, selected, form) {
						if (selected === 'github') {
							form.entries[1].value = 'github.com';
							form.entries[1].type = 'readonly';

							form.entries[4].label = 'Username';

							if (!form.entries[2].value[2]) {
								form.entries[2].value.push({'v': 'organization_public', 'l': 'Organization - Public'});
							}
						}
						else {
							if (form.entries[2].value[2] && form.entries[2].value[2].v === 'organization_public') {
								form.entries[2].value.splice(2, 1);
							}

							if (selected === 'bitbucket_org') {
								form.entries[1].value = 'bitbucket.org';
								form.entries[1].type = 'readonly';

								form.entries[4].label = 'Email Address';
							}
							else if (selected === 'bitbucket_enterprise') {
								form.entries[1].value = ' ';
								form.entries[1].type = 'text';

								form.entries[4].label = 'Username';
							}
						}

						form.entries = form.entries.slice(0, 5);
						form.refresh();
					}
				},
				{
					'name': 'providerDomain',
					'label': 'Provider Domain',
					'type': 'text',
					'value': '',
					'required': true
				},
				{
		            'name': 'type',
		            'label': 'Account Type',
		            'class': 'accountType',
		            'type': 'radio',
		            'value': [
						{'v': 'personal_public', 'l': 'Personal Account - Public Repositories', 'selected': true},
		                {'v': 'personal_private', 'l': 'Personal Account - Public and Private Repositories'}
					],
		            'required': true,
		            onAction: function (label, selected, formConfig) {
						if (selected.split('_')[1] === 'private') {
							if (!formConfig.entries[5] || (formConfig.entries[5] && formConfig.entries[5].name !== 'password')) {
								var password = {
			                        'name': 'password',
			                        'label': 'Password',
			                        'type': 'password',
			                        'value': '',
			                        'tooltip': 'Account Password',
			                        'placeholder': 'Your Password',
			                        'required': true
			                    };
			                    formConfig.entries.splice(5, 0, password);
							}

							var currentProvider;
							for (var i =0; i < formConfig.entries[0].value.length; i++) {
								if (formConfig.entries[0].value[i].selected) {
									currentProvider = formConfig.entries[0].value[i];
								}
							}
							if (currentProvider.v === 'bitbucket_org' && !formConfig.entries[6] && !formConfig.entries[7]) {
								var oauth = [
									{
										'name': 'oauthKey',
										'label': 'OAuth 2.0 Consumer Key',
										'type': 'text',
										'value': '',
										'placeholder': 'OAuth consumer key generated using Bitbucket account settings',
										'required': true
									},
									{
										'name': 'oauthSecret',
										'label': 'OAuth 2.0 Consumer Secret',
										'type': 'text',
										'value': '',
										'placeholder': 'OAuth consumer secret generated using Bitbucket account settings',
										'required': true
									},
									{
										"name": "bitbucketMessage",
										"type": "html",
										"value": "

In order to generate OAuth consumer key/secret, follow the following steps:

Login to your bitbucket account, go to Bitbucket Settings > OAuth

Under OAuth consumers section, click on Add consumer and fill in the required information

Make sure you grant this consumer permission to read repositories

Finally, grab the generated key and secret and use them to login to SOAJS Git app using your bitbucket account

"
									}
								];
								formConfig.entries.splice(6, 0, oauth[0], oauth[1], oauth[2]);
							}
							else if (currentProvider.v === 'github') {
								var githubMessage = {
									"name": "tokenMessage",
									"type": "html",
									"value": "

" + translation.loginMessagePermissionsPartOne[LANG] + "

" + translation.loginMessagePermissionsPartTwo[LANG] + "

" + translation.loginMessagePermissionsPartThree[LANG] + "

" + translation.loginMessagePermissionsPartFour[LANG] + "
"
								};
								formConfig.entries.splice(6, 0, githubMessage);
							}
						}
						else {

							if (formConfig.entries[8] && formConfig.entries[8].name === 'bitbucketMessage') {
								formConfig.entries.splice(8, 1);
							}
							if (formConfig.entries[7] && formConfig.entries[7].name === 'oauthSecret') {
								formConfig.entries.splice(7, 1);
							}
							if (formConfig.entries[6] && formConfig.entries[6].name === 'oauthKey') {
								formConfig.entries.splice(6, 1);
							}
							if (formConfig.entries[5] && formConfig.entries[5].name === 'password') {
								formConfig.entries.splice(5, 1);
							}
						}
		            }
		        },
				{
					'name': 'label',
					'label': translation.accountLabel[LANG],
					'type': 'text',
					'value': '',
					'tooltip': translation.chooseAccountName[LANG],
					'placeholder': translation.exampleMyAccount[LANG],
					'required': true
				},
				{
					'name': 'username',
					'label': translation.username[LANG],
					'type': 'text',
					'value': '',
					'placeholder': translation.yourUsername[LANG],
					'required': true
				}
			]
		},
		'logout': {
			'entries': [
				{
					'name': 'password',
					'label': translation.pleaseProvidePassword[LANG],
					'type': 'password',
					'value': '',
					'placeholder': translation.gitPassword[LANG],
					'required': true
				}
			]
		},
		'selectConfigBranch': {
			'entries': [
				{
					'name': 'branch',
					'label': translation.pleaseSpecifyConfigBranch[LANG],
					'type': 'select',
					'value': [],
					'required': true
				}
			]
		}
	},
	'permissions': {
		listAccounts: ['dashboard', '/gitAccounts/accounts/list', 'get'],
		login: ['dashboard', '/gitAccounts/login', 'post'],
		logout: ['dashboard', '/gitAccounts/logout', 'delete'],
		activateRepo: ['dashboard', '/gitAccounts/repo/activate', 'post'],
		deactivateRepo: ['dashboard', '/gitAccounts/repo/deactivate', 'put'],
		syncRepo: ['dashboard', '/gitAccounts/repo/sync', 'put'],
		getRepos: ['dashboard', '/gitAccounts/getRepos', 'get'],
		getBranches: ['dashboard', '/gitAccounts/getBranches', 'get']
	},

	"blacklistedRepos": [
		'soajs/connect-mongo-soajs',
		'soajs/soajs',
		'soajs/soajs.agent',
		'soajs/soajs.composer',
		'soajs/soajs.dash.example',
		'soajs/soajs.gcs',
		'soajs/soajs.mongodb.data',
		'soajs/soajs.utilities',
		'soajs/soajs.website.contactus',
		'soajs/soajs.jsconfbeirut',
		"soajs/soajs.installer",
		"soajs/soajs.sdk",
		"soajs/soajs.dashboard.ui",
		"soajs/soajs.website.ui",
		"soajs/grunt-soajs",
		"soajs/soajs.urac.driver",
		"soajs/soajs.core.drivers",
		"soajs/soajs.core.modules",
		"soajs/soajs.core.libs"
	]
};
<|endoftext|>


<commit_before>"use strict";

const Discord = require('discord.js');
const mybot = new Discord.Client();
const now = require('performance-now');
const yt = require('ytdl-core');
const prefix = 's.';
const token = 'TOKEN';
const oauth = 'https://discordapp.com/oauth2/authorize?client_id=224495611741863936&scope=bot&permissions=37088320';

mybot.on("ready", function() {
    mybot.user.setGame(`Custom playlists! s.help | s.invite`);
    console.log(`Spotify online, on ${mybot.guilds.size} guilds!`);
});

mybot.on("message", message => {
  if (message.author.bot) return; //ignore bots
  if(message.content.startsWith("<@224495611741863936>")) {
    message.reply("Hey! My help command is `s.help`");
  }

    if (message.content === prefix + "ping") {
        var start = now();
        message.channel.sendMessage("*Pinging...*")
            .then(message => {
                var end = now();
                message.edit(`Pong! **${(end - start).toFixed(0)}ms**`);
            });
    }

    if (message.content.startsWith(prefix + "help")) {
        message.reply("I've sent a list of commands to you. Check your DM's.");
        var help = [
            "Prefix is `s.`",
            "**help** = Sends this message.",
            "**play** = Starts playing your playlist in the voice channel you are in.",
            "**skip** = Skips the currently playing song.",
            "**stop** = Stops playing.",
            "**force <song>** = Plays the specified song. *(YouTube videos only)*",
            "**addsong <song>** = Adds the specified song to your custom playlist. *(YouTube videos only)*",
            "**songs** = List's all of your songs.",
            "**invite** = Sends the OAuth link to invite me to your server.",
        ];
        message.author.sendMessage(help);
        console.log(`Help sent!`);
    }

    if (message.content.startsWith(prefix + "connections")) {
        message.channel.sendMessage(`Currently playing music in **${mybot.voiceConnections.size}** voice channels!`);
    }

    if (message.content.startsWith(prefix + "servers")) {
        message.channel.sendMessage(`On **${mybot.guilds.size}** servers!`)
    }

    if (message.content === prefix + "invite") {
        message.channel.sendMessage(`Feel free to invite me using this: ${oauth}`)
    }

  /*  if (message.content.startsWith(prefix + "addsong")) {
		const connections = new Map();
      const connectionData = connections.get(message.guild.id);
     // const queue = connectionData.queue;
        let url = message.content.replace(prefix + "addsong ", "");
        if (!url) return message.reply("no_entry_sign: Please specify a song for me to add to your playlist!")
        yt.getInfo(url, (err) => {
            if (err) return message.reply(":no_entry_sign: It seems like the song you tried to submit is invalid. You can **only** add YouTube video links!\n\n" + err);
        });
        let data = JSON.parse(fs.readFileSync('./Toasty/spotify.json'));
        if (!data[message.author.id]) data[message.author.id] = {
            songs: []
        };
        data[message.author.id].songs.push(url);
        let updateValue = JSON.stringify(data, null, 2);
        fs.writeFileSync('./Toasty/spotify.json', updateValue);
        yt.getInfo(url, function(err, info) {
            if (err) return message.reply(":no_entry_sign: Something went wrong:\n" + err);
            message.reply("I have added the song: **" + info.title + `** to your playlist`);
        });
    }*/

    if (message.content === prefix + "restart") {
        if (!message.author.id === '193378071141810176') return;
        if (!message.author.id === '138431969418543104') return;
        //Gotcha Toasty ;)
        message.channel.sendMessage("```css\nRestarting...```");
        console.log("Restarting...");
        setTimeout(function() {
            console.log(process.exit(0));
        }, 400);
    }

    //end message event
});

mybot.login(token);
<commit_msg>Delete text.js<commit_after><|endoftext|>


<commit_before>var headLimb;
var torso;
var LShoulderLimb, LUpperArmLimb, LLowerArmLimb;
var RShoulderLimb, RUpperArmLimb, RLowerArmLimb;
var leftUpperLeg;
var leftLowerLeg;
var rightUpperLeg;
var rightLowerLeg;
var body = [];

function setup() {
  createCanvas(windowWidth, windowHeight);
  noStroke();

  // body = [
  // neckLimb = new StLimb("Neck", 0, 40, 100, 90, 90),
  // headLimb = new StLimb("Head", 50, 100, 100, 200, 340, neckLimb),
  // torso = new StLimb("Torso", 200, 100, 100, 90, 90, neckLimb),
  // RShoulderLimb = new StLimb("R \nShoulder", 50, 0, 0, -20, 20, neckLimb),
  // RUpperArmLimb = new StLimb("R\n Upper Arm", 50, 0, 0, -180, 180, RShoulderLimb),
  // RLowerArmLimb = new BendLimb("R \nLower Arm", 50, 0, 0, 0, 90, RUpperArmLimb),
  // LShoulderLimb = new BendLimb("L \nShoulder", 50, 0, 0, 180 - 20, 180 + 20, neckLimb),
  // LUpperArmLimb = new BendLimb("L \nUpper Arm", -50, 10, 0, -10, 90, LShoulderLimb),
  // LLowerArmLimb = new BendLimb("L \nLower Arm", -50, 10, 0, -10, 90, LUpperArmLimb),
  // Lthight = new BendLimb('L thigh', -70, 20, -40, -20, 0, torso),
  // Rthight = new BendLimb('R thigh', 70, 20, -40, -20, 0, torso),
  // Lshin = new BendLimb('L knee', -70, 20, -40, -20, 0, Lthight),
  // Rshin = new BendLimb('R knee', 70, 20, -40, -20, 0, Rthight)
  // ];

  neckLimb = new StLimb("Neck", 0, 40, 100, 90, 90);
  headLimb = new StLimb("Head", 50, 100, 100, 200, 340, neckLimb);
  torso = new StLimb("Torso", 200, 100, 100, 90, 90, neckLimb);
  RShoulderLimb = new StLimb("R \nShoulder", 50, 0, 0, -20, 20, neckLimb);
  RUpperArmLimb = new StLimb("R\n Upper Arm", 50, 0, 0, -180, 180, RShoulderLimb);
  RLowerArmLimb = new BendLimb("R \nLower Arm", 50, 0, 0, 0, 90, RUpperArmLimb);
  LShoulderLimb = new BendLimb("L \nShoulder", 50, 0, 0, 180 - 20, 180 + 20, neckLimb);
  LUpperArmLimb = new BendLimb("L \nUpper Arm", -50, 10, 0, -10, 90, LShoulderLimb);
  LLowerArmLimb = new BendLimb("L \nLower Arm", -50, 10, 0, -10, 90, LUpperArmLimb);
  Lthight = new BendLimb('L thigh', -70, 20, -40, -20, 0, torso);
  Rthight = new BendLimb('R thigh', 70, 20, -40, -20, 0, torso);
  Lshin = new BendLimb('L knee', -70, 20, -40, -20, 0, Lthight);
  Rshin = new BendLimb('R knee', 70, 20, -40, -20, 0, Rthight);

  // body.push([neckLimb, headLimb,torso]);
  // console.log(body)
}

function draw() {
  background(255);

  if (mouseIsPressed) {
    neckLimb.startJointX = mouseX;
    neckLimb.startJointY = mouseY;
  }

  neckLimb.draw();
  headLimb.draw();
  torso.draw();
  RShoulderLimb.draw();
  LShoulderLimb.draw();
  RUpperArmLimb.draw();
  RLowerArmLimb.draw();
  LUpperArmLimb.draw();
  LLowerArmLimb.draw();
  Lthight.draw();
  Rthight.draw();
  Lshin.draw();
  Rshin.draw();
}

// Construct a limb, it will be the length staring at the start joing position, towards the end joint position, not to exceed the min and max degree parameters
var StLimb = function(_label, _length, _startJointX, _startJointY,
  _startJointMinDegrees, _startJointMaxDegrees, _parentEnd) {
  this.label = _label;
  this.limbLength = _length; // In pixels, angled off startJoint
  this.parentEnd = _parentEnd;
  this.startJointX = _startJointX;
  this.startJointY = _startJointY;
  this.startJointMinDegrees = _startJointMinDegrees;
  this.startJointMaxDegrees = _startJointMaxDegrees;

  this.update((this.startJointMinDegrees + this.startJointMaxDegrees) / 2);
  //start at the average
  //if reaches beyond min or max, equals min max
}

StLimb.prototype.update = function(_currentDegrees) {
  if (typeof _currentDegrees != "undefined") {
    this.currentDegrees = _currentDegrees;
  }

  if (typeof this.parentEnd !== 'undefined' || this.parentEnd != null) { //if it exists
    this.startJointX = this.parentEnd.endJointX; //start this joint at the parent's end
    this.startJointY = this.parentEnd.endJointY;
  }

  this.endJointX = this.startJointX + cos(radians(this.currentDegrees)) * this.limbLength;
  this.endJointY = this.startJointY + sin(radians(this.currentDegrees)) * this.limbLength;

  //dont go beyond min and max
  if (this.currentDegrees < this.startJointMinDegrees) {
    this.currentDegrees = this.currentDegrees;
  }
  if (this.currentDegrees > this.startJointMaxDegrees) {
    this.currentDegrees = this.currentDegrees;
  }

}

StLimb.prototype.draw = function() {
  this.update();

  //print("line("+this.startJointX+", "+this.startJointY+", "+this.endJointX+", "+this.endJointY+")");
  stroke(0);
  fill(0, 255, 0); //green at start
  ellipse(this.startJointX, this.startJointY, 10, 10);
  line(this.startJointX, this.startJointY, this.endJointX, this.endJointY);
  fill(255, 0, 0); //red to end
  ellipse(this.endJointX, this.endJointY, 10, 10);
  text(this.label, this.endJointX, this.endJointY + 10);
}

//////CONSTRUCTOR OF A BEND LIMB//////////////
//////////2 BONES AND A JOINT ///////////////
// Construct a limb, it will be the length staring at the start joing position, towards the end joint position, not to exceed the min and max degree parameters
var BendLimb = function(_label, _length, _startJointX, _startJointY,
  _startJointMinDegrees, _startJointMaxDegrees, _parentEnd) {
  this.label = _label;
  this.limbLength = _length; // In pixels, angled off startJoint
  this.parentEnd = _parentEnd;
  this.startJointX = _startJointX;
  this.startJointY = _startJointY;
  this.startJointMinDegrees = _startJointMinDegrees;
  this.startJointMaxDegrees = _startJointMaxDegrees;
  this.elbowX;
  this.elbowY;

  this.update((this.startJointMinDegrees + this.startJointMaxDegrees) / 2);

}

BendLimb.prototype.dJoints = function(parentEnd, leaderPt) {
  return dist(parentEnd.x, parentEnd.y, leaderPt.x, leaderPt.y);
}

BendLimb.prototype.update = function(_currentDegrees) {
  if (typeof _currentDegrees != "undefined") {
    this.currentDegrees = _currentDegrees;
  }

  if (typeof this.parentEnd !== 'undefined' || this.parentEnd != null) { //if it exists
    this.startJointX = this.parentEnd.endJointX; //start this joint at the parent's end
    this.startJointY = this.parentEnd.endJointY;
  }

  this.endJointX = this.startJointX + cos(radians(this.currentDegrees)) * this.limbLength;
  this.endJointY = this.startJointY + sin(radians(this.currentDegrees)) * this.limbLength;

  //dont go beyond min and max
  if (this.currentDegrees < this.startJointMinDegrees) {
    this.currentDegrees = this.currentDegrees;
  }
  if (this.currentDegrees > this.startJointMaxDegrees) {
    this.currentDegrees = this.currentDegrees;
  }

}

BendLimb.prototype.draw = function() {
  this.update();
  fill(255, 0, 0); //red
  noStroke();
  rect(this.x, this.y, 20, 20);
  strokeWeight(5);
  stroke(0)
  line(this.startJointX, this.startJointY, this.elbowX, this.elbowY); //draw a line from this x,y to
  noStroke();
  text(this.label, this.endJointX, this.endJointY + 10);
}

BendLimb.prototype.linkStart = function(leaderPt) {
  var distance = dJoints(this, leaderPt);
  console.log("distance of joints" + dJoints(forearm, leaderPt))

  var a = (Math.pow(this.limbLength, 2) - Math.pow(this.limbLength, 2) + Math.pow(distance, 2) / (2 * distance));
  var h = Math.sqrt(Math.pow(this.limbLength, 2) - Math.pow(a, 2));

  var px = this.startJointX + a * (leaderPt.x - this.startJointX) / distance;
  var py = this.startJointY + a * (leaderPt.y - this.startJointY) / distance;

  // fill(0);
  // noStroke();
  // text('P', px, py - 6);
  // ellipse(px, py, 5, 5);

  this.elbowX = px + h * (leaderPt.y - this.startJointY) / distance;
  this.elbowY = py - h * (leaderPt.x - this.startJointX) / distance;

  // this.draw();//can I just call this here?
}<commit_msg>skeleton<commit_after>var headLimb;
var torso;
var LShoulderLimb, LUpperArmLimb, LLowerArmLimb;
var RShoulderLimb, RUpperArmLimb, RLowerArmLimb;
var leftUpperLeg;
var leftLowerLeg;
var rightUpperLeg;
var rightLowerLeg;
var body = [];

function setup() {
  createCanvas(windowWidth, windowHeight);
  noStroke();

  // body = [
  // neckLimb = new StLimb("Neck", 0, 40, 100, 90, 90),
  // headLimb = new StLimb("Head", 50, 100, 100, 200, 340, neckLimb),
  // torso = new StLimb("Torso", 200, 100, 100, 90, 90, neckLimb),
  // RShoulderLimb = new StLimb("R \nShoulder", 50, 0, 0, -20, 20, neckLimb),
  // RUpperArmLimb = new StLimb("R\n Upper Arm", 50, 0, 0, -180, 180, RShoulderLimb),
  // RLowerArmLimb = new BendLimb("R \nLower Arm", 50, 0, 0, 0, 90, RUpperArmLimb),
  // LShoulderLimb = new BendLimb("L \nShoulder", 50, 0, 0, 180 - 20, 180 + 20, neckLimb),
  // LUpperArmLimb = new BendLimb("L \nUpper Arm", -50, 10, 0, -10, 90, LShoulderLimb),
  // LLowerArmLimb = new BendLimb("L \nLower Arm", -50, 10, 0, -10, 90, LUpperArmLimb),
  // Lthight = new BendLimb('L thigh', -70, 20, -40, -20, 0, torso),
  // Rthight = new BendLimb('R thigh', 70, 20, -40, -20, 0, torso),
  // Lshin = new BendLimb('L knee', -70, 20, -40, -20, 0, Lthight),
  // Rshin = new BendLimb('R knee', 70, 20, -40, -20, 0, Rthight)
  // ];

  neckLimb = new StLimb("Neck", 0, 40, 100, 90, 90);
  headLimb = new StLimb("Head", 50, 100, 100, 200, 340, neckLimb);
  torso = new StLimb("Torso", 200, 100, 100, 90, 90, neckLimb);
  RShoulderLimb = new StLimb("R \nShoulder", 50, 0, 0, -20, 20, neckLimb);
  RUpperArmLimb = new StLimb("R\n Upper Arm", 50, 0, 0, -180, 180, RShoulderLimb);
  RLowerArmLimb = new BendLimb("R \nLower Arm", 50, 0, 0, 0, 90, RUpperArmLimb);
  LShoulderLimb = new BendLimb("L \nShoulder", 50, 0, 0, 180 - 20, 180 + 20, neckLimb);
  LUpperArmLimb = new BendLimb("L \nUpper Arm", -50, 10, 0, -10, 90, LShoulderLimb);
  LLowerArmLimb = new BendLimb("L \nLower Arm", -50, 10, 0, -10, 90, LUpperArmLimb);
  Lthight = new BendLimb('L thigh', -70, 20, -40, -20, 0, torso);
  Rthight = new BendLimb('R thigh', 70, 20, -40, -20, 0, torso);
  Lshin = new BendLimb('L knee', -70, 20, -40, -20, 0, Lthight);
  Rshin = new BendLimb('R knee', 70, 20, -40, -20, 0, Rthight);

  // body.push([neckLimb, headLimb,torso,RShoulderLimb,LShoulderLimb,LUpperArmLimb,LLowerArmLimb,Lthight,Rthight,Lshin,Rshin]);
  // console.log(body)
}

function draw() {
  background(255);

  if (mouseIsPressed) {
    neckLimb.startJointX = mouseX;
    neckLimb.startJointY = mouseY;
  }

  neckLimb.draw();
  headLimb.draw();
  torso.draw();
  RShoulderLimb.draw();
  LShoulderLimb.draw();
  RUpperArmLimb.draw();
  RLowerArmLimb.draw();
  LUpperArmLimb.draw();
  LLowerArmLimb.draw();
  Lthight.draw();
  Rthight.draw();
  Lshin.draw();
  Rshin.draw();
}

// Construct a static limb, it will be the length staring at the start joing position, towards the end joint position, not to exceed the min and max degree parameters
var StLimb = function(_label, _length, _startJointX, _startJointY,
  _startJointMinDegrees, _startJointMaxDegrees, _parentEnd) {
  this.label = _label;
  this.limbLength = _length; // In pixels, angled off startJoint
  this.parentEnd = _parentEnd;
  this.startJointX = _startJointX;
  this.startJointY = _startJointY;
  this.startJointMinDegrees = _startJointMinDegrees;
  this.startJointMaxDegrees = _startJointMaxDegrees;

  this.update((this.startJointMinDegrees + this.startJointMaxDegrees) / 2);
  //start at the average
  //if reaches beyond min or max, equals min max
}

StLimb.prototype.update = function(_currentDegrees) {
  if (typeof _currentDegrees != "undefined") {
    this.currentDegrees = _currentDegrees;
  }

  if (typeof this.parentEnd !== 'undefined' || this.parentEnd != null) { //if it exists
    this.startJointX = this.parentEnd.endJointX; //start this joint at the parent's end
    this.startJointY = this.parentEnd.endJointY;
  }

  this.endJointX = this.startJointX + cos(radians(this.currentDegrees)) * this.limbLength;
  this.endJointY = this.startJointY + sin(radians(this.currentDegrees)) * this.limbLength;

  //dont go beyond min and max
  if (this.currentDegrees < this.startJointMinDegrees) {
    this.currentDegrees = this.currentDegrees;
  }
  if (this.currentDegrees > this.startJointMaxDegrees) {
    this.currentDegrees = this.currentDegrees;
  }

}

StLimb.prototype.draw = function() {
  this.update();

  //print("line("+this.startJointX+", "+this.startJointY+", "+this.endJointX+", "+this.endJointY+")");
  stroke(0);
  fill(0, 255, 0); //green at start
  ellipse(this.startJointX, this.startJointY, 10, 10);
  line(this.startJointX, this.startJointY, this.endJointX, this.endJointY);
  fill(255, 0, 0); //red to end
  ellipse(this.endJointX, this.endJointY, 10, 10);
  text(this.label, this.endJointX, this.endJointY + 10);
}

//////CONSTRUCTOR OF A BEND LIMB//////////////
//////////2 BONES AND A JOINT ///////////////
// Construct a limb, it will be the length staring at the start joing position, towards the end joint position, not to exceed the min and max degree parameters
var BendLimb = function(_label, _length, _startJointX, _startJointY,
  _startJointMinDegrees, _startJointMaxDegrees, _parentEnd) {
  this.label = _label;
  this.limbLength = _length; // In pixels, angled off startJoint
  this.parentEnd = _parentEnd;
  this.startJointX = _startJointX;
  this.startJointY = _startJointY;
  this.startJointMinDegrees = _startJointMinDegrees;
  this.startJointMaxDegrees = _startJointMaxDegrees;
  this.elbowX;
  this.elbowY;

  this.update((this.startJointMinDegrees + this.startJointMaxDegrees) / 2);//start at this degree

}

BendLimb.prototype.dJoints = function(parentEnd, leaderPt) {//whatever you feed it later
  return dist(parentEnd.x, parentEnd.y, leaderPt.x, leaderPt.y);
}

BendLimb.prototype.update = function(_currentDegrees) {
  if (typeof _currentDegrees != "undefined") {
    this.currentDegrees = _currentDegrees;
  }

  if (typeof this.parentEnd !== 'undefined' || this.parentEnd != null) { //if it exists
    this.startJointX = this.parentEnd.endJointX; //start this joint at the parent's end
    this.startJointY = this.parentEnd.endJointY;
  }

  this.endJointX = this.startJointX + cos(radians(this.currentDegrees)) * this.limbLength;
  this.endJointY = this.startJointY + sin(radians(this.currentDegrees)) * this.limbLength;

  //dont go beyond min and max
  if (this.currentDegrees < this.startJointMinDegrees) {
    this.currentDegrees = this.currentDegrees;
  }
  if (this.currentDegrees > this.startJointMaxDegrees) {
    this.currentDegrees = this.currentDegrees;
  }

}

BendLimb.prototype.draw = function() {
  this.update();
  fill(255, 0, 0); //red
  noStroke();
  rect(this.x, this.y, 20, 20);
  strokeWeight(5);
  stroke(0)
  line(this.startJointX, this.startJointY, this.elbowX, this.elbowY); //draw a line from this x,y to
  noStroke();
  text(this.label, this.endJointX, this.endJointY + 10);
}

BendLimb.prototype.linkStart = function(leaderPt) {//where do I call this?
  var distance = dJoints(this, leaderPt);//itself to what you pass it later. Where do I pass this?
  // console.log("distance of joints" + dJoints(this.parentEnd, leaderPt))

  var a = (Math.pow(this.limbLength, 2) - Math.pow(this.limbLength, 2) + Math.pow(distance, 2) / (2 * distance));
  var h = Math.sqrt(Math.pow(this.limbLength, 2) - Math.pow(a, 2));

  var px = this.startJointX + a * (leaderPt.x - this.startJointX) / distance;
  var py = this.startJointY + a * (leaderPt.y - this.startJointY) / distance;

  this.elbowX = px + h * (leaderPt.y - this.startJointY) / distance;
  this.elbowY = py - h * (leaderPt.x - this.startJointX) / distance;

  // this.draw();//can I just call this here?
}

BendLimb.prototype.linkEnd = function(leaderPt) {//where do I call this?
  var distance = -dJoints(this, leaderPt);//itself to what you pass it later. Where do I pass this?
  // console.log("distance of joints" + dJoints(this.parentEnd, leaderPt))

  var a = (Math.pow(this.limbLength, 2) - Math.pow(this.limbLength, 2) + Math.pow(distance, 2) / (2 * distance));
  var h = Math.sqrt(Math.pow(this.limbLength, 2) - Math.pow(a, 2));

  var px = this.startJointX + a * (leaderPt.x - this.startJointX) / distance;
  var py = this.startJointY + a * (leaderPt.y - this.startJointY) / distance;

  this.elbowX = px + h * (leaderPt.y - this.startJointY) / distance;
  this.elbowY = py - h * (leaderPt.x - this.startJointX) / distance;

  // this.draw();//can I just call this here?
}<|endoftext|>


<commit_before>window.addEventListener('load', function(){

  var GAME_WIDTH = 640;
  var GAME_HEIGHT = 360;

  var enemies = [
    {
      x: 100, //x coordinate
      y: 100, //y coordinate
      speedY: 1, //speed in Y
      speedX: 2,
      w: 40, //width
      h: 40 //heght
    },
    {
      x: 260,
      y: 100,
      speedY: 2,
      speedX: 1,
      w: 40,
      h: 40
    },
    {
      x: 380,
      y: 100,
      speedY: 2,
      speedX: 4,
      w: 40,
      h: 40
    }
  ];

  var player = {
    x:10,
    y:160,
    speedX: 3,
    w: 20,
    h:20,
    isMoving: false
  }

  var movePlayer = function(){
    player.isMoving = true;
  }

  var stopPlayer = function(){
    player.isMoving = false;
  }

  var canvas = document.getElementById("myCanvas");
  var ctx = canvas.getContext("2d");
  canvas.addEventListener("mousedown", movePlayer);
  canvas.addEventListener("mouseup", stopPlayer);
  canvas.addEventListener("touchstart", movePlayer);
  canvas.addEventListener("touchend", stopPlayer)

  var update = function() {

    if(player.isMoving){
      player.x += player.speedX;
    }

    enemies.forEach(function(element, index){
      element.y += element.speedY;
      element.x += element.speedX;

      if(element.y <= 10) {
        element.y = 10;
        element.speedY *= -1;
      }
      else if(element.y >= GAME_HEIGHT - 50) {
        element.y = GAME_HEIGHT - 50;
        element.speedY *= -1;
      }

      if(element.x <= 10) {
        element.x = 10;
        element.speedX *= -1;
      }
      else if(element.x >= GAME_WIDTH - 50) {
        element.x = GAME_WIDTH - 50;
        element.speedX *= -1;
      }
    });
  };

  var draw = function() {
    ctx.clearRect(0,0,GAME_WIDTH,GAME_HEIGHT);

    ctx.fillStyle = "blue"
    ctx.fillRect(player.x,player.y,player.w,player.h)

    ctx.fillStyle = "orange";
    enemies.forEach(function(element, index){
      ctx.fillRect(element.x, element.y, element.w, element.h);
    });
  };

  var step = function() {

    update();
    draw();

    window.requestAnimationFrame(step);
  };

  step();
});<commit_msg>add collision<commit_after>window.addEventListener('load', function(){

  var GAME_WIDTH = 640;
  var GAME_HEIGHT = 360;
  var gameLive = true;

  var enemies = [
    {
      x: 100, //x coordinate
      y: 100, //y coordinate
      speedY: 1, //speed in Y
      speedX: 2,
      w: 40, //width
      h: 40 //heght
    },
    {
      x: 260,
      y: 100,
      speedY: 2,
      speedX: 1,
      w: 40,
      h: 40
    },
    {
      x: 380,
      y: 100,
      speedY: 2,
      speedX: 4,
      w: 40,
      h: 40
    }
  ];

  var player = {
    x:10,
    y:160,
    speedX: 3,
    w: 20,
    h:20,
    isMoving: false
  }

  var movePlayer = function(){
    player.isMoving = true;
  }

  var stopPlayer = function(){
    player.isMoving = false;
  }

  var canvas = document.getElementById("myCanvas");
  var ctx = canvas.getContext("2d");
  canvas.addEventListener("mousedown", movePlayer);
  canvas.addEventListener("mouseup", stopPlayer);
  canvas.addEventListener("touchstart", movePlayer);
  canvas.addEventListener("touchend", stopPlayer)

  var update = function() {

    if(player.isMoving){
      player.x += player.speedX;
    }

    enemies.forEach(function(element, index){

      if(checkCollision(player, element)){

        gameLive = false;

        alert('Game Over');

        window.location = ""; // this reloads page

      }

      element.y += element.speedY;
      element.x += element.speedX;

      if(element.y <= 10) {
        element.y = 10;
        element.speedY *= -1;
      }
      else if(element.y >= GAME_HEIGHT - 50) {
        element.y = GAME_HEIGHT - 50;
        element.speedY *= -1;
      }

      if(element.x <= 10) {
        element.x = 10;
        element.speedX *= -1;
      }
      else if(element.x >= GAME_WIDTH - 50) {
        element.x = GAME_WIDTH - 50;
        element.speedX *= -1;
      }
    });
  };

  var draw = function() {
    ctx.clearRect(0,0,GAME_WIDTH,GAME_HEIGHT);

    ctx.fillStyle = "blue"
    ctx.fillRect(player.x,player.y,player.w,player.h)

    ctx.fillStyle = "orange";
    enemies.forEach(function(element, index){
      ctx.fillRect(element.x, element.y, element.w, element.h);
    });
  };

  var step = function() {

    update();
    draw();

    if(gameLive){
      window.requestAnimationFrame(step);
    }
  };

  var checkCollision = function(rect1,rect2){
    var closeOnWidth = Math.abs(rect1.x - rect2.x) <= Math.max(rect1.w, rect2.w);
    var closeOnHeight = Math.abs(rect1.y - rect2.y) <= Math.max(rect1.h, rect2.h);

    return closeOnHeight && closeOnWidth
  }
  step();
});<|endoftext|>


<commit_before>/*!
 * QUnit CLI Boilerplate v1.3.0
 * Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
 * Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
 * Available under MIT license <http://mths.be/mit>
 */
;(function(root) {
  'use strict';

  /** Detect free variable `exports` */
  var freeExports = typeof exports == 'object' && exports;

  /** Detect free variable `global`, from Node.js or Browserified code, and use it as `root` */
  var freeGlobal = typeof global == 'object' && global;
  if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
    root = freeGlobal;
  }

  /*--------------------------------------------------------------------------*/

  /**
   * Installs the CLI boilerplate additions on the given `context` object.
   *
   * @memberOf exports
   * @param {Object} context The context object.
   */
  function runInContext(context) {
    // exit early if no `context` is provided or if `QUnit` does not exist
    if (!context || !context.QUnit) {
      return;
    }

    /**
     * Schedules timer-based callbacks.
     *
     * @private
     * @param {Function|string} fn The function to call.
     * @param {number} delay The number of milliseconds to delay the `fn` call.
     * @param [arg1, arg2, ...] Arguments to invoke `fn` with.
     * @param {boolean} repeated A flag to specify whether `fn` is called repeatedly.
     * @returns {number} The the ID of the timeout.
     */
    function schedule(fn, delay, args, repeated) {
      // Rhino 1.7RC4 will error assigning `task` below
      // https://bugzilla.mozilla.org/show_bug.cgi?id=775566
      var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
        'run': function() {
          fn.apply(context, args);
        }
      });
      // support non-functions
      if (typeof fn != 'function') {
        fn = (function(code) {
          code = String(code);
          return function() { eval(code); };
        }(fn));
      }
      // used by setInterval
      if (repeated) {
        timer.schedule(task, delay, delay);
      }
      // used by setTimeout
      else {
        timer.schedule(task, delay);
      }
      return counter;
    }

    /**
     * Clears the delay set by `setInterval` or `setTimeout`.
     *
     * @memberOf context
     * @param {number} id The ID of the timeout to be cleared.
     */
    function clearTimer(id) {
      if (ids[id]) {
        ids[id].cancel();
        timer.purge();
        delete ids[id];
      }
    }

    /**
     * Executes a code snippet or function repeatedly, with a delay between each call.
     *
     * @memberOf context
     * @param {Function|string} fn The function to call or string to evaluate.
     * @param {number} delay The number of milliseconds to delay each `fn` call.
     * @param [arg1, arg2, ...] Arguments to invoke `fn` with.
     * @returns {number} The the ID of the timeout.
     */
    function setInterval(fn, delay) {
      return schedule(fn, delay, slice.call(arguments, 2), true);
    }

    /**
     * Executes a code snippet or a function after specified delay.
     *
     * @memberOf context
     * @param {Function|string} fn The function to call or string to evaluate.
     * @param {number} delay The number of milliseconds to delay the `fn` call.
     * @param [arg1, arg2, ...] Arguments to invoke `fn` with.
     * @returns {number} The the ID of the timeout.
     */
    function setTimeout(fn, delay) {
      return schedule(fn, delay, slice.call(arguments, 2));
    }

    /*------------------------------------------------------------------------*/

    /** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
    var console = context.console || (context.console = { 'log': context.print });

    /** Shorten `context.QUnit.QUnit` to `context.QUnit` */
    var QUnit = context.QUnit = context.QUnit.QUnit || context.QUnit;

    /** Used as a horizontal rule in console output */
    var hr = '----------------------------------------';

    /**
     * A logging callback triggered when all testing is completed.
     *
     * @memberOf QUnit
     * @param {Object} details An object with properties `failed`, `passed`, `runtime`, and `total`.
     */
    QUnit.done(function() {
      var ran;
      return function(details) {
        // stop `asyncTest()` from erroneously calling `done()` twice in
        // environments w/o timeouts
        if (ran) {
          return;
        }
        ran = true;

        console.log(hr);
        console.log('    PASS: ' + details.passed + '  FAIL: ' + details.failed + '  TOTAL: ' + details.total);
        console.log('    Finished in ' + details.runtime + ' milliseconds.');
        console.log(hr);

        // exit out of Narhwal, Rhino, or Ringo
        try {
          quit();
        } catch(e) { }

        // exit out of Node.js or PhantomJS
        try {
          var process = context.process || context.phantom;
          if (details.failed) {
            console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.');
            process.exit(1);
          } else {
            process.exit(0);
          }
        } catch(e) { }
      };
    }());

    /**
     * A logging callback triggered after every assertion.
     *
     * @memberOf QUnit
     * @param {Object} details An object with properties `actual`, `expected`, `message`, and `result`.
     */
    QUnit.log(function(details) {
      var expected = details.expected,
          result = details.result,
          type = typeof expected != 'undefined' ? 'EQ' : 'OK';

      var assertion = [
        result ? 'PASS' : 'FAIL',
        type,
        details.message || 'ok'
      ];

      if (!result && type == 'EQ') {
        assertion.push('Expected: ' + expected + ', Actual: ' + details.actual);
      }
      QUnit.config.testStats.assertions.push(assertion.join(' | '));
    });

    /**
     * A logging callback triggered at the start of every test module.
     *
     * @memberOf QUnit
     * @param {Object} details An object with property `name`.
     */
    QUnit.moduleStart(function(details) {
      console.log(hr);
      console.log(details.name);
      console.log(hr);
    });

    /**
     * Converts an object into a string representation.
     *
     * @memberOf QUnit
     * @type Function
     * @param {Object} object The object to stringify.
     * @returns {string} The result string.
     */
    QUnit.jsDump.parsers.object = (function() {
      var func = QUnit.jsDump.parsers.object;
      return function(object) {
        // fork to support Rhino's error objects
        if (typeof object.rhinoException == 'object') {
          return object.name +
            ' { message: "' + object.message +
            '", fileName: "' + object.fileName +
            '", lineNumber: ' + object.lineNumber + ' }';
        }
        return func(object);
      };
    }());

    /**
     * A logging callback triggered after a test is completed.
     *
     * @memberOf QUnit
     * @param {Object} details An object with properties `failed`, `name`, `passed`, and `total`.
     */
    QUnit.testDone(function(details) {
      var assertions = QUnit.config.testStats.assertions,
          testName = details.name;

      if (details.failed > 0) {
        console.log(' FAIL - '+ testName);
        assertions.forEach(function(value) {
          console.log('    ' + value);
        });
      }
      else {
        console.log(' PASS - ' + testName);
      }
      assertions.length = 0;
    });

    /**
     * An object used to hold information about the current running test.
     *
     * @memberOf QUnit.config
     * @type Object
     */
    QUnit.config.testStats = {

      /**
       * An array of test summaries (pipe separated).
       *
       * @memberOf QUnit.config.testStats
       * @type Array
       */
      'assertions': []
    };

    /*------------------------------------------------------------------------*/

    // Timeout fallbacks based on the work of Andrea Giammarchi and Weston C.
    // https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js
    // http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
    try {
      var counter = 0,
          ids = {},
          slice = Array.prototype.slice,
          timer = new java.util.Timer;

      context.clearInterval =
      context.clearTimeout = clearTimer;
      context.setInterval = setInterval;
      context.setTimeout = setTimeout;
    } catch(e) { }

    // expose shortcuts
    // exclude `module` because some environments have it as a built-in object
    ('asyncTest deepEqual equal equals expect notDeepEqual notEqual notStrictEqual ' +
     'ok raises same start stop strictEqual test throws').replace(/\S+/g, function(methodName) {
      context[methodName] = QUnit[methodName];
    });

    // must call `QUnit.start()` in the test file if not loaded in a browser
    if (!context.document || context.phantom) {
      QUnit.config.autostart = false;
      QUnit.init();
    }
  }

  /*--------------------------------------------------------------------------*/

  // expose QUnit CLIB
  if (freeExports && !freeExports.nodeType) {
    freeExports.runInContext = runInContext;
  } else {
    runInContext(root);
  }
}(this));
<commit_msg>Make qunit-clib less chatty for passed tests.<commit_after>/*!
 * QUnit CLI Boilerplate v1.3.0
 * Copyright 2011-2012 John-David Dalton <http://allyoucanleet.com/>
 * Based on a gist by Jörn Zaefferer <https://gist.github.com/722381>
 * Available under MIT license <http://mths.be/mit>
 */
;(function(root) {
  'use strict';

  /** Detect free variable `exports` */
  var freeExports = typeof exports == 'object' && exports;

  /** Detect free variable `global`, from Node.js or Browserified code, and use it as `root` */
  var freeGlobal = typeof global == 'object' && global;
  if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
    root = freeGlobal;
  }

  /*--------------------------------------------------------------------------*/

  /**
   * Installs the CLI boilerplate additions on the given `context` object.
   *
   * @memberOf exports
   * @param {Object} context The context object.
   */
  function runInContext(context) {
    // exit early if no `context` is provided or if `QUnit` does not exist
    if (!context || !context.QUnit) {
      return;
    }

    /**
     * Schedules timer-based callbacks.
     *
     * @private
     * @param {Function|string} fn The function to call.
     * @param {number} delay The number of milliseconds to delay the `fn` call.
     * @param [arg1, arg2, ...] Arguments to invoke `fn` with.
     * @param {boolean} repeated A flag to specify whether `fn` is called repeatedly.
     * @returns {number} The the ID of the timeout.
     */
    function schedule(fn, delay, args, repeated) {
      // Rhino 1.7RC4 will error assigning `task` below
      // https://bugzilla.mozilla.org/show_bug.cgi?id=775566
      var task = ids[++counter] = new JavaAdapter(java.util.TimerTask, {
        'run': function() {
          fn.apply(context, args);
        }
      });
      // support non-functions
      if (typeof fn != 'function') {
        fn = (function(code) {
          code = String(code);
          return function() { eval(code); };
        }(fn));
      }
      // used by setInterval
      if (repeated) {
        timer.schedule(task, delay, delay);
      }
      // used by setTimeout
      else {
        timer.schedule(task, delay);
      }
      return counter;
    }

    /**
     * Clears the delay set by `setInterval` or `setTimeout`.
     *
     * @memberOf context
     * @param {number} id The ID of the timeout to be cleared.
     */
    function clearTimer(id) {
      if (ids[id]) {
        ids[id].cancel();
        timer.purge();
        delete ids[id];
      }
    }

    /**
     * Executes a code snippet or function repeatedly, with a delay between each call.
     *
     * @memberOf context
     * @param {Function|string} fn The function to call or string to evaluate.
     * @param {number} delay The number of milliseconds to delay each `fn` call.
     * @param [arg1, arg2, ...] Arguments to invoke `fn` with.
     * @returns {number} The the ID of the timeout.
     */
    function setInterval(fn, delay) {
      return schedule(fn, delay, slice.call(arguments, 2), true);
    }

    /**
     * Executes a code snippet or a function after specified delay.
     *
     * @memberOf context
     * @param {Function|string} fn The function to call or string to evaluate.
     * @param {number} delay The number of milliseconds to delay the `fn` call.
     * @param [arg1, arg2, ...] Arguments to invoke `fn` with.
     * @returns {number} The the ID of the timeout.
     */
    function setTimeout(fn, delay) {
      return schedule(fn, delay, slice.call(arguments, 2));
    }

    /*------------------------------------------------------------------------*/

    /** Used to report the test module for failing tests */
    var moduleName,
        modulePrinted;

    /** Add `console.log()` support for Narwhal, Rhino, and RingoJS */
    var console = context.console || (context.console = { 'log': context.print });

    /** Used as a horizontal rule in console output */
    var hr = '----------------------------------------';

    /** Shorten `context.QUnit.QUnit` to `context.QUnit` */
    var QUnit = context.QUnit = context.QUnit.QUnit || context.QUnit;

    /**
     * A logging callback triggered when all testing is completed.
     *
     * @memberOf QUnit
     * @param {Object} details An object with properties `failed`, `passed`, `runtime`, and `total`.
     */
    QUnit.done(function() {
      var ran;
      return function(details) {
        // stop `asyncTest()` from erroneously calling `done()` twice in
        // environments w/o timeouts
        if (ran) {
          return;
        }
        ran = true;

        console.log(hr);
        console.log('    PASS: ' + details.passed + '  FAIL: ' + details.failed + '  TOTAL: ' + details.total);
        console.log('    Finished in ' + details.runtime + ' milliseconds.');
        console.log(hr);

        // exit out of Narhwal, Rhino, or Ringo
        try {
          quit();
        } catch(e) { }

        // exit out of Node.js or PhantomJS
        try {
          var process = context.process || context.phantom;
          if (details.failed) {
            console.error('Error: ' + details.failed + ' of ' + details.total + ' tests failed.');
            process.exit(1);
          } else {
            process.exit(0);
          }
        } catch(e) { }
      };
    }());

    /**
     * A logging callback triggered after every assertion.
     *
     * @memberOf QUnit
     * @param {Object} details An object with properties `actual`, `expected`, `message`, and `result`.
     */
    QUnit.log(function(details) {
      var expected = details.expected,
          result = details.result,
          type = typeof expected != 'undefined' ? 'EQ' : 'OK';

      var assertion = [
        result ? 'PASS' : 'FAIL',
        type,
        details.message || 'ok'
      ];

      if (!result && type == 'EQ') {
        assertion.push('Expected: ' + expected + ', Actual: ' + details.actual);
      }
      QUnit.config.testStats.assertions.push(assertion.join(' | '));
    });

    /**
     * A logging callback triggered at the start of every test module.
     *
     * @memberOf QUnit
     * @param {Object} details An object with property `name`.
     */
    QUnit.moduleStart(function(details) {
      var newModuleName = details.name;
      if (moduleName != newModuleName) {
        moduleName = newModuleName;
        modulePrinted = false;
      }
    });

    /**
     * Converts an object into a string representation.
     *
     * @memberOf QUnit
     * @type Function
     * @param {Object} object The object to stringify.
     * @returns {string} The result string.
     */
    QUnit.jsDump.parsers.object = (function() {
      var func = QUnit.jsDump.parsers.object;
      return function(object) {
        // fork to support Rhino's error objects
        if (typeof object.rhinoException == 'object') {
          return object.name +
            ' { message: "' + object.message +
            '", fileName: "' + object.fileName +
            '", lineNumber: ' + object.lineNumber + ' }';
        }
        return func(object);
      };
    }());

    /**
     * A logging callback triggered after a test is completed.
     *
     * @memberOf QUnit
     * @param {Object} details An object with properties `failed`, `name`, `passed`, and `total`.
     */
    QUnit.testDone(function(details) {
      var assertions = QUnit.config.testStats.assertions,
          testName = details.name;

      if (details.failed > 0) {
        if (!modulePrinted) {
          modulePrinted = true;
          console.log(hr);
          console.log(moduleName);
          console.log(hr);
        }
        console.log(' FAIL - '+ testName);
        assertions.forEach(function(value) {
          console.log('    ' + value);
        });
      }
      assertions.length = 0;
    });

    /**
     * An object used to hold information about the current running test.
     *
     * @memberOf QUnit.config
     * @type Object
     */
    QUnit.config.testStats = {

      /**
       * An array of test summaries.
       *
       * @memberOf QUnit.config.testStats
       * @type Array
       */
      'assertions': []
    };

    /*------------------------------------------------------------------------*/

    // Timeout fallbacks based on the work of Andrea Giammarchi and Weston C.
    // https://github.com/WebReflection/wru/blob/master/src/rhinoTimers.js
    // http://stackoverflow.com/questions/2261705/how-to-run-a-javascript-function-asynchronously-without-using-settimeout
    try {
      var counter = 0,
          ids = {},
          slice = Array.prototype.slice,
          timer = new java.util.Timer;

      context.clearInterval =
      context.clearTimeout = clearTimer;
      context.setInterval = setInterval;
      context.setTimeout = setTimeout;
    } catch(e) { }

    // expose shortcuts
    // exclude `module` because some environments have it as a built-in object
    ('asyncTest deepEqual equal equals expect notDeepEqual notEqual notStrictEqual ' +
     'ok raises same start stop strictEqual test throws').replace(/\S+/g, function(methodName) {
      context[methodName] = QUnit[methodName];
    });

    // must call `QUnit.start()` in the test file if not loaded in a browser
    if (!context.document || context.phantom) {
      QUnit.config.autostart = false;
      QUnit.init();
    }
  }

  /*--------------------------------------------------------------------------*/

  // expose QUnit CLIB
  if (freeExports && !freeExports.nodeType) {
    freeExports.runInContext = runInContext;
  } else {
    runInContext(root);
  }
}(this));
<|endoftext|>


<commit_before>steal('jquery','jquery/dom/range').then(function($){
var convertType = function(type){
	return  type.replace(/([a-z])([a-z]+)/gi, function(all,first,  next){
			  return first+next.toLowerCase()
			}).replace(/_/g,"");
},
reverse = function(type){
	return type.replace(/^([a-z]+)_TO_([a-z]+)/i, function(all, first, last){
		return last+"_TO_"+first;
	});
},
getWindow = function( element ) {
	return element ? element.ownerDocument.defaultView || element.ownerDocument.parentWindow : window
},
// A helper that uses range to abstract out getting the current start and endPos.
getElementsSelection = function(el, win){
	var current = $.Range.current(el).clone(),
		entireElement = $.Range(el).select(el);
	if(!current.overlaps(entireElement)){
		return null;
	}
	// we need to check if it starts before our element ...
	if(current.compare("START_TO_START", entireElement) < 1){
		startPos = 0;
		// we should move current ...
		current.move("START_TO_START",entireElement);
	}else{
		fromElementToCurrent =entireElement.clone();
		fromElementToCurrent.move("END_TO_START", current);
		startPos = fromElementToCurrent.toString().length
	}

	// now we need to make sure current isn't to the right of us ...
	if(current.compare("END_TO_END", entireElement) >= 0){
		endPos = entireElement.toString().length
	}else{
		endPos = startPos+current.toString().length
	}
	return {
		start: startPos,
		end : endPos
	};
},
getSelection = function(el){
	// use selectionStart if we can.
	var win = getWindow(el);

	if (el.selectionStart !== undefined) {

		if(document.activeElement
		 	&& document.activeElement != el
			&& el.selectionStart == el.selectionEnd
			&& el.selectionStart == 0){
			return {start: el.value.length, end: el.value.length};
		}
		return  {start: el.selectionStart, end: el.selectionEnd}
	} else if(win.getSelection){
		return getElementsSelection(el, win)
	} else{

		try {
			//try 2 different methods that work differently
			// one should only work for input elements, but sometimes doesn't
			// I don't know why this is, or what to detect
			if (el.nodeName.toLowerCase() == 'input') {
				var real = getWindow(el).document.selection.createRange(), r = el.createTextRange();
				r.setEndPoint("EndToStart", real);

				var start = r.text.length
				return {
					start: start,
					end: start + real.text.length
				}
			}
			else {
				var res = getElementsSelection(el,win)
				if(!res){
					return res;
				}
				// we have to clean up for ie's textareas
				var current = $.Range.current().clone(),
					r2 = current.clone().collapse().range,
					r3 = current.clone().collapse(false).range;

				r2.moveStart('character', -1)
				r3.moveStart('character', -1)
				// if we aren't at the start, but previous is empty, we are at start of newline
				if (res.startPos != 0 && r2.text == "") {
					res.startPos += 2;
				}
				// do a similar thing for the end of the textarea
				if (res.endPos != 0 && r3.text == "") {
					res.endPos += 2;
				}

				return res
			}
		}catch(e){
			return {start: el.value.length, end: el.value.length};
		}
	}
},
select = function( el, start, end ) {
	var win = getWindow(el)
	if(el.setSelectionRange){
		if(end === undefined){
            el.focus();
            el.setSelectionRange(start, start);
		} else {
			el.select();
			el.selectionStart = start;
			el.selectionEnd = end;
		}
	} else if (el.createTextRange) {
		//el.focus();
		var r = el.createTextRange();
		r.moveStart('character', start);
		end = end || start;
		r.moveEnd('character', end - el.value.length);

		r.select();
	} else if(win.getSelection){
		var	doc = win.document,
			sel = win.getSelection(),
			range = doc.createRange(),
			ranges = [start,  end !== undefined ? end : start];
		getCharElement([el],ranges);
		range.setStart(ranges[0].el, ranges[0].count);
		range.setEnd(ranges[1].el, ranges[1].count);

		// removeAllRanges is suprisingly necessary for webkit ... BOOO!
        sel.removeAllRanges();
        sel.addRange(range);

	} else if(win.document.body.createTextRange){ //IE's weirdness
		var range = document.body.createTextRange();
		range.moveToElementText(el);
		range.collapse()
		range.moveStart('character', start)
		range.moveEnd('character', end !== undefined ? end : start)
        range.select();
	}

},
/*
 * If one of the range values is within start and len, replace the range
 * value with the element and its offset.
 */
replaceWithLess = function(start, len, range, el){
	if(typeof range[0] === 'number' && range[0] < len){
			range[0] = {
				el: el,
				count: range[0] - start
			};
	}
	if(typeof range[1] === 'number' && range[1] <= len){
			range[1] = {
				el: el,
				count: range[1] - start
			};;
	}
},
getCharElement = function( elems , range, len ) {
	var elem,
		start;

	len = len || 0;
	for ( var i = 0; elems[i]; i++ ) {
		elem = elems[i];
		// Get the text from text nodes and CDATA nodes
		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
			start = len
			len += elem.nodeValue.length;
			//check if len is now greater than what's in counts
			replaceWithLess(start, len, range, elem )
		// Traverse everything else, except comment nodes
		} else if ( elem.nodeType !== 8 ) {
			len = getCharElement( elem.childNodes, range, len );
		}
	}
	return len;
};
/**
 * @parent dom
 * @tag beta
 *
 * Gets or sets the current text selection.
 *
 * ## Getting
 *
 * Gets the current selection in the context of an element.  For example:
 *
 *     $('textarea').selection() // -> { .... }
 *
 * returns an object with:
 *
 *   - __start__ - The number of characters from the start of the element to the start of the selection.
 *   - __end__ - The number of characters from teh start of the element to the end of the selection.
 *   - __range__ - A [jQuery.Range $.Range] that represents the current selection.
 *
 * This lets you get the selected text in a textarea like:
 *
 *     var textarea = $('textarea')
 *       selection = textarea.selection(),
 *       selected = textarea.val().substr(selection.start, selection.end);
 *
 *     alert('You selected '+selected+'.');
 *
 * Selection works with all elements.  If you want to get selection information of the document:
 *
 *     $(document.body).selection();
 *
 * ## Setting
 *
 * By providing a start and end offset, you can select text within a given element.
 *
 *     $('#rte').selection(30, 40)
 *
 * ## Demo
 *
 * This demo shows setting the selection in various elements
 *
 * @demo jquery/dom/selection/selection.html
 *
 * @param {Number} [start] Start of the range
 * @param {Number} [end] End of the range
 * @return {Object|jQuery} returns the selection information or the jQuery collection for
 * chaining.
 */
$.fn.selection = function(start, end){
	if(start !== undefined){
		return this.each(function(){
			select(this, start, end)
		})
	}else{
		return getSelection(this[0])
	}
};
// for testing
$.fn.selection.getCharElement = getCharElement;

});<commit_msg>Spelling mistake in dom_selection.<commit_after>steal('jquery','jquery/dom/range').then(function($){
var convertType = function(type){
	return  type.replace(/([a-z])([a-z]+)/gi, function(all,first,  next){
			  return first+next.toLowerCase()
			}).replace(/_/g,"");
},
reverse = function(type){
	return type.replace(/^([a-z]+)_TO_([a-z]+)/i, function(all, first, last){
		return last+"_TO_"+first;
	});
},
getWindow = function( element ) {
	return element ? element.ownerDocument.defaultView || element.ownerDocument.parentWindow : window
},
// A helper that uses range to abstract out getting the current start and endPos.
getElementsSelection = function(el, win){
	var current = $.Range.current(el).clone(),
		entireElement = $.Range(el).select(el);
	if(!current.overlaps(entireElement)){
		return null;
	}
	// we need to check if it starts before our element ...
	if(current.compare("START_TO_START", entireElement) < 1){
		startPos = 0;
		// we should move current ...
		current.move("START_TO_START",entireElement);
	}else{
		fromElementToCurrent =entireElement.clone();
		fromElementToCurrent.move("END_TO_START", current);
		startPos = fromElementToCurrent.toString().length
	}

	// now we need to make sure current isn't to the right of us ...
	if(current.compare("END_TO_END", entireElement) >= 0){
		endPos = entireElement.toString().length
	}else{
		endPos = startPos+current.toString().length
	}
	return {
		start: startPos,
		end : endPos
	};
},
getSelection = function(el){
	// use selectionStart if we can.
	var win = getWindow(el);

	if (el.selectionStart !== undefined) {

		if(document.activeElement
		 	&& document.activeElement != el
			&& el.selectionStart == el.selectionEnd
			&& el.selectionStart == 0){
			return {start: el.value.length, end: el.value.length};
		}
		return  {start: el.selectionStart, end: el.selectionEnd}
	} else if(win.getSelection){
		return getElementsSelection(el, win)
	} else{

		try {
			//try 2 different methods that work differently
			// one should only work for input elements, but sometimes doesn't
			// I don't know why this is, or what to detect
			if (el.nodeName.toLowerCase() == 'input') {
				var real = getWindow(el).document.selection.createRange(), r = el.createTextRange();
				r.setEndPoint("EndToStart", real);

				var start = r.text.length
				return {
					start: start,
					end: start + real.text.length
				}
			}
			else {
				var res = getElementsSelection(el,win)
				if(!res){
					return res;
				}
				// we have to clean up for ie's textareas
				var current = $.Range.current().clone(),
					r2 = current.clone().collapse().range,
					r3 = current.clone().collapse(false).range;

				r2.moveStart('character', -1)
				r3.moveStart('character', -1)
				// if we aren't at the start, but previous is empty, we are at start of newline
				if (res.startPos != 0 && r2.text == "") {
					res.startPos += 2;
				}
				// do a similar thing for the end of the textarea
				if (res.endPos != 0 && r3.text == "") {
					res.endPos += 2;
				}

				return res
			}
		}catch(e){
			return {start: el.value.length, end: el.value.length};
		}
	}
},
select = function( el, start, end ) {
	var win = getWindow(el)
	if(el.setSelectionRange){
		if(end === undefined){
            el.focus();
            el.setSelectionRange(start, start);
		} else {
			el.select();
			el.selectionStart = start;
			el.selectionEnd = end;
		}
	} else if (el.createTextRange) {
		//el.focus();
		var r = el.createTextRange();
		r.moveStart('character', start);
		end = end || start;
		r.moveEnd('character', end - el.value.length);

		r.select();
	} else if(win.getSelection){
		var	doc = win.document,
			sel = win.getSelection(),
			range = doc.createRange(),
			ranges = [start,  end !== undefined ? end : start];
		getCharElement([el],ranges);
		range.setStart(ranges[0].el, ranges[0].count);
		range.setEnd(ranges[1].el, ranges[1].count);

		// removeAllRanges is suprisingly necessary for webkit ... BOOO!
        sel.removeAllRanges();
        sel.addRange(range);

	} else if(win.document.body.createTextRange){ //IE's weirdness
		var range = document.body.createTextRange();
		range.moveToElementText(el);
		range.collapse()
		range.moveStart('character', start)
		range.moveEnd('character', end !== undefined ? end : start)
        range.select();
	}

},
/*
 * If one of the range values is within start and len, replace the range
 * value with the element and its offset.
 */
replaceWithLess = function(start, len, range, el){
	if(typeof range[0] === 'number' && range[0] < len){
			range[0] = {
				el: el,
				count: range[0] - start
			};
	}
	if(typeof range[1] === 'number' && range[1] <= len){
			range[1] = {
				el: el,
				count: range[1] - start
			};;
	}
},
getCharElement = function( elems , range, len ) {
	var elem,
		start;

	len = len || 0;
	for ( var i = 0; elems[i]; i++ ) {
		elem = elems[i];
		// Get the text from text nodes and CDATA nodes
		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
			start = len
			len += elem.nodeValue.length;
			//check if len is now greater than what's in counts
			replaceWithLess(start, len, range, elem )
		// Traverse everything else, except comment nodes
		} else if ( elem.nodeType !== 8 ) {
			len = getCharElement( elem.childNodes, range, len );
		}
	}
	return len;
};
/**
 * @parent dom
 * @tag beta
 *
 * Gets or sets the current text selection.
 *
 * ## Getting
 *
 * Gets the current selection in the context of an element.  For example:
 *
 *     $('textarea').selection() // -> { .... }
 *
 * returns an object with:
 *
 *   - __start__ - The number of characters from the start of the element to the start of the selection.
 *   - __end__ - The number of characters from the start of the element to the end of the selection.
 *   - __range__ - A [jQuery.Range $.Range] that represents the current selection.
 *
 * This lets you get the selected text in a textarea like:
 *
 *     var textarea = $('textarea')
 *       selection = textarea.selection(),
 *       selected = textarea.val().substr(selection.start, selection.end);
 *
 *     alert('You selected '+selected+'.');
 *
 * Selection works with all elements.  If you want to get selection information of the document:
 *
 *     $(document.body).selection();
 *
 * ## Setting
 *
 * By providing a start and end offset, you can select text within a given element.
 *
 *     $('#rte').selection(30, 40)
 *
 * ## Demo
 *
 * This demo shows setting the selection in various elements
 *
 * @demo jquery/dom/selection/selection.html
 *
 * @param {Number} [start] Start of the range
 * @param {Number} [end] End of the range
 * @return {Object|jQuery} returns the selection information or the jQuery collection for
 * chaining.
 */
$.fn.selection = function(start, end){
	if(start !== undefined){
		return this.each(function(){
			select(this, start, end)
		})
	}else{
		return getSelection(this[0])
	}
};
// for testing
$.fn.selection.getCharElement = getCharElement;

});<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name core.Services.LsService
 * @description LsService Service
 */
angular
    .module('core')
    .service('LsService', [

        function() {

            /**
             * @ngdoc function
             * @name core.Services.LsService#add
             * @methodOf core.Services.LsService
             * @return {boolean} Returns the added element
             */
            var add = function(element) {
                var elements = get();
                elements.push(element);
                localStorage.setItem(
                    "yemory.elements",
                    JSON.stringify(elements)
                );
                return element;
            };

            /**
             * @ngdoc function
             * @name core.Services.LsService#get
             * @methodOf core.Services.LsService
             * @return {boolean} Returns all elements
             */
            var get = function() {
                var elements = JSON.parse(
                  localStorage.getItem("yemory.elements")
                );
                if (elements){
                  return elements;
                }
                else{
                  return [];
                }
            };

            /**
             * @ngdoc function
             * @name core.Services.LsService#remove
             * @methodOf core.Services.LsService
             * @return {boolean} Returns the removed element
             */
            var remove = function(element) {
                var elements = JSON.parse(localStorage.getItem("yemory.elements"));
                var index = elements.indexOf(element);
                if (index > -1) {
                    elements.splice(index, 1);
                    localStorage.setItem(
                        "yemory.elements",
                        JSON.stringify(elements)
                    );
                    return element;
                }
                return null;
            };

            return{
                add: add,
                get: get,
                remove: remove
            }

        }
    ]);
<commit_msg>Fix duplicated element<commit_after>'use strict';

/**
 * @ngdoc service
 * @name core.Services.LsService
 * @description LsService Service
 */
angular
    .module('core')
    .service('LsService', [

        function() {

            /**
             * @ngdoc function
             * @name core.Services.LsService#add
             * @methodOf core.Services.LsService
             * @return {boolean} Returns the added element
             */
            var add = function(element) {
                var elements = get();
                // Verify if the new element is not into elements
                if (elements.indexOf(element) == -1){
                  elements.push(element);
                  localStorage.setItem(
                    "yemory.elements",
                    JSON.stringify(elements)
                  );
                }
                return element;
            };

            /**
             * @ngdoc function
             * @name core.Services.LsService#get
             * @methodOf core.Services.LsService
             * @return {boolean} Returns all elements
             */
            var get = function() {
                var elements = JSON.parse(
                  localStorage.getItem("yemory.elements")
                );
                if (elements){
                  return elements;
                }
                else{
                  return [];
                }
            };

            /**
             * @ngdoc function
             * @name core.Services.LsService#remove
             * @methodOf core.Services.LsService
             * @return {boolean} Returns the removed element
             */
            var remove = function(element) {
                var elements = JSON.parse(localStorage.getItem("yemory.elements"));
                var index = elements.indexOf(element);
                if (index > -1) {
                    elements.splice(index, 1);
                    localStorage.setItem(
                        "yemory.elements",
                        JSON.stringify(elements)
                    );
                    return element;
                }
                return null;
            };

            return{
                add: add,
                get: get,
                remove: remove
            }

        }
    ]);
<|endoftext|>