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

    var gulp, minifyHTML, concat, stripDebug, uglify, jshint, changed, imagemin, autoprefix, sass, rjs, minifyCSS,
        browserSync, pngquant, del, paths, host, themes, FOUNDATION_URI;

    gulp = require('gulp');
    minifyHTML = require('gulp-minify-html');
    concat = require('gulp-concat');
    stripDebug = require('gulp-strip-debug');
    uglify = require('gulp-uglify');
    jshint = require('gulp-jshint');
    changed = require('gulp-changed');
    imagemin = require('gulp-imagemin');
    autoprefix = require('gulp-autoprefixer');
    sass = require('gulp-sass');
    rjs = require('gulp-requirejs');
    minifyCSS = require('gulp-minify-css');
    browserSync = require('browser-sync');
    pngquant = require('imagemin-pngquant');
    del = require('del');
    paths = {
        "app": require('./bower.json').appPath || 'app',
        "dist": 'dist',
        "themes": 'themes',
        "js": ['app/scripts/*.js', 'app/scripts/**/*.js'],
        "vendor": 'app/lib/**/*.js',
        "vendorTheme": 'app/themes/**/lib/*',
        "sass": 'app/styles/sass/**/*.scss',
        "css": 'app/themes/**/styles/**/*.css',
        "images": 'app/themes/**/images/**/*',
        "fonts": 'app/themes/**/styles/fonts/**/*',
        "html": 'app/**/*.html',
        "misc": 'app/*.{txt,htaccess,ico}',
        "themeDest": "dist/themes"

    };
    host = {
        port: '8080',
        lrPort: '35729'
    };
    themes = [];
    FOUNDATION_URI = 'http://ottemo.local:3000';

    // Empties folders to start fresh
    gulp.task('clean', function (cb) {
        del(['dist'], cb);
    });

    // Actions with js-files from theme
    gulp.task('vendorTheme', ['clean'], function () {
        /**
         * Minify and uglify the custom scripts in folder 'scripts' in each theme
         */
        gulp.src('app/themes/**/scripts/**/*.js')
            .pipe(stripDebug())
            .pipe(uglify({mangle: false}))
            .pipe(gulp.dest(paths.themeDest));

        /**
         * copy vendor js from theme folder
         */
        return gulp.src(paths.vendorTheme)
            .pipe(gulp.dest(paths.themeDest));
    });

    // copy vendor js
    gulp.task('vendor', ['clean', 'vendorTheme'], function () {
        return gulp.src(paths.vendor)
            .pipe(gulp.dest(paths.dist + '/lib'));
    });

    // copy misc assets
    gulp.task('misc', ['clean'], function () {
        return gulp.src(paths.misc)
            .pipe(gulp.dest(paths.dist));
    });

    // Run JSHint
    gulp.task('jshint', function () {
        gulp.src(paths.js)
            .pipe(jshint())
            .pipe(jshint.reporter(require('jshint-stylish')));
    });

    gulp.task('requirejs', ['clean', 'jshint'], function () {
        rjs({
            out: 'main.js',
            name: 'main',
            preserveLicenseComments: false, // remove all comments
            removeCombined: true,
            baseUrl: paths.app + '/scripts',
            mainConfigFile: 'app/scripts/main.js'
        })
            .pipe(stripDebug())
            .pipe(uglify({mangle: false}))
            .pipe(gulp.dest(paths.dist + '/scripts/'));
    });

    // Sass task, will run when any SCSS files change & BrowserSync
    // will auto-update browsers
    gulp.task('sass', function () {
        return gulp.src(paths.sass)
            .pipe(sass({imagePath: '../../images'}))
            .pipe(autoprefix('last 1 version'))
            .pipe(gulp.dest(paths.dist + '/styles'))
            .pipe(gulp.dest(paths.app + '/styles'));
    });

    // minify new images
    gulp.task('imagemin', ['clean'], function () {
        return gulp.src(paths.images)
            .pipe(changed(paths.themeDest))
            .pipe(imagemin())
            .pipe(gulp.dest(paths.themeDest));
    });

    // minify new or changed HTML pages
    gulp.task('html', ['clean'], function () {
        return gulp.src(paths.html)
            .pipe(changed(paths.dist))
            .pipe(minifyHTML({
                collapseWhitespace: true,
                collapseBooleanAttributes: true,
                removeCommentsFromCDATA: true,
                removeOptionalTags: true,
                conditionals: true,
                quotes: true,
                empty: true
            }))
            .pipe(gulp.dest(paths.dist));
    });

    // CSS auto-prefix and minify
    gulp.task('autoprefixer', ['clean', 'sass'], function () {
        gulp.src(paths.css)
            .pipe(autoprefix('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
            .pipe(minifyCSS())
            .pipe(gulp.dest(paths.themeDest));
        gulp.src(paths.fonts)
            .pipe(gulp.dest(paths.themeDest));
    });

    // Protractor tests
    // gulp.task('protractorUpdate', protractor.webdriverUpdate);
    // gulp.task('protractor', ['protractorUpdate'], function (cb) {
    //     gulp.src(['tests/e2e/**/*.js']).pipe(protractor.protractor({
    //         configFile: 'protractor.conf.js'
    //     })).on('error', function (e) {
    //         console.log(e);
    //     }).on('end', cb);
    // });
    //
    // // Jasmine test
    // gulp.task('jasmine', function() {
    //     gulp.src('spec/**/*.js')
    //         .pipe(jasmine({verbose:true, includeStackTrace: true}));
    // });
    //
    // gulp.task('test', ['protractor', 'jasmine'], function () {});

    // browser-sync task for starting server
    gulp.task('browser-sync', function () {
        browserSync({
            server: {
                baseDir: './app'
            },
            port: host.port
        });
    });

    gulp.task('bs-reload', function () {
        browserSync.reload();
    });

    // run in development mode with easy browser reloading
    gulp.task('dev', ['browser-sync'], function () {

        gulp.watch('app/views/**/*.html', [browserSync.reload]);
        gulp.watch('app/styles/**/*.css', [browserSync.reload]);
        gulp.watch('app/styles/**/*.scss', ['sass', browserSync.reload]);
        gulp.watch('app/scripts/**/*.js', ['jshint', browserSync.reload]);
    });

    gulp.task('serve', ['dev', 'retrieve-files']);

    gulp.task('build', function(){
        var themesDir, jsCode, fs, recursive, themesData, request;

        themesData = '';
        fs = require('fs');
        request = require('request');
        recursive = require('recursive-readdir');

        themesDir = './app/themes';

        recursive(themesDir, function (err, files) {
            var i, theme, filePath, parts, regExp;
            theme = null;
            regExp = new RegExp('app[/\\\\]themes[/\\\\](\\w+)[/\\\\](.+)', 'i');

            jsCode = '/* jshint ignore:start */\n' +
                '(function (define) {\n' +
                '"use strict";\n' +
                'define(function () {\n' +
                'return {\n';

            for (i = 0; i < files.length; i += 1) {
                filePath = files[i];
                parts = filePath.match(regExp);
                if (parts instanceof Array) {
                    if (theme !== parts[1] && theme === null) {
                        themes.push(parts[1]);
                        jsCode += '\'' + parts[1] + '\' : [\n';
                    }
                    if (theme !== parts[1] && theme !== null) {
                        themes.push(parts[1]);
                        jsCode += '],\n\'' + parts[1] + '\' : [\n';
                    }
                    jsCode += '\'/' + parts[2] + '\',\n';
                    theme = parts[1];
                }
            }

            jsCode += ']\n};\n' +
                '});\n' +
                '})(window.define);\n' +
                '/* jshint ignore:end */';

            fs.writeFile('./app/scripts/design/themeFiles.js', jsCode, function (err) {
                if (err) {
                    return console.log(err);
                }
            });

            themesData = '{';
            for (i = 0; i < themes.length; i += 1) {
                themesData += '"' + themes[i] + '":"' + themes[i] + '"';
                if (i < themes.length - 1) {
                    themesData += ',';
                }
            }
            themesData += '}';

            request({
                uri: FOUNDATION_URI + '/config/unregister/themes',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', '');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            // Create group
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', 'themes_manager');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list.active',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list.active');
                form.append('value', 'default');
                form.append('type', '');
                form.append('editor', 'themes_manager');
                form.append('options', themesData);
                form.append('label', 'Active theme');
                form.append('description', 'Active theme on storefront');
            });

            gulp.start('requirejs');
            gulp.start('vendor');
            gulp.start('misc');
            gulp.start('html');
            gulp.start('autoprefixer');
            gulp.start('imagemin');
        });
    });

    gulp.task('default', ['build']);

    gulp.task('retrieve-files', function () {
        var themesDir, jsCode, fs, request, themesData, recursive;

        themesData = '';
        fs = require('fs');
        request = require('request');
        recursive = require('recursive-readdir');

        themesDir = './app/themes';

        recursive(themesDir, function (err, files) {
            var i, theme, filePath, parts, regExp;
            theme = null;
            regExp = new RegExp('app[/\\\\]themes[/\\\\](\\w+)[/\\\\](.+)', 'i');

            jsCode = '/* jshint ignore:start */\n' +
                '(function (define) {\n' +
                '"use strict";\n' +
                'define(function () {\n' +
                'return {\n';

            for (i = 0; i < files.length; i += 1) {
                filePath = files[i];
                parts = filePath.match(regExp);
                if (parts instanceof Array) {
                    if (theme !== parts[1] && theme === null) {
                        themes.push(parts[1]);
                        jsCode += '\'' + parts[1] + '\' : [\n';
                    }
                    if (theme !== parts[1] && theme !== null) {
                        themes.push(parts[1]);
                        jsCode += '],\n\'' + parts[1] + '\' : [\n';
                    }
                    jsCode += '\'/' + parts[2] + '\',\n';
                    theme = parts[1];
                }
            }

            jsCode += ']\n};\n' +
                '});\n' +
                '})(window.define);\n' +
                '/* jshint ignore:end */';

            fs.writeFile('./app/scripts/design/themeFiles.js', jsCode, function (err) {
                if (err) {
                    return console.log(err);
                }
            });
            themesData = '{';
            for (i = 0; i < themes.length; i += 1) {
                themesData += '"' + themes[i] + '":"' + themes[i] + '"';
                if (i < themes.length - 1) {
                    themesData += ',';
                }
            }
            themesData += '}';

            request({
                uri: FOUNDATION_URI + '/config/unregister/themes',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', '');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            // Create group
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', 'themes_manager');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list.active',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list.active');
                form.append('value', 'default');
                form.append('type', '');
                form.append('editor', 'themes_manager');
                form.append('options', themesData);
                form.append('label', 'Active theme');
                form.append('description', 'Active theme on storefront');
            });

        });

    });

})();<commit_msg>Bugdixing wercker error<commit_after>(function () {
    'use strict';

    var gulp, minifyHTML, concat, stripDebug, uglify, jshint, changed, imagemin, autoprefix, sass, rjs, minifyCSS,
        browserSync, pngquant, del, paths, host, themes, FOUNDATION_URI;

    gulp = require('gulp');
    minifyHTML = require('gulp-minify-html');
    concat = require('gulp-concat');
    stripDebug = require('gulp-strip-debug');
    uglify = require('gulp-uglify');
    jshint = require('gulp-jshint');
    changed = require('gulp-changed');
    imagemin = require('gulp-imagemin');
    autoprefix = require('gulp-autoprefixer');
    sass = require('gulp-sass');
    rjs = require('gulp-requirejs');
    minifyCSS = require('gulp-minify-css');
    browserSync = require('browser-sync');
    pngquant = require('imagemin-pngquant');
    del = require('del');
    paths = {
        "app": require('./bower.json').appPath || 'app',
        "dist": 'dist',
        "themes": 'themes',
        "js": ['app/scripts/*.js', 'app/scripts/**/*.js'],
        "vendor": 'app/lib/**/*.js',
        "vendorTheme": 'app/themes/**/lib/*',
        "sass": 'app/styles/sass/**/*.scss',
        "css": 'app/themes/**/styles/**/*.css',
        "images": 'app/themes/**/images/**/*',
        "fonts": 'app/themes/**/styles/fonts/**/*',
        "html": 'app/**/*.html',
        "misc": 'app/*.{txt,htaccess,ico}',
        "themeDest": "dist/themes"

    };
    host = {
        port: '8080',
        lrPort: '35729'
    };
    themes = [];
    FOUNDATION_URI = 'http://dev.ottemo.io:3000';

    // Empties folders to start fresh
    gulp.task('clean', function (cb) {
        del(['dist'], cb);
    });

    // Actions with js-files from theme
    gulp.task('vendorTheme', ['clean'], function () {
        /**
         * Minify and uglify the custom scripts in folder 'scripts' in each theme
         */
        gulp.src('app/themes/**/scripts/**/*.js')
            .pipe(stripDebug())
            .pipe(uglify({mangle: false}))
            .pipe(gulp.dest(paths.themeDest));

        /**
         * copy vendor js from theme folder
         */
        return gulp.src(paths.vendorTheme)
            .pipe(gulp.dest(paths.themeDest));
    });

    // copy vendor js
    gulp.task('vendor', ['clean', 'vendorTheme'], function () {
        return gulp.src(paths.vendor)
            .pipe(gulp.dest(paths.dist + '/lib'));
    });

    // copy misc assets
    gulp.task('misc', ['clean'], function () {
        return gulp.src(paths.misc)
            .pipe(gulp.dest(paths.dist));
    });

    // Run JSHint
    gulp.task('jshint', function () {
        gulp.src(paths.js)
            .pipe(jshint())
            .pipe(jshint.reporter(require('jshint-stylish')));
    });

    gulp.task('requirejs', ['clean', 'jshint'], function () {
        rjs({
            out: 'main.js',
            name: 'main',
            preserveLicenseComments: false, // remove all comments
            removeCombined: true,
            baseUrl: paths.app + '/scripts',
            mainConfigFile: 'app/scripts/main.js'
        })
            .pipe(stripDebug())
            .pipe(uglify({mangle: false}))
            .pipe(gulp.dest(paths.dist + '/scripts/'));
    });

    // Sass task, will run when any SCSS files change & BrowserSync
    // will auto-update browsers
    gulp.task('sass', function () {
        return gulp.src(paths.sass)
            .pipe(sass({imagePath: '../../images'}))
            .pipe(autoprefix('last 1 version'))
            .pipe(gulp.dest(paths.dist + '/styles'))
            .pipe(gulp.dest(paths.app + '/styles'));
    });

    // minify new images
    gulp.task('imagemin', ['clean'], function () {
        return gulp.src(paths.images)
            .pipe(changed(paths.themeDest))
            .pipe(imagemin())
            .pipe(gulp.dest(paths.themeDest));
    });

    // minify new or changed HTML pages
    gulp.task('html', ['clean'], function () {
        return gulp.src(paths.html)
            .pipe(changed(paths.dist))
            .pipe(minifyHTML({
                collapseWhitespace: true,
                collapseBooleanAttributes: true,
                removeCommentsFromCDATA: true,
                removeOptionalTags: true,
                conditionals: true,
                quotes: true,
                empty: true
            }))
            .pipe(gulp.dest(paths.dist));
    });

    // CSS auto-prefix and minify
    gulp.task('autoprefixer', ['clean', 'sass'], function () {
        gulp.src(paths.css)
            .pipe(autoprefix('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
            .pipe(minifyCSS())
            .pipe(gulp.dest(paths.themeDest));
        gulp.src(paths.fonts)
            .pipe(gulp.dest(paths.themeDest));
    });

    // Protractor tests
    // gulp.task('protractorUpdate', protractor.webdriverUpdate);
    // gulp.task('protractor', ['protractorUpdate'], function (cb) {
    //     gulp.src(['tests/e2e/**/*.js']).pipe(protractor.protractor({
    //         configFile: 'protractor.conf.js'
    //     })).on('error', function (e) {
    //         console.log(e);
    //     }).on('end', cb);
    // });
    //
    // // Jasmine test
    // gulp.task('jasmine', function() {
    //     gulp.src('spec/**/*.js')
    //         .pipe(jasmine({verbose:true, includeStackTrace: true}));
    // });
    //
    // gulp.task('test', ['protractor', 'jasmine'], function () {});

    // browser-sync task for starting server
    gulp.task('browser-sync', function () {
        browserSync({
            server: {
                baseDir: './app'
            },
            port: host.port
        });
    });

    gulp.task('bs-reload', function () {
        browserSync.reload();
    });

    // run in development mode with easy browser reloading
    gulp.task('dev', ['browser-sync'], function () {

        gulp.watch('app/views/**/*.html', [browserSync.reload]);
        gulp.watch('app/styles/**/*.css', [browserSync.reload]);
        gulp.watch('app/styles/**/*.scss', ['sass', browserSync.reload]);
        gulp.watch('app/scripts/**/*.js', ['jshint', browserSync.reload]);
    });

    gulp.task('serve', ['dev', 'retrieve-files']);

    gulp.task('build', function(){
        var themesDir, jsCode, fs, recursive, themesData, request;

        themesData = '';
        fs = require('fs');
        request = require('request');
        recursive = require('recursive-readdir');

        themesDir = './app/themes';

        recursive(themesDir, function (err, files) {
            var i, theme, filePath, parts, regExp;
            theme = null;
            regExp = new RegExp('app[/\\\\]themes[/\\\\](\\w+)[/\\\\](.+)', 'i');

            jsCode = '/* jshint ignore:start */\n' +
                '(function (define) {\n' +
                '"use strict";\n' +
                'define(function () {\n' +
                'return {\n';

            for (i = 0; i < files.length; i += 1) {
                filePath = files[i];
                parts = filePath.match(regExp);
                if (parts instanceof Array) {
                    if (theme !== parts[1] && theme === null) {
                        themes.push(parts[1]);
                        jsCode += '\'' + parts[1] + '\' : [\n';
                    }
                    if (theme !== parts[1] && theme !== null) {
                        themes.push(parts[1]);
                        jsCode += '],\n\'' + parts[1] + '\' : [\n';
                    }
                    jsCode += '\'/' + parts[2] + '\',\n';
                    theme = parts[1];
                }
            }

            jsCode += ']\n};\n' +
                '});\n' +
                '})(window.define);\n' +
                '/* jshint ignore:end */';

            fs.writeFile('./app/scripts/design/themeFiles.js', jsCode, function (err) {
                if (err) {
                    return console.log(err);
                }
            });

            themesData = '{';
            for (i = 0; i < themes.length; i += 1) {
                themesData += '"' + themes[i] + '":"' + themes[i] + '"';
                if (i < themes.length - 1) {
                    themesData += ',';
                }
            }
            themesData += '}';

            request({
                uri: FOUNDATION_URI + '/config/unregister/themes',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', '');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            // Create group
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', 'themes_manager');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list.active',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list.active');
                form.append('value', 'default');
                form.append('type', '');
                form.append('editor', 'themes_manager');
                form.append('options', themesData);
                form.append('label', 'Active theme');
                form.append('description', 'Active theme on storefront');
            });

            gulp.start('requirejs');
            gulp.start('vendor');
            gulp.start('misc');
            gulp.start('html');
            gulp.start('autoprefixer');
            gulp.start('imagemin');
        });
    });

    gulp.task('default', ['build']);

    gulp.task('retrieve-files', function () {
        var themesDir, jsCode, fs, request, themesData, recursive;

        themesData = '';
        fs = require('fs');
        request = require('request');
        recursive = require('recursive-readdir');

        themesDir = './app/themes';

        recursive(themesDir, function (err, files) {
            var i, theme, filePath, parts, regExp;
            theme = null;
            regExp = new RegExp('app[/\\\\]themes[/\\\\](\\w+)[/\\\\](.+)', 'i');

            jsCode = '/* jshint ignore:start */\n' +
                '(function (define) {\n' +
                '"use strict";\n' +
                'define(function () {\n' +
                'return {\n';

            for (i = 0; i < files.length; i += 1) {
                filePath = files[i];
                parts = filePath.match(regExp);
                if (parts instanceof Array) {
                    if (theme !== parts[1] && theme === null) {
                        themes.push(parts[1]);
                        jsCode += '\'' + parts[1] + '\' : [\n';
                    }
                    if (theme !== parts[1] && theme !== null) {
                        themes.push(parts[1]);
                        jsCode += '],\n\'' + parts[1] + '\' : [\n';
                    }
                    jsCode += '\'/' + parts[2] + '\',\n';
                    theme = parts[1];
                }
            }

            jsCode += ']\n};\n' +
                '});\n' +
                '})(window.define);\n' +
                '/* jshint ignore:end */';

            fs.writeFile('./app/scripts/design/themeFiles.js', jsCode, function (err) {
                if (err) {
                    return console.log(err);
                }
            });
            themesData = '{';
            for (i = 0; i < themes.length; i += 1) {
                themesData += '"' + themes[i] + '":"' + themes[i] + '"';
                if (i < themes.length - 1) {
                    themesData += ',';
                }
            }
            themesData += '}';

            request({
                uri: FOUNDATION_URI + '/config/unregister/themes',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', '');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            // Create group
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list');
                form.append('value', '');
                form.append('type', 'group');
                form.append('editor', 'themes_manager');
                form.append('options', '');
                form.append('label', 'Themes');
                form.append('description', '');
            });
            request({
                uri: FOUNDATION_URI + '/config/unregister/themes.list.active',
                method: 'DELETE'
            }, function () {
                var r = request.post(FOUNDATION_URI + '/config/register');
                var form = r.form();
                form.append('path', 'themes.list.active');
                form.append('value', 'default');
                form.append('type', '');
                form.append('editor', 'themes_manager');
                form.append('options', themesData);
                form.append('label', 'Active theme');
                form.append('description', 'Active theme on storefront');
            });

        });

    });

})();<|endoftext|>


<commit_before>define(
  'ephox.phoenix.extract.Extract',

  [
    'ephox.compass.Arr',
    'ephox.phoenix.api.data.Spot',
    'ephox.phoenix.extract.TypedItem',
    'ephox.phoenix.extract.TypedList'
  ],

  function (Arr, Spot, TypedItem, TypedList) {
    /**
     * Flattens the item tree into TypedItem representations.
     *
     * Boundaries are returned twice, before and after their children.
     */
    var typed = function (universe, item, optimise) {
      if (universe.property().isText(item)) {
        return [ TypedItem.text(item, universe) ];
      } else if (universe.property().isEmptyTag(item)) {
        return [ TypedItem.empty(item, universe) ];
      } else if (universe.property().isElement(item)) {
        var children = universe.property().children(item);
        var boundary = universe.property().isBoundary(item) ? [TypedItem.boundary(item, universe)] : [];
        var rest = optimise !== undefined && optimise(item) ? [] : Arr.bind(children, function (child) {
          return typed(universe, child, optimise);
        });
        return boundary.concat(rest).concat(boundary);
      } else {
        return [];
      }
    };

    /**
     * Returns just the actual elements from a call to typed().
     */
    var items = function (universe, item, optimise) {
      var typedItemList = typed(universe, item, optimise);

      var raw = function (item, universe) { return item; };

      return Arr.map(typedItemList, function (typedItem) {
        return typedItem.fold(raw, raw, raw);
      });
    };

    var extractToElem = function (universe, child, offset, item, optimise) {
      var extractions = typed(universe, item, optimise);
      var prior = TypedList.dropUntil(extractions, child);
      var count = TypedList.count(prior);
      return Spot.point(item, count + offset);
    };

    /**
     * Generates an absolute point in the child's parent
     * that can be used to reference the offset into child later.
     *
     * To find the exact reference later, use Find.
     */
    var extract = function (universe, child, offset, optimise) {
      return universe.property().parent(child).fold(function () {
        return Spot.point(child, offset);
      }, function (parent) {
        return extractToElem(universe, child, offset, parent, optimise);
      });
    };

    /**
     * Generates an absolute point that can be used to reference the offset into child later.
     * This absolute point will be relative to a parent node (specified by predicate).
     *
     * To find the exact reference later, use Find.
     */
    var extractTo = function (universe, child, offset, pred, optimise) {
      return universe.up().predicate(child, pred).fold(function () {
        return Spot.point(child, offset);
      }, function (v) {
        return extractToElem(universe, child, offset, v, optimise);
      });
    };

    return {
      typed: typed,
      items: items,
      extractTo: extractTo,
      extract: extract
    };
  }
);
<commit_msg>TBIO-2299: update doc string<commit_after>define(
  'ephox.phoenix.extract.Extract',

  [
    'ephox.compass.Arr',
    'ephox.phoenix.api.data.Spot',
    'ephox.phoenix.extract.TypedItem',
    'ephox.phoenix.extract.TypedList'
  ],

  function (Arr, Spot, TypedItem, TypedList) {
    /**
     * Flattens the item tree into an array of TypedItem representations.
     *
     * Boundaries are returned twice, before and after their children.
     *
     * Returns: [array of TypedItem] where:
     *  If item is a text node or empty tag, returns a single-element array [item]
     *  If item is an element, returns all children recursively as an array.
     *  - if the element is also boundary, item is added to the front and end of the return array.
     *  Otherwise returns []
     */
    var typed = function (universe, item, optimise) {
      if (universe.property().isText(item)) {
        return [ TypedItem.text(item, universe) ];
      } else if (universe.property().isEmptyTag(item)) {
        return [ TypedItem.empty(item, universe) ];
      } else if (universe.property().isElement(item)) {
        var children = universe.property().children(item);
        var boundary = universe.property().isBoundary(item) ? [TypedItem.boundary(item, universe)] : [];
        var rest = optimise !== undefined && optimise(item) ? [] : Arr.bind(children, function (child) {
          return typed(universe, child, optimise);
        });
        return boundary.concat(rest).concat(boundary);
      } else {
        return [];
      }
    };

    /**
     * Returns just the actual elements from a call to typed().
     */
    var items = function (universe, item, optimise) {
      var typedItemList = typed(universe, item, optimise);

      var raw = function (item, universe) { return item; };

      return Arr.map(typedItemList, function (typedItem) {
        return typedItem.fold(raw, raw, raw);
      });
    };

    var extractToElem = function (universe, child, offset, item, optimise) {
      var extractions = typed(universe, item, optimise);
      var prior = TypedList.dropUntil(extractions, child);
      var count = TypedList.count(prior);
      return Spot.point(item, count + offset);
    };

    /**
     * Generates an absolute point in the child's parent
     * that can be used to reference the offset into child later.
     *
     * To find the exact reference later, use Find.
     */
    var extract = function (universe, child, offset, optimise) {
      return universe.property().parent(child).fold(function () {
        return Spot.point(child, offset);
      }, function (parent) {
        return extractToElem(universe, child, offset, parent, optimise);
      });
    };

    /**
     * Generates an absolute point that can be used to reference the offset into child later.
     * This absolute point will be relative to a parent node (specified by predicate).
     *
     * To find the exact reference later, use Find.
     */
    var extractTo = function (universe, child, offset, pred, optimise) {
      return universe.up().predicate(child, pred).fold(function () {
        return Spot.point(child, offset);
      }, function (v) {
        return extractToElem(universe, child, offset, v, optimise);
      });
    };

    return {
      typed: typed,
      items: items,
      extractTo: extractTo,
      extract: extract
    };
  }
);
<|endoftext|>


<commit_before>'use strict';

const LEVELS = {
  SILLY: 0,
  VERBOSE: 1,
  DEBUG: 2,
  INFO: 3,
  WARNING: 4,
  ERROR: 5,
};

let _nextRequestId = 0;

const nextRequestId = () => ++_nextRequestId;

const Logger = {
  LEVELS,

  METHODS: {
    [LEVELS.SILLY]: 'debug',
    [LEVELS.VERBOSE]: 'debug',
    [LEVELS.DEBUG]: 'log',
    [LEVELS.INFO]: 'info',
    [LEVELS.WARN]: 'warn',
    [LEVELS.ERROR]: 'error',
  },

  LEVEL: 2,
  SILENT: false,
  TRACE_ALL: false,

  silly(...msgs) { this.log(LEVELS.SILLY, ...msgs); },
  verbose(...msgs) { this.log(LEVELS.VERBOSE, ...msgs); },
  debug(...msgs) { this.log(LEVELS.DEBUG, ...msgs); },
  info(...msgs) { this.log(LEVELS.INFO, ...msgs); },
  warn(...msgs) { this.log(LEVELS.WARN, ...msgs); },
  error(...msgs) { this.log(LEVELS.ERROR, ...msgs); },
  logRequest(req) {
    const id = `request#${nextRequestId()}`;

    this.verbose(id, req.method, req.path);

    req.on('error', err =>
      this.error(id, 'error occured', err, req));
    req.on('abort', (...args) =>
      this.verbose(id, 'aborted by client', ...args));
    req.on('aborted', (...args) =>
      this.verbose(id, 'aborted by server', ...args));
    req.on('connect', (...args) =>
      this.verbose(id, 'connected', ...args));
  },
  logResponse(resp) {
    let data = '';
    const key = [resp.statusCode, resp.req.method, resp.req.path].join(' ');
    this.verbose(key, 'response received', resp);

    resp.on('error', err =>
      this.error(key, 'error occured', err, resp));
    resp.on('aborted', (...args) =>
      this.verbose(key, 'response aborted', ...args));
    resp.on('close', (...args) =>
      this.verbose(key, 'response closed', ...args));
    resp.on('data', (chunk) => {
      data += chunk;
      this.silly(key, 'data received', chunk);
    });
    resp.on('end', () => this.debug(key, 'response ended', data));
  },
  log(level, ...msgs) {
    if (level >= this.LEVEL && !this.SILENT) {
      console[this.METHODS[level]](...msgs);
      if (this.TRACE_ALL) { console.trace(); }
    }
  },
};

module.exports = Logger;
<commit_msg>Tweak responses logs<commit_after>'use strict';

const LEVELS = {
  SILLY: 0,
  VERBOSE: 1,
  DEBUG: 2,
  INFO: 3,
  WARNING: 4,
  ERROR: 5,
};

let _nextRequestId = 0;

const nextRequestId = () => ++_nextRequestId;

const Logger = {
  LEVELS,

  METHODS: {
    [LEVELS.SILLY]: 'debug',
    [LEVELS.VERBOSE]: 'debug',
    [LEVELS.DEBUG]: 'log',
    [LEVELS.INFO]: 'info',
    [LEVELS.WARN]: 'warn',
    [LEVELS.ERROR]: 'error',
  },

  LEVEL: 2,
  SILENT: false,
  TRACE_ALL: false,

  silly(...msgs) { this.log(LEVELS.SILLY, ...msgs); },
  verbose(...msgs) { this.log(LEVELS.VERBOSE, ...msgs); },
  debug(...msgs) { this.log(LEVELS.DEBUG, ...msgs); },
  info(...msgs) { this.log(LEVELS.INFO, ...msgs); },
  warn(...msgs) { this.log(LEVELS.WARN, ...msgs); },
  error(...msgs) { this.log(LEVELS.ERROR, ...msgs); },
  logRequest(req) {
    const id = `request#${nextRequestId()}`;

    this.verbose(id, req.method, req.path);

    req.on('error', err =>
      this.error(id, 'error occured', err, req));
    req.on('abort', (...args) =>
      this.verbose(id, 'aborted by client', ...args));
    req.on('aborted', (...args) =>
      this.verbose(id, 'aborted by server', ...args));
    req.on('connect', (...args) =>
      this.verbose(id, 'connected', ...args));
  },
  logResponse(resp) {
    let data = '';
    const key = [resp.statusCode, resp.req.method, resp.req.path].join(' ');
    this.verbose(key, 'response received', resp);

    resp.on('error', err =>
      this.error(key, 'error occured', err, resp));
    resp.on('aborted', (...args) =>
      this.verbose(key, 'response aborted', ...args));
    resp.on('close', (...args) =>
      this.verbose(key, 'response closed', ...args));
    resp.on('data', (chunk) => {
      data += chunk;
      this.silly(key, 'data:', chunk);
    });
    resp.on('end', () => this.debug(key, 'response:', data));
  },
  log(level, ...msgs) {
    if (level >= this.LEVEL && !this.SILENT) {
      console[this.METHODS[level]](...msgs);
      if (this.TRACE_ALL) { console.trace(); }
    }
  },
};

module.exports = Logger;
<|endoftext|>


<commit_before>/*global $, jQuery, alert*/

function highlightAddress(markerId) {
    'use strict';
    // console.log('marker : '+markerId);
    var item = $('#item-' + markerId);
    if (item.length && !item.hasClass('active')) {
        $('.places-list .active').removeClass('active');
        item.addClass('active');
    }
}

var onMarkerClick = function () {
    'use strict';
    highlightAddress(this.id);
    infoWindow.setContent(this.html);
    infoWindow.open(map, this);
};

// Gmaps
if ($('#map').length) {
    var infoWindow = new google.maps.InfoWindow(),
        jsonData = [],
        markers = [],
        markersPoints = [],
        markersPos = [],
        noms = [],
        iterator = 0,
        mapOptions = {
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            center: new google.maps.LatLng(50.85, 4.36),
            mapTypeControl: false,
            streetViewControl: false,
            zoom: 12
        },
        markerShape = {
            coord: [0, 0, 27, 0, 27, 37, 0, 37],
            type: 'poly'
        },
        map = new google.maps.Map(document.getElementById('map'), mapOptions);

    google.maps.event.addListener(map, 'click', function () {
        'use strict';
        infoWindow.close();
    });

    $.getJSON(location.search, function (data) {
        'use strict';
        var i = 0,
            coords = [],
            locale = $('html').attr('lang');
        if (!$.isArray(data)) {
            jsonData = [data];
        } else {
            jsonData = data;
        }
        for (i = 0; i < jsonData.length; i += 1) {
            if (jsonData[i].latitude > 0 && jsonData[i].longitude > 0) {
                markersPos[i] = new google.maps.LatLng(jsonData[i].latitude, jsonData[i].longitude);
                markers[i] = {};
                coords = [];
                markers[i].id = jsonData[i].id;
                markers[i].shape = jsonData[i].shape;
                markers[i].html = '
' + jsonData[i].title[locale] + '
';
                markers[i].html += '
';
                if (jsonData[i].address) { coords.push(jsonData[i].address); }
                if (jsonData[i].phone) { coords.push('T ' + jsonData[i].phone); }
                if (jsonData[i].fax) { coords.push('F ' + jsonData[i].fax); }
                if (jsonData[i].email) { coords.push('' + jsonData[i].email + ''); }
                if (jsonData[i].website) { coords.push('' + data[i].website + ''); }
                markers[i].html += coords.join('
');
                markers[i].html += '
';
            }
        }
        // console.log(markers);
        if (markers.length > 0) {
            drop();
            AutoCenter();
        }
    });

    // Search Postcode
    $('#search-nearest button').click(function () {
        'use strict';

        var address = $('#search-nearest input').val(),
            geocoder;

        if (!address.length) {
            return false;
        }

        geocoder = new google.maps.Geocoder();
        geocoder.geocode(
            {
                address: address
            },
            function (results_array) {
                var p = results_array[0].geometry.location,
                    lat = p.lat(),
                    lng = p.lng();
                setDistancesForMarkers(lat, lng);
            }
        );

        return false;
    });

    // Click on a marker in the list to open the info window on the map.
    $('.places-item-btn-map').on('click', function(){
        var id = $(this).closest('li').attr('id').replace(/item-/gi,'');
        for (var i = markers.length - 1; i >= 0; i--){
            if (markers[i].id == id) {
                var latLng = new google.maps.LatLng(markersPos[i].lat(),markersPos[i].lng());
                map.panTo( latLng );
                map.setZoom(18);
                google.maps.event.trigger(markersPoints[i], 'click');
            };
        };
        return false;
    })

    // Compute distance between two points
    var rad = function (x) {
        'use strict';
        return x * Math.PI / 180;
    };

    function getDistance(p1_lat, p1_lng, p2_lat, p2_lng) {
        'use strict';
        var R = 6378137, // Earth’s mean radius in meter
            dLat = rad(p2_lat - p1_lat),
            dLong = rad(p2_lng - p1_lng),
            a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(rad(p1_lat)) * Math.cos(rad(p2_lat)) *
                Math.sin(dLong / 2) * Math.sin(dLong / 2),
            c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)),
            d = R * c;
        return d; // returns the distance in meter
    }

    // Get the distance between a given point and the markers
    function setDistancesForMarkers(lat, lng) {
        'use strict';
        var i = 0;
        for (i = 0; i < jsonData.length; i += 1) {
            if (jsonData[i].latitude > 0 && jsonData[i].longitude > 0) {
                jsonData[i].distance = getDistance(lat, lng, jsonData[i].latitude, jsonData[i].longitude);
                jsonData.sort(function (a, b) {
                    return parseFloat(a.distance) - parseFloat(b.distance);
                });
            }
        }
        openMarkerId(jsonData[0].id);
    }

}

function getMarkerIcon(shape) {
    'use strict';
    if (!shape) {
        shape = '/img/marker.png';
    }
    return new google.maps.MarkerImage(shape,
        new google.maps.Size(34, 44),
        new google.maps.Point(0, 0),
        new google.maps.Point(14, 36));
}

function addMarker(animation) {
    'use strict';

    // decaler un marker s'il y a déjà un point à la même position
    var dedans = 0,
        i = 0,
        latLng;
    for (i = markers.length - 1; i >= 0; i -= 1) {
        // console.log(markers[iterator].lat());
        if (markersPos[iterator].lat() === markersPos[i].lat() && markersPos[iterator].lng() === markersPos[i].lng()) {
            // markers[i]['html'] += markers[iterator]['html'];
            dedans += 1;
        }
    }
    if (dedans >= 2) {
        // console.log(dedans+' '+iterator);
        // Il y a au moins deux points ayant la même position, alors on décale un des deux
        latLng = new google.maps.LatLng(markersPos[iterator].lat(), markersPos[iterator].lng() + Math.random() / 4000 + 0.00001);
    } else {
        latLng = markersPos[iterator];
    }

    markersPoints[iterator] = new google.maps.Marker({
        // icon: getMarkerIcon('/img/marker.png'),
        shape: markerShape,
        position: latLng,
        map: map,
        draggable: false,
        animation: animation
    });
    // console.log(markers[iterator]);
    markersPoints[iterator].html = markers[iterator].html;
    markersPoints[iterator].id = markers[iterator].id;
    google.maps.event.addListener(markersPoints[iterator], 'click', onMarkerClick);
    if (markers.length === 1) {
        google.maps.event.trigger(markersPoints[iterator], 'click');
    }
    iterator += 1;
}

function drop() {
    'use strict';
    var i = 0;
    if (markers.length <= 3) {
        for (i = 0; i < markers.length; i += 1) {
            setTimeout(function () {
                addMarker(google.maps.Animation.DROP);
            }, i * 200);
        }
    } else {
        for (i = 0; i < markers.length; i += 1) {
            addMarker(false);
        }
    }
}

function AutoCenter() {
    'use strict';
    var bounds = new google.maps.LatLngBounds(),
        listener;
    $.each(markers, function (index) {
        bounds.extend(markersPos[index]);
    });
    map.fitBounds(bounds);
    listener = google.maps.event.addListener(map, 'idle', function () {
        if (map.getZoom() > 17) {
            map.setZoom(17);
        }
        google.maps.event.removeListener(listener);
    });
}

function openMarkerId(id) {
    'use strict';
    var i = 0,
        latLng;
    // console.log('click : '+id );
    for (i = markers.length - 1; i >= 0; i -= 1) {
        // console.log(markers[i].id );
        if (markers[i].id === id) {
            latLng = new google.maps.LatLng(markersPos[i].lat(), markersPos[i].lng());
            map.panTo(latLng);
            map.setZoom(13);
            google.maps.event.trigger(markersPoints[i], 'click');
        }
    }
    return false;
}
<commit_msg>code form google maps marker icon<commit_after>/*global $, jQuery, alert*/

function highlightAddress(markerId) {
    'use strict';
    // console.log('marker : '+markerId);
    var item = $('#item-' + markerId);
    if (item.length && !item.hasClass('active')) {
        $('.places-list .active').removeClass('active');
        item.addClass('active');
    }
}

var onMarkerClick = function () {
    'use strict';
    highlightAddress(this.id);
    infoWindow.setContent(this.html);
    infoWindow.open(map, this);
};

// Gmaps
if ($('#map').length) {
    var infoWindow = new google.maps.InfoWindow(),
        jsonData = [],
        markers = [],
        markersPoints = [],
        markersPos = [],
        noms = [],
        iterator = 0,
        mapOptions = {
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            center: new google.maps.LatLng(50.85, 4.36),
            mapTypeControl: false,
            streetViewControl: false,
            zoom: 12
        },
        map = new google.maps.Map(document.getElementById('map'), mapOptions);

    google.maps.event.addListener(map, 'click', function () {
        'use strict';
        infoWindow.close();
    });

    $.getJSON(location.search, function (data) {
        'use strict';
        var i = 0,
            coords = [],
            locale = $('html').attr('lang');
        if (!$.isArray(data)) {
            jsonData = [data];
        } else {
            jsonData = data;
        }
        for (i = 0; i < jsonData.length; i += 1) {
            if (jsonData[i].latitude > 0 && jsonData[i].longitude > 0) {
                markersPos[i] = new google.maps.LatLng(jsonData[i].latitude, jsonData[i].longitude);
                markers[i] = {};
                coords = [];
                markers[i].id = jsonData[i].id;
                markers[i].shape = jsonData[i].shape;
                markers[i].html = '
' + jsonData[i].title[locale] + '
';
                markers[i].html += '
';
                if (jsonData[i].address) { coords.push(jsonData[i].address); }
                if (jsonData[i].phone) { coords.push('T ' + jsonData[i].phone); }
                if (jsonData[i].fax) { coords.push('F ' + jsonData[i].fax); }
                if (jsonData[i].email) { coords.push('' + jsonData[i].email + ''); }
                if (jsonData[i].website) { coords.push('' + data[i].website + ''); }
                markers[i].html += coords.join('
');
                markers[i].html += '
';
            }
        }
        // console.log(markers);
        if (markers.length > 0) {
            drop();
            AutoCenter();
        }
    });

    // Search Postcode
    $('#search-nearest button').click(function () {
        'use strict';

        var address = $('#search-nearest input').val(),
            geocoder;

        if (!address.length) {
            return false;
        }

        geocoder = new google.maps.Geocoder();
        geocoder.geocode(
            {
                address: address
            },
            function (results_array) {
                var p = results_array[0].geometry.location,
                    lat = p.lat(),
                    lng = p.lng();
                setDistancesForMarkers(lat, lng);
            }
        );

        return false;
    });

    // Click on a marker in the list to open the info window on the map.
    $('.places-item-btn-map').on('click', function(){
        var id = $(this).closest('li').attr('id').replace(/item-/gi,'');
        for (var i = markers.length - 1; i >= 0; i--){
            if (markers[i].id == id) {
                var latLng = new google.maps.LatLng(markersPos[i].lat(),markersPos[i].lng());
                map.panTo( latLng );
                map.setZoom(18);
                google.maps.event.trigger(markersPoints[i], 'click');
            };
        };
        return false;
    })

    // Compute distance between two points
    var rad = function (x) {
        'use strict';
        return x * Math.PI / 180;
    };

    function getDistance(p1_lat, p1_lng, p2_lat, p2_lng) {
        'use strict';
        var R = 6378137, // Earth’s mean radius in meter
            dLat = rad(p2_lat - p1_lat),
            dLong = rad(p2_lng - p1_lng),
            a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(rad(p1_lat)) * Math.cos(rad(p2_lat)) *
                Math.sin(dLong / 2) * Math.sin(dLong / 2),
            c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)),
            d = R * c;
        return d; // returns the distance in meter
    }

    // Get the distance between a given point and the markers
    function setDistancesForMarkers(lat, lng) {
        'use strict';
        var i = 0;
        for (i = 0; i < jsonData.length; i += 1) {
            if (jsonData[i].latitude > 0 && jsonData[i].longitude > 0) {
                jsonData[i].distance = getDistance(lat, lng, jsonData[i].latitude, jsonData[i].longitude);
                jsonData.sort(function (a, b) {
                    return parseFloat(a.distance) - parseFloat(b.distance);
                });
            }
        }
        openMarkerId(jsonData[0].id);
    }

}

function addMarker(animation) {
    'use strict';

    // decaler un marker s'il y a déjà un point à la même position
    var dedans = 0,
        i = 0,
        latLng;
    for (i = markers.length - 1; i >= 0; i -= 1) {
        // console.log(markers[iterator].lat());
        if (markersPos[iterator].lat() === markersPos[i].lat() && markersPos[iterator].lng() === markersPos[i].lng()) {
            // markers[i]['html'] += markers[iterator]['html'];
            dedans += 1;
        }
    }
    if (dedans >= 2) {
        // console.log(dedans+' '+iterator);
        // Il y a au moins deux points ayant la même position, alors on décale un des deux
        latLng = new google.maps.LatLng(markersPos[iterator].lat(), markersPos[iterator].lng() + Math.random() / 4000 + 0.00001);
    } else {
        latLng = markersPos[iterator];
    }

    markersPoints[iterator] = new google.maps.Marker({
        // icon: {
        //     url: '/img/marker.png',
        //     size: new google.maps.Size(36, 52),
        //     origin: new google.maps.Point(0, 0),
        //     anchor: new google.maps.Point(18, 48),
        //     scaledSize: new google.maps.Size(36, 52)
        // },
        position: latLng,
        map: map,
        draggable: false,
        animation: animation
    });
    // console.log(markers[iterator]);
    markersPoints[iterator].html = markers[iterator].html;
    markersPoints[iterator].id = markers[iterator].id;
    google.maps.event.addListener(markersPoints[iterator], 'click', onMarkerClick);
    if (markers.length === 1) {
        google.maps.event.trigger(markersPoints[iterator], 'click');
    }
    iterator += 1;
}

function drop() {
    'use strict';
    var i = 0;
    if (markers.length <= 3) {
        for (i = 0; i < markers.length; i += 1) {
            setTimeout(function () {
                addMarker(google.maps.Animation.DROP);
            }, i * 200);
        }
    } else {
        for (i = 0; i < markers.length; i += 1) {
            addMarker(false);
        }
    }
}

function AutoCenter() {
    'use strict';
    var bounds = new google.maps.LatLngBounds(),
        listener;
    $.each(markers, function (index) {
        bounds.extend(markersPos[index]);
    });
    map.fitBounds(bounds);
    listener = google.maps.event.addListener(map, 'idle', function () {
        if (map.getZoom() > 17) {
            map.setZoom(17);
        }
        google.maps.event.removeListener(listener);
    });
}

function openMarkerId(id) {
    'use strict';
    var i = 0,
        latLng;
    // console.log('click : '+id );
    for (i = markers.length - 1; i >= 0; i -= 1) {
        // console.log(markers[i].id );
        if (markers[i].id === id) {
            latLng = new google.maps.LatLng(markersPos[i].lat(), markersPos[i].lng());
            map.panTo(latLng);
            map.setZoom(13);
            google.maps.event.trigger(markersPoints[i], 'click');
        }
    }
    return false;
}
<|endoftext|>


<commit_before>'use strict';

exports.notReady = function (err, res, p) {
  res.status(503).send('Server not yet ready. Percentage:' + p);
};

exports.handleErrors = function (err, res) {
  if (err) {
    if (err.code)  {
      res.status(400).send(err.message + '. Code:' + err.code);
    }
    else {
      res.status(503).send(err.message);
    }
  }
  else {
    res.status(404).send('Not found');
  }
};
<commit_msg>better msg<commit_after>'use strict';

exports.notReady = function (err, res, p) {
  res.status(503).send('Server not yet ready. Sync Percentage:' + p);
};

exports.handleErrors = function (err, res) {
  if (err) {
    if (err.code)  {
      res.status(400).send(err.message + '. Code:' + err.code);
    }
    else {
      res.status(503).send(err.message);
    }
  }
  else {
    res.status(404).send('Not found');
  }
};
<|endoftext|>


<commit_before>var db = require('./db.js');
var models = require('./models.js');
var Promise = require('bluebird');
var events = require('events');
var eventEmitter = new events.EventEmitter();
var path = require('path');
var socket = require(path.resolve('server/sockets'));

module.exports.findOrCreate = function (Model, attributes) {

  return new Promise (function (resolve, reject) {
    Model.forge(attributes).fetch()
    .then(function (model) {
      if (!model) {
        model = new Model(attributes);
      }
      model.save()
      .then(function () {
        resolve(model);
      })
      .catch(function (error) {
        reject(error);
      });
    })
    .catch(function (error) {
      reject(error);
    });
  });
};

module.exports.getFriends = function (ids_obj, my_fb_id) {
  var ids_array = [];
  for (var id in ids_obj) {
    ids_array.push(id);
  }
  var friends = [];
  var friendCount = 0;
  var my_id = 0;
  return new Promise(function (res, rej) {
    return ids_array.forEach(function (id) {
      return db.knex
      .select()
      .from('users')
      .where('facebook_id', id)
      .then(function (user) {
        if (id === my_fb_id && user) {
          my_id = user[0].id;
        }
        if (user.length) {
          friends.push(user[0]);
          if (++friendCount === ids_array.length) {
            res({friends: friends, my_id: my_id});
          }
        } else {
          new models.User({'facebook_id': id}).save()
          .then(function (user) {
            friends.push(user);
            if (++friendCount === ids_array.length) {
              res({friends: friends, my_id: my_id});
            }
          })
          .catch(function (error) {
            console.log(error);
          })
        }
      })
    });
  });
};

module.exports.createGame = function (data, my_fb_id) {
  return new Promise(function (res, rej) {
    module.exports.getFriends(data.friends, my_fb_id)
    .then(function (result) {
      new models.Game({
        creator_id: data.creator_id,
        max_score: data.rules.maxScore
      }).save()
      .then(function (game) {
        module.exports.inviteFriends(game, result.friends, result.my_id)
        .then(function (game) {
          models.User.forge({id: game.attributes.creator_id}).fetch()
          .then(function (user) {
            user.set('current_game_id', game.attributes.id)
            .save()
            .then(function (game) {
              res(game);
            })
          })
        });
      })
      .catch(function (error) {
        rej(error);
      })
    });
  });

}

module.exports.inviteFriends = function (game, friends, my_id) {
  return new Promise(function (res, rej) {
    var inviteCount = 0;
    friends.forEach(function (friend) {
      var invite = null;
      if (my_id === friend.id) {
        invite = 1;
      }
      module.exports.findOrCreate(models.UserGame, {game_id: game.id, user_id: friend.id, invite: invite})
      .then(function (userGame) {
        socket.inviteFriend(friend.id);
        if (++inviteCount === friends.length) {
          res(game);
        }
      })
      .catch(function (error) {
        rej(error);
      });
    });
  });
};

module.exports.getInvites = function (user_fb) {
  return new Promise(function (res, rej) {
    module.exports.findOrCreate(models.User, {facebook_id: user_fb})
    .then( function (user) {
      db.knex('users_games').where({
        user_id: user.attributes.id,
        invite: null
      }).select('game_id')
      .then(function (userGames) {
        var invitedGames = [];
        userGames.forEach(function (userGame) {
          invitedGames.push(module.exports.findOrCreate(models.Game, {id: userGame.game_id}));
        });
        Promise.all(invitedGames)
        .then(function (games) {
          var creators = [];
          var gameResults = [];
          games.forEach(function (game) {
            gameResults.push(game.attributes);
            creators.push(module.exports.findOrCreate(models.User, {id: game.attributes.creator_id}));
          });
          Promise.all(creators)
          .then(function (creators) {
            var results = [];
            for (var i = 0; i < gameResults.length; i++) {
              var result = {};
              result.id = gameResults[i].id;
              result.name = gameResults[i].name;
              result.creator = creators[i].attributes;
              results.push(result);
            }
            res(results);
          })
          .catch(function (error) {
            console.log(error)
            rej(error);
          });
        });
      });
    });
  });
};

module.exports.resolveInvite = function (user_fb, invitation, accepted) {
  return new Promise(function (res, rej) {
    module.exports.findOrCreate(models.User, {facebook_id: user_fb})
    .then( function (user) {
      var invite;
      if (accepted === true) {
        invite = 1;
      } else {
        invite = 2;
      }
      db.knex('users_games')
      .where({
        user_id: user.id,
        game_id: invitation.id
      })
      .update({
        invite: invite
      })
      .then( function (result) {
        module.exports.getPlayers(invitation.id)
        .then(function (players) {
          socket.inviteResult(players, result);
        });
        if (accepted) {
          user.set('current_game_id', invitation.id).save()
          .then(function () {
            res(result);
          })
          .catch(function (error) {
            rej(error);
          });
        } else {
          res(result);
        }
      });
    })
    .catch( function (error) {
      rej(error);
    });
  });
};

module.exports.getGame = function (game_id) {
  return new Promise(function (res, rej) {
    module.exports.getPlayers(game_id)
    .then(function (players) {
      models.Round.query('where', 'game_id', '=', game_id).fetchAll({withRelated: ['responses', 'reader']})
      .then(function (rounds) {
        models.Game.forge({id: game_id}).fetch()
        .then(function (game) {
          var polishedRounds = [];
          rounds.forEach(function (round) {
            polishedRounds.push(round.attributes);
            polishedRounds[polishedRounds.length - 1].reader_name = round.relations.reader.attributes.full_name;
            var polishedResponses = [];
            round.relations.responses.models.forEach(function (response) {
              polishedResponses.push(response.attributes);
            })
            polishedRounds[polishedRounds.length - 1].responses = polishedResponses;
          });
          res({
            rounds: polishedRounds,
            players: players,
            game: game
          });
        });
      });
    })
    .catch(function (error) {
      console.log(error);
      rej(error);
    });
  });
};

module.exports.getPlayers = function (game_id) {
  return new Promise(function (res, rej) {
    db.knex.select('users.id', 'users.pic_url', 'users.full_name', 'users_games.score')
    .from('users_games')
    .where('users_games.game_id', game_id)
    .innerJoin('games', 'users_games.game_id', 'games.id')
    .innerJoin('users', 'users_games.user_id', 'users.id')
    .groupBy('users.full_name')
    .groupBy('users.id')
    .groupBy('users.pic_url')
    .groupBy('users_games.score')
    .whereNot('users_games.invite', 2)
    .whereNotNull('users_games.invite')
    .then(function (players) {
      models.Game.forge({id: game_id}).fetch()
      .then(function (game) {
        if (!game) {
          return;
        }
        for (var i = 0; i < players.length; i++) {
          if (game.attributes.creator_id === players[i].id) {
            players[i].creator = true;
            break;
          }
        }
        res(players);
      });
    })
    .catch(function (error) {
      rej(error);
    });
  });
}

module.exports.startGame = function (game_id) {
  return new Promise(function (res, rej) {
    models.Game.forge({id: game_id}).fetch()
    .then(function (game) {
      game.set('started', true)
      .save()
      .then(function (game) {
        socket.gameStarted(game_id);
        module.exports.startRound(game_id, game.get('creator_id'));
        res();
      });
    })
    .catch(function (error) {
      console.log(error);
      rej(error);
    })
  });
};

module.exports.startRound = function (game_id, reader_id) {
  return new Promise(function (res, rej) {
    models.Game.forge({id: game_id}).fetch()
    .then(function (game) {
      models.Round.forge({
        game_id: game_id,
        reader_id: reader_id,
        topic: ''
      })
      .save()
      .then(function (round) {
        round.fetch({withRelated: ['reader']})
        .then(function (round) {
          socket.newRound(game_id, round);
          res(round);
        })
        .catch(function (error) {
          console.log(error);
        })
      });
    })
    .catch(function (error) {
      rej(error);
    })
  });
};

module.exports.setTopic = function (round_id, topic) {
  return new Promise(function (res, rej) {
    module.exports.findOrCreate(models.Round, {id: round_id})
    .then(function (round) {
      round.save({topic: topic})
      .then(function () {
        socket.newTopic(round, topic);
        res();
      })
    })
    .catch(function (error) {
      rej(error);
    })
  });
};

module.exports.saveResponse = function (round_id, response, user_id) {
  return new Promise(function (res, rej) {
    models.Response.forge({
      round_id: round_id,
      user_id: user_id
    }).fetch()
    .then(function (response) {
      if (response) {
        rej('duplicate');
      } else {
        models.Response.forge({
          round_id: round_id,
          user_id: user_id,
          text: response
        })
        .save()
        .then(function (response) {
          socket.newResponse(round_id, response);
          res(response);
        })
      }
    })
    .catch(function (error) {
      rej(error);
    })
  });
};

module.exports.eventEmitter = eventEmitter;<commit_msg>(fix) save text response to db<commit_after>var db = require('./db.js');
var models = require('./models.js');
var Promise = require('bluebird');
var events = require('events');
var eventEmitter = new events.EventEmitter();
var path = require('path');
var socket = require(path.resolve('server/sockets'));

module.exports.findOrCreate = function (Model, attributes) {

  return new Promise (function (resolve, reject) {
    Model.forge(attributes).fetch()
    .then(function (model) {
      if (!model) {
        model = new Model(attributes);
      }
      model.save()
      .then(function () {
        resolve(model);
      })
      .catch(function (error) {
        reject(error);
      });
    })
    .catch(function (error) {
      reject(error);
    });
  });
};

module.exports.getFriends = function (ids_obj, my_fb_id) {
  var ids_array = [];
  for (var id in ids_obj) {
    ids_array.push(id);
  }
  var friends = [];
  var friendCount = 0;
  var my_id = 0;
  return new Promise(function (res, rej) {
    return ids_array.forEach(function (id) {
      return db.knex
      .select()
      .from('users')
      .where('facebook_id', id)
      .then(function (user) {
        if (id === my_fb_id && user) {
          my_id = user[0].id;
        }
        if (user.length) {
          friends.push(user[0]);
          if (++friendCount === ids_array.length) {
            res({friends: friends, my_id: my_id});
          }
        } else {
          new models.User({'facebook_id': id}).save()
          .then(function (user) {
            friends.push(user);
            if (++friendCount === ids_array.length) {
              res({friends: friends, my_id: my_id});
            }
          })
          .catch(function (error) {
            console.log(error);
          })
        }
      })
    });
  });
};

module.exports.createGame = function (data, my_fb_id) {
  return new Promise(function (res, rej) {
    module.exports.getFriends(data.friends, my_fb_id)
    .then(function (result) {
      new models.Game({
        creator_id: data.creator_id,
        max_score: data.rules.maxScore
      }).save()
      .then(function (game) {
        module.exports.inviteFriends(game, result.friends, result.my_id)
        .then(function (game) {
          models.User.forge({id: game.attributes.creator_id}).fetch()
          .then(function (user) {
            user.set('current_game_id', game.attributes.id)
            .save()
            .then(function (game) {
              res(game);
            })
          })
        });
      })
      .catch(function (error) {
        rej(error);
      })
    });
  });

}

module.exports.inviteFriends = function (game, friends, my_id) {
  return new Promise(function (res, rej) {
    var inviteCount = 0;
    friends.forEach(function (friend) {
      var invite = null;
      if (my_id === friend.id) {
        invite = 1;
      }
      module.exports.findOrCreate(models.UserGame, {game_id: game.id, user_id: friend.id, invite: invite})
      .then(function (userGame) {
        socket.inviteFriend(friend.id);
        if (++inviteCount === friends.length) {
          res(game);
        }
      })
      .catch(function (error) {
        rej(error);
      });
    });
  });
};

module.exports.getInvites = function (user_fb) {
  return new Promise(function (res, rej) {
    module.exports.findOrCreate(models.User, {facebook_id: user_fb})
    .then( function (user) {
      db.knex('users_games').where({
        user_id: user.attributes.id,
        invite: null
      }).select('game_id')
      .then(function (userGames) {
        var invitedGames = [];
        userGames.forEach(function (userGame) {
          invitedGames.push(module.exports.findOrCreate(models.Game, {id: userGame.game_id}));
        });
        Promise.all(invitedGames)
        .then(function (games) {
          var creators = [];
          var gameResults = [];
          games.forEach(function (game) {
            gameResults.push(game.attributes);
            creators.push(module.exports.findOrCreate(models.User, {id: game.attributes.creator_id}));
          });
          Promise.all(creators)
          .then(function (creators) {
            var results = [];
            for (var i = 0; i < gameResults.length; i++) {
              var result = {};
              result.id = gameResults[i].id;
              result.name = gameResults[i].name;
              result.creator = creators[i].attributes;
              results.push(result);
            }
            res(results);
          })
          .catch(function (error) {
            console.log(error)
            rej(error);
          });
        });
      });
    });
  });
};

module.exports.resolveInvite = function (user_fb, invitation, accepted) {
  return new Promise(function (res, rej) {
    module.exports.findOrCreate(models.User, {facebook_id: user_fb})
    .then( function (user) {
      var invite;
      if (accepted === true) {
        invite = 1;
      } else {
        invite = 2;
      }
      db.knex('users_games')
      .where({
        user_id: user.id,
        game_id: invitation.id
      })
      .update({
        invite: invite
      })
      .then( function (result) {
        module.exports.getPlayers(invitation.id)
        .then(function (players) {
          socket.inviteResult(players, result);
        });
        if (accepted) {
          user.set('current_game_id', invitation.id).save()
          .then(function () {
            res(result);
          })
          .catch(function (error) {
            rej(error);
          });
        } else {
          res(result);
        }
      });
    })
    .catch( function (error) {
      rej(error);
    });
  });
};

module.exports.getGame = function (game_id) {
  return new Promise(function (res, rej) {
    module.exports.getPlayers(game_id)
    .then(function (players) {
      models.Round.query('where', 'game_id', '=', game_id).fetchAll({withRelated: ['responses', 'reader']})
      .then(function (rounds) {
        models.Game.forge({id: game_id}).fetch()
        .then(function (game) {
          var polishedRounds = [];
          rounds.forEach(function (round) {
            polishedRounds.push(round.attributes);
            polishedRounds[polishedRounds.length - 1].reader_name = round.relations.reader.attributes.full_name;
            var polishedResponses = [];
            round.relations.responses.models.forEach(function (response) {
              polishedResponses.push(response.attributes);
            })
            polishedRounds[polishedRounds.length - 1].responses = polishedResponses;
          });
          res({
            rounds: polishedRounds,
            players: players,
            game: game
          });
        });
      });
    })
    .catch(function (error) {
      console.log(error);
      rej(error);
    });
  });
};

module.exports.getPlayers = function (game_id) {
  return new Promise(function (res, rej) {
    db.knex.select('users.id', 'users.pic_url', 'users.full_name', 'users_games.score')
    .from('users_games')
    .where('users_games.game_id', game_id)
    .innerJoin('games', 'users_games.game_id', 'games.id')
    .innerJoin('users', 'users_games.user_id', 'users.id')
    .groupBy('users.full_name')
    .groupBy('users.id')
    .groupBy('users.pic_url')
    .groupBy('users_games.score')
    .whereNot('users_games.invite', 2)
    .whereNotNull('users_games.invite')
    .then(function (players) {
      models.Game.forge({id: game_id}).fetch()
      .then(function (game) {
        if (!game) {
          return;
        }
        for (var i = 0; i < players.length; i++) {
          if (game.attributes.creator_id === players[i].id) {
            players[i].creator = true;
            break;
          }
        }
        res(players);
      });
    })
    .catch(function (error) {
      rej(error);
    });
  });
}

module.exports.startGame = function (game_id) {
  return new Promise(function (res, rej) {
    models.Game.forge({id: game_id}).fetch()
    .then(function (game) {
      game.set('started', true)
      .save()
      .then(function (game) {
        socket.gameStarted(game_id);
        module.exports.startRound(game_id, game.get('creator_id'));
        res();
      });
    })
    .catch(function (error) {
      console.log(error);
      rej(error);
    })
  });
};

module.exports.startRound = function (game_id, reader_id) {
  return new Promise(function (res, rej) {
    models.Game.forge({id: game_id}).fetch()
    .then(function (game) {
      models.Round.forge({
        game_id: game_id,
        reader_id: reader_id,
        topic: ''
      })
      .save()
      .then(function (round) {
        round.fetch({withRelated: ['reader']})
        .then(function (round) {
          socket.newRound(game_id, round);
          res(round);
        })
        .catch(function (error) {
          console.log(error);
        })
      });
    })
    .catch(function (error) {
      rej(error);
    })
  });
};

module.exports.setTopic = function (round_id, topic) {
  return new Promise(function (res, rej) {
    module.exports.findOrCreate(models.Round, {id: round_id})
    .then(function (round) {
      round.save({topic: topic})
      .then(function () {
        socket.newTopic(round, topic);
        res();
      })
    })
    .catch(function (error) {
      rej(error);
    })
  });
};

module.exports.saveResponse = function (round_id, response, user_id) {
  var text = response;
  return new Promise(function (res, rej) {
    models.Response.forge({
      round_id: round_id,
      user_id: user_id
    }).fetch()
    .then(function (response) {
      if (response) {
        rej('duplicate');
      } else {
        models.Response.forge({
          round_id: round_id,
          user_id: user_id,
          text: text
        })
        .save()
        .then(function (response) {
          socket.newResponse(round_id, response);
          res(response);
        })
      }
    })
    .catch(function (error) {
      rej(error);
    })
  });
};

module.exports.eventEmitter = eventEmitter;<|endoftext|>


<commit_before>const h = require('hyperscript');
const classNames = require('classnames');
const tippy = require('tippy.js');
const config = require('../../config');

//Manage the creation and display of metadata HTML content
//Requires a valid name, cytoscape element, and parsedMetadata array
class MetadataTip {

  constructor(name, data, cyElement) {
    this.name = name;
    this.data = data.parsedMetadata;
    this.cyElement = cyElement;
    this.db = config.databases;
  }

  //Generate HTML elements for Each Parsed Metadata Field
  //Optional trim parameter indicates if the data presented should be trimmed to a reasonable length
  parseMetadata(pair, trim = true) {
    let key = pair[0];

    //Get HTML for current data pair based on key value
    if (key === 'Standard Name') {
      return h('div.fake-paragraph', h('div.field-name', 'Approved Name: '), pair[1].toString());
    }
    else if (key === 'Data Source') {
      let source = pair[1].replace('http://pathwaycommons.org/pc2/', '');
      let link = this.generateDataSourceLink(source, 'Data Source: ');
      return h('div.fake-paragraph', link);
    }
    else if (key === 'Type' && !trim) {
      return h('div.fake-paragraph', [h('div.field-name', key + ': '), pair[1].toString().substring(3)]);
    }
    else if (key === 'Names') {
      //Trim results to first 3 names to avoid overflow
      let shortArray = pair[1];
      if (trim) { shortArray = pair[1].slice(0, 3); }

      //Filter out Chemical formulas
      if (shortArray instanceof Array) shortArray = shortArray.filter(name => (!name.trim().match(/^([^J][0-9BCOHNSOPrIFla@+\-\[\]\(\)\\=#$]{6,})$/ig)));
      return h('div.fake-paragraph', h('div.field-name', 'Synonyms: '), shortArray.toString());
    }
    else if (key === 'Database IDs') {
      //Sort the array by database names
      let sortedArray = this.sortByDatabaseId(pair[1]);
      if (sortedArray.length < 1) { return; }
      return h('div.fake-paragraph',
        [
          h('div.field-name', 'Database References:'),
          h('div.wrap-text', h('ul.db-list', sortedArray.map(item => this.generateIdList(item, trim), this)))
        ]);
    }
    else if (key === 'Comment' && !(trim)) {
      //Get comments
      let comments = pair[1];

      //Remove any strings with replaced
      if (comments instanceof Array) {
        comments = comments.filter(value => value.toUpperCase().indexOf('REPLACED') === -1);
      }
      else if (typeof comments === 'string' && comments.toUpperCase().indexOf('REPLACED') === -1) {
        comments = [comments];
      }
      else {
        comments = [];
      }

      //Generate HTML
      if (comments.length > 0) {
        return h('div.fake-paragraph', [
          h('div.field-name', 'Comments' + ': '),
          comments.map(item => h('div.comment', [
            h('div.tooltip-comment', item),
            h('br')]))
        ]);
      }

    }
    else if (!(trim)) {
      return h('div.fake-paragraph', [h('div.field-name', key + ': '), h('div.tooltip-value', pair[1].toString())]);
    }

    return;
  }

  //Validate the name of object and use Display Name as the fall back option
  validateName() {
    if (!(this.name)) {
      let displayName = this.data.filter(pair => pair[0] === 'Display Name');
      if (displayName.length > 0) { this.name = displayName[0][1].toString(); }
    }
  }

  //Generate HTML Elements for tooltips
  generateToolTip(callback) {

    //Order the data array
    let data = this.orderArray(this.data);
    if (!(data)) data = [];

    //Ensure name is not blank
    this.validateName();

    if (!(this.data)) { this.data = []; }
    return h('div.tooltip-image',
      h('div.tooltip-heading', this.name),
      h('div.tooltip-internal', h('div', (data).map(item => this.parseMetadata(item, true), this))),
      h('div.tooltip-buttons',
        [
          h('div.tooltip-button-container',
            [
              h('div.tooltip-button', { onclick: this.displayMore(callback) }, [
                h('i', { className: classNames('material-icons', 'tooltip-button-show') }, 'bubble_chart'),
                h('div.describe-button', 'Open in Sidebar')
              ])
            ])
        ])
    );
  }

  //Generate HTML Elements for the side bar
  generateSideBar() {
    //Order the data array
    let data = this.orderArray(this.data);
    if (!(data)) data = [];

    //Ensure name is not blank
    this.validateName();

    if (!(this.data)) { this.data = []; }
    return h('div.sidebar-body',
      h('h1', this.name),
      h('div.sidebar-internal', h('div', (data).map(item => this.parseMetadata(item, false), this))));
  }

  //Show Tippy Tooltip
  show(cy, callback) {
    //Get tooltip object from class
    let tooltip = this.tooltip;

    //Hide all other tooltips
    this.hideAll(cy);

    //If no tooltip exists create one
    if (!tooltip) {
      let tooltipHTML = this.generateToolTip(callback);
      let refObject = this.cyElement.popperRef();
      tooltip = tippy(refObject, { html: tooltipHTML, theme: 'light', interactive: true });
      tooltip.selector.dim = refObject.dim;
      tooltip.selector.cyElement = refObject.cyElement;
      this.tooltip = tooltip;
    }

    //Show Tooltip
    tooltip.show(tooltip.store[0].popper);
    this.visible = true;
  }

  //Generate a database link
  generateDBLink(dbName, dbId) {
    //Get base url for dbid
    let link = this.db.filter(value => dbName.toUpperCase() === value[0].toUpperCase());
    if (!link || link.length !== 1) {
      link = this.db.filter(value => dbName.toUpperCase().indexOf(value[0].toUpperCase()) !== -1);
    }

    //Build reference url
    if (link.length === 1 && link[0][1]) {
      let url = link[0][1] + link[0][2] + dbId;
      return h('a.db-link', { href: url, target: '_blank' }, dbId);
    }
    else {
      return h('div.db-no-link', dbId);
    }
  }

  //Generate list of all given database id's
  //Requires a valid database Id Object
  generateIdList(dbIdObject, trim) {
    //get name and trim ID list to 5 items
    let name = dbIdObject.database;
    let list = dbIdObject.ids;

    //Format names
    let dbScan = this.db.filter(data => name.toUpperCase().indexOf(data[0].toUpperCase()) !== -1);
    if (dbScan.length > 0) { name = dbScan[0][0]; }

    if (trim) { list = dbIdObject.ids.slice(0, 5); }
    return h('li.db-item', h('div.db-name', name + ": "), list.map(data => this.generateDBLink(name, data), this));
  }

  //Sort Database ID's by database name
  //Requires a valid database ID array
  sortByDatabaseId(dbArray) {
    let databases = {};

    //Group Ids by database
    for (let i = 0; i < dbArray.length; i++) {
      let databaseName = dbArray[i][0];
      if (!databases[databaseName]) {
        databases[databaseName] = [];
      }
      databases[databaseName].push(dbArray[i][1]);
    }

    //Produce final array with group names as the keys
    dbArray = [];
    for (let databaseName in databases) {
      dbArray.push({ database: databaseName, ids: databases[databaseName] });
    }

    //Return result
    return dbArray;
  }

  //Generate a data source link based on database name
  //Requires a valid database name
  //Note : prefix is optional
  generateDataSourceLink(name, prefix = '') {
    let link = this.db.filter(value => name.toUpperCase().indexOf(value[0].toUpperCase()) !== -1);
    if (link.length === 1 && link[0][1]) {
      return h('div', h('div.field-name', prefix), h('a.plain-link', { href: link[0][1], target: '_blank' }, link[0][0]));
    }
    else if (link.length === 1) {
      return link[0][1];
    }
    else {
      return name;
    }
  }

  //Hide all tooltip objects
  hideAll(cy) {
    cy.elements().each(function (element) {
      var tempElement = element.scratch('tooltip');
      if (tempElement && tempElement.isVisible()) { tempElement.hide(); }
    });
  }

  //Hide Tippy tooltip
  hide() {
    if (this.tooltip) {
      this.tooltip.hide(this.tooltip.store[0].popper);
    }
    this.visible = false;
  }

  //Destroy Tippy tooltip
  destroy() {
    if (this.tooltip) {
      this.tooltip.destory(this.tooltip.store[0].popper);
      this.tooltip = null;
    }
  }

  //Get display status of tooltip
  isVisible() {
    return this.visible;
  }

  //Return a function that binds a tooltip to the sidebar more info view
  displayMore(callback) {
    //Get id from state
    let id = this.cyElement.id();
    return () => callback(id);
  }

  //Order a given metadata data array
  orderArray(data) {
    for (var x in data) {
      data[x][0] == "Database IDs" ? data.push(data.splice(x, 1)[0]) : 0;
    }
    return data;
  }

}

module.exports = MetadataTip;<commit_msg>Styled Other Fields<commit_after>const h = require('hyperscript');
const classNames = require('classnames');
const tippy = require('tippy.js');
const config = require('../../config');

//Manage the creation and display of metadata HTML content
//Requires a valid name, cytoscape element, and parsedMetadata array
class MetadataTip {

  constructor(name, data, cyElement) {
    this.name = name;
    this.data = data.parsedMetadata;
    this.cyElement = cyElement;
    this.db = config.databases;
  }

  //Generate HTML elements for Each Parsed Metadata Field
  //Optional trim parameter indicates if the data presented should be trimmed to a reasonable length
  parseMetadata(pair, trim = true) {
    let key = pair[0];

    //Get HTML for current data pair based on key value
    if (key === 'Standard Name') {
      return h('div.fake-paragraph', [h('div.field-name', 'Approved Name: '), h('div.tooltip-value', pair[1].toString())]);
    }
    else if (key === 'Data Source') {
      let source = pair[1].replace('http://pathwaycommons.org/pc2/', '');
      let link = this.generateDataSourceLink(source, 'Data Source: ');
      return h('div.fake-paragraph', link);
    }
    else if (key === 'Type' && !trim) {
      let type = pair[1].toString().substring(3);
      let formattedType = type.replace(/([A-Z])/g, ' $1').trim();
      return h('div.fake-paragraph', [h('div.field-name', key + ': '), formattedType]);
    }
    else if (key === 'Names') {
      //Trim results to first 3 names to avoid overflow
      let shortArray = pair[1];
      if (trim) { shortArray = pair[1].slice(0, 3); }

      //Filter out Chemical formulas
      if (shortArray instanceof Array) shortArray = shortArray.filter(name => (!name.trim().match(/^([^J][0-9BCOHNSOPrIFla@+\-\[\]\(\)\\=#$]{6,})$/ig)));
      return h('div.fake-paragraph', [h('div.field-name', 'Synonyms: '), h('div.tooltip-value', shortArray.toString())]);
    }
    else if (key === 'Database IDs') {
      //Sort the array by database names
      let sortedArray = this.sortByDatabaseId(pair[1]);
      if (sortedArray.length < 1) { return; }
      return h('div.fake-paragraph',
        [
          h('div.field-name', 'Database References:'),
          h('div.wrap-text', h('ul.db-list', sortedArray.map(item => this.generateIdList(item, trim), this)))
        ]);
    }
    else if (key === 'Comment' && !(trim)) {
      //Get comments
      let comments = pair[1];

      //Remove any strings with replaced
      if (comments instanceof Array) {
        comments = comments.filter(value => value.toUpperCase().indexOf('REPLACED') === -1);
      }
      else if (typeof comments === 'string' && comments.toUpperCase().indexOf('REPLACED') === -1) {
        comments = [comments];
      }
      else {
        comments = [];
      }

      //Generate HTML
      if (comments.length > 0) {
        return h('div.fake-paragraph', [
          h('div.field-name', 'Comments' + ': '),
          comments.map(item => h('div.comment', [
            h('div.tooltip-comment', item),
            h('br')]))
        ]);
      }

    }
    else if (!(trim)) {
      return h('div.fake-paragraph', [h('div.field-name', key + ': '), h('div.tooltip-value', pair[1].toString())]);
    }

    return;
  }

  //Validate the name of object and use Display Name as the fall back option
  validateName() {
    if (!(this.name)) {
      let displayName = this.data.filter(pair => pair[0] === 'Display Name');
      if (displayName.length > 0) { this.name = displayName[0][1].toString(); }
    }
  }

  //Generate HTML Elements for tooltips
  generateToolTip(callback) {

    //Order the data array
    let data = this.orderArray(this.data);
    if (!(data)) data = [];

    //Ensure name is not blank
    this.validateName();

    if (!(this.data)) { this.data = []; }
    return h('div.tooltip-image',
      h('div.tooltip-heading', this.name),
      h('div.tooltip-internal', h('div', (data).map(item => this.parseMetadata(item, true), this))),
      h('div.tooltip-buttons',
        [
          h('div.tooltip-button-container',
            [
              h('div.tooltip-button', { onclick: this.displayMore(callback) }, [
                h('i', { className: classNames('material-icons', 'tooltip-button-show') }, 'bubble_chart'),
                h('div.describe-button', 'Open in Sidebar')
              ])
            ])
        ])
    );
  }

  //Generate HTML Elements for the side bar
  generateSideBar() {
    //Order the data array
    let data = this.orderArray(this.data);
    if (!(data)) data = [];

    //Ensure name is not blank
    this.validateName();

    if (!(this.data)) { this.data = []; }
    return h('div.sidebar-body',
      h('h1', this.name),
      h('div.sidebar-internal', h('div', (data).map(item => this.parseMetadata(item, false), this))));
  }

  //Show Tippy Tooltip
  show(cy, callback) {
    //Get tooltip object from class
    let tooltip = this.tooltip;

    //Hide all other tooltips
    this.hideAll(cy);

    //If no tooltip exists create one
    if (!tooltip) {
      let tooltipHTML = this.generateToolTip(callback);
      let refObject = this.cyElement.popperRef();
      tooltip = tippy(refObject, { html: tooltipHTML, theme: 'light', interactive: true });
      tooltip.selector.dim = refObject.dim;
      tooltip.selector.cyElement = refObject.cyElement;
      this.tooltip = tooltip;
    }

    //Show Tooltip
    tooltip.show(tooltip.store[0].popper);
    this.visible = true;
  }

  //Generate a database link
  generateDBLink(dbName, dbId) {
    //Get base url for dbid
    let link = this.db.filter(value => dbName.toUpperCase() === value[0].toUpperCase());
    if (!link || link.length !== 1) {
      link = this.db.filter(value => dbName.toUpperCase().indexOf(value[0].toUpperCase()) !== -1);
    }

    //Build reference url
    if (link.length === 1 && link[0][1]) {
      let url = link[0][1] + link[0][2] + dbId;
      return h('a.db-link', { href: url, target: '_blank' }, dbId);
    }
    else {
      return h('div.db-no-link', dbId);
    }
  }

  //Generate list of all given database id's
  //Requires a valid database Id Object
  generateIdList(dbIdObject, trim) {
    //get name and trim ID list to 5 items
    let name = dbIdObject.database;
    let list = dbIdObject.ids;

    //Format names
    let dbScan = this.db.filter(data => name.toUpperCase().indexOf(data[0].toUpperCase()) !== -1);
    if (dbScan.length > 0) { name = dbScan[0][0]; }

    if (trim) { list = dbIdObject.ids.slice(0, 5); }
    return h('li.db-item', h('div.db-name', name + ": "), list.map(data => this.generateDBLink(name, data), this));
  }

  //Sort Database ID's by database name
  //Requires a valid database ID array
  sortByDatabaseId(dbArray) {
    let databases = {};

    //Group Ids by database
    for (let i = 0; i < dbArray.length; i++) {
      let databaseName = dbArray[i][0];
      if (!databases[databaseName]) {
        databases[databaseName] = [];
      }
      databases[databaseName].push(dbArray[i][1]);
    }

    //Produce final array with group names as the keys
    dbArray = [];
    for (let databaseName in databases) {
      dbArray.push({ database: databaseName, ids: databases[databaseName] });
    }

    //Return result
    return dbArray;
  }

  //Generate a data source link based on database name
  //Requires a valid database name
  //Note : prefix is optional
  generateDataSourceLink(name, prefix = '') {
    let link = this.db.filter(value => name.toUpperCase().indexOf(value[0].toUpperCase()) !== -1);
    if (link.length === 1 && link[0][1]) {
      return h('div', h('div.field-name', prefix), h('a.plain-link', { href: link[0][1], target: '_blank' }, link[0][0]));
    }
    else if (link.length === 1) {
      return link[0][1];
    }
    else {
      return name;
    }
  }

  //Hide all tooltip objects
  hideAll(cy) {
    cy.elements().each(function (element) {
      var tempElement = element.scratch('tooltip');
      if (tempElement && tempElement.isVisible()) { tempElement.hide(); }
    });
  }

  //Hide Tippy tooltip
  hide() {
    if (this.tooltip) {
      this.tooltip.hide(this.tooltip.store[0].popper);
    }
    this.visible = false;
  }

  //Destroy Tippy tooltip
  destroy() {
    if (this.tooltip) {
      this.tooltip.destory(this.tooltip.store[0].popper);
      this.tooltip = null;
    }
  }

  //Get display status of tooltip
  isVisible() {
    return this.visible;
  }

  //Return a function that binds a tooltip to the sidebar more info view
  displayMore(callback) {
    //Get id from state
    let id = this.cyElement.id();
    return () => callback(id);
  }

  //Order a given metadata data array
  orderArray(data) {
    for (var x in data) {
      data[x][0] == "Database IDs" ? data.push(data.splice(x, 1)[0]) : 0;
    }
    return data;
  }

}

module.exports = MetadataTip;<|endoftext|>