<commit_before>/*jshint globals: false, unused: false, strict: false, debug: true, globalstrict: true, moz: true, browser: true, devel: true, jquery: true*/
var bolides = {
    canvas: {
        ctx: '',
    },
    // Attributes of the player's ship declared
    spaceship: {
        // Starting x and y
        x: 100,
        y: 100,
        // Starting speed
        speed: 0,
        // Starting angle
        angle: 0,
        // Starting direction
        direction: {
            x: 0,
            y: 0
        },
        // Starting health
        hearts: 3
    },
    // Attributes of the asteroids declared
    asteriod: {
        // Same attributes as the ship, aside from pos
        x: Math.floor(Math.random() * 50 + 800),
        y: Math.floor(Math.random() * 600 + 20),
        angle: 0,
        direction: {
            x: 0,
            y: 0
        },
        speed: 5
    },
    // Oh snap, Spaceship's got a gun!
    bullet : {
        // Coordinates
        x: 0,
        y: 0,
        // Speed is constant, btw.
        speed: 10,
        // Angle is spaceship's angle until fired
        angle: 0,
        // Direction stuff again! How advanced!
        direction: {
            x: 0,
            y: 0
        },
        // Is what it says on the tin
        isBeingFired: false,
        // Shooty gun
        fire: function() {
            bolides.bullet.isBeingFired = true;
        }
    },
    // Images used by the project are created here
    images: {
        ship: document.createElement('img'),
        asteroid: document.createElement('img'),
        heart: document.createElement('img'),
        bullet: document.createElement("img")
    },
    initiate: function(){
        // Declare the canvas's context as 2D
        var canva = document.getElementById('canvas');
        bolides.canvas.ctx = canva.getContext('2d');
        // EventListener for keypresses to change speed and stuff
        addEventListener('keydown', function(e){bolides.control(e);});
        // Interval for slowdown
        setInterval(function(){ if(bolides.spaceship.speed > 0) {bolides.spaceship.speed -= 0.5;}}, 500);
        // Set the image sources
        bolides.images.ship.setAttribute('src', "../bolides/images/spaceship.png");
        bolides.images.asteroid.setAttribute('src', "../bolides/images/asteroid.png");
        bolides.images.heart.setAttribute('src', "../bolides/images/heart.png");
        bolides.images.bullet.setAttribute('src', "../bolides/images/bullet.png");
        // Start looping
        bolides.loop();
    },
    loop: function() {
        // Is the player out of health?
        if(bolides.spaceship.hearts === 0) {
            // Then display "Game over"
            bolides.canvas.ctx.clearRect(0, 0, 800, 600);
            bolides.canvas.ctx.font = "48px Ubuntu";
            bolides.canvas.ctx.fillStyle = "white";
            bolides.canvas.ctx.fillText("Game Over", 200, 200);
        } else {
            // No? Then move and draw everything, then loop again.
            bolides.move();
            bolides.draw();
            requestAnimationFrame(function() { bolides.loop(); });
        }
    },
    control: function(key) {
        // Up key or W key?
        if (key.keyCode === 38 || key.keyCode === 87) {
            // Then increase speed.
            bolides.spaceship.speed += 1;
        // Down key or S key?
        } else if (key.keyCode === 40 || key.keyCode === 83) {
            // Then decrease speed.
            if (bolides.spaceship.speed > 0){
            bolides.spaceship.speed -= 1;
            }
        // R key?
        } else if (key.keyCode === 82) {
            // Then remove a heart.
            bolides.spaceship.hearts -= 1;
        // Left key or A key?
        } else if (key.keyCode === 37 || key.keyCode === 65) {
            // Then change its angle by 7.5 degrees
            bolides.spaceship.angle -= 0.1308996938995747;
        // Right key or D key?
        } else if (key.keyCode === 39 || key.keyCode === 68) {
            // Then change its angle by -7.5 degrees
            bolides.spaceship.angle += 0.1308996938995747;
        // Space bar or Q key?
        } else if (key.keyCode === 32 || key.keyCode === 81) {
            bolides.bullet.fire();
        }
    },
    move: function() {
        // Math
        bolides.spaceship.direction.x = Math.sin(bolides.spaceship.angle);
        bolides.spaceship.direction.y = -Math.cos(bolides.spaceship.angle);
        bolides.spaceship.x += bolides.spaceship.direction.x * bolides.spaceship.speed;
        bolides.spaceship.y += bolides.spaceship.direction.y * bolides.spaceship.speed;
        // Side warps
        if (bolides.spaceship.x <= -25){
            bolides.spaceship.x = 800;
        } else if (bolides.spaceship.x >=800) {
            bolides.spaceship.x = 0;
        }
        if (bolides.spaceship.y >= 630) {
            bolides.spaceship.y = 0;
        } else if (bolides.spaceship.y <= 0) {
            bolides.spaceship.y = 600;
        }
        // If it's moving,
        if (bolides.spaceship.speed !== 0) {
            // Use the moving ship pic.
            bolides.images.ship.setAttribute('src', "../bolides/images/spaceship-move.png");
        // Elsewise, don't.
        } else {
            bolides.images.ship.setAttribute('src', "../bolides/images/spaceship.png");
        }
        if (!bolides.bullet.isBeingFired) {
            bolides.bullet.x = bolides.spaceship.x;
            bolides.bullet.y = bolides.spaceship.y;
            bolides.bullet.angle = bolides.spaceship.angle;
        }
        // Because decimals
        if ((bolides.spaceship.speed > 0) && (bolides.spaceship.speed < 0.5)) {
            bolides.spaceship.speed = 0;
        } else if (bolides.spaceship.speed < 0) {
            bolides.spaceship.speed = 0;
        }
//        bolides.asteriod.x = ;
//        bolides.asteriod.y = 650;
    },
    draw: function() {
        // Clear the canvas
        bolides.canvas.ctx.clearRect(0, 0, 800, 600);
        // Save it so I can f*** about as much as I want
        bolides.canvas.ctx.save();
        // Set the origin to the ship's center
        bolides.canvas.ctx.translate(bolides.spaceship.x + 18, bolides.spaceship.y - 31);
        // Rotate the ship around the center by the angle of the ship
        bolides.canvas.ctx.rotate(bolides.spaceship.angle);
        // Draw the ship
        bolides.canvas.ctx.drawImage(bolides.images.ship, -18, -31, 36, 62);
        // Restore all f***ing about
        bolides.canvas.ctx.restore();
        // Oh boy more saving
        bolides.canvas.ctx.save();
        // Set the origin to the bullet's origin
        bolides.canvas.ctx.translate(bolides.bullet.x + 3, bolides.bullet.y - 12.5);
        // Rotate the canvas
        bolides.canvas.ctx.rotate(bolides.bullet.angle);
        // Fastest draw in the west
        bolides.canvas.ctx.drawImage(bolides.images.bullet, -3, -12.5);
        // Full Restore
        bolides.canvas.ctx.restore();
        bolides.canvas.ctx.fillStyle = "red";
        bolides.canvas.ctx.fillRect(100, 100, 1, 1);
        // Draw the asteroid (doesn't turn up because it's off the screen)
        bolides.canvas.ctx.drawImage(bolides.images.asteroid, bolides.asteriod.x, bolides.asteriod.y);
        // Test asteriod x & y
        bolides.canvas.ctx.font = "48px Ubuntu";
        bolides.canvas.ctx.fillText(bolides.bullet.isBeingFired, 500, 500);
        // Check for the number of hearts and draw that many
        if (bolides.spaceship.hearts >= 3) {
            bolides.canvas.ctx.drawImage(bolides.images.heart, 10, 10);
            bolides.canvas.ctx.drawImage(bolides.images.heart, 35, 10);
            bolides.canvas.ctx.drawImage(bolides.images.heart, 60, 10);
        } else if (bolides.spaceship.hearts === 2) {
            bolides.canvas.ctx.drawImage(bolides.images.heart, 10, 10);
            bolides.canvas.ctx.drawImage(bolides.images.heart, 35, 10);
        } else {
            bolides.canvas.ctx.drawImage(bolides.images.heart, 10, 10);
        }
    }
};
// Actually start the program
addEventListener('load', function() { bolides.initiate(); });
<commit_msg>Terminal velocity + bullet mechanics.<commit_after>/*jshint globals: false, unused: false, strict: false, debug: true, globalstrict: true, moz: true, browser: true, devel: true, jquery: true*/
var bolides = {
    canvas: {
        ctx: '',
    },
    // Attributes of the player's ship declared
    spaceship: {
        // Starting x and y
        x: 100,
        y: 100,
        // Starting speed
        speed: 0,
        // Starting angle
        angle: 0,
        // Starting direction
        direction: {
            x: 0,
            y: 0
        },
        // Starting health
        hearts: 3
    },
    // Attributes of the asteroids declared
    asteriod: {
        // Same attributes as the ship, aside from pos
        x: Math.floor(Math.random() * 50 + 800),
        y: Math.floor(Math.random() * 600 + 20),
        angle: 0,
        direction: {
            x: 0,
            y: 0
        },
        speed: 5
    },
    // Oh snap, Spaceship's got a gun!
    bullet : {
        // Coordinates
        x: 0,
        y: 0,
        // Speed is constant, btw.
        speed: 15,
        // Angle is spaceship's angle until fired
        angle: 0,
        // Direction stuff again! How advanced!
        direction: {
            x: 0,
            y: 0
        },
        // Is what it says on the tin
        isBeingFired: false,
        // Shooty gun
        fire: function() {
            bolides.bullet.isBeingFired = true;
            bolides.bullet.x = bolides.spaceship.x;
            bolides.bullet.y = bolides.spaceship.y;
            bolides.bullet.angle = bolides.spaceship.angle;
        }
    },
    // Images used by the project are created here
    images: {
        ship: document.createElement('img'),
        asteroid: document.createElement('img'),
        heart: document.createElement('img'),
        bullet: document.createElement("img")
    },
    initiate: function(){
        // Declare the canvas's context as 2D
        var canva = document.getElementById('canvas');
        bolides.canvas.ctx = canva.getContext('2d');
        // EventListener for keypresses to change speed and stuff
        addEventListener('keydown', function(e){bolides.control(e);});
        // Interval for slowdown
        setInterval(function(){ if(bolides.spaceship.speed > 0) {bolides.spaceship.speed -= 0.5;}}, 500);
        // Set the image sources
        bolides.images.ship.setAttribute('src', "../bolides/images/spaceship.png");
        bolides.images.asteroid.setAttribute('src', "../bolides/images/asteroid.png");
        bolides.images.heart.setAttribute('src', "../bolides/images/heart.png");
        bolides.images.bullet.setAttribute('src', "../bolides/images/bullet.png");
        // Start looping
        bolides.loop();
    },
    loop: function() {
        // Is the player out of health?
        if(bolides.spaceship.hearts === 0) {
            // Then display "Game over"
            bolides.canvas.ctx.clearRect(0, 0, 800, 600);
            bolides.canvas.ctx.font = "48px Ubuntu";
            bolides.canvas.ctx.fillStyle = "white";
            bolides.canvas.ctx.fillText("Game Over", 200, 200);
        } else {
            // No? Then move and draw everything, then loop again.
            bolides.move();
            bolides.draw();
            requestAnimationFrame(function() { bolides.loop(); });
        }
    },
    control: function(key) {
        // Up key or W key?
        if (key.keyCode === 38 || key.keyCode === 87) {
            // Then increase speed if not past terminal velocity
            if (bolides.spaceship.speed < 25) {
            bolides.spaceship.speed += 1;
            }
        // Down key or S key?
        } else if (key.keyCode === 40 || key.keyCode === 83) {
            // Then decrease speed.
            if (bolides.spaceship.speed > 0){
            bolides.spaceship.speed -= 1;
            }
        // R key?
        } else if (key.keyCode === 82) {
            // Then remove a heart.
            bolides.spaceship.hearts -= 1;
        // Left key or A key?
        } else if (key.keyCode === 37 || key.keyCode === 65) {
            // Then change its angle by 7.5 degrees
            bolides.spaceship.angle -= 0.1308996938995747;
        // Right key or D key?
        } else if (key.keyCode === 39 || key.keyCode === 68) {
            // Then change its angle by -7.5 degrees
            bolides.spaceship.angle += 0.1308996938995747;
        // Space bar or Q key?
        } else if (key.keyCode === 32 || key.keyCode === 81) {
            bolides.bullet.fire();
        }
    },
    move: function() {
        // Ship Math
        bolides.spaceship.direction.x = Math.sin(bolides.spaceship.angle);
        bolides.spaceship.direction.y = -Math.cos(bolides.spaceship.angle);
        bolides.spaceship.x += bolides.spaceship.direction.x * bolides.spaceship.speed;
        bolides.spaceship.y += bolides.spaceship.direction.y * bolides.spaceship.speed;
        // Side warps
        if (bolides.spaceship.x <= -25){
            bolides.spaceship.x = 800;
        } else if (bolides.spaceship.x >=800) {
            bolides.spaceship.x = 0;
        }
        if (bolides.spaceship.y >= 630) {
            bolides.spaceship.y = 0;
        } else if (bolides.spaceship.y <= 0) {
            bolides.spaceship.y = 600;
        }
        // If it's moving,
        if (bolides.spaceship.speed !== 0) {
            // Use the moving ship pic.
            bolides.images.ship.setAttribute('src', "../bolides/images/spaceship-move.png");
        // Elsewise, don't.
        } else {
            bolides.images.ship.setAttribute('src', "../bolides/images/spaceship.png");
        }
        // Stop bullet
        if (!bolides.bullet.isBeingFired) {
            bolides.bullet.x = bolides.spaceship.x;
            bolides.bullet.y = bolides.spaceship.y;
            bolides.bullet.angle = bolides.spaceship.angle;
        } else {
        // Bullet math
        bolides.bullet.direction.x = Math.sin(bolides.bullet.angle);
        bolides.bullet.direction.y = -Math.cos(bolides.bullet.angle);
        bolides.bullet.x += bolides.bullet.direction.x * bolides.bullet.speed;
        bolides.bullet.y += bolides.bullet.direction.y * bolides.bullet.speed;
        }
        // Because decimals
        if ((bolides.spaceship.speed > 0) && (bolides.spaceship.speed < 0.5)) {
            bolides.spaceship.speed = 0;
        } else if (bolides.spaceship.speed < 0) {
            bolides.spaceship.speed = 0;
        }
        // Bullet dissipation
        if (bolides.bullet.x <= -25){
            bolides.bullet.isBeingFired = false;
        } else if (bolides.bullet.x >=800) {
            bolides.bullet.isBeingFired = false;
        }
        if (bolides.bullet.y >= 630) {
            bolides.bullet.isBeingFired = false;
        } else if (bolides.bullet.y <= 0) {
            bolides.bullet.isBeingFired = false;
        }
    },
    draw: function() {
        // Clear the canvas
        bolides.canvas.ctx.clearRect(0, 0, 800, 600);
        // Save it so I can f*** about as much as I want
        bolides.canvas.ctx.save();
        // Set the origin to the ship's center
        bolides.canvas.ctx.translate(bolides.spaceship.x + 18, bolides.spaceship.y - 31);
        // Rotate the ship around the center by the angle of the ship
        bolides.canvas.ctx.rotate(bolides.spaceship.angle);
        // Draw the ship
        bolides.canvas.ctx.drawImage(bolides.images.ship, -18, -31, 36, 62);
        // Restore all f***ing about
        bolides.canvas.ctx.restore();
        // Oh boy more saving
        bolides.canvas.ctx.save();
        // Set the origin to the bullet's origin
        bolides.canvas.ctx.translate(bolides.bullet.x + 3, bolides.bullet.y - 12.5);
        // Rotate the canvas
        bolides.canvas.ctx.rotate(bolides.bullet.angle);
        // Fastest draw in the west
        if (bolides.bullet.isBeingFired === true) {
        bolides.canvas.ctx.drawImage(bolides.images.bullet, -3, -12.5);
        }
        // Full Restore
        bolides.canvas.ctx.restore();
        bolides.canvas.ctx.fillStyle = "red";
        bolides.canvas.ctx.fillRect(100, 100, 1, 1);
        // Draw the asteroid (doesn't turn up because it's off the screen)
        bolides.canvas.ctx.drawImage(bolides.images.asteroid, bolides.asteriod.x, bolides.asteriod.y);
        // Test asteriod x & y
        bolides.canvas.ctx.font = "48px Ubuntu";
        bolides.canvas.ctx.fillText(bolides.bullet.isBeingFired, 500, 500);
        // Check for the number of hearts and draw that many
        if (bolides.spaceship.hearts >= 3) {
            bolides.canvas.ctx.drawImage(bolides.images.heart, 10, 10);
            bolides.canvas.ctx.drawImage(bolides.images.heart, 35, 10);
            bolides.canvas.ctx.drawImage(bolides.images.heart, 60, 10);
        } else if (bolides.spaceship.hearts === 2) {
            bolides.canvas.ctx.drawImage(bolides.images.heart, 10, 10);
            bolides.canvas.ctx.drawImage(bolides.images.heart, 35, 10);
        } else {
            bolides.canvas.ctx.drawImage(bolides.images.heart, 10, 10);
        }
    }
};
// Actually start the program
addEventListener('load', function() { bolides.initiate(); });
<|endoftext|>


<commit_before>import Select from './Select';
import Async from './Async';
import AsyncCreatable from './AsyncCreatable';
import Creatable from './Creatable';
import Value from './Value';
import Option from './Option';

Select.Async = Async;
Select.AsyncCreatable = AsyncCreatable;
Select.Creatable = Creatable;
Select.Value = Value;
Select.Option = Option;

export default Select;
export {
	Async,
	AsyncCreatable,
	Creatable,
	Value,
	Option
};
<commit_msg>Export default util functions<commit_after>import Select from './Select';
import Async from './Async';
import AsyncCreatable from './AsyncCreatable';
import Creatable from './Creatable';
import Value from './Value';
import Option from './Option';

import defaultMenuRenderer from './utils/defaultMenuRenderer';
import defaultArrowRenderer from './utils/defaultArrowRenderer';
import defaultClearRenderer from './utils/defaultClearRenderer';
import defaultFilterOptions from './utils/defaultFilterOptions';

Select.Async = Async;
Select.AsyncCreatable = AsyncCreatable;
Select.Creatable = Creatable;
Select.Value = Value;
Select.Option = Option;

export default Select;
export {
	Async,
	AsyncCreatable,
	Creatable,
	Value,
	Option,
	defaultMenuRenderer,
	defaultArrowRenderer,
	defaultClearRenderer,
	defaultFilterOptions
};
<|endoftext|>


<commit_before>$(document).ready(function(){
$('.responsive').slick({
  dots: true,
  infinite: true,
  speed: 300,
  slidesToShow: 3,
  slidesToScroll: 3,
  responsive: [
    {
      breakpoint: 1024,
      settings: {
        slidesToShow: 3,
        slidesToScroll: 3,
        infinite: true,
        dots: true
      }
    },
    {
      breakpoint: 600,
      settings: {
        slidesToShow: 2,
        slidesToScroll: 2
      }
    },
    {
      breakpoint: 480,
      settings: {
        slidesToShow: 1,
        slidesToScroll: 1
      }
    }
    // You can unslick at a given breakpoint now by adding:
    // settings: "unslick"
    // instead of a settings object
  ]
});
});
<commit_msg>Update carousel.js<commit_after>$(document).ready(function(){
$('.responsive').slick({
  dots: true,
  infinite: true,
  speed: 300,
  slidesToShow: 3,
  slidesToScroll: 1,
  responsive: [
    {
      breakpoint: 1024,
      settings: {
        slidesToShow: 3,
        slidesToScroll: 1,
        infinite: true,
        dots: true
      }
    },
    {
      breakpoint: 600,
      settings: {
        slidesToShow: 2,
        slidesToScroll: 1
      }
    },
    {
      breakpoint: 480,
      settings: {
        slidesToShow: 1,
        slidesToScroll: 1
      }
    }
    // You can unslick at a given breakpoint now by adding:
    // settings: "unslick"
    // instead of a settings object
  ]
});
});
<|endoftext|>


<commit_before>/**
 * Created by xiaolin on 16/12/26.
 */

// ------------------------------------
// Android 4.4 Version Below
// ------------------------------------
require('es6-promise').polyfill();
var a = 1;

// ------------------------------------
// Resource Import
// ------------------------------------
require.ensure([],
    function(require) {

        var dva = require('dva').default
        var FastClick  = require('fastclick')
        var router  = require('./routes')
        var business  = require('./model/business')
        var model  = require('./model')

        // ------------------------------------
        // App Starting
        // ------------------------------------
        const html5ForStartApp = dva()
        function html5ForLogin(_app) {
            if (_app) {

                _app.model(business)
                _app.model(model)

                _app.router(router)

                _app.start('.page-container')

            }
            else {
                html5ForStartApp.model(business)
                html5ForStartApp.model(model)

                html5ForStartApp.router(router)

                html5ForStartApp.start('.page-container')
            }

        }

        // ------------------------------------
        // Debug Here
        // ------------------------------------
        html5ForLogin(html5ForStartApp);
        var b = 1;

        // ------------------------------------
        // Client Login
        // ------------------------------------
        // if(navigator.userAgent.match(/Android/i)) {
        //     if (typeof QBaoJSBridge != 'undefined') {
        //         QBaoJSBridge.login("mqbii.qbao.com", String(html5ForLogin(html5ForStartApp)));
        //     }
        // }
        // else if(navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
        //     if (typeof ioswebview != 'undefined') {
        //         ioswebview.showLoginViewAnd("mqbii.qbao.com", String(html5ForLogin(html5ForStartApp)));
        //     }
        // }
        // else {
        //     html5ForLogin(html5ForStartApp);
        // }

        // ------------------------------------
        // Fast Click Adding For System
        // ------------------------------------
        if ('addEventListener' in document) {
            document.addEventListener('DOMContentLoaded', function () {
                FastClick.attach(document.body);
            }, false);
        }

    }
)<commit_msg>git withoutNode adding 11<commit_after>/**
 * Created by xiaolin on 16/12/26.
 */

// ------------------------------------
// Android 4.4 Version Below
// ------------------------------------
require('es6-promise').polyfill();
var a = 11;

// ------------------------------------
// Resource Import
// ------------------------------------
require.ensure([],
    function(require) {

        var dva = require('dva').default
        var FastClick  = require('fastclick')
        var router  = require('./routes')
        var business  = require('./model/business')
        var model  = require('./model')

        // ------------------------------------
        // App Starting
        // ------------------------------------
        const html5ForStartApp = dva()
        function html5ForLogin(_app) {
            if (_app) {

                _app.model(business)
                _app.model(model)

                _app.router(router)

                _app.start('.page-container')

            }
            else {
                html5ForStartApp.model(business)
                html5ForStartApp.model(model)

                html5ForStartApp.router(router)

                html5ForStartApp.start('.page-container')
            }

        }

        // ------------------------------------
        // Debug Here
        // ------------------------------------
        html5ForLogin(html5ForStartApp);
        var b = 11;

        // ------------------------------------
        // Client Login
        // ------------------------------------
        // if(navigator.userAgent.match(/Android/i)) {
        //     if (typeof QBaoJSBridge != 'undefined') {
        //         QBaoJSBridge.login("mqbii.qbao.com", String(html5ForLogin(html5ForStartApp)));
        //     }
        // }
        // else if(navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
        //     if (typeof ioswebview != 'undefined') {
        //         ioswebview.showLoginViewAnd("mqbii.qbao.com", String(html5ForLogin(html5ForStartApp)));
        //     }
        // }
        // else {
        //     html5ForLogin(html5ForStartApp);
        // }

        // ------------------------------------
        // Fast Click Adding For System
        // ------------------------------------
        if ('addEventListener' in document) {
            document.addEventListener('DOMContentLoaded', function () {
                FastClick.attach(document.body);
            }, false);
        }

    }
)<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError, AuthenticationError, NotSupported } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class coinspot extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coinspot',
            'name': 'CoinSpot',
            'countries': [ 'AU' ], // Australia
            'rateLimit': 1000,
            'has': {
                'CORS': false,
                'createMarketOrder': false,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/28208429-3cacdf9a-6896-11e7-854e-4c79a772a30f.jpg',
                'api': {
                    'public': 'https://www.coinspot.com.au/pubapi',
                    'private': 'https://www.coinspot.com.au/api',
                },
                'www': 'https://www.coinspot.com.au',
                'doc': 'https://www.coinspot.com.au/api',
                'referral': 'https://www.coinspot.com.au/join/FSM11C',
            },
            'api': {
                'public': {
                    'get': [
                        'latest',
                    ],
                },
                'private': {
                    'post': [
                        'orders',
                        'orders/history',
                        'my/coin/deposit',
                        'my/coin/send',
                        'quote/buy',
                        'quote/sell',
                        'my/balances',
                        'my/orders',
                        'my/buy',
                        'my/sell',
                        'my/buy/cancel',
                        'my/sell/cancel',
                    ],
                },
            },
            'markets': {
                'BTC/AUD': { 'id': 'BTC', 'symbol': 'BTC/AUD', 'base': 'BTC', 'quote': 'AUD' },
                'LTC/AUD': { 'id': 'LTC', 'symbol': 'LTC/AUD', 'base': 'LTC', 'quote': 'AUD' },
                'DOGE/AUD': { 'id': 'DOGE', 'symbol': 'DOGE/AUD', 'base': 'DOGE', 'quote': 'AUD' },
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        const response = await this.privatePostMyBalances (params);
        let result = { 'info': response };
        if ('balance' in response) {
            let balances = response['balance'];
            let currencies = Object.keys (balances);
            for (let c = 0; c < currencies.length; c++) {
                let currency = currencies[c];
                let uppercase = currency.toUpperCase ();
                let account = {
                    'free': balances[currency],
                    'used': 0.0,
                    'total': balances[currency],
                };
                if (uppercase === 'DRK')
                    uppercase = 'DASH';
                result[uppercase] = account;
            }
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        let market = this.market (symbol);
        let orderbook = await this.privatePostOrders (this.extend ({
            'cointype': market['id'],
        }, params));
        return this.parseOrderBook (orderbook, undefined, 'buyorders', 'sellorders', 'rate', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        let response = await this.publicGetLatest (params);
        let id = this.marketId (symbol);
        id = id.toLowerCase ();
        let ticker = response['prices'][id];
        let timestamp = this.milliseconds ();
        let last = this.safeFloat (ticker, 'last');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        return this.privatePostOrdersHistory (this.extend ({
            'cointype': this.marketId (symbol),
        }, params));
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        let method = 'privatePostMy' + this.capitalize (side);
        if (type === 'market')
            throw new ExchangeError (this.id + ' allows limit orders only');
        let order = {
            'cointype': this.marketId (symbol),
            'amount': amount,
            'rate': price,
        };
        return this[method] (this.extend (order, params));
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        throw new NotSupported (this.id + ' cancelOrder () is not fully implemented yet');
        // let method = 'privatePostMyBuy';
        // return await this[method] ({ 'id': id });
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        if (!this.apiKey)
            throw new AuthenticationError (this.id + ' requires apiKey for all requests');
        let url = this.urls['api'][api] + '/' + path;
        if (api === 'private') {
            this.checkRequiredCredentials ();
            let nonce = this.nonce ();
            body = this.json (this.extend ({ 'nonce': nonce }, params));
            headers = {
                'Content-Type': 'application/json',
                'key': this.apiKey,
                'sign': this.hmac (this.encode (body), this.encode (this.secret), 'sha512'),
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }
};
<commit_msg>coinspot cleanup for eslint curly<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError, AuthenticationError, NotSupported } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class coinspot extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'coinspot',
            'name': 'CoinSpot',
            'countries': [ 'AU' ], // Australia
            'rateLimit': 1000,
            'has': {
                'CORS': false,
                'createMarketOrder': false,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/28208429-3cacdf9a-6896-11e7-854e-4c79a772a30f.jpg',
                'api': {
                    'public': 'https://www.coinspot.com.au/pubapi',
                    'private': 'https://www.coinspot.com.au/api',
                },
                'www': 'https://www.coinspot.com.au',
                'doc': 'https://www.coinspot.com.au/api',
                'referral': 'https://www.coinspot.com.au/join/FSM11C',
            },
            'api': {
                'public': {
                    'get': [
                        'latest',
                    ],
                },
                'private': {
                    'post': [
                        'orders',
                        'orders/history',
                        'my/coin/deposit',
                        'my/coin/send',
                        'quote/buy',
                        'quote/sell',
                        'my/balances',
                        'my/orders',
                        'my/buy',
                        'my/sell',
                        'my/buy/cancel',
                        'my/sell/cancel',
                    ],
                },
            },
            'markets': {
                'BTC/AUD': { 'id': 'btc', 'symbol': 'BTC/AUD', 'base': 'BTC', 'quote': 'AUD', 'baseId': 'btc', 'quoteId': 'aud' },
                'LTC/AUD': { 'id': 'ltc', 'symbol': 'LTC/AUD', 'base': 'LTC', 'quote': 'AUD', 'baseId': 'ltc', 'quoteId': 'aud' },
                'DOGE/AUD': { 'id': 'doge', 'symbol': 'DOGE/AUD', 'base': 'DOGE', 'quote': 'AUD', 'baseId': 'doge', 'quoteId': 'aud' },
            },
            'commonCurrencies': {
                'DRK': 'DASH',
            },
        });
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        const response = await this.privatePostMyBalances (params);
        const result = { 'info': response };
        if ('balance' in response) {
            const balances = response['balance'];
            const currencyIds = Object.keys (balances);
            for (let i = 0; i < currencyIds.length; i++) {
                const currencyId = currencyIds[i];
                const uppercase = currencyId.toUpperCase ();
                const code = this.commonCurrencyCode (uppercase);
                let account = {
                    'free': balances[currencyId],
                    'used': 0.0,
                    'total': balances[currencyId],
                };
                result[code] = account;
            }
        }
        return this.parseBalance (result);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'cointype': market['id'],
        };
        const orderbook = await this.privatePostOrders (this.extend (request, params));
        return this.parseOrderBook (orderbook, undefined, 'buyorders', 'sellorders', 'rate', 'amount');
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        const response = await this.publicGetLatest (params);
        let id = this.marketId (symbol);
        id = id.toLowerCase ();
        const ticker = response['prices'][id];
        const timestamp = this.milliseconds ();
        const last = this.safeFloat (ticker, 'last');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': undefined,
            'low': undefined,
            'bid': this.safeFloat (ticker, 'bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': undefined,
            'baseVolume': undefined,
            'quoteVolume': undefined,
            'info': ticker,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'cointype': this.marketId (symbol),
        };
        return await this.privatePostOrdersHistory (this.extend (request, params));
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        const method = 'privatePostMy' + this.capitalize (side);
        if (type === 'market') {
            throw new ExchangeError (this.id + ' allows limit orders only');
        }
        const request = {
            'cointype': this.marketId (symbol),
            'amount': amount,
            'rate': price,
        };
        return await this[method] (this.extend (request, params));
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        throw new NotSupported (this.id + ' cancelOrder () is not fully implemented yet');
        // let method = 'privatePostMyBuy';
        // return await this[method] ({ 'id': id });
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        if (!this.apiKey) {
            throw new AuthenticationError (this.id + ' requires apiKey for all requests');
        }
        const url = this.urls['api'][api] + '/' + path;
        if (api === 'private') {
            this.checkRequiredCredentials ();
            const nonce = this.nonce ();
            body = this.json (this.extend ({ 'nonce': nonce }, params));
            headers = {
                'Content-Type': 'application/json',
                'key': this.apiKey,
                'sign': this.hmac (this.encode (body), this.encode (this.secret), 'sha512'),
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }
};
<|endoftext|>


<commit_before>var hasNativePE = window.PointerEvent || window.MSPointerEvent;
if (!hasNativePE) {
  import(/* webpackChunkName: "pepjs"*/ 'pepjs')
}

import { ENV } from '../constants.js'

import Scrambo from 'scrambo'
import './style.css'

const APP_DEBUG = false;
const MOVEMENT_THRESHOLD = 5;
const STARTING_THRESHOLD = 1000;
const READY_THRESHOLD = 100;

const COLOURS = [
  'green', 'blue', 'red', 'orange', 'yellow', 'white'
];

function randomColor() {
  return COLOURS[Math.floor(Math.random() * COLOURS.length)]
}

function hashCode(string) {
  var hash = 0, i, chr, len;
    /* istanbul ignore if */
  if (string.length === 0) return hash;
  for (i = 0, len = string.length; i < len; i++) {
    chr   = string.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
}

function uuidv4() {
  return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  )
}

function debug (attributes) {
  if (APP_DEBUG) {
    console.log(attributes)
  }
}

function bodyOrContext(element) {
  var activeElement = document.activeElement;
  return (
    activeElement === element ||
    activeElement === document.body
  )
}

function addKeyListener(context, keyCode, handleDown, handleUp) {
  var isKeydown = false // Ensure repeat keys are not triggered
  document.addEventListener('keydown', event => {
    if (isKeydown) {
      return;
    }
    isKeydown = true;
    if (event.keyCode === keyCode && bodyOrContext(context)) {
      handleDown(event);
      event.preventDefault();
    }
  }, false)
  document.addEventListener('keyup', event => {
    isKeydown = false;
    if (event.keyCode === keyCode && bodyOrContext(context)) {
      handleUp(event);
      event.preventDefault();
    }
  }, false)
}

function Timer(callback) {
  var readyTime = -1
  var startTime = -1
  var endTime = -1
  var currentTime = -1

  var state = 'idle'

  var $root = document.documentElement
  var $timer = document.querySelector('.js-timer')

  var timerOriginalClassName = $timer.className.slice(0)

  $timer.addEventListener('pointerdown', handlePointerDown)
  $timer.addEventListener('pointerup', handlePointerUp)

  addKeyListener($timer, 32, handlePointerDown, handlePointerUp)
  addKeyListener($timer, 13, handlePointerDown, handlePointerUp)

  if (window.DeviceMotionEvent) {
    window.addEventListener("devicemotion", function(event) {
      var movement = Math.abs(event.acceleration.z)

      var hasWaitedAfterStarting = ((currentTime - startTime) > STARTING_THRESHOLD)

      if (movement >= MOVEMENT_THRESHOLD) {
        if (state === 'running' && hasWaitedAfterStarting) {
          callback(currentTime - startTime)
          stopTimer()
          debug('DeviceMotionEvent:down:stopTimer()')
        }
      }
    }, true);
  }

  function handlePointerDown () {
    if (state === 'running') {
      callback(currentTime - startTime)
      stopTimer()
      debug('down:stopTimer()')
    } else {
      readyTimer()
      debug('down:readyTimer()')
    }
  }

  function handlePointerUp (event) {
    // See if they have waited after first pressing down
    var hasWaitedBeforeStarting = ((currentTime - readyTime) > READY_THRESHOLD)
    hasWaitedBeforeStarting = true
    if (state === 'ready' && hasWaitedBeforeStarting) {
      startTimer()
      debug('up:startTimer()')
    } else {
      stopTimer()
      debug('up:stopTimer()')
    }
  }

  function readyTimer () {
    state = 'ready'
    readyTime = currentTime
    startTime = 0
    endTime = 0
  }

  function startTimer () {
    state = 'running'
    startTime = currentTime
  }

  function stopTimer () {
    state = 'idle'
    endTime = currentTime
  }

  function getTimestamp () {
    var hasPerformanceApi = (
      window.performance &&
      window.performance.now &&
      window.performance.timing &&
      window.performance.timing.navigationStart
    )
    if (hasPerformanceApi) {
      return window.performance.now() + window.performance.timing.navigationStart
    }
    return Date.now()
  }

  function updateCurrentTime () {
    currentTime = getTimestamp()
  }

  function render () {
    if (state === 'ready') {
      $timer.innerHTML = formatTimestamp(0)
    }
    if (state === 'running') {
      $timer.innerHTML = formatTimestamp(
        currentTime - startTime
      )
    }

    $timer.className = `${timerOriginalClassName} timer--${state}`
  }

  (function renderLoop () {
    updateCurrentTime()
    render()
    window.requestAnimationFrame(renderLoop)
  })()
}

function formatTimestamp (timestamp) {
  return (timestamp / 1000).toFixed(3)
}

var $scrambleOutput = document.querySelector('.js-scramble-output')
var scrambleSeed = $scrambleOutput.getAttribute('data-seed');
var threebythree = new Scrambo();
var currentScramble

function renderScramble () {
  currentScramble = threebythree.get()
  $scrambleOutput.innerHTML = currentScramble
}

var times = JSON.parse(window.localStorage.getItem('times')) || []
var $timesOutput = document.querySelector('.js-times-output')
function renderTimes () {
  const averageOfFive = 5;

  function renderTimes (time) {
    return `

        ${time.timestamp}
        ${time.id}

        ${time.scramble}

        <button id="${time.id}" class="js-delete-button button--danger">Delete</button>

    `
  }

  var chunkedTimes = chunkArray(times, averageOfFive)
    .map(chunk => {
      if (chunk.length === averageOfFive) {
        return `

            ${averageArray(chunk.map(time => time.timestamp))} (average of five)

              ${chunk.map(renderTimes).join('')}

`
      }
      return `<li>${chunk.map(renderTimes).join('')}</li>`
    })

  let deleteAllButtonHTML = `
    <button class="js-delete-all-button button--danger">Delete all</button>
  `

  $timesOutput.innerHTML = `
    ${chunkedTimes.reverse().join('')}
    ${(times.length > 1) ? deleteAllButtonHTML : ''}
  `
}

function averageArray(array) {
  var length = array.length;
  // TODO: Change from this hacky way to ensure no floats
  var decimalPlaceBuffer = 3;
  var bufferToInteger = 10 * decimalPlaceBuffer;
  var arraySum = 0;
  for (var i = 0; i < length; i++){
    arraySum += parseInt(array[i] * bufferToInteger, 10);
  }

  return ((arraySum / length) / bufferToInteger).toFixed(decimalPlaceBuffer);
}

function chunkArray (array, size) {
  var chunkedArray = [];
  for (var i = 0, length = array.length; i < length; i += size) {
    chunkedArray.push(
      array.slice(i, i + size)
    );
  }
  return chunkedArray;
}

function randomiseCube() {
  const logoCubies = document.querySelectorAll('.logo__cubie');

  const middleCubieIndex = 4

  logoCubies.forEach((logoCubie, i) => {
    const isMiddleCubie = i === middleCubieIndex
    const cubieColor = isMiddleCubie ? 'green' : randomColor()
    logoCubie.classList.add(`logo__cubie--${cubieColor}`);
  })
}

document.addEventListener('click', event => {
  const target = event.target
  if (!target) {
    return;
  }
  if (target.classList.contains('js-delete-button')){
    const id = target.id
    times = times.filter(time => time.id !== id);
    window.localStorage.setItem('times', JSON.stringify(times))
    renderTimes()
  }
  if (target.classList.contains('js-delete-all-button')){
    if (window.confirm('Are you sure you want to delete all your times?')) {
      // TODO: Replace this with an undo mode
      times = [];
      window.localStorage.setItem('times', JSON.stringify(times))
      renderTimes()
    }
  }
})

document.addEventListener('DOMContentLoaded', () => {
  randomiseCube()
  if ($scrambleOutput.textContent.includes('{{', '}}')) {
    renderScramble()
  }
  renderTimes()

  Timer(timestamp => {
    times.push(
      {
        id: uuidv4(),
        scramble: currentScramble,
        timestamp: formatTimestamp(timestamp)
      }
    )
    window.localStorage.setItem('times', JSON.stringify(times))
    renderScramble()
    renderTimes()
  })
})<commit_msg>Make sure space cannot scroll the screen<commit_after>var hasNativePE = window.PointerEvent || window.MSPointerEvent;
if (!hasNativePE) {
  import(/* webpackChunkName: "pepjs"*/ 'pepjs')
}

import { ENV } from '../constants.js'

import Scrambo from 'scrambo'
import './style.css'

const APP_DEBUG = false;
const MOVEMENT_THRESHOLD = 5;
const STARTING_THRESHOLD = 1000;
const READY_THRESHOLD = 100;

const COLOURS = [
  'green', 'blue', 'red', 'orange', 'yellow', 'white'
];

function randomColor() {
  return COLOURS[Math.floor(Math.random() * COLOURS.length)]
}

function hashCode(string) {
  var hash = 0, i, chr, len;
    /* istanbul ignore if */
  if (string.length === 0) return hash;
  for (i = 0, len = string.length; i < len; i++) {
    chr   = string.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
}

function uuidv4() {
  return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
    (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
  )
}

function debug (attributes) {
  if (APP_DEBUG) {
    console.log(attributes)
  }
}

function bodyOrContext(element) {
  var activeElement = document.activeElement;
  return (
    activeElement === element ||
    activeElement === document.body
  )
}

function addKeyListener(context, keyCode, handleDown, handleUp) {
  var isKeydown = false // Ensure repeat keys are not triggered
  document.addEventListener('keydown', event => {
    if (event.keyCode === keyCode && bodyOrContext(context)) {
      event.preventDefault();
      if (isKeydown) {
        return;
      }
      handleDown(event);
    }
    isKeydown = true;
  }, false)
  document.addEventListener('keyup', event => {
    isKeydown = false;
    if (event.keyCode === keyCode && bodyOrContext(context)) {
      handleUp(event);
      event.preventDefault();
    }
  }, false)
}

function Timer(callback) {
  var readyTime = -1
  var startTime = -1
  var endTime = -1
  var currentTime = -1

  var state = 'idle'

  var $root = document.documentElement
  var $timer = document.querySelector('.js-timer')

  var timerOriginalClassName = $timer.className.slice(0)

  $timer.addEventListener('pointerdown', handlePointerDown)
  $timer.addEventListener('pointerup', handlePointerUp)

  addKeyListener($timer, 32, handlePointerDown, handlePointerUp)
  addKeyListener($timer, 13, handlePointerDown, handlePointerUp)

  if (window.DeviceMotionEvent) {
    window.addEventListener("devicemotion", function(event) {
      var movement = Math.abs(event.acceleration.z)

      var hasWaitedAfterStarting = ((currentTime - startTime) > STARTING_THRESHOLD)

      if (movement >= MOVEMENT_THRESHOLD) {
        if (state === 'running' && hasWaitedAfterStarting) {
          callback(currentTime - startTime)
          stopTimer()
          debug('DeviceMotionEvent:down:stopTimer()')
        }
      }
    }, true);
  }

  function handlePointerDown () {
    if (state === 'running') {
      callback(currentTime - startTime)
      stopTimer()
      debug('down:stopTimer()')
    } else {
      readyTimer()
      debug('down:readyTimer()')
    }
  }

  function handlePointerUp (event) {
    // See if they have waited after first pressing down
    var hasWaitedBeforeStarting = ((currentTime - readyTime) > READY_THRESHOLD)
    hasWaitedBeforeStarting = true
    if (state === 'ready' && hasWaitedBeforeStarting) {
      startTimer()
      debug('up:startTimer()')
    } else {
      stopTimer()
      debug('up:stopTimer()')
    }
  }

  function readyTimer () {
    state = 'ready'
    readyTime = currentTime
    startTime = 0
    endTime = 0
  }

  function startTimer () {
    state = 'running'
    startTime = currentTime
  }

  function stopTimer () {
    state = 'idle'
    endTime = currentTime
  }

  function getTimestamp () {
    var hasPerformanceApi = (
      window.performance &&
      window.performance.now &&
      window.performance.timing &&
      window.performance.timing.navigationStart
    )
    if (hasPerformanceApi) {
      return window.performance.now() + window.performance.timing.navigationStart
    }
    return Date.now()
  }

  function updateCurrentTime () {
    currentTime = getTimestamp()
  }

  function render () {
    if (state === 'ready') {
      $timer.innerHTML = formatTimestamp(0)
    }
    if (state === 'running') {
      $timer.innerHTML = formatTimestamp(
        currentTime - startTime
      )
    }

    $timer.className = `${timerOriginalClassName} timer--${state}`
  }

  (function renderLoop () {
    updateCurrentTime()
    render()
    window.requestAnimationFrame(renderLoop)
  })()
}

function formatTimestamp (timestamp) {
  return (timestamp / 1000).toFixed(3)
}

var $scrambleOutput = document.querySelector('.js-scramble-output')
var scrambleSeed = $scrambleOutput.getAttribute('data-seed');
var threebythree = new Scrambo();
var currentScramble

function renderScramble () {
  currentScramble = threebythree.get()
  $scrambleOutput.innerHTML = currentScramble
}

var times = JSON.parse(window.localStorage.getItem('times')) || []
var $timesOutput = document.querySelector('.js-times-output')
function renderTimes () {
  const averageOfFive = 5;

  function renderTimes (time) {
    return `

        ${time.timestamp}
        ${time.id}

        ${time.scramble}

        <button id="${time.id}" class="js-delete-button button--danger">Delete</button>

    `
  }

  var chunkedTimes = chunkArray(times, averageOfFive)
    .map(chunk => {
      if (chunk.length === averageOfFive) {
        return `

            ${averageArray(chunk.map(time => time.timestamp))} (average of five)

              ${chunk.map(renderTimes).join('')}

`
      }
      return `<li>${chunk.map(renderTimes).join('')}</li>`
    })

  let deleteAllButtonHTML = `
    <button class="js-delete-all-button button--danger">Delete all</button>
  `

  $timesOutput.innerHTML = `
    ${chunkedTimes.reverse().join('')}
    ${(times.length > 1) ? deleteAllButtonHTML : ''}
  `
}

function averageArray(array) {
  var length = array.length;
  // TODO: Change from this hacky way to ensure no floats
  var decimalPlaceBuffer = 3;
  var bufferToInteger = 10 * decimalPlaceBuffer;
  var arraySum = 0;
  for (var i = 0; i < length; i++){
    arraySum += parseInt(array[i] * bufferToInteger, 10);
  }

  return ((arraySum / length) / bufferToInteger).toFixed(decimalPlaceBuffer);
}

function chunkArray (array, size) {
  var chunkedArray = [];
  for (var i = 0, length = array.length; i < length; i += size) {
    chunkedArray.push(
      array.slice(i, i + size)
    );
  }
  return chunkedArray;
}

function randomiseCube() {
  const logoCubies = document.querySelectorAll('.logo__cubie');

  const middleCubieIndex = 4

  logoCubies.forEach((logoCubie, i) => {
    const isMiddleCubie = i === middleCubieIndex
    const cubieColor = isMiddleCubie ? 'green' : randomColor()
    logoCubie.classList.add(`logo__cubie--${cubieColor}`);
  })
}

document.addEventListener('click', event => {
  const target = event.target
  if (!target) {
    return;
  }
  if (target.classList.contains('js-delete-button')){
    const id = target.id
    times = times.filter(time => time.id !== id);
    window.localStorage.setItem('times', JSON.stringify(times))
    renderTimes()
  }
  if (target.classList.contains('js-delete-all-button')){
    if (window.confirm('Are you sure you want to delete all your times?')) {
      // TODO: Replace this with an undo mode
      times = [];
      window.localStorage.setItem('times', JSON.stringify(times))
      renderTimes()
    }
  }
})

document.addEventListener('DOMContentLoaded', () => {
  randomiseCube()
  if ($scrambleOutput.textContent.includes('{{', '}}')) {
    renderScramble()
  }
  renderTimes()

  Timer(timestamp => {
    times.push(
      {
        id: uuidv4(),
        scramble: currentScramble,
        timestamp: formatTimestamp(timestamp)
      }
    )
    window.localStorage.setItem('times', JSON.stringify(times))
    renderScramble()
    renderTimes()
  })
})<|endoftext|>


<commit_before>/* ========================================================================
 * Bootstrap: collapse.js v3.0.0
 * http://twitter.github.com/bootstrap/javascript.html#collapse
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */

+function ($) { "use strict";

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.transitioning = null

    if (this.options.parent) this.$parent = $(this.options.parent)
    if (this.options.toggle) this.toggle()
  }

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var dimension = this.dimension()
    var scroll    = $.camelCase(['scroll', dimension].join('-'))
    var actives   = this.$parent && this.$parent.find('> .accordion-group > .in')

    if (actives && actives.length) {
      var hasData = actives.data('collapse')
      if (hasData && hasData.transitioning) return
      actives.collapse('hide')
      hasData || actives.data('collapse', null)
    }

    this.$element[dimension](0)
    this.transition('addClass', $.Event('show.bs.collapse'), 'shown.bs.collapse')

    if ($.support.transition) this.$element[dimension](this.$element[0][scroll])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return
    var dimension = this.dimension()
    this.reset(this.$element[dimension]())
    this.transition('removeClass', $.Event('hide.bs.collapse'), 'hidden')
    this.$element[dimension](0)
  }

  Collapse.prototype.reset = function (size) {
    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      [dimension](size || 'auto')
      [0].offsetWidth

    this.$element[size != null ? 'addClass' : 'removeClass']('collapse')

    return this
  }

  Collapse.prototype.transition = function (method, startEvent, completeEvent) {
    var that     = this
    var complete = function () {
      if (startEvent.type == 'show') that.reset()
      that.transitioning = 0
      that.$element.trigger(completeEvent)
    }

    this.$element.trigger(startEvent)

    if (startEvent.isDefaultPrevented()) return

    this.transitioning = 1

    this.$element[method]('in')

    $.support.transition && this.$element.hasClass('collapse') ?
      this.$element.one($.support.transition.end, complete) :
      complete()
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  var old = $.fn.collapse

  $.fn.collapse = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.collapse.Constructor = Collapse

  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }

  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
    var $this  = $(this), href
    var target = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
    var option = $(target).data('collapse') ? 'toggle' : $this.data()
    var parent = $this.attr('data-parent')
    var $parent = parent && $(parent)

    if ($parent) $parent.find('[data-toggle=collapse][data-parent=' + parent + ']').not($this).addClass('collapsed')
    $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
    $(target).collapse(option)
  })

}(window.jQuery);
<commit_msg>maybe fix this old ass issue #5973<commit_after>/* ========================================================================
 * Bootstrap: collapse.js v3.0.0
 * http://twitter.github.com/bootstrap/javascript.html#collapse
 * ========================================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================================== */

+function ($) { "use strict";

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.transitioning = null

    if (this.options.parent) this.$parent = $(this.options.parent)
    if (this.options.toggle) this.toggle()
  }

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()
    var scroll    = $.camelCase(['scroll', dimension].join('-'))
    var actives   = this.$parent && this.$parent.find('> .accordion-group > .in')

    if (actives && actives.length) {
      var hasData = actives.data('collapse')
      if (hasData && hasData.transitioning) return
      actives.collapse('hide')
      hasData || actives.data('collapse', null)
    }

    this.$element[dimension](0)
    this.transition('addClass', 'shown.bs.collapse')

    if ($.support.transition) this.$element[dimension](this.$element[0][scroll])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()
    this.reset(this.$element[dimension]())
    this.transition('removeClass', 'shown.bs.hidden')
    this.$element[dimension](0)
  }

  Collapse.prototype.reset = function (size) {
    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      [dimension](size || 'auto')
      [0].offsetWidth

    this.$element[size != null ? 'addClass' : 'removeClass']('collapse')

    return this
  }

  Collapse.prototype.transition = function (method, completeEvent) {
    var that     = this
    var complete = function () {
      if (completeEvent == 'shown.bs.collapse') that.reset()
      that.transitioning = 0
      that.$element.trigger(completeEvent)
    }

    this.transitioning = 1

    this.$element[method]('in')

    $.support.transition && this.$element.hasClass('collapse') ?
      this.$element.one($.support.transition.end, complete) :
      complete()
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  var old = $.fn.collapse

  $.fn.collapse = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data) $this.data('collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.collapse.Constructor = Collapse

  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }

  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {
    var $this  = $(this), href
    var target = $this.attr('data-target')
        || e.preventDefault()
        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
    var option = $(target).data('collapse') ? 'toggle' : $this.data()
    var parent = $this.attr('data-parent')
    var $parent = parent && $(parent)

    if ($parent) $parent.find('[data-toggle=collapse][data-parent=' + parent + ']').not($this).addClass('collapsed')
    $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
    $(target).collapse(option)
  })

}(window.jQuery);
<|endoftext|>


<commit_before>import React from 'react';

import GifPlayer from './GifPlayer';

const preloadGif = src => {
  new Image().src = src;
};

class GifPlayerContainer extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      playing: false
    };
    if (props.gif) {
      preloadGif(props.gif);
    }
  }

  componentDidMount (nextProps) {
    const oldGif = this.props.gif;
    const newGif = nextProps.gif;
    if (newGif && oldGif !== newGif) {
      preloadGif(newGif);
    }
  }

  toggle () {
    this.setState({
      playing: !this.state.playing
    });
  }

  render () {
    return (
      <GifPlayer
        {...this.props}
        playing={this.state.playing}
        toggle={() => this.toggle()}
      />
    );
  }
}

GifPlayerContainer.propTypes = {
  gif: React.PropTypes.string,
  still: React.PropTypes.string
};

module.exports = GifPlayerContainer;
<commit_msg>Cleaned up bugs in GifPlayerContainer.<commit_after>import React from 'react';

import GifPlayer from './GifPlayer';

const preloadGif = src => {
  new Image().src = src;
};

class GifPlayerContainer extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      playing: false
    };
  }

  componentDidMount() {
    const { gif } = this.props;
    if (gif) {
      preloadGif(gif);
    }
  }

  componentWillReceiveProps (nextProps) {
    const oldGif = this.props.gif;
    const newGif = nextProps.gif;
    if (newGif && oldGif !== newGif) {
      preloadGif(newGif);
    }
  }

  toggle () {
    this.setState({
      playing: !this.state.playing
    });
  }

  render () {
    return (
      <GifPlayer
        {...this.props}
        playing={this.state.playing}
        toggle={() => this.toggle()}
      />
    );
  }
}

GifPlayerContainer.propTypes = {
  gif: React.PropTypes.string,
  still: React.PropTypes.string
};

module.exports = GifPlayerContainer;
<|endoftext|>


<commit_before>/* ========================================================================
 * Bootstrap: collapse.js v3.3.6
 * http://getbootstrap.com/javascript/#collapse
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */

/* jshint latedef: false */

+function ($) {
  'use strict';

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
    this.transitioning = null

    if (this.options.parent) {
      this.$parent = this.getParent()
    } else {
      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
    }

    if (this.options.toggle) this.toggle()
  }

  Collapse.VERSION  = '3.3.6'

  Collapse.TRANSITION_DURATION = 350

  Collapse.DEFAULTS = {
    toggle: true
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var activesData
    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')

    if (actives && actives.length) {
      activesData = actives.data('bs.collapse')
      if (activesData && activesData.transitioning) return
    }

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    if (actives && actives.length) {
      Plugin.call(actives, 'hide')
      activesData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()

    this.$element
      .removeClass('collapse')
      .addClass('collapsing')[dimension](0)
      .attr('aria-expanded', true)

    this.$trigger
      .removeClass('collapsed')
      .attr('aria-expanded', true)

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass('collapsing')
        .addClass('collapse in')[dimension]('')
      this.transitioning = 0
      this.$element
        .trigger('shown.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    var scrollSize = $.camelCase(['scroll', dimension].join('-'))

    this.$element
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()

    this.$element[dimension](this.$element[dimension]())[0].offsetHeight

    this.$element
      .addClass('collapsing')
      .removeClass('collapse in')
      .attr('aria-expanded', false)

    this.$trigger
      .addClass('collapsed')
      .attr('aria-expanded', false)

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .removeClass('collapsing')
        .addClass('collapse')
        .trigger('hidden.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    this.$element
      [dimension](0)
      .one('bsTransitionEnd', $.proxy(complete, this))
      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  Collapse.prototype.getParent = function () {
    return $(this.options.parent)
      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
      .each($.proxy(function (i, element) {
        var $element = $(element)
        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
      }, this))
      .end()
  }

  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
    var isOpen = $element.hasClass('in')

    $element.attr('aria-expanded', isOpen)
    $trigger
      .toggleClass('collapsed', !isOpen)
      .attr('aria-expanded', isOpen)
  }

  function getTargetFromTrigger($trigger) {
    var href
    var target = $trigger.attr('data-target')
      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7

    return $(target)
  }

  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.collapse

  $.fn.collapse             = Plugin
  $.fn.collapse.Constructor = Collapse

  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }

  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
    var $this   = $(this)

    if (!$this.attr('data-target')) e.preventDefault()

    var $target = getTargetFromTrigger($this)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()

    Plugin.call($target, option)
  })

}(jQuery);
<commit_msg>Şu özellikler eklendi:<commit_after>/* ========================================================================
 * Bootstrap: collapse.js v3.3.6
 * http://getbootstrap.com/javascript/#collapse
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */

/* jshint latedef: false */

+function ($) {
  'use strict';

  // COLLAPSE PUBLIC CLASS DEFINITION
  // ================================

  var Collapse = function (element, options) {
    this.$element      = $(element)
    this.options       = $.extend({}, Collapse.DEFAULTS, options)
    this.$trigger      = $(this.options.trigger || ('[data-toggle="collapse"][href="#' + element.id + '"],' + '[data-toggle="collapse"][data-target="#' + element.id + '"]'))
    this.transitioning = null

    if (this.options.parent) {
      this.$parent = this.getParent()
    } else {
      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
    }

    if (this.options.toggle) this.toggle()
  }

  Collapse.VERSION  = '3.3.6'

  Collapse.TRANSITION_DURATION = 350

  Collapse.DEFAULTS = {
    toggle: true,
    skipTransition: false,
    trigger: null
  }

  Collapse.prototype.dimension = function () {
    var hasWidth = this.$element.hasClass('width')
    return hasWidth ? 'width' : 'height'
  }

  Collapse.prototype.show = function () {
    if (this.transitioning || this.$element.hasClass('in')) return

    var activesData
    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')

    if (actives && actives.length) {
      activesData = actives.data('bs.collapse')
      if (activesData && activesData.transitioning) return
    }

    var startEvent = $.Event('show.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    if (actives && actives.length) {
      Plugin.call(actives, 'hide')
      activesData || actives.data('bs.collapse', null)
    }

    var dimension = this.dimension()
    var skipTransition = this.options.skipTransition === true
    var collapsingCls = skipTransition ? '' : 'collapsing'

    this.$element
      .removeClass('collapse')
      .addClass(collapsingCls)[dimension](0)
      .attr('aria-expanded', true)

    this.$trigger
      .removeClass('collapsed')
      .attr('aria-expanded', true)

    this.transitioning = 1

    var complete = function () {
      this.$element
        .removeClass(collapsingCls)
        .addClass('collapse in')[dimension]('')
      this.transitioning = 0
      this.$element
        .trigger('shown.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    var scrollSize = $.camelCase(['scroll', dimension].join('-'))

    if (skipTransition) {
      complete.call(this)
      this.$element[dimension](this.$element[0][scrollSize])
    } else {
      this.$element
        .one('bsTransitionEnd', $.proxy(complete, this))
        .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
    }
  }

  Collapse.prototype.hide = function () {
    if (this.transitioning || !this.$element.hasClass('in')) return

    var startEvent = $.Event('hide.bs.collapse')
    this.$element.trigger(startEvent)
    if (startEvent.isDefaultPrevented()) return

    var dimension = this.dimension()
    var skipTransition = this.options.skipTransition === true
    var collapsingCls = skipTransition ? '' : 'collapsing'

    this.$element[dimension](this.$element[dimension]())[0].offsetHeight

    this.$element
      .addClass(collapsingCls)
      .removeClass('collapse in')
      .attr('aria-expanded', false)

    this.$trigger
      .addClass('collapsed')
      .attr('aria-expanded', false)

    this.transitioning = 1

    var complete = function () {
      this.transitioning = 0
      this.$element
        .removeClass(collapsingCls)
        .addClass('collapse')
        .trigger('hidden.bs.collapse')
    }

    if (!$.support.transition) return complete.call(this)

    if (skipTransition) {
      this.$element[dimension](0)
      complete.call(this);
    } else {
      this.$element
        [dimension](0)
        .one('bsTransitionEnd', $.proxy(complete, this))
        .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
    }
  }

  Collapse.prototype.toggle = function () {
    this[this.$element.hasClass('in') ? 'hide' : 'show']()
  }

  Collapse.prototype.getParent = function () {
    return $(this.options.parent)
      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
      .each($.proxy(function (i, element) {
        var $element = $(element)
        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
      }, this))
      .end()
  }

  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
    var isOpen = $element.hasClass('in')

    $element.attr('aria-expanded', isOpen)
    $trigger
      .toggleClass('collapsed', !isOpen)
      .attr('aria-expanded', isOpen)
  }

  function getTargetFromTrigger($trigger) {
    var href
    var target = $trigger.attr('data-target')
      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7

    return $(target)
  }

  // COLLAPSE PLUGIN DEFINITION
  // ==========================

  function Plugin(option) {
    return this.each(function () {
      var $this   = $(this)
      var data    = $this.data('bs.collapse')
      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)

      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  var old = $.fn.collapse

  $.fn.collapse             = Plugin
  $.fn.collapse.Constructor = Collapse

  // COLLAPSE NO CONFLICT
  // ====================

  $.fn.collapse.noConflict = function () {
    $.fn.collapse = old
    return this
  }

  // COLLAPSE DATA-API
  // =================

  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
    var $this   = $(this)

    if (!$this.attr('data-target')) e.preventDefault()

    var $target = getTargetFromTrigger($this)
    var data    = $target.data('bs.collapse')
    var option  = data ? 'toggle' : $this.data()

    Plugin.call($target, option)
  })

}(jQuery);
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function Square(props) {
  return (
    <button className="square" onClick={() => props.onClick()}>
      {props.value}
    </button>
  );
}

function Row(props) {
  const squareIndex = props.row * props.NUMBER_OF_COLS;
  const squares = range(squareIndex, squareIndex + props.NUMBER_OF_COLS).map((index) =>
    <Square key={index} value={props.squares[index]} onClick={() => props.onClick(index)} />
  );

  return (

      {squares}

  )
}

function Board(props) {
  const NUMBER_OF_ROWS = 3;
  const NUMBER_OF_COLS = 3;
  const rows = range(0, NUMBER_OF_ROWS).map((index) =>
    <Row key={index}
         row={index}
         squares={props.squares}
         onClick={props.onClick}
         NUMBER_OF_COLS={NUMBER_OF_COLS}
    />
  );
  return (

      {rows}

  );
}

function Status(props) {
  const winner = calculateWinner(props.squares);
  let status;
  if (winner) {
    status = 'Winner: ' + winner;
  } else {
    status = 'Next player: ' + (props.xIsNext ? 'X' : 'O');
  }
  return (

{status}

  )
}

function MoveDescription(props) {
  return (

       props.jumpTo(props.move)}>{props.description};

  )
}

function BoldMoveDescription(props) {
  return (

      <MoveDescription
        move={props.move}
        description={props.description}
        jumpTo={props.jumpTo}
      />

  )
}

function Moves(props) {
  const moves = props.history.map((step, move) => {
    const description = move ?
      'Move ' + moveLocation(step.squareNum) :
      'Game start';
    if (move === props.currentStep) {
      return (
        <BoldMoveDescription
          move={move}
          description={description}
          jumpTo={props.jumpTo}
        />
      );
    }
    return (
      <MoveDescription
        move={move}
        description={description}
        jumpTo={props.jumpTo}
      />
    );
  });
  return (

{moves}

  )
}

function GameInfo(props) {
  return (

      <Status squares={props.squares} xIsNext={props.xIsNext} />
      <Moves history={props.history} jumpTo={props.jumpTo} />

  );
}

class Game extends React.Component {
  constructor() {
    super();
    this.state = {
      history: [{
        squares: Array(9).fill(null)
      }],
      xIsNext: true,
      stepNumber: 0,
    };
  }
  render() {
    const history = this.state.history;
    const current = history[this.state.stepNumber];

    return (

          <Board
            squares={current.squares}
            onClick={(i) => this.handleClick(i)}
          />

        <GameInfo
          history={history}
          squares={current.squares}
          currentStep={this.state.currentStep}
          xIsNext={this.state.xIsNext}
          jumpTo={(move) => this.jumpTo(move)}
        />

    );
  }
  handleClick(i) {
    const stepNumber = this.state.stepNumber;
    const history = this.state.history.slice(0, stepNumber + 1);
    const current = history[history.length - 1];
    const squares = current.squares.slice();
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      history: history.concat([{
        squares: squares,
        squareNum: i,
      }]),
      stepNumber: history.length,
      xIsNext: !this.state.xIsNext,
    });
  }
  jumpTo(step) {
    this.setState({
      stepNumber: step,
      xIsNext: (step % 2) ? false : true,
    });
  }
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

function range(start, end) {
  return Array.from({length: (end - start)}, (v, k) => k + start);
}

function moveLocation(squareNum) {
  return "(" + row(squareNum) + ", " + col(squareNum) + ")";
}

function row(squareNum) {
  return Math.floor(squareNum / 3);
};

function col(squareNum){
  return squareNum % 3
};
<commit_msg>Fix list keys & bold step<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function Square(props) {
  return (
    <button className="square" onClick={() => props.onClick()}>
      {props.value}
    </button>
  );
}

function Row(props) {
  const squareIndex = props.row * props.NUMBER_OF_COLS;
  const squares = range(squareIndex, squareIndex + props.NUMBER_OF_COLS).map((index) =>
    <Square key={index} value={props.squares[index]} onClick={() => props.onClick(index)} />
  );

  return (

      {squares}

  )
}

function Board(props) {
  const NUMBER_OF_ROWS = 3;
  const NUMBER_OF_COLS = 3;
  const rows = range(0, NUMBER_OF_ROWS).map((index) =>
    <Row key={index}
         row={index}
         squares={props.squares}
         onClick={props.onClick}
         NUMBER_OF_COLS={NUMBER_OF_COLS}
    />
  );
  return (

      {rows}

  );
}

function Status(props) {
  const winner = calculateWinner(props.squares);
  const status = winner ?
    'Winner: ' + winner :
    'Next player: ' + (props.xIsNext ? 'X' : 'O')

  return (

{status}

  )
}

function MoveDescription(props) {
  const description = props.move ?
    'Move ' + moveLocation(props.squareNum) :
    'Game start'

  return (

       props.jumpTo(props.move)}>{description}

  )
}

function BoldMoveDescription(props) {
  return (

      <MoveDescription
        move={props.move}
        squareNum={props.squareNum}
        jumpTo={props.jumpTo}
      />

  )
}

function Moves(props) {
  const moves = props.history.map((step, move) => {
    if (move === props.currentStep) {
      return (
        <BoldMoveDescription
          key={move}
          move={move}
          squareNum={step.squareNum}
          jumpTo={props.jumpTo}
        />
      );
    } else {
      return (
        <MoveDescription
          key={move}
          move={move}
          squareNum={step.squareNum}
          jumpTo={props.jumpTo}
        />
      );
    }
  });

  return (

{moves}

  )
}

function GameInfo(props) {
  return (

      <Status squares={props.squares} xIsNext={props.xIsNext} />
      <Moves history={props.history} jumpTo={props.jumpTo} currentStep={props.currentStep}/>

  );
}

class Game extends React.Component {
  constructor() {
    super();
    this.state = {
      history: [{
        squares: Array(9).fill(null)
      }],
      xIsNext: true,
      stepNumber: 0,
    };
  }
  render() {
    const history = this.state.history;
    const current = history[this.state.stepNumber];

    return (

          <Board
            squares={current.squares}
            onClick={(i) => this.handleClick(i)}
          />

        <GameInfo
          history={history}
          squares={current.squares}
          currentStep={this.state.stepNumber}
          xIsNext={this.state.xIsNext}
          jumpTo={(move) => this.jumpTo(move)}
        />

    );
  }
  handleClick(i) {
    const stepNumber = this.state.stepNumber;
    const history = this.state.history.slice(0, stepNumber + 1);
    const current = history[history.length - 1];
    const squares = current.squares.slice();
    if (calculateWinner(squares) || squares[i]) {
      return;
    }
    squares[i] = this.state.xIsNext ? 'X' : 'O';
    this.setState({
      history: history.concat([{
        squares: squares,
        squareNum: i,
      }]),
      stepNumber: history.length,
      xIsNext: !this.state.xIsNext,
    });
  }
  jumpTo(step) {
    this.setState({
      stepNumber: step,
      xIsNext: (step % 2) ? false : true,
    });
  }
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

function range(start, end) {
  return Array.from({length: (end - start)}, (v, k) => k + start);
}

function moveLocation(squareNum) {
  return "(" + row(squareNum) + ", " + col(squareNum) + ")";
}

function row(squareNum) {
  return Math.floor(squareNum / 3);
};

function col(squareNum){
  return squareNum % 3
};
<|endoftext|>