<commit_before>var gulp        = require('gulp'),
    concat      = require('gulp-concat'),
    browserSync = require('browser-sync'),
    plumber     = require('gulp-plumber'),
    cp          = require('child_process');

    // stylus
    stylus      = require('gulp-stylus'),
	rupture     = require('rupture'),
	prefixer    = require('autoprefixer-stylus'),
    nib         = require('nib'),

    // images
    imagemin    = require('gulp-imagemin');

var messages = {
	jekyllBuild: 'Running: $ jekyll build'
};

gulp.task('jekyll-build', function (done) {
    browserSync.notify(messages.jekyllBuild);
    return cp.spawn('bundle', ['exec', 'jekyll', 'build', '--drafts'], {stdio: 'inherit'}).on('close', done);
    // return cp.spawn('bundle', ['exec', 'jekyll', 'build'], {stdio: 'inherit'}).on('close', done);
});

gulp.task('jekyll-rebuild', ['jekyll-build'], function () {
    browserSync.reload();
});

gulp.task('browserSync', ['jekyll-build'], function() {
    browserSync({
        server: { baseDir: "_site/" },
        open: false
    });
});

gulp.task('styles', function() {
    return gulp.src('src/styles/main.styl')
        .pipe(plumber())
        .pipe(stylus({
            use:[prefixer(), rupture(), nib()],
			compress: false
        }))
        .pipe(gulp.dest('_site/assets/styles'))
        .pipe(gulp.dest('_includes'))
        .pipe(browserSync.reload({stream: true}))
        .pipe(gulp.dest('assets/styles'));
});

gulp.task('imagemin', function(tmp) {
    return gulp.src('assets/images/**/*.{jpg,png,gif}')
        .pipe(plumber())
        .pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
        .pipe(gulp.dest('assets/images'));
});

gulp.task('watch', function() {
    gulp.watch('src/styles/**/*', ['styles']);
    gulp.watch('src/images/**/*.{jpg,png,gif}', ['imagemin']);
    gulp.watch(['_drafts/*','_includes/*','_layouts/*','_posts/*','*.{html,md}'], ['jekyll-rebuild']);
});

gulp.task('default', ['styles', 'imagemin', 'browserSync', 'watch']);
<commit_msg>watch for _config<commit_after>var gulp        = require('gulp'),
    concat      = require('gulp-concat'),
    browserSync = require('browser-sync'),
    plumber     = require('gulp-plumber'),
    cp          = require('child_process');

    // stylus
    stylus      = require('gulp-stylus'),
	rupture     = require('rupture'),
	prefixer    = require('autoprefixer-stylus'),
    nib         = require('nib'),

    // images
    imagemin    = require('gulp-imagemin');

var messages = {
	jekyllBuild: 'Running: $ jekyll build'
};

gulp.task('jekyll-build', function (done) {
    browserSync.notify(messages.jekyllBuild);
    return cp.spawn('bundle', ['exec', 'jekyll', 'build', '--drafts'], {stdio: 'inherit'}).on('close', done);
    // return cp.spawn('bundle', ['exec', 'jekyll', 'build'], {stdio: 'inherit'}).on('close', done);
});

gulp.task('jekyll-rebuild', ['jekyll-build'], function () {
    browserSync.reload();
});

gulp.task('browserSync', ['jekyll-build'], function() {
    browserSync({
        server: { baseDir: "_site/" },
        open: false
    });
});

gulp.task('styles', function() {
    return gulp.src('src/styles/main.styl')
        .pipe(plumber())
        .pipe(stylus({
            use:[prefixer(), rupture(), nib()],
			compress: false
        }))
        .pipe(gulp.dest('_site/assets/styles'))
        .pipe(gulp.dest('_includes'))
        .pipe(browserSync.reload({stream: true}))
        .pipe(gulp.dest('assets/styles'));
});

gulp.task('imagemin', function(tmp) {
    return gulp.src('assets/images/**/*.{jpg,png,gif}')
        .pipe(plumber())
        .pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))
        .pipe(gulp.dest('assets/images'));
});

gulp.task('watch', function() {
    gulp.watch('src/styles/**/*', ['styles']);
    gulp.watch('src/images/**/*.{jpg,png,gif}', ['imagemin']);
    gulp.watch(['_drafts/*', '_includes/*', '_layouts/*', '_posts/*', '*.{html,md}', '_config.yml'], ['jekyll-rebuild']);
});

gulp.task('default', ['styles', 'imagemin', 'browserSync', 'watch']);
<|endoftext|>


<commit_before>var theProject;
var ui = {};

var Refine = {
    refineHelperService: "http://6.gridworks-helper.dfhuynh.user.dev.freebaseapps.com"
};

Refine.reportException = function(e) {
    if (window.console) {
        console.log(e);
    }
};

function resize() {
    var header = $("#header");

    ui.menuBarContainer.css("top", header.outerHeight() + "px");

    var leftPanelWidth = 300;
    var leftPanelMargin = 7;
    var width = $(window).width();
    var top = ui.menuBarContainer.offset().top + ui.menuBarContainer.outerHeight();
    var height = $(window).height() - top;

    ui.viewPanel
        .css("top", top + "px")
        .css("left", leftPanelWidth + "px")
        .css("height", height + "px")
        .css("width", (width - leftPanelWidth) + "px");

    ui.leftPanel
        .css("top", (top + leftPanelMargin) + "px")
        .css("left", leftPanelMargin + "px")
        .css("height", (height - 2 * leftPanelMargin) + "px")
        .css("width", (leftPanelWidth - 2 * leftPanelMargin) + "px");

    var leftPanelTabsPaddings = ui.leftPanelTabs.outerHeight(true) - ui.leftPanelTabs.innerHeight();
    ui.leftPanelTabs
        .height(ui.leftPanel.height() - leftPanelTabsPaddings);

    var processPanelWidth = 400;
    ui.processPanel
        .css("width", processPanelWidth + "px")
        .css("left", Math.floor((width - processPanelWidth) / 2) + "px");
}

function resizeTabs() {
    var totalHeight = ui.leftPanel.height();
    var headerHeight = ui.leftPanelTabs.find(".ui-tabs-nav").outerHeight(true);

    var visibleTabPanels = ui.leftPanelTabs.find(".ui-tabs-panel:not(.ui-tabs-hide)");
    var paddings = visibleTabPanels.innerHeight(true) - visibleTabPanels.height();

    var allTabPanels = ui.leftPanelTabs.find(".ui-tabs-panel");
    allTabPanels.height(totalHeight - headerHeight - paddings - 1);
}

function resizeAll() {
    resize();
    resizeTabs();

    ui.menuBar.resize();
    ui.browsingEngine.resize();
    ui.processWidget.resize();
    ui.historyWidget.resize();
    ui.dataTableView.resize();
}

function initializeUI(uiState) {
    var path = $("#path");
    $('').appendTo(path);
    $('permalink')
        .mouseenter(function() {
            this.href = Refine.getPermanentLink();
        }).appendTo(path);

    Refine.setTitle();

    var body = $("#body").empty().html(
        '

' +
        '

' +
        '
' +
            '
' +
                '
' +
                    '
Facet/Filter
' +
                    '
Undo/Redo
' +
                '
' +
                '

' +
                '

' +
            '
' +
        '
' +
        '

'
    );
    ui = DOM.bind(body);

    ui.menuBarContainer.css("top", $("#header").outerHeight() + "px");
    ui.menuBar = new MenuBar(ui.menuBarPanel); // construct the menu first so we can resize everything else

    ui.leftPanelTabs.tabs({ selected: 0 });
    resize();
    resizeTabs();

    ui.browsingEngine = new BrowsingEngine(ui.facetPanel, uiState.facets || []);
    ui.processWidget = new ProcessWidget(ui.processPanel);
    ui.historyWidget = new HistoryWidget(ui.historyPanel, ui.historyTabHeader);
    ui.dataTableView = new DataTableView(ui.viewPanel);

    ui.leftPanelTabs.bind('tabsshow', function(event, tabs) {
        if (tabs.index === 0) {
            ui.browsingEngine.resize();
        } else if (tabs.index === 1) {
            ui.historyWidget.resize();
        }
    });

    $(window).bind("resize", resizeAll);

    if (uiState.facets) {
        Refine.update({ engineChanged: true });
    }
}

Refine.setTitle = function(status) {
    var title = theProject.metadata.name + " - Google Refine";
    if (status) {
        title = status + " - " + title;
    }
    document.title = title;

    var name = $("#project-name-in-path");
    name.empty();
    name.text('project: ');
    $('' + theProject.metadata.name + '').appendTo(name);
};

Refine.reinitializeProjectData = function(f) {
    Ajax.chainGetJSON(
        "/command/core/get-project-metadata?" + $.param({ project: theProject.id }), null,
        function(data) {
            theProject.metadata = data;
        },
        "/command/core/get-models?" + $.param({ project: theProject.id }), null,
        function(data) {
            for (var n in data) {
                if (data.hasOwnProperty(n)) {
                    theProject[n] = data[n];
                }
            }
        },
        f
    );
};

/*
 *  Utility state functions
 */

Refine.createUpdateFunction = function(options, onFinallyDone) {
    var functions = [];
    var pushFunction = function(f) {
        var index = functions.length;
        functions.push(function() {
            f(functions[index + 1]);
        });
    };

    pushFunction(function(onDone) {
        ui.historyWidget.update(onDone);
    });
    if (options.everythingChanged || options.modelsChanged || options.columnStatsChanged) {
        pushFunction(Refine.reinitializeProjectData);
    }
    if (options.everythingChanged || options.modelsChanged || options.rowsChanged || options.rowMetadataChanged || options.cellsChanged || options.engineChanged) {
        pushFunction(function(onDone) {
            ui.dataTableView.update(onDone);
        });
        pushFunction(function(onDone) {
            ui.browsingEngine.update(onDone);
        });
    }

    functions.push(onFinallyDone || function() {});

    return functions[0];
};

Refine.update = function(options, onFinallyDone) {
    var done = false;
    var dismissBusy = null;

    Refine.setAjaxInProgress();

    Refine.createUpdateFunction(options, function() {
        Refine.clearAjaxInProgress();

        done = true;
        if (dismissBusy) {
            dismissBusy();
        }
        if (onFinallyDone) {
            onFinallyDone();
        }
    })();

    window.setTimeout(function() {
        if (!done) {
            dismissBusy = DialogSystem.showBusy();
        }
    }, 500);
};

Refine.postCoreProcess = function(command, params, body, updateOptions, callbacks) {
    Refine.postProcess("core", command, params, body, updateOptions, callbacks);
};

Refine.postProcess = function(moduleName, command, params, body, updateOptions, callbacks) {
    updateOptions = updateOptions || {};
    callbacks = callbacks || {};

    params = params || {};
    params.project = theProject.id;

    body = body || {};
    if (!("includeEngine" in updateOptions) || updateOptions.includeEngine) {
        body.engine = JSON.stringify(
            "engineConfig" in updateOptions ?
                updateOptions.engineConfig :
                ui.browsingEngine.getJSON()
        );
    }

    var done = false;
    var dismissBusy = null;

    function onDone(o) {
        done = true;
        if (dismissBusy) {
            dismissBusy();
        }

        Refine.clearAjaxInProgress();

        if (o.code == "error") {
            if ("onError" in callbacks) {
                try {
                    callbacks.onError(o);
                } catch (e) {
                    Refine.reportException(e);
                }
            } else {
                alert(o.message);
            }
        } else {
            if ("onDone" in callbacks) {
                try {
                    callbacks.onDone(o);
                } catch (e) {
                    Refine.reportException(e);
                }
            }

            if (o.code == "ok") {
                Refine.update(updateOptions, callbacks.onFinallyDone);

                if ("historyEntry" in o) {
                    ui.processWidget.showUndo(o.historyEntry);
                }
            } else if (o.code == "pending") {
                if ("onPending" in callbacks) {
                    try {
                        callbacks.onPending(o);
                    } catch (e) {
                        Refine.reportException(e);
                    }
                }
                ui.processWidget.update(updateOptions, callbacks.onFinallyDone);
            }
        }
    }

    Refine.setAjaxInProgress();

    $.post(
        "/command/" + moduleName + "/" + command + "?" + $.param(params),
        body,
        onDone,
        "json"
    );

    window.setTimeout(function() {
        if (!done) {
            dismissBusy = DialogSystem.showBusy();
        }
    }, 500);
};

Refine.setAjaxInProgress = function() {
    $(document.body).attr("ajax_in_progress", "true");
};

Refine.clearAjaxInProgress = function() {
    $(document.body).attr("ajax_in_progress", "false");
};

/*
 *  Utility model functions
 */

Refine.cellIndexToColumn = function(cellIndex) {
    var columns = theProject.columnModel.columns;
    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (column.cellIndex == cellIndex) {
            return column;
        }
    }
    return null;
};
Refine.columnNameToColumn = function(columnName) {
    var columns = theProject.columnModel.columns;
    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (column.name == columnName) {
            return column;
        }
    }
    return null;
};
Refine.columnNameToColumnIndex = function(columnName) {
    var columns = theProject.columnModel.columns;
    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (column.name == columnName) {
            return i;
        }
    }
    return -1;
};

Refine.preparePool = function(pool) {
    for (var id in pool.recons) {
        if (pool.recons.hasOwnProperty(id)) {
            var recon = pool.recons[id];
            if (recon.m) {
                recon.m = pool.reconCandidates[recon.m];
            }
            if (recon.c) {
                for (var j = 0; j < recon.c.length; j++) {
                    recon.c[j] = pool.reconCandidates[recon.c[j]];
                }
            }
        }
    }
};

Refine.fetchRows = function(start, limit, onDone, sorting) {
    var body = {
        engine: JSON.stringify(ui.browsingEngine.getJSON())
    };
    if (sorting) {
        body.sorting = JSON.stringify(sorting)
    }

    $.post(
        "/command/core/get-rows?" + $.param({ project: theProject.id, start: start, limit: limit }) + "&callback=?",
        body,
        function(data) {
            theProject.rowModel = data;

            // Un-pool objects
            Refine.preparePool(data.pool);
            for (var r = 0; r < data.rows.length; r++) {
                var row = data.rows[r];
                for (var c = 0; c < row.cells.length; c++) {
                    var cell = row.cells[c];
                    if ((cell) && ("r" in cell)) {
                        cell.r = data.pool.recons[cell.r];
                    }
                }
            }

            if (onDone) {
                onDone();
            }
        },
        "jsonp"
    );
};

Refine.getPermanentLink = function() {
    var params = [
        "project=" + escape(theProject.id),
        "ui=" + escape(JSON.stringify({
            facets: ui.browsingEngine.getFacetUIStates()
        }))
    ];
    return "project?" + params.join("&");
};

/*
 * Loader
 */

function onLoad() {
    var params = URL.getParameters();
    if ("project" in params) {
        var uiState = {};
        if ("ui" in params) {
            try {
                uiState = JSON.parse(params.ui);
            } catch (e) {
            }
        }

        Refine.reinitializeProjectData(function() {
            initializeUI(uiState);
        });
    }
}

$(onLoad);
<commit_msg>and with this, the 'gridworks->refine' renaming is done. yay!<commit_after>var theProject;
var ui = {};

var Refine = {
    refineHelperService: "http://1.refine-helper.stefanomazzocchi.user.dev.freebaseapps.com/"
};

Refine.reportException = function(e) {
    if (window.console) {
        console.log(e);
    }
};

function resize() {
    var header = $("#header");

    ui.menuBarContainer.css("top", header.outerHeight() + "px");

    var leftPanelWidth = 300;
    var leftPanelMargin = 7;
    var width = $(window).width();
    var top = ui.menuBarContainer.offset().top + ui.menuBarContainer.outerHeight();
    var height = $(window).height() - top;

    ui.viewPanel
        .css("top", top + "px")
        .css("left", leftPanelWidth + "px")
        .css("height", height + "px")
        .css("width", (width - leftPanelWidth) + "px");

    ui.leftPanel
        .css("top", (top + leftPanelMargin) + "px")
        .css("left", leftPanelMargin + "px")
        .css("height", (height - 2 * leftPanelMargin) + "px")
        .css("width", (leftPanelWidth - 2 * leftPanelMargin) + "px");

    var leftPanelTabsPaddings = ui.leftPanelTabs.outerHeight(true) - ui.leftPanelTabs.innerHeight();
    ui.leftPanelTabs
        .height(ui.leftPanel.height() - leftPanelTabsPaddings);

    var processPanelWidth = 400;
    ui.processPanel
        .css("width", processPanelWidth + "px")
        .css("left", Math.floor((width - processPanelWidth) / 2) + "px");
}

function resizeTabs() {
    var totalHeight = ui.leftPanel.height();
    var headerHeight = ui.leftPanelTabs.find(".ui-tabs-nav").outerHeight(true);

    var visibleTabPanels = ui.leftPanelTabs.find(".ui-tabs-panel:not(.ui-tabs-hide)");
    var paddings = visibleTabPanels.innerHeight(true) - visibleTabPanels.height();

    var allTabPanels = ui.leftPanelTabs.find(".ui-tabs-panel");
    allTabPanels.height(totalHeight - headerHeight - paddings - 1);
}

function resizeAll() {
    resize();
    resizeTabs();

    ui.menuBar.resize();
    ui.browsingEngine.resize();
    ui.processWidget.resize();
    ui.historyWidget.resize();
    ui.dataTableView.resize();
}

function initializeUI(uiState) {
    var path = $("#path");
    $('').appendTo(path);
    $('permalink')
        .mouseenter(function() {
            this.href = Refine.getPermanentLink();
        }).appendTo(path);

    Refine.setTitle();

    var body = $("#body").empty().html(
        '

' +
        '

' +
        '
' +
            '
' +
                '
' +
                    '
Facet/Filter
' +
                    '
Undo/Redo
' +
                '
' +
                '

' +
                '

' +
            '
' +
        '
' +
        '

'
    );
    ui = DOM.bind(body);

    ui.menuBarContainer.css("top", $("#header").outerHeight() + "px");
    ui.menuBar = new MenuBar(ui.menuBarPanel); // construct the menu first so we can resize everything else

    ui.leftPanelTabs.tabs({ selected: 0 });
    resize();
    resizeTabs();

    ui.browsingEngine = new BrowsingEngine(ui.facetPanel, uiState.facets || []);
    ui.processWidget = new ProcessWidget(ui.processPanel);
    ui.historyWidget = new HistoryWidget(ui.historyPanel, ui.historyTabHeader);
    ui.dataTableView = new DataTableView(ui.viewPanel);

    ui.leftPanelTabs.bind('tabsshow', function(event, tabs) {
        if (tabs.index === 0) {
            ui.browsingEngine.resize();
        } else if (tabs.index === 1) {
            ui.historyWidget.resize();
        }
    });

    $(window).bind("resize", resizeAll);

    if (uiState.facets) {
        Refine.update({ engineChanged: true });
    }
}

Refine.setTitle = function(status) {
    var title = theProject.metadata.name + " - Google Refine";
    if (status) {
        title = status + " - " + title;
    }
    document.title = title;

    var name = $("#project-name-in-path");
    name.empty();
    name.text('project: ');
    $('' + theProject.metadata.name + '').appendTo(name);
};

Refine.reinitializeProjectData = function(f) {
    Ajax.chainGetJSON(
        "/command/core/get-project-metadata?" + $.param({ project: theProject.id }), null,
        function(data) {
            theProject.metadata = data;
        },
        "/command/core/get-models?" + $.param({ project: theProject.id }), null,
        function(data) {
            for (var n in data) {
                if (data.hasOwnProperty(n)) {
                    theProject[n] = data[n];
                }
            }
        },
        f
    );
};

/*
 *  Utility state functions
 */

Refine.createUpdateFunction = function(options, onFinallyDone) {
    var functions = [];
    var pushFunction = function(f) {
        var index = functions.length;
        functions.push(function() {
            f(functions[index + 1]);
        });
    };

    pushFunction(function(onDone) {
        ui.historyWidget.update(onDone);
    });
    if (options.everythingChanged || options.modelsChanged || options.columnStatsChanged) {
        pushFunction(Refine.reinitializeProjectData);
    }
    if (options.everythingChanged || options.modelsChanged || options.rowsChanged || options.rowMetadataChanged || options.cellsChanged || options.engineChanged) {
        pushFunction(function(onDone) {
            ui.dataTableView.update(onDone);
        });
        pushFunction(function(onDone) {
            ui.browsingEngine.update(onDone);
        });
    }

    functions.push(onFinallyDone || function() {});

    return functions[0];
};

Refine.update = function(options, onFinallyDone) {
    var done = false;
    var dismissBusy = null;

    Refine.setAjaxInProgress();

    Refine.createUpdateFunction(options, function() {
        Refine.clearAjaxInProgress();

        done = true;
        if (dismissBusy) {
            dismissBusy();
        }
        if (onFinallyDone) {
            onFinallyDone();
        }
    })();

    window.setTimeout(function() {
        if (!done) {
            dismissBusy = DialogSystem.showBusy();
        }
    }, 500);
};

Refine.postCoreProcess = function(command, params, body, updateOptions, callbacks) {
    Refine.postProcess("core", command, params, body, updateOptions, callbacks);
};

Refine.postProcess = function(moduleName, command, params, body, updateOptions, callbacks) {
    updateOptions = updateOptions || {};
    callbacks = callbacks || {};

    params = params || {};
    params.project = theProject.id;

    body = body || {};
    if (!("includeEngine" in updateOptions) || updateOptions.includeEngine) {
        body.engine = JSON.stringify(
            "engineConfig" in updateOptions ?
                updateOptions.engineConfig :
                ui.browsingEngine.getJSON()
        );
    }

    var done = false;
    var dismissBusy = null;

    function onDone(o) {
        done = true;
        if (dismissBusy) {
            dismissBusy();
        }

        Refine.clearAjaxInProgress();

        if (o.code == "error") {
            if ("onError" in callbacks) {
                try {
                    callbacks.onError(o);
                } catch (e) {
                    Refine.reportException(e);
                }
            } else {
                alert(o.message);
            }
        } else {
            if ("onDone" in callbacks) {
                try {
                    callbacks.onDone(o);
                } catch (e) {
                    Refine.reportException(e);
                }
            }

            if (o.code == "ok") {
                Refine.update(updateOptions, callbacks.onFinallyDone);

                if ("historyEntry" in o) {
                    ui.processWidget.showUndo(o.historyEntry);
                }
            } else if (o.code == "pending") {
                if ("onPending" in callbacks) {
                    try {
                        callbacks.onPending(o);
                    } catch (e) {
                        Refine.reportException(e);
                    }
                }
                ui.processWidget.update(updateOptions, callbacks.onFinallyDone);
            }
        }
    }

    Refine.setAjaxInProgress();

    $.post(
        "/command/" + moduleName + "/" + command + "?" + $.param(params),
        body,
        onDone,
        "json"
    );

    window.setTimeout(function() {
        if (!done) {
            dismissBusy = DialogSystem.showBusy();
        }
    }, 500);
};

Refine.setAjaxInProgress = function() {
    $(document.body).attr("ajax_in_progress", "true");
};

Refine.clearAjaxInProgress = function() {
    $(document.body).attr("ajax_in_progress", "false");
};

/*
 *  Utility model functions
 */

Refine.cellIndexToColumn = function(cellIndex) {
    var columns = theProject.columnModel.columns;
    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (column.cellIndex == cellIndex) {
            return column;
        }
    }
    return null;
};
Refine.columnNameToColumn = function(columnName) {
    var columns = theProject.columnModel.columns;
    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (column.name == columnName) {
            return column;
        }
    }
    return null;
};
Refine.columnNameToColumnIndex = function(columnName) {
    var columns = theProject.columnModel.columns;
    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (column.name == columnName) {
            return i;
        }
    }
    return -1;
};

Refine.preparePool = function(pool) {
    for (var id in pool.recons) {
        if (pool.recons.hasOwnProperty(id)) {
            var recon = pool.recons[id];
            if (recon.m) {
                recon.m = pool.reconCandidates[recon.m];
            }
            if (recon.c) {
                for (var j = 0; j < recon.c.length; j++) {
                    recon.c[j] = pool.reconCandidates[recon.c[j]];
                }
            }
        }
    }
};

Refine.fetchRows = function(start, limit, onDone, sorting) {
    var body = {
        engine: JSON.stringify(ui.browsingEngine.getJSON())
    };
    if (sorting) {
        body.sorting = JSON.stringify(sorting)
    }

    $.post(
        "/command/core/get-rows?" + $.param({ project: theProject.id, start: start, limit: limit }) + "&callback=?",
        body,
        function(data) {
            theProject.rowModel = data;

            // Un-pool objects
            Refine.preparePool(data.pool);
            for (var r = 0; r < data.rows.length; r++) {
                var row = data.rows[r];
                for (var c = 0; c < row.cells.length; c++) {
                    var cell = row.cells[c];
                    if ((cell) && ("r" in cell)) {
                        cell.r = data.pool.recons[cell.r];
                    }
                }
            }

            if (onDone) {
                onDone();
            }
        },
        "jsonp"
    );
};

Refine.getPermanentLink = function() {
    var params = [
        "project=" + escape(theProject.id),
        "ui=" + escape(JSON.stringify({
            facets: ui.browsingEngine.getFacetUIStates()
        }))
    ];
    return "project?" + params.join("&");
};

/*
 * Loader
 */

function onLoad() {
    var params = URL.getParameters();
    if ("project" in params) {
        var uiState = {};
        if ("ui" in params) {
            try {
                uiState = JSON.parse(params.ui);
            } catch (e) {
            }
        }

        Refine.reinitializeProjectData(function() {
            initializeUI(uiState);
        });
    }
}

$(onLoad);
<|endoftext|>


<commit_before>'use strict';

/**
 * @module dhsniem
 *
 * @description
 * Main module of the application.
 */
angular
  .module('dhsniem', [
    'ui.router',
    'ui.bootstrap',
    'ngAria'
  ])
  .config(function ($urlRouterProvider) {
    $urlRouterProvider.when('', '/'); // redirect to root if the state is ''
    $urlRouterProvider.otherwise('/'); // redirect to root if state is not found
  })

  .run(function ($rootScope, $window, $location) {
    $window.ga('create', 'UA-27432921-1', 'auto');
    $rootScope.$on('$stateChangeSuccess', function () {
      $window.scroll(0, 0);
      $window.ga('send', 'pageview', $location.url());
    });
  });

<commit_msg>added new ga code for new domain name<commit_after>'use strict';

/**
 * @module dhsniem
 *
 * @description
 * Main module of the application.
 */
angular
  .module('dhsniem', [
    'ui.router',
    'ui.bootstrap',
    'ngAria'
  ])
  .config(function ($urlRouterProvider) {
    $urlRouterProvider.when('', '/'); // redirect to root if the state is ''
    $urlRouterProvider.otherwise('/'); // redirect to root if state is not found
  })

  .run(function ($rootScope, $window, $location) {
    $window.ga('create', 'UA-96555344-1', 'auto');
    $rootScope.$on('$stateChangeSuccess', function () {
      $window.scroll(0, 0);
      $window.ga('send', 'pageview', $location.url());
    });
  });

<|endoftext|>


<commit_before>/**
 * Created by Mihail on 9/14/2016.
 */
var express = require('express');
var router = express.Router();
var jwt = require('express-jwt');
require('dotenv').config();

var auth = jwt({
	secret:  process.env.DB_SECRET,
	userProperty: 'payload'
});

// Back office app
var ctrlBackOffice = require('../controllers/back-office');
var ctrlAdminsAuth = require('../controllers/admins-auth');
router.get('/getPlayersData', auth, ctrlBackOffice.getPlayersData);
router.post('/createPlayer', auth, ctrlBackOffice.createPlayer);
router.post('/deletePlayer', auth, ctrlBackOffice.deletePlayer);
router.post('/updatePlayerData', auth, ctrlBackOffice.updatePlayerData);
router.post('/loginAdmin', ctrlAdminsAuth.loginAdmin);
// Disabled for security reasons - for the moment the admins will be added only manually
// router.post('/registerAdmin', ctrlAdminsAuth.register);

// Main app
var ctrlProfile = require('../controllers/profile');
var ctrlAuth = require('../controllers/users-auth');
router.post('/setNewBalance', auth, ctrlProfile.setNewBalance);
router.get('/profile', auth, ctrlProfile.profileRead);
router.post('/register', ctrlAuth.register);
router.post('/login', ctrlAuth.login);
router.post('/setWins', auth, ctrlProfile.setWins);

module.exports = router;<commit_msg>:hammer: Cleanup.<commit_after>const express = require('express');
const router = express.Router();
const jwt = require('express-jwt');
require('dotenv').config();

const auth = jwt({
	secret: process.env.DB_SECRET,
	userProperty: 'payload'
});

// Back office app
const ctrlBackOffice = require('../controllers/back-office');
const ctrlAdminsAuth = require('../controllers/admins-auth');
router.get('/getPlayersData', auth, ctrlBackOffice.getPlayersData);
router.post('/createPlayer', auth, ctrlBackOffice.createPlayer);
router.post('/deletePlayer', auth, ctrlBackOffice.deletePlayer);
router.post('/updatePlayerData', auth, ctrlBackOffice.updatePlayerData);
router.post('/loginAdmin', ctrlAdminsAuth.loginAdmin);
// Disabled for security reasons - for the moment the admins will be added only manually
// router.post('/registerAdmin', ctrlAdminsAuth.register);

// Main app
const ctrlProfile = require('../controllers/profile');
const ctrlAuth = require('../controllers/users-auth');
router.post('/setNewBalance', auth, ctrlProfile.setNewBalance);
router.get('/profile', auth, ctrlProfile.profileRead);
router.post('/register', ctrlAuth.register);
router.post('/login', ctrlAuth.login);
router.post('/setWins', auth, ctrlProfile.setWins);

module.exports = router;
<|endoftext|>


<commit_before>window.JSFile = window.JSFile || {};

(function(module) {
    'use strict';

    /**
     * FileDownloader Class
     *
     * @constructor
     */
    var FileDownloader = function() {

        var self = this;
        var message_prefix = "FileDownloader: ";

        this.MESSAGE_WORKBOOK_IS_REQUIRED       = message_prefix + "workbook param is required for FileDownloader.downloadWorkbook";
        this.MESSAGE_WORKBOOK_MODEL_IS_INVALID  = message_prefix + "workbook param must be an instance of JSFile.Workbook";
        this.MESSAGE_FILE_NAME_IS_REQUIRED      = message_prefix + "file_name is required";
        this.CURRENTLY_UNSUPPORTED_FILE_TYPE    = message_prefix + "this file type is currently not supported.";
        this.UNSUPPORTED_BROWSER_FEATURE_AND_NO_FALLBACK = message_prefix + "browser does support the required feature and no fallback method was provided";

        ///////////////////////////////////////////////////////////
        //
        // public methods
        //
        ///////////////////////////////////////////////////////////

        /**
         * downloadWorkbook
         *
         * @param workbook
         * @param filename
         * @param file_extension
         */
        this.downloadWorkbook = function(workbook, filename, file_extension) {

            // validate args
            if (_.isUndefined(workbook) || _.isNull(workbook)) {
                throw new Error(this.MESSAGE_WORKBOOK_IS_REQUIRED);
            }
            if (!(workbook instanceof module.Workbook)) {
                throw new Error(this.MESSAGE_WORKBOOK_MODEL_IS_INVALID);
            }
            if (_.isUndefined(filename) || _.isNull(filename) || filename === "") {
                throw new Error(this.MESSAGE_FILE_NAME_IS_REQUIRED);
            }

            // transform file data (name & extension)
            var file_data = module.FileUtil.transformFilenameAndExtension(filename, file_extension);

            // create file array buffer
            var file_array_buffer = this.create_file_handlers[file_data.file_extension](workbook, file_data.file_extension);

            // get file mime_type
            var file_mimetype = module.FileUtil.getFileMimeType(file_data.file_extension);

            // initiate download
            initiateFileDownload(file_array_buffer, file_data.filename, file_mimetype);
        };

        ///////////////////////////////////////////////////////////
        //
        // private methods
        //
        ///////////////////////////////////////////////////////////

        /**
         * convertStringToArrayBuffer
         *
         * @param str
         * @returns {ArrayBuffer}
         */
        var convertStringToArrayBuffer = function(str) {
            var array_buffer = new ArrayBuffer(str.length);
            var view = new Uint8Array(array_buffer);
            for (var i = 0; i !== str.length; ++i) {
                view[i] = str.charCodeAt(i) & 0xFF;
            }
            return array_buffer;
        };

        /**
         * createXlsxFile
         *
         * @param workbook
         * @param file_extension
         */
        var createXlsxFile = function(workbook, file_extension) {
            var workbook_output = XLSX.write(workbook, {bookType: file_extension, bookSST: false, type: 'binary'});
            return convertStringToArrayBuffer(workbook_output);
        };

        /**
         * createOdsFile
         *
         * @param workbook
         * @param file_extension
         */
        var createOdsFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * createXlsFile
         *
         * @param workbook
         * @param file_extension
         */
        var createXlsFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * createTxtFile
         *
         * @param workbook
         * @param file_extension
         */
        var createTxtFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * createCsvFile
         *
         * @param workbook
         * @param file_extension
         */
        var createCsvFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * initiateFileDownload
         *
         * @param array_buffer
         * @param filename
         * @param file_mimetype
         */
        var initiateFileDownload = function(file_array_buffer, filename, file_mimetype) {
            var blob = null;

            // Blob is natively supported by all but ie8 & ie9
            // Blob.js creates a shim for ie8 & ie9
            // TODO: add seperate handling for text & csv

            // if browser is IE10+
            if (window.navigator.msSaveBlob) {

                // create ie10 Blob
                blob = new Blob(["\ufeff", file_array_buffer], {type: file_mimetype});

                // initiate ie10 download
                return window.navigator.msSaveBlob(blob, filename);
            }

            // create Blob
            blob = new Blob([file_array_buffer], {type: file_mimetype});

            // adownload is not supported by browser (ie8, ie9, Safari)
            if (!Modernizr.adownload) {

                // no initiateFileDownloadFallback method is defined
                if (_.isUndefined(self.initiateFileDownloadFallback)) {
                    throw new Error(self.UNSUPPORTED_BROWSER_FEATURE_AND_NO_FALLBACK);
                }

                // call initiate download fallback
                return self.initiateFileDownloadFallback(blob, filename);
            }

            // initiate download
            return window.saveAs(blob, filename);
        };

        ///////////////////////////////////////////////////////////
        //
        // init
        //
        ///////////////////////////////////////////////////////////

        // handlers mapped by file type

        this.create_file_handlers = {
            xlsx:   createXlsxFile,
            ods:    createOdsFile,
            xls:    createXlsFile,
            txt:    createTxtFile,
            csv:    createCsvFile
        };
    };

    module.FileDownloader = new FileDownloader();

})(window.JSFile);
<commit_msg>Fixing IE10+ download<commit_after>window.JSFile = window.JSFile || {};

(function(module) {
    'use strict';

    /**
     * FileDownloader Class
     *
     * @constructor
     */
    var FileDownloader = function() {

        var self = this;
        var message_prefix = "FileDownloader: ";

        this.MESSAGE_WORKBOOK_IS_REQUIRED       = message_prefix + "workbook param is required for FileDownloader.downloadWorkbook";
        this.MESSAGE_WORKBOOK_MODEL_IS_INVALID  = message_prefix + "workbook param must be an instance of JSFile.Workbook";
        this.MESSAGE_FILE_NAME_IS_REQUIRED      = message_prefix + "file_name is required";
        this.CURRENTLY_UNSUPPORTED_FILE_TYPE    = message_prefix + "this file type is currently not supported.";
        this.UNSUPPORTED_BROWSER_FEATURE_AND_NO_FALLBACK = message_prefix + "browser does support the required feature and no fallback method was provided";

        ///////////////////////////////////////////////////////////
        //
        // public methods
        //
        ///////////////////////////////////////////////////////////

        /**
         * downloadWorkbook
         *
         * @param workbook
         * @param filename
         * @param file_extension
         */
        this.downloadWorkbook = function(workbook, filename, file_extension) {

            // validate args
            if (_.isUndefined(workbook) || _.isNull(workbook)) {
                throw new Error(this.MESSAGE_WORKBOOK_IS_REQUIRED);
            }
            if (!(workbook instanceof module.Workbook)) {
                throw new Error(this.MESSAGE_WORKBOOK_MODEL_IS_INVALID);
            }
            if (_.isUndefined(filename) || _.isNull(filename) || filename === "") {
                throw new Error(this.MESSAGE_FILE_NAME_IS_REQUIRED);
            }

            // transform file data (name & extension)
            var file_data = module.FileUtil.transformFilenameAndExtension(filename, file_extension);

            // create file array buffer
            var file_array_buffer = this.create_file_handlers[file_data.file_extension](workbook, file_data.file_extension);

            // get file mime_type
            var file_mimetype = module.FileUtil.getFileMimeType(file_data.file_extension);

            // initiate download
            initiateFileDownload(file_array_buffer, file_data.filename, file_mimetype);
        };

        ///////////////////////////////////////////////////////////
        //
        // private methods
        //
        ///////////////////////////////////////////////////////////

        /**
         * convertStringToArrayBuffer
         *
         * @param str
         * @returns {ArrayBuffer}
         */
        var convertStringToArrayBuffer = function(str) {
            var array_buffer = new ArrayBuffer(str.length);
            var view = new Uint8Array(array_buffer);
            for (var i = 0; i !== str.length; ++i) {
                view[i] = str.charCodeAt(i) & 0xFF;
            }
            return array_buffer;
        };

        /**
         * createXlsxFile
         *
         * @param workbook
         * @param file_extension
         */
        var createXlsxFile = function(workbook, file_extension) {
            var workbook_output = XLSX.write(workbook, {bookType: file_extension, bookSST: false, type: 'binary'});
            return convertStringToArrayBuffer(workbook_output);
        };

        /**
         * createOdsFile
         *
         * @param workbook
         * @param file_extension
         */
        var createOdsFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * createXlsFile
         *
         * @param workbook
         * @param file_extension
         */
        var createXlsFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * createTxtFile
         *
         * @param workbook
         * @param file_extension
         */
        var createTxtFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * createCsvFile
         *
         * @param workbook
         * @param file_extension
         */
        var createCsvFile = function() {
            throw new Error(this.CURRENTLY_UNSUPPORTED_FILE_TYPE);
        };

        /**
         * initiateFileDownload
         *
         * @param array_buffer
         * @param filename
         * @param file_mimetype
         */
        var initiateFileDownload = function(file_array_buffer, filename, file_mimetype) {
            // create Blob
            var blob = new Blob([file_array_buffer], {type: file_mimetype});

            // Blob is natively supported by all but ie8 & ie9
            // Blob.js creates a shim for ie8 & ie9
            // TODO: add seperate handling for text & csv

            // if browser is IE10+
            if (window.navigator.msSaveBlob) {

                // initiate ie10 download
                return window.navigator.msSaveBlob(blob, filename);
            }

            // adownload is not supported by browser (ie8, ie9, Safari)
            if (!Modernizr.adownload) {

                // no initiateFileDownloadFallback method is defined
                if (_.isUndefined(self.initiateFileDownloadFallback)) {
                    throw new Error(self.UNSUPPORTED_BROWSER_FEATURE_AND_NO_FALLBACK);
                }

                // call initiate download fallback
                return self.initiateFileDownloadFallback(blob, filename);
            }

            // initiate download
            return window.saveAs(blob, filename);
        };

        ///////////////////////////////////////////////////////////
        //
        // init
        //
        ///////////////////////////////////////////////////////////

        // handlers mapped by file type

        this.create_file_handlers = {
            xlsx:   createXlsxFile,
            ods:    createOdsFile,
            xls:    createXlsFile,
            txt:    createTxtFile,
            csv:    createCsvFile
        };
    };

    module.FileDownloader = new FileDownloader();

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


<commit_before>

function HTTPGET(url) {
    var req = new XMLHttpRequest();
    req.open("GET", url, false);
    req.send(null);
    return req.responseText;
}

function timeToMinutes(time) {
       var c = time.split(':');
       return parseInt(c[0]) * 60 + parseInt(c[1]);
}

var gpsRetry = 0;

var departures = {
  departure_list: [],
  servertime: 0,
  servertime_text: "",

  loadDepartures: function(stopId, directionId) {
      var httpstring = "http://api.vasttrafik.se/bin/rest.exe/v1/departureBoard?" +
                "authKey=" + authKey + "&format=json" +
                  "&id="+stopId;
      if (directionId !== "") httpstring += "&direction="+directionId;
      httpstring += "&timeSpan=60&maxDeparturesPerLine=20";

      console.log("Get departures: " + httpstring);

      var response = HTTPGET(httpstring);
      // TODO: handle no response?

      var json = JSON.parse(response);

      this.servertime_text = json.DepartureBoard.servertime;

      if (json.DepartureBoard.Departure===null || json.DepartureBoard.Departure===undefined) {
        // No departures
        console.log("No departures found");
        return;
      }

      //console.log("Found departures: " + JSON.stringify(json.DepartureBoard.Departure));
      this.departure_list = this.departure_list.concat(json.DepartureBoard.Departure);
      //console.log("Departures found so far: " + JSON.stringify(this.departure_list));
      return;

  },

  getDepartures: function(stopID, direction) {
    var i;
    this.departure_list = [];

    console.log("Get departures for stopId " + stopID + ", directions: " + JSON.stringify(direction));

    if (direction.length === 0) {
      console.log("Get departures without direction");
      this.loadDepartures(stopID, "");
    } else {
      for (i=0; i<direction.length; i++) {
        this.loadDepartures(stopID, direction[i]);
      }
    }

    console.log("Got departures:" + JSON.stringify(this.departure_list));

    this.servertime = timeToMinutes(this.servertime_text);

    if (this.departure_list.length === 0) {
      // No departures
      MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_STATUS": 2})
      return;
    }

    var departure;

    //Calculate times before sorting
    for(i=0; i<this.departure_list.length;i++) {
      departure = this.departure_list[i];

     if (departure.rtTime)
        this.departure_list[i].calcTime = timeToMinutes(departure.rtTime) - this.servertime - 1;
      else
        this.departure_list[i].calcTime = timeToMinutes(departure.time) - this.servertime - 1;

      //dirty fix for midnight handling
      if (this.departure_list[i].calcTime<-10) this.departure_list[i].calcTime+=1440;
    }

    //Sort by time first, then line. Make an option?
    this.departure_list.sort(function(a, b) {
        var x = parseInt(a.sname); var y = parseInt(b.sname);
        if (a.calcTime<b.calcTime) return -1;
        if (a.calcTime>b.calcTime) return 1;
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });

    var stop = this.departure_list[0].stop.split(',')[0];
    MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_NAME": stop});
    //MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_SIZE": departures.length});
    for(i=0;i<this.departure_list.length;i++) {
        departure = this.departure_list[i];

        var time = "";
        if (departure.rtTime) {
          if (departure.calcTime === 0 || departure.calcTime === -1) time = "nu";
          else  time = String(departure.calcTime) + " min";
        } else {
            time = "~" + String(departure.calcTime) + " min";
        }

        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_ROUTENR": departure.sname});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_DIRECTION": departure.direction});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_TIME": time});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_FGCOLOR": GColorFromHex(departure.fgColor.substr(1))});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_BGCOLOR": GColorFromHex(departure.bgColor.substr(1))});

      console.log(departure.sname + "  " + departure.direction + ": " + time );
    }
    MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_COMPLETE": this.servertime_text});

  },
};

var favoriteStops = {
  settings_timestamp: 6,    // Timestamp for latest setting done, seconds since 1 January 1970 00:00:00 UTC

  stops: [
    {stopName: "Borås resecentrum", stopId: "9021014082017000",
     directionId: ["9021014082500000","9022014082053001"],
     directionName: ["Byttorpsklint", "Fjällgatan"] },
    {stopName: "Delsjömotet", stopId: "9022014002043002",
     directionId: ["9021014082017000"],
     directionName: ["Borås resecentrum"]},
    {stopName: "Fjällkroken", stopId: "9021014082689000",
     directionId: ["9021014082017000"],
     directionName: ["Borås resecentrum"]},
    {stopName: "Fjällgatan", stopId: "9021014082053000",
     directionId: ["9021014082017000"],
     directionName: ["Borås resecentrum"]},
    {stopName: "Södra Torget", stopId: "9022014082087020",
     directionId: [],
     directionName: []},
    {stopName: "Korsvägen", stopId: "9021014003980000",
     directionId: ["9021014082017000","9022014012153001","9021014012110000"],
     directionName: ["Borås resecentrum", "Bergfotsgatan", "Mölndal centrum"]},

  ],

    sendList: function() {
      console.log("Start sending favorites");
      MessageQueue.sendAppMessage({"KEY_FAVORITES_INIT": 1});
      for (var i=0; i<this.stops.length; i++) {
        MessageQueue.sendAppMessage({"KEY_FAVORITES_NAME":this.stops[i].stopName});
        for (var j=0; j<this.stops[i].directionName.length; j++) {
          MessageQueue.sendAppMessage({"KEY_FAVORITES_DIRECTION":"» " + this.stops[i].directionName[j]});
        }
      }
      MessageQueue.sendAppMessage({"KEY_FAVORITES_COMPLETE": this.settings_timestamp});
      console.log("Completed sending favorites");
    },

    getDepartures: function(i) {
      console.log("Get departureboard for favorite " + i);
      if (i<this.stops.length) {
        departures.getDepartures(this.stops[i].stopId, this.stops[i].directionId);
      }
    }
};

var locationOptions = {
  enableHighAccuracy: true,
  maximumAge: 30000,
  timeout: 60000
};

function getNearbyStations(pos) {
  var httpstring = "http://api.vasttrafik.se/bin/rest.exe/v1/location.nearbystops?" +
            "authKey=" + authKey + "&format=json" +
            //"&originCoordLat=57.719556&originCoordLong=12.902289" +
            "&originCoordLat=" + pos.coords.latitude + "&originCoordLong=" + pos.coords.longitude +
            "&maxNo=40&maxDist=3000";
  console.log('Request nearby stops:' + httpstring);
    var response = HTTPGET(httpstring);
    //Convert to JSON
    var json = JSON.parse(response);

  if (!json.LocationList.StopLocation) {
    console.log("No nearby stops");
    MessageQueue.sendAppMessage({"KEY_NEARBY_STATUS":4});
    return;
  }
  var stops = json.LocationList.StopLocation;
  var checkDuplicates = [];

  var temp;
  for (var i=0; i<stops.length; i++) {
    if (stops[i].name === null || stops[i].name === undefined) {
      console.log("Stop without name");
      stops.splice(i,1);
    }
    else if (checkDuplicates.indexOf(stops[i].name)>=0) {
      // Only interested in each stop once
      temp = stops.splice(i,1);
      i--;
    }
    else {
      checkDuplicates.push(stops[i].name);
      stops[i].calcDist = ( getDistance(pos.coords.latitude,pos.coords.longitude,parseFloat(stops[i].lat),parseFloat(stops[i].lon)));
      //stops[i].calcDist = ( getDistance(57.719556,12.902289,parseFloat(stops[i].lat),parseFloat(stops[i].lon)));
      //console.log("Stop: " + stops[i].name + ". Calculated distance:" + stops[i].calcDist);
    }
  }
  /** Shall already be received in order from api
  stops.sort(function(a, b) {
    return ((a.calcDist < b.calcDist) ? -1 : ((a.calcDist > b.calcDist) ? 1 : 0));
  });
  */

  MessageQueue.sendAppMessage({"KEY_NEARBY_INIT":1});

  for (i=0; i<stops.length && i<10; i++) {
    //console.log("Nearby "+i+": " + JSON.stringify(stops[i]));
    MessageQueue.sendAppMessage({"KEY_NEARBY_NAME":stops[i].name});
    MessageQueue.sendAppMessage({"KEY_NEARBY_DISTANCE": (Math.round(stops[i].calcDist/100)*100) + "m"});
    MessageQueue.sendAppMessage({"KEY_NEARBY_ID":stops[i].id});
  }
  MessageQueue.sendAppMessage({"KEY_NEARBY_COMPLETE":i+1});

}

function locationNotAvailable(err) {
  if (gpsRetry<3) {
    console.log("No gps position, retrying...");
    gpsRetry++;
    MessageQueue.sendAppMessage({"KEY_NEARBY_STATUS":2});
    navigator.geolocation.getCurrentPosition(getNearbyStations,locationNotAvailable, locationOptions);
  }
  else {
    MessageQueue.sendAppMessage({"KEY_NEARBY_STATUS":3});
    console.log("No gps position available");
  }
}

Pebble.addEventListener("ready",
  function(e) {
    MessageQueue.sendAppMessage({"KEY_PHONE_STARTUP":favoriteStops.settings_timestamp});
    //Watchapp opened, send stop list
    //favoriteStations.sendList();

    //Get nearby stations
    gpsRetry = 0;
    console.log("Try to get gps position...");
    navigator.geolocation.getCurrentPosition(getNearbyStations,locationNotAvailable, locationOptions);
  }
);

Pebble.addEventListener("appmessage",
  function(e) {
    console.log('Received message: ' + JSON.stringify(e.payload));
    if (e.payload.KEY_REQUEST_FAVORITE_DEPARTUREBOARD !== null && e.payload.KEY_REQUEST_FAVORITE_DEPARTUREBOARD !==undefined) {
      favoriteStops.getDepartures(e.payload.KEY_REQUEST_FAVORITE_DEPARTUREBOARD);
    }
    if (e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD !== null && e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD!==undefined) {
      console.log("Get departures for stopID: " + e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD);
      departures.getDepartures(e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD,[]);
    }
    if (e.payload.KEY_REQUEST_NEARBY_STOPS !== null && e.payload.KEY_REQUEST_NEARBY_STOPS!==undefined) {
      gpsRetry = 0;
      navigator.geolocation.getCurrentPosition(getNearbyStations,locationNotAvailable, locationOptions);
    }
    if (e.payload.KEY_REQUEST_SETTINGS !== null && e.payload.KEY_REQUEST_SETTINGS!==undefined) {
      //if (e.payload.KEY_REQUEST_SETTINGS < favoriteStations.settings_timestamp) {
        favoriteStops.sendList();
      //}
    }
  }
);<commit_msg>Test of configuration page<commit_after>

function HTTPGET(url) {
    var req = new XMLHttpRequest();
    req.open("GET", url, false);
    req.send(null);
    return req.responseText;
}

function timeToMinutes(time) {
       var c = time.split(':');
       return parseInt(c[0]) * 60 + parseInt(c[1]);
}

var gpsRetry = 0;

var departures = {
  departure_list: [],
  servertime: 0,
  servertime_text: "",

  loadDepartures: function(stopId, directionId) {
      var httpstring = "http://api.vasttrafik.se/bin/rest.exe/v1/departureBoard?" +
                "authKey=" + authKey + "&format=json" +
                  "&id="+stopId;
      if (directionId !== "") httpstring += "&direction="+directionId;
      httpstring += "&timeSpan=60&maxDeparturesPerLine=20";

      console.log("Get departures: " + httpstring);

      var response = HTTPGET(httpstring);
      // TODO: handle no response?

      var json = JSON.parse(response);

      this.servertime_text = json.DepartureBoard.servertime;

      if (json.DepartureBoard.Departure===null || json.DepartureBoard.Departure===undefined) {
        // No departures
        console.log("No departures found");
        return;
      }

      //console.log("Found departures: " + JSON.stringify(json.DepartureBoard.Departure));
      this.departure_list = this.departure_list.concat(json.DepartureBoard.Departure);
      //console.log("Departures found so far: " + JSON.stringify(this.departure_list));
      return;

  },

  getDepartures: function(stopID, direction) {
    var i;
    this.departure_list = [];

    console.log("Get departures for stopId " + stopID + ", directions: " + JSON.stringify(direction));

    if (direction.length === 0) {
      console.log("Get departures without direction");
      this.loadDepartures(stopID, "");
    } else {
      for (i=0; i<direction.length; i++) {
        this.loadDepartures(stopID, direction[i]);
      }
    }

    console.log("Got departures:" + JSON.stringify(this.departure_list));

    this.servertime = timeToMinutes(this.servertime_text);

    if (this.departure_list.length === 0) {
      // No departures
      MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_STATUS": 2})
      return;
    }

    var departure;

    //Calculate times before sorting
    for(i=0; i<this.departure_list.length;i++) {
      departure = this.departure_list[i];

     if (departure.rtTime)
        this.departure_list[i].calcTime = timeToMinutes(departure.rtTime) - this.servertime - 1;
      else
        this.departure_list[i].calcTime = timeToMinutes(departure.time) - this.servertime - 1;

      //dirty fix for midnight handling
      if (this.departure_list[i].calcTime<-10) this.departure_list[i].calcTime+=1440;
    }

    //Sort by time first, then line. Make an option?
    this.departure_list.sort(function(a, b) {
        var x = parseInt(a.sname); var y = parseInt(b.sname);
        if (a.calcTime<b.calcTime) return -1;
        if (a.calcTime>b.calcTime) return 1;
        return ((x < y) ? -1 : ((x > y) ? 1 : 0));
    });

    var stop = this.departure_list[0].stop.split(',')[0];
    MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_NAME": stop});
    //MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_SIZE": departures.length});
    for(i=0;i<this.departure_list.length;i++) {
        departure = this.departure_list[i];

        var time = "";
        if (departure.rtTime) {
          if (departure.calcTime === 0 || departure.calcTime === -1) time = "nu";
          else  time = String(departure.calcTime) + " min";
        } else {
            time = "~" + String(departure.calcTime) + " min";
        }

        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_ROUTENR": departure.sname});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_DIRECTION": departure.direction});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_TIME": time});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_FGCOLOR": GColorFromHex(departure.fgColor.substr(1))});
        MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_BGCOLOR": GColorFromHex(departure.bgColor.substr(1))});

      console.log(departure.sname + "  " + departure.direction + ": " + time );
    }
    MessageQueue.sendAppMessage({"KEY_DEPARTUREBOARD_COMPLETE": this.servertime_text});

  },
};

var favoriteStops = {
  settings_timestamp: 6,    // Timestamp for latest setting done, seconds since 1 January 1970 00:00:00 UTC

  stops: [
    {stopName: "Borås resecentrum", stopId: "9021014082017000",
     directionId: ["9021014082500000","9022014082053001"],
     directionName: ["Byttorpsklint", "Fjällgatan"] },
    {stopName: "Delsjömotet", stopId: "9022014002043002",
     directionId: ["9021014082017000"],
     directionName: ["Borås resecentrum"]},
    {stopName: "Fjällkroken", stopId: "9021014082689000",
     directionId: ["9021014082017000"],
     directionName: ["Borås resecentrum"]},
    {stopName: "Fjällgatan", stopId: "9021014082053000",
     directionId: ["9021014082017000"],
     directionName: ["Borås resecentrum"]},
    {stopName: "Södra Torget", stopId: "9022014082087020",
     directionId: [],
     directionName: []},
    {stopName: "Korsvägen", stopId: "9021014003980000",
     directionId: ["9021014082017000","9022014012153001","9021014012110000"],
     directionName: ["Borås resecentrum", "Bergfotsgatan", "Mölndal centrum"]},

  ],

    sendList: function() {
      console.log("Start sending favorites");
      MessageQueue.sendAppMessage({"KEY_FAVORITES_INIT": 1});
      for (var i=0; i<this.stops.length; i++) {
        MessageQueue.sendAppMessage({"KEY_FAVORITES_NAME":this.stops[i].stopName});
        for (var j=0; j<this.stops[i].directionName.length; j++) {
          MessageQueue.sendAppMessage({"KEY_FAVORITES_DIRECTION":"» " + this.stops[i].directionName[j]});
        }
      }
      MessageQueue.sendAppMessage({"KEY_FAVORITES_COMPLETE": this.settings_timestamp});
      console.log("Completed sending favorites");
    },

    getDepartures: function(i) {
      console.log("Get departureboard for favorite " + i);
      if (i<this.stops.length) {
        departures.getDepartures(this.stops[i].stopId, this.stops[i].directionId);
      }
    }
};

var locationOptions = {
  enableHighAccuracy: true,
  maximumAge: 30000,
  timeout: 60000
};

function getNearbyStations(pos) {
  var httpstring = "http://api.vasttrafik.se/bin/rest.exe/v1/location.nearbystops?" +
            "authKey=" + authKey + "&format=json" +
            //"&originCoordLat=57.719556&originCoordLong=12.902289" +
            "&originCoordLat=" + pos.coords.latitude + "&originCoordLong=" + pos.coords.longitude +
            "&maxNo=40&maxDist=3000";
  console.log('Request nearby stops:' + httpstring);
    var response = HTTPGET(httpstring);
    //Convert to JSON
    var json = JSON.parse(response);

  if (!json.LocationList.StopLocation) {
    console.log("No nearby stops");
    MessageQueue.sendAppMessage({"KEY_NEARBY_STATUS":4});
    return;
  }
  var stops = json.LocationList.StopLocation;
  var checkDuplicates = [];

  var temp;
  for (var i=0; i<stops.length; i++) {
    if (stops[i].name === null || stops[i].name === undefined) {
      console.log("Stop without name");
      stops.splice(i,1);
    }
    else if (checkDuplicates.indexOf(stops[i].name)>=0) {
      // Only interested in each stop once
      temp = stops.splice(i,1);
      i--;
    }
    else {
      checkDuplicates.push(stops[i].name);
      stops[i].calcDist = ( getDistance(pos.coords.latitude,pos.coords.longitude,parseFloat(stops[i].lat),parseFloat(stops[i].lon)));
      //stops[i].calcDist = ( getDistance(57.719556,12.902289,parseFloat(stops[i].lat),parseFloat(stops[i].lon)));
      //console.log("Stop: " + stops[i].name + ". Calculated distance:" + stops[i].calcDist);
    }
  }
  /** Shall already be received in order from api
  stops.sort(function(a, b) {
    return ((a.calcDist < b.calcDist) ? -1 : ((a.calcDist > b.calcDist) ? 1 : 0));
  });
  */

  MessageQueue.sendAppMessage({"KEY_NEARBY_INIT":1});

  for (i=0; i<stops.length && i<10; i++) {
    //console.log("Nearby "+i+": " + JSON.stringify(stops[i]));
    MessageQueue.sendAppMessage({"KEY_NEARBY_NAME":stops[i].name});
    MessageQueue.sendAppMessage({"KEY_NEARBY_DISTANCE": (Math.round(stops[i].calcDist/100)*100) + "m"});
    MessageQueue.sendAppMessage({"KEY_NEARBY_ID":stops[i].id});
  }
  MessageQueue.sendAppMessage({"KEY_NEARBY_COMPLETE":i+1});

}

function locationNotAvailable(err) {
  if (gpsRetry<3) {
    console.log("No gps position, retrying...");
    gpsRetry++;
    MessageQueue.sendAppMessage({"KEY_NEARBY_STATUS":2});
    navigator.geolocation.getCurrentPosition(getNearbyStations,locationNotAvailable, locationOptions);
  }
  else {
    MessageQueue.sendAppMessage({"KEY_NEARBY_STATUS":3});
    console.log("No gps position available");
  }
}

Pebble.addEventListener("ready",
  function(e) {
    MessageQueue.sendAppMessage({"KEY_PHONE_STARTUP":favoriteStops.settings_timestamp});
    //Watchapp opened, send stop list
    //favoriteStations.sendList();

    //Get nearby stations
    gpsRetry = 0;
    console.log("Try to get gps position...");
    navigator.geolocation.getCurrentPosition(getNearbyStations,locationNotAvailable, locationOptions);
  }
);

Pebble.addEventListener("appmessage",
  function(e) {
    console.log('Received message: ' + JSON.stringify(e.payload));
    if (e.payload.KEY_REQUEST_FAVORITE_DEPARTUREBOARD !== null && e.payload.KEY_REQUEST_FAVORITE_DEPARTUREBOARD !==undefined) {
      favoriteStops.getDepartures(e.payload.KEY_REQUEST_FAVORITE_DEPARTUREBOARD);
    }
    if (e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD !== null && e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD!==undefined) {
      console.log("Get departures for stopID: " + e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD);
      departures.getDepartures(e.payload.KEY_REQUEST_NEARBY_DEPARTUREBOARD,[]);
    }
    if (e.payload.KEY_REQUEST_NEARBY_STOPS !== null && e.payload.KEY_REQUEST_NEARBY_STOPS!==undefined) {
      gpsRetry = 0;
      navigator.geolocation.getCurrentPosition(getNearbyStations,locationNotAvailable, locationOptions);
    }
    if (e.payload.KEY_REQUEST_SETTINGS !== null && e.payload.KEY_REQUEST_SETTINGS!==undefined) {
      //if (e.payload.KEY_REQUEST_SETTINGS < favoriteStations.settings_timestamp) {
        favoriteStops.sendList();
      //}
    }
  }
);

Pebble.addEventListener("showConfiguration",
  function(e) {
    Pebble.openURL("http://davidsvantesson.github.io/vasttid.html")
  }
);

Pebble.addEventListener("webwiewclosed"),
  function(e) {
    var fullConfiguration = JSON.parse(decodeURIComponent(e.response));
    console.log("Configuration window returned: " + JSON.stringify(configuration));
  }
);
<|endoftext|>


<commit_before>import React from 'react'
import Example from './example-component'

class App extends React.Component {

  render() {
    return <Example place="world" />
  }

}

export default App
<commit_msg>use stateless component when possible<commit_after>import React from 'react'
import Example from './example-component'

const App = () => (
  <Example place="world" />
)

export default App
<|endoftext|>


<commit_before>var vows = require('vows');
var assert = require('assert');

var TIMING_EPSILON = 10;

var TokenBucket = require('../lib/tokenBucket');
var gBucket;
var gStart;

vows.describe('TokenBucket').addBatch({
  'capacity 10, 1 per 100ms': {
    topic: new TokenBucket(10, 1, 100),

    'is initialized empty': function(bucket) {
      gBucket = bucket;
      assert.equal(bucket.bucketSize, 10);
      assert.equal(bucket.tokensPerInterval, 1);
      assert.equal(bucket.content, 0);
    },
    'removing 10 tokens': {
      topic: function(bucket) {
        gStart = +new Date();
        bucket.removeTokens(10, this.callback);
      },
      'takes 1 second': function(remainingTokens) {
        var duration = +new Date() - gStart;
        var diff = Math.abs(1000 - duration);
        assert.ok(diff < TIMING_EPSILON, diff+'');
        assert.equal(remainingTokens, 0);
      },
      'and removing another 10 tokens': {
        topic: function() {
          gStart = +new Date();
          assert.equal(gBucket.content, 0);
          gBucket.removeTokens(10, this.callback);
        },
        'takes 1 second': function() {
          var duration = +new Date() - gStart;
          var diff = Math.abs(1000 - duration);
          assert.ok(diff < TIMING_EPSILON, diff+'');
        }
      },
      'and waiting 2 seconds': {
        topic: function() {
          var self = this;
          setTimeout(function() {
            gStart = +new Date();
            gBucket.removeTokens(10, self.callback);
          }, 2000);
        },
        'gives us only 10 tokens': function(remainingTokens) {
          var duration = +new Date() - gStart;
          assert.ok(duration < TIMING_EPSILON, duration+'');
          assert.equal(remainingTokens, 0);
        },
        'and removing 1 token': {
          topic: function() {
            gStart = +new Date();
            gBucket.removeTokens(1, this.callback);
          },
          'takes 100ms': function() {
            var duration = +new Date() - gStart;
            var diff = Math.abs(100 - duration);
            assert.ok(diff < TIMING_EPSILON, diff+'');
          }
        }
      }
    }
  },
}).export(module);
<commit_msg>Eliminates module-scoped variables from tokenbucket-test.<commit_after>var vows = require('vows');
var assert = require('assert');

var TIMING_EPSILON = 10;

var TokenBucket = require('../lib/tokenBucket');

vows.describe('TokenBucket').addBatch({
  'capacity 10, 1 per 100ms': {
    topic: new TokenBucket(10, 1, 100),

    'is initialized empty': function(bucket) {
      assert.equal(bucket.bucketSize, 10);
      assert.equal(bucket.tokensPerInterval, 1);
      assert.equal(bucket.content, 0);
    },
    'removing 10 tokens': {
      topic: function(bucket) {
        this.gStart = +new Date();
        bucket.removeTokens(10, this.callback);
      },
      'takes 1 second': function(remainingTokens) {
        var duration = +new Date() - this.gStart;
        var diff = Math.abs(1000 - duration);
        assert.ok(diff < TIMING_EPSILON, diff+'');
        assert.equal(remainingTokens, 0);
      },
      'and removing another 10 tokens': {
        topic: function(_, bucket) {
          this.gStart = +new Date();
          assert.equal(bucket.content, 0);
          bucket.removeTokens(10, this.callback);
        },
        'takes 1 second': function() {
          var duration = +new Date() - this.gStart;
          var diff = Math.abs(1000 - duration);
          assert.ok(diff < TIMING_EPSILON, diff+'');
        }
      },
      'and waiting 2 seconds': {
        topic: function(_, bucket) {
          var self = this;
          setTimeout(function() {
            self.gStart = +new Date();
            bucket.removeTokens(10, self.callback);
          }, 2000);
        },
        'gives us only 10 tokens': function(remainingTokens) {
          var duration = +new Date() - this.gStart;
          assert.ok(duration < TIMING_EPSILON, duration+'');
          assert.equal(remainingTokens, 0);
        },
        'and removing 1 token': {
          topic: function(_, _, bucket) {
            this.gStart = +new Date();
            bucket.removeTokens(1, this.callback);
          },
          'takes 100ms': function() {
            var duration = +new Date() - this.gStart;
            var diff = Math.abs(100 - duration);
            assert.ok(diff < TIMING_EPSILON, diff+'');
          }
        }
      }
    }
  },
}).export(module);
<|endoftext|>


<commit_before>'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });

var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  grunt.loadNpmTasks('assemble');

  // configurable paths
  var config = {
    app: 'app',
    dist: 'public',
    tests: 'tests'
  };

  grunt.initConfig({
    config: config,
    watch: {
      grunt: {
        files: ['Gruntfile.js'],
        options: { reload: true }
      },
      assemble: {
        files: [ '<%= config.app %>/templates/{,*/}*.{hbs,html}' ],
        tasks: [ 'assemble:server' ]
      },
      sass: {
        files: [ '<%= config.app %>/styles/{,*/}*.{scss,sass}' ],
        tasks: [ 'sass:server' ]
      },
      livereload: {
        options: {
          livereload: LIVERELOAD_PORT
        },
        files: [
          '{.tmp,<%= config.app %>/views}/{,*/}*.html',
          '{.tmp,<%= config.app %>}/styles/{,*/}*.css',
          '{.tmp,<%= config.app %>}/scripts/{,*/}*.js',
          '<%= config.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '0.0.0.0'
      },
      livereload: {
        options: {
          middleware: function (connect) {
            return [
              lrSnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, config.app),
              mountFolder(connect, config.tests)
            ];
          }
        }
      },
// 			test: {
// 				options: {
// 					middleware: function (connect) {
// 						return [
// 							mountFolder(connect, '.tmp'),
// 							mountFolder(connect, 'test')
// 						];
// 					}
// 				}
// 			},
      dist: {
        options: {
          middleware: function (connect) {
            return [
              mountFolder(connect, config.dist)
            ];
          }
        }
      }
    },
    clean: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.dist %>',
          src: [
            '*'
          ]
        }]
      },
      server: '.tmp',
      test: [
        '<%= config.tests %>/media/themes',
        '<%= config.tests %>/media/themes-diff'
      ]
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= config.app %>/scripts/{,*/}*.js'
      ]
    },
    assemble: {
      options: {
        layoutdir: '<%= config.app %>/templates/layouts',
        partials: [
          '<%= config.app %>/templates/partials/**/*.html'
        ]
      },
      server: {
        options: {
          collections: [{
            name: 'posted',
            inflection: 'post',
            sortby: 'posted',
            sortorder: 'descending'
          }]
        },
        files: [{
          expand: true,
          cwd: '<%= config.app %>/templates',
          src: '**/*.hbs',
          dest: '.tmp'
        }]
      },
      dist: {
        options: {
          collections: [{
            name: 'posted',
            inflection: 'post',
            sortby: 'posted',
            sortorder: 'descending'
          }]
        },
        files: [{
          expand: true,
          cwd: '<%= config.app %>/templates',
          src: '**/*.hbs',
          dest: '<%= config.dist %>'
        }]
      }
    },
    sass: {
      dist: {
        files: {
          '.tmp/styles/main.css': '<%= config.app %>/styles/main.scss'
        }
      },
      server: {
        files: {
          '.tmp/styles/main.css': '<%= config.app %>/styles/main.scss'
        }
      }
    },
    rev: {
      dist: {
        files: {
          src: [
            '<%= config.dist %>/scripts/{,*/}*.js',
            '<%= config.dist %>/styles/{,*/}*.css',
            '<%= config.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= config.dist %>/styles/fonts/*'
          ]
        }
      }
    },
    useminPrepare: {
      html: [
        //'<%= config.dist %>/{,*/}*.{html,hbs}'
        '<%= config.dist %>/{,*/}index.html'
      ],
      options: {
        dest: '<%= config.dist %>'
      }
    },
    usemin: {
      html: ['<%= config.dist %>/{,*/}*.html'],
      css: ['<%= config.dist %>/styles/{,*/}*.css'],
      js: ['<%= config.dist %>/scripts/*.js'],
      options: {
        assetsDirs: [
          '<%= config.dist %>',
          '<%= config.dist %>/images'
        ],
        patterns: {
          js: [
            [/(images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm]
          ]
        }
      }
    },
    htmlmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.dist %>',
          src: ['*.html', 'views/*.html'],
          dest: '<%= config.dist %>'
        }]
      }
    },
    copy: {
      dev: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>/dev',
          dest: '<%= config.dist %>',
          src: [
            'CNAME',
            '*.*'
          ]
        }]
      },
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>',
          dest: '<%= config.dist %>',
          src: [
            'CNAME',
            '*.*',
            //'bower_components/**/*',
            'bower_components/font-awesome/**/*',
            'images/{,*/}*.*',
            'styles/fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= config.dist %>/images',
          src: [
            'generated/*'
          ]
        }]
      }
    },
    karma: {
      unit: {
        configFile: 'tests/karma.conf.js',
        singleRun: true
      }
    },
    ngtemplates: {
      dist: {
        options: {
          usemin: '<%= config.dist %>/scripts/app.js',
          module: 'businessCardMaker'
        },
        cwd: '<%= config.app %>',
        src: 'views/{,*/}*.html',
        dest: '.tmp/scripts/templates.js'
      }
    },
    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat/scripts',
          src: '*.js',
          dest: '.tmp/concat/scripts'
        }]
      }
    },
    uglify: {
      options: {
        compress: {
          drop_console: true
        }
      }
    },
    protractor: {
      options: {
        keepAlive: false,
        configFile: 'tests/protractor.conf.js'
      },
      themes: {
        options: {
          args: {
            specs: [
              'tests/e2e/themes.spec.js'
            ]
          }
        }
      }
    },
    execute: {
      themes: {
        src: [ 'tests/themes/themes-diff.js' ]
      }
    },
    'ftp-deploy': {
      development: {
        auth: {
          host: 'server134.web-hosting.com',
          authPath: 'deploy.json',
          authKey: 'namecheap'
        },
        src: '<%= config.dist %>',
        dest: './releases/development/'
      },
      staging: {
        auth: {
          host: 'server134.web-hosting.com',
          authPath: 'deploy.json',
          authKey: 'namecheap'
        },
        src: '<%= config.dist %>',
        dest: './releases/staging/'
      },
      www: {
        auth: {
          host: 'server134.web-hosting.com',
          authPath: 'deploy.json',
          authKey: 'namecheap'
        },
        src: '<%= config.dist %>',
        dest: './releases/www/'
      }
    }
  });

  grunt.registerTask('server', function (target) {
    if (target === 'dist') {
      return grunt.task.run([
        'default',
        'connect:dist:keepalive'
      ]);
    }

    grunt.task.run([
      'clean:server',
      'sass:server',
      'assemble:server',
      'connect:livereload',
      'watch'
    ]);

  });

// 	grunt.registerTask('test', [
// 		'clean:server',
// 		'concurrent:test',
// 		'connect:test',
// 		'karma'
// 	]);

  grunt.registerTask('build', [
    'clean:dist',
    'sass:dist',
    'assemble:dist',
    'htmlmin',
    'useminPrepare',
    'ngtemplates',
    'copy:dist',
    'concat',
    'ngAnnotate',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);

  grunt.registerTask('default', [
    'jshint',
    'build'
  ]);

  grunt.registerTask('test', function(target) {

    grunt.task.run([
      'default',
      'connect:dist',
      'clean:test',
      'protractor:themes',
      'execute:themes'
    ]);

  });

  var deployConfig = grunt.file.readJSON('deploy.json');

  var purgeCloudflareCache = function() {

    var done = this.async();

    var https = require('https');
    var querystring = require('querystring');

    // Build the post string from an object
    var postData = querystring.stringify({
      tkn: deployConfig.cloudflare.key,
      email: deployConfig.cloudflare.email,
      a: 'fpurge_ts',
      v: 1,
      z: 'bizcardmaker.com'
    });

    // An object of options to indicate where to post to
    var post_options = {
        host: 'www.cloudflare.com',
        path: '/api_json.html',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': postData.length
        }
    };

    // Set up the request
    var postReq = https.request(post_options, function(res) {

      res.setEncoding('utf8');
      res.on('data', function (chunk) {
        console.log(chunk);
        done();
      });

    });

    // post the data
    postReq.write(postData);
    postReq.end();

  };

  grunt.registerTask('cloudflare', purgeCloudflareCache);

  grunt.registerTask('deploy', function (target) {

    if (target === 'live') {
      return grunt.task.run([
        //'test',
        'default',

        'ftp-deploy:www',
        'cloudflare'
      ]);
    }

    grunt.task.run([
      //'test',
      'default',

      'copy:dev',
      'ftp-deploy:development',
      'ftp-deploy:staging',
      'cloudflare'
    ]);

  });

};
<commit_msg>Fix the copy task to include all subdirs in the images folder.<commit_after>'use strict';
var LIVERELOAD_PORT = 35729;
var lrSnippet = require('connect-livereload')({ port: LIVERELOAD_PORT });

var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
  grunt.loadNpmTasks('assemble');

  // configurable paths
  var config = {
    app: 'app',
    dist: 'public',
    tests: 'tests'
  };

  grunt.initConfig({
    config: config,
    watch: {
      grunt: {
        files: ['Gruntfile.js'],
        options: { reload: true }
      },
      assemble: {
        files: [ '<%= config.app %>/templates/{,*/}*.{hbs,html}' ],
        tasks: [ 'assemble:server' ]
      },
      sass: {
        files: [ '<%= config.app %>/styles/{,*/}*.{scss,sass}' ],
        tasks: [ 'sass:server' ]
      },
      livereload: {
        options: {
          livereload: LIVERELOAD_PORT
        },
        files: [
          '{.tmp,<%= config.app %>/views}/{,*/}*.html',
          '{.tmp,<%= config.app %>}/styles/{,*/}*.css',
          '{.tmp,<%= config.app %>}/scripts/{,*/}*.js',
          '<%= config.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
        ]
      }
    },
    connect: {
      options: {
        port: 9000,
        // Change this to '0.0.0.0' to access the server from outside.
        hostname: '0.0.0.0'
      },
      livereload: {
        options: {
          middleware: function (connect) {
            return [
              lrSnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, config.app),
              mountFolder(connect, config.tests)
            ];
          }
        }
      },
// 			test: {
// 				options: {
// 					middleware: function (connect) {
// 						return [
// 							mountFolder(connect, '.tmp'),
// 							mountFolder(connect, 'test')
// 						];
// 					}
// 				}
// 			},
      dist: {
        options: {
          middleware: function (connect) {
            return [
              mountFolder(connect, config.dist)
            ];
          }
        }
      }
    },
    clean: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.dist %>',
          src: [
            '*'
          ]
        }]
      },
      server: '.tmp',
      test: [
        '<%= config.tests %>/media/themes',
        '<%= config.tests %>/media/themes-diff'
      ]
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        '<%= config.app %>/scripts/{,*/}*.js'
      ]
    },
    assemble: {
      options: {
        layoutdir: '<%= config.app %>/templates/layouts',
        partials: [
          '<%= config.app %>/templates/partials/**/*.html'
        ]
      },
      server: {
        options: {
          collections: [{
            name: 'posted',
            inflection: 'post',
            sortby: 'posted',
            sortorder: 'descending'
          }]
        },
        files: [{
          expand: true,
          cwd: '<%= config.app %>/templates',
          src: '**/*.hbs',
          dest: '.tmp'
        }]
      },
      dist: {
        options: {
          collections: [{
            name: 'posted',
            inflection: 'post',
            sortby: 'posted',
            sortorder: 'descending'
          }]
        },
        files: [{
          expand: true,
          cwd: '<%= config.app %>/templates',
          src: '**/*.hbs',
          dest: '<%= config.dist %>'
        }]
      }
    },
    sass: {
      dist: {
        files: {
          '.tmp/styles/main.css': '<%= config.app %>/styles/main.scss'
        }
      },
      server: {
        files: {
          '.tmp/styles/main.css': '<%= config.app %>/styles/main.scss'
        }
      }
    },
    rev: {
      dist: {
        files: {
          src: [
            '<%= config.dist %>/scripts/{,*/}*.js',
            '<%= config.dist %>/styles/{,*/}*.css',
            '<%= config.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '<%= config.dist %>/styles/fonts/*'
          ]
        }
      }
    },
    useminPrepare: {
      html: [
        //'<%= config.dist %>/{,*/}*.{html,hbs}'
        '<%= config.dist %>/{,*/}index.html'
      ],
      options: {
        dest: '<%= config.dist %>'
      }
    },
    usemin: {
      html: ['<%= config.dist %>/{,*/}*.html'],
      css: ['<%= config.dist %>/styles/{,*/}*.css'],
      js: ['<%= config.dist %>/scripts/*.js'],
      options: {
        assetsDirs: [
          '<%= config.dist %>',
          '<%= config.dist %>/images'
        ],
        patterns: {
          js: [
            [/(images\/.*?\.(?:gif|jpeg|jpg|png|webp|svg))/gm]
          ]
        }
      }
    },
    htmlmin: {
      dist: {
        files: [{
          expand: true,
          cwd: '<%= config.dist %>',
          src: ['*.html', 'views/*.html'],
          dest: '<%= config.dist %>'
        }]
      }
    },
    copy: {
      dev: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>/dev',
          dest: '<%= config.dist %>',
          src: [
            'CNAME',
            '*.*'
          ]
        }]
      },
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= config.app %>',
          dest: '<%= config.dist %>',
          src: [
            'CNAME',
            '*.*',
            //'bower_components/**/*',
            'bower_components/font-awesome/**/*',
            'images/**/*',
            'styles/fonts/*'
          ]
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= config.dist %>/images',
          src: [
            'generated/*'
          ]
        }]
      }
    },
    karma: {
      unit: {
        configFile: 'tests/karma.conf.js',
        singleRun: true
      }
    },
    ngtemplates: {
      dist: {
        options: {
          usemin: '<%= config.dist %>/scripts/app.js',
          module: 'businessCardMaker'
        },
        cwd: '<%= config.app %>',
        src: 'views/{,*/}*.html',
        dest: '.tmp/scripts/templates.js'
      }
    },
    ngAnnotate: {
      dist: {
        files: [{
          expand: true,
          cwd: '.tmp/concat/scripts',
          src: '*.js',
          dest: '.tmp/concat/scripts'
        }]
      }
    },
    uglify: {
      options: {
        compress: {
          drop_console: true
        }
      }
    },
    protractor: {
      options: {
        keepAlive: false,
        configFile: 'tests/protractor.conf.js'
      },
      themes: {
        options: {
          args: {
            specs: [
              'tests/e2e/themes.spec.js'
            ]
          }
        }
      }
    },
    execute: {
      themes: {
        src: [ 'tests/themes/themes-diff.js' ]
      }
    },
    'ftp-deploy': {
      development: {
        auth: {
          host: 'server134.web-hosting.com',
          authPath: 'deploy.json',
          authKey: 'namecheap'
        },
        src: '<%= config.dist %>',
        dest: './releases/development/'
      },
      staging: {
        auth: {
          host: 'server134.web-hosting.com',
          authPath: 'deploy.json',
          authKey: 'namecheap'
        },
        src: '<%= config.dist %>',
        dest: './releases/staging/'
      },
      www: {
        auth: {
          host: 'server134.web-hosting.com',
          authPath: 'deploy.json',
          authKey: 'namecheap'
        },
        src: '<%= config.dist %>',
        dest: './releases/www/'
      }
    }
  });

  grunt.registerTask('server', function (target) {
    if (target === 'dist') {
      return grunt.task.run([
        'default',
        'connect:dist:keepalive'
      ]);
    }

    grunt.task.run([
      'clean:server',
      'sass:server',
      'assemble:server',
      'connect:livereload',
      'watch'
    ]);

  });

// 	grunt.registerTask('test', [
// 		'clean:server',
// 		'concurrent:test',
// 		'connect:test',
// 		'karma'
// 	]);

  grunt.registerTask('build', [
    'clean:dist',
    'sass:dist',
    'assemble:dist',
    'htmlmin',
    'useminPrepare',
    'ngtemplates',
    'copy:dist',
    'concat',
    'ngAnnotate',
    'cssmin',
    'uglify',
    'rev',
    'usemin'
  ]);

  grunt.registerTask('default', [
    'jshint',
    'build'
  ]);

  grunt.registerTask('test', function(target) {

    grunt.task.run([
      'default',
      'connect:dist',
      'clean:test',
      'protractor:themes',
      'execute:themes'
    ]);

  });

  var deployConfig = grunt.file.readJSON('deploy.json');

  var purgeCloudflareCache = function() {

    var done = this.async();

    var https = require('https');
    var querystring = require('querystring');

    // Build the post string from an object
    var postData = querystring.stringify({
      tkn: deployConfig.cloudflare.key,
      email: deployConfig.cloudflare.email,
      a: 'fpurge_ts',
      v: 1,
      z: 'bizcardmaker.com'
    });

    // An object of options to indicate where to post to
    var post_options = {
        host: 'www.cloudflare.com',
        path: '/api_json.html',
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Content-Length': postData.length
        }
    };

    // Set up the request
    var postReq = https.request(post_options, function(res) {

      res.setEncoding('utf8');
      res.on('data', function (chunk) {
        console.log(chunk);
        done();
      });

    });

    // post the data
    postReq.write(postData);
    postReq.end();

  };

  grunt.registerTask('cloudflare', purgeCloudflareCache);

  grunt.registerTask('deploy', function (target) {

    if (target === 'live') {
      return grunt.task.run([
        //'test',
        'default',

        'ftp-deploy:www',
        'cloudflare'
      ]);
    }

    grunt.task.run([
      //'test',
      'default',

      'copy:dev',
      'ftp-deploy:development',
      'ftp-deploy:staging',
      'cloudflare'
    ]);

  });

};
<|endoftext|>