<commit_before>// Copyright (c) 2016-18 <NAME>
// Copyright (c) 2016 <NAME>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the The GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Affero General Public
// License along with this library; if not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA

// This widget enable us to manipulate the beats per minute. It
// behaves like a metronome and updates the master BPM block.


function Tempo () {
    const TEMPOINTERVAL = 5;
    const BUTTONDIVWIDTH = 476;  // 8 buttons 476 = (55 + 4) * 8
    const BUTTONSIZE = 53;
    const ICONSIZE = 32;
    const TEMPOWIDTH = 700;
    const TEMPOHEIGHT = 100;
    const YRADIUS = 75;

    this._xradius = YRADIUS / 3;

    this.BPMs = [];
    this.BPMBlocks = [];

    this._updateBPM = function (i) {
        this._intervals[i] = (60 / this.BPMs[i]) * 1000;

        if (this.BPMBlocks[i] != null) {
            var blockNumber = this._logo.blocks.blockList[this.BPMBlocks[i]].connections[1];
            if (blockNumber != null) {
                this._logo.blocks.blockList[blockNumber].value = parseFloat(this.BPMs[i]);
                this._logo.blocks.blockList[blockNumber].text.text = this.BPMs[i];
                this._logo.blocks.blockList[blockNumber].updateCache();
                this._logo.refreshCanvas();
                saveLocally();
            }
        }
    };

    this.pause = function () {
        clearInterval(this._intervalID);
    };

    this.resume = function () {
        // Reset widget time since we are restarting.
        // We will no longer keep synch with the turtles.
        var d = new Date();
        for (var i = 0; i < this.BPMs.length; i++) {
            this._widgetFirstTimes[i] = d.getTime();
            this._widgetNextTimes[i] = this._widgetFirstTimes[i] + this._intervals[i];
            this._directions[i] = 1;
        }

        // Restart the interval.
        var that = this;
        if (this._intervalID !== null) {
            clearInterval(this._intervalID);
        }

        this._intervalID = setInterval(function() {
            that._draw();
        }, TEMPOINTERVAL);
    };

    this._useBPM = function (i) {
        this.BPMs[i] = docById('BPMInput' + i).value
        if (this.BPMs[i] > 1000) {
            this.BPMs[i] = 1000;
        } else if (this.BPMs[i] < 30) {
            this.BPMs[i] = 30;
        }

        this._updateBPM(i);
    };

    this._speedUp = function (i) {
        this.BPMs[i] = parseFloat(this.BPMs[i]) + 5;

        if (this.BPMs[i] > 1000) {
            this.BPMs[i] = 1000;
        }

        this._updateBPM(i);
        docById('BPMInput' + i).value = this.BPMs[i];
    };

    this._slowDown = function (i) {
        this.BPMs[i] = parseFloat(this.BPMs[i]) - 5;
        if (this.BPMs[i] < 30) {
            this.BPMs[i] = 30;
        }

        this._updateBPM(i);
        docById('BPMInput' + i).value = this.BPMs[i];
    };

    this._draw = function() {
        // First thing to do is figure out where we are supposed to be
        // based on the elapsed time.
        var d = new Date();

        for (var i = 0; i < this.BPMs.length; i++) {
            var tempoCanvas = docById('tempoCanvas' + i);

            // We start the music clock as the first note is being
            // played.
            if (this._widgetFirstTimes[i] == null) {
                this._widgetFirstTimes[i] = d.getTime();
                this._widgetNextTimes[i] = this._widgetFirstTimes[i] + this._intervals[i];
            }

            // How much time has gone by?
            var deltaTime = this._widgetNextTimes[i] - d.getTime();

            // Are we done yet?
            if (d.getTime() > this._widgetNextTimes[i]) {
                // Play a tone.
                this._logo.synth.trigger(0, 'C4', 0.125, 'default', null, null);
                this._widgetNextTimes[i] += this._intervals[i];

                // Ensure we are at the edge.
                if (this._directions[i] === -1) {
                    this._directions[i] = 1;
                } else {
                    this._directions[i] = -1;
                }
            } else {
                // Determine new x position based on delta time.
                if (this._intervals[i] !== 0) {
                    var dx = (tempoCanvas.width) * (deltaTime / this._intervals[i]);
                } else {
                    var dx = 0;
                }

                // Set this._xradius based on the dx to achieve the compressing effect
                if (tempoCanvas.width - dx <= YRADIUS / 3) {
                    this._xradius =  tempoCanvas.width - dx;
                } else if (dx <= YRADIUS / 3) {
                    this._xradius = dx;
                } else {
                    this._xradius = YRADIUS / 3;
                }

                // Set x based on dx and direction
                if (this._directions[i] === -1) {
                    var x = tempoCanvas.width - dx;
                } else {
                    var x = dx;
                }
            }

            // Set x value if it is undefined
            if (x === undefined) {
                if (this._directions[i] === -1) {
                    x = 0;
                } else {
                    x = tempoCanvas.width;
                }
            }

            var ctx = tempoCanvas.getContext('2d');
            ctx.clearRect(0, 0, tempoCanvas.width, tempoCanvas.height);
            ctx.beginPath();
            ctx.fillStyle = 'rgba(0,0,0,1)';
            ctx.ellipse(x, YRADIUS, Math.max(this._xradius, 1), YRADIUS, 0, 0, Math.PI * 2);
            ctx.fill();
            ctx.closePath();
        }
    };

    this.init = function (logo) {
        this._logo = logo;
        this._directions = [];
        this._widgetFirstTimes = [];
        this._widgetNextTimes = [];
        this._firstClickTimes = null;
        this._intervals = [];
        this.isMoving = true;
        this._intervalID = null;

        if (this._intervalID != null) {
            clearInterval(this._intervalID);
        }

        var w = window.innerWidth;
        var iconSize = ICONSIZE;

        var canvas = docById('myCanvas');

        // Position the widget and make it visible.
        var tempoDiv = docById('tempoDiv');
        tempoDiv.style.visibility = 'visible';
        tempoDiv.setAttribute('draggable', 'true');
        tempoDiv.style.left = '200px';
        tempoDiv.style.top = '150px';

        // The widget buttons
        var widgetButtonsDiv = docById('tempoButtonsDiv');
        widgetButtonsDiv.style.display = 'inline';
        widgetButtonsDiv.style.visibility = 'visible';<commit_msg>fixes #1113 -- changed to a more percussive sound with a bit more volume.<commit_after>// Copyright (c) 2016-18 <NAME>
// Copyright (c) 2016 <NAME>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the The GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Affero General Public
// License along with this library; if not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA

// This widget enable us to manipulate the beats per minute. It
// behaves like a metronome and updates the master BPM block.


function Tempo () {
    const TEMPOSYNTH = 'bottle';
    const TEMPOINTERVAL = 5;
    const BUTTONDIVWIDTH = 476;  // 8 buttons 476 = (55 + 4) * 8
    const BUTTONSIZE = 53;
    const ICONSIZE = 32;
    const TEMPOWIDTH = 700;
    const TEMPOHEIGHT = 100;
    const YRADIUS = 75;

    this._xradius = YRADIUS / 3;

    this.BPMs = [];
    this.BPMBlocks = [];

    this._updateBPM = function (i) {
        this._intervals[i] = (60 / this.BPMs[i]) * 1000;

        if (this.BPMBlocks[i] != null) {
            var blockNumber = this._logo.blocks.blockList[this.BPMBlocks[i]].connections[1];
            if (blockNumber != null) {
                this._logo.blocks.blockList[blockNumber].value = parseFloat(this.BPMs[i]);
                this._logo.blocks.blockList[blockNumber].text.text = this.BPMs[i];
                this._logo.blocks.blockList[blockNumber].updateCache();
                this._logo.refreshCanvas();
                saveLocally();
            }
        }
    };

    this.pause = function () {
        clearInterval(this._intervalID);
    };

    this.resume = function () {
        // Reset widget time since we are restarting.
        // We will no longer keep synch with the turtles.
        var d = new Date();
        for (var i = 0; i < this.BPMs.length; i++) {
            this._widgetFirstTimes[i] = d.getTime();
            this._widgetNextTimes[i] = this._widgetFirstTimes[i] + this._intervals[i];
            this._directions[i] = 1;
        }

        // Restart the interval.
        var that = this;
        if (this._intervalID !== null) {
            clearInterval(this._intervalID);
        }

        this._intervalID = setInterval(function() {
            that._draw();
        }, TEMPOINTERVAL);
    };

    this._useBPM = function (i) {
        this.BPMs[i] = docById('BPMInput' + i).value
        if (this.BPMs[i] > 1000) {
            this.BPMs[i] = 1000;
        } else if (this.BPMs[i] < 30) {
            this.BPMs[i] = 30;
        }

        this._updateBPM(i);
    };

    this._speedUp = function (i) {
        this.BPMs[i] = parseFloat(this.BPMs[i]) + 5;

        if (this.BPMs[i] > 1000) {
            this.BPMs[i] = 1000;
        }

        this._updateBPM(i);
        docById('BPMInput' + i).value = this.BPMs[i];
    };

    this._slowDown = function (i) {
        this.BPMs[i] = parseFloat(this.BPMs[i]) - 5;
        if (this.BPMs[i] < 30) {
            this.BPMs[i] = 30;
        }

        this._updateBPM(i);
        docById('BPMInput' + i).value = this.BPMs[i];
    };

    this._draw = function() {
        // First thing to do is figure out where we are supposed to be
        // based on the elapsed time.
        var d = new Date();

        for (var i = 0; i < this.BPMs.length; i++) {
            var tempoCanvas = docById('tempoCanvas' + i);

            // We start the music clock as the first note is being
            // played.
            if (this._widgetFirstTimes[i] == null) {
                this._widgetFirstTimes[i] = d.getTime();
                this._widgetNextTimes[i] = this._widgetFirstTimes[i] + this._intervals[i];
            }

            // How much time has gone by?
            var deltaTime = this._widgetNextTimes[i] - d.getTime();

            // Are we done yet?
            if (d.getTime() > this._widgetNextTimes[i]) {
                // Play a tone.
                this._logo.synth.trigger(0, ['C2'], 0.0625, TEMPOSYNTH, null, null, false);
                this._widgetNextTimes[i] += this._intervals[i];

                // Ensure we are at the edge.
                if (this._directions[i] === -1) {
                    this._directions[i] = 1;
                } else {
                    this._directions[i] = -1;
                }
            } else {
                // Determine new x position based on delta time.
                if (this._intervals[i] !== 0) {
                    var dx = (tempoCanvas.width) * (deltaTime / this._intervals[i]);
                } else {
                    var dx = 0;
                }

                // Set this._xradius based on the dx to achieve the compressing effect
                if (tempoCanvas.width - dx <= YRADIUS / 3) {
                    this._xradius =  tempoCanvas.width - dx;
                } else if (dx <= YRADIUS / 3) {
                    this._xradius = dx;
                } else {
                    this._xradius = YRADIUS / 3;
                }

                // Set x based on dx and direction
                if (this._directions[i] === -1) {
                    var x = tempoCanvas.width - dx;
                } else {
                    var x = dx;
                }
            }

            // Set x value if it is undefined
            if (x === undefined) {
                if (this._directions[i] === -1) {
                    x = 0;
                } else {
                    x = tempoCanvas.width;
                }
            }

            var ctx = tempoCanvas.getContext('2d');
            ctx.clearRect(0, 0, tempoCanvas.width, tempoCanvas.height);
            ctx.beginPath();
            ctx.fillStyle = 'rgba(0,0,0,1)';
            ctx.ellipse(x, YRADIUS, Math.max(this._xradius, 1), YRADIUS, 0, 0, Math.PI * 2);
            ctx.fill();
            ctx.closePath();
        }
    };

    this.init = function (logo) {
        this._logo = logo;
        this._directions = [];
        this._widgetFirstTimes = [];
        this._widgetNextTimes = [];
        this._firstClickTimes = null;
        this._intervals = [];
        this.isMoving = true;
        this._intervalID = null;

        this._logo.synth.loadSynth(0, getDrumSynthName(TEMPOSYNTH));

        if (this._intervalID != null) {
            clearInterval(this._intervalID);
        }

        var w = window.innerWidth;
        var iconSize = ICONSIZE;

        var canvas = docById('myCanvas');

        // Position the widget and make it visible.
        var tempoDiv = docById('tempoDiv');
        tempoDiv.style.visibility = 'visible';
        tempoDiv.setAttribute('draggable', 'true');
        tempoDiv.style.left = '200px';
        tempoDiv.style.top = '150px';

        // The widget buttons
        var widgetButtonsDiv = docById('tempoButtonsDiv');
        widgetButtonsDiv.style.display = 'inline';
        widgetButtonsDiv.style.visibility = 'visible';
{'fraction_non_alphanumeric': 0.1221570590759548, 'fraction_numerical': 0.017594049492204264, 'mean_word_length': 1.5837028824833703, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7277438', 'n_tokens_mistral': 4479, 'n_tokens_neox': 4061, 'n_words': 1069}