<commit_before>define('components', ['$', 'consts', 'buttons', 'utils'], function($, consts, buttons, utils) {
    'use strict';

    let _createTable = (parent) => {
            let table = consts.DOC.createElement('table'),
                rows = 10,
                columns = 10,
                trRange = utils.range(0, rows, 0),
                tdRange = utils.range(0, columns, 0),
                lettersRange = utils.range('a', 'j', 0);

            table.className = 'panelGamerBoard';

            Array.from(trRange).forEach((x) => {
                let trElement = consts.DOC.createElement('tr');

                if (x === 0) {
                    trElement.className = 'tr' + x;
                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdNumber = consts.DOC.createElement('p');

                        if (s !== 0) {
                            tdElement.className = 'td' + s;
                            tdNumber.innerHTML = s + '';
                            tdElement.appendChild(tdNumber);
                        }

                        trElement.appendChild(tdElement);
                    });
                } else {
                    trElement.className = 'tr' + x;

                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdLetter = consts.DOC.createElement('p'),
                            letter = lettersRange[x - 1];

                        tdElement.className = 'td' + s;
                        tdElement.setAttribute('data-number', s + '');
                        tdElement.setAttribute('data-letter', letter);
                        tdLetter.innerHTML = letter;

                        if (s === 0) {
                            tdElement.appendChild(tdLetter);
                        }
                        trElement.appendChild(tdElement);
                    });
                }

                table.appendChild(trElement);
            });
            _moveShips(table);
            _hoverShips(table);
            return table;
        },
        _tableObject = (table) => {
            let tableObject = {};

            Object.keys(table.childNodes).forEach((x) => {
                if (table.childNodes[x].className !== 'tr0') {
                    let arr = [],
                        selected = [];
                    Object.keys(table.childNodes[x].childNodes).forEach((d) => {
                        if (table.childNodes[x].childNodes[d].className !== 'td0') {
                            arr.push(table.childNodes[x].childNodes[d]);
                        }
                        if (table.childNodes[x].childNodes[d].classList.contains('selected')) {
                            selected.push(table.childNodes[x].childNodes[d]);
                        }
                    });
                    tableObject[table.childNodes[x].className] = {
                        childs: arr,
                        selected: selected
                    };
                    arr = [];
                    selected = [];
                }
            });

            return tableObject;
        },
        _hoverSelected = {},
        _showShip = (element) => {
            // TODO: pending...
        },
        _moveShips = (table) => {
            table.onclick = (e) => {
                let tableObject = _tableObject(table),
                    elementClass = e.target.classList,
                    elementDataName = e.target.getAttribute('data-name') || null,
                    elementParent = e.target.parentNode.className,
                    elementNumber = e.target.getAttribute('data-number');

                Array.from(elementClass).forEach((x) => {
                    if (x === 'selected') {
                        let selectedLen = tableObject[elementParent].selected.length,
                            selecteds = tableObject[elementParent].selected;

                        if (elementDataName !== null && selectedLen > 1) {
                            Array.from(selecteds).forEach((f) => {
                                _hoverSelected = {
                                    name: elementDataName,
                                    position: 'horizontal',
                                    parent: elementParent,
                                    len: selectedLen,
                                    number: elementNumber,
                                    selected: e.target,
                                    hover: true
                                }

                                if (f.classList.contains('selected')) {
                                    f.classList.remove('selected');
                                } else if (f.classList.contains('hover')) {
                                    _showShip(_hoverSelected);
                                }
                            });
                        } else if (elementDataName !== null && selectedLen === 1) {
                            // TODO: pending...
                        }
                    } else {
                        return;
                    }
                });
            };
        },
        _removeSelected = () => {
            let table = consts.DOC.getElementsByClassName('panelGamerBoard');

            Array.from(table[0].childNodes).forEach((tr) => {
                let tds = tr.childNodes;
                Array.from(tds).forEach((td) => {
                    if (td.hasAttribute('class') && td.className !== 'panelGamerBoard' && td.classList.contains('hover')) {
                        $(td).removeClass('selected hover');
                    }
                });
            });

        },
        _hoverShips = (table) => {
            $(table).find('td').hover((e) => {
                let element = e.currentTarget,
                    elementParent = e.currentTarget.parentNode,
                    elementNumber = parseInt(e.currentTarget.getAttribute('data-number')),
                    printSelected = (_hoverSelected.len <= (11 - elementNumber)) ? true : false,
                    len = _hoverSelected.len,
                    i = 0;

                if (elementParent.className !== 'tr0' && element.className !== 'td0' && _hoverSelected.hasOwnProperty('name')) {
                    _removeSelected();

                    if (printSelected) {
                        for (i; i < len; i++) {
                            let selected = $('.td' + elementNumber);

                            if (selected.parent().hasClass(elementParent.className)) {
                                $('.' + elementParent.className).find(selected).addClass('selected hover');
                                $('.' + elementParent.className).find(selected).attr('data-name', _hoverSelected.name);
                                elementNumber++;
                            }
                        }
                    }
                }
            });
        },
        _shipSelected = {},
        _positionSelected = null,
        _checkTds = (trChilds, range) => {
            let table = {},
                arr = [];

            Array.from(trChilds).forEach((x) => {
                let arr = [],
                    name = [];
                Array.from(x.childNodes).forEach((f) => {
                    if (f.className !== 'td0') arr.push(f);
                    if (f.hasAttribute('data-name')) name.push(f);
                });
                table[x.className] = {
                    childs: arr,
                    childsShips: name
                };
            });
            return table;
        },
        _changeVerticalBox = (trs, range, name) => {
            let i = 0,
                arr = {},
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < range.length) {
                    arr[x] = trs[x];
                    i++;
                }
            });

            if (i === range.length) {
                Object.keys(arr).forEach((d) => {
                    let arrChild = arr[d].childs[0];
                    arrChild.className += ' selected';
                    arrChild.setAttribute('data-name', name);
                });
                menuGamer.removeElement(name);
            } else {
                let message = 'Move your ships form place more.';
                utils.message('green', message);
            }
        },
        _verticalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeVerticalBox(_resultTrs, _range, name);
        },
        _changeHorizontalBox = (trs, range, name) => {
            let i = 0,
                d = 0,
                arr = {},
                firstChild = null,
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < 1) {
                    firstChild = x;
                    arr[x] = trs[x];
                    i++;
                }
            });
            Array.from(arr[firstChild].childs).forEach((j) => {
                let arrChilds = arr[firstChild].childs;
                if (d < range.length) {
                    j.className += ' selected';
                    j.setAttribute('data-name', name);
                    d++;
                }
            });
            menuGamer.removeElement(name);
        },
        _horizontalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeHorizontalBox(_resultTrs, _range, name);
        },
        _placeShip = (ship, position) => {
            let num = 0,
                result = {},
                defaultPosition = (position !== null) ? position : 'horizontal',
                defaultShip = () => {
                    let select = consts.DOC.getElementById('gamerSelect');
                    Object.keys(select.childNodes).forEach((x) => {
                        if (select.hasOwnProperty(x) && num < 1) {
                            let selected = select.childNodes[x];
                            result.value = selected.value;
                            result.name = selected.getAttribute('data-name');
                            result.boxes = selected.getAttribute('data-box');
                            num++;
                        }
                    });
                    return result;
                },
                shipSelected = (typeof ship === 'object' && Object.keys(ship).length !== 0) ? ship : defaultShip();

            if (shipSelected.value && defaultPosition) {
                switch (defaultPosition) {
                    case 'vertical':
                        _verticalShip(shipSelected.boxes, shipSelected.name);
                        break;
                    case 'horizontal':
                        _horizontalShip(shipSelected.boxes, shipSelected.name);
                        break;
                }
            } else {
                let message = 'You must choose one ship and the position you want to place it.';
                utils.message('red', message);
            }
            _shipSelected = {};
            _positionSelected = null;
        };

    class _GameMenu {
        constructor() {
            this.gameMenu = consts.DOC.createElement('div');
            this.gameMenu.id = 'gameMenu';
        }
        getParent() {
            return consts.DOC.getElementById('parentContainer');
        }
        getGameMenu() {
            return this.gameMenu;
        }
        appendMenu(parent) {
            parent.appendChild(this.gameMenu);
        }
    }

    class _StartButtons {
        constructor() {
            this.start = buttons.START;
            this.load = buttons.LOAD;
            this.exit = buttons.EXIT;
            this.options = buttons.OPTIONS;
        }
        appendStartButton(parent) {
            parent.appendChild(this.start);
        }
        appendLoadButton(parent) {
            parent.appendChild(this.load);
        }
        appendExitButton(parent) {
            parent.appendChild(this.exit);
        }
        appendOptionsButton(parent) {
            parent.appendChild(this.options);
        }
    }

    class _GameContainer {
        constructor() {
            this.gameContainer = consts.DOC.createElement('div');
            this.gameContainer.id = 'gameContainer';
        }
        getGameContainer() {
            return this.gameContainer;
        }
        appendGameContainer(parent) {
            parent.appendChild(this.gameContainer);
        }
    }

    class _MenuGamer {
        constructor() {
            this.menuGamer = consts.DOC.createElement('div');
            this.menuGamer.id = 'menuGamer';
        }
        getMenuGamer() {
            return this.menuGamer;
        }
        removeElement(element) {
            let select = consts.DOC.getElementById('gamerSelect');
            Object.keys(select.childNodes).forEach((x) => {
                if (select.childNodes[x]) {
                    let dataName = select.childNodes[x].getAttribute('data-name');
                    if (dataName === element) {
                        select.remove(select.selectedIndex);
                    }
                }
            });
        }
        shipsMenu() {
            let ships = {
                    aircraftCarrier: {
                        name: 'Aircraft Carrier',
                        boxes: 5
                    },
                    battleship: {
                        name: 'Battleship',
                        boxes: 4
                    },
                    submarine: {
                        name: 'Submarine',
                        boxes: 3
                    },
                    destroyer: {
                        name: 'Destroyer',
                        boxes: 3
                    },
                    patrolBoat: {
                        name: 'Patrol boat',
                        boxes: 2
                    }
                },
                selectTitle = consts.DOC.createElement('h3'),
                selectPositionText = consts.DOC.createElement('h3'),
                position = ['horizontal', 'vertical'],
                divSelect1 = consts.DOC.createElement('div'),
                divSelect2 = consts.DOC.createElement('div'),
                divSelect3 = consts.DOC.createElement('div'),
                placeButton = consts.DOC.createElement('input');

            placeButton.id = 'placeShipButton';
            placeButton.type = 'button';
            placeButton.value = 'PLACE';

            divSelect1.className = 'divSelect1';
            divSelect2.className = 'divSelect2';
            divSelect3.className = 'divSelect3';

            selectTitle.className = 'selectShipsText';
            selectTitle.innerHTML = 'Place your ships:';

            this.selectMenuShips = consts.DOC.createElement('select');
            this.selectMenuShips.id = 'gamerSelect';

            Object.keys(ships).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = ships[x].name;
                option.innerHTML = ships[x].name;
                option.setAttribute('data-name', x + '');
                option.setAttribute('data-box', ships[x].boxes + '');

                this.selectMenuShips.appendChild(option);
            });

            divSelect1.appendChild(selectTitle);
            divSelect1.appendChild(this.selectMenuShips);
            this.menuGamer.appendChild(divSelect1);

            this.selectMenuShips.onchange = (event) => {
                let evTarget = event.target.selectedOptions[0];
                _shipSelected.value = evTarget.value;
                _shipSelected.boxes = evTarget.getAttribute('data-box');
                _shipSelected.name = evTarget.getAttribute('data-name');
            };

            selectPositionText.className = 'selectPositionText';
            selectPositionText.innerHTML = 'Ship Position:';

            this.selectShipPosition = consts.DOC.createElement('select');
            this.selectShipPosition.id = 'selectPosition';

            Array.from(position).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = x;
                option.innerHTML = x + '';

                this.selectShipPosition.appendChild(option);
            });

            divSelect2.appendChild(selectPositionText);
            divSelect2.appendChild(this.selectShipPosition);
            this.menuGamer.appendChild(divSelect2);

            this.selectShipPosition.onchange = (event) => {
                _positionSelected = event.target.selectedOptions[0].value;
            };

            divSelect3.appendChild(placeButton);
            this.menuGamer.appendChild(divSelect3);

            placeButton.onclick = () => {
                _placeShip(_shipSelected, _positionSelected);
            }
        }
        appendMenuGamer(parent) {
            this.shipsMenu();
            parent.appendChild(this.menuGamer);
        }
    }

    class _PanelGamer {
        constructor() {
            this.panelGamer = consts.DOC.createElement('div');
            this.panelGamer.id = 'panelGamer';

            this._menuGamer = new _MenuGamer();
            this._menuGamer.appendMenuGamer(this.panelGamer);

            this._table = _createTable(this.panelGamer);
            this.panelGamer.appendChild(this._table);
        }
        getPanelGamer() {
            return this.panelGamer;
        }
        appendPanelGamer(parent) {
            parent.appendChild(this.panelGamer);
        }
    }

    return {
        GameMenu: _GameMenu,
        StartButtons: _StartButtons,
        GameContainer: _GameContainer,
        MenuGamer: _MenuGamer,
        PanelGamer: _PanelGamer,
        createTable: _createTable
    }
});
<commit_msg>Improved _hoverShips method<commit_after>define('components', ['$', 'consts', 'buttons', 'utils'], function($, consts, buttons, utils) {
    'use strict';

    let _createTable = (parent) => {
            let table = consts.DOC.createElement('table'),
                rows = 10,
                columns = 10,
                trRange = utils.range(0, rows, 0),
                tdRange = utils.range(0, columns, 0),
                lettersRange = utils.range('a', 'j', 0);

            table.className = 'panelGamerBoard';

            Array.from(trRange).forEach((x) => {
                let trElement = consts.DOC.createElement('tr');

                if (x === 0) {
                    trElement.className = 'tr' + x;
                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdNumber = consts.DOC.createElement('p');

                        if (s !== 0) {
                            tdElement.className = 'td' + s;
                            tdNumber.innerHTML = s + '';
                            tdElement.appendChild(tdNumber);
                        }

                        trElement.appendChild(tdElement);
                    });
                } else {
                    trElement.className = 'tr' + x;

                    Array.from(tdRange).forEach((s) => {
                        let tdElement = consts.DOC.createElement('td'),
                            tdLetter = consts.DOC.createElement('p'),
                            letter = lettersRange[x - 1];

                        tdElement.className = 'td' + s;
                        tdElement.setAttribute('data-number', s + '');
                        tdElement.setAttribute('data-letter', letter);
                        tdLetter.innerHTML = letter;

                        if (s === 0) {
                            tdElement.appendChild(tdLetter);
                        }
                        trElement.appendChild(tdElement);
                    });
                }

                table.appendChild(trElement);
            });
            _moveShips(table);
            _hoverShips(table);
            return table;
        },
        _tableObject = (table) => {
            let tableObject = {};

            Object.keys(table.childNodes).forEach((x) => {
                if (table.childNodes[x].className !== 'tr0') {
                    let arr = [],
                        selected = [];
                    Object.keys(table.childNodes[x].childNodes).forEach((d) => {
                        if (table.childNodes[x].childNodes[d].className !== 'td0') {
                            arr.push(table.childNodes[x].childNodes[d]);
                        }
                        if (table.childNodes[x].childNodes[d].classList.contains('selected')) {
                            selected.push(table.childNodes[x].childNodes[d]);
                        }
                    });
                    tableObject[table.childNodes[x].className] = {
                        childs: arr,
                        selected: selected
                    };
                    arr = [];
                    selected = [];
                }
            });

            return tableObject;
        },
        _hoverSelected = {},
        _showShip = (element) => {
            // TODO: pending...
        },
        _moveShips = (table) => {
            table.onclick = (e) => {
                let tableObject = _tableObject(table),
                    elementClass = e.target.classList,
                    elementDataName = e.target.getAttribute('data-name') || null,
                    elementParent = e.target.parentNode.className,
                    elementNumber = e.target.getAttribute('data-number');

                Array.from(elementClass).forEach((x) => {
                    if (x === 'selected') {
                        let selectedLen = tableObject[elementParent].selected.length,
                            selecteds = tableObject[elementParent].selected;

                        if (elementDataName !== null && selectedLen > 1) {
                            Array.from(selecteds).forEach((f) => {
                                _hoverSelected = {
                                    name: elementDataName,
                                    position: 'horizontal',
                                    parent: elementParent,
                                    len: selectedLen,
                                    number: elementNumber,
                                    selected: e.target,
                                    hover: true
                                }

                                if (f.classList.contains('selected')) {
                                    f.classList.remove('selected');
                                } else if (f.classList.contains('hover')) {
                                    _showShip(_hoverSelected);
                                }
                            });
                        } else if (elementDataName !== null && selectedLen === 1) {
                            // TODO: pending...
                        }
                    } else {
                        return;
                    }
                });
            };
        },
        _removeSelected = () => {
            let table = consts.DOC.getElementsByClassName('panelGamerBoard');

            Array.from(table[0].childNodes).forEach((tr) => {
                let tds = tr.childNodes;
                Array.from(tds).forEach((td) => {
                    if (td.hasAttribute('class') && td.className !== 'panelGamerBoard' && td.classList.contains('hover')) {
                        $(td).removeClass('selected hover');
                    }
                });
            });
        },
        _hoverShips = (table) => {
            $(table).find('td').hover((e) => {
                let element = e.currentTarget,
                    elementParent = e.currentTarget.parentNode,
                    elementNumber = parseInt(e.currentTarget.getAttribute('data-number')),
                    printSelected = (_hoverSelected.len <= (11 - elementNumber)) ? true : false,
                    len = _hoverSelected.len,
                    i = 0;

                if (_hoverSelected.position) {
                    switch (_hoverSelected.position) {
                        case 'horizontal':
                            if (elementParent.className !== 'tr0' && element.className !== 'td0' && _hoverSelected.hasOwnProperty('name')) {
                                _removeSelected();

                                if (printSelected) {
                                    for (i; i < len; i++) {
                                        let selected = $('.td' + elementNumber);

                                        if (selected.parent().hasClass(elementParent.className)) {
                                            $('.' + elementParent.className).find(selected).addClass('selected hover');
                                            $('.' + elementParent.className).find(selected).attr('data-name', _hoverSelected.name);
                                            elementNumber++;
                                        }
                                    }
                                }
                            }
                            break;
                        case 'vertical':
                            // TODO: pending...
                            break;
                    }
                }
            });
        },
        _shipSelected = {},
        _positionSelected = null,
        _checkTds = (trChilds, range) => {
            let table = {},
                arr = [];

            Array.from(trChilds).forEach((x) => {
                let arr = [],
                    name = [];
                Array.from(x.childNodes).forEach((f) => {
                    if (f.className !== 'td0') arr.push(f);
                    if (f.hasAttribute('data-name')) name.push(f);
                });
                table[x.className] = {
                    childs: arr,
                    childsShips: name
                };
            });
            return table;
        },
        _changeVerticalBox = (trs, range, name) => {
            let i = 0,
                arr = {},
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < range.length) {
                    arr[x] = trs[x];
                    i++;
                }
            });

            if (i === range.length) {
                Object.keys(arr).forEach((d) => {
                    let arrChild = arr[d].childs[0];
                    arrChild.className += ' selected';
                    arrChild.setAttribute('data-name', name);
                });
                menuGamer.removeElement(name);
            } else {
                let message = 'Move your ships form place more.';
                utils.message('green', message);
            }
        },
        _verticalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeVerticalBox(_resultTrs, _range, name);
        },
        _changeHorizontalBox = (trs, range, name) => {
            let i = 0,
                d = 0,
                arr = {},
                firstChild = null,
                menuGamer = new _MenuGamer();

            Object.keys(trs).forEach((x) => {
                if (trs[x].childsShips.length === 0 && i < 1) {
                    firstChild = x;
                    arr[x] = trs[x];
                    i++;
                }
            });
            Array.from(arr[firstChild].childs).forEach((j) => {
                let arrChilds = arr[firstChild].childs;
                if (d < range.length) {
                    j.className += ' selected';
                    j.setAttribute('data-name', name);
                    d++;
                }
            });
            menuGamer.removeElement(name);
        },
        _horizontalShip = (num, name) => {
            let _table = consts.DOC.getElementsByClassName('panelGamerBoard'),
                _range = utils.range(1, parseFloat(num), 0),
                _trs = _table[0].childNodes,
                _trArr = [],
                _resultTrs = {};

            Array.from(_trs).forEach((x) => {
                if (x.className !== 'tr0') {
                    _trArr.push(x);
                }
            });
            _resultTrs = _checkTds(_trArr, _range);
            _changeHorizontalBox(_resultTrs, _range, name);
        },
        _placeShip = (ship, position) => {
            let num = 0,
                result = {},
                defaultPosition = (position !== null) ? position : 'horizontal',
                defaultShip = () => {
                    let select = consts.DOC.getElementById('gamerSelect');
                    Object.keys(select.childNodes).forEach((x) => {
                        if (select.hasOwnProperty(x) && num < 1) {
                            let selected = select.childNodes[x];
                            result.value = selected.value;
                            result.name = selected.getAttribute('data-name');
                            result.boxes = selected.getAttribute('data-box');
                            num++;
                        }
                    });
                    return result;
                },
                shipSelected = (typeof ship === 'object' && Object.keys(ship).length !== 0) ? ship : defaultShip();

            if (shipSelected.value && defaultPosition) {
                switch (defaultPosition) {
                    case 'vertical':
                        _verticalShip(shipSelected.boxes, shipSelected.name);
                        break;
                    case 'horizontal':
                        _horizontalShip(shipSelected.boxes, shipSelected.name);
                        break;
                }
            } else {
                let message = 'You must choose one ship and the position you want to place it.';
                utils.message('red', message);
            }
            _shipSelected = {};
            _positionSelected = null;
        };

    class _GameMenu {
        constructor() {
            this.gameMenu = consts.DOC.createElement('div');
            this.gameMenu.id = 'gameMenu';
        }
        getParent() {
            return consts.DOC.getElementById('parentContainer');
        }
        getGameMenu() {
            return this.gameMenu;
        }
        appendMenu(parent) {
            parent.appendChild(this.gameMenu);
        }
    }

    class _StartButtons {
        constructor() {
            this.start = buttons.START;
            this.load = buttons.LOAD;
            this.exit = buttons.EXIT;
            this.options = buttons.OPTIONS;
        }
        appendStartButton(parent) {
            parent.appendChild(this.start);
        }
        appendLoadButton(parent) {
            parent.appendChild(this.load);
        }
        appendExitButton(parent) {
            parent.appendChild(this.exit);
        }
        appendOptionsButton(parent) {
            parent.appendChild(this.options);
        }
    }

    class _GameContainer {
        constructor() {
            this.gameContainer = consts.DOC.createElement('div');
            this.gameContainer.id = 'gameContainer';
        }
        getGameContainer() {
            return this.gameContainer;
        }
        appendGameContainer(parent) {
            parent.appendChild(this.gameContainer);
        }
    }

    class _MenuGamer {
        constructor() {
            this.menuGamer = consts.DOC.createElement('div');
            this.menuGamer.id = 'menuGamer';
        }
        getMenuGamer() {
            return this.menuGamer;
        }
        removeElement(element) {
            let select = consts.DOC.getElementById('gamerSelect');
            Object.keys(select.childNodes).forEach((x) => {
                if (select.childNodes[x]) {
                    let dataName = select.childNodes[x].getAttribute('data-name');
                    if (dataName === element) {
                        select.remove(select.selectedIndex);
                    }
                }
            });
        }
        shipsMenu() {
            let ships = {
                    aircraftCarrier: {
                        name: 'Aircraft Carrier',
                        boxes: 5
                    },
                    battleship: {
                        name: 'Battleship',
                        boxes: 4
                    },
                    submarine: {
                        name: 'Submarine',
                        boxes: 3
                    },
                    destroyer: {
                        name: 'Destroyer',
                        boxes: 3
                    },
                    patrolBoat: {
                        name: 'Patrol boat',
                        boxes: 2
                    }
                },
                selectTitle = consts.DOC.createElement('h3'),
                selectPositionText = consts.DOC.createElement('h3'),
                position = ['horizontal', 'vertical'],
                divSelect1 = consts.DOC.createElement('div'),
                divSelect2 = consts.DOC.createElement('div'),
                divSelect3 = consts.DOC.createElement('div'),
                placeButton = consts.DOC.createElement('input');

            placeButton.id = 'placeShipButton';
            placeButton.type = 'button';
            placeButton.value = 'PLACE';

            divSelect1.className = 'divSelect1';
            divSelect2.className = 'divSelect2';
            divSelect3.className = 'divSelect3';

            selectTitle.className = 'selectShipsText';
            selectTitle.innerHTML = 'Place your ships:';

            this.selectMenuShips = consts.DOC.createElement('select');
            this.selectMenuShips.id = 'gamerSelect';

            Object.keys(ships).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = ships[x].name;
                option.innerHTML = ships[x].name;
                option.setAttribute('data-name', x + '');
                option.setAttribute('data-box', ships[x].boxes + '');

                this.selectMenuShips.appendChild(option);
            });

            divSelect1.appendChild(selectTitle);
            divSelect1.appendChild(this.selectMenuShips);
            this.menuGamer.appendChild(divSelect1);

            this.selectMenuShips.onchange = (event) => {
                let evTarget = event.target.selectedOptions[0];
                _shipSelected.value = evTarget.value;
                _shipSelected.boxes = evTarget.getAttribute('data-box');
                _shipSelected.name = evTarget.getAttribute('data-name');
            };

            selectPositionText.className = 'selectPositionText';
            selectPositionText.innerHTML = 'Ship Position:';

            this.selectShipPosition = consts.DOC.createElement('select');
            this.selectShipPosition.id = 'selectPosition';

            Array.from(position).forEach((x) => {
                let option = consts.DOC.createElement('option');
                option.value = x;
                option.innerHTML = x + '';

                this.selectShipPosition.appendChild(option);
            });

            divSelect2.appendChild(selectPositionText);
            divSelect2.appendChild(this.selectShipPosition);
            this.menuGamer.appendChild(divSelect2);

            this.selectShipPosition.onchange = (event) => {
                _positionSelected = event.target.selectedOptions[0].value;
            };

            divSelect3.appendChild(placeButton);
            this.menuGamer.appendChild(divSelect3);

            placeButton.onclick = () => {
                _placeShip(_shipSelected, _positionSelected);
            }
        }
        appendMenuGamer(parent) {
            this.shipsMenu();
            parent.appendChild(this.menuGamer);
        }
    }

    class _PanelGamer {
        constructor() {
            this.panelGamer = consts.DOC.createElement('div');
            this.panelGamer.id = 'panelGamer';

            this._menuGamer = new _MenuGamer();
            this._menuGamer.appendMenuGamer(this.panelGamer);

            this._table = _createTable(this.panelGamer);
            this.panelGamer.appendChild(this._table);
        }
        getPanelGamer() {
            return this.panelGamer;
        }
        appendPanelGamer(parent) {
            parent.appendChild(this.panelGamer);
        }
    }

    return {
        GameMenu: _GameMenu,
        StartButtons: _StartButtons,
        GameContainer: _GameContainer,
        MenuGamer: _MenuGamer,
        PanelGamer: _PanelGamer,
        createTable: _createTable
    }
});
<|endoftext|>


<commit_before>define('components', ['consts', 'buttons', 'utils'], function(consts, buttons, utils) {
    'use strict';

    let createTable = (parent) => {
        let table = consts.DOC.createElement('table'),
            rows = 20,
            columns = 20,
            trRange = utils.range(0, rows, 0),
            tdRange = utils.range(0, columns, 0),
            trs = [],
            tds = [];

        table.className = 'panelGamerBoard';

        Array.from(trRange).forEach((x) => {
            let trElement = consts.DOC.createElement('tr');
            trElement.className = 'tr' + x;

            Array.from(tdRange).forEach((s) => {
                let tdElement = consts.DOC.createElement('td');
                tdElement.className = 'td' + s;
                trElement.appendChild(tdElement);
            });

            table.appendChild(trElement);
        });

        return table;
    };

    class _GameMenu {
        constructor() {
            this.gameMenu = consts.DOC.createElement('div');
            this.gameMenu.id = 'gameMenu';
        }
        getParent() {
            return consts.DOC.getElementById('parentContainer');
        }
        getGameMenu() {
            return this.gameMenu;
        }
        appendMenu(parent) {
            parent.appendChild(this.gameMenu);
        }
    }

    class _StartButtons {
        constructor() {
            this.start = buttons.START;
            this.load = buttons.LOAD;
            this.exit = buttons.EXIT;
            this.options = buttons.OPTIONS;
        }
        appendStartButton(parent) {
            parent.appendChild(this.start);
        }
        appendLoadButton(parent) {
            parent.appendChild(this.load);
        }
        appendExitButton(parent) {
            parent.appendChild(this.exit);
        }
        appendOptionsButton(parent) {
            parent.appendChild(this.options);
        }
    }

    class _GameContainer {
        constructor() {
            this.gameContainer = consts.DOC.createElement('div');
            this.gameContainer.id = 'gameContainer';
        }
        getGameContainer() {
            return this.gameContainer;
        }
        appendGameContainer(parent) {
            parent.appendChild(this.gameContainer);
        }
    }

    class _PanelGamer {
        constructor() {
            this.panelGamer = consts.DOC.createElement('div');
            this.panelGamer.id = 'panelGamer';

            this.menuGamer = consts.DOC.createElement('div');
            this.menuGamer.id = 'menuGamer';

            this.table = createTable(this.panelGamer);
        }
        getPanelGamer() {
            return this.panelGamer;
        }
        appendPanelGamer(parent) {
            parent.appendChild(this.panelGamer);
            this.panelGamer.appendChild(this.menuGamer);
            this.panelGamer.appendChild(this.table);
        }
    }

    return {
        GameMenu: _GameMenu,
        StartButtons: _StartButtons,
        GameContainer: _GameContainer,
        PanelGamer: _PanelGamer
    }
});
<commit_msg>Changes in createTable method<commit_after>define('components', ['consts', 'buttons', 'utils'], function(consts, buttons, utils) {
    'use strict';

    let createTable = (parent) => {
        let table = consts.DOC.createElement('table'),
            rows = 10,
            columns = 10,
            trRange = utils.range(0, rows, 0),
            tdRange = utils.range(0, columns, 0),
            lettersRange = utils.range('a', 'j', 0),
            trs = [],
            tds = [];

        table.className = 'panelGamerBoard';

        Array.from(trRange).forEach((x) => {
            let trElement = consts.DOC.createElement('tr');

            if (x === 0) {
                trElement.className = 'tr' + x;
                Array.from(tdRange).forEach((s) => {
                    let tdElement = consts.DOC.createElement('td'),
                        tdNumber = consts.DOC.createElement('p');

                    if (s !== 0) {
                        tdElement.className = 'td' + s;
                        tdNumber.innerHTML = s + '';
                        tdElement.appendChild(tdNumber);
                    }

                    trElement.appendChild(tdElement);
                });
            } else {
                trElement.className = 'tr' + x;

                Array.from(tdRange).forEach((s) => {
                    let tdElement = consts.DOC.createElement('td'),
                        tdLetter = consts.DOC.createElement('p'),
                        letter = lettersRange[x - 1];

                    tdElement.className = 'td' + s;
                    tdLetter.innerHTML = letter;

                    if (s === 0) {
                        tdElement.appendChild(tdLetter);
                    }
                    trElement.appendChild(tdElement);
                });
            }

            table.appendChild(trElement);
        });

        return table;
    };

    class _GameMenu {
        constructor() {
            this.gameMenu = consts.DOC.createElement('div');
            this.gameMenu.id = 'gameMenu';
        }
        getParent() {
            return consts.DOC.getElementById('parentContainer');
        }
        getGameMenu() {
            return this.gameMenu;
        }
        appendMenu(parent) {
            parent.appendChild(this.gameMenu);
        }
    }

    class _StartButtons {
        constructor() {
            this.start = buttons.START;
            this.load = buttons.LOAD;
            this.exit = buttons.EXIT;
            this.options = buttons.OPTIONS;
        }
        appendStartButton(parent) {
            parent.appendChild(this.start);
        }
        appendLoadButton(parent) {
            parent.appendChild(this.load);
        }
        appendExitButton(parent) {
            parent.appendChild(this.exit);
        }
        appendOptionsButton(parent) {
            parent.appendChild(this.options);
        }
    }

    class _GameContainer {
        constructor() {
            this.gameContainer = consts.DOC.createElement('div');
            this.gameContainer.id = 'gameContainer';
        }
        getGameContainer() {
            return this.gameContainer;
        }
        appendGameContainer(parent) {
            parent.appendChild(this.gameContainer);
        }
    }

    class _PanelGamer {
        constructor() {
            this.panelGamer = consts.DOC.createElement('div');
            this.panelGamer.id = 'panelGamer';

            this.menuGamer = consts.DOC.createElement('div');
            this.menuGamer.id = 'menuGamer';

            this.table = createTable(this.panelGamer);
        }
        getPanelGamer() {
            return this.panelGamer;
        }
        appendPanelGamer(parent) {
            parent.appendChild(this.panelGamer);
            this.panelGamer.appendChild(this.menuGamer);
            this.panelGamer.appendChild(this.table);
        }
    }

    return {
        GameMenu: _GameMenu,
        StartButtons: _StartButtons,
        GameContainer: _GameContainer,
        PanelGamer: _PanelGamer
    }
});
<|endoftext|>


<commit_before>export default [
    'Simon',
    'Nils',
    'Budi',
    'Etienne',
    'Arno',
    'Michael',
    'Dennis',
    'Gregor',
    'Daniel',
    'Jan',
    'Uke',
    'Hauke',
    'Gunnar',
    'Marco',
    'Steffen',
    'Jens',
    'Colin',
    'Fabian',
    'Sia',
    'Gino',
    'Anja',
    'Nasti',
    'Bell',
    'Sofia',
    'Tim',
    'Timm',
    'Lars',
    'Andi',
    'Andy',
    'Julia',
    'Olli',
    'Ben',
    'Eduard',
    'Felix',
    'Florian',
    'Hannes',
    'Miriam',
    'Max',
    'Robin',
    'Alwin',
    'Ralph',
    'Aurel',
    'Florentin'
]<commit_msg>Added name<commit_after>export default [
    'Simon',
    'Nils',
    'Budi',
    'Etienne',
    'Arno',
    'Michael',
    'Dennis',
    'Gregor',
    'Daniel',
    'Jan',
    'Uke',
    'Hauke',
    'Gunnar',
    'Marco',
    'Steffen',
    'Jens',
    'Colin',
    'Fabian',
    'Sia',
    'Gino',
    'Anja',
    'Nasti',
    'Bell',
    'Sofia',
    'Tim',
    'Timm',
    'Lars',
    'Andi',
    'Andy',
    'Julia',
    'Olli',
    'Ben',
    'Eduard',
    'Felix',
    'Florian',
    'Hannes',
    'Miriam',
    'Max',
    'Robin',
    'Alwin',
    'Ralph',
    'Aurel',
    'Florentin',
    'Wolf'
]<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Route.extend({
});
<commit_msg>Add a model to access the data from Foursquare API<commit_after>import Ember from 'ember';
import config from '../config/environment';

export default Ember.Route.extend({
  model: function(params) {
      var CLIENT_ID = config.myCLIENT_ID;
      var CLIENT_SECRET = config.myCLIENT_SECRET;
      var location= Object.values(params);
      var url = 'https://api.foursquare.com/v2/venues/search?near='+location+'&client_id='+CLIENT_ID+'&client_secret='+CLIENT_SECRET+'&v=20171003';
    return Ember.$.getJSON(url).then(function(responseJSON) {

      return responseJSON.response.venues;
    });
  },
});
<|endoftext|>


<commit_before>/**
 * Created by ken on 2017/4/26.
 */
const Koa = require('koa')
const bodyParser = require('koa-bodyparser');
const config = require('./config')
const app = new Koa()
app.use(bodyParser());
// response
app.use(ctx => {
  ctx.body = 'Hello Koa!!!!!'
  console.log(ctx.request.query)
  console.log(ctx.request.body)
})

app.listen(config.http.port)

module.exports = app
<commit_msg>v0.0.2<commit_after>/**
 * Created by ken on 2017/4/26.
 */
const Koa = require('koa')
const bodyParser = require('koa-bodyparser');
const config = require('./config')
const app = new Koa()
app.use(bodyParser());
// response
app.use(ctx => {
  ctx.body = 'Hello Koa!!'
  console.log(ctx.request.query)
  console.log(ctx.request.body)
})

app.listen(config.http.port)

module.exports = app
<|endoftext|>


<commit_before>var elementalNames=['Air', 'Water', 'Earth', 'Fire'];

var Enemy = function(nameCode, type, x, vx, actionpipe, hp, pixelSize, coldown, triggerType){
  var m = this;
  //m.type = type;
  m.name = elementalNames[type]+' '+monsterNames[nameCode];
  m.color = elementColors[type]
  //load sprite depending on nameCode and type
  m.monsterCode = elementalNames[type][0]+nameCode;
  m.sprite = new Sprite(monsterSprites[m.monsterCode], monsterAnimations[m.monsterCode]);
  m.sprite.color = 'hsl('+m.color+',100%, 50%)';
  m.sprite.setAnimation('i');
  m.sprite.setPixelSize(pixelSize);

  m.sprite.maxVx = vx||m.pixelSize*2.2;
  m.sprite.x = x;
  m.skills = new ElementalSkill([type]);
  m.maxhp = hp;
  m.sprite.hp = hp;
  m.maxColdown = coldown;
  m.coldown = coldown;
  m.triggerType = triggerType||2;
  m.ghostTime = 100;
  m.del = 0;
  //action options:
  //f: forward
  //t: change direction
  //j: jump
  //a: main attack
  //b: second attack
  //c: third attack
  //w: wait
  //l: lock until land, do nothing
  //d: move forward until land
  //g: go for the hero
  //r: run away from the hero

  m.setActionPipe = function(actionpipe){
    var newPipe = '';
    for (var i = 0; i < actionpipe.length; i++) {
      var action = actionpipe[i];
      var times = parseInt(actionpipe.substring(i+1,i+4));
      if(!times){
        newPipe+=action;
        continue;
      }
      i+= (''+times).length;
      for (var j = 0; j < times; j++) {
        newPipe+=(action);
      }
    }
    m.actionpipe = newPipe;
  }
  m.setActionPipe(actionpipe||'f60taw20');
  //m.setActionPipe('lf30sw10tjl');
  //m.setActionPipe('lf60sw10tf60sw10ta');
  m.actionIndex = 0;

  m.attack1 = function(){
    if(m.coldown<=0){
      m.sprite.setAnimation('p');
      //var vy = 0;
      //m.skills.power(vy);
      var vx = -(m.sprite.x - heroS.x);
      var vy = -(m.sprite.y - heroS.y);
      var h = Math.sqrt(vx*vx+vy*vy);
      vx/=h;
      vy/=h;
      var power = new Power(m.skills.current, 2, m.sprite.x+8*3, m.sprite.y, 3*vx, 3*vy);

      enemypowers.push(power);
      m.coldown = m.maxColdown;
      //power.sprite.vy=vy;
      //m.coldown = 16;
    }
  }
  //follow the hero
  m.follow = function(){
    m.sprite.direction = m.sprite.x<heroS.x;
    m.sprite.forward();
  }
  //run away from the hero
  m.away = function(){
    m.sprite.direction = m.sprite.x>heroS.x;
    m.sprite.forward();
  }
  m.actions = {
    f: m.sprite.forward,
    t: m.sprite.turn,
    j: m.sprite.jump,
    m: function(){},
    a: m.attack1,
    b: m.attack2,
    c: m.attack3,
    s: m.sprite.stopX,
    w: function(){},
    l: function(){
      if(!m.sprite.landed)
        m.actionIndex--;
    },
    d: function(){
      if(!m.sprite.landed){
        m.actionIndex--;
        m.sprite.forward();
      }else{
        m.sprite.stopX();
      }
    },
    g: m.follow,
    r: m.away
  }

  //do the next action in the pipe
  m.nextAction = function(){
    var action = m.actionpipe[m.actionIndex];
    m.actions[action]();
    if(++m.actionIndex>=m.actionpipe.length) m.actionIndex = 0;
  }

  m.update = function(){
    //m.follow();
    //m.away();
    m.nextAction();
    //evaluar
//    m.attack();
    m.sprite.update();
    if(--m.coldown<0) m.coldown=0;
  }

  //triggers coded in an array
  // m.trigger[0] = create energy booster
  // m.trigger[1] = create health booster
  // m.trigger[2] = create random booster 1/10 to drop life
  // m.trigger[3] = hummm
  m.triggers = [
    function(){
      createBooster(m.skills.current, m.maxhp,m.sprite.x, m.sprite.y);
    },
    function(){
      createBooster(4, m.maxhp, m.sprite.x, m.sprite.y);
    },
    function(){
      if(~~(Math.random()*10)==0)
        m.triggers[1]();
      else
        m.triggers[0]();
    },
    function(){
      console.log('otra cosa')
    }
  ];
  m.trigger = function(event){
    enemies.push(new Enemy(~~(Math.random()*7), ~~(Math.random()*4), Math.random()*xlevel.w, Math.random()*14, 'f300t',Math.random()*10,7,32));
    m.triggers[m.triggerType]();
  }

  m.hit = function(type, damage){
    //damage =getTotalDamage(type, m.skills.current, damage) ;
    if(m.sprite.hit(getTotalDamage(type, m.skills.current, damage))&&!m.del){
      m.del = 1;
      //make me particles
      createParticles(m.sprite, damage, 0, 0, m.color);
      //create a new element cell to drop out
      m.trigger('death');
      //enemies.push(new Enemy(~~(Math.random()*4), new Sprite(hero)));
    }
    currentEnemy = m;
  }

  m.drawAvatar = function(vx, vy){
    ctx.fillStyle=white;
    ctx.fillText(m.name, vx-120, vy+20);
    ctx.fillStyle=loop%16==0?black:'yellow';
    ctx.fillRect(vx-335, vy+35, 300,8);
    ctx.fillStyle = '#300';
    ctx.fillRect (vx-334, vy+36, 300*(1-m.sprite.hp/m.maxhp)-2,6);
    m.sprite.drawFace(vx-135, vy+50);
  }

}<commit_msg>flashes the head when the enemy dies<commit_after>var elementalNames=['Air', 'Water', 'Earth', 'Fire'];

var Enemy = function(nameCode, type, x, vx, actionpipe, hp, pixelSize, coldown, triggerType){
  var m = this;
  //m.type = type;
  m.name = elementalNames[type]+' '+monsterNames[nameCode];
  m.color = elementColors[type]
  //load sprite depending on nameCode and type
  m.monsterCode = elementalNames[type][0]+nameCode;
  m.sprite = new Sprite(monsterSprites[m.monsterCode], monsterAnimations[m.monsterCode]);
  m.sprite.color = 'hsl('+m.color+',100%, 50%)';
  m.sprite.setAnimation('i');
  m.sprite.setPixelSize(pixelSize);

  m.sprite.maxVx = vx||m.pixelSize*2.2;
  m.sprite.x = x;
  m.skills = new ElementalSkill([type]);
  m.maxhp = hp;
  m.sprite.hp = hp;
  m.maxColdown = coldown;
  m.coldown = coldown;
  m.triggerType = triggerType||2;
  m.ghostTime = 100;
  m.del = 0;
  //action options:
  //f: forward
  //t: change direction
  //j: jump
  //a: main attack
  //b: second attack
  //c: third attack
  //w: wait
  //l: lock until land, do nothing
  //d: move forward until land
  //g: go for the hero
  //r: run away from the hero

  m.setActionPipe = function(actionpipe){
    var newPipe = '';
    for (var i = 0; i < actionpipe.length; i++) {
      var action = actionpipe[i];
      var times = parseInt(actionpipe.substring(i+1,i+4));
      if(!times){
        newPipe+=action;
        continue;
      }
      i+= (''+times).length;
      for (var j = 0; j < times; j++) {
        newPipe+=(action);
      }
    }
    m.actionpipe = newPipe;
  }
  m.setActionPipe(actionpipe||'f60taw20');
  //m.setActionPipe('lf30sw10tjl');
  //m.setActionPipe('lf60sw10tf60sw10ta');
  m.actionIndex = 0;

  m.attack1 = function(){
    if(m.coldown<=0){
      m.sprite.setAnimation('p');
      //var vy = 0;
      //m.skills.power(vy);
      var vx = -(m.sprite.x - heroS.x);
      var vy = -(m.sprite.y - heroS.y);
      var h = Math.sqrt(vx*vx+vy*vy);
      vx/=h;
      vy/=h;
      var power = new Power(m.skills.current, 2, m.sprite.x+8*3, m.sprite.y, 3*vx, 3*vy);

      enemypowers.push(power);
      m.coldown = m.maxColdown;
      //power.sprite.vy=vy;
      //m.coldown = 16;
    }
  }
  //follow the hero
  m.follow = function(){
    m.sprite.direction = m.sprite.x<heroS.x;
    m.sprite.forward();
  }
  //run away from the hero
  m.away = function(){
    m.sprite.direction = m.sprite.x>heroS.x;
    m.sprite.forward();
  }
  m.actions = {
    f: m.sprite.forward,
    t: m.sprite.turn,
    j: m.sprite.jump,
    m: function(){},
    a: m.attack1,
    b: m.attack2,
    c: m.attack3,
    s: m.sprite.stopX,
    w: function(){},
    l: function(){
      if(!m.sprite.landed)
        m.actionIndex--;
    },
    d: function(){
      if(!m.sprite.landed){
        m.actionIndex--;
        m.sprite.forward();
      }else{
        m.sprite.stopX();
      }
    },
    g: m.follow,
    r: m.away
  }

  //do the next action in the pipe
  m.nextAction = function(){
    var action = m.actionpipe[m.actionIndex];
    m.actions[action]();
    if(++m.actionIndex>=m.actionpipe.length) m.actionIndex = 0;
  }

  m.update = function(){
    //m.follow();
    //m.away();
    m.nextAction();
    //evaluar
//    m.attack();
    m.sprite.update();
    if(--m.coldown<0) m.coldown=0;
  }

  //triggers coded in an array
  // m.trigger[0] = create energy booster
  // m.trigger[1] = create health booster
  // m.trigger[2] = create random booster 1/10 to drop life
  // m.trigger[3] = hummm
  m.triggers = [
    function(){
      createBooster(m.skills.current, m.maxhp,m.sprite.x, m.sprite.y);
    },
    function(){
      createBooster(4, m.maxhp, m.sprite.x, m.sprite.y);
    },
    function(){
      if(~~(Math.random()*10)==0)
        m.triggers[1]();
      else
        m.triggers[0]();
    },
    function(){
      console.log('otra cosa')
    }
  ];
  m.trigger = function(event){
    enemies.push(new Enemy(~~(Math.random()*7), ~~(Math.random()*4), Math.random()*xlevel.w, ~~(Math.random()*14), 'f300t',~~(Math.random()*10),7,32));
    m.triggers[m.triggerType]();
  }

  m.hit = function(type, damage){
    //damage =getTotalDamage(type, m.skills.current, damage) ;
    if(m.sprite.hit(getTotalDamage(type, m.skills.current, damage))&&!m.del){
      m.del = 1;
      //make me particles
      createParticles(m.sprite, damage, 0, 0, m.color);
      //create a new element cell to drop out
      m.trigger('death');
      //enemies.push(new Enemy(~~(Math.random()*4), new Sprite(hero)));
    }
    currentEnemy = m;
  }

  m.drawAvatar = function(vx, vy){
    ctx.fillStyle=white;
    ctx.fillText(m.name, vx-120, vy+20);
    ctx.fillStyle=loop%16==0?black:'yellow';
    ctx.fillRect(vx-335, vy+35, 300,8);
    ctx.fillStyle = '#300';
    ctx.fillRect (vx-334, vy+36, 300*(1-m.sprite.hp/m.maxhp)-2,6);
    if(!m.del||loop%8==0)
      m.sprite.drawFace(vx-135, vy+50);
  }

}<|endoftext|>


<commit_before>var chrome = {};
chrome.app = {};
chrome.app.runtime = {};
chrome.app.runtime.onLaunched = {};
/**
 * @param {function} callback
 */
chrome.app.runtime.onLaunched.addListener = function(callback) {};

chrome.app.window = {};
/**
 * @param {function(AppWindow)}
 */
chrome.app.window.create = function(callback) {};

chrome.fileSystem = {};
/**
 * @param {FileEntry} entry
 * @param {function(FileEntry)} callback
 */
chrome.fileSystem.getWritableEntry = function(entry, callback) {};

/**
 * @constructor
 */
function AppWindow() {}

AppWindow.prototype.onClosed = {};
/**
 * @param {function} callback
 */
AppWindow.prototype.onClosed.addListener = function(callback) {};
/**
 * @type {Window}
 */
AppWindow.prototype.contentWindow = {};

/**
 * @constructor
 */
function TextDrive() {}
/**
 * @param {boolean} v
 */
TextDrive.prototype.setHasChromeFrame = function(v) {};
/**
 * @param {Array.<FileEntry>} entries
 */
TextDrive.prototype.openEntries = function(entries) {};
TextDrive.prototype.openNew = function() {};

/**
 * @type {TextDrive}
 */
window.textDrive = {};<commit_msg>Add TextDrive.getFilesToSave to externs to fix autosave.<commit_after>var chrome = {};
chrome.app = {};
chrome.app.runtime = {};
chrome.app.runtime.onLaunched = {};
/**
 * @param {function} callback
 */
chrome.app.runtime.onLaunched.addListener = function(callback) {};

chrome.app.window = {};
/**
 * @param {function(AppWindow)}
 */
chrome.app.window.create = function(callback) {};

chrome.fileSystem = {};
/**
 * @param {FileEntry} entry
 * @param {function(FileEntry)} callback
 */
chrome.fileSystem.getWritableEntry = function(entry, callback) {};

/**
 * @constructor
 */
function AppWindow() {}

AppWindow.prototype.onClosed = {};
/**
 * @param {function} callback
 */
AppWindow.prototype.onClosed.addListener = function(callback) {};
/**
 * @type {Window}
 */
AppWindow.prototype.contentWindow = {};

/**
 * @constructor
 */
function TextDrive() {}
/**
 * @param {boolean} v
 */
TextDrive.prototype.setHasChromeFrame = function(v) {};
/**
 * @param {Array.<FileEntry>} entries
 */
TextDrive.prototype.openEntries = function(entries) {};
TextDrive.prototype.openNew = function() {};
/**
 * @return {Array.<Object>}
 */
TextDrive.prototype.getFilesToSave = function() {};

/**
 * @type {TextDrive}
 */
window.textDrive = {};<|endoftext|>


<commit_before>var mongoose = require( 'mongoose' );

var Schema = mongoose.Schema;

var SensorReadingSchema = Schema( {
    date: Date,
    temp_c: Number,
    temp_f: Number,
    humidity: Number,
    pressure: Number,
    luminosity: Number
} );

SensorReadingSchema.statics = {
    calcStatsForDateRange: function ( startDate, endDate, cb ) {
        var matchOptions = {
            date: {
                $gte: startDate,
                $lte: endDate
            }
        };

        var groupOptions = {
            _id: null,
            avg_temp_c: {
                $avg: "$temp_c"
            },
            min_temp_c: {
                $min: "$temp_c"
            },
            max_temp_c: {
                $max: "$temp_c"
            },
            avg_temp_f: {
                $avg: "$temp_f"
            },
            min_temp_f: {
                $min: "$temp_f"
            },
            max_temp_f: {
                $max: "$temp_f"
            },
            avg_humidity: {
                $avg: "$humidity"
            },
            min_humidity: {
                $min: "$humidity"
            },
            max_humidity: {
                $max: "$humidity"
            },
            avg_pressure: {
                $avg: "$pressure"
            },
            min_pressure: {
                $min: "$pressure"
            },
            max_pressure: {
                $max: "$pressure"
            },
            avg_luminosity: {
                $avg: "$luminosity"
            },
            min_luminosity: {
                $min: "$luminosity"
            },
            max_luminosity: {
                $max: "$luminosity"
            }
        };

        var q = this.aggregate()
                    .match( matchOptions )
                    .group( groupOptions );

        q.exec( cb );
    }
};

exports.SensorReading = mongoose.model( 'SensorReading', SensorReadingSchema );

var SystemReadingSchema = Schema( {
    date: Date,
    cpu_temp_c: Number,
    cpu_temp_f: Number
} );

exports.SystemReading = mongoose.model( 'SystemReading', SystemReadingSchema );
<commit_msg>Update models<commit_after>var mongoose = require( 'mongoose' );

var Schema = mongoose.Schema;

var SensorReadingSchema = Schema( {
    date: Date,
    temp_c: Number,
    temp_f: Number,
    humidity: Number,
    pressure: Number,
    luminosity: Number
} );

SensorReadingSchema.statics = {
    add: function ( sensorReadingData, cb ) {
        // Override the date here in case time from Raspberry Pi is off
        sensorReadingData.data = new Date();
        this.create( sensorReadingData, function ( err, newSensorReading ) {
            if ( err ) {
                return cb( err );
            }
            return cb( null, newSensorReading );
        } );
    },
    calcStatsForDateRange: function ( startDate, endDate, cb ) {
        var matchOptions = {
            date: {
                $gte: startDate,
                $lte: endDate
            }
        };

        var groupOptions = {
            _id: null,
            avg_temp_c: {
                $avg: "$temp_c"
            },
            min_temp_c: {
                $min: "$temp_c"
            },
            max_temp_c: {
                $max: "$temp_c"
            },
            avg_temp_f: {
                $avg: "$temp_f"
            },
            min_temp_f: {
                $min: "$temp_f"
            },
            max_temp_f: {
                $max: "$temp_f"
            },
            avg_humidity: {
                $avg: "$humidity"
            },
            min_humidity: {
                $min: "$humidity"
            },
            max_humidity: {
                $max: "$humidity"
            },
            avg_pressure: {
                $avg: "$pressure"
            },
            min_pressure: {
                $min: "$pressure"
            },
            max_pressure: {
                $max: "$pressure"
            },
            avg_luminosity: {
                $avg: "$luminosity"
            },
            min_luminosity: {
                $min: "$luminosity"
            },
            max_luminosity: {
                $max: "$luminosity"
            }
        };

        var q = this.aggregate()
                    .match( matchOptions )
                    .group( groupOptions );

        q.exec( cb );
    }
};

exports.SensorReading = mongoose.model( 'SensorReading', SensorReadingSchema );

var SystemReadingSchema = Schema( {
    date: Date,
    cpu_temp_c: Number,
    cpu_temp_f: Number
} );

SystemReadingSchema.statics = {
    add: function ( systemReadingData, cb ) {
        // Override the date here in case time from Raspberry Pi is off
        systemReadingData.data = new Date();
        this.create( systemReadingData, function ( err, newSystemReading ) {
            if ( err ) {
                return cb( err );
            }
            return cb( null, newSystemReading );
        } );
    }
};

exports.SystemReading = mongoose.model( 'SystemReading', SystemReadingSchema );
<|endoftext|>


<commit_before>(function(jQuery) {
var $ = jQuery;

"use strict";

Echo.Tests.Download = {};

var suite = Echo.Tests.Unit.Loader = function() {};

suite.prototype.info = {
	"className": "Echo.Loader",
	"functions": [
		"init",
		"download",
		"override",
		"getURL"
	]
};

suite.prototype.tests = {};

suite.prototype.cases = {};

// checking resources downloading mechanisms

suite.prototype.tests.resourceDownloadingTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		this.sequentialAsyncTests([
			"invalidParameters",
			"nonExistingScripts",
			"alreadyLoadedScripts",
			"validScriptsLoading",
			"validAndInvalidScriptsMix",
			"loadingSameScriptMultipleTimes"
		], "cases");
	}
};

suite.prototype.tests.urlConvertingTests = {
	"check": function() {
		var cdnBaseURL = Echo.Loader.config.cdnBaseURL;
		var urls = {
			"absolute": [
				"//cdn/echoenabled.com/image.png",
				"http://echoenabled.com/image.png",
				"https://echoenabled.com/image.png"
			],
			"relative": [
				"/web/image.png",
				"web/image.png",
				"sdk"
			]
		};
		$.each(urls, function(key, val) {
			var checked = true;
			$.map(val, function(url) {
				if (key === "absolute" && url !== Echo.Loader.getURL(url) ||
					key === "relative" && cdnBaseURL + url !== Echo.Loader.getURL(url)
				) {
					checked = false;
				}
			});
			QUnit.ok(checked, "Checking if " + key + " URL has been correctly converted");
		});
	}
};

suite.prototype.cases.invalidParameters = function(callback) {
	var emptyArray = function(_callback) {
		Echo.Loader.download({
			"scripts": [],
			"callback": function() {
				QUnit.ok(true, "Checking if the callback is fired even if the list of the scripts to load is empty (empty array)");
				_callback();
			}
		});
	};
	var scriptsParamMissing = function(_callback) {
		Echo.Loader.download({
			"callback": function() {
				QUnit.ok(true, "Checking if the callback is fired even if the scripts list is undefined");
				_callback();
			}
		});
	};
	var callbackCheck = function(_callback) {
		try {
			Echo.Loader.download({"scripts": []});
			QUnit.ok(true, "Checking if the callback is an optional parameter (no JS error expected)");
			_callback();
		} catch(e) {
			QUnit.ok(false, "Received JS error when trying to launch \"download\" function without a \"callback\" function");
			_callback();
		}
	};
	Echo.Utils.sequentialCall([
		emptyArray,
		scriptsParamMissing,
		callbackCheck
	], callback);
};

suite.prototype.cases.nonExistingScripts = function(callback) {
	Echo.Loader.download({
		"errorTimeout": 1000, // 1 sec
		"scripts": [{
			"url": "non-existing-folder/1.js"
		}, {
			"url": "non-existing-folder/2.js"
		}, {
			"url": "non-existing-folder/3.js"
		}],
		"callback": function() {
			QUnit.ok(true, "Checking if the callback is executed when non-existing scripts were passed as a function arguments");
			callback();
		}
	});
};

suite.prototype.cases.alreadyLoadedScripts = function(callback) {
	Echo.Loader.download({
		"scripts": [{
			"url": "sdk/events.js"
		}, {
			"url": "sdk/labels.js",
			"loaded": function() { return !!Echo.Labels; }
		}, {
			"url": "sdk/plugin.js"
		}],
		"callback": function() {
			QUnit.ok(true, "Checking if the callback is executed when the scripts loaded previously are loaded again");
			callback();
		}
	});
};

suite.prototype.cases.validScriptsLoading = function(callback, count, description) {
	count = count || 5
	var scripts = [];
	var existingScriptsCount = 5;
	for (var i = 1; i <= count; i++) {
		scripts.push({
			"url": "sdk/tests/unit/loader/scripts/" + (count > existingScriptsCount ? "non-existing" : i) + ".js",
			"loaded": function() { return !!Echo.Tests.Download["object" + i]; }
		});
	}
 	Echo.Loader.download({
		"errorTimeout": 1000, // 1 sec
		"scripts": scripts,
		"callback": function() {
			var success = true;
			// check only existing scripts
			for (var i = 1; i <= existingScriptsCount; i++) {
				if (success) {
					success = !!Echo.Tests.Download["object" + i];
				}
			}
			QUnit.ok(success, description || "Checking if all the test scripts were loaded successfully");
			callback();
		}
	});
};

suite.prototype.cases.validAndInvalidScriptsMix = function(callback) {
	this.cases.validScriptsLoading(callback, 7, "Checking if the mix of valid and invalid scripts is handled by the loader correctly");
};

suite.prototype.cases.loadingSameScriptMultipleTimes = function(callback) {
	var scripts = [];
	for (var i = 1; i <= 5; i++) {
		scripts.push({
			"url": "sdk/tests/unit/loader/scripts/1.js"
		});
	}
 	Echo.Loader.download({
		"scripts": scripts,
		"callback": function() {
			QUnit.ok(true, "Checking the situation when the same script is loaded multiple times (checking if the callback is executed)");
			callback();
		}
	});
};

// checking canvases initialization scenarios

suite.prototype.tests.canvasesInitializationTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		var self = this;
		this.sequentialAsyncTests($.map([
			"simple-valid-canvas",
			"valid-and-invalid-canvases",
			"double-initialization-prevention",
			"different-initialization-schemas",
			"multiple-apps-canvas",
			"app-config-overrides"
		], function(name) {
			return self.loaderIframeTest(name);
		}));
	}
};

// dynamic interface with utils functions

suite.prototype.loaderIframeTest = function(name) {
	return function(callback) {
		var iframe = $('');
		$(document.body).append(iframe);
		iframe.on("load", function() {
			iframe.get(0).contentWindow.test(callback);
		});
		iframe.attr("src", "unit/loader/pages/" + name + ".html");
	};
};

// static interface with utils functions (to be accessible within nested iframes)

suite.eventsCountCheck = function(events) {
	var success = true;
	$.each(events, function(id, event) {
		if (event[0] != event[1]) {
			success = false;
			return false; // break
		}
	});
	return success;
};

})(Echo.jQuery);
<commit_msg>[Loader] Added test for checking if stylesheets loaded correctly<commit_after>(function(jQuery) {
var $ = jQuery;

"use strict";

Echo.Tests.Download = {};

var suite = Echo.Tests.Unit.Loader = function() {};

suite.prototype.info = {
	"className": "Echo.Loader",
	"functions": [
		"init",
		"download",
		"override",
		"getURL"
	]
};

suite.prototype.tests = {};

suite.prototype.cases = {};

// checking resources downloading mechanisms

suite.prototype.tests.resourceDownloadingTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		this.sequentialAsyncTests([
			"alreadyLoadedStylesheets",
			"invalidParameters",
			"nonExistingScripts",
			"alreadyLoadedScripts",
			"validScriptsLoading",
			"validAndInvalidScriptsMix",
			"loadingSameScriptMultipleTimes"
		], "cases");
	}
};

suite.prototype.tests.urlConvertingTests = {
	"check": function() {
		var cdnBaseURL = Echo.Loader.config.cdnBaseURL;
		var urls = {
			"absolute": [
				"//cdn/echoenabled.com/image.png",
				"http://echoenabled.com/image.png",
				"https://echoenabled.com/image.png"
			],
			"relative": [
				"/web/image.png",
				"web/image.png",
				"sdk"
			]
		};
		$.each(urls, function(key, val) {
			var checked = true;
			$.map(val, function(url) {
				if (key === "absolute" && url !== Echo.Loader.getURL(url) ||
					key === "relative" && cdnBaseURL + url !== Echo.Loader.getURL(url)
				) {
					checked = false;
				}
			});
			QUnit.ok(checked, "Checking if " + key + " URL has been correctly converted");
		});
	}
};

suite.prototype.cases.invalidParameters = function(callback) {
	var emptyArray = function(_callback) {
		Echo.Loader.download({
			"scripts": [],
			"callback": function() {
				QUnit.ok(true, "Checking if the callback is fired even if the list of the scripts to load is empty (empty array)");
				_callback();
			}
		});
	};
	var scriptsParamMissing = function(_callback) {
		Echo.Loader.download({
			"callback": function() {
				QUnit.ok(true, "Checking if the callback is fired even if the scripts list is undefined");
				_callback();
			}
		});
	};
	var callbackCheck = function(_callback) {
		try {
			Echo.Loader.download({"scripts": []});
			QUnit.ok(true, "Checking if the callback is an optional parameter (no JS error expected)");
			_callback();
		} catch(e) {
			QUnit.ok(false, "Received JS error when trying to launch \"download\" function without a \"callback\" function");
			_callback();
		}
	};
	Echo.Utils.sequentialCall([
		emptyArray,
		scriptsParamMissing,
		callbackCheck
	], callback);
};

suite.prototype.cases.nonExistingScripts = function(callback) {
	Echo.Loader.download({
		"errorTimeout": 1000, // 1 sec
		"scripts": [{
			"url": "non-existing-folder/1.js"
		}, {
			"url": "non-existing-folder/2.js"
		}, {
			"url": "non-existing-folder/3.js"
		}],
		"callback": function() {
			QUnit.ok(true, "Checking if the callback is executed when non-existing scripts were passed as a function arguments");
			callback();
		}
	});
};

suite.prototype.cases.alreadyLoadedScripts = function(callback) {
	Echo.Loader.download({
		"scripts": [{
			"url": "sdk/events.js"
		}, {
			"url": "sdk/labels.js",
			"loaded": function() { return !!Echo.Labels; }
		}, {
			"url": "sdk/plugin.js"
		}],
		"callback": function() {
			QUnit.ok(true, "Checking if the callback is executed when the scripts loaded previously are loaded again");
			callback();
		}
	});
};

suite.prototype.cases.alreadyLoadedStylesheets = function(callback) {
	Echo.Loader.download({
		"scripts": [{
			"url": "sdk/third-party/jquery/css/fancybox.css"
		}, {
			"url": "sdk/third-party/jquery/css/fancybox.css"
		}],
		"callback": function() {
			QUnit.ok(true, "Checking if the callback is executed when the stylesheets loaded previously are loaded again");
			callback();
		}
	});
};

suite.prototype.cases.validScriptsLoading = function(callback, count, description) {
	count = count || 5
	var scripts = [];
	var existingScriptsCount = 5;
	for (var i = 1; i <= count; i++) {
		scripts.push({
			"url": "sdk/tests/unit/loader/scripts/" + (count > existingScriptsCount ? "non-existing" : i) + ".js",
			"loaded": function() { return !!Echo.Tests.Download["object" + i]; }
		});
	}
 	Echo.Loader.download({
		"errorTimeout": 1000, // 1 sec
		"scripts": scripts,
		"callback": function() {
			var success = true;
			// check only existing scripts
			for (var i = 1; i <= existingScriptsCount; i++) {
				if (success) {
					success = !!Echo.Tests.Download["object" + i];
				}
			}
			QUnit.ok(success, description || "Checking if all the test scripts were loaded successfully");
			callback();
		}
	});
};

suite.prototype.cases.validAndInvalidScriptsMix = function(callback) {
	this.cases.validScriptsLoading(callback, 7, "Checking if the mix of valid and invalid scripts is handled by the loader correctly");
};

suite.prototype.cases.loadingSameScriptMultipleTimes = function(callback) {
	var scripts = [];
	for (var i = 1; i <= 5; i++) {
		scripts.push({
			"url": "sdk/tests/unit/loader/scripts/1.js"
		});
	}
 	Echo.Loader.download({
		"scripts": scripts,
		"callback": function() {
			QUnit.ok(true, "Checking the situation when the same script is loaded multiple times (checking if the callback is executed)");
			callback();
		}
	});
};

// checking canvases initialization scenarios

suite.prototype.tests.canvasesInitializationTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		var self = this;
		this.sequentialAsyncTests($.map([
			"simple-valid-canvas",
			"valid-and-invalid-canvases",
			"double-initialization-prevention",
			"different-initialization-schemas",
			"multiple-apps-canvas",
			"app-config-overrides"
		], function(name) {
			return self.loaderIframeTest(name);
		}));
	}
};

// dynamic interface with utils functions

suite.prototype.loaderIframeTest = function(name) {
	return function(callback) {
		var iframe = $('');
		$(document.body).append(iframe);
		iframe.on("load", function() {
			iframe.get(0).contentWindow.test(callback);
		});
		iframe.attr("src", "unit/loader/pages/" + name + ".html");
	};
};

// static interface with utils functions (to be accessible within nested iframes)

suite.eventsCountCheck = function(events) {
	var success = true;
	$.each(events, function(id, event) {
		if (event[0] != event[1]) {
			success = false;
			return false; // break
		}
	});
	return success;
};

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


<commit_before>(function(jQuery) {
var $ = jQuery;

"use strict";

Echo.Tests.Download = {};

var suite = Echo.Tests.Unit.Loader = function() {};

suite.prototype.info = {
	"className": "Echo.Loader",
	"functions": [
		"init",
		"download",
		"override",
		"getURL"
	]
};

suite.prototype.tests = {};

suite.prototype.cases = {};

// checking resources downloading mechanisms

suite.prototype.tests.resourceDownloadingTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		this.sequentialAsyncTests([
			"equalUrlsPerSingleCall",
			"equalUrlsPerSequentialCalls",
			"equalUrlsPerParallelCalls",
			"invalidParameters",
			"nonExistingScripts",
			"alreadyLoadedScripts",
			"validScriptsLoading",
			"validAndInvalidScriptsMix",
			"loadingSameScriptMultipleTimes"
		], "cases");
	}
};

suite.prototype.tests.urlConvertingTests = {
	"check": function() {
		var cdnBaseURL = Echo.Loader.config.cdnBaseURL;
		var version = Echo.Loader.version;
		var urls = {
			"absolute": [
				"//cdn/echoenabled.com/image.png",
				"http://echoenabled.com/image.png",
				"https://echoenabled.com/image.png"
			],
			"relative": [
				"/web/image.png",
				"web/image.png",
				"sdk"
			],
			"sdk": [
				"{sdk}/web/image.png",
				"{sdk}web/image.png",
				"{sdk}"
			],
			"apps": [
				"{apps}/web/image.png",
				"{apps}/web/image.png",
				"{apps}"
			]
		};
		$.each(urls, function(key, val) {
			var checked = true;
			$.map(val, function(url) {
				if ((key === "absolute" || key === "relative") && url !== Echo.Loader.getURL(url) ||
					key === "apps" && url.replace("{apps}", cdnBaseURL + "apps") !== Echo.Loader.getURL(url) ||
					key === "sdk" && url.replace("{sdk}", cdnBaseURL + "sdk/v" + version) !== Echo.Loader.getURL(url)
				) {
					checked = false;
				}
			});
			QUnit.ok(checked, "Checking if " + key + " URL has been correctly converted");
		});
	}
};

suite.prototype.cases.invalidParameters = function(callback) {
	var emptyArray = function(_callback) {
		Echo.Loader.download([], function() {
			QUnit.ok(true, "Checking if the callback is fired even if the list of the scripts to load is empty (empty array)");
			_callback();
		});
	};
	var scriptsParamMissing = function(_callback) {
		Echo.Loader.download(undefined, function() {
			QUnit.ok(true, "Checking if the callback is fired even if the scripts list is undefined");
			_callback();
		});
	};
	var callbackCheck = function(_callback) {
		try {
			Echo.Loader.download([]);
			QUnit.ok(true, "Checking if the callback is an optional parameter (no JS error expected)");
			_callback();
		} catch(e) {
			QUnit.ok(false, "Received JS error when trying to launch \"download\" function without a \"callback\" function");
			_callback();
		}
	};
	Echo.Utils.sequentialCall([
		emptyArray,
		scriptsParamMissing,
		callbackCheck
	], callback);
};

suite.prototype.cases.nonExistingScripts = function(callback) {
	Echo.Loader.download([{
		"url": "non-existing-folder/1.js"
	}, {
		"url": "non-existing-folder/2.js"
	}, {
		"url": "non-existing-folder/3.js"
	}], function() {
		QUnit.ok(true, "Checking if the callback is executed when non-existing scripts were passed as a function arguments");
		callback();
	}, {
		"errorTimeout": 1000 // 1 sec
	});
};

suite.prototype.cases.alreadyLoadedScripts = function(callback) {
	Echo.Loader.download([{
		"url": "{sdk}/events.js"
	}, {
		"url": "{sdk}/labels.js",
		"loaded": function() { return !!Echo.Labels; }
	}, {
		"url": "{sdk}/plugin.js"
	}], function() {
		QUnit.ok(true, "Checking if the callback is executed when the scripts loaded previously are loaded again");
		callback();
	});
};

suite.prototype.cases.equalUrlsPerSingleCall = function(callback) {
	Echo.Loader.download([
		{"url": "unit/loader/scripts/d1.js"},
		{"url": "unit/loader/scripts/d1.js"},
		{"url": "unit/loader/styles/1.css"},
		{"url": "unit/loader/styles/1.css"}
	], function() {
		QUnit.ok(!!Echo.Tests.Download.duplicate1, "Checking if the callback is executed when equal urls of js/css was loaded per single call");
		callback();
	});
};

suite.prototype.cases.equalUrlsPerSequentialCalls = function(callback) {
	Echo.Loader.download([
		{"url": "unit/loader/scripts/d2.js"},
		{"url": "unit/loader/styles/2.css"}
	], function() {
		Echo.Loader.download([
			{"url": "unit/loader/scripts/d2.js"},
			{"url": "unit/loader/styles/2.css"}
		], function() {
			QUnit.ok(!!Echo.Tests.Download.duplicate2, "Checking if the callback is executed when equal urls of js/css was loaded per sequential call");
			callback();
		});
	});
};

suite.prototype.cases.equalUrlsPerParallelCalls = function(callback) {
	var k = 2;
	var commonCallback = function() {
		if(!--k) {
			QUnit.ok(!!Echo.Tests.Download.duplicate3, "Checking if the callback is executed when equal urls of js/css was loaded per parallel call");
			callback();
		}
	};
	Echo.Loader.download([
		{"url": "unit/loader/scripts/d3.js"},
		{"url": "unit/loader/styles/3.css"}
	], commonCallback);

	Echo.Loader.download([
		{"url": "unit/loader/scripts/d3.js"},
		{"url": "unit/loader/styles/3.css"}
	], commonCallback);
};

suite.prototype.cases.validScriptsLoading = function(callback, count, description) {
	count = count || 5;
	var resources = [];
	var existingScriptsCount = 5;
	for (var i = 1; i <= count; i++) {
		resources.push({
			"url": "unit/loader/scripts/" + (count > existingScriptsCount ? "non-existing" : i) + ".js",
			"loaded": function() { return !!Echo.Tests.Download["object" + i]; }
		});
	}
	Echo.Loader.download(resources, function() {
		var success = true;
		// check only existing scripts
		for (var i = 1; i <= existingScriptsCount; i++) {
			if (success) {
				success = !!Echo.Tests.Download["object" + i];
			}
		}
		QUnit.ok(success, description || "Checking if all the test scripts were loaded successfully");
		callback();
	}, {
		"errorTimeout": 1000 // 1 sec
	});
};

suite.prototype.cases.validAndInvalidScriptsMix = function(callback) {
	this.cases.validScriptsLoading(callback, 7, "Checking if the mix of valid and invalid scripts is handled by the loader correctly");
};

suite.prototype.cases.loadingSameScriptMultipleTimes = function(callback) {
	var resources = [];
	for (var i = 1; i <= 5; i++) {
		resources.push({
			"url": "unit/loader/scripts/1.js"
		});
	}
	Echo.Loader.download(resources, function() {
		QUnit.ok(true, "Checking the situation when the same script is loaded multiple times (checking if the callback is executed)");
		callback();
	});
};

// checking canvases initialization scenarios

suite.prototype.tests.canvasesInitializationTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		var self = this;
		this.sequentialAsyncTests($.map([
			"simple-valid-canvas",
			"valid-and-invalid-canvases",
			"double-initialization-prevention",
			"different-initialization-schemas",
			"multiple-apps-canvas",
			"app-config-overrides"
		], function(name) {
			return self.loaderIframeTest(name);
		}));
	}
};

// dynamic interface with utils functions

suite.prototype.loaderIframeTest = function(name) {
	return function(callback) {
		var iframe = $('');
		$(document.body).append(iframe);
		iframe.on("load", function() {
			iframe.get(0).contentWindow.test(callback);
		});
		iframe.attr("src", "unit/loader/pages/" + name + ".html");
	};
};

// static interface with utils functions (to be accessible within nested iframes)

suite.eventsCountCheck = function(events) {
	var success = true;
	$.each(events, function(id, event) {
		if (event[0] != event[1]) {
			success = false;
			return false; // break
		}
	});
	return success;
};

})(Echo.jQuery);
<commit_msg>Hardly reworked URL conversion test<commit_after>(function(jQuery) {
var $ = jQuery;

"use strict";

Echo.Tests.Download = {};

var suite = Echo.Tests.Unit.Loader = function() {};

suite.prototype.info = {
	"className": "Echo.Loader",
	"functions": [
		"init",
		"download",
		"override",
		"getURL"
	]
};

suite.prototype.tests = {};

suite.prototype.cases = {};

// checking resources downloading mechanisms

suite.prototype.tests.resourceDownloadingTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		this.sequentialAsyncTests([
			"equalUrlsPerSingleCall",
			"equalUrlsPerSequentialCalls",
			"equalUrlsPerParallelCalls",
			"invalidParameters",
			"nonExistingScripts",
			"alreadyLoadedScripts",
			"validScriptsLoading",
			"validAndInvalidScriptsMix",
			"loadingSameScriptMultipleTimes"
		], "cases");
	}
};

suite.prototype.tests.urlConvertingTests = {
	"check": function() {
		var cdnBaseURL = Echo.Loader.config.cdnBaseURL;
		var version = Echo.Loader.version;
		var debug = Echo.Loader.debug;
		function checkURLs(urls) {
			$.each(urls, function(i, spec) {
				QUnit.ok(spec.expect === Echo.Loader.getURL(spec.data), "Checking URL conversion: " + spec.data);
			});
		};
		var urls = {
			"plain": [{
				"data": "//cdn/echoenabled.com/image.png",
				"expect": "//cdn/echoenabled.com/image.png"
			}, {
				"data": "http://echoenabled.com/image.png",
				"expect": "http://echoenabled.com/image.png"
			}, {
				"data": "https://echoenabled.com/image.png",
				"expect": "https://echoenabled.com/image.png"
			}, {
				"data": "/web/image.png",
				"expect": "/web/image.png"
			}],
			"placeholders": [{
				"data": "{apps}/web/image.png",
				"expect": cdnBaseURL + "apps/web/image.png"
			}, {
				"data": "{sdk-assets}/web/image.png",
				"expect": cdnBaseURL + "sdk/v" + version + "/web/image.png"
			}, {
				"data": "{sdk}/web/image.png",
				"expect": cdnBaseURL + "sdk/v" + version + "/web/image.png"
			}],
			"placeholdersDev": [{
				"data": "{apps}/web/image.png",
				"expect": cdnBaseURL + "apps/web/image.png"
			}, {
				"data": "{sdk-assets}/web/image.png",
				"expect": cdnBaseURL + "sdk/v" + version + "/web/image.png"
			}, {
				"data": "{sdk}/web/image.png",
				"expect": cdnBaseURL + "sdk/v" + version + "/dev/web/image.png"
			}]
		};
		checkURLs(urls.plain);
		Echo.Loader.debug = false;
		checkURLs(urls.placeholders);
		Echo.Loader.debug = true;
		checkURLs(urls.placeholdersDev);
		Echo.Loader.debug = debug;
	}
};

suite.prototype.cases.invalidParameters = function(callback) {
	var emptyArray = function(_callback) {
		Echo.Loader.download([], function() {
			QUnit.ok(true, "Checking if the callback is fired even if the list of the scripts to load is empty (empty array)");
			_callback();
		});
	};
	var scriptsParamMissing = function(_callback) {
		Echo.Loader.download(undefined, function() {
			QUnit.ok(true, "Checking if the callback is fired even if the scripts list is undefined");
			_callback();
		});
	};
	var callbackCheck = function(_callback) {
		try {
			Echo.Loader.download([]);
			QUnit.ok(true, "Checking if the callback is an optional parameter (no JS error expected)");
			_callback();
		} catch(e) {
			QUnit.ok(false, "Received JS error when trying to launch \"download\" function without a \"callback\" function");
			_callback();
		}
	};
	Echo.Utils.sequentialCall([
		emptyArray,
		scriptsParamMissing,
		callbackCheck
	], callback);
};

suite.prototype.cases.nonExistingScripts = function(callback) {
	Echo.Loader.download([{
		"url": "non-existing-folder/1.js"
	}, {
		"url": "non-existing-folder/2.js"
	}, {
		"url": "non-existing-folder/3.js"
	}], function() {
		QUnit.ok(true, "Checking if the callback is executed when non-existing scripts were passed as a function arguments");
		callback();
	}, {
		"errorTimeout": 1000 // 1 sec
	});
};

suite.prototype.cases.alreadyLoadedScripts = function(callback) {
	Echo.Loader.download([{
		"url": "{sdk}/events.js"
	}, {
		"url": "{sdk}/labels.js",
		"loaded": function() { return !!Echo.Labels; }
	}, {
		"url": "{sdk}/plugin.js"
	}], function() {
		QUnit.ok(true, "Checking if the callback is executed when the scripts loaded previously are loaded again");
		callback();
	});
};

suite.prototype.cases.equalUrlsPerSingleCall = function(callback) {
	Echo.Loader.download([
		{"url": "unit/loader/scripts/d1.js"},
		{"url": "unit/loader/scripts/d1.js"},
		{"url": "unit/loader/styles/1.css"},
		{"url": "unit/loader/styles/1.css"}
	], function() {
		QUnit.ok(!!Echo.Tests.Download.duplicate1, "Checking if the callback is executed when equal urls of js/css was loaded per single call");
		callback();
	});
};

suite.prototype.cases.equalUrlsPerSequentialCalls = function(callback) {
	Echo.Loader.download([
		{"url": "unit/loader/scripts/d2.js"},
		{"url": "unit/loader/styles/2.css"}
	], function() {
		Echo.Loader.download([
			{"url": "unit/loader/scripts/d2.js"},
			{"url": "unit/loader/styles/2.css"}
		], function() {
			QUnit.ok(!!Echo.Tests.Download.duplicate2, "Checking if the callback is executed when equal urls of js/css was loaded per sequential call");
			callback();
		});
	});
};

suite.prototype.cases.equalUrlsPerParallelCalls = function(callback) {
	var k = 2;
	var commonCallback = function() {
		if(!--k) {
			QUnit.ok(!!Echo.Tests.Download.duplicate3, "Checking if the callback is executed when equal urls of js/css was loaded per parallel call");
			callback();
		}
	};
	Echo.Loader.download([
		{"url": "unit/loader/scripts/d3.js"},
		{"url": "unit/loader/styles/3.css"}
	], commonCallback);

	Echo.Loader.download([
		{"url": "unit/loader/scripts/d3.js"},
		{"url": "unit/loader/styles/3.css"}
	], commonCallback);
};

suite.prototype.cases.validScriptsLoading = function(callback, count, description) {
	count = count || 5;
	var resources = [];
	var existingScriptsCount = 5;
	for (var i = 1; i <= count; i++) {
		resources.push({
			"url": "unit/loader/scripts/" + (count > existingScriptsCount ? "non-existing" : i) + ".js",
			"loaded": function() { return !!Echo.Tests.Download["object" + i]; }
		});
	}
	Echo.Loader.download(resources, function() {
		var success = true;
		// check only existing scripts
		for (var i = 1; i <= existingScriptsCount; i++) {
			if (success) {
				success = !!Echo.Tests.Download["object" + i];
			}
		}
		QUnit.ok(success, description || "Checking if all the test scripts were loaded successfully");
		callback();
	}, {
		"errorTimeout": 1000 // 1 sec
	});
};

suite.prototype.cases.validAndInvalidScriptsMix = function(callback) {
	this.cases.validScriptsLoading(callback, 7, "Checking if the mix of valid and invalid scripts is handled by the loader correctly");
};

suite.prototype.cases.loadingSameScriptMultipleTimes = function(callback) {
	var resources = [];
	for (var i = 1; i <= 5; i++) {
		resources.push({
			"url": "unit/loader/scripts/1.js"
		});
	}
	Echo.Loader.download(resources, function() {
		QUnit.ok(true, "Checking the situation when the same script is loaded multiple times (checking if the callback is executed)");
		callback();
	});
};

// checking canvases initialization scenarios

suite.prototype.tests.canvasesInitializationTests = {
	"config": {
		"async": true,
		"testTimeout": 15000
	},
	"check": function() {
		var self = this;
		this.sequentialAsyncTests($.map([
			"simple-valid-canvas",
			"valid-and-invalid-canvases",
			"double-initialization-prevention",
			"different-initialization-schemas",
			"multiple-apps-canvas",
			"app-config-overrides"
		], function(name) {
			return self.loaderIframeTest(name);
		}));
	}
};

// dynamic interface with utils functions

suite.prototype.loaderIframeTest = function(name) {
	return function(callback) {
		var iframe = $('');
		$(document.body).append(iframe);
		iframe.on("load", function() {
			iframe.get(0).contentWindow.test(callback);
		});
		iframe.attr("src", "unit/loader/pages/" + name + ".html");
	};
};

// static interface with utils functions (to be accessible within nested iframes)

suite.eventsCountCheck = function(events) {
	var success = true;
	$.each(events, function(id, event) {
		if (event[0] != event[1]) {
			success = false;
			return false; // break
		}
	});
	return success;
};

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