<commit_before>/* See license.txt for terms of usage */

define([
    "firebug/lib/object",
    "firebug/firebug",
    "firebug/lib/locale",
    "firebug/lib/url",
    "firebug/chrome/tabWatcher",
    "firebug/chrome/annotations",
],
function(Obj, Firebug, Locale, Url, TabWatcher, Annotations) {

// ********************************************************************************************* //
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

// ********************************************************************************************* //

/**
 * @module Implements Firebug activation logic.
 *
 * 1) Part of the logic is based on annotation service (see components/firebug-annotations.js)
 *    in order to remember whether Firebug is activated for given site or not.
 *    If there is "firebugged.showFirebug" annotation for a given site Firbug is activated.
 *    If there is "firebugged.closed" annotation for a given site Firbug is not activated.
 *
 * 2) Other part is based on extensions.firebug.allPagesActivation option. This option
 *    can be set to the following values:
 *    none: The option isn't used (default value)
 *    on:   Firebug is activated for all URLs.
 *    off:  Firebug is never activated.
 *
 *    This logic has higher priority over the URL annotations.
 *    If "off" options is selected, all existing URL annotations are removed.
 */
Firebug.Activation = Obj.extend(Firebug.Module,
{
    dispatchName: "activation",

    // called once
    initializeUI: function()
    {
        Firebug.Module.initializeUI.apply(this, arguments);

        TabWatcher.initializeUI();
        TabWatcher.addListener(this);
    },

    shutdown: function()
    {
        Firebug.Module.shutdown.apply(this, arguments);

        TabWatcher.removeListener(this);
    },

    // true if the Places annotation the URI "firebugged"
    shouldCreateContext: function(browser, url, userCommands)
    {
        if (FBTrace.DBG_ACTIVATION)
            FBTrace.sysout("shouldCreateContext allPagesActivation " +
                Firebug.allPagesActivation);

        if (Firebug.allPagesActivation == "on")
            return true;

        // if about:blank gets thru, 1483 fails
        if (Firebug.filterSystemURLs && Url.isSystemURL(url))
            return false;

        if (userCommands)
            return true;

        // document.open on a firebugged page
        if (browser && browser.showFirebug && url.substr(0, 8) === "wyciwyg:")
            return true;

        try
        {
            var uri = this.convertToURIKey(url, Firebug.activateSameOrigin);
            if (!uri)
                return false;

            var hasAnnotation = Annotations.pageHasAnnotation(uri);

            if (FBTrace.DBG_ACTIVATION)
                FBTrace.sysout("shouldCreateContext hasAnnotation "+hasAnnotation +
                    " for "+uri.spec+" in "+browser.contentWindow.location +
                    " using activateSameOrigin: "+Firebug.activateSameOrigin);

            // Annotated, so return the value.
            if (hasAnnotation)
                return this.checkAnnotation(browser, uri);

            if (browser.FirebugLink) // then Firebug.TabWatcher found a connection
            {
                var dst = browser.FirebugLink.dst;
                var dstURI = this.convertToURIKey(dst.spec, Firebug.activateSameOrigin);
                if (FBTrace.DBG_ACTIVATION)
                    FBTrace.sysout("shouldCreateContext found FirebugLink pointing to " +
                        dstURI.spec, browser.FirebugLink);

                if (dstURI && dstURI.equals(uri)) // and it matches us now
                {
                    var srcURI = this.convertToURIKey(browser.FirebugLink.src.spec,
                        Firebug.activateSameOrigin);

                    if (srcURI)
                    {
                        if (FBTrace.DBG_ACTIVATION)
                            FBTrace.sysout("shouldCreateContext found FirebugLink pointing from " +
                                srcURI.spec, browser.FirebugLink);

                        // and it's on the same domain
                        if (srcURI.schemeIs("file") || (dstURI.host == srcURI.host))
                        {
                            hasAnnotation = Annotations.pageHasAnnotation(srcURI);
                            if (hasAnnotation) // and the source page was annotated.
                            {
                                var srcShow = this.checkAnnotation(browser, srcURI);
                                if (srcShow)  // and the source annotation said show it
                                    this.watchBrowser(browser);  // so we show dst as well.
                                return srcShow;
                            }
                        }
                    }
                }
                else
                {
                    if (FBTrace.DBG_ACTIVATION)
                        FBTrace.sysout("shouldCreateContext FirebugLink does not match " +
                            uri.spec, browser.FirebugLink);
                }
            }
            else if (browser.contentWindow.opener)
            {
                var openerContext = Firebug.TabWatcher.getContextByWindow(
                    browser.contentWindow.opener);

                if (FBTrace.DBG_ACTIVATION)
                    FBTrace.sysout("shouldCreateContext opener found, has " +
                        (openerContext ? "a " : "no ") + " context: " +
                        browser.contentWindow.opener.location);

                if (openerContext)
                    return true;  // popup windows of Firebugged windows are Firebugged
            }

            return false;   // don't createContext
        }
        catch (exc)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("pageHasAnnotation FAILS for url: " + url + " which gave uri " +
                    (uri ? uri.spec : "null"), exc);
        }
    },

    shouldShowContext: function(context)
    {
        return this.shouldCreateContext(context.browser, context.getWindowLocation().toString());
    },

    // Firebug is opened in browser
    watchBrowser: function(browser)
    {
        try
        {
            var annotation = "firebugged.showFirebug";
            this.setPageAnnotation(browser.currentURI.spec, annotation);
        }
        catch (e)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("activation.watchBrowser; EXCEPTION " + e, e);
        }
    },

    // Firebug closes in browser
    unwatchBrowser: function(browser, userCommands)
    {
        var uri = browser.currentURI.spec;
        if (userCommands)  // then mark to not open virally.
            this.setPageAnnotation(uri, "firebugged.closed");
        else
            this.removePageAnnotation(uri); // unmark this URI
    },

    clearAnnotations: function()
    {
        Annotations.clear();
        Annotations.flush();

        Firebug.connection.dispatch("onClearAnnotations", []);
    },

    // process the URL to canonicalize it. Need not be reversible.
    convertToURIKey: function(url, sameOrigin)
    {
        // Remove fragment, it shouldn't have any impact on the activation.
        url = url.replace(/#.*/, "");

        var uri = Url.makeURI(Url.normalizeURL(url));

        if (Firebug.filterSystemURLs && Url.isSystemURL(url))
            return uri;

        if (url == "about:blank")  // avoid exceptions.
            return uri;

        if (uri && sameOrigin)
        {
            try
            {
                // returns the string before the path (such as "scheme://user:password@host:port").
                var prePath = uri.prePath;
                var shortURI = Url.makeURI(prePath);
                if (!shortURI)
                    return uri;

                // annoying "about" URIs throw if you access .host
                if (shortURI.scheme === "about")
                    return shortURI;

                if (shortURI.scheme === "file")
                    return shortURI;

                var host = shortURI.host;
                if (host)
                {
                    // Slice the subdomain (if any) from the URL so that activateSameOrigin works
                    // for domains (including TLD domains). So we want:
                    // 1) www.google.com -> google.com
                    // 2) www.stuff.co.nz -> stuff.co.nz
                    // 3) getfirebug.com -> getfirebug.com
                    // (XXX: This makes a.co.uk -> co.uk and mail.cn.mozilla.com -> cn.mozilla.com,
                    // which is wrong. See issue 2202.)
                    var levels = host.split('.');
                    if (levels.length > 2)
                        levels = levels.slice(1);
                    shortURI.host = levels.join('.');
                    return shortURI;
                }
            }
            catch (exc)
            {
                if (FBTrace.DBG_ERRORS)
                    FBTrace.sysout("activation.convertToURIKey returning full URI, " +
                        "activateSameOrigin FAILS for shortURI " + shortURI + " because: " + exc,
                        exc);

                return uri;
            }
        }
        return uri;
    },

    checkAnnotation: function(browser, uri)
    {
        var annotation = Annotations.getPageAnnotation(uri);

        if (FBTrace.DBG_ACTIVATION)
            FBTrace.sysout("shouldCreateContext read back annotation " + annotation +
                " for uri " + uri.spec);

        // then the user closed Firebug on this page last time
        if ((Firebug.allPagesActivation != "on") && (annotation.indexOf("closed") > 0))
            return false;   // annotated as 'closed', don't create
        else
            return true;    // annotated, createContext
    },

    setPageAnnotation: function(currentURI, annotation)
    {
        var uri = this.convertToURIKey(currentURI, Firebug.activateSameOrigin);
        if (uri)
            Annotations.setPageAnnotation(uri, annotation);

        if (FBTrace.DBG_ACTIVATION || FBTrace.DBG_ANNOTATION)
            FBTrace.sysout("setPageAnnotation currentURI " + currentURI + " becomes URI key "+
                (uri ? uri.spec : "ERROR"));

        if (Firebug.activateSameOrigin)
        {
            uri = this.convertToURIKey(currentURI, false);
            if (uri)
                Annotations.setPageAnnotation(uri, annotation);

            if (FBTrace.DBG_ACTIVATION || FBTrace.DBG_ANNOTATION)
                FBTrace.sysout("setPageAnnotation with activeSameOrigin currentURI " +
                    currentURI.spec + " becomes URI key " + (uri ? uri.spec : "ERROR"));
        }
    },

    removePageAnnotation: function(currentURI)
    {
        var uri = this.convertToURIKey(currentURI, Firebug.activateSameOrigin);
        if (uri)
            Annotations.removePageAnnotation(uri);

        if (Firebug.activateSameOrigin)
        {
            uri = this.convertToURIKey(currentURI, false);
            if (uri)
                Annotations.removePageAnnotation(uri);
        }

        if (FBTrace.DBG_ACTIVATION)
            FBTrace.sysout("Firebug.Activation.unwatchBrowser untagged "+uri.spec);
    },

    // stops at the first fn(uri) that returns a true value
    iterateAnnotations: function(fn)
    {
        var annotations = Annotations.getAnnotations(this.annotationName);
        for (var uri in annotations)
        {
            var rc = fn(uri, annotations[uri]);
            if (rc)
                return rc;
        }
    },
});

// ********************************************************************************************* //
// Registration

Firebug.registerModule(Firebug.Activation);

return Firebug.Activation;

// ********************************************************************************************* //
});
<commit_msg>Update tracing (avoid exception)<commit_after>/* See license.txt for terms of usage */

define([
    "firebug/lib/object",
    "firebug/firebug",
    "firebug/lib/locale",
    "firebug/lib/url",
    "firebug/chrome/tabWatcher",
    "firebug/chrome/annotations",
],
function(Obj, Firebug, Locale, Url, TabWatcher, Annotations) {

// ********************************************************************************************* //
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

// ********************************************************************************************* //

/**
 * @module Implements Firebug activation logic.
 *
 * 1) Part of the logic is based on annotation service (see components/firebug-annotations.js)
 *    in order to remember whether Firebug is activated for given site or not.
 *    If there is "firebugged.showFirebug" annotation for a given site Firbug is activated.
 *    If there is "firebugged.closed" annotation for a given site Firbug is not activated.
 *
 * 2) Other part is based on extensions.firebug.allPagesActivation option. This option
 *    can be set to the following values:
 *    none: The option isn't used (default value)
 *    on:   Firebug is activated for all URLs.
 *    off:  Firebug is never activated.
 *
 *    This logic has higher priority over the URL annotations.
 *    If "off" options is selected, all existing URL annotations are removed.
 */
Firebug.Activation = Obj.extend(Firebug.Module,
{
    dispatchName: "activation",

    // called once
    initializeUI: function()
    {
        Firebug.Module.initializeUI.apply(this, arguments);

        TabWatcher.initializeUI();
        TabWatcher.addListener(this);
    },

    shutdown: function()
    {
        Firebug.Module.shutdown.apply(this, arguments);

        TabWatcher.removeListener(this);
    },

    // true if the Places annotation the URI "firebugged"
    shouldCreateContext: function(browser, url, userCommands)
    {
        if (FBTrace.DBG_ACTIVATION)
            FBTrace.sysout("shouldCreateContext allPagesActivation " +
                Firebug.allPagesActivation);

        if (Firebug.allPagesActivation == "on")
            return true;

        // if about:blank gets thru, 1483 fails
        if (Firebug.filterSystemURLs && Url.isSystemURL(url))
            return false;

        if (userCommands)
            return true;

        // document.open on a firebugged page
        if (browser && browser.showFirebug && url.substr(0, 8) === "wyciwyg:")
            return true;

        try
        {
            var uri = this.convertToURIKey(url, Firebug.activateSameOrigin);
            if (!uri)
                return false;

            var hasAnnotation = Annotations.pageHasAnnotation(uri);

            if (FBTrace.DBG_ACTIVATION)
            {
                FBTrace.sysout("shouldCreateContext hasAnnotation " + hasAnnotation +
                    " for " + uri.spec + " in " +
                    (browser ? browser.contentWindow.location : "no browser") +
                    " using activateSameOrigin: " + Firebug.activateSameOrigin);
            }

            // Annotated, so return the value.
            if (hasAnnotation)
                return this.checkAnnotation(browser, uri);

            if (browser.FirebugLink) // then Firebug.TabWatcher found a connection
            {
                var dst = browser.FirebugLink.dst;
                var dstURI = this.convertToURIKey(dst.spec, Firebug.activateSameOrigin);

                if (FBTrace.DBG_ACTIVATION)
                {
                    FBTrace.sysout("shouldCreateContext found FirebugLink pointing to " +
                        dstURI.spec, browser.FirebugLink);
                }

                if (dstURI && dstURI.equals(uri)) // and it matches us now
                {
                    var srcURI = this.convertToURIKey(browser.FirebugLink.src.spec,
                        Firebug.activateSameOrigin);

                    if (srcURI)
                    {
                        if (FBTrace.DBG_ACTIVATION)
                        {
                            FBTrace.sysout("shouldCreateContext found FirebugLink pointing from " +
                                srcURI.spec, browser.FirebugLink);
                        }

                        // and it's on the same domain
                        if (srcURI.schemeIs("file") || (dstURI.host == srcURI.host))
                        {
                            hasAnnotation = Annotations.pageHasAnnotation(srcURI);
                            if (hasAnnotation) // and the source page was annotated.
                            {
                                var srcShow = this.checkAnnotation(browser, srcURI);
                                if (srcShow)  // and the source annotation said show it
                                    this.watchBrowser(browser);  // so we show dst as well.
                                return srcShow;
                            }
                        }
                    }
                }
                else
                {
                    if (FBTrace.DBG_ACTIVATION)
                        FBTrace.sysout("shouldCreateContext FirebugLink does not match " +
                            uri.spec, browser.FirebugLink);
                }
            }
            else if (browser.contentWindow.opener)
            {
                var openerContext = Firebug.TabWatcher.getContextByWindow(
                    browser.contentWindow.opener);

                if (FBTrace.DBG_ACTIVATION)
                    FBTrace.sysout("shouldCreateContext opener found, has " +
                        (openerContext ? "a " : "no ") + " context: " +
                        browser.contentWindow.opener.location);

                if (openerContext)
                    return true;  // popup windows of Firebugged windows are Firebugged
            }

            return false;   // don't createContext
        }
        catch (exc)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("pageHasAnnotation FAILS for url: " + url + " which gave uri " +
                    (uri ? uri.spec : "null"), exc);
        }
    },

    shouldShowContext: function(context)
    {
        return this.shouldCreateContext(context.browser, context.getWindowLocation().toString());
    },

    // Firebug is opened in browser
    watchBrowser: function(browser)
    {
        try
        {
            var annotation = "firebugged.showFirebug";
            this.setPageAnnotation(browser.currentURI.spec, annotation);
        }
        catch (e)
        {
            if (FBTrace.DBG_ERRORS)
                FBTrace.sysout("activation.watchBrowser; EXCEPTION " + e, e);
        }
    },

    // Firebug closes in browser
    unwatchBrowser: function(browser, userCommands)
    {
        var uri = browser.currentURI.spec;
        if (userCommands)  // then mark to not open virally.
            this.setPageAnnotation(uri, "firebugged.closed");
        else
            this.removePageAnnotation(uri); // unmark this URI
    },

    clearAnnotations: function()
    {
        Annotations.clear();
        Annotations.flush();

        Firebug.connection.dispatch("onClearAnnotations", []);
    },

    // process the URL to canonicalize it. Need not be reversible.
    convertToURIKey: function(url, sameOrigin)
    {
        // Remove fragment, it shouldn't have any impact on the activation.
        url = url.replace(/#.*/, "");

        var uri = Url.makeURI(Url.normalizeURL(url));

        if (Firebug.filterSystemURLs && Url.isSystemURL(url))
            return uri;

        if (url == "about:blank")  // avoid exceptions.
            return uri;

        if (uri && sameOrigin)
        {
            try
            {
                // returns the string before the path (such as "scheme://user:password@host:port").
                var prePath = uri.prePath;
                var shortURI = Url.makeURI(prePath);
                if (!shortURI)
                    return uri;

                // annoying "about" URIs throw if you access .host
                if (shortURI.scheme === "about")
                    return shortURI;

                if (shortURI.scheme === "file")
                    return shortURI;

                var host = shortURI.host;
                if (host)
                {
                    // Slice the subdomain (if any) from the URL so that activateSameOrigin works
                    // for domains (including TLD domains). So we want:
                    // 1) www.google.com -> google.com
                    // 2) www.stuff.co.nz -> stuff.co.nz
                    // 3) getfirebug.com -> getfirebug.com
                    // (XXX: This makes a.co.uk -> co.uk and mail.cn.mozilla.com -> cn.mozilla.com,
                    // which is wrong. See issue 2202.)
                    var levels = host.split('.');
                    if (levels.length > 2)
                        levels = levels.slice(1);
                    shortURI.host = levels.join('.');
                    return shortURI;
                }
            }
            catch (exc)
            {
                if (FBTrace.DBG_ERRORS)
                    FBTrace.sysout("activation.convertToURIKey returning full URI, " +
                        "activateSameOrigin FAILS for shortURI " + shortURI + " because: " + exc,
                        exc);

                return uri;
            }
        }
        return uri;
    },

    checkAnnotation: function(browser, uri)
    {
        var annotation = Annotations.getPageAnnotation(uri);

        if (FBTrace.DBG_ACTIVATION)
            FBTrace.sysout("shouldCreateContext read back annotation " + annotation +
                " for uri " + uri.spec);

        // then the user closed Firebug on this page last time
        if ((Firebug.allPagesActivation != "on") && (annotation.indexOf("closed") > 0))
            return false;   // annotated as 'closed', don't create
        else
            return true;    // annotated, createContext
    },

    setPageAnnotation: function(currentURI, annotation)
    {
        var uri = this.convertToURIKey(currentURI, Firebug.activateSameOrigin);
        if (uri)
            Annotations.setPageAnnotation(uri, annotation);

        if (FBTrace.DBG_ACTIVATION || FBTrace.DBG_ANNOTATION)
            FBTrace.sysout("setPageAnnotation currentURI " + currentURI + " becomes URI key "+
                (uri ? uri.spec : "ERROR"));

        if (Firebug.activateSameOrigin)
        {
            uri = this.convertToURIKey(currentURI, false);
            if (uri)
                Annotations.setPageAnnotation(uri, annotation);

            if (FBTrace.DBG_ACTIVATION || FBTrace.DBG_ANNOTATION)
                FBTrace.sysout("setPageAnnotation with activeSameOrigin currentURI " +
                    currentURI.spec + " becomes URI key " + (uri ? uri.spec : "ERROR"));
        }
    },

    removePageAnnotation: function(currentURI)
    {
        var uri = this.convertToURIKey(currentURI, Firebug.activateSameOrigin);
        if (uri)
            Annotations.removePageAnnotation(uri);

        if (Firebug.activateSameOrigin)
        {
            uri = this.convertToURIKey(currentURI, false);
            if (uri)
                Annotations.removePageAnnotation(uri);
        }

        if (FBTrace.DBG_ACTIVATION)
            FBTrace.sysout("Firebug.Activation.unwatchBrowser untagged "+uri.spec);
    },

    // stops at the first fn(uri) that returns a true value
    iterateAnnotations: function(fn)
    {
        var annotations = Annotations.getAnnotations(this.annotationName);
        for (var uri in annotations)
        {
            var rc = fn(uri, annotations[uri]);
            if (rc)
                return rc;
        }
    },
});

// ********************************************************************************************* //
// Registration

Firebug.registerModule(Firebug.Activation);

return Firebug.Activation;

// ********************************************************************************************* //
});
<|endoftext|>


<commit_before>/**
 * HistoryController
 *
 * @module      ::  Controller
 * @description ::  Contains logic for handling requests.
 */
var jQuery = require("jquery");
var JsonDiffPatch = require("jsondiffpatch");
var moment = require("moment-timezone");

module.exports = {
    /**
     * Main history action.
     *
     * @param   {Request}   req Request object
     * @param   {Response}  res Response object
     */
    index: function(req, res) {
        var objectId = req.param("objectId");
        var objectName = req.param("objectName");
        var data = [];

        // Fetch history rows
        History
            .find()
            .where({
                objectName: objectName,
                objectId: objectId
            })
            .sort("id ASC")
            .done(function(error, data) {
                var histories = [];

                // Remove duplicate rows
                jQuery.each(data, function(key, row) {
                    if (key === 0
                        || row.objectData !== data[key - 1].objectData
                        || row.message !== data[key - 1].message
                    ) {
                        histories.push(row);
                    }
                });

                // Process history data
                processHistoryData(histories);
            });

        /**
         * Function process history data and fetches possible relation data
         * from models.
         *
         * Please note that this function is very complicated so be very
         * carefully when you change this functionality - good luck.
         *
         * @param   {sails.helper.history[]}  histories
         */
        function processHistoryData(histories) {
            var dataCount = histories.length;

            // First call makeView, this is needed for objects that have no history
            makeView();

            // Iterate history data
            jQuery.each(histories, function(key, history) {
                var dateObject = DateService.convertDateObjectToUtc(history.createdAt);

                var historyRow = {
                    stamp: dateObject.tz(req.user.momentTimezone),
                    data: []
                };

                // First record, assume that object is created at this point
                if (key === 0) {
                    historyRow.message = "Object created";

                    data.push(historyRow);

                    makeView();
                } else { // Otherwise we have some object data updated
                    if (history.message) {
                        historyRow.message = history.message;
                    }

                    // Determine previous and current rows as JSON objects
                    var previousRow = JSON.parse(histories[key - 1].objectData);
                    var currentRow = JSON.parse(history.objectData);

                    // Calculate object difference to previous one
                    var difference = JsonDiffPatch.diff(previousRow, currentRow);

                    // No difference between objects
                    if (typeof difference == "undefined") {
                        dataCount--;
                    } else { // Otherwise make data row
                        var changeCount = _.size(difference);

                        // Iterate each difference
                        jQuery.each(difference, function(column, value) {
                            var valueOld    = false;
                            var objectIdOld = false;
                            var valueNew    = false;
                            var objectIdNew = false;
                            var columnType  = false;
                            var changeType  = '';

                            if (value.length === 3) {
                                changeType = "delete";
                            } else if (value.length == 2) {
                                changeType = "update";

                                valueOld    = value[0];
                                objectIdOld = value[0];
                                valueNew    = value[1];
                                objectIdNew = value[1];
                            } else {
                                changeType = "insert";

                                valueNew    = value[0];
                                objectIdNew = value[0];
                            }

                            /**
                             * Magic happens here, we can assume that attributes which ends with 'Id'
                             * strings are actual relations to another models.
                             *
                             * In these cases we want to fetch actual text values for changed old and
                             * new values.
                             *
                             * Note that fetching old and new value must be done at in same process
                             * otherwise this doesn't work right.
                             */
                            if (column.match(/Id$/) !== null) {
                                var object = column.charAt(0).toUpperCase() + column.slice(1, -2);

                                // In project object managerId refers to User object
                                if (object == "Manager") {
                                    object = "User";
                                }

                                columnType = 'relation';

                                // Only fetch possible relation data if change type is insert or update
                                if (changeType != 'delete') {
                                    // Fetch new value
                                    global[object]
                                        .findOne(objectIdNew)
                                        .done(function(error, objectData) {
                                            // Store real new value
                                            valueNew = (!objectData) ? "none" : objectData.objectTitle();

                                            // Fetch old value only in update
                                            if (changeType == 'update') {
                                                // Fetch old value
                                                global[object]
                                                    .findOne(objectIdOld)
                                                    .done(function(error, objectData) {
                                                        // Store real old value
                                                        valueOld = (!objectData) ? "none" : objectData.objectTitle();

                                                        // Make necessary checks if we can show page or not
                                                        checkData();
                                                    });
                                            } else {
                                                checkData();
                                            }
                                        });
                                } else {
                                    checkData();
                                }
                            } else { // No relation
                                // Determine column type
                                if (valueOld === true && valueNew === false
                                    || valueOld === false && valueNew === true
                                ) {
                                    columnType = 'boolean';
                                } else {
                                    columnType = 'normal';
                                }

                                checkData();
                            }

                            /**
                             * Private function to check that we have processed all required
                             * data for view.
                             *
                             * This function is called x times in this action.
                             */
                            function checkData() {
                                var ready = false;

                                // Add data to history row object
                                historyRow.data.push({
                                    column: column,
                                    columnType: columnType,
                                    changeType: changeType,
                                    valueNew: valueNew,
                                    valueOld: valueOld,
                                    valueIdOld: objectIdOld,
                                    valueIdNew: objectIdNew
                                });

                                // Check if have processed all required rows
                                if (changeCount == historyRow.data.length) {
                                    ready = true;

                                    // Add data to view object
                                    data.push(historyRow);
                                }

                                if (ready) {
                                    makeView();
                                }
                            }
                        });
                    }
                }
            });

            /**
             * This function will make actual view to client.
             */
            function makeView() {
                var ready = data.length === dataCount;

                // We're ready to show some stuff
                if (ready) {
                    // Data sorting function
                    function sortByStamp(a, b) {
                        if (a.stamp < b.stamp)
                            return 1;
                        if (a.stamp > b.stamp)
                            return -1;
                        return 0;
                    }

                    // Sort data
                    data.sort(sortByStamp);

                    // Make view
                    res.view({
                        layout: req.isAjax ? "layout_ajax" : "layout",
                        currentUser: req.user,
                        data: data
                    });
                }
            }
        }
    }
};
<commit_msg>Fixed object history to show *Id fields right in cases those aren't really relations.<commit_after>/**
 * HistoryController
 *
 * @module      ::  Controller
 * @description ::  Contains logic for handling requests.
 */
var jQuery = require("jquery");
var JsonDiffPatch = require("jsondiffpatch");
var moment = require("moment-timezone");

module.exports = {
    /**
     * Main history action.
     *
     * @param   {Request}   req Request object
     * @param   {Response}  res Response object
     */
    index: function(req, res) {
        var objectId = req.param("objectId");
        var objectName = req.param("objectName");
        var data = [];

        // Fetch history rows
        History
            .find()
            .where({
                objectName: objectName,
                objectId: objectId
            })
            .sort("id ASC")
            .done(function(error, data) {
                var histories = [];

                // Remove duplicate rows
                jQuery.each(data, function(key, row) {
                    if (key === 0
                        || row.objectData !== data[key - 1].objectData
                        || row.message !== data[key - 1].message
                    ) {
                        histories.push(row);
                    }
                });

                // Process history data
                processHistoryData(histories);
            });

        /**
         * Function process history data and fetches possible relation data
         * from models.
         *
         * Please note that this function is very complicated so be very
         * carefully when you change this functionality - good luck.
         *
         * @param   {sails.helper.history[]}  histories
         */
        function processHistoryData(histories) {
            var dataCount = histories.length;

            // First call makeView, this is needed for objects that have no history
            makeView();

            // Iterate history data
            jQuery.each(histories, function(key, history) {
                var dateObject = DateService.convertDateObjectToUtc(history.createdAt);

                var historyRow = {
                    stamp: dateObject.tz(req.user.momentTimezone),
                    data: []
                };

                // First record, assume that object is created at this point
                if (key === 0) {
                    historyRow.message = "Object created";

                    data.push(historyRow);

                    makeView();
                } else { // Otherwise we have some object data updated
                    if (history.message) {
                        historyRow.message = history.message;
                    }

                    // Determine previous and current rows as JSON objects
                    var previousRow = JSON.parse(histories[key - 1].objectData);
                    var currentRow = JSON.parse(history.objectData);

                    // Calculate object difference to previous one
                    var difference = JsonDiffPatch.diff(previousRow, currentRow);

                    // No difference between objects
                    if (typeof difference == "undefined") {
                        dataCount--;
                    } else { // Otherwise make data row
                        var changeCount = _.size(difference);

                        // Iterate each difference
                        jQuery.each(difference, function(column, value) {
                            var valueOld    = false;
                            var objectIdOld = false;
                            var valueNew    = false;
                            var objectIdNew = false;
                            var columnType  = false;
                            var changeType  = '';

                            if (value.length === 3) {
                                changeType = "delete";
                            } else if (value.length == 2) {
                                changeType = "update";

                                valueOld    = value[0];
                                objectIdOld = value[0];
                                valueNew    = value[1];
                                objectIdNew = value[1];
                            } else {
                                changeType = "insert";

                                valueNew    = value[0];
                                objectIdNew = value[0];
                            }

                            /**
                             * Magic happens here, we can assume that attributes which ends with 'Id'
                             * strings are actual relations to another models.
                             *
                             * In these cases we want to fetch actual text values for changed old and
                             * new values.
                             *
                             * Note that fetching old and new value must be done at in same process
                             * otherwise this doesn't work right.
                             */
                            if (column.match(/Id$/) !== null) {
                                var object = column.charAt(0).toUpperCase() + column.slice(1, -2);

                                // In project object managerId refers to User object
                                if (object == "Manager") {
                                    object = "User";
                                }

                                columnType = 'relation';

                                // Only fetch possible relation data if change type is insert or update
                                if (global[object] && typeof global[object] === "object" && changeType != 'delete') {
                                    // Fetch new value
                                    global[object]
                                        .findOne(objectIdNew)
                                        .done(function(error, objectData) {
                                            // Store real new value
                                            valueNew = (!objectData) ? "none" : objectData.objectTitle();

                                            // Fetch old value only in update
                                            if (changeType == 'update') {
                                                // Fetch old value
                                                global[object]
                                                    .findOne(objectIdOld)
                                                    .done(function(error, objectData) {
                                                        // Store real old value
                                                        valueOld = (!objectData) ? "none" : objectData.objectTitle();

                                                        // Make necessary checks if we can show page or not
                                                        checkData();
                                                    });
                                            } else {
                                                checkData();
                                            }
                                        });
                                } else {
                                    checkData();
                                }
                            } else { // No relation
                                // Determine column type
                                if (valueOld === true && valueNew === false
                                    || valueOld === false && valueNew === true
                                ) {
                                    columnType = 'boolean';
                                } else {
                                    columnType = 'normal';
                                }

                                checkData();
                            }

                            /**
                             * Private function to check that we have processed all required
                             * data for view.
                             *
                             * This function is called x times in this action.
                             */
                            function checkData() {
                                var ready = false;

                                // Add data to history row object
                                historyRow.data.push({
                                    column: column,
                                    columnType: columnType,
                                    changeType: changeType,
                                    valueNew: valueNew,
                                    valueOld: valueOld,
                                    valueIdOld: objectIdOld,
                                    valueIdNew: objectIdNew
                                });

                                // Check if have processed all required rows
                                if (changeCount == historyRow.data.length) {
                                    ready = true;

                                    // Add data to view object
                                    data.push(historyRow);
                                }

                                if (ready) {
                                    makeView();
                                }
                            }
                        });
                    }
                }
            });

            /**
             * This function will make actual view to client.
             */
            function makeView() {
                var ready = data.length === dataCount;

                // We're ready to show some stuff
                if (ready) {
                    // Data sorting function
                    function sortByStamp(a, b) {
                        if (a.stamp < b.stamp)
                            return 1;
                        if (a.stamp > b.stamp)
                            return -1;
                        return 0;
                    }

                    // Sort data
                    data.sort(sortByStamp);

                    // Make view
                    res.view({
                        layout: req.isAjax ? "layout_ajax" : "layout",
                        currentUser: req.user,
                        data: data
                    });
                }
            }
        }
    }
};
<|endoftext|>


<commit_before>// Client
var sock = require('net').Socket();
sock.connect(8080);

sock.on('data', function (data) {
	console.log(data.toString());
});

process.stdin.on('data', function (text) {
	if (text === 'quit\n') {
		console.log("bye!");
		process.exit();
	}
	sock.write(util.inspect(text));
});

sock.end();<commit_msg>Kinda works<commit_after>// Client
var stdin = process.openStdin();
var sock  = require('net').Socket();

sock.connect(8080);

sock.on('data', function (data) {
	console.log(data.toString());
});

stdin.addListener("data", function(text) {
	try {
		sock.write(text.toString().trim());
		sock.end();
	}

	catch (err) {
		console.log(err.message);
	}
});<|endoftext|>


<commit_before>const fs = require("fs")
const path = require("path")
const ora = require("ora")
const { execSync } = require("child_process")

const BUILD_DIR = path.resolve("build/packages")
const EXAMPLES_DIR = path.resolve("examples")

function listDirs(dir) {
  return fs
    .readdirSync(dir)
    .filter(dirname => fs.lstatSync(path.join(dir, dirname)).isDirectory())
}

function linkDependencies(example) {
  const spinner = ora("Linking " + example)
  const dependencies = packages.map(name => `@lingui/${name}`).join(" ")
  execSync("yalc link " + dependencies, {
    cwd: path.join(EXAMPLES_DIR, example)
  })
  spinner.succeed()
}

function linkPackage(packageName) {
  execSync("yalc publish", { cwd: path.join(BUILD_DIR, packageName) })
}

const packages = listDirs(BUILD_DIR)
const examples = listDirs(EXAMPLES_DIR)

packages.forEach(linkPackage)
examples.forEach(linkDependencies)
<commit_msg>chore: remove ora from setup script for intergration tests<commit_after>const fs = require("fs")
const path = require("path")
const { execSync } = require("child_process")

const BUILD_DIR = path.resolve("build/packages")
const EXAMPLES_DIR = path.resolve("examples")

function listDirs(dir) {
  return fs
    .readdirSync(dir)
    .filter(dirname => fs.lstatSync(path.join(dir, dirname)).isDirectory())
}

function linkDependencies(example) {
  console.log("Linking " + example)
  const dependencies = packages.map(name => `@lingui/${name}`).join(" ")
  execSync("yalc link " + dependencies, {
    cwd: path.join(EXAMPLES_DIR, example)
  })
}

function linkPackage(packageName) {
  execSync("yalc publish", { cwd: path.join(BUILD_DIR, packageName) })
}

const packages = listDirs(BUILD_DIR)
const examples = listDirs(EXAMPLES_DIR)

packages.forEach(linkPackage)
examples.forEach(linkDependencies)
<|endoftext|>


<commit_before>var document,
    window,
    funcArray;

(function () {
    "use strict";
    var d = new Date(),
        day = d.getDate(),
        month = d.getMonth() + 1,
        year = d.getFullYear(),
        dayOfWeek = d.getDay(),
        dayOfMonth,
        endOfMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
        lang = "",
        dayOfWeekName = [
            ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
            ["Pn", "Wt", "Śr", "Cz", "Pt", "So", "Nd"]
        ],
        monthName = [
            ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
            ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"]
        ],
        tableHeader = [
            ["previous month", "next month"],
            ["poprzedni miesiąc", "następny miesiąc"]
        ],
        table,
        numberOfWeeks;
    if (lang === undefined || lang === "" || lang === "en") {
        lang = 0;
    } else if (lang === "pl") {
        lang = 1;
    }
    if (dayOfWeek === 0) {
        dayOfWeek = 7;
    }
    if (year % 4 === 0) {
        endOfMonth[1] = 29;
    }
    endOfMonth.unshift("");
    dayOfWeekName[lang].unshift("");
    monthName[lang].unshift("");

    /* table with all day of current month */
    function tableOfDays(a, b, c) { // a - day, b - No. day in the week, c - month
        var x, // day in the month
            y; // day of the week
        dayOfMonth = [];
        dayOfMonth[0] = "";
        for (x = a, y = b; x > 0; x -= 1, y -= 1) {
            if (y === 0) {
                y = 7;
            }
            dayOfMonth[x] = {
                dayInMonth: x,
                dayInWeek: y
            };
        }
        for (x = a, y = b; x < endOfMonth[c] + 1; x += 1, y += 1) {
            if (y === 8) {
                y = 1;
            }
            dayOfMonth[x] = {
                dayInMonth: x,
                dayInWeek: y
            };
        }
        return dayOfMonth;
    }

    function nOw() {
        var i = 1;
        if (dayOfMonth[1].dayInWeek !== 1) {
            numberOfWeeks = 1;
        } else {
            numberOfWeeks = 0;
        }
        while (dayOfMonth[i]) {
            if (dayOfMonth[i].dayInWeek === 1) {
                numberOfWeeks += 1;
            }
            i += 1;
        }
        return numberOfWeeks;
    }

    function createCalendar(c) {
        var trOn = "
",
            trOff = "
",
            monthHeader,
            weekHeader = "",
            content = "",
            i = 1,
            j = 1;
        monthHeader = trOn + 'navigate_before	' + monthName[lang][c] + ', ' + year + '	navigate_next	' + trOff;
        while (dayOfWeekName[lang][i]) {
            weekHeader += '' + dayOfWeekName[lang][i] + '	';
            i += 1;
        }
        for (j; j < numberOfWeeks + 1; j += 1) {
            content += trOn + '							' + trOff;
        }
        table = '
' + monthHeader + trOn + weekHeader + trOff + content + "
";
        return table;
    }

    function drawCalendar(c) {
        var a = 0, // number of week
            b = 1; // number of day
        if (dayOfMonth[1].dayInWeek !== 1) {
            a = 1;
        }
        document.getElementById("calendar").innerHTML = table;
        for (b; b < endOfMonth[c] + 1; b += 1) {
            if (dayOfMonth[b].dayInWeek === 1) {
                a += 1;
            }
            document.getElementById(a + "-" + dayOfMonth[b].dayInWeek).innerHTML = dayOfMonth[b].dayInMonth;
            document.getElementById(a + "-" + dayOfMonth[b].dayInWeek).className += "currentMonth";
        }
        if (month === d.getMonth() + 1 && year === d.getFullYear()) {
            document.getElementsByClassName("currentMonth")[d.getDate() - 1].className += " today";
        }
    }

    dayOfMonth = (tableOfDays(day, dayOfWeek, month));
    numberOfWeeks = (nOw());
    table = (createCalendar(month));
    (drawCalendar(month));

    function prevMonth() {
        month = month - 1;
        if (month === 0) {
            month = 12;
            year = year - 1;
            if (year % 4 === 0) {
                endOfMonth[2] = 29;
            } else {
                endOfMonth[2] = 28;
            }
        }
        dayOfWeek = dayOfMonth[1].dayInWeek - 1;
        if (dayOfWeek === 0) {
            dayOfWeek = 7;
        }
        dayOfMonth = (tableOfDays(endOfMonth[month], dayOfWeek, month));
        numberOfWeeks = (nOw());
        table = (createCalendar(month));
        (drawCalendar(month));
    }

    function nextMonth() {
        dayOfWeek = dayOfMonth[(endOfMonth[month])].dayInWeek + 1;
        if (dayOfWeek === 8) {
            dayOfWeek = 1;
        }
        month = month + 1;
        if (month === 13) {
            month = 1;
            year = year + 1;
            if (year % 4 === 0) {
                endOfMonth[2] = 29;
            } else {
                endOfMonth[2] = 28;
            }
        }
        dayOfMonth = (tableOfDays(1, dayOfWeek, month));
        numberOfWeeks = (nOw());
        table = (createCalendar(month));
        (drawCalendar(month));
    }

    window.onkeyup = function (e) {
        var key;
        if (e.keyCode) {
            key = e.keyCode;
        } else {
            key = e.which;
        }
        if (key === 37) {
            prevMonth();
        } else if (key === 39) {
            nextMonth();
        }
    };

    funcArray = {
        prevMonth: prevMonth,
        nextMonth: nextMonth
    };
}());
<commit_msg>German added<commit_after>var document,
    window,
    funcArray;

(function () {
    "use strict";
    var d = new Date(),
        day = d.getDate(),
        month = d.getMonth() + 1,
        year = d.getFullYear(),
        dayOfWeek = d.getDay(),
        dayOfMonth,
        endOfMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
        lang = "",
        dayOfWeekName = [
            ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
            ["Pn", "Wt", "Śr", "Cz", "Pt", "So", "Nd"],
            ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"]
        ],
        monthName = [
            ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
            ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"],
            ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"]
        ],
        tableHeader = [
            ["previous month", "next month"],
            ["poprzedni miesiąc", "następny miesiąc"],
            ["Vormonat", "nächsten Monat"]
        ],
        table,
        numberOfWeeks;
    if (lang === undefined || lang === "" || lang === "en") {
        lang = 0;
    } else if (lang === "pl") {
        lang = 1;
    } else if (lang === "de") {
        lang = 2;
    }
    if (dayOfWeek === 0) {
        dayOfWeek = 7;
    }
    if (year % 4 === 0) {
        endOfMonth[1] = 29;
    }
    endOfMonth.unshift("");
    dayOfWeekName[lang].unshift("");
    monthName[lang].unshift("");

    /* table with all day of current month */
    function tableOfDays(a, b, c) { // a - day, b - No. day in the week, c - month
        var x, // day in the month
            y; // day of the week
        dayOfMonth = [];
        dayOfMonth[0] = "";
        for (x = a, y = b; x > 0; x -= 1, y -= 1) {
            if (y === 0) {
                y = 7;
            }
            dayOfMonth[x] = {
                dayInMonth: x,
                dayInWeek: y
            };
        }
        for (x = a, y = b; x < endOfMonth[c] + 1; x += 1, y += 1) {
            if (y === 8) {
                y = 1;
            }
            dayOfMonth[x] = {
                dayInMonth: x,
                dayInWeek: y
            };
        }
        return dayOfMonth;
    }

    function nOw() {
        var i = 1;
        if (dayOfMonth[1].dayInWeek !== 1) {
            numberOfWeeks = 1;
        } else {
            numberOfWeeks = 0;
        }
        while (dayOfMonth[i]) {
            if (dayOfMonth[i].dayInWeek === 1) {
                numberOfWeeks += 1;
            }
            i += 1;
        }
        return numberOfWeeks;
    }

    function createCalendar(c) {
        var trOn = "
",
            trOff = "
",
            monthHeader,
            weekHeader = "",
            content = "",
            i = 1,
            j = 1;
        monthHeader = trOn + 'navigate_before	' + monthName[lang][c] + ', ' + year + '	navigate_next	' + trOff;
        while (dayOfWeekName[lang][i]) {
            weekHeader += '' + dayOfWeekName[lang][i] + '	';
            i += 1;
        }
        for (j; j < numberOfWeeks + 1; j += 1) {
            content += trOn + '							' + trOff;
        }
        table = '
' + monthHeader + trOn + weekHeader + trOff + content + "
";
        return table;
    }

    function drawCalendar(c) {
        var a = 0, // number of week
            b = 1; // number of day
        if (dayOfMonth[1].dayInWeek !== 1) {
            a = 1;
        }
        document.getElementById("calendar").innerHTML = table;
        for (b; b < endOfMonth[c] + 1; b += 1) {
            if (dayOfMonth[b].dayInWeek === 1) {
                a += 1;
            }
            document.getElementById(a + "-" + dayOfMonth[b].dayInWeek).innerHTML = dayOfMonth[b].dayInMonth;
            document.getElementById(a + "-" + dayOfMonth[b].dayInWeek).className += "currentMonth";
        }
        if (month === d.getMonth() + 1 && year === d.getFullYear()) {
            document.getElementsByClassName("currentMonth")[d.getDate() - 1].className += " today";
        }
    }

    dayOfMonth = (tableOfDays(day, dayOfWeek, month));
    numberOfWeeks = (nOw());
    table = (createCalendar(month));
    (drawCalendar(month));

    function prevMonth() {
        month = month - 1;
        if (month === 0) {
            month = 12;
            year = year - 1;
            if (year % 4 === 0) {
                endOfMonth[2] = 29;
            } else {
                endOfMonth[2] = 28;
            }
        }
        dayOfWeek = dayOfMonth[1].dayInWeek - 1;
        if (dayOfWeek === 0) {
            dayOfWeek = 7;
        }
        dayOfMonth = (tableOfDays(endOfMonth[month], dayOfWeek, month));
        numberOfWeeks = (nOw());
        table = (createCalendar(month));
        (drawCalendar(month));
    }

    function nextMonth() {
        dayOfWeek = dayOfMonth[(endOfMonth[month])].dayInWeek + 1;
        if (dayOfWeek === 8) {
            dayOfWeek = 1;
        }
        month = month + 1;
        if (month === 13) {
            month = 1;
            year = year + 1;
            if (year % 4 === 0) {
                endOfMonth[2] = 29;
            } else {
                endOfMonth[2] = 28;
            }
        }
        dayOfMonth = (tableOfDays(1, dayOfWeek, month));
        numberOfWeeks = (nOw());
        table = (createCalendar(month));
        (drawCalendar(month));
    }

    window.onkeyup = function (e) {
        var key;
        if (e.keyCode) {
            key = e.keyCode;
        } else {
            key = e.which;
        }
        if (key === 37) {
            prevMonth();
        } else if (key === 39) {
            nextMonth();
        }
    };

    funcArray = {
        prevMonth: prevMonth,
        nextMonth: nextMonth
    };
}());
<|endoftext|>


<commit_before>var appConfig = require('./passport-config'),
    passport = require('passport'),
    passportOauth = require('passport-oauth'),
    OAuthStrategy = passportOauth.OAuthStrategy,
    OAuth2Strategy = passportOauth.OAuth2Strategy,
    request = require('request');

var passportPlugin = {};

var storage = undefined;

var hasApi = function(apiName) {
  return typeof(appConfig[apiName]) === "object"
         && appConfig[apiName].enabled === true;
};
passportPlugin.hasApi = hasApi;

var findUser = function(apiName,req,callback) {
  if(req.session.user == undefined) {
    callback(undefined);
  }
  else if(!hasApi(apiName)) {
    callback(undefined);
  }
  else {
    if(appConfig[apiName].type == 'api-key' ||
       appConfig[apiName].type == 'public') {
      callback({ api : apiName });
    }
    else if(appConfig[apiName].type == 'composite') {
      callback({ isComposite : true, api : apiName });
    }
    else {
      storage.findUserAccount({'_login' : req.session.user.id, '_api' : apiName}, function(err,user){
        // todo - error handling
        callback(user);
      });
    }
  }
};
passportPlugin.findUser = findUser;

var removeUser = function(apiName,req,callback) {
  if(req.session.user == undefined) {
    callback(false);
  }
  else if(!hasApi(apiName)) {
    callback(false);
  }
  else {
    findUser(apiName,req, function(user) {
      if(user && user._api) { // these can be deleted
        storage.removeUserAccount({'_login' : req.session.user.id, '_api' : apiName}, function(err){
          callback(!err);
        });
      }
      else {
        callback(false);
      }
    });
  }
};
passportPlugin.removeUser = removeUser;

var apiDetails = function(apiId) {
  if(!hasApi(apiId)) {
    return undefined;
  }

  var apiConfig = appConfig[apiId];
  var apiName = apiConfig.name ? apiConfig.name : apiId;
  var authFlag = apiConfig.type.match(/^oauth/)?true:false;
  var api = { 'id' : apiId, 'name' : apiName, 'authRequired' : authFlag };

  return api;
};
passportPlugin.apiDetails=apiDetails;

var allApiDetails = function() {
  var apis = [];
  for(var apiName in appConfig) {
    var api = apiDetails(apiName)
    if(api) {
      apis.push(api);
    }
  }
  apis.sort(function(a,b) {
    if(a.id==b.id) return 0;
    if(a.id<b.id) return -1;
    else return 1;
  });
};
passportPlugin.allApiDetails=allApiDetails;

var init = function(app, dataStorage) {
  storage = dataStorage;

  app.use(passport.initialize());
  app.use(passport.session());

  // store user in persistent storage for passport
  passport.serializeUser(function(user, done) {
    //console.log('serialize user ' + user._id);

    storage.saveUserAccount(user, function(err,doc) {
      // todo - error handling
      done(null, user._id);
    });
  });

  // retrieve user from persistent store for passport
  passport.deserializeUser(function(id, done) {
    //console.log('deserialize user ' + id);

    storage.findUserAccount({'_id' : id}, function(err,user){
      // todo - error handling
      done(null, user);
    });
  });

  // load all app configs
  for(var apiName in appConfig) {
    if(hasApi(apiName)) {
      console.log('register = ' + apiName);
      register(apiName);
    }
  }

};
passportPlugin.init = init;

var register = function(apiName) {

  var strategyCallback = function(req, token, tokenSecret, profile, done) {
    var fakeUser = { 'token' : token,
                     'tokenSecret' : tokenSecret };
    var options =  { 'method' : 'GET',
                     'uri' : appConfig[apiName].defaultLoadUrl };
    var callback = function(user, data) {
      var fullUser = null;

      //var profileUser = appConfig[apiName].userElementName?data[appConfig[apiName].userElementName]:data;
      var profileUserId = null;
      if(data) {
        var userIdPath = appConfig[apiName].userIdPath.split('.');
        var profileUser = data;
        for(var i=0;i<userIdPath.length;i++) {
          if(i==userIdPath.length-1) {
            profileUserId = profileUser[userIdPath[i]];
          }
          else {
            profileUser = profileUser[userIdPath[i]];
          }
        }
      }

      if(profileUserId) {
        fullUser = {};
        fullUser.profile = data;
        fullUser._id = apiName + "~" + profileUserId;
        fullUser.token = fakeUser.token;
        fullUser.tokenSecret = fakeUser.tokenSecret;
        fullUser._login = req.session.user.id;
        fullUser._api = apiName;
      }
      done(null, fullUser);
    };
    handleRequest(apiName,fakeUser,options,callback);
  };

  var apiCallbackUrl = appConfig._host + '/auth/' + apiName  + '/callback';
  if(appConfig[apiName].type == 'oauth-1.0') {
    // setup oauth1 through passport
    passport.use(apiName,
      new OAuthStrategy({
          userAuthorizationURL: appConfig[apiName].authorizationUrl,
          requestTokenURL: appConfig[apiName].requestTokenUrl,
          accessTokenURL: appConfig[apiName].accessTokenUrl,
          consumerKey: appConfig[apiName].clientId,
          consumerSecret: appConfig[apiName].clientSecret,
          callbackURL: apiCallbackUrl,
          passReqToCallback: true
      }, strategyCallback
    ));
  }
  else if(appConfig[apiName].type == 'oauth-2.0') {
    // setup oauth2 through passport
    passport.use(apiName,
      new OAuth2Strategy({
          authorizationURL: appConfig[apiName].authorizationUrl,
          tokenURL: appConfig[apiName].accessTokenUrl,
          clientID: appConfig[apiName].clientId,
          clientSecret: appConfig[apiName].clientSecret,
          callbackURL: apiCallbackUrl,
          passReqToCallback: true,
          customHeaders: { 'User-Agent' : 'node-oauth' }
      }, strategyCallback
    ));
  }
  else if(appConfig[apiName].type == 'public') {
    // no registration action necessary
  }
  else if(appConfig[apiName].type == 'api-key') {
    // no registration action necessary
  }
  else if(appConfig[apiName].type == 'composite') {
    // no registration action necessary
  }
  else {
    console.log(apiName + " has unknown auth type of " + appConfig[apiName].type);
  }
};
passportPlugin.register = register;

// simplified request handling
var handleRequest = function(apiName, user, options, callback) {
  console.log('handling ' + options.method + ' request to '  + apiName + ': ' + options.uri);

  if(options.method != 'GET') {
    console.log('Only handling GET request right now');
    callback(user,null);
    return;
  }

  var getCallback = function(error, body, response) {
    if(error) {
      console.log('handle request error ' + JSON.stringify(error));
      callback(user,null);
      return;
    }

    if (response.statusCode === 200) {
      //console.log("RESULT=" + body);
      callback(user,JSON.parse(body));
    } else {
      console.log('handle request error ' + response.statusCode);
      callback(user,response.statusCode);
    }
  };

  var uri = appConfig[apiName].baseUrl + options.uri;
  if(appConfig[apiName].type == 'oauth-1.0') {
    passport._strategy(apiName)._oauth.get(uri, user.token, user.tokenSecret, getCallback);
  }
  else if(appConfig[apiName].type == 'oauth-2.0') {
    passport._strategy(apiName)._oauth2.get(uri, user.token, getCallback);
  }
  else if(appConfig[apiName].type == 'api-key') {
    var headers =  {'Content-Type': 'application/json'};
    if(appConfig[apiName].isKeyInUrl === true) {
      uri += uri.indexOf('?')==-1 ? '?' : '&';
      uri += appConfig[apiName].keyName + '=' + appConfig[apiName].keyValue;
    }
    else {
      headers[appConfig[apiName].keyName] = appConfig[apiName].keyValue;
    }
    var requestOptions = { 'uri' : uri, 'method' : 'GET', 'headers' : headers };
    request(requestOptions,function (error, body, response) { getCallback(error,response,body) });
  }
  else if(appConfig[apiName].type == 'public') {
    var requestOptions = { 'uri' : uri, 'method' : 'GET', 'headers' : headers };
    request(requestOptions,function (error, body, response) { getCallback(error,response,body) });
  }
  else {
    console.log('No request handling for ' + appConfig[apiName].type);
    return;
  }
};
passportPlugin.handleRequest = handleRequest;

var handleComposite = function(apiName,options,req,done) {
  var getCallback = function(error, body) {
    if(error) {
      console.log('handle request error ' + JSON.stringify(error));
      done(null);
      return;
    }

    done(body);
  };

  var compositeAccess = {
    params : req.query,
    api : function(accessApiName,accessOptions, accessCallback) {
      var compositeAccessCallback = function(user) {
        handleRequest(accessApiName, user, accessOptions, function (user,data) {
         accessCallback(data);
        });
      };
      findUser(accessApiName,req,compositeAccessCallback);
    },
    query : function(queryParams, queryCallback) {
      var meta = {
        'user' : req.session.user.id
      };
      storage.queryUserData(meta, queryParams,queryCallback);
    }
  };

  appConfig[apiName].buildComposite(compositeAccess, options, getCallback);
};
passportPlugin.handleComposite = handleComposite;

var auth = function(apiName,streams) {
  //console.log('auth attempt');
  passport.authenticate(apiName)(streams.req,streams.res,streams.next);
}
passportPlugin.auth = auth;

var authCallback = function(apiName,urls,streams) {
  //console.log('authCallback attempt');
  passport.authenticate(apiName,
                          {
                            'successRedirect' : urls.successUrl,
                            'failureRedirect' : urls.failureUrl
                          }
                       )(streams.req,streams.res,streams.next);
}
passportPlugin.authCallback = authCallback;

var findParamStringInUri = function(paramName, paramValue, uri) {
  var paramString = paramName + '=' + paramValue;
  var paramIndex = uri.indexOf(paramString);

  if(paramIndex == -1) {
    return '';
  }
  else {
    paramIndex--;
  }

  var paramPrefix = uri.charAt(paramIndex);
  if(paramPrefix == '&') {
    paramString = '&' + paramString;
  }
  else {
    if(paramPrefix == '?' && paramIndex+paramString.length == uri.length-1) {
      paramString = '?' + paramString;
    }
    else {
      paramString = paramString + '&';
    }
  }
  return paramString;
};
passportPlugin.findParamStringInUri=findParamStringInUri;

module.exports = passportPlugin;
<commit_msg>allApiDetails correction<commit_after>var appConfig = require('./passport-config'),
    passport = require('passport'),
    passportOauth = require('passport-oauth'),
    OAuthStrategy = passportOauth.OAuthStrategy,
    OAuth2Strategy = passportOauth.OAuth2Strategy,
    request = require('request');

var passportPlugin = {};

var storage = undefined;

var hasApi = function(apiName) {
  return typeof(appConfig[apiName]) === "object"
         && appConfig[apiName].enabled === true;
};
passportPlugin.hasApi = hasApi;

var findUser = function(apiName,req,callback) {
  if(req.session.user == undefined) {
    callback(undefined);
  }
  else if(!hasApi(apiName)) {
    callback(undefined);
  }
  else {
    if(appConfig[apiName].type == 'api-key' ||
       appConfig[apiName].type == 'public') {
      callback({ api : apiName });
    }
    else if(appConfig[apiName].type == 'composite') {
      callback({ isComposite : true, api : apiName });
    }
    else {
      storage.findUserAccount({'_login' : req.session.user.id, '_api' : apiName}, function(err,user){
        // todo - error handling
        callback(user);
      });
    }
  }
};
passportPlugin.findUser = findUser;

var removeUser = function(apiName,req,callback) {
  if(req.session.user == undefined) {
    callback(false);
  }
  else if(!hasApi(apiName)) {
    callback(false);
  }
  else {
    findUser(apiName,req, function(user) {
      if(user && user._api) { // these can be deleted
        storage.removeUserAccount({'_login' : req.session.user.id, '_api' : apiName}, function(err){
          callback(!err);
        });
      }
      else {
        callback(false);
      }
    });
  }
};
passportPlugin.removeUser = removeUser;

var apiDetails = function(apiId) {
  if(!hasApi(apiId)) {
    return undefined;
  }

  var apiConfig = appConfig[apiId];
  var apiName = apiConfig.name ? apiConfig.name : apiId;
  var authFlag = apiConfig.type.match(/^oauth/)?true:false;
  var api = { 'id' : apiId, 'name' : apiName, 'authRequired' : authFlag };

  return api;
};
passportPlugin.apiDetails=apiDetails;

var allApiDetails = function() {
  var apis = [];
  for(var apiName in appConfig) {
    var api = apiDetails(apiName);
    if(api) {
      apis.push(api);
    }
  }
  apis.sort(function(a,b) {
    if(a.id==b.id) return 0;
    if(a.id<b.id) return -1;
    else return 1;
  });
  return apis;
};
passportPlugin.allApiDetails=allApiDetails;

var init = function(app, dataStorage) {
  storage = dataStorage;

  app.use(passport.initialize());
  app.use(passport.session());

  // store user in persistent storage for passport
  passport.serializeUser(function(user, done) {
    //console.log('serialize user ' + user._id);

    storage.saveUserAccount(user, function(err,doc) {
      // todo - error handling
      done(null, user._id);
    });
  });

  // retrieve user from persistent store for passport
  passport.deserializeUser(function(id, done) {
    //console.log('deserialize user ' + id);

    storage.findUserAccount({'_id' : id}, function(err,user){
      // todo - error handling
      done(null, user);
    });
  });

  // load all app configs
  for(var apiName in appConfig) {
    if(hasApi(apiName)) {
      console.log('register = ' + apiName);
      register(apiName);
    }
  }

};
passportPlugin.init = init;

var register = function(apiName) {

  var strategyCallback = function(req, token, tokenSecret, profile, done) {
    var fakeUser = { 'token' : token,
                     'tokenSecret' : tokenSecret };
    var options =  { 'method' : 'GET',
                     'uri' : appConfig[apiName].defaultLoadUrl };
    var callback = function(user, data) {
      var fullUser = null;

      //var profileUser = appConfig[apiName].userElementName?data[appConfig[apiName].userElementName]:data;
      var profileUserId = null;
      if(data) {
        var userIdPath = appConfig[apiName].userIdPath.split('.');
        var profileUser = data;
        for(var i=0;i<userIdPath.length;i++) {
          if(i==userIdPath.length-1) {
            profileUserId = profileUser[userIdPath[i]];
          }
          else {
            profileUser = profileUser[userIdPath[i]];
          }
        }
      }

      if(profileUserId) {
        fullUser = {};
        fullUser.profile = data;
        fullUser._id = apiName + "~" + profileUserId;
        fullUser.token = fakeUser.token;
        fullUser.tokenSecret = fakeUser.tokenSecret;
        fullUser._login = req.session.user.id;
        fullUser._api = apiName;
      }
      done(null, fullUser);
    };
    handleRequest(apiName,fakeUser,options,callback);
  };

  var apiCallbackUrl = appConfig._host + '/auth/' + apiName  + '/callback';
  if(appConfig[apiName].type == 'oauth-1.0') {
    // setup oauth1 through passport
    passport.use(apiName,
      new OAuthStrategy({
          userAuthorizationURL: appConfig[apiName].authorizationUrl,
          requestTokenURL: appConfig[apiName].requestTokenUrl,
          accessTokenURL: appConfig[apiName].accessTokenUrl,
          consumerKey: appConfig[apiName].clientId,
          consumerSecret: appConfig[apiName].clientSecret,
          callbackURL: apiCallbackUrl,
          passReqToCallback: true
      }, strategyCallback
    ));
  }
  else if(appConfig[apiName].type == 'oauth-2.0') {
    // setup oauth2 through passport
    passport.use(apiName,
      new OAuth2Strategy({
          authorizationURL: appConfig[apiName].authorizationUrl,
          tokenURL: appConfig[apiName].accessTokenUrl,
          clientID: appConfig[apiName].clientId,
          clientSecret: appConfig[apiName].clientSecret,
          callbackURL: apiCallbackUrl,
          passReqToCallback: true,
          customHeaders: { 'User-Agent' : 'node-oauth' }
      }, strategyCallback
    ));
  }
  else if(appConfig[apiName].type == 'public') {
    // no registration action necessary
  }
  else if(appConfig[apiName].type == 'api-key') {
    // no registration action necessary
  }
  else if(appConfig[apiName].type == 'composite') {
    // no registration action necessary
  }
  else {
    console.log(apiName + " has unknown auth type of " + appConfig[apiName].type);
  }
};
passportPlugin.register = register;

// simplified request handling
var handleRequest = function(apiName, user, options, callback) {
  console.log('handling ' + options.method + ' request to '  + apiName + ': ' + options.uri);

  if(options.method != 'GET') {
    console.log('Only handling GET request right now');
    callback(user,null);
    return;
  }

  var getCallback = function(error, body, response) {
    if(error) {
      console.log('handle request error ' + JSON.stringify(error));
      callback(user,null);
      return;
    }

    if (response.statusCode === 200) {
      //console.log("RESULT=" + body);
      callback(user,JSON.parse(body));
    } else {
      console.log('handle request error ' + response.statusCode);
      callback(user,response.statusCode);
    }
  };

  var uri = appConfig[apiName].baseUrl + options.uri;
  if(appConfig[apiName].type == 'oauth-1.0') {
    passport._strategy(apiName)._oauth.get(uri, user.token, user.tokenSecret, getCallback);
  }
  else if(appConfig[apiName].type == 'oauth-2.0') {
    passport._strategy(apiName)._oauth2.get(uri, user.token, getCallback);
  }
  else if(appConfig[apiName].type == 'api-key') {
    var headers =  {'Content-Type': 'application/json'};
    if(appConfig[apiName].isKeyInUrl === true) {
      uri += uri.indexOf('?')==-1 ? '?' : '&';
      uri += appConfig[apiName].keyName + '=' + appConfig[apiName].keyValue;
    }
    else {
      headers[appConfig[apiName].keyName] = appConfig[apiName].keyValue;
    }
    var requestOptions = { 'uri' : uri, 'method' : 'GET', 'headers' : headers };
    request(requestOptions,function (error, body, response) { getCallback(error,response,body) });
  }
  else if(appConfig[apiName].type == 'public') {
    var requestOptions = { 'uri' : uri, 'method' : 'GET', 'headers' : headers };
    request(requestOptions,function (error, body, response) { getCallback(error,response,body) });
  }
  else {
    console.log('No request handling for ' + appConfig[apiName].type);
    return;
  }
};
passportPlugin.handleRequest = handleRequest;

var handleComposite = function(apiName,options,req,done) {
  var getCallback = function(error, body) {
    if(error) {
      console.log('handle request error ' + JSON.stringify(error));
      done(null);
      return;
    }

    done(body);
  };

  var compositeAccess = {
    params : req.query,
    api : function(accessApiName,accessOptions, accessCallback) {
      var compositeAccessCallback = function(user) {
        handleRequest(accessApiName, user, accessOptions, function (user,data) {
         accessCallback(data);
        });
      };
      findUser(accessApiName,req,compositeAccessCallback);
    },
    query : function(queryParams, queryCallback) {
      var meta = {
        'user' : req.session.user.id
      };
      storage.queryUserData(meta, queryParams,queryCallback);
    }
  };

  appConfig[apiName].buildComposite(compositeAccess, options, getCallback);
};
passportPlugin.handleComposite = handleComposite;

var auth = function(apiName,streams) {
  //console.log('auth attempt');
  passport.authenticate(apiName)(streams.req,streams.res,streams.next);
}
passportPlugin.auth = auth;

var authCallback = function(apiName,urls,streams) {
  //console.log('authCallback attempt');
  passport.authenticate(apiName,
                          {
                            'successRedirect' : urls.successUrl,
                            'failureRedirect' : urls.failureUrl
                          }
                       )(streams.req,streams.res,streams.next);
}
passportPlugin.authCallback = authCallback;

var findParamStringInUri = function(paramName, paramValue, uri) {
  var paramString = paramName + '=' + paramValue;
  var paramIndex = uri.indexOf(paramString);

  if(paramIndex == -1) {
    return '';
  }
  else {
    paramIndex--;
  }

  var paramPrefix = uri.charAt(paramIndex);
  if(paramPrefix == '&') {
    paramString = '&' + paramString;
  }
  else {
    if(paramPrefix == '?' && paramIndex+paramString.length == uri.length-1) {
      paramString = '?' + paramString;
    }
    else {
      paramString = paramString + '&';
    }
  }
  return paramString;
};
passportPlugin.findParamStringInUri=findParamStringInUri;

module.exports = passportPlugin;
<|endoftext|>


<commit_before>
var deps = [
  'js/vendor/jquery-*.js',
  'js/vendor/underscore-*.js',
  'js/vendor/backbone-*.js',
  'js/vendor/knockout-*.js',
  'js/vendor/knockback-*.js',
  'js/vendor/**/*.js',
  'bootstrap/js/bootstrap-tooltip.js',
  'bootstrap/js/*.js'
];

var apps = [
  'js/src/core.js',
  'js/src/**/*.js'
];

module.exports = function(grunt) {

  grunt.initConfig({
    lint: {
      files: ['grunt.js', 'js/src/**/*.js', 'js/spec/**/*.js']
    },

    // Dev-mode - just concatenate our js files
    concat: {
      app: {
        src: apps,
        dest: '../july/static/js/app.js'
      },
      vendor: {
        src: deps,
        dest: '../july/static/js/vendor.js'
      }
    },

    // Production-mode - minify app and vendor
    uglify: {
      app: {
        src: apps,
        dest: '../july/static/js/app.js'
      },
      vendor: {
        src: deps,
        dest: '../july/static/js/vendor.js'
      }
    },

    // less compilation
    less: {
      dev: {
        options: {
            paths: ["assets/bootstrap/less"]
        },
        files: {
            "../july/static/css/main.css": "less/layout.less"
        }
      },
      prod: {
        options: {
            paths: ["assets/bootstrap/less"],
            compress: true
        },
        files: {
            "../july/static/css/main.css": "less/layout.less"
        }
      }
    },

    // Watch tasks for development
    watch: {
      less: {
        files: 'less/*.less',
        tasks: 'less:dev'
      },

      js: {
        files: 'js/src/**/*.js',
        tasks: 'concat:app'
      },

      vendor: {
        files: 'js/vendor/**/*.js',
        tasks: 'concat:vendor'
      }
    },

    // Run our Jasmine tests
    jasmine: {
      src: deps.concat(apps),
      specs: 'js/spec/**/*Spec.js',
      junit: {
        output: 'junit/'
      }
    }

  });

  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
};
<commit_msg>Removed unused loadNpmTasks.<commit_after>
var deps = [
  'js/vendor/jquery-*.js',
  'js/vendor/underscore-*.js',
  'js/vendor/backbone-*.js',
  'js/vendor/knockout-*.js',
  'js/vendor/knockback-*.js',
  'js/vendor/**/*.js',
  'bootstrap/js/bootstrap-tooltip.js',
  'bootstrap/js/*.js'
];

var apps = [
  'js/src/core.js',
  'js/src/**/*.js'
];

module.exports = function(grunt) {

  grunt.initConfig({
    lint: {
      files: ['grunt.js', 'js/src/**/*.js', 'js/spec/**/*.js']
    },

    // Dev-mode - just concatenate our js files
    concat: {
      app: {
        src: apps,
        dest: '../july/static/js/app.js'
      },
      vendor: {
        src: deps,
        dest: '../july/static/js/vendor.js'
      }
    },

    // Production-mode - minify app and vendor
    uglify: {
      app: {
        src: apps,
        dest: '../july/static/js/app.js'
      },
      vendor: {
        src: deps,
        dest: '../july/static/js/vendor.js'
      }
    },

    // less compilation
    less: {
      dev: {
        options: {
            paths: ["assets/bootstrap/less"]
        },
        files: {
            "../july/static/css/main.css": "less/layout.less"
        }
      },
      prod: {
        options: {
            paths: ["assets/bootstrap/less"],
            compress: true
        },
        files: {
            "../july/static/css/main.css": "less/layout.less"
        }
      }
    },

    // Watch tasks for development
    watch: {
      less: {
        files: 'less/*.less',
        tasks: 'less:dev'
      },

      js: {
        files: 'js/src/**/*.js',
        tasks: 'concat:app'
      },

      vendor: {
        files: 'js/vendor/**/*.js',
        tasks: 'concat:vendor'
      }
    },

    // Run our Jasmine tests
    jasmine: {
      src: deps.concat(apps),
      specs: 'js/spec/**/*Spec.js',
      junit: {
        output: 'junit/'
      }
    }

  });

  grunt.loadNpmTasks('grunt-contrib-jasmine');
  grunt.loadNpmTasks('grunt-contrib-less');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');
};
<|endoftext|>


<commit_before>import configureStore from '../common/store/configureStore';
import App from '../common/components/App';
import { Provider } from 'react-redux';

global.App = App;
global.Provider = Provider;
global.configureStore = configureStore;
<commit_msg>remove global.Provider<commit_after>import configureStore from '../common/store/configureStore';
import App from '../common/components/App';

global.App = App;
global.configureStore = configureStore;
<|endoftext|>


<commit_before>var util = require('./fx_util')

function createPixel(temp, name) {
	return {
		maxTemp: temp,
		minTemp: Math.max(5, temp / 10),
		speed: Math.random()*temp/8 + 2,
		counter: Math.random()*200
	}
}

function createPixels(pixels, i, j) {
	if (i+1 >= j) return
	var m = ((j - i) >> 1) + i
	var temp2 = rndTemp()
	var temp = util.map(pixels[i].maxTemp, pixels[j].maxTemp, 50)
	temp = util.map(temp, temp2, 10)
	pixels[m] = createPixel(temp)
	createPixels(pixels, i, m)
	createPixels(pixels, m, j)
}

function rndTemp() {
	return Math.floor(Math.random()*Math.random()*200 + Math.random()*100)
}

function createAllPixels(numLeds) {
//    console.log("Recreating " + numLeds + " pixels")
	var pixels = []
	pixels[0] = createPixel(rndTemp())
	for(var i = 0; i < numLeds; i += 7) {
		var j = Math.min(i + 7, numLeds-1)
		pixels[j] = createPixel(rndTemp())
		createPixels(pixels, i, j)
	}
	return pixels
}

function createTemperatureMap(color) {
    var colors = new Array(256)
	var colormap
	console.log("fire: color=" + color)
	if (color == 'blue') {
		colormap = [
			{idx:   0, col: {r:   0, g:   0, b:   0}},
			{idx:  25, col: {r:   0, g:   0, b:  50}},
			{idx: 100, col: {r:   0, g:   0, b: 200}},
			{idx: 220, col: {r:   0, g: 100, b: 210}},
			{idx: 245, col: {r:  30, g: 160, b: 220}},
			{idx: 256, col: {r: 150, g: 200, b: 255}},
		]
	} else if (color == 'green') {
		colormap = [
			{idx:   0, col: {r:   0, b:   0, g:   0}},
			{idx:  25, col: {r:   0, b:   0, g:  50}},
			{idx: 100, col: {r:   0, b:   0, g: 200}},
			{idx: 220, col: {r:   0, b: 100, g: 210}},
			{idx: 245, col: {r:  30, b: 160, g: 220}},
			{idx: 256, col: {r: 150, b: 200, g: 255}},
		]
	} else {
		colormap = [
			{idx:   0, col: {r:   0, g:   0, b:   0}},
			{idx:  25, col: {r:  50, g:   0, b:   0}},
			{idx: 100, col: {r: 255, g:   0, b:   0}},
			{idx: 220, col: {r: 255, g: 128, b:   0}},
			{idx: 245, col: {r: 255, g: 180, b:  32}},
			{idx: 256, col: {r: 255, g: 230, b: 200}},
		]
	}

    lastIdx = 0
    lastCol = {r: 0, g: 0, b: 0}
    for(var mapidx = 0; mapidx < colormap.length; mapidx++) {
        var len = colormap[mapidx].idx - lastIdx
        var thisCol = colormap[mapidx].col
        for(var colorIdxRel = 0; colorIdxRel < len; colorIdxRel++) {
            colors[lastIdx + colorIdxRel] = util.mapColor(lastCol, thisCol, colorIdxRel * 100 / (len-1))
        }
        lastIdx = colormap[mapidx].idx
        lastCol = thisCol
    }
    return colors
}

module.exports = function(_numLeds) {
	var self = {

    // FX configuration
    _inputIndexes: [],
    numLeds: _numLeds,
    pixels: [ createAllPixels(_numLeds), createAllPixels(_numLeds) ] ,
    foo: 0,
	type: 'fire',
	color: 'red',
	temperatureColorMap: [],

    getInputIndexes: function() {
        return this._inputIndexes
    },

    getName: function() {
        return "Fire effect"
    },

	init: function() {
		temperatureColorMap = createTemperatureMap(this.color)
	},

    /** idx: the index in the effect list. Can be used to identify parameters.
     */
    getConfigHtml: function(idx) {
		var colorValues = {
			red: "Red Fire",
			blue: "Blue Fire",
			green: "Green Fire",
		}
		var typeValues = {
			fire: 'fire',
			linear: "linear",
		}
		var metaconfig = { c: [
			{ name: 'color', type: 'combo', id: 'color', desc: 'Color of the effect', css:'width:150px;', combo: colorValues },
			{ name: 'type', type: 'combo', id: 'type', desc: 'Type of the effect', css:'width:150px;', combo: typeValues },
		],
		name: this.getName(),
		}
        return util.generateConfigHtml(idx, metaconfig, this.getConfigData())
    },

	getConfigData: function() {
        return {
			color: this.color,
			type: this.type,
        }
	},

	setConfigData: function(data) {
		this.color = data.color
		this.type = data.type
        temperatureColorMap = createTemperatureMap(this.color)
	},

	saveConfigData: function() {
	    var cfg = {
	        foo: this.foo,
	        pixels: this.pixels,
			color: this.color,
			type: this.type,
	    }
		return cfg
	},

	loadConfigData: function(data) {
		this.foo = data.foo
		this.pixels = data.pixels
		this.color = data.color
		this.type = data.type
        temperatureColorMap = createTemperatureMap(this.color)
	},

    renderColors: function(inputColors) {
        var colors = []
    	this.foo += 0.1
    	if (this.foo >= 100) {
    		this.foo -= 100
    		for(var i = 0; i < this.numLeds; i++) {
    			this.pixels[1][i].counter = this.pixels[0][i].counter
    		}
    		this.pixels[0] = this.pixels[1]
    		this.pixels[1] = createAllPixels(this.numLeds)
    	}
    	for(var i = 0; i < this.numLeds; i++) {
    		this.pixels[0][i].counter += (Math.random() + 0.5) * util.map(this.pixels[0][i].speed, this.pixels[1][i].speed, this.foo)
    		if (this.pixels[0][i].counter > 200) this.pixels[0][i].counter = 0
    		var varianz = this.pixels[0][i].counter > 100 ? 200 - this.pixels[0][i].counter : this.pixels[0][i].counter
    		var maxTemp = util.map(this.pixels[0][i].maxTemp, this.pixels[1][i].maxTemp, this.foo)
    		var minTemp = util.map(this.pixels[0][i].minTemp, this.pixels[1][i].minTemp, this.foo)
    		var temp = util.map(maxTemp, minTemp, varianz)

			if (this.type == "linear") {
				temp = 255 * i / (this.numLeds-1)
			}

    		temp = Math.max(0, Math.min(Math.floor(temp), 255))
    		colors[i] = temperatureColorMap[temp]
    	}
    	return colors
    },

}
    self.init()
    return self
}
<commit_msg>slowed down fx fire<commit_after>var util = require('./fx_util')

function createPixel(temp) {
	return {
		maxTemp: temp,
		minTemp: Math.max(5, temp / 10),
//		speed: Math.random()*temp/8 + 2,
		speed: Math.random()*temp/128 + 1,
		counter: Math.random()*200
	}
}

function createSmoothedPixel(pixel1, pixel2) {
	var temp2 = rndTemp()
	var temp = util.map(pixel1.maxTemp, pixel2.maxTemp, 50)
//	temp = util.map(temp, temp2, 10)
	return {
		maxTemp: temp,
		minTemp: Math.max(5, temp / 10),
		speed: util.map(pixel1.speed, pixel2.speed, 50),
		counter: util.map(pixel1.counter, pixel2.counter, 50),
	}
}

function createPixels(pixels, i, j) {
	if (i+1 >= j) return
	var m = ((j - i) >> 1) + i
	var temp2 = rndTemp()
	var temp = util.map(pixels[i].maxTemp, pixels[j].maxTemp, 50)
	temp = util.map(temp, temp2, 10)
	pixels[m] = createPixel(temp)
    pixels[m] = createSmoothedPixel(pixels[i], pixels[j])
	createPixels(pixels, i, m)
	createPixels(pixels, m, j)
}

function rndTemp() {
	return Math.floor(Math.random()*Math.random()*200 + Math.random()*100)
}

function createAllPixels(numLeds) {
//    console.log("Recreating " + numLeds + " pixels")
	var pixels = []
	pixels[0] = createPixel(rndTemp())
	for(var i = 0; i < numLeds; i += 7) {
		var j = Math.min(i + 7, numLeds-1)
		pixels[j] = createPixel(rndTemp())
		createPixels(pixels, i, j)
	}
	return pixels
}

function createTemperatureMap(color) {
    var colors = new Array(256)
	var colormap
	console.log("fire: color=" + color)
	if (color == 'blue') {
		colormap = [
			{idx:   0, col: {r:   0, g:   0, b:   0}},
			{idx:  25, col: {r:   0, g:   0, b:  50}},
			{idx: 100, col: {r:   0, g:   0, b: 200}},
			{idx: 220, col: {r:   0, g: 100, b: 210}},
			{idx: 245, col: {r:  30, g: 160, b: 220}},
			{idx: 256, col: {r: 150, g: 200, b: 255}},
		]
	} else if (color == 'green') {
		colormap = [
			{idx:   0, col: {r:   0, b:   0, g:   0}},
			{idx:  25, col: {r:   0, b:   0, g:  50}},
			{idx: 100, col: {r:   0, b:   0, g: 200}},
			{idx: 220, col: {r:   0, b: 100, g: 210}},
			{idx: 245, col: {r:  30, b: 160, g: 220}},
			{idx: 256, col: {r: 150, b: 200, g: 255}},
		]
	} else {
		colormap = [
			{idx:   0, col: {r:   0, g:   0, b:   0}},
			{idx:  25, col: {r:  50, g:   0, b:   0}},
			{idx: 100, col: {r: 255, g:   0, b:   0}},
			{idx: 220, col: {r: 255, g: 128, b:   0}},
			{idx: 245, col: {r: 255, g: 180, b:  32}},
			{idx: 256, col: {r: 255, g: 230, b: 200}},
		]
	}

    lastIdx = 0
    lastCol = {r: 0, g: 0, b: 0}
    for(var mapidx = 0; mapidx < colormap.length; mapidx++) {
        var len = colormap[mapidx].idx - lastIdx
        var thisCol = colormap[mapidx].col
        for(var colorIdxRel = 0; colorIdxRel < len; colorIdxRel++) {
            colors[lastIdx + colorIdxRel] = util.mapColor(lastCol, thisCol, colorIdxRel * 100 / (len-1))
        }
        lastIdx = colormap[mapidx].idx
        lastCol = thisCol
    }
    return colors
}

module.exports = function(_numLeds) {
	var self = {

    // FX configuration
    _inputIndexes: [],
    numLeds: _numLeds,
    pixels: [ createAllPixels(_numLeds), createAllPixels(_numLeds) ] ,
    foo: 0,
	type: 'fire',
	color: 'red',
	temperatureColorMap: [],

    getInputIndexes: function() {
        return this._inputIndexes
    },

    getName: function() {
        return "Fire effect"
    },

	init: function() {
		temperatureColorMap = createTemperatureMap(this.color)
	},

    /** idx: the index in the effect list. Can be used to identify parameters.
     */
    getConfigHtml: function(idx) {
		var colorValues = {
			red: "Red Fire",
			blue: "Blue Fire",
			green: "Green Fire",
		}
		var typeValues = {
			fire: 'fire',
			linear: "linear",
		}
		var metaconfig = { c: [
			{ name: 'color', type: 'combo', id: 'color', desc: 'Color of the effect', css:'width:150px;', combo: colorValues },
			{ name: 'type', type: 'combo', id: 'type', desc: 'Type of the effect', css:'width:150px;', combo: typeValues },
		],
		name: this.getName(),
		}
        return util.generateConfigHtml(idx, metaconfig, this.getConfigData())
    },

	getConfigData: function() {
        return {
			color: this.color,
			type: this.type,
        }
	},

	setConfigData: function(data) {
		this.color = data.color
		this.type = data.type
        temperatureColorMap = createTemperatureMap(this.color)
	},

	saveConfigData: function() {
	    var cfg = {
	        foo: this.foo,
	        pixels: this.pixels,
			color: this.color,
			type: this.type,
	    }
		return cfg
	},

	loadConfigData: function(data) {
		this.foo = data.foo
		this.pixels = data.pixels
		this.color = data.color
		this.type = data.type
        temperatureColorMap = createTemperatureMap(this.color)
	},

    renderColors: function(inputColors) {
        var colors = []
    	this.foo += 0.1
    	if (this.foo >= 100) {
    		this.foo -= 100
    		for(var i = 0; i < this.numLeds; i++) {
    			this.pixels[1][i].counter = this.pixels[0][i].counter
    		}
    		this.pixels[0] = this.pixels[1]
console.log("Fire: Recreate Pixels")
    		this.pixels[1] = createAllPixels(this.numLeds)
    	}
    	for(var i = 0; i < this.numLeds; i++) {
    		this.pixels[0][i].counter += (Math.random() + 0.5) * util.map(this.pixels[0][i].speed, this.pixels[1][i].speed, this.foo)
    		if (this.pixels[0][i].counter > 200) this.pixels[0][i].counter = 0
    		var varianz = this.pixels[0][i].counter > 100 ? 200 - this.pixels[0][i].counter : this.pixels[0][i].counter
    		var maxTemp = util.map(this.pixels[0][i].maxTemp, this.pixels[1][i].maxTemp, this.foo)
    		var minTemp = util.map(this.pixels[0][i].minTemp, this.pixels[1][i].minTemp, this.foo)
    		var temp = util.map(maxTemp, minTemp, varianz)

			if (this.type == "linear") {
				temp = 255 * i / (this.numLeds-1)
			}

    		temp = Math.max(0, Math.min(Math.floor(temp), 255))
    		colors[i] = temperatureColorMap[temp]
    	}
    	return colors
    },

}
    self.init()
    return self
}
<|endoftext|>


<commit_before>let box = document.createElement('div');
box.style = 'display:none; position:fixed; top:0px; left:0px; background-color:rgba(0,0,0,0.7); width:100%; height:100%';
let img = document.createElement('img');
img.style = 'display:block; margin:auto; max-width:100%; max-height:100%';
let x = document.createElement('div');
x.style = 'position:fixed;top:0px;right:0px;font-size:1.5em;padding:0.5em;background:rgba(255,255,255,0.7);';
x.textContent = "X";
box.appendChild(img);
box.appendChild(x);
box.addEventListener('click', function(e) { hide(); });
img.addEventListener('click', function(e) { move(+1); e.stopPropagation(); });

let imgs = null, active = null;

function move(n) { show(active + n); }
function hide() { box.style.display = "none"; }

function show(i) {
	if (i >= imgs.length || i < 0) {
		hide();
	} else {
		box.style.display = "block";
		img.src = "";
		img.src = imgs[i].parentNode.href;
		active = i;
	}
}

window.addEventListener('load', function (e) {
	imgs = document.querySelectorAll('img.thz');
	for (let i = 0; i < imgs.length; i++) {
		imgs[i].addEventListener('click', function (e) {
			show(i);
			e.preventDefault();
		});
	}
	document.body.appendChild(box);
});

document.addEventListener('keydown', function (e) {
	if (box.style.display === 'block') {
		let k = {/* <- -> */ 37:-1, 39:+1, /* PgUp, PgDn */ 33:-1, 34:+1};
		if (e.keyCode in k) { move(k[e.keyCode]); e.preventDefault(); }
		else { hide(); }
	}
});
<commit_msg>better cross<commit_after>let box = document.createElement('div');
box.style = 'display:none; position:fixed; top:0px; left:0px; background-color:rgba(0,0,0,0.7); width:100%; height:100%';
let img = document.createElement('img');
img.style = 'display:block; margin:auto; max-width:100%; max-height:100%';
let x = document.createElement('div');
x.style = 'position:fixed;top:0px;right:0px;font-size:1.5em;padding:0.5em;background:rgba(255,255,255,0.7);cursor:pointer';
x.textContent = "❌";
box.appendChild(img);
box.appendChild(x);
box.addEventListener('click', function(e) { hide(); });
img.addEventListener('click', function(e) { move(+1); e.stopPropagation(); });

let imgs = null, active = null;

function move(n) { show(active + n); }
function hide() { box.style.display = "none"; }

function show(i) {
	if (i >= imgs.length || i < 0) {
		hide();
	} else {
		box.style.display = "block";
		img.src = "";
		img.src = imgs[i].parentNode.href;
		active = i;
	}
}

window.addEventListener('load', function (e) {
	imgs = document.querySelectorAll('img.thz');
	for (let i = 0; i < imgs.length; i++) {
		imgs[i].addEventListener('click', function (e) {
			show(i);
			e.preventDefault();
		});
	}
	document.body.appendChild(box);
});

document.addEventListener('keydown', function (e) {
	if (box.style.display === 'block') {
		let k = {/* <- -> */ 37:-1, 39:+1, /* PgUp, PgDn */ 33:-1, 34:+1};
		if (e.keyCode in k) { move(k[e.keyCode]); e.preventDefault(); }
		else { hide(); }
	}
});
<|endoftext|>