<commit_before>(function(){
    'use strict';

    if(!global.cloudcmd)
        return console.log(
            '# commander.js'                                   + '\n'  +
            '# -----------'                                    + '\n'  +
            '# Module is part of Cloud Commander,'             + '\n'  +
            '# used for getting dir content.'                  + '\n'  +
            '# and forming html content'                       + '\n'  +
            '# http://coderaiser.github.com/cloudcmd'          + '\n');

    var main                = global.cloudcmd.main,
        fs                  = main.fs,
        CloudFunc           = main.cloudfunc,
        DIR                 = main.DIR,
        LIBDIR              = main.LIBDIR,
        HTMLDIR             = main.HTMLDIR,
        Util                = main.util,
        url                 = main.url,
        querystring         = main.querystring,
        zlib                = main.zlib,

        FILE_NOT_FOUND      = 404,
        OK                  = 200,

        FS                  = CloudFunc.FS,
        NO_JS               = CloudFunc.NOJS,

        INDEX               = null,
        REQUEST             = 'request',
        RESPONSE            = 'response',

        IndexProcessingFunc = null;

    exports.sendContent = function(pParams){
        var lRet = Util.checkObj(pParams,
            ['processing'],
            [REQUEST, RESPONSE, 'index']);

        if(lRet){
            var p       = pParams,
                lPath   = getCleanPath(p.request);

            INDEX   = p.index;
            IndexProcessingFunc = pParams.processing;

            fs.stat(lPath, function(pError, pStat){
                if(!pError)
                    if(pStat.isDirectory())
                        fs.readdir(lPath, Util.call(readDir, pParams) );
                    else
                        main.sendFile({
                            name        : lPath,
                            request     : p.request,
                            response    : p.response
                        });
                else
                    sendResponse({
                        name        : lPath,
                        status      : FILE_NOT_FOUND,
                        data        : pError.toString(),
                        request     : p.request,
                        response    : p.response
                    });
            });

            lRet = true;
        }

        return lRet;
    };

    /**
     * Функция читает ссылку или выводит информацию об ошибке
     * @param pError
     * @param pFiles
     */
    function readDir(pParams){
          var lRet = Util.checkObj(pParams,
                ['error', 'data', 'params'])    &&

                Util.checkObjTrue(pParams.params,
                    [REQUEST, RESPONSE]);
        if(lRet){
            var p           = pParams,
                c           = p.params,
                lFiles      = p.data,
                lDirPath    = getDirPath(c.request);

            if(!p.error && p.data){
                lFiles.data = lFiles.sort();

                /* Получаем информацию о файлах */
                var n           = lFiles.length,
                    lStats      = {},
                    lFilesData  = {
                        files       : lFiles,
                        stats       : lStats,
                        request     : c.request,
                        response    : c.response
                    },

                    lFill   = function(){
                        fillJSON(lFilesData);
                    };

                if(n){
                    for(var i = 0; i < n; i++){
                        var lName = lDirPath + lFiles[i],
                            lParams =  {
                                callback    : lFill,
                                count       : n,
                                name        : lFiles[i],
                                stats       : lStats,
                            };

                        fs.stat( lName, Util.call(getFilesStat, lParams) );
                    }
                }
                else
                    fillJSON(lFilesData);
            }
            else
                sendResponse({
                    data    : p.Error.toString(),
                    name    : lDirPath,
                    request : c.request,
                    response: c.response,
                    status  : FILE_NOT_FOUND
                });
        }
    }

    /**
     * async getting file states
     * and putting it to lStats object
     */
    function getFilesStat(pParams){
        var lRet = Util.checkObj(pParams,
                ['error', 'data', 'params'])    &&

            Util.checkObj(pParams.params,
                ['callback'], ['stats', 'name', 'count']);

        if(lRet){
            var p = pParams,
                c = p.params;

            if(c.stats)
                c.stats[c.name] = !p.error ? p.data   : {
                    'mode'          : 0,
                    'size'          : 0,
                    'isDirectory'   : Util.retFalse
                };

            if(c.count === Object.keys(c.stats).length)
                Util.exec(c.callback);
        }
    }

    /**
     * Function fill JSON by file stats
     *
     * @param pStats - object, contain file stats.
     *          example {'1.txt': stat}
     *
     * @param pFiles - array of files of current directory
     */
    function fillJSON(pParams){
        var lFiles, lAllStats,
            i, n, lReq, lRes;

        if(pParams){
            lFiles      = pParams.files;
            lFiles &&(n = lFiles.length || 0);
            lAllStats   = pParams.stats;
            lReq        = pParams.request,
            lRes        = pParams.response;
        }
        /* данные о файлах в формате JSON*/
        var lJSON       = [],
            lJSONFile   = {},
            lList,
            lDirPath    = getDirPath(lReq);

        lJSON[0]        = {
            path    : lDirPath,
            size    : 'dir'
        };

        var lName, lStats, lMode, lIsDir;
        for( i = 0; i < n; i++ ){
            /* Переводим права доступа в 8-ричную систему */
            lName   = lFiles[i],
            lStats  = lAllStats[lName];

            if(lStats){
                lMode   = (lStats.mode - 0).toString(8),
                lIsDir  = lStats.isDirectory();
            }

            /* Если папка - выводим пиктограмму папки   *
             * В противоположном случае - файла         */
            lJSONFile = {
                'name'  : lFiles[i],
                'size'  : lIsDir ? 'dir' : lStats.size,
                'uid'   : lStats.uid,
                'mode'  : lMode
            };

            lJSON[i+1] = lJSONFile;
        }

        /* если js недоступен
         * или отключен выcылаем html-код
         * и прописываем соответствующие заголовки
         */
        if( noJS(lReq) ){
            var lPanel  = CloudFunc.buildFromJSON(lJSON);
            lList       = '
'  + lPanel + '
' +
                          '
' + lPanel + '
';

            fs.readFile(INDEX, Util.call(readFile, {
                    list     : lList,
                    request  : lReq,
                    response : lRes
                })
            );

        }else{
            lDirPath = lDirPath.substr(lDirPath, lDirPath.lastIndexOf('/') );

            /* в обычном режиме(когда js включен
             * высылаем json-структуру файлов
             * с соответствующими заголовками
             */
            lList   = JSON.stringify(lJSON);

            sendResponse({
                name    : lDirPath + '.json',
                data    : lList,
                request : lReq,
                response: lRes
            });

        }
    }

    /**
     * Функция генерирует функцию считывания файла
     * таким образом, что бы у нас было
     * имя считываемого файла
     * @param pName - полное имя файла
     */
    function readFile(pParams){
        var lRet = checkParams(pParams) &&
            Util.checkObjTrue(pParams.params,
                [REQUEST, RESPONSE, 'list']);

        if(lRet){
            var p           = pParams,
                c           = pParams.params;

            p.data = p.data.toString();

            var lParams     = {
                    name        : INDEX,
                    request     : c.request,
                    response    : c.response,
                },

                lProccessed = Util.exec(IndexProcessingFunc, {
                    additional  : c.list,
                    data        : p.data,
                });

            if(lProccessed)
                p.data = lProccessed;

            if (!p.Error){
                lParams.data      = p.data;
                Util.log('file ' + c.name + ' readed');
            }
            else{
                lParams.status    = FILE_NOT_FOUND;
                lParams.data      = p.error.toString();
            }

            sendResponse(lParams);
        }
    }
          /**
     * Функция высылает ответ серверу
     * @param pHead     - заголовок
     * @param Data      - данные
     * @param pName     - имя отсылаемого файла
     */
    function sendResponse(pParams){
         var lRet = Util.checkObjTrue(pParams,
            ['name', 'data', REQUEST, RESPONSE]);

        if(lRet){
            var p = pParams;

            var lPath       = p.name || getCleanPath(p.request),
                lQuery      = main.getQuery(p.request),
                /* download, json */
                lGzip       = isGZIP(p.request),
                lHead       = main.generateHeaders(lPath, lGzip, lQuery);

            /* если браузер поддерживает gzip-сжатие - сжимаем данные*/
            Util.ifExec(!lGzip,
                function(pParams){
                    var lRet = Util.checkObj(pParams, ['data']);

                    if(lRet){
                        p.status    = pParams.status || p.status;
                        p.data      = pParams.data;
                    }

                    p.response.writeHead(p.status || OK, lHead);
                    p.response.end(p.data);

                    Util.log(lPath + ' sended');
                    Util.log( p.status === FILE_NOT_FOUND && p.data );
                },

                function(pCallBack){
                    zlib.gzip (p.data, Util.call(gzipData, {
                        callback    : pCallBack
                    }));
                });
        }
    }

       /**
     * Функция получает сжатые данные
     * @param pHeader - заголовок файла
     * @pName
     */
    function gzipData(pParams){
        var lRet = checkParams(pParams);

        if(lRet)
            lRet = Util.checkObj(pParams.params, ['callback']);

        if(lRet){
            var p           = pParams,
                c           = pParams.params,
                lParams       = {};

            if(!p.error)
                lParams.data      = p.data;
            else{
                lParams.status    = FILE_NOT_FOUND;
                lParams.data      = p.error.toString();
            }

            Util.exec(c.callback, lParams);
        }
    }

    function checkParams(pParams){
        return Util.checkObj(pParams, ['error', 'data', 'params']);
    }

    function getPath(pReq){
        var lParsedUrl  = url.parse(pReq.url),
            lPath       = lParsedUrl.pathname;

        lPath           = querystring.unescape(lPath);
        return lPath;
    }

    function getCleanPath(pReq){
        var lPath = getPath(pReq),
            lRet = Util.removeStr(lPath, [NO_JS, FS]) || main.SLASH;

        return lRet;
    }

    function getDirPath(pReq){
        var lRet = getCleanPath(pReq);

        if(lRet !== '/')
            lRet += '/';

        return lRet;
    }

    function noJS(pReq){
        var lNoJS, lPath;

        if(pReq){
            lPath = getPath(pReq);

            lNoJS = Util.isContainStr(lPath, NO_JS)
                || lPath === '/' || main.getQuery() == 'json';
        }

        return lNoJS;
    }

    function isGZIP(pReq){
        var lEnc, lGZIP;
        if(pReq){
            lEnc        = pReq.headers['accept-encoding'] || '',
            lGZIP       = lEnc.match(/\bgzip\b/);
        }

        return lGZIP;
    }

})();<commit_msg>refactored<commit_after>(function(){
    'use strict';

    if(!global.cloudcmd)
        return console.log(
            '# commander.js'                                   + '\n'  +
            '# -----------'                                    + '\n'  +
            '# Module is part of Cloud Commander,'             + '\n'  +
            '# used for getting dir content.'                  + '\n'  +
            '# and forming html content'                       + '\n'  +
            '# http://coderaiser.github.com/cloudcmd'          + '\n');

    var main                = global.cloudcmd.main,
        fs                  = main.fs,
        CloudFunc           = main.cloudfunc,
        DIR                 = main.DIR,
        LIBDIR              = main.LIBDIR,
        HTMLDIR             = main.HTMLDIR,
        Util                = main.util,
        url                 = main.url,
        querystring         = main.querystring,
        zlib                = main.zlib,

        FILE_NOT_FOUND      = 404,
        OK                  = 200,

        FS                  = CloudFunc.FS,
        NO_JS               = CloudFunc.NOJS,

        INDEX               = null,
        REQUEST             = 'request',
        RESPONSE            = 'response',

        IndexProcessingFunc = null;

    exports.sendContent = function(pParams){
        var lRet = Util.checkObj(pParams,
            ['processing'],
            [REQUEST, RESPONSE, 'index']);

        if(lRet){
            var p       = pParams,
                lPath   = getCleanPath(p.request);

            INDEX   = p.index;
            IndexProcessingFunc = pParams.processing;

            fs.stat(lPath, function(pError, pStat){
                if(!pError)
                    if(pStat.isDirectory())
                        fs.readdir(lPath, Util.call(readDir, pParams) );
                    else
                        main.sendFile({
                            name        : lPath,
                            request     : p.request,
                            response    : p.response
                        });
                else
                    sendResponse({
                        name        : lPath,
                        status      : FILE_NOT_FOUND,
                        data        : pError.toString(),
                        request     : p.request,
                        response    : p.response
                    });
            });

            lRet = true;
        }

        return lRet;
    };

    /**
     * Функция читает ссылку или выводит информацию об ошибке
     * @param pError
     * @param pFiles
     */
    function readDir(pParams){
        var lRet = checkParams(pParams);

        if(lRet)
            lRet = Util.checkObjTrue(pParams.params,
                    [REQUEST, RESPONSE]);
        if(lRet){
            var p           = pParams,
                c           = p.params,
                lFiles      = p.data,
                lDirPath    = getDirPath(c.request);

            if(!p.error && p.data){
                lFiles.data = lFiles.sort();

                /* Получаем информацию о файлах */
                var n           = lFiles.length,
                    lStats      = {},
                    lFilesData  = {
                        files       : lFiles,
                        stats       : lStats,
                        request     : c.request,
                        response    : c.response
                    },

                    lFill   = function(){
                        fillJSON(lFilesData);
                    };

                if(n){
                    for(var i = 0; i < n; i++){
                        var lName = lDirPath + lFiles[i],
                            lParams =  {
                                callback    : lFill,
                                count       : n,
                                name        : lFiles[i],
                                stats       : lStats,
                            };

                        fs.stat( lName, Util.call(getFilesStat, lParams) );
                    }
                }
                else
                    fillJSON(lFilesData);
            }
            else
                sendResponse({
                    data    : p.Error.toString(),
                    name    : lDirPath,
                    request : c.request,
                    response: c.response,
                    status  : FILE_NOT_FOUND
                });
        }
    }

    /**
     * async getting file states
     * and putting it to lStats object
     */
    function getFilesStat(pParams){
        var lRet = checkParams(pParams);

        if(lRet)
            lRet = Util.checkObj(pParams.params,
                ['callback'], ['stats', 'name', 'count']);

        if(lRet){
            var p = pParams,
                c = p.params;

            if(c.stats)
                c.stats[c.name] = !p.error ? p.data   : {
                    'mode'          : 0,
                    'size'          : 0,
                    'isDirectory'   : Util.retFalse
                };

            if(c.count === Object.keys(c.stats).length)
                Util.exec(c.callback);
        }
    }

    /**
     * Function fill JSON by file stats
     *
     * @param pStats - object, contain file stats.
     *          example {'1.txt': stat}
     *
     * @param pFiles - array of files of current directory
     */
    function fillJSON(pParams){
        var lFiles, lAllStats,
            i, n, lReq, lRes;

        if(pParams){
            lFiles      = pParams.files;
            lFiles &&(n = lFiles.length || 0);
            lAllStats   = pParams.stats;
            lReq        = pParams.request,
            lRes        = pParams.response;
        }
        /* данные о файлах в формате JSON*/
        var lJSON       = [],
            lJSONFile   = {},
            lList,
            lDirPath    = getDirPath(lReq);

        lJSON[0]        = {
            path    : lDirPath,
            size    : 'dir'
        };

        var lName, lStats, lMode, lIsDir;
        for( i = 0; i < n; i++ ){
            /* Переводим права доступа в 8-ричную систему */
            lName   = lFiles[i],
            lStats  = lAllStats[lName];

            if(lStats){
                lMode   = (lStats.mode - 0).toString(8),
                lIsDir  = lStats.isDirectory();
            }

            /* Если папка - выводим пиктограмму папки   *
             * В противоположном случае - файла         */
            lJSONFile = {
                'name'  : lFiles[i],
                'size'  : lIsDir ? 'dir' : lStats.size,
                'uid'   : lStats.uid,
                'mode'  : lMode
            };

            lJSON[i+1] = lJSONFile;
        }

        /* если js недоступен
         * или отключен выcылаем html-код
         * и прописываем соответствующие заголовки
         */
        if( noJS(lReq) ){
            var lPanel  = CloudFunc.buildFromJSON(lJSON);
            lList       = '
'  + lPanel + '
' +
                          '
' + lPanel + '
';

            fs.readFile(INDEX, Util.call(readFile, {
                    list     : lList,
                    request  : lReq,
                    response : lRes
                })
            );

        }else{
            lDirPath = lDirPath.substr(lDirPath, lDirPath.lastIndexOf('/') );

            /* в обычном режиме(когда js включен
             * высылаем json-структуру файлов
             * с соответствующими заголовками
             */
            lList   = JSON.stringify(lJSON);

            sendResponse({
                name    : lDirPath + '.json',
                data    : lList,
                request : lReq,
                response: lRes
            });

        }
    }

    /**
     * Функция генерирует функцию считывания файла
     * таким образом, что бы у нас было
     * имя считываемого файла
     * @param pName - полное имя файла
     */
    function readFile(pParams){
        var lRet = checkParams(pParams);

        if(lRet)
            lRet = Util.checkObjTrue(pParams.params,
                [REQUEST, RESPONSE, 'list']);

        if(lRet){
            var p           = pParams,
                c           = pParams.params;

            p.data = p.data.toString();

            var lParams     = {
                    name        : INDEX,
                    request     : c.request,
                    response    : c.response,
                },

                lProccessed = Util.exec(IndexProcessingFunc, {
                    additional  : c.list,
                    data        : p.data,
                });

            if(lProccessed)
                p.data = lProccessed;

            if (!p.Error){
                lParams.data      = p.data;
                Util.log('file ' + c.name + ' readed');
            }
            else{
                lParams.status    = FILE_NOT_FOUND;
                lParams.data      = p.error.toString();
            }

            sendResponse(lParams);
        }
    }
          /**
     * Функция высылает ответ серверу
     * @param pHead     - заголовок
     * @param Data      - данные
     * @param pName     - имя отсылаемого файла
     */
    function sendResponse(pParams){
         var lRet = Util.checkObjTrue(pParams,
            ['name', 'data', REQUEST, RESPONSE]);

        if(lRet){
            var p = pParams;

            var lPath       = p.name || getCleanPath(p.request),
                lQuery      = main.getQuery(p.request),
                /* download, json */
                lGzip       = isGZIP(p.request),
                lHead       = main.generateHeaders(lPath, lGzip, lQuery);

            /* если браузер поддерживает gzip-сжатие - сжимаем данные*/
            Util.ifExec(!lGzip,
                function(pParams){
                    var lRet = Util.checkObj(pParams, ['data']);

                    if(lRet){
                        p.status    = pParams.status || p.status;
                        p.data      = pParams.data;
                    }

                    p.response.writeHead(p.status || OK, lHead);
                    p.response.end(p.data);

                    Util.log(lPath + ' sended');
                    Util.log( p.status === FILE_NOT_FOUND && p.data );
                },

                function(pCallBack){
                    zlib.gzip (p.data, Util.call(gzipData, {
                        callback    : pCallBack
                    }));
                });
        }
    }

       /**
     * Функция получает сжатые данные
     * @param pHeader - заголовок файла
     * @pName
     */
    function gzipData(pParams){
        var lRet = checkParams(pParams);

        if(lRet)
            lRet = Util.checkObj(pParams.params, ['callback']);

        if(lRet){
            var p           = pParams,
                c           = pParams.params,
                lParams       = {};

            if(!p.error)
                lParams.data      = p.data;
            else{
                lParams.status    = FILE_NOT_FOUND;
                lParams.data      = p.error.toString();
            }

            Util.exec(c.callback, lParams);
        }
    }

    function checkParams(pParams){
        return Util.checkObj(pParams, ['error', 'data', 'params']);
    }

    function getPath(pReq){
        var lParsedUrl  = url.parse(pReq.url),
            lPath       = lParsedUrl.pathname;

        lPath           = querystring.unescape(lPath);
        return lPath;
    }

    function getCleanPath(pReq){
        var lPath = getPath(pReq),
            lRet = Util.removeStr(lPath, [NO_JS, FS]) || main.SLASH;

        return lRet;
    }

    function getDirPath(pReq){
        var lRet = getCleanPath(pReq);

        if(lRet !== '/')
            lRet += '/';

        return lRet;
    }

    function noJS(pReq){
        var lNoJS, lPath;

        if(pReq){
            lPath = getPath(pReq);

            lNoJS = Util.isContainStr(lPath, NO_JS)
                || lPath === '/' || main.getQuery() == 'json';
        }

        return lNoJS;
    }

    function isGZIP(pReq){
        var lEnc, lGZIP;
        if(pReq){
            lEnc        = pReq.headers['accept-encoding'] || '',
            lGZIP       = lEnc.match(/\bgzip\b/);
        }

        return lGZIP;
    }

})();<|endoftext|>


<commit_before>(function(scope) {
    'use strict';

    var Scope = scope.window ? window : global;

    if (typeof module === 'object' && module.exports)
        module.exports = new UtilProto();
    else if (!Scope.Util)
        Scope.Util = new UtilProto();

    function UtilProto() {
        var Util = this;

        /*
         * apply arguemnts to constructor
         *
         * @param constructor
         * @param args
         */
        this.applyConstructor   = function(constructor, args) {
            var F = function () {
                return constructor.apply(this, args);
            };

            F.prototype = constructor.prototype;
            return new F();
        };

        /**
         * Функция ищет в имени файла расширение
         * и если находит возвращает true
         * @param name - получает имя файла
         * @param ext - расширение
         */
        this.checkExt           = function(name, ext) {
            var isMatch, str,
                type        = Util.type(ext),
                regStr      = '\\.({{ exts }})$',
                regExp;

            switch(type) {
            case 'string':
                regStr      = Util.render(regStr, {
                    exts: ext
                });

                regExp      = new RegExp(regStr, 'i');
                isMatch     = regExp.test(name);

                break;

            case 'array':
                str         = ext.join('|');
                isMatch     = Util.checkExt(name, str);

                break;
            }

            return isMatch;
        };

        this.check              = new checkProto();

        function checkProto() {
            /**
             * Check is all arguments with names present
             *
             * @param name
             * @param arg
             * @param type
             */
            var check = function check(args, names) {
                var msg         = '',
                    name        = '',
                    template    = '{{ name }} coud not be empty!',

                    indexOf     = Array.prototype.indexOf,

                    lenNames    = names.length,
                    lenArgs     = args.length,
                    lessArgs    = lenArgs < lenNames,
                    emptyIndex  = indexOf.call(args),
                    isEmpty     = ~emptyIndex;

                if (lessArgs || isEmpty) {
                    if (lessArgs)
                        name        = names[lenNames - 1];
                    else
                        name        = names[emptyIndex];

                    msg         = Util.render(template, {
                        name: name
                    });

                    throw(Error(msg));
                }

                return check;
            };

            check.check = check;

            /**
             * Check is type of arg with name is equal to type
             *
             * @param name
             * @param arg
             * @param type
             */
            check.type  = function(name, arg, type) {
                var is = Util.type(arg) === type;

                if (!is)
                    throw(Error(name + ' should be ' + type));

                return check;
            };

            return check;
        }

        /**
         * Copy properties from from to to
         *
         * @param from
         * @param to
         */
        this.copyObj                = function(to, from) {
            if (!from) {
                from    = to;
                to      = {};
            }

            if (to)
                Object.keys(from).forEach(function(name) {
                    to[name]    = from[name];
                });

            return to;
        };

        /**
         * copy objFrom properties to target
         *
         * @target
         * @objFrom
         */
        this.extend                 = function(target, objFrom) {
            var obj,
                keys,
                proto,
                isFunc  = Util.type.function(objFrom),
                isArray = Util.type.array(objFrom),
                isObj   = Util.type.object(target),
                ret     = isObj ? target : {};

            if (isArray)
                objFrom.forEach(function(item) {
                   ret = Util.extend(target, item);
                });

            else if (objFrom) {
                obj     = isFunc ? new objFrom() : objFrom;
                keys    = Object.keys(obj);

                if (!keys.length) {
                    proto = Object.getPrototypeOf(objFrom);
                    keys  = Object.keys(proto);
                }

                keys.forEach(function(name) {
                    ret[name] = obj[name];
                });
            }

            return ret;
        };

        /**
         * extend proto
         *
         * @obj
         */
        this.extendProto           = function(obj) {
            var ret, F      = function() {};
            F.prototype     = Util.extend({}, obj);
            ret             = new F();

            return ret;
        };

        this.json               = new JsonProto();

        function JsonProto() {
            /**
             * @param str
             */
            this.parse      = function(str) {
                var obj;

                Util.exec.try(function() {
                    obj = JSON.parse(str);
                });

                return obj;
            },

            /**
             * @param obj
             */
            this.stringify  = function(obj) {
                var str;

                Util.exec.try(function() {
                    str = JSON.stringify(obj, null, 4);
                });

                return str;
            };
        }

        this.escapeRegExp = function(str) {
            var isStr   = Util.type.string(str);

            if (isStr)
                str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');

            return str;
        };

        /**
         * get regexp from wild card
         */
        this.getRegExp              = function(wildcard) {
            var regExp;

            if (!wildcard)
                wildcard = '*';

            wildcard    = '^' + wildcard /* search from start of line */
                .replace('.', '\\.')
                .replace('*', '.*')
                .replace('?', '.?');

            wildcard    += '$'; /* search to end of line */

            regExp      = new RegExp(wildcard);

            return regExp;
        };

        /**
         * function render template with view and own symbols
         *
         * @param templ
         * @param view
         */
        this.render = function(templ, view) {
            var str, regExp,
                result  = templ;

            Object
                .keys(view)
                .forEach(function(param) {
                    str     = view[param];
                    regExp  = RegExp('{{\\s' + param + '\\s}}', 'g');
                    result  = result.replace(regExp, str);
                });

            if (~result.indexOf('{{'))
                result = result.replace(/{{.*}}/g, '');

            return result;
        };

        this.type                   = new TypeProto();

        function TypeProto() {
            /**
             * get type of variable
             *
             * @param variable
             */
            function type(variable) {
                var regExp      = /\s([a-zA-Z]+)/,
                    str         = {}.toString.call(variable),
                    typeBig     = str.match(regExp)[1],
                    result      = typeBig.toLowerCase();

                return result;
            }

            /**
             * functions check is variable is type of name
             *
             * @param variable
             */
            function typeOf(name, variable) {
                return type(variable) === name;
            }

            function typeOfSimple(name, variable) {
                return typeof variable === name;
            }

            ['null', 'arrayBuffer', 'file', 'array', 'object']
                .forEach(function(name) {
                    type[name] = typeOf.bind(null, name);
                });

            ['string', 'undefined', 'boolean', 'number', 'function']
                .forEach(function(name) {
                    type[name] = typeOfSimple.bind(null, name);
                });

            return type;
        }

        this.exec                       = new ExecProto();

        function ExecProto() {
            /**
             * function do save exec of function
             * @param callback
             * @param arg1
             * ...
             * @param argN
             */
            var exec        = function(callback) {
                var ret,
                    isFunc  = Util.type.function(callback),
                    args    = [].slice.call(arguments, 1);

                if (isFunc)
                    ret     = callback.apply(null, args);

                return ret;
            };

            /*
             * return function that calls callback with arguments
             */

            exec.with           =  function(callback) {
                var result,
                    bind        = Function.bind;

                arguments[0]    = null;
                result          = bind.apply(callback, arguments);

                return result;
            };

             /**
             * return save exec function
             * @param callback
             */
            exec.ret        = function() {
                var result,
                    args        = [].slice.call(arguments);

                args.unshift(exec);
                result          = exec.with.apply(null, args);

                return result;
            };

            /**
             * function do conditional save exec of function
             * @param condition
             * @param callback
             * @param func
             */
            exec.if         = function(condition, callback, func) {
                var ret;

                if (condition)
                    exec(callback);
                else
                    exec(func, callback);

                return ret;
            };

            /**
             * exec function if it exist in object
             *
             * @param obj
             * @param name
             * @param arg
             */
            exec.ifExist                = function(obj, name, arg) {
                var ret,
                    func    = obj && obj[name];

                if (func)
                    func    = func.apply(obj, arg);

                return ret;
            };

            exec.parallel   = function(funcs, callback) {
                var keys        = [],
                    callbackWas = false,
                    arr         = [],
                    obj         = {},
                    count       = 0,
                    countFuncs  = 0,
                    type        = Util.type(funcs);

                Util.check(arguments, ['funcs', 'callback']);

                switch(type) {
                case 'array':
                    countFuncs  = funcs.length;

                    funcs.forEach(function(func, num) {
                        exec(func, function() {
                            checkFunc(num, arguments, arr);
                        });
                    });
                    break;

                case 'object':
                    keys        = Object.keys(funcs);
                    countFuncs  = keys.length;

                    keys.forEach(function(name) {
                        var func    = funcs[name];

                        exec(func, function() {
                            checkFunc(name, arguments, obj);
                        });
                    });
                    break;
                }

                function checkFunc(num, data, all) {
                    var args    = [].slice.call(data, 1),
                        isLast  = false,
                        error   = data[0],
                        length  = args.length;

                    ++count;

                    isLast = count === countFuncs;

                    if (!error)
                        if (length >= 2)
                            all[num] = args;
                        else
                            all[num] = args[0];

                    if (!callbackWas && (error || isLast)) {
                        callbackWas = true;

                        if (type === 'array')
                            callback.apply(null, [error].concat(all));
                        else
                            callback(error, all);
                    }
                }
            };

            /**
             * load functions thrue callbacks one-by-one
             * @param funcs {Array} - array of functions
             */
            exec.series             = function(funcs) {
                var func, callback,
                    isArray     = Util.type.array(funcs);

                if (isArray) {
                    func        = funcs.shift();

                    callback    = function() {
                        return exec.series(funcs);
                    };

                    exec(func, callback);
                }
            };

           /**
             * function execute param function in
             * try...catch block
             *
             * @param callback
             */
            exec.try                = function(callback) {
                var ret;
                try {
                    ret = callback();
                } catch(error) {
                    ret = error;
                }

                return ret;
            };

            return exec;
        }

        /**
         * function gets file extension
         * @param pFileName
         * @return Ext
         */
        this.getExt                     = function(name) {
            var ret     = '',
                dot,
                isStr   = Util.type.string(name);

            if (isStr) {
                dot = name.lastIndexOf('.');

                if (~dot)
                    ret = name.substr(dot);
            }

            return ret;
        };

       /**
         * get values from Object Array name properties
         * or
         * @pObj
         */
        this.getNamesFromObjArray       = function(arr) {
            var ret     = [],
                isArray = Util.type.array(arr);

            if (arr && !isArray)
                arr = arr.data;

            if (arr)
                arr.forEach(function(item) {
                    ret.push(item.name || item);
                });

            return ret;
        };

        /**
         * find object by name in arrray
         *
         * @param array
         * @param name
         */
        this.findObjByNameInArr         = function(array, name) {
            var ret;

             if (!Array.isArray(array))
                throw(Error('array should be array!'));

            if (typeof name !== 'string')
                throw(Error('name should be string!'));

            array.some(function(item) {
                var is = item.name === name,
                    isArray = Util.type.array(item);

                if (is)
                    ret = item;
                else if (isArray)
                    item.some(function(item) {
                        is = item.name === name;

                        if (is)
                            ret = item.data;

                        return is;
                    });

                return is;
            });

            return ret;
        };

        /**
         * Gets current time in format hh:mm:ss
         */
        this.getTime                    = function() {
            var ret,
                date        = new Date(),
                hours       = date.getHours(),
                minutes     = date.getMinutes(),
                seconds     = date.getSeconds();

            minutes         = minutes < 10 ? '0' + minutes : minutes;
            seconds         = seconds < 10 ? '0' + seconds : seconds;

            ret            = hours + ':' + minutes + ':' + seconds;

            return ret;
        };

        /**
         * start timer
         * @param name
         */
        this.time                       = function(name) {
            var console     = Scope.console;

            Util.exec.ifExist(console, 'time', [name]);

            return this;
        };

        /**
         * stop timer
         * @param name
         */
        this.timeEnd                   = function(name) {
            var console    = Scope.console;

            Util.exec.ifExist(console, 'timeEnd', [name]);

            return this;
        };
    }

})(this);
<commit_msg>refactor(util) getNamesFromObjArray<commit_after>(function(scope) {
    'use strict';

    var Scope = scope.window ? window : global;

    if (typeof module === 'object' && module.exports)
        module.exports = new UtilProto();
    else if (!Scope.Util)
        Scope.Util = new UtilProto();

    function UtilProto() {
        var Util = this;

        /*
         * apply arguemnts to constructor
         *
         * @param constructor
         * @param args
         */
        this.applyConstructor   = function(constructor, args) {
            var F = function () {
                return constructor.apply(this, args);
            };

            F.prototype = constructor.prototype;
            return new F();
        };

        /**
         * Функция ищет в имени файла расширение
         * и если находит возвращает true
         * @param name - получает имя файла
         * @param ext - расширение
         */
        this.checkExt           = function(name, ext) {
            var isMatch, str,
                type        = Util.type(ext),
                regStr      = '\\.({{ exts }})$',
                regExp;

            switch(type) {
            case 'string':
                regStr      = Util.render(regStr, {
                    exts: ext
                });

                regExp      = new RegExp(regStr, 'i');
                isMatch     = regExp.test(name);

                break;

            case 'array':
                str         = ext.join('|');
                isMatch     = Util.checkExt(name, str);

                break;
            }

            return isMatch;
        };

        this.check              = new checkProto();

        function checkProto() {
            /**
             * Check is all arguments with names present
             *
             * @param name
             * @param arg
             * @param type
             */
            var check = function check(args, names) {
                var msg         = '',
                    name        = '',
                    template    = '{{ name }} coud not be empty!',

                    indexOf     = Array.prototype.indexOf,

                    lenNames    = names.length,
                    lenArgs     = args.length,
                    lessArgs    = lenArgs < lenNames,
                    emptyIndex  = indexOf.call(args),
                    isEmpty     = ~emptyIndex;

                if (lessArgs || isEmpty) {
                    if (lessArgs)
                        name        = names[lenNames - 1];
                    else
                        name        = names[emptyIndex];

                    msg         = Util.render(template, {
                        name: name
                    });

                    throw(Error(msg));
                }

                return check;
            };

            check.check = check;

            /**
             * Check is type of arg with name is equal to type
             *
             * @param name
             * @param arg
             * @param type
             */
            check.type  = function(name, arg, type) {
                var is = Util.type(arg) === type;

                if (!is)
                    throw(Error(name + ' should be ' + type));

                return check;
            };

            return check;
        }

        /**
         * Copy properties from from to to
         *
         * @param from
         * @param to
         */
        this.copyObj                = function(to, from) {
            if (!from) {
                from    = to;
                to      = {};
            }

            if (to)
                Object.keys(from).forEach(function(name) {
                    to[name]    = from[name];
                });

            return to;
        };

        /**
         * copy objFrom properties to target
         *
         * @target
         * @objFrom
         */
        this.extend                 = function(target, objFrom) {
            var obj,
                keys,
                proto,
                isFunc  = Util.type.function(objFrom),
                isArray = Util.type.array(objFrom),
                isObj   = Util.type.object(target),
                ret     = isObj ? target : {};

            if (isArray)
                objFrom.forEach(function(item) {
                   ret = Util.extend(target, item);
                });

            else if (objFrom) {
                obj     = isFunc ? new objFrom() : objFrom;
                keys    = Object.keys(obj);

                if (!keys.length) {
                    proto = Object.getPrototypeOf(objFrom);
                    keys  = Object.keys(proto);
                }

                keys.forEach(function(name) {
                    ret[name] = obj[name];
                });
            }

            return ret;
        };

        /**
         * extend proto
         *
         * @obj
         */
        this.extendProto           = function(obj) {
            var ret, F      = function() {};
            F.prototype     = Util.extend({}, obj);
            ret             = new F();

            return ret;
        };

        this.json               = new JsonProto();

        function JsonProto() {
            /**
             * @param str
             */
            this.parse      = function(str) {
                var obj;

                Util.exec.try(function() {
                    obj = JSON.parse(str);
                });

                return obj;
            },

            /**
             * @param obj
             */
            this.stringify  = function(obj) {
                var str;

                Util.exec.try(function() {
                    str = JSON.stringify(obj, null, 4);
                });

                return str;
            };
        }

        this.escapeRegExp = function(str) {
            var isStr   = Util.type.string(str);

            if (isStr)
                str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');

            return str;
        };

        /**
         * get regexp from wild card
         */
        this.getRegExp              = function(wildcard) {
            var regExp;

            if (!wildcard)
                wildcard = '*';

            wildcard    = '^' + wildcard /* search from start of line */
                .replace('.', '\\.')
                .replace('*', '.*')
                .replace('?', '.?');

            wildcard    += '$'; /* search to end of line */

            regExp      = new RegExp(wildcard);

            return regExp;
        };

        /**
         * function render template with view and own symbols
         *
         * @param templ
         * @param view
         */
        this.render = function(templ, view) {
            var str, regExp,
                result  = templ;

            Object
                .keys(view)
                .forEach(function(param) {
                    str     = view[param];
                    regExp  = RegExp('{{\\s' + param + '\\s}}', 'g');
                    result  = result.replace(regExp, str);
                });

            if (~result.indexOf('{{'))
                result = result.replace(/{{.*}}/g, '');

            return result;
        };

        this.type                   = new TypeProto();

        function TypeProto() {
            /**
             * get type of variable
             *
             * @param variable
             */
            function type(variable) {
                var regExp      = /\s([a-zA-Z]+)/,
                    str         = {}.toString.call(variable),
                    typeBig     = str.match(regExp)[1],
                    result      = typeBig.toLowerCase();

                return result;
            }

            /**
             * functions check is variable is type of name
             *
             * @param variable
             */
            function typeOf(name, variable) {
                return type(variable) === name;
            }

            function typeOfSimple(name, variable) {
                return typeof variable === name;
            }

            ['null', 'arrayBuffer', 'file', 'array', 'object']
                .forEach(function(name) {
                    type[name] = typeOf.bind(null, name);
                });

            ['string', 'undefined', 'boolean', 'number', 'function']
                .forEach(function(name) {
                    type[name] = typeOfSimple.bind(null, name);
                });

            return type;
        }

        this.exec                       = new ExecProto();

        function ExecProto() {
            /**
             * function do save exec of function
             * @param callback
             * @param arg1
             * ...
             * @param argN
             */
            var exec        = function(callback) {
                var ret,
                    isFunc  = Util.type.function(callback),
                    args    = [].slice.call(arguments, 1);

                if (isFunc)
                    ret     = callback.apply(null, args);

                return ret;
            };

            /*
             * return function that calls callback with arguments
             */

            exec.with           =  function(callback) {
                var result,
                    bind        = Function.bind;

                arguments[0]    = null;
                result          = bind.apply(callback, arguments);

                return result;
            };

             /**
             * return save exec function
             * @param callback
             */
            exec.ret        = function() {
                var result,
                    args        = [].slice.call(arguments);

                args.unshift(exec);
                result          = exec.with.apply(null, args);

                return result;
            };

            /**
             * function do conditional save exec of function
             * @param condition
             * @param callback
             * @param func
             */
            exec.if         = function(condition, callback, func) {
                var ret;

                if (condition)
                    exec(callback);
                else
                    exec(func, callback);

                return ret;
            };

            /**
             * exec function if it exist in object
             *
             * @param obj
             * @param name
             * @param arg
             */
            exec.ifExist                = function(obj, name, arg) {
                var ret,
                    func    = obj && obj[name];

                if (func)
                    func    = func.apply(obj, arg);

                return ret;
            };

            exec.parallel   = function(funcs, callback) {
                var keys        = [],
                    callbackWas = false,
                    arr         = [],
                    obj         = {},
                    count       = 0,
                    countFuncs  = 0,
                    type        = Util.type(funcs);

                Util.check(arguments, ['funcs', 'callback']);

                switch(type) {
                case 'array':
                    countFuncs  = funcs.length;

                    funcs.forEach(function(func, num) {
                        exec(func, function() {
                            checkFunc(num, arguments, arr);
                        });
                    });
                    break;

                case 'object':
                    keys        = Object.keys(funcs);
                    countFuncs  = keys.length;

                    keys.forEach(function(name) {
                        var func    = funcs[name];

                        exec(func, function() {
                            checkFunc(name, arguments, obj);
                        });
                    });
                    break;
                }

                function checkFunc(num, data, all) {
                    var args    = [].slice.call(data, 1),
                        isLast  = false,
                        error   = data[0],
                        length  = args.length;

                    ++count;

                    isLast = count === countFuncs;

                    if (!error)
                        if (length >= 2)
                            all[num] = args;
                        else
                            all[num] = args[0];

                    if (!callbackWas && (error || isLast)) {
                        callbackWas = true;

                        if (type === 'array')
                            callback.apply(null, [error].concat(all));
                        else
                            callback(error, all);
                    }
                }
            };

            /**
             * load functions thrue callbacks one-by-one
             * @param funcs {Array} - array of functions
             */
            exec.series             = function(funcs) {
                var func, callback,
                    isArray     = Util.type.array(funcs);

                if (isArray) {
                    func        = funcs.shift();

                    callback    = function() {
                        return exec.series(funcs);
                    };

                    exec(func, callback);
                }
            };

           /**
             * function execute param function in
             * try...catch block
             *
             * @param callback
             */
            exec.try                = function(callback) {
                var ret;
                try {
                    ret = callback();
                } catch(error) {
                    ret = error;
                }

                return ret;
            };

            return exec;
        }

        /**
         * function gets file extension
         * @param pFileName
         * @return Ext
         */
        this.getExt                     = function(name) {
            var ret     = '',
                dot,
                isStr   = Util.type.string(name);

            if (isStr) {
                dot = name.lastIndexOf('.');

                if (~dot)
                    ret = name.substr(dot);
            }

            return ret;
        };

       /**
         * get values from Object Array name properties
         * or
         * @pObj
         */
        this.getNamesFromObjArray       = function(arr) {
            var ret     = [];

            if (!Array.isArray(arr))
                throw(Error('arr should be array!'));

            arr.forEach(function(item) {
                ret.push(item.name);
            });

            return ret;
        };

        /**
         * find object by name in arrray
         *
         * @param array
         * @param name
         */
        this.findObjByNameInArr         = function(array, name) {
            var ret;

             if (!Array.isArray(array))
                throw(Error('array should be array!'));

            if (typeof name !== 'string')
                throw(Error('name should be string!'));

            array.some(function(item) {
                var is = item.name === name,
                    isArray = Util.type.array(item);

                if (is)
                    ret = item;
                else if (isArray)
                    item.some(function(item) {
                        is = item.name === name;

                        if (is)
                            ret = item.data;

                        return is;
                    });

                return is;
            });

            return ret;
        };

        /**
         * Gets current time in format hh:mm:ss
         */
        this.getTime                    = function() {
            var ret,
                date        = new Date(),
                hours       = date.getHours(),
                minutes     = date.getMinutes(),
                seconds     = date.getSeconds();

            minutes         = minutes < 10 ? '0' + minutes : minutes;
            seconds         = seconds < 10 ? '0' + seconds : seconds;

            ret            = hours + ':' + minutes + ':' + seconds;

            return ret;
        };

        /**
         * start timer
         * @param name
         */
        this.time                       = function(name) {
            var console     = Scope.console;

            Util.exec.ifExist(console, 'time', [name]);

            return this;
        };

        /**
         * stop timer
         * @param name
         */
        this.timeEnd                   = function(name) {
            var console    = Scope.console;

            Util.exec.ifExist(console, 'timeEnd', [name]);

            return this;
        };
    }

})(this);
<|endoftext|>


<commit_before>/*
	Utility Functions
*/

// Set the width of the side navigation to show
function openNav() {
  $('#mySidenav').css('width', '25%');
}

// Set the width of the side navigation to 0
function closeNav() {
  $('#mySidenav').css('width','0px');
}

function getIDFromPokemonURL(url){
  /*
    Grabs the value between the last two /'s
    (i.e http://pokeapi.co/api/v2/pokemon/1/ => 1)
  */
  // var id = url.replace(/(.*)(pokemon|pokemon\-species)\/(.*)\//, '$3');
  var id = url.replace(/.*\/.*\/(.*?)\//, '$1');
  return id;
}

function showSection(sectionName){
  sectionName = sectionName.trim();

  if ($( "#" + sectionName ).hasClass("hidden")) {
    $('.' + sectionName + ' button').html('–');
    $('#' + sectionName).removeClass("hidden").addClass("expanded");
    $('#' + sectionName).focus();
  }else {
    $('.' + sectionName + ' button').html('+');
    $('#' + sectionName).addClass("hidden").removeClass("expanded");
  }
}

function setAutoComplete(results, searchBox, passedArray) {
  $.each(results, function(index, value){
    var name = value.name;
    passedArray.push(name);
  });
  var options = {
    data        :   passedArray,
    theme       :   'square',
    adjustWidth :   false,

    list        :   {
      match          : {
        enabled: true
      },
      onChooseEvent   :   function(){
        var pokemonName = $("#" + searchBox).getSelectedItemData();
        // newFunction(pokemonName, passedArray);
        // changePage(pokemonName, passedArray);
        if (pokemonName !== null) {
          pokemonName = pokemonName.toLowerCase();
          //make sure that pokemon name exists
          if(passedArray.indexOf(pokemonName) > -1){
            console.log('x');
            loadOverlay(pokemonName);
            // window.location = "./" + pokemonID;
          }
        }
      }
    }
  }

  $('#' + searchBox).easyAutocomplete(options);

}

function newFunction(pokemonName, passedArray) {
  showSearch();
}

function changePage(pokemonID) {
  window.location = "./" + pokemonID;
  // console.log(pokemonID);
  // if (pokemonID !== null) {
  //   pokemonID = pokemonID.toLowerCase();
  //   //make sure that pokemon name exists
  //   if(passedArray.indexOf(pokemonID) > -1){
  //     console.log('x');
  //     loadOverlay(pokemonID);
  //
  //   }
  // };
};

function showSearch(){
  if ($( "#searchContainer" ).hasClass("hidden")) {
    $('#searchContainer').removeClass("hidden");
    $('#pokemonSearchBox').focus();
  }else {
    $('#searchContainer').addClass("hidden");
  }
}

// Call Page Change Animation
function loadOverlay(pokemonID){
  // alert('load overlay');
  $('#loadingAnimation').removeClass('hidden');
  console.log('loading new page...');
  $('#searchContainer').addClass('hidden');
  $('#loadingDiv').removeClass('hidden');
  // window.location = "./" + pokemonID;
  changePage(pokemonID);
  // $('#loadingAnimation').removeClass('hidden');
}

function getQS(object){
  /*
  Query string values get returned back to the object
  Use object.key|object[key] //returns value
  */
  var pl     = /\+/g;  // Regex for replacing addition symbol with a space
  var search = /([^&=]+)=?([^&]*)/g;
  var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
  var query  = window.location.search.substring(1);
  var match;

  while (match = search.exec(query)){
    object[decode(match[1])] = decode(match[2]);
  }
}
<commit_msg>removing old code<commit_after>/*
	Utility Functions
*/

// Set the width of the side navigation to show
function openNav() {
  $('#mySidenav').css('width', '25%');
}

// Set the width of the side navigation to 0
function closeNav() {
  $('#mySidenav').css('width','0px');
}

function getIDFromPokemonURL(url){
  /*
    Grabs the value between the last two /'s
    (i.e http://pokeapi.co/api/v2/pokemon/1/ => 1)
  */
  // var id = url.replace(/(.*)(pokemon|pokemon\-species)\/(.*)\//, '$3');
  var id = url.replace(/.*\/.*\/(.*?)\//, '$1');
  return id;
}

function showSection(sectionName){
  sectionName = sectionName.trim();

  if ($( "#" + sectionName ).hasClass("hidden")) {
    $('.' + sectionName + ' button').html('–');
    $('#' + sectionName).removeClass("hidden").addClass("expanded");
    $('#' + sectionName).focus();
  }else {
    $('.' + sectionName + ' button').html('+');
    $('#' + sectionName).addClass("hidden").removeClass("expanded");
  }
}

function setAutoComplete(results, searchBox, passedArray) {
  $.each(results, function(index, value){
    var name = value.name;
    passedArray.push(name);
  });
  var options = {
    data        :   passedArray,
    theme       :   'square',
    adjustWidth :   false,

    list        :   {
      match          : {
        enabled: true
      },
      onChooseEvent   :   function(){
        var pokemonName = $("#" + searchBox).getSelectedItemData();
        // newFunction(pokemonName, passedArray);
        // changePage(pokemonName, passedArray);
        if (pokemonName !== null) {
          pokemonName = pokemonName.toLowerCase();
          //make sure that pokemon name exists
          if(passedArray.indexOf(pokemonName) > -1){
            console.log('x');
            loadOverlay(pokemonName);
            // window.location = "./" + pokemonID;
          }
        }
      }
    }
  }

  $('#' + searchBox).easyAutocomplete(options);

}

function newFunction(pokemonName, passedArray) {
  showSearch();
}

function changePage(pokemonID) {
  window.location = "./" + pokemonID;
};

function showSearch(){
  if ($( "#searchContainer" ).hasClass("hidden")) {
    $('#searchContainer').removeClass("hidden");
    $('#pokemonSearchBox').focus();
  }else {
    $('#searchContainer').addClass("hidden");
  }
}

// Call Page Change Animation
function loadOverlay(pokemonID){
  // alert('load overlay');
  $('#loadingAnimation').removeClass('hidden');
  console.log('loading new page...');
  $('#searchContainer').addClass('hidden');
  $('#loadingDiv').removeClass('hidden');
  changePage(pokemonID);
}

function getQS(object){
  /*
  Query string values get returned back to the object
  Use object.key|object[key] //returns value
  */
  var pl     = /\+/g;  // Regex for replacing addition symbol with a space
  var search = /([^&=]+)=?([^&]*)/g;
  var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); };
  var query  = window.location.search.substring(1);
  var match;

  while (match = search.exec(query)){
    object[decode(match[1])] = decode(match[2]);
  }
}
<|endoftext|>


<commit_before>'use strict';

const urlParser = require('url');

// Priorities list of matchers
const MIME_TYPE_MATCHERS = [
  [/^text\/html/, 'html'],
  [/^text\/plain/, 'plain'],
  [/^text\/css/, 'css'],
  [/^text\/xml/, 'xml'],
  [/javascript/, 'javascript'],
  [/flash/, 'flash'],
  [/^image\/x-icon/, 'favicon'],
  [/^image\/vnd.microsoft.icon/, 'favicon'],
  [/svg/, 'svg'],
  [/^image/, 'image'],
  [/^application\/.*font/, 'font'],
  [/^font\/.*/, 'font'],
  [/^application\/json/, 'json'],
  [/^application\/xml/, 'xml'],
  [/^application\/pdf/, 'pdf'],
  [/^audio\/.*/, 'audio'],
  [/^video\/.*/, 'video'],
  [/^application\/ocsp-response/, 'oscp'],
  [/.*/, 'other'] // Always match 'other' if all else fails
];

/**
 * Utilities for getting content from HAR:s.
 * @module util
 */
module.exports = {
  /**
   * Get the content type from mime type.
   * @param {string} mimeType The mimeType
   * @returns {string} the content type or 'other'.
   */
  getContentType: mimeType =>
    MIME_TYPE_MATCHERS.find(matcher => matcher[0].test(mimeType))[1],

  getHTTPVersion: version => {
    if (version === 'h2' || version === 'HTTP/2.0') {
      return 'HTTP/2.0';
    } else if (version.indexOf('spdy') > -1) {
      return version.toUpperCase();
    } else if (version === '') {
      return 'Unknown';
    }
    return version.toUpperCase();
  },
  getConnectionType: version => {
    if (version === 'h2' || version === 'HTTP/2.0') {
      return 'h2';
    } else if (version.indexOf('spdy') > -1) {
      return 'spdy';
    } else if (version === '') {
      return 'Unknown';
    }
    return 'h1';
  },
  /**
   * Get the hostname from a URL string.
   * @param {string} url The URL like https://www.example.com/hepp
   * @returns {string} the hostname
   */
  getHostname: url => {
    if (!url) {
      return '';
    }

    return urlParser.parse(url).hostname || '';
  },
  /**
   * Get the main domain from a hostname
   * www.sitespeed.io -> sitespeed
   * www.sitespeed.co.uk ->  sitespeed
   */
  getMainDomain: hostname => {
    let domain = hostname;

    if (hostname != null) {
      const parts = hostname.split('.').reverse();
      if (parts != null && parts.length > 1) {
        domain = parts[1] + '.' + parts[0];
        if (
          hostname.toLowerCase().indexOf('.co.uk') != -1 &&
          parts.length > 2
        ) {
          domain = parts[2] + '.' + domain;
        }
      }
    }
    return domain.split('.')[0];
  },
  /**
   * Get when the page is fully loaded
   * @param {Object} pageId
   * @param entries
   * @param {Object} pageStartDateTime
   */
  getFullyLoaded: (pageId, entries, pageStartDateTime) => {
    let pageEntries = Array.from(entries);
    pageEntries = Array.from(
      pageEntries.filter(entry => entry.pageref === pageId)
    );

    let pageEnd = 0;
    for (let entry of pageEntries) {
      let entryEnd =
        new Date(entry.startedDateTime).getTime() +
        entry.time -
        new Date(pageStartDateTime).getTime();
      if (entryEnd > pageEnd) {
        pageEnd = entryEnd;
      }
    }
    return pageEnd;
  },
  /**
   * Get main document requests (including redirects) for a HAR file.
   * @param entries
   * @param {Object} pageId
   * @returns {Object} redirect chain.
   */
  getDocumentRequests: (entries, pageId) => {
    let pageEntries = Array.from(entries);
    if (pageId) {
      pageEntries = Array.from(
        entries.filter(entry => entry.pageref === pageId)
      );
    }

    const requests = [];
    let entry;

    do {
      entry = pageEntries.shift();
      requests.push(entry);
    } while (entry.response.redirectURL);

    return requests;
  }
};
<commit_msg>Pickup h3 (#95)<commit_after>'use strict';

const urlParser = require('url');

// Priorities list of matchers
const MIME_TYPE_MATCHERS = [
  [/^text\/html/, 'html'],
  [/^text\/plain/, 'plain'],
  [/^text\/css/, 'css'],
  [/^text\/xml/, 'xml'],
  [/javascript/, 'javascript'],
  [/flash/, 'flash'],
  [/^image\/x-icon/, 'favicon'],
  [/^image\/vnd.microsoft.icon/, 'favicon'],
  [/svg/, 'svg'],
  [/^image/, 'image'],
  [/^application\/.*font/, 'font'],
  [/^font\/.*/, 'font'],
  [/^application\/json/, 'json'],
  [/^application\/xml/, 'xml'],
  [/^application\/pdf/, 'pdf'],
  [/^audio\/.*/, 'audio'],
  [/^video\/.*/, 'video'],
  [/^application\/ocsp-response/, 'oscp'],
  [/.*/, 'other'] // Always match 'other' if all else fails
];

/**
 * Utilities for getting content from HAR:s.
 * @module util
 */
module.exports = {
  /**
   * Get the content type from mime type.
   * @param {string} mimeType The mimeType
   * @returns {string} the content type or 'other'.
   */
  getContentType: mimeType =>
    MIME_TYPE_MATCHERS.find(matcher => matcher[0].test(mimeType))[1],

  getHTTPVersion: version => {
    if (version === 'h2' || version === 'HTTP/2.0') {
      return 'HTTP/2.0';
    } else if (version.indexOf('spdy') > -1) {
      return version.toUpperCase();
    } else if (version === '') {
      return 'Unknown';
    }
    return version.toUpperCase();
  },

  getConnectionType: version => {
    if (version === 'h2' || version === 'HTTP/2.0') {
      return 'h2';
    } else if (version.indexOf('spdy') > -1) {
      return 'spdy';
    } else if (version === '') {
      return 'Unknown';
    } else if (version.startsWith('h3')) {
      return 'h3';
    }
    return 'h1';
  },
  /**
   * Get the hostname from a URL string.
   * @param {string} url The URL like https://www.example.com/hepp
   * @returns {string} the hostname
   */
  getHostname: url => {
    if (!url) {
      return '';
    }

    return urlParser.parse(url).hostname || '';
  },
  /**
   * Get the main domain from a hostname
   * www.sitespeed.io -> sitespeed
   * www.sitespeed.co.uk ->  sitespeed
   */
  getMainDomain: hostname => {
    let domain = hostname;

    if (hostname != null) {
      const parts = hostname.split('.').reverse();
      if (parts != null && parts.length > 1) {
        domain = parts[1] + '.' + parts[0];
        if (
          hostname.toLowerCase().indexOf('.co.uk') != -1 &&
          parts.length > 2
        ) {
          domain = parts[2] + '.' + domain;
        }
      }
    }
    return domain.split('.')[0];
  },
  /**
   * Get when the page is fully loaded
   * @param {Object} pageId
   * @param entries
   * @param {Object} pageStartDateTime
   */
  getFullyLoaded: (pageId, entries, pageStartDateTime) => {
    let pageEntries = Array.from(entries);
    pageEntries = Array.from(
      pageEntries.filter(entry => entry.pageref === pageId)
    );

    let pageEnd = 0;
    for (let entry of pageEntries) {
      let entryEnd =
        new Date(entry.startedDateTime).getTime() +
        entry.time -
        new Date(pageStartDateTime).getTime();
      if (entryEnd > pageEnd) {
        pageEnd = entryEnd;
      }
    }
    return pageEnd;
  },
  /**
   * Get main document requests (including redirects) for a HAR file.
   * @param entries
   * @param {Object} pageId
   * @returns {Object} redirect chain.
   */
  getDocumentRequests: (entries, pageId) => {
    let pageEntries = Array.from(entries);
    if (pageId) {
      pageEntries = Array.from(
        entries.filter(entry => entry.pageref === pageId)
      );
    }

    const requests = [];
    let entry;

    do {
      entry = pageEntries.shift();
      requests.push(entry);
    } while (entry.response.redirectURL);

    return requests;
  }
};
<|endoftext|>


<commit_before>//604800000 is the magic number for a week in milliseconds
timify = function(date) {
	d = moment(date);
	c = moment();
	if(c.diff(d, 'hours') <= 12)
		return d.fromNow();
	else if(c.diff(d,'days') <= 7)
		return d.calendar();
	else return d.format('LL');
}

forEach = function(array, action) {
    for(var i=0; i <array.length; i++)
        action(array[i]);
}

getItemIdArray = function(c) {
    var ret = [];
    forEach(c, function(o) {
        ret.push(o.itemId);
    });
    return ret;
}
<commit_msg>timify modification<commit_after>//604800000 is the magic number for a week in milliseconds
timify = function(date) {
	d = moment(date);
	c = moment();
	var d_diff = c.diff(d, 'days');
	if(c.diff(d, 'hours') <= 12)
		return d.fromNow();
	else if(d_diff <= 1)
		return d.calendar();
	else if(d_diff < 4)
		return d.fromNow();
	else if(d_diff <= 7)
		return d.calendar();
	else return d.format('LL');
}

forEach = function(array, action) {
    for(var i=0; i <array.length; i++)
        action(array[i]);
}

getItemIdArray = function(c) {
    var ret = [];
    forEach(c, function(o) {
        ret.push(o.itemId);
    });
    return ret;
}
<|endoftext|>


<commit_before>/* jshint -W069 */
/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict'

var fs = require('fs')
var split = require('split2')
var pump = require('pump')
var async = require('async')
var _ = require('lodash')
var chalk = require('chalk')
var sgrep = require('simple-grep')
var readline = require('readline')

module.exports = function () {
  var colourSelector = 0

  var isExecutableContainer = function (container) {
    return (['docker', 'node', 'process'].indexOf(container.type) !== -1) && container.specific.execute
  }

  var isNodeProcess = function (container) {
    return (['node', 'process'].indexOf(container.type) !== -1) && container.specific.execute && /node|iojs/.test(container.specific.execute.exec)
  }

  var findProcess = function (processes, name) {
    var pid = _.find(_.keys(processes), function (key) { return processes[key].identifier === name })
    return processes[pid]
  }

  var findContainer = function (system, name) {
    return _.find(system.topology.containers, function (c) { return c.name === name })
  }

  var selectColour = function (processes, name) {
    var colour
    var process

    if (processes) {
      process = findProcess(processes, name)
    }

    if (process) {
      colour = process.colour
    } else {
      var colours = [chalk.white,
                     chalk.green,
                     chalk.yellow,
                     chalk.blue,
                     chalk.magenta,
                     chalk.cyan,
                     chalk.black,
                     chalk.gray]
      colour = colours[colourSelector]
      colourSelector++
      if (colourSelector > 7) {
        colourSelector = 0
      }
    }
    return colour
  }

  var streamOutput = function (proc, config) {
    var colorizer = split(function (line) {
      return proc.colour('[' + proc.identifier + ' - ' + proc.child.pid + ']: ' + line) + '\n'
    })
    var errorColorizer = split(function (line) {
      return chalk.red('[' + proc.identifier + ' - ' + proc.child.pid + ']: ' + line) + '\n'
    })
    var logStream = fs.createWriteStream(config.logPath + '/' + proc.identifier + '.log')

    if (proc.tail) {
      pump(proc.child.stdout, colorizer)
      colorizer.pipe(process.stdout, { end: false })
      pump(proc.child.stderr, errorColorizer)
      errorColorizer.pipe(process.stdout, { end: false })
    }

    pump(proc.child.stdout, logStream)
    pump(proc.child.stderr, logStream)
  }

  var grep = function (name, config, search, cb) {
    var path = config.logPath + '/' + name + '.log'

    if (fs.existsSync(path)) {
      sgrep(search, path, function (list) {
        _.each(list, function (item) {
          _.each(item.results, function (loc) {
            var output = item.file + ' ' + loc['line_number'] + ': ' + loc.line
            console.log(output)
          })
        })
        cb()
      })
    } else {
      cb()
    }
  }

  var grepAll = function (system, config, search, cb) {
    async.eachSeries(_.keys(system.topology.containers), function (key, next) {
      var c = system.topology.containers[key]
      grep(c.name, config, search, next)
    }, function (err) { cb(err) })
  }

  var showLogTail = function (name, proc, config, count, cb) {
    var path = config.logPath + '/' + name + '.log'
    var lines = []

    if (fs.existsSync(path)) {
      var instream = fs.createReadStream(path)
      var rl = readline.createInterface({
        input: instream
      })

      rl.on('line', function (line) {
        lines.push(line)
        if (lines.length > count) {
          lines.shift()
        }
      })

      rl.on('close', function () {
        _.each(lines, function (line) {
          if (proc) {
            console.log(proc.colour(line))
          } else {
            console.log(line)
          }
        })
        cb()
      })
    } else {
      cb()
    }
  }

  return {
    isExecutableContainer: isExecutableContainer,
    isNodeProcess: isNodeProcess,
    selectColour: selectColour,
    streamOutput: streamOutput,
    findContainer: findContainer,
    findProcess: findProcess,
    grep: grep,
    grepAll: grepAll,
    showLogTail: showLogTail
  }
}
<commit_msg>Remove black from colour listing<commit_after>/* jshint -W069 */
/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict'

var fs = require('fs')
var split = require('split2')
var pump = require('pump')
var async = require('async')
var _ = require('lodash')
var chalk = require('chalk')
var sgrep = require('simple-grep')
var readline = require('readline')

module.exports = function () {
  var colourSelector = 0

  var isExecutableContainer = function (container) {
    return (['docker', 'node', 'process'].indexOf(container.type) !== -1) && container.specific.execute
  }

  var isNodeProcess = function (container) {
    return (['node', 'process'].indexOf(container.type) !== -1) && container.specific.execute && /node|iojs/.test(container.specific.execute.exec)
  }

  var findProcess = function (processes, name) {
    var pid = _.find(_.keys(processes), function (key) { return processes[key].identifier === name })
    return processes[pid]
  }

  var findContainer = function (system, name) {
    return _.find(system.topology.containers, function (c) { return c.name === name })
  }

  var selectColour = function (processes, name) {
    var colour
    var process

    if (processes) {
      process = findProcess(processes, name)
    }

    if (process) {
      colour = process.colour
    } else {
      var colours = [chalk.white,
                     chalk.green,
                     chalk.yellow,
                     chalk.blue,
                     chalk.magenta,
                     chalk.cyan,
                     chalk.gray]
      colour = colours[colourSelector]
      colourSelector++
      if (colourSelector === colours.length) {
        colourSelector = 0
      }
    }
    return colour
  }

  var streamOutput = function (proc, config) {
    var colorizer = split(function (line) {
      return proc.colour('[' + proc.identifier + ' - ' + proc.child.pid + ']: ' + line) + '\n'
    })
    var errorColorizer = split(function (line) {
      return chalk.red('[' + proc.identifier + ' - ' + proc.child.pid + ']: ' + line) + '\n'
    })
    var logStream = fs.createWriteStream(config.logPath + '/' + proc.identifier + '.log')

    if (proc.tail) {
      pump(proc.child.stdout, colorizer)
      colorizer.pipe(process.stdout, { end: false })
      pump(proc.child.stderr, errorColorizer)
      errorColorizer.pipe(process.stdout, { end: false })
    }

    pump(proc.child.stdout, logStream)
    pump(proc.child.stderr, logStream)
  }

  var grep = function (name, config, search, cb) {
    var path = config.logPath + '/' + name + '.log'

    if (fs.existsSync(path)) {
      sgrep(search, path, function (list) {
        _.each(list, function (item) {
          _.each(item.results, function (loc) {
            var output = item.file + ' ' + loc['line_number'] + ': ' + loc.line
            console.log(output)
          })
        })
        cb()
      })
    } else {
      cb()
    }
  }

  var grepAll = function (system, config, search, cb) {
    async.eachSeries(_.keys(system.topology.containers), function (key, next) {
      var c = system.topology.containers[key]
      grep(c.name, config, search, next)
    }, function (err) { cb(err) })
  }

  var showLogTail = function (name, proc, config, count, cb) {
    var path = config.logPath + '/' + name + '.log'
    var lines = []

    if (fs.existsSync(path)) {
      var instream = fs.createReadStream(path)
      var rl = readline.createInterface({
        input: instream
      })

      rl.on('line', function (line) {
        lines.push(line)
        if (lines.length > count) {
          lines.shift()
        }
      })

      rl.on('close', function () {
        _.each(lines, function (line) {
          if (proc) {
            console.log(proc.colour(line))
          } else {
            console.log(line)
          }
        })
        cb()
      })
    } else {
      cb()
    }
  }

  return {
    isExecutableContainer: isExecutableContainer,
    isNodeProcess: isNodeProcess,
    selectColour: selectColour,
    streamOutput: streamOutput,
    findContainer: findContainer,
    findProcess: findProcess,
    grep: grep,
    grepAll: grepAll,
    showLogTail: showLogTail
  }
}
<|endoftext|>


<commit_before>// Start enchant.js
enchant();

var browserWidth = window.innerWidth || document.body.clientWidth;
var browserHeight = window.innerHeight || document.body.clientHeight;
window.onload = function() {

    // Starting point
    //var game = new Game(320, 440);
	//var game = new Game(440, 320);
	var game = new Game(browserWidth, browserHeight);
    game.preload(//'res/BG.png',
				 'res/newBGV001.jpg',
                 'res/unicornSheetV1.png',
                 'res/drive.png',
				 'res/unicornGameOver.png',
                 'res/Hit.mp3',
                 'res/bgm.mp3',
				 'res/deadUnicornV001.jpg');
    game.fps = 30;
    game.scale = 1;
    game.onload = function() {
        // Once Game finish loading
        console.log("Hi, Boxer!");
        var scene = new SceneGame();
        game.pushScene(scene);
    }
    window.scrollTo(0,0);
    game.start();
};

/**
 * SceneGame
 */
var SceneGame = Class.create(Scene, {
    /**
     * The main gameplay scene.
     */
    initialize: function() {
        var game, label, bg, unicorn, driveGroup;

        // Call superclass constructor
        Scene.apply(this);

        // Access to the game singleton instance
        game = Game.instance;

        label = new Label('SCORE:
0');
        label.x = game.width/2-130;
        label.y = 32;
        label.color = 'white';
        label.font = '16px strong';
        label.textAlign = 'center';
        label._style.textShadow ="-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black";
        this.scoreLabel = label;

        bg = new Sprite(browserWidth, browserHeight);
        bg.image = game.assets['res/newBGV001.jpg'];

        unicorn = new Unicorn();
        unicorn.y = game.height/2 - unicorn.height/2;
        unicorn.x = 10;
        this.unicorn = unicorn;

        driveGroup = new Group();
        this.driveGroup = driveGroup;

        this.addChild(bg);
        this.addChild(driveGroup);
        this.addChild(unicorn);
        this.addChild(label);

        this.addEventListener(Event.TOUCH_START,this.handleTouchControl);
        this.addEventListener(Event.ENTER_FRAME,this.update);

        // Instance variables
        this.generatedriveTimer = 0;
        this.scoreTimer = 0;
        this.score = 0;

        this.bgm = game.assets['res/bgm.mp3']; // Add this line

        // Start BGM
        this.bgm.play();
    },

    handleTouchControl: function (evt) {
        var laneHeight, lane;
        laneHeight = 600/3;
        lane = Math.floor(evt.y/laneHeight);
        lane = Math.max(Math.min(2,lane),0);
        this.unicorn.switchToLaneNumber(lane);
    },

    update: function(evt) {
        // Score increase as time pass
        this.scoreTimer += evt.elapsed * 0.001;
        if(this.scoreTimer >= 0.5)
        {
            this.setScore(this.score + 1);
            this.scoreTimer -= 0.5;
        }

        // Check if it's time to create a new set of obstacles
        this.generatedriveTimer += evt.elapsed * 0.001;
        if(this.generatedriveTimer >= 0.5)
        {
            var drive;
            this.generatedriveTimer -= 0.5;
            drive = new Drive(Math.floor(Math.random()*3));
            this.driveGroup.addChild(drive);
        }

        // Check collision
        for (var i = this.driveGroup.childNodes.length - 1; i >= 0; i--) {
            var drive;
            drive = this.driveGroup.childNodes[i];
            if(drive.intersect(this.unicorn)){
                var game;
                game = Game.instance;
                game.assets['res/Hit.mp3'].play();
                this.driveGroup.removeChild(drive);
                this.bgm.stop();
                game.replaceScene(new SceneGameOver(this.score));
                break;
            }
        }

        // Loop BGM
        if( this.bgm.currentTime >= this.bgm.duration ){
            this.bgm.play();
        }
    },

    setScore: function (value) {
        this.score = value;
        this.scoreLabel.text = 'SCORE
' + this.score;
    }
});

/**
 * unicorn
 */
 var Unicorn = Class.create(Sprite, {
    /**
     * The player character.
     */
    initialize: function() {
        // Call superclass constructor
        Sprite.apply(this,[100, 60]);
        this.image = Game.instance.assets['res/unicornSheetV1.png'];
        this.animationDuration = 0;
        this.addEventListener(Event.ENTER_FRAME, this.updateAnimation);
    },

    updateAnimation: function (evt) {
        this.animationDuration += evt.elapsed * 0.001;
        if(this.animationDuration >= 0.25)
        {
            this.frame = (this.frame + 1) % 2;
            this.animationDuration -= 0.25;
        }
    },

    switchToLaneNumber: function(lane){
        var targetY = 300 - this.height/2 + (lane-1)*170;
        this.y = targetY;
    }
});

var UnicornGameOver = Class.create (Sprite, {
	initialize: function() {
		Sprite.apply(this,[browserWidth,browserHeight]);
		this.image = Game.instance.assets['res/deadUnicornV001.jpg'];
	}
});

var Drive = Class.create(Sprite, {
    /**
     * The obstacle that the unicorn must avoid
     */
    initialize: function(lane) {
        // Call superclass constructor
        Sprite.apply(this,[48, 49]);
        this.image  = Game.instance.assets['res/drive.png'];
        this.rotationSpeed = 0;
        this.setLane(lane);
        this.addEventListener(Event.ENTER_FRAME, this.update);
    },

    setLane: function(lane) {
        var game, distance;
        game = Game.instance;
        distance = 170;

        this.rotationSpeed = Math.random() * 100 - 50;

        this.y = game.height/2 - this.height/2 + (lane - 1) * distance;
        this.x = game.width;
        this.rotation = Math.floor( Math.random() * 360 );
    },

    update: function(evt) {
        var ySpeed, game;

        game = Game.instance;
        ySpeed = 300;

        this.x -= ySpeed * evt.elapsed * 0.001;
        this.rotation += this.rotationSpeed * evt.elapsed * 0.001;
        if(this.x < 0)
        {
            this.parentNode.removeChild(this);
        }
    }
});

/**
 * SceneGameOver
 */
var SceneGameOver = Class.create(Scene, {
    initialize: function(score) {
        var gameOverLabel, scoreLabel, unicornGameOver, game;
		game = Game.instance;
        Scene.apply(this);
        this.backgroundColor = 'black';
		this.image = Game.instance.assets['res/deadUnicornV001.jpg'];

        gameOverLabel = new Label("GAME OVER

Tap to Restart");
        gameOverLabel.x = (game.width/2)-150;
        gameOverLabel.y = (game.height/2)-100;
        gameOverLabel.color = 'white';
        gameOverLabel.font = '32px strong';
        gameOverLabel.textAlign = 'center';

        scoreLabel = new Label('SCORE
' + score);
        scoreLabel.x = (game.width/2)-150;
        scoreLabel.y = 50;
        scoreLabel.color = 'white';
        scoreLabel.font = '16px strong';
        scoreLabel.textAlign = 'center';

		unicornGameOver = new UnicornGameOver();

		this.addChild(unicornGameOver);
        this.addChild(gameOverLabel);
        this.addChild(scoreLabel);

        this.addEventListener(Event.TOUCH_START, this.touchToRestart);

    },

    touchToRestart: function(evt) {
        var game = Game.instance;
        game.replaceScene(new SceneGame());
    }
});<commit_msg>qwerfgdnfdsads<commit_after>// Start enchant.js
enchant();

var browserWidth = window.innerWidth || document.body.clientWidth;
var browserHeight = window.innerHeight || document.body.clientHeight;
window.onload = function() {

    // Starting point
    //var game = new Game(320, 440);
	//var game = new Game(440, 320);
	var game = new Game(browserWidth, browserHeight);
    game.preload(//'res/BG.png',
				 'res/newBGV001.png',
                 'res/unicornSheetV1.png',
                 'res/drive.png',
				 'res/unicornGameOver.png',
                 'res/Hit.mp3',
                 'res/bgm.mp3',
				 'res/deadUnicornV001.jpg');
    game.fps = 30;
    game.scale = 1;
    game.onload = function() {
        // Once Game finish loading
        console.log("Hi, Boxer!");
        var scene = new SceneGame();
        game.pushScene(scene);
    }
    window.scrollTo(0,0);
    game.start();
};

/**
 * SceneGame
 */
var SceneGame = Class.create(Scene, {
    /**
     * The main gameplay scene.
     */
    initialize: function() {
        var game, label, bg, unicorn, driveGroup;

        // Call superclass constructor
        Scene.apply(this);

        // Access to the game singleton instance
        game = Game.instance;

        label = new Label('SCORE:
0');
        label.x = game.width/2-130;
        label.y = 32;
        label.color = 'white';
        label.font = '16px strong';
        label.textAlign = 'center';
        label._style.textShadow ="-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black";
        this.scoreLabel = label;

        bg = new Sprite(browserWidth, browserHeight);
        bg.image = game.assets['res/newBGV001.jpg'];

        unicorn = new Unicorn();
        unicorn.y = game.height/2 - unicorn.height/2;
        unicorn.x = 10;
        this.unicorn = unicorn;

        driveGroup = new Group();
        this.driveGroup = driveGroup;

        this.addChild(bg);
        this.addChild(driveGroup);
        this.addChild(unicorn);
        this.addChild(label);

        this.addEventListener(Event.TOUCH_START,this.handleTouchControl);
        this.addEventListener(Event.ENTER_FRAME,this.update);

        // Instance variables
        this.generatedriveTimer = 0;
        this.scoreTimer = 0;
        this.score = 0;

        this.bgm = game.assets['res/bgm.mp3']; // Add this line

        // Start BGM
        this.bgm.play();
    },

    handleTouchControl: function (evt) {
        var laneHeight, lane;
        laneHeight = 600/3;
        lane = Math.floor(evt.y/laneHeight);
        lane = Math.max(Math.min(2,lane),0);
        this.unicorn.switchToLaneNumber(lane);
    },

    update: function(evt) {
        // Score increase as time pass
        this.scoreTimer += evt.elapsed * 0.001;
        if(this.scoreTimer >= 0.5)
        {
            this.setScore(this.score + 1);
            this.scoreTimer -= 0.5;
        }

        // Check if it's time to create a new set of obstacles
        this.generatedriveTimer += evt.elapsed * 0.001;
        if(this.generatedriveTimer >= 0.5)
        {
            var drive;
            this.generatedriveTimer -= 0.5;
            drive = new Drive(Math.floor(Math.random()*3));
            this.driveGroup.addChild(drive);
        }

        // Check collision
        for (var i = this.driveGroup.childNodes.length - 1; i >= 0; i--) {
            var drive;
            drive = this.driveGroup.childNodes[i];
            if(drive.intersect(this.unicorn)){
                var game;
                game = Game.instance;
                game.assets['res/Hit.mp3'].play();
                this.driveGroup.removeChild(drive);
                this.bgm.stop();
                game.replaceScene(new SceneGameOver(this.score));
                break;
            }
        }

        // Loop BGM
        if( this.bgm.currentTime >= this.bgm.duration ){
            this.bgm.play();
        }
    },

    setScore: function (value) {
        this.score = value;
        this.scoreLabel.text = 'SCORE
' + this.score;
    }
});

/**
 * unicorn
 */
 var Unicorn = Class.create(Sprite, {
    /**
     * The player character.
     */
    initialize: function() {
        // Call superclass constructor
        Sprite.apply(this,[100, 60]);
        this.image = Game.instance.assets['res/unicornSheetV1.png'];
        this.animationDuration = 0;
        this.addEventListener(Event.ENTER_FRAME, this.updateAnimation);
    },

    updateAnimation: function (evt) {
        this.animationDuration += evt.elapsed * 0.001;
        if(this.animationDuration >= 0.25)
        {
            this.frame = (this.frame + 1) % 2;
            this.animationDuration -= 0.25;
        }
    },

    switchToLaneNumber: function(lane){
        var targetY = 300 - this.height/2 + (lane-1)*170;
        this.y = targetY;
    }
});

var UnicornGameOver = Class.create (Sprite, {
	initialize: function() {
		Sprite.apply(this,[browserWidth,browserHeight]);
		this.image = Game.instance.assets['res/deadUnicornV001.jpg'];
	}
});

var Drive = Class.create(Sprite, {
    /**
     * The obstacle that the unicorn must avoid
     */
    initialize: function(lane) {
        // Call superclass constructor
        Sprite.apply(this,[48, 49]);
        this.image  = Game.instance.assets['res/drive.png'];
        this.rotationSpeed = 0;
        this.setLane(lane);
        this.addEventListener(Event.ENTER_FRAME, this.update);
    },

    setLane: function(lane) {
        var game, distance;
        game = Game.instance;
        distance = 170;

        this.rotationSpeed = Math.random() * 100 - 50;

        this.y = game.height/2 - this.height/2 + (lane - 1) * distance;
        this.x = game.width;
        this.rotation = Math.floor( Math.random() * 360 );
    },

    update: function(evt) {
        var ySpeed, game;

        game = Game.instance;
        ySpeed = 300;

        this.x -= ySpeed * evt.elapsed * 0.001;
        this.rotation += this.rotationSpeed * evt.elapsed * 0.001;
        if(this.x < 0)
        {
            this.parentNode.removeChild(this);
        }
    }
});

/**
 * SceneGameOver
 */
var SceneGameOver = Class.create(Scene, {
    initialize: function(score) {
        var gameOverLabel, scoreLabel, unicornGameOver, game;
		game = Game.instance;
        Scene.apply(this);
        this.backgroundColor = 'black';
		this.image = Game.instance.assets['res/deadUnicornV001.jpg'];

        gameOverLabel = new Label("GAME OVER

Tap to Restart");
        gameOverLabel.x = (game.width/2)-150;
        gameOverLabel.y = (game.height/2)-100;
        gameOverLabel.color = 'white';
        gameOverLabel.font = '32px strong';
        gameOverLabel.textAlign = 'center';

        scoreLabel = new Label('SCORE
' + score);
        scoreLabel.x = (game.width/2)-150;
        scoreLabel.y = 50;
        scoreLabel.color = 'white';
        scoreLabel.font = '16px strong';
        scoreLabel.textAlign = 'center';

		unicornGameOver = new UnicornGameOver();

		this.addChild(unicornGameOver);
        this.addChild(gameOverLabel);
        this.addChild(scoreLabel);

        this.addEventListener(Event.TOUCH_START, this.touchToRestart);

    },

    touchToRestart: function(evt) {
        var game = Game.instance;
        game.replaceScene(new SceneGame());
    }
});<|endoftext|>